@soleri/core 7.0.0 → 8.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/dist/agency/agency-manager.d.ts +27 -1
  2. package/dist/agency/agency-manager.d.ts.map +1 -1
  3. package/dist/agency/agency-manager.js +180 -9
  4. package/dist/agency/agency-manager.js.map +1 -1
  5. package/dist/agency/default-rules.d.ts +7 -0
  6. package/dist/agency/default-rules.d.ts.map +1 -0
  7. package/dist/agency/default-rules.js +79 -0
  8. package/dist/agency/default-rules.js.map +1 -0
  9. package/dist/agency/types.d.ts +48 -0
  10. package/dist/agency/types.d.ts.map +1 -1
  11. package/dist/brain/brain.d.ts +17 -2
  12. package/dist/brain/brain.d.ts.map +1 -1
  13. package/dist/brain/brain.js +118 -8
  14. package/dist/brain/brain.js.map +1 -1
  15. package/dist/brain/knowledge-synthesizer.d.ts +37 -0
  16. package/dist/brain/knowledge-synthesizer.d.ts.map +1 -0
  17. package/dist/brain/knowledge-synthesizer.js +159 -0
  18. package/dist/brain/knowledge-synthesizer.js.map +1 -0
  19. package/dist/brain/learning-radar.d.ts +96 -0
  20. package/dist/brain/learning-radar.d.ts.map +1 -0
  21. package/dist/brain/learning-radar.js +202 -0
  22. package/dist/brain/learning-radar.js.map +1 -0
  23. package/dist/brain/types.d.ts +15 -0
  24. package/dist/brain/types.d.ts.map +1 -1
  25. package/dist/context/context-engine.d.ts.map +1 -1
  26. package/dist/context/context-engine.js +82 -17
  27. package/dist/context/context-engine.js.map +1 -1
  28. package/dist/context/types.d.ts +5 -0
  29. package/dist/context/types.d.ts.map +1 -1
  30. package/dist/control/intent-router.d.ts +12 -1
  31. package/dist/control/intent-router.d.ts.map +1 -1
  32. package/dist/control/intent-router.js +68 -0
  33. package/dist/control/intent-router.js.map +1 -1
  34. package/dist/control/types.d.ts +17 -0
  35. package/dist/control/types.d.ts.map +1 -1
  36. package/dist/curator/classifier.d.ts +18 -0
  37. package/dist/curator/classifier.d.ts.map +1 -0
  38. package/dist/curator/classifier.js +59 -0
  39. package/dist/curator/classifier.js.map +1 -0
  40. package/dist/curator/quality-gate.d.ts +29 -0
  41. package/dist/curator/quality-gate.d.ts.map +1 -0
  42. package/dist/curator/quality-gate.js +86 -0
  43. package/dist/curator/quality-gate.js.map +1 -0
  44. package/dist/domain-packs/index.d.ts +0 -3
  45. package/dist/domain-packs/index.d.ts.map +1 -1
  46. package/dist/domain-packs/index.js +0 -3
  47. package/dist/domain-packs/index.js.map +1 -1
  48. package/dist/domain-packs/loader.d.ts.map +1 -1
  49. package/dist/domain-packs/loader.js +20 -4
  50. package/dist/domain-packs/loader.js.map +1 -1
  51. package/dist/domain-packs/pack-runtime.d.ts +5 -5
  52. package/dist/domain-packs/pack-runtime.d.ts.map +1 -1
  53. package/dist/domain-packs/pack-runtime.js +2 -2
  54. package/dist/domain-packs/pack-runtime.js.map +1 -1
  55. package/dist/domain-packs/types.d.ts +8 -2
  56. package/dist/domain-packs/types.d.ts.map +1 -1
  57. package/dist/domain-packs/types.js.map +1 -1
  58. package/dist/engine/bin/soleri-engine.js +13 -2
  59. package/dist/engine/bin/soleri-engine.js.map +1 -1
  60. package/dist/engine/index.d.ts +2 -0
  61. package/dist/engine/index.d.ts.map +1 -1
  62. package/dist/engine/index.js +1 -0
  63. package/dist/engine/index.js.map +1 -1
  64. package/dist/engine/module-manifest.d.ts +28 -0
  65. package/dist/engine/module-manifest.d.ts.map +1 -0
  66. package/dist/engine/module-manifest.js +85 -0
  67. package/dist/engine/module-manifest.js.map +1 -0
  68. package/dist/engine/register-engine.d.ts +19 -0
  69. package/dist/engine/register-engine.d.ts.map +1 -1
  70. package/dist/engine/register-engine.js +15 -2
  71. package/dist/engine/register-engine.js.map +1 -1
  72. package/dist/events/event-bus.d.ts +30 -0
  73. package/dist/events/event-bus.d.ts.map +1 -0
  74. package/dist/events/event-bus.js +51 -0
  75. package/dist/events/event-bus.js.map +1 -0
  76. package/dist/flows/chain-runner.d.ts +46 -0
  77. package/dist/flows/chain-runner.d.ts.map +1 -0
  78. package/dist/flows/chain-runner.js +271 -0
  79. package/dist/flows/chain-runner.js.map +1 -0
  80. package/dist/flows/chain-types.d.ts +103 -0
  81. package/dist/flows/chain-types.d.ts.map +1 -0
  82. package/dist/flows/chain-types.js +23 -0
  83. package/dist/flows/chain-types.js.map +1 -0
  84. package/dist/health/doctor-checks.d.ts +15 -0
  85. package/dist/health/doctor-checks.d.ts.map +1 -0
  86. package/dist/health/doctor-checks.js +98 -0
  87. package/dist/health/doctor-checks.js.map +1 -0
  88. package/dist/index.d.ts +0 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +0 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/intake/content-classifier.d.ts.map +1 -1
  93. package/dist/intake/content-classifier.js +0 -2
  94. package/dist/intake/content-classifier.js.map +1 -1
  95. package/dist/intake/text-ingester.d.ts +52 -0
  96. package/dist/intake/text-ingester.d.ts.map +1 -0
  97. package/dist/intake/text-ingester.js +181 -0
  98. package/dist/intake/text-ingester.js.map +1 -0
  99. package/dist/llm/llm-client.d.ts.map +1 -1
  100. package/dist/llm/llm-client.js +45 -5
  101. package/dist/llm/llm-client.js.map +1 -1
  102. package/dist/llm/oauth-discovery.d.ts +18 -0
  103. package/dist/llm/oauth-discovery.d.ts.map +1 -0
  104. package/dist/llm/oauth-discovery.js +130 -0
  105. package/dist/llm/oauth-discovery.js.map +1 -0
  106. package/dist/llm/types.d.ts +4 -2
  107. package/dist/llm/types.d.ts.map +1 -1
  108. package/dist/packs/pack-installer.d.ts +2 -1
  109. package/dist/packs/pack-installer.d.ts.map +1 -1
  110. package/dist/packs/pack-installer.js +10 -1
  111. package/dist/packs/pack-installer.js.map +1 -1
  112. package/dist/persistence/index.d.ts +0 -1
  113. package/dist/persistence/index.d.ts.map +1 -1
  114. package/dist/persistence/index.js +0 -1
  115. package/dist/persistence/index.js.map +1 -1
  116. package/dist/persistence/types.d.ts +2 -6
  117. package/dist/persistence/types.d.ts.map +1 -1
  118. package/dist/planning/evidence-collector.d.ts +41 -0
  119. package/dist/planning/evidence-collector.d.ts.map +1 -0
  120. package/dist/planning/evidence-collector.js +194 -0
  121. package/dist/planning/evidence-collector.js.map +1 -0
  122. package/dist/planning/planner.d.ts +4 -0
  123. package/dist/planning/planner.d.ts.map +1 -1
  124. package/dist/planning/planner.js +11 -0
  125. package/dist/planning/planner.js.map +1 -1
  126. package/dist/plugins/index.d.ts +4 -0
  127. package/dist/plugins/index.d.ts.map +1 -1
  128. package/dist/plugins/index.js +4 -0
  129. package/dist/plugins/index.js.map +1 -1
  130. package/dist/plugins/plugin-registry.d.ts +4 -0
  131. package/dist/plugins/plugin-registry.d.ts.map +1 -1
  132. package/dist/plugins/plugin-registry.js +4 -0
  133. package/dist/plugins/plugin-registry.js.map +1 -1
  134. package/dist/plugins/types.d.ts +32 -27
  135. package/dist/plugins/types.d.ts.map +1 -1
  136. package/dist/plugins/types.js +6 -3
  137. package/dist/plugins/types.js.map +1 -1
  138. package/dist/queue/job-queue.d.ts +92 -0
  139. package/dist/queue/job-queue.d.ts.map +1 -0
  140. package/dist/queue/job-queue.js +180 -0
  141. package/dist/queue/job-queue.js.map +1 -0
  142. package/dist/queue/pipeline-runner.d.ts +62 -0
  143. package/dist/queue/pipeline-runner.d.ts.map +1 -0
  144. package/dist/queue/pipeline-runner.js +126 -0
  145. package/dist/queue/pipeline-runner.js.map +1 -0
  146. package/dist/runtime/admin-setup-ops.d.ts +20 -0
  147. package/dist/runtime/admin-setup-ops.d.ts.map +1 -0
  148. package/dist/runtime/admin-setup-ops.js +583 -0
  149. package/dist/runtime/admin-setup-ops.js.map +1 -0
  150. package/dist/runtime/chain-ops.d.ts +9 -0
  151. package/dist/runtime/chain-ops.d.ts.map +1 -0
  152. package/dist/runtime/chain-ops.js +107 -0
  153. package/dist/runtime/chain-ops.js.map +1 -0
  154. package/dist/runtime/claude-md-helpers.d.ts +56 -0
  155. package/dist/runtime/claude-md-helpers.d.ts.map +1 -0
  156. package/dist/runtime/claude-md-helpers.js +160 -0
  157. package/dist/runtime/claude-md-helpers.js.map +1 -0
  158. package/dist/runtime/curator-extra-ops.d.ts +3 -2
  159. package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
  160. package/dist/runtime/curator-extra-ops.js +81 -3
  161. package/dist/runtime/curator-extra-ops.js.map +1 -1
  162. package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
  163. package/dist/runtime/facades/admin-facade.js +5 -2
  164. package/dist/runtime/facades/admin-facade.js.map +1 -1
  165. package/dist/runtime/facades/agency-facade.d.ts.map +1 -1
  166. package/dist/runtime/facades/agency-facade.js +64 -0
  167. package/dist/runtime/facades/agency-facade.js.map +1 -1
  168. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  169. package/dist/runtime/facades/brain-facade.js +122 -1
  170. package/dist/runtime/facades/brain-facade.js.map +1 -1
  171. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  172. package/dist/runtime/facades/control-facade.js +42 -0
  173. package/dist/runtime/facades/control-facade.js.map +1 -1
  174. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  175. package/dist/runtime/facades/memory-facade.js +20 -2
  176. package/dist/runtime/facades/memory-facade.js.map +1 -1
  177. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  178. package/dist/runtime/facades/plan-facade.js +2 -0
  179. package/dist/runtime/facades/plan-facade.js.map +1 -1
  180. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  181. package/dist/runtime/facades/vault-facade.js +25 -5
  182. package/dist/runtime/facades/vault-facade.js.map +1 -1
  183. package/dist/runtime/intake-ops.d.ts +7 -5
  184. package/dist/runtime/intake-ops.d.ts.map +1 -1
  185. package/dist/runtime/intake-ops.js +98 -5
  186. package/dist/runtime/intake-ops.js.map +1 -1
  187. package/dist/runtime/memory-extra-ops.d.ts +6 -3
  188. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  189. package/dist/runtime/memory-extra-ops.js +292 -4
  190. package/dist/runtime/memory-extra-ops.js.map +1 -1
  191. package/dist/runtime/pack-ops.d.ts +3 -0
  192. package/dist/runtime/pack-ops.d.ts.map +1 -1
  193. package/dist/runtime/pack-ops.js +18 -1
  194. package/dist/runtime/pack-ops.js.map +1 -1
  195. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  196. package/dist/runtime/planning-extra-ops.js +85 -0
  197. package/dist/runtime/planning-extra-ops.js.map +1 -1
  198. package/dist/runtime/playbook-ops.js +1 -1
  199. package/dist/runtime/playbook-ops.js.map +1 -1
  200. package/dist/runtime/plugin-ops.d.ts.map +1 -1
  201. package/dist/runtime/plugin-ops.js +3 -0
  202. package/dist/runtime/plugin-ops.js.map +1 -1
  203. package/dist/runtime/runtime.d.ts.map +1 -1
  204. package/dist/runtime/runtime.js +143 -2
  205. package/dist/runtime/runtime.js.map +1 -1
  206. package/dist/runtime/session-briefing.d.ts +23 -0
  207. package/dist/runtime/session-briefing.d.ts.map +1 -0
  208. package/dist/runtime/session-briefing.js +154 -0
  209. package/dist/runtime/session-briefing.js.map +1 -0
  210. package/dist/runtime/types.d.ts +23 -0
  211. package/dist/runtime/types.d.ts.map +1 -1
  212. package/dist/runtime/vault-linking-ops.d.ts.map +1 -1
  213. package/dist/runtime/vault-linking-ops.js +3 -7
  214. package/dist/runtime/vault-linking-ops.js.map +1 -1
  215. package/dist/vault/vault.d.ts +34 -0
  216. package/dist/vault/vault.d.ts.map +1 -1
  217. package/dist/vault/vault.js +89 -3
  218. package/dist/vault/vault.js.map +1 -1
  219. package/package.json +6 -4
  220. package/src/__tests__/admin-setup-ops.test.ts +355 -0
  221. package/src/__tests__/async-infrastructure.test.ts +307 -0
  222. package/src/__tests__/cognee-client-gaps.test.ts +6 -2
  223. package/src/__tests__/cognee-hybrid-search.test.ts +49 -35
  224. package/src/__tests__/cognee-sync-manager-deep.test.ts +89 -65
  225. package/src/__tests__/curator-extra-ops.test.ts +6 -2
  226. package/src/__tests__/curator-pipeline-e2e.test.ts +545 -0
  227. package/src/__tests__/memory-extra-ops.test.ts +2 -2
  228. package/src/__tests__/module-manifest-drift.test.ts +59 -0
  229. package/src/__tests__/planning-extra-ops.test.ts +2 -2
  230. package/src/__tests__/second-brain-features.test.ts +583 -0
  231. package/src/agency/agency-manager.ts +217 -9
  232. package/src/agency/default-rules.ts +83 -0
  233. package/src/agency/types.ts +61 -0
  234. package/src/brain/brain.ts +110 -8
  235. package/src/brain/knowledge-synthesizer.ts +216 -0
  236. package/src/brain/learning-radar.ts +340 -0
  237. package/src/brain/types.ts +16 -0
  238. package/src/context/context-engine.ts +114 -15
  239. package/src/context/types.ts +5 -0
  240. package/src/control/intent-router.ts +107 -0
  241. package/src/control/types.ts +10 -0
  242. package/src/curator/classifier.ts +86 -0
  243. package/src/curator/quality-gate.ts +127 -0
  244. package/src/domain-packs/index.ts +0 -6
  245. package/src/domain-packs/loader.ts +25 -5
  246. package/src/domain-packs/pack-runtime.ts +6 -6
  247. package/src/domain-packs/types.ts +8 -2
  248. package/src/engine/bin/soleri-engine.ts +18 -2
  249. package/src/engine/index.ts +2 -0
  250. package/src/engine/module-manifest.ts +99 -0
  251. package/src/engine/register-engine.ts +21 -2
  252. package/src/events/event-bus.ts +58 -0
  253. package/src/flows/chain-runner.ts +369 -0
  254. package/src/flows/chain-types.ts +57 -0
  255. package/src/index.ts +0 -1
  256. package/src/intake/content-classifier.ts +0 -2
  257. package/src/intake/text-ingester.ts +234 -0
  258. package/src/llm/llm-client.ts +50 -7
  259. package/src/llm/oauth-discovery.ts +151 -0
  260. package/src/llm/types.ts +4 -2
  261. package/src/packs/pack-installer.ts +16 -1
  262. package/src/persistence/index.ts +0 -1
  263. package/src/persistence/types.ts +2 -6
  264. package/src/planning/evidence-collector.ts +247 -0
  265. package/src/planning/planner.ts +11 -0
  266. package/src/plugins/index.ts +4 -0
  267. package/src/plugins/plugin-registry.ts +6 -1
  268. package/src/plugins/types.ts +10 -5
  269. package/src/queue/job-queue.ts +281 -0
  270. package/src/queue/pipeline-runner.ts +149 -0
  271. package/src/runtime/admin-setup-ops.ts +664 -0
  272. package/src/runtime/chain-ops.ts +121 -0
  273. package/src/runtime/claude-md-helpers.ts +218 -0
  274. package/src/runtime/curator-extra-ops.ts +86 -3
  275. package/src/runtime/facades/admin-facade.ts +5 -2
  276. package/src/runtime/facades/agency-facade.ts +68 -0
  277. package/src/runtime/facades/brain-facade.ts +142 -1
  278. package/src/runtime/facades/control-facade.ts +45 -0
  279. package/src/runtime/facades/memory-facade.ts +20 -2
  280. package/src/runtime/facades/plan-facade.ts +2 -0
  281. package/src/runtime/facades/vault-facade.ts +28 -5
  282. package/src/runtime/intake-ops.ts +107 -5
  283. package/src/runtime/memory-extra-ops.ts +312 -4
  284. package/src/runtime/pack-ops.ts +26 -1
  285. package/src/runtime/planning-extra-ops.ts +94 -0
  286. package/src/runtime/playbook-ops.ts +1 -1
  287. package/src/runtime/plugin-ops.ts +3 -0
  288. package/src/runtime/runtime.ts +138 -2
  289. package/src/runtime/session-briefing.ts +175 -0
  290. package/src/runtime/types.ts +23 -0
  291. package/src/runtime/vault-linking-ops.ts +3 -7
  292. package/src/vault/vault.ts +105 -4
  293. package/src/__tests__/postgres-provider.test.ts +0 -116
  294. package/src/persistence/postgres-provider.ts +0 -310
