claude-code
v0.1.9Claude Code as an iii worker — claude::* functions run headless Claude Code turns, mirror raw messages onto claude::events, and stream AgentEvent frames onto agent::events.
exact versions are immutable; binary and bundle artifacts are digest-pinned.
skill doc
claude-code
The claude-code worker exposes the Claude Code API as iii functions. One
claude::run call executes one headless Claude Code turn — the same agent
the user runs in their terminal, with the same login, filesystem, and
permission model — in a chosen working directory, and returns the final
result, token usage, and cost. The worker is a pure pass-through: named
payload fields cover the common path, the options field forwards any Agent
SDK option verbatim, and every message Claude Code emits mirrors untouched
onto the claude::events stream. A translated AgentEvent view lands on
agent::events, which is what the iii console and the acp worker render.
Requires the claude CLI on the host with an existing login or
ANTHROPIC_API_KEY in the worker environment. When a turn needs a
capability beyond Claude Code itself, add another iii worker to the bus
instead of bolting anything onto this one.
When to Use
- Delegate a whole coding task ("add an endpoint and run the tests") in one
call, instead of orchestrating individual
coder::*/shell::*calls yourself:claude::runwithpromptandcwd. - Continue a conversation across calls: pass the same
session_idagain and the worker resumes the underlying Claude Code session with full context. - Run long jobs without holding the call open:
claude::startreturns{session_id, started}immediately; followclaude::events(group_id = session_id) for raw progress oragent::eventsfor the rendered view; interrupt withclaude::stop. - Act on the whole backend: turns carry the iii runtime context by default,
so the agent discovers and calls any registered function through the iii
CLI (engine::functions::list,
iii trigger) with the matching Bash allow rule pre-set; disable per turn with--help iii_context: false. - Plan before touching anything:
permission_mode: "plan"runs Claude Code's native plan mode (read-only, returns the plan as the result); then send "implement the plan" on the samesession_idwithpermission_mode: "acceptEdits". - Reach past the named payload fields: anything the Agent SDK accepts goes
through
optionsunchanged —{"options": {"forkSession": true, "includePartialMessages": true}}— andincludePartialMessagesputs token-levelstream_eventframes onclaude::events.
Boundaries
- Spawns the host
claudeCLI per turn — needs Claude Code installed and authenticated; not available inside a bare container without it. - Function execution happens inside Claude Code's own permission model
(
permission_mode,allowed_tools,disallowed_tools), not the engine's; setapproval_gate: trueto route every call throughpolicy::check_permissions(fail-closed, needs the harness worker). - One turn per session at a time: check
claude::status(live: true) before sending anotherclaude::runfor the samesession_id; parallel runs against one session race on the underlying Claude Code resume. agent::eventscarries whole-message frames (message_complete,function_execution_start/end,turn_end,agent_end); token deltas exist only onclaude::eventsand only whenincludePartialMessagesis set.
Functions
claude::run— run one Claude Code turn and wait; acceptsprompt(or amessagesarray whose last user entry becomes the prompt), plusmodel,cwd,permission_mode,allowed_tools,disallowed_tools,max_turns,system_prompt,append_system_prompt, and rawoptions; returns{session_id, claude_session_id, result, stop_reason, usage, total_cost_usd}.claude::start— same payload, returns{session_id, started}immediately; progress arrives on the streams.claude::stop— interrupt the live run for a session.claude::status— point-in-time session view: live flag, status, turns, usage, cost.claude::sessions::list— every session this worker has run.run::start_and_wait— alias forclaude::rununder the entrypoint the console and acp worker drive, so both run Claude Code with no changes.