waymark-hub 1.0.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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +176 -0
  3. package/dashboard/README.md +71 -0
  4. package/dashboard/index.html +520 -0
  5. package/dashboard/server.mjs +343 -0
  6. package/dashboard/vendor/tailwind.js +83 -0
  7. package/dist/cli/benchmark.d.ts +3 -0
  8. package/dist/cli/benchmark.d.ts.map +1 -0
  9. package/dist/cli/benchmark.js +222 -0
  10. package/dist/cli/benchmark.js.map +1 -0
  11. package/dist/cli/waymark.d.ts +3 -0
  12. package/dist/cli/waymark.d.ts.map +1 -0
  13. package/dist/cli/waymark.js +216 -0
  14. package/dist/cli/waymark.js.map +1 -0
  15. package/dist/context/builder.d.ts +67 -0
  16. package/dist/context/builder.d.ts.map +1 -0
  17. package/dist/context/builder.js +270 -0
  18. package/dist/context/builder.js.map +1 -0
  19. package/dist/db/client.d.ts +5 -0
  20. package/dist/db/client.d.ts.map +1 -0
  21. package/dist/db/client.js +67 -0
  22. package/dist/db/client.js.map +1 -0
  23. package/dist/db/migrations/001_initial.sql +85 -0
  24. package/dist/db/migrations/002_usage_experiments.sql +52 -0
  25. package/dist/db/migrations/003_agent_identity.sql +37 -0
  26. package/dist/db/migrations/004_memory_lifecycle.sql +25 -0
  27. package/dist/db/migrations/005_task_coordination.sql +17 -0
  28. package/dist/db/schema.d.ts +132 -0
  29. package/dist/db/schema.d.ts.map +1 -0
  30. package/dist/db/schema.js +3 -0
  31. package/dist/db/schema.js.map +1 -0
  32. package/dist/server.d.ts +12 -0
  33. package/dist/server.d.ts.map +1 -0
  34. package/dist/server.js +164 -0
  35. package/dist/server.js.map +1 -0
  36. package/dist/telemetry/tokens.d.ts +9 -0
  37. package/dist/telemetry/tokens.d.ts.map +1 -0
  38. package/dist/telemetry/tokens.js +23 -0
  39. package/dist/telemetry/tokens.js.map +1 -0
  40. package/dist/tools/agents.d.ts +3 -0
  41. package/dist/tools/agents.d.ts.map +1 -0
  42. package/dist/tools/agents.js +126 -0
  43. package/dist/tools/agents.js.map +1 -0
  44. package/dist/tools/context.d.ts +3 -0
  45. package/dist/tools/context.d.ts.map +1 -0
  46. package/dist/tools/context.js +53 -0
  47. package/dist/tools/context.js.map +1 -0
  48. package/dist/tools/memory.d.ts +3 -0
  49. package/dist/tools/memory.d.ts.map +1 -0
  50. package/dist/tools/memory.js +273 -0
  51. package/dist/tools/memory.js.map +1 -0
  52. package/dist/tools/projects.d.ts +3 -0
  53. package/dist/tools/projects.d.ts.map +1 -0
  54. package/dist/tools/projects.js +92 -0
  55. package/dist/tools/projects.js.map +1 -0
  56. package/dist/tools/sessions.d.ts +3 -0
  57. package/dist/tools/sessions.d.ts.map +1 -0
  58. package/dist/tools/sessions.js +113 -0
  59. package/dist/tools/sessions.js.map +1 -0
  60. package/dist/tools/tasks.d.ts +3 -0
  61. package/dist/tools/tasks.d.ts.map +1 -0
  62. package/dist/tools/tasks.js +304 -0
  63. package/dist/tools/tasks.js.map +1 -0
  64. package/dist/tools/telemetry.d.ts +3 -0
  65. package/dist/tools/telemetry.d.ts.map +1 -0
  66. package/dist/tools/telemetry.js +291 -0
  67. package/dist/tools/telemetry.js.map +1 -0
  68. package/docs/AGENT_IDENTITY.md +67 -0
  69. package/docs/BENCHMARKING.md +161 -0
  70. package/docs/CONTEXT.md +95 -0
  71. package/docs/MEMORY_LIFECYCLE.md +65 -0
  72. package/docs/TASK_COORDINATION.md +27 -0
  73. package/package.json +70 -0
  74. package/scripts/hooks/session-start-resume.cjs +70 -0
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildContextPacket = buildContextPacket;
4
+ const client_js_1 = require("../db/client.js");
5
+ const tokens_js_1 = require("../telemetry/tokens.js");
6
+ const TYPE_WEIGHT = {
7
+ handoff: 60,
8
+ decision: 50,
9
+ user: 45,
10
+ feedback: 35,
11
+ project: 30,
12
+ reference: 20,
13
+ };
14
+ const FEEDBACK_WEIGHT = {
15
+ used: 3,
16
+ helpful: 8,
17
+ not_used: -2,
18
+ irrelevant: -12,
19
+ stale: -20,
20
+ incorrect: -30,
21
+ too_verbose: -5,
22
+ };
23
+ function terms(value) {
24
+ return new Set(value.toLowerCase()
25
+ .split(/[^\p{L}\p{N}_-]+/u)
26
+ .map(term => term.trim())
27
+ .filter(term => term.length >= 3));
28
+ }
29
+ function overlapScore(queryTerms, value) {
30
+ if (queryTerms.size === 0)
31
+ return 0;
32
+ const valueTerms = terms(value);
33
+ let matches = 0;
34
+ for (const term of queryTerms) {
35
+ if (valueTerms.has(term))
36
+ matches++;
37
+ }
38
+ return matches * 25;
39
+ }
40
+ function recencyScore(updatedAt) {
41
+ const ageMs = Date.now() - new Date(updatedAt).getTime();
42
+ if (!Number.isFinite(ageMs) || ageMs < 0)
43
+ return 10;
44
+ const ageDays = ageMs / 86_400_000;
45
+ if (ageDays <= 1)
46
+ return 15;
47
+ if (ageDays <= 7)
48
+ return 10;
49
+ if (ageDays <= 30)
50
+ return 5;
51
+ return 0;
52
+ }
53
+ function compact(value, maxChars) {
54
+ if (value === null)
55
+ return null;
56
+ const normalized = value.replace(/\s+/g, ' ').trim();
57
+ if (normalized.length <= maxChars)
58
+ return normalized;
59
+ return `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
60
+ }
61
+ function packetTokens(packet) {
62
+ const serializable = { ...packet, estimated_tokens: 999_999 };
63
+ return (0, tokens_js_1.estimateTokens)(JSON.stringify(serializable, null, 2));
64
+ }
65
+ function fits(packet) {
66
+ return packetTokens(packet) <= packet.max_tokens;
67
+ }
68
+ function finalize(packet) {
69
+ packet.estimated_tokens = packetTokens(packet);
70
+ return packet;
71
+ }
72
+ function addWithinBudget(packet, target, item) {
73
+ target.push(item);
74
+ if (fits(packet))
75
+ return true;
76
+ target.pop();
77
+ return false;
78
+ }
79
+ function parseTags(tags) {
80
+ if (!tags)
81
+ return '';
82
+ try {
83
+ const parsed = JSON.parse(tags);
84
+ return Array.isArray(parsed) ? parsed.join(' ') : tags;
85
+ }
86
+ catch {
87
+ return tags;
88
+ }
89
+ }
90
+ function buildContextPacket(options) {
91
+ const db = (0, client_js_1.getDb)();
92
+ const project = db.prepare('SELECT * FROM projects WHERE id = ?').get(options.projectId);
93
+ if (!project)
94
+ return null;
95
+ const queryTerms = terms(options.task ?? '');
96
+ const packet = {
97
+ project: {
98
+ id: project.id,
99
+ name: compact(project.name, 120) ?? project.name,
100
+ root_path: compact(project.root_path, 240) ?? project.root_path,
101
+ stack: compact(project.stack, 240),
102
+ description: compact(project.description, 360),
103
+ },
104
+ task: compact(options.task ?? null, 500),
105
+ active_tasks: [],
106
+ memories: [],
107
+ recent_sessions: [],
108
+ omitted: {
109
+ active_tasks: 0,
110
+ memories: 0,
111
+ recent_sessions: 0,
112
+ },
113
+ estimated_tokens: 0,
114
+ max_tokens: options.maxTokens,
115
+ };
116
+ const notices = [];
117
+ if (options.agentId) {
118
+ const knownAgent = db.prepare('SELECT 1 FROM agents WHERE id = ?').get(options.agentId);
119
+ if (!knownAgent) {
120
+ notices.push(`agent_id "${options.agentId}" is not registered; call agent_register (HUB_TOOLS=full) ` +
121
+ 'or reuse a registered id so sessions and handoffs are attributed.');
122
+ }
123
+ }
124
+ else {
125
+ notices.push('No agent_id supplied: pass a stable agent_id so other agents can see who did what.');
126
+ }
127
+ if (notices.length)
128
+ packet.notices = notices;
129
+ // Very small budgets keep identity and task while progressively trimming metadata.
130
+ if (!fits(packet))
131
+ packet.project.description = null;
132
+ if (!fits(packet))
133
+ packet.project.stack = null;
134
+ if (!fits(packet))
135
+ packet.project.root_path = '';
136
+ if (!fits(packet) && packet.task)
137
+ packet.task = compact(packet.task, 160);
138
+ const taskRows = db.prepare(`
139
+ SELECT * FROM tasks
140
+ WHERE project_id = ?
141
+ AND status IN ('pending', 'in_progress')
142
+ ORDER BY
143
+ CASE WHEN assigned_agent_id = ? THEN 0
144
+ WHEN assigned_to = ? THEN 1
145
+ WHEN assigned_agent_id IS NULL AND assigned_to IS NULL THEN 2
146
+ ELSE 3 END,
147
+ priority DESC,
148
+ updated_at DESC
149
+ `).all(options.projectId, options.agentId ?? null, options.clientId ?? null);
150
+ for (const row of taskRows) {
151
+ const item = {
152
+ id: row.id,
153
+ title: compact(row.title, 180) ?? row.title,
154
+ description: compact(row.description, 320),
155
+ status: row.status,
156
+ priority: row.priority,
157
+ assigned_to: row.assigned_to,
158
+ assigned_agent_id: row.assigned_agent_id,
159
+ updated_at: row.updated_at,
160
+ };
161
+ if (!addWithinBudget(packet, packet.active_tasks, item)) {
162
+ packet.omitted.active_tasks++;
163
+ }
164
+ }
165
+ // Handoffs are inherently project-bound: a global one is almost always a
166
+ // session_log that forgot project_id, and surfacing it in every project's
167
+ // resume cross-contaminates unrelated work.
168
+ const memories = db.prepare(`
169
+ SELECT * FROM memory_nodes
170
+ WHERE (project_id = ? OR project_id IS NULL)
171
+ AND status = 'active'
172
+ AND NOT (type = 'handoff' AND project_id IS NULL)
173
+ AND (valid_from IS NULL OR valid_from <= ?)
174
+ AND (valid_until IS NULL OR valid_until >= ?)
175
+ ORDER BY updated_at DESC
176
+ `).all(options.projectId, new Date().toISOString(), new Date().toISOString());
177
+ const feedbackRows = db.prepare(`
178
+ SELECT memory_id, rating, COUNT(*) AS count
179
+ FROM memory_feedback
180
+ GROUP BY memory_id, rating
181
+ `).all();
182
+ const feedbackScores = new Map();
183
+ for (const feedback of feedbackRows) {
184
+ const current = feedbackScores.get(feedback.memory_id) ?? 0;
185
+ feedbackScores.set(feedback.memory_id, current + (FEEDBACK_WEIGHT[feedback.rating] ?? 0) * feedback.count);
186
+ }
187
+ const rankedMemories = memories
188
+ .filter(row => !options.memoryTypes || options.memoryTypes.includes(row.type))
189
+ .map(row => {
190
+ const searchable = [
191
+ row.name,
192
+ row.description ?? '',
193
+ row.body,
194
+ parseTags(row.tags),
195
+ ].join(' ');
196
+ const projectBoost = row.project_id === options.projectId ? 20 : 0;
197
+ const termScore = overlapScore(queryTerms, searchable);
198
+ const recentScore = recencyScore(row.updated_at);
199
+ const feedbackScore = feedbackScores.get(row.id) ?? 0;
200
+ const reasons = [
201
+ row.type,
202
+ row.project_id === options.projectId ? 'project-memory' : 'global-memory',
203
+ ];
204
+ if (termScore > 0)
205
+ reasons.push('task-term-match');
206
+ if (recentScore >= 10)
207
+ reasons.push('recent');
208
+ if (row.importance >= 75)
209
+ reasons.push('high-importance');
210
+ if (row.confidence >= 75)
211
+ reasons.push('high-confidence');
212
+ if (feedbackScore > 0)
213
+ reasons.push('positive-feedback');
214
+ return {
215
+ row,
216
+ score: TYPE_WEIGHT[row.type] +
217
+ projectBoost +
218
+ termScore +
219
+ recentScore +
220
+ Math.round(row.importance / 5) +
221
+ Math.round(row.confidence / 10) +
222
+ feedbackScore,
223
+ reasons,
224
+ };
225
+ })
226
+ .sort((a, b) => b.score - a.score || b.row.updated_at.localeCompare(a.row.updated_at));
227
+ for (const { row, score, reasons } of rankedMemories) {
228
+ const item = {
229
+ id: row.id,
230
+ name: compact(row.name, 120) ?? row.name,
231
+ type: row.type,
232
+ summary: compact(row.description || row.body, 360) ?? '',
233
+ updated_at: row.updated_at,
234
+ source: row.project_id === options.projectId ? 'project' : 'global',
235
+ score,
236
+ reasons,
237
+ importance: row.importance,
238
+ confidence: row.confidence,
239
+ source_type: row.source_type,
240
+ source_ref: row.source_ref,
241
+ };
242
+ if (options.includeSources) {
243
+ item.body = compact(row.body, 1000) ?? '';
244
+ }
245
+ if (!addWithinBudget(packet, packet.memories, item)) {
246
+ packet.omitted.memories++;
247
+ }
248
+ }
249
+ const sessions = db.prepare(`
250
+ SELECT * FROM sessions
251
+ WHERE project_id = ? AND summary IS NOT NULL
252
+ ORDER BY COALESCE(ended_at, started_at) DESC
253
+ LIMIT 20
254
+ `).all(options.projectId);
255
+ for (const row of sessions) {
256
+ const item = {
257
+ id: row.id,
258
+ summary: compact(row.summary, 360),
259
+ outcome: row.outcome,
260
+ agent_id: row.agent_id,
261
+ client: row.client ?? row.surface,
262
+ ended_at: row.ended_at,
263
+ };
264
+ if (!addWithinBudget(packet, packet.recent_sessions, item)) {
265
+ packet.omitted.recent_sessions++;
266
+ }
267
+ }
268
+ return finalize(packet);
269
+ }
270
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/context/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import Database from 'better-sqlite3';
2
+ export declare function resolveDbPath(): string;
3
+ export declare function getDb(): Database.Database;
4
+ export declare function closeDb(): void;
5
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAatC,wBAAgB,aAAa,IAAI,MAAM,CAMtC;AAMD,wBAAgB,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,CAI9B"}
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveDbPath = resolveDbPath;
7
+ exports.getDb = getDb;
8
+ exports.closeDb = closeDb;
9
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const os_1 = __importDefault(require("os"));
13
+ // DB location, in priority order:
14
+ // 1. DB_PATH — explicit override (tests, benchmarks, custom deployments)
15
+ // 2. WAYMARK_HOME — explicit data home; DB lives at $WAYMARK_HOME/hub.db
16
+ // 3. <install>/data/hub.db — but only when it ALREADY exists (git-clone installs
17
+ // that have been running; anchored via __dirname, never process.cwd(), since
18
+ // clients spawn the hub from arbitrary project directories)
19
+ // 4. ~/.waymark/hub.db — default for fresh installs. npm upgrades replace the
20
+ // package directory, so the DB must not live inside it.
21
+ function resolveDbPath() {
22
+ if (process.env.DB_PATH)
23
+ return process.env.DB_PATH;
24
+ if (process.env.WAYMARK_HOME)
25
+ return path_1.default.join(process.env.WAYMARK_HOME, 'hub.db');
26
+ const installDbPath = path_1.default.resolve(__dirname, '..', '..', 'data', 'hub.db');
27
+ if (fs_1.default.existsSync(installDbPath))
28
+ return installDbPath;
29
+ return path_1.default.join(os_1.default.homedir(), '.waymark', 'hub.db');
30
+ }
31
+ const DB_PATH = resolveDbPath();
32
+ let _db = null;
33
+ function getDb() {
34
+ if (_db)
35
+ return _db;
36
+ const dir = path_1.default.dirname(DB_PATH);
37
+ if (!fs_1.default.existsSync(dir))
38
+ fs_1.default.mkdirSync(dir, { recursive: true });
39
+ _db = new better_sqlite3_1.default(DB_PATH);
40
+ _db.pragma('journal_mode = WAL');
41
+ _db.pragma('foreign_keys = ON');
42
+ runMigrations(_db);
43
+ return _db;
44
+ }
45
+ function closeDb() {
46
+ if (!_db)
47
+ return;
48
+ _db.close();
49
+ _db = null;
50
+ }
51
+ function runMigrations(db) {
52
+ const migrationDir = path_1.default.join(__dirname, 'migrations');
53
+ const files = fs_1.default.readdirSync(migrationDir).filter(f => f.endsWith('.sql')).sort();
54
+ db.exec(`CREATE TABLE IF NOT EXISTS _migrations (
55
+ name TEXT PRIMARY KEY,
56
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
57
+ )`);
58
+ for (const file of files) {
59
+ const already = db.prepare('SELECT 1 FROM _migrations WHERE name = ?').get(file);
60
+ if (already)
61
+ continue;
62
+ const sql = fs_1.default.readFileSync(path_1.default.join(migrationDir, file), 'utf8');
63
+ db.exec(sql);
64
+ db.prepare('INSERT INTO _migrations (name) VALUES (?)').run(file);
65
+ }
66
+ }
67
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/db/client.ts"],"names":[],"mappings":";;;;;AAaA,sCAMC;AAMD,sBAYC;AAED,0BAIC;AA3CD,oEAAsC;AACtC,gDAAwB;AACxB,4CAAoB;AACpB,4CAAoB;AAEpB,kCAAkC;AAClC,kFAAkF;AAClF,6EAA6E;AAC7E,mFAAmF;AACnF,kFAAkF;AAClF,iEAAiE;AACjE,gFAAgF;AAChF,6DAA6D;AAC7D,SAAgB,aAAa;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IACpD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY;QAAE,OAAO,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACnF,MAAM,aAAa,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5E,IAAI,YAAE,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,aAAa,CAAC;IACvD,OAAO,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAEhC,IAAI,GAAG,GAA6B,IAAI,CAAC;AAEzC,SAAgB,KAAK;IACnB,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAEpB,MAAM,GAAG,GAAG,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,YAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEhE,GAAG,GAAG,IAAI,wBAAQ,CAAC,OAAO,CAAC,CAAC;IAC5B,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEhC,aAAa,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,OAAO;IACrB,IAAI,CAAC,GAAG;QAAE,OAAO;IACjB,GAAG,CAAC,KAAK,EAAE,CAAC;IACZ,GAAG,GAAG,IAAI,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,EAAqB;IAC1C,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,YAAE,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAElF,EAAE,CAAC,IAAI,CAAC;;;IAGN,CAAC,CAAC;IAEJ,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjF,IAAI,OAAO;YAAE,SAAS;QAEtB,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACnE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,EAAE,CAAC,OAAO,CAAC,2CAA2C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpE,CAAC;AACH,CAAC"}
@@ -0,0 +1,85 @@
1
+ CREATE TABLE IF NOT EXISTS projects (
2
+ id TEXT PRIMARY KEY,
3
+ name TEXT NOT NULL,
4
+ root_path TEXT NOT NULL,
5
+ stack TEXT,
6
+ status TEXT NOT NULL DEFAULT 'active',
7
+ description TEXT,
8
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
9
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
10
+ );
11
+
12
+ CREATE TABLE IF NOT EXISTS memory_nodes (
13
+ id TEXT PRIMARY KEY,
14
+ project_id TEXT REFERENCES projects(id),
15
+ surface TEXT NOT NULL DEFAULT 'claude-code',
16
+ name TEXT NOT NULL,
17
+ description TEXT,
18
+ type TEXT NOT NULL DEFAULT 'project',
19
+ body TEXT NOT NULL,
20
+ tags TEXT,
21
+ origin_session TEXT,
22
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
23
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
24
+ );
25
+
26
+ CREATE TABLE IF NOT EXISTS tasks (
27
+ id TEXT PRIMARY KEY,
28
+ project_id TEXT REFERENCES projects(id),
29
+ title TEXT NOT NULL,
30
+ description TEXT,
31
+ status TEXT NOT NULL DEFAULT 'pending',
32
+ priority INTEGER NOT NULL DEFAULT 50,
33
+ created_by TEXT NOT NULL,
34
+ assigned_to TEXT,
35
+ context_json TEXT,
36
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
37
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
38
+ completed_at TEXT
39
+ );
40
+
41
+ CREATE TABLE IF NOT EXISTS sessions (
42
+ id TEXT PRIMARY KEY,
43
+ project_id TEXT REFERENCES projects(id),
44
+ surface TEXT NOT NULL,
45
+ started_at TEXT NOT NULL,
46
+ ended_at TEXT,
47
+ summary TEXT,
48
+ files_touched TEXT,
49
+ commits_made TEXT,
50
+ outcome TEXT
51
+ );
52
+
53
+ CREATE INDEX IF NOT EXISTS idx_memory_project ON memory_nodes(project_id);
54
+ CREATE INDEX IF NOT EXISTS idx_memory_type ON memory_nodes(type);
55
+ CREATE INDEX IF NOT EXISTS idx_memory_name ON memory_nodes(name);
56
+ CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
57
+ CREATE INDEX IF NOT EXISTS idx_tasks_project ON tasks(project_id);
58
+ CREATE INDEX IF NOT EXISTS idx_tasks_assigned ON tasks(assigned_to);
59
+ CREATE INDEX IF NOT EXISTS idx_sessions_proj ON sessions(project_id);
60
+
61
+ CREATE VIRTUAL TABLE IF NOT EXISTS memory_fts USING fts5(
62
+ name,
63
+ description,
64
+ body,
65
+ tags,
66
+ content='memory_nodes',
67
+ content_rowid='rowid'
68
+ );
69
+
70
+ CREATE TRIGGER IF NOT EXISTS memory_fts_insert AFTER INSERT ON memory_nodes BEGIN
71
+ INSERT INTO memory_fts(rowid, name, description, body, tags)
72
+ VALUES (new.rowid, new.name, new.description, new.body, new.tags);
73
+ END;
74
+
75
+ CREATE TRIGGER IF NOT EXISTS memory_fts_delete AFTER DELETE ON memory_nodes BEGIN
76
+ INSERT INTO memory_fts(memory_fts, rowid, name, description, body, tags)
77
+ VALUES ('delete', old.rowid, old.name, old.description, old.body, old.tags);
78
+ END;
79
+
80
+ CREATE TRIGGER IF NOT EXISTS memory_fts_update AFTER UPDATE ON memory_nodes BEGIN
81
+ INSERT INTO memory_fts(memory_fts, rowid, name, description, body, tags)
82
+ VALUES ('delete', old.rowid, old.name, old.description, old.body, old.tags);
83
+ INSERT INTO memory_fts(rowid, name, description, body, tags)
84
+ VALUES (new.rowid, new.name, new.description, new.body, new.tags);
85
+ END;
@@ -0,0 +1,52 @@
1
+ CREATE TABLE IF NOT EXISTS experiments (
2
+ id TEXT PRIMARY KEY,
3
+ project_id TEXT REFERENCES projects(id),
4
+ name TEXT NOT NULL,
5
+ description TEXT,
6
+ scenario TEXT NOT NULL,
7
+ status TEXT NOT NULL DEFAULT 'active',
8
+ target_runs INTEGER NOT NULL DEFAULT 5,
9
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
10
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
11
+ );
12
+
13
+ CREATE TABLE IF NOT EXISTS usage_reports (
14
+ id TEXT PRIMARY KEY,
15
+ project_id TEXT REFERENCES projects(id),
16
+ session_id TEXT REFERENCES sessions(id),
17
+ experiment_id TEXT REFERENCES experiments(id),
18
+ variant TEXT,
19
+ provider TEXT,
20
+ model TEXT,
21
+ client TEXT,
22
+ measurement TEXT NOT NULL DEFAULT 'estimated',
23
+ input_tokens INTEGER,
24
+ output_tokens INTEGER,
25
+ cached_input_tokens INTEGER,
26
+ hub_llm_input_tokens INTEGER NOT NULL DEFAULT 0,
27
+ hub_llm_output_tokens INTEGER NOT NULL DEFAULT 0,
28
+ context_tokens INTEGER,
29
+ context_chars INTEGER,
30
+ tool_calls INTEGER,
31
+ files_read TEXT,
32
+ repeated_files INTEGER,
33
+ clarification_count INTEGER,
34
+ duration_ms INTEGER,
35
+ result_quality REAL,
36
+ success INTEGER,
37
+ notes TEXT,
38
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_experiments_project
42
+ ON experiments(project_id);
43
+ CREATE INDEX IF NOT EXISTS idx_experiments_status
44
+ ON experiments(status);
45
+ CREATE INDEX IF NOT EXISTS idx_usage_project
46
+ ON usage_reports(project_id);
47
+ CREATE INDEX IF NOT EXISTS idx_usage_session
48
+ ON usage_reports(session_id);
49
+ CREATE INDEX IF NOT EXISTS idx_usage_experiment
50
+ ON usage_reports(experiment_id);
51
+ CREATE INDEX IF NOT EXISTS idx_usage_variant
52
+ ON usage_reports(variant);
@@ -0,0 +1,37 @@
1
+ CREATE TABLE IF NOT EXISTS agents (
2
+ id TEXT PRIMARY KEY,
3
+ display_name TEXT NOT NULL,
4
+ provider TEXT,
5
+ model TEXT,
6
+ client TEXT,
7
+ client_version TEXT,
8
+ capabilities TEXT,
9
+ metadata TEXT,
10
+ status TEXT NOT NULL DEFAULT 'active',
11
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
12
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
13
+ );
14
+
15
+ ALTER TABLE sessions ADD COLUMN agent_id TEXT REFERENCES agents(id);
16
+ ALTER TABLE sessions ADD COLUMN provider TEXT;
17
+ ALTER TABLE sessions ADD COLUMN model TEXT;
18
+ ALTER TABLE sessions ADD COLUMN client TEXT;
19
+ ALTER TABLE sessions ADD COLUMN client_session_id TEXT;
20
+
21
+ ALTER TABLE usage_reports ADD COLUMN agent_id TEXT REFERENCES agents(id);
22
+
23
+ ALTER TABLE memory_nodes ADD COLUMN created_by_agent TEXT REFERENCES agents(id);
24
+
25
+ ALTER TABLE tasks ADD COLUMN created_by_agent TEXT REFERENCES agents(id);
26
+ ALTER TABLE tasks ADD COLUMN assigned_agent_id TEXT REFERENCES agents(id);
27
+
28
+ CREATE INDEX IF NOT EXISTS idx_agents_provider ON agents(provider);
29
+ CREATE INDEX IF NOT EXISTS idx_agents_model ON agents(model);
30
+ CREATE INDEX IF NOT EXISTS idx_agents_client ON agents(client);
31
+ CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status);
32
+ CREATE INDEX IF NOT EXISTS idx_sessions_agent ON sessions(agent_id);
33
+ CREATE INDEX IF NOT EXISTS idx_sessions_client_session ON sessions(client_session_id);
34
+ CREATE INDEX IF NOT EXISTS idx_usage_agent ON usage_reports(agent_id);
35
+ CREATE INDEX IF NOT EXISTS idx_memory_agent ON memory_nodes(created_by_agent);
36
+ CREATE INDEX IF NOT EXISTS idx_tasks_created_agent ON tasks(created_by_agent);
37
+ CREATE INDEX IF NOT EXISTS idx_tasks_assigned_agent ON tasks(assigned_agent_id);
@@ -0,0 +1,25 @@
1
+ ALTER TABLE memory_nodes ADD COLUMN status TEXT NOT NULL DEFAULT 'active';
2
+ ALTER TABLE memory_nodes ADD COLUMN importance INTEGER NOT NULL DEFAULT 50;
3
+ ALTER TABLE memory_nodes ADD COLUMN confidence INTEGER NOT NULL DEFAULT 50;
4
+ ALTER TABLE memory_nodes ADD COLUMN source_type TEXT;
5
+ ALTER TABLE memory_nodes ADD COLUMN source_ref TEXT;
6
+ ALTER TABLE memory_nodes ADD COLUMN valid_from TEXT;
7
+ ALTER TABLE memory_nodes ADD COLUMN valid_until TEXT;
8
+ ALTER TABLE memory_nodes ADD COLUMN supersedes_id TEXT REFERENCES memory_nodes(id);
9
+ ALTER TABLE memory_nodes ADD COLUMN last_verified_at TEXT;
10
+
11
+ CREATE TABLE IF NOT EXISTS memory_feedback (
12
+ id TEXT PRIMARY KEY,
13
+ memory_id TEXT NOT NULL REFERENCES memory_nodes(id) ON DELETE CASCADE,
14
+ agent_id TEXT REFERENCES agents(id),
15
+ session_id TEXT REFERENCES sessions(id),
16
+ rating TEXT NOT NULL,
17
+ notes TEXT,
18
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
19
+ );
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_memory_status ON memory_nodes(status);
22
+ CREATE INDEX IF NOT EXISTS idx_memory_valid_until ON memory_nodes(valid_until);
23
+ CREATE INDEX IF NOT EXISTS idx_memory_supersedes ON memory_nodes(supersedes_id);
24
+ CREATE INDEX IF NOT EXISTS idx_memory_feedback_memory ON memory_feedback(memory_id);
25
+ CREATE INDEX IF NOT EXISTS idx_memory_feedback_agent ON memory_feedback(agent_id);
@@ -0,0 +1,17 @@
1
+ ALTER TABLE tasks ADD COLUMN required_capabilities TEXT;
2
+ ALTER TABLE tasks ADD COLUMN claimed_by_agent TEXT REFERENCES agents(id);
3
+ ALTER TABLE tasks ADD COLUMN claimed_at TEXT;
4
+ ALTER TABLE tasks ADD COLUMN blocker TEXT;
5
+ ALTER TABLE tasks ADD COLUMN progress INTEGER NOT NULL DEFAULT 0;
6
+
7
+ CREATE TABLE IF NOT EXISTS task_dependencies (
8
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
9
+ depends_on_task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
10
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
11
+ PRIMARY KEY (task_id, depends_on_task_id),
12
+ CHECK (task_id <> depends_on_task_id)
13
+ );
14
+
15
+ CREATE INDEX IF NOT EXISTS idx_tasks_claimed_agent ON tasks(claimed_by_agent);
16
+ CREATE INDEX IF NOT EXISTS idx_task_dependencies_task ON task_dependencies(task_id);
17
+ CREATE INDEX IF NOT EXISTS idx_task_dependencies_dependency ON task_dependencies(depends_on_task_id);