@claude-flow/memory 3.0.2 → 3.0.4
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/dist/agentdb-backend-lock.test.d.ts +2 -0
- package/dist/agentdb-backend-lock.test.d.ts.map +1 -0
- package/dist/agentdb-backend-lock.test.js +60 -0
- package/dist/agentdb-backend-lock.test.js.map +1 -0
- package/dist/agentdb-backend.d.ts.map +1 -1
- package/dist/agentdb-backend.js +26 -9
- package/dist/agentdb-backend.js.map +1 -1
- package/dist/agentdb-lock-guard.d.ts +72 -0
- package/dist/agentdb-lock-guard.d.ts.map +1 -0
- package/dist/agentdb-lock-guard.js +226 -0
- package/dist/agentdb-lock-guard.js.map +1 -0
- package/dist/agentdb-lock-guard.test.d.ts +2 -0
- package/dist/agentdb-lock-guard.test.d.ts.map +1 -0
- package/dist/agentdb-lock-guard.test.js +219 -0
- package/dist/agentdb-lock-guard.test.js.map +1 -0
- package/dist/agentdb-native-driver.d.ts +21 -0
- package/dist/agentdb-native-driver.d.ts.map +1 -0
- package/dist/agentdb-native-driver.js +68 -0
- package/dist/agentdb-native-driver.js.map +1 -0
- package/dist/agentdb-native-driver.test.d.ts +9 -0
- package/dist/agentdb-native-driver.test.d.ts.map +1 -0
- package/dist/agentdb-native-driver.test.js +271 -0
- package/dist/agentdb-native-driver.test.js.map +1 -0
- package/dist/controller-registry-lock.test.d.ts +2 -0
- package/dist/controller-registry-lock.test.d.ts.map +1 -0
- package/dist/controller-registry-lock.test.js +73 -0
- package/dist/controller-registry-lock.test.js.map +1 -0
- package/dist/controller-registry.d.ts +1 -0
- package/dist/controller-registry.d.ts.map +1 -1
- package/dist/controller-registry.js +32 -5
- package/dist/controller-registry.js.map +1 -1
- package/dist/hybrid-backend.d.ts.map +1 -1
- package/dist/hybrid-backend.js +7 -1
- package/dist/hybrid-backend.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real-agentdb regression tests for the sql.js lock/concurrency guard.
|
|
3
|
+
* Reproduces the two alpha.20 failure modes (lost-update refusal, stale
|
|
4
|
+
* `<db>.agentdb.lock` from a dead writer) against the actual agentdb build,
|
|
5
|
+
* then proves the guard's behaviour. sql.js is forced so the lock path runs.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
import * as fs from 'node:fs';
|
|
9
|
+
import * as os from 'node:os';
|
|
10
|
+
import * as path from 'node:path';
|
|
11
|
+
import { AgentdbLockError, closeWithAgentdbLockRecovery, clearStaleAgentdbLock, inspectAgentdbLock, isConcurrentModificationError, withAgentdbLockRecovery, } from './agentdb-lock-guard.js';
|
|
12
|
+
let createDatabase;
|
|
13
|
+
let dir;
|
|
14
|
+
let dbFile;
|
|
15
|
+
let lockFile;
|
|
16
|
+
const DEAD_PID = 2_147_483_000; // far above pid_max on Linux/mac; ESRCH
|
|
17
|
+
const OLD = new Date(Date.now() - 3600_000);
|
|
18
|
+
function plantLock(content, mtime = OLD) {
|
|
19
|
+
fs.writeFileSync(lockFile, content);
|
|
20
|
+
fs.utimesSync(lockFile, mtime, mtime);
|
|
21
|
+
}
|
|
22
|
+
async function rows(file) {
|
|
23
|
+
const db = await createDatabase(file);
|
|
24
|
+
try {
|
|
25
|
+
return db.prepare('SELECT x FROM t').all().map((r) => r.x);
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
try {
|
|
29
|
+
db.close();
|
|
30
|
+
}
|
|
31
|
+
catch { /* read-only use */ }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
beforeAll(async () => {
|
|
35
|
+
process.env.AGENTDB_FORCE_SQLJS = '1';
|
|
36
|
+
({ createDatabase } = (await import('agentdb/db-fallback')));
|
|
37
|
+
});
|
|
38
|
+
beforeEach(() => {
|
|
39
|
+
dir = fs.mkdtempSync(path.join(os.tmpdir(), 'agentdb-lock-guard-'));
|
|
40
|
+
dbFile = path.join(dir, 'test.db');
|
|
41
|
+
lockFile = `${dbFile}.agentdb.lock`;
|
|
42
|
+
});
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
45
|
+
});
|
|
46
|
+
describe('failure reproduction (agentdb alpha.20 behaviour)', () => {
|
|
47
|
+
it('a stale handle save is refused with AGENTDB_SQLJS_CONCURRENT_MODIFICATION and keeps the other writer row', async () => {
|
|
48
|
+
const a = await createDatabase(dbFile);
|
|
49
|
+
const b = await createDatabase(dbFile);
|
|
50
|
+
a.exec('CREATE TABLE t(x)');
|
|
51
|
+
a.exec("INSERT INTO t VALUES('from-A')");
|
|
52
|
+
a.close();
|
|
53
|
+
b.exec('CREATE TABLE IF NOT EXISTS t(x)');
|
|
54
|
+
b.exec("INSERT INTO t VALUES('from-B')");
|
|
55
|
+
let err;
|
|
56
|
+
try {
|
|
57
|
+
b.close();
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
err = e;
|
|
61
|
+
}
|
|
62
|
+
expect(isConcurrentModificationError(err)).toBe(true);
|
|
63
|
+
expect(await rows(dbFile)).toEqual(['from-A']); // refused, not silently lost-updated
|
|
64
|
+
});
|
|
65
|
+
it('a lock left by a dead PID makes the first save fail and the db file is never created', async () => {
|
|
66
|
+
plantLock(`${DEAD_PID}\n`);
|
|
67
|
+
const a = await createDatabase(dbFile);
|
|
68
|
+
a.exec('CREATE TABLE t(x)');
|
|
69
|
+
let err;
|
|
70
|
+
try {
|
|
71
|
+
a.close();
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
err = e;
|
|
75
|
+
}
|
|
76
|
+
expect(isConcurrentModificationError(err)).toBe(true);
|
|
77
|
+
expect(fs.existsSync(dbFile)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('inspectAgentdbLock / clearStaleAgentdbLock', () => {
|
|
81
|
+
it('absent', () => {
|
|
82
|
+
expect(inspectAgentdbLock(dbFile).state).toBe('absent');
|
|
83
|
+
});
|
|
84
|
+
it('stale: dead PID and old', () => {
|
|
85
|
+
plantLock(`${DEAD_PID}\n`);
|
|
86
|
+
expect(inspectAgentdbLock(dbFile).state).toBe('stale');
|
|
87
|
+
});
|
|
88
|
+
it('live: PID alive is never cleared', () => {
|
|
89
|
+
plantLock(`${process.ppid}\n`);
|
|
90
|
+
const r = clearStaleAgentdbLock(dbFile);
|
|
91
|
+
expect(r.cleared).toBe(false);
|
|
92
|
+
expect(r.inspection.state).toBe('live');
|
|
93
|
+
expect(fs.existsSync(lockFile)).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
it('own PID is treated as live', () => {
|
|
96
|
+
plantLock(`${process.pid}\n`);
|
|
97
|
+
expect(inspectAgentdbLock(dbFile).state).toBe('live');
|
|
98
|
+
});
|
|
99
|
+
it('dead PID but fresh lock is not cleared', () => {
|
|
100
|
+
plantLock(`${DEAD_PID}\n`, new Date());
|
|
101
|
+
const r = clearStaleAgentdbLock(dbFile);
|
|
102
|
+
expect(r.cleared).toBe(false);
|
|
103
|
+
expect(fs.existsSync(lockFile)).toBe(true);
|
|
104
|
+
});
|
|
105
|
+
it('non-PID content is unverifiable and untouched', () => {
|
|
106
|
+
plantLock('hello\n');
|
|
107
|
+
const r = clearStaleAgentdbLock(dbFile);
|
|
108
|
+
expect(r.cleared).toBe(false);
|
|
109
|
+
expect(r.inspection.state).toBe('unverifiable');
|
|
110
|
+
expect(fs.readFileSync(lockFile, 'utf8')).toBe('hello\n');
|
|
111
|
+
});
|
|
112
|
+
it('a symlinked lock is never followed or removed', () => {
|
|
113
|
+
const target = path.join(dir, 'victim.txt');
|
|
114
|
+
fs.writeFileSync(target, `${DEAD_PID}\n`);
|
|
115
|
+
fs.symlinkSync(target, lockFile);
|
|
116
|
+
const r = clearStaleAgentdbLock(dbFile);
|
|
117
|
+
expect(r.cleared).toBe(false);
|
|
118
|
+
expect(fs.existsSync(target)).toBe(true);
|
|
119
|
+
expect(fs.lstatSync(lockFile).isSymbolicLink()).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
it('clears exactly the lock and leaves siblings alone', () => {
|
|
122
|
+
plantLock(`${DEAD_PID}\n`);
|
|
123
|
+
const sibling = path.join(dir, 'other.db.agentdb.lock');
|
|
124
|
+
fs.writeFileSync(sibling, `${DEAD_PID}\n`);
|
|
125
|
+
const r = clearStaleAgentdbLock(dbFile);
|
|
126
|
+
expect(r.cleared).toBe(true);
|
|
127
|
+
expect(fs.existsSync(lockFile)).toBe(false);
|
|
128
|
+
expect(fs.existsSync(sibling)).toBe(true);
|
|
129
|
+
expect(fs.readdirSync(dir).filter((f) => f.includes('.stale-'))).toEqual([]);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('withAgentdbLockRecovery', () => {
|
|
133
|
+
it('recovers a stale lock and the save succeeds exactly once more (no data loss)', async () => {
|
|
134
|
+
plantLock(`${DEAD_PID}\n`);
|
|
135
|
+
const a = await createDatabase(dbFile);
|
|
136
|
+
a.exec('CREATE TABLE t(x)');
|
|
137
|
+
a.exec("INSERT INTO t VALUES('kept')");
|
|
138
|
+
await withAgentdbLockRecovery(dbFile, () => a.save());
|
|
139
|
+
expect(fs.existsSync(lockFile)).toBe(false);
|
|
140
|
+
a.close();
|
|
141
|
+
expect(await rows(dbFile)).toEqual(['kept']);
|
|
142
|
+
});
|
|
143
|
+
it('does not retry or delete a live holder lock; surfaces an actionable error', async () => {
|
|
144
|
+
plantLock(`${process.ppid}\n`);
|
|
145
|
+
const a = await createDatabase(dbFile);
|
|
146
|
+
a.exec('CREATE TABLE t(x)');
|
|
147
|
+
let err;
|
|
148
|
+
try {
|
|
149
|
+
await withAgentdbLockRecovery(dbFile, () => a.save());
|
|
150
|
+
}
|
|
151
|
+
catch (e) {
|
|
152
|
+
err = e;
|
|
153
|
+
}
|
|
154
|
+
expect(err).toBeInstanceOf(AgentdbLockError);
|
|
155
|
+
expect(err.lockState).toBe('live');
|
|
156
|
+
expect(err.message).toMatch(/another process/i);
|
|
157
|
+
expect(fs.existsSync(lockFile)).toBe(true);
|
|
158
|
+
expect(fs.existsSync(dbFile)).toBe(false);
|
|
159
|
+
});
|
|
160
|
+
it('a true lost-update (no lock) is surfaced, never retried, never overwritten', async () => {
|
|
161
|
+
const a = await createDatabase(dbFile);
|
|
162
|
+
const b = await createDatabase(dbFile);
|
|
163
|
+
a.exec('CREATE TABLE t(x)');
|
|
164
|
+
a.exec("INSERT INTO t VALUES('from-A')");
|
|
165
|
+
a.close();
|
|
166
|
+
b.exec('CREATE TABLE IF NOT EXISTS t(x)');
|
|
167
|
+
b.exec("INSERT INTO t VALUES('from-B')");
|
|
168
|
+
let calls = 0;
|
|
169
|
+
let err;
|
|
170
|
+
try {
|
|
171
|
+
await withAgentdbLockRecovery(dbFile, () => { calls++; return b.save(); });
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
err = e;
|
|
175
|
+
}
|
|
176
|
+
expect(calls).toBe(1);
|
|
177
|
+
expect(err).toBeInstanceOf(AgentdbLockError);
|
|
178
|
+
expect(err.lockState).toBe('absent');
|
|
179
|
+
expect(await rows(dbFile)).toEqual(['from-A']);
|
|
180
|
+
});
|
|
181
|
+
it('passes unrelated errors through untouched and never inspects the filesystem for them', async () => {
|
|
182
|
+
const boom = new Error('boom');
|
|
183
|
+
await expect(withAgentdbLockRecovery(dbFile, () => { throw boom; })).rejects.toBe(boom);
|
|
184
|
+
});
|
|
185
|
+
it(':memory: databases are not guarded', async () => {
|
|
186
|
+
const e = Object.assign(new Error('x'), { code: 'AGENTDB_SQLJS_CONCURRENT_MODIFICATION' });
|
|
187
|
+
await expect(withAgentdbLockRecovery(':memory:', () => { throw e; })).rejects.toBe(e);
|
|
188
|
+
});
|
|
189
|
+
it('error message does not leak the full directory path', async () => {
|
|
190
|
+
plantLock(`${process.ppid}\n`);
|
|
191
|
+
const e = Object.assign(new Error('x'), { code: 'AGENTDB_SQLJS_CONCURRENT_MODIFICATION' });
|
|
192
|
+
let err;
|
|
193
|
+
try {
|
|
194
|
+
await withAgentdbLockRecovery(dbFile, () => { throw e; });
|
|
195
|
+
}
|
|
196
|
+
catch (x) {
|
|
197
|
+
err = x;
|
|
198
|
+
}
|
|
199
|
+
expect(err.message).not.toContain(dir);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
describe('closeWithAgentdbLockRecovery', () => {
|
|
203
|
+
it('clears a stale lock first so close persists the data', async () => {
|
|
204
|
+
plantLock(`${DEAD_PID}\n`);
|
|
205
|
+
const a = await createDatabase(dbFile);
|
|
206
|
+
a.exec('CREATE TABLE t(x)');
|
|
207
|
+
a.exec("INSERT INTO t VALUES('persisted')");
|
|
208
|
+
await closeWithAgentdbLockRecovery(dbFile, () => a.close());
|
|
209
|
+
expect(await rows(dbFile)).toEqual(['persisted']);
|
|
210
|
+
});
|
|
211
|
+
it('surfaces (never swallows) a close that cannot persist because of a live lock', async () => {
|
|
212
|
+
plantLock(`${process.ppid}\n`);
|
|
213
|
+
const a = await createDatabase(dbFile);
|
|
214
|
+
a.exec('CREATE TABLE t(x)');
|
|
215
|
+
await expect(closeWithAgentdbLockRecovery(dbFile, () => a.close())).rejects.toBeInstanceOf(AgentdbLockError);
|
|
216
|
+
expect(fs.existsSync(lockFile)).toBe(true);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=agentdb-lock-guard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-lock-guard.test.js","sourceRoot":"","sources":["../src/agentdb-lock-guard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
type DbCtor = new (path: string, opts?: Record<string, unknown>) => {
|
|
2
|
+
pragma(sql: string): unknown;
|
|
3
|
+
};
|
|
4
|
+
type AgentDBLike = {
|
|
5
|
+
config?: {
|
|
6
|
+
forceWasm?: boolean;
|
|
7
|
+
};
|
|
8
|
+
usingWasm?: boolean;
|
|
9
|
+
initializeDatabase?: (dbPath: string) => Promise<unknown>;
|
|
10
|
+
};
|
|
11
|
+
/** The better-sqlite3 constructor this package resolves, or null when it is not installed. */
|
|
12
|
+
export declare function getHostSqliteDriver(): DbCtor | null;
|
|
13
|
+
/**
|
|
14
|
+
* Replace `agentdb.initializeDatabase` so `initialize()` opens the database
|
|
15
|
+
* with getHostSqliteDriver(). Must be called before `agentdb.initialize()`.
|
|
16
|
+
* Falls back to AgentDB's own loader when ours cannot open the file, and
|
|
17
|
+
* leaves `forceWasm` instances alone. Returns whether the loader was replaced.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useHostSqliteDriver(agentdb: AgentDBLike | null | undefined): boolean;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=agentdb-native-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-native-driver.d.ts","sourceRoot":"","sources":["../src/agentdb-native-driver.ts"],"names":[],"mappings":"AAwBA,KAAK,MAAM,GAAG,KAAK,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;IAAE,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAErG,KAAK,WAAW,GAAG;IACjB,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D,CAAC;AAIF,8FAA8F;AAC9F,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CASnD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAoBpF"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open AgentDB's native SQLite handle with this package's better-sqlite3.
|
|
3
|
+
*
|
|
4
|
+
* agentdb 3.0.0-alpha.x declares `better-sqlite3: ^11.8.1`, so npm gives it a
|
|
5
|
+
* nested 11.x copy next to our 12.x one. better-sqlite3 11.x ships no prebuilt
|
|
6
|
+
* binary for Node 24 (ABI 137), so on Node 24 that copy is compiled from
|
|
7
|
+
* source against the local headers. Node 24.19+ headers carry a partial
|
|
8
|
+
* backport of `node::ObjectWrap` cleanup hooks (nodejs/node#65446): a
|
|
9
|
+
* Statement collected by an allocation-driven GC calls
|
|
10
|
+
* RemoveEnvironmentCleanupHook() with no Environment and the process aborts
|
|
11
|
+
* with `Assertion failed: (env) != nullptr` — exit 134 for the CLI, "Connection
|
|
12
|
+
* closed" for the MCP server.
|
|
13
|
+
*
|
|
14
|
+
* The 12.x copy we depend on ships a Node 24 prebuild, so routing AgentDB's
|
|
15
|
+
* handle through it keeps the source-built 11.x addon out of the process.
|
|
16
|
+
* `overrides` cannot do this: npm ignores them in a dependency's package.json,
|
|
17
|
+
* which is where ours sit for anyone installing ruflo.
|
|
18
|
+
*
|
|
19
|
+
* getHostSqliteDriver() is the single source of the constructor: the CLI's
|
|
20
|
+
* shared-sqlite loader (#3693/#3883) resolves better-sqlite3 from this file's
|
|
21
|
+
* location too, so every handle on memory.db shares one native copy.
|
|
22
|
+
*/
|
|
23
|
+
import { createRequire } from 'node:module';
|
|
24
|
+
let hostDriver;
|
|
25
|
+
/** The better-sqlite3 constructor this package resolves, or null when it is not installed. */
|
|
26
|
+
export function getHostSqliteDriver() {
|
|
27
|
+
if (hostDriver !== undefined)
|
|
28
|
+
return hostDriver;
|
|
29
|
+
try {
|
|
30
|
+
const mod = createRequire(import.meta.url)('better-sqlite3');
|
|
31
|
+
hostDriver = (mod?.default ?? mod);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
hostDriver = null;
|
|
35
|
+
}
|
|
36
|
+
return hostDriver;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Replace `agentdb.initializeDatabase` so `initialize()` opens the database
|
|
40
|
+
* with getHostSqliteDriver(). Must be called before `agentdb.initialize()`.
|
|
41
|
+
* Falls back to AgentDB's own loader when ours cannot open the file, and
|
|
42
|
+
* leaves `forceWasm` instances alone. Returns whether the loader was replaced.
|
|
43
|
+
*/
|
|
44
|
+
export function useHostSqliteDriver(agentdb) {
|
|
45
|
+
if (!agentdb || typeof agentdb.initializeDatabase !== 'function')
|
|
46
|
+
return false;
|
|
47
|
+
if (agentdb.config?.forceWasm)
|
|
48
|
+
return false;
|
|
49
|
+
const agentdbLoader = agentdb.initializeDatabase.bind(agentdb);
|
|
50
|
+
agentdb.initializeDatabase = async (dbPath) => {
|
|
51
|
+
const Database = getHostSqliteDriver();
|
|
52
|
+
if (!Database)
|
|
53
|
+
return agentdbLoader(dbPath);
|
|
54
|
+
let db;
|
|
55
|
+
try {
|
|
56
|
+
db = new Database(dbPath);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return agentdbLoader(dbPath);
|
|
60
|
+
}
|
|
61
|
+
// Same setup as AgentDB.initializeDatabase()'s native branch.
|
|
62
|
+
db.pragma('journal_mode = WAL');
|
|
63
|
+
agentdb.usingWasm = false;
|
|
64
|
+
return db;
|
|
65
|
+
};
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=agentdb-native-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-native-driver.js","sourceRoot":"","sources":["../src/agentdb-native-driver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAU5C,IAAI,UAAqC,CAAC;AAE1C,8FAA8F;AAC9F,MAAM,UAAU,mBAAmB;IACjC,IAAI,UAAU,KAAK,SAAS;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,gBAAgB,CAAC,CAAC;QAC7D,UAAU,GAAG,CAAC,GAAG,EAAE,OAAO,IAAI,GAAG,CAAW,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAuC;IACzE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,CAAC,kBAAkB,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAC/E,IAAI,OAAO,CAAC,MAAM,EAAE,SAAS;QAAE,OAAO,KAAK,CAAC;IAE5C,MAAM,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/D,OAAO,CAAC,kBAAkB,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACpD,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QACvC,IAAI,CAAC,QAAQ;YAAE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5C,IAAI,EAAwB,CAAC;QAC7B,IAAI,CAAC;YACH,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC;QACD,8DAA8D;QAC9D,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAChC,OAAO,CAAC,SAAS,GAAG,KAAK,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node 24 abort in agentdb's nested better-sqlite3 11.x
|
|
3
|
+
* (`Assertion failed: (env) != nullptr` in Statement::~Statement).
|
|
4
|
+
*
|
|
5
|
+
* useHostSqliteDriver() must make AgentDB open its handle with this
|
|
6
|
+
* package's better-sqlite3, so the source-built 11.x addon is never loaded.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=agentdb-native-driver.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-native-driver.test.d.ts","sourceRoot":"","sources":["../src/agentdb-native-driver.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node 24 abort in agentdb's nested better-sqlite3 11.x
|
|
3
|
+
* (`Assertion failed: (env) != nullptr` in Statement::~Statement).
|
|
4
|
+
*
|
|
5
|
+
* useHostSqliteDriver() must make AgentDB open its handle with this
|
|
6
|
+
* package's better-sqlite3, so the source-built 11.x addon is never loaded.
|
|
7
|
+
*/
|
|
8
|
+
import { afterAll, afterEach, describe, it, expect, vi } from 'vitest';
|
|
9
|
+
import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, utimesSync, writeFileSync } from 'node:fs';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
import { tmpdir } from 'node:os';
|
|
12
|
+
import { dirname, join } from 'node:path';
|
|
13
|
+
import Database from 'better-sqlite3';
|
|
14
|
+
import { getHostSqliteDriver, useHostSqliteDriver } from './agentdb-native-driver.js';
|
|
15
|
+
import { AGENTDB_CONCURRENT_MODIFICATION_CODE } from './agentdb-lock-guard.js';
|
|
16
|
+
function fakeAgentDB(config = {}) {
|
|
17
|
+
const calls = [];
|
|
18
|
+
const own = { own: true };
|
|
19
|
+
const agentdb = {
|
|
20
|
+
config,
|
|
21
|
+
usingWasm: true,
|
|
22
|
+
async initializeDatabase(dbPath) {
|
|
23
|
+
calls.push(dbPath);
|
|
24
|
+
return own;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
return { agentdb, calls, own };
|
|
28
|
+
}
|
|
29
|
+
describe('useHostSqliteDriver', () => {
|
|
30
|
+
it('opens the AgentDB handle with our better-sqlite3, not agentdb\'s', async () => {
|
|
31
|
+
const dir = mkdtempSync(join(tmpdir(), 'cf-agentdb-driver-'));
|
|
32
|
+
const { agentdb, calls } = fakeAgentDB();
|
|
33
|
+
try {
|
|
34
|
+
useHostSqliteDriver(agentdb);
|
|
35
|
+
const db = await agentdb.initializeDatabase(join(dir, 'agentdb-memory.db'));
|
|
36
|
+
expect(db).toBeInstanceOf(Database);
|
|
37
|
+
expect(calls).toEqual([]);
|
|
38
|
+
expect(agentdb.usingWasm).toBe(false);
|
|
39
|
+
expect(db.pragma('journal_mode', { simple: true })).toBe('wal');
|
|
40
|
+
db.close();
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
rmSync(dir, { recursive: true, force: true });
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
it('falls back to AgentDB\'s own loader when ours cannot open the path', async () => {
|
|
47
|
+
const { agentdb, calls, own } = fakeAgentDB();
|
|
48
|
+
useHostSqliteDriver(agentdb);
|
|
49
|
+
const missingDir = join(tmpdir(), 'cf-agentdb-driver-missing', 'nested', 'x.db');
|
|
50
|
+
await expect(agentdb.initializeDatabase(missingDir)).resolves.toBe(own);
|
|
51
|
+
expect(calls).toEqual([missingDir]);
|
|
52
|
+
});
|
|
53
|
+
it('leaves forceWasm instances on AgentDB\'s own loader', async () => {
|
|
54
|
+
const { agentdb, calls, own } = fakeAgentDB({ forceWasm: true });
|
|
55
|
+
useHostSqliteDriver(agentdb);
|
|
56
|
+
await expect(agentdb.initializeDatabase(':memory:')).resolves.toBe(own);
|
|
57
|
+
expect(calls).toEqual([':memory:']);
|
|
58
|
+
});
|
|
59
|
+
it('reports objects without initializeDatabase instead of throwing', () => {
|
|
60
|
+
expect(useHostSqliteDriver(null)).toBe(false);
|
|
61
|
+
expect(useHostSqliteDriver({})).toBe(false);
|
|
62
|
+
expect(useHostSqliteDriver(fakeAgentDB().agentdb)).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
it('getHostSqliteDriver is the better-sqlite3 this package resolves', () => {
|
|
65
|
+
expect(getHostSqliteDriver()).toBe(Database);
|
|
66
|
+
});
|
|
67
|
+
it('hands the real AgentDB.initialize() a working handle', async () => {
|
|
68
|
+
const { AgentDB } = (await import('agentdb'));
|
|
69
|
+
const agentdb = new AgentDB({ dbPath: ':memory:' });
|
|
70
|
+
useHostSqliteDriver(agentdb);
|
|
71
|
+
let opened;
|
|
72
|
+
const wrapped = agentdb.initializeDatabase.bind(agentdb);
|
|
73
|
+
agentdb.initializeDatabase = async (p) => (opened = await wrapped(p));
|
|
74
|
+
try {
|
|
75
|
+
await agentdb.initialize();
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Embedder/vector-backend setup may fail offline; the handle is what matters.
|
|
79
|
+
}
|
|
80
|
+
expect(opened).toBeInstanceOf(Database);
|
|
81
|
+
opened?.close();
|
|
82
|
+
}, 60_000);
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* A nested agentdb copy of better-sqlite3 — the installed layout that aborts on
|
|
86
|
+
* Node 24. pnpm dedupes the workspace onto one copy, so build a second native
|
|
87
|
+
* copy under a temp `node_modules/agentdb`, like graph-writer-shared-sqlite-3693.
|
|
88
|
+
*/
|
|
89
|
+
describe('useHostSqliteDriver with a nested agentdb copy', () => {
|
|
90
|
+
const req = createRequire(import.meta.url);
|
|
91
|
+
const root = mkdtempSync(join(tmpdir(), 'cf-agentdb-nested-'));
|
|
92
|
+
const agentdbDir = join(root, 'node_modules', 'agentdb');
|
|
93
|
+
let NestedCtor;
|
|
94
|
+
let FakeAgentDB;
|
|
95
|
+
try {
|
|
96
|
+
const nm = join(agentdbDir, 'node_modules');
|
|
97
|
+
mkdirSync(nm, { recursive: true });
|
|
98
|
+
cpSync(dirname(req.resolve('better-sqlite3/package.json')), join(nm, 'better-sqlite3'), { recursive: true });
|
|
99
|
+
for (const dep of ['bindings', 'file-uri-to-path']) {
|
|
100
|
+
try {
|
|
101
|
+
symlinkSync(dirname(req.resolve(`${dep}/package.json`)), join(nm, dep));
|
|
102
|
+
}
|
|
103
|
+
catch { /* optional */ }
|
|
104
|
+
}
|
|
105
|
+
// Same shape as AgentDB.initializeDatabase(): load better-sqlite3 from agentdb's own location.
|
|
106
|
+
writeFileSync(join(agentdbDir, 'index.cjs'), `
|
|
107
|
+
class AgentDB {
|
|
108
|
+
constructor(config = {}) { this.config = config; this.usingWasm = true; }
|
|
109
|
+
async initializeDatabase(dbPath) {
|
|
110
|
+
const Database = require('better-sqlite3');
|
|
111
|
+
const db = new Database(dbPath);
|
|
112
|
+
db.pragma('journal_mode = WAL');
|
|
113
|
+
this.usingWasm = false;
|
|
114
|
+
return db;
|
|
115
|
+
}
|
|
116
|
+
async initialize() { this.db = await this.initializeDatabase(this.config.dbPath || ':memory:'); }
|
|
117
|
+
get database() { return this.db; }
|
|
118
|
+
}
|
|
119
|
+
module.exports = { AgentDB, NestedDatabase: require('better-sqlite3') };
|
|
120
|
+
`);
|
|
121
|
+
({ AgentDB: FakeAgentDB, NestedDatabase: NestedCtor } = createRequire(join(agentdbDir, 'index.cjs'))('./index.cjs'));
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
NestedCtor = null;
|
|
125
|
+
}
|
|
126
|
+
afterAll(() => { rmSync(root, { recursive: true, force: true }); });
|
|
127
|
+
it.skipIf(!NestedCtor)('control: without the helper AgentDB opens its handle with the nested copy', async () => {
|
|
128
|
+
expect(NestedCtor).not.toBe(Database);
|
|
129
|
+
const agentdb = new FakeAgentDB({ dbPath: ':memory:' });
|
|
130
|
+
await agentdb.initialize();
|
|
131
|
+
expect(agentdb.database).toBeInstanceOf(NestedCtor);
|
|
132
|
+
agentdb.database.close();
|
|
133
|
+
});
|
|
134
|
+
it.skipIf(!NestedCtor)('with the helper the handle comes from getHostSqliteDriver(), not the nested copy', async () => {
|
|
135
|
+
const agentdb = new FakeAgentDB({ dbPath: ':memory:' });
|
|
136
|
+
useHostSqliteDriver(agentdb);
|
|
137
|
+
await agentdb.initialize();
|
|
138
|
+
expect(agentdb.database).toBeInstanceOf(getHostSqliteDriver());
|
|
139
|
+
expect(agentdb.database).not.toBeInstanceOf(NestedCtor);
|
|
140
|
+
agentdb.database.close();
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
/**
|
|
144
|
+
* Fake agentdb module whose AgentDB records the handle its initialize() opened.
|
|
145
|
+
* With `failFirstInit`, the first instance fails like agentdb alpha.20 does on a
|
|
146
|
+
* stale `<db>.agentdb.lock`, so withAgentdbLockRecovery retries with a new instance.
|
|
147
|
+
*/
|
|
148
|
+
function agentdbModuleRecordingHandle(failFirstInit = false) {
|
|
149
|
+
const opened = [];
|
|
150
|
+
let instances = 0;
|
|
151
|
+
class AgentDB {
|
|
152
|
+
config;
|
|
153
|
+
usingWasm = true;
|
|
154
|
+
database = null;
|
|
155
|
+
instance = ++instances;
|
|
156
|
+
constructor(config = {}) { this.config = config; }
|
|
157
|
+
async initializeDatabase(_dbPath) { return { agentdbOwnLoader: true }; }
|
|
158
|
+
async initialize() {
|
|
159
|
+
if (failFirstInit && this.instance === 1) {
|
|
160
|
+
throw Object.assign(new Error('concurrent modification'), { code: AGENTDB_CONCURRENT_MODIFICATION_CODE });
|
|
161
|
+
}
|
|
162
|
+
this.database = await this.initializeDatabase(this.config.dbPath || ':memory:');
|
|
163
|
+
opened.push(this.database);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { opened, instances: () => instances, module: { AgentDB, default: AgentDB } };
|
|
167
|
+
}
|
|
168
|
+
/** A db path whose `<db>.agentdb.lock` belongs to a dead writer (provably stale). */
|
|
169
|
+
function dbWithStaleLock(dir) {
|
|
170
|
+
const dbPath = join(dir, 'agentdb-memory.db');
|
|
171
|
+
const lock = `${dbPath}.agentdb.lock`;
|
|
172
|
+
writeFileSync(lock, '2147483000\n');
|
|
173
|
+
const old = new Date(Date.now() - 3600_000);
|
|
174
|
+
utimesSync(lock, old, old);
|
|
175
|
+
return dbPath;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* vitest applies the queued doMock/doUnmock entries for one path in
|
|
179
|
+
* resolve-completion order, not call order (see graph-writer-shared-sqlite-3693
|
|
180
|
+
* in the CLI). Never leave two queued: apply each change with an import
|
|
181
|
+
* before the next is queued.
|
|
182
|
+
*/
|
|
183
|
+
async function clearAgentdbMock() {
|
|
184
|
+
vi.resetModules();
|
|
185
|
+
vi.doUnmock('agentdb');
|
|
186
|
+
await import('agentdb').catch(() => null);
|
|
187
|
+
vi.resetModules();
|
|
188
|
+
}
|
|
189
|
+
async function mockAgentdb(module) {
|
|
190
|
+
await clearAgentdbMock();
|
|
191
|
+
vi.doMock('agentdb', () => module);
|
|
192
|
+
await import('agentdb');
|
|
193
|
+
}
|
|
194
|
+
describe('AgentDB construction sites apply useHostSqliteDriver', () => {
|
|
195
|
+
afterEach(clearAgentdbMock);
|
|
196
|
+
it('ControllerRegistry.initAgentDB', async () => {
|
|
197
|
+
const fake = agentdbModuleRecordingHandle();
|
|
198
|
+
await mockAgentdb(fake.module);
|
|
199
|
+
const { ControllerRegistry } = await import('./controller-registry.js');
|
|
200
|
+
await new ControllerRegistry().initAgentDB({ dbPath: ':memory:' });
|
|
201
|
+
expect(fake.opened).toHaveLength(1);
|
|
202
|
+
expect(fake.opened[0]).toBeInstanceOf(Database);
|
|
203
|
+
fake.opened[0].close();
|
|
204
|
+
});
|
|
205
|
+
it('AgentDBBackend.initialize', async () => {
|
|
206
|
+
const fake = agentdbModuleRecordingHandle();
|
|
207
|
+
await mockAgentdb(fake.module);
|
|
208
|
+
const { AgentDBBackend } = await import('./agentdb-backend.js');
|
|
209
|
+
const errors = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
210
|
+
// Schema setup after initialize() may fail against the fake; the handle is what matters.
|
|
211
|
+
await new AgentDBBackend({ dbPath: ':memory:' }).initialize();
|
|
212
|
+
errors.mockRestore();
|
|
213
|
+
expect(fake.opened).toHaveLength(1);
|
|
214
|
+
expect(fake.opened[0]).toBeInstanceOf(Database);
|
|
215
|
+
fake.opened[0].close();
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('AgentDB construction sites reroute the stale-lock retry instance too', () => {
|
|
219
|
+
afterEach(clearAgentdbMock);
|
|
220
|
+
it('ControllerRegistry.initAgentDB retry', async () => {
|
|
221
|
+
const dir = mkdtempSync(join(tmpdir(), 'cf-agentdb-retry-'));
|
|
222
|
+
try {
|
|
223
|
+
const fake = agentdbModuleRecordingHandle(true);
|
|
224
|
+
await mockAgentdb(fake.module);
|
|
225
|
+
const { ControllerRegistry } = await import('./controller-registry.js');
|
|
226
|
+
await new ControllerRegistry().initAgentDB({ dbPath: dbWithStaleLock(dir) });
|
|
227
|
+
expect(fake.instances()).toBe(2);
|
|
228
|
+
expect(fake.opened).toHaveLength(1);
|
|
229
|
+
expect(fake.opened[0]).toBeInstanceOf(Database);
|
|
230
|
+
fake.opened[0].close();
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
rmSync(dir, { recursive: true, force: true });
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
it('AgentDBBackend.initialize retry', async () => {
|
|
237
|
+
const dir = mkdtempSync(join(tmpdir(), 'cf-agentdb-retry-'));
|
|
238
|
+
const errors = vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
239
|
+
try {
|
|
240
|
+
const fake = agentdbModuleRecordingHandle(true);
|
|
241
|
+
await mockAgentdb(fake.module);
|
|
242
|
+
const { AgentDBBackend } = await import('./agentdb-backend.js');
|
|
243
|
+
await new AgentDBBackend({ dbPath: dbWithStaleLock(dir) }).initialize();
|
|
244
|
+
expect(fake.instances()).toBe(2);
|
|
245
|
+
expect(fake.opened).toHaveLength(1);
|
|
246
|
+
expect(fake.opened[0]).toBeInstanceOf(Database);
|
|
247
|
+
fake.opened[0].close();
|
|
248
|
+
}
|
|
249
|
+
finally {
|
|
250
|
+
errors.mockRestore();
|
|
251
|
+
rmSync(dir, { recursive: true, force: true });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
/**
|
|
256
|
+
* Drift guard: useHostSqliteDriver replaces AgentDB.initializeDatabase(). If
|
|
257
|
+
* agentdb renames it or stops routing initialize() through it, the helper would
|
|
258
|
+
* silently do nothing — fail here instead.
|
|
259
|
+
*/
|
|
260
|
+
describe('agentdb AgentDB contract the helper depends on', () => {
|
|
261
|
+
it('initialize() opens its handle through initializeDatabase(dbPath) with native better-sqlite3', async () => {
|
|
262
|
+
const { AgentDB } = (await import('agentdb'));
|
|
263
|
+
const source = readFileSync(createRequire(import.meta.url).resolve('agentdb').replace(/index\.js$/, 'core/AgentDB.js'), 'utf8');
|
|
264
|
+
expect(typeof AgentDB.prototype.initializeDatabase).toBe('function');
|
|
265
|
+
expect(useHostSqliteDriver(new AgentDB({ dbPath: ':memory:' }))).toBe(true);
|
|
266
|
+
expect(source).toMatch(/this\.db\s*=\s*await\s+this\.initializeDatabase\(dbPath\)/);
|
|
267
|
+
expect(source).toMatch(/import\('better-sqlite3'\)/);
|
|
268
|
+
expect(source).toMatch(/pragma\('journal_mode = WAL'\)/);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
//# sourceMappingURL=agentdb-native-driver.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentdb-native-driver.test.js","sourceRoot":"","sources":["../src/agentdb-native-driver.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller-registry-lock.test.d.ts","sourceRoot":"","sources":["../src/controller-registry-lock.test.ts"],"names":[],"mappings":""}
|