Skip to content

Vendor adapters

Each adapter records the CLI version it was verified against, the official sources, and whether it was checked against the real --help (help) or against the official docs and source only (docs). The record is on adapter.verification. Every check was made on 2026-10-17.

“Docs only” means the CLI ships through a curl installer or needs a Python version this check could not run. Those adapters still go through the capability probe, which reads the installed binary’s --help before the first run, so a flag that does not exist fails the run up front.

FactoryCommandVerified againstPrompt viaStreamMCPHome variableAPI key variable
cli.claudeCodeclaude2.1.302 · helpargv, stdin--output-format stream-json--mcp-config <file>CLAUDE_CONFIG_DIRANTHROPIC_API_KEY
cli.codexcodex0.163.0 · helpargv, stdin (-)exec --jsonconfig.toml / -c + envCODEX_HOMECODEX_API_KEY
cli.antigravityagy1.4.0 · docsargv, stdin JSON--output-format stream-json~/.gemini/config/mcp_config.jsonHOME (no own variable)GEMINI_API_KEY
cli.qwenCodeqwen0.25.2 · helpargv, stdin--output-format stream-json--mcp-config <file>QWEN_HOMEOPENAI_API_KEY
cli.kimikimi2.2.0 · helpargv (-p)--output-format stream-json$KIMI_CODE_HOME/mcp.jsonKIMI_CODE_HOMEKIMI_MODEL_API_KEY
cli.cursorcursor-agent2026.10.16-e3cb207 · docsargv, stdin--output-format stream-json~/.cursor/mcp.jsonHOME, CURSOR_CONFIG_DIRCURSOR_API_KEY
cli.copilotcopilot1.0.98 · helpargv (-p), stdin--output-format json--additional-mcp-config @<file>COPILOT_HOMECOPILOT_GITHUB_TOKEN
cli.grokgrok1.0.62 · docsargv, --prompt-file--output-format streaming-json$GROK_HOME/config.tomlGROK_HOMEXAI_API_KEY
cli.opencodeopencode1.19.3 · helpargv, stdinrun --format jsonOPENCODE_CONFIG=<file>XDG_*provider’s own
cli.ampamp0.0.1792254886-g14d018 · helpargv, stdin-x --stream-json--mcp-config <file>XDG_*AMP_API_KEY
cli.droiddroid0.244.0 · helpargv, --fileexec --output-format stream-json<home>/.factory/mcp.jsonFACTORY_HOME_OVERRIDEFACTORY_API_KEY
cli.mistralVibevibe2.26.1 · docsargv, --prompt-file, stdin--output streaming + export.json$VIBE_HOME/config.tomlVIBE_HOMEMISTRAL_API_KEY
cli.aideraider0.86.2 · docsargv, --message-fileplain text + analytics lognot supportedHOMEprovider’s own
cli.reasonixreasonix2.43.0 · helpargv, stdinrun --output-format stream-json$REASONIX_HOME/config.tomlREASONIX_HOMEDEEPSEEK_API_KEY (written to .env)

“Prompt via” lists the transports in order of preference. The runner moves the prompt to the next transport when argv cannot carry it, for example a long prompt, or a prompt cmd.exe cannot quote on Windows. A prompt that starts with - gets one leading space so no CLI parses it as a flag.

Factory"standard" (default)"bypass"
cli.claudeCodePrint mode auto-denies anything that would prompt.--dangerously-skip-permissions (refused as root outside a sandbox)
cli.codexApproval policy “never” with the read-only sandbox; allow edits with args: ["-c", "sandbox_mode=workspace-write"].--dangerously-bypass-approvals-and-sandbox
cli.antigravitySoft-denies tools that need approval; the run continues and exits 0.--dangerously-skip-permissions
cli.qwenCodeAuto-denies tools that need confirmation (permission_denials).--yolo
cli.kimiRefused: print mode runs every tool call without asking.Required, to accept that behaviour
cli.cursorAllowlist mode: unlisted actions are rejected, changes only proposed.--force
cli.copilotUnapproved tool requests are auto-denied.--allow-all
cli.grokEvery approval request is answered “cancelled”.--always-approve
cli.opencodeOpenCode’s own rules (permissive by default); asks are auto-rejected.--auto
cli.ampAmp’s own rules (tools run without approval by default); approvals are rejected.--dangerously-allow-all (accepted, not in --help)
cli.droidRead-only autonomy; raise with args: ["--auto", "medium"].--skip-permissions-unsafe
cli.mistralVibeEvery approval is auto-denied (the default agent auto-approves file edits).--auto-approve
cli.aiderEdits apply without approval; suggested shell commands never run headless.Same as standard (Aider has no other mode)
cli.reasonix“Ask” mode refuses writes headless (exit 4 in an untrusted folder).--yolo
Factorymodeleffort mapping
cli.claudeCode--model--effort low · medium · high · xhigh · max
cli.codex--model-c model_reasoning_effort= low … max
cli.antigravity--model--effort low · medium · high
cli.qwenCode--modelrefused (a settings value, not a flag)
cli.kimi--model (alias from config.toml)refused (a config value)
cli.cursor--modelrefused (part of the model id)
cli.copilot--model--reasoning-effort none … max
cli.grok--model--reasoning-effort none … max
cli.opencode--model provider/model--variant (provider-specific; passed as-is)
cli.amprefused (the mode picks the model)--mode low · medium · high · ultra (for max)
cli.droid--model--reasoning-effort (per model, passed as-is)
cli.mistralVibeVIBE_ACTIVE_MODEL envrefused (a per-model config value)
cli.aider--model (always pass one)--reasoning-effort low · medium · high
cli.reasonix--model--effort disabled · low · high · max

