Agent Setup

Cloche supports any agent that can read a prompt from stdin and print CLOCHE_RESULT:<name> to stdout.

Built-in Agents

Cloche has a concept of known agents — agent commands it understands natively. Known agents receive default arguments automatically, and some arguments are required and will always be injected regardless of agent_args. Unknown agents (e.g. codex) receive no default arguments; the prompt is passed on stdin and the command is invoked as-is.

Known agents

Command Default args (overridable) Required args (always injected)
claude -p --dangerously-skip-permissions --model sonnet --output-format stream-json --verbose

How agent_args interacts with defaults

When agent_args is not set, the agent receives its full default argument list.

When agent_args is set, it replaces the default args entirely — but required args are always appended if not already present. You cannot remove a required arg.

For claude, this means:

  • -p, --dangerously-skip-permissions, and --model sonnet are overridable: they are present by default but absent if you supply agent_args without them.
  • --output-format stream-json and --verbose are required: Cloche injects them even if your agent_args omits them. --output-format stream-json is necessary because the prompt adapter parses Claude’s streaming JSON output to extract results and token usage. --verbose is required for that stream to include the result event.

Overriding arguments

Use agent_args to replace the default args. Required args are always present, so you do not need to include them.

step implement {
  prompt     = file(".cloche/prompts/implement.md")
  agent_args = "-p --dangerously-skip-permissions --model claude-opus-4-5"
  results    = [success, fail]
}

Note that -p and --dangerously-skip-permissions must be included explicitly when using agent_args, since they are overridable defaults and will not be injected automatically.

Named agent declarations

Rather than repeating agent_args on every step, declare named agents at the workflow level and reference them from steps:

workflow "develop" {
  agent haiku_claude {
    command = "claude"
    args    = "-p --dangerously-skip-permissions --model claude-haiku-4-5"
  }

  agent opus_claude {
    command = "claude"
    args    = "-p --dangerously-skip-permissions --model claude-opus-4-6"
  }

  step commit {
    prompt  = file(".cloche/prompts/commit.md")
    agent   = haiku_claude
    results = [success, fail]
  }

  step implement {
    prompt  = file(".cloche/prompts/implement.md")
    agent   = opus_claude
    results = [success, fail]
  }

  implement:success -> commit
  implement:fail    -> abort
  commit:success    -> done
  commit:fail       -> abort
}

Required args (--output-format stream-json and --verbose) are still injected automatically — you do not need to include them in args. Step-level agent_command and agent_args override the agent declaration.

Unknown agents

Any agent_command value not in the known agents table is treated as unknown. Unknown agents receive no default arguments, the prompt on stdin, and agent_args is passed through verbatim.

Fallback Chains

Specify multiple agent commands as a comma-separated list. Cloche tries each in order until one succeeds:

agent_command = "claude,gemini,codex"

Fallback behavior:

Outcome Action
Command not found / failed to start Try next command in the list.
Exit non-zero without CLOCHE_RESULT marker Try next command in the list.
Exit non-zero with CLOCHE_RESULT marker Use that result — no fallback.
Exit 0 Use result — no fallback.
All commands fail to start Step returns an error.
Last command crashes without marker Step returns fail.

Claude Code

Prerequisites

  • Claude Code installed on the host machine:
    npm install -g @anthropic-ai/claude-code
    
  • An active Claude Code session on the host. Run claude once interactively to authenticate before starting the daemon.

How Authentication Works

Cloche automatically copies ~/.claude/ and ~/.claude.json from the host into each container at /home/agent/.claude and /home/agent/.claude.json. The files are copied — not bind-mounted — so each container gets its own isolated credential copy. Cloche runs chown -R agent:agent on the copied auth files at container startup so the unprivileged agent user can read them.

Dockerfile

FROM cloche-base:latest
USER root

# Install Node.js (required for Claude Code)
RUN apt-get update \
    && apt-get install -y --no-install-recommends nodejs npm \
    && rm -rf /var/lib/apt/lists/*

# Install Claude Code
RUN npm install -g @anthropic-ai/claude-code

# Add your project's build dependencies here
# RUN apt-get install -y ...

USER agent

Workflow Config

Claude is the default agent — no explicit configuration is required. The full default invocation is:

claude -p --output-format stream-json --verbose --dangerously-skip-permissions --model sonnet

Override with agent_args in your workflow or step config if needed. See overriding arguments above for how defaults and required args interact.

API Key Alternative

Set ANTHROPIC_API_KEY in the daemon’s environment and it will be passed into containers automatically — no session files required.

Troubleshooting

  • Claude Code not found in container — Ensure the Dockerfile installs @anthropic-ai/claude-code via npm.
  • Authentication errors — Run claude on the host to ensure the session is active before starting the daemon.
  • Permission errors on ~/.claude — Check that the Dockerfile does not override the container entrypoint, which handles credential injection and runs chown -R agent:agent on the auth files.

Codex

Prerequisites

An OpenAI API key with Codex access.

How Authentication Works

Codex authenticates via API key. Pass it to containers using CLOCHE_EXTRA_ENV:

export CLOCHE_EXTRA_ENV="OPENAI_API_KEY=sk-..."
cloched &

Dockerfile

FROM cloche-base:latest
USER root

RUN apt-get update \
    && apt-get install -y --no-install-recommends nodejs npm \
    && rm -rf /var/lib/apt/lists/*

RUN npm install -g @openai/codex

USER agent

Workflow Config

Set agent_command = "codex" in your workflow or config.toml. Codex is not a known agent, so it receives the prompt on stdin with no default arguments. Add agent_args if your version requires explicit flags:

agent_command = "codex"
agent_args = "--full-auto"

Token Usage Capture

Codex does not emit token usage in its standard output. Use usage_command to capture it separately. The command must output JSON with input_tokens and output_tokens fields:

{"input_tokens": 1234, "output_tokens": 567}

Configure via config.toml (applies to all Codex steps):

[agents.codex]
usage_command = "codex usage --last --json"

Or per-step in the workflow file:

step implement {
  ...
  usage_command = "codex usage --last --json"
}

Step-level usage_command takes precedence over the [agents.codex] config.toml value.

Troubleshooting

  • Codex not found — Ensure the Dockerfile installs @openai/codex via npm.
  • Authentication errors — Verify CLOCHE_EXTRA_ENV includes a valid OPENAI_API_KEY and that the daemon was started after the variable was set.
  • No output — Ensure the installed Codex CLI version supports reading prompts from stdin.