Skip to content

feat: agent install telemetry (installer side, spec §8.3)#30

Open
lxcong wants to merge 4 commits into
mainfrom
feat/installer-telemetry
Open

feat: agent install telemetry (installer side, spec §8.3)#30
lxcong wants to merge 4 commits into
mainfrom
feat/installer-telemetry

Conversation

@lxcong
Copy link
Copy Markdown
Contributor

@lxcong lxcong commented May 11, 2026

Summary

Installer-side half of the agent-install telemetry rollout (spec §8.3). Adds --no-telemetry opt-out, telemetry status banner, and 7-var env passthrough to npx -y @agentkey/mcp --auth-login so the server can capture install_completed with full install context.

  • scripts/install.sh: --no-telemetry flag, compute_device_fingerprint() helper, env exports immediately before the --auth-login invocation
  • scripts/install.ps1: PowerShell-mirror of the same — -NoTelemetry, SHA-256 fingerprint, $env:AGENTKEY_* exports

Blocked on

AgentKey-Server PR that consumes the 7 transparent env vars (AGENTKEY_TELEMETRY, AGENTKEY_INSTALL_SOURCE, AGENTKEY_DETECTED_AGENTS, AGENTKEY_SELECTED_AGENTS, AGENTKEY_INSTALLER_FLAGS, AGENTKEY_DEVICE_FINGERPRINT — plus implicit skill-version detection on the server side) and capture install_completed. Until that lands, the env passthrough goes to a process that does nothing with them — harmless, but the telemetry signal is incomplete.

This PR can be merged independently — it does not break the existing installer flow either way.

Test plan

  • bash -n scripts/install.sh — syntactic check passes
  • bash scripts/install.sh --help--no-telemetry documented in Options
  • bash scripts/install.sh --list-agents — early-return path unaffected
  • bash scripts/install.sh --no-telemetry --skip-skill --skip-mcp --yes — creates ~/.config/agentkey/telemetry-disabled, prints "Telemetry: disabled (--no-telemetry)"
  • Pre-existing opt-out file recognized — prints "Telemetry: disabled (~/.config/agentkey/telemetry-disabled exists)"
  • Default (no flag / no file) — prints "Telemetry: anonymous usage stats enabled (re-run with --no-telemetry to opt out)"
  • install.ps1 structural checks (line count, \$NoTelemetry references, single param(...) block, brace balance)
  • PowerShell parse on Windows runner (relies on existing windows-latest CI for any install.ps1-touching PR)

🤖 Generated with Claude Code

@lxcong
Copy link
Copy Markdown
Contributor Author

lxcong commented May 11, 2026

@claude review

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Claude security review requested by @lxcong. Running against HEAD ba123d1e92d8e9d679e5acfd65b2e2eb905dcfd5...

@claude
Copy link
Copy Markdown

claude Bot commented May 11, 2026

🤖 Claude security review — HEAD: ba123d1

Scope: scripts/install.sh + scripts/install.ps1 — adds --no-telemetry / -NoTelemetry flag, opt-out sentinel file, device fingerprint (SHA-256 of hostname+platform+username), and env-var telemetry context passed to npx @agentkey/mcp

⚠️ Convention (violates project rules)

  • Misleading opt-out semantics — both scripts — When --no-telemetry / -NoTelemetry is active, AGENTKEY_DEVICE_FINGERPRINT (derived from hostname+username), AGENTKEY_DETECTED_AGENTS, AGENTKEY_SELECTED_AGENTS, AGENTKEY_INSTALL_SOURCE, and AGENTKEY_INSTALLER_FLAGS are still exported and inherited by the child npx @agentkey/mcp process. Only AGENTKEY_TELEMETRY=0 signals the server. The help text says "Disable anonymous usage telemetry" and the UI prints "Telemetry: disabled", but hostname-derived data still flows to the MCP package unconditionally. If the intent is opt-out-at-server-side (not opt-out-at-source), both the help text and the UI confirmation message must disclose this explicitly; otherwise users have a false expectation of data suppression.

  • install.ps1 help text — -NoTelemetry description says ~/.config/agentkey/telemetry-disabled (Unix notation) but the Windows code writes to %USERPROFILE%\.config\agentkey\telemetry-disabled. Update to use Windows path notation so users know where to find the file.

