Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

CLI Adapters

Overview

Crewship runs each agent as a subprocess of a vendor coding CLI inside the crew container. The agent record’s cli_adapter column picks which binary and which command line; the orchestrator’s BuildCLICommand (internal/orchestrator/exec.go) is the one place that knows the per-vendor flag conventions. Everything else in the orchestrator — prompt assembly, memory injection, journal writing, tool routing — is adapter-agnostic; the adapter layer is only responsible for translating Crewship’s uniform internal representation into whatever flags / files / stdio shape a given vendor CLI expects. The adapter pattern exists because no two coding-CLI vendors agree on anything. Claude Code reads its system prompt from a --system-prompt flag; every other adapter has no equivalent flag, so Crewship prepends the preamble inline with [SYSTEM]/[USER] delimiters on turn 1 and lets the CLI’s own file-discovery path (AGENTS.md, CLAUDE.md, GEMINI.md, .cursor/rules/, .factory/AGENTS.md) carry the same content into turn 2+. Factory Droid additionally expresses autonomy as a tier (--auto low|medium) instead of a tool list. Rather than picking a winner, Crewship supports all of them — six adapters as of 2026-04 — and lets the operator choose per agent. The selection lives on the agent row, so a backend crew can run Claude Code while a data crew uses Gemini, with no orchestrator-wide config change. Adding another vendor is intentionally small: one new case in BuildCLICommand for the command-line translation, plus a normalisation rule in agents_create.go for the default tool profile and any vendor-specific defaults. The adapter_hint field on the CLI pairing request is telemetry only — the backend never routes on it, and the frontend list of adapters lives in lib/cli-adapters.ts rather than in Go, so a new adapter is a TypeScript file plus a Go switch arm, not a schema migration.

Supported adapters

AdapterBinaryTurn-1 system promptTurn-2+ persistenceOutputNotes
CLAUDE_CODEclaude --print --output-format stream-json --include-partial-messages --dangerously-skip-permissions --verbose--system-prompt flagAGENTS.md + canonical memory file set written to CWDstream-JSON on stdoutSupports --model, --tools, --mcp-config <path>. Default.
CODEX_CLIcodex exec --json --sandbox <mode>[SYSTEM]/[USER] prepend in the prompt body (Codex has no system-prompt flag)AGENTS.md written into CWD before execNDJSON--sandbox enabled when tool_profile=CODING.
GEMINI_CLIgemini -p <message> --output-format stream-json[SYSTEM]/[USER] prepend (no documented --system-instruction flag in headless mode)GEMINI.md + canonical memory file setNDJSONUses -p for the user message.
OPENCODEopencode run <message>[SYSTEM]/[USER] prependAGENTS.md written into CWD before exectextsst.dev’s BYOK CLI; works with any provider.
CURSOR_CLIcursor-agent -p --output-format stream-json[SYSTEM]/[USER] prepend (no --system-prompt flag in headless mode).cursor/rules/, AGENTS.md, CLAUDE.md written into CWDstream-JSON on stdout (same shape as Claude Code)Added 2026-04. -m <model> for model override.
FACTORY_DROIDdroid exec --auto {low|medium}[SYSTEM]/[USER] prependAGENTS.md + .factory/AGENTS.md written into CWDtextAdded 2026-04. Tiered autonomy — see below.
The default fallback when cli_adapter is empty or unknown is claude --print <message> — minimal flags, no streaming, lowest-risk degradation.

Cursor (CURSOR_CLI)

