feat(sdk): emit X-DevHelm-Surface telemetry headers#13
Merged
Conversation
Adds optional surface identification to every authenticated API call so the API can attribute usage to the right devtool. Wire contract docs at https://devhelm.io/telemetry; matching API-side handler in mono#332. Headers emitted by default (every request): - X-DevHelm-Surface: sdk-js - X-DevHelm-Surface-Version: package.json version (resolved at module load via createRequire so the constant tracks pkg without a release-script edit) - X-DevHelm-Sdk-Name: sdk-js Wrappers can override `surface` / `surfaceVersion` / `surfaceMetadata` at construction time so their traffic is attributed correctly: new Devhelm({ token: ..., surface: 'mcp', surfaceVersion: '0.5.0', surfaceMetadata: { 'Mcp-Client': 'cursor' }, }) The SDK identity (X-DevHelm-Sdk-Name) is preserved alongside the wrapper surface so the API can still distinguish wrapper-on-top-of-v0.5-SDK from wrapper-on-top-of-v0.6-SDK when debugging client-version skew. Opt-out is a single env var, not per-call: DEVHELM_TELEMETRY=0 drops every X-DevHelm-Surface* header at the client level. Auth + tenant headers are unaffected. Zero callsite changes — the surface is set once when the Devhelm client is constructed; every existing tool/test using `new Devhelm(...)` keeps working unchanged. Tests: 3 new tests in http.test.ts using a stub global fetch to assert the outbound Headers, covering defaults, wrapper override, and env opt-out. Full suite (1306) green; eslint + tsc clean. Bumped to 0.6.0 (additive feature; matches sdk-python release cadence). Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reports the SDK's identity to the DevHelm API on every authenticated request so the API can attribute usage to the right devtool. Wire contract documented at https://devhelm.io/telemetry; the matching API-side handler shipped in
devhelmhq/mono#332.Companion PR for the Python SDK:
devhelmhq/sdk-python#19.What lands on the wire (defaults)
The version is read from `package.json` at module load with `createRequire` so the constant tracks the published version automatically — no release-script edit needed to keep them in lockstep.
Wrapper override
```ts
new Devhelm({
token: ...,
surface: 'mcp',
surfaceVersion: '0.5.0',
surfaceMetadata: { 'Mcp-Client': 'cursor' },
})
```
The SDK identity (`X-DevHelm-Sdk-Name: sdk-js`) is preserved alongside the wrapper surface so the API can distinguish wrapper-on-top-of-v0.5-SDK from wrapper-on-top-of-v0.6-SDK when debugging client-version skew.
Opt-out
`DEVHELM_TELEMETRY=0` drops every `X-DevHelm-Surface*` header at the client level. Single env var, not per-call. Auth and tenant headers are unaffected.
Zero callsite changes
Surface is set once when `new Devhelm(...)` is constructed. Every existing tool/test using the SDK keeps working unchanged.
Tests
Version bumped to `0.6.0` (additive feature; matches `sdk-python` release cadence).
Test plan
Made with Cursor