Jesse A. Green / notebook

oh-my-codex (OMX) — Administrator & Developer Guide

Generated May 2026 from Yeachan-Heo/oh-my-codex at 09d2126

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Version: 0.13.1 | License: MIT | Repository: Yeachan-Heo/oh-my-codex


Table of Contents

  1. Architecture Overview
  2. System Requirements
  3. Configuration Reference
  4. Deployment & Scaling
  5. Operations
  6. Performance
  7. Security
  8. Developer Internals
  9. Integration Points

1. Architecture Overview

oh-my-codex (OMX) is a multi-agent orchestration layer that sits on top of OpenAI Codex CLI. It transforms single-agent Codex sessions into coordinated multi-agent teams operating inside tmux sessions, with a Rust-backed native runtime for state management and an extensible hook and plugin system for deep Codex integration.

1.1 Component Inventory

oh-my-codex
├── TypeScript Layer (src/)
│   ├── cli/           — CLI entry + all subcommand handlers (28 files, ~490K chars)
│   ├── team/          — Multi-agent team orchestration (27 files, ~600K chars)
│   ├── notifications/ — Discord / Telegram / Slack (18 files, ~180K chars)
│   ├── mcp/           — 5 MCP servers (8 files, ~97K chars)
│   ├── hooks/         — Codex hook integration (8 files, ~95K chars)
│   │   ├── extensibility/ — Plugin system (9 files, ~27K chars)
│   │   └── code-simplifier/ — Code simplification hook
│   ├── hud/           — Heads-up display (9 files, ~52K chars)
│   ├── autoresearch/  — Experiment loops (2 files, ~53K chars)
│   ├── config/        — Config generators (4 files, ~52K chars)
│   ├── adapt/         — Adapter framework (6 files, ~47K chars)
│   ├── state/         — Mode state management (6 files, ~41K chars)
│   ├── openclaw/      — OpenClaw integration (4 files, ~35K chars)
│   ├── utils/         — Shared utilities (9 files, ~33K chars)
│   ├── agents/        — Agent definitions (2 files, ~21K chars)
│   ├── catalog/       — Skill/agent catalog (3 files, ~16K chars)
│   ├── pipeline/      — Pipeline orchestrator (3 files, ~15K chars)
│   ├── ralph/         — Verification loop (2 files, ~14K chars)
│   ├── session-history/ — Session history search (1 file, ~12K chars)
│   ├── runtime/       — Runtime bridge to Rust (1 file, ~10K chars)
│   ├── modes/         — Base mode lifecycle (1 file, ~9K chars)
│   ├── ralplan/       — RALPLAN mode runtime (1 file, ~9K chars)
│   ├── subagents/     — Subagent tracker (1 file, ~8K chars)
│   ├── planning/      — Planning artifacts (1 file, ~5K chars)
│   ├── verification/  — Verifier (1 file, ~3.5K chars)
│   └── visual/        — Visual verdict validation (2 files, ~3K chars)
│
├── Rust Layer (crates/)
│   ├── omx-explore-harness — Sandboxed exploration binary
│   ├── omx-mux             — tmux multiplexer abstractions
│   ├── omx-runtime-core    — Core runtime engine
│   ├── omx-runtime         — Runtime binary wrapper
│   └── omx-sparkshell      — Shell command runner with AI summary
│
├── prompts/   — 30+ agent prompt files
├── skills/    — 35+ skill definitions (SKILL.md)
├── missions/  — Experiment mission definitions
├── templates/ — AGENTS.md template, catalog-manifest.json
└── playground/ — Demo scripts

1.2 High-Level Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                         User / CI / Script                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │  omx <command>
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       CLI Layer  (src/cli/)                         │
│   team | run | skill | plan | research | history | config | ...     │
└───────────┬─────────────────────────────────────────────────────────┘
            │
     ┌──────┴──────────────────────────────────┐
     │                                         │
     ▼                                         ▼
┌─────────────────┐                 ┌────────────────────────┐
│  Pipeline       │                 │  Direct Skill / Mode   │
│  (RALPLAN →     │                 │  Execution             │
│   Team Exec →   │                 └────────────────────────┘
│   Ralph Verify) │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   Team Orchestration  (src/team/)                   │
│                                                                     │
│  ┌──────────┐  ┌──────────────┐  ┌──────────┐  ┌───────────────┐  │
│  │  Leader  │  │  Workers     │  │  Mailbox │  │ Phase Control │  │
│  │  (tmux)  │◄─┤  (tmux panes)│  │  (MCP)  │  │  (lifecycle)  │  │
│  └──────────┘  └──────────────┘  └──────────┘  └───────────────┘  │
└───────────┬──────────────────────┬──────────────────────────────────┘
            │                      │
            ▼                      ▼
┌────────────────────┐  ┌──────────────────────────────────────────┐
│  Rust Runtime      │  │  MCP Servers (stdio processes)           │
│  (omx-runtime)     │  │  state | memory | code_intel | trace     │
│  omx-runtime-core  │  │  | wiki                                  │
│  omx-mux           │  └──────────────────────────────────────────┘
│  omx-sparkshell    │
│  omx-explore-      │
│  harness           │
└────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    Codex CLI  (external)                            │
│               hooks: SessionStart, PreToolUse, PostToolUse,         │
│                      UserPromptSubmit, Stop                         │
└─────────────────────────────────────────────────────────────────────┘
            │
            ▼
┌─────────────────────────────────────────────────────────────────────┐
│                Notifications  (src/notifications/)                  │
│          Discord webhook/bot | Telegram | Slack                     │
└─────────────────────────────────────────────────────────────────────┘

1.3 Technology Stack

Layer Technology Version / Notes
CLI runtime Node.js >= 20 required
Language (TS) TypeScript Compiled to JS
Language (native) Rust Edition 2021
Agent protocol OpenAI Codex CLI External dependency
Terminal multiplexer tmux Required for team mode
MCP protocol Model Context Protocol stdio transport
Distribution cargo-dist Cross-platform native binaries
Test runner Node.js --test Built-in test runner
Coverage c8 V8 coverage
Cargo tests cargo test Per-crate + compat tests

1.4 Key Design Decisions

File-based state machine. All mode state lives in .omx/state/ as JSON files. No database, no message broker. This makes state inspectable with any text tool and resilient to process crashes — the last-written file wins.

Atomic tmux pane operations. The Rust omx-mux crate wraps tmux pane I/O through capture, input injection, and delivery confirmation primitives. Injection is confirmed before the caller proceeds, preventing race conditions in multi-pane environments.

Authority lease system. omx-runtime-core's AuthorityLease model ensures only one runtime process holds authority over a session at a time. Replays reconstruct state from a DispatchLog on restart, making the runtime crash-safe.

Dual-model architecture. SparkShell selects between a "spark" (lighter, faster) model and a "frontier" (more capable) model based on output line count. This caps cost for routine shell summaries while preserving quality for large outputs.

POSIX-only explore harness. omx-explore-harness runs only on POSIX systems. The sandboxed PATH allowlist ensures the Codex subprocess cannot access host tools outside the approved set.


