spawn/packages/cli/src
Ahmed Abushagur 1e64d34e5a
Some checks are pending
CLI Release / Build and release CLI (push) Waiting to run
Lint / macOS Compatibility (push) Waiting to run
Lint / ShellCheck (push) Waiting to run
Lint / Biome Lint (push) Waiting to run
feat(telemetry): funnel + lifecycle events for onboarding drop-off (#3305)
* feat(telemetry): funnel + lifecycle events for onboarding drop-off

Adds low-volume, high-signal product events on top of the existing
errors/warnings telemetry (shared/telemetry.ts). Answers "where do users
bail before reaching a running agent" at the fleet level.

Funnel events (in orchestrate.ts, both fast and sequential paths):

  funnel_started              pipeline begins
  funnel_cloud_authed         cloud.authenticate() ok
  funnel_credentials_ready    OR key + preProvision resolved
  funnel_vm_ready             VM booted and SSH-reachable
  funnel_install_completed    agent install succeeded (tarball or live)
  funnel_configure_completed  agent.configure() ran
  funnel_prelaunch_completed  gateway / dashboard / preLaunch hooks done
  funnel_handoff              about to launch TUI (final step)

Every event carries elapsed_ms since funnel_started, plus agent and cloud
via telemetry context. Per-step counts reveal the drop-off funnel in
PostHog without touching any PII.

Lifecycle events (new shared/lifecycle-telemetry.ts):

  spawn_connected  { spawn_id, agent, cloud, connect_count, date }
    fired from list.ts when the user reconnects via the interactive picker.
    Increments connection.metadata.connect_count and writes last_connected_at
    so subsequent events and the eventual spawn_deleted have the total.

  spawn_deleted    { spawn_id, agent, cloud, lifetime_hours, connect_count, date }
    fired from delete.ts (both interactive confirmAndDelete and headless
    cmdDelete loop) after a successful cloud destroy. lifetime_hours is
    computed from SpawnRecord.timestamp to now. Clamped at 0 for corrupt
    clocks. connect_count is read from metadata.

New captureEvent(name, properties) helper in telemetry.ts:
- Respects SPAWN_TELEMETRY=0 opt-out (no new flag)
- Runs every string property through the existing scrubber (API keys,
  GitHub tokens, bearer, emails, IPs, base64 blobs, home paths)
- Non-string values pass through untouched

Tests: 20 new (15 lifecycle-telemetry + 2 captureEvent + 3 assertion
additions to disabled-telemetry). Full suite: 2129/2129 pass.

Bumps 1.0.10 -> 1.0.11. Patch bump — auto-propagates under #3296 policy.

* fix(test): replace mock.module with spyOn in lifecycle-telemetry tests

mock.module contaminates the global module registry when running under
--coverage, causing telemetry.test.ts and history-cov.test.ts to receive
mocked implementations instead of the real modules. Switch to spyOn with
mockRestore in afterEach so the real modules are preserved across files.

Agent: pr-maintainer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: L <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 11:35:53 +07:00
..
__tests__ feat(telemetry): funnel + lifecycle events for onboarding drop-off (#3305) 2026-04-15 11:35:53 +07:00
aws fix(security): shell-quote package names in cloud-init scripts (#3220) 2026-04-07 15:35:44 +07:00
commands feat(telemetry): funnel + lifecycle events for onboarding drop-off (#3305) 2026-04-15 11:35:53 +07:00
daytona fix(security): replace eval-style interpolation with env var in allowOpenClawPreviewOrigin (#3217) 2026-04-06 23:09:45 -07:00
digitalocean fix(security): shell-quote package names in cloud-init scripts (#3220) 2026-04-07 15:35:44 +07:00
gcp fix(security): shell-quote package names in cloud-init scripts (#3220) 2026-04-07 15:35:44 +07:00
hetzner fix(security): shell-quote package names in cloud-init scripts (#3220) 2026-04-07 15:35:44 +07:00
local fix: resolve 4 production TypeScript type errors (#3266) 2026-04-11 17:16:47 +07:00
shared feat(telemetry): funnel + lifecycle events for onboarding drop-off (#3305) 2026-04-15 11:35:53 +07:00
sprite fix(security): expand $HOME before path validation in downloadFile (#3080) 2026-03-30 19:56:05 +00:00
flags.ts fix(cli): add --flat to KNOWN_FLAGS so spawn list --flat works (#3137) 2026-04-01 16:33:45 +07:00
guidance-data.ts refactor: remove dead exports only used within their own files (#2431) 2026-03-10 08:51:15 -04:00
history.ts feat: recursive spawn (--beta recursive) (#2978) 2026-03-25 10:42:09 -07:00
index.ts feat: --beta skills — pre-install MCP servers and skills on VMs (#3258) 2026-04-10 09:02:16 -07:00
manifest.ts fix: always fetch manifest from GitHub, 3s timeout for bad wifi (#3272) 2026-04-12 07:54:40 +07:00
picker.ts refactor: remove dead exported types from picker.ts and spawn-config.ts (#2553) 2026-03-12 21:43:05 -04:00
security.ts fix(test): check sensitive paths before lstat to fix macOS permission error (#3157) 2026-04-03 10:12:20 +07:00
unicode-detect.ts feat: Bun workspace monorepo — packages/cli + packages/shared (#1853) 2026-02-23 22:07:05 -08:00
update-check.ts fix(update-check): validate install script content before execution (#3302) 2026-04-14 20:41:38 +07:00