Skip to content

Add Codex CLI container harness - #47

Merged
CrypticSwarm merged 10 commits into
masterfrom
codex-cli-harness
Aug 26, 2026
Merged

CrypticSwarm merged 10 commits into
masterfrom
codex-cli-harness

Conversation

@CrypticSwarm

@CrypticSwarm CrypticSwarm commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Adds containerized support for OpenAI's Codex CLI as a fourth harness, with persistent authentication and session state, layered configuration, shared assets, MCP tongs, and stable workspace mounts.

Run it with:

make build_codex
make run_codex PROJECT_DIR=$(pwd)

Runtime layout

The official Codex release includes companion binaries, so the package remains intact under /opt/codex and its installer-provided symlink exposes codex on PATH.

CODEX_HOME_DIR persists credentials and sessions. The entrypoint rebuilds config.toml from repo, user, and org layers on every launch, merges settings by key, then copies the result into the writable Codex home. Same-named MCP server definitions replace one another as units, and durable settings belong in a source layer.

Shared assets

Shared skills use Codex's native ~/.agents/skills location. Portable slash commands are translated into same-named skills while preserving layer precedence.

Unified agent definitions are translated into project-agent TOML under <workspace>/.codex/agents. Codex-specific model, reasoning, and sandbox settings can be supplied through the unified codex: override block.

MCP tongs

Codex and Grok share the TOML MCP emitter. Generated servers are maintained in a managed block, refreshed each run, and yield to user-configured servers with the same name.

Sandbox

Codex's sandbox remains enabled by default. Use CODEX_ARGS='--dangerously-bypass-approvals-and-sandbox' for a run, or configure sandbox_mode in a config layer when the container environment requires it.

Add containerized support for OpenAI's Codex CLI, following the Claude and
Grok pattern: a persistent credentialed home, the harness's native skills
dir, and the stable repo-slug mount path.

Codex is the first harness whose release is not a single file. bin/codex
resolves ripgrep, bwrap, and a bundled zsh beside itself, so the image
cannot relocate one binary the way the other three arms do -- the package
stays whole under /opt/codex and the installer's own symlink is what lands
at /usr/local/bin/codex. CODEX_HOME is set only for the build, so the
runtime config dir is still ~/.codex.

It is also the first harness whose skills location is the harness-neutral
one: Codex reads ~/.agents/skills, the same convention the portable overlay
layers are already written in. Only that dir is masked with tmpfs, because
Codex has no user-defined slash commands -- skills are its one extension
point -- so copy_shared_assets leaves the commands destination empty and
copy_dir_entries now treats an empty destination as nothing to do.

- Makefile: build_codex/update_codex/run_codex/stop_codex and the matching
  image/home/args vars; config dest ~/.codex with reset disabled so
  credentials persist across runs.
- entrypoint: exclude the host installer's packages/ tree from the layered
  merge, along with the sessions, history, and log a persistent home would
  otherwise keep from another machine.
A session with an mcp-interface tong refused to launch under run_codex
because no MCP config emitter existed for the harness. Codex reads servers
in the same shape Grok does -- TOML [mcp_servers.<name>] tables where a url
key selects the remote transport -- and merges into a persistent home the
same way, so the two harnesses now share one emitter and one renderer
instead of gaining a second copy of each.

Rename swarmforge.config.merge_grok_mcp to merge_toml_mcp and
tongs.mcp_config_grok to mcp_config_toml, and point both harnesses at them
from MCP_EMITTERS and the entrypoint's per-harness dispatch. Neither had
anything Grok-specific in it beyond the name: the managed-block behaviour
(rewritten every run, stripped when a session has no MCP tongs, yielding to
a same-named server the user defines) is what any harness merging generated
servers into a persistent config.toml needs.
Add a Codex CLI section to the README: the package-shaped install, the
persistent ~/.codex home, AGENTS.md discovery, skills delivery through the
.agents convention, MCP tongs, and config layering.

Codex's own sandbox is the one thing a reader has to act on rather than
just know about. It is redundant inside an anvil and may not initialize in
one at all, so the section names both ways to relax it.

A fourth harness also makes the two-harness prose above wrong in two more
places. Point the org-config root and the repo config layer at every
harness instead of enumerating a pair.
Build layered config in a per-run location while credentials and sessions
remain in the persistent Codex home.
Compose repo, user, and org settings without replacing config.toml
wholesale. Replace same-named MCP server definitions as units so transport
fields cannot leak across layers.
Convert shared slash commands into Codex skills while preserving layer
precedence and adapting arguments and shell interpolation.
Codex atomically replaces config.toml when saving settings. Copy the merged
file into its persistent home instead of bind-mounting the file so settings
updates succeed.
Emit native project-agent TOML so shared definitions reach Codex. Define
Codex-specific model, sandbox, override, disable, and name handling.
Correct unified-agent coverage and condense the comments for command
translation, config publication, and agent fields.
Register temporary role files through the derived Codex config so
unified agents remain available without modifying the project or
persistent home. Preserve configured-role precedence and guard reserved
agent names.
@CrypticSwarm
CrypticSwarm merged commit b841214 into master Aug 26, 2026
4 checks passed
@CrypticSwarm
CrypticSwarm deleted the codex-cli-harness branch August 26, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant