bd867019f9
Adds a new Codex plugin component `telemetry` that emits a single omo_codex_daily_active event (reason: session_start) from every Codex SessionStart hook, with the same UTC-day deduplication, hashed installation identifier, and four-flag opt-out as the install-time event. Previously omo-codex telemetry only fired on install_completed, so DAU/WAU/MAU under-reported real Codex usage. - New plugin component packages/omo-codex/plugin/components/telemetry/ mirrors the rules/comment-checker/lsp pattern: own src/, tsc build, vitest tests, package.json (posthog-node dep), hooks/hooks.json. - src/codex-hook.ts wraps createPluginPostHog().trackActive(..., "session_start") with safeShutdown so Codex session startup never blocks on telemetry. - Plugin root hooks.json + workspaces register the new component alongside rules and ultrawork on SessionStart. - Aggregate test expectations updated to include the telemetry directory. - cross-package-equivalence.test.ts pins product-identity constants and shouldDisablePostHog behavior to stay byte-equivalent between the CLI installer (src/telemetry/) and the plugin runtime (plugin/components/telemetry/src/), so the two PostHog sources never drift on event name, distinct_id base, dedup file path, or opt-out flags. - PostHogActivityReason union in the CLI-side posthog.ts gains "session_start" so future CLI paths can emit the same reason without a type break.
103 lines
3.3 KiB
Markdown
103 lines
3.3 KiB
Markdown
# codex-telemetry
|
|
|
|
Codex plugin component that emits a single anonymous daily-active event (`omo_codex_daily_active`) to PostHog whenever a Codex session starts.
|
|
|
|
The event is sent **at most once per UTC day per machine**. It uses a SHA256-hashed installation identifier derived from `omo-codex:${hostname}` and never sends the raw hostname. PostHog person profiles are explicitly disabled.
|
|
|
|
## Hook Wiring
|
|
|
|
The component registers a single `SessionStart` hook:
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"SessionStart": [
|
|
{
|
|
"hooks": [
|
|
{
|
|
"type": "command",
|
|
"command": "node \"${PLUGIN_ROOT}/dist/cli.js\" hook session-start",
|
|
"timeout": 5
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
The aggregate `plugin/hooks/hooks.json` mounts this hook alongside `rules` and `ultrawork` so all three fire in parallel at the start of every Codex session.
|
|
|
|
## What Is Captured
|
|
|
|
A single PostHog `capture` call with:
|
|
|
|
- `event: "omo_codex_daily_active"`
|
|
- `distinctId: sha256("omo-codex:" + hostname)`
|
|
- `properties`:
|
|
- `platform`, `product_name`, `package_name`, `package_version`
|
|
- `runtime` (`"node"`), `runtime_version`
|
|
- `source: "plugin"`, `reason: "session_start"`
|
|
- `$os`, `$os_version`, `os_arch`, `os_type`
|
|
- `cpu_count`, `cpu_model`, `total_memory_gb`
|
|
- `locale`, `timezone`, `shell`, `ci`, `terminal`
|
|
- `day_utc` (today's UTC date)
|
|
- `$process_person_profile: false`
|
|
|
|
The component never sends prompt contents, file contents, API keys, raw hostnames, or any user-identifying data.
|
|
|
|
## Opt-Out
|
|
|
|
Set any of the following environment variables before launching Codex:
|
|
|
|
```bash
|
|
# Codex-only opt-out
|
|
export OMO_CODEX_DISABLE_POSTHOG=1
|
|
export OMO_CODEX_SEND_ANONYMOUS_TELEMETRY=0
|
|
|
|
# Global opt-out (covers both omo and omo-codex)
|
|
export OMO_DISABLE_POSTHOG=1
|
|
export OMO_SEND_ANONYMOUS_TELEMETRY=0
|
|
```
|
|
|
|
When any of these is set the component creates a no-op PostHog client and exits without any network call.
|
|
|
|
## Daily Deduplication
|
|
|
|
The component writes a small JSON state file at:
|
|
|
|
```
|
|
$XDG_DATA_HOME/omo-codex/posthog-activity.json
|
|
# or, when XDG_DATA_HOME is unset:
|
|
~/.local/share/omo-codex/posthog-activity.json
|
|
```
|
|
|
|
containing `{ "lastActiveDayUTC": "YYYY-MM-DD" }`. If the stored day matches today (UTC), the hook returns without sending anything. The file is written atomically via `rename(2)`.
|
|
|
|
## Failure Behavior
|
|
|
|
Every telemetry path is wrapped in `try`/`catch`. The hook always exits 0 with no stdout output, even when PostHog construction, capture, or shutdown fails. Codex session startup is never blocked or slowed by telemetry failures.
|
|
|
|
## Endpoint Overrides
|
|
|
|
| Variable | Default |
|
|
|----------|---------|
|
|
| `POSTHOG_HOST` | `https://us.i.posthog.com` |
|
|
| `POSTHOG_API_KEY` | shared `omo-codex` project key |
|
|
|
|
## Development
|
|
|
|
```bash
|
|
npm install
|
|
npm test # vitest (in-process + subprocess CLI smoke)
|
|
npm run typecheck
|
|
npm run build # tsc -> dist/
|
|
npm run check # typecheck + biome + build
|
|
```
|
|
|
|
The component shares its product identity constants with the `@oh-my-opencode/omo-codex` CLI installer. Drift between the two implementations is guarded by `packages/omo-codex/src/telemetry/cross-package-equivalence.test.ts`.
|
|
|
|
## Privacy
|
|
|
|
See [the omo Privacy Policy](https://github.com/code-yeongyu/oh-my-openagent/blob/dev/docs/legal/privacy-policy.md) for the full disclosure.
|