@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,127 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { createVaultSharingOps } from './vault-sharing-ops.js';
3
+ import type { AgentRuntime } from './types.js';
4
+
5
+ // ---------------------------------------------------------------------------
6
+ // Mocks
7
+ // ---------------------------------------------------------------------------
8
+
9
+ vi.mock('../vault/scope-detector.js', () => ({
10
+ detectScope: vi.fn().mockReturnValue({
11
+ tier: 'project',
12
+ confidence: 'HIGH',
13
+ reason: 'project-specific pattern',
14
+ signals: [],
15
+ }),
16
+ }));
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Mock runtime
20
+ // ---------------------------------------------------------------------------
21
+
22
+ function mockRuntime(): AgentRuntime {
23
+ return {
24
+ config: { agentId: 'test-agent' },
25
+ vault: {
26
+ get: vi.fn(),
27
+ seed: vi.fn(),
28
+ getProvider: vi.fn().mockReturnValue({
29
+ all: vi.fn().mockReturnValue([]),
30
+ get: vi.fn(),
31
+ run: vi.fn(),
32
+ }),
33
+ },
34
+ } as unknown as AgentRuntime;
35
+ }
36
+
37
+ function findOp(ops: ReturnType<typeof createVaultSharingOps>, name: string) {
38
+ const op = ops.find((o) => o.name === name);
39
+ if (!op) throw new Error(`Op "${name}" not found`);
40
+ return op;
41
+ }
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // Tests — scope ops only (sync/review ops moved to separate files)
45
+ // ---------------------------------------------------------------------------
46
+
47
+ describe('createVaultSharingOps', () => {
48
+ let rt: AgentRuntime;
49
+ let ops: ReturnType<typeof createVaultSharingOps>;
50
+
51
+ beforeEach(() => {
52
+ vi.clearAllMocks();
53
+ rt = mockRuntime();
54
+ ops = createVaultSharingOps(rt);
55
+ });
56
+
57
+ it('returns 3 scope ops', () => {
58
+ expect(ops.length).toBe(3);
59
+ });
60
+
61
+ it('has the expected op names', () => {
62
+ const names = ops.map((o) => o.name);
63
+ expect(names).toEqual(['vault_detect_scope', 'vault_set_scope', 'vault_list_by_scope']);
64
+ });
65
+
66
+ // ─── vault_detect_scope ───────────────────────────────────────
67
+
68
+ describe('vault_detect_scope', () => {
69
+ it('returns scope detection result', async () => {
70
+ const op = findOp(ops, 'vault_detect_scope');
71
+ const result = (await op.handler({
72
+ title: 'Test pattern',
73
+ description: 'A project-specific pattern',
74
+ })) as Record<string, unknown>;
75
+ expect(result.tier).toBe('project');
76
+ expect(result.confidence).toBe('HIGH');
77
+ });
78
+ });
79
+
80
+ // ─── vault_set_scope ──────────────────────────────────────────
81
+
82
+ describe('vault_set_scope', () => {
83
+ it('returns error when entry not found', async () => {
84
+ const op = findOp(ops, 'vault_set_scope');
85
+ vi.mocked(rt.vault.get).mockReturnValue(undefined as never);
86
+ const result = (await op.handler({ id: 'missing', tier: 'team' })) as Record<string, unknown>;
87
+ expect(result.error).toContain('not found');
88
+ });
89
+
90
+ it('updates scope tier on existing entry', async () => {
91
+ const op = findOp(ops, 'vault_set_scope');
92
+ vi.mocked(rt.vault.get).mockReturnValue({
93
+ id: 'e1',
94
+ title: 'Entry',
95
+ tier: 'agent',
96
+ } as never);
97
+ const result = (await op.handler({ id: 'e1', tier: 'team' })) as Record<string, unknown>;
98
+ expect(result.updated).toBe(true);
99
+ expect(result.tier).toBe('team');
100
+ expect(rt.vault.seed).toHaveBeenCalled();
101
+ });
102
+ });
103
+
104
+ // ─── vault_list_by_scope ──────────────────────────────────────
105
+
106
+ describe('vault_list_by_scope', () => {
107
+ it('queries entries filtered by tier', async () => {
108
+ const op = findOp(ops, 'vault_list_by_scope');
109
+ const provider = rt.vault.getProvider();
110
+ vi.mocked(provider.all).mockReturnValue([
111
+ {
112
+ id: 'e1',
113
+ type: 'pattern',
114
+ domain: 'general',
115
+ title: 'Entry 1',
116
+ severity: 'suggestion',
117
+ description: 'desc',
118
+ tier: 'team',
119
+ tags: '["a"]',
120
+ },
121
+ ]);
122
+ const result = (await op.handler({ tier: 'team' })) as Record<string, unknown>;
123
+ expect(result.count).toBe(1);
124
+ expect(result.tier).toBe('team');
125
+ });
126
+ });
127
+ });
@@ -1,27 +1,20 @@
1
1
  /**
2
- * Vault Sharing Ops — knowledge scoping, export, sync, and review ops.
2
+ * Vault Sharing Ops — knowledge scoping operations.
3
3
  *
4
4
  * Covers:
5
5
  * - #105: Knowledge scoping (detect_scope, set_scope, scope-aware filtering)
6
- * - #104: Vault export to shareable packs
7
- * - #67: Vault push/pull git sync with conflict resolution
8
- * - #65: Team review workflows (submit/approve/reject)
6
+ *
7
+ * Git/Obsidian/pack sync ops sync-ops.ts (sync facade)
8
+ * Review workflow ops review-ops.ts (review facade)
9
9
  */