@@ -19,10 +19,12 @@ import { LoopManager } from '../loop/loop-manager.js';
19
19
  import { IdentityManager } from '../control/identity-manager.js';
20
20
  import { IntentRouter } from '../control/intent-router.js';
21
21
  import { KeyPool, loadKeyPoolConfig } from '../llm/key-pool.js';
22
+ import { discoverAnthropicToken } from '../llm/oauth-discovery.js';
22
23
  import { loadIntelligenceData } from '../intelligence/loader.js';
23
24
  import { LLMClient } from '../llm/llm-client.js';
24
25
  import { CogneeSyncManager } from '../cognee/sync-manager.js';
25
26
  import { IntakePipeline } from '../intake/intake-pipeline.js';
27
+ import { TextIngester } from '../intake/text-ingester.js';
26
28
  import { Telemetry } from '../telemetry/telemetry.js';
27
29
  import { ProjectRegistry } from '../project/project-registry.js';
28
30
  import { TemplateManager } from '../prompts/template-manager.js';
@@ -39,6 +41,14 @@ import { VaultBranching } from '../vault/vault-branching.js';
39
41
  import { ContextEngine } from '../context/context-engine.js';
40
42
  import { AgencyManager } from '../agency/agency-manager.js';
41
43
  import { KnowledgeReview } from '../vault/knowledge-review.js';
