@soleri/core 9.0.3 → 9.2.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 (701) hide show
  1. package/dist/brain/intelligence.d.ts +27 -0
  2. package/dist/brain/intelligence.d.ts.map +1 -1
  3. package/dist/brain/intelligence.js +160 -14
  4. package/dist/brain/intelligence.js.map +1 -1
  5. package/dist/brain/learning-radar.d.ts +4 -0
  6. package/dist/brain/learning-radar.d.ts.map +1 -1
  7. package/dist/brain/learning-radar.js +20 -1
  8. package/dist/brain/learning-radar.js.map +1 -1
  9. package/dist/brain/strength-scorer.d.ts +31 -0
  10. package/dist/brain/strength-scorer.d.ts.map +1 -0
  11. package/dist/brain/strength-scorer.js +264 -0
  12. package/dist/brain/strength-scorer.js.map +1 -0
  13. package/dist/chat/agent-loop.d.ts.map +1 -1
  14. package/dist/chat/agent-loop.js +2 -0
  15. package/dist/chat/agent-loop.js.map +1 -1
  16. package/dist/chat/notifications.d.ts.map +1 -1
  17. package/dist/chat/notifications.js +2 -0
  18. package/dist/chat/notifications.js.map +1 -1
  19. package/dist/claudemd/compose.js +1 -1
  20. package/dist/claudemd/compose.js.map +1 -1
  21. package/dist/control/intent-router.d.ts.map +1 -1
  22. package/dist/control/intent-router.js +12 -4
  23. package/dist/control/intent-router.js.map +1 -1
  24. package/dist/curator/contradiction-detector.d.ts +27 -0
  25. package/dist/curator/contradiction-detector.d.ts.map +1 -0
  26. package/dist/curator/contradiction-detector.js +62 -0
  27. package/dist/curator/contradiction-detector.js.map +1 -0
  28. package/dist/curator/curator.d.ts +3 -4
  29. package/dist/curator/curator.d.ts.map +1 -1
  30. package/dist/curator/curator.js +90 -525
  31. package/dist/curator/curator.js.map +1 -1
  32. package/dist/curator/duplicate-detector.d.ts +14 -0
  33. package/dist/curator/duplicate-detector.d.ts.map +1 -0
  34. package/dist/curator/duplicate-detector.js +77 -0
  35. package/dist/curator/duplicate-detector.js.map +1 -0
  36. package/dist/curator/health-audit.d.ts +15 -0
  37. package/dist/curator/health-audit.d.ts.map +1 -0
  38. package/dist/curator/health-audit.js +97 -0
  39. package/dist/curator/health-audit.js.map +1 -0
  40. package/dist/curator/metadata-enricher.d.ts +17 -0
  41. package/dist/curator/metadata-enricher.d.ts.map +1 -0
  42. package/dist/curator/metadata-enricher.js +60 -0
  43. package/dist/curator/metadata-enricher.js.map +1 -0
  44. package/dist/curator/schema.d.ts +7 -0
  45. package/dist/curator/schema.d.ts.map +1 -0
  46. package/dist/curator/schema.js +62 -0
  47. package/dist/curator/schema.js.map +1 -0
  48. package/dist/curator/tag-manager.d.ts +36 -0
  49. package/dist/curator/tag-manager.d.ts.map +1 -0
  50. package/dist/curator/tag-manager.js +78 -0
  51. package/dist/curator/tag-manager.js.map +1 -0
  52. package/dist/engine/bin/soleri-engine.js +55 -3
  53. package/dist/engine/bin/soleri-engine.js.map +1 -1
  54. package/dist/engine/core-ops.d.ts.map +1 -1
  55. package/dist/engine/core-ops.js +33 -10
  56. package/dist/engine/core-ops.js.map +1 -1
  57. package/dist/engine/module-manifest.d.ts.map +1 -1
  58. package/dist/engine/module-manifest.js +22 -2
  59. package/dist/engine/module-manifest.js.map +1 -1
  60. package/dist/engine/register-engine.d.ts.map +1 -1
  61. package/dist/engine/register-engine.js +26 -2
  62. package/dist/engine/register-engine.js.map +1 -1
  63. package/dist/errors/retry.d.ts.map +1 -1
  64. package/dist/errors/retry.js +2 -0
  65. package/dist/errors/retry.js.map +1 -1
  66. package/dist/facades/types.d.ts +1 -1
  67. package/dist/flows/chain-types.d.ts +18 -18
  68. package/dist/flows/gate-evaluator.d.ts.map +1 -1
  69. package/dist/flows/gate-evaluator.js +22 -0
  70. package/dist/flows/gate-evaluator.js.map +1 -1
  71. package/dist/flows/types.d.ts +157 -28
  72. package/dist/flows/types.d.ts.map +1 -1
  73. package/dist/flows/types.js +4 -0
  74. package/dist/flows/types.js.map +1 -1
  75. package/dist/index.d.ts +10 -2
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +9 -1
  78. package/dist/index.js.map +1 -1
  79. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  80. package/dist/intake/intake-pipeline.js +1 -0
  81. package/dist/intake/intake-pipeline.js.map +1 -1
  82. package/dist/intake/text-ingester.d.ts.map +1 -1
  83. package/dist/intake/text-ingester.js +2 -0
  84. package/dist/intake/text-ingester.js.map +1 -1
  85. package/dist/llm/key-pool.d.ts +1 -1
  86. package/dist/llm/key-pool.d.ts.map +1 -1
  87. package/dist/llm/key-pool.js +3 -4
  88. package/dist/llm/key-pool.js.map +1 -1
  89. package/dist/llm/utils.d.ts.map +1 -1
  90. package/dist/llm/utils.js +2 -0
  91. package/dist/llm/utils.js.map +1 -1
  92. package/dist/migrations/migration-runner.test-helpers.d.ts +13 -0
  93. package/dist/migrations/migration-runner.test-helpers.d.ts.map +1 -0
  94. package/dist/migrations/migration-runner.test-helpers.js +47 -0
  95. package/dist/migrations/migration-runner.test-helpers.js.map +1 -0
  96. package/dist/operator/operator-profile.d.ts +44 -0
  97. package/dist/operator/operator-profile.d.ts.map +1 -0
  98. package/dist/operator/operator-profile.js +377 -0
  99. package/dist/operator/operator-profile.js.map +1 -0
  100. package/dist/operator/operator-signals.d.ts +45 -0
  101. package/dist/operator/operator-signals.d.ts.map +1 -0
  102. package/dist/operator/operator-signals.js +228 -0
  103. package/dist/operator/operator-signals.js.map +1 -0
  104. package/dist/operator/operator-types.d.ts +360 -0
  105. package/dist/operator/operator-types.d.ts.map +1 -0
  106. package/dist/operator/operator-types.js +24 -0
  107. package/dist/operator/operator-types.js.map +1 -0
  108. package/dist/packs/types.d.ts +27 -27
  109. package/dist/paths.d.ts +40 -0
  110. package/dist/paths.d.ts.map +1 -0
  111. package/dist/paths.js +98 -0
  112. package/dist/paths.js.map +1 -0
  113. package/dist/persistence/index.d.ts +1 -1
  114. package/dist/persistence/index.d.ts.map +1 -1
  115. package/dist/persistence/index.js +1 -1
  116. package/dist/persistence/index.js.map +1 -1
  117. package/dist/persistence/sqlite-provider.d.ts +2 -0
  118. package/dist/persistence/sqlite-provider.d.ts.map +1 -1
  119. package/dist/persistence/sqlite-provider.js +8 -5
  120. package/dist/persistence/sqlite-provider.js.map +1 -1
  121. package/dist/planning/evidence-collector.d.ts +13 -1
  122. package/dist/planning/evidence-collector.d.ts.map +1 -1
  123. package/dist/planning/evidence-collector.js +33 -0
  124. package/dist/planning/evidence-collector.js.map +1 -1
  125. package/dist/planning/gap-analysis.d.ts +5 -4
  126. package/dist/planning/gap-analysis.d.ts.map +1 -1
  127. package/dist/planning/gap-analysis.js +7 -341
  128. package/dist/planning/gap-analysis.js.map +1 -1
  129. package/dist/planning/gap-passes.d.ts +19 -0
  130. package/dist/planning/gap-passes.d.ts.map +1 -0
  131. package/dist/planning/gap-passes.js +157 -0
  132. package/dist/planning/gap-passes.js.map +1 -0
  133. package/dist/planning/gap-patterns.d.ts +29 -0
  134. package/dist/planning/gap-patterns.d.ts.map +1 -0
  135. package/dist/planning/gap-patterns.js +129 -0
  136. package/dist/planning/gap-patterns.js.map +1 -0
  137. package/dist/planning/gap-types.d.ts +1 -1
  138. package/dist/planning/gap-types.d.ts.map +1 -1
  139. package/dist/planning/gap-types.js +1 -0
  140. package/dist/planning/gap-types.js.map +1 -1
  141. package/dist/planning/github-projection.d.ts +122 -0
  142. package/dist/planning/github-projection.d.ts.map +1 -0
  143. package/dist/planning/github-projection.js +294 -0
  144. package/dist/planning/github-projection.js.map +1 -0
  145. package/dist/planning/impact-analyzer.d.ts +26 -0
  146. package/dist/planning/impact-analyzer.d.ts.map +1 -0
  147. package/dist/planning/impact-analyzer.js +199 -0
  148. package/dist/planning/impact-analyzer.js.map +1 -0
  149. package/dist/planning/plan-lifecycle.d.ts +136 -0
  150. package/dist/planning/plan-lifecycle.d.ts.map +1 -0
  151. package/dist/planning/plan-lifecycle.js +296 -0
  152. package/dist/planning/plan-lifecycle.js.map +1 -0
  153. package/dist/planning/planner-types.d.ts +202 -0
  154. package/dist/planning/planner-types.d.ts.map +1 -0
  155. package/dist/planning/planner-types.js +6 -0
  156. package/dist/planning/planner-types.js.map +1 -0
  157. package/dist/planning/planner.d.ts +31 -383
  158. package/dist/planning/planner.d.ts.map +1 -1
  159. package/dist/planning/planner.js +154 -878
  160. package/dist/planning/planner.js.map +1 -1
  161. package/dist/planning/rationalization-detector.d.ts +32 -0
  162. package/dist/planning/rationalization-detector.d.ts.map +1 -0
  163. package/dist/planning/rationalization-detector.js +89 -0
  164. package/dist/planning/rationalization-detector.js.map +1 -0
  165. package/dist/planning/reconciliation-engine.d.ts +47 -0
  166. package/dist/planning/reconciliation-engine.d.ts.map +1 -0
  167. package/dist/planning/reconciliation-engine.js +128 -0
  168. package/dist/planning/reconciliation-engine.js.map +1 -0
  169. package/dist/planning/task-verifier.d.ts +85 -0
  170. package/dist/planning/task-verifier.d.ts.map +1 -0
  171. package/dist/planning/task-verifier.js +227 -0
  172. package/dist/planning/task-verifier.js.map +1 -0
  173. package/dist/plugins/types.d.ts +4 -4
  174. package/dist/runtime/admin-ops.d.ts +2 -2
  175. package/dist/runtime/admin-ops.d.ts.map +1 -1
  176. package/dist/runtime/admin-ops.js +44 -17
  177. package/dist/runtime/admin-ops.js.map +1 -1
  178. package/dist/runtime/admin-setup-ops.d.ts.map +1 -1
  179. package/dist/runtime/admin-setup-ops.js +21 -46
  180. package/dist/runtime/admin-setup-ops.js.map +1 -1
  181. package/dist/runtime/archive-ops.d.ts +10 -0
  182. package/dist/runtime/archive-ops.d.ts.map +1 -0
  183. package/dist/runtime/archive-ops.js +310 -0
  184. package/dist/runtime/archive-ops.js.map +1 -0
  185. package/dist/runtime/capture-ops.d.ts.map +1 -1
  186. package/dist/runtime/capture-ops.js +42 -7
  187. package/dist/runtime/capture-ops.js.map +1 -1
  188. package/dist/runtime/claude-md-helpers.js +1 -1
  189. package/dist/runtime/claude-md-helpers.js.map +1 -1
  190. package/dist/runtime/context-health.d.ts +31 -0
  191. package/dist/runtime/context-health.d.ts.map +1 -0
  192. package/dist/runtime/context-health.js +57 -0
  193. package/dist/runtime/context-health.js.map +1 -0
  194. package/dist/runtime/facades/archive-facade.d.ts +10 -0
  195. package/dist/runtime/facades/archive-facade.d.ts.map +1 -0
  196. package/dist/runtime/facades/archive-facade.js +11 -0
  197. package/dist/runtime/facades/archive-facade.js.map +1 -0
  198. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  199. package/dist/runtime/facades/brain-facade.js +2 -0
  200. package/dist/runtime/facades/brain-facade.js.map +1 -1
  201. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  202. package/dist/runtime/facades/chat-facade.d.ts.map +1 -1
  203. package/dist/runtime/facades/chat-facade.js +15 -800
  204. package/dist/runtime/facades/chat-facade.js.map +1 -1
  205. package/dist/runtime/facades/chat-service-ops.d.ts +9 -0
  206. package/dist/runtime/facades/chat-service-ops.d.ts.map +1 -0
  207. package/dist/runtime/facades/chat-service-ops.js +330 -0
  208. package/dist/runtime/facades/chat-service-ops.js.map +1 -0
  209. package/dist/runtime/facades/chat-session-ops.d.ts +8 -0
  210. package/dist/runtime/facades/chat-session-ops.d.ts.map +1 -0
  211. package/dist/runtime/facades/chat-session-ops.js +136 -0
  212. package/dist/runtime/facades/chat-session-ops.js.map +1 -0
  213. package/dist/runtime/facades/chat-state.d.ts +31 -0
  214. package/dist/runtime/facades/chat-state.d.ts.map +1 -0
  215. package/dist/runtime/facades/chat-state.js +32 -0
  216. package/dist/runtime/facades/chat-state.js.map +1 -0
  217. package/dist/runtime/facades/chat-transport-ops.d.ts +9 -0
  218. package/dist/runtime/facades/chat-transport-ops.d.ts.map +1 -0
  219. package/dist/runtime/facades/chat-transport-ops.js +337 -0
  220. package/dist/runtime/facades/chat-transport-ops.js.map +1 -0
  221. package/dist/runtime/facades/control-facade.d.ts.map +1 -1
  222. package/dist/runtime/facades/control-facade.js +4 -1
  223. package/dist/runtime/facades/control-facade.js.map +1 -1
  224. package/dist/runtime/facades/index.d.ts.map +1 -1
  225. package/dist/runtime/facades/index.js +6 -0
  226. package/dist/runtime/facades/index.js.map +1 -1
  227. package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
  228. package/dist/runtime/facades/memory-facade.js +75 -6
  229. package/dist/runtime/facades/memory-facade.js.map +1 -1
  230. package/dist/runtime/facades/operator-facade.d.ts +8 -0
  231. package/dist/runtime/facades/operator-facade.d.ts.map +1 -0
  232. package/dist/runtime/facades/operator-facade.js +220 -0
  233. package/dist/runtime/facades/operator-facade.js.map +1 -0
  234. package/dist/runtime/facades/orchestrate-facade.js +3 -3
  235. package/dist/runtime/facades/orchestrate-facade.js.map +1 -1
  236. package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
  237. package/dist/runtime/facades/plan-facade.js +39 -6
  238. package/dist/runtime/facades/plan-facade.js.map +1 -1
  239. package/dist/runtime/facades/review-facade.d.ts +7 -0
  240. package/dist/runtime/facades/review-facade.d.ts.map +1 -0
  241. package/dist/runtime/facades/review-facade.js +8 -0
  242. package/dist/runtime/facades/review-facade.js.map +1 -0
  243. package/dist/runtime/facades/sync-facade.d.ts +7 -0
  244. package/dist/runtime/facades/sync-facade.d.ts.map +1 -0
  245. package/dist/runtime/facades/sync-facade.js +8 -0
  246. package/dist/runtime/facades/sync-facade.js.map +1 -0
  247. package/dist/runtime/facades/vault-facade.d.ts +4 -1
  248. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  249. package/dist/runtime/facades/vault-facade.js +13 -66
  250. package/dist/runtime/facades/vault-facade.js.map +1 -1
  251. package/dist/runtime/github-integration.d.ts +49 -0
  252. package/dist/runtime/github-integration.d.ts.map +1 -0
  253. package/dist/runtime/github-integration.js +113 -0
  254. package/dist/runtime/github-integration.js.map +1 -0
  255. package/dist/runtime/grading-ops.js +1 -1
  256. package/dist/runtime/grading-ops.js.map +1 -1
  257. package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
  258. package/dist/runtime/memory-extra-ops.js +6 -2
  259. package/dist/runtime/memory-extra-ops.js.map +1 -1
  260. package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
  261. package/dist/runtime/orchestrate-ops.js +367 -40
  262. package/dist/runtime/orchestrate-ops.js.map +1 -1
  263. package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
  264. package/dist/runtime/planning-extra-ops.js +69 -4
  265. package/dist/runtime/planning-extra-ops.js.map +1 -1
  266. package/dist/runtime/review-ops.d.ts +10 -0
  267. package/dist/runtime/review-ops.d.ts.map +1 -0
  268. package/dist/runtime/review-ops.js +97 -0
  269. package/dist/runtime/review-ops.js.map +1 -0
  270. package/dist/runtime/runtime.d.ts.map +1 -1
  271. package/dist/runtime/runtime.js +27 -12
  272. package/dist/runtime/runtime.js.map +1 -1
  273. package/dist/runtime/session-briefing.d.ts +3 -0
  274. package/dist/runtime/session-briefing.d.ts.map +1 -1
  275. package/dist/runtime/session-briefing.js +68 -1
  276. package/dist/runtime/session-briefing.js.map +1 -1
  277. package/dist/runtime/sync-ops.d.ts +12 -0
  278. package/dist/runtime/sync-ops.d.ts.map +1 -0
  279. package/dist/runtime/sync-ops.js +288 -0
  280. package/dist/runtime/sync-ops.js.map +1 -0
  281. package/dist/runtime/types.d.ts +10 -4
  282. package/dist/runtime/types.d.ts.map +1 -1
  283. package/dist/runtime/vault-extra-ops.d.ts +5 -4
  284. package/dist/runtime/vault-extra-ops.d.ts.map +1 -1
  285. package/dist/runtime/vault-extra-ops.js +5 -300
  286. package/dist/runtime/vault-extra-ops.js.map +1 -1
  287. package/dist/runtime/vault-sharing-ops.d.ts +4 -4
  288. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -1
  289. package/dist/runtime/vault-sharing-ops.js +5 -300
  290. package/dist/runtime/vault-sharing-ops.js.map +1 -1
  291. package/dist/skills/sync-skills.d.ts +27 -0
  292. package/dist/skills/sync-skills.d.ts.map +1 -0
  293. package/dist/skills/sync-skills.js +81 -0
  294. package/dist/skills/sync-skills.js.map +1 -0
  295. package/dist/update-check.d.ts +14 -0
  296. package/dist/update-check.d.ts.map +1 -0
  297. package/dist/update-check.js +96 -0
  298. package/dist/update-check.js.map +1 -0
  299. package/dist/vault/linking.d.ts +10 -12
  300. package/dist/vault/linking.d.ts.map +1 -1
  301. package/dist/vault/linking.js +104 -161
  302. package/dist/vault/linking.js.map +1 -1
  303. package/dist/vault/vault-entries.d.ts +69 -0
  304. package/dist/vault/vault-entries.d.ts.map +1 -0
  305. package/dist/vault/vault-entries.js +257 -0
  306. package/dist/vault/vault-entries.js.map +1 -0
  307. package/dist/vault/vault-interfaces.d.ts +153 -0
  308. package/dist/vault/vault-interfaces.d.ts.map +1 -0
  309. package/dist/vault/vault-interfaces.js +2 -0
  310. package/dist/vault/vault-interfaces.js.map +1 -0
  311. package/dist/vault/vault-maintenance.d.ts +40 -0
  312. package/dist/vault/vault-maintenance.d.ts.map +1 -0
  313. package/dist/vault/vault-maintenance.js +142 -0
  314. package/dist/vault/vault-maintenance.js.map +1 -0
  315. package/dist/vault/vault-markdown-sync.d.ts +22 -0
  316. package/dist/vault/vault-markdown-sync.d.ts.map +1 -0
  317. package/dist/vault/vault-markdown-sync.js +143 -0
  318. package/dist/vault/vault-markdown-sync.js.map +1 -0
  319. package/dist/vault/vault-memories.d.ts +61 -0
  320. package/dist/vault/vault-memories.d.ts.map +1 -0
  321. package/dist/vault/vault-memories.js +240 -0
  322. package/dist/vault/vault-memories.js.map +1 -0
  323. package/dist/vault/vault-schema.d.ts +9 -0
  324. package/dist/vault/vault-schema.d.ts.map +1 -0
  325. package/dist/vault/vault-schema.js +179 -0
  326. package/dist/vault/vault-schema.js.map +1 -0
  327. package/dist/vault/vault.d.ts +29 -81
  328. package/dist/vault/vault.d.ts.map +1 -1
  329. package/dist/vault/vault.js +78 -931
  330. package/dist/vault/vault.js.map +1 -1
  331. package/package.json +1 -1
  332. package/src/agency/agency-manager.test.ts +600 -0
  333. package/src/agency/default-rules.test.ts +228 -0
  334. package/src/{__tests__ → brain}/brain-intelligence.test.ts +37 -14
  335. package/src/{__tests__ → brain}/brain.test.ts +1 -1
  336. package/src/brain/intelligence.ts +196 -15
  337. package/src/brain/learning-radar.ts +22 -1
  338. package/src/{__tests__ → brain}/second-brain-features.test.ts +4 -4
  339. package/src/{__tests__ → brain}/session-lifecycle.test.ts +2 -2
  340. package/src/brain/strength-scorer.ts +404 -0
  341. package/src/capabilities/chain-mapping.test.ts +66 -0
  342. package/src/capabilities/registry.test.ts +369 -0
  343. package/src/chat/agent-loop.test.ts +394 -0
  344. package/src/chat/agent-loop.ts +2 -0
  345. package/src/{__tests__ → chat}/chat-differentiators.test.ts +3 -3
  346. package/src/{__tests__ → chat}/chat-enhanced.test.ts +4 -4
  347. package/src/{__tests__ → chat}/chat-transport.test.ts +6 -6
  348. package/src/chat/mcp-bridge.test.ts +173 -0
  349. package/src/chat/notifications.ts +2 -0
  350. package/src/chat/output-compressor.test.ts +164 -0
  351. package/src/claudemd/compose.test.ts +178 -0
  352. package/src/claudemd/compose.ts +1 -1
  353. package/src/claudemd/inject.test.ts +211 -0
  354. package/src/context/context-engine.test.ts +461 -0
  355. package/src/control/identity-manager.test.ts +305 -0
  356. package/src/control/intent-router.test.ts +360 -0
  357. package/src/control/intent-router.ts +13 -4
  358. package/src/curator/classifier.test.ts +104 -0
  359. package/src/curator/contradiction-detector.test.ts +180 -0
  360. package/src/curator/contradiction-detector.ts +87 -0
  361. package/src/{__tests__ → curator}/curator-pipeline-e2e.test.ts +10 -10
  362. package/src/{__tests__ → curator}/curator.test.ts +77 -1
  363. package/src/curator/curator.ts +115 -777
  364. package/src/curator/duplicate-detector.test.ts +183 -0
  365. package/src/curator/duplicate-detector.ts +103 -0
  366. package/src/curator/health-audit.ts +126 -0
  367. package/src/curator/metadata-enricher.ts +84 -0
  368. package/src/curator/quality-gate.test.ts +135 -0
  369. package/src/curator/schema.ts +65 -0
  370. package/src/curator/tag-manager.test.ts +165 -0
  371. package/src/curator/tag-manager.ts +109 -0
  372. package/src/domain-packs/inject-rules.test.ts +117 -0
  373. package/src/domain-packs/knowledge-installer.test.ts +171 -0
  374. package/src/domain-packs/loader.test.ts +86 -0
  375. package/src/domain-packs/pack-runtime.test.ts +140 -0
  376. package/src/domain-packs/skills-installer.test.ts +135 -0
  377. package/src/domain-packs/token-resolver.test.ts +150 -0
  378. package/src/domain-packs/types.test.ts +130 -0
  379. package/src/enforcement/adapters/claude-code.test.ts +216 -0
  380. package/src/enforcement/registry.test.ts +264 -0
  381. package/src/engine/bin/soleri-engine.ts +59 -3
  382. package/src/engine/core-ops.test.ts +254 -0
  383. package/src/engine/core-ops.ts +35 -10
  384. package/src/engine/module-manifest.test.ts +124 -0
  385. package/src/engine/module-manifest.ts +22 -2
  386. package/src/engine/register-engine.test.ts +230 -0
  387. package/src/engine/register-engine.ts +26 -2
  388. package/src/errors/classify.test.ts +199 -0
  389. package/src/errors/retry.test.ts +156 -0
  390. package/src/errors/retry.ts +2 -0
  391. package/src/errors/types.test.ts +108 -0
  392. package/src/events/event-bus.test.ts +149 -0
  393. package/src/extensions/middleware.test.ts +234 -0
  394. package/src/facades/facade-factory.test.ts +424 -0
  395. package/src/flows/chain-runner.test.ts +273 -0
  396. package/src/flows/context-router.test.ts +52 -0
  397. package/src/flows/dispatch-registry.test.ts +128 -0
  398. package/src/flows/epilogue.test.ts +107 -0
  399. package/src/flows/executor.test.ts +263 -0
  400. package/src/flows/gate-evaluator.test.ts +194 -0
  401. package/src/flows/gate-evaluator.ts +25 -0
  402. package/src/flows/types.ts +4 -0
  403. package/src/governance/governance.test.ts +726 -0
  404. package/src/health/health-registry.test.ts +186 -0
  405. package/src/health/vault-integrity.test.ts +110 -0
  406. package/src/index.ts +92 -0
  407. package/src/intake/content-classifier.test.ts +209 -0
  408. package/src/intake/dedup-gate.test.ts +131 -0
  409. package/src/intake/intake-pipeline.test.ts +506 -0
  410. package/src/intake/intake-pipeline.ts +1 -0
  411. package/src/intake/text-ingester.test.ts +194 -0
  412. package/src/intake/text-ingester.ts +2 -0
  413. package/src/llm/key-pool.test.ts +236 -0
  414. package/src/llm/key-pool.ts +3 -4
  415. package/src/llm/llm-client.test.ts +345 -0
  416. package/src/llm/oauth-discovery.test.ts +180 -0
  417. package/src/llm/utils.test.ts +327 -0
  418. package/src/llm/utils.ts +2 -0
  419. package/src/{__tests__ → logging}/logger.test.ts +41 -62
  420. package/src/loop/loop-manager.test.ts +519 -0
  421. package/src/migrations/migration-runner.edge-cases.test.ts +319 -0
  422. package/src/migrations/migration-runner.test-helpers.ts +64 -0
  423. package/src/migrations/migration-runner.test.ts +385 -0
  424. package/src/operator/auto-signal-pipeline.test.ts +207 -0
  425. package/src/operator/operator-profile-extended.test.ts +320 -0
  426. package/src/operator/operator-profile.test.ts +314 -0
  427. package/src/operator/operator-profile.ts +469 -0
  428. package/src/operator/operator-signals-extended.test.ts +245 -0
  429. package/src/operator/operator-signals.test.ts +281 -0
  430. package/src/operator/operator-signals.ts +261 -0
  431. package/src/operator/operator-types.ts +444 -0
  432. package/src/operator/prompts/hook-precompact-operator-dispatch.md +94 -0
  433. package/src/operator/prompts/subagent-soft-signal-extractor.md +125 -0
  434. package/src/operator/prompts/subagent-synthesis-cognition.md +181 -0
  435. package/src/operator/prompts/subagent-synthesis-communication.md +140 -0
  436. package/src/operator/prompts/subagent-synthesis-technical.md +160 -0
  437. package/src/operator/prompts/subagent-synthesis-trust.md +143 -0
  438. package/src/{__tests__ → packs}/pack-lockfile.test.ts +3 -3
  439. package/src/{__tests__ → packs}/pack-system.test.ts +2 -2
  440. package/src/paths.ts +115 -0
  441. package/src/persistence/index.ts +1 -1
  442. package/src/persistence/sqlite-provider.test.ts +540 -0
  443. package/src/persistence/sqlite-provider.ts +8 -5
  444. package/src/persona/defaults.test.ts +59 -0
  445. package/src/persona/loader.test.ts +67 -0
  446. package/src/persona/prompt-generator.test.ts +127 -0
  447. package/src/planning/evidence-collector.test.ts +406 -0
  448. package/src/planning/evidence-collector.ts +50 -0
  449. package/src/planning/gap-analysis-alternatives.test.ts +169 -0
  450. package/src/planning/gap-analysis.ts +21 -636
  451. package/src/planning/gap-passes.test.ts +372 -0
  452. package/src/planning/gap-passes.ts +298 -0
  453. package/src/planning/gap-patterns.test.ts +320 -0
  454. package/src/planning/gap-patterns.ts +234 -0
  455. package/src/planning/gap-types.ts +4 -1
  456. package/src/planning/github-projection.test.ts +177 -0
  457. package/src/planning/github-projection.ts +425 -0
  458. package/src/planning/impact-analyzer.test.ts +180 -0
  459. package/src/planning/impact-analyzer.ts +264 -0
  460. package/src/planning/plan-lifecycle.test.ts +312 -0
  461. package/src/planning/plan-lifecycle.ts +346 -0
  462. package/src/planning/planner-types.ts +215 -0
  463. package/src/{__tests__ → planning}/planner.test.ts +169 -15
  464. package/src/planning/planner.ts +197 -1228
  465. package/src/planning/rationalization-detector.test.ts +171 -0
  466. package/src/planning/rationalization-detector.ts +138 -0
  467. package/src/planning/reconciliation-engine.test.ts +141 -0
  468. package/src/planning/reconciliation-engine.ts +162 -0
  469. package/src/planning/task-verifier.test.ts +235 -0
  470. package/src/planning/task-verifier.ts +303 -0
  471. package/src/planning/verification-protocol.test.ts +201 -0
  472. package/src/playbooks/generic/generic-playbooks.test.ts +438 -0
  473. package/src/playbooks/index.test.ts +77 -0
  474. package/src/playbooks/playbook-executor.test.ts +255 -0
  475. package/src/playbooks/playbook-registry.test.ts +232 -0
  476. package/src/playbooks/playbook-seeder.test.ts +153 -0
  477. package/src/plugins/plugin-loader.test.ts +212 -0
  478. package/src/plugins/plugin-registry.test.ts +272 -0
  479. package/src/project/project-registry.test.ts +428 -0
  480. package/src/prompts/parser.test.ts +100 -0
  481. package/src/prompts/template-manager.test.ts +109 -0
  482. package/src/{__tests__ → queue}/async-infrastructure.test.ts +3 -3
  483. package/src/queue/job-queue.test.ts +331 -0
  484. package/src/queue/pipeline-runner.test.ts +209 -0
  485. package/src/runtime/admin-extra-ops.test.ts +527 -0
  486. package/src/runtime/admin-ops.test.ts +257 -0
  487. package/src/runtime/admin-ops.ts +45 -17
  488. package/src/runtime/admin-setup-ops.test.ts +328 -0
  489. package/src/runtime/admin-setup-ops.ts +20 -43
  490. package/src/runtime/archive-ops.test.ts +269 -0
  491. package/src/runtime/archive-ops.ts +347 -0
  492. package/src/runtime/capture-ops.test.ts +433 -0
  493. package/src/runtime/capture-ops.ts +50 -8
  494. package/src/runtime/chain-ops.test.ts +149 -0
  495. package/src/runtime/claude-md-helpers.test.ts +191 -0
  496. package/src/runtime/claude-md-helpers.ts +1 -1
  497. package/src/runtime/context-health.test.ts +78 -0
  498. package/src/runtime/context-health.ts +85 -0
  499. package/src/runtime/curator-extra-ops.test.ts +202 -0
  500. package/src/runtime/deprecation.test.ts +98 -0
  501. package/src/runtime/domain-ops.test.ts +268 -0
  502. package/src/runtime/facades/admin-facade.test.ts +333 -0
  503. package/src/runtime/facades/agency-facade.test.ts +278 -0
  504. package/src/runtime/facades/archive-facade.test.ts +294 -0
  505. package/src/runtime/facades/archive-facade.ts +14 -0
  506. package/src/runtime/facades/brain-facade.test.ts +714 -0
  507. package/src/runtime/facades/brain-facade.ts +2 -0
  508. package/src/runtime/facades/chat-facade.test.ts +166 -0
  509. package/src/runtime/facades/chat-facade.ts +15 -906
  510. package/src/runtime/facades/chat-service-ops.test.ts +276 -0
  511. package/src/runtime/facades/chat-service-ops.ts +374 -0
  512. package/src/runtime/facades/chat-session-ops.test.ts +197 -0
  513. package/src/runtime/facades/chat-session-ops.ts +146 -0
  514. package/src/runtime/facades/chat-state.ts +60 -0
  515. package/src/runtime/facades/chat-transport-ops.test.ts +269 -0
  516. package/src/runtime/facades/chat-transport-ops.ts +380 -0
  517. package/src/runtime/facades/context-facade.test.ts +108 -0
  518. package/src/runtime/facades/control-facade.test.ts +436 -0
  519. package/src/runtime/facades/control-facade.ts +6 -1
  520. package/src/runtime/facades/curator-facade.test.ts +303 -0
  521. package/src/runtime/facades/index.ts +6 -0
  522. package/src/runtime/facades/loop-facade.test.ts +245 -0
  523. package/src/runtime/facades/memory-facade.test.ts +269 -0
  524. package/src/runtime/facades/memory-facade.ts +78 -6
  525. package/src/runtime/facades/operator-facade.test.ts +208 -0
  526. package/src/runtime/facades/operator-facade.ts +236 -0
  527. package/src/runtime/facades/orchestrate-facade.test.ts +185 -0
  528. package/src/runtime/facades/orchestrate-facade.ts +3 -3
  529. package/src/runtime/facades/plan-facade.test.ts +266 -0
  530. package/src/runtime/facades/plan-facade.ts +42 -6
  531. package/src/runtime/facades/review-facade.test.ts +82 -0
  532. package/src/runtime/facades/review-facade.ts +11 -0
  533. package/src/runtime/facades/sync-facade.test.ts +113 -0
  534. package/src/runtime/facades/sync-facade.ts +11 -0
  535. package/src/runtime/facades/vault-facade.test.ts +631 -0
  536. package/src/runtime/facades/vault-facade.ts +15 -70
  537. package/src/runtime/feature-flags.test.ts +140 -0
  538. package/src/runtime/github-integration.test.ts +89 -0
  539. package/src/runtime/github-integration.ts +159 -0
  540. package/src/runtime/grading-ops.test.ts +141 -0
  541. package/src/runtime/grading-ops.ts +1 -1
  542. package/src/runtime/intake-ops.test.ts +208 -0
  543. package/src/runtime/loop-ops.test.ts +238 -0
  544. package/src/runtime/memory-cross-project-ops.test.ts +177 -0
  545. package/src/runtime/memory-extra-ops.test.ts +453 -0
  546. package/src/runtime/memory-extra-ops.ts +6 -2
  547. package/src/runtime/orchestrate-ops.test.ts +302 -0
  548. package/src/runtime/orchestrate-ops.ts +435 -46
  549. package/src/runtime/pack-ops.test.ts +158 -0
  550. package/src/runtime/planning-extra-ops.test.ts +583 -0
  551. package/src/runtime/planning-extra-ops.ts +72 -4
  552. package/src/{__tests__ → runtime}/playbook-ops-execution.test.ts +3 -3
  553. package/src/runtime/playbook-ops.test.ts +262 -0
  554. package/src/runtime/plugin-ops.test.ts +201 -0
  555. package/src/runtime/project-ops.test.ts +235 -0
  556. package/src/runtime/review-ops.test.ts +142 -0
  557. package/src/runtime/review-ops.ts +99 -0
  558. package/src/runtime/runtime.test.ts +363 -0
  559. package/src/runtime/runtime.ts +39 -12
  560. package/src/runtime/session-briefing.test.ts +302 -0
  561. package/src/runtime/session-briefing.ts +80 -1
  562. package/src/runtime/sync-ops.test.ts +221 -0
  563. package/src/runtime/sync-ops.ts +325 -0
  564. package/src/runtime/telemetry-ops.test.ts +132 -0
  565. package/src/runtime/types.ts +10 -4
  566. package/src/runtime/vault-extra-ops.test.ts +246 -0
  567. package/src/runtime/vault-extra-ops.ts +5 -332
  568. package/src/runtime/vault-linking-ops.test.ts +237 -0
  569. package/src/runtime/vault-sharing-ops.test.ts +130 -0
  570. package/src/runtime/vault-sharing-ops.ts +5 -329
  571. package/src/skills/sync-skills.ts +108 -0
  572. package/src/streams/normalize.test.ts +95 -0
  573. package/src/streams/replayable-stream.test.ts +166 -0
  574. package/src/telemetry/telemetry.test.ts +143 -0
  575. package/src/transport/http-server.test.ts +394 -0
  576. package/src/transport/lsp-server.test.ts +458 -0
  577. package/src/transport/rate-limiter.test.ts +126 -0
  578. package/src/transport/session-manager.test.ts +133 -0
  579. package/src/transport/token-auth.test.ts +136 -0
  580. package/src/transport/ws-server.test.ts +294 -0
  581. package/src/update-check.ts +111 -0
  582. package/src/vault/__tests__/vault-characterization.test.ts +168 -0
  583. package/src/vault/content-hash.test.ts +78 -0
  584. package/src/vault/git-vault-sync.test.ts +234 -0
  585. package/src/vault/knowledge-review.test.ts +269 -0
  586. package/src/vault/linking.test.ts +358 -0
  587. package/src/vault/linking.ts +149 -183
  588. package/src/vault/obsidian-sync.test.ts +342 -0
  589. package/src/vault/playbook.test.ts +152 -0
  590. package/src/vault/scope-detector.test.ts +187 -0
  591. package/src/vault/vault-branching.test.ts +250 -0
  592. package/src/{__tests__ → vault}/vault-connect.test.ts +1 -1
  593. package/src/vault/vault-entries.ts +282 -0
  594. package/src/vault/vault-interfaces.ts +56 -0
  595. package/src/vault/vault-maintenance.ts +205 -0
  596. package/src/vault/vault-manager.test.ts +206 -0
  597. package/src/vault/vault-markdown-sync.test.ts +203 -0
  598. package/src/vault/vault-markdown-sync.ts +160 -0
  599. package/src/vault/vault-memories.ts +339 -0
  600. package/src/{__tests__ → vault}/vault-scaling.test.ts +1 -1
  601. package/src/vault/vault-schema.ts +181 -0
  602. package/src/{__tests__ → vault}/vault-sharing.test.ts +4 -4
  603. package/src/{__tests__ → vault}/vault.test.ts +2 -2
  604. package/src/vault/vault.ts +89 -1171
  605. package/dist/cognee/client.d.ts +0 -43
  606. package/dist/cognee/client.d.ts.map +0 -1
  607. package/dist/cognee/client.js +0 -375
  608. package/dist/cognee/client.js.map +0 -1
  609. package/dist/cognee/sync-manager.d.ts +0 -153
  610. package/dist/cognee/sync-manager.d.ts.map +0 -1
  611. package/dist/cognee/sync-manager.js +0 -390
  612. package/dist/cognee/sync-manager.js.map +0 -1
  613. package/dist/cognee/types.d.ts +0 -62
  614. package/dist/cognee/types.d.ts.map +0 -1
  615. package/dist/cognee/types.js +0 -3
  616. package/dist/cognee/types.js.map +0 -1
  617. package/dist/governance/index.d.ts +0 -3
  618. package/dist/governance/index.d.ts.map +0 -1
  619. package/dist/governance/index.js +0 -2
  620. package/dist/governance/index.js.map +0 -1
  621. package/dist/health/doctor-checks.d.ts +0 -15
  622. package/dist/health/doctor-checks.d.ts.map +0 -1
  623. package/dist/health/doctor-checks.js +0 -98
  624. package/dist/health/doctor-checks.js.map +0 -1
  625. package/dist/persistence/postgres-provider.d.ts +0 -81
  626. package/dist/persistence/postgres-provider.d.ts.map +0 -1
  627. package/dist/persistence/postgres-provider.js +0 -256
  628. package/dist/persistence/postgres-provider.js.map +0 -1
  629. package/dist/runtime/cognee-sync-ops.d.ts +0 -12
  630. package/dist/runtime/cognee-sync-ops.d.ts.map +0 -1
  631. package/dist/runtime/cognee-sync-ops.js +0 -93
  632. package/dist/runtime/cognee-sync-ops.js.map +0 -1
  633. package/dist/runtime/core-ops.d.ts +0 -23
  634. package/dist/runtime/core-ops.d.ts.map +0 -1
  635. package/dist/runtime/core-ops.js +0 -1296
  636. package/dist/runtime/core-ops.js.map +0 -1
  637. package/dist/runtime/facades/cognee-facade.d.ts +0 -8
  638. package/dist/runtime/facades/cognee-facade.d.ts.map +0 -1
  639. package/dist/runtime/facades/cognee-facade.js +0 -156
  640. package/dist/runtime/facades/cognee-facade.js.map +0 -1
  641. package/src/__tests__/admin-extra-ops.test.ts +0 -484
  642. package/src/__tests__/admin-ops.test.ts +0 -268
  643. package/src/__tests__/admin-setup-ops.test.ts +0 -355
  644. package/src/__tests__/agency-manager.test.ts +0 -374
  645. package/src/__tests__/agent-loop.test.ts +0 -256
  646. package/src/__tests__/capture-ops.test.ts +0 -784
  647. package/src/__tests__/claudemd.test.ts +0 -282
  648. package/src/__tests__/content-hash.test.ts +0 -60
  649. package/src/__tests__/context-engine.test.ts +0 -251
  650. package/src/__tests__/core-ops.test.ts +0 -550
  651. package/src/__tests__/curator-extra-ops.test.ts +0 -383
  652. package/src/__tests__/deprecation.test.ts +0 -78
  653. package/src/__tests__/domain-ops.test.ts +0 -226
  654. package/src/__tests__/domain-packs.test.ts +0 -421
  655. package/src/__tests__/enforcement.test.ts +0 -153
  656. package/src/__tests__/errors.test.ts +0 -388
  657. package/src/__tests__/extensions.test.ts +0 -233
  658. package/src/__tests__/facade-factory.test.ts +0 -271
  659. package/src/__tests__/feature-flags.test.ts +0 -137
  660. package/src/__tests__/flows.test.ts +0 -604
  661. package/src/__tests__/git-vault-sync.test.ts +0 -230
  662. package/src/__tests__/governance.test.ts +0 -522
  663. package/src/__tests__/grading-ops.test.ts +0 -361
  664. package/src/__tests__/health-registry.test.ts +0 -173
  665. package/src/__tests__/identity-manager.test.ts +0 -243
  666. package/src/__tests__/intake-pipeline.test.ts +0 -162
  667. package/src/__tests__/intent-router.test.ts +0 -222
  668. package/src/__tests__/knowledge-review.test.ts +0 -104
  669. package/src/__tests__/llm-client.test.ts +0 -69
  670. package/src/__tests__/llm.test.ts +0 -556
  671. package/src/__tests__/loader.test.ts +0 -176
  672. package/src/__tests__/loop-ops.test.ts +0 -469
  673. package/src/__tests__/lsp-transport.test.ts +0 -442
  674. package/src/__tests__/memory-cross-project-ops.test.ts +0 -248
  675. package/src/__tests__/memory-extra-ops.test.ts +0 -352
  676. package/src/__tests__/migration-runner.test.ts +0 -170
  677. package/src/__tests__/module-manifest-drift.test.ts +0 -59
  678. package/src/__tests__/normalize.test.ts +0 -85
  679. package/src/__tests__/obsidian-sync.test.ts +0 -354
  680. package/src/__tests__/orchestrate-ops.test.ts +0 -289
  681. package/src/__tests__/pack-ops.test.ts +0 -146
  682. package/src/__tests__/persistence.test.ts +0 -291
  683. package/src/__tests__/planning-extra-ops.test.ts +0 -706
  684. package/src/__tests__/playbook-executor.test.ts +0 -249
  685. package/src/__tests__/playbook-registry.test.ts +0 -326
  686. package/src/__tests__/playbook-seeder.test.ts +0 -163
  687. package/src/__tests__/playbook.test.ts +0 -389
  688. package/src/__tests__/plugin-ops.test.ts +0 -411
  689. package/src/__tests__/plugin-system.test.ts +0 -509
  690. package/src/__tests__/project-ops.test.ts +0 -381
  691. package/src/__tests__/replayable-stream.test.ts +0 -177
  692. package/src/__tests__/runtime.test.ts +0 -95
  693. package/src/__tests__/scope-detector.test.ts +0 -121
  694. package/src/__tests__/template-manager.test.ts +0 -222
  695. package/src/__tests__/token-resolver.test.ts +0 -79
  696. package/src/__tests__/transport.test.ts +0 -758
  697. package/src/__tests__/vault-branching.test.ts +0 -274
  698. package/src/__tests__/vault-extra-ops.test.ts +0 -482
  699. package/src/__tests__/vault-integrity.test.ts +0 -71
  700. package/src/__tests__/vault-manager.test.ts +0 -238
  701. package/src/__tests__/ws-transport.test.ts +0 -479
