Skip to main content

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.
Each invocation creates a new chat by default (origin=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 identify means 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-config where most entries fail validation.
  • unrecognized_shape as 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.
The same rule holds on every surface: the chat card, the 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

When stdin is a pipe and a positional prompt is also given, the positional becomes the instruction and stdin is appended as context.

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

Ctrl-C cancels the current turn (sends a cancel message over WS) without killing the REPL. A second Ctrl-C exits.

Cancel-friendly streaming

Save the answer to disk

Saved bytes are sanitised — any ANSI / OSC sequences a tool result emitted are stripped before they hit the file, so cat adr.md is safe.

List recent runs

Use --format json for piping (crewship run list --format json | jq '.[] | select(.status=="FAILED")').

Fleet-ops insights

run insights aggregates every run in the workspace (not just routine runs) over a window into an ops snapshot: success/fail split, duration percentiles (p50/p95), and breakdowns by trigger, crew, and model. Backed by GET /api/v1/runs/insights?window=<w>. 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: 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 before done. 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.
  • save commit: ...--save tempfile couldn’t be atomically renamed (disk full, permission denied). Reported separately from a stream error so neither one masks the other.

See also