2. System Requirements

2.1 Runtime Prerequisites

Requirement Minimum Notes
Node.js 20.0.0 LTS or current; ESM support required
tmux Any recent Required for team mode; must be in PATH
OpenAI Codex CLI Latest Installed separately; codex must be in PATH
Git 2.x+ Used for worktree management and branch operations
Rust toolchain 1.70+ (approx.) Only needed for building from source
OS Linux / macOS POSIX required for omx-explore-harness; Windows supported for other features via x86_64-pc-windows-msvc binary

2.2 Optional Prerequisites

Dependency Purpose Required When
Discord bot token / webhook Discord notifications OMX_DISCORD_* configured
Telegram bot Telegram notifications OMX_TELEGRAM_* configured
Slack webhook Slack notifications OMX_SLACK_WEBHOOK_URL configured
OpenClaw server External tool adapter OMX_OPENCLAW=true

2.3 Supported Platforms (cargo-dist targets)

Target Platform
aarch64-apple-darwin macOS ARM (M-series)
x86_64-apple-darwin macOS Intel
aarch64-unknown-linux-gnu Linux ARM64 (glibc)
aarch64-unknown-linux-musl Linux ARM64 (musl/static)
x86_64-unknown-linux-gnu Linux x86_64 (glibc)
x86_64-unknown-linux-musl Linux x86_64 (musl/static)
x86_64-pc-windows-msvc Windows x86_64

Important

omx-explore-harness is POSIX-only and will not build or run on Windows. All other crates support the full target matrix above.

2.4 Network Requirements

  • Outbound HTTPS to OpenAI API endpoints (via Codex CLI)
  • Outbound HTTPS to Discord/Telegram/Slack APIs (if notifications enabled)
  • No inbound port requirements — OMX is a CLI tool, not a server

3. Configuration Reference

3.1 Environment Variables — Complete Reference

All environment variables are sourced from config_keys.tsv. They are grouped by subsystem below.

3.1.1 Team & Session Variables

Variable Purpose Default
OMX_TEAM_STATE_ROOT Override team state directory path .omx/state/
OMX_JOBS_DIR Jobs directory path (derived from state root)
OMX_TEAM_WORKER_CLI_MAP JSON mapping of worker names to CLI commands —
OMX_JOB_ID Current job identifier (injected by leader into worker env) —
OMX_TEAM_WORKER Current worker identifier (injected by leader) —
OMX_TEAM_WORKER_LAUNCH_ARGS Additional CLI arguments appended to worker launch command —
OMX_TEAM_MOUSE Enable mouse support in team tmux session —
OMX_TEAM_AUTO_ACCEPT_BYPASS Auto-accept bypass for worker prompts (dangerous — see §7) —
OMX_TEAM_SEND_STRATEGY Message delivery strategy for workers —
OMX_TEAM_AUTO_TRUST Auto-trust worker agents without confirmation —
OMX_TEAM_STRICT_SUBMIT Require strict submit validation before task acceptance —
OMX_RUNTIME_CLI_DISABLE_AUTO_START Disable automatic runtime CLI startup —
CODEX_HOME Codex home directory (read by both OMX and Codex) ~/.codex
OMX_SESSION_ID Session identifier (checked first) —
CODEX_SESSION_ID Session identifier (checked second) —
SESSION_ID Session identifier (checked third) —
TMUX_PANE Current tmux pane ID (set by tmux) —
SHELL Default shell for command execution System default
WSL_DISTRO_NAME WSL distro name (used for WSL detection) —
WSL_INTEROP WSL interop socket path (used for WSL detection) —

3.1.2 Notification Variables

Variable Purpose
OMX_DISCORD_WEBHOOK_URL Discord incoming webhook URL
OMX_DISCORD_NOTIFIER_BOT_TOKEN Discord bot token (for bot-based notifications)
OMX_DISCORD_NOTIFIER_CHANNEL Discord channel ID (used with bot token)
OMX_DISCORD_MENTION Discord mention string: <@!USER_ID> or <@&ROLE_ID>
OMX_TELEGRAM_BOT_TOKEN Telegram bot token (primary key)
OMX_TELEGRAM_NOTIFIER_BOT_TOKEN Telegram bot token (alternate key)
OMX_TELEGRAM_CHAT_ID Telegram chat ID (primary key)
OMX_TELEGRAM_NOTIFIER_CHAT_ID Telegram chat ID (alternate key)
OMX_TELEGRAM_NOTIFIER_UID Telegram user ID (alternate key)
OMX_SLACK_WEBHOOK_URL Slack incoming webhook URL
OMX_SLACK_MENTION Slack mention: <@USERID>, <!channel>, <!here>
OMX_NOTIFY_PROFILE Active notification profile name
OMX_NOTIFY_VERBOSITY Notification verbosity level
OMX_DISPATCH_COOLDOWN_SECONDS Minimum seconds between dispatched notifications
OMX_IDLE_COOLDOWN_SECONDS Idle notification cooldown seconds
OMX_HOOK_CONFIG Hook configuration path or JSON
OMX_REPLY_ENABLED Enable reply listener (accepts commands via notification platform)
OMX_REPLY_DISCORD_USER_IDS Comma-separated Discord user IDs allowed to send replies
OMX_REPLY_POLL_INTERVAL_MS Polling interval (ms) for the reply listener
OMX_REPLY_RATE_LIMIT Max replies per interval before throttling
OMX_REPLY_INCLUDE_PREFIX Prefix required in reply messages
OMX_NOTIFY_FALLBACK_MAX_LIFETIME_MS Max lifetime (ms) of the fallback notification watcher

3.1.3 OpenClaw Variables

Variable Purpose
OMX_OPENCLAW Set to true to enable OpenClaw integration
OMX_OPENCLAW_CONFIG Path to OpenClaw config file (overrides auto-discovery)
OMX_OPENCLAW_COMMAND OpenClaw command gateway executable
OMX_OPENCLAW_COMMAND_TIMEOUT_MS Timeout (ms) for command gateway calls
OMX_OPENCLAW_DEBUG Enable OpenClaw debug logging
OPENCLAW_REPLY_CHANNEL Reply routing: channel name
OPENCLAW_REPLY_TARGET Reply routing: target identifier
OPENCLAW_REPLY_THREAD Reply routing: thread identifier

3.1.4 SparkShell & Explore Variables

Variable Purpose
OMX_SPARKSHELL_MODEL Override SparkShell model
OMX_DEFAULT_SPARK_MODEL Default spark (lightweight) model
OMX_SPARK_MODEL Spark model selection
OMX_SPARKSHELL_FALLBACK_MODEL Fallback if primary model fails
OMX_DEFAULT_FRONTIER_MODEL Default frontier (powerful) model
OMX_SPARKSHELL_SUMMARY_TIMEOUT_MS Timeout (ms) for AI summary generation
OMX_SPARKSHELL_LINES Line count threshold: outputs above this get frontier model
ComSpec Windows command spec (used on Windows platforms)

