@soleri/core 9.0.4 → 9.3.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 (744) hide show
  1. package/data/flows/build.flow.yaml +8 -9
  2. package/data/flows/deliver.flow.yaml +9 -10
  3. package/data/flows/design.flow.yaml +3 -4
  4. package/data/flows/enhance.flow.yaml +5 -6
  5. package/data/flows/explore.flow.yaml +3 -4
  6. package/data/flows/fix.flow.yaml +5 -6
  7. package/data/flows/plan.flow.yaml +4 -5
  8. package/data/flows/review.flow.yaml +3 -4
  9. package/dist/brain/intelligence.d.ts +27 -0
  10. package/dist/brain/intelligence.d.ts.map +1 -1
  11. package/dist/brain/intelligence.js +160 -14
  12. package/dist/brain/intelligence.js.map +1 -1
  13. package/dist/brain/learning-radar.d.ts +4 -0
  14. package/dist/brain/learning-radar.d.ts.map +1 -1
  15. package/dist/brain/learning-radar.js +20 -1
  16. package/dist/brain/learning-radar.js.map +1 -1
  17. package/dist/brain/strength-scorer.d.ts +31 -0
  18. package/dist/brain/strength-scorer.d.ts.map +1 -0
  19. package/dist/brain/strength-scorer.js +264 -0
  20. package/dist/brain/strength-scorer.js.map +1 -0
  21. package/dist/chat/agent-loop.d.ts.map +1 -1
  22. package/dist/chat/agent-loop.js +2 -0
  23. package/dist/chat/agent-loop.js.map +1 -1
  24. package/dist/chat/notifications.d.ts.map +1 -1
  25. package/dist/chat/notifications.js +2 -0
  26. package/dist/chat/notifications.js.map +1 -1
  27. package/dist/claudemd/compose.js +1 -1
  28. package/dist/claudemd/compose.js.map +1 -1
  29. package/dist/control/intent-router.d.ts.map +1 -1
  30. package/dist/control/intent-router.js +12 -4
  31. package/dist/control/intent-router.js.map +1 -1
  32. package/dist/curator/contradiction-detector.d.ts +27 -0
  33. package/dist/curator/contradiction-detector.d.ts.map +1 -0
  34. package/dist/curator/contradiction-detector.js +62 -0
  35. package/dist/curator/contradiction-detector.js.map +1 -0
  36. package/dist/curator/curator.d.ts +3 -4
  37. package/dist/curator/curator.d.ts.map +1 -1
  38. package/dist/curator/curator.js +94 -453
  39. package/dist/curator/curator.js.map +1 -1
  40. package/dist/curator/duplicate-detector.d.ts +14 -0
  41. package/dist/curator/duplicate-detector.d.ts.map +1 -0
  42. package/dist/curator/duplicate-detector.js +77 -0
  43. package/dist/curator/duplicate-detector.js.map +1 -0
  44. package/dist/curator/health-audit.d.ts +15 -0
  45. package/dist/curator/health-audit.d.ts.map +1 -0
  46. package/dist/curator/health-audit.js +97 -0
  47. package/dist/curator/health-audit.js.map +1 -0
  48. package/dist/curator/metadata-enricher.d.ts +17 -0
  49. package/dist/curator/metadata-enricher.d.ts.map +1 -0
  50. package/dist/curator/metadata-enricher.js +60 -0
  51. package/dist/curator/metadata-enricher.js.map +1 -0
  52. package/dist/curator/schema.d.ts +7 -0
  53. package/dist/curator/schema.d.ts.map +1 -0
  54. package/dist/curator/schema.js +62 -0
  55. package/dist/curator/schema.js.map +1 -0
  56. package/dist/curator/tag-manager.d.ts +36 -0
  57. package/dist/curator/tag-manager.d.ts.map +1 -0
  58. package/dist/curator/tag-manager.js +78 -0
  59. package/dist/curator/tag-manager.js.map +1 -0
  60. package/dist/engine/bin/soleri-engine.js +24 -3
  61. package/dist/engine/bin/soleri-engine.js.map +1 -1
  62. package/dist/engine/core-ops.d.ts.map +1 -1
  63. package/dist/engine/core-ops.js +23 -8
  64. package/dist/engine/core-ops.js.map +1 -1
  65. package/dist/engine/module-manifest.d.ts.map +1 -1
  66. package/dist/engine/module-manifest.js +42 -2
  67. package/dist/engine/module-manifest.js.map +1 -1
  68. package/dist/engine/register-engine.d.ts.map +1 -1
  69. package/dist/engine/register-engine.js +50 -2
  70. package/dist/engine/register-engine.js.map +1 -1
  71. package/dist/errors/retry.d.ts.map +1 -1
  72. package/dist/errors/retry.js +2 -0
  73. package/dist/errors/retry.js.map +1 -1
  74. package/dist/facades/types.d.ts +1 -1
  75. package/dist/flows/chain-types.d.ts +18 -18
  76. package/dist/flows/gate-evaluator.d.ts.map +1 -1
  77. package/dist/flows/gate-evaluator.js +22 -0
  78. package/dist/flows/gate-evaluator.js.map +1 -1
  79. package/dist/flows/types.d.ts +157 -28
  80. package/dist/flows/types.d.ts.map +1 -1
  81. package/dist/flows/types.js +4 -0
  82. package/dist/flows/types.js.map +1 -1
  83. package/dist/index.d.ts +10 -2
  84. package/dist/index.d.ts.map +1 -1
  85. package/dist/index.js +9 -1
  86. package/dist/index.js.map +1 -1
  87. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  88. package/dist/intake/intake-pipeline.js +1 -0
  89. package/dist/intake/intake-pipeline.js.map +1 -1
  90. package/dist/intake/text-ingester.d.ts.map +1 -1
  91. package/dist/intake/text-ingester.js +2 -0
  92. package/dist/intake/text-ingester.js.map +1 -1
  93. package/dist/llm/key-pool.d.ts +1 -1
  94. package/dist/llm/key-pool.d.ts.map +1 -1
  95. package/dist/llm/key-pool.js +3 -4
  96. package/dist/llm/key-pool.js.map +1 -1
  97. package/dist/llm/utils.d.ts.map +1 -1
  98. package/dist/llm/utils.js +2 -0
  99. package/dist/llm/utils.js.map +1 -1
  100. package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
  101. package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
  102. package/dist/migrations/migration-runner.test-helpers.js +47 -0
  103. package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
  104. package/dist/operator/operator-profile.d.ts +44 -0
  105. package/dist/operator/operator-profile.d.ts.map +1 -0
  106. package/dist/operator/operator-profile.js +383 -0
  107. package/dist/operator/operator-profile.js.map +1 -0
  108. package/dist/operator/operator-signals.d.ts +45 -0
  109. package/dist/operator/operator-signals.d.ts.map +1 -0
  110. package/dist/operator/operator-signals.js +228 -0
  111. package/dist/operator/operator-signals.js.map +1 -0
  112. package/dist/operator/operator-types.d.ts +360 -0
  113. package/dist/operator/operator-types.d.ts.map +1 -0
  114. package/dist/operator/operator-types.js +24 -0
  115. package/dist/operator/operator-types.js.map +1 -0
  116. package/dist/packs/types.d.ts +27 -27
  117. package/dist/paths.d.ts +40 -0
  118. package/dist/paths.d.ts.map +1 -0
  119. package/dist/paths.js +98 -0
  120. package/dist/paths.js.map +1 -0
  121. package/dist/persistence/index.d.ts +1 -1
  122. package/dist/persistence/index.d.ts.map +1 -1
  123. package/dist/persistence/index.js +1 -1
  124. package/dist/persistence/index.js.map +1 -1
  125. package/dist/persistence/sqlite-provider.d.ts +2 -0
  126. package/dist/persistence/sqlite-provider.d.ts.map +1 -1
  127. package/dist/persistence/sqlite-provider.js +8 -5
  128. package/dist/persistence/sqlite-provider.js.map +1 -1
  129. package/dist/planning/evidence-collector.d.ts +13 -1
  130. package/dist/planning/evidence-collector.d.ts.map +1 -1
  131. package/dist/planning/evidence-collector.js +33 -0
  132. package/dist/planning/evidence-collector.js.map +1 -1
  133. package/dist/planning/gap-analysis.d.ts +5 -4
  134. package/dist/planning/gap-analysis.d.ts.map +1 -1
  135. package/dist/planning/gap-analysis.js +7 -341
  136. package/dist/planning/gap-analysis.js.map +1 -1
  137. package/dist/planning/gap-passes.d.ts +19 -0
  138. package/dist/planning/gap-passes.d.ts.map +1 -0
  139. package/dist/planning/gap-passes.js +174 -0
  140. package/dist/planning/gap-passes.js.map +1 -0
  141. package/dist/planning/gap-patterns.d.ts +29 -0
  142. package/dist/planning/gap-patterns.d.ts.map +1 -0
  143. package/dist/planning/gap-patterns.js +175 -0
  144. package/dist/planning/gap-patterns.js.map +1 -0
  145. package/dist/planning/gap-types.d.ts +1 -1
  146. package/dist/planning/gap-types.d.ts.map +1 -1
  147. package/dist/planning/gap-types.js +1 -0
  148. package/dist/planning/gap-types.js.map +1 -1
  149. package/dist/planning/github-projection.d.ts +122 -0
  150. package/dist/planning/github-projection.d.ts.map +1 -0
  151. package/dist/planning/github-projection.js +313 -0
  152. package/dist/planning/github-projection.js.map +1 -0
  153. package/dist/planning/impact-analyzer.d.ts +26 -0
  154. package/dist/planning/impact-analyzer.d.ts.map +1 -0
  155. package/dist/planning/impact-analyzer.js +201 -0
  156. package/dist/planning/impact-analyzer.js.map +1 -0
  157. package/dist/planning/plan-lifecycle.d.ts +136 -0
  158. package/dist/planning/plan-lifecycle.d.ts.map +1 -0
  159. package/dist/planning/plan-lifecycle.js +309 -0
  160. package/dist/planning/plan-lifecycle.js.map +1 -0
  161. package/dist/planning/planner-types.d.ts +202 -0
  162. package/dist/planning/planner-types.d.ts.map +1 -0
  163. package/dist/planning/planner-types.js +6 -0
  164. package/dist/planning/planner-types.js.map +1 -0
  165. package/dist/planning/planner.d.ts +31 -383
  166. package/dist/planning/planner.d.ts.map +1 -1
  167. package/dist/planning/planner.js +151 -832
  168. package/dist/planning/planner.js.map +1 -1
  169. package/dist/planning/rationalization-detector.d.ts +32 -0
  170. package/dist/planning/rationalization-detector.d.ts.map +1 -0
  171. package/dist/planning/rationalization-detector.js +89 -0
  172. package/dist/planning/rationalization-detector.js.map +1 -0
  173. package/dist/planning/reconciliation-engine.d.ts +47 -0
  174. package/dist/planning/reconciliation-engine.d.ts.map +1 -0
  175. package/dist/planning/reconciliation-engine.js +128 -0
  176. package/dist/planning/reconciliation-engine.js.map +1 -0
  177. package/dist/planning/task-verifier.d.ts +85 -0
  178. package/dist/planning/task-verifier.d.ts.map +1 -0
  179. package/dist/planning/task-verifier.js +235 -0
  180. package/dist/planning/task-verifier.js.map +1 -0
  181. package/dist/plugins/types.d.ts +4 -4
  182. package/dist/runtime/admin-ops.d.ts +2 -2
  183. package/dist/runtime/admin-ops.d.ts.map +1 -1
  184. package/dist/runtime/admin-ops.js +44 -17
  185. package/dist/runtime/admin-ops.js.map +1 -1
  186. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  187. package/dist/runtime/admin-setup-ops.js +22 -46
  188. package/dist/runtime/admin-setup-ops.js.map +1 -1
  189. package/dist/runtime/archive-ops.d.ts +10 -0
  190. package/dist/runtime/archive-ops.d.ts.map +1 -0
  191. package/dist/runtime/archive-ops.js +310 -0
  192. package/dist/runtime/archive-ops.js.map +1 -0
  193. package/dist/runtime/branching-ops.d.ts +12 -0
  194. package/dist/runtime/branching-ops.d.ts.map +1 -0
  195. package/dist/runtime/branching-ops.js +100 -0
  196. package/dist/runtime/branching-ops.js.map +1 -0
  197. package/dist/runtime/capture-ops.d.ts.map +1 -1
  198. package/dist/runtime/capture-ops.js +42 -7
  199. package/dist/runtime/capture-ops.js.map +1 -1
  200. package/dist/runtime/claude-md-helpers.js +1 -1
  201. package/dist/runtime/claude-md-helpers.js.map +1 -1
  202. package/dist/runtime/context-health.d.ts +31 -0
  203. package/dist/runtime/context-health.d.ts.map +1 -0
  204. package/dist/runtime/context-health.js +57 -0
  205. package/dist/runtime/context-health.js.map +1 -0
  206. package/dist/runtime/facades/archive-facade.d.ts +10 -0
  207. package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
  208. package/dist/runtime/facades/archive-facade.js +11 -0
  209. package/dist/runtime/facades/archive-facade.js.map +1 -0
  210. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  211. package/dist/runtime/facades/brain-facade.js +2 -0
  212. package/dist/runtime/facades/brain-facade.js.map +1 -1
  213. package/dist/runtime/facades/branching-facade.d.ts +7 -0
  214. package/dist/runtime/facades/branching-facade.d.ts.map +1 -0
  215. package/dist/runtime/facades/branching-facade.js +8 -0
  216. package/dist/runtime/facades/branching-facade.js.map +1 -0
  217. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  218. package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
  219. package/dist/runtime/facades/chat-facade.js +15 -800
  220. package/dist/runtime/facades/chat-facade.js.map +1 -1
  221. package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
  222. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
  223. package/dist/runtime/facades/chat-service-ops.js +332 -0
  224. package/dist/runtime/facades/chat-service-ops.js.map +1 -0
  225. package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
  226. package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
  227. package/dist/runtime/facades/chat-session-ops.js +136 -0
  228. package/dist/runtime/facades/chat-session-ops.js.map +1 -0
  229. package/dist/runtime/facades/chat-state.d.ts +31 -0
  230. package/dist/runtime/facades/chat-state.d.ts.map +1 -0
  231. package/dist/runtime/facades/chat-state.js +32 -0
  232. package/dist/runtime/facades/chat-state.js.map +1 -0
  233. package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
  234. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
  235. package/dist/runtime/facades/chat-transport-ops.js +337 -0
  236. package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
  237. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  238. package/dist/runtime/facades/control-facade.js +4 -1
  239. package/dist/runtime/facades/control-facade.js.map +1 -1
  240. package/dist/runtime/facades/index.d.ts.map +1 -1
  241. package/dist/runtime/facades/index.js +48 -0
  242. package/dist/runtime/facades/index.js.map +1 -1
  243. package/dist/runtime/facades/intake-facade.d.ts +9 -0
  244. package/dist/runtime/facades/intake-facade.d.ts.map +1 -0
  245. package/dist/runtime/facades/intake-facade.js +11 -0
  246. package/dist/runtime/facades/intake-facade.js.map +1 -0
  247. package/dist/runtime/facades/links-facade.d.ts +9 -0
  248. package/dist/runtime/facades/links-facade.d.ts.map +1 -0
  249. package/dist/runtime/facades/links-facade.js +10 -0
  250. package/dist/runtime/facades/links-facade.js.map +1 -0
  251. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  252. package/dist/runtime/facades/memory-facade.js +75 -6
  253. package/dist/runtime/facades/memory-facade.js.map +1 -1
  254. package/dist/runtime/facades/operator-facade.d.ts +8 -0
  255. package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
  256. package/dist/runtime/facades/operator-facade.js +220 -0
  257. package/dist/runtime/facades/operator-facade.js.map +1 -0
  258. package/dist/runtime/facades/orchestrate-facade.js +3 -3
  259. package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
  260. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  261. package/dist/runtime/facades/plan-facade.js +42 -6
  262. package/dist/runtime/facades/plan-facade.js.map +1 -1
  263. package/dist/runtime/facades/review-facade.d.ts +7 -0
  264. package/dist/runtime/facades/review-facade.d.ts.map +1 -0
  265. package/dist/runtime/facades/review-facade.js +8 -0
  266. package/dist/runtime/facades/review-facade.js.map +1 -0
  267. package/dist/runtime/facades/sync-facade.d.ts +7 -0
  268. package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
  269. package/dist/runtime/facades/sync-facade.js +8 -0
  270. package/dist/runtime/facades/sync-facade.js.map +1 -0
  271. package/dist/runtime/facades/tier-facade.d.ts +7 -0
  272. package/dist/runtime/facades/tier-facade.d.ts.map +1 -0
  273. package/dist/runtime/facades/tier-facade.js +8 -0
  274. package/dist/runtime/facades/tier-facade.js.map +1 -0
  275. package/dist/runtime/facades/vault-facade.d.ts +12 -1
  276. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  277. package/dist/runtime/facades/vault-facade.js +55 -251
  278. package/dist/runtime/facades/vault-facade.js.map +1 -1
  279. package/dist/runtime/github-integration.d.ts +49 -0
  280. package/dist/runtime/github-integration.d.ts.map +1 -0
  281. package/dist/runtime/github-integration.js +120 -0
  282. package/dist/runtime/github-integration.js.map +1 -0
  283. package/dist/runtime/grading-ops.js +1 -1
  284. package/dist/runtime/grading-ops.js.map +1 -1
  285. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  286. package/dist/runtime/memory-extra-ops.js +6 -2
  287. package/dist/runtime/memory-extra-ops.js.map +1 -1
  288. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  289. package/dist/runtime/orchestrate-ops.js +386 -37
  290. package/dist/runtime/orchestrate-ops.js.map +1 -1
  291. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  292. package/dist/runtime/planning-extra-ops.js +69 -4
  293. package/dist/runtime/planning-extra-ops.js.map +1 -1
  294. package/dist/runtime/review-ops.d.ts +10 -0
  295. package/dist/runtime/review-ops.d.ts.map +1 -0
  296. package/dist/runtime/review-ops.js +97 -0
  297. package/dist/runtime/review-ops.js.map +1 -0
  298. package/dist/runtime/runtime.d.ts.map +1 -1
  299. package/dist/runtime/runtime.js +29 -12
  300. package/dist/runtime/runtime.js.map +1 -1
  301. package/dist/runtime/session-briefing.d.ts +3 -0
  302. package/dist/runtime/session-briefing.d.ts.map +1 -1
  303. package/dist/runtime/session-briefing.js +72 -1
  304. package/dist/runtime/session-briefing.js.map +1 -1
  305. package/dist/runtime/sync-ops.d.ts +12 -0
  306. package/dist/runtime/sync-ops.d.ts.map +1 -0
  307. package/dist/runtime/sync-ops.js +288 -0
  308. package/dist/runtime/sync-ops.js.map +1 -0
  309. package/dist/runtime/tier-ops.d.ts +13 -0
  310. package/dist/runtime/tier-ops.d.ts.map +1 -0
  311. package/dist/runtime/tier-ops.js +110 -0
  312. package/dist/runtime/tier-ops.js.map +1 -0
  313. package/dist/runtime/types.d.ts +10 -4
  314. package/dist/runtime/types.d.ts.map +1 -1
  315. package/dist/runtime/vault-extra-ops.d.ts +5 -4
  316. package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
  317. package/dist/runtime/vault-extra-ops.js +5 -300
  318. package/dist/runtime/vault-extra-ops.js.map +1 -1
  319. package/dist/runtime/vault-sharing-ops.d.ts +4 -4
  320. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  321. package/dist/runtime/vault-sharing-ops.js +5 -300
  322. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  323. package/dist/skills/sync-skills.d.ts +27 -0
  324. package/dist/skills/sync-skills.d.ts.map +1 -0
  325. package/dist/skills/sync-skills.js +81 -0
  326. package/dist/skills/sync-skills.js.map +1 -0
  327. package/dist/update-check.d.ts +14 -0
  328. package/dist/update-check.d.ts.map +1 -0
  329. package/dist/update-check.js +96 -0
  330. package/dist/update-check.js.map +1 -0
  331. package/dist/vault/linking.d.ts +10 -12
  332. package/dist/vault/linking.d.ts.map +1 -1
  333. package/dist/vault/linking.js +140 -161
  334. package/dist/vault/linking.js.map +1 -1
  335. package/dist/vault/vault-entries.d.ts +69 -0
  336. package/dist/vault/vault-entries.d.ts.map +1 -0
  337. package/dist/vault/vault-entries.js +299 -0
  338. package/dist/vault/vault-entries.js.map +1 -0
  339. package/dist/vault/vault-interfaces.d.ts +153 -0
  340. package/dist/vault/vault-interfaces.d.ts.map +1 -0
  341. package/dist/vault/vault-interfaces.js +2 -0
  342. package/dist/vault/vault-interfaces.js.map +1 -0
  343. package/dist/vault/vault-maintenance.d.ts +40 -0
  344. package/dist/vault/vault-maintenance.d.ts.map +1 -0
  345. package/dist/vault/vault-maintenance.js +146 -0
  346. package/dist/vault/vault-maintenance.js.map +1 -0
  347. package/dist/vault/vault-markdown-sync.d.ts +22 -0
  348. package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
  349. package/dist/vault/vault-markdown-sync.js +143 -0
  350. package/dist/vault/vault-markdown-sync.js.map +1 -0
  351. package/dist/vault/vault-memories.d.ts +61 -0
  352. package/dist/vault/vault-memories.d.ts.map +1 -0
  353. package/dist/vault/vault-memories.js +242 -0
  354. package/dist/vault/vault-memories.js.map +1 -0
  355. package/dist/vault/vault-schema.d.ts +9 -0
  356. package/dist/vault/vault-schema.d.ts.map +1 -0
  357. package/dist/vault/vault-schema.js +205 -0
  358. package/dist/vault/vault-schema.js.map +1 -0
  359. package/dist/vault/vault.d.ts +29 -81
  360. package/dist/vault/vault.d.ts.map +1 -1
  361. package/dist/vault/vault.js +82 -931
  362. package/dist/vault/vault.js.map +1 -1
  363. package/package.json +7 -7
  364. package/src/agency/agency-manager.test.ts +620 -0
  365. package/src/agency/default-rules.test.ts +236 -0
  366. package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
  367. package/src/{__tests__ → brain}/brain.test.ts +1 -1
  368. package/src/brain/intelligence.ts +196 -15
  369. package/src/brain/learning-radar.ts +22 -1
  370. package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
  371. package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
  372. package/src/capabilities/chain-mapping.test.ts +66 -0
  373. package/src/capabilities/registry.test.ts +359 -0
  374. package/src/chat/agent-loop.test.ts +384 -0
  375. package/src/chat/agent-loop.ts +2 -0
  376. package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
  377. package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
  378. package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
  379. package/src/chat/mcp-bridge.test.ts +178 -0
  380. package/src/chat/notifications.ts +2 -0
  381. package/src/chat/output-compressor.test.ts +164 -0
  382. package/src/claudemd/compose.test.ts +178 -0
  383. package/src/claudemd/compose.ts +1 -1
  384. package/src/claudemd/inject.test.ts +201 -0
  385. package/src/context/context-engine.test.ts +506 -0
  386. package/src/control/identity-manager.test.ts +305 -0
  387. package/src/control/intent-router.test.ts +360 -0
  388. package/src/control/intent-router.ts +13 -4
  389. package/src/curator/classifier.test.ts +110 -0
  390. package/src/curator/contradiction-detector.test.ts +205 -0
  391. package/src/curator/contradiction-detector.ts +87 -0
  392. package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
  393. package/src/{__tests__ → curator}/curator.test.ts +77 -1
  394. package/src/curator/curator.ts +160 -600
  395. package/src/curator/duplicate-detector.test.ts +245 -0
  396. package/src/curator/duplicate-detector.ts +103 -0
  397. package/src/curator/health-audit.ts +126 -0
  398. package/src/curator/metadata-enricher.ts +84 -0
  399. package/src/curator/quality-gate.test.ts +175 -0
  400. package/src/curator/schema.ts +65 -0
  401. package/src/curator/tag-manager.test.ts +173 -0
  402. package/src/curator/tag-manager.ts +109 -0
  403. package/src/domain-packs/inject-rules.test.ts +117 -0
  404. package/src/domain-packs/knowledge-installer.test.ts +163 -0
  405. package/src/domain-packs/loader.test.ts +86 -0
  406. package/src/domain-packs/pack-runtime.test.ts +140 -0
  407. package/src/domain-packs/skills-installer.test.ts +135 -0
  408. package/src/domain-packs/token-resolver.test.ts +148 -0
  409. package/src/domain-packs/types.test.ts +144 -0
  410. package/src/enforcement/adapters/claude-code.test.ts +216 -0
  411. package/src/enforcement/registry.test.ts +258 -0
  412. package/src/engine/bin/soleri-engine.ts +30 -4
  413. package/src/engine/core-ops.test.ts +254 -0
  414. package/src/engine/core-ops.ts +25 -8
  415. package/src/engine/module-manifest.test.ts +125 -0
  416. package/src/engine/module-manifest.ts +42 -2
  417. package/src/engine/register-engine.test.ts +235 -0
  418. package/src/engine/register-engine.ts +50 -3
  419. package/src/errors/classify.test.ts +203 -0
  420. package/src/errors/retry.test.ts +153 -0
  421. package/src/errors/retry.ts +2 -0
  422. package/src/errors/types.test.ts +108 -0
  423. package/src/events/event-bus.test.ts +149 -0
  424. package/src/extensions/middleware.test.ts +234 -0
  425. package/src/facades/facade-factory.test.ts +470 -0
  426. package/src/flows/chain-runner.test.ts +273 -0
  427. package/src/flows/context-router.test.ts +52 -0
  428. package/src/flows/dispatch-registry.test.ts +128 -0
  429. package/src/flows/epilogue.test.ts +113 -0
  430. package/src/flows/executor.test.ts +263 -0
  431. package/src/flows/gate-evaluator.test.ts +200 -0
  432. package/src/flows/gate-evaluator.ts +23 -0
  433. package/src/flows/types.ts +4 -0
  434. package/src/governance/governance.test.ts +842 -0
  435. package/src/{__tests__ → health}/health-registry.test.ts +75 -55
  436. package/src/health/vault-integrity.test.ts +110 -0
  437. package/src/index.ts +92 -0
  438. package/src/intake/content-classifier.test.ts +279 -0
  439. package/src/intake/dedup-gate.test.ts +147 -0
  440. package/src/intake/intake-pipeline.test.ts +508 -0
  441. package/src/intake/intake-pipeline.ts +1 -0
  442. package/src/intake/text-ingester.test.ts +200 -0
  443. package/src/intake/text-ingester.ts +2 -0
  444. package/src/llm/key-pool.test.ts +234 -0
  445. package/src/llm/key-pool.ts +3 -4
  446. package/src/llm/llm-client.test.ts +342 -0
  447. package/src/llm/oauth-discovery.test.ts +180 -0
  448. package/src/llm/utils.test.ts +371 -0
  449. package/src/llm/utils.ts +2 -0
  450. package/src/{__tests__ → logging}/logger.test.ts +44 -62
  451. package/src/loop/loop-manager.test.ts +515 -0
  452. package/src/migrations/migration-runner.edge-cases.test.ts +314 -0
  453. package/src/migrations/migration-runner.test-helpers.ts +64 -0
  454. package/src/migrations/migration-runner.test.ts +385 -0
  455. package/src/operator/auto-signal-pipeline.test.ts +207 -0
  456. package/src/operator/operator-profile-extended.test.ts +330 -0
  457. package/src/operator/operator-profile.test.ts +332 -0
  458. package/src/operator/operator-profile.ts +485 -0
  459. package/src/operator/operator-signals-extended.test.ts +257 -0
  460. package/src/operator/operator-signals.test.ts +277 -0
  461. package/src/operator/operator-signals.ts +262 -0
  462. package/src/operator/operator-types.ts +444 -0
  463. package/src/operator/prompts/hook-precompact-operator-dispatch.md +98 -0
  464. package/src/operator/prompts/subagent-soft-signal-extractor.md +130 -0
  465. package/src/operator/prompts/subagent-synthesis-cognition.md +190 -0
  466. package/src/operator/prompts/subagent-synthesis-communication.md +146 -0
  467. package/src/operator/prompts/subagent-synthesis-technical.md +170 -0
  468. package/src/operator/prompts/subagent-synthesis-trust.md +149 -0
  469. package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
  470. package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
  471. package/src/paths.ts +115 -0
  472. package/src/persistence/index.ts +1 -1
  473. package/src/persistence/sqlite-provider.test.ts +540 -0
  474. package/src/persistence/sqlite-provider.ts +8 -5
  475. package/src/persona/defaults.test.ts +55 -0
  476. package/src/persona/loader.test.ts +67 -0
  477. package/src/persona/prompt-generator.test.ts +127 -0
  478. package/src/planning/evidence-collector.test.ts +515 -0
  479. package/src/planning/evidence-collector.ts +47 -0
  480. package/src/planning/gap-analysis-alternatives.test.ts +199 -0
  481. package/src/planning/gap-analysis.ts +21 -636
  482. package/src/planning/gap-passes.test.ts +554 -0
  483. package/src/planning/gap-passes.ts +367 -0
  484. package/src/planning/gap-patterns.test.ts +394 -0
  485. package/src/planning/gap-patterns.ts +317 -0
  486. package/src/planning/gap-types.ts +4 -1
  487. package/src/planning/github-projection.test.ts +182 -0
  488. package/src/planning/github-projection.ts +446 -0
  489. package/src/planning/impact-analyzer.test.ts +167 -0
  490. package/src/planning/impact-analyzer.ts +251 -0
  491. package/src/planning/plan-lifecycle.test.ts +379 -0
  492. package/src/planning/plan-lifecycle.ts +377 -0
  493. package/src/planning/planner-types.ts +215 -0
  494. package/src/{__tests__ → planning}/planner.test.ts +179 -15
  495. package/src/planning/planner.ts +221 -1112
  496. package/src/planning/rationalization-detector.test.ts +156 -0
  497. package/src/planning/rationalization-detector.ts +136 -0
  498. package/src/planning/reconciliation-engine.test.ts +158 -0
  499. package/src/planning/reconciliation-engine.ts +161 -0
  500. package/src/planning/task-verifier.test.ts +267 -0
  501. package/src/planning/task-verifier.ts +309 -0
  502. package/src/planning/verification-protocol.test.ts +201 -0
  503. package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
  504. package/src/playbooks/index.test.ts +77 -0
  505. package/src/playbooks/playbook-executor.test.ts +253 -0
  506. package/src/playbooks/playbook-registry.test.ts +232 -0
  507. package/src/playbooks/playbook-seeder.test.ts +153 -0
  508. package/src/plugins/plugin-loader.test.ts +217 -0
  509. package/src/plugins/plugin-registry.test.ts +284 -0
  510. package/src/project/project-registry.test.ts +439 -0
  511. package/src/prompts/parser.test.ts +100 -0
  512. package/src/prompts/template-manager.test.ts +112 -0
  513. package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
  514. package/src/queue/job-queue.test.ts +327 -0
  515. package/src/queue/pipeline-runner.test.ts +209 -0
  516. package/src/runtime/admin-extra-ops.test.ts +513 -0
  517. package/src/runtime/admin-ops.test.ts +255 -0
  518. package/src/runtime/admin-ops.ts +45 -17
  519. package/src/runtime/admin-setup-ops.test.ts +327 -0
  520. package/src/runtime/admin-setup-ops.ts +26 -42
  521. package/src/runtime/archive-ops.test.ts +272 -0
  522. package/src/runtime/archive-ops.ts +347 -0
  523. package/src/runtime/branching-ops.test.ts +144 -0
  524. package/src/runtime/branching-ops.ts +107 -0
  525. package/src/runtime/capture-ops.test.ts +419 -0
  526. package/src/runtime/capture-ops.ts +50 -8
  527. package/src/runtime/chain-ops.test.ts +159 -0
  528. package/src/runtime/claude-md-helpers.test.ts +189 -0
  529. package/src/runtime/claude-md-helpers.ts +1 -1
  530. package/src/runtime/context-health.test.ts +76 -0
  531. package/src/runtime/context-health.ts +83 -0
  532. package/src/runtime/curator-extra-ops.test.ts +204 -0
  533. package/src/runtime/deprecation.test.ts +98 -0
  534. package/src/runtime/domain-ops.test.ts +278 -0
  535. package/src/runtime/facades/admin-facade.test.ts +330 -0
  536. package/src/runtime/facades/agency-facade.test.ts +278 -0
  537. package/src/runtime/facades/archive-facade.test.ts +308 -0
  538. package/src/runtime/facades/archive-facade.ts +14 -0
  539. package/src/runtime/facades/brain-facade.test.ts +818 -0
  540. package/src/runtime/facades/brain-facade.ts +2 -0
  541. package/src/runtime/facades/branching-facade.test.ts +43 -0
  542. package/src/runtime/facades/branching-facade.ts +11 -0
  543. package/src/runtime/facades/chat-facade.test.ts +219 -0
  544. package/src/runtime/facades/chat-facade.ts +15 -906
  545. package/src/runtime/facades/chat-service-ops.test.ts +381 -0
  546. package/src/runtime/facades/chat-service-ops.ts +376 -0
  547. package/src/runtime/facades/chat-session-ops.test.ts +212 -0
  548. package/src/runtime/facades/chat-session-ops.ts +146 -0
  549. package/src/runtime/facades/chat-state.ts +60 -0
  550. package/src/runtime/facades/chat-transport-ops.test.ts +336 -0
  551. package/src/runtime/facades/chat-transport-ops.ts +379 -0
  552. package/src/runtime/facades/context-facade.test.ts +123 -0
  553. package/src/runtime/facades/control-facade.test.ts +436 -0
  554. package/src/runtime/facades/control-facade.ts +6 -1
  555. package/src/runtime/facades/curator-facade.test.ts +303 -0
  556. package/src/runtime/facades/index.ts +48 -0
  557. package/src/runtime/facades/intake-facade.test.ts +215 -0
  558. package/src/runtime/facades/intake-facade.ts +14 -0
  559. package/src/runtime/facades/links-facade.test.ts +203 -0
  560. package/src/runtime/facades/links-facade.ts +13 -0
  561. package/src/runtime/facades/loop-facade.test.ts +262 -0
  562. package/src/runtime/facades/memory-facade.test.ts +283 -0
  563. package/src/runtime/facades/memory-facade.ts +78 -6
  564. package/src/runtime/facades/operator-facade.test.ts +221 -0
  565. package/src/runtime/facades/operator-facade.ts +244 -0
  566. package/src/runtime/facades/orchestrate-facade.test.ts +191 -0
  567. package/src/runtime/facades/orchestrate-facade.ts +3 -3
  568. package/src/runtime/facades/plan-facade.test.ts +283 -0
  569. package/src/runtime/facades/plan-facade.ts +47 -6
  570. package/src/runtime/facades/review-facade.test.ts +82 -0
  571. package/src/runtime/facades/review-facade.ts +11 -0
  572. package/src/runtime/facades/sync-facade.test.ts +113 -0
  573. package/src/runtime/facades/sync-facade.ts +11 -0
  574. package/src/runtime/facades/tier-facade.test.ts +47 -0
  575. package/src/runtime/facades/tier-facade.ts +11 -0
  576. package/src/runtime/facades/vault-facade.test.ts +563 -0
  577. package/src/runtime/facades/vault-facade.ts +66 -265
  578. package/src/runtime/feature-flags.test.ts +140 -0
  579. package/src/runtime/github-integration.test.ts +89 -0
  580. package/src/runtime/github-integration.ts +162 -0
  581. package/src/runtime/grading-ops.test.ts +172 -0
  582. package/src/runtime/grading-ops.ts +1 -1
  583. package/src/runtime/intake-ops.test.ts +261 -0
  584. package/src/runtime/loop-ops.test.ts +248 -0
  585. package/src/runtime/memory-cross-project-ops.test.ts +188 -0
  586. package/src/runtime/memory-extra-ops.test.ts +453 -0
  587. package/src/runtime/memory-extra-ops.ts +6 -2
  588. package/src/runtime/orchestrate-ops.test.ts +302 -0
  589. package/src/runtime/orchestrate-ops.ts +461 -45
  590. package/src/runtime/pack-ops.test.ts +175 -0
  591. package/src/runtime/planning-extra-ops.test.ts +593 -0
  592. package/src/runtime/planning-extra-ops.ts +74 -4
  593. package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
  594. package/src/runtime/playbook-ops.test.ts +285 -0
  595. package/src/runtime/plugin-ops.test.ts +259 -0
  596. package/src/runtime/project-ops.test.ts +255 -0
  597. package/src/runtime/review-ops.test.ts +142 -0
  598. package/src/runtime/review-ops.ts +99 -0
  599. package/src/runtime/runtime.test.ts +363 -0
  600. package/src/runtime/runtime.ts +41 -12
  601. package/src/runtime/session-briefing.test.ts +431 -0
  602. package/src/runtime/session-briefing.ts +86 -1
  603. package/src/runtime/sync-ops.test.ts +212 -0
  604. package/src/runtime/sync-ops.ts +325 -0
  605. package/src/runtime/telemetry-ops.test.ts +157 -0
  606. package/src/runtime/tier-ops.test.ts +159 -0
  607. package/src/runtime/tier-ops.ts +119 -0
  608. package/src/runtime/types.ts +10 -4
  609. package/src/runtime/vault-extra-ops.test.ts +270 -0
  610. package/src/runtime/vault-extra-ops.ts +5 -332
  611. package/src/runtime/vault-linking-ops.test.ts +237 -0
  612. package/src/runtime/vault-sharing-ops.test.ts +127 -0
  613. package/src/runtime/vault-sharing-ops.ts +5 -329
  614. package/src/skills/sync-skills.ts +98 -0
  615. package/src/streams/normalize.test.ts +95 -0
  616. package/src/streams/replayable-stream.test.ts +166 -0
  617. package/src/telemetry/telemetry.test.ts +143 -0
  618. package/src/transport/http-server.test.ts +394 -0
  619. package/src/transport/lsp-server.test.ts +458 -0
  620. package/src/transport/rate-limiter.test.ts +126 -0
  621. package/src/transport/session-manager.test.ts +133 -0
  622. package/src/transport/token-auth.test.ts +136 -0
  623. package/src/transport/ws-server.test.ts +297 -0
  624. package/src/update-check.ts +111 -0
  625. package/src/vault/__tests__/vault-characterization.test.ts +579 -0
  626. package/src/vault/content-hash.test.ts +78 -0
  627. package/src/vault/git-vault-sync.test.ts +234 -0
  628. package/src/vault/knowledge-review.test.ts +269 -0
  629. package/src/vault/linking.test.ts +391 -0
  630. package/src/vault/linking.ts +188 -181
  631. package/src/vault/obsidian-sync.test.ts +345 -0
  632. package/src/vault/playbook.test.ts +152 -0
  633. package/src/vault/scope-detector.test.ts +185 -0
  634. package/src/vault/vault-branching.test.ts +252 -0
  635. package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
  636. package/src/vault/vault-entries.ts +426 -0
  637. package/src/vault/vault-maintenance.ts +200 -0
  638. package/src/vault/vault-manager.test.ts +206 -0
  639. package/src/vault/vault-markdown-sync.test.ts +203 -0
  640. package/src/vault/vault-markdown-sync.ts +163 -0
  641. package/src/vault/vault-memories.ts +339 -0
  642. package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
  643. package/src/vault/vault-schema.ts +238 -0
  644. package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
  645. package/src/{__tests__ → vault}/vault.test.ts +2 -2
  646. package/src/vault/vault.ts +87 -1123
  647. package/dist/cognee/client.d.ts +0 -43
  648. package/dist/cognee/client.d.ts.map +0 -1
  649. package/dist/cognee/client.js +0 -375
  650. package/dist/cognee/client.js.map +0 -1
  651. package/dist/cognee/sync-manager.d.ts +0 -153
  652. package/dist/cognee/sync-manager.d.ts.map +0 -1
  653. package/dist/cognee/sync-manager.js +0 -390
  654. package/dist/cognee/sync-manager.js.map +0 -1
  655. package/dist/cognee/types.d.ts +0 -62
  656. package/dist/cognee/types.d.ts.map +0 -1
  657. package/dist/cognee/types.js +0 -3
  658. package/dist/cognee/types.js.map +0 -1
  659. package/dist/governance/index.d.ts +0 -3
  660. package/dist/governance/index.d.ts.map +0 -1
  661. package/dist/governance/index.js +0 -2
  662. package/dist/governance/index.js.map +0 -1
  663. package/dist/health/doctor-checks.d.ts +0 -15
  664. package/dist/health/doctor-checks.d.ts.map +0 -1
  665. package/dist/health/doctor-checks.js +0 -98
  666. package/dist/health/doctor-checks.js.map +0 -1
  667. package/dist/persistence/postgres-provider.d.ts +0 -81
  668. package/dist/persistence/postgres-provider.d.ts.map +0 -1
  669. package/dist/persistence/postgres-provider.js +0 -256
  670. package/dist/persistence/postgres-provider.js.map +0 -1
  671. package/dist/runtime/cognee-sync-ops.d.ts +0 -12
  672. package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
  673. package/dist/runtime/cognee-sync-ops.js +0 -93
  674. package/dist/runtime/cognee-sync-ops.js.map +0 -1
  675. package/dist/runtime/core-ops.d.ts +0 -23
  676. package/dist/runtime/core-ops.d.ts.map +0 -1
  677. package/dist/runtime/core-ops.js +0 -1296
  678. package/dist/runtime/core-ops.js.map +0 -1
  679. package/dist/runtime/facades/cognee-facade.d.ts +0 -8
  680. package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
  681. package/dist/runtime/facades/cognee-facade.js +0 -156
  682. package/dist/runtime/facades/cognee-facade.js.map +0 -1
  683. package/src/__tests__/admin-extra-ops.test.ts +0 -484
  684. package/src/__tests__/admin-ops.test.ts +0 -268
  685. package/src/__tests__/admin-setup-ops.test.ts +0 -355
  686. package/src/__tests__/agency-manager.test.ts +0 -374
  687. package/src/__tests__/agent-loop.test.ts +0 -256
  688. package/src/__tests__/capture-ops.test.ts +0 -784
  689. package/src/__tests__/claudemd.test.ts +0 -282
  690. package/src/__tests__/content-hash.test.ts +0 -60
  691. package/src/__tests__/context-engine.test.ts +0 -251
  692. package/src/__tests__/core-ops.test.ts +0 -550
  693. package/src/__tests__/curator-extra-ops.test.ts +0 -383
  694. package/src/__tests__/deprecation.test.ts +0 -78
  695. package/src/__tests__/domain-ops.test.ts +0 -226
  696. package/src/__tests__/domain-packs.test.ts +0 -421
  697. package/src/__tests__/enforcement.test.ts +0 -153
  698. package/src/__tests__/errors.test.ts +0 -388
  699. package/src/__tests__/extensions.test.ts +0 -233
  700. package/src/__tests__/facade-factory.test.ts +0 -271
  701. package/src/__tests__/feature-flags.test.ts +0 -137
  702. package/src/__tests__/flows.test.ts +0 -604
  703. package/src/__tests__/git-vault-sync.test.ts +0 -230
  704. package/src/__tests__/governance.test.ts +0 -522
  705. package/src/__tests__/grading-ops.test.ts +0 -361
  706. package/src/__tests__/identity-manager.test.ts +0 -243
  707. package/src/__tests__/intake-pipeline.test.ts +0 -162
  708. package/src/__tests__/intent-router.test.ts +0 -222
  709. package/src/__tests__/knowledge-review.test.ts +0 -104
  710. package/src/__tests__/llm-client.test.ts +0 -69
  711. package/src/__tests__/llm.test.ts +0 -556
  712. package/src/__tests__/loader.test.ts +0 -176
  713. package/src/__tests__/loop-ops.test.ts +0 -469
  714. package/src/__tests__/lsp-transport.test.ts +0 -442
  715. package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
  716. package/src/__tests__/memory-extra-ops.test.ts +0 -352
  717. package/src/__tests__/migration-runner.test.ts +0 -170
  718. package/src/__tests__/module-manifest-drift.test.ts +0 -59
  719. package/src/__tests__/normalize.test.ts +0 -85
  720. package/src/__tests__/obsidian-sync.test.ts +0 -354
  721. package/src/__tests__/orchestrate-ops.test.ts +0 -289
  722. package/src/__tests__/pack-ops.test.ts +0 -146
  723. package/src/__tests__/persistence.test.ts +0 -291
  724. package/src/__tests__/planning-extra-ops.test.ts +0 -706
  725. package/src/__tests__/playbook-executor.test.ts +0 -249
  726. package/src/__tests__/playbook-registry.test.ts +0 -326
  727. package/src/__tests__/playbook-seeder.test.ts +0 -163
  728. package/src/__tests__/playbook.test.ts +0 -389
  729. package/src/__tests__/plugin-ops.test.ts +0 -411
  730. package/src/__tests__/plugin-system.test.ts +0 -509
  731. package/src/__tests__/project-ops.test.ts +0 -381
  732. package/src/__tests__/replayable-stream.test.ts +0 -177
  733. package/src/__tests__/runtime.test.ts +0 -95
  734. package/src/__tests__/scope-detector.test.ts +0 -121
  735. package/src/__tests__/template-manager.test.ts +0 -222
  736. package/src/__tests__/token-resolver.test.ts +0 -79
  737. package/src/__tests__/transport.test.ts +0 -758
  738. package/src/__tests__/vault-branching.test.ts +0 -274
  739. package/src/__tests__/vault-extra-ops.test.ts +0 -482
  740. package/src/__tests__/vault-integrity.test.ts +0 -71
  741. package/src/__tests__/vault-manager.test.ts +0 -238
  742. package/src/__tests__/ws-transport.test.ts +0 -479
  743. package/src/engine/index.ts +0 -21
  744. package/src/persona/index.ts +0 -9
@@ -0,0 +1,283 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { Vault } from '../../vault/vault.js';
3
+ import { OperatorProfileStore } from '../../operator/operator-profile.js';
4
+ import { ProjectRegistry } from '../../project/project-registry.js';
5
+ import { createMemoryFacadeOps } from './memory-facade.js';
6
+ import { captureOps, executeOp } from '../../engine/test-helpers.js';
7
+ import type { CapturedOp } from '../../engine/test-helpers.js';
8
+ import type { AgentRuntime } from '../types.js';
9
+
10
+ // ─── Helpers ────────────────────────────────────────────────────────
11
+
12
+ function makeRuntime(vault: Vault): AgentRuntime {
13
+ const operatorProfile = new OperatorProfileStore(vault);
14
+ const projectRegistry = new ProjectRegistry(vault.getProvider());
15
+ return { vault, operatorProfile, projectRegistry } as unknown as AgentRuntime;
16
+ }
17
+
18
+ // ─── Tests ──────────────────────────────────────────────────────────
19
+
20
+ describe('memory-facade', () => {
21
+ let vault: Vault;
22
+ let ops: Map<string, CapturedOp>;
23
+
24
+ beforeEach(() => {
25
+ vault = new Vault(':memory:');
26
+ ops = captureOps(createMemoryFacadeOps(makeRuntime(vault)));
27
+ });
28
+
29
+ afterEach(() => {
30
+ vault.close();
31
+ });
32
+
33
+ it('registers base + extra + cross-project ops', () => {
34
+ // 4 base + 18 extra + 3 cross-project = 25
35
+ expect(ops.size).toBeGreaterThanOrEqual(25);
36
+ expect([...ops.keys()]).toContain('memory_search');
37
+ expect([...ops.keys()]).toContain('memory_capture');
38
+ expect([...ops.keys()]).toContain('memory_list');
39
+ expect([...ops.keys()]).toContain('session_capture');
40
+ expect([...ops.keys()]).toContain('memory_delete');
41
+ expect([...ops.keys()]).toContain('memory_promote_to_global');
42
+ });
43
+
44
+ it('has correct auth levels for base ops', () => {
45
+ expect(ops.get('memory_search')!.auth).toBe('read');
46
+ expect(ops.get('memory_capture')!.auth).toBe('write');
47
+ expect(ops.get('memory_list')!.auth).toBe('read');
48
+ expect(ops.get('session_capture')!.auth).toBe('write');
49
+ });
50
+
51
+ // ─── memory_capture ────────────────────────────────────────────
52
+
53
+ it('memory_capture stores a memory', async () => {
54
+ const result = await executeOp(ops, 'memory_capture', {
55
+ projectPath: '/test',
56
+ type: 'lesson',
57
+ context: 'learned about tokens',
58
+ summary: 'Token migration pattern',
59
+ topics: ['tokens'],
60
+ });
61
+ expect(result.success).toBe(true);
62
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
63
+ });
64
+
65
+ // ─── memory_search ─────────────────────────────────────────────
66
+
67
+ it('memory_search returns empty for no matches', async () => {
68
+ const result = await executeOp(ops, 'memory_search', { query: 'nonexistent' });
69
+ expect(result.success).toBe(true);
70
+ expect((result.data as Record<string, unknown>).total).toBe(0);
71
+ });
72
+
73
+ it('memory_search finds captured memories', async () => {
74
+ await executeOp(ops, 'memory_capture', {
75
+ projectPath: '/test',
76
+ type: 'lesson',
77
+ context: 'context',
78
+ summary: 'Token migration best practices',
79
+ });
80
+ const result = await executeOp(ops, 'memory_search', { query: 'token migration' });
81
+ expect(result.success).toBe(true);
82
+ expect((result.data as Record<string, unknown>).total).toBeGreaterThanOrEqual(1);
83
+ });
84
+
85
+ it('memory_search returns summaries by default', async () => {
86
+ await executeOp(ops, 'memory_capture', {
87
+ projectPath: '/test',
88
+ type: 'lesson',
89
+ context: 'ctx',
90
+ summary: 'short summary',
91
+ });
92
+ const result = await executeOp(ops, 'memory_search', { query: 'short summary' });
93
+ expect(result.success).toBe(true);
94
+ const data = result.data as { results: Array<{ summary: string }> };
95
+ expect(data.results[0]).toHaveProperty('summary');
96
+ expect(data.results[0]).not.toHaveProperty('context');
97
+ });
98
+
99
+ it('memory_search returns full objects with verbose:true', async () => {
100
+ await executeOp(ops, 'memory_capture', {
101
+ projectPath: '/test',
102
+ type: 'lesson',
103
+ context: 'ctx',
104
+ summary: 'verbose test',
105
+ });
106
+ const result = await executeOp(ops, 'memory_search', { query: 'verbose test', verbose: true });
107
+ expect(result.success).toBe(true);
108
+ const data = result.data as { results: Array<Record<string, unknown>> };
109
+ expect(data.results[0]).toHaveProperty('context');
110
+ });
111
+
112
+ // ─── memory_list ───────────────────────────────────────────────
113
+
114
+ it('memory_list returns entries with stats', async () => {
115
+ await executeOp(ops, 'memory_capture', {
116
+ projectPath: '/test',
117
+ type: 'session',
118
+ context: 'ctx',
119
+ summary: 'session 1',
120
+ });
121
+ const result = await executeOp(ops, 'memory_list', {});
122
+ expect(result.success).toBe(true);
123
+ const data = result.data as { entries: unknown[]; total: number };
124
+ expect(data.total).toBeGreaterThanOrEqual(1);
125
+ expect(data.entries.length).toBeGreaterThanOrEqual(1);
126
+ });
127
+
128
+ it('memory_list filters by type', async () => {
129
+ await executeOp(ops, 'memory_capture', {
130
+ projectPath: '/test',
131
+ type: 'lesson',
132
+ context: 'c',
133
+ summary: 'lesson',
134
+ });
135
+ await executeOp(ops, 'memory_capture', {
136
+ projectPath: '/test',
137
+ type: 'preference',
138
+ context: 'c',
139
+ summary: 'pref',
140
+ });
141
+ const result = await executeOp(ops, 'memory_list', { type: 'lesson' });
142
+ expect(result.success).toBe(true);
143
+ const data = result.data as { entries: unknown[]; total: number };
144
+ expect(data.entries.length).toBe(1);
145
+ });
146
+
147
+ it('memory_list verbose returns full objects', async () => {
148
+ await executeOp(ops, 'memory_capture', {
149
+ projectPath: '/test',
150
+ type: 'lesson',
151
+ context: 'c',
152
+ summary: 'verbose list',
153
+ });
154
+ const result = await executeOp(ops, 'memory_list', { verbose: true });
155
+ expect(result.success).toBe(true);
156
+ const data = result.data as { memories: Array<Record<string, unknown>> };
157
+ expect(data.memories[0]).toHaveProperty('context');
158
+ });
159
+
160
+ // ─── session_capture ───────────────────────────────────────────
161
+
162
+ it('session_capture stores with summary', async () => {
163
+ const result = await executeOp(ops, 'session_capture', {
164
+ summary: 'Built token migration feature',
165
+ topics: ['tokens'],
166
+ });
167
+ expect(result.success).toBe(true);
168
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
169
+ });
170
+
171
+ it('session_capture accepts conversationContext alias', async () => {
172
+ const result = await executeOp(ops, 'session_capture', {
173
+ conversationContext: 'aliased summary',
174
+ });
175
+ expect(result.success).toBe(true);
176
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
177
+ });
178
+
179
+ it('session_capture fails without summary or conversationContext', async () => {
180
+ const result = await executeOp(ops, 'session_capture', { topics: ['test'] });
181
+ expect(result.success).toBe(true);
182
+ expect((result.data as Record<string, unknown>).captured).toBe(false);
183
+ });
184
+
185
+ it('session_capture stores rich fields', async () => {
186
+ const result = await executeOp(ops, 'session_capture', {
187
+ summary: 'test session',
188
+ intent: 'BUILD',
189
+ decisions: ['used pattern X'],
190
+ currentState: 'half done',
191
+ nextSteps: ['finish Y'],
192
+ vaultEntriesReferenced: ['entry-1'],
193
+ filesModified: ['src/app.ts'],
194
+ toolsUsed: ['vault_search'],
195
+ });
196
+ expect(result.success).toBe(true);
197
+ expect((result.data as Record<string, unknown>).captured).toBe(true);
198
+ });
199
+
200
+ // ─── memory_delete ─────────────────────────────────────────────
201
+
202
+ it('memory_delete removes a memory', async () => {
203
+ const captureResult = await executeOp(ops, 'memory_capture', {
204
+ projectPath: '/test',
205
+ type: 'lesson',
206
+ context: 'c',
207
+ summary: 'to delete',
208
+ });
209
+ const memoryId = (
210
+ (captureResult.data as Record<string, unknown>).memory as Record<string, unknown>
211
+ ).id as string;
212
+ const result = await executeOp(ops, 'memory_delete', { memoryId });
213
+ expect(result.success).toBe(true);
214
+ expect((result.data as Record<string, unknown>).deleted).toBe(true);
215
+ });
216
+
217
+ it('memory_delete returns false for nonexistent memory', async () => {
218
+ const result = await executeOp(ops, 'memory_delete', { memoryId: 'nonexistent' });
219
+ expect(result.success).toBe(true);
220
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
221
+ });
222
+
223
+ it('memory_delete accepts id alias', async () => {
224
+ const result = await executeOp(ops, 'memory_delete', { id: 'nonexistent' });
225
+ expect(result.success).toBe(true);
226
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
227
+ });
228
+
229
+ it('memory_delete fails without any id param', async () => {
230
+ const result = await executeOp(ops, 'memory_delete', {});
231
+ expect(result.success).toBe(true);
232
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
233
+ expect((result.data as Record<string, unknown>).error).toContain('required');
234
+ });
235
+
236
+ // ─── memory_stats ──────────────────────────────────────────────
237
+
238
+ it('memory_stats returns statistics', async () => {
239
+ const result = await executeOp(ops, 'memory_stats', {});
240
+ expect(result.success).toBe(true);
241
+ expect(result.data).toHaveProperty('total');
242
+ });
243
+
244
+ // ─── memory_topics ─────────────────────────────────────────────
245
+
246
+ it('memory_topics returns empty initially', async () => {
247
+ const result = await executeOp(ops, 'memory_topics', {});
248
+ expect(result.success).toBe(true);
249
+ expect((result.data as Record<string, unknown>).count).toBe(0);
250
+ });
251
+
252
+ // ─── memory_deduplicate ────────────────────────────────────────
253
+
254
+ it('memory_deduplicate runs without error', async () => {
255
+ const result = await executeOp(ops, 'memory_deduplicate', {});
256
+ expect(result.success).toBe(true);
257
+ });
258
+
259
+ // ─── memory_promote_to_global ──────────────────────────────────
260
+
261
+ it('memory_promote_to_global fails on missing entry', async () => {
262
+ const result = await executeOp(ops, 'memory_promote_to_global', { entryId: 'missing' });
263
+ expect(result.success).toBe(true);
264
+ expect((result.data as Record<string, unknown>).promoted).toBe(false);
265
+ });
266
+
267
+ it('memory_promote_to_global adds _global tag', async () => {
268
+ vault.add({
269
+ id: 'test-entry',
270
+ type: 'pattern',
271
+ domain: 'general',
272
+ title: 'test',
273
+ description: 'test',
274
+ severity: 'suggestion',
275
+ tags: ['foo'],
276
+ });
277
+ const result = await executeOp(ops, 'memory_promote_to_global', { entryId: 'test-entry' });
278
+ expect(result.success).toBe(true);
279
+ const data = result.data as { promoted: boolean; tags: string[] };
280
+ expect(data.promoted).toBe(true);
281
+ expect(data.tags).toContain('_global');
282
+ });
283
+ });
@@ -8,6 +8,14 @@ import type { OpDefinition } from '../../facades/types.js';
8
8
  import type { AgentRuntime } from '../types.js';
