smithers-orchestrator 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +401 -0
- package/bin/cli.js +14259 -0
- package/bin/cli.ts +69 -0
- package/dist/components/Claude.d.ts +27 -0
- package/dist/components/Claude.d.ts.map +1 -0
- package/dist/components/Claude.jsx +82 -0
- package/dist/components/Claude.jsx.map +1 -0
- package/dist/components/Git/Commit.d.ts +33 -0
- package/dist/components/Git/Commit.d.ts.map +1 -0
- package/dist/components/Git/Commit.jsx +118 -0
- package/dist/components/Git/Commit.jsx.map +1 -0
- package/dist/components/Git/Notes.d.ts +25 -0
- package/dist/components/Git/Notes.d.ts.map +1 -0
- package/dist/components/Git/Notes.jsx +57 -0
- package/dist/components/Git/Notes.jsx.map +1 -0
- package/dist/components/Git/index.d.ts +3 -0
- package/dist/components/Git/index.d.ts.map +1 -0
- package/dist/components/Git/index.js +4 -0
- package/dist/components/Git/index.js.map +1 -0
- package/dist/components/Hooks/OnCIFailure.d.ts +42 -0
- package/dist/components/Hooks/OnCIFailure.d.ts.map +1 -0
- package/dist/components/Hooks/OnCIFailure.jsx +164 -0
- package/dist/components/Hooks/OnCIFailure.jsx.map +1 -0
- package/dist/components/Hooks/PostCommit.d.ts +32 -0
- package/dist/components/Hooks/PostCommit.d.ts.map +1 -0
- package/dist/components/Hooks/PostCommit.jsx +113 -0
- package/dist/components/Hooks/PostCommit.jsx.map +1 -0
- package/dist/components/Hooks/index.d.ts +3 -0
- package/dist/components/Hooks/index.d.ts.map +1 -0
- package/dist/components/Hooks/index.js +5 -0
- package/dist/components/Hooks/index.js.map +1 -0
- package/dist/components/JJ/Commit.d.ts +15 -0
- package/dist/components/JJ/Commit.d.ts.map +1 -0
- package/dist/components/JJ/Commit.jsx +83 -0
- package/dist/components/JJ/Commit.jsx.map +1 -0
- package/dist/components/JJ/Describe.d.ts +14 -0
- package/dist/components/JJ/Describe.d.ts.map +1 -0
- package/dist/components/JJ/Describe.jsx +77 -0
- package/dist/components/JJ/Describe.jsx.map +1 -0
- package/dist/components/JJ/Rebase.d.ts +15 -0
- package/dist/components/JJ/Rebase.d.ts.map +1 -0
- package/dist/components/JJ/Rebase.jsx +128 -0
- package/dist/components/JJ/Rebase.jsx.map +1 -0
- package/dist/components/JJ/Snapshot.d.ts +13 -0
- package/dist/components/JJ/Snapshot.d.ts.map +1 -0
- package/dist/components/JJ/Snapshot.jsx +52 -0
- package/dist/components/JJ/Snapshot.jsx.map +1 -0
- package/dist/components/JJ/Status.d.ts +18 -0
- package/dist/components/JJ/Status.d.ts.map +1 -0
- package/dist/components/JJ/Status.jsx +67 -0
- package/dist/components/JJ/Status.jsx.map +1 -0
- package/dist/components/JJ/index.d.ts +6 -0
- package/dist/components/JJ/index.d.ts.map +1 -0
- package/dist/components/JJ/index.js +8 -0
- package/dist/components/JJ/index.js.map +1 -0
- package/dist/components/MCP/Sqlite.d.ts +25 -0
- package/dist/components/MCP/Sqlite.d.ts.map +1 -0
- package/dist/components/MCP/Sqlite.jsx +24 -0
- package/dist/components/MCP/Sqlite.jsx.map +1 -0
- package/dist/components/MCP/index.d.ts +2 -0
- package/dist/components/MCP/index.d.ts.map +1 -0
- package/dist/components/MCP/index.js +4 -0
- package/dist/components/MCP/index.js.map +1 -0
- package/dist/components/Phase.d.ts +12 -0
- package/dist/components/Phase.d.ts.map +1 -0
- package/dist/components/Phase.jsx +10 -0
- package/dist/components/Phase.jsx.map +1 -0
- package/dist/components/Ralph.d.ts +28 -0
- package/dist/components/Ralph.d.ts.map +1 -0
- package/dist/components/Ralph.jsx +58 -0
- package/dist/components/Ralph.jsx.map +1 -0
- package/dist/components/Review.d.ts +56 -0
- package/dist/components/Review.d.ts.map +1 -0
- package/dist/components/Review.jsx +235 -0
- package/dist/components/Review.jsx.map +1 -0
- package/dist/components/Step.d.ts +12 -0
- package/dist/components/Step.d.ts.map +1 -0
- package/dist/components/Step.jsx +10 -0
- package/dist/components/Step.jsx.map +1 -0
- package/dist/components/index.d.ts +11 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +16 -0
- package/dist/components/index.js.map +1 -0
- package/dist/core/execute.d.ts +15 -0
- package/dist/core/execute.d.ts.map +1 -0
- package/dist/core/execute.js +53 -0
- package/dist/core/execute.js.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +6 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/root.d.ts +28 -0
- package/dist/core/root.d.ts.map +1 -0
- package/dist/core/root.js +40 -0
- package/dist/core/root.js.map +1 -0
- package/dist/core/serialize.d.ts +15 -0
- package/dist/core/serialize.d.ts.map +1 -0
- package/dist/core/serialize.js +90 -0
- package/dist/core/serialize.js.map +1 -0
- package/dist/core/types.d.ts +55 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +11 -0
- package/dist/core/types.js.map +1 -0
- package/dist/debug/index.d.ts +10 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +11 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/commands/db.d.ts +6 -0
- package/dist/orchestrator/commands/db.d.ts.map +1 -0
- package/dist/orchestrator/commands/db.js +272 -0
- package/dist/orchestrator/commands/db.js.map +1 -0
- package/dist/orchestrator/commands/init.d.ts +6 -0
- package/dist/orchestrator/commands/init.d.ts.map +1 -0
- package/dist/orchestrator/commands/init.js +61 -0
- package/dist/orchestrator/commands/init.js.map +1 -0
- package/dist/orchestrator/commands/monitor.d.ts +7 -0
- package/dist/orchestrator/commands/monitor.d.ts.map +1 -0
- package/dist/orchestrator/commands/monitor.js +136 -0
- package/dist/orchestrator/commands/monitor.js.map +1 -0
- package/dist/orchestrator/commands/run.d.ts +6 -0
- package/dist/orchestrator/commands/run.d.ts.map +1 -0
- package/dist/orchestrator/commands/run.js +62 -0
- package/dist/orchestrator/commands/run.js.map +1 -0
- package/dist/orchestrator/components/Claude.d.ts +31 -0
- package/dist/orchestrator/components/Claude.d.ts.map +1 -0
- package/dist/orchestrator/components/Claude.jsx +195 -0
- package/dist/orchestrator/components/Claude.jsx.map +1 -0
- package/dist/orchestrator/components/Orchestration.d.ts +76 -0
- package/dist/orchestrator/components/Orchestration.d.ts.map +1 -0
- package/dist/orchestrator/components/Orchestration.jsx +154 -0
- package/dist/orchestrator/components/Orchestration.jsx.map +1 -0
- package/dist/orchestrator/components/Phase.d.ts +35 -0
- package/dist/orchestrator/components/Phase.d.ts.map +1 -0
- package/dist/orchestrator/components/Phase.jsx +76 -0
- package/dist/orchestrator/components/Phase.jsx.map +1 -0
- package/dist/orchestrator/components/Smithers.d.ts +94 -0
- package/dist/orchestrator/components/Smithers.d.ts.map +1 -0
- package/dist/orchestrator/components/Smithers.jsx +128 -0
- package/dist/orchestrator/components/Smithers.jsx.map +1 -0
- package/dist/orchestrator/components/SmithersProvider.d.ts +95 -0
- package/dist/orchestrator/components/SmithersProvider.d.ts.map +1 -0
- package/dist/orchestrator/components/SmithersProvider.jsx +70 -0
- package/dist/orchestrator/components/SmithersProvider.jsx.map +1 -0
- package/dist/orchestrator/components/Step.d.ts +47 -0
- package/dist/orchestrator/components/Step.d.ts.map +1 -0
- package/dist/orchestrator/components/Step.jsx +120 -0
- package/dist/orchestrator/components/Step.jsx.map +1 -0
- package/dist/orchestrator/components/agents/ClaudeCodeCLI.d.ts +37 -0
- package/dist/orchestrator/components/agents/ClaudeCodeCLI.d.ts.map +1 -0
- package/dist/orchestrator/components/agents/ClaudeCodeCLI.js +440 -0
- package/dist/orchestrator/components/agents/ClaudeCodeCLI.js.map +1 -0
- package/dist/orchestrator/components/agents/SmithersCLI.d.ts +72 -0
- package/dist/orchestrator/components/agents/SmithersCLI.d.ts.map +1 -0
- package/dist/orchestrator/components/agents/SmithersCLI.js +274 -0
- package/dist/orchestrator/components/agents/SmithersCLI.js.map +1 -0
- package/dist/orchestrator/components/agents/types.d.ts +332 -0
- package/dist/orchestrator/components/agents/types.d.ts.map +1 -0
- package/dist/orchestrator/components/agents/types.js +4 -0
- package/dist/orchestrator/components/agents/types.js.map +1 -0
- package/dist/orchestrator/components/index.d.ts +14 -0
- package/dist/orchestrator/components/index.d.ts.map +1 -0
- package/dist/orchestrator/components/index.js +13 -0
- package/dist/orchestrator/components/index.js.map +1 -0
- package/dist/orchestrator/db/execution.d.ts +148 -0
- package/dist/orchestrator/db/execution.d.ts.map +1 -0
- package/dist/orchestrator/db/execution.js +497 -0
- package/dist/orchestrator/db/execution.js.map +1 -0
- package/dist/orchestrator/db/index.d.ts +381 -0
- package/dist/orchestrator/db/index.d.ts.map +1 -0
- package/dist/orchestrator/db/index.js +192 -0
- package/dist/orchestrator/db/index.js.map +1 -0
- package/dist/orchestrator/db/live-query.d.ts +39 -0
- package/dist/orchestrator/db/live-query.d.ts.map +1 -0
- package/dist/orchestrator/db/live-query.js +64 -0
- package/dist/orchestrator/db/live-query.js.map +1 -0
- package/dist/orchestrator/db/memories.d.ts +66 -0
- package/dist/orchestrator/db/memories.d.ts.map +1 -0
- package/dist/orchestrator/db/memories.js +193 -0
- package/dist/orchestrator/db/memories.js.map +1 -0
- package/dist/orchestrator/db/state.d.ts +62 -0
- package/dist/orchestrator/db/state.d.ts.map +1 -0
- package/dist/orchestrator/db/state.js +179 -0
- package/dist/orchestrator/db/state.js.map +1 -0
- package/dist/orchestrator/db/types.d.ts +198 -0
- package/dist/orchestrator/db/types.d.ts.map +1 -0
- package/dist/orchestrator/db/types.js +3 -0
- package/dist/orchestrator/db/types.js.map +1 -0
- package/dist/orchestrator/db/vcs.d.ts +96 -0
- package/dist/orchestrator/db/vcs.d.ts.map +1 -0
- package/dist/orchestrator/db/vcs.js +225 -0
- package/dist/orchestrator/db/vcs.js.map +1 -0
- package/dist/orchestrator/monitor/haiku-summarizer.d.ts +10 -0
- package/dist/orchestrator/monitor/haiku-summarizer.d.ts.map +1 -0
- package/dist/orchestrator/monitor/haiku-summarizer.js +59 -0
- package/dist/orchestrator/monitor/haiku-summarizer.js.map +1 -0
- package/dist/orchestrator/monitor/log-writer.d.ts +13 -0
- package/dist/orchestrator/monitor/log-writer.d.ts.map +1 -0
- package/dist/orchestrator/monitor/log-writer.js +64 -0
- package/dist/orchestrator/monitor/log-writer.js.map +1 -0
- package/dist/orchestrator/monitor/output-parser.d.ts +22 -0
- package/dist/orchestrator/monitor/output-parser.d.ts.map +1 -0
- package/dist/orchestrator/monitor/output-parser.js +114 -0
- package/dist/orchestrator/monitor/output-parser.js.map +1 -0
- package/dist/orchestrator/monitor/stream-formatter.d.ts +26 -0
- package/dist/orchestrator/monitor/stream-formatter.d.ts.map +1 -0
- package/dist/orchestrator/monitor/stream-formatter.js +137 -0
- package/dist/orchestrator/monitor/stream-formatter.js.map +1 -0
- package/dist/orchestrator/tools/ReportTool.d.ts +25 -0
- package/dist/orchestrator/tools/ReportTool.d.ts.map +1 -0
- package/dist/orchestrator/tools/ReportTool.js +136 -0
- package/dist/orchestrator/tools/ReportTool.js.map +1 -0
- package/dist/orchestrator/tools/index.d.ts +3 -0
- package/dist/orchestrator/tools/index.d.ts.map +1 -0
- package/dist/orchestrator/tools/index.js +8 -0
- package/dist/orchestrator/tools/index.js.map +1 -0
- package/dist/orchestrator/tools/registry.d.ts +132 -0
- package/dist/orchestrator/tools/registry.d.ts.map +1 -0
- package/dist/orchestrator/tools/registry.js +90 -0
- package/dist/orchestrator/tools/registry.js.map +1 -0
- package/dist/orchestrator/utils/mcp-config.d.ts +24 -0
- package/dist/orchestrator/utils/mcp-config.d.ts.map +1 -0
- package/dist/orchestrator/utils/mcp-config.js +82 -0
- package/dist/orchestrator/utils/mcp-config.js.map +1 -0
- package/dist/orchestrator/utils/structured-output.d.ts +41 -0
- package/dist/orchestrator/utils/structured-output.d.ts.map +1 -0
- package/dist/orchestrator/utils/structured-output.js +218 -0
- package/dist/orchestrator/utils/structured-output.js.map +1 -0
- package/dist/solid/index.d.ts +7 -0
- package/dist/solid/index.d.ts.map +1 -0
- package/dist/solid/index.js +8 -0
- package/dist/solid/index.js.map +1 -0
- package/dist/solid/renderer-methods.d.ts +20 -0
- package/dist/solid/renderer-methods.d.ts.map +1 -0
- package/dist/solid/renderer-methods.js +75 -0
- package/dist/solid/renderer-methods.js.map +1 -0
- package/dist/solid/renderer.d.ts +21 -0
- package/dist/solid/renderer.d.ts.map +1 -0
- package/dist/solid/renderer.js +42 -0
- package/dist/solid/renderer.js.map +1 -0
- package/dist/solid/root.d.ts +20 -0
- package/dist/solid/root.d.ts.map +1 -0
- package/dist/solid/root.js +38 -0
- package/dist/solid/root.js.map +1 -0
- package/dist/utils/vcs.d.ts +125 -0
- package/dist/utils/vcs.d.ts.map +1 -0
- package/dist/utils/vcs.js +271 -0
- package/dist/utils/vcs.js.map +1 -0
- package/package.json +103 -0
- package/postinstall.cjs +82 -0
- package/templates/main.tsx.template +320 -0
package/README.md
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
# Smithers
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/smithers)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
[](https://bun.sh/)
|
|
7
|
+
|
|
8
|
+
**Declarative JSX framework for building AI agent orchestration workflows.**
|
|
9
|
+
|
|
10
|
+
I use Smithers for both long-term (weeks) agentic work, as well as one-off scripts.
|
|
11
|
+
|
|
12
|
+
<!-- TODO: Add GIF demo -->
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Table of Contents
|
|
19
|
+
|
|
20
|
+
- [Why](#why)
|
|
21
|
+
- [Installation](#installation)
|
|
22
|
+
- [Dependencies](#dependencies)
|
|
23
|
+
- [Usage](#usage)
|
|
24
|
+
- [Recipes](#recipes)
|
|
25
|
+
- [Features](#features)
|
|
26
|
+
- [Claude Component](#claude-component)
|
|
27
|
+
- [Ralph Loop Controller](#ralph-loop-controller)
|
|
28
|
+
- [Structured Output with Zod](#structured-output-with-zod)
|
|
29
|
+
- [MCP Tool Integration](#mcp-tool-integration)
|
|
30
|
+
- [Smithers Subagent](#smithers-subagent)
|
|
31
|
+
- [Git/JJ VCS Integration](#gitjj-vcs-integration)
|
|
32
|
+
- [Database State Management](#database-state-management)
|
|
33
|
+
- [Contributing](#contributing)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Why
|
|
38
|
+
|
|
39
|
+
I wanted a tool that allows me to:
|
|
40
|
+
|
|
41
|
+
- **Write agent workflows as JSX** - because declarative composition is easier to reason about than imperative chains
|
|
42
|
+
- **Let Claude Code write the orchestration for me** - I describe what I want, and my agent builds the workflow
|
|
43
|
+
- **Persist state across sessions** - pick up where I left off, even days later
|
|
44
|
+
- **Mix short scripts with long-running workflows** - same syntax for a quick task or a week-long project
|
|
45
|
+
- **See what my agents are doing** - full observability with database logging and reports
|
|
46
|
+
- **Use reactive primitives** - Solid.js signals mean my workflows respond to state changes automatically
|
|
47
|
+
- **Compose complex behaviors from simple components** - loops, phases, steps, and validation all snap together
|
|
48
|
+
- **Keep everything in version control** - workflows are just TypeScript files
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
### Install the Smithers Plugin for Claude Code
|
|
55
|
+
|
|
56
|
+
**Step 1:** Add the Smithers marketplace:
|
|
57
|
+
```bash
|
|
58
|
+
/plugin marketplace add evmts/smithers
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Step 2:** Install the plugin:
|
|
62
|
+
```bash
|
|
63
|
+
/plugin install smithers@smithers
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
This gives Claude Code the `smithers-orchestrator` skill for creating multi-agent workflows.
|
|
67
|
+
|
|
68
|
+
### Optional: Install the npm package for programmatic use
|
|
69
|
+
|
|
70
|
+
If you want to use Smithers components directly in your own scripts:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
bun add smithers
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Dependencies
|
|
79
|
+
|
|
80
|
+
### Required
|
|
81
|
+
|
|
82
|
+
- **[Bun](https://bun.sh/)** - JavaScript runtime (v1.0+)
|
|
83
|
+
- **[Claude Code](https://www.npmjs.com/package/@anthropic-ai/claude-code)** - `npm install -g @anthropic-ai/claude-code`
|
|
84
|
+
|
|
85
|
+
### Optional
|
|
86
|
+
|
|
87
|
+
- **[jj (Jujutsu)](https://github.com/martinvonz/jj)** - Alternative VCS with better snapshot support
|
|
88
|
+
- **Gemini CLI** - For Gemini model support (coming soon)
|
|
89
|
+
- **Codex CLI** - For OpenAI model support (coming soon)
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Usage
|
|
94
|
+
|
|
95
|
+
### Let Your Agent Write Smithers
|
|
96
|
+
|
|
97
|
+
**You don't have to write Smithers yourself.** Tell your agent what you want, and it generates the workflow:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
User: "Create a workflow that monitors my CI, fixes failures automatically, and escalates after 3 failed attempts"
|
|
101
|
+
|
|
102
|
+
Claude: *generates ci-recovery.tsx*
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Your agent understands the component model and generates correct, working orchestration scripts.
|
|
106
|
+
|
|
107
|
+
### State Persistence
|
|
108
|
+
|
|
109
|
+
All Smithers state is saved in a **PGlite database** on your system that can be easily inspected:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# View execution history
|
|
113
|
+
smithers-orchestrator db executions
|
|
114
|
+
|
|
115
|
+
# View state for a specific execution
|
|
116
|
+
smithers-orchestrator db state --execution-id abc123
|
|
117
|
+
|
|
118
|
+
# Query the database directly
|
|
119
|
+
smithers-orchestrator db query "SELECT * FROM agents ORDER BY started_at DESC LIMIT 10"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Basic Example
|
|
123
|
+
|
|
124
|
+
```tsx
|
|
125
|
+
#!/usr/bin/env bun
|
|
126
|
+
|
|
127
|
+
import { createSmithersRoot } from "smithers";
|
|
128
|
+
import { createSmithersDB } from "smithers/smithers-orchestrator/src/db";
|
|
129
|
+
import { SmithersProvider } from "smithers/smithers-orchestrator/src/components/SmithersProvider";
|
|
130
|
+
import { Claude } from "smithers/smithers-orchestrator/src/components/Claude";
|
|
131
|
+
|
|
132
|
+
const db = await createSmithersDB({ path: ".smithers/my-task" });
|
|
133
|
+
const executionId = await db.execution.start("My Task", "scripts/my-task.tsx");
|
|
134
|
+
|
|
135
|
+
async function MyWorkflow() {
|
|
136
|
+
return (
|
|
137
|
+
<SmithersProvider db={db} executionId={executionId}>
|
|
138
|
+
<Claude
|
|
139
|
+
model="sonnet"
|
|
140
|
+
maxTurns={10}
|
|
141
|
+
onFinished={(result) => console.log("Done:", result.output)}
|
|
142
|
+
>
|
|
143
|
+
Analyze this codebase and suggest three improvements.
|
|
144
|
+
</Claude>
|
|
145
|
+
</SmithersProvider>
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const root = createSmithersRoot();
|
|
150
|
+
await root.mount(MyWorkflow);
|
|
151
|
+
await db.close();
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Run it:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
bun my-workflow.tsx
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Recipes
|
|
163
|
+
|
|
164
|
+
### Multi-Phase Review Workflow
|
|
165
|
+
|
|
166
|
+
```tsx
|
|
167
|
+
async function ReviewWorkflow() {
|
|
168
|
+
const phase = (await db.state.get("phase")) ?? "implement";
|
|
169
|
+
|
|
170
|
+
return (
|
|
171
|
+
<SmithersProvider db={db} executionId={executionId}>
|
|
172
|
+
<Orchestration globalTimeout={3600000}>
|
|
173
|
+
<Ralph maxIterations={10}>
|
|
174
|
+
{phase === "implement" && (
|
|
175
|
+
<Phase name="Implementation">
|
|
176
|
+
<Claude
|
|
177
|
+
model="sonnet"
|
|
178
|
+
onFinished={() => db.state.set("phase", "review")}
|
|
179
|
+
>
|
|
180
|
+
Implement the user authentication feature.
|
|
181
|
+
</Claude>
|
|
182
|
+
</Phase>
|
|
183
|
+
)}
|
|
184
|
+
|
|
185
|
+
{phase === "review" && (
|
|
186
|
+
<Phase name="Code Review">
|
|
187
|
+
<Review
|
|
188
|
+
target={{ type: "diff", ref: "main" }}
|
|
189
|
+
criteria={[
|
|
190
|
+
"No security vulnerabilities",
|
|
191
|
+
"Tests cover edge cases",
|
|
192
|
+
"Types are properly defined",
|
|
193
|
+
]}
|
|
194
|
+
onFinished={(review) => {
|
|
195
|
+
if (review.approved) {
|
|
196
|
+
db.state.set("phase", "complete");
|
|
197
|
+
} else {
|
|
198
|
+
db.state.set("phase", "implement");
|
|
199
|
+
}
|
|
200
|
+
}}
|
|
201
|
+
/>
|
|
202
|
+
</Phase>
|
|
203
|
+
)}
|
|
204
|
+
</Ralph>
|
|
205
|
+
</Orchestration>
|
|
206
|
+
</SmithersProvider>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Structured Output with Validation
|
|
212
|
+
|
|
213
|
+
```tsx
|
|
214
|
+
import { z } from 'zod'
|
|
215
|
+
|
|
216
|
+
const AnalysisSchema = z.object({
|
|
217
|
+
summary: z.string(),
|
|
218
|
+
issues: z.array(z.object({
|
|
219
|
+
severity: z.enum(['low', 'medium', 'high', 'critical']),
|
|
220
|
+
file: z.string(),
|
|
221
|
+
description: z.string(),
|
|
222
|
+
})),
|
|
223
|
+
recommendations: z.array(z.string()),
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
<Claude
|
|
227
|
+
model="sonnet"
|
|
228
|
+
schema={AnalysisSchema}
|
|
229
|
+
schemaRetries={2}
|
|
230
|
+
onFinished={(result) => {
|
|
231
|
+
// result.structured is typed!
|
|
232
|
+
for (const issue of result.structured.issues) {
|
|
233
|
+
console.log(`[${issue.severity}] ${issue.file}: ${issue.description}`)
|
|
234
|
+
}
|
|
235
|
+
}}
|
|
236
|
+
>
|
|
237
|
+
Analyze this codebase for security issues.
|
|
238
|
+
</Claude>
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Database Access with MCP
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
<Claude model="sonnet" maxTurns={5}>
|
|
245
|
+
<Sqlite path="./analytics.db">
|
|
246
|
+
The database contains user_events and sessions tables. Use this to answer
|
|
247
|
+
questions about user behavior.
|
|
248
|
+
</Sqlite>
|
|
249
|
+
What are the top 10 most common user actions this week?
|
|
250
|
+
</Claude>
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Spawning Subagent Workflows
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
<Smithers
|
|
257
|
+
plannerModel="opus"
|
|
258
|
+
executionModel="sonnet"
|
|
259
|
+
onFinished={(result) => console.log(result.output)}
|
|
260
|
+
>
|
|
261
|
+
Create a comprehensive test suite for the authentication module. Include unit
|
|
262
|
+
tests, integration tests, and edge cases. Set up proper mocking for external
|
|
263
|
+
dependencies.
|
|
264
|
+
</Smithers>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Features
|
|
270
|
+
|
|
271
|
+
### Claude Component
|
|
272
|
+
|
|
273
|
+
The core agent component that executes Claude with full tool access:
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
<Claude
|
|
277
|
+
model="sonnet" // opus | sonnet | haiku
|
|
278
|
+
maxTurns={10} // Limit agentic loops
|
|
279
|
+
permissionMode="acceptEdits" // Auto-accept file edits
|
|
280
|
+
systemPrompt="You are a senior engineer..."
|
|
281
|
+
allowedTools={["Read", "Edit", "Bash"]}
|
|
282
|
+
stopConditions={[
|
|
283
|
+
{ type: "token_limit", value: 50000 },
|
|
284
|
+
{ type: "pattern", value: /DONE/i },
|
|
285
|
+
]}
|
|
286
|
+
onProgress={(msg) => console.log(msg)}
|
|
287
|
+
onFinished={(result) => handleResult(result)}
|
|
288
|
+
onError={(err) => handleError(err)}
|
|
289
|
+
>
|
|
290
|
+
Your prompt here
|
|
291
|
+
</Claude>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Ralph Loop Controller
|
|
295
|
+
|
|
296
|
+
Named after Ralph Wiggum's "I'm in danger" catchphrase - controls iterative loops that could run away:
|
|
297
|
+
|
|
298
|
+
```tsx
|
|
299
|
+
<Ralph maxIterations={10} onMaxIterations={() => console.log("I'm in danger!")}>
|
|
300
|
+
{/* Children re-render on each iteration */}
|
|
301
|
+
<Claude
|
|
302
|
+
onFinished={() => {
|
|
303
|
+
/* state change triggers next iteration */
|
|
304
|
+
}}
|
|
305
|
+
>
|
|
306
|
+
Keep improving until tests pass.
|
|
307
|
+
</Claude>
|
|
308
|
+
</Ralph>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Structured Output with Zod
|
|
312
|
+
|
|
313
|
+
Get typed, validated responses with automatic retry:
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
const UserSchema = z.object({
|
|
317
|
+
name: z.string(),
|
|
318
|
+
email: z.string().email(),
|
|
319
|
+
})
|
|
320
|
+
|
|
321
|
+
<Claude schema={UserSchema} schemaRetries={2}>
|
|
322
|
+
Extract user info from: John Doe (john@example.com)
|
|
323
|
+
</Claude>
|
|
324
|
+
// result.structured: { name: string, email: string }
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### MCP Tool Integration
|
|
328
|
+
|
|
329
|
+
Give Claude access to external tools via Model Context Protocol:
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
<Claude>
|
|
333
|
+
<Sqlite path="./data.db" readOnly>
|
|
334
|
+
Database schema: users(id, name, email), orders(id, user_id, total)
|
|
335
|
+
</Sqlite>
|
|
336
|
+
Generate a report of top customers by order value.
|
|
337
|
+
</Claude>
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Smithers Subagent
|
|
341
|
+
|
|
342
|
+
Spawn a new Smithers instance to plan and execute complex subtasks:
|
|
343
|
+
|
|
344
|
+
```tsx
|
|
345
|
+
<Smithers
|
|
346
|
+
plannerModel="opus" // Model for planning the script
|
|
347
|
+
executionModel="sonnet" // Model for agents in the script
|
|
348
|
+
timeout={600000} // 10 minute timeout
|
|
349
|
+
keepScript // Save the generated script for debugging
|
|
350
|
+
>
|
|
351
|
+
Create a new REST API endpoint with full CRUD operations, database migrations,
|
|
352
|
+
and comprehensive test coverage.
|
|
353
|
+
</Smithers>
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Git/JJ VCS Integration
|
|
357
|
+
|
|
358
|
+
First-class version control support:
|
|
359
|
+
|
|
360
|
+
```tsx
|
|
361
|
+
// Git
|
|
362
|
+
<Commit message="feat: Add user auth" notes={{ smithers: true }} />
|
|
363
|
+
|
|
364
|
+
// Jujutsu (jj)
|
|
365
|
+
<Snapshot description="Before refactoring" />
|
|
366
|
+
<Commit autoDescribe />
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### Database State Management
|
|
370
|
+
|
|
371
|
+
Persistent state that survives restarts:
|
|
372
|
+
|
|
373
|
+
```tsx
|
|
374
|
+
// Set state
|
|
375
|
+
await db.state.set("phase", "review", "code_complete");
|
|
376
|
+
|
|
377
|
+
// Get state
|
|
378
|
+
const phase = await db.state.get("phase");
|
|
379
|
+
|
|
380
|
+
// Query history
|
|
381
|
+
const history = await db.state.getHistory("phase");
|
|
382
|
+
|
|
383
|
+
// View all state
|
|
384
|
+
const all = await db.state.getAll();
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## Contributing
|
|
390
|
+
|
|
391
|
+
We accept **vibe-coded contributions** as long as you include your original prompt in a git note:
|
|
392
|
+
|
|
393
|
+
```bash
|
|
394
|
+
git notes add -m "User prompt: <your prompt here>"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for details.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
**Built with Solid.js, powered by Claude.**
|