Skip to main content
Three levels of inspection: CLI commands, NDJSON log files, and direct SQLite queries.

CLI Inspection

inspect

bunx smithers inspect <id>
Shows run metadata, node statuses, approvals, and loop state.

logs

bunx smithers logs <id> --tail 10 --follow false
Shows persisted lifecycle events. For raw render frames, query _smithers_frames or use renderFrame.

ps

bunx smithers ps --limit 20
bunx smithers ps --status running
bunx smithers ps --status failed

graph

bunx smithers graph workflow.tsx --run-id <id>
bunx smithers graph workflow.tsx --input '{"description": "Fix bugs"}'
Shows task dependency structure. The second form previews the graph without running.

NDJSON Logs

.smithers/executions/<runId>/logs/stream.ndjson
Each line is a JSON-encoded SmithersEvent.
tail -f .smithers/executions/<runId>/logs/stream.ndjson
Filter by event type:
grep '"type":"Node' .smithers/executions/<runId>/logs/stream.ndjson
grep '"type":"NodeFailed"' .smithers/executions/<runId>/logs/stream.ndjson
grep '"type":"ToolCall' .smithers/executions/<runId>/logs/stream.ndjson
Parse with jq:
tail -5 .smithers/executions/<runId>/logs/stream.ndjson | jq .
cat .smithers/executions/<runId>/logs/stream.ndjson | jq 'select(.type == "NodeFinished" or .type == "NodeFailed") | {nodeId, type}'
Custom log location or disable:
bunx smithers up workflow.tsx --log-dir ./my-logs
bunx smithers up workflow.tsx --log false

SQLite Inspection

Internal Tables

TablePurpose
_smithers_runsRun metadata: status, timestamps
_smithers_nodesPer-node state: status, iteration, attempt count
_smithers_attemptsPer-attempt: status, times, errors, JJ pointer
_smithers_framesRender frame snapshots (XML of JSX tree)
_smithers_approvalsApproval decisions
_smithers_cacheCached task results
_smithers_tool_callsTool invocations: name, args, result, duration
_smithers_eventsAll events with sequence numbers and JSON payloads
_smithers_ralphLoop iteration state

Queries

# Run status
sqlite3 smithers.db "SELECT run_id, status, created_at_ms, updated_at_ms FROM _smithers_runs ORDER BY created_at_ms DESC LIMIT 5;"

# Node states
sqlite3 smithers.db "SELECT node_id, status, iteration FROM _smithers_nodes WHERE run_id = '<id>' ORDER BY updated_at_ms;"

# Failed attempts
sqlite3 smithers.db "SELECT node_id, attempt, status, error_message FROM _smithers_attempts WHERE run_id = '<id>' AND status = 'failed';"

# Tool calls
sqlite3 smithers.db "SELECT tool_name, arguments, duration_ms FROM _smithers_tool_calls WHERE run_id = '<id>' AND node_id = '<node-id>';"

# Events
sqlite3 smithers.db "SELECT seq, type, payload_json FROM _smithers_events WHERE run_id = '<id>' ORDER BY seq LIMIT 50;"

# Approvals
sqlite3 smithers.db "SELECT node_id, approved, decided_by, note FROM _smithers_approvals WHERE run_id = '<id>';"

# Loop state
sqlite3 smithers.db "SELECT * FROM _smithers_ralph WHERE run_id = '<id>';"

# Output tables
sqlite3 smithers.db "SELECT * FROM analysis WHERE run_id = '<id>';"
sqlite3 smithers.db "SELECT * FROM report WHERE run_id = '<id>';"

Common Issues

Stuck at “waiting-approval”

bunx smithers inspect <id>
bunx smithers approve <id> --node <node-id>
# or: bunx smithers deny <id> --node <node-id>
bunx smithers up workflow.tsx --run-id <id> --resume true

Duplicate task IDs

Error: Duplicate Task id detected: "analyze"
Every <Task> needs a globally unique id. For dynamic tasks, derive IDs from unique identifiers: id={$:process}.

Missing output rows

ctx.output() throws “No output found” when the task has not completed, failed, or its id changed between renders. Use ctx.outputMaybe() for conditional access:
const result = ctx.outputMaybe("analysis", { nodeId: "analyze" });
if (result) {
  // safe to use
}

Task keeps retrying

Check for schema validation errors, timeouts, or tool failures:
grep "NodeRetrying" .smithers/executions/<runId>/logs/stream.ndjson | jq .
sqlite3 smithers.db "SELECT node_id, attempt, error_message FROM _smithers_attempts WHERE run_id = '<id>' AND status = 'failed';"

Stale in-progress tasks

Tasks in-progress for over 15 minutes are auto-cancelled and retried on resume:
bunx smithers up workflow.tsx --run-id <id> --resume true

Next Steps