nodebench-mcp 2.17.0 → 2.18.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 (57) hide show
  1. package/LICENSE +21 -0
  2. package/NODEBENCH_AGENTS.md +2 -2
  3. package/README.md +514 -82
  4. package/dist/__tests__/analytics.test.d.ts +11 -0
  5. package/dist/__tests__/analytics.test.js +546 -0
  6. package/dist/__tests__/analytics.test.js.map +1 -0
  7. package/dist/__tests__/dynamicLoading.test.d.ts +1 -0
  8. package/dist/__tests__/dynamicLoading.test.js +278 -0
  9. package/dist/__tests__/dynamicLoading.test.js.map +1 -0
  10. package/dist/__tests__/evalHarness.test.js +1 -1
  11. package/dist/__tests__/evalHarness.test.js.map +1 -1
  12. package/dist/__tests__/helpers/answerMatch.js +22 -22
  13. package/dist/__tests__/presetRealWorldBench.test.js +9 -0
  14. package/dist/__tests__/presetRealWorldBench.test.js.map +1 -1
  15. package/dist/__tests__/tools.test.js +1 -1
  16. package/dist/__tests__/toolsetGatingEval.test.js +9 -1
  17. package/dist/__tests__/toolsetGatingEval.test.js.map +1 -1
  18. package/dist/analytics/index.d.ts +10 -0
  19. package/dist/analytics/index.js +11 -0
  20. package/dist/analytics/index.js.map +1 -0
  21. package/dist/analytics/projectDetector.d.ts +19 -0
  22. package/dist/analytics/projectDetector.js +259 -0
  23. package/dist/analytics/projectDetector.js.map +1 -0
  24. package/dist/analytics/schema.d.ts +57 -0
  25. package/dist/analytics/schema.js +157 -0
  26. package/dist/analytics/schema.js.map +1 -0
  27. package/dist/analytics/smartPreset.d.ts +63 -0
  28. package/dist/analytics/smartPreset.js +300 -0
  29. package/dist/analytics/smartPreset.js.map +1 -0
  30. package/dist/analytics/toolTracker.d.ts +59 -0
  31. package/dist/analytics/toolTracker.js +163 -0
  32. package/dist/analytics/toolTracker.js.map +1 -0
  33. package/dist/analytics/usageStats.d.ts +64 -0
  34. package/dist/analytics/usageStats.js +252 -0
  35. package/dist/analytics/usageStats.js.map +1 -0
  36. package/dist/db.js +359 -321
  37. package/dist/db.js.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.js +652 -89
  40. package/dist/index.js.map +1 -1
  41. package/dist/tools/architectTools.js +13 -13
  42. package/dist/tools/critterTools.js +14 -14
  43. package/dist/tools/parallelAgentTools.js +176 -176
  44. package/dist/tools/patternTools.js +11 -11
  45. package/dist/tools/progressiveDiscoveryTools.d.ts +5 -1
  46. package/dist/tools/progressiveDiscoveryTools.js +111 -19
  47. package/dist/tools/progressiveDiscoveryTools.js.map +1 -1
  48. package/dist/tools/researchWritingTools.js +42 -42
  49. package/dist/tools/rssTools.js +396 -396
  50. package/dist/tools/toolRegistry.d.ts +17 -0
  51. package/dist/tools/toolRegistry.js +65 -17
  52. package/dist/tools/toolRegistry.js.map +1 -1
  53. package/dist/tools/voiceBridgeTools.js +498 -498
  54. package/dist/toolsetRegistry.d.ts +10 -0
  55. package/dist/toolsetRegistry.js +84 -0
  56. package/dist/toolsetRegistry.js.map +1 -0
  57. package/package.json +4 -4
package/dist/db.js CHANGED
@@ -3,327 +3,365 @@ import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { mkdirSync } from "node:fs";
5
5
  let _db = null;
