James Russo
|
d845068f16
|
feat(cli): add opt-out anonymous telemetry via PostHog (#52)
## Summary
- Add anonymous usage telemetry to the CLI via PostHog's HTTP batch API (zero new dependencies)
- Track command invocations, render performance, template choices, and environment info
- Add `hyperframes telemetry [enable|disable|status]` command for user control
- Config stored at `~/.hyperframes/config.json` — future-proofed for more settings
## Design Decisions
| Decision | Rationale |
|---|---|
| **Raw `fetch` instead of `posthog-node`** | Zero new dependencies. Node 22 has built-in `fetch`. Can swap to SDK later if needed. |
| **Opt-out with first-run disclosure** | Industry standard (Next.js, Homebrew, .NET CLI). Opt-in gets <3% participation. |
| **Disabled in dev mode** | Uses `.ts` extension detection (shared `utils/env.ts`). Running via `tsx` = dev. |
| **`phc_` prefix check** | Safety net — if the API key is ever reverted to a placeholder, telemetry silently disables. |
| **5-second timeout, fail-silent** | Telemetry must never slow down or break the CLI. |
| **Detached spawn for exit flush** | `flushSync` spawns a detached child process so `process.exit()` paths don't block. |
## What's Collected
- Command names (init, render, dev, etc.)
- Render metrics (duration, fps, quality, workers, docker/gpu)
- Template choices during init
- OS, architecture, Node.js version, CLI version
## What's NOT Collected
- File paths, project names, or video content
- IP addresses — `$ip: null` on every event payload (client-side) + "Discard client IP data" enabled in PostHog project settings (server-side)
- Any personally identifiable information
## Opt-Out Mechanisms
- `hyperframes telemetry disable`
- `HYPERFRAMES_NO_TELEMETRY=1`
- `DO_NOT_TRACK=1`
- Automatically disabled in CI (`CI=true`)
## Files Changed
**New files:**
- `packages/cli/src/telemetry/config.ts` — Config read/write at `~/.hyperframes/config.json` (dir 0700, file 0600)
- `packages/cli/src/telemetry/client.ts` — PostHog HTTP client (queue, batch, flush, detached flushSync)
- `packages/cli/src/telemetry/events.ts` — Typed event helpers
- `packages/cli/src/telemetry/index.ts` — Barrel exports
- `packages/cli/src/commands/telemetry.ts` — `hyperframes telemetry` command
- `packages/cli/src/utils/env.ts` — Shared `isDevMode()` (extracted from dev.ts)
**Modified files:**
- `packages/cli/src/cli.ts` — Wire telemetry at entry point + add telemetry subcommand
- `packages/cli/src/commands/render.ts` — Track render success/failure metrics
- `packages/cli/src/commands/init.ts` — Track template selection
- `packages/cli/src/commands/browser.ts` — Track browser download events
- `packages/cli/src/commands/dev.ts` — Use shared `isDevMode()` from utils/env.ts
## Testing
- Verified typecheck passes (`tsc --noEmit`)
- Verified lint passes (`oxlint`)
- Verified format passes (`oxfmt --check`)
- Tested `hyperframes telemetry status/enable/disable` commands
- Verified first-run notice is suppressed in dev mode
- Verified `--help`/`--version` don't trigger telemetry
- Verified config file creation with correct permissions
- Verified telemetry is no-op when API key lacks `phc_` prefix
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
2026-03-25 16:49:16 -07:00 |
|