cursor-agent -p is Cursor’s headless mode. -p (print) prevents the interactive TUI from spawning; --output-format stream-json aligns the JSONL stream with the format the chat-bridge already parses for Claude Code, so the same reader handles both. Cursor reads its system instructions from files in the working directory: .cursor/rules/, AGENTS.md, and CLAUDE.md. SetupSystemPrompt writes those before exec, so there is no --system-prompt flag on the command line. The very first turn, however, has no file-discovery yet, so the orchestrator also prepends the preamble inline with [SYSTEM]/[USER] delimiters — turn-2+ then falls back to file-discovery so persona edits land without burning a re-prepend. --mode=plan and --mode=ask are valid Cursor flags (added 2026-01-16) but are not exposed today; the default agent mode is what BuildCLICommand emits. If a tool profile needs read-only browsing, extend the CURSOR_CLI case to map tool_profile=CONSULTATIVE to --mode=ask.

Factory Droid (FACTORY_DROID)

droid exec is Factory’s headless single-shot mode. The --auto flag picks the autonomy tier:
--auto valueBehaviourWhen
lowRead-only — agent inspects but does not mutate files.tool_profile is MINIMAL or CONSULTATIVE.
mediumCan edit files within scope.Default — tool_profile is CODING or unset.
highFully autonomous. Not exposed by Crewship.Factory’s docs warn it can perform destructive operations without further confirmation.
The default is medium because the API normalises an empty ToolProfile to CODING (see internal/api/agents_create.go), and CODING agents are expected to write code. The previous “default = low” choice was theoretical; in production almost every agent would be told to write code anyway. The current inversion (default-medium, explicit-low) is honest about production behaviour. If a customer genuinely needs --auto high, add a new tool_profile value (e.g. AUTONOMOUS) and gate it behind a Harbor Master approval. Do not flip the default.

Adapters that are deliberately NOT supported

BuildCLICommand skips several CLIs that would superficially fit. The reasoning:
CLIWhy skipped
AiderPair-programming UX — designed around interactive turns, not single-shot exec. Wrapping it as headless drops most of what makes it good.
GitHub Copilot CLIMicrosoft removed the --stdio flag without deprecation on 2026-01-14, breaking every wrapper. Waiting for the surface to stabilise.
Cody CLIIDE-tied — Sourcegraph deprecates the standalone CLI in favour of the editor extension.
Replit AgentBrowser-only; no headless binary.
Adding any of these is a one-line change once the upstream surface is stable. Track the conversation in the project’s GitHub issues before opening a PR.

How the adapter signals the sidecar

The orchestrator stamps two environment variables on the container env (visible to every process running inside that crew container — both the agent CLI and the sidecar process). The sidecar reads them once at startup and tags every POST /api/v1/internal/cost/record it sends to the server:
  • CREWSHIP_BILLING_MODEmetered for API-key credentials, flat_rate for subscription credentials (Claude Max, ChatGPT Plus, Cursor, Copilot).
  • CREWSHIP_SUBSCRIPTION_PLAN — display label, currently "Anthropic Max" for the OAuth Claude Code path. Only set when CREWSHIP_BILLING_MODE=flat_rate.
The agent CLI process technically inherits the same env (containers don’t isolate env vars between sibling exec sessions), but the agent has no reason to read them — the variables are interpreted by the sidecar, which is the one code path that knows what to do with billing mode. See Environment Variables for the operator-facing reference and Paymaster billing modes for the full rationale.

Picking an adapter for an agent

Set cli_adapter on the agent (UI: agent canvas → “Runtime” panel; CLI: crewship agent update <slug> --cli-adapter CURSOR_CLI; API: PUT /api/v1/agents/{id} with cli_adapter in the body). The string must match one of the constants above exactly. Pick by what the credential supports:
  • Anthropic API key or Claude Max OAuthCLAUDE_CODE.
  • OpenAI API key or ChatGPT PlusCODEX_CLI.
  • Google AI key or Pro/UltraGEMINI_CLI.
  • Cursor subscriptionCURSOR_CLI.
  • Factory accountFACTORY_DROID.
  • Anything else (BYOK)OPENCODE.
Switching adapters is hot — the next exec uses the new value. The container does not need to be rebuilt unless the new adapter’s binary is missing from the image (verify with crewship runtimes info <runtime>).