presents omp as codex for use with chatgpt remote
omp-codex-bridge AGENTS.md
10.0 kB · 151 lines
Markdown
at main

OMP Codex Bridge — Agent & Developer Reference #

This document covers the internal architecture, protocol mechanics, backend integration paths, and development workflows for @oh-my-pi/codex-bridge.

System Overview #

@oh-my-pi/codex-bridge is an adapter that speaks the Codex CLI and app-server JSON-RPC / WebSocket protocols on the frontend while driving Oh My Pi on the backend.

+---------------------+               +--------------------------------------+
|  ChatGPT Desktop    | --(SSH/stdio)-->|  codex shim (bin/codex.mjs)          |
|  or Remote Control  | --(Unix sock)->|    |                                 |
+---------------------+               |    v                                 |
                                      |  AppServer (src/app-server.mjs)      |
                                      |    |                                 |
                                      |    +--> Backend (src/backend/omp.mjs)|
                                      |           |                          |
                                      +-----------|--------------------------+
                                                  v
                                      +-----------------------+
                                      |  Oh My Pi (OMP)       |
                                      |  (SDK / RPC Process)  |
                                      +-----------------------+

Backend Modes #

Configured via backend in config.json or OMP_CODEX_BACKEND (auto, sdk, rpc, prime, both, mock):

  1. auto (default): Tries direct SDK import first; if unavailable, falls back to the omp CLI in RPC mode.

  2. sdk: Imports the OMP coding-agent module directly in-process. Resolves in order:

    • process.env.OMP_CODEX_OMP_MODULE (explicit path or package name)
    • @oh-my-pi/pi-coding-agent
    • @oh-my-pi/coding-agent
    • @oh-my-pi/agent
    • Local Bun workspace paths (packages/coding-agent/src/index.ts)
  3. rpc: Spawns omp as a subprocess with JSONL RPC communication (omp --mode rpc-ui). Override binary path with OMP_CODEX_OMP_BIN and args with OMP_CODEX_OMP_RPC_ARGS.

  4. prime: Spawns Prime (prime-agent, Prime 0.8.0 or newer) as a subprocess speaking Prime's own JSONL RPC protocol (--mode rpc). Reached through a dynamic import of src/backend/prime.mjs, so auto never loads it and a machine without Prime installed starts exactly as before. Binary resolution order:

    • primeExecutable passed programmatically or set under sessionOptions in config.json
    • OMP_CODEX_PRIME_BIN
    • ~/.local/bin, ~/.bun/bin, ~/.nix-profile/bin, /opt/homebrew/bin, /usr/local/bin
    • prime-agent on PATH

    Extra flags come from OMP_CODEX_PRIME_RPC_ARGS (JSON array) and are appended — unlike OMP_CODEX_OMP_RPC_ARGS, they never replace the base argument vector, so --resume/--model/--cwd survive.

    Prime publishes its own short model catalog, so the factory declares modelCatalogPolicy = "all" and model/list exempts its rows from the OMP featured-model filter (see below). Rows carry a bare id (gpt-5.6-luna) plus a provider-qualified selector (openai-codex/gpt-5.6-luna). Prime's own dialogs (extension_ui_request) map onto the Codex user-input request and are answered with extension_ui_response.

    Prime enforces no approvals and no sandbox. It has no Codex/OMP command or file approval primitive, so defaultApprovalPolicy is not applied, no approval round-trip is sent to the client, and shell commands and file writes run with the daemon's own privileges. Use it only where unattended edits are acceptable.

  5. both: Loads the normal OMP auto backend and Prime together. It advertises a synthetic custom provider through config/read, allowing Desktop/iOS to accept unique model IDs such as gpt-5.6-luna-via-omp and gpt-5.6-luna-via-prime-agent. Display names append (OMP) or (Prime Agent). Selecting the qualified ID chooses the backend for a new thread. Persisted backend.kind chooses the backend when a thread resumes; an existing thread cannot switch agent families through a later model change. Local modelCatalog policy controls filtering and ordering without changing the packaged catalogs.

  6. mock: In-memory deterministic backend for unit tests, offline development, and verification suites.

Model Catalog Visibility #

model/list hides every model outside FEATURED_MODEL_IDS (src/backend/omp.mjs), because OMP's catalog runs to hundreds of rows and the Desktop picker becomes unusable otherwise. A backend whose catalog is already short would lose all of its rows to that filter, so it opts out explicitly:

  • Factory-level: modelCatalogPolicy = "all" on the backend factory (instance or static). createBackendFactory defaults this for prime when the factory does not set it itself.
  • Row-level: catalogPassthrough: true on an individual model row.

Neither is inferred from a provider name or id prefix. A row that sets hidden: true stays hidden regardless of policy.

