feat: add client_connected telemetry and surface/client labels for the IDE funnel

Draft
AN
4h ago
+96-0

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_ready gains surface and client. client is ALTIMATE_CLI_CLIENT (e.g. datamates), which the event didn't carry before; surface is the explicit analytics name mirroring the existing command field.
  • New client_connected event. Emitted once per process the first time an authenticated client subscribes to the event stream (GET /event or /global/event). It lives in a .use middleware after basic-auth in Server.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 to ANCHOR_EVENTS so 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_ready now carries surface and client (from ALTIMATE_CLI_CLIENT, e.g. datamates); only command was recorded before.
  • New client_connected event fires once per process on the first authenticated GET /event or /global/event subscription, splitting "backend launched but no client connected" from "connected but no message sent".
  • It flushes immediately via ANCHOR_EVENTS since 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.