44
+ import { LinkManager } from '../vault/linking.js';
45
+ import { LearningRadar } from '../brain/learning-radar.js';
46
+ import { KnowledgeSynthesizer } from '../brain/knowledge-synthesizer.js';
47
+ import { ChainRunner } from '../flows/chain-runner.js';
48
+ import { JobQueue } from '../queue/job-queue.js';
49
+ import { PipelineRunner } from '../queue/pipeline-runner.js';
50
+ import { evaluateQuality } from '../curator/quality-gate.js';
51
+ import { classifyEntry } from '../curator/classifier.js';
42
52
  import type { AgentRuntimeConfig, AgentRuntime } from './types.js';
43
53
 
44
54
  /**
@@ -96,7 +106,8 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
96
106
  }
97
107
 
98
108
  // Brain — intelligence layer (TF-IDF scoring, auto-tagging, dedup)
99
- const brain = new Brain(vault, cognee ?? undefined);
109
+ // Pass vaultManager so intelligentSearch queries all connected sources (not just agent tier)
110
+ const brain = new Brain(vault, cognee ?? undefined, vaultManager);
100
111
 
101
112
  // Brain Intelligence — pattern strengths, session knowledge, intelligence pipeline
102
113
  const brainIntelligence = new BrainIntelligence(vault, brain);
@@ -130,9 +141,15 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
130
141
  }
131
142
 
132
143
  // LLM key pools and client
144
+ // Try OAuth token discovery for Anthropic (Claude Code subscription → free API access)
133
145
  const keyPoolFiles = loadKeyPoolConfig(agentId);
146
+ const oauthToken = discoverAnthropicToken();
147
+ const anthropicConfig = keyPoolFiles.anthropic;
148
+ if (oauthToken && anthropicConfig.keys.length === 0) {
149
+ anthropicConfig.keys.push(oauthToken);
150
+ }
134
151
  const openaiKeyPool = new KeyPool(keyPoolFiles.openai);
135
- const anthropicKeyPool = new KeyPool(keyPoolFiles.anthropic);
152
+ const anthropicKeyPool = new KeyPool(anthropicConfig);
136
153
  const llmClient = new LLMClient(openaiKeyPool, anthropicKeyPool, agentId);
137
154
 
138
155
  // Cognee Sync Manager — queue-based dirty tracking with offline resilience (only when Cognee enabled)
@@ -146,8 +163,13 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
146
163
  vault.setSyncManager(syncManager);
147
164
  }
148
165
 
166
+ // Link Manager — Zettelkasten auto-linking on vault ingestion
167
+ const linkManager = new LinkManager(vault.getProvider());
168
+ vault.setLinkManager(linkManager, { enabled: true, maxLinks: 3 });
169
+
149
170
  // Intake Pipeline — PDF/book ingestion with LLM classification
150
171
  const intakePipeline = new IntakePipeline(vault.getProvider(), vault, llmClient);
172
+ const textIngester = new TextIngester(vault, llmClient);
151
173
 
152
174
  // Playbook Executor — in-memory step-by-step workflow sessions
153
175
  const playbookExecutor = new PlaybookExecutor();
@@ -217,6 +239,7 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
217
239
  templateManager,
218
240
  syncManager,
219
241
  intakePipeline,
242
+ textIngester,
220
243
  authPolicy: { mode: 'permissive', callerLevel: 'admin' },
221
244
  flags: new FeatureFlags(join(agentHome, 'flags.json')),
222
245
  health,
@@ -228,6 +251,119 @@ export function createAgentRuntime(config: AgentRuntimeConfig): AgentRuntime {
228
251
  contextEngine,
229
252
  agencyManager,
230
253
  knowledgeReview,
254
+ linkManager,
255
+ learningRadar: new LearningRadar(vault, brain),
256
+ knowledgeSynthesizer: new KnowledgeSynthesizer(brain, llmClient),
257
+ chainRunner: new ChainRunner(vault.getProvider()),
258
+ jobQueue: new JobQueue(vault.getProvider()),
259
+ pipelineRunner: (() => {
260
+ const jq = new JobQueue(vault.getProvider());
261
+ const pr = new PipelineRunner(jq);
262
+ // Register default job handlers for curator pipeline
263
+ pr.registerHandler('tag-normalize', async (job) => {
264
+ const entry = vault.get(job.entryId ?? '');
265
+ if (!entry) return { skipped: true, reason: 'entry not found' };
266
+ const result = curator.normalizeTag(entry.tags[0] ?? '');
267
+ return result;
268
+ });
269
+ pr.registerHandler('dedup-check', async (job) => {
270
+ const entry = vault.get(job.entryId ?? '');
271
+ if (!entry) return { skipped: true, reason: 'entry not found' };
272
+ return curator.detectDuplicates(entry.id);
273
+ });
274
+ pr.registerHandler('auto-link', async (job) => {
275
+ if (linkManager) {
276
+ const suggestions = linkManager.suggestLinks(job.entryId ?? '', 3);
277
+ for (const s of suggestions) {
278
+ linkManager.addLink(
279
+ job.entryId ?? '',
280
+ s.entryId,
281
+ s.suggestedType,
282
+ `pipeline: ${s.reason}`,
283
+ );
284
+ }
285
+ return { linked: suggestions.length };
286
+ }
287
+ return { skipped: true, reason: 'link manager not available' };
288
+ });
289
+ pr.registerHandler('quality-gate', async (job) => {
290
+ const entry = vault.get(job.entryId ?? '');
291
+ if (!entry) return { skipped: true, reason: 'entry not found' };
292
+ return evaluateQuality(entry, llmClient);
293
+ });
294
+ pr.registerHandler('classify', async (job) => {
295
+ const entry = vault.get(job.entryId ?? '');
296
+ if (!entry) return { skipped: true, reason: 'entry not found' };
297
+ return classifyEntry(entry, llmClient);
298
+ });
299
+
300
+ // ─── 9 additional handlers for full Salvador parity (#216) ────
301
+ pr.registerHandler('enrich-frontmatter', async (job) => {
302
+ const entry = vault.get(job.entryId ?? '');
303
+ if (!entry) return { skipped: true, reason: 'entry not found' };
304
+ return curator.enrichMetadata(entry.id);
305
+ });
306
+ pr.registerHandler('detect-staleness', async (job) => {
307
+ const entry = vault.get(job.entryId ?? '');
308
+ if (!entry) return { skipped: true, reason: 'entry not found' };
309
+ // Check if entry is older than 90 days (using validFrom or fallback to 0)
310
+ const entryTimestamp = (entry.validFrom ?? 0) * 1000 || Date.now();
311
+ const ageMs = Date.now() - entryTimestamp;
312
+ const staleDays = 90;
313
+ const isStale = ageMs > staleDays * 86400000;
314
+ return { stale: isStale, ageDays: Math.floor(ageMs / 86400000), entryId: entry.id };
315
+ });
316
+ pr.registerHandler('detect-duplicate', async (job) => {
317
+ const entry = vault.get(job.entryId ?? '');
318
+ if (!entry) return { skipped: true, reason: 'entry not found' };
319
+ return curator.detectDuplicates(entry.id);
320
+ });
321
+ pr.registerHandler('detect-contradiction', async (job) => {
322
+ const entry = vault.get(job.entryId ?? '');
323
+ if (!entry) return { skipped: true, reason: 'entry not found' };
324
+ const contradictions = curator.detectContradictions(0.4);
325
+ const relevant = contradictions.filter(
326
+ (c) => c.patternId === job.entryId || c.antipatternId === job.entryId,
327
+ );
328
+ return { found: relevant.length, contradictions: relevant };
329
+ });
330
+ pr.registerHandler('consolidate-duplicates', async (_job) => {
331
+ return curator.consolidate({ dryRun: false, staleDaysThreshold: 90 });
332
+ });
333
+ pr.registerHandler('archive-stale', async (_job) => {
334
+ // Run consolidation with stale detection
335
+ const result = curator.consolidate({ dryRun: false, staleDaysThreshold: 90 });
336
+ return { archived: result.staleEntries.length, result };
337
+ });
338
+ pr.registerHandler('cognee-ingest', async (job) => {
339
+ if (!cognee) return { skipped: true, reason: 'cognee not available' };
340
+ const entry = vault.get(job.entryId ?? '');
341
+ if (!entry) return { skipped: true, reason: 'entry not found' };
342
+ try {
343
+ const result = await cognee.addEntries([entry]);
344
+ return { ingested: result.added };
345
+ } catch {
346
+ return { skipped: true, reason: 'cognee ingestion failed' };
347
+ }
348
+ });
349
+ pr.registerHandler('cognee-cognify', async (_job) => {
350
+ if (!cognee) return { skipped: true, reason: 'cognee not available' };
351
+ try {
352
+ const result = await cognee.cognify();
353
+ return result;
354
+ } catch {
355
+ return { skipped: true, reason: 'cognee cognify failed' };
356
+ }
357
+ });
358
+ pr.registerHandler('verify-searchable', async (job) => {
359
+ const entry = vault.get(job.entryId ?? '');
360
+ if (!entry) return { skipped: true, reason: 'entry not found' };
361
+ const searchResults = vault.search(entry.title, { limit: 1 });
362
+ const found = searchResults.some((r) => r.entry.id === entry.id);
363
+ return { searchable: found, entryId: entry.id };
364
+ });
365
+ return pr;
366
+ })(),
231
367
  createdAt: Date.now(),
232
368
  close: () => {
233
369
  syncManager?.close();
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Session Briefing — proactive context loading on session start.
3
+ *
4
+ * Gathers data from all subsystems (sessions, plans, vault, brain, curator)
5
+ * and produces a concise, structured briefing for the agent.
6
+ *
7
+ * Design: gather all data in parallel, skip sections with nothing to report.
8
+ * Target: < 15 lines of output, < 3 seconds latency.
9
+ */
10
+
11
+ import { z } from 'zod';
12
+ import type { OpDefinition } from '../facades/types.js';
13
+ import type { AgentRuntime } from './types.js';
14
+
15
+ export interface BriefingSection {
16
+ label: string;
17
+ content: string;
18
+ }
19
+
20
+ export interface SessionBriefing {
21
+ sections: BriefingSection[];
22
+ generatedAt: number;
23
+ /** Total entries consulted across all data sources. */
24
+ dataPointsConsulted: number;
25
+ }
26
+
27
+ export function createSessionBriefingOps(runtime: AgentRuntime): OpDefinition[] {
28
+ const { brainIntelligence, planner, vault, curator } = runtime;
29
+
30
+ return [
31
+ {
32
+ name: 'session_briefing',
33
+ description:
34
+ 'Proactive session briefing — gathers last session, active plans, recent vault captures, brain recommendations, and stale knowledge warnings into a concise summary.',
35
+ auth: 'read',
36
+ schema: z.object({
37
+ maxSections: z.number().optional().default(6).describe('Max sections to include'),
38
+ recencyHours: z.number().optional().default(48).describe('Look back window in hours'),
39
+ }),
40
+ handler: async (params) => {
41
+ const maxSections = params.maxSections as number;
42
+ const sections: BriefingSection[] = [];
43
+ let dataPoints = 0;
44
+
45
+ // 0. Day-one welcome (vault has few non-playbook entries)
46
+ try {
47
+ const stats = vault.stats();
48
+ const nonPlaybook = stats.totalEntries - (stats.byType?.playbook ?? 0);
49
+ if (nonPlaybook < 10) {
50
+ sections.push({
51
+ label: 'Welcome',
52
+ content: `Vault has ${nonPlaybook} knowledge entries. Capture patterns as you work — the brain learns from every session. Use op:capture_knowledge to persist insights.`,
53
+ });
54
+ }
55
+ } catch {
56
+ // Vault stats unavailable — skip
57
+ }
58
+
59
+ // 1. Last session
60
+ try {
61
+ const sessions = brainIntelligence.listSessions({ limit: 1, active: false });
62
+ dataPoints += sessions.length;
63
+ if (sessions.length > 0) {
64
+ const last = sessions[0];
65
+ const ago = formatTimeAgo(last.endedAt ? new Date(last.endedAt).getTime() : Date.now());
66
+ const domain = last.domain ? ` [${last.domain}]` : '';
67
+ const context = last.context ? `: ${last.context.slice(0, 80)}` : '';
68
+ const tools = last.toolsUsed.length > 0 ? `, used ${last.toolsUsed.length} tools` : '';
69
+ const files =
70
+ last.filesModified.length > 0 ? `, modified ${last.filesModified.length} files` : '';
71
+ sections.push({
72
+ label: 'Last session',
73
+ content: `(${ago})${domain}${context}${tools}${files}`,
74
+ });
75
+ }
76
+ } catch {
77
+ // Session data unavailable — skip
78
+ }
79
+
80
+ // 2. Active plans
81
+ try {
82
+ const plans = planner.list();
83
+ const active = plans.filter(
84
+ (p) =>
85
+ p.status === 'executing' ||
86
+ p.status === 'approved' ||
87
+ p.status === 'reconciling' ||
88
+ p.status === 'validating',
89
+ );
90
+ dataPoints += plans.length;
91
+ if (active.length > 0) {
92
+ const summaries = active.map((p) => {
93
+ const tasksDone = p.tasks.filter((t) => t.status === 'completed').length;
94
+ return `${p.objective?.slice(0, 40) || p.id} (${p.status}, ${tasksDone}/${p.tasks.length} tasks)`;
95
+ });
96
+ sections.push({
97
+ label: active.length === 1 ? 'Active plan' : `Active plans (${active.length})`,
98
+ content: summaries.join('; '),
99
+ });
100
+ }
101
+ } catch {
102
+ // Planner unavailable — skip
103
+ }
104
+
105
+ // 3. Recent vault captures
106
+ try {
107
+ const recent = vault.getRecent(10);
108
+ dataPoints += recent.length;
109
+ if (recent.length > 0) {
110
+ const count = Math.min(recent.length, 5);
111
+ const titles = recent.slice(0, 3).map((e) => e.title.slice(0, 50));
112
+ sections.push({
113
+ label: 'Recent captures',
114
+ content: `${count} entries — ${titles.join(', ')}${count > 3 ? '...' : ''}`,
115
+ });
116
+ }
117
+ } catch {
118
+ // Vault unavailable — skip
119
+ }
120
+
121
+ // 4. Brain recommendations
122
+ try {
123
+ const recs = brainIntelligence.recommend({ limit: 3 });
124
+ dataPoints += recs.length;
125
+ if (recs.length > 0) {
126
+ const items = recs.map((r) => `"${r.pattern}" (strength: ${r.strength.toFixed(2)})`);
127
+ sections.push({
128
+ label: 'Brain recommends',
129
+ content: items.join(', '),
130
+ });
131
+ }
132
+ } catch {
133
+ // Brain unavailable — skip
134
+ }
135
+
136
+ // 5. Stale knowledge / health warnings
137
+ try {
138
+ const health = curator.healthAudit();
139
+ dataPoints += 1;
140
+ const warnings: string[] = [];
141
+ if (health.score < 70) {
142
+ warnings.push(`vault health: ${health.score}/100`);
143
+ }
144
+ if (health.recommendations && health.recommendations.length > 0) {
145
+ warnings.push(health.recommendations[0]);
146
+ }
147
+ if (warnings.length > 0) {
148
+ sections.push({
149
+ label: 'Attention',
150
+ content: warnings.join('. '),
151
+ });
152
+ }
153
+ } catch {
154
+ // Curator unavailable — skip
155
+ }
156
+
157
+ return {
158
+ sections: sections.slice(0, maxSections),
159
+ generatedAt: Date.now(),
160
+ dataPointsConsulted: dataPoints,
161
+ } satisfies SessionBriefing;
162
+ },
163
+ },
164
+ ];
165
+ }
166
+
167
+ function formatTimeAgo(timestamp: number): string {
168
+ const diff = Date.now() - timestamp;
169
+ const minutes = Math.floor(diff / 60000);
170
+ if (minutes < 60) return `${minutes}m ago`;
171
+ const hours = Math.floor(minutes / 60);
172
+ if (hours < 24) return `${hours}h ago`;
173
+ const days = Math.floor(hours / 24);
174
+ return `${days}d ago`;
175
+ }
@@ -28,6 +28,13 @@ import type { VaultBranching } from '../vault/vault-branching.js';
28
28
  import type { ContextEngine } from '../context/context-engine.js';
