@aexol/spectral 0.9.184 → 0.9.186
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/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +8 -2
- package/dist/memory/branch.d.ts +13 -0
- package/dist/memory/branch.d.ts.map +1 -1
- package/dist/memory/branch.js +100 -0
- package/dist/memory/hooks/compaction-hook.d.ts.map +1 -1
- package/dist/memory/hooks/compaction-hook.js +43 -1
- package/dist/memory/hooks/observer-trigger.d.ts.map +1 -1
- package/dist/memory/hooks/observer-trigger.js +9 -3
- package/dist/memory/index.d.ts +13 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +17 -26
- package/dist/memory/project-observation-memory.d.ts +16 -0
- package/dist/memory/project-observation-memory.d.ts.map +1 -0
- package/dist/memory/project-observation-memory.js +27 -0
- package/dist/memory/project-observations-store.d.ts +8 -0
- package/dist/memory/project-observations-store.d.ts.map +1 -1
- package/dist/memory/project-observations-store.js +5 -0
- package/dist/memory/prompts.d.ts +2 -2
- package/dist/memory/prompts.d.ts.map +1 -1
- package/dist/memory/prompts.js +1 -1
- package/dist/memory/session-memory.d.ts +21 -0
- package/dist/memory/session-memory.d.ts.map +1 -0
- package/dist/memory/session-memory.js +33 -0
- package/dist/memory/tool-output-compressor.d.ts +0 -1
- package/dist/memory/tool-output-compressor.d.ts.map +1 -1
- package/dist/memory/tool-output-compressor.js +0 -1
- package/dist/memory/tools/compact-context.d.ts +31 -0
- package/dist/memory/tools/compact-context.d.ts.map +1 -1
- package/dist/memory/tools/compact-context.js +224 -23
- package/dist/memory/tools/read-project-observations.d.ts.map +1 -1
- package/dist/memory/tools/read-project-observations.js +6 -3
- package/dist/memory/tools/recall-observation.d.ts.map +1 -1
- package/dist/memory/tools/recall-observation.js +18 -4
- package/dist/memory/tools/receive-agent-observations.d.ts.map +1 -1
- package/dist/memory/tools/receive-agent-observations.js +4 -2
- package/dist/memory/tools/share-project-observation.d.ts.map +1 -1
- package/dist/memory/tools/share-project-observation.js +5 -3
- package/dist/memory/tools/write-project-observation.d.ts.map +1 -1
- package/dist/memory/tools/write-project-observation.js +16 -3
- package/dist/sdk/coding-agent/core/agent-session.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/agent-session.js +0 -1
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts +11 -0
- package/dist/sdk/coding-agent/core/compaction/compaction.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/compaction/compaction.js +15 -2
- package/dist/sdk/coding-agent/core/compaction/policy.d.ts +22 -4
- package/dist/sdk/coding-agent/core/compaction/policy.d.ts.map +1 -1
- package/dist/sdk/coding-agent/core/compaction/policy.js +39 -6
- package/dist/server/inter-agent-broker.d.ts +12 -7
- package/dist/server/inter-agent-broker.d.ts.map +1 -1
- package/dist/server/inter-agent-broker.js +12 -7
- package/dist/server/session-stream.d.ts.map +1 -1
- package/dist/server/session-stream.js +6 -4
- package/dist/server/sqlite-adapter.d.ts +11 -8
- package/dist/server/sqlite-adapter.d.ts.map +1 -1
- package/dist/server/sqlite-adapter.js +195 -44
- package/dist/server/storage.d.ts +22 -5
- package/dist/server/storage.d.ts.map +1 -1
- package/dist/server/storage.js +52 -6
- package/package.json +1 -1
|
@@ -1,18 +1,92 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Abstract SQLite interface to decouple SessionStore from a specific SQLite
|
|
3
|
-
* binding. Enables Bun standalone binary builds (bun:sqlite)
|
|
4
|
-
* the existing better-sqlite3 path
|
|
3
|
+
* binding. Enables Bun standalone binary builds (bun:sqlite) and modern
|
|
4
|
+
* Node.js (node:sqlite) while preserving the existing better-sqlite3 path as
|
|
5
|
+
* a fallback for older Node runtimes that lack a built-in SQLite module.
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
* -
|
|
7
|
+
* Three implementations:
|
|
8
|
+
* - NodeBuiltinSqliteAdapter — wraps node:sqlite (Node >= 22.5, zero deps)
|
|
9
|
+
* - NodeSqliteAdapter — wraps better-sqlite3 (legacy Node fallback)
|
|
10
|
+
* - BunSqliteAdapter — wraps bun:sqlite (Bun built-in, zero deps)
|
|
9
11
|
*
|
|
10
12
|
* The factory `createSqliteAdapter()` detects the runtime and returns the
|
|
11
13
|
* correct adapter. Callers (SessionStore) only interact with the `SqliteAdapter`
|
|
12
|
-
* interface — they never import better-sqlite3 or bun:sqlite
|
|
14
|
+
* interface — they never import better-sqlite3, node:sqlite or bun:sqlite
|
|
15
|
+
* directly.
|
|
13
16
|
*/
|
|
14
17
|
import { createRequire } from "node:module";
|
|
15
18
|
const _require = createRequire(import.meta.url);
|
|
19
|
+
// node:sqlite is still flagged "experimental" by Node and emits an
|
|
20
|
+
// ExperimentalWarning on first load. We deliberately opt into the built-in
|
|
21
|
+
// binding (validated by the full test suite), so we cache the load and narrow
|
|
22
|
+
// the warning suppression to that one message to keep `spectral serve` clean.
|
|
23
|
+
let nodeSqliteModule;
|
|
24
|
+
let nodeSqliteProbed = false;
|
|
25
|
+
function loadNodeSqlite() {
|
|
26
|
+
if (nodeSqliteProbed)
|
|
27
|
+
return nodeSqliteModule;
|
|
28
|
+
nodeSqliteProbed = true;
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
const proc = process;
|
|
31
|
+
const originalEmitWarning = proc.emitWarning;
|
|
32
|
+
try {
|
|
33
|
+
proc.emitWarning = (warning, ...rest) => {
|
|
34
|
+
const message = typeof warning === "string"
|
|
35
|
+
? warning
|
|
36
|
+
: warning instanceof Error
|
|
37
|
+
? warning.message
|
|
38
|
+
: String(warning);
|
|
39
|
+
if (message.includes("SQLite is an experimental feature"))
|
|
40
|
+
return;
|
|
41
|
+
return originalEmitWarning.call(process, warning, ...rest);
|
|
42
|
+
};
|
|
43
|
+
nodeSqliteModule = _require("node:sqlite");
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
nodeSqliteModule = null;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
proc.emitWarning = originalEmitWarning;
|
|
50
|
+
}
|
|
51
|
+
return nodeSqliteModule;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Paged iterator collector shared by the Node adapters. Reads rows from a
|
|
55
|
+
* lazy statement iterator in bounded chunks, yielding to the event loop
|
|
56
|
+
* between chunks so large result sets don't block the process in one
|
|
57
|
+
* uninterrupted burst.
|
|
58
|
+
*/
|
|
59
|
+
function collectPaged(iterator, pageSize) {
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const rows = [];
|
|
62
|
+
const page = [];
|
|
63
|
+
const safePageSize = Number.isFinite(pageSize) && pageSize > 0
|
|
64
|
+
? Math.floor(pageSize)
|
|
65
|
+
: 200;
|
|
66
|
+
const advance = () => {
|
|
67
|
+
try {
|
|
68
|
+
let next = iterator.next();
|
|
69
|
+
while (!next.done) {
|
|
70
|
+
page.push(next.value);
|
|
71
|
+
if (page.length >= safePageSize) {
|
|
72
|
+
rows.push(...page);
|
|
73
|
+
page.length = 0;
|
|
74
|
+
setImmediate(advance);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
next = iterator.next();
|
|
78
|
+
}
|
|
79
|
+
if (page.length > 0)
|
|
80
|
+
rows.push(...page);
|
|
81
|
+
resolve(rows);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
advance();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
16
90
|
// ---------------------------------------------------------------------------
|
|
17
91
|
// Node.js adapter (better-sqlite3)
|
|
18
92
|
// ---------------------------------------------------------------------------
|
|
@@ -44,42 +118,14 @@ class NodeSqliteAdapter {
|
|
|
44
118
|
return this.queryAllPaged(sql, 200, ...params);
|
|
45
119
|
}
|
|
46
120
|
queryAllPaged(sql, pageSize, ...params) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
: 200;
|
|
56
|
-
const advance = () => {
|
|
57
|
-
try {
|
|
58
|
-
let next = iterator.next();
|
|
59
|
-
while (!next.done) {
|
|
60
|
-
page.push(next.value);
|
|
61
|
-
if (page.length >= safePageSize) {
|
|
62
|
-
rows.push(...page);
|
|
63
|
-
page.length = 0;
|
|
64
|
-
setImmediate(advance);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
next = iterator.next();
|
|
68
|
-
}
|
|
69
|
-
if (page.length > 0)
|
|
70
|
-
rows.push(...page);
|
|
71
|
-
resolve(rows);
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
advance();
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
81
|
-
}
|
|
82
|
-
});
|
|
121
|
+
try {
|
|
122
|
+
const stmt = this.db.prepare(sql);
|
|
123
|
+
const iterator = stmt.iterate(...params);
|
|
124
|
+
return collectPaged(iterator, pageSize);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
return Promise.reject(err instanceof Error ? err : new Error(String(err)));
|
|
128
|
+
}
|
|
83
129
|
}
|
|
84
130
|
exec(sql) {
|
|
85
131
|
this.db.exec(sql);
|
|
@@ -95,6 +141,98 @@ class NodeSqliteAdapter {
|
|
|
95
141
|
}
|
|
96
142
|
}
|
|
97
143
|
// ---------------------------------------------------------------------------
|
|
144
|
+
// Node.js built-in adapter (node:sqlite)
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
/**
|
|
147
|
+
* Statement wrapper for node:sqlite's `StatementSync`. Its `.all`, `.get`,
|
|
148
|
+
* `.run` and `.iterate` methods match the adapter surface directly; `run` is
|
|
149
|
+
* normalized to the shared `{ changes }` result shape.
|
|
150
|
+
*/
|
|
151
|
+
class NodeBuiltinStatement {
|
|
152
|
+
stmt;
|
|
153
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
|
+
constructor(stmt) {
|
|
155
|
+
this.stmt = stmt;
|
|
156
|
+
}
|
|
157
|
+
all(...params) {
|
|
158
|
+
return this.stmt.all(...params);
|
|
159
|
+
}
|
|
160
|
+
get(...params) {
|
|
161
|
+
return this.stmt.get(...params);
|
|
162
|
+
}
|
|
163
|
+
run(...params) {
|
|
164
|
+
return { changes: this.stmt.run(...params).changes };
|
|
165
|
+
}
|
|
166
|
+
iterate(...params) {
|
|
167
|
+
return this.stmt.iterate(...params);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* SQLite adapter backed by Node's built-in `node:sqlite` module (available
|
|
172
|
+
* without a flag since Node 22.13 / 23.4, and in earlier 22.5+ builds behind
|
|
173
|
+
* `--experimental-sqlite`). Using the built-in removes the native
|
|
174
|
+
* better-sqlite3 compilation/prebuild download from the common `npm install
|
|
175
|
+
* -g @aexol/spectral` path.
|
|
176
|
+
*
|
|
177
|
+
* PRAGMAs and transactions are expressed via `exec()` because `node:sqlite`
|
|
178
|
+
* exposes neither a `.pragma()` convenience method nor a `.transaction()`
|
|
179
|
+
* helper.
|
|
180
|
+
*/
|
|
181
|
+
class NodeBuiltinSqliteAdapter {
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
183
|
+
db;
|
|
184
|
+
constructor(path) {
|
|
185
|
+
const { DatabaseSync } = loadNodeSqlite();
|
|
186
|
+
this.db = new DatabaseSync(path);
|
|
187
|
+
this.db.exec("PRAGMA journal_mode = WAL");
|
|
188
|
+
this.db.exec("PRAGMA foreign_keys = ON");
|
|
189
|
+
}
|
|
190
|
+
prepare(sql) {
|
|
191
|
+
return new NodeBuiltinStatement(this.db.prepare(sql));
|
|
192
|
+
}
|
|
193
|
+
queryAll(sql, ...params) {
|
|
194
|
+
return this.queryAllPaged(sql, 200, ...params);
|
|
195
|
+
}
|
|
196
|
+
queryAllPaged(sql, pageSize, ...params) {
|
|
197
|
+
try {
|
|
198
|
+
const stmt = this.db.prepare(sql);
|
|
199
|
+
const iterator = stmt.iterate(...params);
|
|
200
|
+
return collectPaged(iterator, pageSize);
|
|
201
|
+
}
|
|
202
|
+
catch (err) {
|
|
203
|
+
return Promise.reject(err instanceof Error ? err : new Error(String(err)));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exec(sql) {
|
|
207
|
+
this.db.exec(sql);
|
|
208
|
+
}
|
|
209
|
+
pragma(sql) {
|
|
210
|
+
this.db.exec(`PRAGMA ${sql}`);
|
|
211
|
+
}
|
|
212
|
+
transaction(fn) {
|
|
213
|
+
return () => {
|
|
214
|
+
this.db.exec("BEGIN");
|
|
215
|
+
try {
|
|
216
|
+
const result = fn();
|
|
217
|
+
this.db.exec("COMMIT");
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
try {
|
|
222
|
+
this.db.exec("ROLLBACK");
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// ignore rollback failures; the original error is more useful
|
|
226
|
+
}
|
|
227
|
+
throw err;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
close() {
|
|
232
|
+
this.db.close();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// ---------------------------------------------------------------------------
|
|
98
236
|
// Bun adapter (bun:sqlite)
|
|
99
237
|
// ---------------------------------------------------------------------------
|
|
100
238
|
/**
|
|
@@ -168,14 +306,27 @@ class BunSqliteAdapter {
|
|
|
168
306
|
function isBun() {
|
|
169
307
|
return typeof globalThis.Bun !== "undefined";
|
|
170
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Detect Node's built-in SQLite module. Returns true when `node:sqlite` is
|
|
311
|
+
* available and usable (Node >= 22.5 with the experimental flag, or any
|
|
312
|
+
* unflagged build since 22.13 / 23.4). On older Node this throws and we fall
|
|
313
|
+
* back to better-sqlite3.
|
|
314
|
+
*/
|
|
315
|
+
function canUseNodeSqlite() {
|
|
316
|
+
const mod = loadNodeSqlite();
|
|
317
|
+
return typeof mod?.DatabaseSync === "function";
|
|
318
|
+
}
|
|
171
319
|
/**
|
|
172
320
|
* Create a SQLite adapter for the given filesystem path. Auto-detects the
|
|
173
|
-
* runtime (
|
|
174
|
-
* matching implementation.
|
|
321
|
+
* runtime (Bun → bun:sqlite, Node >= 22.5 → node:sqlite, older Node →
|
|
322
|
+
* better-sqlite3) and returns the matching implementation.
|
|
175
323
|
*/
|
|
176
324
|
export function createSqliteAdapter(path) {
|
|
177
325
|
if (isBun()) {
|
|
178
326
|
return new BunSqliteAdapter(path);
|
|
179
327
|
}
|
|
328
|
+
if (canUseNodeSqlite()) {
|
|
329
|
+
return new NodeBuiltinSqliteAdapter(path);
|
|
330
|
+
}
|
|
180
331
|
return new NodeSqliteAdapter(path);
|
|
181
332
|
}
|
package/dist/server/storage.d.ts
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* Two-tier model:
|
|
5
5
|
* projects ─< sessions ─< messages
|
|
6
6
|
*
|
|
7
|
-
* Single-process, single-file.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Single-process, single-file. The storage layer goes through the `SqliteAdapter`
|
|
8
|
+
* abstraction (see `sqlite-adapter.ts`) which prefers Node's built-in
|
|
9
|
+
* `node:sqlite` on modern Node, `bun:sqlite` under Bun, and only falls back
|
|
10
|
+
* to `better-sqlite3` on older Node runtimes. The synchronous adapter API is a
|
|
11
|
+
* perfect fit for the per-WS-event write pattern: no connection pool, no
|
|
12
|
+
* callback churn, transactions are trivial.
|
|
11
13
|
*
|
|
12
14
|
* Schema migrations:
|
|
13
15
|
* We track schema with the `user_version` PRAGMA. When opening a DB whose
|
|
@@ -27,6 +29,7 @@
|
|
|
27
29
|
*/
|
|
28
30
|
import type { ImageAttachment, WireMessage, WireProject, WireSessionDetail, WireSessionSummary } from "./wire.js";
|
|
29
31
|
import type { SupportedMemoryDetails } from "../memory/types.js";
|
|
32
|
+
import type { Entry } from "../memory/branch.js";
|
|
30
33
|
import { type StudioBinding } from "../studio-binding.js";
|
|
31
34
|
import type { InterAgentMessage } from "./inter-agent-broker.js";
|
|
32
35
|
/** A single message as stored in SQLite. Identical to WireMessage. */
|
|
@@ -132,6 +135,8 @@ export declare class SessionStore {
|
|
|
132
135
|
private stmtSearchProjectObs;
|
|
133
136
|
private stmtGetProjectObsById;
|
|
134
137
|
private stmtGetProjectByCwd;
|
|
138
|
+
private stmtUpsertProjectRecallSource;
|
|
139
|
+
private stmtGetProjectRecallSource;
|
|
135
140
|
private stmtEnqueuePrompt;
|
|
136
141
|
private stmtGetPromptQueue;
|
|
137
142
|
private stmtDequeuePrompt;
|
|
@@ -417,6 +422,17 @@ export declare class SessionStore {
|
|
|
417
422
|
* Returns null when no project has been registered for the given path.
|
|
418
423
|
*/
|
|
419
424
|
getProjectByCwd(cwd: string): string | null;
|
|
425
|
+
/**
|
|
426
|
+
* Persist the source-context archive for a single observational-memory id.
|
|
427
|
+
* Keyed by project (cwd), not session/branch, so a later session in the
|
|
428
|
+
* same working directory can recall source evidence from an earlier branch.
|
|
429
|
+
*/
|
|
430
|
+
upsertProjectRecallSource(projectId: string, memoryId: string, entries: Entry[]): void;
|
|
431
|
+
/**
|
|
432
|
+
* Read the source-context archive for a single observational-memory id.
|
|
433
|
+
* Returns null when no archive exists for that project/id.
|
|
434
|
+
*/
|
|
435
|
+
getProjectRecallSource(projectId: string, memoryId: string): Entry[] | null;
|
|
420
436
|
insertInterAgentMessage(msg: InterAgentMessage): void;
|
|
421
437
|
pollInterAgentMessages(input: {
|
|
422
438
|
projectId: string;
|
|
@@ -455,7 +471,8 @@ export declare class SessionStore {
|
|
|
455
471
|
close(): void;
|
|
456
472
|
}
|
|
457
473
|
/**
|
|
458
|
-
* Pre-flight: verify that
|
|
474
|
+
* Pre-flight: verify that the SQLite adapter loads and a writable DB can be
|
|
475
|
+
* opened.
|
|
459
476
|
*
|
|
460
477
|
* Called before binding the port so a broken native build fails loudly with
|
|
461
478
|
* a helpful hint instead of crashing later when the first WS connection
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/server/storage.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/server/storage.ts"],"names":[],"mappings":"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"}
|
package/dist/server/storage.js
CHANGED
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
* Two-tier model:
|
|
5
5
|
* projects ─< sessions ─< messages
|
|
6
6
|
*
|
|
7
|
-
* Single-process, single-file.
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Single-process, single-file. The storage layer goes through the `SqliteAdapter`
|
|
8
|
+
* abstraction (see `sqlite-adapter.ts`) which prefers Node's built-in
|
|
9
|
+
* `node:sqlite` on modern Node, `bun:sqlite` under Bun, and only falls back
|
|
10
|
+
* to `better-sqlite3` on older Node runtimes. The synchronous adapter API is a
|
|
11
|
+
* perfect fit for the per-WS-event write pattern: no connection pool, no
|
|
12
|
+
* callback churn, transactions are trivial.
|
|
11
13
|
*
|
|
12
14
|
* Schema migrations:
|
|
13
15
|
* We track schema with the `user_version` PRAGMA. When opening a DB whose
|
|
@@ -99,6 +101,14 @@ CREATE TABLE IF NOT EXISTS project_observations (
|
|
|
99
101
|
|
|
100
102
|
CREATE INDEX IF NOT EXISTS idx_project_obs_project ON project_observations(project_id, created_at DESC);
|
|
101
103
|
|
|
104
|
+
CREATE TABLE IF NOT EXISTS project_recall_sources (
|
|
105
|
+
project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
|
|
106
|
+
memory_id TEXT NOT NULL,
|
|
107
|
+
entries_json TEXT NOT NULL,
|
|
108
|
+
updated_at INTEGER NOT NULL,
|
|
109
|
+
PRIMARY KEY (project_id, memory_id)
|
|
110
|
+
);
|
|
111
|
+
|
|
102
112
|
CREATE TABLE IF NOT EXISTS prompt_queue (
|
|
103
113
|
id TEXT PRIMARY KEY,
|
|
104
114
|
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
|
@@ -248,6 +258,8 @@ export class SessionStore {
|
|
|
248
258
|
stmtSearchProjectObs;
|
|
249
259
|
stmtGetProjectObsById;
|
|
250
260
|
stmtGetProjectByCwd;
|
|
261
|
+
stmtUpsertProjectRecallSource;
|
|
262
|
+
stmtGetProjectRecallSource;
|
|
251
263
|
// Prompt queue statements
|
|
252
264
|
stmtEnqueuePrompt;
|
|
253
265
|
stmtGetPromptQueue;
|
|
@@ -480,6 +492,12 @@ export class SessionStore {
|
|
|
480
492
|
FROM project_observations
|
|
481
493
|
WHERE project_id = ? AND id = ?`);
|
|
482
494
|
this.stmtGetProjectByCwd = this.db.prepare(`SELECT id FROM projects WHERE path = ? LIMIT 1`);
|
|
495
|
+
this.stmtUpsertProjectRecallSource = this.db.prepare(`INSERT OR REPLACE INTO project_recall_sources
|
|
496
|
+
(project_id, memory_id, entries_json, updated_at)
|
|
497
|
+
VALUES (?, ?, ?, ?)`);
|
|
498
|
+
this.stmtGetProjectRecallSource = this.db.prepare(`SELECT project_id, memory_id, entries_json, updated_at
|
|
499
|
+
FROM project_recall_sources
|
|
500
|
+
WHERE project_id = ? AND memory_id = ?`);
|
|
483
501
|
// ---- prompt queue statements ----------------------------------------
|
|
484
502
|
this.stmtEnqueuePrompt = this.db.prepare(`INSERT INTO prompt_queue (id, session_id, content, images_json, position, created_at)
|
|
485
503
|
VALUES (?, ?, ?, ?, ?, ?)`);
|
|
@@ -1312,6 +1330,33 @@ export class SessionStore {
|
|
|
1312
1330
|
const row = this.stmtGetProjectByCwd.get(cwd);
|
|
1313
1331
|
return row?.id ?? null;
|
|
1314
1332
|
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Persist the source-context archive for a single observational-memory id.
|
|
1335
|
+
* Keyed by project (cwd), not session/branch, so a later session in the
|
|
1336
|
+
* same working directory can recall source evidence from an earlier branch.
|
|
1337
|
+
*/
|
|
1338
|
+
upsertProjectRecallSource(projectId, memoryId, entries) {
|
|
1339
|
+
this.stmtUpsertProjectRecallSource.run(projectId, memoryId, JSON.stringify(entries), Date.now());
|
|
1340
|
+
}
|
|
1341
|
+
/**
|
|
1342
|
+
* Read the source-context archive for a single observational-memory id.
|
|
1343
|
+
* Returns null when no archive exists for that project/id.
|
|
1344
|
+
*/
|
|
1345
|
+
getProjectRecallSource(projectId, memoryId) {
|
|
1346
|
+
const row = this.stmtGetProjectRecallSource.get(projectId, memoryId);
|
|
1347
|
+
if (!row)
|
|
1348
|
+
return null;
|
|
1349
|
+
try {
|
|
1350
|
+
const parsed = JSON.parse(row.entries_json);
|
|
1351
|
+
if (!Array.isArray(parsed))
|
|
1352
|
+
return null;
|
|
1353
|
+
return parsed;
|
|
1354
|
+
}
|
|
1355
|
+
catch (err) {
|
|
1356
|
+
console.warn(`[storage] invalid project recall source for ${projectId}/${memoryId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1357
|
+
return null;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1315
1360
|
// ----------------------------------------------------------------------
|
|
1316
1361
|
// Inter-agent messages
|
|
1317
1362
|
// ----------------------------------------------------------------------
|
|
@@ -1435,8 +1480,9 @@ export function preflightSqlite(dbPath) {
|
|
|
1435
1480
|
const msg = err instanceof Error ? err.message : String(err);
|
|
1436
1481
|
return {
|
|
1437
1482
|
ok: false,
|
|
1438
|
-
error: `Failed to load
|
|
1439
|
-
`
|
|
1483
|
+
error: `Failed to load the SQLite storage module (${msg}).\n` +
|
|
1484
|
+
` On Node >= 22.5 spectral uses the built-in node:sqlite module; on older\n` +
|
|
1485
|
+
` Node it falls back to better-sqlite3, which needs its native binary built.\n` +
|
|
1440
1486
|
` Try: cd ${getConfigDir()} && npm rebuild better-sqlite3\n` +
|
|
1441
1487
|
` Or reinstall: npm install -g @aexol/spectral`,
|
|
1442
1488
|
};
|