feat(sdk,cli): SDK usage telemetry and client identity headers for the SDK and CLI
Merged
SA
2mo ago+242+242+012345678901234567890123456789-55-55-01234567890123456789
Summary
Instruments @superset_sh/sdk the way the CLI is instrumented so the "MCP & CLI Usage" dashboard can show SDK usage. The four SDK tiles on dashboard 1566665 read sdk_method_called, broken down by method and sdk_version; those names are unchanged.
- Every public resource method reports one
sdk_method_calledevent toanalytics.captureEventwithsource: "sdk"andproperties: { method, sdk_version, sdk_lang, runtime, target, success, duration_ms }.methodis the public name the caller typed (tasks.list,workspaces.create), never the tRPC path. - The report is issued from the
APIPromiseparse step inside the hand-written tRPC helpers, which now also owns the envelope unwrap:success: trueonly once the caller's data has resolved,falseon transport, HTTP, or parse errors, andduration_msruns to final settlement. It never sits in the caller's chain (no await, no throw, no retry, one 10 s timeout) and does not force a parse on callers that only wantasResponse(), so those calls go unreported rather than double-reading the body. The capture goes throughpost, so it is not itself reported. A sync bug in telemetry is caught too. SUPERSET_TELEMETRY=0(orfalse) opts out. The CLI has no opt-out today, so there was no existing name to reuse.- Cloud requests send
x-superset-client: sdk/<version>.ApiClientInfo.productandCLIENT_HEADER_PATTERNacceptsdk. The only consumers ofproductare the Sentry tag inapps/apiand theclient_productproperty; neither switches on it exhaustively. No test fixtures reference the header. - Docs: a Telemetry note in
apps/docs/.../sdk/reference.mdxandpackages/sdk/api.md. The CLI reference says nothing about its telemetry, so there was nothing to mirror; the note is short.
Design notes
- Stainless's CONTRIBUTING says the generator never touches
src/lib/, so the telemetry module lives atpackages/sdk/src/lib/telemetry.ts. Neitherstainless-sdks/superset-typescriptnorcadra-typescriptwires analytics, and the generated client only exposes pre-request hooks (prepareOptions,prepareRequest), so observing the response promise in our own helpers is the smallest way to getsuccessandduration_ms. client.tscarries a "generated" header but has eight hand-edit commits (the tRPC and host helpers are ours, no Stainless config exists in the repo). The edits are confined to those helpers plus one header line inbuildHeaders, next toUser-Agentand theX-Stainless-*identity headers.- The helpers now take
{ method, procedure }instead of a bare procedure string, which touches all 32 resource call sites but keeps the label explicit rather than a mapping table that would drift. VERSIONinversion.tswas still0.0.1-alpha.7whilepackage.jsonand npm are atalpha.12, so every published SDK since alpha.8 has identified itself as alpha.7.scripts/build.tsnow rewritessrc/version.tsfrompackage.jsonbefore bundling, so the publishedUser-Agent,x-superset-client, andsdk_versionalways match. Publishing is manual (bun run build, thennpm publishfromdist/) with no CI path around it, so the stamp cannot be skipped; the build script header now documents the release steps and thatversion.tsis never hand-edited.runtimereusesdetect-platform.ts(X-Stainless-Runtime) and adds aprocess.versions.buncheck, since Stainless reports Bun asnode.- The CLI did not send
x-superset-clientat all (only desktop and mobile did), so CLI-caused API errors and CLI procedure usage were invisible to the same two consumers. It now sendscli/<version>from theheaders()callback inpackages/cli/src/lib/api-client.ts; the server already acceptedcli. Dev builds sendcli/0.0.0-dev, which matches the pattern.
Verification
bun run lint:fix,bun run typecheck,bunx sherif --fix: clean.bun testper package:packages/trpc125 pass,packages/cli143 pass. (A root-levelbun testshows 258 unrelated failures in host-service, desktop, workspace-client, and pty-daemon that pass when run per package.)- No unit test:
packages/sdkhas no test setup and its tsconfig deliberately setstypes: [], so abun:testfile fails its typecheck. Per the brief, no new test setup was introduced. - End to end against the local dev stack (API on the workspace's Neon branch, dev API key minted for satya@superset.sh, revoked afterwards): one
client.tasks.list()producedGET /api/trpc/task.list 200followed byPOST /api/trpc/analytics.captureEvent 200, and the event arrived in PostHog project 264828 ("Local Development", confirmed as the owner of theNEXT_PUBLIC_POSTHOG_KEYin.env):
{
"uuid": "01a06902-9f1a-71fb-be5b-fb5147b49811",
"event": "sdk_method_called",
"timestamp": "2026-09-03T20:42:54.859000Z",
"distinct_id": "0da9ed59-9eb3-4f73-ac71-6f1df5a44816",
"properties": {
"source": "sdk",
"method": "tasks.list",
"sdk_version": "0.0.1-alpha.7",
"sdk_lang": "js",
"runtime": "bun",
"target": "cloud",
"success": true,
"duration_ms": 2212,
"active_organization_id": "b2c3d4e5-f6a7-4890-9bcd-ef1234567891",
"plan": null
}
}
(sdk_version reads alpha.7 because the run predates the VERSION bump in this PR.)
https://claude.ai/code/session_01Ckhb622VMbkDVoaKsjVTqg
Summary by CodeRabbit
-
New Features
- Added SDK usage telemetry for resource method calls, including method, runtime, success status, and duration.
- Telemetry excludes request and response data, runs best-effort after calls complete, and can be disabled with
SUPERSET_TELEMETRY=0orfalse. - SDK requests now identify the SDK client and version.
-
Breaking Changes
- Updated low-level SDK request methods to accept structured call descriptors.
-
Documentation
- Added telemetry details to the SDK reference documentation.
-
Chores
- Updated the SDK version to
0.0.1-alpha.12.
- Updated the SDK version to