@cleocode/core 2026.9.8 → 2026.9.10

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 (569) hide show
  1. package/dist/audit/reconstruct.d.ts +13 -43
  2. package/dist/audit/reconstruct.d.ts.map +1 -1
  3. package/dist/audit/reconstruct.js +295 -290
  4. package/dist/audit/reconstruct.js.map +1 -1
  5. package/dist/bootstrap.d.ts.map +1 -1
  6. package/dist/bootstrap.js +8 -2
  7. package/dist/bootstrap.js.map +1 -1
  8. package/dist/compliance/protocol-rules.d.ts.map +1 -1
  9. package/dist/compliance/protocol-rules.js +3 -1
  10. package/dist/compliance/protocol-rules.js.map +1 -1
  11. package/dist/dispatch/mutate-projection.d.ts.map +1 -1
  12. package/dist/dispatch/mutate-projection.js +12 -0
  13. package/dist/dispatch/mutate-projection.js.map +1 -1
  14. package/dist/dispatch/mvi-projection.d.ts +29 -6
  15. package/dist/dispatch/mvi-projection.d.ts.map +1 -1
  16. package/dist/dispatch/mvi-projection.js +109 -139
  17. package/dist/dispatch/mvi-projection.js.map +1 -1
  18. package/dist/docs/docs-read-model.d.ts +3 -2
  19. package/dist/docs/docs-read-model.d.ts.map +1 -1
  20. package/dist/docs/docs-read-model.js +4 -3
  21. package/dist/docs/docs-read-model.js.map +1 -1
  22. package/dist/docs/export-document.js +5129 -2297
  23. package/dist/docs/export-document.js.map +3 -3
  24. package/dist/docs/projection.d.ts +67 -0
  25. package/dist/docs/projection.d.ts.map +1 -0
  26. package/dist/docs/projection.js +370 -0
  27. package/dist/docs/projection.js.map +1 -0
  28. package/dist/doctor/acceptance-drift.d.ts +6 -2
  29. package/dist/doctor/acceptance-drift.d.ts.map +1 -1
  30. package/dist/doctor/acceptance-drift.js +43 -5
  31. package/dist/doctor/acceptance-drift.js.map +1 -1
  32. package/dist/doctor/knowledge-summary.d.ts +41 -0
  33. package/dist/doctor/knowledge-summary.d.ts.map +1 -0
  34. package/dist/doctor/knowledge-summary.js +81 -0
  35. package/dist/doctor/knowledge-summary.js.map +1 -0
  36. package/dist/doctor/knowledge.d.ts +192 -0
  37. package/dist/doctor/knowledge.d.ts.map +1 -0
  38. package/dist/doctor/knowledge.js +1864 -0
  39. package/dist/doctor/knowledge.js.map +1 -0
  40. package/dist/git/work-tree.d.ts +169 -0
  41. package/dist/git/work-tree.d.ts.map +1 -0
  42. package/dist/git/work-tree.js +341 -0
  43. package/dist/git/work-tree.js.map +1 -0
  44. package/dist/hooks/handlers/task-hooks.d.ts +8 -5
  45. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  46. package/dist/hooks/handlers/task-hooks.js +15 -60
  47. package/dist/hooks/handlers/task-hooks.js.map +1 -1
  48. package/dist/identity/cleo-identity.d.ts +13 -0
  49. package/dist/identity/cleo-identity.d.ts.map +1 -1
  50. package/dist/identity/cleo-identity.js +20 -6
  51. package/dist/identity/cleo-identity.js.map +1 -1
  52. package/dist/injection.d.ts.map +1 -1
  53. package/dist/injection.js +29 -13
  54. package/dist/injection.js.map +1 -1
  55. package/dist/internal.d.ts +3 -0
  56. package/dist/internal.d.ts.map +1 -1
  57. package/dist/internal.js +4 -0
  58. package/dist/internal.js.map +1 -1
  59. package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
  60. package/dist/lifecycle/verification/satisfies-validator.js +124 -120
  61. package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
  62. package/dist/llm/plugin-facade.js +4047 -1726
  63. package/dist/llm/plugin-facade.js.map +3 -3
  64. package/dist/memory/brain-backfill.d.ts +27 -12
  65. package/dist/memory/brain-backfill.d.ts.map +1 -1
  66. package/dist/memory/brain-backfill.js +325 -134
  67. package/dist/memory/brain-backfill.js.map +1 -1
  68. package/dist/memory/brain-doctor.d.ts +21 -0
  69. package/dist/memory/brain-doctor.d.ts.map +1 -1
  70. package/dist/memory/brain-doctor.js +111 -53
  71. package/dist/memory/brain-doctor.js.map +1 -1
  72. package/dist/memory/brain-links.d.ts.map +1 -1
  73. package/dist/memory/brain-links.js +31 -4
  74. package/dist/memory/brain-links.js.map +1 -1
  75. package/dist/memory/brain-reasoning.d.ts.map +1 -1
  76. package/dist/memory/brain-reasoning.js +28 -2
  77. package/dist/memory/brain-reasoning.js.map +1 -1
  78. package/dist/memory/brain-reconciler.d.ts +14 -19
  79. package/dist/memory/brain-reconciler.d.ts.map +1 -1
  80. package/dist/memory/brain-reconciler.js +70 -97
  81. package/dist/memory/brain-reconciler.js.map +1 -1
  82. package/dist/memory/brain-search.d.ts +2 -0
  83. package/dist/memory/brain-search.d.ts.map +1 -1
  84. package/dist/memory/brain-search.js +59 -29
  85. package/dist/memory/brain-search.js.map +1 -1
  86. package/dist/memory/brain-similarity.d.ts.map +1 -1
  87. package/dist/memory/brain-similarity.js +5 -4
  88. package/dist/memory/brain-similarity.js.map +1 -1
  89. package/dist/memory/brain-stub-prune.d.ts +31 -9
  90. package/dist/memory/brain-stub-prune.d.ts.map +1 -1
  91. package/dist/memory/brain-stub-prune.js +65 -18
  92. package/dist/memory/brain-stub-prune.js.map +1 -1
  93. package/dist/memory/brain-writer-handlers.d.ts +10 -1
  94. package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
  95. package/dist/memory/brain-writer-handlers.js +23 -3
  96. package/dist/memory/brain-writer-handlers.js.map +1 -1
  97. package/dist/memory/brain-writer-thread.d.ts +11 -1
  98. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  99. package/dist/memory/brain-writer-thread.js +87 -20
  100. package/dist/memory/brain-writer-thread.js.map +1 -1
  101. package/dist/memory/brain-writer-worker.js +8 -1
  102. package/dist/memory/brain-writer-worker.js.map +1 -1
  103. package/dist/memory/decision-cross-link.d.ts +39 -0
  104. package/dist/memory/decision-cross-link.d.ts.map +1 -1
  105. package/dist/memory/decision-cross-link.js +316 -0
  106. package/dist/memory/decision-cross-link.js.map +1 -1
  107. package/dist/memory/decisions.d.ts +4 -1
  108. package/dist/memory/decisions.d.ts.map +1 -1
  109. package/dist/memory/decisions.js +7 -24
  110. package/dist/memory/decisions.js.map +1 -1
  111. package/dist/memory/dispatch-trace.d.ts +12 -5
  112. package/dist/memory/dispatch-trace.d.ts.map +1 -1
  113. package/dist/memory/dispatch-trace.js +17 -7
  114. package/dist/memory/dispatch-trace.js.map +1 -1
  115. package/dist/memory/eligibility.d.ts +51 -0
  116. package/dist/memory/eligibility.d.ts.map +1 -0
  117. package/dist/memory/eligibility.js +77 -0
  118. package/dist/memory/eligibility.js.map +1 -0
  119. package/dist/memory/engine-compat.d.ts +2 -0
  120. package/dist/memory/engine-compat.d.ts.map +1 -1
  121. package/dist/memory/engine-compat.js +10 -0
  122. package/dist/memory/engine-compat.js.map +1 -1
  123. package/dist/memory/extraction-gate.d.ts +21 -7
  124. package/dist/memory/extraction-gate.d.ts.map +1 -1
  125. package/dist/memory/extraction-gate.js +178 -216
  126. package/dist/memory/extraction-gate.js.map +1 -1
  127. package/dist/memory/graph-auto-populate.d.ts +38 -5
  128. package/dist/memory/graph-auto-populate.d.ts.map +1 -1
  129. package/dist/memory/graph-auto-populate.js +182 -60
  130. package/dist/memory/graph-auto-populate.js.map +1 -1
  131. package/dist/memory/graph-memory-bridge.d.ts +14 -1
  132. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  133. package/dist/memory/graph-memory-bridge.js +66 -28
  134. package/dist/memory/graph-memory-bridge.js.map +1 -1
  135. package/dist/memory/index.d.ts +1 -19
  136. package/dist/memory/index.d.ts.map +1 -1
  137. package/dist/memory/index.js +1 -50
  138. package/dist/memory/index.js.map +1 -1
  139. package/dist/memory/learnings.d.ts.map +1 -1
  140. package/dist/memory/learnings.js +2 -23
  141. package/dist/memory/learnings.js.map +1 -1
  142. package/dist/memory/manifest-filter.d.ts +21 -0
  143. package/dist/memory/manifest-filter.d.ts.map +1 -0
  144. package/dist/memory/manifest-filter.js +51 -0
  145. package/dist/memory/manifest-filter.js.map +1 -0
  146. package/dist/memory/manifest-ingestion.d.ts +28 -30
  147. package/dist/memory/manifest-ingestion.d.ts.map +1 -1
  148. package/dist/memory/manifest-ingestion.js +104 -235
  149. package/dist/memory/manifest-ingestion.js.map +1 -1
  150. package/dist/memory/observer-reflector.d.ts +2 -0
  151. package/dist/memory/observer-reflector.d.ts.map +1 -1
  152. package/dist/memory/observer-reflector.js +6 -49
  153. package/dist/memory/observer-reflector.js.map +1 -1
  154. package/dist/memory/patterns.d.ts +10 -0
  155. package/dist/memory/patterns.d.ts.map +1 -1
  156. package/dist/memory/patterns.js +25 -33
  157. package/dist/memory/patterns.js.map +1 -1
  158. package/dist/memory/pipeline-manifest-sqlite.d.ts +72 -9
  159. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  160. package/dist/memory/pipeline-manifest-sqlite.js +508 -412
  161. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  162. package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
  163. package/dist/memory/retrieval/build-retrieval-bundle.js +16 -15
  164. package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
  165. package/dist/memory/retrieval/fetch.d.ts +7 -0
  166. package/dist/memory/retrieval/fetch.d.ts.map +1 -1
  167. package/dist/memory/retrieval/fetch.js +14 -11
  168. package/dist/memory/retrieval/fetch.js.map +1 -1
  169. package/dist/memory/retrieval/observe.d.ts +7 -1
  170. package/dist/memory/retrieval/observe.d.ts.map +1 -1
  171. package/dist/memory/retrieval/observe.js +58 -4
  172. package/dist/memory/retrieval/observe.js.map +1 -1
  173. package/dist/memory/retrieval/search.d.ts +14 -1
  174. package/dist/memory/retrieval/search.d.ts.map +1 -1
  175. package/dist/memory/retrieval/search.js +133 -69
  176. package/dist/memory/retrieval/search.js.map +1 -1
  177. package/dist/memory/retrieval/telemetry.d.ts +31 -0
  178. package/dist/memory/retrieval/telemetry.d.ts.map +1 -0
  179. package/dist/memory/retrieval/telemetry.js +53 -0
  180. package/dist/memory/retrieval/telemetry.js.map +1 -0
  181. package/dist/nexus/analyze-orchestrator.d.ts +41 -9
  182. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  183. package/dist/nexus/analyze-orchestrator.js +257 -58
  184. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  185. package/dist/nexus/api-contracts.d.ts +2 -6
  186. package/dist/nexus/api-contracts.d.ts.map +1 -1
  187. package/dist/nexus/api-contracts.js +11 -2
  188. package/dist/nexus/api-contracts.js.map +1 -1
  189. package/dist/nexus/context.d.ts.map +1 -1
  190. package/dist/nexus/context.js +14 -37
  191. package/dist/nexus/context.js.map +1 -1
  192. package/dist/nexus/diff.d.ts.map +1 -1
  193. package/dist/nexus/diff.js +2 -1
  194. package/dist/nexus/diff.js.map +1 -1
  195. package/dist/nexus/identity.d.ts +29 -3
  196. package/dist/nexus/identity.d.ts.map +1 -1
  197. package/dist/nexus/identity.js +63 -12
  198. package/dist/nexus/identity.js.map +1 -1
  199. package/dist/nexus/impact.d.ts +21 -19
  200. package/dist/nexus/impact.d.ts.map +1 -1
  201. package/dist/nexus/impact.js +96 -192
  202. package/dist/nexus/impact.js.map +1 -1
  203. package/dist/nexus/knowledge.d.ts +80 -0
  204. package/dist/nexus/knowledge.d.ts.map +1 -0
  205. package/dist/nexus/knowledge.js +786 -0
  206. package/dist/nexus/knowledge.js.map +1 -0
  207. package/dist/nexus/living-brain.d.ts +8 -5
  208. package/dist/nexus/living-brain.d.ts.map +1 -1
  209. package/dist/nexus/living-brain.js +252 -188
  210. package/dist/nexus/living-brain.js.map +1 -1
  211. package/dist/nexus/registry.d.ts +11 -2
  212. package/dist/nexus/registry.d.ts.map +1 -1
  213. package/dist/nexus/registry.js +144 -128
  214. package/dist/nexus/registry.js.map +1 -1
  215. package/dist/nexus/source-roots.d.ts +16 -0
  216. package/dist/nexus/source-roots.d.ts.map +1 -0
  217. package/dist/nexus/source-roots.js +174 -0
  218. package/dist/nexus/source-roots.js.map +1 -0
  219. package/dist/nexus/task-evidence.d.ts +22 -0
  220. package/dist/nexus/task-evidence.d.ts.map +1 -0
  221. package/dist/nexus/task-evidence.js +210 -0
  222. package/dist/nexus/task-evidence.js.map +1 -0
  223. package/dist/nexus/tasks-bridge.d.ts +14 -7
  224. package/dist/nexus/tasks-bridge.d.ts.map +1 -1
  225. package/dist/nexus/tasks-bridge.js +81 -40
  226. package/dist/nexus/tasks-bridge.js.map +1 -1
  227. package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
  228. package/dist/orchestrate/lifecycle-ops.js +170 -120
  229. package/dist/orchestrate/lifecycle-ops.js.map +1 -1
  230. package/dist/orchestrate/query-ops.d.ts +6 -7
  231. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  232. package/dist/orchestrate/query-ops.js +509 -532
  233. package/dist/orchestrate/query-ops.js.map +1 -1
  234. package/dist/orchestration/bootstrap.d.ts +15 -1
  235. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  236. package/dist/orchestration/bootstrap.js +21 -10
  237. package/dist/orchestration/bootstrap.js.map +1 -1
  238. package/dist/orchestration/index.d.ts +35 -3
  239. package/dist/orchestration/index.d.ts.map +1 -1
  240. package/dist/orchestration/index.js +64 -35
  241. package/dist/orchestration/index.js.map +1 -1
  242. package/dist/orchestration/lead-rollup.d.ts +24 -1
  243. package/dist/orchestration/lead-rollup.d.ts.map +1 -1
  244. package/dist/orchestration/lead-rollup.js +31 -11
  245. package/dist/orchestration/lead-rollup.js.map +1 -1
  246. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  247. package/dist/orchestration/spawn-prompt.js +25 -45
  248. package/dist/orchestration/spawn-prompt.js.map +1 -1
  249. package/dist/orchestration/unblock.d.ts +15 -1
  250. package/dist/orchestration/unblock.d.ts.map +1 -1
  251. package/dist/orchestration/unblock.js +23 -12
  252. package/dist/orchestration/unblock.js.map +1 -1
  253. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  254. package/dist/orchestration/validate-spawn.js +3 -3
  255. package/dist/orchestration/validate-spawn.js.map +1 -1
  256. package/dist/orchestration/waves.d.ts +29 -13
  257. package/dist/orchestration/waves.d.ts.map +1 -1
  258. package/dist/orchestration/waves.js +43 -55
  259. package/dist/orchestration/waves.js.map +1 -1
  260. package/dist/paths.d.ts +17 -163
  261. package/dist/paths.d.ts.map +1 -1
  262. package/dist/paths.js +145 -496
  263. package/dist/paths.js.map +1 -1
  264. package/dist/project-info.d.ts +2 -11
  265. package/dist/project-info.d.ts.map +1 -1
  266. package/dist/project-info.js +3 -31
  267. package/dist/project-info.js.map +1 -1
  268. package/dist/project-scope.d.ts +239 -0
  269. package/dist/project-scope.d.ts.map +1 -0
  270. package/dist/project-scope.js +473 -0
  271. package/dist/project-scope.js.map +1 -0
  272. package/dist/release/pr-evidence.d.ts +23 -4
  273. package/dist/release/pr-evidence.d.ts.map +1 -1
  274. package/dist/release/pr-evidence.js +65 -9
  275. package/dist/release/pr-evidence.js.map +1 -1
  276. package/dist/render/nexus/graph/index.d.ts.map +1 -1
  277. package/dist/render/nexus/graph/index.js +4 -2
  278. package/dist/render/nexus/graph/index.js.map +1 -1
  279. package/dist/render/orchestration/audit-reconstruct.d.ts +11 -0
  280. package/dist/render/orchestration/audit-reconstruct.d.ts.map +1 -1
  281. package/dist/render/orchestration/audit-reconstruct.js +21 -6
  282. package/dist/render/orchestration/audit-reconstruct.js.map +1 -1
  283. package/dist/render/tasks/show.js +2 -1
  284. package/dist/render/tasks/show.js.map +1 -1
  285. package/dist/resources/spawn-wrapper.d.ts +82 -14
  286. package/dist/resources/spawn-wrapper.d.ts.map +1 -1
  287. package/dist/resources/spawn-wrapper.js +585 -27
  288. package/dist/resources/spawn-wrapper.js.map +1 -1
  289. package/dist/selfimprove/fix-gen.js +4055 -1734
  290. package/dist/selfimprove/fix-gen.js.map +3 -3
  291. package/dist/sequence/index.d.ts.map +1 -1
  292. package/dist/sequence/index.js +76 -68
  293. package/dist/sequence/index.js.map +1 -1
  294. package/dist/session/canon-lint.d.ts +24 -3
  295. package/dist/session/canon-lint.d.ts.map +1 -1
  296. package/dist/session/canon-lint.js +72 -31
  297. package/dist/session/canon-lint.js.map +1 -1
  298. package/dist/session/engine-ops.d.ts +1 -4
  299. package/dist/session/engine-ops.d.ts.map +1 -1
  300. package/dist/session/engine-ops.js +42 -6
  301. package/dist/session/engine-ops.js.map +1 -1
  302. package/dist/sessions/briefing.d.ts +11 -1
  303. package/dist/sessions/briefing.d.ts.map +1 -1
  304. package/dist/sessions/briefing.js +76 -8
  305. package/dist/sessions/briefing.js.map +1 -1
  306. package/dist/sessions/handoff.d.ts +3 -1
  307. package/dist/sessions/handoff.d.ts.map +1 -1
  308. package/dist/sessions/handoff.js +2 -0
  309. package/dist/sessions/handoff.js.map +1 -1
  310. package/dist/shutdown-deadline.d.ts +24 -33
  311. package/dist/shutdown-deadline.d.ts.map +1 -1
  312. package/dist/shutdown-deadline.js +71 -14
  313. package/dist/shutdown-deadline.js.map +1 -1
  314. package/dist/shutdown.d.ts +21 -10
  315. package/dist/shutdown.d.ts.map +1 -1
  316. package/dist/shutdown.js +89 -42
  317. package/dist/shutdown.js.map +1 -1
  318. package/dist/skills/index.d.ts +1 -1
  319. package/dist/skills/index.d.ts.map +1 -1
  320. package/dist/skills/index.js +1 -1
  321. package/dist/skills/index.js.map +1 -1
  322. package/dist/skills/orchestrator/validator.d.ts +87 -20
  323. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  324. package/dist/skills/orchestrator/validator.js +330 -241
  325. package/dist/skills/orchestrator/validator.js.map +1 -1
  326. package/dist/store/agent-resolver.d.ts.map +1 -1
  327. package/dist/store/agent-resolver.js +16 -9
  328. package/dist/store/agent-resolver.js.map +1 -1
  329. package/dist/store/attachment-store.d.ts +4 -1
  330. package/dist/store/attachment-store.d.ts.map +1 -1
  331. package/dist/store/attachment-store.js +20 -3
  332. package/dist/store/attachment-store.js.map +1 -1
  333. package/dist/store/background-jobs.d.ts +426 -105
  334. package/dist/store/background-jobs.d.ts.map +1 -1
  335. package/dist/store/background-jobs.js +1208 -252
  336. package/dist/store/background-jobs.js.map +1 -1
  337. package/dist/store/background-ops.d.ts +145 -8
  338. package/dist/store/background-ops.d.ts.map +1 -1
  339. package/dist/store/background-ops.js +459 -15
  340. package/dist/store/background-ops.js.map +1 -1
  341. package/dist/store/backup-inspect.d.ts +48 -4
  342. package/dist/store/backup-inspect.d.ts.map +1 -1
  343. package/dist/store/backup-inspect.js +384 -4
  344. package/dist/store/backup-inspect.js.map +1 -1
  345. package/dist/store/converters.d.ts.map +1 -1
  346. package/dist/store/converters.js +19 -2
  347. package/dist/store/converters.js.map +1 -1
  348. package/dist/store/data-accessor.d.ts +9 -1
  349. package/dist/store/data-accessor.d.ts.map +1 -1
  350. package/dist/store/data-accessor.js +22 -5
  351. package/dist/store/data-accessor.js.map +1 -1
  352. package/dist/store/data-safety-central.d.ts.map +1 -1
  353. package/dist/store/data-safety-central.js +272 -232
  354. package/dist/store/data-safety-central.js.map +1 -1
  355. package/dist/store/db-helpers.d.ts +19 -3
  356. package/dist/store/db-helpers.d.ts.map +1 -1
  357. package/dist/store/db-helpers.js +42 -58
  358. package/dist/store/db-helpers.js.map +1 -1
  359. package/dist/store/dual-scope-db.d.ts +63 -4
  360. package/dist/store/dual-scope-db.d.ts.map +1 -1
  361. package/dist/store/dual-scope-db.js +166 -19
  362. package/dist/store/dual-scope-db.js.map +1 -1
  363. package/dist/store/exodus/archive.d.ts +21 -7
  364. package/dist/store/exodus/archive.d.ts.map +1 -1
  365. package/dist/store/exodus/archive.js +60 -18
  366. package/dist/store/exodus/archive.js.map +1 -1
  367. package/dist/store/exodus/migrate.d.ts.map +1 -1
  368. package/dist/store/exodus/migrate.js +27 -23
  369. package/dist/store/exodus/migrate.js.map +1 -1
  370. package/dist/store/exodus/on-open.d.ts +16 -27
  371. package/dist/store/exodus/on-open.d.ts.map +1 -1
  372. package/dist/store/exodus/on-open.js +121 -169
  373. package/dist/store/exodus/on-open.js.map +1 -1
  374. package/dist/store/exodus/recovery.d.ts +90 -0
  375. package/dist/store/exodus/recovery.d.ts.map +1 -0
  376. package/dist/store/exodus/recovery.js +434 -0
  377. package/dist/store/exodus/recovery.js.map +1 -0
  378. package/dist/store/exodus/types.d.ts +15 -0
  379. package/dist/store/exodus/types.d.ts.map +1 -1
  380. package/dist/store/memory-accessor.d.ts +52 -3
  381. package/dist/store/memory-accessor.d.ts.map +1 -1
  382. package/dist/store/memory-accessor.js +122 -7
  383. package/dist/store/memory-accessor.js.map +1 -1
  384. package/dist/store/nexus-sqlite.d.ts +24 -6
  385. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  386. package/dist/store/nexus-sqlite.js +39 -20
  387. package/dist/store/nexus-sqlite.js.map +1 -1
  388. package/dist/store/ports/domain-binding.d.ts.map +1 -1
  389. package/dist/store/ports/domain-binding.js +27 -5
  390. package/dist/store/ports/domain-binding.js.map +1 -1
  391. package/dist/store/schema/background-jobs.d.ts +181 -2
  392. package/dist/store/schema/background-jobs.d.ts.map +1 -1
  393. package/dist/store/schema/background-jobs.js +27 -3
  394. package/dist/store/schema/background-jobs.js.map +1 -1
  395. package/dist/store/schema/cleo-global/skills.d.ts +2 -2
  396. package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
  397. package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
  398. package/dist/store/schema/cleo-project/tasks-core.d.ts +1 -1
  399. package/dist/store/schema/lifecycle.d.ts +2 -2
  400. package/dist/store/schema/skills-schema.d.ts +2 -2
  401. package/dist/store/schema/tasks.d.ts +1 -1
  402. package/dist/store/session-store.d.ts +3 -1
  403. package/dist/store/session-store.d.ts.map +1 -1
  404. package/dist/store/session-store.js +252 -207
  405. package/dist/store/session-store.js.map +1 -1
  406. package/dist/store/sqlite-data-accessor.d.ts +39 -4
  407. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  408. package/dist/store/sqlite-data-accessor.js +689 -527
  409. package/dist/store/sqlite-data-accessor.js.map +1 -1
  410. package/dist/store/tasks-sqlite.d.ts +3 -1
  411. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  412. package/dist/store/tasks-sqlite.js +309 -279
  413. package/dist/store/tasks-sqlite.js.map +1 -1
  414. package/dist/store/validation-schemas.d.ts +8 -8
  415. package/dist/store/writer-lease.d.ts +80 -8
  416. package/dist/store/writer-lease.d.ts.map +1 -1
  417. package/dist/store/writer-lease.js +503 -134
  418. package/dist/store/writer-lease.js.map +1 -1
  419. package/dist/system/audit.d.ts +2 -1
  420. package/dist/system/audit.d.ts.map +1 -1
  421. package/dist/system/audit.js +118 -71
  422. package/dist/system/audit.js.map +1 -1
  423. package/dist/system/backup.d.ts.map +1 -1
  424. package/dist/system/backup.js +5 -5
  425. package/dist/system/backup.js.map +1 -1
  426. package/dist/system/inject-generate.js +1 -1
  427. package/dist/task-work/index.d.ts +3 -0
  428. package/dist/task-work/index.d.ts.map +1 -1
  429. package/dist/task-work/index.js +34 -37
  430. package/dist/task-work/index.js.map +1 -1
  431. package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
  432. package/dist/tasks/ac-coverage-gate.js +4 -0
  433. package/dist/tasks/ac-coverage-gate.js.map +1 -1
  434. package/dist/tasks/ac-immutability.d.ts +7 -4
  435. package/dist/tasks/ac-immutability.d.ts.map +1 -1
  436. package/dist/tasks/ac-immutability.js +19 -17
  437. package/dist/tasks/ac-immutability.js.map +1 -1
  438. package/dist/tasks/ac-table.d.ts +5 -5
  439. package/dist/tasks/ac-table.d.ts.map +1 -1
  440. package/dist/tasks/ac-table.js +26 -12
  441. package/dist/tasks/ac-table.js.map +1 -1
  442. package/dist/tasks/acceptance-input.d.ts +52 -0
  443. package/dist/tasks/acceptance-input.d.ts.map +1 -0
  444. package/dist/tasks/acceptance-input.js +259 -0
  445. package/dist/tasks/acceptance-input.js.map +1 -0
  446. package/dist/tasks/add.d.ts +67 -29
  447. package/dist/tasks/add.d.ts.map +1 -1
  448. package/dist/tasks/add.js +255 -97
  449. package/dist/tasks/add.js.map +1 -1
  450. package/dist/tasks/complete.d.ts +16 -1
  451. package/dist/tasks/complete.d.ts.map +1 -1
  452. package/dist/tasks/complete.js +152 -55
  453. package/dist/tasks/complete.js.map +1 -1
  454. package/dist/tasks/decompose.d.ts +103 -0
  455. package/dist/tasks/decompose.d.ts.map +1 -0
  456. package/dist/tasks/decompose.js +224 -0
  457. package/dist/tasks/decompose.js.map +1 -0
  458. package/dist/tasks/delete.d.ts +5 -8
  459. package/dist/tasks/delete.d.ts.map +1 -1
  460. package/dist/tasks/delete.js +4 -3
  461. package/dist/tasks/delete.js.map +1 -1
  462. package/dist/tasks/dependency-check.d.ts +59 -0
  463. package/dist/tasks/dependency-check.d.ts.map +1 -1
  464. package/dist/tasks/dependency-check.js +73 -0
  465. package/dist/tasks/dependency-check.js.map +1 -1
  466. package/dist/tasks/deps-ready.d.ts +13 -1
  467. package/dist/tasks/deps-ready.d.ts.map +1 -1
  468. package/dist/tasks/deps-ready.js +16 -5
  469. package/dist/tasks/deps-ready.js.map +1 -1
  470. package/dist/tasks/engine-converters.d.ts +7 -0
  471. package/dist/tasks/engine-converters.d.ts.map +1 -1
  472. package/dist/tasks/engine-converters.js +8 -1
  473. package/dist/tasks/engine-converters.js.map +1 -1
  474. package/dist/tasks/evidence.d.ts +88 -27
  475. package/dist/tasks/evidence.d.ts.map +1 -1
  476. package/dist/tasks/evidence.js +344 -43
  477. package/dist/tasks/evidence.js.map +1 -1
  478. package/dist/tasks/find.d.ts +16 -12
  479. package/dist/tasks/find.d.ts.map +1 -1
  480. package/dist/tasks/find.js +107 -93
  481. package/dist/tasks/find.js.map +1 -1
  482. package/dist/tasks/gate-preview.d.ts +73 -0
  483. package/dist/tasks/gate-preview.d.ts.map +1 -0
  484. package/dist/tasks/gate-preview.js +119 -0
  485. package/dist/tasks/gate-preview.js.map +1 -0
  486. package/dist/tasks/gate-runner.d.ts +88 -14
  487. package/dist/tasks/gate-runner.d.ts.map +1 -1
  488. package/dist/tasks/gate-runner.js +719 -250
  489. package/dist/tasks/gate-runner.js.map +1 -1
  490. package/dist/tasks/hierarchy-policy.d.ts +8 -0
  491. package/dist/tasks/hierarchy-policy.d.ts.map +1 -1
  492. package/dist/tasks/hierarchy-policy.js +9 -2
  493. package/dist/tasks/hierarchy-policy.js.map +1 -1
  494. package/dist/tasks/hierarchy.d.ts +67 -1
  495. package/dist/tasks/hierarchy.d.ts.map +1 -1
  496. package/dist/tasks/hierarchy.js +81 -1
  497. package/dist/tasks/hierarchy.js.map +1 -1
  498. package/dist/tasks/index.d.ts +3 -0
  499. package/dist/tasks/index.d.ts.map +1 -1
  500. package/dist/tasks/index.js +3 -0
  501. package/dist/tasks/index.js.map +1 -1
  502. package/dist/tasks/infer-add-params.d.ts +1 -20
  503. package/dist/tasks/infer-add-params.d.ts.map +1 -1
  504. package/dist/tasks/infer-add-params.js +2 -203
  505. package/dist/tasks/infer-add-params.js.map +1 -1
  506. package/dist/tasks/list.d.ts +7 -2
  507. package/dist/tasks/list.d.ts.map +1 -1
  508. package/dist/tasks/list.js +24 -36
  509. package/dist/tasks/list.js.map +1 -1
  510. package/dist/tasks/ops.d.ts +6 -61
  511. package/dist/tasks/ops.d.ts.map +1 -1
  512. package/dist/tasks/ops.js +5 -53
  513. package/dist/tasks/ops.js.map +1 -1
  514. package/dist/tasks/plan.d.ts +15 -1
  515. package/dist/tasks/plan.d.ts.map +1 -1
  516. package/dist/tasks/plan.js +23 -25
  517. package/dist/tasks/plan.js.map +1 -1
  518. package/dist/tasks/population.d.ts +46 -0
  519. package/dist/tasks/population.d.ts.map +1 -0
  520. package/dist/tasks/population.js +88 -0
  521. package/dist/tasks/population.js.map +1 -0
  522. package/dist/tasks/reconcile-scope.d.ts +157 -0
  523. package/dist/tasks/reconcile-scope.d.ts.map +1 -0
  524. package/dist/tasks/reconcile-scope.js +242 -0
  525. package/dist/tasks/reconcile-scope.js.map +1 -0
  526. package/dist/tasks/req.d.ts +51 -12
  527. package/dist/tasks/req.d.ts.map +1 -1
  528. package/dist/tasks/req.js +125 -69
  529. package/dist/tasks/req.js.map +1 -1
  530. package/dist/tasks/session-scope.d.ts +6 -31
  531. package/dist/tasks/session-scope.d.ts.map +1 -1
  532. package/dist/tasks/session-scope.js +3 -17
  533. package/dist/tasks/session-scope.js.map +1 -1
  534. package/dist/tasks/severity-attestation.d.ts +39 -10
  535. package/dist/tasks/severity-attestation.d.ts.map +1 -1
  536. package/dist/tasks/severity-attestation.js +75 -36
  537. package/dist/tasks/severity-attestation.js.map +1 -1
  538. package/dist/tasks/task-next.d.ts +5 -0
  539. package/dist/tasks/task-next.d.ts.map +1 -1
  540. package/dist/tasks/task-next.js +10 -9
  541. package/dist/tasks/task-next.js.map +1 -1
  542. package/dist/tasks/task-reparent.d.ts.map +1 -1
  543. package/dist/tasks/task-reparent.js +3 -13
  544. package/dist/tasks/task-reparent.js.map +1 -1
  545. package/dist/tasks/update.d.ts +20 -43
  546. package/dist/tasks/update.d.ts.map +1 -1
  547. package/dist/tasks/update.js +64 -49
  548. package/dist/tasks/update.js.map +1 -1
  549. package/dist/validation/engine-ops.d.ts +17 -1
  550. package/dist/validation/engine-ops.d.ts.map +1 -1
  551. package/dist/validation/engine-ops.js +149 -11
  552. package/dist/validation/engine-ops.js.map +1 -1
  553. package/dist/workgraph/reparent-preflight.d.ts +1 -1
  554. package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
  555. package/dist/workgraph/reparent-preflight.js +6 -1
  556. package/dist/workgraph/reparent-preflight.js.map +1 -1
  557. package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
  558. package/dist/workgraph/scaffold-apply.js +81 -76
  559. package/dist/workgraph/scaffold-apply.js.map +1 -1
  560. package/dist/workgraph/structure-validation.d.ts +1 -1
  561. package/dist/workgraph/structure-validation.d.ts.map +1 -1
  562. package/dist/workgraph/structure-validation.js +6 -1
  563. package/dist/workgraph/structure-validation.js.map +1 -1
  564. package/migrations/drizzle-tasks/20260919180000_t12263-job-ownership-fences/migration.sql +34 -0
  565. package/migrations/drizzle-tasks/20260919184500_t12265-durable-pending-proposals/migration.sql +4 -0
  566. package/package.json +18 -13
  567. package/schemas/config.schema.json +2 -2
  568. package/schemas/project-context.schema.json +12 -0
  569. package/templates/CLEO-INJECTION.md +114 -101
