Files
oh-my-opencode/packages/omo-codex/plugin/components/telemetry
YeonGyu-Kim bd867019f9 feat(omo-codex): wire Codex SessionStart telemetry for DAU/WAU/MAU
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.
2026-05-28 13:58:11 +09:00
..

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:

{
  "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:

# 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

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 for the full disclosure.