You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: Add CLI telemetry instrumentation and remove deprecated SDK (#233)
* feat: implement CLI and MCP telemetry instrumentation
Extend the telemetry header with source, environment, command_path,
invocation_id, and mcp_client fields so the API server can distinguish
CLI from MCP requests and correlate multiple API calls to a single
command invocation.
Phase 1 - Telemetry struct & CLI wiring:
- Add Source, Environment, InvocationID, MCPClient fields to CLITelemetry
- Add NewInvocationID() generator (8 random bytes, hex-encoded)
- Add initTelemetry() helper called from root PersistentPreRun
- Fix Cobra PersistentPreRun chaining for connection command
Phase 2 - MCP per-request telemetry:
- Add Telemetry field + WithTelemetry() clone method on Client
- Update PerformRequest to use per-request telemetry when set
- Wrap MCP tool handlers to set per-invocation telemetry context
- Extract MCP client info from ServerSession.InitializeParams()
Phase 3 - SDK client:
- Works automatically: PersistentPreRun populates singleton before
GetClient() bakes headers at construction time
Phase 5 - Config-based opt-out:
- Add TelemetryDisabled to Config, read from config.toml
- Update telemetryOptedOut() to accept config flag
- Thread TelemetryDisabled through API and SDK client construction
Phase 6 - CI detection:
- Add DetectEnvironment() checking CI, GITHUB_ACTIONS, GITLAB_CI,
JENKINS_URL, CODEBUILD_BUILD_ID, BUILDKITE, TF_BUILD env vars
- Tag requests with environment: "ci" or "interactive"
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* test: add end-to-end MCP telemetry integration tests
Add 6 integration tests that exercise the full pipeline:
MCP tool call → wrapWithTelemetry → HTTP request → mock API server,
verifying the Hookdeck-CLI-Telemetry header arrives with correct content.
Tests cover:
- Header sent with correct source/command_path/invocation_id/mcp_client
- Each tool call gets a unique invocation ID
- Command path reflects the action (hookdeck_sources/list vs /get)
- Telemetry disabled by config (TelemetryDisabled=true)
- Telemetry disabled by env var (HOOKDECK_CLI_TELEMETRY_OPTOUT=true)
- Multiple API calls within one tool invocation share the same ID
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* feat: add `hookdeck telemetry enable/disable` CLI command
Adds a telemetry subcommand with enable/disable actions so users can
toggle anonymous telemetry without manually editing config.toml.
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* refactor: make enable/disable positional args of telemetry command
Instead of separate subcommands, `hookdeck telemetry enable` and
`hookdeck telemetry disable` now use a single command with a required
positional argument. Also adds telemetry section to the README.
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* test: add singleton reset functions and CLI telemetry tests
Add ResetTelemetryInstanceForTesting() and ResetAPIClientForTesting()
to enable isolated testing of the CLI telemetry path. Add tests that
verify the singleton reset → populate → HTTP request → header cycle,
singleton isolation between sequential commands, and initTelemetry
correctness including generated resource detection.
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* Extract telemetry header name to constant with RFC 6648 comment
Add TelemetryHeaderName constant to avoid hardcoded header strings
across the codebase. Include a comment explaining why we omit the
"X-" prefix (deprecated by RFC 6648).
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* Remove deprecated hookdeck-go-sdk, migrate listen to direct API client
The listen command was the only consumer of the hookdeck-go-sdk (pinned
to API version 2024-03-01). This migrates it to use the direct
hookdeck.Client which hits the current API version (2025-07-01) and
reads telemetry from the singleton on every request — fixing the gap
where the SDK client baked headers at creation time and never updated.
- Replace all hookdecksdk types with hookdeck types (Source, Connection,
Destination) across listen/, proxy/, and tui/ packages
- Replace SDK client calls (Source.List, Connection.Create, etc.) with
direct Client methods (ListSources, CreateConnection, etc.)
- Use Destination.GetCLIPath()/SetCLIPath() instead of direct CliPath field
- Delete pkg/hookdeck/sdkclient.go and pkg/config/sdkclient.go
- Remove github.com/hookdeck/hookdeck-go-sdk from go.mod
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* Rename telemetry header to X-Hookdeck-CLI-Telemetry
Add X- prefix for consistency with X-Hookdeck-Client-User-Agent.
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
* test: parallelize acceptance tests into three slices (#234)
* docs: generate REFERENCE.md in-place, remove REFERENCE.template.md
- Default input is REFERENCE.md; run with no args for in-place update
- Update README generator instructions and --check example
- Remove REFERENCE.template.md
Made-with: Cursor
* feat!: introduce Hookdeck config file and root --hookdeck-config flag
- Rename root-level --config to --hookdeck-config to avoid conflict with
source/destination --config (JSON body) and --config-file (JSON path).
- Add HOOKDECK_CONFIG_FILE env var for config path; precedence is flag,
then env, then .hookdeck/config.toml, then default location.
- Document env var and flag in README (precedence list and Global Flags).
- Update REFERENCE.md global options and acceptance tests.
Made-with: Cursor
* test: parallelize acceptance tests into three slices
- Add feature build tags to all automated acceptance test files so tests
can be split across parallel runs (CI and local).
- CI: run three matrix jobs with tags split by estimated runtime; each job
uses its own API key (HOOKDECK_CLI_TESTING_API_KEY, _2, _3).
- Local: run_parallel.sh runs three slices in parallel, writing to
test/acceptance/logs/slice0.log, slice1.log, slice2.log; add logs/ to
.gitignore.
- Helpers: support ACCEPTANCE_SLICE=2 and HOOKDECK_CLI_TESTING_API_KEY_3;
per-slice config path and API key selection for isolated projects.
- Rebalance slices for ~5–5.5 min wall time (slice 0: connection/source/
destination/gateway/etc.; slice 1: request, event; slice 2: attempt,
metrics, issue, transformation).
- Document three-slice setup, tags, and run commands in test/acceptance/README.md.
Made-with: Cursor
* Consolidate API client usage and fix telemetry opt-out for all clients
Several places constructed hookdeck.Client directly, bypassing
GetAPIClient(). These clients didn't carry TelemetryDisabled from
config, so they'd send telemetry even when the user had opted out.
Two-layer fix:
1. Safety net: Add Disabled flag to the telemetry singleton. PerformRequest
now checks both the per-client TelemetryDisabled and the singleton's
Disabled flag, so even stray clients respect the config-level opt-out.
2. Consistency: Route as many callers as possible through GetAPIClient():
- project.go: use config.GetAPIClient() instead of raw construction
- whoami.go: use Config.GetAPIClient().ValidateAPIKey()
- Login() validate path: use config.GetAPIClient().ValidateAPIKey()
- proxy.go createSession: receive APIClient via proxy.Config
- tui/model.go: receive APIClient via tui.Config
- Remove login/validate.go (no longer called)
For unauthenticated login clients (Login, GuestLogin, CILogin,
InteractiveLogin, MCP tool_login), pass TelemetryDisabled from config.
https://claude.ai/code/session_01TQFynqFrXsP38LuYmdERYL
---------
Co-authored-by: Claude <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: AGENTS.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -354,6 +354,9 @@ if apiErr, ok := err.(*hookdeck.APIError); ok {
354
354
### Acceptance Test Setup
355
355
Acceptance tests require a Hookdeck API key. See [`test/acceptance/README.md`](test/acceptance/README.md) for full details. Quick setup: create `test/acceptance/.env` with `HOOKDECK_CLI_TESTING_API_KEY=<key>`. The `.env` file is git-ignored and must never be committed.
356
356
357
+
### Acceptance tests and feature tags
358
+
Acceptance tests in `test/acceptance/` are partitioned by **feature build tags** so they can run in parallel (two slices in CI and locally). Each test file must have exactly one feature tag (e.g. `//go:build connection`, `//go:build request`). The runner (CI workflow or `run_parallel.sh`) maps features to slices and passes the corresponding `-tags="..."`; see [test/acceptance/README.md](test/acceptance/README.md) for slice mapping and setup. **Every new acceptance test file must have a feature tag**; otherwise it is included in every build and runs in both slices (duplicated). Use tags to balance and parallelize; same commands and env for local and CI.
0 commit comments