@bloodyeagle/megamemory 1.6.3-fork.1 → 1.6.3-fork.3
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/README.md +21 -5
- package/README.ru.md +22 -6
- package/dist/auto-migrate.d.ts +53 -0
- package/dist/auto-migrate.d.ts.map +1 -0
- package/dist/auto-migrate.js +190 -0
- package/dist/auto-migrate.js.map +1 -0
- package/dist/db.d.ts +20 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +51 -2
- package/dist/db.js.map +1 -1
- package/dist/digest.d.ts +15 -0
- package/dist/digest.d.ts.map +1 -1
- package/dist/digest.js +22 -0
- package/dist/digest.js.map +1 -1
- package/dist/doctor.d.ts +31 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +93 -9
- package/dist/doctor.js.map +1 -1
- package/dist/export.d.ts +9 -1
- package/dist/export.d.ts.map +1 -1
- package/dist/export.js +12 -6
- package/dist/export.js.map +1 -1
- package/dist/index.js +22 -8
- package/dist/index.js.map +1 -1
- package/dist/migrate-schema.d.ts +1 -1
- package/dist/migrate-schema.d.ts.map +1 -1
- package/dist/migrate-schema.js +35 -3
- package/dist/migrate-schema.js.map +1 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +4 -2
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web.d.ts.map +1 -1
- package/dist/web.js +97 -0
- package/dist/web.js.map +1 -1
- package/docs/FORK.md +88 -64
- package/docs/FORK.ru.md +118 -0
- package/fixtures/demo.db +0 -0
- package/package.json +1 -1
- package/web/index.html +170 -9
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="./LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" /></a>
|
|
8
8
|
<img alt="node" src="https://img.shields.io/badge/node-%3E%3D18-brightgreen?style=flat-square" />
|
|
9
|
-
<img alt="version" src="https://img.shields.io/badge/version-1.6.3--fork.
|
|
9
|
+
<img alt="version" src="https://img.shields.io/badge/version-1.6.3--fork.3-orange?style=flat-square" />
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -60,15 +60,27 @@ database at `.megamemory/knowledge.db`.
|
|
|
60
60
|
Requires Node.js >= 18. For Russian-only projects a much smaller model (`cointegrated/rubert-tiny2`, 312-dim) works after an ONNX conversion; the model unloads after 5 minutes idle (`MEGAMEMORY_EMBED_IDLE_MS=0` disables that), and `MEGAMEMORY_SEARCH=fts` avoids loading it at all. The embedding model (~120 MB, multilingual) downloads on first use and is
|
|
61
61
|
cached in `~/.cache/huggingface`.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Install globally from npm:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install -g @bloodyeagle/megamemory
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Or download the tarball from GitHub Releases (no build needed):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install -g ./megamemory-1.6.3-fork.3.tgz
|
|
74
|
+
```
|
|
75
|
+
Or build from a checkout (for development):
|
|
64
76
|
|
|
65
77
|
```bash
|
|
66
78
|
git clone https://github.com/BloodyEagle/MegaMemoryAgent.git
|
|
67
79
|
cd MegaMemoryAgent
|
|
68
80
|
npm ci
|
|
69
81
|
npm run build
|
|
70
|
-
npm pack # megamemory-1.6.3-fork.
|
|
71
|
-
npm install -g ./megamemory-1.6.3-fork.
|
|
82
|
+
npm pack # bloodyeagle-megamemory-1.6.3-fork.3.tgz
|
|
83
|
+
npm install -g ./bloodyeagle-megamemory-1.6.3-fork.3.tgz
|
|
72
84
|
```
|
|
73
85
|
|
|
74
86
|
Then either run the installer or register the MCP server by hand:
|
|
@@ -163,9 +175,13 @@ megamemory serve --port 8080
|
|
|
163
175
|
|
|
164
176
|
- nodes colored by kind, sized by edge count; `digest` nodes and outdated (`superseded`) nodes are visually distinct
|
|
165
177
|
- `supersedes` edges drawn dashed, status badges in the node card, "show outdated" toggle
|
|
166
|
-
- search hits carry a `via` badge (vector / fts / both) and a budget line: `N nodes, ~X tokens, dropped M`
|
|
178
|
+
- search hits carry a `via` badge (vector / fts / both) and a budget line: `N nodes, ~X tokens, dropped M · saved ~Z vs full`
|
|
167
179
|
- **Tokens** panel: average answer size and saved tokens over 7 days
|
|
168
180
|
- **Consolidate** tab: duplicate candidates with apply
|
|
181
|
+
- per-kind filter checkboxes (persisted), visible/total counter, **export bundle** button and per-node `download .md`
|
|
182
|
+
- **Health** chip: vectors, FTS sync, digests, empty ids, orphans, memory — with remedy hints
|
|
183
|
+
- digest cards list source concepts with a `stale` badge and a **focus** toggle
|
|
184
|
+
- timeline **status changes** mode; node cards show recent status transitions with reasons
|
|
169
185
|
|
|
170
186
|
---
|
|
171
187
|
|
package/README.ru.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<p align="center">
|
|
7
7
|
<a href="./LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" /></a>
|
|
8
8
|
<img alt="node" src="https://img.shields.io/badge/node-%3E%3D18-brightgreen?style=flat-square" />
|
|
9
|
-
<img alt="version" src="https://img.shields.io/badge/version-1.6.3--fork.
|
|
9
|
+
<img alt="version" src="https://img.shields.io/badge/version-1.6.3--fork.3-orange?style=flat-square" />
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
@@ -60,15 +60,27 @@
|
|
|
60
60
|
Нужен Node.js >= 18. Для чисто русских проектов подойдёт значительно меньшая модель (`cointegrated/rubert-tiny2`, 312-мерная) после конвертации в ONNX; модель выгружается после 5 минут простоя (`MEGAMEMORY_EMBED_IDLE_MS=0` отключает выгрузку), а `MEGAMEMORY_SEARCH=fts` не загружает её вовсе. Модель эмбеддингов (~120 МБ, мультиязычная) скачивается при первом
|
|
61
61
|
запуске и кешируется в `~/.cache/huggingface`.
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
Установка глобально из npm:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install -g @bloodyeagle/megamemory
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Или скачайте tarball из GitHub Releases (без сборки):
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm install -g ./megamemory-1.6.3-fork.3.tgz
|
|
74
|
+
```
|
|
75
|
+
Или сборка из чекаута (для разработки):
|
|
64
76
|
|
|
65
77
|
```bash
|
|
66
78
|
git clone https://github.com/BloodyEagle/MegaMemoryAgent.git
|
|
67
79
|
cd MegaMemoryAgent
|
|
68
80
|
npm ci
|
|
69
81
|
npm run build
|
|
70
|
-
npm pack # megamemory-1.6.3-fork.
|
|
71
|
-
npm install -g ./megamemory-1.6.3-fork.
|
|
82
|
+
npm pack # bloodyeagle-megamemory-1.6.3-fork.3.tgz
|
|
83
|
+
npm install -g ./bloodyeagle-megamemory-1.6.3-fork.3.tgz
|
|
72
84
|
```
|
|
73
85
|
|
|
74
86
|
Дальше — либо установщик, либо регистрация MCP-сервера руками:
|
|
@@ -164,9 +176,13 @@ megamemory serve --port 8080
|
|
|
164
176
|
|
|
165
177
|
- узлы раскрашены по типу, размер — по числу рёбер; `digest` и устаревшие (`superseded`) визуально отличаются
|
|
166
178
|
- рёбра `supersedes` — пунктиром, бейдж статуса в карточке узла, тумблер «показывать устаревшие»
|
|
167
|
-
- у результатов поиска бейдж `via` (vector / fts / both) и строка бюджета: `N nodes, ~X tokens, dropped M`
|
|
179
|
+
- у результатов поиска бейдж `via` (vector / fts / both) и строка бюджета: `N nodes, ~X tokens, dropped M` · `saved ~Z vs full`
|
|
168
180
|
- панель **Tokens**: средний размер ответа и сэкономленные токены за 7 дней
|
|
169
181
|
- вкладка **Consolidate**: кандидаты-дубликаты с кнопкой применения
|
|
182
|
+
- чекбоксы фильтра по типам узлов (с сохранением), счётчик видимых, кнопка **export bundle** и `download .md` в карточке
|
|
183
|
+
- чип **Health**: векторы, синхронность FTS, digest, пустые id, сироты, память — с подсказками
|
|
184
|
+
- карточка digest показывает исходные концепции, бейдж `stale` и переключатель **focus**
|
|
185
|
+
- режим **status changes** в таймлайне; в карточке узла — последние смены статусов с причинами
|
|
170
186
|
|
|
171
187
|
---
|
|
172
188
|
|
|
@@ -198,4 +214,4 @@ npx vitest run # всё (
|
|
|
198
214
|
|
|
199
215
|
Основа — [MegaMemory](https://github.com/0xK3vin/MegaMemory), автор 0xK3vin (MIT).
|
|
200
216
|
Форк поддерживает [BloodyEagle](https://github.com/BloodyEagle). MIT, см. [LICENSE](./LICENSE).
|
|
201
|
-
Отличия и порядок синхронизации с upstream: [docs/FORK.md](./docs/FORK.md).
|
|
217
|
+
Отличия и порядок синхронизации с upstream: [docs/FORK.ru.md](./docs/FORK.ru.md) (english: [docs/FORK.md](./docs/FORK.md)).
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { KnowledgeDB } from "./db.js";
|
|
2
|
+
/**
|
|
3
|
+
* F14: automatic conversion of a legacy database on first open.
|
|
4
|
+
*
|
|
5
|
+
* open db
|
|
6
|
+
* ├─ preflight: integrity_check, counters, empty ids, orphan edges
|
|
7
|
+
* ├─ already on the target schema with intact ids → nothing to do (idempotent)
|
|
8
|
+
* ├─ else: backup → ONE transaction [ensureSchema → id repair (aliases) →
|
|
9
|
+
* │ FTS rebuild → name_norm backfill → embed meta (F10) →
|
|
10
|
+
* │ schema_version=3 → postflight] — a failed postflight rolls the
|
|
11
|
+
* │ whole transaction back, the file on disk is never touched
|
|
12
|
+
* └─ one stderr line + a JSON report next to the database
|
|
13
|
+
*
|
|
14
|
+
* The backup is still written before the transaction: a cheap safety
|
|
15
|
+
* artifact, but the rollback mechanism does not depend on it.
|
|
16
|
+
*/
|
|
17
|
+
export interface PreflightReport {
|
|
18
|
+
integrity: "ok" | string;
|
|
19
|
+
nodes: number;
|
|
20
|
+
edges: number;
|
|
21
|
+
empty_ids: number;
|
|
22
|
+
trailing_slash_ids: number;
|
|
23
|
+
orphan_edges: number;
|
|
24
|
+
schema_version: string | null;
|
|
25
|
+
fts_rows: number | null;
|
|
26
|
+
has_vectors: number;
|
|
27
|
+
legacy: boolean;
|
|
28
|
+
}
|
|
29
|
+
export declare function preflight(db: KnowledgeDB): PreflightReport;
|
|
30
|
+
export interface AutoMigrationResult {
|
|
31
|
+
performed: boolean;
|
|
32
|
+
legacy: boolean;
|
|
33
|
+
before: PreflightReport;
|
|
34
|
+
after: PreflightReport | null;
|
|
35
|
+
ids_repaired: Array<{
|
|
36
|
+
old: string;
|
|
37
|
+
new: string;
|
|
38
|
+
}>;
|
|
39
|
+
backup: string | null;
|
|
40
|
+
reembed_required: boolean;
|
|
41
|
+
warnings: string[];
|
|
42
|
+
report_file: string | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Convert a legacy database on first open. The whole conversion runs in one
|
|
46
|
+
* transaction; a failed postflight verification rolls it back, so the file
|
|
47
|
+
* on disk is never left half-migrated. Never runs reembed or digest
|
|
48
|
+
* building — those are separate, slower commands.
|
|
49
|
+
*/
|
|
50
|
+
export declare function autoMigrateIfNeeded(db: KnowledgeDB, dbPath: string): Promise<AutoMigrationResult>;
|
|
51
|
+
/** One-line stderr summary for startup (F14.4). */
|
|
52
|
+
export declare function describeAutoMigration(r: AutoMigrationResult): string | null;
|
|
53
|
+
//# sourceMappingURL=auto-migrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate.d.ts","sourceRoot":"","sources":["../src/auto-migrate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAStC;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,GAAG,eAAe,CAqD1D;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,mBAAmB,CAAC,CAyK9B;AAED,mDAAmD;AACnD,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAM3E"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { MIGRATION_TARGET_SCHEMA_VERSION, ensureSchema, ensureEmbedMeta, emptyReport, } from "./migrate-schema.js";
|
|
4
|
+
import { planIdRepair, applyIdRepair, backupDb } from "./migrate.js";
|
|
5
|
+
export function preflight(db) {
|
|
6
|
+
const integrityRow = db.execSqlFirst("PRAGMA integrity_check");
|
|
7
|
+
const integrity = typeof integrityRow === "object" && integrityRow !== null
|
|
8
|
+
? (integrityRow.result ?? "ok")
|
|
9
|
+
: typeof integrityRow === "string"
|
|
10
|
+
? integrityRow
|
|
11
|
+
: "ok";
|
|
12
|
+
const count = (sql) => db.execSqlFirst(sql).n;
|
|
13
|
+
const emptyIds = count("SELECT count(*) AS n FROM nodes WHERE id = ''");
|
|
14
|
+
const trailingSlash = count("SELECT count(*) AS n FROM nodes WHERE id LIKE '%/'");
|
|
15
|
+
const orphanEdges = count(`SELECT count(*) AS n FROM edges
|
|
16
|
+
WHERE from_id NOT IN (SELECT id FROM nodes)
|
|
17
|
+
OR to_id NOT IN (SELECT id FROM nodes)`);
|
|
18
|
+
const schemaVersion = db.getMetaValue("schema_version") ?? null;
|
|
19
|
+
const hasFts = db.execSqlFirst("SELECT 1 FROM sqlite_master WHERE type='table' AND name='nodes_fts'") !== undefined;
|
|
20
|
+
const ftsRows = hasFts
|
|
21
|
+
? db.execSqlFirst("SELECT count(*) AS n FROM nodes_fts").n
|
|
22
|
+
: null;
|
|
23
|
+
const hasVectors = count("SELECT count(*) AS n FROM nodes WHERE embedding IS NOT NULL");
|
|
24
|
+
const legacy = schemaVersion !== MIGRATION_TARGET_SCHEMA_VERSION ||
|
|
25
|
+
emptyIds > 0 ||
|
|
26
|
+
trailingSlash > 0;
|
|
27
|
+
return {
|
|
28
|
+
integrity,
|
|
29
|
+
nodes: count("SELECT count(*) AS n FROM nodes"),
|
|
30
|
+
edges: count("SELECT count(*) AS n FROM edges"),
|
|
31
|
+
empty_ids: emptyIds,
|
|
32
|
+
trailing_slash_ids: trailingSlash,
|
|
33
|
+
orphan_edges: orphanEdges,
|
|
34
|
+
schema_version: schemaVersion,
|
|
35
|
+
fts_rows: ftsRows,
|
|
36
|
+
has_vectors: hasVectors,
|
|
37
|
+
legacy,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Convert a legacy database on first open. The whole conversion runs in one
|
|
42
|
+
* transaction; a failed postflight verification rolls it back, so the file
|
|
43
|
+
* on disk is never left half-migrated. Never runs reembed or digest
|
|
44
|
+
* building — those are separate, slower commands.
|
|
45
|
+
*/
|
|
46
|
+
export async function autoMigrateIfNeeded(db, dbPath) {
|
|
47
|
+
const before = preflight(db);
|
|
48
|
+
const result = {
|
|
49
|
+
performed: false,
|
|
50
|
+
legacy: before.legacy,
|
|
51
|
+
before,
|
|
52
|
+
after: null,
|
|
53
|
+
ids_repaired: [],
|
|
54
|
+
backup: null,
|
|
55
|
+
reembed_required: false,
|
|
56
|
+
warnings: [],
|
|
57
|
+
report_file: null,
|
|
58
|
+
};
|
|
59
|
+
if (!before.legacy)
|
|
60
|
+
return result; // idempotent: nothing to do
|
|
61
|
+
if (before.integrity !== "ok") {
|
|
62
|
+
// F14.1: a corrupted database is not converted — conversion writes, and
|
|
63
|
+
// writing to a corrupt file risks data loss. The caller decides whether
|
|
64
|
+
// to continue in a degraded (text-search) mode.
|
|
65
|
+
result.warnings.push(`integrity_check failed (${before.integrity}) — auto-migration skipped`);
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
// F14.2: backup before conversion (always). wal_checkpoint makes the file
|
|
69
|
+
// copy self-contained.
|
|
70
|
+
db.pragma("wal_checkpoint(TRUNCATE)");
|
|
71
|
+
result.backup = backupDb(dbPath);
|
|
72
|
+
const report = emptyReport();
|
|
73
|
+
let rollbackReason = null;
|
|
74
|
+
try {
|
|
75
|
+
db.runInTransaction(() => {
|
|
76
|
+
// Renames touch parents, children and edges in several statements;
|
|
77
|
+
// PRAGMA foreign_keys is a no-op inside a transaction, so FK checks
|
|
78
|
+
// are deferred to COMMIT where the graph is consistent again.
|
|
79
|
+
db.pragma("defer_foreign_keys = ON");
|
|
80
|
+
ensureSchema(db, report);
|
|
81
|
+
// Id repair is automatic here (top-down, aliases recorded).
|
|
82
|
+
const plan = planIdRepair(db);
|
|
83
|
+
const repair = applyIdRepair(db, plan);
|
|
84
|
+
result.ids_repaired = plan.entries.map((e) => ({
|
|
85
|
+
old: e.oldId,
|
|
86
|
+
new: e.newId,
|
|
87
|
+
}));
|
|
88
|
+
report.repairedIds = repair.renamed;
|
|
89
|
+
// FTS rebuilt over the fresh data.
|
|
90
|
+
const hasFts = db.execSqlFirst("SELECT 1 FROM sqlite_master WHERE type='table' AND name='nodes_fts'") !== undefined;
|
|
91
|
+
if (hasFts) {
|
|
92
|
+
db.execSql("INSERT INTO nodes_fts(nodes_fts) VALUES('rebuild')");
|
|
93
|
+
}
|
|
94
|
+
// name_norm backfill for every row (may lag on old dbs).
|
|
95
|
+
const pendingNorm = db.execSqlAll("SELECT id, name FROM nodes WHERE name_norm = '' LIMIT 100000");
|
|
96
|
+
for (const row of pendingNorm) {
|
|
97
|
+
db.execSqlRun("UPDATE nodes SET name_norm = ? WHERE id = ?", row.name.normalize("NFKD").toLowerCase().normalize("NFC"), row.id);
|
|
98
|
+
}
|
|
99
|
+
ensureEmbedMeta(db, report);
|
|
100
|
+
db.setMetaValue("schema_version", MIGRATION_TARGET_SCHEMA_VERSION);
|
|
101
|
+
// F14.3: postflight INSIDE the transaction — a failed verification
|
|
102
|
+
// rolls everything back instead of restoring files under locks.
|
|
103
|
+
const after = preflight(db);
|
|
104
|
+
result.after = after;
|
|
105
|
+
const ok = after.nodes === before.nodes &&
|
|
106
|
+
after.empty_ids === 0 &&
|
|
107
|
+
after.orphan_edges === 0 &&
|
|
108
|
+
(!after.fts_rows || after.fts_rows === after.nodes);
|
|
109
|
+
if (!ok) {
|
|
110
|
+
rollbackReason =
|
|
111
|
+
"migration failed verification, database rolled back (no changes written)";
|
|
112
|
+
throw new Error(rollbackReason);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (rollbackReason !== null) {
|
|
118
|
+
result.performed = false;
|
|
119
|
+
result.reembed_required = false;
|
|
120
|
+
result.warnings.push(rollbackReason);
|
|
121
|
+
result.warnings.push(...report.warnings);
|
|
122
|
+
try {
|
|
123
|
+
const dir = path.dirname(dbPath);
|
|
124
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
125
|
+
const reportPath = path.join(dir, `migration-report-${stamp}.json`);
|
|
126
|
+
fs.writeFileSync(reportPath, JSON.stringify({
|
|
127
|
+
at: new Date().toISOString(),
|
|
128
|
+
rolled_back: true,
|
|
129
|
+
reason: rollbackReason,
|
|
130
|
+
backup: result.backup,
|
|
131
|
+
}, null, 2), "utf8");
|
|
132
|
+
result.report_file = reportPath;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// a failed report write must not mask the failure
|
|
136
|
+
}
|
|
137
|
+
throw new Error(rollbackReason);
|
|
138
|
+
}
|
|
139
|
+
throw err;
|
|
140
|
+
}
|
|
141
|
+
result.performed = true;
|
|
142
|
+
result.reembed_required = report.reembedNeeded;
|
|
143
|
+
result.warnings.push(...report.warnings);
|
|
144
|
+
// F14.4: JSON report next to the database.
|
|
145
|
+
try {
|
|
146
|
+
const dir = path.dirname(dbPath);
|
|
147
|
+
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
148
|
+
const reportPath = path.join(dir, `migration-report-${stamp}.json`);
|
|
149
|
+
fs.writeFileSync(reportPath, JSON.stringify({
|
|
150
|
+
at: new Date().toISOString(),
|
|
151
|
+
from_schema: before.schema_version,
|
|
152
|
+
to_schema: Number(MIGRATION_TARGET_SCHEMA_VERSION),
|
|
153
|
+
before: {
|
|
154
|
+
nodes: before.nodes,
|
|
155
|
+
edges: before.edges,
|
|
156
|
+
empty_ids: before.empty_ids,
|
|
157
|
+
orphan_edges: before.orphan_edges,
|
|
158
|
+
},
|
|
159
|
+
after: {
|
|
160
|
+
nodes: result.after?.nodes,
|
|
161
|
+
edges: result.after?.edges,
|
|
162
|
+
empty_ids: result.after?.empty_ids,
|
|
163
|
+
orphan_edges: result.after?.orphan_edges,
|
|
164
|
+
fts_rows: result.after?.fts_rows,
|
|
165
|
+
},
|
|
166
|
+
ids_repaired: result.ids_repaired,
|
|
167
|
+
aliases: result.ids_repaired.length,
|
|
168
|
+
backup: result.backup,
|
|
169
|
+
reembed_required: result.reembed_required,
|
|
170
|
+
warnings: result.warnings,
|
|
171
|
+
}, null, 2), "utf8");
|
|
172
|
+
result.report_file = reportPath;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// a failed report write must not fail the migration itself
|
|
176
|
+
}
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/** One-line stderr summary for startup (F14.4). */
|
|
180
|
+
export function describeAutoMigration(r) {
|
|
181
|
+
if (!r.performed)
|
|
182
|
+
return null;
|
|
183
|
+
const parts = [`${r.after?.nodes ?? r.before.nodes} nodes`];
|
|
184
|
+
if (r.ids_repaired.length > 0)
|
|
185
|
+
parts.push(`${r.ids_repaired.length} ids repaired`);
|
|
186
|
+
if (r.reembed_required)
|
|
187
|
+
parts.push("reembed required");
|
|
188
|
+
return `migrated: upstream schema → v${MIGRATION_TARGET_SCHEMA_VERSION} · ${parts.join(" · ")}`;
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=auto-migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-migrate.js","sourceRoot":"","sources":["../src/auto-migrate.ts"],"names":[],"mappings":"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"}
|
package/dist/db.d.ts
CHANGED
|
@@ -73,7 +73,26 @@ export declare class KnowledgeDB {
|
|
|
73
73
|
* Set a node's lifecycle status. Only superseded nodes get valid_until.
|
|
74
74
|
* Idempotent: setting the same status again is a harmless rewrite.
|
|
75
75
|
*/
|
|
76
|
-
|
|
76
|
+
private statusHistoryReady;
|
|
77
|
+
private ensureStatusHistoryTable;
|
|
78
|
+
setNodeStatus(id: string, status: string, validUntil?: string, reason?: string): boolean;
|
|
79
|
+
/** U5: append a status transition row (table self-heals on legacy dbs). */
|
|
80
|
+
recordStatusHistory(nodeId: string, fromStatus: string | null, toStatus: string, reason?: string): void;
|
|
81
|
+
/** U5: transitions of one node, newest first. */
|
|
82
|
+
getStatusHistory(nodeId: string, limit?: number): Array<{
|
|
83
|
+
from_status: string | null;
|
|
84
|
+
to_status: string;
|
|
85
|
+
reason: string | null;
|
|
86
|
+
at: string;
|
|
87
|
+
}>;
|
|
88
|
+
/** U5: all status transitions, newest first (timeline). */
|
|
89
|
+
getAllStatusHistory(limit?: number): Array<{
|
|
90
|
+
node_id: string;
|
|
91
|
+
from_status: string | null;
|
|
92
|
+
to_status: string;
|
|
93
|
+
reason: string | null;
|
|
94
|
+
at: string;
|
|
95
|
+
}>;
|
|
77
96
|
/**
|
|
78
97
|
* Mark old nodes superseded and link them from the replacement
|
|
79
98
|
* (new --supersedes--> old). Returns the ids that were actually
|
package/dist/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
package/dist/db.js
CHANGED
|
@@ -378,15 +378,64 @@ export class KnowledgeDB {
|
|
|
378
378
|
* Set a node's lifecycle status. Only superseded nodes get valid_until.
|
|
379
379
|
* Idempotent: setting the same status again is a harmless rewrite.
|
|
380
380
|
*/
|
|
381
|
-
|
|
381
|
+
statusHistoryReady = false;
|
|
382
|
+
ensureStatusHistoryTable() {
|
|
383
|
+
if (this.statusHistoryReady)
|
|
384
|
+
return;
|
|
385
|
+
this.db.exec("CREATE TABLE IF NOT EXISTS status_history (\
|
|
386
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,\
|
|
387
|
+
node_id TEXT NOT NULL,\
|
|
388
|
+
from_status TEXT,\
|
|
389
|
+
to_status TEXT NOT NULL,\
|
|
390
|
+
reason TEXT,\
|
|
391
|
+
at TEXT NOT NULL DEFAULT (datetime('now'))\
|
|
392
|
+
)");
|
|
393
|
+
this.db.exec("CREATE INDEX IF NOT EXISTS idx_status_history_node ON status_history(node_id)");
|
|
394
|
+
this.statusHistoryReady = true;
|
|
395
|
+
}
|
|
396
|
+
setNodeStatus(id, status, validUntil, reason) {
|
|
397
|
+
// U5: record every real transition (active -> superseded, ...).
|
|
398
|
+
const previous = this.execSqlFirst("SELECT status FROM nodes WHERE id = ?", id)?.status;
|
|
382
399
|
const result = this.db
|
|
383
400
|
.prepare(`UPDATE nodes SET status = @status,
|
|
384
401
|
valid_until = COALESCE(@validUntil, valid_until),
|
|
385
402
|
updated_at = datetime('now')
|
|
386
403
|
WHERE id = @id`)
|
|
387
404
|
.run({ status, validUntil: validUntil ?? null, id });
|
|
405
|
+
if (result.changes > 0 && previous !== status) {
|
|
406
|
+
this.recordStatusHistory(id, previous ?? null, status, reason);
|
|
407
|
+
}
|
|
388
408
|
return result.changes > 0;
|
|
389
409
|
}
|
|
410
|
+
/** U5: append a status transition row (table self-heals on legacy dbs). */
|
|
411
|
+
recordStatusHistory(nodeId, fromStatus, toStatus, reason) {
|
|
412
|
+
this.ensureStatusHistoryTable();
|
|
413
|
+
this.db
|
|
414
|
+
.prepare("INSERT INTO status_history (node_id, from_status, to_status, reason) VALUES (?, ?, ?, ?)")
|
|
415
|
+
.run(nodeId, fromStatus, toStatus, reason ?? null);
|
|
416
|
+
}
|
|
417
|
+
/** U5: transitions of one node, newest first. */
|
|
418
|
+
getStatusHistory(nodeId, limit = 5) {
|
|
419
|
+
const has = this.db
|
|
420
|
+
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='status_history'")
|
|
421
|
+
.get();
|
|
422
|
+
if (!has)
|
|
423
|
+
return [];
|
|
424
|
+
return this.db
|
|
425
|
+
.prepare("SELECT from_status, to_status, reason, at FROM status_history WHERE node_id = ? ORDER BY id DESC LIMIT ?")
|
|
426
|
+
.all(nodeId, limit);
|
|
427
|
+
}
|
|
428
|
+
/** U5: all status transitions, newest first (timeline). */
|
|
429
|
+
getAllStatusHistory(limit = 200) {
|
|
430
|
+
const has = this.db
|
|
431
|
+
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='status_history'")
|
|
432
|
+
.get();
|
|
433
|
+
if (!has)
|
|
434
|
+
return [];
|
|
435
|
+
return this.db
|
|
436
|
+
.prepare("SELECT node_id, from_status, to_status, reason, at FROM status_history ORDER BY id DESC LIMIT ?")
|
|
437
|
+
.all(limit);
|
|
438
|
+
}
|
|
390
439
|
/**
|
|
391
440
|
* Mark old nodes superseded and link them from the replacement
|
|
392
441
|
* (new --supersedes--> old). Returns the ids that were actually
|
|
@@ -406,7 +455,7 @@ export class KnowledgeDB {
|
|
|
406
455
|
to_id: oldId,
|
|
407
456
|
relation: "supersedes",
|
|
408
457
|
});
|
|
409
|
-
this.setNodeStatus(oldId, "superseded", new Date().toISOString());
|
|
458
|
+
this.setNodeStatus(oldId, "superseded", new Date().toISOString(), `superseded by ${newId}`);
|
|
410
459
|
superseded.push(oldId);
|
|
411
460
|
}
|
|
412
461
|
});
|