The Python SessionStart hook (sync-agents.py) was a runtime side-effect
that copied agent TOMLs into CODEX_HOME/agents on every session start.
That design had three problems:
1. It was a Python script invoked via 'python3 ${PLUGIN_ROOT}/...' which
is fragile on Windows where the binary may be 'python', and is the
wrong layer for a one-shot install task.
2. Agent TOMLs landed as regular file copies, with no provenance link to
the plugin cache and no tracking for clean uninstall.
3. An older release shipped TOMLs without the required 'name' field;
because the current bundle no longer ships them, the hook never had
a chance to overwrite the broken copies on disk, leaving Codex
permanently warning at session start.
Replace the runtime hook with an install-time linker:
linkCachedPluginAgents() (src/cli/install-codex/link-cached-plugin-agents.ts).
The omo-codex CLI now calls it right after linkCachedPluginBins(). For
each 'components/*/agents/*.toml' in the plugin cache, it:
- Linux / macOS: creates a symlink at ${CODEX_HOME}/agents/<basename>
pointing at the cache TOML. The cache directory is the single source
of truth; removing the cache cleanly breaks the link.
- Windows: copies the file (symlinks require admin or Developer Mode).
- Both platforms: writes a '.installed-agents.json' manifest under the
plugin cache listing the installed absolute paths, so a future
'omo uninstall --platform=codex' can remove them deterministically.
Stale regular-file copies (from the old sync-agents.py) are removed and
replaced on Unix. On Windows the existing copy is overwritten.
Tests (src/cli/install-codex/link-cached-plugin-agents.test.ts):
9 cross-platform tests that mock the 'platform' parameter to exercise
the Linux, macOS, and Windows code paths in a single 'bun test' run,
matching the existing pattern from linkCachedPluginBins. Covers symlink
creation, Windows copy, stale-file replacement, manifest writing,
idempotency, multi-component discovery, and the empty-bundle edge case.
Removed:
- packages/omo-codex/plugin/components/ultrawork/hooks/sync-agents.py
- packages/omo-codex/plugin/test/bundled-agents.test.mjs
(it tested the Python hook; behaviour is now covered by the TS tests)
- SessionStart hook entry in both ultrawork and aggregate hooks.json
- 2 sync-agents tests + 1 manifest assertion in ultrawork-hooks.test.mjs
- 'hooks/sync-agents.py' in ultrawork/package.json files list
- sync-agents.py reference from aggregate.test.mjs component markers
Updated:
- components/ultrawork/README.md, AGENTS.md: describe the install-time
linker as the source of truth, no more SessionStart agent sync.
Verified end-to-end:
bun run src/cli/index.ts install --no-tui --platform=codex
ls -la ~/.codex/agents/ # all 4 TOMLs are symlinks pointing to cache
cat ~/.codex/plugins/cache/.../omo/0.1.0/.installed-agents.json # manifest present
@oh-my-opencode/omo-codex
Codex harness adapter for oh-my-openagent. Brings the OMO experience (rules injection, comment checker, LSP MCP, ultrawork, ultragoal) into OpenAI Codex CLI through Codex's native plugin system.
Layout
| Path | Purpose |
|---|---|
plugin/ |
Vendored Codex plugin namespace omo with 5 components. Shipped to the user via ~/.codex/plugins/cache/. |
marketplace.json |
Codex marketplace manifest. Identifies omo as the single installable plugin. |
scripts/ |
Node ESM build scripts (port of the original codex-plugins/scripts/install-local.mjs). |
src/ |
TypeScript runtime: installer + telemetry consumed by the omodex CLI. |
MARKETPLACE.md |
Vendored upstream marketplace README. |
Components Vendored
rules(TypeScript) - injectsAGENTS.md/CLAUDE.md/.omo/rules/**into context viaSessionStart,UserPromptSubmit,PostToolUse,PostCompact.comment-checker(TypeScript) - runs@code-yeongyu/comment-checkerafterapply_patch/edit/writetool use.lsp(TypeScript + LSP MCP) - exposes LSP diagnostics, navigation, symbols, rename via MCP + post-edit hooks.ultrawork(Python) - keyword detector (ulw/ultrawork) that injects the full ultrawork directive, plus aSessionStarthook that syncs bundled agent TOML files intoCODEX_HOME/agents.ultragoal(TypeScript) - durable multi-goal orchestration backed by.omo/ultragoal/evidence audit.
Install
End users invoke through the omodex CLI:
bunx omo install --codex=yes
# or, equivalently:
bunx oh-my-opencode install --codex=yes
bunx oh-my-openagent install --codex=yes
The installer copies the built plugin into ~/.codex/plugins/cache/code-yeongyu-codex-plugins/omo/<version>/, enables it in ~/.codex/config.toml, and links the per-component binaries into ~/.local/bin/ (or CODEX_LOCAL_BIN_DIR).
Telemetry
Anonymous telemetry uses the same PostHog project as oh-my-openagent but emits the distinct event omo_codex_daily_active. The event is sent at most once per UTC day per machine from two sources:
| Source | Reason | Trigger |
|---|---|---|
install |
install_completed |
bunx omo install --codex=yes finishes (handled by src/cli/install-codex/install-codex.ts) |
plugin |
session_start |
Codex plugin SessionStart hook fires (handled by plugin/components/telemetry/) |
Both sources share the same SHA256-hashed installation identifier (sha256("omo-codex:" + hostname)), suppress PostHog person profiles, and write the daily dedup state to ~/.local/share/omo-codex/posthog-activity.json.
Opt out with:
# Codex-only
export OMO_CODEX_DISABLE_POSTHOG=1
export OMO_CODEX_SEND_ANONYMOUS_TELEMETRY=0
# Globally (also disables oh-my-openagent telemetry)
export OMO_DISABLE_POSTHOG=1
export OMO_SEND_ANONYMOUS_TELEMETRY=0
The identity constants and opt-out behavior are pinned across both sources by src/telemetry/cross-package-equivalence.test.ts.
See /Users/yeongyu/local-workspaces/omodex/docs/legal/privacy-policy.md for the full disclosure.
Provenance
Vendored from code-yeongyu/codex-plugins at the snapshot present in /Users/yeongyu/local-workspaces/codex-plugins/ on 2026-05-25. Per-component upstream: