feat: add client_connected telemetry and surface/client labels for the IDE funnel
Issue for this PR
Closes #
Type of change
- New feature
What does this PR do?
Makes the IDE-extension onboarding funnel measurable from backend telemetry.
Context: ~92% of installs run the VS Code extension (telemetry source="datamates"), which runs altimate serve as its backend. On that process we emit startup_ready and then nothing until session_start (the first model prompt), so the large launch -> first-message drop was invisible.
Two additions:
startup_readygainssurfaceandclient.clientisALTIMATE_CLI_CLIENT(e.g.datamates), which the event didn't carry before;surfaceis the explicit analytics name mirroring the existingcommandfield.- New
client_connectedevent. Emitted once per process the first time an authenticated client subscribes to the event stream (GET /eventor/global/event). It lives in a.usemiddleware after basic-auth inServer.createApp, so unauthenticated probes/health checks don't count. This splits the launch->session drop into "backend launched but no client connected" vs "connected but no message sent". Added toANCHOR_EVENTSso it flushes immediately.
Telemetry-only, fail-safe (dynamic import + .catch), non-blocking. The server.ts change is wrapped in altimate_change markers (upstream-shared file); the telemetry module is under src/altimate/** (altimate-owned, no markers required).
How did you verify your code works?
bun test test/altimate/telemetry/first-run-health.test.ts plus the telemetry suite: 371 pass, 0 fail. New tests assert startup_ready carries surface+client and that client_connected fires exactly once across repeated calls. Typecheck clean on the changed telemetry module. Marker placement checked by hand against script/upstream/utils/config.ts (the --markers guard currently no-ops against the v2 upstream baseline).
Screenshots / recordings
N/A (backend telemetry only).
Checklist
- I have tested my changes locally
- I have not included unrelated changes in this PR
Summary by cubic
Makes the IDE extension onboarding funnel measurable: the altimate serve backend used by the VS Code extension previously went silent after startup_ready until the first session_start, hiding the launch→first-message drop.
startup_readynow carriessurfaceandclient(fromALTIMATE_CLI_CLIENT, e.g.datamates); onlycommandwas recorded before.- New
client_connectedevent fires once per process on the first authenticatedGET /eventor/global/eventsubscription, splitting "backend launched but no client connected" from "connected but no message sent". - It flushes immediately via
ANCHOR_EVENTSsince a short-lived extension host may die before the flush interval.
Telemetry-only and fail-safe: the server hook is a dynamic import with .catch, and the server.ts change is wrapped in altimate_change markers because it's an upstream-shared file.