@cleocode/core 2026.3.43 → 2026.3.45

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 (183) hide show
  1. package/dist/admin/export-tasks.d.ts.map +1 -1
  2. package/dist/admin/import-tasks.d.ts +10 -2
  3. package/dist/admin/import-tasks.d.ts.map +1 -1
  4. package/dist/agents/agent-schema.d.ts +358 -0
  5. package/dist/agents/agent-schema.d.ts.map +1 -0
  6. package/dist/agents/capacity.d.ts +57 -0
  7. package/dist/agents/capacity.d.ts.map +1 -0
  8. package/dist/agents/index.d.ts +17 -0
  9. package/dist/agents/index.d.ts.map +1 -0
  10. package/dist/agents/registry.d.ts +115 -0
  11. package/dist/agents/registry.d.ts.map +1 -0
  12. package/dist/agents/retry.d.ts +83 -0
  13. package/dist/agents/retry.d.ts.map +1 -0
  14. package/dist/hooks/index.d.ts +4 -1
  15. package/dist/hooks/index.d.ts.map +1 -1
  16. package/dist/hooks/payload-schemas.d.ts +214 -0
  17. package/dist/hooks/payload-schemas.d.ts.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +16937 -2371
  21. package/dist/index.js.map +4 -4
  22. package/dist/inject/index.d.ts.map +1 -1
  23. package/dist/intelligence/impact.d.ts +51 -0
  24. package/dist/intelligence/impact.d.ts.map +1 -0
  25. package/dist/intelligence/index.d.ts +15 -0
  26. package/dist/intelligence/index.d.ts.map +1 -0
  27. package/dist/intelligence/patterns.d.ts +66 -0
  28. package/dist/intelligence/patterns.d.ts.map +1 -0
  29. package/dist/intelligence/prediction.d.ts +51 -0
  30. package/dist/intelligence/prediction.d.ts.map +1 -0
  31. package/dist/intelligence/types.d.ts +221 -0
  32. package/dist/intelligence/types.d.ts.map +1 -0
  33. package/dist/internal.d.ts +12 -1
  34. package/dist/internal.d.ts.map +1 -1
  35. package/dist/issue/template-parser.d.ts +8 -2
  36. package/dist/issue/template-parser.d.ts.map +1 -1
  37. package/dist/lifecycle/pipeline.d.ts +2 -2
  38. package/dist/lifecycle/pipeline.d.ts.map +1 -1
  39. package/dist/lifecycle/state-machine.d.ts +1 -1
  40. package/dist/lifecycle/state-machine.d.ts.map +1 -1
  41. package/dist/memory/brain-lifecycle.d.ts.map +1 -1
  42. package/dist/memory/brain-retrieval.d.ts.map +1 -1
  43. package/dist/memory/brain-row-types.d.ts +40 -6
  44. package/dist/memory/brain-row-types.d.ts.map +1 -1
  45. package/dist/memory/brain-search.d.ts.map +1 -1
  46. package/dist/memory/brain-similarity.d.ts.map +1 -1
  47. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  48. package/dist/nexus/discover.d.ts.map +1 -1
  49. package/dist/nexus/index.d.ts +2 -0
  50. package/dist/nexus/index.d.ts.map +1 -1
  51. package/dist/nexus/transfer-types.d.ts +123 -0
  52. package/dist/nexus/transfer-types.d.ts.map +1 -0
  53. package/dist/nexus/transfer.d.ts +31 -0
  54. package/dist/nexus/transfer.d.ts.map +1 -0
  55. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  56. package/dist/orchestration/skill-ops.d.ts +4 -4
  57. package/dist/orchestration/skill-ops.d.ts.map +1 -1
  58. package/dist/otel/index.d.ts +1 -1
  59. package/dist/otel/index.d.ts.map +1 -1
  60. package/dist/sessions/briefing.d.ts.map +1 -1
  61. package/dist/sessions/handoff.d.ts.map +1 -1
  62. package/dist/sessions/index.d.ts +1 -1
  63. package/dist/sessions/index.d.ts.map +1 -1
  64. package/dist/sessions/types.d.ts +8 -42
  65. package/dist/sessions/types.d.ts.map +1 -1
  66. package/dist/signaldock/signaldock-transport.d.ts +1 -1
  67. package/dist/signaldock/signaldock-transport.d.ts.map +1 -1
  68. package/dist/skills/injection/subagent.d.ts +3 -3
  69. package/dist/skills/injection/subagent.d.ts.map +1 -1
  70. package/dist/skills/manifests/contribution.d.ts +2 -2
  71. package/dist/skills/manifests/contribution.d.ts.map +1 -1
  72. package/dist/skills/orchestrator/spawn.d.ts +6 -6
  73. package/dist/skills/orchestrator/spawn.d.ts.map +1 -1
  74. package/dist/skills/orchestrator/startup.d.ts +1 -1
  75. package/dist/skills/orchestrator/startup.d.ts.map +1 -1
  76. package/dist/skills/orchestrator/validator.d.ts +2 -2
  77. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  78. package/dist/skills/precedence-types.d.ts +24 -1
  79. package/dist/skills/precedence-types.d.ts.map +1 -1
  80. package/dist/skills/types.d.ts +70 -4
  81. package/dist/skills/types.d.ts.map +1 -1
  82. package/dist/store/brain-sqlite.d.ts +4 -1
  83. package/dist/store/brain-sqlite.d.ts.map +1 -1
  84. package/dist/store/export.d.ts +5 -4
  85. package/dist/store/export.d.ts.map +1 -1
  86. package/dist/store/nexus-sqlite.d.ts +4 -1
  87. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  88. package/dist/store/sqlite.d.ts +4 -1
  89. package/dist/store/sqlite.d.ts.map +1 -1
  90. package/dist/store/tasks-schema.d.ts +14 -4
  91. package/dist/store/tasks-schema.d.ts.map +1 -1
  92. package/dist/store/typed-query.d.ts +12 -0
  93. package/dist/store/typed-query.d.ts.map +1 -0
  94. package/dist/store/validation-schemas.d.ts +2423 -50
  95. package/dist/store/validation-schemas.d.ts.map +1 -1
  96. package/dist/system/inject-generate.d.ts.map +1 -1
  97. package/dist/validation/doctor/checks.d.ts +5 -0
  98. package/dist/validation/doctor/checks.d.ts.map +1 -1
  99. package/dist/validation/engine.d.ts +10 -10
  100. package/dist/validation/engine.d.ts.map +1 -1
  101. package/dist/validation/index.d.ts +6 -2
  102. package/dist/validation/index.d.ts.map +1 -1
  103. package/dist/validation/protocol-common.d.ts +10 -2
  104. package/dist/validation/protocol-common.d.ts.map +1 -1
  105. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/migration.sql +84 -0
  106. package/migrations/drizzle-tasks/20260320013731_wave0-schema-hardening/snapshot.json +4060 -0
  107. package/migrations/drizzle-tasks/20260320020000_agent-dimension/migration.sql +35 -0
  108. package/migrations/drizzle-tasks/20260320020000_agent-dimension/snapshot.json +4312 -0
  109. package/package.json +2 -2
  110. package/src/admin/export-tasks.ts +2 -5
  111. package/src/admin/import-tasks.ts +53 -29
  112. package/src/agents/__tests__/capacity.test.ts +219 -0
  113. package/src/agents/__tests__/registry.test.ts +457 -0
  114. package/src/agents/__tests__/retry.test.ts +289 -0
  115. package/src/agents/agent-schema.ts +107 -0
  116. package/src/agents/capacity.ts +151 -0
  117. package/src/agents/index.ts +68 -0
  118. package/src/agents/registry.ts +449 -0
  119. package/src/agents/retry.ts +255 -0
  120. package/src/hooks/index.ts +20 -1
  121. package/src/hooks/payload-schemas.ts +199 -0
  122. package/src/index.ts +69 -0
  123. package/src/inject/index.ts +14 -14
  124. package/src/intelligence/__tests__/impact.test.ts +453 -0
  125. package/src/intelligence/__tests__/patterns.test.ts +450 -0
  126. package/src/intelligence/__tests__/prediction.test.ts +418 -0
  127. package/src/intelligence/impact.ts +638 -0
  128. package/src/intelligence/index.ts +47 -0
  129. package/src/intelligence/patterns.ts +621 -0
  130. package/src/intelligence/prediction.ts +621 -0
  131. package/src/intelligence/types.ts +273 -0
  132. package/src/internal.ts +89 -2
  133. package/src/issue/template-parser.ts +65 -4
  134. package/src/lifecycle/pipeline.ts +14 -7
  135. package/src/lifecycle/state-machine.ts +6 -2
  136. package/src/memory/brain-lifecycle.ts +5 -11
  137. package/src/memory/brain-retrieval.ts +44 -38
  138. package/src/memory/brain-row-types.ts +43 -6
  139. package/src/memory/brain-search.ts +53 -32
  140. package/src/memory/brain-similarity.ts +9 -8
  141. package/src/memory/claude-mem-migration.ts +4 -3
  142. package/src/nexus/__tests__/nexus-e2e.test.ts +1481 -0
  143. package/src/nexus/__tests__/transfer.test.ts +446 -0
  144. package/src/nexus/discover.ts +1 -0
  145. package/src/nexus/index.ts +14 -0
  146. package/src/nexus/transfer-types.ts +129 -0
  147. package/src/nexus/transfer.ts +314 -0
  148. package/src/orchestration/bootstrap.ts +11 -17
  149. package/src/orchestration/skill-ops.ts +52 -32
  150. package/src/otel/index.ts +48 -4
  151. package/src/sessions/__tests__/briefing.test.ts +31 -2
  152. package/src/sessions/briefing.ts +27 -42
  153. package/src/sessions/handoff.ts +52 -86
  154. package/src/sessions/index.ts +5 -1
  155. package/src/sessions/types.ts +9 -43
  156. package/src/signaldock/signaldock-transport.ts +5 -2
  157. package/src/skills/injection/subagent.ts +10 -16
  158. package/src/skills/manifests/contribution.ts +5 -13
  159. package/src/skills/orchestrator/__tests__/spawn-tier.test.ts +44 -30
  160. package/src/skills/orchestrator/spawn.ts +18 -31
  161. package/src/skills/orchestrator/startup.ts +78 -65
  162. package/src/skills/orchestrator/validator.ts +26 -31
  163. package/src/skills/precedence-types.ts +24 -1
  164. package/src/skills/types.ts +72 -5
  165. package/src/store/__tests__/test-db-helper.d.ts +4 -4
  166. package/src/store/__tests__/test-db-helper.js +5 -16
  167. package/src/store/__tests__/test-db-helper.ts +5 -18
  168. package/src/store/brain-sqlite.ts +7 -3
  169. package/src/store/chain-schema.ts +1 -1
  170. package/src/store/export.ts +22 -12
  171. package/src/store/nexus-sqlite.ts +7 -3
  172. package/src/store/sqlite.ts +9 -3
  173. package/src/store/tasks-schema.ts +65 -8
  174. package/src/store/typed-query.ts +17 -0
  175. package/src/store/validation-schemas.ts +347 -23
  176. package/src/system/inject-generate.ts +9 -23
  177. package/src/validation/doctor/checks.ts +24 -2
  178. package/src/validation/engine.ts +11 -11
  179. package/src/validation/index.ts +131 -3
  180. package/src/validation/protocol-common.ts +54 -3
  181. package/dist/tasks/reparent.d.ts +0 -38
  182. package/dist/tasks/reparent.d.ts.map +0 -1
  183. package/src/tasks/reparent.ts +0 -134
