Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,27 @@ Skills follow the [Agent Skills](https://agentskills.io/) format and the kit shi

👉 **Capabilities and skill catalog:** [`docs/SKILLS.md`](docs/SKILLS.md)

### Install scripts (with optional usage telemetry)

Cross-platform installers copy or symlink the `skills/` folder into your agent's
skills directory:

```powershell
# Windows / PowerShell
./scripts/install.ps1 -Target claude-user
```

```bash
# macOS / Linux
./scripts/install.sh --target claude-user
```

These installers can send **anonymous, opt-in** usage telemetry (which skills
were installed) to help maintainers prioritize. Telemetry is **off by default**
and only sent when you pass `-Telemetry` / `--telemetry` (or set
`DDBKIT_TELEMETRY=1`). See [TELEMETRY.md](TELEMETRY.md) for exactly what is and
is not collected.

## Repo Structure

```
Expand Down
59 changes: 59 additions & 0 deletions TELEMETRY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Usage Telemetry

The documentdb-agent-kit installers (`scripts/install.ps1`, `scripts/install.sh`)
can send **anonymous, opt-in** usage telemetry so the maintainers can see which
skills are actually installed and prioritize accordingly.

## Opt-in only — off by default

Telemetry is **never** sent unless you explicitly enable it:

- PowerShell: `./scripts/install.ps1 -Target claude-user -Telemetry`
- Bash: `./scripts/install.sh --target claude-user --telemetry`
- Or set the environment variable `DDBKIT_TELEMETRY=1`.

If you do nothing, no network call is made. A telemetry failure never blocks or
fails an install.

## What is collected

A single `skill_install` event with these fields:

| Field | Example | Purpose |
|---|---|---|
| `kitVersion` | `1.0.0` | Which kit version was installed |
| `target` | `claude-user` | Which agent/target folder |
| `osFamily` | `windows` / `macos` / `linux` | Coarse platform mix |
| `method` | `copy` / `symlink` | How skills were installed |
| `skills` | `data-modeling,indexing,…` | Which skill folders were installed |
| `skillCount` | `16` | Number of skills installed |
| `invocationId` | random GUID | De-duplicate a single run; **not** stable across runs |

## What is NOT collected

- No file contents, source code, or query data.
- No connection strings, credentials, or App Insights keys.
- No usernames, hostnames, IP-derived identity, MAC addresses, or any stable
machine/user identifier. `invocationId` is random per run and cannot be
correlated across installs.

## Where it goes

Events are sent to an Azure Application Insights resource via its ingestion
endpoint (`https://dc.services.visualstudio.com/v2/track`). The installers ship
**without** a live key — the `INSTRUMENTATION_KEY` is a `<placeholder>`. To
enable telemetry against your own resource, provide an ingestion-only
instrumentation key through the `DDBKIT_AIKEY` environment variable:

```bash
DDBKIT_AIKEY="<your-instrumentation-key>" ./scripts/install.sh --target claude-user --telemetry
```

If no key is configured, the installer skips the telemetry send even when
`--telemetry` is passed.

## Opting out permanently

Simply never pass `--telemetry` / `-Telemetry` and leave `DDBKIT_TELEMETRY`
unset (or set it to `0`). You can also delete the telemetry block at the bottom
of the install scripts.
135 changes: 135 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<#
.SYNOPSIS
Install the documentdb-agent-kit skills into an agent's skills directory,
with OPTIONAL, opt-in usage telemetry.

.DESCRIPTION
Copies (or symlinks) the skills/ folder into a target agent directory.
Telemetry is OFF by default. It is only sent when you explicitly pass
-Telemetry, or set the environment variable DDBKIT_TELEMETRY=1.

When enabled, a single anonymous "install" event is sent to Azure
Application Insights recording: which target agent was used, the list of
skill names installed, kit version, and coarse OS family. No file contents,
no personal data, no connection strings, and no machine identifiers beyond a
random per-invocation id are collected. See TELEMETRY.md for the full schema.

.PARAMETER Target
Where to install: 'claude-user', 'claude-project', or a custom path.

.PARAMETER Telemetry
Opt in to sending the anonymous install event.

.PARAMETER Symlink
Symlink instead of copy (requires privilege/developer mode on Windows).

.EXAMPLE
./scripts/install.ps1 -Target claude-project

.EXAMPLE
./scripts/install.ps1 -Target claude-user -Telemetry
#>
[CmdletBinding()]
param(
[ValidateNotNullOrEmpty()]
[string]$Target = 'claude-project',
[switch]$Telemetry,
[switch]$Symlink
)

$ErrorActionPreference = 'Stop'

# --- Config -----------------------------------------------------------------
$KitVersion = '1.0.0'
# App Insights ingestion key. Supply your own via the DDBKIT_AIKEY environment
# variable. An instrumentation key is an ingestion-only identifier; it is kept
# out of source control here so the repo ships without a live endpoint.
$InstrumentationKey = if ($env:DDBKIT_AIKEY) { $env:DDBKIT_AIKEY } else { '<YOUR_APPINSIGHTS_INSTRUMENTATION_KEY>' }
$IngestionEndpoint = 'https://dc.services.visualstudio.com/v2/track'

$RepoRoot = Split-Path -Parent $PSScriptRoot
$SkillsRoot = Join-Path $RepoRoot 'skills'

if (-not (Test-Path $SkillsRoot)) {
throw "skills/ not found at '$SkillsRoot'. Run this from inside the documentdb-agent-kit repo."
}

# --- Resolve target directory ----------------------------------------------
switch ($Target) {
'claude-project' { $Dest = Join-Path $RepoRoot '.claude/skills' }
'claude-user' { $Dest = Join-Path $HOME '.claude/skills' }
default { $Dest = $Target }
}

New-Item -ItemType Directory -Force -Path $Dest | Out-Null

# --- Install ----------------------------------------------------------------
$installed = @()
Get-ChildItem -Path $SkillsRoot -Directory | ForEach-Object {
$name = $_.Name
$linkPath = Join-Path $Dest $name
if (Test-Path $linkPath) { Remove-Item $linkPath -Recurse -Force }

if ($Symlink) {
New-Item -ItemType SymbolicLink -Path $linkPath -Target $_.FullName | Out-Null
}
else {
Copy-Item -Path $_.FullName -Destination $linkPath -Recurse -Force
}
$installed += $name
}

Write-Host "Installed $($installed.Count) skills into $Dest" -ForegroundColor Green
$installed | ForEach-Object { Write-Host " - $_" }

# --- Opt-in telemetry -------------------------------------------------------
$telemetryOn = $Telemetry -or ($env:DDBKIT_TELEMETRY -eq '1')

if (-not $telemetryOn) {
Write-Host ''
Write-Host 'Usage telemetry: OFF. Re-run with -Telemetry (or set DDBKIT_TELEMETRY=1) to' -ForegroundColor DarkGray
Write-Host 'help the maintainers see which skills are installed. See TELEMETRY.md.' -ForegroundColor DarkGray
return
}

if ($InstrumentationKey -like '<*>') {
Write-Host ''
Write-Host 'Telemetry requested but no App Insights key configured. Set DDBKIT_AIKEY to enable. Skipping.' -ForegroundColor DarkYellow
return
}

try {
$osFamily = if ($IsWindows) { 'windows' } elseif ($IsMacOS) { 'macos' } elseif ($IsLinux) { 'linux' } else { 'unknown' }

$payload = @{
name = 'Microsoft.ApplicationInsights.Event'
time = (Get-Date).ToUniversalTime().ToString('o')
iKey = $InstrumentationKey
tags = @{ 'ai.cloud.role' = 'documentdb-agent-kit-installer' }
data = @{
baseType = 'EventData'
baseData = @{
ver = 2
name = 'skill_install'
properties = @{
kitVersion = $KitVersion
target = $Target
osFamily = $osFamily
method = if ($Symlink) { 'symlink' } else { 'copy' }
skills = ($installed -join ',')
invocationId = [guid]::NewGuid().ToString()
}
measurements = @{ skillCount = $installed.Count }
}
}
} | ConvertTo-Json -Depth 6 -Compress

Invoke-RestMethod -Uri $IngestionEndpoint -Method Post -Body $payload -ContentType 'application/json' -TimeoutSec 10 | Out-Null
Write-Host ''
Write-Host 'Anonymous install event sent. Thank you!' -ForegroundColor Green
}
catch {
# Telemetry must never break an install.
Write-Host ''
Write-Host "Telemetry send failed (ignored): $($_.Exception.Message)" -ForegroundColor DarkYellow
}
134 changes: 134 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#!/usr/bin/env bash
#
# Install the documentdb-agent-kit skills into an agent's skills directory,
# with OPTIONAL, opt-in usage telemetry.
#
# Telemetry is OFF by default. It is only sent when you pass --telemetry or set
# DDBKIT_TELEMETRY=1. When enabled, one anonymous "install" event is sent to
# Azure Application Insights: target agent, list of skill names, kit version,
# and OS family. No file contents, personal data, or machine identifiers beyond
# a random per-invocation id. See TELEMETRY.md.
#
# Usage:
# ./scripts/install.sh [--target claude-project|claude-user|<path>] [--symlink] [--telemetry]
#
set -euo pipefail

# --- Config -----------------------------------------------------------------
KIT_VERSION="1.0.0"
# App Insights ingestion key. Supply your own via the DDBKIT_AIKEY environment
# variable. An instrumentation key is an ingestion-only identifier; it is kept
# out of source control here so the repo ships without a live endpoint.
INSTRUMENTATION_KEY="${DDBKIT_AIKEY:-<YOUR_APPINSIGHTS_INSTRUMENTATION_KEY>}"
INGESTION_ENDPOINT="https://dc.services.visualstudio.com/v2/track"

TARGET="claude-project"
SYMLINK=0
TELEMETRY=0

while [[ $# -gt 0 ]]; do
case "$1" in
--target) TARGET="$2"; shift 2 ;;
--symlink) SYMLINK=1; shift ;;
--telemetry) TELEMETRY=1; shift ;;
*) echo "Unknown option: $1" >&2; exit 1 ;;
esac
done

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
SKILLS_ROOT="$REPO_ROOT/skills"