package/dist/paths.js CHANGED
@@ -14,7 +14,6 @@
14
14
  * @epic T4454
15
15
  * @task T4458
16
16
  */
17
- import { AsyncLocalStorage } from 'node:async_hooks';
18
17
  import { existsSync, readFileSync, statSync } from 'node:fs';
19
18
  import { createRequire } from 'node:module';
20
19
  import { homedir } from 'node:os';
@@ -22,6 +21,9 @@ import { basename, dirname, join, resolve } from 'node:path';
22
21
  import { E_CWD_WALKUP_FORBIDDEN, ExitCode } from '@cleocode/contracts';
23
22
  import { computeCanonicalProjectId as _computeCanonicalProjectId, getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath, getCleoTemplatesTildePath as _getCleoTemplatesTildePath, isAbsolutePath as _isAbsolutePath, resolveProjectByCwd as _pathsResolveProjectByCwd, resolveCanonicalCleoDir as _resolveCanonicalCleoDir, } from '@cleocode/paths';
24
23
  import { CleoError } from './errors.js';
24
+ import { _resolveMainRepoFromGitlink, captureProjectScope, getProjectRoot, validateProjectRoot, worktreeScope, } from './project-scope.js';
25
+ export { getProjectRoot, validateProjectRoot, worktreeScope } from './project-scope.js';
26
+ import { createOperationExecutionContext, trackBackgroundOp } from './store/background-ops.js';
25
27
  import { getPlatformPaths } from './system/platform-paths.js';