3.1.5 MCP Server Variables

Variable Purpose
OMX_MCP_SERVER_DISABLE_AUTO_START Disable all MCP server auto-start globally
OMX_STATE_SERVER_DISABLE_AUTO_START Disable state MCP server only
OMX_MEMORY_SERVER_DISABLE_AUTO_START Disable memory MCP server only
OMX_CODE_INTEL_SERVER_DISABLE_AUTO_START Disable code_intel MCP server only
OMX_TRACE_SERVER_DISABLE_AUTO_START Disable trace MCP server only
OMX_WIKI_SERVER_DISABLE_AUTO_START Disable wiki MCP server only
OMX_MCP_TRANSPORT_DEBUG Enable MCP transport debug logging to stderr

3.1.6 Runtime & Miscellaneous Variables

Variable Purpose
OMX_AUTO_UPDATE Auto-update behavior on startup
OMX_MOUSE Enable mouse support globally
OMX_HOOK_DERIVED_SIGNALS Hook derived signals configuration
OMX_RUNTIME_BRIDGE Override path to the runtime bridge binary
OMX_RUNTIME_BINARY Override path to the runtime binary
OMX_TMUX_PID_FALLBACK Fallback PID for tmux attachment

3.2 Configuration Files

3.2.1 AGENTS.md (per-project)

OMX reads and writes AGENTS.md at project root. This file defines agent roles, capabilities, and inter-agent communication protocols. A template lives at templates/AGENTS.md.

Warning

GitHub issue #1671 documents a bug where omx update may overwrite a project's existing AGENTS.md. Until fixed, back up AGENTS.md before running update commands.

3.2.2 Catalog Manifest (templates/catalog-manifest.json)

Defines the registry of available skills and agents. The src/catalog/ module reads this manifest and validates entries against a JSON schema. Keys include skill names, entry points, and metadata.

3.2.3 Codex Hooks Config

Generated by src/config/ (the hooks config generator). Produces a JSON/TOML config consumed by Codex CLI specifying which OMX hook handlers fire on which Codex events.

3.2.4 OpenClaw Config

Path set via OMX_OPENCLAW_CONFIG or auto-discovered. Contains gateway type (HTTP or command), endpoint, timeout, and reply routing parameters.

3.3 State Directory Layout

.omx/
└── state/
    ├── mode/          — Active mode state files (JSON)
    ├── session/       — Per-session state files
    ├── jobs/          — Job definitions and status
    ├── ralph/         — Verification phase state
    ├── subagents/     — Subagent tracker state
    └── dispatch/      — Dispatch notification log

All state files are JSON. Write operations are atomic (write temp → rename).

3.4 Skill Definitions (skills/)

Each skill is defined by a SKILL.md file. The catalog loader reads these files and registers skills into the catalog. Skills define:

  • Name and description
  • Required inputs / parameters
  • Execution entry point
  • Agent role affinity

