Documentation
¶
Overview ¶
Package codex implements adapters.HarnessAdapter for the Codex CLI.
Phase 3-c prototype: the goal is to validate that adapters.HarnessAdapter composes for a non-claude harness, not to reach feature parity with the claude adapter. Run() forks `codex exec` with signal forwarding and exit normalisation; session persistence, payload_patch.json writes and boid task notify integration are deliberately left out (see docs/plans/agent-aware-boid.md Phase 3-c).
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Adapter ¶
type Adapter struct{}
Adapter implements adapters.HarnessAdapter for the Codex CLI.
func (*Adapter) Bindings ¶
Bindings declares the host bind-mounts codex.Adapter.Run() needs inside the sandbox. Three concerns, each handled by one entry:
- ~/.codex/ — rw state dir (sessions, sqlite, auth.json, config.toml).
- The parent dir of the resolved `codex` binary on the host PATH. We resolve symlinks first so a volta-shimmed install (~/.volta/bin/codex → volta-shim) lands on the shim's own dir, not on a dangling link. The dispatcher's buildPATH automatically lifts this dir onto PATH.
- ~/.volta/ — ro shim runtime tree. volta-shim execs binaries from ~/.volta/tools/ under the hood, so binding only the bin dir is not enough. Optional means non-volta hosts silently skip this entry.
- ~/.local/share/boid/skills/<name> → ~/.claude/skills/<name> per embedded skill. codex has no slash-command / skill loader, so the task hook bootstrap prompt (see run.go taskBootstrapPrompt) tells the agent to read ~/.claude/skills/boid-task/SKILL.md. We deliberately reuse the ~/.claude/skills/ target that the claude adapter also mounts: opencode auto-detects skills under ~/.claude/ as well, and aligning the codex mount with that convention keeps a single canonical sandbox path ("~/.claude/skills/boid-task/SKILL.md") for every harness.
All entries are Optional: missing source paths just drop out of the mount set instead of failing the dispatch. That keeps a host without codex installed (e.g. CI) from breaking dispatch unrelated to the codex agent.
func (*Adapter) Run ¶
Run forks codex. Interactive vs non-interactive is keyed off rc.TaskID: session jobs (JobKindSession) carry no task and are user-initiated, so they land in interactive TUI mode; hook jobs carry a BOID_TASK_ID and fall through to non-interactive `codex exec`. This mirrors how the claude adapter discriminates JobKindSession from JobKindHook via rc.TaskID == "".
Other responsibilities mirror the claude / opencode adapters: signal forwarding via sigutil, exit code normalisation for daemon-initiated stops, PWD strip on the child env, and cmd.Dir as the source of truth for the workdir.
Session persistence and payload_patch.json writes are deliberately NOT wired here — see docs/plans/multi-harness-production.md for the explicit non-goals (interactive sessions are run-and-done, no resume yet).