CLI Inspection
The Smithers CLI provides four inspection commands:status
View the current state of a run, including all node statuses:frames
View the render frames for a run. Each frame is a snapshot of the JSX tree at a point in time, showing which tasks were mounted and their states:--tail N to limit output to the most recent N frames. Frames are useful for understanding the re-render cycle — you can see when tasks mount, when outputs become available, and how the tree evolves.
list
List all runs, optionally filtered by status:graph
View the execution graph for a run. This shows the task dependency structure:NDJSON Log Inspection
Smithers writes every event to an NDJSON log file at:SmithersEvent. You can tail the log in real time during execution:
jq for structured inspection:
SQLite Inspection
Smithers stores all internal state in tables prefixed with_smithers_. You can query them directly for deep debugging.
Internal Tables
| Table | Purpose |
|---|---|
_smithers_runs | Run metadata: status, created/updated timestamps |
_smithers_nodes | Per-node state: status, iteration, attempt count |
_smithers_attempts | Per-attempt details: status, started/finished times, error messages, JJ pointer |
_smithers_frames | Render frame snapshots (XML representation of the JSX tree) |
_smithers_approvals | Approval decisions: approved/denied, decided_by, note |
_smithers_cache | Cached task results (when caching is enabled) |
_smithers_tool_calls | Tool invocations: tool name, arguments, result, duration |
_smithers_events | All events with sequence numbers and JSON payloads |
_smithers_ralph | Ralph loop state: iteration counts, termination reasons |
Useful Queries
View run status:Common Issues
Run stuck at “waiting-approval”
A task withneedsApproval is blocking the workflow. Check which node is waiting:
Duplicate task IDs
Task IDs must be unique within a workflow. Duplicate IDs cause an error at render time:- Two
<Task>elements with the sameidprop. - Dynamic tasks generated from an array where the IDs collide (e.g., using array indices).
- A task inside a
<Ralph>loop that should be outside (or vice versa).
<Task> has a globally unique id within the workflow. For dynamic tasks, derive IDs from unique identifiers: id={$:process}.
Missing output rows
Ifctx.output() throws “No output found for nodeId”, the task has not completed yet. Common causes:
- The task is still pending or in-progress.
- The task failed (check
_smithers_nodesfor its status). - The task’s
idprop changed between renders. - The output table is missing the required
runIdornodeIdcolumn (when using the manual Drizzle API).
ctx.outputMaybe() for safe conditional access:
Task keeps retrying
If a task retries indefinitely (up to its retry limit), check:- Schema validation errors — The agent may be returning invalid JSON. Check the NDJSON logs for
NodeRetryingevents. - Timeout — The agent call may be timing out. Check
timeoutMssettings. - Tool errors — A tool used by the agent may be failing. Check
_smithers_tool_callsfor errors.
Stale in-progress tasks
If a run was interrupted and tasks are stuck inin-progress, resume the run. Tasks in-progress for longer than 15 minutes are automatically cancelled and retried:
Next Steps
- Monitoring & Logs — Set up live monitoring with events and SSE.
- Resumability — How resume handles stale tasks.
- CLI Reference — All CLI commands and options.