26
28
  /**
27
29
  * Lazily-resolved `node:sqlite` `DatabaseSync` constructor.
@@ -39,36 +41,9 @@ function _getDatabaseSyncCtor() {
39
41
  const mod = _require('node:sqlite');
40
42
  return mod.DatabaseSync;
41
43
  }
42
- /**
43
- * AsyncLocalStorage instance that carries the active {@link WorktreeScope}
44
- * for the current async execution context.
45
- *
46
- * @remarks
47
- * Set by the spawn adapter (or any caller that wants to redirect CLEO path
48
- * resolution to a worktree directory) before invoking subagent logic.
49
- * `getProjectRoot()` checks this store BEFORE the `CLEO_ROOT` env-var and
50
- * ancestor-walk, so scoped callers transparently receive the worktree root.
51
- *
52
- * Callers outside a worktree context receive `undefined` from
53
- * `worktreeScope.getStore()` and fall through to the existing resolution
54
- * order unchanged.
55
- *
56
- * @example
57
- * ```ts
58
- * import { worktreeScope } from '@cleocode/core/paths';
59
- *
60
- * worktreeScope.run(
61
- * { worktreeRoot: '/path/to/worktree', projectHash: 'abc123' },
62
- * async () => {
63
- * const root = getProjectRoot(); // returns '/path/to/worktree'
64
- * }
65
- * );
66
- * ```
67
- *
68
- * @task T380
69
- * @public
70
- */
71
- export const worktreeScope = new AsyncLocalStorage();
44
+ // ============================================================================
45
+ // Worktree Scope (T380/ADR-041 §D3)
46
+ // ============================================================================
72
47
  /**
73
48
  * Run `fn` inside a `worktreeScope.run()` AsyncLocalStorage frame derived
74
49
  * from the `CLEO_WORKTREE_ROOT` and `CLEO_PROJECT_HASH` environment variables.
@@ -297,10 +272,16 @@ export function getCleoDir(cwd) {
297
272
  * getCleoDirAbsolute('/tmp/new-project', { bootstrap: true }); // "/tmp/new-project/.cleo"
298
273
  * ```
299
274
  *
275
+ * @remarks Active worktree scope takes precedence over ambient CLEO_DIR, matching
276
+ * resolveCleoDir. Outside a scope, absolute CLEO_DIR retains its override behavior.
300
277
  * @deprecated Migrate to {@link resolveProjectByCwd} + {@link resolveCanonicalCleoDir}
301
278
  * @task T11009
302
279
  */