@@ -0,0 +1,327 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { CircuitBreaker, CircuitOpenError, computeDelay, retry, parseRateLimitHeaders } from './utils.js';
3
+ import { LLMError } from './types.js';
4
+
5
+ // ─── CircuitOpenError ───────────────────────────────────────────────
6
+
7
+ describe('CircuitOpenError', () => {
8
+ it('should include the breaker name in the message', () => {
9
+ const err = new CircuitOpenError('test-breaker');
10
+ expect(err.message).toContain('test-breaker');
11
+ expect(err.name).toBe('CircuitOpenError');
12
+ });
13
+
14
+ it('should not be retryable', () => {
15
+ const err = new CircuitOpenError('x');
16
+ expect(err.retryable).toBe(false);
17
+ });
18
+
19
+ it('should be an instance of CircuitOpenError', () => {
20
+ const err = new CircuitOpenError('x');
21
+ expect(err).toBeInstanceOf(CircuitOpenError);
22
+ expect(err).toBeInstanceOf(Error);
23
+ });
24
+ });
25
+
26
+ // ─── CircuitBreaker ─────────────────────────────────────────────────
27
+
28
+ describe('CircuitBreaker', () => {
29
+ beforeEach(() => {
30
+ vi.restoreAllMocks();
31
+ vi.spyOn(console, 'error').mockImplementation(() => {});
32
+ });
33
+
34
+ it('should start in closed state', () => {
35
+ const cb = new CircuitBreaker({ name: 'test' });
36
+ const snap = cb.getState();
37
+ expect(snap.state).toBe('closed');
38
+ expect(snap.failureCount).toBe(0);
39
+ });
40
+
41
+ it('should pass through successful calls in closed state', async () => {
42
+ const cb = new CircuitBreaker({ name: 'test' });
43
+ const result = await cb.call(async () => 42);
44
+ expect(result).toBe(42);
45
+ });
46
+
47
+ it('should rethrow errors from the wrapped function', async () => {
48
+ const cb = new CircuitBreaker({ name: 'test' });
49
+ await expect(cb.call(async () => { throw new Error('boom'); })).rejects.toThrow('boom');
50
+ });
51
+
52
+ it('should not count non-retryable errors as failures', async () => {
53
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
54
+ const nonRetryable = new Error('not retryable');
55
+
56
+ for (let i = 0; i < 5; i++) {
57
+ await expect(cb.call(async () => { throw nonRetryable; })).rejects.toThrow();
58
+ }
59
+ expect(cb.getState().state).toBe('closed');
60
+ });
61
+
62
+ it('should open after reaching failure threshold with retryable errors', async () => {
63
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
64
+ const retryableErr = new LLMError('rate limited', { retryable: true });
65
+
66
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
67
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
68
+ expect(cb.isOpen()).toBe(true);
69
+ });
70
+
71
+ it('should reject calls when open', async () => {
72
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 999_999 });
73
+ const retryableErr = new LLMError('fail', { retryable: true });
74
+
75
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
76
+ await expect(cb.call(async () => 'ok')).rejects.toThrow(CircuitOpenError);
77
+ });
78
+
79
+ it('should transition to half-open after reset timeout', async () => {
80
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
81
+ const retryableErr = new LLMError('fail', { retryable: true });
82
+
83
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
84
+ expect(cb.isOpen()).toBe(true);
85
+
86
+ // Wait for reset timeout
87
+ await new Promise((r) => setTimeout(r, 20));
88
+ expect(cb.isOpen()).toBe(false); // shouldProbe returns true
89
+ expect(cb.getState().state).toBe('half-open');
90
+ });
91
+
92
+ it('should close on success after half-open probe', async () => {
93
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
94
+ const retryableErr = new LLMError('fail', { retryable: true });
95
+
96
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
97
+ await new Promise((r) => setTimeout(r, 20));
98
+
99
+ const result = await cb.call(async () => 'recovered');
100
+ expect(result).toBe('recovered');
101
+ expect(cb.getState().state).toBe('closed');
102
+ });
103
+
104
+ it('should re-open on failure in half-open state', async () => {
105
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
106
+ const retryableErr = new LLMError('fail', { retryable: true });
107
+
108
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
109
+ await new Promise((r) => setTimeout(r, 20));
110
+
111
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
112
+ expect(cb.getState().state).toBe('open');
113
+ });
114
+
115
+ it('should reset state completely via reset()', async () => {
116
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 999_999 });
117
+ const retryableErr = new LLMError('fail', { retryable: true });
118
+
119
+ await expect(cb.call(async () => { throw retryableErr; })).rejects.toThrow();
120
+ expect(cb.isOpen()).toBe(true);
121
+
122
+ cb.reset();
123
+ expect(cb.getState().state).toBe('closed');
124
+ expect(cb.getState().failureCount).toBe(0);
125
+ expect(cb.getState().lastFailureAt).toBeNull();
126
+ });
127
+
128
+ it('should record failures synchronously via recordFailure()', () => {
129
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
130
+ cb.recordFailure();
131
+ expect(cb.getState().failureCount).toBe(1);
132
+ expect(cb.getState().state).toBe('closed');
133
+
134
+ cb.recordFailure();
135
+ expect(cb.getState().state).toBe('open');
136
+ });
137
+
138
+ it('should use default config values when none provided', () => {
139
+ const cb = new CircuitBreaker();
140
+ const snap = cb.getState();
141
+ expect(snap.state).toBe('closed');
142
+ });
143
+ });
144
+
145
+ // ─── computeDelay ───────────────────────────────────────────────────
146
+
147
+ describe('computeDelay', () => {
148
+ it('should use retryAfterMs from error when available', () => {
149
+ const error = { retryAfterMs: 5000 };
150
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
151
+ expect(computeDelay(error, 0, config)).toBe(5000);
152
+ });
153
+
154
+ it('should cap retryAfterMs at maxDelayMs', () => {
155
+ const error = { retryAfterMs: 100_000 };
156
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
157
+ expect(computeDelay(error, 0, config)).toBe(30000);
158
+ });
159
+
160
+ it('should compute exponential backoff without jitter', () => {
161
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
162
+ expect(computeDelay({}, 0, config)).toBe(1000);
163
+ expect(computeDelay({}, 1, config)).toBe(2000);
164
+ expect(computeDelay({}, 2, config)).toBe(4000);
165
+ });
166
+
167
+ it('should cap exponential delay at maxDelayMs', () => {
168
+ const config = { maxAttempts: 10, baseDelayMs: 1000, maxDelayMs: 5000, jitter: 0 };
169
+ expect(computeDelay({}, 10, config)).toBe(5000);
170
+ });
171
+
172
+ it('should apply jitter within range', () => {
173
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0.5 };
174
+ const delays = Array.from({ length: 50 }, () => computeDelay({}, 0, config));
175
+ expect(delays.every((d) => d >= 500 && d <= 1500)).toBe(true);
176
+ });
177
+
178
+ it('should never return negative delay', () => {
179
+ vi.spyOn(Math, 'random').mockReturnValue(0);
180
+ const config = { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 30000, jitter: 1 };
181
+ expect(computeDelay({}, 0, config)).toBeGreaterThanOrEqual(0);
182
+ vi.restoreAllMocks();
183
+ });
184
+ });
185
+
186
+ // ─── retry ──────────────────────────────────────────────────────────
187
+
188
+ describe('retry', () => {
189
+ beforeEach(() => {
190
+ vi.useFakeTimers();
191
+ });
192
+
193
+ afterAll(() => {
194
+ vi.useRealTimers();
195
+ });
196
+
197
+ it('should return on first success', async () => {
198
+ vi.useRealTimers();
199
+ const fn = vi.fn().mockResolvedValue('ok');
200
+ const result = await retry(fn);
201
+ expect(result).toBe('ok');
202
+ expect(fn).toHaveBeenCalledTimes(1);
203
+ });
204
+
205
+ it('should throw if maxAttempts < 1', async () => {
206
+ vi.useRealTimers();
207
+ await expect(retry(async () => 'ok', { maxAttempts: 0 })).rejects.toThrow('maxAttempts must be >= 1');
208
+ });
209
+
210
+ it('should throw non-retryable errors immediately', async () => {
211
+ vi.useRealTimers();
212
+ const fn = vi.fn().mockRejectedValue(new Error('fatal'));
213
+ await expect(retry(fn, { maxAttempts: 3 })).rejects.toThrow('fatal');
214
+ expect(fn).toHaveBeenCalledTimes(1);
215
+ });
216
+
217
+ it('should retry retryable errors up to maxAttempts', async () => {
218
+ vi.useRealTimers();
219
+ const retryableErr = new LLMError('rate limited', { retryable: true });
220
+ const fn = vi.fn().mockRejectedValue(retryableErr);
221
+ await expect(
222
+ retry(fn, { maxAttempts: 2, baseDelayMs: 1, maxDelayMs: 1, jitter: 0 }),
223
+ ).rejects.toThrow('rate limited');
224
+ expect(fn).toHaveBeenCalledTimes(2);
225
+ });
226
+
227
+ it('should succeed on retry after initial failures', async () => {
228
+ vi.useRealTimers();
229
+ const retryableErr = new LLMError('transient', { retryable: true });
230
+ const fn = vi.fn()
231
+ .mockRejectedValueOnce(retryableErr)
232
+ .mockResolvedValueOnce('recovered');
233
+
234
+ const result = await retry(fn, { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 1, jitter: 0 });
235
+ expect(result).toBe('recovered');
236
+ expect(fn).toHaveBeenCalledTimes(2);
237
+ });
238
+
239
+ it('should call onRetry callback on each retry', async () => {
240
+ vi.useRealTimers();
241
+ const retryableErr = new LLMError('transient', { retryable: true });
242
+ const onRetry = vi.fn();
243
+ const fn = vi.fn()
244
+ .mockRejectedValueOnce(retryableErr)
245
+ .mockResolvedValueOnce('ok');
246
+
247
+ await retry(fn, { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 1, jitter: 0, onRetry });
248
+ expect(onRetry).toHaveBeenCalledTimes(1);
249
+ expect(onRetry).toHaveBeenCalledWith(retryableErr, 1, expect.any(Number));
250
+ });
251
+
252
+ it('should respect custom shouldRetry predicate', async () => {
253
+ vi.useRealTimers();
254
+ const customErr = new Error('custom');
255
+ const fn = vi.fn().mockRejectedValue(customErr);
256
+ const shouldRetry = vi.fn().mockReturnValue(true);
257
+
258
+ await expect(
259
+ retry(fn, { maxAttempts: 2, baseDelayMs: 1, maxDelayMs: 1, jitter: 0, shouldRetry }),
260
+ ).rejects.toThrow('custom');
261
+ expect(fn).toHaveBeenCalledTimes(2);
262
+ expect(shouldRetry).toHaveBeenCalled();
263
+ });
264
+ });
265
+
266
+ // Need this import for afterAll
267
+ import { afterAll } from 'vitest';
268
+
269
+ // ─── parseRateLimitHeaders ──────────────────────────────────────────
270
+
271
+ describe('parseRateLimitHeaders', () => {
272
+ function makeHeaders(obj: Record<string, string>): Headers {
273
+ return new Headers(obj);
274
+ }
275
+
276
+ it('should parse remaining requests header', () => {
277
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-remaining-requests': '42' }));
278
+ expect(info.remaining).toBe(42);
279
+ });
280
+
281
+ it('should return null for missing remaining header', () => {
282
+ const info = parseRateLimitHeaders(makeHeaders({}));
283
+ expect(info.remaining).toBeNull();
284
+ });
285
+
286
+ it('should return null for non-numeric remaining header', () => {
287
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-remaining-requests': 'abc' }));
288
+ expect(info.remaining).toBeNull();
289
+ });
290
+
291
+ it('should parse retry-after header as seconds', () => {
292
+ const info = parseRateLimitHeaders(makeHeaders({ 'retry-after': '2.5' }));
293
+ expect(info.retryAfterMs).toBe(2500);
294
+ });
295
+
296
+ it('should return null for non-numeric retry-after', () => {
297
+ const info = parseRateLimitHeaders(makeHeaders({ 'retry-after': 'invalid' }));
298
+ expect(info.retryAfterMs).toBeNull();
299
+ });
300
+
301
+ it('should parse reset duration with minutes and seconds', () => {
302
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '2m30s' }));
303
+ expect(info.resetMs).toBe(2 * 60_000 + 30 * 1000);
304
+ });
305
+
306
+ it('should parse reset duration with milliseconds', () => {
307
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '500ms' }));
308
+ expect(info.resetMs).toBe(500);
309
+ });
310
+
311
+ it('should parse reset duration with seconds only', () => {
312
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '45s' }));
313
+ expect(info.resetMs).toBe(45000);
314
+ });
315
+
316
+ it('should return null for unparseable reset duration', () => {
317
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': 'unknown' }));
318
+ expect(info.resetMs).toBeNull();
319
+ });
320
+
321
+ it('should return all nulls when no headers present', () => {
322
+ const info = parseRateLimitHeaders(makeHeaders({}));
323
+ expect(info.remaining).toBeNull();
324
+ expect(info.resetMs).toBeNull();
325
+ expect(info.retryAfterMs).toBeNull();
326
+ });
327
+ });
package/src/llm/utils.ts CHANGED
@@ -182,6 +182,7 @@ export async function retry<T>(fn: () => Promise<T>, config?: Partial<RetryConfi
182
182
 
183
183
  for (let attempt = 0; attempt < resolved.maxAttempts; attempt++) {
184
184
  try {
185
+ // oxlint-disable-next-line eslint(no-await-in-loop)
185
186
  return await fn();
186
187
  } catch (error) {
187
188
  lastError = error;
@@ -193,6 +194,7 @@ export async function retry<T>(fn: () => Promise<T>, config?: Partial<RetryConfi
193
194
  const delay = computeDelay(error, attempt, resolved);
194
195
  resolved.onRetry?.(error, attempt + 1, delay);
195
196
 
197
+ // oxlint-disable-next-line eslint(no-await-in-loop)
196
198
  await sleep(delay);
197
199
  }
198
200
  }
@@ -2,7 +2,7 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
2
  import { mkdirSync, rmSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { tmpdir } from 'node:os';
5
- import { Logger, createLogger } from '../logging/logger.js';
5
+ import { Logger, createLogger } from './logger.js';
6
6
 
7
7
  describe('Logger', () => {
8
8
  let errorSpy: ReturnType<typeof vi.spyOn>;
@@ -18,96 +18,82 @@ describe('Logger', () => {
18
18
  delete process.env.SOLERI_LOG_LEVEL;
19
19
  });
20
20
 
21
- it('should default to info level', () => {
21
+ it('defaults to info level (debug suppressed, info visible)', () => {
22
22
  const logger = createLogger();
23
23
  logger.debug('hidden');
24
24
  logger.info('visible');
25
-
26
25
  expect(errorSpy).toHaveBeenCalledTimes(1);
27
26
  expect(errorSpy).toHaveBeenCalledWith('[Soleri][INFO] visible');
28
27
  });
29
28
 
30
- it('should suppress messages below configured level', () => {
31
- const logger = createLogger({ level: 'warn' });
29
+ it('suppresses below configured level', () => {
30
+ const logger = createLogger({ level: 'error' });
32
31
  logger.debug('d');
33
32
  logger.info('i');
34
33
  logger.warn('w');
35
34
  logger.error('e');
36
-
37
- expect(errorSpy).toHaveBeenCalledTimes(1); // error
38
- expect(warnSpy).toHaveBeenCalledTimes(1); // warn
39
- expect(warnSpy).toHaveBeenCalledWith('[Soleri][WARN] w');
40
- expect(errorSpy).toHaveBeenCalledWith('[Soleri][ERROR] e');
35
+ expect(errorSpy).toHaveBeenCalledTimes(1);
36
+ expect(warnSpy).not.toHaveBeenCalled();
41
37
  });
42
38
 
43
- it('should output everything at debug level', () => {
39
+ it('shows everything at debug level', () => {
44
40
  const logger = createLogger({ level: 'debug' });
45
41
  logger.debug('d');
46
42
  logger.info('i');
47
43
  logger.warn('w');
48
44
  logger.error('e');
49
-
50
- // debug, info, error go through console.error; warn goes through console.warn
51
- expect(errorSpy).toHaveBeenCalledTimes(3);
45
+ expect(errorSpy).toHaveBeenCalledTimes(3); // debug, info, error
52
46
  expect(warnSpy).toHaveBeenCalledTimes(1);
53
47
  });
54
48
 
55
- it('should route all output to stderr (not stdout)', () => {
49
+ it('never uses console.log (stdout reserved for MCP)', () => {
56
50
  const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
57
51
  const logger = createLogger({ level: 'debug' });
58
52
  logger.debug('d');
59
53
  logger.info('i');
60
54
  logger.warn('w');
61
55
  logger.error('e');
62
-
63
56
  expect(logSpy).not.toHaveBeenCalled();
64
57
  });
65
58
 
66
- it('should use custom prefix', () => {
67
- const logger = createLogger({ prefix: '[my-agent]' });
68
- logger.info('hello');
69
-
70
- expect(errorSpy).toHaveBeenCalledWith('[my-agent][INFO] hello');
59
+ it('uses custom prefix', () => {
60
+ const logger = createLogger({ prefix: '[MyAgent]' });
61
+ logger.info('hi');
62
+ expect(errorSpy).toHaveBeenCalledWith('[MyAgent][INFO] hi');
71
63
  });
72
64
 
73
- it('should include context in log output', () => {
65
+ it('passes context object alongside message', () => {
74
66
  const logger = createLogger();
75
- logger.info('msg', { key: 'value' });
76
-
77
- expect(errorSpy).toHaveBeenCalledWith('[Soleri][INFO] msg', { key: 'value' });
67
+ logger.info('event', { key: 'val' });
68
+ expect(errorSpy).toHaveBeenCalledWith('[Soleri][INFO] event', { key: 'val' });
78
69
  });
79
70
 
80
- it('should respect SOLERI_LOG_LEVEL env var', () => {
81
- process.env.SOLERI_LOG_LEVEL = 'error';
71
+ it('respects SOLERI_LOG_LEVEL env var', () => {
72
+ process.env.SOLERI_LOG_LEVEL = 'warn';
82
73
  const logger = createLogger();
83
74
  logger.info('hidden');
84
- logger.error('visible');
85
-
86
- expect(errorSpy).toHaveBeenCalledTimes(1);
87
- expect(errorSpy).toHaveBeenCalledWith('[Soleri][ERROR] visible');
75
+ logger.warn('visible');
76
+ expect(errorSpy).not.toHaveBeenCalled();
77
+ expect(warnSpy).toHaveBeenCalledTimes(1);
88
78
  });
89
79
 
90
- it('should prefer explicit level over env var', () => {
80
+ it('prefers explicit level over env var', () => {
91
81
  process.env.SOLERI_LOG_LEVEL = 'error';
92
82
  const logger = createLogger({ level: 'debug' });
93
83
  logger.debug('visible');
94
-
95
84
  expect(errorSpy).toHaveBeenCalledTimes(1);
96
85
  });
97
86
 
98
- it('should fall back to info level for invalid SOLERI_LOG_LEVEL', () => {
99
- process.env.SOLERI_LOG_LEVEL = 'verbose'; // invalid
87
+ it('falls back to info for invalid SOLERI_LOG_LEVEL', () => {
88
+ process.env.SOLERI_LOG_LEVEL = 'banana';
100
89
  const logger = createLogger();
101
90
  logger.debug('hidden');
102
91
  logger.info('visible');
103
-
104
92
  expect(errorSpy).toHaveBeenCalledTimes(1);
105
- expect(errorSpy).toHaveBeenCalledWith('[Soleri][INFO] visible');
106
93
  });
107
94
 
108
- it('createLogger with no args returns a Logger instance', () => {
109
- const logger = createLogger();
110
- expect(logger).toBeInstanceOf(Logger);
95
+ it('createLogger returns Logger instance', () => {
96
+ expect(createLogger()).toBeInstanceOf(Logger);
111
97
  });
112
98
  });
113
99
 
@@ -117,7 +103,7 @@ describe('Logger file logging', () => {
117
103
  beforeEach(() => {
118
104
  vi.spyOn(console, 'error').mockImplementation(() => {});
119
105
  vi.spyOn(console, 'warn').mockImplementation(() => {});
120
- tempDir = join(tmpdir(), `logger-test-${Date.now()}`);
106
+ tempDir = join(tmpdir(), `logger-colocated-${Date.now()}-${Math.random().toString(36).slice(2)}`);
121
107
  mkdirSync(tempDir, { recursive: true });
122
108
  });
123
109
 
@@ -126,7 +112,7 @@ describe('Logger file logging', () => {
126
112
  rmSync(tempDir, { recursive: true, force: true });
127
113
  });
128
114
 
129
- it('should create log directory and write log files', () => {
115
+ it('creates log directory and writes daily log file', () => {
130
116
  const logDir = join(tempDir, 'logs');
131
117
  const logger = createLogger({ fileLogDir: logDir });
132
118
  logger.info('test message');
@@ -139,62 +125,55 @@ describe('Logger file logging', () => {
139
125
  expect(content).toContain('[INFO] test message');
140
126
  });
141
127
 
142
- it('should include context in file output', () => {
128
+ it('includes JSON-serialized context in file output', () => {
143
129
  const logDir = join(tempDir, 'logs');
144
130
  const logger = createLogger({ fileLogDir: logDir });
145
- logger.info('event', { action: 'test' });
131
+ logger.info('action', { id: 42 });
146
132
 
147
- const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'));
148
- expect(logFile).toBeDefined();
149
- const content = readFileSync(join(logDir, logFile!), 'utf-8');
150
- expect(content).toContain('"action":"test"');
133
+ const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'))!;
134
+ const content = readFileSync(join(logDir, logFile), 'utf-8');
135
+ expect(content).toContain('"id":42');
151
136
  });
152
137
 
153
- it('enableFileLog with custom prefix uses that prefix', () => {
138
+ it('enableFileLog accepts custom prefix for filename', () => {
154
139
  const logDir = join(tempDir, 'logs');
155
140
  const logger = createLogger();
156
141
  logger.enableFileLog(logDir, 'custom');
157
142
  logger.info('test');
158
143
 
159
- const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'));
160
- expect(logFile).toBeDefined();
144
+ const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'))!;
161
145
  expect(logFile).toMatch(/^custom-/);
162
146
  });
163
147
 
164
- it('should prune log files older than 7 days', () => {
148
+ it('prunes log files older than 7 days', () => {
165
149
  const logDir = join(tempDir, 'logs');
166
150
  mkdirSync(logDir, { recursive: true });
167
151
 
168
- // Create an "old" log file (10 days ago)
169
152
  const oldDate = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
170
- writeFileSync(join(logDir, `agent-${oldDate}.log`), 'old log\n');
153
+ writeFileSync(join(logDir, `agent-${oldDate}.log`), 'old\n');
171
154
 
172
- // Create a "recent" log file (2 days ago)
173
155
  const recentDate = new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
174
- writeFileSync(join(logDir, `agent-${recentDate}.log`), 'recent log\n');
156
+ writeFileSync(join(logDir, `agent-${recentDate}.log`), 'recent\n');
175
157
 
176
- // enableFileLog triggers pruning
177
158
  const logger = createLogger();
178
159
  logger.enableFileLog(logDir);
179
160
 
180
161
  const files = readdirSync(logDir).filter((f) => f.endsWith('.log'));
181
-
182
- // Old file should be pruned, recent + today should remain
183
162
  expect(files).not.toContain(`agent-${oldDate}.log`);
184
163
  expect(files).toContain(`agent-${recentDate}.log`);
185
164
  });
186
165
 
187
- it('should not prune files from different prefix', () => {
166
+ it('does not prune files with different prefix', () => {
188
167
  const logDir = join(tempDir, 'logs');
189
168
  mkdirSync(logDir, { recursive: true });
190
169
 
191
170
  const oldDate = new Date(Date.now() - 10 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
192
- writeFileSync(join(logDir, `other-${oldDate}.log`), 'other log\n');
171
+ writeFileSync(join(logDir, `other-${oldDate}.log`), 'keep\n');
193
172
 
194
173
  const logger = createLogger();
195
174
  logger.enableFileLog(logDir);
196
175
 
197
- const files = readdirSync(logDir).filter((f) => f.endsWith('.log'));
176
+ const files = readdirSync(logDir);
198
177
  expect(files).toContain(`other-${oldDate}.log`);
199
178
  });
200
179
  });