💡 Suggestion (nice-to-have)

  • scripts/install.sh:L495for _f in "$@" always iterates zero times: the argument-parsing while loop at the top of main() exhausts all positional parameters via shift, so $@ is empty by the time execution reaches the telemetry block. AGENTKEY_INSTALLER_FLAGS is always "". Fix: capture args at main() entry (local _orig_flags="$*") and use that variable here.

Review triggered by @lxcong
via @claude review.

… capture

Three review findings addressed:

1. Misleading opt-out semantics (both scripts) — when --no-telemetry /
   -NoTelemetry was active, only AGENTKEY_TELEMETRY=0 signaled the server,
   but AGENTKEY_DEVICE_FINGERPRINT (sha256 of hostname|platform|user) +
   AGENTKEY_DETECTED_AGENTS + AGENTKEY_SELECTED_AGENTS + the rest were
   still computed and exported to the child `npx @agentkey/mcp` process.
   The help text "Disable anonymous usage telemetry" and the UI banner
   "Telemetry: disabled" implied source-level suppression — the actual
   behavior leaked hostname-derived data regardless. Now opt-out is
   honored at the source: TELEMETRY=0 is the only env exported, the
   fingerprint is never computed, agent lists never passed.

2. install.ps1 -NoTelemetry help text and inline comment referenced
   ~/.config/agentkey/telemetry-disabled (Unix path notation) while
   actually writing to %USERPROFILE%\.config\agentkey\telemetry-disabled.
   Updated to Windows path notation for both.

3. install.sh: `for _f in "$@"` ran on an exhausted $@ — main()'s arg
   parse loop shifts every positional out via `shift`, so by the time the
   telemetry block executed, AGENTKEY_INSTALLER_FLAGS was always empty.
   Snapshot args at main() entry into _orig_args=("$@") and iterate that.
   install.ps1 was already correct because $PSBoundParameters captures
   the parameter set at script entry and is not modified by execution.

Verified opt-out path now exports ONLY AGENTKEY_TELEMETRY=0; opt-in path
exports all 5 context vars with AGENTKEY_INSTALLER_FLAGS correctly
populated (e.g. "--yes,--skip-skill").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lxcong
Copy link
Copy Markdown
Contributor Author

lxcong commented May 11, 2026

@claude review

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Claude security review requested by @lxcong. Running against HEAD cc2b90c5a5b4aa75c7e43c45620d795f883912bf...

@claude
Copy link
Copy Markdown

claude Bot commented May 11, 2026

🤖 Claude security review — HEAD: cc2b90c

Scope: scripts/install.sh + scripts/install.ps1 — adds --no-telemetry / -NoTelemetry flag, opt-out file persistence, and telemetry env-var passthrough to child npx @agentkey/mcp process.

💡 Suggestion (nice-to-have)

  • install.sh vs install.ps1 flag-value asymmetryAGENTKEY_INSTALLER_FLAGS in bash is built from _orig_args[@] (captures raw positional values, e.g. --only,claude-code,cursor), while PowerShell uses $PSBoundParameters.Keys (flag names only, e.g. -Only). Both are harmless in practice (no secret values in these flags), but aligning to names-only in bash avoids unexpected value leakage if the schema ever gains a value-bearing flag that is more sensitive.

    # consider filtering to flag-only tokens:
    for _f in "${_orig_args[@]:-}"; do
        case "$_f" in --*) _flags="${_flags:+$_flags,}$_f" ;; esac
    done
  • install.ps1 SHA256 object not disposed$_sha = [System.Security.Cryptography.SHA256]::Create() allocates an unmanaged crypto object that is never explicitly freed. Add $_sha.Dispose() after the ComputeHash call to release the handle promptly.


✅ No credential leaks, shell injection, or supply-chain issues found. SKILL_REPO / $SkillRepo invariants intact. PR title is valid conventional-commit format. No managed files (version.txt, CHANGELOG.md, plugin.json) touched.

Review triggered by @lxcong
via @claude review.

@lxcong lxcong marked this pull request as ready for review May 11, 2026 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant