@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,175 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { evaluateQuality } from './quality-gate.js';
3
+ import type { IntelligenceEntry } from '../intelligence/types.js';
4
+ import type { LLMClient } from '../llm/llm-client.js';
5
+
6
+ function makeEntry(overrides: Partial<IntelligenceEntry> = {}): IntelligenceEntry {
7
+ return {
8
+ id: overrides.id ?? 'test-1',
9
+ type: overrides.type ?? 'pattern',
10
+ domain: overrides.domain ?? 'testing',
11
+ title: overrides.title ?? 'Test Pattern',
12
+ severity: overrides.severity ?? 'warning',
13
+ description: overrides.description ?? 'A test pattern.',
14
+ tags: overrides.tags ?? ['testing'],
15
+ };
16
+ }
17
+
18
+ function mockLLM(response: string): LLMClient {
19
+ return {
20
+ complete: vi.fn().mockResolvedValue({ text: response }),
21
+ } as unknown as LLMClient;
22
+ }
23
+
24
+ describe('evaluateQuality', () => {
25
+ it('returns ACCEPT fallback when llm is null', async () => {
26
+ const result = await evaluateQuality(makeEntry(), null);
27
+ expect(result.evaluated).toBe(false);
28
+ expect(result.verdict).toBe('ACCEPT');
29
+ expect(result.overallScore).toBe(50);
30
+ expect(result.reasoning).toContain('LLM unavailable');
31
+ });
32
+
33
+ it('returns ACCEPT for high-quality entry', async () => {
34
+ const llm = mockLLM(
35
+ JSON.stringify({
36
+ verdict: 'ACCEPT',
37
+ overallScore: 85,
38
+ scores: {
39
+ novelty: 80,
40
+ actionability: 90,
41
+ specificity: 85,
42
+ relevance: 80,
43
+ informationDensity: 90,
44
+ },
45
+ reasoning: 'High quality entry with specific guidance.',
46
+ }),
47
+ );
48
+
49
+ const result = await evaluateQuality(makeEntry(), llm);
50
+ expect(result.evaluated).toBe(true);
51
+ expect(result.verdict).toBe('ACCEPT');
52
+ expect(result.overallScore).toBe(85);
53
+ });
54
+
55
+ it('returns REJECT for low-quality entry', async () => {
56
+ const llm = mockLLM(
57
+ JSON.stringify({
58
+ verdict: 'REJECT',
59
+ overallScore: 30,
60
+ scores: {
61
+ novelty: 10,
62
+ actionability: 30,
63
+ specificity: 40,
64
+ relevance: 50,
65
+ informationDensity: 20,
66
+ },
67
+ reasoning: 'Too generic.',
68
+ rejectReasons: ['Low novelty', 'Not actionable'],
69
+ }),
70
+ );
71
+
72
+ const result = await evaluateQuality(makeEntry(), llm);
73
+ expect(result.evaluated).toBe(true);
74
+ expect(result.verdict).toBe('REJECT');
75
+ expect(result.overallScore).toBe(30);
76
+ expect(result.rejectReasons).toEqual(['Low novelty', 'Not actionable']);
77
+ });
78
+
79
+ it('returns fallback with error on LLM failure', async () => {
80
+ const llm = {
81
+ complete: vi.fn().mockRejectedValue(new Error('timeout')),
82
+ } as unknown as LLMClient;
83
+
84
+ const result = await evaluateQuality(makeEntry(), llm);
85
+ expect(result.evaluated).toBe(false);
86
+ expect(result.verdict).toBe('ACCEPT');
87
+ expect(result.error).toBe('timeout');
88
+ });
89
+
90
+ it('returns fallback with error on invalid JSON', async () => {
91
+ const llm = mockLLM('invalid json response');
92
+ const result = await evaluateQuality(makeEntry(), llm);
93
+ expect(result.evaluated).toBe(false);
94
+ expect(result.error).toBeDefined();
95
+ });
96
+
97
+ it('handles missing fields in LLM response', async () => {
98
+ const llm = mockLLM(JSON.stringify({ verdict: 'ACCEPT' }));
99
+ const result = await evaluateQuality(makeEntry(), llm);
100
+ expect(result.evaluated).toBe(true);
101
+ expect(result.overallScore).toBe(50);
102
+ expect(result.reasoning).toBe('');
103
+ });
104
+
105
+ it('normalizes non-REJECT verdict to ACCEPT', async () => {
106
+ const llm = mockLLM(
107
+ JSON.stringify({
108
+ verdict: 'MAYBE',
109
+ overallScore: 60,
110
+ scores: {
111
+ novelty: 60,
112
+ actionability: 60,
113
+ specificity: 60,
114
+ relevance: 60,
115
+ informationDensity: 60,
116
+ },
117
+ reasoning: 'Borderline entry.',
118
+ }),
119
+ );
120
+
121
+ const result = await evaluateQuality(makeEntry(), llm);
122
+ expect(result.verdict).toBe('ACCEPT');
123
+ });
124
+
125
+ it('includes optional entry fields in prompt', async () => {
126
+ const llm = mockLLM(
127
+ JSON.stringify({
128
+ verdict: 'ACCEPT',
129
+ overallScore: 70,
130
+ scores: {
131
+ novelty: 70,
132
+ actionability: 70,
133
+ specificity: 70,
134
+ relevance: 70,
135
+ informationDensity: 70,
136
+ },
137
+ reasoning: 'OK.',
138
+ }),
139
+ );
140
+
141
+ const entry = makeEntry();
142
+ entry.why = 'Because security matters';
143
+ entry.example = 'jwt.verify(token)';
144
+ entry.context = 'Node.js backend';
145
+
146
+ await evaluateQuality(entry, llm);
147
+
148
+ const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
149
+ expect(call.userPrompt).toContain('Because security matters');
150
+ expect(call.userPrompt).toContain('jwt.verify(token)');
151
+ expect(call.userPrompt).toContain('Node.js backend');
152
+ });
153
+
154
+ it('uses low temperature for consistent scoring', async () => {
155
+ const llm = mockLLM(
156
+ JSON.stringify({
157
+ verdict: 'ACCEPT',
158
+ overallScore: 70,
159
+ scores: {
160
+ novelty: 70,
161
+ actionability: 70,
162
+ specificity: 70,
163
+ relevance: 70,
164
+ informationDensity: 70,
165
+ },
166
+ reasoning: 'OK.',
167
+ }),
168
+ );
169
+
170
+ await evaluateQuality(makeEntry(), llm);
171
+
172
+ const call = (llm.complete as ReturnType<typeof vi.fn>).mock.calls[0][0];
173
+ expect(call.temperature).toBe(0.1);
174
+ });
175
+ });
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Curator Schema — DDL for curator tables.
3
+ */
4
+
5
+ import type { PersistenceProvider } from '../persistence/types.js';
6
+
7
+ export const CURATOR_SCHEMA = `
8
+ CREATE TABLE IF NOT EXISTS curator_entry_state (
9
+ entry_id TEXT PRIMARY KEY,
10
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'stale', 'archived')),
11
+ confidence REAL NOT NULL DEFAULT 1.0,
12
+ source TEXT NOT NULL DEFAULT 'unknown' CHECK(source IN ('manual', 'capture', 'seed', 'unknown')),
13
+ last_groomed_at INTEGER,
14
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
15
+ );
16
+
17
+ CREATE TABLE IF NOT EXISTS curator_tag_canonical (
18
+ tag TEXT PRIMARY KEY,
19
+ description TEXT,
20
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
21
+ );
22
+
23
+ CREATE TABLE IF NOT EXISTS curator_tag_alias (
24
+ alias TEXT PRIMARY KEY,
25
+ canonical TEXT NOT NULL,
26
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
27
+ FOREIGN KEY (canonical) REFERENCES curator_tag_canonical(tag)
28
+ );
29
+
30
+ CREATE TABLE IF NOT EXISTS curator_changelog (
31
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
32
+ action TEXT NOT NULL,
33
+ entry_id TEXT NOT NULL,
34
+ before_value TEXT,
35
+ after_value TEXT,
36
+ reason TEXT NOT NULL,
37
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
38
+ );
39
+
40
+ CREATE TABLE IF NOT EXISTS curator_entry_history (
41
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
42
+ entry_id TEXT NOT NULL,
43
+ snapshot TEXT NOT NULL,
44
+ changed_by TEXT DEFAULT 'system',
45
+ change_reason TEXT,
46
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
47
+ );
48
+
49
+ CREATE TABLE IF NOT EXISTS curator_contradictions (
50
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
51
+ pattern_id TEXT NOT NULL,
52
+ antipattern_id TEXT NOT NULL,
53
+ similarity REAL NOT NULL,
54
+ status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open', 'resolved', 'dismissed')),
55
+ created_at INTEGER NOT NULL DEFAULT (unixepoch()),
56
+ resolved_at INTEGER,
57
+ UNIQUE(pattern_id, antipattern_id)
58
+ );
59
+ CREATE INDEX IF NOT EXISTS idx_curator_state_status ON curator_entry_state(status);
60
+ CREATE INDEX IF NOT EXISTS idx_curator_changelog_entry ON curator_changelog(entry_id);
61
+ `;
62
+
63
+ export function initializeTables(provider: PersistenceProvider): void {
64
+ provider.execSql(CURATOR_SCHEMA);
65
+ }
@@ -0,0 +1,173 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import {
3
+ normalizeTag,
4
+ normalizeTags,
5
+ normalizeAndDedup,
6
+ addTagAlias,
7
+ getCanonicalTags,
8
+ seedDefaultAliases,
9
+ DEFAULT_TAG_ALIASES,
10
+ type TagStore,
11
+ } from './tag-manager.js';
12
+
13
+ function mockTagStore(): TagStore {
14
+ const aliases = new Map<string, string>();
15
+ const canonicals = new Map<string, string | null>();
16
+
17
+ return {
18
+ getAlias: vi.fn((lower: string) => aliases.get(lower) ?? null),
19
+ insertCanonical: vi.fn((tag: string) => {
20
+ canonicals.set(tag, null);
21
+ }),
22
+ upsertAlias: vi.fn((alias: string, canonical: string) => {
23
+ aliases.set(alias, canonical);
24
+ }),
25
+ getCanonicalRows: vi.fn(() =>
26
+ Array.from(canonicals.entries()).map(([tag, description]) => ({
27
+ tag,
28
+ description,
29
+ alias_count: Array.from(aliases.values()).filter((c) => c === tag).length,
30
+ })),
31
+ ),
32
+ countTagUsage: vi.fn(() => 0),
33
+ };
34
+ }
35
+
36
+ describe('tag-manager', () => {
37
+ let store: TagStore;
38
+
39
+ beforeEach(() => {
40
+ store = mockTagStore();
41
+ });
42
+
43
+ describe('DEFAULT_TAG_ALIASES', () => {
44
+ it('exports expected alias count', () => {
45
+ expect(DEFAULT_TAG_ALIASES.length).toBe(13);
46
+ });
47
+
48
+ it('includes common aliases', () => {
49
+ const aliasMap = new Map(DEFAULT_TAG_ALIASES);
50
+ expect(aliasMap.get('a11y')).toBe('accessibility');
51
+ expect(aliasMap.get('ts')).toBe('typescript');
52
+ expect(aliasMap.get('js')).toBe('javascript');
53
+ expect(aliasMap.get('perf')).toBe('performance');
54
+ });
55
+ });
56
+
57
+ describe('normalizeTag', () => {
58
+ it('returns aliased result when store has alias', () => {
59
+ (store.getAlias as ReturnType<typeof vi.fn>).mockReturnValue('accessibility');
60
+ const result = normalizeTag('a11y', store);
61
+ expect(result).toEqual({ original: 'a11y', normalized: 'accessibility', wasAliased: true });
62
+ });
63
+
64
+ it('returns lowercased tag when no alias found', () => {
65
+ const result = normalizeTag('MyCustomTag', store);
66
+ expect(result).toEqual({
67
+ original: 'MyCustomTag',
68
+ normalized: 'mycustomtag',
69
+ wasAliased: false,
70
+ });
71
+ });
72
+
73
+ it('trims whitespace', () => {
74
+ const result = normalizeTag(' spaced ', store);
75
+ expect(result.normalized).toBe('spaced');
76
+ });
77
+
78
+ it('lowercases before lookup', () => {
79
+ normalizeTag('A11Y', store);
80
+ expect(store.getAlias).toHaveBeenCalledWith('a11y');
81
+ });
82
+ });
83
+
84
+ describe('normalizeTags', () => {
85
+ it('normalizes each tag in the array', () => {
86
+ (store.getAlias as ReturnType<typeof vi.fn>)
87
+ .mockReturnValueOnce('accessibility')
88
+ .mockReturnValueOnce(null);
89
+ const results = normalizeTags(['a11y', 'custom'], store);
90
+ expect(results).toHaveLength(2);
91
+ expect(results[0].wasAliased).toBe(true);
92
+ expect(results[1].wasAliased).toBe(false);
93
+ });
94
+
95
+ it('returns empty array for empty input', () => {
96
+ expect(normalizeTags([], store)).toEqual([]);
97
+ });
98
+ });
99
+
100
+ describe('normalizeAndDedup', () => {
101
+ it('deduplicates after normalization', () => {
102
+ (store.getAlias as ReturnType<typeof vi.fn>)
103
+ .mockReturnValueOnce('styling') // css -> styling
104
+ .mockReturnValueOnce('styling'); // tailwind -> styling
105
+ const { results, dedupedTags, changed } = normalizeAndDedup(['css', 'tailwind'], store);
106
+ expect(results).toHaveLength(2);
107
+ expect(dedupedTags).toEqual(['styling']);
108
+ expect(changed).toBe(true);
109
+ });
110
+
111
+ it('reports changed=false when no aliases applied', () => {
112
+ const { changed } = normalizeAndDedup(['custom', 'other'], store);
113
+ expect(changed).toBe(false);
114
+ });
115
+
116
+ it('reports changed=true when any tag is aliased', () => {
117
+ (store.getAlias as ReturnType<typeof vi.fn>)
118
+ .mockReturnValueOnce('accessibility')
119
+ .mockReturnValueOnce(null);
120
+ const { changed } = normalizeAndDedup(['a11y', 'custom'], store);
121
+ expect(changed).toBe(true);
122
+ });
123
+ });
124
+
125
+ describe('addTagAlias', () => {
126
+ it('inserts canonical and upserts alias', () => {
127
+ addTagAlias('react', 'frontend', store);
128
+ expect(store.insertCanonical).toHaveBeenCalledWith('frontend');
129
+ expect(store.upsertAlias).toHaveBeenCalledWith('react', 'frontend');
130
+ });
131
+
132
+ it('lowercases and trims both alias and canonical', () => {
133
+ addTagAlias(' React ', ' Frontend ', store);
134
+ expect(store.insertCanonical).toHaveBeenCalledWith('frontend');
135
+ expect(store.upsertAlias).toHaveBeenCalledWith('react', 'frontend');
136
+ });
137
+ });
138
+
139
+ describe('getCanonicalTags', () => {
140
+ it('maps rows to CanonicalTag objects', () => {
141
+ (store.getCanonicalRows as ReturnType<typeof vi.fn>).mockReturnValue([
142
+ { tag: 'styling', description: 'CSS stuff', alias_count: 3 },
143
+ ]);
144
+ (store.countTagUsage as ReturnType<typeof vi.fn>).mockReturnValue(5);
145
+
146
+ const tags = getCanonicalTags(store);
147
+ expect(tags).toEqual([
148
+ { tag: 'styling', description: 'CSS stuff', usageCount: 5, aliasCount: 3 },
149
+ ]);
150
+ });
151
+
152
+ it('returns empty array when no canonicals', () => {
153
+ (store.getCanonicalRows as ReturnType<typeof vi.fn>).mockReturnValue([]);
154
+ expect(getCanonicalTags(store)).toEqual([]);
155
+ });
156
+ });
157
+
158
+ describe('seedDefaultAliases', () => {
159
+ it('inserts all unique canonical tags', () => {
160
+ seedDefaultAliases(store);
161
+ const uniqueCanonicals = new Set(DEFAULT_TAG_ALIASES.map(([, c]) => c));
162
+ expect(store.insertCanonical).toHaveBeenCalledTimes(uniqueCanonicals.size);
163
+ });
164
+
165
+ it('upserts all alias pairs', () => {
166
+ seedDefaultAliases(store);
167
+ expect(store.upsertAlias).toHaveBeenCalledTimes(DEFAULT_TAG_ALIASES.length);
168
+ // Spot check
169
+ expect(store.upsertAlias).toHaveBeenCalledWith('a11y', 'accessibility');
170
+ expect(store.upsertAlias).toHaveBeenCalledWith('ts', 'typescript');
171
+ });
172
+ });
173
+ });
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Tag Manager — tag normalization, aliasing, and suggestion logic.
3
+ *
4
+ * Pure logic where possible; database access is delegated via a TagStore interface.
5
+ */
6
+
7
+ import type { TagNormalizationResult, CanonicalTag } from './types.js';
8
+
9
+ // ─── Constants ──────────────────────────────────────────────────────
10
+
11
+ export const DEFAULT_TAG_ALIASES: Array<[string, string]> = [
12
+ ['a11y', 'accessibility'],
13
+ ['ts', 'typescript'],
14
+ ['js', 'javascript'],
15
+ ['css', 'styling'],
16
+ ['tailwind', 'styling'],
17
+ ['tw', 'styling'],
18
+ ['vitest', 'testing'],
19
+ ['jest', 'testing'],
20
+ ['perf', 'performance'],
21
+ ['sec', 'security'],
22
+ ['auth', 'authentication'],
23
+ ['i18n', 'internationalization'],
24
+ ['l10n', 'localization'],
25
+ ];
26
+
27
+ // ─── Tag Store Interface ────────────────────────────────────────────
28
+
29
+ /**
30
+ * Thin abstraction over the persistence layer for tag operations.
31
+ * Implemented by the Curator facade using its PersistenceProvider.
32
+ */
33
+ export interface TagStore {
34
+ getAlias(lower: string): string | null;
35
+ insertCanonical(tag: string): void;
36
+ upsertAlias(alias: string, canonical: string): void;
37
+ getCanonicalRows(): Array<{ tag: string; description: string | null; alias_count: number }>;
38
+ countTagUsage(tag: string): number;
39
+ }
40
+
41
+ // ─── Normalize ──────────────────────────────────────────────────────
42
+
43
+ export function normalizeTag(tag: string, store: TagStore): TagNormalizationResult {
44
+ const lower = tag.toLowerCase().trim();
45
+ const canonical = store.getAlias(lower);
46
+ if (canonical) {
47
+ return { original: tag, normalized: canonical, wasAliased: true };
48
+ }
49
+ return { original: tag, normalized: lower, wasAliased: false };
50
+ }
51
+
52
+ export function normalizeTags(tags: string[], store: TagStore): TagNormalizationResult[] {
53
+ return tags.map((tag) => normalizeTag(tag, store));
54
+ }
55
+
56
+ /**
57
+ * Deduplicate and return final tag list after normalization.
58
+ */
59
+ export function normalizeAndDedup(
60
+ tags: string[],
61
+ store: TagStore,
62
+ ): { results: TagNormalizationResult[]; dedupedTags: string[]; changed: boolean } {
63
+ const results: TagNormalizationResult[] = [];
64
+ const normalizedTags: string[] = [];
65
+ let changed = false;
66
+
67
+ for (const tag of tags) {
68
+ const result = normalizeTag(tag, store);
69
+ results.push(result);
70
+ normalizedTags.push(result.normalized);
71
+ if (result.normalized !== tag) changed = true;
72
+ }
73
+
74
+ const dedupedTags = [...new Set(normalizedTags)];
75
+ return { results, dedupedTags, changed };
76
+ }
77
+
78
+ // ─── Alias Management ───────────────────────────────────────────────
79
+
80
+ export function addTagAlias(alias: string, canonical: string, store: TagStore): void {
81
+ const lower = alias.toLowerCase().trim();
82
+ const canonicalLower = canonical.toLowerCase().trim();
83
+ store.insertCanonical(canonicalLower);
84
+ store.upsertAlias(lower, canonicalLower);
85
+ }
86
+
87
+ // ─── Canonical Tags ─────────────────────────────────────────────────
88
+
89
+ export function getCanonicalTags(store: TagStore): CanonicalTag[] {
90
+ const rows = store.getCanonicalRows();
91
+ return rows.map((row) => ({
92
+ tag: row.tag,
93
+ description: row.description,
94
+ usageCount: store.countTagUsage(row.tag),
95
+ aliasCount: row.alias_count,
96
+ }));
97
+ }
98
+
99
+ // ─── Seed ───────────────────────────────────────────────────────────
100
+
101
+ export function seedDefaultAliases(store: TagStore): void {
102
+ const canonicals = new Set(DEFAULT_TAG_ALIASES.map(([, c]) => c));
103
+ for (const tag of canonicals) {
104
+ store.insertCanonical(tag);
105
+ }
106
+ for (const [alias, canonical] of DEFAULT_TAG_ALIASES) {
107
+ store.upsertAlias(alias, canonical);
108
+ }
109
+ }
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Colocated tests for domain-packs/inject-rules.ts
3
+ *
4
+ * Tests: inject into new file, inject into existing, idempotent replace,
5
+ * remove, no-op on empty content.
6
+ */
7
+
8
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
9
+ import { mkdtempSync, writeFileSync, readFileSync, rmSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { tmpdir } from 'node:os';
12
+ import { injectDomainRules, removeDomainRules } from './inject-rules.js';
13
+
14
+ let tempDir: string;
15
+
16
+ beforeEach(() => {
17
+ tempDir = mkdtempSync(join(tmpdir(), 'inject-rules-test-'));
18
+ });
19
+
20
+ afterEach(() => {
21
+ rmSync(tempDir, { recursive: true, force: true });
22
+ });
23
+
24
+ describe('injectDomainRules', () => {
25
+ it('creates file if it does not exist', () => {
26
+ const filePath = join(tempDir, 'CLAUDE.md');
27
+ injectDomainRules(filePath, 'design', '## Design Rules\nUse semantic tokens.');
28
+ const content = readFileSync(filePath, 'utf-8');
29
+ expect(content).toContain('<!-- domain:design -->');
30
+ expect(content).toContain('## Design Rules');
31
+ expect(content).toContain('<!-- /domain:design -->');
32
+ });
33
+
34
+ it('appends to existing file', () => {
35
+ const filePath = join(tempDir, 'CLAUDE.md');
36
+ writeFileSync(filePath, '# Agent Rules\n\nExisting content.\n');
37
+ injectDomainRules(filePath, 'security', 'Security rules here.');
38
+ const content = readFileSync(filePath, 'utf-8');
39
+ expect(content).toContain('# Agent Rules');
40
+ expect(content).toContain('<!-- domain:security -->');
41
+ expect(content).toContain('Security rules here.');
42
+ });
43
+
44
+ it('is idempotent — replaces existing block', () => {
45
+ const filePath = join(tempDir, 'CLAUDE.md');
46
+ writeFileSync(filePath, '# Header\n');
47
+ injectDomainRules(filePath, 'design', 'Version 1');
48
+ injectDomainRules(filePath, 'design', 'Version 2');
49
+ const content = readFileSync(filePath, 'utf-8');
50
+ expect(content).not.toContain('Version 1');
51
+ expect(content).toContain('Version 2');
52
+ // Only one pair of markers
53
+ const openCount = content.split('<!-- domain:design -->').length - 1;
54
+ expect(openCount).toBe(1);
55
+ });
56
+
57
+ it('does nothing when content is empty', () => {
58
+ const filePath = join(tempDir, 'CLAUDE.md');
59
+ writeFileSync(filePath, 'Original');
60
+ injectDomainRules(filePath, 'design', '');
61
+ expect(readFileSync(filePath, 'utf-8')).toBe('Original');
62
+ });
63
+
64
+ it('does nothing when content is whitespace-only', () => {
65
+ const filePath = join(tempDir, 'CLAUDE.md');
66
+ writeFileSync(filePath, 'Original');
67
+ injectDomainRules(filePath, 'design', ' \n \n ');
68
+ expect(readFileSync(filePath, 'utf-8')).toBe('Original');
69
+ });
70
+
71
+ it('handles multiple pack injections independently', () => {
72
+ const filePath = join(tempDir, 'CLAUDE.md');
73
+ writeFileSync(filePath, '# Agent\n');
74
+ injectDomainRules(filePath, 'design', 'Design rules');
75
+ injectDomainRules(filePath, 'security', 'Security rules');
76
+ const content = readFileSync(filePath, 'utf-8');
77
+ expect(content).toContain('<!-- domain:design -->');
78
+ expect(content).toContain('<!-- domain:security -->');
79
+ expect(content).toContain('Design rules');
80
+ expect(content).toContain('Security rules');
81
+ });
82
+ });
83
+
84
+ describe('removeDomainRules', () => {
85
+ it('removes injected block', () => {
86
+ const filePath = join(tempDir, 'CLAUDE.md');
87
+ writeFileSync(filePath, '# Header\n');
88
+ injectDomainRules(filePath, 'design', 'Rules to remove');
89
+ removeDomainRules(filePath, 'design');
90
+ const content = readFileSync(filePath, 'utf-8');
91
+ expect(content).not.toContain('<!-- domain:design -->');
92
+ expect(content).not.toContain('Rules to remove');
93
+ });
94
+
95
+ it('does nothing if file does not exist', () => {
96
+ // Should not throw
97
+ removeDomainRules(join(tempDir, 'nonexistent.md'), 'design');
98
+ });
99
+
100
+ it('does nothing if markers are not found', () => {
101
+ const filePath = join(tempDir, 'CLAUDE.md');
102
+ writeFileSync(filePath, '# Header\nNo markers here.\n');
103
+ removeDomainRules(filePath, 'design');
104
+ expect(readFileSync(filePath, 'utf-8')).toBe('# Header\nNo markers here.\n');
105
+ });
106
+
107
+ it('only removes the targeted pack block', () => {
108
+ const filePath = join(tempDir, 'CLAUDE.md');
109
+ writeFileSync(filePath, '# Header\n');
110
+ injectDomainRules(filePath, 'design', 'Design rules');
111
+ injectDomainRules(filePath, 'security', 'Security rules');
112
+ removeDomainRules(filePath, 'design');
113
+ const content = readFileSync(filePath, 'utf-8');
114
+ expect(content).not.toContain('Design rules');
115
+ expect(content).toContain('Security rules');
116
+ });
117
+ });