fastrmemory 0.5.0 → 0.6.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -2
- package/.cursor/skills/skills.json +1 -1
- package/README.md +40 -30
- package/dist/bin/fastr.js +122 -14
- package/dist/bin/fastr.js.map +1 -1
- package/dist/src/bench/harness.d.ts.map +1 -1
- package/dist/src/bench/harness.js +4 -0
- package/dist/src/bench/harness.js.map +1 -1
- package/dist/src/bench/marker-corpus.d.ts +98 -0
- package/dist/src/bench/marker-corpus.d.ts.map +1 -0
- package/dist/src/bench/marker-corpus.js +306 -0
- package/dist/src/bench/marker-corpus.js.map +1 -0
- package/dist/src/bench/mcp-stdio.d.ts +55 -0
- package/dist/src/bench/mcp-stdio.d.ts.map +1 -0
- package/dist/src/bench/mcp-stdio.js +146 -0
- package/dist/src/bench/mcp-stdio.js.map +1 -0
- package/dist/src/bench/public-datasets.d.ts +2 -0
- package/dist/src/bench/public-datasets.d.ts.map +1 -1
- package/dist/src/bench/public-datasets.js +2 -1
- package/dist/src/bench/public-datasets.js.map +1 -1
- package/dist/src/bench/public-harness.d.ts +14 -0
- package/dist/src/bench/public-harness.d.ts.map +1 -1
- package/dist/src/bench/public-harness.js +83 -8
- package/dist/src/bench/public-harness.js.map +1 -1
- package/dist/src/bench/public-pins.js +5 -5
- package/dist/src/bench/public-pins.js.map +1 -1
- package/dist/src/bench/split.d.ts +33 -0
- package/dist/src/bench/split.d.ts.map +1 -0
- package/dist/src/bench/split.js +56 -0
- package/dist/src/bench/split.js.map +1 -0
- package/dist/src/bench/stats.d.ts +40 -0
- package/dist/src/bench/stats.d.ts.map +1 -0
- package/dist/src/bench/stats.js +99 -0
- package/dist/src/bench/stats.js.map +1 -0
- package/dist/src/bench/vs-engines.d.ts +51 -0
- package/dist/src/bench/vs-engines.d.ts.map +1 -0
- package/dist/src/bench/vs-engines.js +121 -0
- package/dist/src/bench/vs-engines.js.map +1 -0
- package/dist/src/config.d.ts +33 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +84 -1
- package/dist/src/config.js.map +1 -1
- package/dist/src/db/doctor.d.ts +8 -0
- package/dist/src/db/doctor.d.ts.map +1 -1
- package/dist/src/db/doctor.js +65 -1
- package/dist/src/db/doctor.js.map +1 -1
- package/dist/src/db/fts-queue.d.ts +35 -0
- package/dist/src/db/fts-queue.d.ts.map +1 -0
- package/dist/src/db/fts-queue.js +78 -0
- package/dist/src/db/fts-queue.js.map +1 -0
- package/dist/src/db/repository.d.ts +63 -1
- package/dist/src/db/repository.d.ts.map +1 -1
- package/dist/src/db/repository.js +244 -50
- package/dist/src/db/repository.js.map +1 -1
- package/dist/src/db/schema.d.ts +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +63 -2
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/installer/copilot.d.ts +21 -0
- package/dist/src/installer/copilot.d.ts.map +1 -1
- package/dist/src/installer/copilot.js +72 -1
- package/dist/src/installer/copilot.js.map +1 -1
- package/dist/src/installer/gemini.d.ts +13 -0
- package/dist/src/installer/gemini.d.ts.map +1 -1
- package/dist/src/installer/gemini.js +64 -1
- package/dist/src/installer/gemini.js.map +1 -1
- package/dist/src/installer/hooks.d.ts +42 -5
- package/dist/src/installer/hooks.d.ts.map +1 -1
- package/dist/src/installer/hooks.js +270 -62
- package/dist/src/installer/hooks.js.map +1 -1
- package/dist/src/installer/json-config.d.ts +25 -1
- package/dist/src/installer/json-config.d.ts.map +1 -1
- package/dist/src/installer/json-config.js +95 -2
- package/dist/src/installer/json-config.js.map +1 -1
- package/dist/src/installer/mcp-init.d.ts.map +1 -1
- package/dist/src/installer/mcp-init.js +5 -6
- package/dist/src/installer/mcp-init.js.map +1 -1
- package/dist/src/installer/opencode.d.ts +18 -0
- package/dist/src/installer/opencode.d.ts.map +1 -1
- package/dist/src/installer/opencode.js +81 -1
- package/dist/src/installer/opencode.js.map +1 -1
- package/dist/src/installer/setup.d.ts +7 -0
- package/dist/src/installer/setup.d.ts.map +1 -1
- package/dist/src/installer/setup.js +32 -0
- package/dist/src/installer/setup.js.map +1 -1
- package/dist/src/mcp/profiles.d.ts +9 -6
- package/dist/src/mcp/profiles.d.ts.map +1 -1
- package/dist/src/mcp/profiles.js +12 -9
- package/dist/src/mcp/profiles.js.map +1 -1
- package/dist/src/mcp/server.d.ts +1 -1
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +80 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/search/aggregate.d.ts +24 -0
- package/dist/src/search/aggregate.d.ts.map +1 -0
- package/dist/src/search/aggregate.js +59 -0
- package/dist/src/search/aggregate.js.map +1 -0
- package/dist/src/search/backfill.d.ts.map +1 -1
- package/dist/src/search/backfill.js +7 -2
- package/dist/src/search/backfill.js.map +1 -1
- package/dist/src/search/budget.d.ts +2 -0
- package/dist/src/search/budget.d.ts.map +1 -1
- package/dist/src/search/budget.js.map +1 -1
- package/dist/src/search/embeddings.d.ts +35 -2
- package/dist/src/search/embeddings.d.ts.map +1 -1
- package/dist/src/search/embeddings.js +128 -5
- package/dist/src/search/embeddings.js.map +1 -1
- package/dist/src/search/hybrid-rrf.d.ts +45 -0
- package/dist/src/search/hybrid-rrf.d.ts.map +1 -1
- package/dist/src/search/hybrid-rrf.js +212 -56
- package/dist/src/search/hybrid-rrf.js.map +1 -1
- package/dist/src/search/static-model-install.d.ts +43 -0
- package/dist/src/search/static-model-install.d.ts.map +1 -0
- package/dist/src/search/static-model-install.js +112 -0
- package/dist/src/search/static-model-install.js.map +1 -0
- package/dist/src/search/static-model.d.ts +63 -0
- package/dist/src/search/static-model.d.ts.map +1 -0
- package/dist/src/search/static-model.js +244 -0
- package/dist/src/search/static-model.js.map +1 -0
- package/dist/src/search/temporal.d.ts +32 -0
- package/dist/src/search/temporal.d.ts.map +1 -0
- package/dist/src/search/temporal.js +164 -0
- package/dist/src/search/temporal.js.map +1 -0
- package/llms-install.md +3 -3
- package/package.json +5 -1
- package/server.json +1 -1
- package/skills/skills.json +1 -1
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine descriptors for the cross-engine comparison.
|
|
3
|
+
*
|
|
4
|
+
* Each descriptor pins a package version, states how to start it over MCP stdio, how to
|
|
5
|
+
* isolate its on-disk state, and how to map one marker document and one query onto its
|
|
6
|
+
* tools. Nothing engine-specific lives outside this file.
|
|
7
|
+
*
|
|
8
|
+
* Isolation was verified by probing, not assumed:
|
|
9
|
+
* - fastrmemory honours `FASTR_HOME` for the global database and `--project` for the
|
|
10
|
+
* project database.
|
|
11
|
+
* - agentmemory ignores `AGENTMEMORY_DATA_DIR` and resolves `homedir()/.agentmemory`,
|
|
12
|
+
* so `USERPROFILE` and `HOME` both point at a fresh directory per case.
|
|
13
|
+
* - hippo's MCP server ignores `HIPPO_HOME` and writes to `~/.hippo` unless the working
|
|
14
|
+
* directory contains a `.hippo` store, so each case runs `hippo init` in its own
|
|
15
|
+
* project directory first and also gets a fresh home.
|
|
16
|
+
*/
|
|
17
|
+
import { execFileSync } from 'node:child_process';
|
|
18
|
+
import * as fs from 'node:fs';
|
|
19
|
+
import * as path from 'node:path';
|
|
20
|
+
function readVersion(packageJson) {
|
|
21
|
+
const parsed = JSON.parse(fs.readFileSync(packageJson, 'utf8'));
|
|
22
|
+
return parsed.version ?? 'unknown';
|
|
23
|
+
}
|
|
24
|
+
export function createVsEngines(environment) {
|
|
25
|
+
const { repoRoot, externalDir } = environment;
|
|
26
|
+
const fastrEntry = path.join(repoRoot, 'dist', 'bin', 'fastr.js');
|
|
27
|
+
const agentmemoryEntry = path.join(externalDir, 'node_modules', '@agentmemory', 'mcp', 'bin.mjs');
|
|
28
|
+
const hippoEntry = path.join(externalDir, 'node_modules', 'hippo-memory', 'bin', 'hippo.js');
|
|
29
|
+
const fastrVersion = readVersion(path.join(repoRoot, 'package.json'));
|
|
30
|
+
const engines = [
|
|
31
|
+
{
|
|
32
|
+
id: 'fastrmemory',
|
|
33
|
+
label: 'FastrMemory',
|
|
34
|
+
version: fastrVersion,
|
|
35
|
+
entry: fastrEntry,
|
|
36
|
+
needsProjectDir: true,
|
|
37
|
+
bootstrap: async (dirs) => {
|
|
38
|
+
fs.mkdirSync(dirs.project, { recursive: true });
|
|
39
|
+
fs.mkdirSync(dirs.home, { recursive: true });
|
|
40
|
+
},
|
|
41
|
+
spec: (dirs) => ({
|
|
42
|
+
command: process.execPath,
|
|
43
|
+
args: [fastrEntry, 'mcp', '--project', dirs.project],
|
|
44
|
+
cwd: dirs.project,
|
|
45
|
+
env: { FASTR_HOME: dirs.home }
|
|
46
|
+
}),
|
|
47
|
+
rememberTool: 'fastr_remember',
|
|
48
|
+
rememberArgs: (doc) => ({
|
|
49
|
+
module: doc.system,
|
|
50
|
+
kind: 'error_trap',
|
|
51
|
+
title: `${doc.marker} ${doc.system} ${doc.problem}`,
|
|
52
|
+
content: doc.content
|
|
53
|
+
}),
|
|
54
|
+
recallTool: 'fastr_recall',
|
|
55
|
+
recallArgs: (query, budgetTokens) => ({ query, budgetTokens })
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'agentmemory',
|
|
59
|
+
label: 'agentmemory',
|
|
60
|
+
version: readVersion(path.join(externalDir, 'node_modules', '@agentmemory', 'mcp', 'package.json')),
|
|
61
|
+
entry: agentmemoryEntry,
|
|
62
|
+
needsProjectDir: true,
|
|
63
|
+
bootstrap: async (dirs) => {
|
|
64
|
+
fs.mkdirSync(dirs.project, { recursive: true });
|
|
65
|
+
fs.mkdirSync(dirs.home, { recursive: true });
|
|
66
|
+
},
|
|
67
|
+
spec: (dirs) => ({
|
|
68
|
+
command: process.execPath,
|
|
69
|
+
args: [agentmemoryEntry],
|
|
70
|
+
cwd: dirs.project,
|
|
71
|
+
env: { USERPROFILE: dirs.home, HOME: dirs.home }
|
|
72
|
+
}),
|
|
73
|
+
rememberTool: 'memory_save',
|
|
74
|
+
rememberArgs: (doc) => ({
|
|
75
|
+
content: doc.content,
|
|
76
|
+
type: 'fact',
|
|
77
|
+
project: doc.system
|
|
78
|
+
}),
|
|
79
|
+
recallTool: 'memory_recall',
|
|
80
|
+
recallArgs: (query, budgetTokens) => ({ query, limit: 10, token_budget: budgetTokens })
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'hippo',
|
|
84
|
+
label: 'Hippo',
|
|
85
|
+
version: readVersion(path.join(externalDir, 'node_modules', 'hippo-memory', 'package.json')),
|
|
86
|
+
entry: hippoEntry,
|
|
87
|
+
needsProjectDir: true,
|
|
88
|
+
bootstrap: async (dirs) => {
|
|
89
|
+
fs.mkdirSync(dirs.project, { recursive: true });
|
|
90
|
+
fs.mkdirSync(dirs.home, { recursive: true });
|
|
91
|
+
execFileSync(process.execPath, [hippoEntry, 'init', '--no-hooks', '--no-schedule', '--no-learn'], {
|
|
92
|
+
cwd: dirs.project,
|
|
93
|
+
env: { ...process.env, USERPROFILE: dirs.home, HOME: dirs.home },
|
|
94
|
+
stdio: 'ignore',
|
|
95
|
+
timeout: 120_000
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
spec: (dirs) => ({
|
|
99
|
+
command: process.execPath,
|
|
100
|
+
args: [hippoEntry, 'mcp'],
|
|
101
|
+
cwd: dirs.project,
|
|
102
|
+
env: { USERPROFILE: dirs.home, HOME: dirs.home }
|
|
103
|
+
}),
|
|
104
|
+
rememberTool: 'hippo_remember',
|
|
105
|
+
rememberArgs: (doc) => ({ text: doc.content }),
|
|
106
|
+
recallTool: 'hippo_recall',
|
|
107
|
+
recallArgs: (query, budgetTokens) => ({ query, budget: budgetTokens })
|
|
108
|
+
}
|
|
109
|
+
];
|
|
110
|
+
return engines;
|
|
111
|
+
}
|
|
112
|
+
/** Fails early with an actionable message instead of timing out inside the MCP handshake. */
|
|
113
|
+
export function assertEngineAvailable(engine, externalDir) {
|
|
114
|
+
if (!fs.existsSync(engine.entry)) {
|
|
115
|
+
const hint = engine.id.startsWith('fastrmemory')
|
|
116
|
+
? 'run `npm run build:core`'
|
|
117
|
+
: `run \`npm run bench:setup\` (installs the pinned engines into ${externalDir})`;
|
|
118
|
+
throw new Error(`${engine.label} entry point is missing at ${engine.entry}; ${hint}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=vs-engines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vs-engines.js","sourceRoot":"","sources":["../../../src/bench/vs-engines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAoClC,SAAS,WAAW,CAAC,WAAmB;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAyB,CAAC;IACxF,OAAO,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,WAA8B;IAC5D,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,WAAW,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IAClG,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC7F,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IAEtE,MAAM,OAAO,GAAe;QAC1B;YACE,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,YAAY;YACrB,KAAK,EAAE,UAAU;YACjB,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACxB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACf,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,IAAI,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC;gBACpD,GAAG,EAAE,IAAI,CAAC,OAAO;gBACjB,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,EAAE;aAC/B,CAAC;YACF,YAAY,EAAE,gBAAgB;YAC9B,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE;gBACnD,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC;YACF,UAAU,EAAE,cAAc;YAC1B,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;SAC/D;QACD;YACE,EAAE,EAAE,aAAa;YACjB,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;YACnG,KAAK,EAAE,gBAAgB;YACvB,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACxB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;YACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACf,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,IAAI,EAAE,CAAC,gBAAgB,CAAC;gBACxB,GAAG,EAAE,IAAI,CAAC,OAAO;gBACjB,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aACjD,CAAC;YACF,YAAY,EAAE,aAAa;YAC3B,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBACtB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,GAAG,CAAC,MAAM;aACpB,CAAC;YACF,UAAU,EAAE,eAAe;YAC3B,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;SACxF;QACD;YACE,EAAE,EAAE,OAAO;YACX,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;YAC5F,KAAK,EAAE,UAAU;YACjB,eAAe,EAAE,IAAI;YACrB,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;gBACxB,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC7C,YAAY,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE;oBAChG,GAAG,EAAE,IAAI,CAAC,OAAO;oBACjB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;oBAChE,KAAK,EAAE,QAAQ;oBACf,OAAO,EAAE,OAAO;iBACjB,CAAC,CAAC;YACL,CAAC;YACD,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACf,OAAO,EAAE,OAAO,CAAC,QAAQ;gBACzB,IAAI,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC;gBACzB,GAAG,EAAE,IAAI,CAAC,OAAO;gBACjB,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;aACjD,CAAC;YACF,YAAY,EAAE,gBAAgB;YAC9B,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;YAC9C,UAAU,EAAE,cAAc;YAC1B,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;SACvE;KACF,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,qBAAqB,CAAC,MAAgB,EAAE,WAAmB;IACzE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,GACR,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC;YACjC,CAAC,CAAC,0BAA0B;YAC5B,CAAC,CAAC,iEAAiE,WAAW,GAAG,CAAC;QACtF,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,8BAA8B,MAAM,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC,CAAC;IACxF,CAAC;AACH,CAAC"}
|
package/dist/src/config.d.ts
CHANGED
|
@@ -6,7 +6,40 @@ export interface FastrConfig {
|
|
|
6
6
|
globalDbPath: string;
|
|
7
7
|
spoolPath: string;
|
|
8
8
|
pagesDir: string;
|
|
9
|
+
write?: WriteConfig;
|
|
9
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Conflict analysis runs either inline (legacy), from the deferred queue (default), or not
|
|
13
|
+
* at all. 'deferred' keeps the feature but moves the 50-window scan off the write path.
|
|
14
|
+
*/
|
|
15
|
+
export type ConflictMode = 'sync' | 'deferred' | 'off';
|
|
16
|
+
/** Entity extraction runs inline ('sync') or from the deferred analysis queue ('deferred'). */
|
|
17
|
+
export type NerMode = 'sync' | 'deferred';
|
|
18
|
+
/** Full-text indexing runs inline ('sync') or from the deferred index queue ('deferred'). */
|
|
19
|
+
export type FtsMode = 'sync' | 'deferred';
|
|
20
|
+
export interface WriteConfig {
|
|
21
|
+
conflictMode: ConflictMode;
|
|
22
|
+
nerMode: NerMode;
|
|
23
|
+
ftsMode: FtsMode;
|
|
24
|
+
}
|
|
25
|
+
export declare function parseConflictMode(value: unknown): ConflictMode | null;
|
|
26
|
+
export declare function parseNerMode(value: unknown): NerMode | null;
|
|
27
|
+
export declare function parseFtsMode(value: unknown): FtsMode | null;
|
|
28
|
+
/**
|
|
29
|
+
* Resolves write.conflictMode. Precedence: FASTR_CONFLICT_MODE, then
|
|
30
|
+
* `.fastr/project.json` -> `write.conflictMode`, then 'deferred'.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveConflictMode(projectRoot?: string): ConflictMode;
|
|
33
|
+
/**
|
|
34
|
+
* Resolves write.nerMode. Precedence: FASTR_NER_MODE, then
|
|
35
|
+
* `.fastr/project.json` -> `write.nerMode`, then 'deferred'.
|
|
36
|
+
*/
|
|
37
|
+
export declare function resolveNerMode(projectRoot?: string): NerMode;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves write.ftsMode. Precedence: FASTR_FTS_MODE, then
|
|
40
|
+
* `.fastr/project.json` -> `write.ftsMode`, then 'deferred'.
|
|
41
|
+
*/
|
|
42
|
+
export declare function resolveFtsMode(projectRoot?: string): FtsMode;
|
|
10
43
|
export declare function findProjectRoot(startDir?: string): string;
|
|
11
44
|
export declare function resolveFastrHome(homeDir?: string): string;
|
|
12
45
|
export declare function loadConfig(customRoot?: string, homeDir?: string): FastrConfig;
|
package/dist/src/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAgBxE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,CAAC;AAEvD,+FAA+F;AAC/F,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1C,6FAA6F;AAC7F,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAMD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,IAAI,CAGrE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAG3D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAG3D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAetE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAe5D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAe5D;AAED,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAgBxE;AAED,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,WAAW,CA2C7E"}
|
package/dist/src/config.js
CHANGED
|
@@ -2,6 +2,84 @@ import * as path from 'node:path';
|
|
|
2
2
|
import * as fs from 'node:fs';
|
|
3
3
|
import * as crypto from 'node:crypto';
|
|
4
4
|
import * as os from 'node:os';
|
|
5
|
+
const CONFLICT_MODES = new Set(['sync', 'deferred', 'off']);
|
|
6
|
+
const NER_MODES = new Set(['sync', 'deferred']);
|
|
7
|
+
const FTS_MODES = new Set(['sync', 'deferred']);
|
|
8
|
+
export function parseConflictMode(value) {
|
|
9
|
+
const normalized = String(value ?? '').trim().toLowerCase();
|
|
10
|
+
return CONFLICT_MODES.has(normalized) ? normalized : null;
|
|
11
|
+
}
|
|
12
|
+
export function parseNerMode(value) {
|
|
13
|
+
const normalized = String(value ?? '').trim().toLowerCase();
|
|
14
|
+
return NER_MODES.has(normalized) ? normalized : null;
|
|
15
|
+
}
|
|
16
|
+
export function parseFtsMode(value) {
|
|
17
|
+
const normalized = String(value ?? '').trim().toLowerCase();
|
|
18
|
+
return FTS_MODES.has(normalized) ? normalized : null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolves write.conflictMode. Precedence: FASTR_CONFLICT_MODE, then
|
|
22
|
+
* `.fastr/project.json` -> `write.conflictMode`, then 'deferred'.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveConflictMode(projectRoot) {
|
|
25
|
+
const fromEnv = parseConflictMode(process.env.FASTR_CONFLICT_MODE);
|
|
26
|
+
if (fromEnv)
|
|
27
|
+
return fromEnv;
|
|
28
|
+
try {
|
|
29
|
+
const root = projectRoot ? path.resolve(projectRoot) : findProjectRoot();
|
|
30
|
+
const file = path.join(root, '.fastr', 'project.json');
|
|
31
|
+
if (fs.existsSync(file)) {
|
|
32
|
+
const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
33
|
+
const fromFile = parseConflictMode(data?.write?.conflictMode);
|
|
34
|
+
if (fromFile)
|
|
35
|
+
return fromFile;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch { }
|
|
39
|
+
return 'deferred';
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolves write.nerMode. Precedence: FASTR_NER_MODE, then
|
|
43
|
+
* `.fastr/project.json` -> `write.nerMode`, then 'deferred'.
|
|
44
|
+
*/
|
|
45
|
+
export function resolveNerMode(projectRoot) {
|
|
46
|
+
const fromEnv = parseNerMode(process.env.FASTR_NER_MODE);
|
|
47
|
+
if (fromEnv)
|
|
48
|
+
return fromEnv;
|
|
49
|
+
try {
|
|
50
|
+
const root = projectRoot ? path.resolve(projectRoot) : findProjectRoot();
|
|
51
|
+
const file = path.join(root, '.fastr', 'project.json');
|
|
52
|
+
if (fs.existsSync(file)) {
|
|
53
|
+
const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
54
|
+
const fromFile = parseNerMode(data?.write?.nerMode);
|
|
55
|
+
if (fromFile)
|
|
56
|
+
return fromFile;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch { }
|
|
60
|
+
return 'deferred';
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Resolves write.ftsMode. Precedence: FASTR_FTS_MODE, then
|
|
64
|
+
* `.fastr/project.json` -> `write.ftsMode`, then 'deferred'.
|
|
65
|
+
*/
|
|
66
|
+
export function resolveFtsMode(projectRoot) {
|
|
67
|
+
const fromEnv = parseFtsMode(process.env.FASTR_FTS_MODE);
|
|
68
|
+
if (fromEnv)
|
|
69
|
+
return fromEnv;
|
|
70
|
+
try {
|
|
71
|
+
const root = projectRoot ? path.resolve(projectRoot) : findProjectRoot();
|
|
72
|
+
const file = path.join(root, '.fastr', 'project.json');
|
|
73
|
+
if (fs.existsSync(file)) {
|
|
74
|
+
const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
75
|
+
const fromFile = parseFtsMode(data?.write?.ftsMode);
|
|
76
|
+
if (fromFile)
|
|
77
|
+
return fromFile;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch { }
|
|
81
|
+
return 'deferred';
|
|
82
|
+
}
|
|
5
83
|
export function findProjectRoot(startDir = process.cwd()) {
|
|
6
84
|
let cur = path.resolve(startDir);
|
|
7
85
|
while (true) {
|
|
@@ -51,7 +129,12 @@ export function loadConfig(customRoot, homeDir) {
|
|
|
51
129
|
dbPath: path.join(fastrDir, 'fastr.db'),
|
|
52
130
|
globalDbPath: path.join(resolveFastrHome(homeDir), '.fastr', 'global.db'),
|
|
53
131
|
spoolPath: path.join(fastrDir, 'spool', 'pending.jsonl'),
|
|
54
|
-
pagesDir: path.join(fastrDir, 'pages')
|
|
132
|
+
pagesDir: path.join(fastrDir, 'pages'),
|
|
133
|
+
write: {
|
|
134
|
+
conflictMode: resolveConflictMode(projectRoot),
|
|
135
|
+
nerMode: resolveNerMode(projectRoot),
|
|
136
|
+
ftsMode: resolveFtsMode(projectRoot)
|
|
137
|
+
}
|
|
55
138
|
};
|
|
56
139
|
}
|
|
57
140
|
//# sourceMappingURL=config.js.map
|
package/dist/src/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/src/db/doctor.d.ts
CHANGED
|
@@ -18,6 +18,8 @@ export interface DiagnosticReport {
|
|
|
18
18
|
fileLinkCount: number;
|
|
19
19
|
actionCount: number;
|
|
20
20
|
walMode: string;
|
|
21
|
+
pendingConflicts: number;
|
|
22
|
+
pendingFts: number;
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
export interface HealResult {
|
|
@@ -25,12 +27,18 @@ export interface HealResult {
|
|
|
25
27
|
fixedCount: number;
|
|
26
28
|
actionsTaken: string[];
|
|
27
29
|
remainingIssues: number;
|
|
30
|
+
conflictsDrained?: number;
|
|
31
|
+
conflictsCreated?: number;
|
|
32
|
+
entitiesDrained?: number;
|
|
33
|
+
ftsDrained?: number;
|
|
28
34
|
reportBefore: DiagnosticReport;
|
|
29
35
|
reportAfter?: DiagnosticReport;
|
|
30
36
|
}
|
|
31
37
|
export declare function diagnoseDatabase(db: DatabaseSync, projectId: string): DiagnosticReport;
|
|
32
38
|
export declare function healDatabase(db: DatabaseSync, projectId: string, options?: {
|
|
33
39
|
dryRun?: boolean;
|
|
40
|
+
drainConflicts?: boolean;
|
|
41
|
+
conflictBatchSize?: number;
|
|
34
42
|
}): HealResult;
|
|
35
43
|
/**
|
|
36
44
|
* memories_fts is a regular (content-storing) FTS5 table, so the 'rebuild' command is a no-op
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/db/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/db/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,CAAC;IACtE,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,CAAC;QACzB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CA6MtF;AAED,wBAAgB,YAAY,CAC1B,EAAE,EAAE,YAAY,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,UAAU,CAuHZ;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,YAAY,GAAG,MAAM,CAgB3D"}
|
package/dist/src/db/doctor.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FastrRepository } from './repository.js';
|
|
1
2
|
export function diagnoseDatabase(db, projectId) {
|
|
2
3
|
const issues = [];
|
|
3
4
|
// 1. SQLite B-Tree Integrity
|
|
@@ -40,6 +41,7 @@ export function diagnoseDatabase(db, projectId) {
|
|
|
40
41
|
const missingRow = db.prepare(`
|
|
41
42
|
SELECT COUNT(*) as c FROM main.memories m
|
|
42
43
|
WHERE NOT EXISTS (SELECT 1 FROM main.memories_fts f WHERE f.id = m.id)
|
|
44
|
+
AND NOT EXISTS (SELECT 1 FROM main.memory_fts_queue q WHERE q.memory_id = m.id)
|
|
43
45
|
`).get();
|
|
44
46
|
const missing = Number(missingRow?.c || 0);
|
|
45
47
|
const staleRow = db.prepare(`
|
|
@@ -148,6 +150,36 @@ export function diagnoseDatabase(db, projectId) {
|
|
|
148
150
|
}
|
|
149
151
|
catch { }
|
|
150
152
|
const fixableIssues = issues.filter(i => i.fixable).length;
|
|
153
|
+
let pendingConflicts = 0;
|
|
154
|
+
let pendingFts = 0;
|
|
155
|
+
try {
|
|
156
|
+
const queueRow = db.prepare('SELECT COUNT(*) AS c FROM memory_conflict_queue').get();
|
|
157
|
+
pendingConflicts = Number(queueRow?.c || 0);
|
|
158
|
+
if (pendingConflicts > 0) {
|
|
159
|
+
issues.push({
|
|
160
|
+
category: 'integrity',
|
|
161
|
+
severity: 'info',
|
|
162
|
+
description: `${pendingConflicts} memories are queued for deferred conflict analysis.`,
|
|
163
|
+
fixable: true,
|
|
164
|
+
affectedCount: pendingConflicts
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
catch { }
|
|
169
|
+
try {
|
|
170
|
+
const ftsQueueRow = db.prepare('SELECT COUNT(*) AS c FROM memory_fts_queue').get();
|
|
171
|
+
pendingFts = Number(ftsQueueRow?.c || 0);
|
|
172
|
+
if (pendingFts > 0) {
|
|
173
|
+
issues.push({
|
|
174
|
+
category: 'fts5',
|
|
175
|
+
severity: 'info',
|
|
176
|
+
description: `${pendingFts} memories are queued for deferred full-text indexing (readers index them on demand).`,
|
|
177
|
+
fixable: true,
|
|
178
|
+
affectedCount: pendingFts
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
151
183
|
return {
|
|
152
184
|
healthy: issues.filter(i => i.severity === 'error').length === 0,
|
|
153
185
|
timestamp: new Date().toISOString(),
|
|
@@ -159,7 +191,9 @@ export function diagnoseDatabase(db, projectId) {
|
|
|
159
191
|
ftsRowCount,
|
|
160
192
|
fileLinkCount,
|
|
161
193
|
actionCount,
|
|
162
|
-
walMode
|
|
194
|
+
walMode,
|
|
195
|
+
pendingConflicts,
|
|
196
|
+
pendingFts
|
|
163
197
|
}
|
|
164
198
|
};
|
|
165
199
|
}
|
|
@@ -168,6 +202,10 @@ export function healDatabase(db, projectId, options = {}) {
|
|
|
168
202
|
const reportBefore = diagnoseDatabase(db, projectId);
|
|
169
203
|
const actionsTaken = [];
|
|
170
204
|
let fixedCount = 0;
|
|
205
|
+
let conflictsDrained = 0;
|
|
206
|
+
let conflictsCreated = 0;
|
|
207
|
+
let entitiesDrained = 0;
|
|
208
|
+
let ftsDrained = 0;
|
|
171
209
|
if (dryRun) {
|
|
172
210
|
return {
|
|
173
211
|
dryRun: true,
|
|
@@ -238,12 +276,36 @@ export function healDatabase(db, projectId, options = {}) {
|
|
|
238
276
|
actionsTaken.push('Executed PRAGMA wal_checkpoint(TRUNCATE).');
|
|
239
277
|
}
|
|
240
278
|
catch { }
|
|
279
|
+
// 5. Drain the deferred analysis queues in bounded batches.
|
|
280
|
+
if (options.drainConflicts) {
|
|
281
|
+
const batchSize = Math.max(1, Math.floor(options.conflictBatchSize ?? 20));
|
|
282
|
+
const repo = new FastrRepository(db);
|
|
283
|
+
let guard = 0;
|
|
284
|
+
while (guard++ < 10_000) {
|
|
285
|
+
const result = repo.drainAnalysis(batchSize);
|
|
286
|
+
conflictsDrained += result.conflictsDrained;
|
|
287
|
+
conflictsCreated += result.conflictsCreated;
|
|
288
|
+
entitiesDrained += result.entitiesDrained;
|
|
289
|
+
ftsDrained += result.ftsDrained;
|
|
290
|
+
if (result.conflictsDrained === 0 &&
|
|
291
|
+
result.entitiesDrained === 0 &&
|
|
292
|
+
result.ftsDrained === 0)
|
|
293
|
+
break;
|
|
294
|
+
}
|
|
295
|
+
actionsTaken.push(`Drained ${conflictsDrained} queued conflict checks (${conflictsCreated} conflicts recorded), ` +
|
|
296
|
+
`${entitiesDrained} queued entity extractions, and ${ftsDrained} queued full-text index rows.`);
|
|
297
|
+
fixedCount += conflictsDrained + entitiesDrained + ftsDrained;
|
|
298
|
+
}
|
|
241
299
|
const reportAfter = diagnoseDatabase(db, projectId);
|
|
242
300
|
return {
|
|
243
301
|
dryRun: false,
|
|
244
302
|
fixedCount,
|
|
245
303
|
actionsTaken,
|
|
246
304
|
remainingIssues: reportAfter.totalIssues,
|
|
305
|
+
conflictsDrained,
|
|
306
|
+
conflictsCreated,
|
|
307
|
+
entitiesDrained,
|
|
308
|
+
ftsDrained,
|
|
247
309
|
reportBefore,
|
|
248
310
|
reportAfter
|
|
249
311
|
};
|
|
@@ -260,6 +322,8 @@ export function rebuildMemoriesFts(db) {
|
|
|
260
322
|
INSERT INTO main.memories_fts (id, title, module, content)
|
|
261
323
|
SELECT id, title, module, content FROM main.memories
|
|
262
324
|
`).run();
|
|
325
|
+
// Everything is indexed now, so the pending queue is redundant.
|
|
326
|
+
db.exec('DELETE FROM main.memory_fts_queue');
|
|
263
327
|
db.exec('COMMIT');
|
|
264
328
|
return Number(res.changes);
|
|
265
329
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/db/doctor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/db/doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
/**
|
|
3
|
+
* Deferred full-text indexing.
|
|
4
|
+
*
|
|
5
|
+
* The insert trigger only appends to `memory_fts_queue`; tokenizing ~10 KB of text into
|
|
6
|
+
* FTS5 costs about 0.27 ms, which is 74% of the remaining foreground append budget. The
|
|
7
|
+
* queue row is written in the same transaction as the memory row, so a crash can only lose
|
|
8
|
+
* index freshness, never data.
|
|
9
|
+
*
|
|
10
|
+
* Draining is idempotent: the batch deletes any existing index rows for the queued ids
|
|
11
|
+
* before re-inserting, so a duplicate queue row or a concurrent update cannot double-index
|
|
12
|
+
* a memory. Readers call this before BM25 so a memory is always searchable immediately
|
|
13
|
+
* after insertMemory() returns.
|
|
14
|
+
*/
|
|
15
|
+
export type FtsSchema = 'main' | 'global_db';
|
|
16
|
+
export interface DrainFtsResult {
|
|
17
|
+
drained: number;
|
|
18
|
+
}
|
|
19
|
+
/** Number of memories waiting for full-text indexing. */
|
|
20
|
+
export declare function pendingFtsCount(db: DatabaseSync, schema?: FtsSchema): number;
|
|
21
|
+
/**
|
|
22
|
+
* Indexes up to `batchSize` queued memories in one transaction and clears their queue rows.
|
|
23
|
+
* Returns the number of queue rows consumed (which can exceed the number of memories when
|
|
24
|
+
* the same memory was queued twice).
|
|
25
|
+
*/
|
|
26
|
+
export declare function drainFtsQueue(db: DatabaseSync, options?: {
|
|
27
|
+
limit?: number;
|
|
28
|
+
schema?: FtsSchema;
|
|
29
|
+
}): DrainFtsResult;
|
|
30
|
+
/**
|
|
31
|
+
* Indexes one memory immediately and drops its queue row. Used by write.ftsMode = 'sync',
|
|
32
|
+
* which reproduces the historical inline behaviour exactly.
|
|
33
|
+
*/
|
|
34
|
+
export declare function indexMemoryFtsNow(db: DatabaseSync, memoryId: string, schema?: FtsSchema): void;
|
|
35
|
+
//# sourceMappingURL=fts-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fts-queue.d.ts","sourceRoot":"","sources":["../../../src/db/fts-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,MAAM,GAAE,SAAkB,GAAG,MAAM,CASpF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,EAAE,EAAE,YAAY,EAChB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAO,GACnD,cAAc,CAkChB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,SAAkB,GAAG,IAAI,CAmBtG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
function table(schema, name) {
|
|
2
|
+
return schema === 'global_db' ? `global_db.${name}` : name;
|
|
3
|
+
}
|
|
4
|
+
/** Number of memories waiting for full-text indexing. */
|
|
5
|
+
export function pendingFtsCount(db, schema = 'main') {
|
|
6
|
+
try {
|
|
7
|
+
const row = db.prepare(`SELECT COUNT(*) AS c FROM ${table(schema, 'memory_fts_queue')}`).get();
|
|
8
|
+
return Number(row?.c ?? 0);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Indexes up to `batchSize` queued memories in one transaction and clears their queue rows.
|
|
16
|
+
* Returns the number of queue rows consumed (which can exceed the number of memories when
|
|
17
|
+
* the same memory was queued twice).
|
|
18
|
+
*/
|
|
19
|
+
export function drainFtsQueue(db, options = {}) {
|
|
20
|
+
const limit = Math.max(1, Math.floor(options.limit ?? 500));
|
|
21
|
+
const schema = options.schema ?? 'main';
|
|
22
|
+
const queue = table(schema, 'memory_fts_queue');
|
|
23
|
+
const fts = table(schema, 'memories_fts');
|
|
24
|
+
const memories = table(schema, 'memories');
|
|
25
|
+
let boundary;
|
|
26
|
+
try {
|
|
27
|
+
boundary = db
|
|
28
|
+
.prepare(`SELECT MAX(id) AS maxId, COUNT(*) AS rows FROM (SELECT id FROM ${queue} ORDER BY id ASC LIMIT ?)`)
|
|
29
|
+
.get(limit);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return { drained: 0 };
|
|
33
|
+
}
|
|
34
|
+
if (!boundary || boundary.maxId === null || boundary.rows === 0)
|
|
35
|
+
return { drained: 0 };
|
|
36
|
+
db.exec('SAVEPOINT fastr_drain_fts');
|
|
37
|
+
try {
|
|
38
|
+
db.prepare(`DELETE FROM ${fts} WHERE id IN (SELECT memory_id FROM ${queue} WHERE id <= ?)`).run(boundary.maxId);
|
|
39
|
+
db.prepare(`
|
|
40
|
+
INSERT INTO ${fts}(id, title, module, content)
|
|
41
|
+
SELECT m.id, m.title, m.module, m.content FROM ${memories} m
|
|
42
|
+
WHERE m.id IN (SELECT memory_id FROM ${queue} WHERE id <= ?)
|
|
43
|
+
`).run(boundary.maxId);
|
|
44
|
+
db.prepare(`DELETE FROM ${queue} WHERE id <= ?`).run(boundary.maxId);
|
|
45
|
+
db.exec('RELEASE fastr_drain_fts');
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
db.exec('ROLLBACK TO fastr_drain_fts');
|
|
49
|
+
db.exec('RELEASE fastr_drain_fts');
|
|
50
|
+
throw err;
|
|
51
|
+
}
|
|
52
|
+
return { drained: boundary.rows };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Indexes one memory immediately and drops its queue row. Used by write.ftsMode = 'sync',
|
|
56
|
+
* which reproduces the historical inline behaviour exactly.
|
|
57
|
+
*/
|
|
58
|
+
export function indexMemoryFtsNow(db, memoryId, schema = 'main') {
|
|
59
|
+
const fts = table(schema, 'memories_fts');
|
|
60
|
+
const memories = table(schema, 'memories');
|
|
61
|
+
const queue = table(schema, 'memory_fts_queue');
|
|
62
|
+
db.exec('SAVEPOINT fastr_index_fts');
|
|
63
|
+
try {
|
|
64
|
+
db.prepare(`DELETE FROM ${fts} WHERE id = ?`).run(memoryId);
|
|
65
|
+
db.prepare(`
|
|
66
|
+
INSERT INTO ${fts}(id, title, module, content)
|
|
67
|
+
SELECT id, title, module, content FROM ${memories} WHERE id = ?
|
|
68
|
+
`).run(memoryId);
|
|
69
|
+
db.prepare(`DELETE FROM ${queue} WHERE memory_id = ?`).run(memoryId);
|
|
70
|
+
db.exec('RELEASE fastr_index_fts');
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
db.exec('ROLLBACK TO fastr_index_fts');
|
|
74
|
+
db.exec('RELEASE fastr_index_fts');
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=fts-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fts-queue.js","sourceRoot":"","sources":["../../../src/db/fts-queue.ts"],"names":[],"mappings":"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"}
|