ralph-hero-knowledge-index 0.1.16 → 0.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/dist/db.js +22 -0
- package/dist/db.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/db.test.ts +121 -0
- package/src/db.ts +22 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ralph-knowledge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.17",
|
|
4
4
|
"description": "Knowledge graph for ralph-hero: semantic search, relationship traversal, and document indexing across thoughts/ documents. Optional companion to ralph-hero.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Chad Dubiel",
|
package/.mcp.json
CHANGED
package/dist/db.js
CHANGED
|
@@ -76,6 +76,28 @@ export class KnowledgeDB {
|
|
|
76
76
|
catch {
|
|
77
77
|
// Column already exists — expected for new databases
|
|
78
78
|
}
|
|
79
|
+
// Migration: rebuild relationships table for databases created before the
|
|
80
|
+
// context column, post_mortem/untyped CHECK types, and target_id FK were added.
|
|
81
|
+
// SQLite cannot ALTER CHECK constraints, so a full table rebuild is required.
|
|
82
|
+
try {
|
|
83
|
+
this.db.prepare("SELECT context FROM relationships LIMIT 0").get();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
this.db.exec(`
|
|
87
|
+
CREATE TABLE relationships_new (
|
|
88
|
+
source_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
89
|
+
target_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
90
|
+
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by', 'post_mortem', 'untyped')),
|
|
91
|
+
context TEXT,
|
|
92
|
+
PRIMARY KEY (source_id, target_id, type)
|
|
93
|
+
);
|
|
94
|
+
INSERT INTO relationships_new (source_id, target_id, type)
|
|
95
|
+
SELECT source_id, target_id, type FROM relationships;
|
|
96
|
+
DROP TABLE relationships;
|
|
97
|
+
ALTER TABLE relationships_new RENAME TO relationships;
|
|
98
|
+
CREATE INDEX IF NOT EXISTS idx_rel_target ON relationships(target_id, type);
|
|
99
|
+
`);
|
|
100
|
+
}
|
|
79
101
|
}
|
|
80
102
|
upsertDocument(doc) {
|
|
81
103
|
this.db.prepare(`
|
package/dist/db.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuFpC,MAAM,OAAO,WAAW;IACb,EAAE,CAAe;IAE1B,YAAY,MAAc;QACxB,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAEO,YAAY;QAClB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuDZ,CAAC,CAAC;QAEH,yEAAyE;QACzE,0EAA0E;QAC1E,0CAA0C;QAC1C,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;QACvD,CAAC;IACH,CAAC;IAED,cAAc,CAAC,GAAsD;QACnE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;;;KAMf,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,EAAU;QAC3B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;KAGf,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,WAAW,CAAC,EAAU;QACpB,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB,iIAAiI,CAClI,CAAC,GAAG,CAAC,EAAE,CAA4B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,IAAc;QACnC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC;QAC/E,KAAK,MAAM,GAAG,IAAI,IAAI;YAAE,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,CAAC,KAAa;QACnB,OAAQ,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,CAAC,KAAK,CAA4B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACtI,CAAC;IAED,eAAe,CAAC,QAAgB,EAAE,QAAgB,EAAE,IAAY,EAAE,OAAgB;QAChF,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+FAA+F,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC,CAAC;IAClK,CAAC;IAED,oBAAoB,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2GAA2G,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAsB,CAAC;IACzK,CAAC;IAED,kBAAkB,CAAC,QAAgB;QACjC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,2GAA2G,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAsB,CAAC;IACzK,CAAC;IAED,kBAAkB,CAAC,KAAwB;QACzC,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;QAEpD,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;KAGf,CAAC,CAAC,GAAG,CACJ,EAAE,EACF,KAAK,CAAC,SAAS,EACf,KAAK,CAAC,WAAW,EACjB,KAAK,CAAC,SAAS,IAAI,IAAI,EACvB,SAAS,EACT,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,KAAK,CAAC,OAAO,IAAI,IAAI,EACrB,KAAK,CAAC,aAAa,IAAI,IAAI,EAC3B,KAAK,CAAC,QAAQ,IAAI,IAAI,EACtB,KAAK,CAAC,UAAU,IAAI,IAAI,EACxB,KAAK,CAAC,KAAK,IAAI,IAAI,EACnB,KAAK,CAAC,SAAS,IAAI,IAAI,EACvB,KAAK,CAAC,cAAc,IAAI,IAAI,EAC5B,OAAO,CACR,CAAC;QAEF,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC;IACvF,CAAC;IAED,kBAAkB,CAAC,SAA6B,EAAE;QAChD,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAc,EAAE,CAAC;QAE7B,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,UAAU,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YACpC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;YACvC,UAAU,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAClC,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACnC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;QAEjC,MAAM,GAAG,GAAG;;;;;4BAKY,KAAK;;;KAG5B,CAAC;QAEF,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,KAAK,CAAsB,CAAC;IACzE,CAAC;IAED,sBAAsB,CAAC,SAA6B,EAAE;QACpD,oFAAoF;QACpF,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAEtE,MAAM,mBAAmB,GAA2B,EAAE,CAAC;QACvD,MAAM,qBAAqB,GAA2B,EAAE,CAAC;QACzD,MAAM,eAAe,GAA2B,EAAE,CAAC;QACnD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,IAAI,SAAS,GAAG,CAAC,CAAC;QAElB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACzB,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACjF,CAAC;YACD,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,qBAAqB,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvF,IAAI,GAAG,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC/B,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACrF,CAAC;YACD,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC5B,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC;gBAC3B,UAAU,EAAE,CAAC;YACf,CAAC;YACD,IAAI,GAAG,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;gBAChC,OAAO,IAAI,GAAG,CAAC,cAAc,CAAC;gBAC9B,SAAS,EAAE,CAAC;YACd,CAAC;QACH,CAAC;QAED,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;aACtD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;aACzC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAEhB,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,aAAa,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI;YAC5D,iBAAiB,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI;YAC7D,mBAAmB;YACnB,qBAAqB;YACrB,iBAAiB;SAClB,CAAC;IACJ,CAAC;IAED,iBAAiB,CAAC,WAAmB;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACpE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEnC,MAAM,YAAY,GAA2B,EAAE,CAAC;QAChD,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,aAAa,GAAkB,IAAI,CAAC;QAExC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACrE,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC5B,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC;YAC/B,CAAC;YACD,IAAI,GAAG,CAAC,SAAS,KAAK,kBAAkB,EAAE,CAAC;gBACzC,QAAQ,EAAE,CAAC;YACb,CAAC;QACH,CAAC;QAED,0EAA0E;QAC1E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;gBACzB,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC;gBAC5B,MAAM;YACR,CAAC;QACH,CAAC;QAED,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,MAAM;YACxB,aAAa;YACb,UAAU;YACV,QAAQ;YACR,YAAY;SACb,CAAC;IACJ,CAAC;IAED,aAAa,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB,uEAAuE,CACxE,CAAC,GAAG,CAAC,IAAI,CAA2B,CAAC;IACxC,CAAC;IAED,gBAAgB,CAAC,IAAY,EAAE,KAAa;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC;;;;KAIf,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACnD,CAAC;IAED,gBAAgB,CAAC,IAAY;QAC3B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iCAAiC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,eAAe;QACb,OAAQ,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,GAAG,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtG,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5E,OAAO,GAAG,KAAK,SAAS,CAAC;IAC3B,CAAC;IAED,cAAc,CAAC,EAAU;QACvB,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,QAAQ;QACN,0FAA0F;QAC1F,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,uFAAuF,CAAC,CAAC;IACxG,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/__tests__/db.test.ts
CHANGED
|
@@ -407,6 +407,127 @@ describe("Schema migration: is_stub column", () => {
|
|
|
407
407
|
});
|
|
408
408
|
});
|
|
409
409
|
|
|
410
|
+
describe("Schema migration: relationships table rebuild", () => {
|
|
411
|
+
it("rebuilds old schema, preserves data, and enables new features", () => {
|
|
412
|
+
const dir = mkdtempSync(join(tmpdir(), "knowledge-rel-migration-"));
|
|
413
|
+
const dbPath = join(dir, "legacy.db");
|
|
414
|
+
|
|
415
|
+
// Create a DB with the old relationships schema (no context, narrow CHECK, no target_id FK)
|
|
416
|
+
const rawDb = new Database(dbPath);
|
|
417
|
+
rawDb.exec(`
|
|
418
|
+
CREATE TABLE documents (
|
|
419
|
+
id TEXT PRIMARY KEY, path TEXT, title TEXT, date TEXT, type TEXT,
|
|
420
|
+
status TEXT, github_issue INTEGER, content TEXT, is_stub INTEGER DEFAULT 0
|
|
421
|
+
);
|
|
422
|
+
CREATE TABLE tags (doc_id TEXT REFERENCES documents(id) ON DELETE CASCADE, tag TEXT, PRIMARY KEY (doc_id, tag));
|
|
423
|
+
CREATE TABLE relationships (
|
|
424
|
+
source_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
425
|
+
target_id TEXT,
|
|
426
|
+
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by')),
|
|
427
|
+
PRIMARY KEY (source_id, target_id, type)
|
|
428
|
+
);
|
|
429
|
+
CREATE TABLE outcome_events (
|
|
430
|
+
id TEXT PRIMARY KEY, event_type TEXT NOT NULL, issue_number INTEGER NOT NULL,
|
|
431
|
+
session_id TEXT, timestamp TEXT NOT NULL, duration_ms INTEGER, verdict TEXT,
|
|
432
|
+
component_area TEXT, estimate TEXT, drift_count INTEGER, model TEXT,
|
|
433
|
+
agent_type TEXT, iteration_count INTEGER, payload TEXT DEFAULT '{}'
|
|
434
|
+
);
|
|
435
|
+
CREATE TABLE sync (path TEXT PRIMARY KEY, mtime INTEGER NOT NULL, indexed_at INTEGER NOT NULL);
|
|
436
|
+
`);
|
|
437
|
+
// Insert test data
|
|
438
|
+
rawDb.exec(`
|
|
439
|
+
INSERT INTO documents (id, path, title, content) VALUES ('a', 'a.md', 'Doc A', '');
|
|
440
|
+
INSERT INTO documents (id, path, title, content) VALUES ('b', 'b.md', 'Doc B', '');
|
|
441
|
+
INSERT INTO relationships (source_id, target_id, type) VALUES ('a', 'b', 'builds_on');
|
|
442
|
+
`);
|
|
443
|
+
rawDb.close();
|
|
444
|
+
|
|
445
|
+
// Opening via KnowledgeDB should migrate the schema
|
|
446
|
+
const migrated = new KnowledgeDB(dbPath);
|
|
447
|
+
|
|
448
|
+
// Existing data preserved with context = null
|
|
449
|
+
const rels = migrated.getRelationshipsFrom("a");
|
|
450
|
+
expect(rels).toHaveLength(1);
|
|
451
|
+
expect(rels[0].targetId).toBe("b");
|
|
452
|
+
expect(rels[0].type).toBe("builds_on");
|
|
453
|
+
expect(rels[0].context).toBeNull();
|
|
454
|
+
|
|
455
|
+
// New context column is writable
|
|
456
|
+
migrated.addRelationship("b", "a", "tensions", "disagreement on approach");
|
|
457
|
+
const relsBack = migrated.getRelationshipsFrom("b");
|
|
458
|
+
expect(relsBack[0].context).toBe("disagreement on approach");
|
|
459
|
+
|
|
460
|
+
// New CHECK types accepted
|
|
461
|
+
expect(() => migrated.addRelationship("a", "b", "post_mortem")).not.toThrow();
|
|
462
|
+
expect(() => migrated.addRelationship("a", "b", "untyped")).not.toThrow();
|
|
463
|
+
|
|
464
|
+
migrated.close();
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
it("is idempotent on a database that already has the context column", () => {
|
|
468
|
+
const dir = mkdtempSync(join(tmpdir(), "knowledge-rel-migration-"));
|
|
469
|
+
const dbPath = join(dir, "current.db");
|
|
470
|
+
|
|
471
|
+
const db1 = new KnowledgeDB(dbPath);
|
|
472
|
+
db1.upsertDocument({ id: "a", path: "a.md", title: "A", date: null, type: null, status: null, githubIssue: null, content: "" });
|
|
473
|
+
db1.upsertDocument({ id: "b", path: "b.md", title: "B", date: null, type: null, status: null, githubIssue: null, content: "" });
|
|
474
|
+
db1.addRelationship("a", "b", "builds_on", "some context");
|
|
475
|
+
db1.close();
|
|
476
|
+
|
|
477
|
+
// Second open should not error and data should be intact
|
|
478
|
+
const db2 = new KnowledgeDB(dbPath);
|
|
479
|
+
const rels = db2.getRelationshipsFrom("a");
|
|
480
|
+
expect(rels).toHaveLength(1);
|
|
481
|
+
expect(rels[0].context).toBe("some context");
|
|
482
|
+
db2.close();
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("traverse works after migration from old schema", async () => {
|
|
486
|
+
const { Traverser } = await import("../traverse.js");
|
|
487
|
+
const dir = mkdtempSync(join(tmpdir(), "knowledge-rel-migration-"));
|
|
488
|
+
const dbPath = join(dir, "legacy.db");
|
|
489
|
+
|
|
490
|
+
// Create old-schema DB with test data
|
|
491
|
+
const rawDb = new Database(dbPath);
|
|
492
|
+
rawDb.exec(`
|
|
493
|
+
CREATE TABLE documents (
|
|
494
|
+
id TEXT PRIMARY KEY, path TEXT, title TEXT, date TEXT, type TEXT,
|
|
495
|
+
status TEXT, github_issue INTEGER, content TEXT, is_stub INTEGER DEFAULT 0
|
|
496
|
+
);
|
|
497
|
+
CREATE TABLE tags (doc_id TEXT REFERENCES documents(id) ON DELETE CASCADE, tag TEXT, PRIMARY KEY (doc_id, tag));
|
|
498
|
+
CREATE TABLE relationships (
|
|
499
|
+
source_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
500
|
+
target_id TEXT,
|
|
501
|
+
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by')),
|
|
502
|
+
PRIMARY KEY (source_id, target_id, type)
|
|
503
|
+
);
|
|
504
|
+
CREATE TABLE outcome_events (
|
|
505
|
+
id TEXT PRIMARY KEY, event_type TEXT NOT NULL, issue_number INTEGER NOT NULL,
|
|
506
|
+
session_id TEXT, timestamp TEXT NOT NULL, duration_ms INTEGER, verdict TEXT,
|
|
507
|
+
component_area TEXT, estimate TEXT, drift_count INTEGER, model TEXT,
|
|
508
|
+
agent_type TEXT, iteration_count INTEGER, payload TEXT DEFAULT '{}'
|
|
509
|
+
);
|
|
510
|
+
CREATE TABLE sync (path TEXT PRIMARY KEY, mtime INTEGER NOT NULL, indexed_at INTEGER NOT NULL);
|
|
511
|
+
INSERT INTO documents (id, path, title, content) VALUES ('a', 'a.md', 'Doc A', '');
|
|
512
|
+
INSERT INTO documents (id, path, title, content) VALUES ('b', 'b.md', 'Doc B', '');
|
|
513
|
+
INSERT INTO relationships (source_id, target_id, type) VALUES ('a', 'b', 'builds_on');
|
|
514
|
+
`);
|
|
515
|
+
rawDb.close();
|
|
516
|
+
|
|
517
|
+
// Open via KnowledgeDB (triggers migration), then traverse
|
|
518
|
+
const migrated = new KnowledgeDB(dbPath);
|
|
519
|
+
const traverser = new Traverser(migrated);
|
|
520
|
+
|
|
521
|
+
const results = traverser.traverse("a");
|
|
522
|
+
expect(results).toHaveLength(1);
|
|
523
|
+
expect(results[0].targetId).toBe("b");
|
|
524
|
+
expect(results[0].context).toBeNull();
|
|
525
|
+
expect(results[0].doc?.title).toBe("Doc B");
|
|
526
|
+
|
|
527
|
+
migrated.close();
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
410
531
|
describe("documentExists", () => {
|
|
411
532
|
it("returns true for an existing document", () => {
|
|
412
533
|
db.upsertDocument({ id: "doc-1", path: "p", title: "t", date: null, type: null, status: null, githubIssue: null, content: "" });
|
package/src/db.ts
CHANGED
|
@@ -165,6 +165,28 @@ export class KnowledgeDB {
|
|
|
165
165
|
} catch {
|
|
166
166
|
// Column already exists — expected for new databases
|
|
167
167
|
}
|
|
168
|
+
|
|
169
|
+
// Migration: rebuild relationships table for databases created before the
|
|
170
|
+
// context column, post_mortem/untyped CHECK types, and target_id FK were added.
|
|
171
|
+
// SQLite cannot ALTER CHECK constraints, so a full table rebuild is required.
|
|
172
|
+
try {
|
|
173
|
+
this.db.prepare("SELECT context FROM relationships LIMIT 0").get();
|
|
174
|
+
} catch {
|
|
175
|
+
this.db.exec(`
|
|
176
|
+
CREATE TABLE relationships_new (
|
|
177
|
+
source_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
178
|
+
target_id TEXT REFERENCES documents(id) ON DELETE CASCADE,
|
|
179
|
+
type TEXT CHECK(type IN ('builds_on', 'tensions', 'superseded_by', 'post_mortem', 'untyped')),
|
|
180
|
+
context TEXT,
|
|
181
|
+
PRIMARY KEY (source_id, target_id, type)
|
|
182
|
+
);
|
|
183
|
+
INSERT INTO relationships_new (source_id, target_id, type)
|
|
184
|
+
SELECT source_id, target_id, type FROM relationships;
|
|
185
|
+
DROP TABLE relationships;
|
|
186
|
+
ALTER TABLE relationships_new RENAME TO relationships;
|
|
187
|
+
CREATE INDEX IF NOT EXISTS idx_rel_target ON relationships(target_id, type);
|
|
188
|
+
`);
|
|
189
|
+
}
|
|
168
190
|
}
|
|
169
191
|
|
|
170
192
|
upsertDocument(doc: Omit<DocumentRow, "isStub"> & { isStub?: number }): void {
|