9
9
  import { createMemoryExtraOps } from '../memory-extra-ops.js';
10
10
  import { createMemoryCrossProjectOps } from '../memory-cross-project-ops.js';
11
+ import { extractFromSession } from '../../operator/operator-signals.js';
12
+ import type { SessionCaptureData } from '../../operator/operator-signals.js';
13
+
14
+ /** Truncate text to maxLen chars, appending ellipsis when truncated. */
15
+ function truncateSummary(text: string, maxLen = 120): string {
16
+ if (text.length <= maxLen) return text;
17
+ return text.slice(0, maxLen) + '\u2026';
18
+ }
11
19
 
12
20
  export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
13
21
  const { vault } = runtime;
@@ -16,20 +24,38 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
16
24
  // ─── Memory (inline from core-ops.ts) ───────────────────────
17
25
  {
18
26
  name: 'memory_search',
19
- description: 'Search memories using full-text search.',
27
+ description:
28
+ 'Search memories using full-text search. Returns summaries by default; pass verbose: true for full objects.',
20
29
  auth: 'read',
21
30
  schema: z.object({
22
31
  query: z.string(),
23
32
  type: z.enum(['session', 'lesson', 'preference']).optional(),
24
33
  projectPath: z.string().optional(),
25
34
  limit: z.number().optional(),
35
+ verbose: z
36
+ .boolean()
37
+ .optional()
38
+ .default(false)
39
+ .describe('Return full memory objects instead of summaries'),
26
40
  }),
27
41
  handler: async (params) => {
28
- return vault.searchMemories(params.query as string, {
42
+ const memories = vault.searchMemories(params.query as string, {
29
43
  type: params.type as string | undefined,
30
44
  projectPath: params.projectPath as string | undefined,
31
45
  limit: (params.limit as number) ?? 10,
32
46
  });
47
+ if (params.verbose) {
48
+ return { results: memories, total: memories.length };
49
+ }
50
+ return {
51
+ results: memories.map((m) => ({
52
+ id: m.id,
53
+ summary: truncateSummary(m.summary || m.context),
54
+ score: null,
55
+ project: m.projectPath,
56
+ })),
57
+ total: memories.length,
58
+ };
33
59
  },
34
60
  },
35
61
  {
@@ -65,13 +91,19 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
65
91
  },
66
92
  {
67
93
  name: 'memory_list',
68
- description: 'List memories with optional filters.',
94
+ description:
95
+ 'List memories with optional filters. Returns summaries by default; pass verbose: true for full objects.',
69
96
  auth: 'read',
70
97
  schema: z.object({
71
98
  type: z.enum(['session', 'lesson', 'preference']).optional(),
72
99
  projectPath: z.string().optional(),
73
100
  limit: z.number().optional(),
74
101
  offset: z.number().optional(),
102
+ verbose: z
103
+ .boolean()
104
+ .optional()
105
+ .default(false)
106
+ .describe('Return full memory objects instead of summaries'),
75
107
  }),
76
108
  handler: async (params) => {
77
109
  const memories = vault.listMemories({
@@ -81,7 +113,18 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
81
113
  offset: (params.offset as number) ?? 0,
82
114
  });
83
115
  const stats = vault.memoryStats();
84
- return { memories, stats };
116
+ if (params.verbose) {
117
+ return { memories, stats };
118
+ }
119
+ return {
120
+ entries: memories.map((m) => ({
121
+ id: m.id,
122
+ summary: truncateSummary(m.summary || m.context),
123
+ project: m.projectPath,
124
+ createdAt: m.createdAt,
125
+ })),
126
+ total: stats.total,
127
+ };
85
128
  },
86
129
  },
87
130
  {
@@ -91,7 +134,11 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
91
134
  auth: 'write',
92
135
  schema: z.object({
93
136
  projectPath: z.string().optional().default('.'),
94
- summary: z.string().describe('Brief summary of what was accomplished'),
137
+ summary: z.string().optional().describe('Brief summary of what was accomplished'),
138
+ conversationContext: z
139
+ .string()
140
+ .optional()
141
+ .describe('Alias for summary — brief summary of what was accomplished'),
95
142
  topics: z.array(z.string()).optional().default([]),
96
143
  filesModified: z.array(z.string()).optional().default([]),
97
144
  toolsUsed: z.array(z.string()).optional().default([]),
@@ -107,11 +154,15 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
107
154
  handler: async (params) => {
108
155
  const { resolve } = await import('node:path');
109
156
  const projectPath = resolve((params.projectPath as string) ?? '.');
157
+ const summary = (params.summary ?? params.conversationContext) as string;
158
+ if (!summary) {
159
+ return { captured: false, error: 'Either summary or conversationContext is required.' };
160
+ }
110
161
  const memory = vault.captureMemory({
111
162
  projectPath,
112
163
  type: 'session',
113
164
  context: 'Auto-captured before context compaction',
114
- summary: params.summary as string,
165
+ summary,
115
166
  topics: (params.topics as string[]) ?? [],
116
167
  filesModified: (params.filesModified as string[]) ?? [],
117
168
  toolsUsed: (params.toolsUsed as string[]) ?? [],
@@ -121,6 +172,27 @@ export function createMemoryFacadeOps(runtime: AgentRuntime): OpDefinition[] {
121
172
  nextSteps: (params.nextSteps as string[]) ?? [],
122
173
  vaultEntriesReferenced: (params.vaultEntriesReferenced as string[]) ?? [],
123
174
  });
175
+ // ─── Auto-signal extraction (never breaks session_capture) ───
176
+ try {
177
+ if (runtime.operatorProfile) {
178
+ const sessionData: SessionCaptureData = {
179
+ sessionId: memory.id ?? `session-${Date.now()}`,
180
+ intent: (params.intent as string) ?? null,
181
+ capturedAt: new Date().toISOString(),
182
+ toolsUsed: (params.toolsUsed as string[]) ?? null,
183
+ filesModified: (params.filesModified as string[]) ?? null,
184
+ decisions: (params.decisions as string[]) ?? null,
185
+ summary: summary ?? null,
186
+ };
187
+ const signals = extractFromSession(sessionData);
188
+ if (signals.length > 0) {
189
+ runtime.operatorProfile.accumulateSignals(signals);
190
+ }
191
+ }
192
+ } catch {
193
+ // Signal extraction must never break session_capture
194
+ }
195
+
124
196
  return { captured: true, memory, message: 'Session summary saved to memory.' };
125
197
  },
126
198
  },
@@ -0,0 +1,221 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { Vault } from '../../vault/vault.js';
3
+ import { OperatorProfileStore } from '../../operator/operator-profile.js';
4
+ import { SignalType } from '../../operator/operator-types.js';
5
+ import { createOperatorFacadeOps } from './operator-facade.js';
6
+ import { captureOps, executeOp } from '../../engine/test-helpers.js';
7
+ import type { CapturedOp } from '../../engine/test-helpers.js';
8
+ import type { AgentRuntime } from '../types.js';
9
+
10
+ // ─── Helpers ────────────────────────────────────────────────────────
11
+
12
+ function makeRuntime(vault: Vault, store: OperatorProfileStore): AgentRuntime {
13
+ return { operatorProfile: store, vault } as unknown as AgentRuntime;
14
+ }
15
+
16
+ function makeSignalPayload(type: SignalType = SignalType.CommandStyle) {
17
+ return {
18
+ id: `sig-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
19
+ signalType: type,
20
+ data: { style: 'terse', snippet: 'test' },
21
+ timestamp: new Date().toISOString(),
22
+ sessionId: 'test-session',
23
+ confidence: 0.8,
24
+ };
25
+ }
26
+
27
+ // ─── Tests ──────────────────────────────────────────────────────────
28
+
29
+ describe('operator-facade (colocated)', () => {
30
+ let vault: Vault;
31
+ let store: OperatorProfileStore;
32
+ let ops: Map<string, CapturedOp>;
33
+
34
+ beforeEach(() => {
35
+ vault = new Vault(':memory:');
36
+ store = new OperatorProfileStore(vault);
37
+ ops = captureOps(createOperatorFacadeOps(makeRuntime(vault, store)));
38
+ });
39
+
40
+ afterEach(() => {
41
+ vault.close();
42
+ });
43
+
44
+ it('registers all 10 ops', () => {
45
+ expect(ops.size).toBe(10);
46
+ expect([...ops.keys()]).toEqual(
47
+ expect.arrayContaining([
48
+ 'profile_get',
49
+ 'profile_update_section',
50
+ 'profile_correct',
51
+ 'profile_delete',
52
+ 'profile_export',
53
+ 'signal_accumulate',
54
+ 'signal_list',
55
+ 'signal_stats',
56
+ 'synthesis_check',
57
+ 'profile_snapshot',
58
+ ]),
59
+ );
60
+ });
61
+
62
+ it('has correct auth levels', () => {
63
+ expect(ops.get('profile_get')!.auth).toBe('read');
64
+ expect(ops.get('profile_update_section')!.auth).toBe('write');
65
+ expect(ops.get('profile_correct')!.auth).toBe('write');
66
+ expect(ops.get('profile_delete')!.auth).toBe('admin');
67
+ expect(ops.get('profile_export')!.auth).toBe('read');
68
+ expect(ops.get('signal_accumulate')!.auth).toBe('write');
69
+ expect(ops.get('signal_list')!.auth).toBe('read');
70
+ expect(ops.get('signal_stats')!.auth).toBe('read');
71
+ expect(ops.get('synthesis_check')!.auth).toBe('read');
72
+ expect(ops.get('profile_snapshot')!.auth).toBe('write');
73
+ });
74
+
75
+ // ─── profile_get ───────────────────────────────────────────────
76
+
77
+ it('profile_get returns null when no profile', async () => {
78
+ const result = await executeOp(ops, 'profile_get', {});
79
+ expect(result.success).toBe(true);
80
+ expect((result.data as { profile: null }).profile).toBeNull();
81
+ });
82
+
83
+ it('profile_get returns specific section', async () => {
84
+ store.accumulateSignals([makeSignalPayload() as never]);
85
+ const result = await executeOp(ops, 'profile_get', { section: 'communication' });
86
+ expect(result.success).toBe(true);
87
+ expect((result.data as { section: string }).section).toBe('communication');
88
+ });
89
+
90
+ // ─── profile_update_section ────────────────────────────────────
91
+
92
+ it('profile_update_section updates section', async () => {
93
+ const result = await executeOp(ops, 'profile_update_section', {
94
+ section: 'communication',
95
+ data: {
96
+ style: 'concise',
97
+ signalWords: ['yo'],
98
+ formality: 0.3,
99
+ patience: 0.9,
100
+ adaptationRules: [],
101
+ },
102
+ });
103
+ expect(result.success).toBe(true);
104
+ expect((result.data as Record<string, unknown>).updated).toBe(true);
105
+ });
106
+
107
+ // ─── profile_correct ──────────────────────────────────────────
108
+
109
+ it('profile_correct takes snapshot before correcting', async () => {
110
+ store.accumulateSignals([makeSignalPayload() as never]);
111
+ const result = await executeOp(ops, 'profile_correct', {
112
+ section: 'identity',
113
+ data: { background: 'engineer', role: 'lead', philosophy: 'pragmatism', evidence: [] },
114
+ reason: 'User correction',
115
+ });
116
+ expect(result.success).toBe(true);
117
+ expect((result.data as Record<string, unknown>).corrected).toBe(true);
118
+ });
119
+
120
+ // ─── profile_delete ────────────────────────────────────────────
121
+
122
+ it('profile_delete removes profile', async () => {
123
+ store.accumulateSignals([makeSignalPayload() as never]);
124
+ const result = await executeOp(ops, 'profile_delete', {});
125
+ expect(result.success).toBe(true);
126
+ expect((result.data as Record<string, unknown>).deleted).toBe(true);
127
+ expect(store.getProfile()).toBeNull();
128
+ });
129
+
130
+ it('profile_delete returns false when no profile', async () => {
131
+ const result = await executeOp(ops, 'profile_delete', {});
132
+ expect(result.success).toBe(true);
133
+ expect((result.data as Record<string, unknown>).deleted).toBe(false);
134
+ });
135
+
136
+ // ─── profile_export ────────────────────────────────────────────
137
+
138
+ it('profile_export returns JSON by default', async () => {
139
+ store.accumulateSignals([makeSignalPayload() as never]);
140
+ const result = await executeOp(ops, 'profile_export', {});
141
+ expect(result.success).toBe(true);
142
+ const data = result.data as { exported: boolean; format: string; content: string };
143
+ expect(data.exported).toBe(true);
144
+ expect(data.format).toBe('json');
145
+ expect(() => JSON.parse(data.content)).not.toThrow();
146
+ });
147
+
148
+ it('profile_export returns markdown', async () => {
149
+ store.accumulateSignals([makeSignalPayload() as never]);
150
+ const result = await executeOp(ops, 'profile_export', { format: 'markdown' });
151
+ expect(result.success).toBe(true);
152
+ expect((result.data as { content: string }).content).toContain('# Operator Profile');
153
+ });
154
+
155
+ it('profile_export handles missing profile', async () => {
156
+ const result = await executeOp(ops, 'profile_export', {});
157
+ expect(result.success).toBe(true);
158
+ expect((result.data as Record<string, unknown>).exported).toBe(false);
159
+ });
160
+
161
+ // ─── signal_accumulate ─────────────────────────────────────────
162
+
163
+ it('signal_accumulate stores signals', async () => {
164
+ const signals = [makeSignalPayload(), makeSignalPayload(SignalType.Frustration)];
165
+ signals[1].data = { level: 'mild', trigger: 'slow', context: 'test' };
166
+ const result = await executeOp(ops, 'signal_accumulate', { signals });
167
+ expect(result.success).toBe(true);
168
+ expect((result.data as Record<string, unknown>).stored).toBe(2);
169
+ });
170
+
171
+ // ─── signal_list ───────────────────────────────────────────────
172
+
173
+ it('signal_list returns stored signals', async () => {
174
+ store.accumulateSignals([makeSignalPayload() as never]);
175
+ const result = await executeOp(ops, 'signal_list', {});
176
+ expect(result.success).toBe(true);
177
+ expect((result.data as Record<string, unknown>).count).toBe(1);
178
+ });
179
+
180
+ it('signal_list filters by type', async () => {
181
+ store.accumulateSignals([makeSignalPayload(SignalType.CommandStyle) as never]);
182
+ store.accumulateSignals([makeSignalPayload(SignalType.Frustration) as never]);
183
+ const result = await executeOp(ops, 'signal_list', { types: ['command_style'] });
184
+ expect(result.success).toBe(true);
185
+ expect((result.data as Record<string, unknown>).count).toBe(1);
186
+ });
187
+
188
+ // ─── signal_stats ──────────────────────────────────────────────
189
+
190
+ it('signal_stats returns breakdown', async () => {
191
+ store.accumulateSignals([makeSignalPayload() as never, makeSignalPayload() as never]);
192
+ const result = await executeOp(ops, 'signal_stats', {});
193
+ expect(result.success).toBe(true);
194
+ const data = result.data as { byType: Record<string, number>; totalUnprocessed: number };
195
+ expect(data.totalUnprocessed).toBe(2);
196
+ });
197
+
198
+ // ─── synthesis_check ───────────────────────────────────────────
199
+
200
+ it('synthesis_check reports not due with few signals', async () => {
201
+ store.accumulateSignals([makeSignalPayload() as never]);
202
+ const result = await executeOp(ops, 'synthesis_check', {});
203
+ expect(result.success).toBe(true);
204
+ expect((result.data as Record<string, unknown>).due).toBe(false);
205
+ });
206
+
207
+ // ─── profile_snapshot ──────────────────────────────────────────
208
+
209
+ it('profile_snapshot creates version', async () => {
210
+ store.accumulateSignals([makeSignalPayload() as never]);
211
+ const result = await executeOp(ops, 'profile_snapshot', { trigger: 'manual' });
212
+ expect(result.success).toBe(true);
213
+ expect((result.data as Record<string, unknown>).snapshotted).toBe(true);
214
+ });
215
+
216
+ it('profile_snapshot returns false when no profile', async () => {
217
+ const result = await executeOp(ops, 'profile_snapshot', { trigger: 'test' });
218
+ expect(result.success).toBe(true);
219
+ expect((result.data as Record<string, unknown>).snapshotted).toBe(false);
220
+ });
221
+ });