@spool-lab/core 0.4.1 → 0.4.20

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.
Files changed (152) hide show
  1. package/dist/db/db.d.ts +28 -1
  2. package/dist/db/db.d.ts.map +1 -1
  3. package/dist/db/db.js +320 -17
  4. package/dist/db/db.js.map +1 -1
  5. package/dist/db/queries.d.ts +36 -11
  6. package/dist/db/queries.d.ts.map +1 -1
  7. package/dist/db/queries.js +118 -83
  8. package/dist/db/queries.js.map +1 -1
  9. package/dist/db/share-drafts.d.ts +51 -0
  10. package/dist/db/share-drafts.d.ts.map +1 -0
  11. package/dist/db/share-drafts.js +47 -0
  12. package/dist/db/share-drafts.js.map +1 -0
  13. package/dist/doctor/checks/config.d.ts +3 -0
  14. package/dist/doctor/checks/config.d.ts.map +1 -0
  15. package/dist/doctor/checks/config.js +123 -0
  16. package/dist/doctor/checks/config.js.map +1 -0
  17. package/dist/doctor/checks/db.d.ts +3 -0
  18. package/dist/doctor/checks/db.d.ts.map +1 -0
  19. package/dist/doctor/checks/db.js +225 -0
  20. package/dist/doctor/checks/db.js.map +1 -0
  21. package/dist/doctor/checks/env.d.ts +3 -0
  22. package/dist/doctor/checks/env.d.ts.map +1 -0
  23. package/dist/doctor/checks/env.js +70 -0
  24. package/dist/doctor/checks/env.js.map +1 -0
  25. package/dist/doctor/checks/index.d.ts +3 -0
  26. package/dist/doctor/checks/index.d.ts.map +1 -0
  27. package/dist/doctor/checks/index.js +13 -0
  28. package/dist/doctor/checks/index.js.map +1 -0
  29. package/dist/doctor/checks/native.d.ts +3 -0
  30. package/dist/doctor/checks/native.d.ts.map +1 -0
  31. package/dist/doctor/checks/native.js +42 -0
  32. package/dist/doctor/checks/native.js.map +1 -0
  33. package/dist/doctor/checks/versions.d.ts +3 -0
  34. package/dist/doctor/checks/versions.d.ts.map +1 -0
  35. package/dist/doctor/checks/versions.js +79 -0
  36. package/dist/doctor/checks/versions.js.map +1 -0
  37. package/dist/doctor/index.d.ts +3 -0
  38. package/dist/doctor/index.d.ts.map +1 -0
  39. package/dist/doctor/index.js +3 -0
  40. package/dist/doctor/index.js.map +1 -0
  41. package/dist/doctor/preflight.d.ts +18 -0
  42. package/dist/doctor/preflight.d.ts.map +1 -0
  43. package/dist/doctor/preflight.js +27 -0
  44. package/dist/doctor/preflight.js.map +1 -0
  45. package/dist/doctor/runner.d.ts +12 -0
  46. package/dist/doctor/runner.d.ts.map +1 -0
  47. package/dist/doctor/runner.js +37 -0
  48. package/dist/doctor/runner.js.map +1 -0
  49. package/dist/doctor/types.d.ts +27 -0
  50. package/dist/doctor/types.d.ts.map +1 -0
  51. package/dist/doctor/types.js +2 -0
  52. package/dist/doctor/types.js.map +1 -0
  53. package/dist/index.d.ts +7 -1
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +7 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/migrations/agent-search-cleanup.d.ts +36 -0
  58. package/dist/migrations/agent-search-cleanup.d.ts.map +1 -0
  59. package/dist/migrations/agent-search-cleanup.js +182 -0
  60. package/dist/migrations/agent-search-cleanup.js.map +1 -0
  61. package/dist/migrations/worktree-identity-upgrade.d.ts +31 -0
  62. package/dist/migrations/worktree-identity-upgrade.d.ts.map +1 -0
  63. package/dist/migrations/worktree-identity-upgrade.js +22 -0
  64. package/dist/migrations/worktree-identity-upgrade.js.map +1 -0
  65. package/dist/parsers/claude.d.ts.map +1 -1
  66. package/dist/parsers/claude.js +25 -12
  67. package/dist/parsers/claude.js.map +1 -1
  68. package/dist/parsers/codex.d.ts.map +1 -1
  69. package/dist/parsers/codex.js +32 -5
  70. package/dist/parsers/codex.js.map +1 -1
  71. package/dist/parsers/gemini.d.ts.map +1 -1
  72. package/dist/parsers/gemini.js +5 -5
  73. package/dist/parsers/gemini.js.map +1 -1
  74. package/dist/parsers/spool-prelude.d.ts +16 -0
  75. package/dist/parsers/spool-prelude.d.ts.map +1 -0
  76. package/dist/parsers/spool-prelude.js +21 -0
  77. package/dist/parsers/spool-prelude.js.map +1 -0
  78. package/dist/projects/display-name.d.ts +2 -0
  79. package/dist/projects/display-name.d.ts.map +1 -0
  80. package/dist/projects/display-name.js +8 -0
  81. package/dist/projects/display-name.js.map +1 -0
  82. package/dist/projects/fs.d.ts +3 -0
  83. package/dist/projects/fs.d.ts.map +1 -0
  84. package/dist/projects/fs.js +20 -0
  85. package/dist/projects/fs.js.map +1 -0
  86. package/dist/projects/groups.d.ts +4 -0
  87. package/dist/projects/groups.d.ts.map +1 -0
  88. package/dist/projects/groups.js +20 -0
  89. package/dist/projects/groups.js.map +1 -0
  90. package/dist/projects/identity-synthesizers.d.ts +22 -0
  91. package/dist/projects/identity-synthesizers.d.ts.map +1 -0
  92. package/dist/projects/identity-synthesizers.js +29 -0
  93. package/dist/projects/identity-synthesizers.js.map +1 -0
  94. package/dist/projects/identity.d.ts +16 -0
  95. package/dist/projects/identity.d.ts.map +1 -0
  96. package/dist/projects/identity.js +172 -0
  97. package/dist/projects/identity.js.map +1 -0
  98. package/dist/projects/sessions.d.ts +40 -0
  99. package/dist/projects/sessions.d.ts.map +1 -0
  100. package/dist/projects/sessions.js +151 -0
  101. package/dist/projects/sessions.js.map +1 -0
  102. package/dist/projects/worktree-resolvers.d.ts +19 -0
  103. package/dist/projects/worktree-resolvers.d.ts.map +1 -0
  104. package/dist/projects/worktree-resolvers.js +65 -0
  105. package/dist/projects/worktree-resolvers.js.map +1 -0
  106. package/dist/security/index.d.ts +14 -0
  107. package/dist/security/index.d.ts.map +1 -0
  108. package/dist/security/index.js +7 -0
  109. package/dist/security/index.js.map +1 -0
  110. package/dist/security/maintenance.d.ts +15 -0
  111. package/dist/security/maintenance.d.ts.map +1 -0
  112. package/dist/security/maintenance.js +68 -0
  113. package/dist/security/maintenance.js.map +1 -0
  114. package/dist/security/profile.d.ts +47 -0
  115. package/dist/security/profile.d.ts.map +1 -0
  116. package/dist/security/profile.js +122 -0
  117. package/dist/security/profile.js.map +1 -0
  118. package/dist/security/purge.d.ts +49 -0
  119. package/dist/security/purge.d.ts.map +1 -0
  120. package/dist/security/purge.js +159 -0
  121. package/dist/security/purge.js.map +1 -0
  122. package/dist/security/repo.d.ts +141 -0
  123. package/dist/security/repo.d.ts.map +1 -0
  124. package/dist/security/repo.js +469 -0
  125. package/dist/security/repo.js.map +1 -0
  126. package/dist/security/scan.d.ts +50 -0
  127. package/dist/security/scan.d.ts.map +1 -0
  128. package/dist/security/scan.js +120 -0
  129. package/dist/security/scan.js.map +1 -0
  130. package/dist/security/types.d.ts +128 -0
  131. package/dist/security/types.d.ts.map +1 -0
  132. package/dist/security/types.js +10 -0
  133. package/dist/security/types.js.map +1 -0
  134. package/dist/security/worker.d.ts +53 -0
  135. package/dist/security/worker.d.ts.map +1 -0
  136. package/dist/security/worker.js +180 -0
  137. package/dist/security/worker.js.map +1 -0
  138. package/dist/sync/source-paths.d.ts +1 -0
  139. package/dist/sync/source-paths.d.ts.map +1 -1
  140. package/dist/sync/source-paths.js +13 -3
  141. package/dist/sync/source-paths.js.map +1 -1
  142. package/dist/sync/syncer.d.ts +8 -1
  143. package/dist/sync/syncer.d.ts.map +1 -1
  144. package/dist/sync/syncer.js +37 -17
  145. package/dist/sync/syncer.js.map +1 -1
  146. package/dist/types.d.ts +28 -6
  147. package/dist/types.d.ts.map +1 -1
  148. package/dist/util/resolve-bin.d.ts +34 -0
  149. package/dist/util/resolve-bin.d.ts.map +1 -1
  150. package/dist/util/resolve-bin.js +175 -20
  151. package/dist/util/resolve-bin.js.map +1 -1
  152. package/package.json +5 -2