Skills are namespaced under omx: prefix (see known issue #1648 — built-in skills not yet fully namespaced; in-progress).

3.5 Agent Prompts (prompts/)

30+ agent prompt files define role-specific system prompts. Covered roles include (non-exhaustive):

  • analyst.md, architect.md, debugger.md, executor.md
  • planner.md, verifier.md, reviewer.md, researcher.md
  • Domain-specific roles added as the catalog grows

Prompts are loaded by the agent bootstrap process and injected as system context.


4. Deployment & Scaling

4.1 Installation (End-User)

# Via npm (TypeScript layer)
npm install -g oh-my-codex

# Verify
omx --version

Native Rust binaries are bundled with the npm package via cargo-dist. They are extracted to a platform-appropriate location on first run if not already present.

4.2 Building from Source

TypeScript Layer

git clone https://github.com/Yeachan-Heo/oh-my-codex.git
cd oh-my-codex
npm install
npm run build

Rust Crates

# Build all crates
cargo build --release

# Build a specific crate
cargo build -p omx-runtime --release
cargo build -p omx-mux --release
cargo build -p omx-sparkshell --release
cargo build -p omx-explore-harness --release   # POSIX only

Note

omx-explore-harness will fail to compile on Windows (x86_64-pc-windows-msvc). Exclude it from Windows builds: cargo build --release --exclude omx-explore-harness

Running Tests

# TypeScript tests
node --test

# With coverage
npx c8 node --test

# Rust tests (all crates)
cargo test

# TypeScript <-> Rust compat tests
cargo test -p omx-runtime   # includes compat suite

Coverage thresholds (team critical paths):

Metric Threshold
Lines 78%
Functions 90%
Branches 70%
Statements 78%

4.3 Release Process (cargo-dist)

OMX uses cargo-dist for cross-platform binary distribution. The dist configuration lives in Cargo.toml or dist.toml.

# Dry-run release plan
cargo dist plan

# Build release artifacts locally
cargo dist build

# Trigger CI release (tag-based)
git tag v0.13.1
git push origin v0.13.1

CI produces native binaries for all 7 targets and publishes them as GitHub Release assets. The npm package downloads the appropriate binary for the host platform on install.

4.4 Scaling the Team

OMX team mode scales by adjusting the number of worker panes. Workers are tmux panes, not OS processes in the traditional sense — each is a Codex CLI session managed by OMX.

Scale up: Leader spawns additional worker panes via src/team/ scaling logic, assigns new worktrees via Git, and bootstraps new worker sessions.

Scale down: Leader sends graceful shutdown signal; workers finish current tasks, release worktrees, and exit. Leader kills panes.

Worktree isolation: Each worker operates in a dedicated Git worktree, providing filesystem isolation. Tasks are allocated with path-overlap scoring to minimize merge conflicts.

Tip

For CPU-bound analysis tasks, scale up workers. For I/O-bound tasks (API calls, file reads), 3-5 workers is typically optimal. Watch tmux pane activity; idle panes waste Codex API quota.

4.5 Deployment Topology

OMX has no server component. Deployment means installing the package on any machine where users run Codex CLI. For CI/CD use:

# Example GitHub Actions
- name: Install oh-my-codex
  run: npm install -g oh-my-codex

- name: Run OMX pipeline
  run: omx run --skill my-skill
  env:
    OMX_DISCORD_WEBHOOK_URL: ${{ secrets.OMX_DISCORD_WEBHOOK_URL }}

5. Operations

5.1 State Inspection

Because state is file-based, any standard UNIX tool works:

# View current mode
cat .omx/state/mode/*.json | jq .

# View job queue
ls -la .omx/state/jobs/

# View dispatch log
cat .omx/state/dispatch/*.json | jq .

# Watch for state changes
watch -n1 'cat .omx/state/mode/*.json | jq .'

5.2 MCP Server Management

MCP servers are stdio processes started automatically by OMX. Each has a parent watchdog that polls every 25ms; if the parent process disappears, the server exits within one watchdog cycle.

Disable specific servers (useful for debugging or resource constraints):

export OMX_STATE_SERVER_DISABLE_AUTO_START=1
export OMX_MEMORY_SERVER_DISABLE_AUTO_START=1
# ... etc

Disable all servers:

export OMX_MCP_SERVER_DISABLE_AUTO_START=1

Debug MCP transport:

export OMX_MCP_TRANSPORT_DEBUG=1
omx team start
# Transport frames logged to stderr

Caution

GitHub issue #1665 documents that MCP duplicate sibling processes can accumulate if parent detection fails. Monitor process counts with ps aux | grep omx-mcp and kill stray processes if needed. The 5-second sibling detection window reduces but does not eliminate this risk.

5.3 Team Session Management

# Start a new team session
omx team start --workers 3

# Attach to existing session
omx team attach

# List active team sessions
tmux list-sessions | grep omx

# Kill a team session
omx team stop
# Or directly: tmux kill-session -t omx-SESSIONNAME

Warning

GitHub issue #1642 documents that detached leader cleanup may skip tmux kill-session, leaving orphan sessions. Run tmux list-sessions periodically and kill stale sessions manually: tmux kill-session -t <session-name>

5.4 Job Queue Operations

# List pending jobs
ls .omx/state/jobs/

# Inspect a job
cat .omx/state/jobs/<job-id>.json | jq .

# Cancel a stuck job (delete the file — terminal state on next poll)
rm .omx/state/jobs/<job-id>.json

5.5 Session History

# Search session history
omx history search "query string"

# Uses fuzzy matching — partial matches are ranked by relevance
omx history search "fix auth bug"

The session history module (src/session-history/) indexes past sessions and supports fuzzy-match retrieval. History files are stored per-session in .omx/state/session/.

5.6 HUD (Heads-Up Display)

The HUD renders live team state in the tmux leader pane:

  • Authority status (who holds the lease)
  • Worker pane assignments and current task
  • Phase progress (planning → executing → verifying → complete)
  • Pending notifications

HUD state is reconciled from .omx/state/ on each render cycle. If the HUD freezes, inspect the state directory for inconsistencies.

Note

GitHub issue #1635 documents the leader UI getting stuck on MCP startup. If the HUD does not render after ~10 seconds, check MCP server stderr for startup errors and restart with omx team stop && omx team start.

5.7 Monitoring Checklist

Check Command / Method
Active MCP servers ps aux | grep omx-mcp
Stale tmux sessions tmux list-sessions
State directory sanity ls -la .omx/state/
Ralph lock health cat .omx/state/ralph/*.json | jq .phase
Dispatch cooldown cat .omx/state/dispatch/*.json | jq .lastSent
Worker liveness tmux list-panes -t <session>

6. Performance

6.1 SparkShell Model Selection

omx-sparkshell implements a dual-model strategy for AI-assisted shell command summarization:

output_lines < OMX_SPARKSHELL_LINES  → use spark model (OMX_SPARK_MODEL)
output_lines >= OMX_SPARKSHELL_LINES → use frontier model (OMX_DEFAULT_FRONTIER_MODEL)

Tuning recommendations:

Scenario Recommended Setting
Mostly short outputs (build logs) Lower OMX_SPARKSHELL_LINES (e.g., 50)
Mostly long outputs (test suites) Raise OMX_SPARKSHELL_LINES (e.g., 500)
Cost-sensitive environment Set OMX_SPARKSHELL_MODEL to a cheap model
Accuracy-critical environment Set OMX_DEFAULT_FRONTIER_MODEL to best available

SparkShell is language-aware: it constructs prompts adapted to the programming language of the output context, improving summary quality without extra tokens.

6.2 MCP Server Lifecycle

Each MCP server is started as a stdio child process. The 25ms parent watchdog adds negligible overhead but ensures servers die with the parent.

Startup latency: Allow ~2-5 seconds for all 5 MCP servers to initialize and register with the parent. The leader HUD will show "MCP starting" during this window.

Memory footprint: Each MCP server is a lightweight Node.js process. Typical RAM per server: 30-60 MB. Total for 5 servers: ~200 MB baseline.

6.3 Team Worker Allocation Scoring

Task allocation uses a multi-factor scoring algorithm:

  1. Role match — Worker's assigned role vs. task's required role
  2. Domain hints — Keywords in task description vs. worker specialization
  3. Path overlap — Files in task scope vs. worker's current worktree
  4. Load balancing — Prefer workers with fewer in-flight tasks

Workers with the highest combined score receive the task. This is computed in src/team/ allocation logic at dispatch time.

6.4 Dispatch Cooldown

Notifications have two cooldown levels:

  • OMX_DISPATCH_COOLDOWN_SECONDS — Global cooldown between any dispatched notifications
  • OMX_IDLE_COOLDOWN_SECONDS — Cooldown specifically for idle-state notifications

Set these to avoid flooding notification channels during rapid task cycling.

6.5 Runtime Core Performance

omx-runtime-core uses an event-log architecture (DispatchLog) that enables O(1) appends and O(n) replay on restart. For long-lived sessions with thousands of events, consider periodic log rotation (no built-in mechanism; delete .omx/state/dispatch/ to reset).

The MailboxLog similarly grows unbounded over a session. For sessions running >24 hours, monitor mailbox file sizes.


7. Security

Caution

Several known security issues exist in v0.13.1. Review all items in this section before deploying OMX in shared or production environments.

7.1 Shell Injection Risks

Issue #1640 — buildWorkerStartupCommand shell injection.

Worker launch arguments (OMX_TEAM_WORKER_LAUNCH_ARGS) are interpolated into shell command strings. If this variable contains untrusted input, it can inject arbitrary shell commands.

Mitigation: Never set OMX_TEAM_WORKER_LAUNCH_ARGS from untrusted sources. Validate all values in CI pipelines before passing to OMX.

Issue #1659 — hud/state.ts git injection via remoteName.

The HUD reads the git remote name and uses it in git command construction without sanitization. A malicious remoteName (e.g., in .git/config) could inject arbitrary git flags.

Mitigation: Ensure .git/config is from a trusted source. Avoid running OMX against repositories with untrusted git configurations.

7.2 Path Traversal

Issue #1649 — Path traversal via unvalidated identifiers.

Skill names, job IDs, and other identifier fields used in file path construction are not validated for ../ sequences. A crafted identifier could traverse outside .omx/state/.

Mitigation: Until patched, enforce identifier validation at the call site (alphanumeric + hyphens only). Do not allow user-supplied identifiers to flow into OMX without sanitization.

7.3 Sensitive Data in Notifications

Issue #1661 — Reply listener leaks sensitive data.

The reply listener (OMX_REPLY_ENABLED) may include sensitive content (environment variables, file contents) in notification messages sent to Discord/Telegram/Slack.

Mitigation: Disable the reply listener unless required (OMX_REPLY_ENABLED unset or false). If enabled, restrict OMX_REPLY_DISCORD_USER_IDS to trusted operator IDs only. Use private channels for OMX notifications.

7.4 Auto-Accept Bypass

OMX_TEAM_AUTO_ACCEPT_BYPASS causes workers to skip confirmation prompts. This is intended for unattended CI runs but eliminates a human-in-the-loop safety check.

Warning

Do not set OMX_TEAM_AUTO_ACCEPT_BYPASS=true in environments where workers have write access to production systems or sensitive credentials.

7.5 Explore Harness Sandbox

omx-explore-harness restricts the Codex subprocess's PATH to an allowlist. The sandboxed binary runs on POSIX only and provides filesystem-level isolation for exploration tasks.

The allowlist is hardcoded in the harness source. Verify its contents match your security policy before deploying explore mode.

7.6 Dependency Vulnerabilities

Issue #1660 — Transitive dependency vulnerabilities.

Run npm audit and cargo audit periodically:

npm audit
npm audit fix    # for auto-fixable issues

cargo install cargo-audit
cargo audit

7.7 Signal Handling

Issue #1657 — SIGTERM without PID verification.

OMX sends SIGTERM to process groups without verifying PID before signal delivery. In unusual process tree configurations this could terminate unintended processes.

Mitigation: Run OMX in isolated process namespaces (e.g., Docker, systemd unit with PrivateTmp=yes) when operating near sensitive process groups.

7.8 Stale Lock Recovery

Issue #1655 — withTmuxExtendedKeysLeaseLock has no stale-lock recovery.

If a tmux extended keys lease is not released (e.g., process crash), subsequent operations that require this lock will hang indefinitely.

Mitigation: If OMX hangs on tmux operations, inspect .omx/state/ for stale lock files and remove them manually.

7.9 Authority Lease Security Model

The AuthorityLease in omx-runtime-core is a cooperative lock — it relies on all participants honoring the lease protocol. There is no kernel-level enforcement. In adversarial multi-user environments, a rogue process could bypass the lease.


8. Developer Internals

8.1 Repository Structure

oh-my-codex/
├── src/                    TypeScript source
│   ├── cli/                CLI entry + subcommand handlers
│   ├── team/               Team orchestration
│   ├── notifications/      Notification subsystem
│   ├── mcp/                MCP servers
│   ├── hooks/              Codex hook handlers
│   │   ├── extensibility/  Plugin system
│   │   └── code-simplifier/
│   ├── hud/                Heads-up display
│   ├── autoresearch/       Experiment automation
│   ├── config/             Config generators
│   ├── adapt/              External tool adapters
│   ├── state/              Mode state management
│   ├── openclaw/           OpenClaw integration
│   ├── utils/              Shared utilities
│   ├── agents/             Agent definitions
│   ├── catalog/            Skill/agent catalog
│   ├── pipeline/           Pipeline orchestrator
│   ├── ralph/              Verification loop
│   ├── session-history/    Session history
│   ├── runtime/            Rust runtime bridge
│   ├── modes/              Mode base class
│   ├── ralplan/            RALPLAN mode
│   ├── subagents/          Subagent tracker
│   ├── planning/           Planning artifacts
│   ├── verification/       Verifier
│   └── visual/             Visual verdict validation
│
├── crates/                 Rust crates
│   ├── omx-explore-harness/
│   ├── omx-mux/
│   ├── omx-runtime-core/
│   ├── omx-runtime/
│   └── omx-sparkshell/
│
├── prompts/                Agent role prompts (30+)
├── skills/                 Skill definitions (35+ SKILL.md)
├── missions/               Experiment missions
├── templates/              AGENTS.md template, catalog manifest
├── playground/             Demo/benchmark scripts
├── package.json
├── tsconfig.json
└── Cargo.toml              Workspace manifest

8.2 TypeScript Module Reference

src/cli/ — CLI Entry Point (28 files, ~490K chars)

The CLI uses a command-router pattern. omx dispatches to subcommand handlers based on argv[2]. Each subcommand file exports a run(args) function.

Key subcommands (inferred from architecture):

  • team — Team orchestration (start, stop, attach, scale)
  • run — Single-shot skill or pipeline execution
  • skill — Skill management (list, run, validate)
  • plan — RALPLAN planning mode
  • research — Autoresearch experiment loop
  • history — Session history search
  • config — Config generation (hooks, TOML, MCP registry)
  • hud — HUD control

CLI argument parsing is handled inline (no heavy framework dependency). Flag values map directly to the environment variables documented in §3.1.

src/team/ — Team Orchestration (27 files, ~600K chars)

The largest TypeScript module. Key responsibilities:

Allocation (allocation.ts) — Scores worker-task assignments using role match, domain hints, path overlap, and load factors. Returns ranked worker list.

Worktrees (worktrees.ts) — Creates and destroys Git worktrees for worker isolation. Each worker gets its own branch checkout.

tmux Sessions (tmux-sessions.ts) — Creates the tmux session with leader pane + N worker panes. Handles pane layout, window naming, and mouse support.

Worker Bootstrap (worker-bootstrap.ts) — Injects environment variables, AGENTS.md context, and initial task into each worker pane via omx-mux.

Scaling (scaling.ts) — Adds or removes worker panes at runtime without tearing down the session.

Phases (phases.ts) — State machine for team lifecycle: planning → executing → verifying → complete. Phase transitions write to .omx/state/mode/.

Delivery (delivery.ts) — Tracks task delivery confirmation per worker. Uses omx-mux delivery confirmation to ensure injection was received.

Runtime (runtime.ts) — Bridge between TypeScript team logic and the Rust runtime binary.

Mailbox — Workers communicate via MCP-based mailbox. Messages are persisted to the dispatch log in omx-runtime-core.

src/notifications/ — Notification System (18 files, ~180K chars)

Platforms:

  • discord-webhook.ts — Sends via incoming webhook (simplest, no bot required)
  • discord-bot.ts — Full Discord bot with channel targeting and mention support
  • telegram.ts — Telegram Bot API
  • slack.ts — Slack incoming webhook

Profiles (profiles.ts) — Named notification profiles (e.g., "ci", "quiet", "verbose") that bundle platform config, verbosity, and cooldown settings. Selected via OMX_NOTIFY_PROFILE.

Cooldowns (cooldowns.ts) — Enforces OMX_DISPATCH_COOLDOWN_SECONDS and OMX_IDLE_COOLDOWN_SECONDS. State persisted to .omx/state/dispatch/.

Formatters — Platform-specific message formatters. Discord uses markdown embeds; Telegram uses HTML; Slack uses Block Kit.

Reply Listener — Polls notification platform for incoming messages that match the reply prefix. Allowed senders restricted by OMX_REPLY_DISCORD_USER_IDS. See §7.3 for security considerations.

src/mcp/ — MCP Servers (8 files, ~97K chars)

All 5 servers share a common bootstrap pattern:

// Pseudo-code — actual implementation in src/mcp/
const server = new MCPServer({
  parentWatchdog: { intervalMs: 25 },
  siblingDetection: { timeoutMs: 5000 },
  disableEnvVar: 'OMX_<NAME>_SERVER_DISABLE_AUTO_START',
});
server.start();

state server — Exposes MCP tools to read/write .omx/state/ JSON files. Used by all team components for shared state.

memory server — Persistent key-value memory across sessions. Backed by a JSON file in .omx/state/.

code_intel server — Code intelligence queries: symbol lookup, dependency graph, file search. Backed by tree-sitter or similar parser.

trace server — Execution tracing: records tool calls, timing, and results for replay and debugging.

wiki server — Project wiki with ingest (write), query (read), lint (validate), and storage with CJK support. Known issue: #1641 — titleToSlug strips non-ASCII characters, producing hash-based filenames for CJK titles instead of readable slugs.

src/hooks/ — Codex Hook Integration (8 files, ~95K chars)

Hooks fire on Codex lifecycle events:

Event OMX Handler
SessionStart Initialize MCP servers, load agent overlay, build codebase map
PreToolUse Route explore requests, detect keywords, inject prompt guidance
PostToolUse Update state, trigger notifications
UserPromptSubmit Detect task size, adjust agent strategy
Stop Cleanup, persist session state, send completion notification

Agents overlay (agents-overlay.ts) — Injects agent role context into Codex's system prompt at session start.

Codebase map (codebase-map.ts) — Builds a structural map of the codebase (directories, key files) for hook context.

Explore routing (explore-routing.ts) — Decides whether to route a tool call through omx-explore-harness (sandboxed) or allow it to run normally.

Keyword detection (keyword-detection.ts) — Scans prompts for configured keywords and triggers associated actions or notifications.

Task-size detection (task-size-detection.ts) — Classifies incoming tasks as small/medium/large and adjusts parallelism and strategy accordingly.

src/hooks/extensibility/ — Plugin System (9 files, ~27K chars)

Plugin architecture for extending the hook system without modifying core:

Dispatcher (dispatcher.ts) — Routes hook events to registered plugins in priority order.

Events (events.ts) — Typed event definitions for all hook lifecycle points.

Loader (loader.ts) — Discovers and loads plugin modules from configured directories.

Plugin Runner (plugin-runner.ts) — Executes plugin handlers with timeout and error isolation.

SDK (sdk.ts) — Public API for plugin authors. Exposes event subscription, state access, and notification dispatch.

To create a plugin: implement the SDK interface, export a plugin object, and place the module where the loader can discover it.

src/hud/ — Heads-Up Display (9 files, ~52K chars)

Authority (authority.ts) — Reads AuthorityLease from the runtime to display who currently holds authority.

Reconcile (reconcile.ts) — Diffs current rendered state vs. live state and computes minimal update set.

Render (render.ts) — Builds the HUD layout: authority banner, worker grid, phase progress bar, notification queue.

tmux integration (tmux.ts) — Writes HUD output to the leader pane via omx-mux input injection.

Colors (colors.ts) — ANSI color constants and theme definitions.

HUD renders on a tick interval; the interval pauses when the leader pane is inactive.

src/autoresearch/ — Automated Experiment Loops (2 files, ~53K chars)

Mission contracts (missions.ts) — Defines experiment missions as typed contracts: hypothesis, evaluation criteria, max iterations, success threshold.

Sandbox parsing (sandbox.ts) — Parses experiment output from sandboxed Codex runs and extracts structured results.

Worktree management — Each experiment run uses an isolated Git worktree to prevent cross-contamination.

Evaluator scoring — Scores experiment outcomes against mission criteria. Persists scores for trend analysis.

Available experiment missions (in missions/):

  • adaptive-sort — Benchmark adaptive sorting algorithms
  • bayesopt — Bayesian optimization experiments

src/config/ — Config Generation (4 files, ~52K chars)

Codex hooks config generator — Produces the JSON/TOML config telling Codex which OMX hook handlers to call and when.

TOML config generator — Generates OMX's own TOML configuration file from environment variables and defaults.

MCP registry — Generates the MCP server registry config consumed by Codex at startup.

Model defaults — Defines default model selections for spark vs. frontier contexts.

src/adapt/ — Adapter Framework (6 files, ~47K chars)

Abstracts external tool integrations (currently OpenClaw and Hermes):

Contracts (contracts.ts) — TypeScript interfaces for the adapter API: probe(), status(), init(), envelope(), doctor().

Probe — Tests whether the external tool is available and responsive.

Status — Returns current tool status (healthy/degraded/unavailable).

Init — Initializes the tool integration (auth, config load).

Envelope — Wraps an outgoing message in the tool's required format.

Doctor — Runs diagnostics and returns actionable remediation steps.

src/state/ — Mode State Management (6 files, ~41K chars)

Operations (operations.ts) — CRUD operations for state files: read, write, delete, list. All writes are atomic (temp file + rename).

Paths (paths.ts) — Canonical path resolver for all state locations. Single source of truth for .omx/state/ structure.

Skill-active (skill-active.ts) — Tracks which skill is currently executing; prevents conflicting concurrent executions.

Workflow transitions (transitions.ts) — Validates state machine transitions. Illegal transitions (e.g., jumping from planning to complete without executing) are rejected.

File-based locking — Lock files in .omx/state/ prevent concurrent writes. See §7.8 for stale-lock risk.

src/pipeline/ — Pipeline Orchestrator (3 files, ~15K chars)

Three-stage pipeline:

RALPLAN → Team Execution → Ralph Verification

Stage 1 — RALPLAN. Planner agent produces a structured plan: tasks, assignments, acceptance criteria.

Stage 2 — Team Execution. Leader dispatches tasks to workers per plan. Workers execute in parallel worktrees.

Stage 3 — Ralph Verification. Ralph agent verifies outputs against acceptance criteria. Loops with fix attempts if criteria not met.

The pipeline writes stage outputs to .omx/state/ for cross-stage continuity.

src/ralph/ — Verification Loop (2 files, ~14K chars)

Ralph is the verification agent. Its phase contract:

starting → executing → verifying → fixing → complete
                                          ↘ failed
                                          ↘ cancelled

Ralph reads the acceptance criteria from the RALPLAN output, inspects worker outputs, and issues a PASS or FAIL verdict with structured feedback.

On FAIL, Ralph enters fixing phase: it synthesizes a remediation prompt and hands back to the execution layer for one more attempt. The cycle repeats up to a configured maximum.

Note

GitHub issue #1653 documents withRalphSteerLock entering infinite retry if the lock is never acquired. Until fixed, set a maximum wall-clock timeout externally (e.g., timeout 300 omx run ...).

src/openclaw/ — OpenClaw Integration (4 files, ~35K chars)

OpenClaw is an external automation gateway. OMX supports two gateway types:

HTTP gateway — POSTs structured requests to an HTTP endpoint. Configured via OMX_OPENCLAW_COMMAND_TIMEOUT_MS.

Command gateway — Executes a local command (OMX_OPENCLAW_COMMAND) with the request as stdin. Used for local OpenClaw installations.

Hook event mapping (event-mapping.ts) — Maps Codex hook events to OpenClaw event types.

Dispatcher (dispatcher.ts) — Routes events to the configured gateway; handles timeouts and retry.

src/utils/ — Shared Utilities (9 files, ~33K chars)

File Purpose
agents-md.ts Parse and manipulate AGENTS.md files
model-tables.ts Model name to capability/cost tables
git-layout.ts Git worktree and branch helpers
paths.ts Cross-platform path resolution
platform-commands.ts OS-specific command wrappers (Windows vs. POSIX)
repo-deps.ts Repository dependency graph analysis
safe-json.ts JSON parse/stringify with error containment
sleep.ts Promise-based sleep with cancellation
index.ts Re-exports

8.3 Rust Crate Reference

omx-runtime-core — Core Runtime Engine

The foundational crate. All higher-level runtime logic depends on it.

AuthorityLease — Cooperative lock granting one process authority over a session. Backed by a lease file in .omx/state/. Lease is time-limited; holder must renew periodically.

RuntimeEngine — Main event loop. Accepts events, dispatches to handlers, writes to DispatchLog.

DispatchLog — Append-only event log. Enables crash recovery by replaying events on restart. Entries are newline-delimited JSON.

MailboxLog — Per-worker message inbox. Each worker has a dedicated log file. Leader writes; worker reads and acknowledges.

ReplayState — Reconstructs in-memory state from DispatchLog on startup.

RateLimiter — Token-bucket rate limiter used for notification dispatch throttling.

omx-runtime-core/
├── src/
│   ├── authority.rs      AuthorityLease
│   ├── dispatch_log.rs   DispatchLog
│   ├── engine.rs         RuntimeEngine
│   ├── mailbox.rs        MailboxLog
│   ├── rate_limit.rs     RateLimiter
│   ├── replay.rs         ReplayState
│   └── lib.rs
└── Cargo.toml

omx-mux — tmux Multiplexer Abstractions

TmuxAdapter — Primary interface. Wraps the tmux binary with typed methods:

  • capture_pane(pane_id) returns String — Captures current pane content
  • send_keys(pane_id, keys) — Injects keystrokes
  • confirm_delivery(pane_id, sentinel) returns bool — Waits for sentinel string to appear in pane output

InputEnvelope — Typed wrapper for an input injection operation, including pane target, content, and delivery confirmation parameters.

CommandOutput — Structured output from tmux command execution: exit code, stdout, stderr.

Operation types: capture, send, confirm, resize, split, kill.

omx-mux/
├── src/
│   ├── adapter.rs        TmuxAdapter
│   ├── envelope.rs       InputEnvelope
│   ├── output.rs         CommandOutput
│   ├── operations.rs     Operation enum
│   └── lib.rs
└── Cargo.toml

omx-runtime — Runtime Binary Wrapper

Thin binary crate that wraps omx-runtime-core and omx-mux into a standalone executable. Started as a child process by src/runtime/ (the TypeScript bridge). Communicates with the parent via stdin/stdout JSON protocol.

omx-runtime/
├── src/
│   └── main.rs
└── Cargo.toml    (depends on omx-mux, omx-runtime-core)

omx-sparkshell — Shell Command Execution with AI Summary

Standalone binary. Called by OMX hooks to run a shell command and produce an AI-generated summary of the output.

Language-aware prompt construction — Detects the language context from file extensions or explicit hint; selects appropriate prompt template (e.g., Rust compilation errors vs. Python test output).

Line-count thresholding — Checks output line count against OMX_SPARKSHELL_LINES. Selects spark vs. frontier model accordingly.

Summary timeout — Enforced by OMX_SPARKSHELL_SUMMARY_TIMEOUT_MS. If the AI call times out, raw output is returned unchanged.

omx-sparkshell/
├── src/
│   ├── main.rs
│   ├── prompt.rs     Language-aware prompt builder
│   ├── model.rs      Model selection logic
│   └── summarize.rs  AI call + timeout handling
└── Cargo.toml

omx-explore-harness — Sandboxed Exploration Binary

POSIX-only. Wraps Codex CLI with a restricted PATH allowlist, preventing the subprocess from accessing host tools not in the approved list.

The harness:

  1. Parses the allowlist (hardcoded in source)
  2. Constructs a sanitized PATH containing only allowed tool directories
  3. execs Codex with the sanitized environment

No network sandboxing is performed — only PATH restriction.

omx-explore-harness/
├── src/
│   ├── main.rs
│   └── allowlist.rs  PATH allowlist definition
└── Cargo.toml

8.4 Pipeline Architecture Deep Dive

User: omx run --skill my-analysis
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 1: RALPLAN                                           │
│  src/ralplan/ + src/planning/                               │
│                                                             │
│  Planner agent reads task description + codebase map        │
│  Produces structured plan JSON:                             │
│    { tasks: [...], assignments: [...], criteria: [...] }    │
│  Written to .omx/state/mode/ralplan.json                    │
└────────────────────────────┬────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 2: Team Execution                                    │
│  src/team/ + omx-runtime + omx-mux                         │
│                                                             │
│  Leader creates tmux session                                │
│  Leader spawns N worker panes                               │
│  Workers bootstrap with roles + task assignments            │
│  Workers execute in isolated Git worktrees                  │
│  Mailbox system routes inter-worker messages                │
│  Phase controller tracks progress                           │
│  Results written to .omx/state/jobs/<job-id>.json           │
└────────────────────────────┬────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────┐
│  Stage 3: Ralph Verification                                │
│  src/ralph/                                                 │
│                                                             │
│  Ralph reads criteria from RALPLAN output                   │
│  Inspects worker outputs                                    │
│  Issues PASS / FAIL verdict                                 │
│  On FAIL: synthesize fix prompt, back to Stage 2            │
│  On PASS: write final result, notify                        │
└─────────────────────────────────────────────────────────────┘

8.5 Code Patterns & Conventions

State writes are always atomic. Pattern throughout src/state/:

// Write temp, then rename (never corrupt on crash)
await fs.writeFile(tmpPath, JSON.stringify(state), 'utf8');
await fs.rename(tmpPath, finalPath);

Safe JSON everywhere. src/utils/safe-json.ts wraps JSON.parse to return null on error rather than throwing, preventing cascade failures from corrupt state files.

Environment variable resolution with fallback chain. Session ID example:

const sessionId =
  process.env.OMX_SESSION_ID ??
  process.env.CODEX_SESSION_ID ??
  process.env.SESSION_ID;

Platform command abstraction. src/utils/platform-commands.ts provides getPlatformCommand(name) that returns the OS-appropriate command string. Used for shell invocations and tool discovery.

Rust AuthorityLease pattern — Cooperative, not kernel-enforced. All runtime components must respect the lease and not modify shared state while another holder is active.

8.6 Testing Strategy

TypeScript Tests

# Run all tests
node --test

# Run with coverage
npx c8 node --test

# Run specific file
node --test src/team/allocation.test.ts

Tests use Node.js built-in assert module. Mocking is done with manual stubs (no heavy framework).

Coverage thresholds enforced via c8 config:

{
  "lines": 78,
  "functions": 90,
  "branches": 70,
  "statements": 78
}

Rust Tests

# All crates
cargo test

# Specific crate
cargo test -p omx-runtime-core
cargo test -p omx-mux

# With output
cargo test -- --nocapture

TypeScript / Rust Compat Tests

cargo test -p omx-runtime   # includes compat suite

Compat tests verify that the TypeScript bridge and the Rust runtime binary communicate correctly. They serialize test messages from TypeScript, pass through the binary, and assert round-trip fidelity.

8.7 Contributing

Branching: Single main branch development. Feature branches for non-trivial changes.

Commit style: Conventional commits preferred (feat:, fix:, chore:, docs:).

Before submitting:

# TypeScript
npm run build
node --test
npx c8 node --test   # verify coverage thresholds

# Rust
cargo fmt --check
cargo clippy -- -D warnings
cargo test

New skills: Create skills/my-skill/SKILL.md, register in templates/catalog-manifest.json, add prompt in prompts/.

New MCP server: Follow the bootstrap pattern in src/mcp/; add disable env var OMX_<NAME>_SERVER_DISABLE_AUTO_START; add parent watchdog and sibling detection.

New notification platform: Implement the notifier interface (probe, send, format methods), add env vars to config_keys.tsv, add formatter.


9. Integration Points

9.1 MCP Server Integration

OMX exposes its internal state via 5 MCP servers on the stdio transport. External tools (including Codex agents) can connect as MCP clients.

Server discovery: Codex is configured via the generated MCP registry (see src/config/) to connect to all 5 servers on session start.

State server tools:

  • read_state(path) — Read a state file by relative path under .omx/state/
  • write_state(path, content) — Atomic write to a state file
  • list_state(prefix) — List state files matching prefix

Memory server tools:

  • remember(key, value) — Store a key-value pair
  • recall(key) — Retrieve by key
  • forget(key) — Delete a key

Wiki server tools:

  • ingest(title, content) — Write a wiki page
  • query(query) — Full-text search
  • lint(title) — Validate page structure

Note

CJK wiki titles produce hash-based filenames due to issue #1641. Until patched, use ASCII slug titles for pages that must have human-readable filenames.

9.2 OpenClaw Integration

OpenClaw is an external automation gateway. OMX supports two connection modes:

# HTTP gateway
export OMX_OPENCLAW=true
export OMX_OPENCLAW_COMMAND_TIMEOUT_MS=5000
# OpenClaw server must be running at configured endpoint

# Command gateway
export OMX_OPENCLAW=true
export OMX_OPENCLAW_COMMAND=/usr/local/bin/openclaw-cli

The adapter framework (src/adapt/) provides the doctor command to diagnose connectivity:

omx adapt doctor openclaw

9.3 Notification Platform Integration

Discord (Webhook — simplest)

export OMX_DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/..."
export OMX_DISCORD_MENTION="<@!123456789>"   # optional user ping
omx team start

Discord (Bot — full features)

export OMX_DISCORD_NOTIFIER_BOT_TOKEN="Bot ..."
export OMX_DISCORD_NOTIFIER_CHANNEL="987654321"
export OMX_DISCORD_MENTION="<@&112233445>"   # role ping

Telegram

export OMX_TELEGRAM_BOT_TOKEN="123456:ABC..."
export OMX_TELEGRAM_CHAT_ID="-100123456789"

Slack

export OMX_SLACK_WEBHOOK_URL="https://hooks.slack.com/services/..."
export OMX_SLACK_MENTION="<!channel>"

Reply Listener

export OMX_REPLY_ENABLED=true
export OMX_REPLY_DISCORD_USER_IDS="111222333,444555666"
export OMX_REPLY_POLL_INTERVAL_MS=5000
export OMX_REPLY_RATE_LIMIT=10

Caution

The reply listener has a known sensitive data leak (issue #1661). Enable only in private channels with trusted users.

9.4 Hook System Extension

To add a custom hook handler via the plugin system:

// my-plugin.ts
import { OMXPlugin, HookEvent } from 'oh-my-codex/sdk';

export const plugin: OMXPlugin = {
  name: 'my-plugin',
  version: '1.0.0',
  hooks: {
    [HookEvent.PreToolUse]: async (ctx) => {
      // Inspect or modify ctx.toolCall
      return ctx;
    },
    [HookEvent.Stop]: async (ctx) => {
      // Cleanup
    },
  },
};

Place the plugin where the loader discovers it (configured via OMX_HOOK_CONFIG).

9.5 Codex CLI Integration

OMX requires Codex CLI to be installed and configured. It integrates via:

  1. Config generation — omx config writes the Codex hooks config pointing to OMX handlers
  2. Process spawning — Leader spawns codex processes in worker panes via tmux
  3. Hook firing — Codex calls OMX hook handlers via configured endpoints on lifecycle events
  4. Explore harness — omx-explore-harness wraps codex for sandboxed exploration

To initialize OMX for a project:

cd /path/to/project
omx config init          # generate AGENTS.md, hooks config, MCP registry
omx team start --workers 3

9.6 Adapt Framework — Adding New Adapters

Implement the adapter contract in src/adapt/:

// src/adapt/my-tool/index.ts
import { AdapterContract } from '../contracts';

export const myToolAdapter: AdapterContract = {
  probe: async () => { /* check availability */ },
  status: async () => { /* return health */ },
  init: async (config) => { /* initialize */ },
  envelope: (message) => { /* format message */ },
  doctor: async () => { /* run diagnostics */ },
};