303
280
  export function getCleoDirAbsolute(cwd, opts) {
281
+ // Captured ownership has the same precedence as the canonical resolver.
282
+ // Ambient overrides retain their historical behavior only outside a scope.
283
+ if (worktreeScope.getStore() !== undefined)
284
+ return resolveCleoDir(cwd);
304
285
  const cleoDir = getCleoDir();
305
286
  if (isAbsolutePath(cleoDir)) {
306
287
  return cleoDir;
@@ -350,7 +331,7 @@ export function getCleoDirAbsolute(cwd, opts) {
350
331
  // as the path authority.
351
332
  const project = _pathsResolveProjectByCwd(cwd);
352
333
  if (project !== null) {
353
- // T11021: Auto-register project on first encounter (fire-and-forget).
334
+ // T11021: Schedule lifecycle-tracked registration against captured global ownership.
354
335
  // T11023: pass legacyUUID so it gets registered as an alias alongside
355
336
  // the canonical ID.
356
337
  // T11281: unit tests that exercise the nexus registration/reconcile contract
@@ -359,7 +340,9 @@ export function getCleoDirAbsolute(cwd, opts) {
359
340
  // test's explicit registration state. Off by default — production always
360
341
  // auto-registers on encounter.
361
342
  if (process.env['CLEO_DISABLE_PROJECT_AUTOREGISTER'] !== '1') {
362
- registerProjectOnEncounter(project.projectRoot, project.legacyUUID ?? project.projectId).catch(() => { });
343
+ registerProjectOnEncounter(project.projectRoot, project.legacyUUID ?? project.projectId).catch((error) => {
344
+ process.stderr.write(`[cleo] Project encounter registration failed: ${error.message}\n`);
345
+ });
363
346
  }
364
347
  try {
365
348
  const projectRoot = getProjectRoot(cwd);
@@ -808,43 +791,6 @@ function _cwdHasGitAncestor(cwd) {
808
791
  current = parent;
809
792
  }
810
793
  }
811
- /**
812
- * Attempt to resolve the main git repo root from a gitlink (.git as FILE).
813
- * Returns the main repo path if the gitlink is valid and the main repo is a
814
- * CLEO project; otherwise returns `null`.
815
- *
816
- * @internal
817
- * @task T11034
818
- */
819
- function _resolveMainRepoFromGitlink(gitlinkDir) {
820
- try {
821
- const gitLinkPath = join(gitlinkDir, '.git');
822
- if (!existsSync(gitLinkPath))
823
- return null;
824
- const stat = statSync(gitLinkPath);
825
- if (!stat.isFile())
826
- return null;
827
- const gitLinkContent = readFileSync(gitLinkPath, 'utf-8').trim();
828
- const match = gitLinkContent.match(/^gitdir:\s*(.+)$/m);
829
- if (!match)
830
- return null;
831
- const gitdir = match[1].trim();
832
- // gitdir is `<main>/.git/worktrees/<name>` → strip last 3 segments.
833
- const mainRepo = dirname(dirname(dirname(gitdir)));
834
- if (existsSync(join(mainRepo, '.cleo')) && validateProjectRoot(mainRepo)) {
835
- return mainRepo;
836
- }
837
- }
838
- catch {
839
- // Parse error — not a valid gitlink.
840
- }
841
- return null;
842
- }
843
- /**
844
- * Module-level flag: emit the legacy-fallback warning at most once per process.
845
- * Prevents log spam when `validateProjectRoot` is called repeatedly in a session.
846
- */
847
- let _legacyFallbackWarned = false;
848
794
  /**
849
795
  * Module-level flag: emit the T10297 deprecation warning for
850
796
  * `getCleoDirAbsolute` at most once per process (AC4).
@@ -854,133 +800,6 @@ let _legacyFallbackWarned = false;
854
800
  * @saga T10295
855
801
  */
856
802
  let _getCleoDirAbsoluteDeprecatedWarned = false;
857
- /**
858
- * Validate that a candidate project root directory is a legitimate CLEO
859
- * project root and not a stray parent `.cleo/` directory that happened to
860
- * be found by the walk-up algorithm.
861
- *
862
- * ## Primary path (T1864 — project-info.json contract)
863
- *
864
- * A candidate is **accepted** when `.cleo/project-info.json` exists and
865
- * parses as JSON with a non-empty `projectId` string field. This is the
866
- * canonical form written by `cleo init` and is the only form that guarantees
867
- * the directory is a proper CLEO project rather than a stray `.cleo/` left by
868
- * an old installation or a git worktree that auto-created its own `.cleo/`.
869
- *
870
- * ## Legacy fallback (backwards-compatibility)
871
- *
872
- * Projects initialized before `project-info.json` was introduced are still
873
- * accepted when **both** of the following are true:
874
- * 1. `.cleo/` exists in `candidate`
875
- * 2. `.git/` exists as a sibling of `.cleo/` in `candidate`
876
- *
877
- * A one-time stderr warning is emitted (guarded by `_legacyFallbackWarned`)
878
- * so operators know to re-run `cleo init` to upgrade the project metadata.
879
- *
880
- * **Breaking change vs. prior implementation**: bare `package.json` alone is
881
- * no longer sufficient. The old check `existsSync(gitDir) || existsSync(pkgJson)`
882
- * accepted any Node.js package directory as a valid project root, which caused
883
- * the monorepo-package bug where sub-packages inside `packages/` created their
884
- * own empty `.cleo/` databases.
885
- *
886
- * @param candidate - Absolute path to the directory being considered as the
887
- * project root (parent of the `.cleo/` directory).
888
- * @returns `true` when the candidate is a recognised CLEO project root.
889
- *
890
- * @example
891
- * ```typescript
892
- * // Project root with project-info.json — valid (primary path)
893
- * validateProjectRoot('/home/user/myproject'); // true
894
- *
895
- * // Legacy project root with .git/ but no project-info.json — valid + warning
896
- * validateProjectRoot('/home/user/legacy-project'); // true (+ stderr warning)
897
- *
898
- * // Stray .cleo in home dir with no markers — invalid
899
- * validateProjectRoot('/home/user'); // false
900
- * ```
901
- *
902
- * @task T1463
903
- * @task T1864
904
- */
905
- export function validateProjectRoot(candidate) {
906
- const cleoDir = join(candidate, '.cleo');
907
- if (!existsSync(cleoDir)) {
908
- return false;
909
- }
910
- // Primary: .cleo/project-info.json with a valid projectId string.
911
- // T11034 — Worktree guard: a worktree has .git as a gitlink FILE, not a
912
- // directory. project-info.json is copied into worktrees for identity
913
- // inheritance (T11033), but worktrees must NOT be treated as standalone
914
- // project roots — path resolution must walk past them to the parent project.
915
- const projectInfoPath = join(cleoDir, 'project-info.json');
916
- if (existsSync(projectInfoPath)) {
917
- try {
918
- const raw = readFileSync(projectInfoPath, 'utf-8');
919
- const parsed = JSON.parse(raw);
920
- if (typeof parsed === 'object' &&
921
- parsed !== null &&
922
- 'projectId' in parsed &&
923
- typeof parsed['projectId'] === 'string' &&
924
- parsed['projectId'] !== '') {
925
- // T11034: Reject worktrees — .git is a gitlink FILE, not a directory.
926
- // Workers should resolve through to the parent project root.
927
- const gitMarker = join(candidate, '.git');
928
- if (existsSync(gitMarker)) {
929
- try {
930
- if (!statSync(gitMarker).isDirectory()) {
931
- // Gitlink file (worktree) — NOT a project root.
932
- return false;
933
- }
934
- }
935
- catch {
936
- // Stat failed — treat as non-directory (reject).
937
- return false;
938
- }
939
- }
940
- return true;
941
- }
942
- }
943
- catch {
944
- // JSON parse error or read error — fall through to legacy check.
945
- }
946
- }
947
- // Legacy fallback: .cleo/ + .git/ sibling (no project-info.json required).
948
- // Emits a one-time warning to prompt the operator to run `cleo init`.
949
- //
950
- // CRITICAL (T9092): a git worktree has `.git` as a *file* (a "gitlink" pointing
951
- // back to the main repo's .git/worktrees/<name> directory), NOT a directory.
952
- // Accepting such candidates as project roots recreates the 2026-05-04 dead-end-DB
953
- // disaster pattern: workers spawned in a worktree create rogue `.cleo/tasks.db`
954
- // files isolated from the real project database. The legacy fallback MUST only
955
- // accept candidates where `.git` is a true directory (a real repo root).
956
- const gitDir = join(candidate, '.git');
957
- if (existsSync(gitDir)) {
958
- let isRealGitDir = false;
959
- try {
960
- const stat = statSync(gitDir);
961
- isRealGitDir = stat.isDirectory();
962
- }
963
- catch {
964
- isRealGitDir = false;
965
- }
966
- if (!isRealGitDir) {
967
- // .git is a gitlink file (worktree marker) — NOT a project root.
968
- return false;
969
- }
970
- if (!_legacyFallbackWarned) {
971
- _legacyFallbackWarned = true;
972
- // T9774: debug-only — surfaced via CLEO_DEBUG to keep stderr clean by default.
973
- // Cannot use pushWarning here because paths.ts is in the import chain of
974
- // output.ts (output → sessions/context-alert → paths) — circular dep.
975
- if (process.env['CLEO_DEBUG']) {
976
- process.stderr.write(`[cleo][debug] W_PATH_RESOLUTION: ${candidate}/.cleo/ lacks project-info.json. ` +
977
- `Run \`cleo init\` to upgrade project metadata (T1864 legacy-fallback).\n`);
978
- }
979
- }
980
- return true;
981
- }
982
- return false;
983
- }
984
803
  /**
985
804
  * Assert that the given directory is an initialized CLEO project root,
986
805
  * throwing a `CleoError` if it is not.
@@ -1010,184 +829,6 @@ export function assertProjectInitialized(projectRoot) {
1010
829
  });
1011
830
  }
1012
831
  }
1013
- /**
1014
- * Get the project root by walking ancestor directories for `.cleo/` or `.git/`.
1015
- *
1016
- * Stops at the **first** ancestor directory that contains either sentinel
1017
- * directory and never drifts past it — even when multiple nested projects
1018
- * exist above the starting directory.
1019
- *
1020
- * Resolution order:
1021
- * 1. `CLEO_ROOT` env var — bypasses walk entirely (CI / test override)
1022
- * 2. `CLEO_DIR` env var (absolute path only) — derives project root from dirname
1023
- * 3. Walk ancestors from `cwd` (or `process.cwd()`) toward filesystem root:
1024
- * - `.cleo/` found with a sibling `.git/` or `package.json` → accept as root
1025
- * - `.cleo/` found but **no** sibling marker → skip (stray/parent `.cleo/`)
1026
- * - `.git/` found (without `.cleo/` sibling) → throw `E_NOT_INITIALIZED`
1027
- * 4. Filesystem root reached without a valid root → throw `E_INVALID_PROJECT_ROOT`
1028
- * (if at least one `.cleo/` was skipped) or `E_NO_PROJECT` (none found)
1029
- *
1030
- * @param cwd - Optional starting directory; defaults to `process.cwd()`
1031
- * @returns Absolute path to the project root directory (parent of `.cleo/`)
1032
- * @throws {CleoError} `ExitCode.CONFIG_ERROR` (`E_NOT_INITIALIZED`) when a
1033
- * `.git/` is found but no `.cleo/` is present at that level.
1034
- * @throws {CleoError} `ExitCode.CONFIG_ERROR` (`E_INVALID_PROJECT_ROOT`) when
1035
- * one or more `.cleo/` directories are found but none have the required sibling
1036
- * markers (`.git/` or `package.json`). This prevents accidental operations on
1037
- * the wrong project when a stray parent `.cleo/` exists higher in the filesystem.
1038
- * @throws {CleoError} `ExitCode.NOT_FOUND` (`E_NO_PROJECT`) when neither
1039
- * sentinel is found in any ancestor.
1040
- *
1041
- * @remarks
1042
- * `CLEO_ROOT` is an absolute-path escape hatch for environments where the
1043
- * working directory is unrelated to the project (CI tmpdirs, monorepo scripts,
1044
- * test harnesses). When set it is returned as-is without scanning ancestors.
1045
- *
1046
- * `CLEO_DIR` set to an absolute path (e.g. `/project/.cleo`) also bypasses
1047
- * the walk: the project root is derived as its `dirname`. This preserves
1048
- * backward compatibility for test harnesses that use `CLEO_DIR` to pin the
1049
- * project root.
1050
- *
1051
- * NEVER auto-creates `.cleo/`. Project initialisation is an explicit opt-in
1052
- * via `cleo init`.
1053
- *
1054
- * @example
1055
- * ```typescript
1056
- * // Running from packages/core inside the monorepo:
1057
- * const root = getProjectRoot(); // "/mnt/projects/cleocode"
1058
- * ```
1059
- */
1060
- export function getProjectRoot(cwd) {
1061
- // 0. AsyncLocalStorage worktree scope (T380/ADR-041 §D3) — checked FIRST.
1062
- // When a spawn adapter wraps execution in worktreeScope.run(...), the
1063
- // scoped root wins over all env-var and walk-based resolution.
1064
- const scope = worktreeScope.getStore();
1065
- if (scope !== undefined) {
1066
- return scope.worktreeRoot;
1067
- }
1068
- // 1. Honour CLEO_ROOT / CLEO_PROJECT_ROOT env var — bypass walk entirely.
1069
- // CLEO_PROJECT_ROOT is the agent-friendly alias (T090).
1070
- const envRoot = process.env['CLEO_ROOT'] ?? process.env['CLEO_PROJECT_ROOT'];
1071
- if (envRoot) {
1072
- return envRoot;
1073
- }
1074
- // 2. If CLEO_DIR is an absolute path, derive the project root from it.
1075
- // This preserves backward compatibility for test harnesses that set
1076
- // CLEO_DIR=/some/absolute/path/.cleo to pin the project root.
1077
- const cleoDirEnv = process.env['CLEO_DIR'];
1078
- if (cleoDirEnv && isAbsolutePath(cleoDirEnv)) {
1079
- if (cleoDirEnv.endsWith('/.cleo') || cleoDirEnv.endsWith('\\.cleo')) {
1080
- return dirname(cleoDirEnv);
1081
- }
1082
- return cleoDirEnv;
1083
- }
1084
- const start = resolve(cwd ?? process.cwd());
1085
- let current = start;
1086
- // 2.5. T9092 + T11034: if `start` is inside a git worktree (i.e. has `.git` as a
1087
- // gitlink FILE pointing to `<mainrepo>/.git/worktrees/<name>`), the
1088
- // canonical project root is the MAIN repo, not the worktree dir.
1089
- // Delegates to the shared _resolveMainRepoFromGitlink helper which
1090
- // provides deterministic resolution from any worktree path.
1091
- const mainRepoFromStart = _resolveMainRepoFromGitlink(start);
1092
- if (mainRepoFromStart !== null)
1093
- return mainRepoFromStart;
1094
- // T889/T909 guard: snapshot $HOME and filesystem root sentinels.
1095
- //
1096
- // Historical bug: when `cleo` ran with `cwd=$HOME` and a stray
1097
- // `~/.cleo/` existed (from a prior buggy run or user mistake), the
1098
- // walk-up returned `$HOME` as the project root. This silently created
1099
- // `~/.cleo/conduit.db`, `~/.cleo/tasks.db`, etc. — diverging from the
1100
- // real project DBs and losing data on branch switch. See ADR-037
1101
- // (conduit.db is project-tier-only) and the orphan-conduit remediation.
1102
- //
1103
- // Contract: `getProjectRoot` MUST NEVER resolve to `$HOME` or `/`.
1104
- // If the walk would land there, treat it as "no project" rather than
1105
- // silently accepting a pathological root. Users who legitimately want
1106
- // `$HOME` as a project root must set `CLEO_ROOT=$HOME` explicitly — the
1107
- // env-var path above bypasses this guard, making the opt-in explicit.
1108
- const homeRoot = homedir();
1109
- // T1463/P1-7: track if we skipped any .cleo/ dirs that failed validation.
1110
- // Used to produce a more informative error message when every candidate
1111
- // was rejected by validateProjectRoot.
1112
- const skippedCleoDirs = [];
1113
- // 3. Walk ancestors toward filesystem root
1114
- while (true) {
1115
- const cleoDir = join(current, '.cleo');
1116
- const gitDir = join(current, '.git');
1117
- // T889/T909: refuse to accept $HOME or / as a project root, even if a
1118
- // `.cleo/` sentinel exists there. This blocks the orphan-DB vector.
1119
- const isDangerousRoot = current === homeRoot || current === '/' || current === '';
1120
- if (existsSync(cleoDir) && !isDangerousRoot) {
1121
- // T1463/P1-7: validate that the .cleo/ dir has the required sibling
1122
- // markers (.git/ or package.json) before accepting this candidate.
1123
- //
1124
- // T9092: previously the start-directory short-circuit was unconditional —
1125
- // `current === start` returned the candidate without running
1126
- // validateProjectRoot. That allowed a worktree (whose `.git` is a gitlink
1127
- // FILE not a directory) to be accepted as a project root if any process
1128
- // had previously created a stray `.cleo/` inside it. validateProjectRoot
1129
- // now rejects gitlink-only candidates, so we must run it on the start dir
1130
- // too — but only as a *gate* to walk up further, not to reject outright.
1131
- // If start dir validation fails, we continue walking to find the real
1132
- // project root (the main repo).
1133
- if (validateProjectRoot(current)) {
1134
- // Valid project root.
1135
- return current;
1136
- }
1137
- // Stray/rogue .cleo/ found (e.g. worktree with gitlink, or .cleo without
1138
- // project-info.json AND without a real .git/ sibling) — skip it and
1139
- // continue walking up for the canonical project root.
1140
- skippedCleoDirs.push(current);
1141
- }
1142
- if (existsSync(gitDir) && !isDangerousRoot) {
1143
- // T9092: only treat .git as a "real repo root" boundary when it is a
1144
- // DIRECTORY. A gitlink FILE (worktree marker) does not anchor a project
1145
- // root — keep walking up to find the canonical main repo.
1146
- let isRealGitDir = false;
1147
- try {
1148
- isRealGitDir = statSync(gitDir).isDirectory();
1149
- }
1150
- catch {
1151
- isRealGitDir = false;
1152
- }
1153
- if (isRealGitDir) {
1154
- // Real .git/ found but no .cleo/ sibling — not initialised
1155
- throw new CleoError(ExitCode.CONFIG_ERROR, `Run cleo init at ${current}`, {
1156
- fix: `cd ${current} && cleo init`,
1157
- });
1158
- }
1159
- // gitlink file — attempt to resolve the main repo from it (T11034).
1160
- // When a worktree lives under ~/.local/share/cleo/worktrees/... and the
1161
- // caller is in a subdirectory (not the worktree root), the start-level
1162
- // gitlink check misses it. During the walk we must resolve gitlinks
1163
- // to ensure deterministic resolution from any worktree path.
1164
- const mainRepoFromWalk = _resolveMainRepoFromGitlink(current);
1165
- if (mainRepoFromWalk !== null)
1166
- return mainRepoFromWalk;
1167
- // gitlink we couldn't resolve — keep walking up.
1168
- }
1169
- // Move up one level
1170
- const parent = dirname(current);
1171
- if (parent === current) {
1172
- // Reached filesystem root without finding either sentinel
1173
- break;
1174
- }
1175
- current = parent;
1176
- }
1177
- // 4a. At least one .cleo/ was found but all were rejected by validateProjectRoot.
1178
- // This is the "parent .cleo/ trap" scenario: a stray .cleo/ dir higher in
1179
- // the filesystem lacks a .git/ or package.json sibling, so it cannot be
1180
- // trusted as a project root.
1181
- if (skippedCleoDirs.length > 0) {
1182
- throw new CleoError(ExitCode.CONFIG_ERROR, `E_INVALID_PROJECT_ROOT: no .cleo with sibling .git found from ${start} (skipped: ${skippedCleoDirs.join(', ')})`, {
1183
- fix: `cleo init or add a .git directory alongside the .cleo dir`,
1184
- });
1185
- }
1186
- // 4b. No sentinel found in any ancestor
1187
- throw new CleoError(ExitCode.NOT_FOUND, 'Not inside a CLEO project. Run cleo init or cd to an existing project', {
1188
- fix: 'cleo init',
1189
- });
1190
- }
1191
832
  /**
1192
833
  * Resolve an optional caller-provided root, falling back to canonical project root.
1193
834
  *
@@ -2069,133 +1710,141 @@ function _rowToRegistryEntry(row) {
2069
1710
  taskCount: Number(row['taskCount'] ?? 0),
2070
1711
  };
2071
1712
  }
2072
- /** Read project name from .cleo/project-info.json. Returns undefined on failure. */
1713
+ /** Read optional project name; malformed or unreadable existing metadata is a diagnostic. */
2073
1714
  function _readProjectNameFromInfo(projectRoot) {
2074
- try {
2075
- const infoPath = join(projectRoot, '.cleo', 'project-info.json');
2076
- if (!existsSync(infoPath))
2077
- return undefined;
2078
- const raw = readFileSync(infoPath, 'utf-8');
2079
- const data = JSON.parse(raw);
2080
- return typeof data.name === 'string' && data.name.length > 0 ? data.name : undefined;
2081
- }
2082
- catch {
1715
+ const infoPath = join(projectRoot, '.cleo', 'project-info.json');
1716
+ if (!existsSync(infoPath))
2083
1717
  return undefined;
2084
- }
1718
+ const raw = readFileSync(infoPath, 'utf-8');
1719
+ const data = JSON.parse(raw);
1720
+ return typeof data.name === 'string' && data.name.length > 0 ? data.name : undefined;
2085
1721
  }
2086
- /** Auto-register a project on first encounter (AC2, AC3, AC5, AC6). */
1722
+ /**
1723
+ * Register an encountered project's immutable identity in its captured global registry.
1724
+ * @param projectRoot - Explicit project ownership captured before asynchronous work.
1725
+ * @param infoProjectId - Existing immutable project identity, never inferred from similarity.
1726
+ * @returns Completion of the fully tracked operation, including any failure.
1727
+ * @remarks Lazy work obeys the existing transaction/queue boundary and shares the
1728
+ * original execution deadline. Registry writes never initialize the project graph.
1729
+ * Cancellation is checked before the actual synchronous registry transaction commits.
1730
+ * @example
1731
+ * ```ts
1732
+ * await registerProjectOnEncounter(projectRoot, projectId);
1733
+ * ```
1734
+ */
2087
1735
  export async function registerProjectOnEncounter(projectRoot, infoProjectId) {
1736
+ const scope = captureProjectScope(projectRoot, worktreeScope.getStore());
1737
+ const capturedHome = getCleoHome();
1738
+ const resolvedPath = scope.worktreeRoot;
1739
+ const projectName = _readProjectNameFromInfo(resolvedPath) || basename(resolvedPath) || 'unnamed';
1740
+ if (!infoProjectId.trim())
1741
+ throw new Error('Project encounter requires an existing immutable identity');
1742
+ const ownedExecution = !scope.execution;
1743
+ const execution = scope.execution ??
1744
+ createOperationExecutionContext({
1745
+ projectId: infoProjectId,
1746
+ projectRoot: resolvedPath,
1747
+ actor: 'project-encounter',
1748
+ operation: 'nexus.register-encounter',
1749
+ idempotencyKey: `${capturedHome}:${infoProjectId}:${resolvedPath}`,
1750
+ });
2088
1751
  try {
2089
- const { canonicalProjectId: computeCanonicalId } = await import('./nexus/identity.js');
2090
- const { generateProjectHash } = await import('./nexus/hash.js');
2091
- const canonicalResult = await computeCanonicalId(projectRoot);
2092
- const canonicalId = canonicalResult.id;
2093
- // T11281 (owner directive 2026-05-29): the registry's projectId is the
2094
- // project's IMMUTABLE lifetime identity — assigned once, stored in
2095
- // .cleo/project-info.json, and carried verbatim through move / rename /
2096
- // export-import, no matter which nexus it registers with. The path-derived
2097
- // canonical id is NOT move-stable (it changes when the path changes), so it
2098
- // is recorded only as an ALIAS; projectHash (generateProjectHash) is the
2099
- // path fingerprint that updates on move. Fall back to the canonical id only
2100
- // when the project carries no stored id yet (first assignment / fresh init).
2101
- const immutableId = infoProjectId && infoProjectId.length > 0 ? infoProjectId : canonicalId;
2102
- const { getNexusDb } = await import('./store/nexus-sqlite.js');
2103
- const { eq } = await import('drizzle-orm');
2104
- const { projectRegistry, projectIdAliases } = await import('./store/schema/nexus-schema.js');
2105
- const db = await getNexusDb();
2106
- const existingRows = await db
2107
- .select()
2108
- .from(projectRegistry)
2109
- .where(eq(projectRegistry.projectId, immutableId))
2110
- .limit(1);
2111
- const now = new Date().toISOString();
2112
- const resolvedPath = resolve(projectRoot);
2113
- const projectName = _readProjectNameFromInfo(resolvedPath) || basename(projectRoot) || 'unnamed';
2114
- if (existingRows.length > 0) {
2115
- const existingPath = existingRows[0].projectPath;
2116
- if (existingPath !== resolvedPath) {
2117
- // Seamless move/rename/export-import: same immutable projectId, new
2118
- // path. Update the path AND the projectHash fingerprint so the dual
2119
- // fingerprint tracks the new location (T11281).
2120
- const newBrainDbPath = join(resolvedPath, '.cleo', 'brain.db');
2121
- const newTasksDbPath = join(resolvedPath, '.cleo', 'tasks.db');
2122
- await db
2123
- .update(projectRegistry)
2124
- .set({
2125
- projectPath: resolvedPath,
2126
- projectHash: generateProjectHash(resolvedPath),
2127
- brainDbPath: newBrainDbPath,
2128
- tasksDbPath: newTasksDbPath,
2129
- lastSeen: now,
2130
- })
2131
- .where(eq(projectRegistry.projectId, immutableId));
2132
- }
2133
- else {
2134
- await db
2135
- .update(projectRegistry)
2136
- .set({ lastSeen: now })
2137
- .where(eq(projectRegistry.projectId, immutableId));
2138
- }
2139
- return;
2140
- }
2141
- // T11281: This insert follows a non-transactional select-by-projectId
2142
- // "not found" check above. Because the caller is a fire-and-forget
2143
- // `registerProjectOnEncounter(...).catch(() => {})` (paths.ts auto-register
2144
- // on first encounter, T11021), it can race a concurrent explicit
2145
- // `nexusRegister`/`registerProjectOnEncounter` for the same project: both
2146
- // pass the existence check, then both INSERT, and the loser throws
2147
- // `UNIQUE constraint failed: project_registry.project_path` (or the
2148
- // projectId PK). The auto-register is best-effort and idempotent by intent,
2149
- // so a lost race must be a silent no-op, not a thrown error. onConflictDoNothing
2150
- // makes the canonical-id PK and the project_path UNIQUE index both safe.
2151
- await db
2152
- .insert(projectRegistry)
2153
- .values({
2154
- projectId: immutableId,
2155
- // T11280: projectHash MUST be the canonical sha256-derived hash of the
2156
- // resolved path (matching nexusRegister/generateProjectHash), NOT the raw
2157
- // gitRoot path. The previous value polluted the registry with a path in
2158
- // the hash column, producing spurious name-collision errors when a later
2159
- // nexusRegister computed the real hash for the same project.
2160
- projectHash: generateProjectHash(resolvedPath),
2161
- projectPath: resolvedPath,
2162
- name: projectName,
2163
- registeredAt: now,
2164
- lastSeen: now,
2165
- healthStatus: 'unknown',
2166
- healthLastCheck: null,
2167
- permissions: 'read',
2168
- lastSync: now,
2169
- taskCount: 0,
2170
- labelsJson: '[]',
2171
- brainDbPath: join(resolvedPath, '.cleo', 'brain.db'),
2172
- tasksDbPath: join(resolvedPath, '.cleo', 'tasks.db'),
2173
- statsJson: '{}',
2174
- })
2175
- .onConflictDoNothing();
2176
- // Map every alternate identity token — the path-derived canonical id, the
2177
- // legacy base64url id, and any declared legacy aliases — to the IMMUTABLE
2178
- // registry id, so a lookup by ANY of them resolves to the project's lifetime
2179
- // row via the alias table (T11281). The immutable id is never its own alias.
2180
- const aliases = canonicalResult.legacyAliases ?? [];
2181
- const { legacyProjectId } = await import('./nexus/identity.js');
2182
- const directLegacy = legacyProjectId(resolvedPath);
2183
- const allAliases = new Set([directLegacy, canonicalId, infoProjectId, ...aliases]);
2184
- allAliases.delete(immutableId);
2185
- for (const legacyId of allAliases) {
2186
- try {
2187
- await db
2188
- .insert(projectIdAliases)
2189
- .values({ legacyId, canonicalId: immutableId, createdAt: now })
2190
- .onConflictDoNothing();
2191
- }
2192
- catch {
2193
- /* best-effort */
2194
- }
2195
- }
1752
+ const outcome = await trackBackgroundOp(() => worktreeScope.run({ ...scope, execution }, async () => {
1753
+ const { canonicalProjectId, legacyProjectId } = await import('./nexus/identity.js');
1754
+ const { generateProjectHash } = await import('./nexus/hash.js');
1755
+ const canonical = await canonicalProjectId(resolvedPath, execution);
1756
+ execution.assertActive();
1757
+ const { getNexusRegistryDb } = await import('./store/nexus-sqlite.js');
1758
+ const { eq, or } = await import('drizzle-orm');
1759
+ const { projectRegistry, projectIdAliases } = await import('./store/schema/nexus-schema.js');
1760
+ const db = await getNexusRegistryDb(capturedHome);
1761
+ execution.assertActive();
1762
+ const projectHash = generateProjectHash(resolvedPath);
1763
+ const legacyAlias = legacyProjectId(resolvedPath);
1764
+ const skippedAliases = [];
1765
+ const aliases = new Set([legacyAlias, canonical.id, ...(canonical.legacyAliases ?? [])]);
1766
+ aliases.delete(infoProjectId);
1767
+ db.transaction((tx) => {
1768
+ execution.assertActive();
1769
+ const owners = tx
1770
+ .select()
1771
+ .from(projectRegistry)
1772
+ .where(or(eq(projectRegistry.projectId, infoProjectId), eq(projectRegistry.projectPath, resolvedPath), eq(projectRegistry.projectHash, projectHash)))
1773
+ .all();
1774
+ if (owners.some((owner) => owner.projectId !== infoProjectId))
1775
+ throw new Error('Project encounter path or hash belongs to another immutable identity');
1776
+ const now = new Date().toISOString();
1777
+ const existing = owners.find((owner) => owner.projectId === infoProjectId);
1778
+ if (existing) {
1779
+ tx.update(projectRegistry)
1780
+ .set({
1781
+ projectPath: resolvedPath,
1782
+ projectHash,
1783
+ lastSeen: now,
1784
+ brainDbPath: join(resolvedPath, '.cleo', 'brain.db'),
1785
+ tasksDbPath: join(resolvedPath, '.cleo', 'tasks.db'),
1786
+ })
1787
+ .where(eq(projectRegistry.projectId, infoProjectId))
1788
+ .run();
1789
+ }
1790
+ else {
1791
+ tx.insert(projectRegistry)
1792
+ .values({
1793
+ projectId: infoProjectId,
1794
+ projectHash,
1795
+ projectPath: resolvedPath,
1796
+ name: projectName,
1797
+ registeredAt: now,
1798
+ lastSeen: now,
1799
+ healthStatus: 'unknown',
1800
+ healthLastCheck: null,
1801
+ permissions: 'read',
1802
+ lastSync: now,
1803
+ taskCount: 0,
1804
+ labelsJson: '[]',
1805
+ brainDbPath: join(resolvedPath, '.cleo', 'brain.db'),
1806
+ tasksDbPath: join(resolvedPath, '.cleo', 'tasks.db'),
1807
+ statsJson: '{}',
1808
+ })
1809
+ .run();
1810
+ }
1811
+ for (const alias of aliases) {
1812
+ const owner = tx
1813
+ .select()
1814
+ .from(projectIdAliases)
1815
+ .where(eq(projectIdAliases.legacyId, alias))
1816
+ .get();
1817
+ const directOwner = tx
1818
+ .select()
1819
+ .from(projectRegistry)
1820
+ .where(eq(projectRegistry.projectId, alias))
1821
+ .get();
1822
+ if ((owner && owner.canonicalId !== infoProjectId) ||
1823
+ (directOwner && directOwner.projectId !== infoProjectId)) {
1824
+ // Match explicit registration: this old truncated token is lossy.
1825
+ // Preserve its existing owner; the immutable identity still registers.
1826
+ if (alias === legacyAlias) {
1827
+ skippedAliases.push(alias);
1828
+ continue;
1829
+ }
1830
+ throw new Error('Project encounter alias belongs to another immutable identity');
1831
+ }
1832
+ if (!owner)
1833
+ tx.insert(projectIdAliases)
1834
+ .values({ legacyId: alias, canonicalId: infoProjectId, createdAt: now })
1835
+ .run();
1836
+ }
1837
+ execution.assertActive();
1838
+ }, { behavior: 'immediate' });
1839
+ if (skippedAliases.length > 0)
1840
+ process.stderr.write(`[cleo] Project encounter omitted colliding legacy alias: ${skippedAliases.join(', ')}\n`);
1841
+ }), execution);
1842
+ if (outcome.status === 'rejected')
1843
+ throw outcome.reason;
2196
1844
  }
2197
- catch {
2198
- /* best-effort registration */
1845
+ finally {
1846
+ if (ownedExecution)
1847
+ execution.close();
2199
1848
  }
2200
1849
  }
2201
1850
  //# sourceMappingURL=paths.js.map