@soleri/core 2.12.0 → 8.0.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 (430) hide show
  1. package/data/flows/build.flow.yaml +128 -0
  2. package/data/flows/deliver.flow.yaml +110 -0
  3. package/data/flows/design.flow.yaml +108 -0
  4. package/data/flows/enhance.flow.yaml +90 -0
  5. package/data/flows/explore.flow.yaml +84 -0
  6. package/data/flows/fix.flow.yaml +90 -0
  7. package/data/flows/plan.flow.yaml +87 -0
  8. package/data/flows/review.flow.yaml +90 -0
  9. package/dist/agency/agency-manager.d.ts +27 -1
  10. package/dist/agency/agency-manager.d.ts.map +1 -1
  11. package/dist/agency/agency-manager.js +180 -9
  12. package/dist/agency/agency-manager.js.map +1 -1
  13. package/dist/agency/default-rules.d.ts +7 -0
  14. package/dist/agency/default-rules.d.ts.map +1 -0
  15. package/dist/agency/default-rules.js +79 -0
  16. package/dist/agency/default-rules.js.map +1 -0
  17. package/dist/agency/types.d.ts +48 -0
  18. package/dist/agency/types.d.ts.map +1 -1
  19. package/dist/brain/brain.d.ts +17 -2
  20. package/dist/brain/brain.d.ts.map +1 -1
  21. package/dist/brain/brain.js +118 -8
  22. package/dist/brain/brain.js.map +1 -1
  23. package/dist/brain/intelligence.d.ts.map +1 -1
  24. package/dist/brain/intelligence.js +16 -2
  25. package/dist/brain/intelligence.js.map +1 -1
  26. package/dist/brain/knowledge-synthesizer.d.ts +37 -0
  27. package/dist/brain/knowledge-synthesizer.d.ts.map +1 -0
  28. package/dist/brain/knowledge-synthesizer.js +161 -0
  29. package/dist/brain/knowledge-synthesizer.js.map +1 -0
  30. package/dist/brain/learning-radar.d.ts +96 -0
  31. package/dist/brain/learning-radar.d.ts.map +1 -0
  32. package/dist/brain/learning-radar.js +202 -0
  33. package/dist/brain/learning-radar.js.map +1 -0
  34. package/dist/brain/types.d.ts +15 -0
  35. package/dist/brain/types.d.ts.map +1 -1
  36. package/dist/capabilities/chain-mapping.d.ts +21 -0
  37. package/dist/capabilities/chain-mapping.d.ts.map +1 -0
  38. package/dist/capabilities/chain-mapping.js +86 -0
  39. package/dist/capabilities/chain-mapping.js.map +1 -0
  40. package/dist/capabilities/index.d.ts +10 -0
  41. package/dist/capabilities/index.d.ts.map +1 -0
  42. package/dist/capabilities/index.js +8 -0
  43. package/dist/capabilities/index.js.map +1 -0
  44. package/dist/capabilities/registry.d.ts +95 -0
  45. package/dist/capabilities/registry.d.ts.map +1 -0
  46. package/dist/capabilities/registry.js +227 -0
  47. package/dist/capabilities/registry.js.map +1 -0
  48. package/dist/capabilities/types.d.ts +106 -0
  49. package/dist/capabilities/types.d.ts.map +1 -0
  50. package/dist/capabilities/types.js +12 -0
  51. package/dist/capabilities/types.js.map +1 -0
  52. package/dist/context/context-engine.d.ts.map +1 -1
  53. package/dist/context/context-engine.js +82 -17
  54. package/dist/context/context-engine.js.map +1 -1
  55. package/dist/context/types.d.ts +5 -0
  56. package/dist/context/types.d.ts.map +1 -1
  57. package/dist/control/intent-router.d.ts +12 -1
  58. package/dist/control/intent-router.d.ts.map +1 -1
  59. package/dist/control/intent-router.js +126 -2
  60. package/dist/control/intent-router.js.map +1 -1
  61. package/dist/control/types.d.ts +17 -0
  62. package/dist/control/types.d.ts.map +1 -1
  63. package/dist/curator/classifier.d.ts +18 -0
  64. package/dist/curator/classifier.d.ts.map +1 -0
  65. package/dist/curator/classifier.js +61 -0
  66. package/dist/curator/classifier.js.map +1 -0
  67. package/dist/curator/quality-gate.d.ts +29 -0
  68. package/dist/curator/quality-gate.d.ts.map +1 -0
  69. package/dist/curator/quality-gate.js +88 -0
  70. package/dist/curator/quality-gate.js.map +1 -0
  71. package/dist/domain-packs/index.d.ts +8 -0
  72. package/dist/domain-packs/index.d.ts.map +1 -0
  73. package/dist/domain-packs/index.js +8 -0
  74. package/dist/domain-packs/index.js.map +1 -0
  75. package/dist/domain-packs/inject-rules.d.ts +24 -0
  76. package/dist/domain-packs/inject-rules.d.ts.map +1 -0
  77. package/dist/domain-packs/inject-rules.js +65 -0
  78. package/dist/domain-packs/inject-rules.js.map +1 -0
  79. package/dist/domain-packs/knowledge-installer.d.ts +27 -0
  80. package/dist/domain-packs/knowledge-installer.d.ts.map +1 -0
  81. package/dist/domain-packs/knowledge-installer.js +89 -0
  82. package/dist/domain-packs/knowledge-installer.js.map +1 -0
  83. package/dist/domain-packs/loader.d.ts +28 -0
  84. package/dist/domain-packs/loader.d.ts.map +1 -0
  85. package/dist/domain-packs/loader.js +105 -0
  86. package/dist/domain-packs/loader.js.map +1 -0
  87. package/dist/domain-packs/pack-runtime.d.ts +80 -0
  88. package/dist/domain-packs/pack-runtime.d.ts.map +1 -0
  89. package/dist/domain-packs/pack-runtime.js +36 -0
  90. package/dist/domain-packs/pack-runtime.js.map +1 -0
  91. package/dist/domain-packs/skills-installer.d.ts +21 -0
  92. package/dist/domain-packs/skills-installer.d.ts.map +1 -0
  93. package/dist/domain-packs/skills-installer.js +38 -0
  94. package/dist/domain-packs/skills-installer.js.map +1 -0
  95. package/dist/domain-packs/token-resolver.d.ts +37 -0
  96. package/dist/domain-packs/token-resolver.d.ts.map +1 -0
  97. package/dist/domain-packs/token-resolver.js +109 -0
  98. package/dist/domain-packs/token-resolver.js.map +1 -0
  99. package/dist/domain-packs/types.d.ts +91 -0
  100. package/dist/domain-packs/types.d.ts.map +1 -0
  101. package/dist/domain-packs/types.js +122 -0
  102. package/dist/domain-packs/types.js.map +1 -0
  103. package/dist/engine/bin/soleri-engine.d.ts +12 -0
  104. package/dist/engine/bin/soleri-engine.d.ts.map +1 -0
  105. package/dist/engine/bin/soleri-engine.js +184 -0
  106. package/dist/engine/bin/soleri-engine.js.map +1 -0
  107. package/dist/engine/core-ops.d.ts +27 -0
  108. package/dist/engine/core-ops.d.ts.map +1 -0
  109. package/dist/engine/core-ops.js +159 -0
  110. package/dist/engine/core-ops.js.map +1 -0
  111. package/dist/engine/index.d.ts +19 -0
  112. package/dist/engine/index.d.ts.map +1 -0
  113. package/dist/engine/index.js +17 -0
  114. package/dist/engine/index.js.map +1 -0
  115. package/dist/engine/register-engine.d.ts +54 -0
  116. package/dist/engine/register-engine.d.ts.map +1 -0
  117. package/dist/engine/register-engine.js +270 -0
  118. package/dist/engine/register-engine.js.map +1 -0
  119. package/dist/engine/test-helpers.d.ts +30 -0
  120. package/dist/engine/test-helpers.d.ts.map +1 -0
  121. package/dist/engine/test-helpers.js +59 -0
  122. package/dist/engine/test-helpers.js.map +1 -0
  123. package/dist/events/event-bus.d.ts +30 -0
  124. package/dist/events/event-bus.d.ts.map +1 -0
  125. package/dist/events/event-bus.js +51 -0
  126. package/dist/events/event-bus.js.map +1 -0
  127. package/dist/flows/chain-runner.d.ts +46 -0
  128. package/dist/flows/chain-runner.d.ts.map +1 -0
  129. package/dist/flows/chain-runner.js +271 -0
  130. package/dist/flows/chain-runner.js.map +1 -0
  131. package/dist/flows/chain-types.d.ts +103 -0
  132. package/dist/flows/chain-types.d.ts.map +1 -0
  133. package/dist/flows/chain-types.js +23 -0
  134. package/dist/flows/chain-types.js.map +1 -0
  135. package/dist/flows/context-router.d.ts +39 -0
  136. package/dist/flows/context-router.d.ts.map +1 -0
  137. package/dist/flows/context-router.js +206 -0
  138. package/dist/flows/context-router.js.map +1 -0
  139. package/dist/flows/dispatch-registry.d.ts +24 -0
  140. package/dist/flows/dispatch-registry.d.ts.map +1 -0
  141. package/dist/flows/dispatch-registry.js +70 -0
  142. package/dist/flows/dispatch-registry.js.map +1 -0
  143. package/dist/flows/epilogue.d.ts +24 -0
  144. package/dist/flows/epilogue.d.ts.map +1 -0
  145. package/dist/flows/epilogue.js +52 -0
  146. package/dist/flows/epilogue.js.map +1 -0
  147. package/dist/flows/executor.d.ts +25 -0
  148. package/dist/flows/executor.d.ts.map +1 -0
  149. package/dist/flows/executor.js +153 -0
  150. package/dist/flows/executor.js.map +1 -0
  151. package/dist/flows/gate-evaluator.d.ts +26 -0
  152. package/dist/flows/gate-evaluator.d.ts.map +1 -0
  153. package/dist/flows/gate-evaluator.js +162 -0
  154. package/dist/flows/gate-evaluator.js.map +1 -0
  155. package/dist/flows/index.d.ts +14 -0
  156. package/dist/flows/index.d.ts.map +1 -0
  157. package/dist/flows/index.js +20 -0
  158. package/dist/flows/index.js.map +1 -0
  159. package/dist/flows/loader.d.ts +17 -0
  160. package/dist/flows/loader.d.ts.map +1 -0
  161. package/dist/flows/loader.js +61 -0
  162. package/dist/flows/loader.js.map +1 -0
  163. package/dist/flows/plan-builder.d.ts +40 -0
  164. package/dist/flows/plan-builder.d.ts.map +1 -0
  165. package/dist/flows/plan-builder.js +213 -0
  166. package/dist/flows/plan-builder.js.map +1 -0
  167. package/dist/flows/probes.d.ts +11 -0
  168. package/dist/flows/probes.d.ts.map +1 -0
  169. package/dist/flows/probes.js +62 -0
  170. package/dist/flows/probes.js.map +1 -0
  171. package/dist/flows/types.d.ts +950 -0
  172. package/dist/flows/types.d.ts.map +1 -0
  173. package/dist/flows/types.js +105 -0
  174. package/dist/flows/types.js.map +1 -0
  175. package/dist/health/doctor-checks.d.ts +15 -0
  176. package/dist/health/doctor-checks.d.ts.map +1 -0
  177. package/dist/health/doctor-checks.js +98 -0
  178. package/dist/health/doctor-checks.js.map +1 -0
  179. package/dist/index.d.ts +11 -1
  180. package/dist/index.d.ts.map +1 -1
  181. package/dist/index.js +10 -1
  182. package/dist/index.js.map +1 -1
  183. package/dist/intake/text-ingester.d.ts +52 -0
  184. package/dist/intake/text-ingester.d.ts.map +1 -0
  185. package/dist/intake/text-ingester.js +181 -0
  186. package/dist/intake/text-ingester.js.map +1 -0
  187. package/dist/intelligence/loader.d.ts +19 -0
  188. package/dist/intelligence/loader.d.ts.map +1 -1
  189. package/dist/intelligence/loader.js +35 -0
  190. package/dist/intelligence/loader.js.map +1 -1
  191. package/dist/intelligence/types.d.ts +1 -0
  192. package/dist/intelligence/types.d.ts.map +1 -1
  193. package/dist/llm/llm-client.d.ts.map +1 -1
  194. package/dist/llm/llm-client.js +37 -1
  195. package/dist/llm/llm-client.js.map +1 -1
  196. package/dist/llm/oauth-discovery.d.ts +26 -0
  197. package/dist/llm/oauth-discovery.d.ts.map +1 -0
  198. package/dist/llm/oauth-discovery.js +149 -0
  199. package/dist/llm/oauth-discovery.js.map +1 -0
  200. package/dist/packs/types.d.ts +58 -19
  201. package/dist/packs/types.d.ts.map +1 -1
  202. package/dist/packs/types.js +14 -0
  203. package/dist/packs/types.js.map +1 -1
  204. package/dist/planning/evidence-collector.d.ts +41 -0
  205. package/dist/planning/evidence-collector.d.ts.map +1 -0
  206. package/dist/planning/evidence-collector.js +194 -0
  207. package/dist/planning/evidence-collector.js.map +1 -0
  208. package/dist/planning/planner.d.ts +4 -0
  209. package/dist/planning/planner.d.ts.map +1 -1
  210. package/dist/planning/planner.js +11 -0
  211. package/dist/planning/planner.js.map +1 -1
  212. package/dist/playbooks/generic/onboarding.d.ts +9 -0
  213. package/dist/playbooks/generic/onboarding.d.ts.map +1 -0
  214. package/dist/playbooks/generic/onboarding.js +74 -0
  215. package/dist/playbooks/generic/onboarding.js.map +1 -0
  216. package/dist/playbooks/playbook-registry.d.ts.map +1 -1
  217. package/dist/playbooks/playbook-registry.js +2 -0
  218. package/dist/playbooks/playbook-registry.js.map +1 -1
  219. package/dist/queue/job-queue.d.ts +92 -0
  220. package/dist/queue/job-queue.d.ts.map +1 -0
  221. package/dist/queue/job-queue.js +180 -0
  222. package/dist/queue/job-queue.js.map +1 -0
  223. package/dist/queue/pipeline-runner.d.ts +62 -0
  224. package/dist/queue/pipeline-runner.d.ts.map +1 -0
  225. package/dist/queue/pipeline-runner.js +126 -0
  226. package/dist/queue/pipeline-runner.js.map +1 -0
  227. package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
  228. package/dist/runtime/admin-extra-ops.js +15 -9
  229. package/dist/runtime/admin-extra-ops.js.map +1 -1
  230. package/dist/runtime/admin-ops.js +4 -4
  231. package/dist/runtime/admin-ops.js.map +1 -1
  232. package/dist/runtime/admin-setup-ops.d.ts +20 -0
  233. package/dist/runtime/admin-setup-ops.d.ts.map +1 -0
  234. package/dist/runtime/admin-setup-ops.js +583 -0
  235. package/dist/runtime/admin-setup-ops.js.map +1 -0
  236. package/dist/runtime/capture-ops.d.ts.map +1 -1
  237. package/dist/runtime/capture-ops.js +33 -1
  238. package/dist/runtime/capture-ops.js.map +1 -1
  239. package/dist/runtime/chain-ops.d.ts +9 -0
  240. package/dist/runtime/chain-ops.d.ts.map +1 -0
  241. package/dist/runtime/chain-ops.js +107 -0
  242. package/dist/runtime/chain-ops.js.map +1 -0
  243. package/dist/runtime/claude-md-helpers.d.ts +65 -0
  244. package/dist/runtime/claude-md-helpers.d.ts.map +1 -0
  245. package/dist/runtime/claude-md-helpers.js +173 -0
  246. package/dist/runtime/claude-md-helpers.js.map +1 -0
  247. package/dist/runtime/curator-extra-ops.d.ts +3 -2
  248. package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
  249. package/dist/runtime/curator-extra-ops.js +81 -3
  250. package/dist/runtime/curator-extra-ops.js.map +1 -1
  251. package/dist/runtime/domain-ops.d.ts +21 -5
  252. package/dist/runtime/domain-ops.d.ts.map +1 -1
  253. package/dist/runtime/domain-ops.js +64 -6
  254. package/dist/runtime/domain-ops.js.map +1 -1
  255. package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
  256. package/dist/runtime/facades/admin-facade.js +4 -0
  257. package/dist/runtime/facades/admin-facade.js.map +1 -1
  258. package/dist/runtime/facades/agency-facade.d.ts.map +1 -1
  259. package/dist/runtime/facades/agency-facade.js +64 -0
  260. package/dist/runtime/facades/agency-facade.js.map +1 -1
  261. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  262. package/dist/runtime/facades/brain-facade.js +122 -1
  263. package/dist/runtime/facades/brain-facade.js.map +1 -1
  264. package/dist/runtime/facades/cognee-facade.d.ts.map +1 -1
  265. package/dist/runtime/facades/cognee-facade.js +3 -1
  266. package/dist/runtime/facades/cognee-facade.js.map +1 -1
  267. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  268. package/dist/runtime/facades/control-facade.js +42 -0
  269. package/dist/runtime/facades/control-facade.js.map +1 -1
  270. package/dist/runtime/facades/index.d.ts.map +1 -1
  271. package/dist/runtime/facades/index.js +10 -6
  272. package/dist/runtime/facades/index.js.map +1 -1
  273. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  274. package/dist/runtime/facades/memory-facade.js +20 -2
  275. package/dist/runtime/facades/memory-facade.js.map +1 -1
  276. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  277. package/dist/runtime/facades/plan-facade.js +2 -0
  278. package/dist/runtime/facades/plan-facade.js.map +1 -1
  279. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  280. package/dist/runtime/facades/vault-facade.js +27 -5
  281. package/dist/runtime/facades/vault-facade.js.map +1 -1
  282. package/dist/runtime/intake-ops.d.ts +7 -5
  283. package/dist/runtime/intake-ops.d.ts.map +1 -1
  284. package/dist/runtime/intake-ops.js +98 -5
  285. package/dist/runtime/intake-ops.js.map +1 -1
  286. package/dist/runtime/memory-extra-ops.d.ts +6 -3
  287. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  288. package/dist/runtime/memory-extra-ops.js +292 -4
  289. package/dist/runtime/memory-extra-ops.js.map +1 -1
  290. package/dist/runtime/orchestrate-ops.d.ts +8 -7
  291. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  292. package/dist/runtime/orchestrate-ops.js +217 -61
  293. package/dist/runtime/orchestrate-ops.js.map +1 -1
  294. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  295. package/dist/runtime/planning-extra-ops.js +85 -0
  296. package/dist/runtime/planning-extra-ops.js.map +1 -1
  297. package/dist/runtime/playbook-ops.js +1 -1
  298. package/dist/runtime/playbook-ops.js.map +1 -1
  299. package/dist/runtime/runtime.d.ts.map +1 -1
  300. package/dist/runtime/runtime.js +165 -18
  301. package/dist/runtime/runtime.js.map +1 -1
  302. package/dist/runtime/session-briefing.d.ts +23 -0
  303. package/dist/runtime/session-briefing.d.ts.map +1 -0
  304. package/dist/runtime/session-briefing.js +140 -0
  305. package/dist/runtime/session-briefing.js.map +1 -0
  306. package/dist/runtime/types.d.ts +29 -2
  307. package/dist/runtime/types.d.ts.map +1 -1
  308. package/dist/runtime/vault-linking-ops.d.ts +13 -0
  309. package/dist/runtime/vault-linking-ops.d.ts.map +1 -0
  310. package/dist/runtime/vault-linking-ops.js +365 -0
  311. package/dist/runtime/vault-linking-ops.js.map +1 -0
  312. package/dist/vault/linking.d.ts +46 -0
  313. package/dist/vault/linking.d.ts.map +1 -0
  314. package/dist/vault/linking.js +275 -0
  315. package/dist/vault/linking.js.map +1 -0
  316. package/dist/vault/vault-types.d.ts +37 -0
  317. package/dist/vault/vault-types.d.ts.map +1 -1
  318. package/dist/vault/vault.d.ts +37 -0
  319. package/dist/vault/vault.d.ts.map +1 -1
  320. package/dist/vault/vault.js +152 -9
  321. package/dist/vault/vault.js.map +1 -1
  322. package/package.json +4 -1
  323. package/src/__tests__/admin-extra-ops.test.ts +1 -1
  324. package/src/__tests__/admin-ops.test.ts +2 -1
  325. package/src/__tests__/admin-setup-ops.test.ts +355 -0
  326. package/src/__tests__/async-infrastructure.test.ts +307 -0
  327. package/src/__tests__/cognee-client-gaps.test.ts +474 -0
  328. package/src/__tests__/cognee-hybrid-search.test.ts +492 -0
  329. package/src/__tests__/cognee-sync-manager-deep.test.ts +654 -0
  330. package/src/__tests__/cognee-sync-manager.test.ts +1 -0
  331. package/src/__tests__/core-ops.test.ts +9 -61
  332. package/src/__tests__/curator-extra-ops.test.ts +6 -2
  333. package/src/__tests__/curator-pipeline-e2e.test.ts +358 -0
  334. package/src/__tests__/domain-packs.test.ts +421 -0
  335. package/src/__tests__/flows.test.ts +604 -0
  336. package/src/__tests__/memory-extra-ops.test.ts +2 -2
  337. package/src/__tests__/planning-extra-ops.test.ts +2 -2
  338. package/src/__tests__/playbook-registry.test.ts +2 -2
  339. package/src/__tests__/playbook-seeder.test.ts +8 -8
  340. package/src/__tests__/playbook.test.ts +5 -5
  341. package/src/__tests__/second-brain-features.test.ts +583 -0
  342. package/src/__tests__/token-resolver.test.ts +79 -0
  343. package/src/agency/agency-manager.ts +217 -9
  344. package/src/agency/default-rules.ts +83 -0
  345. package/src/agency/types.ts +61 -0
  346. package/src/brain/brain.ts +110 -8
  347. package/src/brain/intelligence.ts +21 -2
  348. package/src/brain/knowledge-synthesizer.ts +218 -0
  349. package/src/brain/learning-radar.ts +340 -0
  350. package/src/brain/types.ts +16 -0
  351. package/src/capabilities/chain-mapping.ts +93 -0
  352. package/src/capabilities/index.ts +21 -0
  353. package/src/capabilities/registry.ts +290 -0
  354. package/src/capabilities/types.ts +143 -0
  355. package/src/context/context-engine.ts +114 -15
  356. package/src/context/types.ts +5 -0
  357. package/src/control/intent-router.ts +153 -2
  358. package/src/control/types.ts +10 -0
  359. package/src/curator/classifier.ts +88 -0
  360. package/src/curator/quality-gate.ts +129 -0
  361. package/src/domain-packs/index.ts +27 -0
  362. package/src/domain-packs/inject-rules.ts +74 -0
  363. package/src/domain-packs/knowledge-installer.ts +116 -0
  364. package/src/domain-packs/loader.ts +124 -0
  365. package/src/domain-packs/pack-runtime.ts +99 -0
  366. package/src/domain-packs/skills-installer.ts +56 -0
  367. package/src/domain-packs/token-resolver.ts +126 -0
  368. package/src/domain-packs/types.ts +229 -0
  369. package/src/engine/__tests__/register-engine.test.ts +104 -0
  370. package/src/engine/bin/soleri-engine.ts +218 -0
  371. package/src/engine/core-ops.ts +178 -0
  372. package/src/engine/index.ts +19 -0
  373. package/src/engine/register-engine.ts +385 -0
  374. package/src/engine/test-helpers.ts +83 -0
  375. package/src/events/event-bus.ts +58 -0
  376. package/src/flows/chain-runner.ts +369 -0
  377. package/src/flows/chain-types.ts +57 -0
  378. package/src/flows/context-router.ts +257 -0
  379. package/src/flows/dispatch-registry.ts +80 -0
  380. package/src/flows/epilogue.ts +65 -0
  381. package/src/flows/executor.ts +182 -0
  382. package/src/flows/gate-evaluator.ts +171 -0
  383. package/src/flows/index.ts +52 -0
  384. package/src/flows/loader.ts +63 -0
  385. package/src/flows/plan-builder.ts +250 -0
  386. package/src/flows/probes.ts +70 -0
  387. package/src/flows/types.ts +217 -0
  388. package/src/health/doctor-checks.ts +115 -0
  389. package/src/index.ts +68 -1
  390. package/src/intake/text-ingester.ts +234 -0
  391. package/src/intelligence/loader.ts +38 -0
  392. package/src/intelligence/types.ts +1 -0
  393. package/src/llm/llm-client.ts +38 -1
  394. package/src/llm/oauth-discovery.ts +169 -0
  395. package/src/packs/types.ts +19 -0
  396. package/src/planning/evidence-collector.ts +247 -0
  397. package/src/planning/planner.ts +11 -0
  398. package/src/playbooks/generic/onboarding.ts +79 -0
  399. package/src/playbooks/playbook-registry.ts +2 -0
  400. package/src/queue/job-queue.ts +281 -0
  401. package/src/queue/pipeline-runner.ts +149 -0
  402. package/src/runtime/admin-extra-ops.ts +14 -8
  403. package/src/runtime/admin-ops.ts +4 -4
  404. package/src/runtime/admin-setup-ops.ts +664 -0
  405. package/src/runtime/capture-ops.ts +40 -1
  406. package/src/runtime/chain-ops.ts +121 -0
  407. package/src/runtime/claude-md-helpers.ts +236 -0
  408. package/src/runtime/curator-extra-ops.ts +86 -3
  409. package/src/runtime/domain-ops.ts +71 -5
  410. package/src/runtime/facades/admin-facade.ts +4 -0
  411. package/src/runtime/facades/agency-facade.ts +68 -0
  412. package/src/runtime/facades/brain-facade.ts +142 -1
  413. package/src/runtime/facades/cognee-facade.ts +3 -1
  414. package/src/runtime/facades/control-facade.ts +45 -0
  415. package/src/runtime/facades/index.ts +12 -6
  416. package/src/runtime/facades/memory-facade.ts +20 -2
  417. package/src/runtime/facades/plan-facade.ts +2 -0
  418. package/src/runtime/facades/vault-facade.ts +30 -5
  419. package/src/runtime/intake-ops.ts +107 -5
  420. package/src/runtime/memory-extra-ops.ts +312 -4
  421. package/src/runtime/orchestrate-ops.ts +261 -65
  422. package/src/runtime/planning-extra-ops.ts +94 -0
  423. package/src/runtime/playbook-ops.ts +1 -1
  424. package/src/runtime/runtime.ts +164 -19
  425. package/src/runtime/session-briefing.ts +161 -0
  426. package/src/runtime/types.ts +29 -2
  427. package/src/runtime/vault-linking-ops.ts +452 -0
  428. package/src/vault/linking.ts +333 -0
  429. package/src/vault/vault-types.ts +46 -0
  430. package/src/vault/vault.ts +173 -11