6
- const SCHEMA_SQL = `
7
- PRAGMA journal_mode = WAL;
8
- PRAGMA busy_timeout = 5000;
9
- PRAGMA foreign_keys = ON;
10
-
11
- -- ═══════════════════════════════════════════
12
- -- VERIFICATION CYCLES (6-Phase)
13
- -- ═══════════════════════════════════════════
14
-
15
- CREATE TABLE IF NOT EXISTS verification_cycles (
16
- id TEXT PRIMARY KEY,
17
- title TEXT NOT NULL,
18
- description TEXT,
19
- status TEXT NOT NULL DEFAULT 'active',
20
- current_phase INTEGER NOT NULL DEFAULT 1,
21
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
22
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
23
- );
24
-
25
- CREATE TABLE IF NOT EXISTS verification_phases (
26
- id TEXT PRIMARY KEY,
27
- cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
28
- phase_number INTEGER NOT NULL,
29
- phase_name TEXT NOT NULL,
30
- status TEXT NOT NULL DEFAULT 'pending',
31
- findings TEXT,
32
- started_at TEXT,
33
- completed_at TEXT,
34
- UNIQUE(cycle_id, phase_number)
35
- );
36
-
37
- CREATE TABLE IF NOT EXISTS gaps (
38
- id TEXT PRIMARY KEY,
39
- cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
40
- severity TEXT NOT NULL,
41
- title TEXT NOT NULL,
42
- description TEXT,
43
- root_cause TEXT,
44
- fix_strategy TEXT,
45
- status TEXT NOT NULL DEFAULT 'open',
46
- resolved_at TEXT,
47
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
48
- );
49
-
50
- CREATE VIRTUAL TABLE IF NOT EXISTS gaps_fts USING fts5(
51
- title,
52
- description,
53
- fix_strategy,
54
- content='gaps',
55
- content_rowid='rowid'
56
- );
57
-
58
- CREATE TRIGGER IF NOT EXISTS gaps_fts_insert AFTER INSERT ON gaps BEGIN
59
- INSERT INTO gaps_fts(rowid, title, description, fix_strategy)
60
- VALUES (new.rowid, new.title, COALESCE(new.description, ''), COALESCE(new.fix_strategy, ''));
61
- END;
62
-
63
- CREATE TRIGGER IF NOT EXISTS gaps_fts_delete AFTER DELETE ON gaps BEGIN
64
- INSERT INTO gaps_fts(gaps_fts, rowid, title, description, fix_strategy)
65
- VALUES ('delete', old.rowid, old.title, COALESCE(old.description, ''), COALESCE(old.fix_strategy, ''));
66
- END;
67
-
68
- CREATE TRIGGER IF NOT EXISTS gaps_fts_update AFTER UPDATE ON gaps BEGIN
69
- INSERT INTO gaps_fts(gaps_fts, rowid, title, description, fix_strategy)
70
- VALUES ('delete', old.rowid, old.title, COALESCE(old.description, ''), COALESCE(old.fix_strategy, ''));
71
- INSERT INTO gaps_fts(rowid, title, description, fix_strategy)
72
- VALUES (new.rowid, new.title, COALESCE(new.description, ''), COALESCE(new.fix_strategy, ''));
73
- END;
74
-
75
- CREATE TABLE IF NOT EXISTS test_results (
76
- id TEXT PRIMARY KEY,
77
- cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
78
- layer TEXT NOT NULL,
79
- label TEXT NOT NULL,
80
- passed INTEGER NOT NULL DEFAULT 0,
81
- output TEXT,
82
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
83
- );
84
-
85
- -- ═══════════════════════════════════════════
86
- -- EVAL RUNS (Eval-Driven Development)
87
- -- ═══════════════════════════════════════════
88
-
89
- CREATE TABLE IF NOT EXISTS eval_runs (
90
- id TEXT PRIMARY KEY,
91
- name TEXT NOT NULL,
92
- description TEXT,
93
- status TEXT NOT NULL DEFAULT 'pending',
94
- summary TEXT,
95
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
96
- completed_at TEXT
97
- );
98
-
99
- CREATE TABLE IF NOT EXISTS eval_cases (
100
- id TEXT PRIMARY KEY,
101
- run_id TEXT NOT NULL REFERENCES eval_runs(id) ON DELETE CASCADE,
102
- input TEXT NOT NULL,
103
- intent TEXT NOT NULL,
104
- expected TEXT,
105
- actual TEXT,
106
- telemetry TEXT,
107
- verdict TEXT,
108
- judge_notes TEXT,
109
- score REAL,
110
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
111
- );
112
-
113
- -- ═══════════════════════════════════════════
114
- -- QUALITY GATES (Boolean Check Pattern)
115
- -- ═══════════════════════════════════════════
116
-
117
- CREATE TABLE IF NOT EXISTS quality_gate_runs (
118
- id TEXT PRIMARY KEY,
119
- gate_name TEXT NOT NULL,
120
- target TEXT,
121
- passed INTEGER NOT NULL DEFAULT 0,
122
- score REAL,
123
- total_rules INTEGER NOT NULL DEFAULT 0,
124
- failures TEXT,
125
- rule_results TEXT,
126
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
127
- );
128
-
129
- -- ═══════════════════════════════════════════
130
- -- LEARNINGS (Agent Memory, reframed)
131
- -- ═══════════════════════════════════════════
132
-
133
- CREATE TABLE IF NOT EXISTS learnings (
134
- id INTEGER PRIMARY KEY AUTOINCREMENT,
135
- key TEXT NOT NULL UNIQUE,
136
- content TEXT NOT NULL,
137
- category TEXT NOT NULL DEFAULT 'general',
138
- tags TEXT,
139
- source_cycle TEXT,
140
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
141
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
142
- );
143
-
144
- CREATE VIRTUAL TABLE IF NOT EXISTS learnings_fts USING fts5(
145
- key,
146
- content,
147
- category,
148
- content='learnings',
149
- content_rowid='id'
150
- );
151
-
152
- CREATE TRIGGER IF NOT EXISTS learnings_fts_insert AFTER INSERT ON learnings BEGIN
153
- INSERT INTO learnings_fts(rowid, key, content, category)
154
- VALUES (new.id, new.key, new.content, new.category);
155
- END;
156
-
157
- CREATE TRIGGER IF NOT EXISTS learnings_fts_delete AFTER DELETE ON learnings BEGIN
158
- INSERT INTO learnings_fts(learnings_fts, rowid, key, content, category)
159
- VALUES ('delete', old.id, old.key, old.content, old.category);
160
- END;
161
-
162
- CREATE TRIGGER IF NOT EXISTS learnings_fts_update AFTER UPDATE ON learnings BEGIN
163
- INSERT INTO learnings_fts(learnings_fts, rowid, key, content, category)
164
- VALUES ('delete', old.id, old.key, old.content, old.category);
165
- INSERT INTO learnings_fts(rowid, key, content, category)
166
- VALUES (new.id, new.key, new.content, new.category);
167
- END;
168
-
169
- -- ═══════════════════════════════════════════
170
- -- RECONNAISSANCE (Research & Context Gathering)
171
- -- ═══════════════════════════════════════════
172
-
173
- CREATE TABLE IF NOT EXISTS recon_sessions (
174
- id TEXT PRIMARY KEY,
175
- target TEXT NOT NULL,
176
- description TEXT,
177
- status TEXT NOT NULL DEFAULT 'active',
178
- created_at TEXT NOT NULL DEFAULT (datetime('now')),
179
- completed_at TEXT
180
- );
181
-
182
- CREATE TABLE IF NOT EXISTS recon_findings (
183
- id TEXT PRIMARY KEY,
184
- session_id TEXT NOT NULL REFERENCES recon_sessions(id) ON DELETE CASCADE,
185
- source_url TEXT,
186
- category TEXT NOT NULL,
187
- summary TEXT NOT NULL,
188
- relevance TEXT,
189
- action_items TEXT,
190
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
191
- );
192
-
193
- CREATE INDEX IF NOT EXISTS idx_recon_findings_session ON recon_findings(session_id);
194
- CREATE INDEX IF NOT EXISTS idx_recon_findings_category ON recon_findings(category);
195
-
196
- CREATE VIRTUAL TABLE IF NOT EXISTS recon_findings_fts USING fts5(
197
- summary,
198
- relevance,
199
- action_items,
200
- content='recon_findings',
201
- content_rowid='rowid'
202
- );
203
-
204
- CREATE TRIGGER IF NOT EXISTS recon_findings_fts_insert AFTER INSERT ON recon_findings BEGIN
205
- INSERT INTO recon_findings_fts(rowid, summary, relevance, action_items)
206
- VALUES (new.rowid, new.summary, COALESCE(new.relevance, ''), COALESCE(new.action_items, ''));
207
- END;
208
-
209
- CREATE TRIGGER IF NOT EXISTS recon_findings_fts_delete AFTER DELETE ON recon_findings BEGIN
210
- INSERT INTO recon_findings_fts(recon_findings_fts, rowid, summary, relevance, action_items)
211
- VALUES ('delete', old.rowid, old.summary, COALESCE(old.relevance, ''), COALESCE(old.action_items, ''));
212
- END;
213
-
214
- CREATE TRIGGER IF NOT EXISTS recon_findings_fts_update AFTER UPDATE ON recon_findings BEGIN
215
- INSERT INTO recon_findings_fts(recon_findings_fts, rowid, summary, relevance, action_items)
216
- VALUES ('delete', old.rowid, old.summary, COALESCE(old.relevance, ''), COALESCE(old.action_items, ''));
217
- INSERT INTO recon_findings_fts(rowid, summary, relevance, action_items)
218
- VALUES (new.rowid, new.summary, COALESCE(new.relevance, ''), COALESCE(new.action_items, ''));
219
- END;
220
-
221
- -- ═══════════════════════════════════════════
222
- -- PROJECT CONTEXT (Persistent project metadata)
223
- -- ═══════════════════════════════════════════
224
-
225
- CREATE TABLE IF NOT EXISTS project_context (
226
- key TEXT PRIMARY KEY,
227
- value TEXT NOT NULL,
228
- updated_at TEXT NOT NULL DEFAULT (datetime('now'))
229
- );
230
-
231
- -- ═══════════════════════════════════════════
232
- -- TOOL CALL LOG (Self-Reinforced Learning)
233
- -- ═══════════════════════════════════════════
234
-
235
- CREATE TABLE IF NOT EXISTS tool_call_log (
236
- id TEXT PRIMARY KEY,
237
- session_id TEXT NOT NULL,
238
- tool_name TEXT NOT NULL,
239
- args_hash TEXT,
240
- result_status TEXT NOT NULL DEFAULT 'success',
241
- duration_ms INTEGER NOT NULL DEFAULT 0,
242
- error TEXT,
243
- phase TEXT,
244
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
245
- );
246
-
247
- CREATE INDEX IF NOT EXISTS idx_tool_call_log_session ON tool_call_log(session_id);
248
- CREATE INDEX IF NOT EXISTS idx_tool_call_log_tool ON tool_call_log(tool_name);
249
- CREATE INDEX IF NOT EXISTS idx_tool_call_log_created ON tool_call_log(created_at);
250
-
251
- -- ═══════════════════════════════════════════
252
- -- PARALLEL AGENT COORDINATION
253
- -- Based on Anthropic "Building a C Compiler with Parallel Claudes" (Feb 2026)
254
- -- ═══════════════════════════════════════════
255
-
256
- CREATE TABLE IF NOT EXISTS agent_tasks (
257
- id TEXT PRIMARY KEY,
258
- task_key TEXT NOT NULL,
259
- session_id TEXT NOT NULL,
260
- status TEXT NOT NULL DEFAULT 'claimed',
261
- description TEXT,
262
- progress_note TEXT,
263
- claimed_at TEXT NOT NULL DEFAULT (datetime('now')),
264
- released_at TEXT,
265
- UNIQUE(task_key, session_id)
266
- );
267
-
268
- CREATE INDEX IF NOT EXISTS idx_agent_tasks_key ON agent_tasks(task_key);
269
- CREATE INDEX IF NOT EXISTS idx_agent_tasks_status ON agent_tasks(status);
270
-
271
- CREATE TABLE IF NOT EXISTS agent_roles (
272
- id TEXT PRIMARY KEY,
273
- session_id TEXT NOT NULL UNIQUE,
274
- role TEXT NOT NULL,
275
- instructions TEXT,
276
- focus_area TEXT,
277
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
278
- );
279
-
280
- CREATE TABLE IF NOT EXISTS context_budget_log (
281
- id TEXT PRIMARY KEY,
282
- session_id TEXT NOT NULL,
283
- event_type TEXT NOT NULL,
284
- tokens_used INTEGER NOT NULL DEFAULT 0,
285
- tokens_limit INTEGER NOT NULL DEFAULT 200000,
286
- description TEXT,
287
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
288
- );
289
-
290
- CREATE INDEX IF NOT EXISTS idx_context_budget_session ON context_budget_log(session_id);
291
-
292
- CREATE TABLE IF NOT EXISTS oracle_comparisons (
293
- id TEXT PRIMARY KEY,
294
- test_label TEXT NOT NULL,
295
- oracle_source TEXT NOT NULL,
296
- actual_output TEXT NOT NULL,
297
- expected_output TEXT NOT NULL,
298
- match INTEGER NOT NULL DEFAULT 0,
299
- diff_summary TEXT,
300
- session_id TEXT,
301
- cycle_id TEXT,
302
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
303
- );
304
-
305
- CREATE INDEX IF NOT EXISTS idx_oracle_comparisons_label ON oracle_comparisons(test_label);
306
-
307
- -- ═══════════════════════════════════════════
308
- -- AGENT MAILBOX (Inter-agent messaging)
309
- -- ═══════════════════════════════════════════
310
-
311
- CREATE TABLE IF NOT EXISTS agent_mailbox (
312
- id TEXT PRIMARY KEY,
313
- sender_id TEXT NOT NULL,
314
- recipient_id TEXT,
315
- recipient_role TEXT,
316
- category TEXT NOT NULL DEFAULT 'status_report',
317
- priority TEXT NOT NULL DEFAULT 'normal',
318
- subject TEXT NOT NULL,
319
- body TEXT NOT NULL,
320
- read INTEGER NOT NULL DEFAULT 0,
321
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
322
- );
323
-
324
- CREATE INDEX IF NOT EXISTS idx_agent_mailbox_recipient ON agent_mailbox(recipient_id);
325
- CREATE INDEX IF NOT EXISTS idx_agent_mailbox_role ON agent_mailbox(recipient_role);
326
- CREATE INDEX IF NOT EXISTS idx_agent_mailbox_read ON agent_mailbox(read);
6
+ const SCHEMA_SQL = `
7
+ PRAGMA journal_mode = WAL;
8
+ PRAGMA busy_timeout = 5000;
9
+ PRAGMA foreign_keys = ON;
10
+
11
+ -- ═══════════════════════════════════════════
12
+ -- VERIFICATION CYCLES (6-Phase)
13
+ -- ═══════════════════════════════════════════
14
+
15
+ CREATE TABLE IF NOT EXISTS verification_cycles (
16
+ id TEXT PRIMARY KEY,
17
+ title TEXT NOT NULL,
18
+ description TEXT,
19
+ status TEXT NOT NULL DEFAULT 'active',
20
+ current_phase INTEGER NOT NULL DEFAULT 1,
21
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
22
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
23
+ );
24
+
25
+ CREATE TABLE IF NOT EXISTS verification_phases (
26
+ id TEXT PRIMARY KEY,
27
+ cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
28
+ phase_number INTEGER NOT NULL,
29
+ phase_name TEXT NOT NULL,
30
+ status TEXT NOT NULL DEFAULT 'pending',
31
+ findings TEXT,
32
+ started_at TEXT,
33
+ completed_at TEXT,
34
+ UNIQUE(cycle_id, phase_number)
35
+ );
36
+
37
+ CREATE TABLE IF NOT EXISTS gaps (
38
+ id TEXT PRIMARY KEY,
39
+ cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
40
+ severity TEXT NOT NULL,
41
+ title TEXT NOT NULL,
42
+ description TEXT,
43
+ root_cause TEXT,
44
+ fix_strategy TEXT,
45
+ status TEXT NOT NULL DEFAULT 'open',
46
+ resolved_at TEXT,
47
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
48
+ );
49
+
50
+ CREATE VIRTUAL TABLE IF NOT EXISTS gaps_fts USING fts5(
51
+ title,
52
+ description,
53
+ fix_strategy,
54
+ content='gaps',
55
+ content_rowid='rowid'
56
+ );
57
+
58
+ CREATE TRIGGER IF NOT EXISTS gaps_fts_insert AFTER INSERT ON gaps BEGIN
59
+ INSERT INTO gaps_fts(rowid, title, description, fix_strategy)
60
+ VALUES (new.rowid, new.title, COALESCE(new.description, ''), COALESCE(new.fix_strategy, ''));
61
+ END;
62
+
63
+ CREATE TRIGGER IF NOT EXISTS gaps_fts_delete AFTER DELETE ON gaps BEGIN
64
+ INSERT INTO gaps_fts(gaps_fts, rowid, title, description, fix_strategy)
65
+ VALUES ('delete', old.rowid, old.title, COALESCE(old.description, ''), COALESCE(old.fix_strategy, ''));
66
+ END;
67
+
68
+ CREATE TRIGGER IF NOT EXISTS gaps_fts_update AFTER UPDATE ON gaps BEGIN
69
+ INSERT INTO gaps_fts(gaps_fts, rowid, title, description, fix_strategy)
70
+ VALUES ('delete', old.rowid, old.title, COALESCE(old.description, ''), COALESCE(old.fix_strategy, ''));
71
+ INSERT INTO gaps_fts(rowid, title, description, fix_strategy)
72
+ VALUES (new.rowid, new.title, COALESCE(new.description, ''), COALESCE(new.fix_strategy, ''));
73
+ END;
74
+
75
+ CREATE TABLE IF NOT EXISTS test_results (
76
+ id TEXT PRIMARY KEY,
77
+ cycle_id TEXT NOT NULL REFERENCES verification_cycles(id) ON DELETE CASCADE,
78
+ layer TEXT NOT NULL,
79
+ label TEXT NOT NULL,
80
+ passed INTEGER NOT NULL DEFAULT 0,
81
+ output TEXT,
82
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
83
+ );
84
+
85
+ -- ═══════════════════════════════════════════
86
+ -- EVAL RUNS (Eval-Driven Development)
87
+ -- ═══════════════════════════════════════════
88
+
89
+ CREATE TABLE IF NOT EXISTS eval_runs (
90
+ id TEXT PRIMARY KEY,
91
+ name TEXT NOT NULL,
92
+ description TEXT,
93
+ status TEXT NOT NULL DEFAULT 'pending',
94
+ summary TEXT,
95
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
96
+ completed_at TEXT
97
+ );
98
+
99
+ CREATE TABLE IF NOT EXISTS eval_cases (
100
+ id TEXT PRIMARY KEY,
101
+ run_id TEXT NOT NULL REFERENCES eval_runs(id) ON DELETE CASCADE,
102
+ input TEXT NOT NULL,
103
+ intent TEXT NOT NULL,
104
+ expected TEXT,
105
+ actual TEXT,
106
+ telemetry TEXT,
107
+ verdict TEXT,
108
+ judge_notes TEXT,
109
+ score REAL,
110
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
111
+ );
112
+
113
+ -- ═══════════════════════════════════════════
114
+ -- QUALITY GATES (Boolean Check Pattern)
115
+ -- ═══════════════════════════════════════════
116
+
117
+ CREATE TABLE IF NOT EXISTS quality_gate_runs (
118
+ id TEXT PRIMARY KEY,
119
+ gate_name TEXT NOT NULL,
120
+ target TEXT,
121
+ passed INTEGER NOT NULL DEFAULT 0,
122
+ score REAL,
123
+ total_rules INTEGER NOT NULL DEFAULT 0,
124
+ failures TEXT,
125
+ rule_results TEXT,
126
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
127
+ );
128
+
129
+ -- ═══════════════════════════════════════════
130
+ -- LEARNINGS (Agent Memory, reframed)
131
+ -- ═══════════════════════════════════════════
132
+
133
+ CREATE TABLE IF NOT EXISTS learnings (
134
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
135
+ key TEXT NOT NULL UNIQUE,
136
+ content TEXT NOT NULL,
137
+ category TEXT NOT NULL DEFAULT 'general',
138
+ tags TEXT,
139
+ source_cycle TEXT,
140
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
141
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
142
+ );
143
+
144
+ CREATE VIRTUAL TABLE IF NOT EXISTS learnings_fts USING fts5(
145
+ key,
146
+ content,
147
+ category,
148
+ content='learnings',
149
+ content_rowid='id'
150
+ );
151
+
152
+ CREATE TRIGGER IF NOT EXISTS learnings_fts_insert AFTER INSERT ON learnings BEGIN
153
+ INSERT INTO learnings_fts(rowid, key, content, category)
154
+ VALUES (new.id, new.key, new.content, new.category);
155
+ END;
156
+
157
+ CREATE TRIGGER IF NOT EXISTS learnings_fts_delete AFTER DELETE ON learnings BEGIN
158
+ INSERT INTO learnings_fts(learnings_fts, rowid, key, content, category)
159
+ VALUES ('delete', old.id, old.key, old.content, old.category);
160
+ END;
161
+
162
+ CREATE TRIGGER IF NOT EXISTS learnings_fts_update AFTER UPDATE ON learnings BEGIN
163
+ INSERT INTO learnings_fts(learnings_fts, rowid, key, content, category)
164
+ VALUES ('delete', old.id, old.key, old.content, old.category);
165
+ INSERT INTO learnings_fts(rowid, key, content, category)
166
+ VALUES (new.id, new.key, new.content, new.category);
167
+ END;
168
+
169
+ -- ═══════════════════════════════════════════
170
+ -- RECONNAISSANCE (Research & Context Gathering)
171
+ -- ═══════════════════════════════════════════
172
+
173
+ CREATE TABLE IF NOT EXISTS recon_sessions (
174
+ id TEXT PRIMARY KEY,
175
+ target TEXT NOT NULL,
176
+ description TEXT,
177
+ status TEXT NOT NULL DEFAULT 'active',
178
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
179
+ completed_at TEXT
180
+ );
181
+
182
+ CREATE TABLE IF NOT EXISTS recon_findings (
183
+ id TEXT PRIMARY KEY,
184
+ session_id TEXT NOT NULL REFERENCES recon_sessions(id) ON DELETE CASCADE,
185
+ source_url TEXT,
186
+ category TEXT NOT NULL,
187
+ summary TEXT NOT NULL,
188
+ relevance TEXT,
189
+ action_items TEXT,
190
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
191
+ );
192
+
193
+ CREATE INDEX IF NOT EXISTS idx_recon_findings_session ON recon_findings(session_id);
194
+ CREATE INDEX IF NOT EXISTS idx_recon_findings_category ON recon_findings(category);
195
+
196
+ CREATE VIRTUAL TABLE IF NOT EXISTS recon_findings_fts USING fts5(
197
+ summary,
198
+ relevance,
199
+ action_items,
200
+ content='recon_findings',
201
+ content_rowid='rowid'
202
+ );
203
+
204
+ CREATE TRIGGER IF NOT EXISTS recon_findings_fts_insert AFTER INSERT ON recon_findings BEGIN
205
+ INSERT INTO recon_findings_fts(rowid, summary, relevance, action_items)
206
+ VALUES (new.rowid, new.summary, COALESCE(new.relevance, ''), COALESCE(new.action_items, ''));
207
+ END;
208
+
209
+ CREATE TRIGGER IF NOT EXISTS recon_findings_fts_delete AFTER DELETE ON recon_findings BEGIN
210
+ INSERT INTO recon_findings_fts(recon_findings_fts, rowid, summary, relevance, action_items)
211
+ VALUES ('delete', old.rowid, old.summary, COALESCE(old.relevance, ''), COALESCE(old.action_items, ''));
212
+ END;
213
+
214
+ CREATE TRIGGER IF NOT EXISTS recon_findings_fts_update AFTER UPDATE ON recon_findings BEGIN
215
+ INSERT INTO recon_findings_fts(recon_findings_fts, rowid, summary, relevance, action_items)
216
+ VALUES ('delete', old.rowid, old.summary, COALESCE(old.relevance, ''), COALESCE(old.action_items, ''));
217
+ INSERT INTO recon_findings_fts(rowid, summary, relevance, action_items)
218
+ VALUES (new.rowid, new.summary, COALESCE(new.relevance, ''), COALESCE(new.action_items, ''));
219
+ END;
220
+
221
+ -- ═══════════════════════════════════════════
222
+ -- PROJECT CONTEXT (Persistent project metadata)
223
+ -- ═══════════════════════════════════════════
224
+
225
+ CREATE TABLE IF NOT EXISTS project_context (
226
+ key TEXT PRIMARY KEY,
227
+ value TEXT NOT NULL,
228
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
229
+ );
230
+
231
+ -- ═══════════════════════════════════════════
232
+ -- TOOL CALL LOG (Self-Reinforced Learning)
233
+ -- ═══════════════════════════════════════════
234
+
235
+ CREATE TABLE IF NOT EXISTS tool_call_log (
236
+ id TEXT PRIMARY KEY,
237
+ session_id TEXT NOT NULL,
238
+ tool_name TEXT NOT NULL,
239
+ args_hash TEXT,
240
+ result_status TEXT NOT NULL DEFAULT 'success',
241
+ duration_ms INTEGER NOT NULL DEFAULT 0,
242
+ error TEXT,
243
+ phase TEXT,
244
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
245
+ );
246
+
247
+ CREATE INDEX IF NOT EXISTS idx_tool_call_log_session ON tool_call_log(session_id);
248
+ CREATE INDEX IF NOT EXISTS idx_tool_call_log_tool ON tool_call_log(tool_name);
249
+ CREATE INDEX IF NOT EXISTS idx_tool_call_log_created ON tool_call_log(created_at);
250
+
251
+ -- ═══════════════════════════════════════════
252
+ -- PARALLEL AGENT COORDINATION
253
+ -- Based on Anthropic "Building a C Compiler with Parallel Claudes" (Feb 2026)
254
+ -- ═══════════════════════════════════════════
255
+
256
+ CREATE TABLE IF NOT EXISTS agent_tasks (
257
+ id TEXT PRIMARY KEY,
258
+ task_key TEXT NOT NULL,
259
+ session_id TEXT NOT NULL,
260
+ status TEXT NOT NULL DEFAULT 'claimed',
261
+ description TEXT,
262
+ progress_note TEXT,
263
+ claimed_at TEXT NOT NULL DEFAULT (datetime('now')),
264
+ released_at TEXT,
265
+ UNIQUE(task_key, session_id)
266
+ );
267
+
268
+ CREATE INDEX IF NOT EXISTS idx_agent_tasks_key ON agent_tasks(task_key);
269
+ CREATE INDEX IF NOT EXISTS idx_agent_tasks_status ON agent_tasks(status);
270
+
271
+ CREATE TABLE IF NOT EXISTS agent_roles (
272
+ id TEXT PRIMARY KEY,
273
+ session_id TEXT NOT NULL UNIQUE,
274
+ role TEXT NOT NULL,
275
+ instructions TEXT,
276
+ focus_area TEXT,
277
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
278
+ );
279
+
280
+ CREATE TABLE IF NOT EXISTS context_budget_log (
281
+ id TEXT PRIMARY KEY,
282
+ session_id TEXT NOT NULL,
283
+ event_type TEXT NOT NULL,
284
+ tokens_used INTEGER NOT NULL DEFAULT 0,
285
+ tokens_limit INTEGER NOT NULL DEFAULT 200000,
286
+ description TEXT,
287
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
288
+ );
289
+
290
+ CREATE INDEX IF NOT EXISTS idx_context_budget_session ON context_budget_log(session_id);
291
+
292
+ CREATE TABLE IF NOT EXISTS oracle_comparisons (
293
+ id TEXT PRIMARY KEY,
294
+ test_label TEXT NOT NULL,
295
+ oracle_source TEXT NOT NULL,
296
+ actual_output TEXT NOT NULL,
297
+ expected_output TEXT NOT NULL,
298
+ match INTEGER NOT NULL DEFAULT 0,
299
+ diff_summary TEXT,
300
+ session_id TEXT,
301
+ cycle_id TEXT,
302
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
303
+ );
304
+
305
+ CREATE INDEX IF NOT EXISTS idx_oracle_comparisons_label ON oracle_comparisons(test_label);
306
+
307
+ -- ═══════════════════════════════════════════
308
+ -- AGENT MAILBOX (Inter-agent messaging)
309
+ -- ═══════════════════════════════════════════
310
+
311
+ CREATE TABLE IF NOT EXISTS agent_mailbox (
312
+ id TEXT PRIMARY KEY,
313
+ sender_id TEXT NOT NULL,
314
+ recipient_id TEXT,
315
+ recipient_role TEXT,
316
+ category TEXT NOT NULL DEFAULT 'status_report',
317
+ priority TEXT NOT NULL DEFAULT 'normal',
318
+ subject TEXT NOT NULL,
319
+ body TEXT NOT NULL,
320
+ read INTEGER NOT NULL DEFAULT 0,
321
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
322
+ );
323
+
324
+ CREATE INDEX IF NOT EXISTS idx_agent_mailbox_recipient ON agent_mailbox(recipient_id);
325
+ CREATE INDEX IF NOT EXISTS idx_agent_mailbox_role ON agent_mailbox(recipient_role);
326
+ CREATE INDEX IF NOT EXISTS idx_agent_mailbox_read ON agent_mailbox(read);
327
+
328
+ -- ═══════════════════════════════════════════
329
+ -- DYNAMIC LOADING A/B TEST TRACKING
330
+ -- Based on: Dynamic ReAct (arxiv 2509.20386),
331
+ -- Anthropic Tool Search Tool, Tool-to-Agent
332
+ -- Retrieval (arxiv 2511.01854)
333
+ -- ═══════════════════════════════════════════
334
+
335
+ CREATE TABLE IF NOT EXISTS ab_test_sessions (
336
+ id TEXT PRIMARY KEY,
337
+ mode TEXT NOT NULL, -- 'static' | 'dynamic'
338
+ initial_preset TEXT NOT NULL, -- preset at session start
339
+ initial_tool_count INTEGER NOT NULL,
340
+ final_tool_count INTEGER,
341
+ toolsets_loaded TEXT, -- JSON array of dynamically loaded toolsets
342
+ total_tool_calls INTEGER DEFAULT 0,
343
+ total_load_events INTEGER DEFAULT 0,
344
+ session_duration_ms INTEGER,
345
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
346
+ ended_at TEXT
347
+ );
348
+
349
+ CREATE TABLE IF NOT EXISTS ab_tool_events (
350
+ id TEXT PRIMARY KEY,
351
+ session_id TEXT NOT NULL,
352
+ event_type TEXT NOT NULL, -- 'load' | 'unload' | 'miss' | 'discovery_suggestion'
353
+ toolset_name TEXT,
354
+ tool_name TEXT,
355
+ tools_before INTEGER, -- tool count before event
356
+ tools_after INTEGER, -- tool count after event
357
+ latency_ms INTEGER,
358
+ metadata TEXT, -- JSON extra context
359
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
360
+ );
361
+
362
+ CREATE INDEX IF NOT EXISTS idx_ab_sessions_mode ON ab_test_sessions(mode);
363
+ CREATE INDEX IF NOT EXISTS idx_ab_events_session ON ab_tool_events(session_id);
364
+ CREATE INDEX IF NOT EXISTS idx_ab_events_type ON ab_tool_events(event_type);
327
365
  `;
328
366
  export function getDb() {
329
367
  if (_db)