codex

package
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 5, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package codex drives the Codex CLI headless (design §5.2): one run per job, `codex exec --json`, resumed by thread id when the job carries one. The CLI's own login state — its subscription tokens, its configuration — is the ambient environment's business; brigada adds nothing of its own to it and takes the runner's share back out.

Index

Constants

View Source
const DefaultModel = "default"

DefaultModel is the agent's name for the CLI's own default model: the one the CLI picks when no -m names another. The runner offers it when the agent's configuration sets no --model, and the adapter's answer to it is no -m flag at all.

Variables

This section is empty.

Functions

This section is empty.

Types

type Adapter

type Adapter struct {
	// Binary is the CLI to run; "codex" when empty.
	Binary string

	// ExtraArgs are further flags the agent's configuration passes
	// through, appended verbatim after the adapter's own, before the
	// prompt. Empty adds nothing.
	ExtraArgs []string
}

Adapter drives the codex CLI (0.162.x) in its headless exec mode. The zero value runs `codex` from PATH; the fields carry what the agent's configuration passes through.

It can also be a foreman harness: codex's config overrides carry the runner-written MCP bridge into `codex exec`.

func (*Adapter) AttachCommand

func (a *Adapter) AttachCommand(job adapter.Job, workdir, resumeSessionID, _ string) (*exec.Cmd, error)

AttachCommand implements adapter.Interactive: Codex's own terminal UI is started directly, with the opening prompt as its positional argument. A saved exec thread is resumed with `codex resume <thread-id>`; without one, plain `codex` starts a fresh conversation. The client-generated session id is intentionally unused: Codex does not expose Claude's fork/session-id pair. On detach the client nevertheless writes its minted id back as the key's session, so a later headless or interactive resume targets a thread Codex never created and falls back to a fresh run; this is the documented limitation until Codex exposes a fork/session-id facility.

A foreman attach (a job carrying the MCP config) runs in workdir, the foreman's reading checkout, with the same read-only sandbox and separate approval settings as a headless turn, without --json or approval bypass. Codex has no equivalent of Claude's statusLine, so StatusLine is ignored. MCPConfig is likewise not translated: Codex has no adapter-supported MCP config flag; the terminal remains the CLI's own interactive session.

func (*Adapter) Command

func (a *Adapter) Command(job adapter.Job, workdir, resumeSessionID string) (*exec.Cmd, error)

Command implements adapter.Adapter: the fresh or resume invocation of the CLI, running in workdir:

A worker runs `codex exec --json -s workspace-write`; a foreman runs `codex exec --json -s read-only` with MCP and approval overrides below. The worker's sandbox lets it edit inside its worktree without approval, while the CLI's default keeps the network off. No --skip-git-repo-check: a worker's directory is a worktree, which is a git repo. The prompt is piped on stdin (the `-` positional), verbatim — the engine's product (§1.4), not the adapter's to edit, and out of argv. A review runs `-s read-only`. For a foreman, use the read-only sandbox and independent approval settings. --approve-for-me selects workspace-write and conflicts with -s. Automatic review remains available to MCP; sandbox and permission escalations are rejected, so policy alone cannot turn the reading checkout writable. The environment is the runner's ambient set minus brigada's own share of it (§5.1): every BRIGADA_-prefixed variable is dropped.

func (*Adapter) Name

func (a *Adapter) Name() string

Name implements adapter.Adapter: the harness this adapter drives, which the runner's advertisement pairs it with (§5.1).

func (*Adapter) ParseErrEvent

func (a *Adapter) ParseErrEvent(line []byte) (adapter.Event, bool)

ParseErrEvent implements adapter.Adapter: one line of the CLI's stderr, the strictest stream the adapter reads. Stderr carries the CLI's chatter — retry notes, warnings, MCP noise — so prose there sorts by the strict table only: a failure message named in full, or nothing, and noise cannot fail a run that ended clean. The CLI's JSON there is an error event, sorted as on stdout.

func (*Adapter) ParseEvent

func (a *Adapter) ParseEvent(line []byte) (adapter.Event, bool)

ParseEvent implements adapter.Adapter: one line of the CLI's --json stream turned into one progress event.

thread.started                    → session id (the thread id)
item.completed agent_message      → assistant message
item.started command_execution    → tool start (the command's first line)
item.completed command_execution  → tool end (the same text)
item.started mcp_tool_call       → tool start (server/tool)
item.completed mcp_tool_call     → tool end, naming the error when the call failed
error, error item                 → an error event, sorted by its text;
                                    marked Notice: a warning until turn.started
turn.failed                       → the final error event, sorted by its text
turn.completed                    → usage counters (not progress)
turn.started                      → ignored

Unknown event and item types and malformed lines are ignored, never fatal, so a stray line cannot fail an otherwise good run.

func (*Adapter) ProbeCommand

func (a *Adapter) ProbeCommand(ctx context.Context) *exec.Cmd

ProbeCommand implements adapter.Adapter: `codex --version`, a cheap command that answers when the CLI is well (§8 "Health"), bound to ctx so a hung CLI is killed and reads as a failing probe.

func (*Adapter) ResultText

func (a *Adapter) ResultText(events []adapter.Event) string

ResultText implements adapter.Adapter: the run's final answer is the last agent_message of the run (§5.4); a run that never spoke has none.

func (*Adapter) StartsTurn

func (a *Adapter) StartsTurn(line []byte) bool

StartsTurn implements adapter.TurnMarker: the line is the stream's turn.started. The adapter keeps no stream state (one adapter serves concurrent jobs); the runner tracks each job's turn and downgrades the errors marked Notice that precede it.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL