@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,371 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import {
3
+ CircuitBreaker,
4
+ CircuitOpenError,
5
+ computeDelay,
6
+ retry,
7
+ parseRateLimitHeaders,
8
+ } from './utils.js';
9
+ import { LLMError } from './types.js';
10
+
11
+ // ─── CircuitOpenError ───────────────────────────────────────────────
12
+
13
+ describe('CircuitOpenError', () => {
14
+ it('should include the breaker name in the message', () => {
15
+ const err = new CircuitOpenError('test-breaker');
16
+ expect(err.message).toContain('test-breaker');
17
+ expect(err.name).toBe('CircuitOpenError');
18
+ });
19
+
20
+ it('should not be retryable', () => {
21
+ const err = new CircuitOpenError('x');
22
+ expect(err.retryable).toBe(false);
23
+ });
24
+
25
+ it('should be an instance of CircuitOpenError', () => {
26
+ const err = new CircuitOpenError('x');
27
+ expect(err).toBeInstanceOf(CircuitOpenError);
28
+ expect(err).toBeInstanceOf(Error);
29
+ });
30
+ });
31
+
32
+ // ─── CircuitBreaker ─────────────────────────────────────────────────
33
+
34
+ describe('CircuitBreaker', () => {
35
+ beforeEach(() => {
36
+ vi.restoreAllMocks();
37
+ vi.spyOn(console, 'error').mockImplementation(() => {});
38
+ });
39
+
40
+ it('should start in closed state', () => {
41
+ const cb = new CircuitBreaker({ name: 'test' });
42
+ const snap = cb.getState();
43
+ expect(snap.state).toBe('closed');
44
+ expect(snap.failureCount).toBe(0);
45
+ });
46
+
47
+ it('should pass through successful calls in closed state', async () => {
48
+ const cb = new CircuitBreaker({ name: 'test' });
49
+ const result = await cb.call(async () => 42);
50
+ expect(result).toBe(42);
51
+ });
52
+
53
+ it('should rethrow errors from the wrapped function', async () => {
54
+ const cb = new CircuitBreaker({ name: 'test' });
55
+ await expect(
56
+ cb.call(async () => {
57
+ throw new Error('boom');
58
+ }),
59
+ ).rejects.toThrow('boom');
60
+ });
61
+
62
+ it('should not count non-retryable errors as failures', async () => {
63
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
64
+ const nonRetryable = new Error('not retryable');
65
+
66
+ for (let i = 0; i < 5; i++) {
67
+ await expect(
68
+ cb.call(async () => {
69
+ throw nonRetryable;
70
+ }),
71
+ ).rejects.toThrow();
72
+ }
73
+ expect(cb.getState().state).toBe('closed');
74
+ });
75
+
76
+ it('should open after reaching failure threshold with retryable errors', async () => {
77
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
78
+ const retryableErr = new LLMError('rate limited', { retryable: true });
79
+
80
+ await expect(
81
+ cb.call(async () => {
82
+ throw retryableErr;
83
+ }),
84
+ ).rejects.toThrow();
85
+ await expect(
86
+ cb.call(async () => {
87
+ throw retryableErr;
88
+ }),
89
+ ).rejects.toThrow();
90
+ expect(cb.isOpen()).toBe(true);
91
+ });
92
+
93
+ it('should reject calls when open', async () => {
94
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 999_999 });
95
+ const retryableErr = new LLMError('fail', { retryable: true });
96
+
97
+ await expect(
98
+ cb.call(async () => {
99
+ throw retryableErr;
100
+ }),
101
+ ).rejects.toThrow();
102
+ await expect(cb.call(async () => 'ok')).rejects.toThrow(CircuitOpenError);
103
+ });
104
+
105
+ it('should transition to half-open after reset timeout', async () => {
106
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
107
+ const retryableErr = new LLMError('fail', { retryable: true });
108
+
109
+ await expect(
110
+ cb.call(async () => {
111
+ throw retryableErr;
112
+ }),
113
+ ).rejects.toThrow();
114
+ expect(cb.isOpen()).toBe(true);
115
+
116
+ // Wait for reset timeout
117
+ await new Promise((r) => setTimeout(r, 20));
118
+ expect(cb.isOpen()).toBe(false); // shouldProbe returns true
119
+ expect(cb.getState().state).toBe('half-open');
120
+ });
121
+
122
+ it('should close on success after half-open probe', async () => {
123
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
124
+ const retryableErr = new LLMError('fail', { retryable: true });
125
+
126
+ await expect(
127
+ cb.call(async () => {
128
+ throw retryableErr;
129
+ }),
130
+ ).rejects.toThrow();
131
+ await new Promise((r) => setTimeout(r, 20));
132
+
133
+ const result = await cb.call(async () => 'recovered');
134
+ expect(result).toBe('recovered');
135
+ expect(cb.getState().state).toBe('closed');
136
+ });
137
+
138
+ it('should re-open on failure in half-open state', async () => {
139
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 10 });
140
+ const retryableErr = new LLMError('fail', { retryable: true });
141
+
142
+ await expect(
143
+ cb.call(async () => {
144
+ throw retryableErr;
145
+ }),
146
+ ).rejects.toThrow();
147
+ await new Promise((r) => setTimeout(r, 20));
148
+
149
+ await expect(
150
+ cb.call(async () => {
151
+ throw retryableErr;
152
+ }),
153
+ ).rejects.toThrow();
154
+ expect(cb.getState().state).toBe('open');
155
+ });
156
+
157
+ it('should reset state completely via reset()', async () => {
158
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 1, resetTimeoutMs: 999_999 });
159
+ const retryableErr = new LLMError('fail', { retryable: true });
160
+
161
+ await expect(
162
+ cb.call(async () => {
163
+ throw retryableErr;
164
+ }),
165
+ ).rejects.toThrow();
166
+ expect(cb.isOpen()).toBe(true);
167
+
168
+ cb.reset();
169
+ expect(cb.getState().state).toBe('closed');
170
+ expect(cb.getState().failureCount).toBe(0);
171
+ expect(cb.getState().lastFailureAt).toBeNull();
172
+ });
173
+
174
+ it('should record failures synchronously via recordFailure()', () => {
175
+ const cb = new CircuitBreaker({ name: 'test', failureThreshold: 2 });
176
+ cb.recordFailure();
177
+ expect(cb.getState().failureCount).toBe(1);
178
+ expect(cb.getState().state).toBe('closed');
179
+
180
+ cb.recordFailure();
181
+ expect(cb.getState().state).toBe('open');
182
+ });
183
+
184
+ it('should use default config values when none provided', () => {
185
+ const cb = new CircuitBreaker();
186
+ const snap = cb.getState();
187
+ expect(snap.state).toBe('closed');
188
+ });
189
+ });
190
+
191
+ // ─── computeDelay ───────────────────────────────────────────────────
192
+
193
+ describe('computeDelay', () => {
194
+ it('should use retryAfterMs from error when available', () => {
195
+ const error = { retryAfterMs: 5000 };
196
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
197
+ expect(computeDelay(error, 0, config)).toBe(5000);
198
+ });
199
+
200
+ it('should cap retryAfterMs at maxDelayMs', () => {
201
+ const error = { retryAfterMs: 100_000 };
202
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
203
+ expect(computeDelay(error, 0, config)).toBe(30000);
204
+ });
205
+
206
+ it('should compute exponential backoff without jitter', () => {
207
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0 };
208
+ expect(computeDelay({}, 0, config)).toBe(1000);
209
+ expect(computeDelay({}, 1, config)).toBe(2000);
210
+ expect(computeDelay({}, 2, config)).toBe(4000);
211
+ });
212
+
213
+ it('should cap exponential delay at maxDelayMs', () => {
214
+ const config = { maxAttempts: 10, baseDelayMs: 1000, maxDelayMs: 5000, jitter: 0 };
215
+ expect(computeDelay({}, 10, config)).toBe(5000);
216
+ });
217
+
218
+ it('should apply jitter within range', () => {
219
+ const config = { maxAttempts: 3, baseDelayMs: 1000, maxDelayMs: 30000, jitter: 0.5 };
220
+ const delays = Array.from({ length: 50 }, () => computeDelay({}, 0, config));
221
+ expect(delays.every((d) => d >= 500 && d <= 1500)).toBe(true);
222
+ });
223
+
224
+ it('should never return negative delay', () => {
225
+ vi.spyOn(Math, 'random').mockReturnValue(0);
226
+ const config = { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 30000, jitter: 1 };
227
+ expect(computeDelay({}, 0, config)).toBeGreaterThanOrEqual(0);
228
+ vi.restoreAllMocks();
229
+ });
230
+ });
231
+
232
+ // ─── retry ──────────────────────────────────────────────────────────
233
+
234
+ describe('retry', () => {
235
+ beforeEach(() => {
236
+ vi.useFakeTimers();
237
+ });
238
+
239
+ afterAll(() => {
240
+ vi.useRealTimers();
241
+ });
242
+
243
+ it('should return on first success', async () => {
244
+ vi.useRealTimers();
245
+ const fn = vi.fn().mockResolvedValue('ok');
246
+ const result = await retry(fn);
247
+ expect(result).toBe('ok');
248
+ expect(fn).toHaveBeenCalledTimes(1);
249
+ });
250
+
251
+ it('should throw if maxAttempts < 1', async () => {
252
+ vi.useRealTimers();
253
+ await expect(retry(async () => 'ok', { maxAttempts: 0 })).rejects.toThrow(
254
+ 'maxAttempts must be >= 1',
255
+ );
256
+ });
257
+
258
+ it('should throw non-retryable errors immediately', async () => {
259
+ vi.useRealTimers();
260
+ const fn = vi.fn().mockRejectedValue(new Error('fatal'));
261
+ await expect(retry(fn, { maxAttempts: 3 })).rejects.toThrow('fatal');
262
+ expect(fn).toHaveBeenCalledTimes(1);
263
+ });
264
+
265
+ it('should retry retryable errors up to maxAttempts', async () => {
266
+ vi.useRealTimers();
267
+ const retryableErr = new LLMError('rate limited', { retryable: true });
268
+ const fn = vi.fn().mockRejectedValue(retryableErr);
269
+ await expect(
270
+ retry(fn, { maxAttempts: 2, baseDelayMs: 1, maxDelayMs: 1, jitter: 0 }),
271
+ ).rejects.toThrow('rate limited');
272
+ expect(fn).toHaveBeenCalledTimes(2);
273
+ });
274
+
275
+ it('should succeed on retry after initial failures', async () => {
276
+ vi.useRealTimers();
277
+ const retryableErr = new LLMError('transient', { retryable: true });
278
+ const fn = vi.fn().mockRejectedValueOnce(retryableErr).mockResolvedValueOnce('recovered');
279
+
280
+ const result = await retry(fn, { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 1, jitter: 0 });
281
+ expect(result).toBe('recovered');
282
+ expect(fn).toHaveBeenCalledTimes(2);
283
+ });
284
+
285
+ it('should call onRetry callback on each retry', async () => {
286
+ vi.useRealTimers();
287
+ const retryableErr = new LLMError('transient', { retryable: true });
288
+ const onRetry = vi.fn();
289
+ const fn = vi.fn().mockRejectedValueOnce(retryableErr).mockResolvedValueOnce('ok');
290
+
291
+ await retry(fn, { maxAttempts: 3, baseDelayMs: 1, maxDelayMs: 1, jitter: 0, onRetry });
292
+ expect(onRetry).toHaveBeenCalledTimes(1);
293
+ expect(onRetry).toHaveBeenCalledWith(retryableErr, 1, expect.any(Number));
294
+ });
295
+
296
+ it('should respect custom shouldRetry predicate', async () => {
297
+ vi.useRealTimers();
298
+ const customErr = new Error('custom');
299
+ const fn = vi.fn().mockRejectedValue(customErr);
300
+ const shouldRetry = vi.fn().mockReturnValue(true);
301
+
302
+ await expect(
303
+ retry(fn, { maxAttempts: 2, baseDelayMs: 1, maxDelayMs: 1, jitter: 0, shouldRetry }),
304
+ ).rejects.toThrow('custom');
305
+ expect(fn).toHaveBeenCalledTimes(2);
306
+ expect(shouldRetry).toHaveBeenCalled();
307
+ });
308
+ });
309
+
310
+ // Need this import for afterAll
311
+ import { afterAll } from 'vitest';
312
+
313
+ // ─── parseRateLimitHeaders ──────────────────────────────────────────
314
+
315
+ describe('parseRateLimitHeaders', () => {
316
+ function makeHeaders(obj: Record<string, string>): Headers {
317
+ return new Headers(obj);
318
+ }
319
+
320
+ it('should parse remaining requests header', () => {
321
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-remaining-requests': '42' }));
322
+ expect(info.remaining).toBe(42);
323
+ });
324
+
325
+ it('should return null for missing remaining header', () => {
326
+ const info = parseRateLimitHeaders(makeHeaders({}));
327
+ expect(info.remaining).toBeNull();
328
+ });
329
+
330
+ it('should return null for non-numeric remaining header', () => {
331
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-remaining-requests': 'abc' }));
332
+ expect(info.remaining).toBeNull();
333
+ });
334
+
335
+ it('should parse retry-after header as seconds', () => {
336
+ const info = parseRateLimitHeaders(makeHeaders({ 'retry-after': '2.5' }));
337
+ expect(info.retryAfterMs).toBe(2500);
338
+ });
339
+
340
+ it('should return null for non-numeric retry-after', () => {
341
+ const info = parseRateLimitHeaders(makeHeaders({ 'retry-after': 'invalid' }));
342
+ expect(info.retryAfterMs).toBeNull();
343
+ });
344
+
345
+ it('should parse reset duration with minutes and seconds', () => {
346
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '2m30s' }));
347
+ expect(info.resetMs).toBe(2 * 60_000 + 30 * 1000);
348
+ });
349
+
350
+ it('should parse reset duration with milliseconds', () => {
351
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '500ms' }));
352
+ expect(info.resetMs).toBe(500);
353
+ });
354
+
355
+ it('should parse reset duration with seconds only', () => {
356
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': '45s' }));
357
+ expect(info.resetMs).toBe(45000);
358
+ });
359
+
360
+ it('should return null for unparseable reset duration', () => {
361
+ const info = parseRateLimitHeaders(makeHeaders({ 'x-ratelimit-reset-requests': 'unknown' }));
362
+ expect(info.resetMs).toBeNull();
363
+ });
364
+
365
+ it('should return all nulls when no headers present', () => {
366
+ const info = parseRateLimitHeaders(makeHeaders({}));
367
+ expect(info.remaining).toBeNull();
368
+ expect(info.resetMs).toBeNull();
369
+ expect(info.retryAfterMs).toBeNull();
370
+ });
371
+ });
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,10 @@ 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(
107
+ tmpdir(),
108
+ `logger-colocated-${Date.now()}-${Math.random().toString(36).slice(2)}`,
109
+ );
121
110
  mkdirSync(tempDir, { recursive: true });
122
111
  });
123
112
 
@@ -126,7 +115,7 @@ describe('Logger file logging', () => {
126
115
  rmSync(tempDir, { recursive: true, force: true });
127
116
  });
128
117
 
129
- it('should create log directory and write log files', () => {
118
+ it('creates log directory and writes daily log file', () => {
130
119
  const logDir = join(tempDir, 'logs');
131
120
  const logger = createLogger({ fileLogDir: logDir });
132
121
  logger.info('test message');
@@ -139,62 +128,55 @@ describe('Logger file logging', () => {
139
128
  expect(content).toContain('[INFO] test message');
140
129
  });
141
130
 
142
- it('should include context in file output', () => {
131
+ it('includes JSON-serialized context in file output', () => {
143
132
  const logDir = join(tempDir, 'logs');
144
133
  const logger = createLogger({ fileLogDir: logDir });
145
- logger.info('event', { action: 'test' });
134
+ logger.info('action', { id: 42 });
146
135
 
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"');
136
+ const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'))!;
137
+ const content = readFileSync(join(logDir, logFile), 'utf-8');
138
+ expect(content).toContain('"id":42');
151
139
  });
152
140
 
153
- it('enableFileLog with custom prefix uses that prefix', () => {
141
+ it('enableFileLog accepts custom prefix for filename', () => {
154
142
  const logDir = join(tempDir, 'logs');
155
143
  const logger = createLogger();
156
144
  logger.enableFileLog(logDir, 'custom');
157
145
  logger.info('test');
158
146
 
159
- const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'));
160
- expect(logFile).toBeDefined();
147
+ const logFile = readdirSync(logDir).find((f) => f.endsWith('.log'))!;
161
148
  expect(logFile).toMatch(/^custom-/);
162
149
  });
163
150
 
164
- it('should prune log files older than 7 days', () => {
151
+ it('prunes log files older than 7 days', () => {
165
152
  const logDir = join(tempDir, 'logs');
166
153
  mkdirSync(logDir, { recursive: true });
167
154
 
168
- // Create an "old" log file (10 days ago)
169
155
  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');
156
+ writeFileSync(join(logDir, `agent-${oldDate}.log`), 'old\n');
171
157
 
172
- // Create a "recent" log file (2 days ago)
173
158
  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');
159
+ writeFileSync(join(logDir, `agent-${recentDate}.log`), 'recent\n');
175
160
 
176
- // enableFileLog triggers pruning
177
161
  const logger = createLogger();
178
162
  logger.enableFileLog(logDir);
179
163
 
180
164
  const files = readdirSync(logDir).filter((f) => f.endsWith('.log'));
181
-
182
- // Old file should be pruned, recent + today should remain
183
165
  expect(files).not.toContain(`agent-${oldDate}.log`);
184
166
  expect(files).toContain(`agent-${recentDate}.log`);
185
167
  });
186
168
 
187
- it('should not prune files from different prefix', () => {
169
+ it('does not prune files with different prefix', () => {
188
170
  const logDir = join(tempDir, 'logs');
189
171
  mkdirSync(logDir, { recursive: true });
190
172
 
191
173
  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');
174
+ writeFileSync(join(logDir, `other-${oldDate}.log`), 'keep\n');
193
175
 
194
176
  const logger = createLogger();
195
177
  logger.enableFileLog(logDir);
196
178
 
197
- const files = readdirSync(logDir).filter((f) => f.endsWith('.log'));
179
+ const files = readdirSync(logDir);
198
180
  expect(files).toContain(`other-${oldDate}.log`);
199
181
  });
200
182
  });