package/dist/db/db.d.ts CHANGED
@@ -1,10 +1,37 @@
1
1
  import Database from 'better-sqlite3';
2
+ import { type IdentityFs } from '../projects/identity.js';
2
3
  export declare const SPOOL_DIR: string;
3
4
  export declare const DB_PATH: string;
4
- export declare function getDB(_readonly?: boolean): Database.Database;
5
+ /**
6
+ * Latest schema version the running build knows how to migrate to.
7
+ * Bump in lockstep with the last `db.pragma('user_version = N')` in runMigrations.
8
+ */
9
+ export declare const LATEST_SCHEMA_VERSION = 13;
10
+ export interface OpenOptions {
11
+ /** Worker-thread callers should pass `false` — the main process has
12
+ * already run migrations on the shared DB file before spawning, and
13
+ * two threads racing through the migration script trip over each
14
+ * other on the `CREATE TRIGGER` / index steps (DROP IF EXISTS +
15
+ * CREATE is not atomic across connections). Default `true`. */
16
+ runMigrations?: boolean;
17
+ }
18
+ export declare function getDB(arg?: boolean | OpenOptions): Database.Database;
5
19
  /** True if the DB file did not exist before this process opened it. */
6
20
  export declare function wasNewDb(): boolean;
7
21
  /** user_version of the DB before any migrations ran this process. Null if getDB() hasn't been called. */
8
22
  export declare function getInitialUserVersion(): number | null;
9
23
  export declare function getDBSize(): number;
24
+ export declare function runMigrations(db: Database.Database): void;
25
+ export declare function backfillProjectIdentities(db: Database.Database, fs: IdentityFs): void;
26
+ /**
27
+ * Snapshot the DB to `<dbDir>/backups/spool-pre-v{fromVersion+1}-<ts>.db`
28
+ * via VACUUM INTO, before a destructive migration runs.
29
+ *
30
+ * Returns the backup file path on success, or null when a backup is skipped:
31
+ * - in-memory DBs (db.memory)
32
+ * - fresh-install / no-data DBs (sessions table empty or missing)
33
+ *
34
+ * Each call writes to a distinct path; v5 and v7 produce separate files.
35
+ */
36
+ export declare function backupBeforeDestructive(db: Database.Database, fromVersion: number): string | null;
10
37
  //# sourceMappingURL=db.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAKrC,eAAO,MAAM,SAAS,QAA6D,CAAA;AACnF,eAAO,MAAM,OAAO,QAA8B,CAAA;AAMlD,wBAAgB,KAAK,CAAC,SAAS,UAAQ,GAAG,QAAQ,CAAC,QAAQ,CAgB1D;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,IAAI,OAAO,CAAqB;AAExD,yGAAyG;AACzG,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAA+B;AAErF,wBAAgB,SAAS,IAAI,MAAM,CAMlC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AAIrC,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAK1E,eAAO,MAAM,SAAS,QAA6D,CAAA;AACnF,eAAO,MAAM,OAAO,QAA8B,CAAA;AAElD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAA;AAMvC,MAAM,WAAW,WAAW;IAC1B;;;;oEAIgE;IAChE,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,wBAAgB,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAqBpE;AAED,uEAAuE;AACvE,wBAAgB,QAAQ,IAAI,OAAO,CAAqB;AAExD,yGAAyG;AACzG,wBAAgB,qBAAqB,IAAI,MAAM,GAAG,IAAI,CAA+B;AAErF,wBAAgB,SAAS,IAAI,MAAM,CAMlC;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAohBzD;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,UAAU,QAgB9E;AA0BD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,IAAI,CAef"}
package/dist/db/db.js CHANGED
@@ -1,15 +1,26 @@
1
1
  import Database from 'better-sqlite3';
2
2
  import { homedir } from 'node:os';
