@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,235 @@
1
+ /**
2
+ * Colocated tests for register-engine.ts
3
+ *
4
+ * Validates registerEngine() registration mechanics:
5
+ * - Module tool naming convention
6
+ * - Engine module ordering and completeness
7
+ * - Core ops registration
8
+ * - Domain and domain pack registration
9
+ * - Hot ops as standalone tools
10
+ * - Auth policy enforcement
11
+ * - Error handling for unknown ops
12
+ * - Dynamic tool registration (registerTool)
13
+ */
14
+
15
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
16
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
17
+ import { createAgentRuntime } from '../runtime/runtime.js';
18
+ import { registerEngine, ENGINE_MODULES } from './register-engine.js';
19
+ import { ENGINE_MODULE_MANIFEST } from './module-manifest.js';
20
+ import type { AgentRuntime } from '../runtime/types.js';
21
+ import type { OpDefinition } from '../facades/types.js';
22
+
23
+ let runtime: AgentRuntime;
24
+
25
+ beforeAll(() => {
26
+ runtime = createAgentRuntime({
27
+ agentId: 'reg-test',
28
+ vaultPath: ':memory:',
29
+ });
30
+ });
31
+
32
+ afterAll(() => {
33
+ runtime.close();
34
+ });
35
+
36
+ function makeServer(): McpServer {
37
+ return new McpServer({ name: 'test-server', version: '1.0.0' });
38
+ }
39
+
40
+ describe('registerEngine — tool naming', () => {
41
+ it('prefixes all tools with agentId', () => {
42
+ const server = makeServer();
43
+ const result = registerEngine(server, runtime, { agentId: 'mybot' });
44
+ for (const tool of result.tools) {
45
+ expect(tool.startsWith('mybot_')).toBe(true);
46
+ }
47
+ });
48
+
49
+ it('creates {agentId}_{suffix} for each engine module', () => {
50
+ const server = makeServer();
51
+ const result = registerEngine(server, runtime, { agentId: 'alfa' });
52
+ const expectedSuffixes = ENGINE_MODULES.map((m) => m.suffix);
53
+ for (const suffix of expectedSuffixes) {
54
+ expect(result.tools).toContain(`alfa_${suffix}`);
55
+ }
56
+ });
57
+ });
58
+
59
+ describe('registerEngine — module completeness', () => {
60
+ it('ENGINE_MODULES matches ENGINE_MODULE_MANIFEST suffixes', () => {
61
+ const moduleSuffixes = ENGINE_MODULES.map((m) => m.suffix);
62
+ const manifestSuffixes = ENGINE_MODULE_MANIFEST.map((m) => m.suffix);
63
+ expect(moduleSuffixes).toEqual(manifestSuffixes);
64
+ });
65
+
66
+ it('ENGINE_MODULES and manifest have same count', () => {
67
+ expect(ENGINE_MODULES.length).toBe(ENGINE_MODULE_MANIFEST.length);
68
+ });
69
+
70
+ it('registers all unconditional modules', () => {
71
+ const server = makeServer();
72
+ const result = registerEngine(server, runtime, { agentId: 'check' });
73
+ const unconditional = ENGINE_MODULES.filter((m) => !m.condition);
74
+ for (const mod of unconditional) {
75
+ expect(result.tools).toContain(`check_${mod.suffix}`);
76
+ }
77
+ });
78
+ });
79
+
80
+ describe('registerEngine — module ordering', () => {
81
+ it('registers vault before brain (dependency order)', () => {
82
+ const server = makeServer();
83
+ const result = registerEngine(server, runtime, { agentId: 'ord' });
84
+ const vaultIdx = result.tools.indexOf('ord_vault');
85
+ const brainIdx = result.tools.indexOf('ord_brain');
86
+ expect(vaultIdx).toBeLessThan(brainIdx);
87
+ });
88
+
89
+ it('registers vault as the first engine module tool', () => {
90
+ const server = makeServer();
91
+ const result = registerEngine(server, runtime, { agentId: 'first' });
92
+ expect(result.tools[0]).toBe('first_vault');
93
+ });
94
+ });
95
+
96
+ describe('registerEngine — core ops', () => {
97
+ it('registers core facade when coreOps provided', () => {
98
+ const server = makeServer();
99
+ const coreOps: OpDefinition[] = [
100
+ {
101
+ name: 'health',
102
+ description: 'Health check',
103
+ auth: 'read',
104
+ handler: async () => ({ ok: true }),
105
+ },
106
+ ];
107
+ const result = registerEngine(server, runtime, { agentId: 'core', coreOps });
108
+ expect(result.tools).toContain('core_core');
109
+ expect(result.totalOps).toBeGreaterThan(ENGINE_MODULES.length); // at least 1 per module + 1 core
110
+ });
111
+
112
+ it('does not register core facade when coreOps is empty', () => {
113
+ const server = makeServer();
114
+ const result = registerEngine(server, runtime, { agentId: 'nocore', coreOps: [] });
115
+ expect(result.tools).not.toContain('nocore_core');
116
+ });
117
+
118
+ it('does not register core facade when coreOps is undefined', () => {
119
+ const server = makeServer();
120
+ const result = registerEngine(server, runtime, { agentId: 'nocore2' });
121
+ expect(result.tools).not.toContain('nocore2_core');
122
+ });
123
+ });
124
+
125
+ describe('registerEngine — hot ops', () => {
126
+ it('registers hot ops as standalone tools', () => {
127
+ const server = makeServer();
128
+ const result = registerEngine(server, runtime, {
129
+ agentId: 'hot',
130
+ hotOps: ['search_intelligent', 'capture_knowledge'],
131
+ });
132
+ expect(result.tools).toContain('hot_search_intelligent');
133
+ expect(result.tools).toContain('hot_capture_knowledge');
134
+ });
135
+
136
+ it('counts hot ops in totalOps', () => {
137
+ const server = makeServer();
138
+ const baseResult = registerEngine(server, runtime, { agentId: 'base' });
139
+
140
+ const server2 = makeServer();
141
+ const hotResult = registerEngine(server2, runtime, {
142
+ agentId: 'hotcount',
143
+ hotOps: ['search_intelligent'],
144
+ });
145
+ // Hot ops don't add to totalOps (they mirror existing ops)
146
+ // But they do add to tools array
147
+ expect(hotResult.tools.length).toBeGreaterThan(baseResult.tools.length);
148
+ });
149
+ });
150
+
151
+ describe('registerEngine — domains', () => {
152
+ it('registers domain facades with correct naming', () => {
153
+ const server = makeServer();
154
+ const result = registerEngine(server, runtime, {
155
+ agentId: 'dom',
156
+ domains: ['testing', 'architecture'],
157
+ });
158
+ expect(result.tools).toContain('dom_testing');
159
+ expect(result.tools).toContain('dom_architecture');
160
+ });
161
+
162
+ it('increments totalOps for domain facade ops', () => {
163
+ const server1 = makeServer();
164
+ const noDomains = registerEngine(server1, runtime, { agentId: 'nod' });
165
+
166
+ const server2 = makeServer();
167
+ const withDomains = registerEngine(server2, runtime, {
168
+ agentId: 'wd',
169
+ domains: ['testing'],
170
+ });
171
+ expect(withDomains.totalOps).toBeGreaterThan(noDomains.totalOps);
172
+ });
173
+ });
174
+
175
+ describe('registerEngine — domain packs', () => {
176
+ it('registers domain pack facades with agentId prefix', () => {
177
+ const server = makeServer();
178
+ const packOp: OpDefinition = {
179
+ name: 'custom_search',
180
+ description: 'Custom search',
181
+ auth: 'read',
182
+ handler: async () => [],
183
+ };
184
+ const result = registerEngine(server, runtime, {
185
+ agentId: 'pk',
186
+ domainPacks: [{ name: 'my-pack', facades: [{ name: 'custom', ops: [packOp] }] }],
187
+ });
188
+ expect(result.tools).toContain('pk_custom');
189
+ });
190
+
191
+ it('skips packs without facades', () => {
192
+ const server = makeServer();
193
+ const result = registerEngine(server, runtime, {
194
+ agentId: 'skip',
195
+ domainPacks: [{ name: 'empty-pack' }],
196
+ });
197
+ // Should still register normally without errors
198
+ expect(result.tools.length).toBeGreaterThan(0);
199
+ });
200
+ });
201
+
202
+ describe('registerEngine — return value', () => {
203
+ it('returns tools array, totalOps count, and registerTool function', () => {
204
+ const server = makeServer();
205
+ const result = registerEngine(server, runtime, { agentId: 'ret' });
206
+ expect(Array.isArray(result.tools)).toBe(true);
207
+ expect(typeof result.totalOps).toBe('number');
208
+ expect(typeof result.registerTool).toBe('function');
209
+ expect(result.totalOps).toBeGreaterThan(0);
210
+ });
211
+
212
+ it('registerTool adds a new tool at runtime', () => {
213
+ const server = makeServer();
214
+ const result = registerEngine(server, runtime, { agentId: 'dyn' });
215
+ const initialCount = result.tools.length;
216
+
217
+ result.registerTool('dyn_extra', 'Extra tool', [
218
+ { name: 'ping', description: 'Ping', auth: 'read', handler: async () => 'pong' },
219
+ ]);
220
+
221
+ expect(result.tools.length).toBe(initialCount + 1);
222
+ expect(result.tools).toContain('dyn_extra');
223
+ });
224
+ });
225
+
226
+ describe('ENGINE_MODULES descriptions match manifest', () => {
227
+ it('each module description aligns with manifest', () => {
228
+ for (let i = 0; i < ENGINE_MODULES.length; i++) {
229
+ const mod = ENGINE_MODULES[i];
230
+ const manifest = ENGINE_MODULE_MANIFEST[i];
231
+ expect(mod.suffix).toBe(manifest.suffix);
232
+ // Descriptions may diverge slightly but suffix must match
233
+ }
234
+ });
235
+ });
@@ -35,6 +35,14 @@ import { createControlFacadeOps } from '../runtime/facades/control-facade.js';
35
35
  import { createContextFacadeOps } from '../runtime/facades/context-facade.js';