if [[ ! -d "$SKILLS_ROOT" ]]; then
echo "skills/ not found at '$SKILLS_ROOT'. Run this from inside the documentdb-agent-kit repo." >&2
exit 1
fi

# --- Resolve target directory ----------------------------------------------
case "$TARGET" in
claude-project) DEST="$REPO_ROOT/.claude/skills" ;;
claude-user) DEST="$HOME/.claude/skills" ;;
*) DEST="$TARGET" ;;
esac

mkdir -p "$DEST"

# --- Install ----------------------------------------------------------------
installed=()
for dir in "$SKILLS_ROOT"/*/; do
name="$(basename "$dir")"
link="$DEST/$name"
rm -rf "$link"
if [[ "$SYMLINK" -eq 1 ]]; then
ln -s "$dir" "$link"
else
cp -R "$dir" "$link"
fi
installed+=("$name")
done

echo "Installed ${#installed[@]} skills into $DEST"
for s in "${installed[@]}"; do echo " - $s"; done

# --- Opt-in telemetry -------------------------------------------------------
if [[ "$TELEMETRY" -ne 1 && "${DDBKIT_TELEMETRY:-}" != "1" ]]; then
echo ""
echo "Usage telemetry: OFF. Re-run with --telemetry (or set DDBKIT_TELEMETRY=1) to"
echo "help the maintainers see which skills are installed. See TELEMETRY.md."
exit 0
fi

case "$INSTRUMENTATION_KEY" in
"<"*">") echo "" ; echo "Telemetry requested but no App Insights key configured. Set DDBKIT_AIKEY to enable. Skipping." ; exit 0 ;;
esac

if ! command -v curl >/dev/null 2>&1; then
echo "" ; echo "curl not found; skipping telemetry." ; exit 0
fi

case "$(uname -s)" in
Linux*) OS_FAMILY="linux" ;;
Darwin*) OS_FAMILY="macos" ;;
MINGW*|MSYS*|CYGWIN*) OS_FAMILY="windows" ;;
*) OS_FAMILY="unknown" ;;
esac

method=$([[ "$SYMLINK" -eq 1 ]] && echo "symlink" || echo "copy")
skills_csv="$(IFS=,; echo "${installed[*]}")"
now="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
invocation_id="$(cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "$RANDOM-$RANDOM-$RANDOM")"

payload=$(cat <<JSON
{
"name": "Microsoft.ApplicationInsights.Event",
"time": "$now",
"iKey": "$INSTRUMENTATION_KEY",
"tags": { "ai.cloud.role": "documentdb-agent-kit-installer" },
"data": {
"baseType": "EventData",
"baseData": {
"ver": 2,
"name": "skill_install",
"properties": {
"kitVersion": "$KIT_VERSION",
"target": "$TARGET",
"osFamily": "$OS_FAMILY",
"method": "$method",
"skills": "$skills_csv",
"invocationId": "$invocation_id"
},
"measurements": { "skillCount": ${#installed[@]} }
}
}
}
JSON
)

# Telemetry must never break an install.
if curl -sf -m 10 -X POST "$INGESTION_ENDPOINT" \
-H "Content-Type: application/json" \
-d "$payload" >/dev/null 2>&1; then
echo "" ; echo "Anonymous install event sent. Thank you!"
else
echo "" ; echo "Telemetry send failed (ignored)."
fi
Loading