modelCatalog in bridge config is an optional local policy layer:

  • include / exclude: * glob patterns over canonical model IDs.
  • excludeProviders: exact provider IDs to remove.
  • backendOrder: backend tags such as ["omp", "prime-agent"].
  • order: ordered * glob patterns applied within each backend group.

When include is present, matching rows bypass FEATURED_MODEL_IDS; omitted policy retains the existing backend-specific visibility and ordering.

Transport Modes #

  • JSONL stdio (codex app-server): Standard entry point invoked by SSH connections from ChatGPT Desktop.
  • Unix Domain Socket (codex remote-control start): Listens on ~/.omp/codex-bridge/run/app-server.sock (mode 0600).
  • WebSocket Proxy (codex app-server proxy): Bridges stdio to the running daemon's Unix socket.
  • Loopback TCP WebSocket: Available for local development. Binding to non-loopback addresses requires OMP_CODEX_ALLOW_PUBLIC_LISTEN=1.

Environment Variables #

Variable Purpose Default
OMP_CODEX_BACKEND auto, sdk, rpc, prime, both, or mock auto
OMP_CODEX_OMP_MODULE Explicit OMP SDK module or file URL autodetected
OMP_CODEX_OMP_BIN Path to omp executable for RPC mode autodetected via PATH
OMP_CODEX_OMP_RPC_ARGS JSON array of arguments for OMP RPC process ["--mode","rpc-ui"]
OMP_CODEX_PRIME_BIN Path to prime-agent executable for prime backend autodetected via PATH
OMP_CODEX_PRIME_RPC_ARGS JSON array of extra flags appended to Prime's RPC argv []
OMP_CODEX_CONFIG Path to bridge config file ~/.omp/codex-bridge/config.json
OMP_CODEX_STATE_FILE Persistent state JSON path ~/.omp/codex-bridge/state.json
OMP_CODEX_DEFAULT_MODEL Default model identifier gemini-3.7-flash
OMP_CODEX_MODEL_ALIASES JSON string of extra model aliases {}
OMP_CODEX_RUNTIME_DIR Directory for daemon sockets/pids/logs ~/.omp/codex-bridge/run
OMP_CODEX_SOCKET Custom Unix domain socket path <runtime>/app-server.sock
OMP_CODEX_COMPAT_VERSION Version reported by codex --version 0.145.0
OMP_CODEX_DEBUG Enable verbose diagnostics to stderr disabled
OMP_CODEX_QUIET Suppress non-error logs disabled
OMP_CODEX_ALLOW_FS_OUTSIDE_WORKSPACE Disable workspace boundary checks disabled (unsafe)
OMP_CODEX_ALLOW_PUBLIC_LISTEN Permit non-loopback TCP listeners disabled (unsafe)

State & Persistence #

  • State file: ~/.omp/codex-bridge/state.json (atomic writes, mode 0600).
  • Tracks thread IDs, turn history, approval cache ("accept for session"), model overrides, and associated OMP session IDs for resumption.
  • Direct filesystem requests (fs/readFile, fs/writeFile, etc.) are canonicalized and guarded against path traversal outside the active workspace root.

Workspace & Worktree Isolation (Jujutsu & Git) #

The bridge provides automatic VCS workspace isolation for threads and forks:

  1. Automatic Detection (src/workspace.mjs):
    • Checks for a Jujutsu (jj) repository first via jj root.
    • If not found, checks for a Git repository via git rev-parse --show-toplevel.
    • Falls back to unisolated direct cwd if outside a repository.
  2. Jujutsu Workspaces (jj workspace add):
    • Preferred when jj is detected.
    • Creates an independent workspace without index locking, stash conflicts, or branch collision.
    • Snapshots all agent mutations automatically in the jj operation log.
    • Automatically forgotten (jj workspace forget) and cleaned up on thread deletion.
  3. Git Worktree Fallback (git worktree add):
    • Used in standard Git repositories when jj is not present.
    • Creates a detached HEAD worktree and removes it on thread deletion.
  4. Configuration:
    • workspaceIsolation in config.json or OMP_CODEX_WORKSPACE_ISOLATION: "auto" (default), "jj", "git", or "none".
    • Custom isolation directory via OMP_CODEX_WORKSPACES_DIR (defaults to ~/.omp/codex-bridge/workspaces).

Protocol Tracing & Replay #

To record live protocol exchanges from the real Codex binary or ChatGPT desktop:

CODEX_REAL=/path/to/real/codex node ./scripts/codex-trace-wrapper.mjs app-server

Recorded traces are written to ~/.omp/codex-bridge/traces/ and can be inspected or replayed for debugging.

Verification & Testing #

Run tests and release checks from the repo root:

# Unit and integration test suite (15 tests)
npm test

# Lint/syntax check all JS modules
node ./scripts/check.mjs

# Full isolated release verification (clean-copy + daemon lifecycle)
./scripts/verify-release.sh

# Install or refresh local shim in ~/.local/bin/codex
./scripts/install-local.sh "$HOME/.local"