Expand description
Subprocess backends: drive a round’s edits by shelling out to the claude,
opencode, codex, or cursor-agent CLI in non-interactive mode, run with
the scheduler crate directory as the cwd so the CLI’s own tools edit the files
in place. The controller then builds/validates the resulting diff exactly as
it does for the built-in openai backend, so keep/revert/dedup work
unchanged.
Each CLI runs in one of two Modes. In Mode::Edit it edits the crate
in place with its approval/permission prompts disabled and full write access,
so only run that where it is acceptable. In Mode::Plan it runs read-only
and returns a textual plan that is handed to the coder role: claude uses its
plan permission mode, codex a read-only sandbox, and cursor-agent its
plan mode (all genuinely cannot write); opencode uses its built-in plan
agent on a best-effort basis and may still touch files (its edits are just
validated/reverted like any other round).
Structs§
- Claude
Plan 🔒Capture - Stream
Printer 🔒 - Streams a subprocess backend’s assistant text and reasoning to stdout as the CLI emits it, mirroring the openai backend. This is chunk-level: each CLI event (text block / part / item) is printed whole as it arrives, not token-by-token. Reasoning is dimmed to set it apart from the answer. Tool-call lines are printed separately to stderr and are not handled here.
Enums§
- Mode
- How a subprocess backend runs this turn.
Functions§
- arg_
hint 🔒 - Pick the most informative argument from a tool-call input object (the command run, or the file/path/pattern it targets), truncated for one-line display.
- claude_
plan_ 🔒path - claude_
supports_ 🔒partial_ messages - Whether the installed
claudeadvertises--include-partial-messages(added in newer versions). Detected once fromclaude --helpand cached: older builds reject unknown flags, so we must not pass it blindly. When absent we fall back to chunk-level output (the result-event text printed at turn end). - codex_
file_ 🔒paths - Best-effort changed-file paths from a codex
file_changeitem. - codex_
item_ 🔒label - A concise label for a codex
item.completeditem, or None for non-tool items (assistant text / reasoning). Includes the command run or files changed. - cursor_
is_ 🔒new_ fragment - cursor streams a message as fragment deltas (with
--stream-partial-output), then repeats the whole message as one consolidation event whose text equals the accumulated fragments. Track the running segment so that consolidation is dropped instead of printed a second time. Returns true iftextis a new fragment to print, false if it is the repeat (and the segment is reset, ready for the next message). - cursor_
tool_ 🔒label - A concise label for a cursor-agent
tool_callevent. Thetool_callobject carries the tool under a single<name>ToolCallkey (e.g.shellToolCall,readToolCall,editToolCall) alongside bookkeeping keys likehookAdditionalContexts/toolCallId. serde_json orders object keys alphabetically, so pick the*ToolCallkey explicitly rather than the first one; strip the suffix and pull a salient argument (command / path) fromargs. - first_
line 🔒 - format_
command 🔒 - codex
commandis a string or an argv array; render it as a single line. - invoke_
claude 🔒 - invoke_
codex 🔒 - invoke_
cursor 🔒 - invoke_
opencode 🔒 - is_
claude_ 🔒plan_ path - nonempty_
string 🔒 - print_
recovered_ 🔒claude_ plan - print_
tool 🔒 - Print a concise tool-call line (matches the openai backend’s non-verbose output).
- run
- Run one prompt through the configured subprocess backend in
cwd, returning the CLI’s final text. InMode::Editthis is the round’s change summary (the CLI editscwddirectly); inMode::Planit is the plan handed to the coder. Whenstream_stdoutis set the assistant’s text and reasoning are streamed to stdout as the CLI emits them (chunk-level, mirroring the openai backend). Token usage reported by the CLI is summed intousage(reliably forclaude;opencode/codexonly when they emit it). - run_
streaming 🔒 - Spawn
cmdwithstdin_payloadpiped in, stream stdout line-by-line, callon_eventfor each JSON line (echoing raw lines to stderr when verbose), and return the exit status plus captured stderr. - terminate_
process_ 🔒group - tool_
label 🔒 name(hint)when a salient argument is available, else justname.- truncate 🔒