Skip to main content

crewship inbox

The inbox is the unified “things needing a human” feed — waitpoints awaiting approval, escalations from agents, failed runs, and direct messages. The CLI is the scriptable mirror of the /inbox web page; cron + jq + inbox list is the canonical “ping Slack when unread piles up” recipe. Defined in cmd/crewship/cmd_inbox.go.
Auth: every subcommand requires crewship login plus an active workspace. The inbox is backed by the inbox_items table (migration v85), written-through by waitpoint creation, escalation creation, and run-failure handlers.

Subcommands

Flags

inbox list

inbox resolve

inbox bulk read

inbox bulk resolve

--ids and --all-unread are mutually exclusive on both bulk subcommands.

Examples

Triage

Output is coloured by state (yellow=unread, cyan=read, green=resolved) and kind (yellow=waitpoint, red=escalation/failed_run, cyan=message), so a 50-row feed scans at a glance.

Polling the badge

inbox count hits GET /api/v1/inbox/count (the bell-badge endpoint) — much cheaper than inbox list when you only need the integer.

Mark an item

inbox get <id> (backed by GET /api/v1/inbox/{id}) is the detail counterpart of list — it returns the markdown body and the structured payload that the list view omits. inbox archive <id> maps to a resolved PATCH with resolved_action=archived; only non-decision kinds (messages, failed-run notices, advisories) archive — the server 409s an archive on a source-managed waitpoint/escalation. On a CREDENTIAL escalation, inbox get also prints whether resolving it needs a second approver, and which of the two controls demands it:
The same answer rides the JSON as second_approver_required / second_approver_by_workspace / second_approver_by_tier / security_level_label, the fields the crew escalations list carries. It is computed when you read the row, not when the escalation was raised: the workspace toggle and the credential’s tier both change afterwards. Absent means the server said nothing, not that a single approver will do — see Keeper → The switch is a floor, not a master switch. resolve is the inbox-side only — it does not call the source endpoint. To actually approve a waitpoint through to the executor, use crewship approvals approve <id>. To resolve an escalation lifecycle, use crewship escalation resolve <id>. The inbox row tracks the decision; the source endpoint enacts it.

Bulk operations

Bulk operations submit the whole id set to the server-side POST /api/v1/inbox/bulk endpoint (one request flips many rows), chunked at 500 ids per call — the endpoint’s id cap. On a resolve the server skips decision items (source-managed waitpoints/escalations and blocking rows) rather than closing them. The final line summarises the aggregated counts:
A stale or already-resolved id lands in not found / skipped; it does not fail the command (the process exits 0). Only a transport error or a non-2xx bulk response exits non-zero. If --all-unread returns exactly the page cap (500), the CLI refuses to proceed and changes nothing, telling you to re-run after the batch or narrow with --ids, so the tail isn’t lost.

Sources

The inbox is human-attention-scoped: it holds the things somebody has to look at, not every event that happened. Where those items are delivered outward — email, webhook, chat, push — is crewship notifychannel.

Common errors

  • either --ids <csv> or --all-unread is required — bulk command needs one of them.
  • --ids and --all-unread are mutually exclusive — pick one.
  • --ids parsed to empty list (got "") — comma-string was blank after trimming.
  • hit the 500 unread-item page cap; no items were changed … pass --ids to target a specific subset--all-unread returned a full page and can’t tell whether more remain, so it changes nothing. Re-run after clearing this batch, or target explicit --ids.

See also