36
36
  import { createAgencyFacadeOps } from '../runtime/facades/agency-facade.js';
37
37
  import { createChatFacadeOps } from '../runtime/facades/chat-facade.js';
38
+ import { createOperatorFacadeOps } from '../runtime/facades/operator-facade.js';
39
+ import { createArchiveFacadeOps } from '../runtime/facades/archive-facade.js';
40
+ import { createSyncFacadeOps } from '../runtime/facades/sync-facade.js';
41
+ import { createReviewFacadeOps } from '../runtime/facades/review-facade.js';
42
+ import { createIntakeFacadeOps } from '../runtime/facades/intake-facade.js';
43
+ import { createLinksFacadeOps } from '../runtime/facades/links-facade.js';
44
+ import { createBranchingFacadeOps } from '../runtime/facades/branching-facade.js';
45
+ import { createTierFacadeOps } from '../runtime/facades/tier-facade.js';
38
46
  import { createDomainFacade } from '../runtime/domain-ops.js';
39
47
 
40
48
  // ─── Types ────────────────────────────────────────────────────────────
@@ -84,7 +92,7 @@ interface ModuleDef {
84
92
  export const ENGINE_MODULES: ModuleDef[] = [
85
93
  {
86
94
  suffix: 'vault',
87
- description: 'Knowledge management — search, CRUD, import/export, intake, archival.',
95
+ description: 'Knowledge management — search, CRUD, capture, sharing scope.',
88
96
  createOps: createVaultFacadeOps,
89
97
  },
90
98
  {
@@ -119,8 +127,7 @@ export const ENGINE_MODULES: ModuleDef[] = [
119
127
  },
120
128
  {
121
129
  suffix: 'orchestrate',
122
- description:
123
- 'Execution orchestration — project registration, playbooks, plan/execute/complete.',
130
+ description: 'Execution orchestration — session start, playbooks, plan/execute/complete.',
124
131
  createOps: createOrchestrateFacadeOps,
125
132
  },
126
133
  {
@@ -143,6 +150,46 @@ export const ENGINE_MODULES: ModuleDef[] = [
143
150
  description: 'Chat transport — session management, response chunking, authentication.',
144
151
  createOps: createChatFacadeOps,
145
152
  },
153
+ {
154
+ suffix: 'operator',
155
+ description: 'Operator profile — personality learning, signals, adaptation.',
156
+ createOps: createOperatorFacadeOps,
157
+ },
158
+ {
159
+ suffix: 'archive',
160
+ description: 'Archival, lifecycle, and knowledge maintenance.',
161
+ createOps: createArchiveFacadeOps,
162
+ },
163
+ {
164
+ suffix: 'sync',
165
+ description: 'Git, Obsidian, and pack sync operations.',
166
+ createOps: createSyncFacadeOps,
167
+ },
168
+ {
169
+ suffix: 'review',
170
+ description: 'Knowledge review workflow.',
171
+ createOps: createReviewFacadeOps,
172
+ },
173
+ {
174
+ suffix: 'intake',
175
+ description: 'Content ingestion — books, URLs, text, batch import.',
176
+ createOps: createIntakeFacadeOps,
177
+ },
178
+ {
179
+ suffix: 'links',
180
+ description: 'Entry linking — create, traverse, suggest, orphan detection.',
181
+ createOps: createLinksFacadeOps,
182
+ },
183
+ {
184
+ suffix: 'branching',
185
+ description: 'Vault branching — create, list, merge, delete branches.',
186
+ createOps: createBranchingFacadeOps,
187
+ },
188
+ {
189
+ suffix: 'tier',
190
+ description: 'Multi-vault tiers — connect, disconnect, search across sources.',
191
+ createOps: createTierFacadeOps,
192
+ },
146
193
  ];
147
194
 
148
195
  // ─── Core Registration ────────────────────────────────────────────────
@@ -0,0 +1,203 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { classifyError } from './classify.js';
3
+ import { SoleriError, SoleriErrorCode } from './types.js';
4
+
5
+ describe('classifyError', () => {
6
+ describe('passthrough', () => {
7
+ it('should return a SoleriError as-is', () => {
8
+ const original = new SoleriError('already classified', SoleriErrorCode.TIMEOUT);
9
+ const result = classifyError(original);
10
+ expect(result).toBe(original);
11
+ });
12
+ });
13
+
14
+ describe('HTTP status classification', () => {
15
+ it('should classify 401 as AUTH', () => {
16
+ const result = classifyError({ status: 401, message: 'Unauthorized' });
17
+ expect(result.code).toBe(SoleriErrorCode.AUTH);
18
+ expect(result.context).toEqual({ httpStatus: 401 });
19
+ });
20
+
21
+ it('should classify 403 as AUTH', () => {
22
+ const result = classifyError({ status: 403, message: 'Forbidden' });
23
+ expect(result.code).toBe(SoleriErrorCode.AUTH);
24
+ });
25
+
26
+ it('should classify 404 as RESOURCE_NOT_FOUND', () => {
27
+ const result = classifyError({ statusCode: 404, message: 'Not found' });
28
+ expect(result.code).toBe(SoleriErrorCode.RESOURCE_NOT_FOUND);
29
+ });
30
+
31
+ it('should classify 408 as TIMEOUT', () => {
32
+ const result = classifyError({ status: 408, message: 'Request Timeout' });
33
+ expect(result.code).toBe(SoleriErrorCode.TIMEOUT);
34
+ });
35
+
36
+ it('should classify 429 as RATE_LIMIT', () => {
37
+ const result = classifyError({ status: 429, message: 'Too Many Requests' });
38
+ expect(result.code).toBe(SoleriErrorCode.RATE_LIMIT);
39
+ });
40
+
41
+ it('should classify 422 as VALIDATION', () => {
42
+ const result = classifyError({ status: 422, message: 'Unprocessable' });
43
+ expect(result.code).toBe(SoleriErrorCode.VALIDATION);
44
+ });
45
+
46
+ it('should classify 500 as INTERNAL', () => {
47
+ const result = classifyError({ status: 500, message: 'Server Error' });
48
+ expect(result.code).toBe(SoleriErrorCode.INTERNAL);
49
+ });
50
+
51
+ it('should classify 503 as INTERNAL', () => {
52
+ const result = classifyError({ status: 503, message: 'Service Unavailable' });
53
+ expect(result.code).toBe(SoleriErrorCode.INTERNAL);
54
+ });
55
+
56
+ it('should prefer statusCode when status is absent', () => {
57
+ const result = classifyError({ statusCode: 429, message: 'throttled' });
58
+ expect(result.code).toBe(SoleriErrorCode.RATE_LIMIT);
59
+ });
60
+ });
61
+
62
+ describe('Node.js error code classification', () => {
63
+ it('should classify ECONNREFUSED as NETWORK', () => {
64
+ const err = Object.assign(new Error('connect failed'), { code: 'ECONNREFUSED' });
65
+ const result = classifyError(err);
66
+ expect(result.code).toBe(SoleriErrorCode.NETWORK);
67
+ expect(result.context).toEqual({ errorCode: 'ECONNREFUSED' });
68
+ });
69
+
70
+ it('should classify ENOTFOUND as NETWORK', () => {
71
+ const err = Object.assign(new Error('dns fail'), { code: 'ENOTFOUND' });
72
+ expect(classifyError(err).code).toBe(SoleriErrorCode.NETWORK);
73
+ });
74
+
75
+ it('should classify ECONNRESET as NETWORK', () => {
76
+ const err = Object.assign(new Error('reset'), { code: 'ECONNRESET' });
77
+ expect(classifyError(err).code).toBe(SoleriErrorCode.NETWORK);
78
+ });
79
+
80
+ it('should classify ETIMEDOUT as TIMEOUT', () => {
81
+ const err = Object.assign(new Error('timed out'), { code: 'ETIMEDOUT' });
82
+ expect(classifyError(err).code).toBe(SoleriErrorCode.TIMEOUT);
83
+ });
84
+
85
+ it('should classify ESOCKETTIMEDOUT as TIMEOUT', () => {
86
+ const err = Object.assign(new Error('socket'), { code: 'ESOCKETTIMEDOUT' });
87
+ expect(classifyError(err).code).toBe(SoleriErrorCode.TIMEOUT);
88
+ });
89
+
90
+ it('should classify UND_ERR_CONNECT_TIMEOUT as TIMEOUT', () => {
91
+ const err = Object.assign(new Error('undici'), { code: 'UND_ERR_CONNECT_TIMEOUT' });
92
+ expect(classifyError(err).code).toBe(SoleriErrorCode.TIMEOUT);
93
+ });
94
+ });
95
+
96
+ describe('message pattern classification', () => {
97
+ it('should classify "overloaded" as LLM_OVERLOAD', () => {
98
+ expect(classifyError(new Error('server is overloaded')).code).toBe(
99
+ SoleriErrorCode.LLM_OVERLOAD,
100
+ );
101
+ });
102
+
103
+ it('should classify "model busy" as LLM_OVERLOAD', () => {
104
+ expect(classifyError(new Error('model is busy')).code).toBe(SoleriErrorCode.LLM_OVERLOAD);
105
+ });
106
+
107
+ it('should classify "timeout" message as TIMEOUT', () => {
108
+ expect(classifyError(new Error('operation timed out')).code).toBe(SoleriErrorCode.TIMEOUT);
109
+ });
110
+
111
+ it('should classify "sqlite" as VAULT_UNREACHABLE', () => {
112
+ expect(classifyError(new Error('sqlite error')).code).toBe(SoleriErrorCode.VAULT_UNREACHABLE);
113
+ });
114
+
115
+ it('should classify "validation" as VALIDATION', () => {
116
+ expect(classifyError(new Error('validation failed')).code).toBe(SoleriErrorCode.VALIDATION);
117
+ });
118
+
119
+ it('should classify "missing key" as CONFIG_ERROR', () => {
120
+ expect(classifyError(new Error('missing key FOO')).code).toBe(SoleriErrorCode.CONFIG_ERROR);
121
+ });
122
+
123
+ it('should classify "unauthorized" as AUTH', () => {
124
+ expect(classifyError(new Error('unauthorized access')).code).toBe(SoleriErrorCode.AUTH);
125
+ });
126
+
127
+ it('should classify "not found" as RESOURCE_NOT_FOUND', () => {
128
+ expect(classifyError(new Error('resource not found')).code).toBe(
129
+ SoleriErrorCode.RESOURCE_NOT_FOUND,
130
+ );
131
+ });
132
+
133
+ it('should classify "rate limit" as RATE_LIMIT', () => {
134
+ expect(classifyError(new Error('rate limit exceeded')).code).toBe(SoleriErrorCode.RATE_LIMIT);
135
+ });
136
+
137
+ it('should classify "network" as NETWORK', () => {
138
+ expect(classifyError(new Error('network failure')).code).toBe(SoleriErrorCode.NETWORK);
139
+ });
140
+ });
141
+
142
+ describe('fallback classification', () => {
143
+ it('should default to INTERNAL for unknown errors', () => {
144
+ const result = classifyError(new Error('something weird'));
145
+ expect(result.code).toBe(SoleriErrorCode.INTERNAL);
146
+ });
147
+
148
+ it('should handle string thrown values', () => {
149
+ const result = classifyError('a string error');
150
+ expect(result).toBeInstanceOf(SoleriError);
151
+ expect(result.message).toBe('a string error');
152
+ });
153
+
154
+ it('should handle number thrown values', () => {
155
+ const result = classifyError(42);
156
+ expect(result).toBeInstanceOf(SoleriError);
157
+ expect(result.message).toBe('42');
158
+ });
159
+
160
+ it('should handle null thrown values', () => {
161
+ const result = classifyError(null);
162
+ expect(result).toBeInstanceOf(SoleriError);
163
+ });
164
+
165
+ it('should handle undefined thrown values', () => {
166
+ const result = classifyError(undefined);
167
+ expect(result).toBeInstanceOf(SoleriError);
168
+ });
169
+
170
+ it('should handle plain objects with no message', () => {
171
+ const result = classifyError({});
172
+ expect(result).toBeInstanceOf(SoleriError);
173
+ expect(result.message).toBe('Unknown error');
174
+ expect(result.code).toBe(SoleriErrorCode.INTERNAL);
175
+ });
176
+ });
177
+
178
+ describe('priority order', () => {
179
+ it('should prefer HTTP status over message pattern', () => {
180
+ const result = classifyError({ status: 404, message: 'network error not found' });
181
+ expect(result.code).toBe(SoleriErrorCode.RESOURCE_NOT_FOUND);
182
+ });
183
+
184
+ it('should prefer error code over message pattern', () => {
185
+ const err = Object.assign(new Error('timeout in database'), { code: 'ECONNREFUSED' });
186
+ const result = classifyError(err);
187
+ expect(result.code).toBe(SoleriErrorCode.NETWORK);
188
+ });
189
+ });
190
+
191
+ describe('cause preservation', () => {
192
+ it('should preserve original Error as cause', () => {
193
+ const original = new Error('root');
194
+ const result = classifyError(original);
195
+ expect(result.cause).toBe(original);
196
+ });
197
+
198
+ it('should not set cause for non-Error values', () => {
199
+ const result = classifyError('string error');
200
+ expect(result.cause).toBeUndefined();
201
+ });
202
+ });
203
+ });
@@ -0,0 +1,153 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { shouldRetry, getRetryDelay, retryWithPreset, RETRY_PRESETS } from './retry.js';
3
+ import { SoleriError, SoleriErrorCode } from './types.js';
4
+
5
+ describe('RETRY_PRESETS', () => {
6
+ it('should define fast, normal, and patient presets', () => {
7
+ expect(RETRY_PRESETS.fast.maxAttempts).toBe(3);
8
+ expect(RETRY_PRESETS.normal.maxAttempts).toBe(10);
9
+ expect(RETRY_PRESETS.patient.maxAttempts).toBe(25);
10
+ });
11
+ });
12
+
13
+ describe('shouldRetry', () => {
14
+ it('should return true for retryable error below max attempts', () => {
15
+ const error = new SoleriError('timeout', SoleriErrorCode.TIMEOUT);
16
+ expect(shouldRetry(error, 1, 'fast')).toBe(true);
17
+ });
18
+
19
+ it('should return false for retryable error at max attempts', () => {
20
+ const error = new SoleriError('timeout', SoleriErrorCode.TIMEOUT);
21
+ expect(shouldRetry(error, 3, 'fast')).toBe(false);
22
+ });
23
+
24
+ it('should return false for non-retryable error', () => {
25
+ const error = new SoleriError('bad auth', SoleriErrorCode.AUTH);
26
+ expect(shouldRetry(error, 1, 'fast')).toBe(false);
27
+ });
28
+
29
+ it('should return false for fixable error', () => {
30
+ const error = new SoleriError('invalid', SoleriErrorCode.VALIDATION);
31
+ expect(shouldRetry(error, 1, 'normal')).toBe(false);
32
+ });
33
+ });
34
+
35
+ describe('getRetryDelay', () => {
36
+ it('should return a positive number', () => {
37
+ const delay = getRetryDelay(0, 'fast');
38
+ expect(delay).toBeGreaterThanOrEqual(0);
39
+ });
40
+
41
+ it('should increase with attempt number', () => {
42
+ const delays = Array.from({ length: 5 }, (_, i) => {
43
+ // Average over multiple samples to reduce jitter impact
44
+ const samples = Array.from({ length: 100 }, () => getRetryDelay(i, 'normal'));
45
+ return samples.reduce((a, b) => a + b, 0) / samples.length;
46
+ });
47
+ // Each averaged delay should generally be >= the previous
48
+ for (let i = 1; i < delays.length - 1; i++) {
49
+ expect(delays[i]).toBeGreaterThanOrEqual(delays[i - 1] * 0.5);
50
+ }
51
+ });
52
+
53
+ it('should not exceed maxIntervalMs plus jitter', () => {
54
+ const config = RETRY_PRESETS.fast;
55
+ const maxWithJitter = config.maxIntervalMs * 1.25;
56
+ for (let i = 0; i < 20; i++) {
57
+ expect(getRetryDelay(10, 'fast')).toBeLessThanOrEqual(maxWithJitter);
58
+ }
59
+ });
60
+
61
+ it('should never return a negative value', () => {
62
+ for (let i = 0; i < 50; i++) {
63
+ expect(getRetryDelay(0, 'fast')).toBeGreaterThanOrEqual(0);
64
+ }
65
+ });
66
+ });
67
+
68
+ describe('retryWithPreset', () => {
69
+ beforeEach(() => {
70
+ vi.useFakeTimers();
71
+ });
72
+
73
+ afterEach(() => {
74
+ vi.useRealTimers();
75
+ });
76
+
77
+ it('should return ok on first success', async () => {
78
+ const fn = vi.fn().mockResolvedValue('done');
79
+ const resultPromise = retryWithPreset(fn, 'fast');
80
+ const result = await resultPromise;
81
+ expect(result).toEqual({ ok: true, value: 'done' });
82
+ expect(fn).toHaveBeenCalledTimes(1);
83
+ });
84
+
85
+ it('should retry retryable errors and succeed', async () => {
86
+ const fn = vi
87
+ .fn()
88
+ .mockRejectedValueOnce(new Error('network error'))
89
+ .mockResolvedValue('recovered');
90
+
91
+ const resultPromise = retryWithPreset(fn, 'fast');
92
+ // Advance past the sleep delay
93
+ await vi.advanceTimersByTimeAsync(20_000);
94
+ const result = await resultPromise;
95
+ expect(result).toEqual({ ok: true, value: 'recovered' });
96
+ expect(fn).toHaveBeenCalledTimes(2);
97
+ });
98
+
99
+ it('should return err immediately for permanent errors', async () => {
100
+ const fn = vi.fn().mockRejectedValue(new SoleriError('denied', SoleriErrorCode.AUTH));
101
+ const result = await retryWithPreset(fn, 'fast');
102
+ expect(result.ok).toBe(false);
103
+ if (!result.ok) {
104
+ expect(result.error.code).toBe(SoleriErrorCode.AUTH);
105
+ }
106
+ expect(fn).toHaveBeenCalledTimes(1);
107
+ });
108
+
109
+ it('should return err after exhausting all attempts', async () => {
110
+ const fn = vi.fn().mockRejectedValue(new SoleriError('down', SoleriErrorCode.NETWORK));
111
+ const resultPromise = retryWithPreset(fn, 'fast');
112
+ // Advance enough time for all retries
113
+ await vi.advanceTimersByTimeAsync(100_000);
114
+ const result = await resultPromise;
115
+ expect(result.ok).toBe(false);
116
+ expect(fn).toHaveBeenCalledTimes(3);
117
+ });
118
+
119
+ it('should call onRetry callback on each retry', async () => {
120
+ const onRetry = vi.fn();
121
+ const fn = vi.fn().mockRejectedValueOnce(new Error('network fail')).mockResolvedValue('ok');
122
+
123
+ const resultPromise = retryWithPreset(fn, 'fast', { onRetry });
124
+ await vi.advanceTimersByTimeAsync(20_000);
125
+ await resultPromise;
126
+ expect(onRetry).toHaveBeenCalledTimes(1);
127
+ expect(onRetry).toHaveBeenCalledWith(expect.any(SoleriError), 1, expect.any(Number));
128
+ });
129
+
130
+ it('should abort when signal is aborted during sleep', async () => {
131
+ const controller = new AbortController();
132
+ const fn = vi.fn().mockRejectedValue(new Error('network error'));
133
+
134
+ const resultPromise = retryWithPreset(fn, 'fast', { signal: controller.signal });
135
+ // Let the first attempt fail and enter sleep
136
+ await vi.advanceTimersByTimeAsync(0);
137
+ // Abort during sleep
138
+ controller.abort(new Error('cancelled'));
139
+ await vi.advanceTimersByTimeAsync(0);
140
+ const result = await resultPromise;
141
+ expect(result.ok).toBe(false);
142
+ });
143
+
144
+ it('should return err for fixable errors without retrying', async () => {
145
+ const fn = vi.fn().mockRejectedValue(new SoleriError('bad', SoleriErrorCode.VALIDATION));
146
+ const result = await retryWithPreset(fn, 'fast');
147
+ expect(result.ok).toBe(false);
148
+ expect(fn).toHaveBeenCalledTimes(1);
149
+ });
150
+ });
151
+
152
+ // Need to import afterEach at top level
153
+ import { afterEach } from 'vitest';
@@ -104,6 +104,7 @@ export async function retryWithPreset<T>(
104
104
 
105
105
  for (let attempt = 0; attempt < RETRY_PRESETS[preset].maxAttempts; attempt++) {
106
106
  try {
107
+ // oxlint-disable-next-line eslint(no-await-in-loop)
107
108
  const value = await fn();
108
109
  return ok(value);
109
110
  } catch (thrown: unknown) {
@@ -117,6 +118,7 @@ export async function retryWithPreset<T>(
117
118
  options?.onRetry?.(lastError, attempt + 1, delay);
118
119
 
119
120
  try {
121
+ // oxlint-disable-next-line eslint(no-await-in-loop)
120
122
  await sleep(delay, options?.signal);
121
123
  } catch {
122
124
  // Aborted during sleep