Skip to main content
The Smithers PI extension runs inside the PI coding agent and gives it complete Smithers knowledge and workflow observability. It does three things at once: it bridges the Smithers MCP server so the agent has live tool access, it injects the Smithers documentation into every system prompt so the LLM understands the full API, and it adds a set of slash commands and UI widgets that let you monitor and control runs without leaving the terminal.

Installation

The extension ships with smithers-orchestrator. Install PI and add it to your PATH, then register the extension:
pi --extension smithers-orchestrator/pi-plugin/extension.ts
Or add it permanently to your PI config:
{
  "extensions": ["smithers-orchestrator/pi-plugin/extension.ts"]
}
PI must be able to reach a running Smithers server. The default URL is http://127.0.0.1:7331. Start one with smithers serve before launching PI.

Setup and configuration

The extension registers two CLI flags you can pass when launching PI:
FlagShortDefaultDescription
--smithers-url-uhttp://127.0.0.1:7331Smithers server base URL
--smithers-key-kAPI key for authenticated servers
The API key is also read from SMITHERS_API_KEY in the environment. Setting the env var is preferred over passing the key on the command line.
SMITHERS_API_KEY=sk-my-token pi --extension smithers-orchestrator/pi-plugin/extension.ts

MCP bridge

On session start, the extension spawns smithers --mcp as a child process and connects to it over stdio using the Model Context Protocol. It then discovers all available Smithers tools and registers them as PI agent tools named smithers_<tool>. This means the agent can call Smithers operations directly as tool calls, with full TypeBox parameter schemas derived from the MCP server’s JSON Schema definitions. The MCP connection is held open for the entire PI session and torn down cleanly on session_shutdown.

Dynamic tool registration

Tools are registered dynamically at session start based on whatever the live MCP server exposes. If the server has a newer or older tool surface, the agent gets exactly that set — no hardcoded list. The tui tool is filtered out since the extension itself handles TUI interactions. Tool call rendering in the PI chat history shows smithers <tool-name> key=value … for calls and a colored success/error indicator for results.

MCP tool reference

PI tool nameUnderlying MCP toolDescription
smithers_runrunStart a new workflow run
smithers_statusstatusGet run status and node summary
smithers_approveapproveApprove a node waiting for human sign-off
smithers_denydenyDeny a node waiting for human sign-off
smithers_cancelcancelCancel a running workflow
smithers_listlistList runs for a workflow from the database
smithers_framesframesList render frames (DAG snapshots) for a run
smithers_graphgraphPreview the execution graph without running
smithers_resumeresumeResume a paused or crashed run
smithers_revertrevertRevert the workspace to a previous task attempt
The agent is guided by the injected system prompt to prefer these tools over shelling out, and to follow the standard workflow pattern: discover with smithers_list, run with smithers_run, monitor with smithers_status, approve with smithers_approve, and debug with smithers_frames or smithers_graph.

System prompt injection

On every before_agent_start event the extension augments the system prompt with two pieces of content.

Full Smithers documentation

The extension loads docs/llms-full.txt (~125k tokens) from the package. It tries several candidate paths and falls back to llms.txt if the full file is not found. This gives the LLM complete knowledge of the Smithers API, component reference, and usage patterns. Resolution order for llms-full.txt:
  1. <package-dir>/docs/llms-full.txt
  2. <package-dir>/../docs/llms-full.txt
  3. <cwd>/docs/llms-full.txt
  4. <cwd>/node_modules/smithers-orchestrator/docs/llms-full.txt
Then the same four paths for the llms.txt fallback.

Active run context

If there is a currently active run being tracked by the extension, a short context block is appended:
## Active Run Context
Run: smi_abc123 (deploy.tsx)
Status: waiting-approval
Nodes waiting approval: checkDeploy
This tells the LLM exactly what is happening right now without it having to call a tool first.

UI components

The following components are active whenever PI is in interactive (TUI) mode. Displays smithers · workflow orchestrator branding at the top of every PI session. Rendered via ctx.ui.setHeader.

Status bar

Shows a live count of active runs, pending approvals, completed runs, and failed runs in the form smithers: 2 active · 1 awaiting approval · 3 done. Updates on every background poll cycle and after every event stream message. Disappears when no runs have been tracked. A separate approval indicator status entry (smithers-approval) appears at the start of each conversation turn when one or more nodes are waiting for approval: ⏳ N node(s) awaiting approval.

Event ticker

When a run is being watched via the event stream, the 5 most recent events are rendered as a widget above the editor input. Each line shows a timestamp and the event message. Updates in real time as events arrive.
  14:32:01  Run started
  14:32:04  analyzeCode started (attempt 1)
  14:32:11  analyzeCode → bash()
  14:32:14  analyzeCode → bash() ✓
  14:32:18  analyzeCode finished

Message renderer

A custom PI message renderer (smithers-event) formats workflow event messages in the chat history. It uses status color coding and status icons, and shows the run ID when the message is expanded.

Auto-polling

Active runs are polled every 10 seconds for status updates even when no event stream is attached. Each poll also fetches Prometheus metrics from the server’s /metrics endpoint. Polling starts on session_start and stops on session_shutdown.