@@ -0,0 +1,79 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ resolveToken,
4
+ listProjectTokens,
5
+ buildReverseIndex,
6
+ } from '../domain-packs/token-resolver.js';
7
+ import type { PackProjectContext } from '../domain-packs/pack-runtime.js';
8
+
9
+ const mockProject: PackProjectContext = {
10
+ id: 'test-project',
11
+ name: 'Test Project',
12
+ path: '/test',
13
+ colors: {
14
+ primary: {
15
+ base: '#3B82F6',
16
+ scale: { '50': '#EFF6FF', '100': '#DBEAFE', '500': '#3B82F6', '900': '#1E3A5F' },
17
+ },
18
+ neutral: {
19
+ base: '#6B7280',
20
+ scale: { '50': '#F9FAFB', '100': '#F3F4F6', '500': '#6B7280', '900': '#111827' },
21
+ },
22
+ },
23
+ semanticTokens: {
24
+ 'text-inverse': '#FFFFFF',
25
+ 'bg-surface': '#F9FAFB',
26
+ },
27
+ };
28
+
29
+ describe('resolveToken', () => {
30
+ it('should pass through hex values', () => {
31
+ expect(resolveToken('#FF0000', mockProject)).toBe('#FF0000');
32
+ });
33
+
34
+ it('should resolve named colors', () => {
35
+ expect(resolveToken('white', mockProject)).toBe('#FFFFFF');
36
+ expect(resolveToken('black', mockProject)).toBe('#000000');
37
+ });
38
+
39
+ it('should resolve semantic tokens', () => {
40
+ expect(resolveToken('text-inverse', mockProject)).toBe('#FFFFFF');
41
+ expect(resolveToken('bg-surface', mockProject)).toBe('#F9FAFB');
42
+ });
43
+
44
+ it('should resolve SCALE[SHADE] format', () => {
45
+ expect(resolveToken('PRIMARY[500]', mockProject)).toBe('#3B82F6');
46
+ expect(resolveToken('neutral[900]', mockProject)).toBe('#111827');
47
+ });
48
+
49
+ it('should resolve Tailwind-style tokens', () => {
50
+ expect(resolveToken('bg-primary-500', mockProject)).toBe('#3B82F6');
51
+ expect(resolveToken('text-neutral-900', mockProject)).toBe('#111827');
52
+ });
53
+
54
+ it('should throw for unknown tokens', () => {
55
+ expect(() => resolveToken('unknown-token', mockProject)).toThrow('Cannot resolve');
56
+ });
57
+
58
+ it('should throw for unknown scales', () => {
59
+ expect(() => resolveToken('ACCENT[500]', mockProject)).toThrow('Unknown color scale');
60
+ });
61
+ });
62
+
63
+ describe('listProjectTokens', () => {
64
+ it('should list all scale and semantic tokens', () => {
65
+ const tokens = listProjectTokens(mockProject);
66
+ expect(tokens.length).toBeGreaterThan(0);
67
+ expect(tokens.some((t) => t.token === 'primary-500')).toBe(true);
68
+ expect(tokens.some((t) => t.token === 'text-inverse')).toBe(true);
69
+ expect(tokens.some((t) => t.scale === 'semantic')).toBe(true);
70
+ });
71
+ });
72
+
73
+ describe('buildReverseIndex', () => {
74
+ it('should map hex to token name', () => {
75
+ const index = buildReverseIndex(mockProject);
76
+ expect(index.get('#3B82F6')).toBe('primary-500');
77
+ expect(index.get('#FFFFFF')).toBe('text-inverse');
78
+ });
79
+ });
@@ -15,6 +15,7 @@ import { watch, readFileSync, existsSync } from 'node:fs';
15
15
  import { join, extname } from 'node:path';