10
10
 
11
11
  import { z } from 'zod';
12
12
  import type { OpDefinition } from '../facades/types.js';
13
13
  import type { AgentRuntime } from './types.js';
14
14
  import { detectScope, type ScopeInput } from '../vault/scope-detector.js';
15
- import { GitVaultSync, type GitVaultSyncConfig } from '../vault/git-vault-sync.js';
16
- import type {
17
- IntelligenceEntry,
18
- IntelligenceBundle,
19
- IntelligenceBundleLink,
20
- } from '../intelligence/types.js';
21
- import { LinkManager } from '../vault/linking.js';
22
15
 
23
16
  export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
24
- const { vault, knowledgeReview } = runtime;
17
+ const { vault } = runtime;
25
18
 
26
19
  return [
27
20
  // ─── Scoping (#105) ───────────────────────────────────────────
@@ -110,322 +103,5 @@ export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
110
103
  return { entries, count: entries.length, tier };
111
104
  },
112
105
  },
113
-
114
- // ─── Export to Pack (#104) ─────────────────────────────────────
115
- {
116
- name: 'vault_export_pack',
117
- description:
118
- 'Export vault entries as a shareable intelligence pack. Filters by tier, domain, or tags. Returns IntelligenceBundle format.',
119
- auth: 'read' as const,
120
- schema: z.object({
121
- name: z.string().optional().describe('Pack name (default: agent ID)'),
122
- version: z.string().optional().describe('Pack version (default: 1.0.0)'),
123
- tier: z.enum(['agent', 'project', 'team']).optional().describe('Filter by scope tier'),
124
- domain: z.string().optional().describe('Filter by domain'),
125
- tags: z.array(z.string()).optional().describe('Filter by tags (OR match)'),
126
- excludeIds: z.array(z.string()).optional().describe('Entry IDs to exclude'),
127
- }),
128
- handler: async (params) => {
129
- const tier = params.tier as string | undefined;
130
- const domain = params.domain as string | undefined;
131
- const tags = params.tags as string[] | undefined;
132
- const excludeIds = new Set((params.excludeIds as string[] | undefined) ?? []);
133
-
134
- // Get all matching entries
135
- let entries = vault.list({ domain, tags, limit: 10000 });
136
-
137
- // Filter by tier if specified
138
- if (tier) {
139
- entries = entries.filter((e) => e.tier === tier);
140
- }
141
-
142
- // Exclude specified IDs
143
- if (excludeIds.size > 0) {
144
- entries = entries.filter((e) => !excludeIds.has(e.id));
145
- }
146
-
147
- // Group by domain into bundles
148
- const byDomain = new Map<string, IntelligenceEntry[]>();
149
- for (const entry of entries) {
150
- const d = entry.domain;
151
- if (!byDomain.has(d)) byDomain.set(d, []);
152
- byDomain.get(d)!.push(entry);
153
- }
154
-
155
- // Collect links for exported entries (Zettelkasten edge export)
156
- const entryIds = new Set(entries.map((e) => e.id));
157
- const linkManager = new LinkManager(vault.getProvider());
158
- const allLinks = linkManager.getAllLinksForEntries([...entryIds]);
159
- // Only include links where BOTH endpoints are in the export set
160
- const exportLinks = allLinks.filter(
161
- (l) => entryIds.has(l.sourceId) && entryIds.has(l.targetId),
162
- );
163
-
164
- // Build a domain→links map (group by source entry's domain)
165
- const entryDomainMap = new Map(entries.map((e) => [e.id, e.domain]));
166
- const linksByDomain = new Map<string, IntelligenceBundleLink[]>();
167
- for (const link of exportLinks) {
168
- const linkDomain = entryDomainMap.get(link.sourceId) ?? 'unknown';
169
- if (!linksByDomain.has(linkDomain)) linksByDomain.set(linkDomain, []);
170
- linksByDomain.get(linkDomain)!.push({
171
- sourceId: link.sourceId,
172
- targetId: link.targetId,
173
- linkType: link.linkType,
174
- note: link.note,
175
- });
176
- }
177
-
178
- const version = (params.version as string) ?? '1.0.0';
179
- const bundles: IntelligenceBundle[] = [];
180
- for (const [d, domainEntries] of byDomain) {
181
- bundles.push({
182
- domain: d,
183
- version,
184
- entries: domainEntries,
185
- links: linksByDomain.get(d) ?? [],
186
- });
187
- }
188
-
189
- return {
190
- name: (params.name as string) ?? runtime.config.agentId,
191
- version,
192
- bundles,
193
- totalEntries: entries.length,
194
- totalLinks: exportLinks.length,
195
- domains: [...byDomain.keys()],
196
- };
197
- },
198
- },
199
- {
200
- name: 'vault_import_pack',
201
- description:
202
- 'Import an intelligence pack into the vault with content-hash dedup. Entries with duplicate content are skipped.',
203
- auth: 'write' as const,
204
- schema: z.object({
205
- bundles: z
206
- .array(
207
- z.object({
208
- domain: z.string(),
209
- version: z.string(),
210
- entries: z.array(z.record(z.unknown())),
211
- }),
212
- )
213
- .describe('Array of IntelligenceBundle objects to import'),
214
- tier: z
215
- .enum(['agent', 'project', 'team'])
216
- .optional()
217
- .describe('Force all imported entries to this tier'),
218
- }),
219
- handler: async (params) => {
220
- const bundles = params.bundles as Array<{
221
- domain: string;
222
- version: string;
223
- entries: IntelligenceEntry[];
224
- links?: IntelligenceBundleLink[];
225
- }>;
226
- const forceTier = params.tier as 'agent' | 'project' | 'team' | undefined;
227
- let imported = 0;
228
- let duplicates = 0;
229
- let linksCreated = 0;
230
- let linksSkipped = 0;
231
-
232
- // Track ID remapping: bundle entry ID → actual vault entry ID
233
- const idRemap = new Map<string, string>();
234
- const linkManager = new LinkManager(vault.getProvider());
235
-
236
- for (const bundle of bundles) {
237
- const entries = bundle.entries.map((e) => ({
238
- ...e,
239
- tier: forceTier ?? e.tier ?? 'project',
240
- }));
241
- const results = vault.seedDedup(entries);
242
- for (let i = 0; i < results.length; i++) {
243
- const r = results[i];
244
- const originalId = bundle.entries[i].id;
245
- // For duplicates, map to the existing vault entry; for inserts, keep original ID
246
- idRemap.set(originalId, r.existingId ?? r.id);
247
- if (r.action === 'inserted') imported++;
248
- else duplicates++;
249
- }
250
-
251
- // Import links if present
252
- if (bundle.links && bundle.links.length > 0) {
253
- for (const link of bundle.links) {
254
- const sourceId = idRemap.get(link.sourceId);
255
- const targetId = idRemap.get(link.targetId);
256
- if (sourceId && targetId) {
257
- linkManager.addLink(sourceId, targetId, link.linkType, link.note);
258
- linksCreated++;
259
- } else {
260
- linksSkipped++;
261
- }
262
- }
263
- }
264
- }
265
-
266
- return { imported, duplicates, linksCreated, linksSkipped, total: imported + duplicates };
267
- },
268
- },
269
-
270
- // ─── Git Sync (#67) ───────────────────────────────────────────
271
- {
272
- name: 'vault_git_push',
273
- description:
274
- 'Push all vault entries to a git-tracked directory. Each entry becomes a JSON file under domain subdirectories.',
275
- auth: 'write' as const,
276
- schema: z.object({
277
- repoDir: z.string().describe('Path to git-tracked vault directory'),
278
- authorName: z.string().optional().describe('Git author name'),
279
- authorEmail: z.string().optional().describe('Git author email'),
280
- }),
281
- handler: async (params) => {
282
- const config: GitVaultSyncConfig = {
283
- repoDir: params.repoDir as string,
284
- authorName: params.authorName as string | undefined,
285
- authorEmail: params.authorEmail as string | undefined,
286
- };
287
- const sync = new GitVaultSync(config);
288
- await sync.init();
289
- const { entries } = vault.exportAll();
290
- return sync.syncAll(entries);
291
- },
292
- },
293
- {
294
- name: 'vault_git_pull',
295
- description:
296
- 'Pull entries from a git-tracked directory into the vault. Reads JSON files and imports with conflict resolution.',
297
- auth: 'write' as const,
298
- schema: z.object({
299
- repoDir: z.string().describe('Path to git-tracked vault directory'),
300
- onConflict: z
301
- .enum(['git', 'vault'])
302
- .optional()
303
- .describe(
304
- 'Conflict resolution: "git" (default) overwrites vault, "vault" keeps existing',
305
- ),
306
- }),
307
- handler: async (params) => {
308
- const config: GitVaultSyncConfig = {
309
- repoDir: params.repoDir as string,
310
- autoCommit: false,
311
- };
312
- const sync = new GitVaultSync(config);
313
- await sync.init();
314
- return sync.pull(vault, {
315
- onConflict: params.onConflict as 'git' | 'vault' | undefined,
316
- });
317
- },
318
- },
319
- {
320
- name: 'vault_git_sync',
321
- description:
322
- 'Bidirectional sync between vault and git directory. Pushes vault entries to git and pulls git-only entries into vault.',
323
- auth: 'write' as const,
324
- schema: z.object({
325
- repoDir: z.string().describe('Path to git-tracked vault directory'),
326
- onConflict: z
327
- .enum(['git', 'vault'])
328
- .optional()
329
- .describe('Conflict resolution for entries that exist in both'),
330
- authorName: z.string().optional(),
331
- authorEmail: z.string().optional(),
332
- }),
333
- handler: async (params) => {
334
- const config: GitVaultSyncConfig = {
335
- repoDir: params.repoDir as string,
336
- authorName: params.authorName as string | undefined,
337
- authorEmail: params.authorEmail as string | undefined,
338
- };
339
- const sync = new GitVaultSync(config);
340
- await sync.init();
341
- return sync.sync(vault, {
342
- onConflict: params.onConflict as 'git' | 'vault' | undefined,
343
- });
344
- },
345
- },
346
-
347
- // ─── Review Workflows (#65) ───────────────────────────────────
348
- {
349
- name: 'vault_submit_review',
350
- description:
351
- 'Submit a vault entry for team review. Transitions entry from draft → pending_review.',
352
- auth: 'write' as const,
353
- schema: z.object({
354
- entryId: z.string().describe('Entry ID to submit for review'),
355
- submittedBy: z.string().optional().describe('Name/ID of the submitter'),
356
- }),
357
- handler: async (params) => {
358
- try {
359
- return knowledgeReview.submit({
360
- entryId: params.entryId as string,
361
- submittedBy: params.submittedBy as string | undefined,
362
- });
363
- } catch (err) {
364
- return { error: (err as Error).message };
365
- }
366
- },
367
- },
368
- {
369
- name: 'vault_approve',
370
- description: 'Approve a pending vault entry. Transitions from pending_review → approved.',
371
- auth: 'admin' as const,
372
- schema: z.object({
373
- entryId: z.string().describe('Entry ID to approve'),
374
- reviewedBy: z.string().optional().describe('Name/ID of the reviewer'),
375
- comment: z.string().optional().describe('Review comment'),
376
- }),
377
- handler: async (params) => {
378
- try {
379
- return knowledgeReview.approve({
380
- entryId: params.entryId as string,
381
- reviewedBy: params.reviewedBy as string | undefined,
382
- comment: params.comment as string | undefined,
383
- });
384
- } catch (err) {
385
- return { error: (err as Error).message };
386
- }
387
- },
388
- },
389
- {
390
- name: 'vault_reject',
391
- description: 'Reject a pending vault entry. Transitions from pending_review → rejected.',
392
- auth: 'admin' as const,
393
- schema: z.object({
394
- entryId: z.string().describe('Entry ID to reject'),
395
- reviewedBy: z.string().optional().describe('Name/ID of the reviewer'),
396
- comment: z.string().optional().describe('Reason for rejection'),
397
- }),
398
- handler: async (params) => {
399
- try {
400
- return knowledgeReview.reject({
401
- entryId: params.entryId as string,
402
- reviewedBy: params.reviewedBy as string | undefined,
403
- comment: params.comment as string | undefined,
404
- });
405
- } catch (err) {
406
- return { error: (err as Error).message };
407
- }
408
- },
409
- },
410
- {
411
- name: 'vault_pending_reviews',
412
- description: 'List all vault entries pending team review.',
413
- auth: 'read' as const,
414
- schema: z.object({
415
- limit: z.number().optional().describe('Max entries to return'),
416
- }),
417
- handler: async (params) => {
418
- const pending = knowledgeReview.listPending((params.limit as number) ?? 50);
419
- return { pending, count: pending.length };
420
- },
421
- },
422
- {
423
- name: 'vault_review_stats',
424
- description: 'Get review workflow statistics — counts by status.',
425
- auth: 'read' as const,
426
- handler: async () => {
427
- return knowledgeReview.stats();
428
- },
429
- },
430
106
  ];
