crewship run
run invokes a named agent and streams its response over WebSocket. Unlike ask, the agent slug is positional (no default-agent fallback) and the command supports interactive sessions, follow-ups on an existing chat, and shell-friendly streaming. Defined in cmd/crewship/cmd_run.go.
CLI, so the web UI sidebar tags it). Pass --chat <chat-id> to continue an existing thread. Auth: crewship login plus workspace context. Both checks are skipped in --dry-run / --estimate offline modes.
Subcommands
Session provenance
run get answers the questions a run record could not answer before: which CLI binary served this run, on which credential, and did everything it was configured with actually load. The values are ground truth from the CLI’s own session-init event, not from what Crewship asked for.
Both lists are deduplicated, bounded, and honest about what they could not read:
- A shortfall line.
… and 2 more the CLI reported in a shape this record could not identifymeans the CLI named more than the record can show. The alarm is never dropped for want of a readable name — a partial list that reads as complete is worse than one that admits it is partial. (list capped)means the run hit the per-list bound. Only a run in real trouble reaches it — an agent retrying a denied tool in a loop, or an--mcp-configwhere most entries fail validation.unrecognized_shapeas a name means the CLI reported the field in a shape this build does not enumerate. The report is still surfaced, because whether a session was degraded is decided by the CLI having reported it, never by our being able to parse it.
run.session_init journal entry and this view all treat presence as the signal.
Fields are omitted entirely when unknown (older runs, and non-Claude adapters, which report none of this) — absence means “never reported”, not “empty”.
The same provenance is recorded twice more: as a run.session_init journal entry at session start (crewship journal --type run.session_init, severity error when a server was skipped), and on the chat’s “Session started” card while the run is live. The journal entry and the run record are the durable copies — the chat card is live-stream only.
Flags
Stdin is read in exactly two cases. With no prompt argument and no
--prompt, piped stdin is read to EOF and becomes the prompt (echo hi | crewship run mia). With a prompt given, stdin is appended as context only when you pass --stdin (git diff | crewship run mia --stdin "review"). Otherwise stdin is never touched, so a harness, CI step or cron job whose stdin is a pipe nobody closes cannot hang the command; when stdin is a pipe or a file the CLI prints a one-line [stdin not read …] hint on stderr.
Examples
Run an agent
Read the prompt from a file
Continue an existing chat
--chat skips the POST /api/v1/agents/{id}/chats step and sends the prompt straight to the existing session over agent:{agentId} WS.
Stdin as context
Interactive REPL
cancel message over WS) without killing the REPL. A second Ctrl-C exits.
Cancel-friendly streaming
Save the answer to disk
cat adr.md is safe.
List recent runs
KIND says which engine produced the row: agent for an ad-hoc agent/chat run,
pipeline for a routine run (#2284). A routine run’s TRIGGER cell is empty —
the pipeline engine does not populate it — so the column is how a script tells
the two apart without guessing. run get shows the same value as its Kind:
row.
Use --format json for piping (crewship run list --format json | jq '.[] | select(.status=="FAILED")').
Fleet-ops insights
run insights aggregates the workspace’s ad-hoc agent runs — chat, CLI,
webhook and cron invocations of an agent — over a window into an ops snapshot:
success/fail split, duration percentiles (p50/p95), and breakdowns by trigger,
crew, and model. Routine runs are not counted: run list reads both engines
(#2284), but the insights aggregate and the stats tiles were deliberately left
ad-hoc-only, so a workspace that only runs routines reports No runs in this window here. Backed by GET /api/v1/runs/insights?window=<w>.
The scope is applied before the aggregate is computed, so totals,
percentiles and every breakdown describe that agent or crew alone — not a
workspace-wide snapshot with one section filtered.
Honours the global
--format json / --format yaml / --format ndjson for
scripting; the default is a human-readable table.
Streaming protocol
run subscribes to session:{chatId} and posts via agent:{agentId}. Event types it renders:
An agent runs one message at a time. A send that arrives while the agent
already has a live run is bounced with
agent_busy and no done follows it —
that frame ends the exchange. run reports it and exits non-zero rather than
waiting, so retry once the live run finishes.
When the crew’s environment image has to be built first — a new crew, or a
cache image that was removed — the send gets crew_provisioning followed by a
done. That done only closes the deferral: the server replays the message
on the same session once the build finishes, and run keeps waiting for that
run’s own answer and done. A crew_provisioning with status failed means
the build never started; run exits non-zero instead of waiting.
Chat sends bounce; assignment dispatches do not. A dispatch that loses the same
per-agent lock — an /assign or an @mention of a busy agent — is queued
behind the live run with queued_reason: agent_busy and drained by the
completion pump instead. Prefer that route when you want work to wait its turn
rather than be rejected.
A dropped WebSocket connection mid-run exits non-zero so wrapping scripts (crewship run x "y" || alert) catch it.
Common errors
prompt is required (provide as argument, --prompt flag, or use --interactive)— every path requires content unless you’re starting a REPL.ws read: ...— the WebSocket dropped beforedone. Most often a server restart.agent error: <message>— the model or a tool returned a hard error event. The exit code is non-zero and the message is sanitised before display.agent busy: <message>— the agent already had a live run, so this message was rejected and never reached it. Nothing ran and nothing was persisted; send it again once the agent is free.environment build failed to start: <message>— the crew needed a new environment image and the build could not be queued. Nothing ran; fix the cause shown and send again.save commit: ...—--savetempfile couldn’t be atomically renamed (disk full, permission denied). Reported separately from a stream error so neither one masks the other.
See also
crewship ask— one-shot variant with default-agent resolution.crewship chat— re-read the chat after the run.crewship agent— manage agents, includingstopandlogs.- Runs API —
GET /api/v1/runs.