29
29
  import type { AgencyManager } from '../agency/agency-manager.js';
30
30
  import type { KnowledgeReview } from '../vault/knowledge-review.js';
31
+ import type { LinkManager } from '../vault/linking.js';
32
+ import type { LearningRadar } from '../brain/learning-radar.js';
33
+ import type { TextIngester } from '../intake/text-ingester.js';
34
+ import type { KnowledgeSynthesizer } from '../brain/knowledge-synthesizer.js';
35
+ import type { ChainRunner } from '../flows/chain-runner.js';
36
+ import type { JobQueue } from '../queue/job-queue.js';
37
+ import type { PipelineRunner } from '../queue/pipeline-runner.js';
31
38
 
32
39
  /**
33
40
  * Configuration for creating an agent runtime.
@@ -50,6 +57,8 @@ export interface AgentRuntimeConfig {
50
57
  sharedVaultPath?: string;
51
58
  /** Enable Cognee vector search integration. Default: false (opt-in). */
52
59
  cognee?: boolean;
60
+ /** Path to the agent's root directory (containing agent.yaml, instructions/, etc.). Optional — set by engine binary. */
61
+ agentDir?: string;
53
62
  }
54
63
 
55
64
  /**
@@ -100,6 +109,20 @@ export interface AgentRuntime {
100
109
  agencyManager: AgencyManager;
101
110
  /** Knowledge review — team review workflows (submit/approve/reject). */