431
107
  }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Skill sync — discovers SKILL.md files in agent skills directories
3
+ * and copies them to ~/.claude/commands/ for Claude Code discovery.
4
+ *
5
+ * Injects agent branding so users know which agent owns the skill.
6
+ * Called automatically at engine startup and by admin_setup_global.
7
+ */
8
+
9
+ import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync, statSync } from 'node:fs';
10
+ import { join } from 'node:path';
11
+ import { homedir } from 'node:os';
12
+
13
+ export interface SkillEntry {
14
+ name: string;
15
+ sourcePath: string;
16
+ }
17
+
18
+ export interface SyncResult {
19
+ installed: string[];
20
+ updated: string[];
21
+ skipped: string[];
22
+ failed: string[];
23
+ }
24
+
25
+ /** Discover skill files (SKILL.md) in skills directories */
26
+ export function discoverSkills(skillsDirs: string[]): SkillEntry[] {
27
+ const skills: SkillEntry[] = [];
28
+
29
+ for (const dir of skillsDirs) {
30
+ if (!existsSync(dir)) continue;
31
+ const entries = readdirSync(dir, { withFileTypes: true });
32
+ for (const entry of entries) {
33
+ if (!entry.isDirectory()) continue;
34
+ const skillPath = join(dir, entry.name, 'SKILL.md');
35
+ if (existsSync(skillPath)) {
36
+ skills.push({ name: entry.name, sourcePath: skillPath });
37
+ }
38
+ }
39
+ }
40
+
41
+ return skills;
42
+ }
43
+
44
+ /** Inject agent branding after YAML frontmatter */
45
+ function brandSkillContent(content: string, agentName: string): string {
46
+ // Find end of frontmatter (second ---)
47
+ const fmEnd = content.indexOf('---', content.indexOf('---') + 3);
48
+ if (fmEnd === -1) return content;
49
+
50
+ const afterFm = fmEnd + 3;
51
+ const before = content.slice(0, afterFm);
52
+ const after = content.slice(afterFm);
53
+
54
+ const brandLine = `\n\n> **${agentName}** skill\n`;
55
+ return before + brandLine + after;
56
+ }
57
+
58
+ /**
59
+ * Sync skills from agent directory to ~/.claude/commands/.
60
+ * - New skills are installed with agent branding
61
+ * - Changed skills are overwritten (compared by mtime)
62
+ * - Missing source skills leave target untouched (other agents may own them)
63
+ */
64
+ export function syncSkillsToClaudeCode(skillsDirs: string[], agentName?: string): SyncResult {
65
+ const commandsDir = join(homedir(), '.claude', 'commands');
66
+ const skills = discoverSkills(skillsDirs);
67
+ const result: SyncResult = { installed: [], updated: [], skipped: [], failed: [] };
68
+
69
+ if (skills.length === 0) return result;
70
+
71
+ mkdirSync(commandsDir, { recursive: true });
72
+
73
+ for (const skill of skills) {
74
+ const targetPath = join(commandsDir, `${skill.name}.md`);
75
+ try {
76
+ const sourceContent = readFileSync(skill.sourcePath, 'utf-8');
77
+ const branded = agentName ? brandSkillContent(sourceContent, agentName) : sourceContent;
78
+
79
+ if (!existsSync(targetPath)) {
80
+ writeFileSync(targetPath, branded);
81
+ result.installed.push(skill.name);
82
+ } else {
83
+ const sourceMtime = statSync(skill.sourcePath).mtimeMs;
84
+ const targetMtime = statSync(targetPath).mtimeMs;
85
+ if (sourceMtime > targetMtime) {
86
+ writeFileSync(targetPath, branded);
87
+ result.updated.push(skill.name);
88
+ } else {
89
+ result.skipped.push(skill.name);
90
+ }
91
+ }
92
+ } catch {
93
+ result.failed.push(skill.name);
94
+ }
95
+ }
96
+
97
+ return result;
98
+ }
@@ -0,0 +1,95 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { normalize, collect } from './normalize.js';
3
+
4
+ // ─── normalize ───────────────────────────────────────────────────────
5
+
6
+ describe('normalize', () => {
7
+ it('yields a single value', async () => {
8
+ const result = await collect(normalize(42));
9
+ expect(result).toEqual([42]);
10
+ });
11
+
12
+ it('yields a flat array', async () => {
13
+ const result = await collect(normalize([1, 2, 3]));
14
+ expect(result).toEqual([1, 2, 3]);
15
+ });
16
+
17
+ it('resolves a promise of a single value', async () => {
18
+ const result = await collect(normalize(Promise.resolve('hello')));
19
+ expect(result).toEqual(['hello']);
20
+ });
21
+
22
+ it('resolves a promise of an array', async () => {
23
+ const result = await collect(normalize(Promise.resolve([10, 20])));
24
+ expect(result).toEqual([10, 20]);
25
+ });
26
+
27
+ it('flattens an async iterable', async () => {
28
+ async function* gen(): AsyncIterable<number> {
29
+ yield 1;
30
+ yield 2;
31
+ yield 3;
32
+ }
33
+ const result = await collect(normalize(gen()));
34
+ expect(result).toEqual([1, 2, 3]);
35
+ });
36
+
37
+ it('flattens nested sync iterables', async () => {
38
+ const nested = [[1, 2], [3], [4, 5]];
39
+ const result = await collect(normalize(nested));
40
+ expect(result).toEqual([1, 2, 3, 4, 5]);
41
+ });
42
+
43
+ it('treats strings as leaf values (not iterables)', async () => {
44
+ const result = await collect(normalize('hello'));
45
+ expect(result).toEqual(['hello']);
46
+ });
47
+
48
+ it('treats an array of strings as individual leaves', async () => {
49
+ const result = await collect(normalize(['a', 'b', 'c']));
50
+ expect(result).toEqual(['a', 'b', 'c']);
51
+ });
52
+
53
+ it('handles mixed nested structure', async () => {
54
+ async function* gen(): AsyncIterable<number> {
55
+ yield 100;
56
+ }
57
+ const mixed = [1, [2, 3], Promise.resolve(4), gen()];
58
+ // normalize expects NestableInput<number>, but mixed iterables work
59
+ const result: number[] = [];
60
+ for await (const item of normalize<number>(mixed as never)) {
61
+ result.push(item);
62
+ }
63
+ expect(result).toEqual([1, 2, 3, 4, 100]);
64
+ });
65
+
66
+ it('handles empty array', async () => {
67
+ const result = await collect(normalize([]));
68
+ expect(result).toEqual([]);
69
+ });
70
+
71
+ it('handles deeply nested arrays', async () => {
72
+ const deep = [[[1]], [[2, 3]]];
73
+ const result = await collect(normalize(deep));
74
+ expect(result).toEqual([1, 2, 3]);
75
+ });
76
+ });
77
+
78
+ // ─── collect ─────────────────────────────────────────────────────────
79
+
80
+ describe('collect', () => {
81
+ it('collects async iterable into array', async () => {
82
+ async function* gen(): AsyncIterable<string> {
83
+ yield 'a';
84
+ yield 'b';
85
+ }
86
+ expect(await collect(gen())).toEqual(['a', 'b']);
87
+ });
88
+
89
+ it('returns empty array for empty source', async () => {
90
+ async function* empty(): AsyncIterable<never> {
91
+ // nothing
92
+ }
93
+ expect(await collect(empty())).toEqual([]);
94
+ });
95
+ });