Slash commands

All commands are available as /smithers-<name> inside the PI interactive session.
CommandArgumentDescription
/smithersOpen the full-screen dashboard overlay
/smithers-runsList all tracked runs; select one to make it active
/smithers-watch[runId]Attach a live SSE event stream to a run
/smithers-run[workflow]Start a workflow and auto-attach the event stream
/smithers-resume[workflow]Resume a paused or crashed run
/smithers-approveInteractive approve/deny flow for waiting nodes
/smithers-cancel[runId]Cancel a running workflow with confirmation
/smithers-status[runId]Show detailed status; defaults to active run
/smithers-logs[nodeId]Scrollable log viewer for a node’s output
/smithers-frames[runId]Browse render frames (DAG snapshots) for a run
/smithers-graph[workflow]Preview the execution graph without running
/smithers-revert[workflow]Revert workspace to a previous task attempt
/smithers-list[workflow]List runs from the database for a workflow
/smithers-metricsLive Prometheus metrics overlay
Arguments in brackets are optional. When omitted the command prompts interactively or falls back to the current active run. Run ID arguments support tab-completion from the set of tracked runs.

/smithers — Dashboard overlay

Full-screen TUI overlay with four tabs:
  • 1 Overview — all tracked runs with status icon, workflow name, run ID prefix, elapsed time, and a node state summary
  • 2 Nodes — per-node breakdown for the selected run with state, duration, and the last two lines of captured output
  • 3 Events — the 20 most recent events for the selected run, color-coded by type
  • 4 Errors — all errors collected for the selected run
Navigate with j/k to select runs, 14 to switch tabs, q or Esc to close.

/smithers-runs

Shows a selection list of all tracked runs. Selecting a run makes it the active run for the event ticker and status bar.

/smithers-watch

Attaches a live SSE stream to a run. Events update the ticker widget and the dashboard in real time. Accepts a run ID as an argument or prompts if omitted.

/smithers-run

Prompts for a workflow path and optional input JSON, calls smithers_run, and automatically attaches the event stream to the new run.

/smithers-resume

Prompts for a workflow path and run ID, calls smithers_resume, and auto-attaches the event stream to the resumed run.

/smithers-approve

Collects all nodes in the waiting-approval state across all tracked runs and presents a selection list. After choosing a node the user picks Approve or Deny and can add an optional note. Posts directly to the Smithers server API.

/smithers-cancel

Presents a selection list of active runs or accepts a run ID argument. Requires confirmation before calling POST /v1/runs/:runId/cancel.

/smithers-status

Calls smithers_status and pastes the result into the editor. Defaults to the active run when no ID is provided.

/smithers-logs

Opens a scrollable log viewer for a specific node’s captured output. Prompts for node selection if no argument is given. Keys: j/k to scroll, g/G for top/bottom, q/Esc to close.

/smithers-frames

Opens a split view: a frame list on top and frame detail below. The detail pane shows the task index, mounted task IDs, any note, and an XML snippet of the DAG snapshot. Navigate with j/k, close with q/Esc.

/smithers-graph

Calls smithers_graph and pastes the JSON execution graph into the editor. Accepts a workflow path as an argument or prompts if omitted.

/smithers-revert

Interactive revert flow: prompts for workflow path, run ID, node ID, and attempt number, then requires confirmation before calling smithers_revert. Warns that this modifies the working directory.

/smithers-list

Calls smithers_list for the given workflow and pastes the JSON run list into the editor.

/smithers-metrics

Full-screen TUI overlay showing live Prometheus metrics fetched from GET /metrics: Counters and gauges — runs started/finished/failed/cancelled/resumed, active runs and nodes, node retries, token counts (input/output/cache read/cache write/reasoning), tool calls and errors, cache hits/misses, approvals requested/granted/denied/pending, hot reloads, HTTP requests, DB retries, scheduler queue depth, events emitted, process uptime and memory. Histograms (p50 / p99 / avg / count) — run duration, node duration, attempt duration, tool duration, tokens per call, prompt and response size, approval wait time, scheduler wait time, DB query latency, HTTP request latency, hot reload duration, VCS duration. Press r to toggle raw Prometheus text output. Close with q or Esc.

JSON Schema to TypeBox conversion

When the extension registers MCP tools as PI tools, it converts the MCP server’s JSON Schema inputSchema to TypeBox schemas on the fly. String, number/integer, boolean, and array properties are mapped to their TypeBox equivalents. Required properties become mandatory fields; optional properties are wrapped in Type.Optional. This allows PI’s parameter validation and UI to work without any hardcoded schema definitions.

Relationship to the PI plugin client

This extension and the smithers-orchestrator/pi-plugin HTTP client are complementary, not overlapping. The extension is loaded by the PI CLI itself and adds agent tools, UI, and slash commands. The HTTP client (pi-plugin) is a lightweight module you import in your own code — a PI extension or any Node process — to drive the Smithers server API from TypeScript. Both are part of the same package. See the PI Plugin Client page for the HTTP client API reference.