102
111
  knowledgeReview: KnowledgeReview;
112
+ /** Link manager — Zettelkasten bidirectional linking with auto-link on ingestion. */
113
+ linkManager: LinkManager;
114
+ /** Learning radar — automatic pattern detection from session signals. */
115
+ learningRadar: LearningRadar;
116
+ /** Text ingester — ingest articles, transcripts, and plain text into vault. */
117
+ textIngester: TextIngester;
118
+ /** Knowledge synthesizer — turn vault knowledge into briefs, outlines, posts. */
119
+ knowledgeSynthesizer: KnowledgeSynthesizer;
120
+ /** Chain runner — composable multi-step workflows with data flow and gates. */
121
+ chainRunner: ChainRunner;
122
+ /** Job queue — SQLite-backed async job processing with DAG dependencies. */
123
+ jobQueue: JobQueue;
124
+ /** Pipeline runner — background polling loop for job execution. */
125
+ pipelineRunner: PipelineRunner;
103
126
  /** Timestamp (ms since epoch) when this runtime was created. */
104
127
  createdAt: number;
105
128
  /** Close the vault database connection. Call on shutdown. */
@@ -11,7 +11,6 @@
11
11
  import { z } from 'zod';
12
12
  import type { OpDefinition } from '../facades/types.js';
