smithers-orchestrator 0.1.7 → 0.1.8

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.
@@ -0,0 +1,429 @@
1
+ -- Smithers Orchestrator Database Schema
2
+ -- PGlite-based state management with full auditability
3
+
4
+ -- Enable extensions
5
+ -- Note: pgvector for embeddings, uuid for ID generation
6
+
7
+ -- ============================================================================
8
+ -- 1. MEMORIES - Long-term Agent Knowledge
9
+ -- ============================================================================
10
+
11
+ CREATE TABLE IF NOT EXISTS memories (
12
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
13
+
14
+ -- Categorization
15
+ category TEXT NOT NULL, -- 'fact', 'learning', 'preference', 'context', 'skill'
16
+ scope TEXT DEFAULT 'global', -- 'global', 'project', 'session'
17
+
18
+ -- Content
19
+ key TEXT NOT NULL, -- Unique identifier within category
20
+ content TEXT NOT NULL, -- The actual memory content
21
+ -- embedding VECTOR(1536), -- Optional: for semantic search (requires pgvector)
22
+
23
+ -- Metadata
24
+ confidence REAL DEFAULT 1.0, -- 0.0-1.0, how certain is this memory
25
+ source TEXT, -- Where did this come from (agent, user, tool)
26
+ source_execution_id UUID, -- Which execution created this
27
+
28
+ -- Timestamps
29
+ created_at TIMESTAMPTZ DEFAULT NOW(),
30
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
31
+ accessed_at TIMESTAMPTZ DEFAULT NOW(),
32
+ expires_at TIMESTAMPTZ, -- Optional TTL
33
+
34
+ -- Constraints
35
+ UNIQUE(category, scope, key)
36
+ );
37
+
38
+ CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
39
+ CREATE INDEX IF NOT EXISTS idx_memories_scope ON memories(scope);
40
+ CREATE INDEX IF NOT EXISTS idx_memories_key ON memories(key);
41
+ CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at DESC);
42
+
43
+ -- ============================================================================
44
+ -- 2. EXECUTIONS - Orchestration Runs
45
+ -- ============================================================================
46
+
47
+ CREATE TABLE IF NOT EXISTS executions (
48
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
49
+
50
+ -- Identity
51
+ name TEXT, -- Human-readable name
52
+ file_path TEXT NOT NULL, -- Path to .smithers/main.tsx
53
+
54
+ -- Status
55
+ status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'completed', 'failed', 'cancelled'
56
+
57
+ -- Configuration
58
+ config JSONB DEFAULT '{}', -- Max iterations, model settings, etc.
59
+
60
+ -- Results
61
+ result JSONB, -- Final output/result
62
+ error TEXT, -- Error message if failed
63
+
64
+ -- Timing
65
+ started_at TIMESTAMPTZ,
66
+ completed_at TIMESTAMPTZ,
67
+ created_at TIMESTAMPTZ DEFAULT NOW(),
68
+
69
+ -- Metrics
70
+ total_iterations INTEGER DEFAULT 0,
71
+ total_agents INTEGER DEFAULT 0,
72
+ total_tool_calls INTEGER DEFAULT 0,
73
+ total_tokens_used INTEGER DEFAULT 0
74
+ );
75
+
76
+ CREATE INDEX IF NOT EXISTS idx_executions_status ON executions(status);
77
+ CREATE INDEX IF NOT EXISTS idx_executions_created ON executions(created_at DESC);
78
+
79
+ -- ============================================================================
80
+ -- 3. PHASES - Workflow Stages
81
+ -- ============================================================================
82
+
83
+ CREATE TABLE IF NOT EXISTS phases (
84
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
85
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
86
+
87
+ -- Identity
88
+ name TEXT NOT NULL,
89
+ iteration INTEGER NOT NULL DEFAULT 0, -- Which Ralph iteration
90
+
91
+ -- Status
92
+ status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'completed', 'skipped', 'failed'
93
+
94
+ -- Timing
95
+ started_at TIMESTAMPTZ,
96
+ completed_at TIMESTAMPTZ,
97
+ created_at TIMESTAMPTZ DEFAULT NOW(),
98
+
99
+ -- Metrics
100
+ duration_ms INTEGER,
101
+ agents_count INTEGER DEFAULT 0
102
+ );
103
+
104
+ CREATE INDEX IF NOT EXISTS idx_phases_execution ON phases(execution_id);
105
+ CREATE INDEX IF NOT EXISTS idx_phases_status ON phases(status);
106
+ CREATE INDEX IF NOT EXISTS idx_phases_created ON phases(created_at DESC);
107
+
108
+ -- ============================================================================
109
+ -- 4. AGENTS - Claude Executions
110
+ -- ============================================================================
111
+
112
+ CREATE TABLE IF NOT EXISTS agents (
113
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
114
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
115
+ phase_id UUID REFERENCES phases(id) ON DELETE SET NULL,
116
+
117
+ -- Configuration
118
+ model TEXT NOT NULL DEFAULT 'sonnet',
119
+ system_prompt TEXT,
120
+
121
+ -- Input
122
+ prompt TEXT NOT NULL, -- The children content
123
+
124
+ -- Status
125
+ status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'completed', 'failed', 'cancelled'
126
+
127
+ -- Output
128
+ result TEXT, -- Agent's response
129
+ result_structured JSONB, -- Parsed/structured result if applicable
130
+ error TEXT,
131
+
132
+ -- Timing
133
+ started_at TIMESTAMPTZ,
134
+ completed_at TIMESTAMPTZ,
135
+ created_at TIMESTAMPTZ DEFAULT NOW(),
136
+
137
+ -- Metrics
138
+ duration_ms INTEGER,
139
+ tokens_input INTEGER,
140
+ tokens_output INTEGER,
141
+ tool_calls_count INTEGER DEFAULT 0
142
+ );
143
+
144
+ CREATE INDEX IF NOT EXISTS idx_agents_execution ON agents(execution_id);
145
+ CREATE INDEX IF NOT EXISTS idx_agents_phase ON agents(phase_id);
146
+ CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status);
147
+ CREATE INDEX IF NOT EXISTS idx_agents_created ON agents(created_at DESC);
148
+
149
+ -- ============================================================================
150
+ -- 5. TOOL_CALLS - Tool Invocations
151
+ -- ============================================================================
152
+
153
+ CREATE TABLE IF NOT EXISTS tool_calls (
154
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
155
+ agent_id UUID NOT NULL REFERENCES agents(id) ON DELETE CASCADE,
156
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
157
+
158
+ -- Tool info
159
+ tool_name TEXT NOT NULL, -- 'Read', 'Edit', 'Bash', 'Glob', etc.
160
+
161
+ -- Input (always stored - usually small)
162
+ input JSONB NOT NULL, -- Tool input parameters
163
+
164
+ -- Output strategy: inline for small, git reference for large
165
+ output_inline TEXT, -- Small outputs (<1KB) stored directly
166
+ output_path TEXT, -- Path to output file (for large outputs)
167
+ output_git_hash TEXT, -- Git hash of output file
168
+ output_summary TEXT, -- Haiku-generated summary (for large outputs)
169
+ output_size_bytes INTEGER,
170
+
171
+ -- Status
172
+ status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'completed', 'failed'
173
+ error TEXT,
174
+
175
+ -- Timing
176
+ started_at TIMESTAMPTZ,
177
+ completed_at TIMESTAMPTZ,
178
+ created_at TIMESTAMPTZ DEFAULT NOW(),
179
+ duration_ms INTEGER
180
+ );
181
+
182
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_agent ON tool_calls(agent_id);
183
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_execution ON tool_calls(execution_id);
184
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_name ON tool_calls(tool_name);
185
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_created ON tool_calls(created_at DESC);
186
+
187
+ -- ============================================================================
188
+ -- 6. STATE - Current State (Replaces Zustand)
189
+ -- ============================================================================
190
+
191
+ CREATE TABLE IF NOT EXISTS state (
192
+ key TEXT PRIMARY KEY,
193
+ value JSONB NOT NULL,
194
+ updated_at TIMESTAMPTZ DEFAULT NOW()
195
+ );
196
+
197
+ -- Initialize default state
198
+ INSERT INTO state (key, value) VALUES
199
+ ('phase', '"initial"'),
200
+ ('iteration', '0'),
201
+ ('data', 'null')
202
+ ON CONFLICT (key) DO NOTHING;
203
+
204
+ -- ============================================================================
205
+ -- 7. TRANSITIONS - State Audit Log (Flux-like)
206
+ -- ============================================================================
207
+
208
+ CREATE TABLE IF NOT EXISTS transitions (
209
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
210
+ execution_id UUID REFERENCES executions(id) ON DELETE CASCADE,
211
+
212
+ -- What changed
213
+ key TEXT NOT NULL,
214
+ old_value JSONB,
215
+ new_value JSONB NOT NULL,
216
+
217
+ -- Context
218
+ trigger TEXT, -- What caused this: 'agent_finished', 'user_action', 'init'
219
+ trigger_agent_id UUID REFERENCES agents(id),
220
+
221
+ -- Timing
222
+ created_at TIMESTAMPTZ DEFAULT NOW()
223
+ );
224
+
225
+ CREATE INDEX IF NOT EXISTS idx_transitions_execution ON transitions(execution_id);
226
+ CREATE INDEX IF NOT EXISTS idx_transitions_key ON transitions(key);
227
+ CREATE INDEX IF NOT EXISTS idx_transitions_created ON transitions(created_at DESC);
228
+
229
+ -- ============================================================================
230
+ -- 8. ARTIFACTS - Generated Files/Outputs (Git References)
231
+ -- ============================================================================
232
+
233
+ CREATE TABLE IF NOT EXISTS artifacts (
234
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
235
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
236
+ agent_id UUID REFERENCES agents(id) ON DELETE SET NULL,
237
+
238
+ -- Identity
239
+ name TEXT NOT NULL,
240
+ type TEXT NOT NULL, -- 'file', 'code', 'document', 'image', 'data'
241
+
242
+ -- Git reference (PRIMARY - content lives in git)
243
+ file_path TEXT NOT NULL, -- Path relative to repo root
244
+ git_hash TEXT, -- Git blob hash (after commit)
245
+ git_commit TEXT, -- Commit that introduced this artifact
246
+
247
+ -- Summary (for quick reference without git lookup)
248
+ summary TEXT, -- Brief description of content
249
+ line_count INTEGER,
250
+ byte_size INTEGER,
251
+
252
+ -- Metadata
253
+ metadata JSONB DEFAULT '{}', -- Language, mime type, etc.
254
+
255
+ -- Timing
256
+ created_at TIMESTAMPTZ DEFAULT NOW()
257
+ );
258
+
259
+ CREATE INDEX IF NOT EXISTS idx_artifacts_execution ON artifacts(execution_id);
260
+ CREATE INDEX IF NOT EXISTS idx_artifacts_type ON artifacts(type);
261
+ CREATE INDEX IF NOT EXISTS idx_artifacts_path ON artifacts(file_path);
262
+ CREATE INDEX IF NOT EXISTS idx_artifacts_git ON artifacts(git_hash);
263
+ CREATE INDEX IF NOT EXISTS idx_artifacts_created ON artifacts(created_at DESC);
264
+
265
+ -- ============================================================================
266
+ -- 9. REPORTS - Agent-Generated Reports
267
+ -- ============================================================================
268
+
269
+ CREATE TABLE IF NOT EXISTS reports (
270
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
271
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
272
+ agent_id UUID REFERENCES agents(id) ON DELETE SET NULL,
273
+
274
+ -- Report content
275
+ type TEXT NOT NULL, -- 'progress', 'finding', 'warning', 'error', 'metric', 'decision'
276
+ title TEXT NOT NULL,
277
+ content TEXT NOT NULL,
278
+ data JSONB, -- Structured data (optional)
279
+ severity TEXT DEFAULT 'info', -- 'info', 'warning', 'critical'
280
+
281
+ -- Timing
282
+ created_at TIMESTAMPTZ DEFAULT NOW()
283
+ );
284
+
285
+ CREATE INDEX IF NOT EXISTS idx_reports_execution ON reports(execution_id);
286
+ CREATE INDEX IF NOT EXISTS idx_reports_agent ON reports(agent_id);
287
+ CREATE INDEX IF NOT EXISTS idx_reports_type ON reports(type);
288
+ CREATE INDEX IF NOT EXISTS idx_reports_severity ON reports(severity);
289
+ CREATE INDEX IF NOT EXISTS idx_reports_created ON reports(created_at DESC);
290
+
291
+ -- ============================================================================
292
+ -- 10. COMMITS - Version Control Commits
293
+ -- ============================================================================
294
+
295
+ CREATE TABLE IF NOT EXISTS commits (
296
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
297
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
298
+ agent_id UUID REFERENCES agents(id) ON DELETE SET NULL,
299
+
300
+ -- VCS info
301
+ vcs_type TEXT NOT NULL, -- 'git', 'jj'
302
+ commit_hash TEXT NOT NULL,
303
+ change_id TEXT, -- JJ change ID (if applicable)
304
+
305
+ -- Commit details
306
+ message TEXT NOT NULL,
307
+ author TEXT,
308
+
309
+ -- Stats
310
+ files_changed TEXT[],
311
+ insertions INTEGER,
312
+ deletions INTEGER,
313
+
314
+ -- Smithers metadata (from git notes)
315
+ smithers_metadata JSONB,
316
+
317
+ -- Timing
318
+ created_at TIMESTAMPTZ DEFAULT NOW(),
319
+
320
+ -- Ensure unique commits per VCS
321
+ UNIQUE(vcs_type, commit_hash)
322
+ );
323
+
324
+ CREATE INDEX IF NOT EXISTS idx_commits_execution ON commits(execution_id);
325
+ CREATE INDEX IF NOT EXISTS idx_commits_agent ON commits(agent_id);
326
+ CREATE INDEX IF NOT EXISTS idx_commits_hash ON commits(commit_hash);
327
+ CREATE INDEX IF NOT EXISTS idx_commits_vcs ON commits(vcs_type);
328
+ CREATE INDEX IF NOT EXISTS idx_commits_created ON commits(created_at DESC);
329
+
330
+ -- ============================================================================
331
+ -- 11. SNAPSHOTS - JJ Working Copy Snapshots
332
+ -- ============================================================================
333
+
334
+ CREATE TABLE IF NOT EXISTS snapshots (
335
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
336
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
337
+
338
+ -- JJ snapshot info
339
+ change_id TEXT NOT NULL,
340
+ commit_hash TEXT,
341
+ description TEXT,
342
+
343
+ -- File changes
344
+ files_modified TEXT[],
345
+ files_added TEXT[],
346
+ files_deleted TEXT[],
347
+
348
+ -- Status
349
+ has_conflicts BOOLEAN DEFAULT false,
350
+
351
+ -- Timing
352
+ created_at TIMESTAMPTZ DEFAULT NOW()
353
+ );
354
+
355
+ CREATE INDEX IF NOT EXISTS idx_snapshots_execution ON snapshots(execution_id);
356
+ CREATE INDEX IF NOT EXISTS idx_snapshots_change ON snapshots(change_id);
357
+ CREATE INDEX IF NOT EXISTS idx_snapshots_created ON snapshots(created_at DESC);
358
+
359
+ -- ============================================================================
360
+ -- 12. REVIEWS - Code Reviews
361
+ -- ============================================================================
362
+
363
+ CREATE TABLE IF NOT EXISTS reviews (
364
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
365
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
366
+ agent_id UUID REFERENCES agents(id) ON DELETE SET NULL,
367
+
368
+ -- Review target
369
+ target_type TEXT NOT NULL, -- 'commit', 'diff', 'pr', 'files'
370
+ target_ref TEXT, -- Commit hash, PR number, etc.
371
+
372
+ -- Review result
373
+ approved BOOLEAN NOT NULL,
374
+ summary TEXT NOT NULL,
375
+ issues JSONB NOT NULL, -- Array of {severity, file, line, message, suggestion}
376
+ approvals JSONB, -- Array of {aspect, reason}
377
+
378
+ -- Reviewer info
379
+ reviewer_model TEXT, -- 'claude-sonnet-4', etc.
380
+
381
+ -- Behavior
382
+ blocking BOOLEAN DEFAULT false,
383
+
384
+ -- Post-review actions
385
+ posted_to_github BOOLEAN DEFAULT false,
386
+ posted_to_git_notes BOOLEAN DEFAULT false,
387
+
388
+ -- Timing
389
+ created_at TIMESTAMPTZ DEFAULT NOW()
390
+ );
391
+
392
+ CREATE INDEX IF NOT EXISTS idx_reviews_execution ON reviews(execution_id);
393
+ CREATE INDEX IF NOT EXISTS idx_reviews_agent ON reviews(agent_id);
394
+ CREATE INDEX IF NOT EXISTS idx_reviews_approved ON reviews(approved);
395
+ CREATE INDEX IF NOT EXISTS idx_reviews_target ON reviews(target_type);
396
+ CREATE INDEX IF NOT EXISTS idx_reviews_blocking ON reviews(blocking);
397
+ CREATE INDEX IF NOT EXISTS idx_reviews_created ON reviews(created_at DESC);
398
+
399
+ -- ============================================================================
400
+ -- 13. STEPS - Fine-grained step tracking
401
+ -- ============================================================================
402
+
403
+ CREATE TABLE IF NOT EXISTS steps (
404
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
405
+ execution_id UUID NOT NULL REFERENCES executions(id) ON DELETE CASCADE,
406
+ phase_id UUID REFERENCES phases(id) ON DELETE SET NULL,
407
+
408
+ -- Identity
409
+ name TEXT,
410
+
411
+ -- Status
412
+ status TEXT NOT NULL DEFAULT 'pending', -- 'pending', 'running', 'completed', 'failed', 'skipped'
413
+
414
+ -- Timing
415
+ started_at TIMESTAMPTZ,
416
+ completed_at TIMESTAMPTZ,
417
+ created_at TIMESTAMPTZ DEFAULT NOW(),
418
+ duration_ms INTEGER,
419
+
420
+ -- VCS integration
421
+ snapshot_before TEXT, -- JJ commit ID before step
422
+ snapshot_after TEXT, -- JJ commit ID after step
423
+ commit_created TEXT -- Commit hash if commitAfter was used
424
+ );
425
+
426
+ CREATE INDEX IF NOT EXISTS idx_steps_execution ON steps(execution_id);
427
+ CREATE INDEX IF NOT EXISTS idx_steps_phase ON steps(phase_id);
428
+ CREATE INDEX IF NOT EXISTS idx_steps_status ON steps(status);
429
+ CREATE INDEX IF NOT EXISTS idx_steps_created ON steps(created_at DESC);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smithers-orchestrator",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "Build AI agents with Solid.js - Declarative JSX for Claude orchestration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -103,7 +103,7 @@
103
103
  "README.md"
104
104
  ],
105
105
  "scripts": {
106
- "build": "tsc && bun build bin/cli.ts --outdir bin --target node",
106
+ "build": "tsc && cp src/orchestrator/db/schema.sql dist/orchestrator/db/ && bun build bin/cli.ts --outdir bin --target node",
107
107
  "build:cli": "bun build bin/cli.ts --outdir bin --target node",
108
108
  "dev": "tsc --watch",
109
109
  "typecheck": "tsc --noEmit",