packages/omo-codex/plugin/components/telemetry/README.md
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.
The component registers a single SessionStart hook:
{
"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.
A single PostHog capture call with:
event: "omo_codex_daily_active"distinctId: sha256("omo-codex:" + hostname)properties:
platform, product_name, package_name, package_versionruntime ("node"), runtime_versionsource: "plugin", reason: "session_start"$os, $os_version, os_arch, os_typecpu_count, cpu_model, total_memory_gblocale, timezone, shell, ci, terminalday_utc (today's UTC date)$process_person_profile: falseThe component never sends prompt contents, file contents, API keys, raw hostnames, or any user-identifying data.
Set any of the following environment variables before launching Codex:
# 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.
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).
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.
| Variable | Default |
|---|---|
POSTHOG_HOST | https://us.i.posthog.com |
POSTHOG_API_KEY | shared omo-codex project key |
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.
See the omo Privacy Policy for the full disclosure.