13
13
  import type { AgentRuntime } from './types.js';
14
- import { LinkManager } from '../vault/linking.js';
15
14
 
16
15
  const EVAL_SYSTEM_PROMPT = `You evaluate pairs of knowledge entries to determine if they should be linked in a Zettelkasten vault. For EACH pair, decide:
17
16
  - If meaningfully related → return { "link": true, "type": "<type>", "note": "<1 sentence why>" }
@@ -26,8 +25,7 @@ Link types:
26
25
  Rules: Same category alone is NOT enough. Be selective. Return a JSON array.`;
27
26
 
28
27
  export function createVaultLinkingOps(runtime: AgentRuntime): OpDefinition[] {
29
- const { vault } = runtime;
30
- const linkManager = new LinkManager(vault.getProvider());
28
+ const { vault, linkManager } = runtime;
31
29
 
32
30
  return [
33
31
  {
@@ -330,13 +328,11 @@ export function createVaultLinkingOps(runtime: AgentRuntime): OpDefinition[] {
330
328
 
331
329
  try {
332
330
  const result = await llmClient.complete({
333
- provider: llmClient.isAvailable().anthropic ? 'anthropic' : 'openai',
334
- model: llmClient.isAvailable().anthropic ? 'claude-sonnet-4-20250514' : 'gpt-4o-mini',
335
331
  systemPrompt: EVAL_SYSTEM_PROMPT,
336
332
  userPrompt: pairsText,
337
333
  maxTokens: 2000,
338
- caller: 'relink_vault',
339
- task: 'link-evaluation',
334
+ caller: 'vault-linking',
335
+ task: 'evaluate-links',
340
336
  });
341
337
  llmCalls++;
342
338
 
@@ -2,6 +2,7 @@ import type { PersistenceProvider } from '../persistence/types.js';
2
2
  import { SQLitePersistenceProvider } from '../persistence/sqlite-provider.js';
3
3
  import type { IntelligenceEntry } from '../intelligence/types.js';
4
4
  import { computeContentHash } from './content-hash.js';
5
+ import type { LinkManager } from './linking.js';
5
6
 
6
7
  export interface SearchResult {
7
8
  entry: IntelligenceEntry;
@@ -29,6 +30,16 @@ export interface Memory {
29
30
  topics: string[];
30
31
  filesModified: string[];
31
32
  toolsUsed: string[];
33
+ /** What the user was trying to accomplish. */
34
+ intent: string | null;
35
+ /** Key decisions made and their rationale. */
36
+ decisions: string[];
37
+ /** Where things stand at capture time. */
38
+ currentState: string | null;
39
+ /** What should happen next session. */
40
+ nextSteps: string[];
41
+ /** Vault entries that informed this session. */
42
+ vaultEntriesReferenced: string[];
32
43
  createdAt: number;
33
44
  archivedAt: number | null;
34
45
  }
@@ -42,6 +53,10 @@ export class Vault {
42
53
  private provider: PersistenceProvider;
43
54
  private sqliteProvider: SQLitePersistenceProvider | null;
44
55
  private syncManager: import('../cognee/sync-manager.js').CogneeSyncManager | null = null;
56
+ private linkManager: LinkManager | null = null;
57
+ private autoLinkEnabled = true;
58
+ /** Minimum number of FTS5 suggestions to auto-link. Top N are linked. */
59
+ private autoLinkMaxLinks = 3;
45
60
 
46
61
  /**
47
62
  * Create a Vault with a PersistenceProvider or a SQLite path (backward compat).
@@ -61,12 +76,60 @@ export class Vault {
61
76
  providerOrPath instanceof SQLitePersistenceProvider ? providerOrPath : null;
62
77
  }
63
78
  this.initialize();
79
+ this.checkFormatVersion();
80
+ }
81
+
82
+ /**
83
+ * Vault format version — tracks schema changes for migration safety.
84
+ * Increment when schema changes in a way that requires migration.
85
+ *
86
+ * History:
87
+ * 1 — Initial schema (v8.0.0): entries, memories, brain_feedback, FTS5
88
+ */
89
+ static readonly FORMAT_VERSION = 1;
90
+
91
+ private checkFormatVersion(): void {
92
+ const row = this.provider.get<{ user_version: number }>('PRAGMA user_version');
93
+ const current = row?.user_version ?? 0;
94
+
95
+ if (current === 0) {
96
+ // Fresh database — stamp with current version
97
+ this.provider.run(`PRAGMA user_version = ${Vault.FORMAT_VERSION}`);
98
+ } else if (current > Vault.FORMAT_VERSION) {
99
+ throw new Error(
100
+ `Vault format version ${current} is newer than engine supports (${Vault.FORMAT_VERSION}). ` +
101
+ `Upgrade @soleri/core to a compatible version.`,
102
+ );
103
+ }
104
+ // current < FORMAT_VERSION → future: run migration scripts here
64
105
  }
65
106
 
66
107
  setSyncManager(mgr: import('../cognee/sync-manager.js').CogneeSyncManager): void {
67
108
  this.syncManager = mgr;
68
109
  }
69
110
 
111
+ setLinkManager(mgr: LinkManager, opts?: { enabled?: boolean; maxLinks?: number }): void {
112
+ this.linkManager = mgr;
113
+ if (opts?.enabled !== undefined) this.autoLinkEnabled = opts.enabled;
114
+ if (opts?.maxLinks !== undefined) this.autoLinkMaxLinks = opts.maxLinks;
115
+ }
116
+
117
+ /**
118
+ * Auto-link a newly added entry using FTS5 suggestions.
119
+ * Called after seed() for each entry. Creates links for top N suggestions.
120
+ */
121
+ private autoLink(entryId: string): void {
122
+ if (!this.linkManager || !this.autoLinkEnabled) return;
123
+ try {
124
+ const suggestions = this.linkManager.suggestLinks(entryId, this.autoLinkMaxLinks);
125
+ for (const s of suggestions) {
126
+ this.linkManager.addLink(entryId, s.entryId, s.suggestedType, `auto: ${s.reason}`);
127
+ }
128
+ } catch {
129
+ // Auto-linking is best-effort — never block ingestion
130
+ }
131
+ }
132
+
70
133
  /** Backward-compatible factory. */
71
134
  static createWithSQLite(dbPath: string = ':memory:'): Vault {
72
135
  return new Vault(dbPath);
@@ -140,7 +203,23 @@ export class Vault {
140
203
  CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
141
204
  id, context, summary, topics,
142
205
  content='memories', content_rowid='rowid', tokenize='porter unicode61'
143
- );
206
+ );`);
207
+
208
+ // Add new columns if they don't exist (backward-compatible migration)
209
+ const memCols = this.provider
210
+ .all<{ name: string }>(`PRAGMA table_info(memories)`)
211
+ .map((r) => r.name);
212
+ if (!memCols.includes('intent')) {
213
+ this.provider.execSql(`
214
+ ALTER TABLE memories ADD COLUMN intent TEXT;
215
+ ALTER TABLE memories ADD COLUMN decisions TEXT NOT NULL DEFAULT '[]';
216
+ ALTER TABLE memories ADD COLUMN current_state TEXT;
217
+ ALTER TABLE memories ADD COLUMN next_steps TEXT NOT NULL DEFAULT '[]';
218
+ ALTER TABLE memories ADD COLUMN vault_entries_referenced TEXT NOT NULL DEFAULT '[]';
219
+ `);
220
+ }
221
+
222
+ this.provider.execSql(`
144
223
  CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
145
224
  INSERT INTO memories_fts(rowid,id,context,summary,topics) VALUES(new.rowid,new.id,new.context,new.summary,new.topics);
146
225
  END;
@@ -339,6 +418,13 @@ export class Vault {
339
418
  this.syncManager.enqueue('ingest', entry.id, entry);
340
419
  }
341
420
  }
421
+ // Auto-link after all entries are inserted (so they can link to each other).
422
+ // Skip for large batches (>100) — use relink_vault for bulk imports.
423
+ if (entries.length <= 100) {
424
+ for (const entry of entries) {
425
+ this.autoLink(entry.id);
426
+ }
427
+ }
342
428
  return count;
343
429
  });
344
430
  }
@@ -676,7 +762,7 @@ export class Vault {
676
762
  }
677
763
  return {
678
764
  total: rows.length,
679
- buckets: bucketDefs.map((b, i) => ({ ...b, count: counts[i] })),
765
+ buckets: bucketDefs.map((b, i) => Object.assign({}, b, { count: counts[i] })),
680
766
  oldestTimestamp: oldest,
681
767
  newestTimestamp: newest,
682
768
  };
@@ -727,7 +813,8 @@ export class Vault {
727
813
  captureMemory(memory: Omit<Memory, 'id' | 'createdAt' | 'archivedAt'>): Memory {
728
814
  const id = `mem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
729
815
  this.provider.run(
730
- `INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used) VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed)`,
816
+ `INSERT INTO memories (id, project_path, type, context, summary, topics, files_modified, tools_used, intent, decisions, current_state, next_steps, vault_entries_referenced)
817
+ VALUES (@id, @projectPath, @type, @context, @summary, @topics, @filesModified, @toolsUsed, @intent, @decisions, @currentState, @nextSteps, @vaultEntriesReferenced)`,
731
818
  {
732
819
  id,
733
820
  projectPath: memory.projectPath,
@@ -737,6 +824,11 @@ export class Vault {
737
824
  topics: JSON.stringify(memory.topics),
738
825
  filesModified: JSON.stringify(memory.filesModified),
739
826
  toolsUsed: JSON.stringify(memory.toolsUsed),
827
+ intent: memory.intent ?? null,
828
+ decisions: JSON.stringify(memory.decisions ?? []),
829
+ currentState: memory.currentState ?? null,
830
+ nextSteps: JSON.stringify(memory.nextSteps ?? []),
831
+ vaultEntriesReferenced: JSON.stringify(memory.vaultEntriesReferenced ?? []),
740
832
  },
741
833
  );
742
834
  return this.getMemory(id)!;
@@ -744,7 +836,7 @@ export class Vault {
744
836
 
745
837
  searchMemories(
746
838
  query: string,
747
- options?: { type?: string; projectPath?: string; limit?: number },
839
+ options?: { type?: string; projectPath?: string; intent?: string; limit?: number },
748
840
  ): Memory[] {
749
841
  const limit = options?.limit ?? 10;
750
842
  const filters: string[] = ['m.archived_at IS NULL'];
@@ -757,6 +849,10 @@ export class Vault {
757
849
  filters.push('m.project_path = @projectPath');
758
850
  fp.projectPath = options.projectPath;
759
851
  }
852
+ if (options?.intent) {
853
+ filters.push('m.intent = @intent');
854
+ fp.intent = options.intent;
855
+ }
760
856
  const wc = filters.length > 0 ? `AND ${filters.join(' AND ')}` : '';
761
857
  try {
762
858
  const rows = this.provider.all<Record<string, unknown>>(
@@ -1239,6 +1335,11 @@ function rowToMemory(row: Record<string, unknown>): Memory {
1239
1335
  topics: JSON.parse((row.topics as string) || '[]'),
1240
1336
  filesModified: JSON.parse((row.files_modified as string) || '[]'),
1241
1337
  toolsUsed: JSON.parse((row.tools_used as string) || '[]'),
1338
+ intent: (row.intent as string) ?? null,
1339
+ decisions: JSON.parse((row.decisions as string) || '[]'),
1340
+ currentState: (row.current_state as string) ?? null,
1341
+ nextSteps: JSON.parse((row.next_steps as string) || '[]'),
1342
+ vaultEntriesReferenced: JSON.parse((row.vault_entries_referenced as string) || '[]'),
1242
1343
  createdAt: row.created_at as number,
1243
1344
  archivedAt: (row.archived_at as number) ?? null,
1244
1345
  };