Levels are mapped with the framework rule: an exact level wins, otherwise the nearest higher level the vendor has, and a level above the vendor’s highest is clamped to it. An adapter without an effort control refuses effort with CliError unsupported-option, rather than ignoring it.

  • Claude Code — system/init carries the session id; stream_event text deltas; assistant/user messages carry tool_use/tool_result; the final result has usage (Anthropic semantics) and total_cost_usd. --verbose is required with stream-json in print mode. Sources: headless, CLI reference, MCP.
  • Codex — thread.started (id), item.started/item.completed items (agent_message, command_execution, file_change, mcp_tool_call, …), turn.completed with the thread’s cumulative usage, turn.failed/error. No deltas, no cost. Resume is codex exec resume <id>. --skip-git-repo-check is always passed, so a run outside a git repository works. With a shared home, MCP goes through -c mcp_servers.<name>.… overrides that name environment variables (env_vars, env_http_headers), so values stay out of argv. Sources: non-interactive mode, config reference.
  • Antigravity — {"event":…} lines: init (conversation_id), step_update (text_delta, tool steps with call and result together), result (cumulative usage, status). Long prompts use the documented stdin protocol. An API key needs "modelProvider": "gemini", which the adapter writes into a private home. Sources: headless, MCP.
  • Qwen Code — Claude Code-compatible stream; input_tokens already include cached tokens; no cost. Sources: headless.
  • Kimi Code — the successor of the archived Python kimi-cli. It prints OpenAI-chat-shaped messages without deltas. The session id comes only in the final session.resume_hint, and no token usage is printed. Shell KIMI_API_KEY is not read; for key auth set KIMI_MODEL_NAME (and the provider type and base URL) in env, and apiKey becomes KIMI_MODEL_API_KEY. Sources: docs.
  • Cursor — system/init, assistant messages, tool_call started/completed (the tool is the single key, e.g. readToolCall), and a final result with usage (input net of cache). Errors are plain stderr with a non-zero exit. --trust is passed because print mode exits in a directory that was never trusted. Sources: headless, output format.
  • Copilot — {type,data} session events (assistant.message_delta, tool.execution_start/_complete, session.error) and a final result with the session id. Tokens are not in the stream, so the adapter passes --usage-output-file and reads it afterwards. Billing is in premium requests, so there is no USD cost. Sources: run programmatically.
  • Grok Build — text deltas, tool_call/tool_call_update, usage per response, and a final end with the session id, totals and total_cost_usd. Sources: headless scripting, repo guide.
  • OpenCode — text blocks (no deltas), tool_use (call and result together), step_finish per step with cost and tokens, and error. --dir is passed because OpenCode prefers a stale PWD. Sources: CLI, MCP servers.
  • Amp — Claude Code-compatible stream, no deltas, no cost. Threads are left unarchived so they can be continued. Sources: streaming JSON.
  • Factory Droid — system/init, whole message records, tool_call/tool_result, a final completion (finalText, usage), and error. The home is relocated with FACTORY_HOME_OVERRIDE. That variable is found in the shipped code, not in the docs, and was confirmed with droid mcp list. Sources: droid exec.
  • Mistral Vibe — completed history entries only (message, effect = tool call + result). Usage, cost, outcome and session id come from --output-dir’s export.json, which the parser reads when the stream ends. Sources: repo.
  • Aider — no machine-readable output. The parser reads the plain text: the banner, the reply, Tokens: … sent, … received. Cost: …, Applied edit to <path> (an edit tool call) and Commit …. Exact usage comes from the local --analytics-log. Aider exits 0 when the model call fails, so litellm.*Error lines are reported as fatal. There are no session ids, so resume is refused. Sources: scripting, options.
  • Reasonix — kind-tagged lines (text deltas, message, tool_dispatch/tool_result, usage, turn_done) and a final {"type":"result"}. Provider keys are read only from $REASONIX_HOME/.env, so apiKey is written there (mode 0600) in a private home. Sources: CLI.

The recorded stream samples behind the adapter tests live in the package’s fixtures/ folder, one folder per vendor.