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.
Files changed (254) hide show
  1. package/README.md +401 -0
  2. package/bin/cli.js +14259 -0
  3. package/bin/cli.ts +69 -0
  4. package/dist/components/Claude.d.ts +27 -0
  5. package/dist/components/Claude.d.ts.map +1 -0
  6. package/dist/components/Claude.jsx +82 -0
  7. package/dist/components/Claude.jsx.map +1 -0
  8. package/dist/components/Git/Commit.d.ts +33 -0
  9. package/dist/components/Git/Commit.d.ts.map +1 -0
  10. package/dist/components/Git/Commit.jsx +118 -0
  11. package/dist/components/Git/Commit.jsx.map +1 -0
  12. package/dist/components/Git/Notes.d.ts +25 -0
  13. package/dist/components/Git/Notes.d.ts.map +1 -0
  14. package/dist/components/Git/Notes.jsx +57 -0
  15. package/dist/components/Git/Notes.jsx.map +1 -0
  16. package/dist/components/Git/index.d.ts +3 -0
  17. package/dist/components/Git/index.d.ts.map +1 -0
  18. package/dist/components/Git/index.js +4 -0
  19. package/dist/components/Git/index.js.map +1 -0
  20. package/dist/components/Hooks/OnCIFailure.d.ts +42 -0
  21. package/dist/components/Hooks/OnCIFailure.d.ts.map +1 -0
  22. package/dist/components/Hooks/OnCIFailure.jsx +164 -0
  23. package/dist/components/Hooks/OnCIFailure.jsx.map +1 -0
  24. package/dist/components/Hooks/PostCommit.d.ts +32 -0
  25. package/dist/components/Hooks/PostCommit.d.ts.map +1 -0
  26. package/dist/components/Hooks/PostCommit.jsx +113 -0
  27. package/dist/components/Hooks/PostCommit.jsx.map +1 -0
  28. package/dist/components/Hooks/index.d.ts +3 -0
  29. package/dist/components/Hooks/index.d.ts.map +1 -0
  30. package/dist/components/Hooks/index.js +5 -0
  31. package/dist/components/Hooks/index.js.map +1 -0
  32. package/dist/components/JJ/Commit.d.ts +15 -0
  33. package/dist/components/JJ/Commit.d.ts.map +1 -0
  34. package/dist/components/JJ/Commit.jsx +83 -0
  35. package/dist/components/JJ/Commit.jsx.map +1 -0
  36. package/dist/components/JJ/Describe.d.ts +14 -0
  37. package/dist/components/JJ/Describe.d.ts.map +1 -0
  38. package/dist/components/JJ/Describe.jsx +77 -0
  39. package/dist/components/JJ/Describe.jsx.map +1 -0
  40. package/dist/components/JJ/Rebase.d.ts +15 -0
  41. package/dist/components/JJ/Rebase.d.ts.map +1 -0
  42. package/dist/components/JJ/Rebase.jsx +128 -0
  43. package/dist/components/JJ/Rebase.jsx.map +1 -0
  44. package/dist/components/JJ/Snapshot.d.ts +13 -0
  45. package/dist/components/JJ/Snapshot.d.ts.map +1 -0
  46. package/dist/components/JJ/Snapshot.jsx +52 -0
  47. package/dist/components/JJ/Snapshot.jsx.map +1 -0
  48. package/dist/components/JJ/Status.d.ts +18 -0
  49. package/dist/components/JJ/Status.d.ts.map +1 -0
  50. package/dist/components/JJ/Status.jsx +67 -0
  51. package/dist/components/JJ/Status.jsx.map +1 -0
  52. package/dist/components/JJ/index.d.ts +6 -0
  53. package/dist/components/JJ/index.d.ts.map +1 -0
  54. package/dist/components/JJ/index.js +8 -0
  55. package/dist/components/JJ/index.js.map +1 -0
  56. package/dist/components/MCP/Sqlite.d.ts +25 -0
  57. package/dist/components/MCP/Sqlite.d.ts.map +1 -0
  58. package/dist/components/MCP/Sqlite.jsx +24 -0
  59. package/dist/components/MCP/Sqlite.jsx.map +1 -0
  60. package/dist/components/MCP/index.d.ts +2 -0
  61. package/dist/components/MCP/index.d.ts.map +1 -0
  62. package/dist/components/MCP/index.js +4 -0
  63. package/dist/components/MCP/index.js.map +1 -0
  64. package/dist/components/Phase.d.ts +12 -0
  65. package/dist/components/Phase.d.ts.map +1 -0
  66. package/dist/components/Phase.jsx +10 -0
  67. package/dist/components/Phase.jsx.map +1 -0
  68. package/dist/components/Ralph.d.ts +28 -0
  69. package/dist/components/Ralph.d.ts.map +1 -0
  70. package/dist/components/Ralph.jsx +58 -0
  71. package/dist/components/Ralph.jsx.map +1 -0
  72. package/dist/components/Review.d.ts +56 -0
  73. package/dist/components/Review.d.ts.map +1 -0
  74. package/dist/components/Review.jsx +235 -0
  75. package/dist/components/Review.jsx.map +1 -0
  76. package/dist/components/Step.d.ts +12 -0
  77. package/dist/components/Step.d.ts.map +1 -0
  78. package/dist/components/Step.jsx +10 -0
  79. package/dist/components/Step.jsx.map +1 -0
  80. package/dist/components/index.d.ts +11 -0
  81. package/dist/components/index.d.ts.map +1 -0
  82. package/dist/components/index.js +16 -0
  83. package/dist/components/index.js.map +1 -0
  84. package/dist/core/execute.d.ts +15 -0
  85. package/dist/core/execute.d.ts.map +1 -0
  86. package/dist/core/execute.js +53 -0
  87. package/dist/core/execute.js.map +1 -0
  88. package/dist/core/index.d.ts +7 -0
  89. package/dist/core/index.d.ts.map +1 -0
  90. package/dist/core/index.js +6 -0
  91. package/dist/core/index.js.map +1 -0
  92. package/dist/core/root.d.ts +28 -0
  93. package/dist/core/root.d.ts.map +1 -0
  94. package/dist/core/root.js +40 -0
  95. package/dist/core/root.js.map +1 -0
  96. package/dist/core/serialize.d.ts +15 -0
  97. package/dist/core/serialize.d.ts.map +1 -0
  98. package/dist/core/serialize.js +90 -0
  99. package/dist/core/serialize.js.map +1 -0
  100. package/dist/core/types.d.ts +55 -0
  101. package/dist/core/types.d.ts.map +1 -0
  102. package/dist/core/types.js +11 -0
  103. package/dist/core/types.js.map +1 -0
  104. package/dist/debug/index.d.ts +10 -0
  105. package/dist/debug/index.d.ts.map +1 -0
  106. package/dist/debug/index.js +11 -0
  107. package/dist/debug/index.js.map +1 -0
  108. package/dist/index.d.ts +14 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +18 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/orchestrator/commands/db.d.ts +6 -0
  113. package/dist/orchestrator/commands/db.d.ts.map +1 -0
  114. package/dist/orchestrator/commands/db.js +272 -0
  115. package/dist/orchestrator/commands/db.js.map +1 -0
  116. package/dist/orchestrator/commands/init.d.ts +6 -0
  117. package/dist/orchestrator/commands/init.d.ts.map +1 -0
  118. package/dist/orchestrator/commands/init.js +61 -0
  119. package/dist/orchestrator/commands/init.js.map +1 -0
  120. package/dist/orchestrator/commands/monitor.d.ts +7 -0
  121. package/dist/orchestrator/commands/monitor.d.ts.map +1 -0
  122. package/dist/orchestrator/commands/monitor.js +136 -0
  123. package/dist/orchestrator/commands/monitor.js.map +1 -0
  124. package/dist/orchestrator/commands/run.d.ts +6 -0
  125. package/dist/orchestrator/commands/run.d.ts.map +1 -0
  126. package/dist/orchestrator/commands/run.js +62 -0
  127. package/dist/orchestrator/commands/run.js.map +1 -0
  128. package/dist/orchestrator/components/Claude.d.ts +31 -0
  129. package/dist/orchestrator/components/Claude.d.ts.map +1 -0
  130. package/dist/orchestrator/components/Claude.jsx +195 -0
  131. package/dist/orchestrator/components/Claude.jsx.map +1 -0
  132. package/dist/orchestrator/components/Orchestration.d.ts +76 -0
  133. package/dist/orchestrator/components/Orchestration.d.ts.map +1 -0
  134. package/dist/orchestrator/components/Orchestration.jsx +154 -0
  135. package/dist/orchestrator/components/Orchestration.jsx.map +1 -0
  136. package/dist/orchestrator/components/Phase.d.ts +35 -0
  137. package/dist/orchestrator/components/Phase.d.ts.map +1 -0
  138. package/dist/orchestrator/components/Phase.jsx +76 -0
  139. package/dist/orchestrator/components/Phase.jsx.map +1 -0
  140. package/dist/orchestrator/components/Smithers.d.ts +94 -0
  141. package/dist/orchestrator/components/Smithers.d.ts.map +1 -0
  142. package/dist/orchestrator/components/Smithers.jsx +128 -0
  143. package/dist/orchestrator/components/Smithers.jsx.map +1 -0
  144. package/dist/orchestrator/components/SmithersProvider.d.ts +95 -0
  145. package/dist/orchestrator/components/SmithersProvider.d.ts.map +1 -0
  146. package/dist/orchestrator/components/SmithersProvider.jsx +70 -0
  147. package/dist/orchestrator/components/SmithersProvider.jsx.map +1 -0
  148. package/dist/orchestrator/components/Step.d.ts +47 -0
  149. package/dist/orchestrator/components/Step.d.ts.map +1 -0
  150. package/dist/orchestrator/components/Step.jsx +120 -0
  151. package/dist/orchestrator/components/Step.jsx.map +1 -0
  152. package/dist/orchestrator/components/agents/ClaudeCodeCLI.d.ts +37 -0
  153. package/dist/orchestrator/components/agents/ClaudeCodeCLI.d.ts.map +1 -0
  154. package/dist/orchestrator/components/agents/ClaudeCodeCLI.js +440 -0
  155. package/dist/orchestrator/components/agents/ClaudeCodeCLI.js.map +1 -0
  156. package/dist/orchestrator/components/agents/SmithersCLI.d.ts +72 -0
  157. package/dist/orchestrator/components/agents/SmithersCLI.d.ts.map +1 -0
  158. package/dist/orchestrator/components/agents/SmithersCLI.js +274 -0
  159. package/dist/orchestrator/components/agents/SmithersCLI.js.map +1 -0
  160. package/dist/orchestrator/components/agents/types.d.ts +332 -0
  161. package/dist/orchestrator/components/agents/types.d.ts.map +1 -0
  162. package/dist/orchestrator/components/agents/types.js +4 -0
  163. package/dist/orchestrator/components/agents/types.js.map +1 -0
  164. package/dist/orchestrator/components/index.d.ts +14 -0
  165. package/dist/orchestrator/components/index.d.ts.map +1 -0
  166. package/dist/orchestrator/components/index.js +13 -0
  167. package/dist/orchestrator/components/index.js.map +1 -0
  168. package/dist/orchestrator/db/execution.d.ts +148 -0
  169. package/dist/orchestrator/db/execution.d.ts.map +1 -0
  170. package/dist/orchestrator/db/execution.js +497 -0
  171. package/dist/orchestrator/db/execution.js.map +1 -0
  172. package/dist/orchestrator/db/index.d.ts +381 -0
  173. package/dist/orchestrator/db/index.d.ts.map +1 -0
  174. package/dist/orchestrator/db/index.js +192 -0
  175. package/dist/orchestrator/db/index.js.map +1 -0
  176. package/dist/orchestrator/db/live-query.d.ts +39 -0
  177. package/dist/orchestrator/db/live-query.d.ts.map +1 -0
  178. package/dist/orchestrator/db/live-query.js +64 -0
  179. package/dist/orchestrator/db/live-query.js.map +1 -0
  180. package/dist/orchestrator/db/memories.d.ts +66 -0
  181. package/dist/orchestrator/db/memories.d.ts.map +1 -0
  182. package/dist/orchestrator/db/memories.js +193 -0
  183. package/dist/orchestrator/db/memories.js.map +1 -0
  184. package/dist/orchestrator/db/state.d.ts +62 -0
  185. package/dist/orchestrator/db/state.d.ts.map +1 -0
  186. package/dist/orchestrator/db/state.js +179 -0
  187. package/dist/orchestrator/db/state.js.map +1 -0
  188. package/dist/orchestrator/db/types.d.ts +198 -0
  189. package/dist/orchestrator/db/types.d.ts.map +1 -0
  190. package/dist/orchestrator/db/types.js +3 -0
  191. package/dist/orchestrator/db/types.js.map +1 -0
  192. package/dist/orchestrator/db/vcs.d.ts +96 -0
  193. package/dist/orchestrator/db/vcs.d.ts.map +1 -0
  194. package/dist/orchestrator/db/vcs.js +225 -0
  195. package/dist/orchestrator/db/vcs.js.map +1 -0
  196. package/dist/orchestrator/monitor/haiku-summarizer.d.ts +10 -0
  197. package/dist/orchestrator/monitor/haiku-summarizer.d.ts.map +1 -0
  198. package/dist/orchestrator/monitor/haiku-summarizer.js +59 -0
  199. package/dist/orchestrator/monitor/haiku-summarizer.js.map +1 -0
  200. package/dist/orchestrator/monitor/log-writer.d.ts +13 -0
  201. package/dist/orchestrator/monitor/log-writer.d.ts.map +1 -0
  202. package/dist/orchestrator/monitor/log-writer.js +64 -0
  203. package/dist/orchestrator/monitor/log-writer.js.map +1 -0
  204. package/dist/orchestrator/monitor/output-parser.d.ts +22 -0
  205. package/dist/orchestrator/monitor/output-parser.d.ts.map +1 -0
  206. package/dist/orchestrator/monitor/output-parser.js +114 -0
  207. package/dist/orchestrator/monitor/output-parser.js.map +1 -0
  208. package/dist/orchestrator/monitor/stream-formatter.d.ts +26 -0
  209. package/dist/orchestrator/monitor/stream-formatter.d.ts.map +1 -0
  210. package/dist/orchestrator/monitor/stream-formatter.js +137 -0
  211. package/dist/orchestrator/monitor/stream-formatter.js.map +1 -0
  212. package/dist/orchestrator/tools/ReportTool.d.ts +25 -0
  213. package/dist/orchestrator/tools/ReportTool.d.ts.map +1 -0
  214. package/dist/orchestrator/tools/ReportTool.js +136 -0
  215. package/dist/orchestrator/tools/ReportTool.js.map +1 -0
  216. package/dist/orchestrator/tools/index.d.ts +3 -0
  217. package/dist/orchestrator/tools/index.d.ts.map +1 -0
  218. package/dist/orchestrator/tools/index.js +8 -0
  219. package/dist/orchestrator/tools/index.js.map +1 -0
  220. package/dist/orchestrator/tools/registry.d.ts +132 -0
  221. package/dist/orchestrator/tools/registry.d.ts.map +1 -0
  222. package/dist/orchestrator/tools/registry.js +90 -0
  223. package/dist/orchestrator/tools/registry.js.map +1 -0
  224. package/dist/orchestrator/utils/mcp-config.d.ts +24 -0
  225. package/dist/orchestrator/utils/mcp-config.d.ts.map +1 -0
  226. package/dist/orchestrator/utils/mcp-config.js +82 -0
  227. package/dist/orchestrator/utils/mcp-config.js.map +1 -0
  228. package/dist/orchestrator/utils/structured-output.d.ts +41 -0
  229. package/dist/orchestrator/utils/structured-output.d.ts.map +1 -0
  230. package/dist/orchestrator/utils/structured-output.js +218 -0
  231. package/dist/orchestrator/utils/structured-output.js.map +1 -0
  232. package/dist/solid/index.d.ts +7 -0
  233. package/dist/solid/index.d.ts.map +1 -0
  234. package/dist/solid/index.js +8 -0
  235. package/dist/solid/index.js.map +1 -0
  236. package/dist/solid/renderer-methods.d.ts +20 -0
  237. package/dist/solid/renderer-methods.d.ts.map +1 -0
  238. package/dist/solid/renderer-methods.js +75 -0
  239. package/dist/solid/renderer-methods.js.map +1 -0
  240. package/dist/solid/renderer.d.ts +21 -0
  241. package/dist/solid/renderer.d.ts.map +1 -0
  242. package/dist/solid/renderer.js +42 -0
  243. package/dist/solid/renderer.js.map +1 -0
  244. package/dist/solid/root.d.ts +20 -0
  245. package/dist/solid/root.d.ts.map +1 -0
  246. package/dist/solid/root.js +38 -0
  247. package/dist/solid/root.js.map +1 -0
  248. package/dist/utils/vcs.d.ts +125 -0
  249. package/dist/utils/vcs.d.ts.map +1 -0
  250. package/dist/utils/vcs.js +271 -0
  251. package/dist/utils/vcs.js.map +1 -0
  252. package/package.json +103 -0
  253. package/postinstall.cjs +82 -0
  254. package/templates/main.tsx.template +320 -0
package/README.md ADDED
@@ -0,0 +1,401 @@
1
+ # Smithers
2
+
3
+ [![npm version](https://img.shields.io/npm/v/smithers.svg)](https://www.npmjs.com/package/smithers)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
+ [![Bun](https://img.shields.io/badge/Bun-1.0+-black.svg)](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
+ ![Smithers Demo](https://via.placeholder.com/800x400?text=Demo+GIF+Coming+Soon)
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.**