Skip to content
Merged
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
46 changes: 46 additions & 0 deletions scripts/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
irm https://agentkey.app/install.ps1 | iex
& ([scriptblock]::Create((irm https://agentkey.app/install.ps1))) -Yes
& ([scriptblock]::Create((irm https://agentkey.app/install.ps1))) -Only "claude-code,cursor"
& ([scriptblock]::Create((irm https://agentkey.app/install.ps1))) -NoTelemetry

Behavior mirrors install.sh: checks Node >= 18 (installs via winget/scoop/choco),
auto-detects which AI agents are installed and runs `npx skills add` for them,
Expand All @@ -28,6 +29,7 @@ param(
[switch]$ForceMcp,
[switch]$SkipSkill,
[switch]$SkipMcp,
[switch]$NoTelemetry,
[switch]$Help
)

Expand Down Expand Up @@ -159,6 +161,9 @@ Parameters:
-ForceMcp Re-run MCP auth even if AgentKey is already configured
-SkipSkill Skip the skill install step (only run MCP auth)
-SkipMcp Skip the MCP auth step (only install the skill)
-NoTelemetry Disable anonymous usage telemetry (writes
%USERPROFILE%\.config\agentkey\telemetry-disabled so
the skill stays opted-out across runs)
-Help Show this help

Behavior:
Expand Down Expand Up @@ -213,6 +218,19 @@ else {
}
Write-Ok "Mode: $Mode"

# Resolve telemetry intent: -NoTelemetry overrides everything; existing
# %USERPROFILE%\.config\agentkey\telemetry-disabled file means already-opted-out.
$TelemetryOptOutFile = Join-Path $env:USERPROFILE '.config\agentkey\telemetry-disabled'
if ($NoTelemetry) {
New-Item -ItemType Directory -Path (Split-Path $TelemetryOptOutFile) -Force | Out-Null
New-Item -ItemType File -Path $TelemetryOptOutFile -Force | Out-Null
Write-Ok 'Telemetry: disabled (-NoTelemetry)'
} elseif (Test-Path -LiteralPath $TelemetryOptOutFile) {
Write-Ok "Telemetry: disabled ($TelemetryOptOutFile exists)"
} else {
Write-Info 'Telemetry: anonymous usage stats enabled (re-run with -NoTelemetry to opt out)'
}

# Node check
function Get-NodeMajor {
try {
Expand Down Expand Up @@ -357,6 +375,34 @@ if ($SkipMcp) {
}
Write-Host ''

# Telemetry context for install_completed. Opt-out is honored at the
# SOURCE: when AGENTKEY_TELEMETRY=0, no other context env vars are
# exported — hostname-derived fingerprint, agent lists, and installer
# flags are never computed nor passed to the child `npx @agentkey/mcp`
# process. The server treats AGENTKEY_TELEMETRY=0 as a hard skip.
if ($NoTelemetry -or (Test-Path -LiteralPath $TelemetryOptOutFile)) {
$env:AGENTKEY_TELEMETRY = '0'
} else {
$env:AGENTKEY_TELEMETRY = '1'

$_hn = [System.Net.Dns]::GetHostName()
$_user = $env:USERNAME
$_input = "$_hn|windows|$_user"
$_bytes = [System.Text.Encoding]::UTF8.GetBytes($_input)
$_sha = [System.Security.Cryptography.SHA256]::Create()
$_hash = ($_sha.ComputeHash($_bytes) | ForEach-Object { $_.ToString('x2') }) -join ''
$DeviceFingerprint = $_hash.Substring(0, 16)

$DetectedAgents = Get-DetectedAgents
if (-not (Get-Variable -Name targets -Scope Script -ErrorAction SilentlyContinue)) { $targets = @() }

$env:AGENTKEY_INSTALL_SOURCE = 'one_liner'
$env:AGENTKEY_DETECTED_AGENTS = ($DetectedAgents -join ',')
$env:AGENTKEY_SELECTED_AGENTS = ($targets -join ',')
$env:AGENTKEY_INSTALLER_FLAGS = ($PSBoundParameters.Keys | ForEach-Object { "-$_" }) -join ','
$env:AGENTKEY_DEVICE_FINGERPRINT = $DeviceFingerprint
}

& npx -y $McpPackage @authArgs
if ($LASTEXITCODE -ne 0) {
Write-Err 'MCP auth failed.'
Expand Down
63 changes: 63 additions & 0 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ Options:
--force-mcp Re-run MCP auth even if AgentKey is already configured
--skip-skill Skip the skill install step (only run MCP auth)
--skip-mcp Skip the MCP auth step (only install the skill)
--no-telemetry Disable anonymous usage telemetry (writes
~/.config/agentkey/telemetry-disabled so the skill
stays opted-out across runs)
-h, --help Show this help

Behavior:
Expand Down Expand Up @@ -237,6 +240,26 @@ install_node() {
ui_ok "Node.js installed"
}

# Compute a stable per-device fingerprint for install_completed dedup.
# spec §6.3: sha256(hostname+platform+username)[:16]. Falls back to a random
# value if neither sha256sum nor shasum is available (extremely rare).
compute_device_fingerprint() {
local platform="$1"
local hn user input hash
hn="$(hostname 2>/dev/null || echo "")"
user="${USER:-$(id -un 2>/dev/null || echo "")}"
input="$hn|$platform|$user"
if command -v sha256sum >/dev/null 2>&1; then
hash="$(printf '%s' "$input" | sha256sum | cut -c1-16)"
elif command -v shasum >/dev/null 2>&1; then
hash="$(printf '%s' "$input" | shasum -a 256 | cut -c1-16)"
else
# Last resort: use $RANDOM. Won't dedup across runs but won't crash.
hash="rnd$(printf '%04x%04x%04x' "$RANDOM" "$RANDOM" "$RANDOM")"
fi
printf '%s' "$hash"
}

# ──────────────────────────────────────────────────────────────────────────
# main — wraps the entire procedural body so that under `curl | bash`
# bash finishes reading the script before any fd-rebinding happens.
Expand All @@ -256,6 +279,11 @@ main() {
# `set -u` happy.
FORCE_REMOTE=false
FORCE_LOCAL=false
local NO_TELEMETRY=false

# Snapshot original args before the parse loop shifts them away — needed
# later for AGENTKEY_INSTALLER_FLAGS env passthrough.
local _orig_args=("$@")

while [ $# -gt 0 ]; do
case "$1" in
Expand All @@ -270,6 +298,7 @@ main() {
--force-mcp) FORCE_MCP=true; shift ;;
--skip-skill) SKIP_SKILL=true; shift ;;
--skip-mcp) SKIP_MCP=true; shift ;;
--no-telemetry) NO_TELEMETRY=true; shift ;;
-h|--help) PRINT_HELP=true; shift ;;
*) ui_warn "Unknown argument: $1"; shift ;;
esac
Expand Down Expand Up @@ -332,6 +361,19 @@ main() {
fi
ui_ok "Mode: $MODE"

# Resolve telemetry intent: --no-telemetry overrides everything; existing
# ~/.config/agentkey/telemetry-disabled file means already-opted-out.
local TELEMETRY_OPT_OUT_FILE="$HOME/.config/agentkey/telemetry-disabled"
if $NO_TELEMETRY; then
mkdir -p "$(dirname "$TELEMETRY_OPT_OUT_FILE")" 2>/dev/null || true
touch "$TELEMETRY_OPT_OUT_FILE" 2>/dev/null || true
ui_ok "Telemetry: disabled (--no-telemetry)"
elif [ -f "$TELEMETRY_OPT_OUT_FILE" ]; then
ui_ok "Telemetry: disabled (~/.config/agentkey/telemetry-disabled exists)"
else
ui_info "Telemetry: anonymous usage stats enabled (re-run with --no-telemetry to opt out)"
fi

# Node check
local NODE_OK=false NODE_VERSION NODE_MAJOR
if command -v node >/dev/null 2>&1; then
Expand Down Expand Up @@ -471,6 +513,27 @@ main() {
fi
echo

# Telemetry context for `install_completed`. Opt-out is honored at
# the SOURCE: when AGENTKEY_TELEMETRY=0, no other context env vars
# are exported — hostname-derived fingerprint, agent lists, and
# installer flags are never computed nor passed to the child
# `npx @agentkey/mcp` process. The server treats AGENTKEY_TELEMETRY=0
# as a hard skip.
if $NO_TELEMETRY || [ -f "$TELEMETRY_OPT_OUT_FILE" ]; then
export AGENTKEY_TELEMETRY=0
else
export AGENTKEY_TELEMETRY=1
local _flags=""
for _f in "${_orig_args[@]:-}"; do
_flags="${_flags:+$_flags,}$_f"
done
export AGENTKEY_INSTALL_SOURCE="one_liner"
export AGENTKEY_DETECTED_AGENTS="$(detect_agents)"
export AGENTKEY_SELECTED_AGENTS="${TARGETS:-}"
export AGENTKEY_INSTALLER_FLAGS="$_flags"
export AGENTKEY_DEVICE_FINGERPRINT="$(compute_device_fingerprint "$PLATFORM")"
fi

if ! npx -y "$MCP_PACKAGE" "${AUTH_ARGS[@]}"; then
ui_error "MCP auth failed."
ui_muted "Retry manually: npx -y $MCP_PACKAGE ${AUTH_ARGS[*]}"
Expand Down
Loading