Quick Start
This guide walks you through creating and running your first Smithers workflow.
Prerequisites
- Bun v1.0+ (required runtime)
- Claude Code -
npm install -g @anthropic-ai/claude-code
Smithers uses Claude Code’s subscription for API access - no separate API key needed.
Installation
Your First Workflow
Create a file called my-workflow.tsx:
#!/usr/bin/env bun
import { createSmithersRoot } from "smithers";
import { createSmithersDB } from "smithers/smithers-orchestrator/src/db";
import { SmithersProvider } from "smithers/smithers-orchestrator/src/components/SmithersProvider";
import { Claude } from "smithers/smithers-orchestrator/src/components/Claude";
// Create a database for state persistence
const db = await createSmithersDB({ path: ".smithers/my-task" });
const executionId = await db.execution.start("My Task", "scripts/my-task.tsx");
async function MyWorkflow() {
return (
<SmithersProvider db={db} executionId={executionId}>
<Claude
model="sonnet"
maxTurns={10}
onFinished={(result) => console.log("Done:", result.output)}
>
Analyze this codebase and suggest three improvements.
</Claude>
</SmithersProvider>
);
}
const root = createSmithersRoot();
await root.mount(MyWorkflow);
await db.close();
Run the Workflow
You’ll see Claude analyze your codebase and output suggestions.
Understanding the Code
Create Database
const db = await createSmithersDB({ path: ".smithers/my-task" });
The PGlite database persists all state, letting you resume workflows.Start Execution
const executionId = await db.execution.start("My Task", "scripts/my-task.tsx");
Each execution is tracked with a unique ID for observability.Wrap in Provider
<SmithersProvider db={db} executionId={executionId}>
{/* components */}
</SmithersProvider>
The provider gives all child components access to database and execution context.Define Agent
<Claude model="sonnet" onFinished={(result) => console.log(result)}>
Your prompt here
</Claude>
The Claude component executes your prompt with the specified model.Mount and Run
const root = createSmithersRoot();
await root.mount(MyWorkflow);
The Solid.js renderer mounts your component tree and executes it.
Multi-Phase Workflow
Here’s a more complex example with phases and state:
async function ReviewWorkflow() {
const phase = (await db.state.get("phase")) ?? "implement";
return (
<SmithersProvider db={db} executionId={executionId}>
{phase === "implement" && (
<Claude
model="sonnet"
onFinished={() => db.state.set("phase", "review")}
>
Implement the user authentication feature.
</Claude>
)}
{phase === "review" && (
<Review
target={{ type: "diff", ref: "main" }}
criteria={[
"No security vulnerabilities",
"Tests cover edge cases",
]}
onFinished={(review) => {
if (review.approved) {
db.state.set("phase", "complete");
} else {
db.state.set("phase", "implement");
}
}}
/>
)}
</SmithersProvider>
);
}
This workflow:
- Starts in the “implement” phase
- Claude implements the feature
- Transitions to “review” phase
- Reviews the changes against criteria
- Loops back to “implement” if not approved
Let Claude Write It
The real power of Smithers: tell your agent what you want and it generates the workflow:
User: "Create a workflow that monitors my CI, fixes failures automatically,
and escalates after 3 failed attempts"
Claude: *generates ci-recovery.tsx*
Install the Claude Code plugin to enable this:
/plugin marketplace add evmts/smithers
/plugin install smithers@smithers
Inspecting State
View execution history and state with the database:
# View execution history
smithers-orchestrator db executions
# View state for a specific execution
smithers-orchestrator db state --execution-id abc123
# Query the database directly
smithers-orchestrator db query "SELECT * FROM agents ORDER BY started_at DESC LIMIT 10"
Next Steps