@@ -22,8 +22,14 @@ import type {
22
22
  BRAIN_OBSERVATION_SOURCE_TYPES,
23
23
  BRAIN_OBSERVATION_TYPES,
24
24
  } from '../store/brain-schema.js';
25
+ import { typedAll } from '../store/typed-query.js';
25
26
  import { embedText, isEmbeddingAvailable } from './brain-embedding.js';
26
- import type { BrainAnchor, BrainFtsRow, BrainNarrativeRow } from './brain-row-types.js';
27
+ import type {
28
+ BrainAnchor,
29
+ BrainFtsRow,
30
+ BrainNarrativeRow,
31
+ BrainTimelineNeighborRow,
32
+ } from './brain-row-types.js';
27
33
  import { searchBrain } from './brain-search.js';
28
34
 
29
35
  // ============================================================================
@@ -305,8 +311,8 @@ export async function timelineBrain(
305
311
 
306
312
  // UNION ALL across all 4 tables to get chronological neighbors.
307
313
  // Excludes the anchor itself.
308
- const beforeRows = nativeDb
309
- .prepare(`
314
+ const beforeRows = typedAll<BrainTimelineNeighborRow>(
315
+ nativeDb.prepare(`
310
316
  SELECT id, 'decision' AS type, created_at AS date FROM brain_decisions WHERE created_at < ? AND id != ?
311
317
  UNION ALL
312
318
  SELECT id, 'pattern' AS type, extracted_at AS date FROM brain_patterns WHERE extracted_at < ? AND id != ?
@@ -316,21 +322,20 @@ export async function timelineBrain(
316
322
  SELECT id, 'observation' AS type, created_at AS date FROM brain_observations WHERE created_at < ? AND id != ?
317
323
  ORDER BY date DESC
318
324
  LIMIT ?
319
- `)
320
- .all(
321
- anchorDate,
322
- anchorId,
323
- anchorDate,
324
- anchorId,
325
- anchorDate,
326
- anchorId,
327
- anchorDate,
328
- anchorId,
329
- depthBefore,
330
- ) as unknown as TimelineNeighbor[];
331
-
332
- const afterRows = nativeDb
333
- .prepare(`
325
+ `),
326
+ anchorDate,
327
+ anchorId,
328
+ anchorDate,
329
+ anchorId,
330
+ anchorDate,
331
+ anchorId,
332
+ anchorDate,
333
+ anchorId,
334
+ depthBefore,
335
+ );
336
+
337
+ const afterRows = typedAll<BrainTimelineNeighborRow>(
338
+ nativeDb.prepare(`
334
339
  SELECT id, 'decision' AS type, created_at AS date FROM brain_decisions WHERE created_at > ? AND id != ?
335
340
  UNION ALL
336
341
  SELECT id, 'pattern' AS type, extracted_at AS date FROM brain_patterns WHERE extracted_at > ? AND id != ?
@@ -340,18 +345,17 @@ export async function timelineBrain(
340
345
  SELECT id, 'observation' AS type, created_at AS date FROM brain_observations WHERE created_at > ? AND id != ?
341
346
  ORDER BY date ASC
342
347
  LIMIT ?
343
- `)
344
- .all(
345
- anchorDate,
346
- anchorId,
347
- anchorDate,
348
- anchorId,
349
- anchorDate,
350
- anchorId,
351
- anchorDate,
352
- anchorId,
353
- depthAfter,
354
- ) as unknown as TimelineNeighbor[];
348
+ `),
349
+ anchorDate,
350
+ anchorId,
351
+ anchorDate,
352
+ anchorId,
353
+ anchorDate,
354
+ anchorId,
355
+ anchorDate,
356
+ anchorId,
357
+ depthAfter,
358
+ );
355
359
 
356
360
  return {
357
361
  anchor: { id: anchorId, type: anchorType, data: anchorData },
@@ -530,11 +534,13 @@ export async function observeBrain(
530
534
  const nativeDb = getBrainNativeDb();
531
535
  if (nativeDb) {
532
536
  const cutoff = new Date(Date.now() - 30000).toISOString().replace('T', ' ').slice(0, 19);
533
- const existing = nativeDb
534
- .prepare(
537
+ const existing = typedAll<BrainFtsRow>(
538
+ nativeDb.prepare(
535
539
  'SELECT id, type, created_at FROM brain_observations WHERE content_hash = ? AND created_at > ?',
536
- )
537
- .all(contentHash, cutoff) as unknown as BrainFtsRow[];
540
+ ),
541
+ contentHash,
542
+ cutoff,
543
+ );
538
544
 
539
545
  if (existing.length > 0) {
540
546
  return {
@@ -639,15 +645,15 @@ export async function populateEmbeddings(
639
645
  let skipped = 0;
640
646
 
641
647
  // Find observations without embeddings
642
- const rows = nativeDb
643
- .prepare(`
648
+ const rows = typedAll<BrainNarrativeRow>(
649
+ nativeDb.prepare(`
644
650
  SELECT o.id, o.narrative, o.title
645
651
  FROM brain_observations o
646
652
  LEFT JOIN brain_embeddings e ON o.id = e.id
647
653
  WHERE e.id IS NULL AND o.narrative IS NOT NULL
648
654
  ORDER BY o.created_at DESC
649
- `)
650
- .all() as unknown as BrainNarrativeRow[];
655
+ `),
656
+ );
651
657
 
652
658
  for (let i = 0; i < rows.length; i += batchSize) {
653
659
  const batch = rows.slice(i, i + batchSize);
@@ -7,21 +7,21 @@
7
7
  * @task T5800
8
8
  */
9
9
 
10
- /** Row returned by FTS content_hash duplicate check. */
10
+ /** Row returned by FTS content_hash duplicate check (brain-retrieval.ts observeBrain). */
11
11
  export interface BrainFtsRow {
12
12
  id: string;
13
13
  type: string;
14
14
  created_at: string;
15
15
  }
16
16
 
17
- /** Row returned by narrative backfill query (missing embeddings). */
17
+ /** Row returned by narrative backfill query (brain-retrieval.ts populateEmbeddings). */
18
18
  export interface BrainNarrativeRow {
19
19
  id: string;
20
20
  narrative: string;
21
21
  title: string;
22
22
  }
23
23
 
24
- /** Flattened FTS hit used in hybrid search scoring. */
24
+ /** Flattened FTS hit used in hybrid search scoring (brain-search.ts hybridSearch). */
25
25
  export interface BrainSearchHit {
26
26
  id: string;
27
27
  type: string;
@@ -29,22 +29,59 @@ export interface BrainSearchHit {
29
29
  text: string;
30
30
  }
31
31
 
32
- /** Row returned by KNN vector similarity query. */
32
+ /** Row returned by KNN vector similarity query (brain-similarity.ts searchSimilar). */
33
33
  export interface BrainKnnRow {
34
34
  id: string;
35
35
  distance: number;
36
36
  }
37
37
 
38
- /** Decision node attached to a blocker in causal traces. */
38
+ /** Decision node attached to a blocker in causal traces (brain-reasoning.ts reasonWhy). */
39
39
  export interface BrainDecisionNode {
40
40
  id: string;
41
41
  title: string;
42
42
  rationale?: string;
43
43
  }
44
44
 
45
- /** Anchor entry in a timeline result. */
45
+ /** Anchor entry in a timeline result (brain-retrieval.ts timelineBrain). */
46
46
  export interface BrainAnchor {
47
47
  id: string;
48
48
  type: string;
49
49
  data: unknown;
50
50
  }
51
+
52
+ /**
53
+ * Row returned by timeline UNION ALL neighbor queries (brain-retrieval.ts timelineBrain).
54
+ *
55
+ * Represents an entry from any of the four brain tables projected to
56
+ * a common {id, type, date} shape for chronological ordering.
57
+ */
58
+ export interface BrainTimelineNeighborRow {
59
+ id: string;
60
+ type: string;
61
+ date: string;
62
+ }
63
+
64
+ /**
65
+ * Row returned by the consolidation observation query (brain-lifecycle.ts consolidateMemories).
66
+ *
67
+ * Fetches old observations for keyword-based clustering and archival.
68
+ * Uses snake_case column names matching the raw SQLite row shape.
69
+ */
70
+ export interface BrainConsolidationObservationRow {
71
+ id: string;
72
+ type: string;
73
+ title: string;
74
+ narrative: string | null;
75
+ project: string | null;
76
+ created_at: string;
77
+ }
78
+
79
+ /**
80
+ * Row returned by ID existence check queries (claude-mem-migration.ts).
81
+ *
82
+ * Used by `SELECT id FROM brain_observations WHERE id = ?` and similar
83
+ * single-column lookups for idempotent migration dedup.
84
+ */
85
+ export interface BrainIdCheckRow {
86
+ id: string;
87
+ }
@@ -16,6 +16,7 @@ import type {
16
16
  BrainObservationRow,
17
17
  BrainPatternRow,
18
18
  } from '../store/brain-schema.js';
19
+ import { typedAll } from '../store/typed-query.js';
19
20
  import type { BrainSearchHit } from './brain-row-types.js';
20
21
  import type { SimilarityResult } from './brain-similarity.js';
21
22
  import { searchSimilar } from './brain-similarity.js';
@@ -332,16 +333,18 @@ function searchWithFts5(
332
333
 
333
334
  if (tables.includes('decisions')) {
334
335
  try {
335
- const rows = nativeDb
336
- .prepare(`
336
+ const rows = typedAll<BrainDecisionRow>(
337
+ nativeDb.prepare(`
337
338
  SELECT d.*
338
339
  FROM brain_decisions_fts fts
339
340
  JOIN brain_decisions d ON d.rowid = fts.rowid
340
341
  WHERE brain_decisions_fts MATCH ?
341
342
  ORDER BY bm25(brain_decisions_fts)
342
343
  LIMIT ?
343
- `)
344
- .all(safeQuery, limit) as unknown as BrainDecisionRow[];
344
+ `),
345
+ safeQuery,
346
+ limit,
347
+ );
345
348
  result.decisions = rows;
346
349
  } catch {
347
350
  // FTS query failed, fall back to LIKE for this table
@@ -351,16 +354,18 @@ function searchWithFts5(
351
354
 
352
355
  if (tables.includes('patterns')) {
353
356
  try {
354
- const rows = nativeDb
355
- .prepare(`
357
+ const rows = typedAll<BrainPatternRow>(
358
+ nativeDb.prepare(`
356
359
  SELECT p.*
357
360
  FROM brain_patterns_fts fts
358
361
  JOIN brain_patterns p ON p.rowid = fts.rowid
359
362
  WHERE brain_patterns_fts MATCH ?
360
363
  ORDER BY bm25(brain_patterns_fts)
361
364
  LIMIT ?
362
- `)
363
- .all(safeQuery, limit) as unknown as BrainPatternRow[];
365
+ `),
366
+ safeQuery,
367
+ limit,
368
+ );
364
369
  result.patterns = rows;
365
370
  } catch {
366
371
  result.patterns = likeSearchPatterns(nativeDb, query, limit);
@@ -369,16 +374,18 @@ function searchWithFts5(
369
374
 
370
375
  if (tables.includes('learnings')) {
371
376
  try {
372
- const rows = nativeDb
373
- .prepare(`
377
+ const rows = typedAll<BrainLearningRow>(
378
+ nativeDb.prepare(`
374
379
  SELECT l.*
375
380
  FROM brain_learnings_fts fts
376
381
  JOIN brain_learnings l ON l.rowid = fts.rowid
377
382
  WHERE brain_learnings_fts MATCH ?
378
383
  ORDER BY bm25(brain_learnings_fts)
379
384
  LIMIT ?
380
- `)
381
- .all(safeQuery, limit) as unknown as BrainLearningRow[];
385
+ `),
386
+ safeQuery,
387
+ limit,
388
+ );
382
389
  result.learnings = rows;
383
390
  } catch {
384
391
  result.learnings = likeSearchLearnings(nativeDb, query, limit);
@@ -387,16 +394,18 @@ function searchWithFts5(
387
394
 
388
395
  if (tables.includes('observations')) {
389
396
  try {
390
- const rows = nativeDb
391
- .prepare(`
397
+ const rows = typedAll<BrainObservationRow>(
398
+ nativeDb.prepare(`
392
399
  SELECT o.*
393
400
  FROM brain_observations_fts fts
394
401
  JOIN brain_observations o ON o.rowid = fts.rowid
395
402
  WHERE brain_observations_fts MATCH ?
396
403
  ORDER BY bm25(brain_observations_fts)
397
404
  LIMIT ?
398
- `)
399
- .all(safeQuery, limit) as unknown as BrainObservationRow[];
405
+ `),
406
+ safeQuery,
407
+ limit,
408
+ );
400
409
  result.observations = rows;
401
410
  } catch {
402
411
  result.observations = likeSearchObservations(nativeDb, query, limit);
@@ -447,14 +456,17 @@ function likeSearchDecisions(
447
456
  limit: number,
448
457
  ): BrainDecisionRow[] {
449
458
  const likePattern = `%${query}%`;
450
- return nativeDb
451
- .prepare(`
459
+ return typedAll<BrainDecisionRow>(
460
+ nativeDb.prepare(`
452
461
  SELECT * FROM brain_decisions
453
462
  WHERE decision LIKE ? OR rationale LIKE ?
454
463
  ORDER BY created_at DESC
455
464
  LIMIT ?
456
- `)
457
- .all(likePattern, likePattern, limit) as unknown as BrainDecisionRow[];
465
+ `),
466
+ likePattern,
467
+ likePattern,
468
+ limit,
469
+ );
458
470
  }
459
471
 
460
472
  function likeSearchPatterns(
@@ -463,14 +475,17 @@ function likeSearchPatterns(
463
475
  limit: number,
464
476
  ): BrainPatternRow[] {
465
477
  const likePattern = `%${query}%`;
466
- return nativeDb
467
- .prepare(`
478
+ return typedAll<BrainPatternRow>(
479
+ nativeDb.prepare(`
468
480
  SELECT * FROM brain_patterns
469
481
  WHERE pattern LIKE ? OR context LIKE ?
470
482
  ORDER BY frequency DESC
471
483
  LIMIT ?
472
- `)
473
- .all(likePattern, likePattern, limit) as unknown as BrainPatternRow[];
484
+ `),
485
+ likePattern,
486
+ likePattern,
487
+ limit,
488
+ );
474
489
  }
475
490
 
476
491
  function likeSearchLearnings(
@@ -479,14 +494,17 @@ function likeSearchLearnings(
479
494
  limit: number,
480
495
  ): BrainLearningRow[] {
481
496
  const likePattern = `%${query}%`;
482
- return nativeDb
483
- .prepare(`
497
+ return typedAll<BrainLearningRow>(
498
+ nativeDb.prepare(`
484
499
  SELECT * FROM brain_learnings
485
500
  WHERE insight LIKE ? OR source LIKE ?
486
501
  ORDER BY confidence DESC
487
502
  LIMIT ?
488
- `)
489
- .all(likePattern, likePattern, limit) as unknown as BrainLearningRow[];
503
+ `),
504
+ likePattern,
505
+ likePattern,
506
+ limit,
507
+ );
490
508
  }
491
509
 
492
510
  function likeSearchObservations(
@@ -495,14 +513,17 @@ function likeSearchObservations(
495
513
  limit: number,
496
514
  ): BrainObservationRow[] {
497
515
  const likePattern = `%${query}%`;
498
- return nativeDb
499
- .prepare(`
516
+ return typedAll<BrainObservationRow>(
517
+ nativeDb.prepare(`
500
518
  SELECT * FROM brain_observations
501
519
  WHERE title LIKE ? OR narrative LIKE ?
502
520
  ORDER BY created_at DESC
503
521
  LIMIT ?
504
- `)
505
- .all(likePattern, likePattern, limit) as unknown as BrainObservationRow[];
522
+ `),
523
+ likePattern,
524
+ likePattern,
525
+ limit,
526
+ );
506
527
  }
507
528
 
508
529
  /**
@@ -10,6 +10,7 @@
10
10
  */
11
11
 
12
12
  import { getBrainAccessor } from '../store/brain-accessor.js';
13
+ import { typedAll } from '../store/typed-query.js';
13
14
  import { embedText, isEmbeddingAvailable } from './brain-embedding.js';
14
15
  import type { BrainKnnRow } from './brain-row-types.js';
15
16
 
@@ -83,14 +84,14 @@ export async function searchSimilar(
83
84
  // Run KNN query against vec0 table
84
85
  let knnRows: BrainKnnRow[];
85
86
  try {
86
- knnRows = nativeDb
87
- .prepare(
88
- 'SELECT id, distance FROM brain_embeddings WHERE embedding MATCH ? ORDER BY distance LIMIT ?',
89
- )
90
- .all(
91
- new Float32Array(queryVector.buffer, queryVector.byteOffset, queryVector.length),
92
- maxResults,
93
- ) as unknown as BrainKnnRow[];
87
+ const stmt = nativeDb.prepare(
88
+ 'SELECT id, distance FROM brain_embeddings WHERE embedding MATCH ? ORDER BY distance LIMIT ?',
89
+ );
90
+ knnRows = typedAll<BrainKnnRow>(
91
+ stmt,
92
+ new Float32Array(queryVector.buffer, queryVector.byteOffset, queryVector.length),
93
+ maxResults,
94
+ );
94
95
  } catch {
95
96
  // vec0 query failed — table may not exist or extension not loaded
96
97
  return [];
@@ -15,6 +15,7 @@ import type { DatabaseSync as _DatabaseSyncType } from 'node:sqlite';
15
15
  import { getClaudeMemDbPath } from '../paths.js';
16
16
  import type { BRAIN_OBSERVATION_TYPES } from '../store/brain-schema.js';
17
17
  import { getBrainDb, getBrainNativeDb } from '../store/brain-sqlite.js';
18
+ import type { BrainIdCheckRow } from './brain-row-types.js';
18
19
  import { ensureFts5Tables, rebuildFts5Index } from './brain-search.js';
19
20
 
20
21
  /** Type-safe wrapper for StatementSync.all(). */
@@ -204,7 +205,7 @@ export async function migrateClaudeMem(
204
205
  // Check if already imported (idempotent)
205
206
  const existing = nativeDb
206
207
  .prepare('SELECT id FROM brain_observations WHERE id = ?')
207
- .get(obsId) as Record<string, unknown> | undefined;
208
+ .get(obsId) as BrainIdCheckRow | undefined;
208
209
 
209
210
  if (existing) {
210
211
  result.observationsSkipped++;
@@ -254,7 +255,7 @@ export async function migrateClaudeMem(
254
255
  const decId = `CMD-${row.id}`;
255
256
  const existingDec = nativeDb
256
257
  .prepare('SELECT id FROM brain_decisions WHERE id = ?')
257
- .get(decId) as Record<string, unknown> | undefined;
258
+ .get(decId) as BrainIdCheckRow | undefined;
258
259
 
259
260
  if (!existingDec) {
260
261
  nativeDb
@@ -324,7 +325,7 @@ export async function migrateClaudeMem(
324
325
  // Check if already imported
325
326
  const existing = nativeDb
326
327
  .prepare('SELECT id FROM brain_learnings WHERE id = ?')
327
- .get(learnId) as Record<string, unknown> | undefined;
328
+ .get(learnId) as BrainIdCheckRow | undefined;
328
329
 
329
330
  if (existing) {
330
331
  // Don't count as skipped — these are separate from observations