3
- import { join } from 'node:path';
3
+ import { dirname, join } from 'node:path';
4
4
  import { existsSync, mkdirSync, statSync } from 'node:fs';
5
+ import { computeIdentity } from '../projects/identity.js';
6
+ import { realFs } from '../projects/fs.js';
7
+ import { runAgentSearchCleanup } from '../migrations/agent-search-cleanup.js';
8
+ import { upgradeWorktreeIdentities } from '../migrations/worktree-identity-upgrade.js';
5
9
  export const SPOOL_DIR = process.env['SPOOL_DATA_DIR'] ?? join(homedir(), '.spool');
6
10
  export const DB_PATH = join(SPOOL_DIR, 'spool.db');
11
+ /**
12
+ * Latest schema version the running build knows how to migrate to.
13
+ * Bump in lockstep with the last `db.pragma('user_version = N')` in runMigrations.
14
+ */
15
+ export const LATEST_SCHEMA_VERSION = 13;
7
16
  let _db = null;
8
17
  let _wasNewDb = false;
9
18
  let _initialUserVersion = null;
10
- export function getDB(_readonly = false) {
19
+ export function getDB(arg) {
11
20
  if (_db)
12
21
  return _db;
22
+ const opts = typeof arg === 'object' && arg !== null ? arg : {};
23
+ const shouldRunMigrations = opts.runMigrations !== false;
13
24
  mkdirSync(SPOOL_DIR, { recursive: true });
14
25
  // Capture pre-open state before better-sqlite3 creates the file. These two
15
26
  // signals together let callers tell apart "fresh install" from "upgrade":
@@ -21,7 +32,9 @@ export function getDB(_readonly = false) {
21
32
  db.pragma('foreign_keys = ON');
22
33
  db.pragma('busy_timeout = 5000');
23
34
  _initialUserVersion = db.pragma('user_version')[0]?.user_version ?? 0;
24
- runMigrations(db);
35
+ if (shouldRunMigrations) {
36
+ runMigrations(db);
37
+ }
25
38
  _db = db;
26
39
  return db;
27
40
  }
@@ -37,7 +50,7 @@ export function getDBSize() {
37
50
  return 0;
38
51
  }
39
52
  }
40
- function runMigrations(db) {
53
+ export function runMigrations(db) {
41
54
  db.exec(`
42
55
  CREATE TABLE IF NOT EXISTS sources (
43
56
  id INTEGER PRIMARY KEY,
@@ -68,6 +81,7 @@ function runMigrations(db) {
68
81
  session_uuid TEXT NOT NULL UNIQUE,
69
82
  file_path TEXT NOT NULL UNIQUE,
70
83
  title TEXT,
84
+ title_source TEXT NOT NULL DEFAULT 'derived',
71
85
  started_at TEXT NOT NULL,
72
86
  ended_at TEXT NOT NULL,
73
87
  message_count INTEGER NOT NULL DEFAULT 0,
@@ -164,6 +178,7 @@ function runMigrations(db) {
164
178
  `);
165
179
  db.exec(`
166
180
  DROP TRIGGER IF EXISTS messages_fts_insert;
181
+ DROP TRIGGER IF EXISTS messages_fts_update;
167
182
  DROP TRIGGER IF EXISTS messages_fts_delete;
168
183
  DROP TRIGGER IF EXISTS session_search_fts_insert;
169
184
  DROP TRIGGER IF EXISTS session_search_fts_update;
@@ -177,6 +192,23 @@ function runMigrations(db) {
177
192
  VALUES(NEW.id, NEW.content_text);
178
193
  END;
179
194
 
195
+ -- Security Scan's Purge action UPDATEs messages.content_text in
196
+ -- place. FTS external-content tables don't auto-sync on UPDATE —
197
+ -- we issue the 'delete' command for the old text and re-insert
198
+ -- the new. Without this trigger the FTS index keeps matching the
199
+ -- raw value after Purge, defeating the threat-model goal.
200
+ CREATE TRIGGER messages_fts_update
201
+ AFTER UPDATE OF content_text ON messages BEGIN
202
+ INSERT INTO messages_fts(messages_fts, rowid, content_text)
203
+ VALUES('delete', OLD.id, OLD.content_text);
204
+ INSERT INTO messages_fts(rowid, content_text)
205
+ VALUES(NEW.id, NEW.content_text);
206
+ INSERT INTO messages_fts_trigram(messages_fts_trigram, rowid, content_text)
207
+ VALUES('delete', OLD.id, OLD.content_text);
208
+ INSERT INTO messages_fts_trigram(rowid, content_text)
209
+ VALUES(NEW.id, NEW.content_text);
210
+ END;
211
+
180
212
  CREATE TRIGGER messages_fts_delete
181
213
  AFTER DELETE ON messages BEGIN
182
214
  INSERT INTO messages_fts(messages_fts, rowid, content_text)
@@ -218,29 +250,27 @@ function runMigrations(db) {
218
250
  // Each migration runs exactly once. Add new migrations at the end with
219
251
  // the next sequential version number.
220
252
  const version = db.pragma('user_version')[0].user_version;
221
- // Historical connector migrations (v1-v3): all operate on the captures /
222
- // connector_sync_state tables that were dropped in v5. Wrapped to no-op
223
- // when those tables aren't present (fresh install on the post-v5 schema).
253
+ // Historical connector migrations (v1-v3): all operate on tables that v5
254
+ // dropped (connector_sync_state, captures, capture_connectors,
255
+ // captures_fts*). Guard each on the relevant table existing fresh
256
+ // installs (post-v5 schema) skip these without ever touching the SQL.
224
257
  if (version < 1) {
225
- try {
258
+ if (tableExists(db, 'connector_sync_state')) {
226
259
  db.exec('ALTER TABLE connector_sync_state ADD COLUMN last_error_at TEXT');
227
260
  }
228
- catch { }
229
261
  db.pragma('user_version = 1');
230
262
  }
231
263
  if (version < 2) {
232
- try {
264
+ if (tableExists(db, 'captures_fts')) {
233
265
  db.exec("INSERT INTO captures_fts(captures_fts) VALUES('rebuild')");
234
266
  }
235
- catch { }
236
- try {
267
+ if (tableExists(db, 'captures_fts_trigram')) {
237
268
  db.exec("INSERT INTO captures_fts_trigram(captures_fts_trigram) VALUES('rebuild')");
238
269
  }
239
- catch { }
240
270
  db.pragma('user_version = 2');
241
271
  }
242
272
  if (version < 3) {
243
- try {
273
+ if (tableExists(db, 'captures') && tableExists(db, 'capture_connectors')) {
244
274
  db.transaction(() => {
245
275
  db.exec(`
246
276
  INSERT OR IGNORE INTO capture_connectors (capture_id, connector_id)
@@ -261,7 +291,6 @@ function runMigrations(db) {
261
291
  db.exec(`DROP INDEX IF EXISTS idx_captures_source`);
262
292
  })();
263
293
  }
264
- catch { }
265
294
  db.pragma('user_version = 3');
266
295
  }
267
296
  if (version < 4) {
@@ -285,8 +314,9 @@ function runMigrations(db) {
285
314
  // SQLite can't ALTER a CHECK constraint, so we rebuild the stars table.
286
315
  // For users who never had the wide CHECK (fresh install on post-v5
287
316
  // schema), the rebuild is a no-op rename round-trip — safe and cheap.
288
- // Captures data is dropped without backup; users were directed to Spool
289
- // Daemon for connector functionality.
317
+ // Captures data is dropped here; users were directed to Spool Daemon for
318
+ // connector functionality. We snapshot first so the data is recoverable.
319
+ backupBeforeDestructive(db, 4);
290
320
  db.transaction(() => {
291
321
  db.exec(`DROP TRIGGER IF EXISTS captures_fts_insert`);
292
322
  db.exec(`DROP TRIGGER IF EXISTS captures_fts_delete`);
@@ -313,10 +343,283 @@ function runMigrations(db) {
313
343
  })();
314
344
  db.pragma('user_version = 5');
315
345
  }
346
+ if (version < 6) {
347
+ db.transaction(() => {
348
+ db.exec(`
349
+ ALTER TABLE projects ADD COLUMN identity_kind TEXT;
350
+ ALTER TABLE projects ADD COLUMN identity_key TEXT;
351
+ CREATE INDEX IF NOT EXISTS idx_projects_identity
352
+ ON projects (identity_kind, identity_key);
353
+
354
+ CREATE VIEW IF NOT EXISTS project_groups_v AS
355
+ SELECT
356
+ p.identity_kind,
357
+ p.identity_key,
358
+ MIN(p.display_name) AS display_name,
359
+ GROUP_CONCAT(DISTINCT s.name) AS sources_csv,
360
+ COALESCE(SUM(c.session_count),0) AS session_count,
361
+ MAX(c.last_session_at) AS last_session_at
362
+ FROM projects p
363
+ JOIN sources s ON s.id = p.source_id
364
+ LEFT JOIN (
365
+ SELECT project_id,
366
+ COUNT(*) AS session_count,
367
+ MAX(started_at) AS last_session_at
368
+ FROM sessions
369
+ WHERE message_count > 0
370
+ GROUP BY project_id
371
+ ) c ON c.project_id = p.id
372
+ WHERE p.identity_kind IS NOT NULL
373
+ GROUP BY p.identity_kind, p.identity_key;
374
+ `);
375
+ })();
376
+ db.pragma('user_version = 6');
377
+ backfillProjectIdentities(db, realFs);
378
+ }
379
+ if (version < 7) {
380
+ backupBeforeDestructive(db, 6);
381
+ db.transaction(() => {
382
+ db.exec(`
383
+ CREATE TABLE pins (
384
+ session_uuid TEXT PRIMARY KEY,
385
+ pinned_at TEXT NOT NULL DEFAULT (datetime('now'))
386
+ );
387
+ CREATE INDEX IF NOT EXISTS idx_pins_pinned_at ON pins (pinned_at DESC);
388
+ INSERT OR IGNORE INTO pins (session_uuid, pinned_at)
389
+ SELECT item_uuid, starred_at FROM stars WHERE item_type = 'session';
390
+ DROP TABLE stars;
391
+ `);
392
+ })();
393
+ db.pragma('user_version = 7');
394
+ }
395
+ if (version < 8) {
396
+ // v8: title_source column distinguishes title authority. 'derived' = parsed
397
+ // from source JSONL (default; sync may overwrite). 'spool' = written by
398
+ // Spool itself (e.g. agent-search session created in-app). 'user' = user
399
+ // edited in Spool. Sync only overwrites 'derived' rows.
400
+ if (!columnExists(db, 'sessions', 'title_source')) {
401
+ db.exec(`ALTER TABLE sessions ADD COLUMN title_source TEXT NOT NULL DEFAULT 'derived'`);
402
+ }
403
+ db.pragma('user_version = 8');
404
+ }
405
+ // Schema sanity runs BEFORE any data migration that depends on these
406
+ // columns. Repairs DBs where a version pragma was bumped (by experimental
407
+ // code, a manual upgrade, or a half-finished migration) without the
408
+ // corresponding column being added. Each check is a fast no-op when the
409
+ // column already exists.
410
+ ensureSchemaSanity(db);
411
+ if (version < 9) {
412
+ // v9: one-time data cleanup of historical agent-search sessions indexed
413
+ // before #150-#153. Detection is gated on the Spool buildPrompt blob in
414
+ // a user message (Spool-unique signal) so it can never sweep up real
415
+ // coding sessions whose first message happened to be Claude Code's
416
+ // injected <local-command-caveat>. See migrations/agent-search-cleanup.ts
417
+ // for the full rationale.
418
+ backupBeforeDestructive(db, 8);
419
+ db.transaction(() => {
420
+ runAgentSearchCleanup(db);
421
+ })();
422
+ db.pragma('user_version = 9');
423
+ }
424
+ if (version < 10) {
425
+ // v10: re-classify path-kind projects that are stranded worktree cwds.
426
+ // Before the worktree resolvers landed, a session synced after its
427
+ // worktree was deleted couldn't reach the upstream git remote and was
428
+ // bucketed as its own path-kind project. The resolver now reads the
429
+ // worktree tool's persistent registry (e.g. ~/.superset/local.db) and
430
+ // recovers the real identity. See migrations/worktree-identity-upgrade.ts.
431
+ db.transaction(() => {
432
+ upgradeWorktreeIdentities(db, realFs);
433
+ })();
434
+ db.pragma('user_version = 10');
435
+ }
436
+ if (version < 11) {
437
+ // v11: share_drafts table — locally-persisted in-progress shares
438
+ // managed by Spool Share's editor. Independent of the sessions index;
439
+ // a draft can survive its source session being deleted because the
440
+ // full snapshot is captured at compose time and stored as JSON.
441
+ //
442
+ // Two JSON payloads per row:
443
+ // - snapshot_json: the complete SpoolDocument (full conversation +
444
+ // opts). Used when opening the editor. Can be hundreds of KB on
445
+ // long sessions.
446
+ // - preview_json: a slim subset used by the Shares grid card —
447
+ // opts + title + source + word count + the first handful of
448
+ // turns. Kept under a few KB so listShareDrafts can SELECT it
449
+ // across hundreds of rows without shipping multi-MB IPC payloads
450
+ // to the renderer.
451
+ db.exec(`
452
+ CREATE TABLE IF NOT EXISTS share_drafts (
453
+ draft_id TEXT PRIMARY KEY,
454
+ source_kind TEXT NOT NULL CHECK (source_kind IN (
455
+ 'spool-session', 'pasted-url', 'imported-file', 'imported-jsonl'
456
+ )),
457
+ source_origin TEXT,
458
+ title TEXT NOT NULL DEFAULT '',
459
+ snapshot_json TEXT NOT NULL,
460
+ preview_json TEXT NOT NULL DEFAULT '{}',
461
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
462
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
463
+ );
464
+ CREATE INDEX IF NOT EXISTS idx_share_drafts_updated_at
465
+ ON share_drafts(updated_at DESC);
466
+ CREATE INDEX IF NOT EXISTS idx_share_drafts_source_origin
467
+ ON share_drafts(source_origin);
468
+ `);
469
+ db.pragma('user_version = 11');
470
+ }
471
+ if (version < 12) {
472
+ // v12: Security Scan — sidecar findings + allowlists. The five
473
+ // scan_* columns on sessions are denormalised counters
474
+ // maintained by the scan worker; findings stores (kind,
475
+ // value_hash, offsets) only — never the raw value. Purge mutates
476
+ // messages.content_text and flips the row to state='purged'; the
477
+ // row remains as an audit record. scan_purged_count is the
478
+ // lifetime tally of purged findings per session, used by the
479
+ // Library row's "all-resolved ✓" badge to distinguish "never
480
+ // had findings" from "was clean after I cleaned it up".
481
+ //
482
+ // Wrapped in a transaction so a mid-migration failure (process
483
+ // killed, disk full, etc.) doesn't leave the DB half-altered.
484
+ // Without this, a partial v12 — say two ALTER TABLEs landed
485
+ // but the third failed — would auto-commit the first two and
486
+ // leave user_version at 11; the next launch would retry from
487
+ // the first ALTER and trip a "duplicate column" error,
488
+ // bricking the app on every subsequent startup.
489
+ db.transaction(() => {
490
+ db.exec(`
491
+ ALTER TABLE sessions ADD COLUMN scan_profile TEXT;
492
+ ALTER TABLE sessions ADD COLUMN scan_completed_at TEXT;
493
+ ALTER TABLE sessions ADD COLUMN scan_finding_count INTEGER NOT NULL DEFAULT 0;
494
+ ALTER TABLE sessions ADD COLUMN scan_high_count INTEGER NOT NULL DEFAULT 0;
495
+ ALTER TABLE sessions ADD COLUMN scan_purged_count INTEGER NOT NULL DEFAULT 0;
496
+
497
+ CREATE TABLE IF NOT EXISTS findings (
498
+ id INTEGER PRIMARY KEY,
499
+ session_id INTEGER NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
500
+ message_id INTEGER REFERENCES messages(id) ON DELETE CASCADE,
501
+ kind TEXT NOT NULL,
502
+ value_hash TEXT NOT NULL,
503
+ confidence REAL NOT NULL,
504
+ provider TEXT NOT NULL,
505
+ start_offset INTEGER NOT NULL,
506
+ end_offset INTEGER NOT NULL,
507
+ state TEXT NOT NULL DEFAULT 'active'
508
+ CHECK (state IN ('active','dismissed','purged')),
509
+ detected_at TEXT NOT NULL DEFAULT (datetime('now')),
510
+ state_changed_at TEXT
511
+ );
512
+ CREATE INDEX IF NOT EXISTS idx_findings_session ON findings(session_id);
513
+ CREATE INDEX IF NOT EXISTS idx_findings_state ON findings(state);
514
+ CREATE INDEX IF NOT EXISTS idx_findings_kind_hash ON findings(kind, value_hash);
515
+
516
+ CREATE TABLE IF NOT EXISTS allowlist_session (
517
+ session_id INTEGER NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
518
+ kind TEXT NOT NULL,
519
+ value_hash TEXT NOT NULL,
520
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
521
+ PRIMARY KEY (session_id, kind, value_hash)
522
+ );
523
+
524
+ CREATE TABLE IF NOT EXISTS allowlist_global (
525
+ kind TEXT NOT NULL,
526
+ value_hash TEXT NOT NULL,
527
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
528
+ PRIMARY KEY (kind, value_hash)
529
+ );
530
+ `);
531
+ db.pragma('user_version = 12');
532
+ })();
533
+ }
534
+ if (version < 13) {
535
+ // v13: purge subagent jsonl rows that hijacked their parent's session_uuid.
536
+ // Claude code writes subagent transcripts to <slug>/<uuid>/subagents/agent-*.jsonl;
537
+ // every record inside carries sessionId = parent uuid, so the indexer used to
538
+ // upsert these on top of the parent row via UNIQUE(session_uuid) — clobbering
539
+ // file_path and zeroing message_count (all messages are isSidechain). The
540
+ // matching read-side fix in source-paths.ts excludes the files going forward;
541
+ // here we delete the orphan rows so the next sync re-indexes the real parent.
542
+ // Cascades cover messages / session_search / findings / allowlist_session;
543
+ // pins survives (keyed by session_uuid TEXT, no FK) and re-attaches on re-sync.
544
+ db.transaction(() => {
545
+ const claudeSourceId = db.prepare("SELECT id FROM sources WHERE name = 'claude'").get()?.id;
546
+ if (claudeSourceId !== undefined) {
547
+ db.prepare(`DELETE FROM sessions
548
+ WHERE source_id = ?
549
+ AND file_path LIKE '%/subagents/agent-%'`).run(claudeSourceId);
550
+ db.prepare(`DELETE FROM sync_log
551
+ WHERE source_id = ?
552
+ AND file_path LIKE '%/subagents/agent-%'`).run(claudeSourceId);
553
+ }
554
+ db.pragma('user_version = 13');
555
+ })();
556
+ }
316
557
  rebuildFtsTableIfEmpty(db, 'messages', 'messages_fts_trigram');
317
558
  rebuildFtsTableIfEmpty(db, 'session_search', 'session_search_fts');
318
559
  rebuildFtsTableIfEmpty(db, 'session_search', 'session_search_fts_trigram');
319
560
  }
561
+ export function backfillProjectIdentities(db, fs) {
562
+ const rows = db.prepare(`SELECT id, display_path FROM projects WHERE identity_kind IS NULL`).all();
563
+ if (rows.length === 0)
564
+ return;
565
+ const update = db.prepare(`UPDATE projects
566
+ SET identity_kind = ?, identity_key = ?, display_name = COALESCE(?, display_name)
567
+ WHERE id = ?`);
568
+ db.transaction(() => {
569
+ for (const r of rows) {
570
+ const id = computeIdentity(r.display_path, fs);
571
+ update.run(id.kind, id.key, id.displayName, r.id);
572
+ }
573
+ })();
574
+ }
575
+ function tableExists(db, name) {
576
+ const row = db.prepare(`SELECT name FROM sqlite_master WHERE type IN ('table','virtual') AND name = ?`).get(name);
577
+ return row !== undefined;
578
+ }
579
+ function columnExists(db, table, column) {
580
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
581
+ return rows.some(r => r.name === column);
582
+ }
583
+ function ensureSchemaSanity(db) {
584
+ // Backfill columns the head schema requires but historical DBs (or test
585
+ // fixtures that seed an intentionally-minimal table) may be missing.
586
+ // Each ALTER is a fast no-op when the column already exists.
587
+ const ensureCol = (col, ddl) => {
588
+ if (!columnExists(db, 'sessions', col))
589
+ db.exec(`ALTER TABLE sessions ADD COLUMN ${col} ${ddl}`);
590
+ };
591
+ ensureCol('title', 'TEXT');
592
+ ensureCol('title_source', `TEXT NOT NULL DEFAULT 'derived'`);
593
+ ensureCol('message_count', 'INTEGER NOT NULL DEFAULT 0');
594
+ }
595
+ /**
596
+ * Snapshot the DB to `<dbDir>/backups/spool-pre-v{fromVersion+1}-<ts>.db`
597
+ * via VACUUM INTO, before a destructive migration runs.
598
+ *
599
+ * Returns the backup file path on success, or null when a backup is skipped:
600
+ * - in-memory DBs (db.memory)
601
+ * - fresh-install / no-data DBs (sessions table empty or missing)
602
+ *
603
+ * Each call writes to a distinct path; v5 and v7 produce separate files.
604
+ */
605
+ export function backupBeforeDestructive(db, fromVersion) {
606
+ if (db.memory)
607
+ return null;
608
+ const dbPath = db.name;
609
+ if (!dbPath)
610
+ return null;
611
+ if (!tableExists(db, 'sessions'))
612
+ return null;
613
+ const sessions = db.prepare(`SELECT COUNT(*) AS c FROM sessions`).get();
614
+ if (sessions.c === 0)
615
+ return null;
616
+ const backupDir = join(dirname(dbPath), 'backups');
617
+ mkdirSync(backupDir, { recursive: true });
618
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
619
+ const backupPath = join(backupDir, `spool-pre-v${fromVersion + 1}-${ts}.db`);
620
+ db.exec(`VACUUM INTO '${backupPath.replace(/'/g, "''")}'`);
621
+ return backupPath;
622
+ }
320
623
  function rebuildFtsTableIfEmpty(db, contentTable, ftsTable) {
321
624
  const sourceCount = db.prepare(`SELECT COUNT(*) AS count FROM ${contentTable}`).get().count;
322
625
  if (sourceCount === 0)
package/dist/db/db.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../src/db/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,EAAE,eAAe,EAAmB,MAAM,yBAAyB,CAAA;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAA;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,4CAA4C,CAAA;AAEtF,MAAM,CAAC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAA;AACnF,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;AAElD;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAEvC,IAAI,GAAG,GAA6B,IAAI,CAAA;AACxC,IAAI,SAAS,GAAG,KAAK,CAAA;AACrB,IAAI,mBAAmB,GAAkB,IAAI,CAAA;AAW7C,MAAM,UAAU,KAAK,CAAC,GAA2B;IAC/C,IAAI,GAAG;QAAE,OAAO,GAAG,CAAA;IACnB,MAAM,IAAI,GACR,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACpD,MAAM,mBAAmB,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAA;IACxD,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,iFAAiF;IACjF,SAAS,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;IAChC,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAA;IAChC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAA;IAC/B,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAC9B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAA;IAChC,mBAAmB,GAAI,EAAE,CAAC,MAAM,CAAC,cAAc,CAAqC,CAAC,CAAC,CAAC,EAAE,YAAY,IAAI,CAAC,CAAA;IAC1G,IAAI,mBAAmB,EAAE,CAAC;QACxB,aAAa,CAAC,EAAE,CAAC,CAAA;IACnB,CAAC;IACD,GAAG,GAAG,EAAE,CAAA;IACR,OAAO,EAAE,CAAA;AACX,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,QAAQ,KAAc,OAAO,SAAS,CAAA,CAAC,CAAC;AAExD,yGAAyG;AACzG,MAAM,UAAU,qBAAqB,KAAoB,OAAO,mBAAmB,CAAA,CAAC,CAAC;AAErF,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAA;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAA;IACV,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAqB;IACjD,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4HP,CAAC,CAAA;IAEF,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEP,CAAC,CAAA;IAEF,2EAA2E;IAC3E,qEAAqE;IACrE,uEAAuE;IACvE,sCAAsC;IACtC,MAAM,OAAO,GAAI,EAAE,CAAC,MAAM,CAAC,cAAc,CAAgC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAA;IAEzF,yEAAyE;IACzE,+DAA+D;IAC/D,oEAAoE;IACpE,sEAAsE;IACtE,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,IAAI,WAAW,CAAC,EAAE,EAAE,sBAAsB,CAAC,EAAE,CAAC;YAC5C,EAAE,CAAC,IAAI,CAAC,gEAAgE,CAAC,CAAA;QAC3E,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,IAAI,WAAW,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC;YACpC,EAAE,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAA;QACrE,CAAC;QACD,IAAI,WAAW,CAAC,EAAE,EAAE,sBAAsB,CAAC,EAAE,CAAC;YAC5C,EAAE,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAA;QACrF,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,IAAI,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC,IAAI,WAAW,CAAC,EAAE,EAAE,oBAAoB,CAAC,EAAE,CAAC;YACzE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;gBAClB,EAAE,CAAC,IAAI,CAAC;;;;;SAKP,CAAC,CAAA;gBACF,EAAE,CAAC,IAAI,CAAC;;;;SAIP,CAAC,CAAA;gBACF,EAAE,CAAC,IAAI,CAAC;;;;SAIP,CAAC,CAAA;gBACF,EAAE,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAA;YACrD,CAAC,CAAC,EAAE,CAAA;QACN,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,0EAA0E;QAC1E,EAAE,CAAC,IAAI,CAAC;;;;;;;;;KASP,CAAC,CAAA;QACF,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,wEAAwE;QACxE,8CAA8C;QAC9C,EAAE;QACF,wEAAwE;QACxE,mEAAmE;QACnE,sEAAsE;QACtE,yEAAyE;QACzE,yEAAyE;QACzE,uBAAuB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9B,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;YACrD,EAAE,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAA;YACrD,EAAE,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;YACpD,EAAE,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAA;YAC5C,EAAE,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAA;YAClD,EAAE,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;YACxC,EAAE,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;YAEpD,EAAE,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAA;YACxD,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;OAYP,CAAC,CAAA;YAEF,EAAE,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAA;QACzD,CAAC,CAAC,EAAE,CAAA;QACJ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BP,CAAC,CAAA;QACJ,CAAC,CAAC,EAAE,CAAA;QACJ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;QAC7B,yBAAyB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,uBAAuB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9B,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;OASP,CAAC,CAAA;QACJ,CAAC,CAAC,EAAE,CAAA;QACJ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,4EAA4E;QAC5E,wEAAwE;QACxE,yEAAyE;QACzE,wDAAwD;QACxD,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,CAAC;YAClD,EAAE,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAA;QACzF,CAAC;QACD,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,qEAAqE;IACrE,0EAA0E;IAC1E,oEAAoE;IACpE,wEAAwE;IACxE,yBAAyB;IACzB,kBAAkB,CAAC,EAAE,CAAC,CAAA;IAEtB,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,wEAAwE;QACxE,wEAAwE;QACxE,qEAAqE;QACrE,mEAAmE;QACnE,0EAA0E;QAC1E,0BAA0B;QAC1B,uBAAuB,CAAC,EAAE,EAAE,CAAC,CAAC,CAAA;QAC9B,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,qBAAqB,CAAC,EAAE,CAAC,CAAA;QAC3B,CAAC,CAAC,EAAE,CAAA;QACJ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAA;IAC/B,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACjB,uEAAuE;QACvE,mEAAmE;QACnE,sEAAsE;QACtE,oEAAoE;QACpE,sEAAsE;QACtE,2EAA2E;QAC3E,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,yBAAyB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QACvC,CAAC,CAAC,EAAE,CAAA;QACJ,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACjB,iEAAiE;QACjE,sEAAsE;QACtE,mEAAmE;QACnE,gEAAgE;QAChE,EAAE;QACF,6BAA6B;QAC7B,qEAAqE;QACrE,oEAAoE;QACpE,qBAAqB;QACrB,iEAAiE;QACjE,gEAAgE;QAChE,kEAAkE;QAClE,qEAAqE;QACrE,uBAAuB;QACvB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;KAiBP,CAAC,CAAA;QACF,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;IAChC,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACjB,+DAA+D;QAC/D,uDAAuD;QACvD,wDAAwD;QACxD,iEAAiE;QACjE,iEAAiE;QACjE,2DAA2D;QAC3D,6DAA6D;QAC7D,6DAA6D;QAC7D,wDAAwD;QACxD,EAAE;QACF,+DAA+D;QAC/D,8DAA8D;QAC9D,4DAA4D;QAC5D,6DAA6D;QAC7D,6DAA6D;QAC7D,uDAAuD;QACvD,gDAAgD;QAChD,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwCP,CAAC,CAAA;YACF,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;QAChC,CAAC,CAAC,EAAE,CAAA;IACN,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACjB,4EAA4E;QAC5E,oFAAoF;QACpF,8EAA8E;QAC9E,8EAA8E;QAC9E,0EAA0E;QAC1E,8EAA8E;QAC9E,8EAA8E;QAC9E,2EAA2E;QAC3E,gFAAgF;QAChF,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YAClB,MAAM,cAAc,GAAI,EAAE,CAAC,OAAO,CAChC,8CAA8C,CAC/C,CAAC,GAAG,EAAiC,EAAE,EAAE,CAAA;YAC1C,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;gBACjC,EAAE,CAAC,OAAO,CACR;;wDAE8C,CAC/C,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;gBACrB,EAAE,CAAC,OAAO,CACR;;wDAE8C,CAC/C,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;YACvB,CAAC;YACD,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAA;QAChC,CAAC,CAAC,EAAE,CAAA;IACN,CAAC;IAED,sBAAsB,CAAC,EAAE,EAAE,UAAU,EAAE,sBAAsB,CAAC,CAAA;IAC9D,sBAAsB,CAAC,EAAE,EAAE,gBAAgB,EAAE,oBAAoB,CAAC,CAAA;IAClE,sBAAsB,CAAC,EAAE,EAAE,gBAAgB,EAAE,4BAA4B,CAAC,CAAA;AAC5E,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EAAqB,EAAE,EAAc;IAC7E,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CACrB,mEAAmE,CACpE,CAAC,GAAG,EAA4C,CAAA;IACjD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAM;IAC7B,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CACvB;;kBAEc,CACf,CAAA;IACD,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;QAClB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;YAC9C,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;QACnD,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;AACN,CAAC;AAED,SAAS,WAAW,CAAC,EAAqB,EAAE,IAAY;IACtD,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CACpB,+EAA+E,CAChF,CAAC,GAAG,CAAC,IAAI,CAAiC,CAAA;IAC3C,OAAO,GAAG,KAAK,SAAS,CAAA;AAC1B,CAAC;AAED,SAAS,YAAY,CAAC,EAAqB,EAAE,KAAa,EAAE,MAAc;IACxE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,qBAAqB,KAAK,GAAG,CAAC,CAAC,GAAG,EAA6B,CAAA;IACvF,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAA;AAC1C,CAAC;AAED,SAAS,kBAAkB,CAAC,EAAqB;IAC/C,wEAAwE;IACxE,qEAAqE;IACrE,6DAA6D;IAC7D,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,GAAW,EAAQ,EAAE;QACnD,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC;YAAE,EAAE,CAAC,IAAI,CAAC,mCAAmC,GAAG,IAAI,GAAG,EAAE,CAAC,CAAA;IAClG,CAAC,CAAA;IACD,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC1B,SAAS,CAAC,cAAc,EAAE,iCAAiC,CAAC,CAAA;IAC5D,SAAS,CAAC,eAAe,EAAE,4BAA4B,CAAC,CAAA;AAC1D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,EAAqB,EACrB,WAAmB;IAEnB,IAAI,EAAE,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,IAAI,CAAA;IACtB,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IACxB,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,UAAU,CAAC;QAAE,OAAO,IAAI,CAAA;IAE7C,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,EAAmB,CAAA;IACxF,IAAI,QAAQ,CAAC,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAEjC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAA;IAClD,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACzC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,cAAc,WAAW,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;IAC5E,EAAE,CAAC,IAAI,CAAC,gBAAgB,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAA;IAC1D,OAAO,UAAU,CAAA;AACnB,CAAC;AAED,SAAS,sBAAsB,CAC7B,EAAqB,EACrB,YAA2C,EAC3C,QAGgC;IAEhC,MAAM,WAAW,GAAI,EAAE,CAAC,OAAO,CAAC,iCAAiC,YAAY,EAAE,CAAC,CAAC,GAAG,EAAwB,CAAC,KAAK,CAAA;IAClH,IAAI,WAAW,KAAK,CAAC;QAAE,OAAM;IAE7B,MAAM,UAAU,GAAI,EAAE,CAAC,OAAO,CAAC,iCAAiC,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAwB,CAAC,KAAK,CAAA;IAC7G,IAAI,UAAU,GAAG,CAAC;QAAE,OAAM;IAE1B,EAAE,CAAC,IAAI,CAAC,eAAe,QAAQ,IAAI,QAAQ,qBAAqB,CAAC,CAAA;AACnE,CAAC"}
@@ -1,7 +1,32 @@
1
1
  import type Database from 'better-sqlite3';
2
- import type { Session, Message, FragmentResult, StatusInfo, SessionSource, StarKind, StarredItem } from '../types.js';
3
- export declare function getOrCreateProject(db: Database.Database, sourceId: number, slug: string, displayPath: string, displayName: string): number;
2
+ import type { Session, Message, FragmentResult, StatusInfo, SessionSource, ProjectIdentityKind } from '../types.js';
3
+ export declare function getOrCreateProject(db: Database.Database, sourceId: number, slug: string, displayPath: string, displayName: string, identity: {
4
+ identityKind: ProjectIdentityKind;
5
+ identityKey: string;
6
+ }): number;
4
7
  export declare function getSourceId(db: Database.Database, name: SessionSource): number;
8
+ /**
9
+ * Get/create the virtual "Asks" project that holds Spool-authored agent-search
10
+ * sessions. One per source so each agent's sessions stay grouped under their
11
+ * own row in project_groups_v (joined by identity for cross-source grouping).
12
+ */
13
+ export declare function getOrCreateAskProject(db: Database.Database, source: SessionSource): number;
14
+ /**
15
+ * Insert a session row authored by Spool itself (e.g. agent search). Title is
16
+ * locked via title_source='spool' so subsequent sync of the source-side JSONL
17
+ * won't overwrite it. file_path uses a sentinel ('spool:pending:<uuid>') that
18
+ * upsertSession rebinds to the real path when sync first sees the JSONL.
19
+ *
20
+ * Idempotent: if a row with the same session_uuid already exists, returns its
21
+ * id without modifying anything.
22
+ */
23
+ export declare function insertSpoolAuthoredSession(db: Database.Database, opts: {
24
+ projectId: number;
25
+ sourceId: number;
26
+ sessionUuid: string;
27
+ title: string;
28
+ cwd: string;
29
+ }): number;
5
30
  export declare function getSessionMtime(db: Database.Database, filePath: string): string | null;
6
31
  export declare function deleteSessionByFilePath(db: Database.Database, filePath: string): boolean;
7
32
  export declare function getAllSessionMtimes(db: Database.Database): Map<string, string>;
@@ -35,7 +60,7 @@ export declare function insertMessages(db: Database.Database, sessionId: number,
35
60
  toolNames: string[];
36
61
  seq: number;
37
62
  }>): void;
38
- export declare function listRecentSessions(db: Database.Database, limit?: number): Session[];
63
+ export declare const SESSION_SELECT = "\n SELECT\n s.id, s.project_id AS projectId, s.source_id AS sourceId,\n s.session_uuid AS sessionUuid, s.file_path AS filePath,\n s.title, s.started_at AS startedAt, s.ended_at AS endedAt,\n s.message_count AS messageCount, s.has_tool_use AS hasToolUse,\n s.cwd, s.model,\n s.scan_finding_count AS scanFindingCount,\n s.scan_high_count AS scanHighCount,\n s.scan_purged_count AS scanPurgedCount,\n s.scan_completed_at AS scanCompletedAt,\n src.name AS source,\n p.display_path AS projectDisplayPath,\n p.display_name AS projectDisplayName\n FROM sessions s\n JOIN sources src ON src.id = s.source_id\n JOIN projects p ON p.id = s.project_id";
39
64
  export declare function getSessionWithMessages(db: Database.Database, sessionUuid: string): {
40
65
  session: Session;
41
66
  messages: Message[];
@@ -44,7 +69,8 @@ export declare function searchFragments(db: Database.Database, query: string, op
44
69
  limit?: number;
45
70
  source?: SessionSource;
46
71
  since?: string;
47
- onlyStarred?: boolean;
72
+ onlyPinned?: boolean;
73
+ identityKey?: string;
48
74
  }): FragmentResult[];
49
75
  export declare function searchSessionPreview(db: Database.Database, query: string, opts?: {
50
76
  limit?: number;
@@ -52,12 +78,11 @@ export declare function searchSessionPreview(db: Database.Database, query: strin
52
78
  since?: string;
53
79
  }): FragmentResult[];
54
80
  export declare function buildLikeSnippet(text: string, terms: string[]): string;
55
- export declare function starItem(db: Database.Database, kind: StarKind, uuid: string): void;
56
- export declare function unstarItem(db: Database.Database, kind: StarKind, uuid: string): void;
57
- export declare function isStarred(db: Database.Database, kind: StarKind, uuid: string): boolean;
58
- export declare function getStarredUuidsByType(db: Database.Database): {
59
- session: string[];
60
- };
61
- export declare function listStarredItems(db: Database.Database, limit?: number): StarredItem[];
81
+ export declare function pinSession(db: Database.Database, sessionUuid: string): void;
82
+ export declare function unpinSession(db: Database.Database, sessionUuid: string): void;
83
+ export declare function isPinned(db: Database.Database, sessionUuid: string): boolean;
84
+ export declare function getPinnedUuids(db: Database.Database): string[];
85
+ export declare function listPinnedSessions(db: Database.Database): Session[];
62
86
  export declare function getStatus(db: Database.Database): StatusInfo;
87
+ export declare function rowToSession(r: Record<string, unknown>): Session;
63
88
  //# sourceMappingURL=queries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"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"}