Register in the adapter registry and add environment variables to config_keys.tsv.

9.7 Known Issues Summary Table

Issue Area Severity Workaround
#1643 macOS TTY (omx exits immediately) High Run in foreground; avoid backgrounding Codex
#1671 omx update overwrites AGENTS.md High Backup AGENTS.md before updating
#1635 Leader HUD stuck on MCP startup Medium Stop + restart team
#1665 MCP duplicate sibling accumulation Medium Kill stray omx-mcp processes
#1657 SIGTERM without PID verification Medium Run in isolated process namespace
#1677 Stream error / connection recovery Medium Restart affected worker pane
#1661 Reply listener leaks sensitive data High Disable OMX_REPLY_ENABLED
#1660 Transitive dep vulnerabilities Medium npm audit fix + cargo audit
#1653 withRalphSteerLock infinite retry Medium External timeout on omx invocations
#1654 stateDirToProjectRoot hardcoded depth Low Keep .omx/ at repo root
#1656 Leader git polling blocks event loop Low Reduce polling frequency (no config yet)
#1655 withTmuxExtendedKeysLeaseLock no stale recovery Medium Delete stale lock files manually
#1642 Detached leader skips tmux kill-session Low Kill orphan sessions manually
#1641 wiki titleToSlug strips non-ASCII Low Use ASCII slug titles for CJK pages
#1648 Built-in skills not namespaced with omx: Low No impact until namespacing enforced
#1640 buildWorkerStartupCommand shell injection High Never pass untrusted LAUNCH_ARGS
#1649 Path traversal via identifiers High Validate all identifiers before passing
#1659 hud/state.ts git injection via remoteName Medium Ensure trusted .git/config only