Skip to main content
The repository ships a first-party Claude Code plugin at claude-plugin/. Installing it wires four things into every Claude Code session:
  1. The smithers MCP server (bunx smithers-orchestrator --mcp): list_workflows, run_workflow, watch_run, resolve_approval, ask_human, and the rest of the semantic tool surface.
  2. The smithers skill: teaches Claude to run durable, multi-step, or background work through Smithers instead of hand-rolled subagent trees, and to consult https://smithers.sh/llms-full.txt before writing any workflow code.
  3. The /workflows mirror: a generic Workflow-tool script, workflows/smithers-run.mjs, that launches or attaches to a Smithers run and mirrors it live into Claude Code’s /workflows progress tree. Works for every workflow with zero per-workflow setup.
  4. A background monitor (experimental Claude Code component): smithers claude monitor streams approval requests, human-input requests, failures, and stalled-heartbeat warnings into the session as notifications, so Claude reacts even when no mirror is running. It follows only the runs this session subscribed to: smithers claude tick (the mirror) and Claude-launched runs (detached up / workflow run, MCP run_workflow) subscribe automatically, and smithers claude subscribe RUN_ID is the explicit path. The workspace store is shared by every session, so without this scoping each session would be woken for every other session’s runs and for pre-existing runs at startup; --all-runs restores the unscoped behavior. Finished and cancelled runs are not broadcast by default either (a followed run already reports completion through its /workflows mirror); pass --transitions all to stream them anyway.

The /workflows mirror

Claude Code’s /workflows tree can only be populated from inside a session by a Workflow-tool script. The plugin therefore ships one generic script; the real work always stays in the Smithers engine, and the mirror is a live view. Claude launches it like this:
In launch mode the script starts the detached run itself and logs the runId. Passing args: { runId: "run-123" } instead attaches to an existing run (after a session restart, or for a run started elsewhere). The SessionStart hook announces the script’s absolute path in every .smithers project, together with the number of non-terminal runs to re-attach to. What the mirror renders:
  • Phases from the workflow’s real container tree: Workflow name, Sequence label, Parallel label, loop containers. Labels are read from the run’s persisted frames, so data-dependent fan-outs and loop iterations appear as they materialize.
  • One row per node: agent, human, approval, and dynamically discovered nodes by default (mirrorAllNodes: true in args adds compute/static rows). A running node gets a live watcher row that resolves with the node’s output; nodes that finished before a slot freed get a completion row.
  • Approval and human-request banners as narrator lines, with the exact resolving command.
  • Continue-as-new is followed: when a run continues as a new runId, the mirror switches to it automatically.
  • Caps respected: at most 6 live watcher rows at a time (the sync loop must never queue behind its own watchers), a 900-agent budget, and per-phase summary rows for runs above 150 nodes. Every cap logs when it engages.
Stopping the mirror workflow never stops the Smithers run. Cancelling the run is explicit: bunx smithers-orchestrator cancel RUN_ID (or the gateway cancelRun RPC).

The smithers claude protocol

The mirror’s agents run exactly one CLI command each and relay its JSON. All derivation and all blocking happens inside the CLI, against the durable store, under a frozen wire contract ("contract": 1 in every response):
One complete mirror frame: run status, event-log cursor (seq), the latest frame’s phase plan, every node with {nodeId, label, phase, kind, state}, the nodeIds that changed after --after-seq, truncated outputs of nodes that became terminal, pending approvals and human requests, and continuedAs for continued runs. --wait blocks until a mirror-relevant event lands (tool-call and heartbeat chatter is ignored), the run reaches a terminal status, or the timeout expires ("timedOut": true, exit 0). With --wait, a store or run that does not exist yet is waited for too, so a mirror launched right after workflow run --detach cannot race the engine’s first write. Ticking a non-terminal run also records the session’s subscription for claude monitor (following a run is subscribing to it).
Blocks until one node reaches a terminal state, then reports {state, output, vanished, timedOut}. A node pruned by a later frame reports state: "skipped", vanished: true. Watchers re-invoke on timedOut: true, which is how a row outlives the 10-minute Bash cap on multi-hour nodes.
NDJSON follower for the plugin monitor: one line per notable transition (approval-pending, human-request, run-finished, run-failed, run-cancelled, run-continued, run-stalled), each with a summary and the resolving command. It follows only the session’s subscribed runs (recorded in .smithers/claude-mirror-subscriptions.json, keyed by the CLAUDE_CODE_SESSION_ID each command sees; --all-runs opts out), does not replay history, surfaces already-pending gates once at startup, and prunes a subscription when its run turns terminal. In a project without a Smithers store it exits silently.
The explicit subscription path: subscribe points the session’s monitor at a run it did not start (it validates the run exists), unsubscribe silences one. Both are session-scoped when CLAUDE_CODE_SESSION_ID is set; from a plain terminal unsubscribe drops the run for every session. These commands are protocol surface for the plugin. Keep responses additive; a breaking shape change bumps contract and the shipped script refuses mismatched majors with an actionable message.

Install

From the repository checkout (or a marketplace once published):
Nothing else is required. The MCP server and CLI run through bunx smithers-orchestrator, so the first invocation bootstraps the CLI from npm. In a project without .smithers/, the skill initializes Smithers before the first run.

Failure modes