Agent CLI lifecycle¶
This page covers the full lifecycle of an agent CLI in Ralph Workflow: selection, detection, authentication, and invocation. It complements Configuration (which configures each phase to use an agent) and Agent Compatibility (which lists every supported agent with caveats and workarounds).
The agent-CLI trust boundary¶
Ralph Workflow does not authenticate agent CLIs. Each agent CLI uses its own native authentication:
Claude Code —
claude login/ Anthropic API key in the local keychainCodex CLI —
codex login/ OpenAI API key in the local keychainOpenCode — provider-specific keys configured per provider
Nanocoder — local-only TUI, no remote auth
Google Anti Gravity (AGY) —
agy login/ Google accountPi —
piprovider configurationCursor —
agent login/CURSOR_API_KEY
You authenticate each agent CLI yourself before invoking Ralph Workflow. Ralph Workflow then calls the agent CLI as-is and supervises the workflow. It does not read, store, or proxy credentials.
This is a deliberate trust boundary: you own your agent credentials. Ralph Workflow’s job is to orchestrate work, not to handle secrets.
Selection — the eight built-in agents¶
The canonical registry is ralph/agents/builtin.py. Ralph Workflow ships
with eight built-in agent specs that the bundled default policy can route
phases to:
Built-in name |
CLI |
Transport |
Headless? |
Use case |
|---|---|---|---|---|
|
|
Interactive (PTY) |
Yes (with |
Anthropic’s Claude Code; canonical reference agent |
|
|
Headless subprocess |
Yes |
Same binary, no PTY |
|
|
Headless subprocess |
Yes |
OpenAI’s Codex CLI |
|
|
Headless subprocess |
Yes |
Open-source terminal coding agent |
|
|
Local TUI |
Yes |
Local-only TUI coding agent |
|
|
Interactive (PTY) |
Yes (mock-backed) |
Google’s Antigravity CLI (v1.0.9+) |
|
|
Headless subprocess |
Yes |
Minimal coding agent; |
|
|
Headless subprocess |
Yes |
Cursor Agent CLI; headless |
Beyond the eight built-ins, the registry resolves dynamic <agent>/<model>
aliases through _resolve_dynamic_agent. So agy/Gemini 3.5 Flash (Medium)
is a valid agent spec that resolves at runtime to the AGY binary with the
named model. The eight canonical agy models display names accepted by
agy models are:
Gemini 3.5 Flash (Medium)Gemini 3.5 Flash (High)Gemini 3.5 Flash (Low)Gemini 3.1 Pro (Low)Gemini 3.1 Pro (High)Claude Sonnet 4.6 (Thinking)Claude Opus 4.6 (Thinking)GPT-OSS 120B (Medium)
For chain and drain routing — using one agent’s output as the next agent’s input across phases — see Configuration.
Detection — finding agents on PATH¶
Ralph Workflow discovers each agent CLI via shutil.which(agent_binary).
Detection happens at the moment a phase is routed to an agent, not at
--init time, so a CLI you install between ralph --init and ralph is
picked up automatically.
To verify detection before a run:
ralph --list-agents
To validate availability alongside the rest of the pre-flight:
ralph --diagnose
Overriding the binary path¶
Some agents allow pointing at a custom executable via environment variable.
The canonical example is RALPH_AGY_BINARY:
RALPH_AGY_BINARY=/path/to/custom/agy ralph --diagnose
The seam lives in ralph/cli/commands/smoke.py via
_maybe_apply_agy_binary_override(agent_config) immediately after
registry.get(agent_name). The plumbing layer stays free of env-var seams;
the CLI surface applies the override at the boundary.
Cursor honors the same pattern via RALPH_CURSOR_BINARY:
RALPH_CURSOR_BINARY=/path/to/cursor-wrapper ralph --diagnose
The seam lives in ralph/cli/commands/smoke.py via
_maybe_apply_cursor_binary_override(agent_config). Unlike AGY there
is no bundled mock binary for Cursor; the override points at a real
wrapper, alternate live binary, or an operator-wired test stub.
For mock-backed deterministic CI runs, point RALPH_AGY_BINARY at the
bundled mock:
RALPH_AGY_BINARY="$(pwd)/tests/_support/mock_agy.sh"
The mock entrypoint is tests/_support/mock_agy.py (run as
python -m tests._support.mock_agy); tests/_support/mock_agy.sh is a thin
shell wrapper suitable for RALPH_AGY_BINARY.
Authentication — you own it¶
This section is short on purpose. Ralph Workflow does not authenticate agents. Before your first run:
Install each agent CLI you want to use (e.g.
pipx install codex-cli).Authenticate each one using its native flow.
Verify the auth worked (e.g.
claude "say hello"works from your shell).Then run
ralph --diagnoseto confirm Ralph Workflow can find the CLI onPATH.
If ralph --diagnose reports the agent is missing but the CLI works in your
shell, the most common cause is that PATH in your non-interactive shell
differs from your interactive shell. Always test from the same shell type
you’ll launch ralph from.
Invocation — per-transport command builders¶
Each transport has a CommandBuilder in ralph/agents/invoke/_command_builders/
that assembles the argv passed to the agent subprocess. The argv shapes
differ by transport:
Claude Code (interactive, PTY)¶
The Claude command builder emits the autonomy flag the bundled policy
declares, plus the session/resume and MCP config injection. With
autonomy_mode = "dangerously-skip-permissions", the argv includes
--dangerously-skip-permissions. Claude’s MCP config injection routes the
Ralph Workflow MCP tools into the agent’s tool surface; see
Advanced MCP Configuration.
claude and claude-headless are both maintained invocation contracts. Do not
remove, deprecate, merge, alias, or silently redirect either one into the other
as part of unrelated agent work. A task about another agent is never a reason to
change either Claude contract.
Claude Code (headless, no PTY)¶
Same binary, no PTY. Use when the documented non-interactive Claude path fits the phase and you do not need live PTY transcript display.
Codex¶
The Codex builder uses OpenAI’s --approve flag for unattended approval
plus any resume/session flags the policy declares.
OpenCode¶
The OpenCode builder uses --approve for unattended approval plus
provider-specific flags forwarded through --provider.
Nanocoder¶
Local-only TUI. The builder launches Nanocoder without autonomy flags —
Nanocoder has no remote auth surface. Ralph Workflow keeps Nanocoder on its
PTY-backed Ink runtime because Nanocoder’s JSON/plain automation path has a
hidden long-run action limit, observed around 100 actions. Do not switch
Nanocoder to JSON/plain mode as the durable backend. The command builder passes
--no-plain before run to force the Ink runtime. The maintained path must
prove prompt submission, parser-visible model text and tool activity, artifact
completion, and process cleanup through the Nanocoder smoke test.
AGY (PTY)¶
The AGY builder runs agy inside a PTY with a bounded drain so buffered
stdout is captured end-to-end. The AGY parser classifies live output into
text: / thinking: / tool_use: events for the smoke report. With
autonomy_mode = "dangerously-bypass-approvals-and-sandbox", the argv
includes the corresponding AGY-side flag.
Pi¶
The Pi builder invokes pi --mode json <prompt> and parses the resulting
NDJSON stream per Pi’s documented AgentSessionEvent vocabulary at
https://pi.dev/docs/latest/json. Pi has no native MCP config file or CLI
flag, so Ralph Workflow materializes a per-run Pi extension and launches Pi
with --no-builtin-tools --extension <generated file> when the Ralph Workflow MCP
endpoint is available. The extension registers Ralph Workflow MCP tools through Pi’s
custom-tool API and proxies calls to the active HTTP MCP endpoint.
Pi is session-capable in JSON mode: a clean rc=0 exit without required
artifact or completion evidence is retried against the captured Pi session
rather than treated as terminal success.
Cursor¶
The Cursor builder invokes agent --print --output-format stream-json --trust --yolo --approve-mcps [--model <id>] <prompt> and parses the
resulting NDJSON stream per Cursor’s documented system / user /
assistant / thinking / tool_call / tool_result / result envelope.
--trust and --approve-mcps are the documented unattended-runner
overrides that skip the interactive workspace-trust and MCP-approval
prompts. --yolo is the documented autonomy flag for the headless
transport. Ralph Workflow wires MCP through the documented .cursor/mcp.json
(workspace-local) AND ~/.cursor/mcp.json (user-global) JSON files so
the agent picks up the endpoint regardless of the cwd it was launched
from. The runtime resolver restores the original bytes on exit so
operator-managed MCP servers are preserved across Ralph Workflow runs.
End-to-end verification paths¶
Each agent has a documented verification path that targets its own contract:
Claude Code (interactive):
ralph smoke-interactive-claudeNanocoder (interactive):
ralph smoke-interactive-nanocoder --agent '<exact nanocoder alias>'AGY (interactive):
ralph smoke-interactive-agy(mock-backed by default)Cursor (headless):
ralph smoke-interactive-cursor(live binary required)Codex, OpenCode, Pi: public-surface black-box pytest suite (
uv run pytest tests/agents/<agent>_blackbox.py -q)
These suites verify Ralph Workflow’s public registry / catalog / parser / command-builder surface for each agent, plus the committed wire-format fixture where applicable. They do not claim live MCP wiring for agents that have no documented CLI MCP path.
The canonical end-to-end AGY verification (mock-backed, always green) is:
cd ralph-workflow && \
RALPH_AGY_BINARY="$(pwd)/tests/_support/mock_agy.sh" \
uv run python -m ralph smoke-interactive-agy --agent 'agy/Gemini 3.5 Flash (Medium)'
Expected green parity table excerpt:
| Agent | Transport | File | Session | Parser events | Tool activity | Artifact | Breaks |
| agy/Gemini 3.5 Flash (Medium) | agy | yes | interactive-agy-smoke-Gemini-3.5-Flash-Medium | 1 | yes | yes | none |
Completion and observability¶
Completion is evaluated from durable evidence, not from a conversational
vibe. Ralph Workflow expects each agent invocation to produce either a phase
artifact that satisfies the phase’s declared contract, or an explicit
declare_complete MCP call. If a session exits incomplete (without
either signal), Ralph Workflow treats the work as incomplete rather than
calling it done — the session can be resumed, retried, or routed through the
next recovery path per policy.
Interactive transports (Claude Code in PTY, AGY in PTY) give Ralph Workflow better streaming observability into what the agent is doing during a live session. Headless transports are cheaper to spawn and simpler to automate, but the tradeoff is less step-by-step visibility while the run is in flight. Pick the transport that matches the operational visibility you need for the run.
Multimodal delivery is decided per session through
ResolvedCapabilityProfile, which acts as the pre-computed, session-owned
contract for how each modality is delivered to the active agent transport.
When something doesn’t work¶
If ralph --diagnose reports an agent problem, check:
The CLI is installed:
which <binary>returns a pathThe CLI works in your shell:
<binary> --versionsucceedsAuth is valid: try a one-shot prompt in your shell
PATH matches: launch
ralphfrom the same shell type you tested inThe right binary override is set:
RALPH_AGY_BINARYif you’re using a custom or mock AGY;RALPH_CURSOR_BINARYif you’re pointing Cursor at a wrapper or alternate live binary
For transport-specific issues, see Troubleshooting and the agent’s verification path above.