16
16
  import type { FSWatcher } from 'node:fs';
17
17
  import type { Vault } from '../vault/vault.js';
18
+ import { DEFAULT_SUGGESTION_RULES } from './default-rules.js';
18
19
  import type {
19
20
  AgencyConfig,
20
21
  AgencyStatus,
@@ -24,6 +25,11 @@ import type {
24
25
  WarningDetector,
25
26
  SurfacedPattern,
26
27
  ClarificationQuestion,
28
+ SuggestionRule,
29
+ SuggestionContext,
30
+ ProactiveSuggestion,
31
+ RichClarificationQuestion,
32
+ Notification,
27
33
  } from './types.js';
28
34
 
29
35
  // ─── Defaults ──────────────────────────────────────────────────────
@@ -57,6 +63,14 @@ export class AgencyManager {
57
63
  private cooldownMap = new Map<string, number>();
58
64
  private debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
59
65
 
66
+ // Proactive intelligence (#211)
67
+ private suggestionRules: SuggestionRule[] = [];
68
+ private recentFiles: FileChange[] = [];
69
+ private suppressedWarningIds = new Set<string>();
70
+ private dismissedPatterns = new Map<string, number>(); // entryId → dismissedAt timestamp
71
+ private dismissalTtlMs = 24 * 60 * 60 * 1000; // 24 hours
72
+ private notificationQueue: Notification[] = [];
73
+
60
74
  constructor(vault: Vault, config?: AgencyConfig) {
61
75
  this.vault = vault;
62
76
  this.config = {
@@ -68,6 +82,11 @@ export class AgencyManager {
68
82
  minPatternConfidence: config?.minPatternConfidence ?? DEFAULT_MIN_CONFIDENCE,
69
83
  cooldownMs: config?.cooldownMs ?? DEFAULT_COOLDOWN_MS,
70
84
  };
85
+
86
+ // Register built-in suggestion rules
87
+ for (const rule of DEFAULT_SUGGESTION_RULES) {
88
+ this.suggestionRules.push(rule);
89
+ }
71
90
  }
72
91
 
73
92
  // ─── Lifecycle ──────────────────────────────────────────────────
@@ -84,15 +103,7 @@ export class AgencyManager {
84
103
  }
85
104
 
86
105
  getStatus(): AgencyStatus {
87
- return {
88
- enabled: this.config.enabled,
89
- watching: this.watchers.length > 0,
90
- watchPaths: this.config.watchPaths,
91
- detectorCount: this.detectors.length,
92
- pendingWarnings: this.pendingWarnings.length,
93
- surfacedPatterns: this.surfacedPatterns.length,
94
- fileChangesProcessed: this.changesProcessed,
95
- };
106
+ return this.getFullStatus();
96
107
  }
97
108
 
98
109
  updateConfig(config: Partial<AgencyConfig>): void {
@@ -323,4 +334,201 @@ export class AgencyManager {
323
334
  const ext = extname(filePath);
324
335
  return this.config.extensions.includes(ext);
325
336
  }
337
+
338
+ // ─── Proactive Suggestions (#211) ──────────────────────────────────
339
+
340
+ registerSuggestionRule(rule: SuggestionRule): void {
341
+ this.suggestionRules.push(rule);
342
+ }
343
+
344
+ /**
345
+ * Evaluate all suggestion rules and return triggered suggestions.
346
+ */
347
+ generateSuggestions(): ProactiveSuggestion[] {
348
+ const context: SuggestionContext = {
349
+ recentFiles: this.recentFiles.slice(-20),
350
+ pendingWarnings: this.pendingWarnings,
351
+ surfacedPatterns: this.surfacedPatterns,
352
+ fileChangesProcessed: this.changesProcessed,
353
+ };
354
+
355
+ const suggestions: ProactiveSuggestion[] = [];
356
+ for (const rule of this.suggestionRules) {
357
+ try {
358
+ if (rule.condition(context)) {
359
+ suggestions.push(rule.generate(context));
360
+ }
361
+ } catch {
362
+ // Rule failure is non-critical
363
+ }
364
+ }
365
+
366
+ // Create notifications for suggestions
367
+ for (const s of suggestions) {
368
+ this.pushNotification('suggestion', s.title, s.description, s.priority);
369
+ }
370
+
371
+ return suggestions.sort((a, b) => {
372
+ const prio = { high: 0, medium: 1, low: 2 };
373
+ return prio[a.priority] - prio[b.priority];
374
+ });
375
+ }
376
+
377
+ // ─── Rich Clarification (#211) ─────────────────────────────────────
378
+
379
+ generateRichClarification(prompt: string): RichClarificationQuestion[] {
380
+ const questions: RichClarificationQuestion[] = [];
381
+
382
+ // Ambiguous scope detection
383
+ const scopeWords = ['everything', 'all', 'the whole', 'entire'];
384
+ if (scopeWords.some((w) => prompt.toLowerCase().includes(w))) {
385
+ questions.push({
386
+ question: 'That sounds like a broad scope. Can you narrow it down?',
387
+ reason: 'Broad requests often lead to unfocused work',
388
+ urgency: 'recommended',
389
+ options: [
390
+ { label: 'Just the current file', description: 'Focus on what I have open' },
391
+ { label: 'This module/directory', description: 'Scope to the current package' },
392
+ {
393
+ label: 'The full project',
394
+ description: 'I really mean everything',
395
+ implications: 'This may take significantly longer',
396
+ },
397
+ ],
398
+ });
399
+ }
400
+
401
+ // Missing context detection
402
+ const vagueVerbs = ['fix', 'improve', 'update', 'change'];
403
+ const hasVagueVerb = vagueVerbs.some((v) => prompt.toLowerCase().startsWith(v));
404
+ const isShort = prompt.split(/\s+/).length < 5;
405
+ if (hasVagueVerb && isShort) {
406
+ questions.push({
407
+ question: 'Could you describe the specific problem or desired outcome?',
408
+ reason: `"${prompt}" is ambiguous — different interpretations lead to different solutions`,
409
+ urgency: 'blocking',
410
+ options: [
411
+ { label: "There's an error/bug", description: 'Something is broken' },
412
+ { label: 'It works but needs improvement', description: 'Refactoring or enhancement' },
413
+ { label: 'Add new behavior', description: 'Feature addition' },
414
+ ],
415
+ });
416
+ }
417
+
418
+ // Destructive operation detection
419
+ const destructiveWords = ['delete', 'remove', 'drop', 'reset', 'wipe', 'purge'];
420
+ if (destructiveWords.some((w) => prompt.toLowerCase().includes(w))) {
421
+ questions.push({
422
+ question: 'This sounds like a destructive operation. Are you sure?',
423
+ reason: 'Destructive actions are hard to undo',
424
+ urgency: 'blocking',
425
+ options: [
426
+ {
427
+ label: 'Yes, proceed',
428
+ description: 'I understand the consequences',
429
+ recommended: false,
430
+ },
431
+ {
432
+ label: 'Let me reconsider',
433
+ description: 'Show me what would be affected first',
434
+ recommended: true,
435
+ },
436
+ ],
437
+ });
438
+ }
439
+
440
+ return questions;
441
+ }
442
+
443
+ // ─── Warning Suppression (#211) ────────────────────────────────────
444
+
445
+ suppressWarning(warningId: string): void {
446
+ this.suppressedWarningIds.add(warningId);
447
+ this.pendingWarnings = this.pendingWarnings.filter((w) => w.id !== warningId);
448
+ }
449
+
450
+ unsuppressWarning(warningId: string): void {
451
+ this.suppressedWarningIds.delete(warningId);
452
+ }
453
+
454
+ getSuppressedWarnings(): string[] {
455
+ return [...this.suppressedWarningIds];
456
+ }
457
+
458
+ /**
459
+ * Override getPendingWarnings to filter out suppressed.
460
+ */
461
+ getFilteredWarnings(): Warning[] {
462
+ return this.pendingWarnings.filter((w) => !this.suppressedWarningIds.has(w.id));
463
+ }
464
+
465
+ // ─── Pattern Dismissal (#211) ──────────────────────────────────────
466
+
467
+ dismissPattern(entryId: string): void {
468
+ this.dismissedPatterns.set(entryId, Date.now());
469
+ this.surfacedPatterns = this.surfacedPatterns.filter((p) => p.entryId !== entryId);
470
+ }
471
+
472
+ isDismissed(entryId: string): boolean {
473
+ const dismissedAt = this.dismissedPatterns.get(entryId);
474
+ if (!dismissedAt) return false;
475
+ if (Date.now() - dismissedAt > this.dismissalTtlMs) {
476
+ this.dismissedPatterns.delete(entryId);
477
+ return false;
478
+ }
479
+ return true;
480
+ }
481
+
482
+ getActiveSurfacedPatterns(): SurfacedPattern[] {
483
+ return this.surfacedPatterns.filter((p) => !this.isDismissed(p.entryId));
484
+ }
485
+
486
+ // ─── Notification Queue (#211) ─────────────────────────────────────
487
+
488
+ pushNotification(
489
+ type: Notification['type'],
490
+ title: string,
491
+ message: string,
492
+ priority: Notification['priority'] = 'medium',
493
+ ): void {
494
+ this.notificationQueue.push({
495
+ id: `notif-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
496
+ type,
497
+ title,
498
+ message,
499
+ priority,
500
+ createdAt: Date.now(),
501
+ });
502
+ }
503
+
504
+ drainNotifications(): Notification[] {
505
+ const notifications = [...this.notificationQueue];
506
+ this.notificationQueue = [];
507
+ return notifications.sort((a, b) => {
508
+ const prio = { high: 0, medium: 1, low: 2 };
509
+ return prio[a.priority] - prio[b.priority];
510
+ });
511
+ }
512
+
513
+ getPendingNotificationCount(): number {
514
+ return this.notificationQueue.length;
515
+ }
516
+
517
+ // ─── Extended Status (#211) ────────────────────────────────────────
518
+
519
+ getFullStatus(): AgencyStatus {
520
+ return {
521
+ enabled: this.config.enabled,
522
+ watching: this.watchers.length > 0,
523
+ watchPaths: this.config.watchPaths,
524
+ detectorCount: this.detectors.length,
525
+ pendingWarnings: this.getFilteredWarnings().length,
526
+ surfacedPatterns: this.getActiveSurfacedPatterns().length,
527
+ fileChangesProcessed: this.changesProcessed,
528
+ suggestionRuleCount: this.suggestionRules.length,
529
+ suppressedWarnings: this.suppressedWarningIds.size,
530
+ dismissedPatterns: this.dismissedPatterns.size,
531
+ pendingNotifications: this.notificationQueue.length,
532
+ };
533
+ }
326
534
  }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Default suggestion rules — 6 built-in rules that work for any agent.
3
+ * Registered on agent startup so agency_suggestions works out of the box.
4
+ */
5
+
6
+ import type { SuggestionRule } from './types.js';
7
+
8
+ export const DEFAULT_SUGGESTION_RULES: SuggestionRule[] = [
9
+ {
10
+ name: 'many-warnings',
11
+ description: 'Fires when 5+ warnings are pending',
12
+ condition: (ctx) => ctx.pendingWarnings.length >= 5,
13
+ generate: (ctx) => ({
14
+ rule: 'many-warnings',
15
+ title: `${ctx.pendingWarnings.length} warnings pending`,
16
+ description: `You have ${ctx.pendingWarnings.length} unresolved warnings — consider running a scan or addressing the critical ones.`,
17
+ priority: 'high',
18
+ action: 'Run agency_warnings to review',
19
+ }),
20
+ },
21
+ {
22
+ name: 'stale-patterns',
23
+ description: 'Fires when surfaced patterns suggest stale knowledge',
24
+ condition: (ctx) => ctx.surfacedPatterns.length === 0 && ctx.fileChangesProcessed > 20,
25
+ generate: () => ({
26
+ rule: 'stale-patterns',
27
+ title: 'Knowledge base maintenance recommended',
28
+ description:
29
+ 'No patterns surfaced despite significant file activity — vault may need grooming or new knowledge.',
30
+ priority: 'medium',
31
+ action: 'Run curator_health_audit',
32
+ }),
33
+ },
34
+ {
35
+ name: 'high-activity-no-capture',
36
+ description: 'Fires when many files changed but no patterns captured',
37
+ condition: (ctx) => ctx.fileChangesProcessed > 50 && ctx.surfacedPatterns.length === 0,
38
+ generate: (ctx) => ({
39
+ rule: 'high-activity-no-capture',
40
+ title: 'Long session without knowledge capture',
41
+ description: `${ctx.fileChangesProcessed} file changes processed — consider capturing what you've learned.`,
42
+ priority: 'medium',
43
+ action: 'Run smart_capture or radar_analyze',
44
+ }),
45
+ },
46
+ {
47
+ name: 'critical-warnings',
48
+ description: 'Fires when critical-severity warnings exist',
49
+ condition: (ctx) => ctx.pendingWarnings.some((w) => w.severity === 'critical'),
50
+ generate: (ctx) => {
51
+ const critical = ctx.pendingWarnings.filter((w) => w.severity === 'critical');
52
+ return {
53
+ rule: 'critical-warnings',
54
+ title: `${critical.length} critical warning(s) need attention`,
55
+ description: critical.map((w) => w.message).join('; '),
56
+ priority: 'high',
57
+ };
58
+ },
59
+ },
60
+ {
61
+ name: 'pattern-surfaced',
62
+ description: 'Fires when relevant vault patterns were found for changed files',
63
+ condition: (ctx) => ctx.surfacedPatterns.length > 0,
64
+ generate: (ctx) => ({
65
+ rule: 'pattern-surfaced',
66
+ title: `${ctx.surfacedPatterns.length} relevant pattern(s) found`,
67
+ description: ctx.surfacedPatterns.map((p) => `${p.title} (${p.domain})`).join(', '),
68
+ priority: 'low',
69
+ }),
70
+ },
71
+ {
72
+ name: 'first-session',
73
+ description: 'Fires on first use when no file changes have been processed',
74
+ condition: (ctx) => ctx.fileChangesProcessed === 0 && ctx.pendingWarnings.length === 0,
75
+ generate: () => ({
76
+ rule: 'first-session',
77
+ title: 'Agency mode ready',
78
+ description:
79
+ 'File watching and proactive suggestions are enabled. Start editing files to see patterns and warnings.',
80
+ priority: 'low',
81
+ }),
82
+ },
83
+ ];
@@ -85,4 +85,65 @@ export interface AgencyStatus {
85
85
  pendingWarnings: number;
86
86
  surfacedPatterns: number;
87
87
  fileChangesProcessed: number;
88
+ suggestionRuleCount: number;
89
+ suppressedWarnings: number;
90
+ dismissedPatterns: number;
91
+ pendingNotifications: number;
92
+ }
93
+
94
+ // ─── Proactive Suggestions (#211) ────────────────────────────────────
95
+
96
+ export interface SuggestionRule {
97
+ /** Unique name for this rule. */
98
+ name: string;
99
+ /** Human description of what this rule detects. */
100
+ description: string;
101
+ /** Condition: returns true if this rule should fire. */
102
+ condition(context: SuggestionContext): boolean;
103
+ /** Generate a suggestion when condition is true. */
104
+ generate(context: SuggestionContext): ProactiveSuggestion;
105
+ }
106
+
107
+ export interface SuggestionContext {
108
+ recentFiles: FileChange[];
109
+ pendingWarnings: Warning[];
110
+ surfacedPatterns: SurfacedPattern[];
111
+ fileChangesProcessed: number;
112
+ }
113
+
114
+ export interface ProactiveSuggestion {
115
+ rule: string;
116
+ title: string;
117
+ description: string;
118
+ priority: 'high' | 'medium' | 'low';
119
+ action?: string;
120
+ }
121
+
122
+ // ─── Rich Clarification (#211) ───────────────────────────────────────
123
+
124
+ export type ClarificationUrgency = 'blocking' | 'recommended' | 'optional';
125
+
126
+ export interface ClarificationOption {
127
+ label: string;
128
+ description?: string;
129
+ implications?: string;
130
+ recommended?: boolean;
131
+ }
132
+
133
+ export interface RichClarificationQuestion {
134
+ question: string;
135
+ reason: string;
136
+ urgency: ClarificationUrgency;
137
+ options?: ClarificationOption[];
138
+ }
139
+
140
+ // ─── Notifications (#211) ────────────────────────────────────────────
141
+
142
+ export interface Notification {
143
+ id: string;
144
+ type: 'suggestion' | 'warning' | 'pattern';
145
+ title: string;
146
+ message: string;
147
+ priority: 'high' | 'medium' | 'low';
148
+ createdAt: number;
88
149
  }
@@ -1,5 +1,6 @@
1
1
  import type { Vault } from '../vault/vault.js';
2
2
  import type { SearchResult } from '../vault/vault.js';
3
+ import type { VaultManager } from '../vault/vault-manager.js';
3
4
  import type { IntelligenceEntry } from '../intelligence/types.js';
4
5
  import { computeContentHash } from '../vault/content-hash.js';
5
6
  import {
@@ -14,6 +15,7 @@ import type {
14
15
  ScoringWeights,
15
16
  ScoreBreakdown,
16
17
  RankedResult,
18
+ ScanResult,
17
19
  SearchOptions,
18
20
  CaptureResult,
19
21
  BrainStats,
@@ -59,12 +61,14 @@ const RECENCY_HALF_LIFE_DAYS = 365;
59
61
 
60
62
  export class Brain {
61
63
  private vault: Vault;
64
+ private vaultManager: VaultManager | undefined;
62
65
  private cognee: CogneeClient | undefined;
63
66
  private vocabulary: Map<string, number> = new Map();
64
67
  private weights: ScoringWeights = { ...DEFAULT_WEIGHTS };
65
68
 
66
- constructor(vault: Vault, cognee?: CogneeClient) {
69
+ constructor(vault: Vault, cognee?: CogneeClient, vaultManager?: VaultManager) {
67
70
  this.vault = vault;
71
+ this.vaultManager = vaultManager;
68
72
  this.cognee = cognee;
69
73
  this.rebuildVocabulary();
70
74
  this.recomputeWeights();
@@ -72,12 +76,31 @@ export class Brain {
72
76
 
73
77
  async intelligentSearch(query: string, options?: SearchOptions): Promise<RankedResult[]> {
74
78
  const limit = options?.limit ?? 10;
75
- const rawResults = this.vault.search(query, {
76
- domain: options?.domain,
77
- type: options?.type,
78
- severity: options?.severity,
79
- limit: Math.max(limit * 3, 30),
80
- });
79
+ const fetchLimit = Math.max(limit * 3, 30);
80
+
81
+ // Use VaultManager when available to search across all connected sources
82
+ // (agent tier + shared vault + dynamically connected external vaults).
83
+ // Falls back to single vault search when no manager is present.
84
+ let rawResults: SearchResult[];
85
+ if (this.vaultManager) {
86
+ rawResults = this.vaultManager.search(query, fetchLimit);
87
+ // Apply domain/type/severity filters that VaultManager.search() doesn't support
88
+ if (options?.domain || options?.type || options?.severity) {
89
+ rawResults = rawResults.filter((r) => {
90
+ if (options.domain && r.entry.domain !== options.domain) return false;
91
+ if (options.type && r.entry.type !== options.type) return false;
92
+ if (options.severity && r.entry.severity !== options.severity) return false;
93
+ return true;
94
+ });
95
+ }
96
+ } else {
97
+ rawResults = this.vault.search(query, {
98
+ domain: options?.domain,
99
+ type: options?.type,
100
+ severity: options?.severity,
101
+ limit: fetchLimit,
102
+ });
103
+ }
81
104
 
82
105
  // Cognee vector search (parallel, with timeout fallback)
83
106
  let cogneeScoreMap: Map<string, number> = new Map();
@@ -212,6 +235,49 @@ export class Brain {
212
235
  return ranked.slice(0, limit);
213
236
  }
214
237
 
238
+ /**
239
+ * Two-pass retrieval — Pass 1: Scan.
240
+ * Returns lightweight results (title, score, snippet) without full entry bodies.
241
+ * Use `loadEntries()` for Pass 2 to fetch full content for selected entries.
242
+ */
243
+ async scanSearch(query: string, options?: Omit<SearchOptions, 'mode'>): Promise<ScanResult[]> {
244
+ const fullResults = await this.intelligentSearch(query, { ...options, mode: 'full' });
245
+ return fullResults.map((r) => ({
246
+ id: r.entry.id,
247
+ title: r.entry.title,
248
+ score: r.score,
249
+ type: r.entry.type,
250
+ domain: r.entry.domain,
251
+ severity: r.entry.severity,
252
+ tags: r.entry.tags,
253
+ snippet: r.entry.description.slice(0, 120) + (r.entry.description.length > 120 ? '...' : ''),
254
+ tokenEstimate: this.estimateTokens(r.entry),
255
+ }));
256
+ }
257
+
258
+ /**
259
+ * Two-pass retrieval — Pass 2: Load.
260
+ * Returns full entries for specific IDs (from a previous scan).
261
+ */
262
+ loadEntries(ids: string[]): IntelligenceEntry[] {
263
+ const results: IntelligenceEntry[] = [];
264
+ for (const id of ids) {
265
+ const entry = this.vault.get(id);
266
+ if (entry) results.push(entry);
267
+ }
268
+ return results;
269
+ }
270
+
271
+ /** Rough token estimate for an entry (chars / 4). */
272
+ private estimateTokens(entry: IntelligenceEntry): number {
273
+ let chars = entry.title.length + entry.description.length;
274
+ if (entry.context) chars += entry.context.length;
275
+ if (entry.example) chars += entry.example.length;
276
+ if (entry.counterExample) chars += entry.counterExample.length;
277
+ if (entry.why) chars += entry.why.length;
278
+ return Math.ceil(chars / 4);
279
+ }
280
+
215
281
  enrichAndCapture(
216
282
  entry: Partial<IntelligenceEntry> & {
217
283
  id: string;
@@ -426,7 +492,43 @@ export class Brain {
426
492
  }
427
493
 
428
494
  rebuildVocabulary(): void {
429
- const entries = this.vault.list({ limit: 100000 });
495
+ // Collect entries from all connected sources when VaultManager is available
496
+ let entries: IntelligenceEntry[];
497
+ if (this.vaultManager) {
498
+ const seen = new Set<string>();
499
+ entries = [];
500
+ // Gather entries from all tier vaults and connected sources via manager
501
+ for (const tierInfo of this.vaultManager.listTiers()) {
502
+ if (!tierInfo.connected) continue;
503
+ try {
504
+ const tierVault = this.vaultManager.getTier(tierInfo.tier);
505
+ for (const e of tierVault.list({ limit: 100000 })) {
506
+ if (!seen.has(e.id)) {
507
+ seen.add(e.id);
508
+ entries.push(e);
509
+ }
510
+ }
511
+ } catch {
512
+ /* tier not connected */
513
+ }
514
+ }
515
+ for (const { name } of this.vaultManager.listConnected()) {
516
+ const cv = this.vaultManager.getConnected(name);
517
+ if (!cv) continue;
518
+ try {
519
+ for (const e of cv.vault.list({ limit: 100000 })) {
520
+ if (!seen.has(e.id)) {
521
+ seen.add(e.id);
522
+ entries.push(e);
523
+ }
524
+ }
525
+ } catch {
526
+ /* source not accessible */
527
+ }
528
+ }
529
+ } else {
530
+ entries = this.vault.list({ limit: 100000 });
531
+ }
430
532
  const docCount = entries.length;
431
533
  if (docCount === 0) {
432
534
  this.vocabulary.clear();
@@ -497,12 +497,31 @@ export class BrainIntelligence {
497
497
  limit?: number;
498
498
  }): PatternStrength[] {
499
499
  const limit = context.limit ?? 5;
500
- const strengths = this.getStrengths({
500
+
501
+ // Try domain-filtered first, fall back to all domains if too few results
502
+ let strengths = this.getStrengths({
501
503
  domain: context.domain,
502
- minStrength: 30,
504
+ minStrength: 20, // lowered from 30 — small corpus needs lower threshold
503
505
  limit: limit * 3,
504
506
  });
505
507
 
508
+ // If domain-filtered returns too few, try without domain filter
509
+ // This handles cases where domain was stored as 'unknown' due to
510
+ // vault.get() returning null during computeStrengths
511
+ if (strengths.length < limit && context.domain) {
512
+ const allStrengths = this.getStrengths({
513
+ minStrength: 20,
514
+ limit: limit * 5,
515
+ });
516
+ // Include domain-matching AND entries where domain lookup failed
517
+ const additional = allStrengths.filter(
518
+ (s) =>
519
+ !strengths.some((existing) => existing.pattern === s.pattern) &&
520
+ (s.domain === context.domain || s.domain === 'unknown'),
521
+ );
522
+ strengths = [...strengths, ...additional];
523
+ }
524
+
506
525
  // If task context provided, boost patterns with matching terms
507
526
  if (context.task) {
508
527
  const taskTerms = new Set(context.task.toLowerCase().split(/\W+/).filter(Boolean));