@cleocode/core 2026.9.8 → 2026.9.9

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 (561) 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/dispatch/mutate-projection.d.ts.map +1 -1
  9. package/dist/dispatch/mutate-projection.js +12 -0
  10. package/dist/dispatch/mutate-projection.js.map +1 -1
  11. package/dist/dispatch/mvi-projection.d.ts +29 -6
  12. package/dist/dispatch/mvi-projection.d.ts.map +1 -1
  13. package/dist/dispatch/mvi-projection.js +109 -139
  14. package/dist/dispatch/mvi-projection.js.map +1 -1
  15. package/dist/docs/docs-read-model.d.ts +3 -2
  16. package/dist/docs/docs-read-model.d.ts.map +1 -1
  17. package/dist/docs/docs-read-model.js +4 -3
  18. package/dist/docs/docs-read-model.js.map +1 -1
  19. package/dist/docs/export-document.js +5100 -2297
  20. package/dist/docs/export-document.js.map +3 -3
  21. package/dist/docs/projection.d.ts +67 -0
  22. package/dist/docs/projection.d.ts.map +1 -0
  23. package/dist/docs/projection.js +370 -0
  24. package/dist/docs/projection.js.map +1 -0
  25. package/dist/doctor/acceptance-drift.d.ts +6 -2
  26. package/dist/doctor/acceptance-drift.d.ts.map +1 -1
  27. package/dist/doctor/acceptance-drift.js +43 -5
  28. package/dist/doctor/acceptance-drift.js.map +1 -1
  29. package/dist/doctor/knowledge-summary.d.ts +41 -0
  30. package/dist/doctor/knowledge-summary.d.ts.map +1 -0
  31. package/dist/doctor/knowledge-summary.js +81 -0
  32. package/dist/doctor/knowledge-summary.js.map +1 -0
  33. package/dist/doctor/knowledge.d.ts +192 -0
  34. package/dist/doctor/knowledge.d.ts.map +1 -0
  35. package/dist/doctor/knowledge.js +1864 -0
  36. package/dist/doctor/knowledge.js.map +1 -0
  37. package/dist/git/work-tree.d.ts +64 -0
  38. package/dist/git/work-tree.d.ts.map +1 -0
  39. package/dist/git/work-tree.js +111 -0
  40. package/dist/git/work-tree.js.map +1 -0
  41. package/dist/hooks/handlers/task-hooks.d.ts +8 -5
  42. package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
  43. package/dist/hooks/handlers/task-hooks.js +15 -60
  44. package/dist/hooks/handlers/task-hooks.js.map +1 -1
  45. package/dist/identity/cleo-identity.d.ts +13 -0
  46. package/dist/identity/cleo-identity.d.ts.map +1 -1
  47. package/dist/identity/cleo-identity.js +20 -6
  48. package/dist/identity/cleo-identity.js.map +1 -1
  49. package/dist/injection.d.ts.map +1 -1
  50. package/dist/injection.js +29 -13
  51. package/dist/injection.js.map +1 -1
  52. package/dist/internal.d.ts +2 -0
  53. package/dist/internal.d.ts.map +1 -1
  54. package/dist/internal.js +2 -0
  55. package/dist/internal.js.map +1 -1
  56. package/dist/lifecycle/verification/satisfies-validator.d.ts.map +1 -1
  57. package/dist/lifecycle/verification/satisfies-validator.js +124 -120
  58. package/dist/lifecycle/verification/satisfies-validator.js.map +1 -1
  59. package/dist/llm/plugin-facade.js +4018 -1726
  60. package/dist/llm/plugin-facade.js.map +3 -3
  61. package/dist/memory/brain-backfill.d.ts +27 -12
  62. package/dist/memory/brain-backfill.d.ts.map +1 -1
  63. package/dist/memory/brain-backfill.js +325 -134
  64. package/dist/memory/brain-backfill.js.map +1 -1
  65. package/dist/memory/brain-doctor.d.ts +21 -0
  66. package/dist/memory/brain-doctor.d.ts.map +1 -1
  67. package/dist/memory/brain-doctor.js +111 -53
  68. package/dist/memory/brain-doctor.js.map +1 -1
  69. package/dist/memory/brain-links.d.ts.map +1 -1
  70. package/dist/memory/brain-links.js +31 -4
  71. package/dist/memory/brain-links.js.map +1 -1
  72. package/dist/memory/brain-reasoning.d.ts.map +1 -1
  73. package/dist/memory/brain-reasoning.js +28 -2
  74. package/dist/memory/brain-reasoning.js.map +1 -1
  75. package/dist/memory/brain-reconciler.d.ts +14 -19
  76. package/dist/memory/brain-reconciler.d.ts.map +1 -1
  77. package/dist/memory/brain-reconciler.js +70 -97
  78. package/dist/memory/brain-reconciler.js.map +1 -1
  79. package/dist/memory/brain-search.d.ts +2 -0
  80. package/dist/memory/brain-search.d.ts.map +1 -1
  81. package/dist/memory/brain-search.js +59 -29
  82. package/dist/memory/brain-search.js.map +1 -1
  83. package/dist/memory/brain-similarity.d.ts.map +1 -1
  84. package/dist/memory/brain-similarity.js +5 -4
  85. package/dist/memory/brain-similarity.js.map +1 -1
  86. package/dist/memory/brain-stub-prune.d.ts +31 -9
  87. package/dist/memory/brain-stub-prune.d.ts.map +1 -1
  88. package/dist/memory/brain-stub-prune.js +65 -18
  89. package/dist/memory/brain-stub-prune.js.map +1 -1
  90. package/dist/memory/brain-writer-handlers.d.ts +10 -1
  91. package/dist/memory/brain-writer-handlers.d.ts.map +1 -1
  92. package/dist/memory/brain-writer-handlers.js +23 -3
  93. package/dist/memory/brain-writer-handlers.js.map +1 -1
  94. package/dist/memory/brain-writer-thread.d.ts +11 -1
  95. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  96. package/dist/memory/brain-writer-thread.js +87 -20
  97. package/dist/memory/brain-writer-thread.js.map +1 -1
  98. package/dist/memory/brain-writer-worker.js +8 -1
  99. package/dist/memory/brain-writer-worker.js.map +1 -1
  100. package/dist/memory/decision-cross-link.d.ts +39 -0
  101. package/dist/memory/decision-cross-link.d.ts.map +1 -1
  102. package/dist/memory/decision-cross-link.js +316 -0
  103. package/dist/memory/decision-cross-link.js.map +1 -1
  104. package/dist/memory/decisions.d.ts +4 -1
  105. package/dist/memory/decisions.d.ts.map +1 -1
  106. package/dist/memory/decisions.js +7 -24
  107. package/dist/memory/decisions.js.map +1 -1
  108. package/dist/memory/dispatch-trace.d.ts +12 -5
  109. package/dist/memory/dispatch-trace.d.ts.map +1 -1
  110. package/dist/memory/dispatch-trace.js +17 -7
  111. package/dist/memory/dispatch-trace.js.map +1 -1
  112. package/dist/memory/eligibility.d.ts +51 -0
  113. package/dist/memory/eligibility.d.ts.map +1 -0
  114. package/dist/memory/eligibility.js +77 -0
  115. package/dist/memory/eligibility.js.map +1 -0
  116. package/dist/memory/engine-compat.d.ts +2 -0
  117. package/dist/memory/engine-compat.d.ts.map +1 -1
  118. package/dist/memory/engine-compat.js +10 -0
  119. package/dist/memory/engine-compat.js.map +1 -1
  120. package/dist/memory/extraction-gate.d.ts +21 -7
  121. package/dist/memory/extraction-gate.d.ts.map +1 -1
  122. package/dist/memory/extraction-gate.js +178 -216
  123. package/dist/memory/extraction-gate.js.map +1 -1
  124. package/dist/memory/graph-auto-populate.d.ts +38 -5
  125. package/dist/memory/graph-auto-populate.d.ts.map +1 -1
  126. package/dist/memory/graph-auto-populate.js +182 -60
  127. package/dist/memory/graph-auto-populate.js.map +1 -1
  128. package/dist/memory/graph-memory-bridge.d.ts +14 -1
  129. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  130. package/dist/memory/graph-memory-bridge.js +66 -28
  131. package/dist/memory/graph-memory-bridge.js.map +1 -1
  132. package/dist/memory/index.d.ts +1 -19
  133. package/dist/memory/index.d.ts.map +1 -1
  134. package/dist/memory/index.js +1 -50
  135. package/dist/memory/index.js.map +1 -1
  136. package/dist/memory/learnings.d.ts.map +1 -1
  137. package/dist/memory/learnings.js +2 -23
  138. package/dist/memory/learnings.js.map +1 -1
  139. package/dist/memory/manifest-filter.d.ts +21 -0
  140. package/dist/memory/manifest-filter.d.ts.map +1 -0
  141. package/dist/memory/manifest-filter.js +51 -0
  142. package/dist/memory/manifest-filter.js.map +1 -0
  143. package/dist/memory/manifest-ingestion.d.ts +28 -30
  144. package/dist/memory/manifest-ingestion.d.ts.map +1 -1
  145. package/dist/memory/manifest-ingestion.js +104 -235
  146. package/dist/memory/manifest-ingestion.js.map +1 -1
  147. package/dist/memory/observer-reflector.d.ts +2 -0
  148. package/dist/memory/observer-reflector.d.ts.map +1 -1
  149. package/dist/memory/observer-reflector.js +6 -49
  150. package/dist/memory/observer-reflector.js.map +1 -1
  151. package/dist/memory/patterns.d.ts +10 -0
  152. package/dist/memory/patterns.d.ts.map +1 -1
  153. package/dist/memory/patterns.js +25 -33
  154. package/dist/memory/patterns.js.map +1 -1
  155. package/dist/memory/pipeline-manifest-sqlite.d.ts +72 -9
  156. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  157. package/dist/memory/pipeline-manifest-sqlite.js +508 -412
  158. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  159. package/dist/memory/retrieval/build-retrieval-bundle.d.ts.map +1 -1
  160. package/dist/memory/retrieval/build-retrieval-bundle.js +16 -15
  161. package/dist/memory/retrieval/build-retrieval-bundle.js.map +1 -1
  162. package/dist/memory/retrieval/fetch.d.ts +7 -0
  163. package/dist/memory/retrieval/fetch.d.ts.map +1 -1
  164. package/dist/memory/retrieval/fetch.js +14 -11
  165. package/dist/memory/retrieval/fetch.js.map +1 -1
  166. package/dist/memory/retrieval/observe.d.ts +7 -1
  167. package/dist/memory/retrieval/observe.d.ts.map +1 -1
  168. package/dist/memory/retrieval/observe.js +58 -4
  169. package/dist/memory/retrieval/observe.js.map +1 -1
  170. package/dist/memory/retrieval/search.d.ts +14 -1
  171. package/dist/memory/retrieval/search.d.ts.map +1 -1
  172. package/dist/memory/retrieval/search.js +133 -69
  173. package/dist/memory/retrieval/search.js.map +1 -1
  174. package/dist/memory/retrieval/telemetry.d.ts +31 -0
  175. package/dist/memory/retrieval/telemetry.d.ts.map +1 -0
  176. package/dist/memory/retrieval/telemetry.js +53 -0
  177. package/dist/memory/retrieval/telemetry.js.map +1 -0
  178. package/dist/nexus/analyze-orchestrator.d.ts +41 -9
  179. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  180. package/dist/nexus/analyze-orchestrator.js +257 -58
  181. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  182. package/dist/nexus/api-contracts.d.ts +2 -6
  183. package/dist/nexus/api-contracts.d.ts.map +1 -1
  184. package/dist/nexus/api-contracts.js +11 -2
  185. package/dist/nexus/api-contracts.js.map +1 -1
  186. package/dist/nexus/context.d.ts.map +1 -1
  187. package/dist/nexus/context.js +14 -37
  188. package/dist/nexus/context.js.map +1 -1
  189. package/dist/nexus/diff.d.ts.map +1 -1
  190. package/dist/nexus/diff.js +2 -1
  191. package/dist/nexus/diff.js.map +1 -1
  192. package/dist/nexus/identity.d.ts +29 -3
  193. package/dist/nexus/identity.d.ts.map +1 -1
  194. package/dist/nexus/identity.js +63 -12
  195. package/dist/nexus/identity.js.map +1 -1
  196. package/dist/nexus/impact.d.ts +21 -19
  197. package/dist/nexus/impact.d.ts.map +1 -1
  198. package/dist/nexus/impact.js +96 -192
  199. package/dist/nexus/impact.js.map +1 -1
  200. package/dist/nexus/knowledge.d.ts +80 -0
  201. package/dist/nexus/knowledge.d.ts.map +1 -0
  202. package/dist/nexus/knowledge.js +786 -0
  203. package/dist/nexus/knowledge.js.map +1 -0
  204. package/dist/nexus/living-brain.d.ts +8 -5
  205. package/dist/nexus/living-brain.d.ts.map +1 -1
  206. package/dist/nexus/living-brain.js +252 -188
  207. package/dist/nexus/living-brain.js.map +1 -1
  208. package/dist/nexus/registry.d.ts +11 -2
  209. package/dist/nexus/registry.d.ts.map +1 -1
  210. package/dist/nexus/registry.js +144 -128
  211. package/dist/nexus/registry.js.map +1 -1
  212. package/dist/nexus/source-roots.d.ts +16 -0
  213. package/dist/nexus/source-roots.d.ts.map +1 -0
  214. package/dist/nexus/source-roots.js +174 -0
  215. package/dist/nexus/source-roots.js.map +1 -0
  216. package/dist/nexus/task-evidence.d.ts +22 -0
  217. package/dist/nexus/task-evidence.d.ts.map +1 -0
  218. package/dist/nexus/task-evidence.js +210 -0
  219. package/dist/nexus/task-evidence.js.map +1 -0
  220. package/dist/nexus/tasks-bridge.d.ts +14 -7
  221. package/dist/nexus/tasks-bridge.d.ts.map +1 -1
  222. package/dist/nexus/tasks-bridge.js +81 -40
  223. package/dist/nexus/tasks-bridge.js.map +1 -1
  224. package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
  225. package/dist/orchestrate/lifecycle-ops.js +170 -120
  226. package/dist/orchestrate/lifecycle-ops.js.map +1 -1
  227. package/dist/orchestrate/query-ops.d.ts +6 -7
  228. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  229. package/dist/orchestrate/query-ops.js +509 -532
  230. package/dist/orchestrate/query-ops.js.map +1 -1
  231. package/dist/orchestration/bootstrap.d.ts +15 -1
  232. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  233. package/dist/orchestration/bootstrap.js +21 -10
  234. package/dist/orchestration/bootstrap.js.map +1 -1
  235. package/dist/orchestration/index.d.ts +35 -3
  236. package/dist/orchestration/index.d.ts.map +1 -1
  237. package/dist/orchestration/index.js +64 -35
  238. package/dist/orchestration/index.js.map +1 -1
  239. package/dist/orchestration/lead-rollup.d.ts +24 -1
  240. package/dist/orchestration/lead-rollup.d.ts.map +1 -1
  241. package/dist/orchestration/lead-rollup.js +31 -11
  242. package/dist/orchestration/lead-rollup.js.map +1 -1
  243. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  244. package/dist/orchestration/spawn-prompt.js +16 -41
  245. package/dist/orchestration/spawn-prompt.js.map +1 -1
  246. package/dist/orchestration/unblock.d.ts +15 -1
  247. package/dist/orchestration/unblock.d.ts.map +1 -1
  248. package/dist/orchestration/unblock.js +23 -12
  249. package/dist/orchestration/unblock.js.map +1 -1
  250. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  251. package/dist/orchestration/validate-spawn.js +3 -3
  252. package/dist/orchestration/validate-spawn.js.map +1 -1
  253. package/dist/orchestration/waves.d.ts +29 -13
  254. package/dist/orchestration/waves.d.ts.map +1 -1
  255. package/dist/orchestration/waves.js +43 -55
  256. package/dist/orchestration/waves.js.map +1 -1
  257. package/dist/paths.d.ts +17 -163
  258. package/dist/paths.d.ts.map +1 -1
  259. package/dist/paths.js +145 -496
  260. package/dist/paths.js.map +1 -1
  261. package/dist/project-info.d.ts +2 -11
  262. package/dist/project-info.d.ts.map +1 -1
  263. package/dist/project-info.js +3 -31
  264. package/dist/project-info.js.map +1 -1
  265. package/dist/project-scope.d.ts +239 -0
  266. package/dist/project-scope.d.ts.map +1 -0
  267. package/dist/project-scope.js +473 -0
  268. package/dist/project-scope.js.map +1 -0
  269. package/dist/release/pr-evidence.d.ts +16 -3
  270. package/dist/release/pr-evidence.d.ts.map +1 -1
  271. package/dist/release/pr-evidence.js +53 -7
  272. package/dist/release/pr-evidence.js.map +1 -1
  273. package/dist/render/nexus/graph/index.d.ts.map +1 -1
  274. package/dist/render/nexus/graph/index.js +4 -2
  275. package/dist/render/nexus/graph/index.js.map +1 -1
  276. package/dist/render/orchestration/audit-reconstruct.d.ts +11 -0
  277. package/dist/render/orchestration/audit-reconstruct.d.ts.map +1 -1
  278. package/dist/render/orchestration/audit-reconstruct.js +21 -6
  279. package/dist/render/orchestration/audit-reconstruct.js.map +1 -1
  280. package/dist/render/tasks/show.js +2 -1
  281. package/dist/render/tasks/show.js.map +1 -1
  282. package/dist/resources/spawn-wrapper.d.ts +82 -14
  283. package/dist/resources/spawn-wrapper.d.ts.map +1 -1
  284. package/dist/resources/spawn-wrapper.js +585 -27
  285. package/dist/resources/spawn-wrapper.js.map +1 -1
  286. package/dist/selfimprove/fix-gen.js +4026 -1734
  287. package/dist/selfimprove/fix-gen.js.map +3 -3
  288. package/dist/sequence/index.d.ts.map +1 -1
  289. package/dist/sequence/index.js +76 -68
  290. package/dist/sequence/index.js.map +1 -1
  291. package/dist/session/canon-lint.d.ts +24 -3
  292. package/dist/session/canon-lint.d.ts.map +1 -1
  293. package/dist/session/canon-lint.js +72 -31
  294. package/dist/session/canon-lint.js.map +1 -1
  295. package/dist/session/engine-ops.d.ts +1 -4
  296. package/dist/session/engine-ops.d.ts.map +1 -1
  297. package/dist/session/engine-ops.js +6 -2
  298. package/dist/session/engine-ops.js.map +1 -1
  299. package/dist/sessions/briefing.d.ts +11 -1
  300. package/dist/sessions/briefing.d.ts.map +1 -1
  301. package/dist/sessions/briefing.js +76 -8
  302. package/dist/sessions/briefing.js.map +1 -1
  303. package/dist/sessions/handoff.d.ts +3 -1
  304. package/dist/sessions/handoff.d.ts.map +1 -1
  305. package/dist/sessions/handoff.js +2 -0
  306. package/dist/sessions/handoff.js.map +1 -1
  307. package/dist/shutdown-deadline.d.ts +24 -33
  308. package/dist/shutdown-deadline.d.ts.map +1 -1
  309. package/dist/shutdown-deadline.js +71 -14
  310. package/dist/shutdown-deadline.js.map +1 -1
  311. package/dist/shutdown.d.ts +21 -10
  312. package/dist/shutdown.d.ts.map +1 -1
  313. package/dist/shutdown.js +89 -42
  314. package/dist/shutdown.js.map +1 -1
  315. package/dist/skills/index.d.ts +1 -1
  316. package/dist/skills/index.d.ts.map +1 -1
  317. package/dist/skills/index.js +1 -1
  318. package/dist/skills/index.js.map +1 -1
  319. package/dist/skills/orchestrator/validator.d.ts +87 -20
  320. package/dist/skills/orchestrator/validator.d.ts.map +1 -1
  321. package/dist/skills/orchestrator/validator.js +330 -241
  322. package/dist/skills/orchestrator/validator.js.map +1 -1
  323. package/dist/store/agent-resolver.d.ts.map +1 -1
  324. package/dist/store/agent-resolver.js +16 -9
  325. package/dist/store/agent-resolver.js.map +1 -1
  326. package/dist/store/attachment-store.d.ts +4 -1
  327. package/dist/store/attachment-store.d.ts.map +1 -1
  328. package/dist/store/attachment-store.js +20 -3
  329. package/dist/store/attachment-store.js.map +1 -1
  330. package/dist/store/background-jobs.d.ts +426 -105
  331. package/dist/store/background-jobs.d.ts.map +1 -1
  332. package/dist/store/background-jobs.js +1208 -252
  333. package/dist/store/background-jobs.js.map +1 -1
  334. package/dist/store/background-ops.d.ts +145 -8
  335. package/dist/store/background-ops.d.ts.map +1 -1
  336. package/dist/store/background-ops.js +459 -15
  337. package/dist/store/background-ops.js.map +1 -1
  338. package/dist/store/backup-inspect.d.ts +48 -4
  339. package/dist/store/backup-inspect.d.ts.map +1 -1
  340. package/dist/store/backup-inspect.js +384 -4
  341. package/dist/store/backup-inspect.js.map +1 -1
  342. package/dist/store/converters.d.ts.map +1 -1
  343. package/dist/store/converters.js +19 -2
  344. package/dist/store/converters.js.map +1 -1
  345. package/dist/store/data-accessor.d.ts +9 -1
  346. package/dist/store/data-accessor.d.ts.map +1 -1
  347. package/dist/store/data-accessor.js +22 -5
  348. package/dist/store/data-accessor.js.map +1 -1
  349. package/dist/store/data-safety-central.d.ts.map +1 -1
  350. package/dist/store/data-safety-central.js +272 -232
  351. package/dist/store/data-safety-central.js.map +1 -1
  352. package/dist/store/db-helpers.d.ts +19 -3
  353. package/dist/store/db-helpers.d.ts.map +1 -1
  354. package/dist/store/db-helpers.js +42 -58
  355. package/dist/store/db-helpers.js.map +1 -1
  356. package/dist/store/dual-scope-db.d.ts +63 -4
  357. package/dist/store/dual-scope-db.d.ts.map +1 -1
  358. package/dist/store/dual-scope-db.js +166 -19
  359. package/dist/store/dual-scope-db.js.map +1 -1
  360. package/dist/store/exodus/archive.d.ts +21 -7
  361. package/dist/store/exodus/archive.d.ts.map +1 -1
  362. package/dist/store/exodus/archive.js +60 -18
  363. package/dist/store/exodus/archive.js.map +1 -1
  364. package/dist/store/exodus/migrate.d.ts.map +1 -1
  365. package/dist/store/exodus/migrate.js +27 -23
  366. package/dist/store/exodus/migrate.js.map +1 -1
  367. package/dist/store/exodus/on-open.d.ts +16 -27
  368. package/dist/store/exodus/on-open.d.ts.map +1 -1
  369. package/dist/store/exodus/on-open.js +121 -169
  370. package/dist/store/exodus/on-open.js.map +1 -1
  371. package/dist/store/exodus/recovery.d.ts +90 -0
  372. package/dist/store/exodus/recovery.d.ts.map +1 -0
  373. package/dist/store/exodus/recovery.js +434 -0
  374. package/dist/store/exodus/recovery.js.map +1 -0
  375. package/dist/store/exodus/types.d.ts +15 -0
  376. package/dist/store/exodus/types.d.ts.map +1 -1
  377. package/dist/store/memory-accessor.d.ts +52 -3
  378. package/dist/store/memory-accessor.d.ts.map +1 -1
  379. package/dist/store/memory-accessor.js +122 -7
  380. package/dist/store/memory-accessor.js.map +1 -1
  381. package/dist/store/nexus-sqlite.d.ts +24 -6
  382. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  383. package/dist/store/nexus-sqlite.js +39 -20
  384. package/dist/store/nexus-sqlite.js.map +1 -1
  385. package/dist/store/ports/domain-binding.d.ts.map +1 -1
  386. package/dist/store/ports/domain-binding.js +27 -5
  387. package/dist/store/ports/domain-binding.js.map +1 -1
  388. package/dist/store/schema/background-jobs.d.ts +181 -2
  389. package/dist/store/schema/background-jobs.d.ts.map +1 -1
  390. package/dist/store/schema/background-jobs.js +27 -3
  391. package/dist/store/schema/background-jobs.js.map +1 -1
  392. package/dist/store/schema/cleo-global/skills.d.ts +2 -2
  393. package/dist/store/schema/cleo-project/lifecycle.d.ts +2 -2
  394. package/dist/store/schema/cleo-project/runtime.d.ts +1 -1
  395. package/dist/store/schema/cleo-project/tasks-core.d.ts +1 -1
  396. package/dist/store/schema/lifecycle.d.ts +2 -2
  397. package/dist/store/schema/skills-schema.d.ts +2 -2
  398. package/dist/store/schema/tasks.d.ts +1 -1
  399. package/dist/store/session-store.d.ts +3 -1
  400. package/dist/store/session-store.d.ts.map +1 -1
  401. package/dist/store/session-store.js +252 -207
  402. package/dist/store/session-store.js.map +1 -1
  403. package/dist/store/sqlite-data-accessor.d.ts +39 -4
  404. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  405. package/dist/store/sqlite-data-accessor.js +689 -527
  406. package/dist/store/sqlite-data-accessor.js.map +1 -1
  407. package/dist/store/tasks-sqlite.d.ts +3 -1
  408. package/dist/store/tasks-sqlite.d.ts.map +1 -1
  409. package/dist/store/tasks-sqlite.js +309 -279
  410. package/dist/store/tasks-sqlite.js.map +1 -1
  411. package/dist/store/validation-schemas.d.ts +8 -8
  412. package/dist/store/writer-lease.d.ts +80 -8
  413. package/dist/store/writer-lease.d.ts.map +1 -1
  414. package/dist/store/writer-lease.js +503 -134
  415. package/dist/store/writer-lease.js.map +1 -1
  416. package/dist/system/audit.d.ts +2 -1
  417. package/dist/system/audit.d.ts.map +1 -1
  418. package/dist/system/audit.js +118 -71
  419. package/dist/system/audit.js.map +1 -1
  420. package/dist/system/backup.d.ts.map +1 -1
  421. package/dist/system/backup.js +5 -5
  422. package/dist/system/backup.js.map +1 -1
  423. package/dist/system/inject-generate.js +1 -1
  424. package/dist/task-work/index.d.ts +3 -0
  425. package/dist/task-work/index.d.ts.map +1 -1
  426. package/dist/task-work/index.js +34 -37
  427. package/dist/task-work/index.js.map +1 -1
  428. package/dist/tasks/ac-coverage-gate.d.ts.map +1 -1
  429. package/dist/tasks/ac-coverage-gate.js +4 -0
  430. package/dist/tasks/ac-coverage-gate.js.map +1 -1
  431. package/dist/tasks/ac-immutability.d.ts +7 -4
  432. package/dist/tasks/ac-immutability.d.ts.map +1 -1
  433. package/dist/tasks/ac-immutability.js +19 -17
  434. package/dist/tasks/ac-immutability.js.map +1 -1
  435. package/dist/tasks/ac-table.d.ts +5 -5
  436. package/dist/tasks/ac-table.d.ts.map +1 -1
  437. package/dist/tasks/ac-table.js +26 -12
  438. package/dist/tasks/ac-table.js.map +1 -1
  439. package/dist/tasks/acceptance-input.d.ts +52 -0
  440. package/dist/tasks/acceptance-input.d.ts.map +1 -0
  441. package/dist/tasks/acceptance-input.js +259 -0
  442. package/dist/tasks/acceptance-input.js.map +1 -0
  443. package/dist/tasks/add.d.ts +67 -29
  444. package/dist/tasks/add.d.ts.map +1 -1
  445. package/dist/tasks/add.js +255 -97
  446. package/dist/tasks/add.js.map +1 -1
  447. package/dist/tasks/complete.d.ts +16 -1
  448. package/dist/tasks/complete.d.ts.map +1 -1
  449. package/dist/tasks/complete.js +152 -55
  450. package/dist/tasks/complete.js.map +1 -1
  451. package/dist/tasks/decompose.d.ts +103 -0
  452. package/dist/tasks/decompose.d.ts.map +1 -0
  453. package/dist/tasks/decompose.js +224 -0
  454. package/dist/tasks/decompose.js.map +1 -0
  455. package/dist/tasks/delete.d.ts +5 -8
  456. package/dist/tasks/delete.d.ts.map +1 -1
  457. package/dist/tasks/delete.js +4 -3
  458. package/dist/tasks/delete.js.map +1 -1
  459. package/dist/tasks/dependency-check.d.ts +59 -0
  460. package/dist/tasks/dependency-check.d.ts.map +1 -1
  461. package/dist/tasks/dependency-check.js +73 -0
  462. package/dist/tasks/dependency-check.js.map +1 -1
  463. package/dist/tasks/deps-ready.d.ts +13 -1
  464. package/dist/tasks/deps-ready.d.ts.map +1 -1
  465. package/dist/tasks/deps-ready.js +16 -5
  466. package/dist/tasks/deps-ready.js.map +1 -1
  467. package/dist/tasks/engine-converters.d.ts +7 -0
  468. package/dist/tasks/engine-converters.d.ts.map +1 -1
  469. package/dist/tasks/engine-converters.js +8 -1
  470. package/dist/tasks/engine-converters.js.map +1 -1
  471. package/dist/tasks/evidence.d.ts +54 -26
  472. package/dist/tasks/evidence.d.ts.map +1 -1
  473. package/dist/tasks/evidence.js +292 -40
  474. package/dist/tasks/evidence.js.map +1 -1
  475. package/dist/tasks/find.d.ts +16 -12
  476. package/dist/tasks/find.d.ts.map +1 -1
  477. package/dist/tasks/find.js +107 -93
  478. package/dist/tasks/find.js.map +1 -1
  479. package/dist/tasks/gate-runner.d.ts +88 -14
  480. package/dist/tasks/gate-runner.d.ts.map +1 -1
  481. package/dist/tasks/gate-runner.js +596 -253
  482. package/dist/tasks/gate-runner.js.map +1 -1
  483. package/dist/tasks/hierarchy-policy.d.ts +8 -0
  484. package/dist/tasks/hierarchy-policy.d.ts.map +1 -1
  485. package/dist/tasks/hierarchy-policy.js +9 -2
  486. package/dist/tasks/hierarchy-policy.js.map +1 -1
  487. package/dist/tasks/hierarchy.d.ts +67 -1
  488. package/dist/tasks/hierarchy.d.ts.map +1 -1
  489. package/dist/tasks/hierarchy.js +81 -1
  490. package/dist/tasks/hierarchy.js.map +1 -1
  491. package/dist/tasks/index.d.ts +3 -0
  492. package/dist/tasks/index.d.ts.map +1 -1
  493. package/dist/tasks/index.js +3 -0
  494. package/dist/tasks/index.js.map +1 -1
  495. package/dist/tasks/infer-add-params.d.ts +1 -20
  496. package/dist/tasks/infer-add-params.d.ts.map +1 -1
  497. package/dist/tasks/infer-add-params.js +2 -203
  498. package/dist/tasks/infer-add-params.js.map +1 -1
  499. package/dist/tasks/list.d.ts +7 -2
  500. package/dist/tasks/list.d.ts.map +1 -1
  501. package/dist/tasks/list.js +24 -36
  502. package/dist/tasks/list.js.map +1 -1
  503. package/dist/tasks/ops.d.ts +6 -61
  504. package/dist/tasks/ops.d.ts.map +1 -1
  505. package/dist/tasks/ops.js +5 -53
  506. package/dist/tasks/ops.js.map +1 -1
  507. package/dist/tasks/plan.d.ts +15 -1
  508. package/dist/tasks/plan.d.ts.map +1 -1
  509. package/dist/tasks/plan.js +23 -25
  510. package/dist/tasks/plan.js.map +1 -1
  511. package/dist/tasks/population.d.ts +46 -0
  512. package/dist/tasks/population.d.ts.map +1 -0
  513. package/dist/tasks/population.js +88 -0
  514. package/dist/tasks/population.js.map +1 -0
  515. package/dist/tasks/reconcile-scope.d.ts +157 -0
  516. package/dist/tasks/reconcile-scope.d.ts.map +1 -0
  517. package/dist/tasks/reconcile-scope.js +242 -0
  518. package/dist/tasks/reconcile-scope.js.map +1 -0
  519. package/dist/tasks/req.d.ts +51 -12
  520. package/dist/tasks/req.d.ts.map +1 -1
  521. package/dist/tasks/req.js +125 -69
  522. package/dist/tasks/req.js.map +1 -1
  523. package/dist/tasks/session-scope.d.ts +6 -31
  524. package/dist/tasks/session-scope.d.ts.map +1 -1
  525. package/dist/tasks/session-scope.js +3 -17
  526. package/dist/tasks/session-scope.js.map +1 -1
  527. package/dist/tasks/severity-attestation.d.ts +39 -10
  528. package/dist/tasks/severity-attestation.d.ts.map +1 -1
  529. package/dist/tasks/severity-attestation.js +75 -36
  530. package/dist/tasks/severity-attestation.js.map +1 -1
  531. package/dist/tasks/task-next.d.ts +5 -0
  532. package/dist/tasks/task-next.d.ts.map +1 -1
  533. package/dist/tasks/task-next.js +10 -9
  534. package/dist/tasks/task-next.js.map +1 -1
  535. package/dist/tasks/task-reparent.d.ts.map +1 -1
  536. package/dist/tasks/task-reparent.js +3 -13
  537. package/dist/tasks/task-reparent.js.map +1 -1
  538. package/dist/tasks/update.d.ts +20 -43
  539. package/dist/tasks/update.d.ts.map +1 -1
  540. package/dist/tasks/update.js +64 -49
  541. package/dist/tasks/update.js.map +1 -1
  542. package/dist/validation/engine-ops.d.ts +17 -1
  543. package/dist/validation/engine-ops.d.ts.map +1 -1
  544. package/dist/validation/engine-ops.js +149 -11
  545. package/dist/validation/engine-ops.js.map +1 -1
  546. package/dist/workgraph/reparent-preflight.d.ts +1 -1
  547. package/dist/workgraph/reparent-preflight.d.ts.map +1 -1
  548. package/dist/workgraph/reparent-preflight.js +6 -1
  549. package/dist/workgraph/reparent-preflight.js.map +1 -1
  550. package/dist/workgraph/scaffold-apply.d.ts.map +1 -1
  551. package/dist/workgraph/scaffold-apply.js +81 -76
  552. package/dist/workgraph/scaffold-apply.js.map +1 -1
  553. package/dist/workgraph/structure-validation.d.ts +1 -1
  554. package/dist/workgraph/structure-validation.d.ts.map +1 -1
  555. package/dist/workgraph/structure-validation.js +6 -1
  556. package/dist/workgraph/structure-validation.js.map +1 -1
  557. package/migrations/drizzle-tasks/20260919180000_t12263-job-ownership-fences/migration.sql +34 -0
  558. package/migrations/drizzle-tasks/20260919184500_t12265-durable-pending-proposals/migration.sql +4 -0
  559. package/package.json +18 -13
  560. package/schemas/config.schema.json +2 -2
  561. package/templates/CLEO-INJECTION.md +103 -101
@@ -1,8 +1,10 @@
1
1
  /**
2
2
  * SQLite-backed task store operations.
3
3
  *
4
- * CRUD operations for tasks, dependencies, and relations backed by tasks.db.
4
+ * CRUD operations for tasks, dependencies, and relations backed by the project cleo.db.
5
5
  * Implements the same interface as the JSON store for StoreProvider compatibility.
6
+ * Every public operation captures canonical project scope before opening a handle;
7
+ * direct SQL, safety checks and accessor transactions retain that same ownership.
6
8
  *
7
9
  * @epic T4454
8
10
  * @task W1-T3
@@ -10,12 +12,20 @@
10
12
  import { ARCHIVE_REASON_TOMBSTONE, ArchiveReasonTombstoneError, ExitCode, isArchiveTombstoneAllowed, isStorableTaskId, } from '@cleocode/contracts';
11
13
  import { and, asc, count, eq, inArray, isNull, ne, sql } from 'drizzle-orm';
12
14
  import { CleoError } from '../errors.js';
15
+ import { getProjectRoot, worktreeScope } from '../project-scope.js';
16
+ import { applyAcPlan, planAcUpdate } from '../tasks/ac-table.js';
13
17
  import { rowToTask, taskToRow } from './converters.js';
14
18
  import { cleanupBrainRefsOnTaskDelete } from './cross-db-cleanup.js';
15
19
  import { safeCreateTask, safeDeleteTask, safeUpdateTask, } from './data-safety-central.js';
16
20
  import { parseLabels, updateTaskLabels } from './db-helpers.js';
17
21
  import { getDb, getNativeDb } from './sqlite.js';
22
+ import { captureTaskAccessorScope, createSqliteDataAccessor } from './sqlite-data-accessor.js';
18
23
  import * as schema from './tasks-schema.js';
24
+ /** Capture one legacy operation before opening a handle or crossing an await. */
25
+ function inTaskStoreScope(cwd, operation) {
26
+ const scope = captureTaskAccessorScope(cwd ?? getProjectRoot(), worktreeScope.getStore());
27
+ return worktreeScope.run(scope, () => operation(scope.worktreeRoot));
28
+ }
19
29
  // === CRUD OPERATIONS ===
20
30
  /** Insert a task row directly. Internal use only — call createTask for the safe path. */
21
31
  async function insertTaskRow(task, cwd) {
@@ -34,168 +44,156 @@ async function insertTaskRow(task, cwd) {
34
44
  });
35
45
  }
36
46
  const db = await getDb(cwd);
37
- const row = taskToRow(task);
38
- db.insert(schema.tasks).values(row).run();
39
- // Insert dependencies
40
- if (task.depends && task.depends.length > 0) {
41
- for (const depId of task.depends) {
47
+ const accessor = await createSqliteDataAccessor(cwd);
48
+ return accessor.transaction(async (tx) => {
49
+ const row = taskToRow(task);
50
+ // Retain INSERT's collision rejection rather than converting creation to
51
+ // an upsert that could overwrite a concurrently-created identity.
52
+ db.insert(schema.tasks).values(row).run();
53
+ for (const depId of task.depends ?? []) {
42
54
  db.insert(schema.taskDependencies).values({ taskId: task.id, dependsOn: depId }).run();
43
55
  }
44
- }
45
- // T11356: keep the task_labels junction in sync with labels_json.
46
- await updateTaskLabels(db, task.id, parseLabels(row.labelsJson));
47
- return task;
56
+ await updateTaskLabels(db, task.id, parseLabels(row.labelsJson));
57
+ if (task.acceptance !== undefined) {
58
+ await applyAcPlan(tx, task.id, planAcUpdate(task.id, [], task.acceptance));
59
+ }
60
+ for (const relation of task.relates ?? []) {
61
+ await tx.addRelation(task.id, relation.taskId, relation.type, relation.reason);
62
+ }
63
+ return task;
64
+ });
48
65
  }
49
66
  /** Get a task by ID, including its dependencies. */
50
67
  export async function getTask(taskId, cwd) {
51
- const db = await getDb(cwd);
52
- const rows = await db.select().from(schema.tasks).where(eq(schema.tasks.id, taskId)).all();
53
- if (rows.length === 0)
54
- return null;
55
- const task = rowToTask(rows[0]);
56
- // Load dependencies
57
- const deps = await db
58
- .select()
59
- .from(schema.taskDependencies)
60
- .where(eq(schema.taskDependencies.taskId, taskId))
61
- .all();
62
- if (deps.length > 0) {
63
- task.depends = deps.map((d) => d.dependsOn);
64
- }
65
- return task;
68
+ return inTaskStoreScope(cwd, async (cwd) => {
69
+ const db = await getDb(cwd);
70
+ const rows = await db.select().from(schema.tasks).where(eq(schema.tasks.id, taskId)).all();
71
+ if (rows.length === 0)
72
+ return null;
73
+ const task = rowToTask(rows[0]);
74
+ // Load dependencies
75
+ const deps = await db
76
+ .select()
77
+ .from(schema.taskDependencies)
78
+ .where(eq(schema.taskDependencies.taskId, taskId))
79
+ .all();
80
+ if (deps.length > 0) {
81
+ task.depends = deps.map((d) => d.dependsOn);
82
+ }
83
+ return task;
84
+ });
66
85
  }
67
86
  /** Update an existing task. */
68
87
  export async function updateTask(taskId, updates, cwd) {
69
- const db = await getDb(cwd);
70
- const existing = await getTask(taskId, cwd);
71
- if (!existing)
72
- return null;
73
- // Build update object (only changed fields)
74
- const updateRow = {
75
- updatedAt: new Date().toISOString(),
76
- };
77
- if (updates.title !== undefined)
78
- updateRow.title = updates.title;
79
- if (updates.description !== undefined)
80
- updateRow.description = updates.description;
81
- if (updates.status !== undefined) {
82
- updateRow.status = updates.status;
83
- // Clear stale timestamps when status resets to non-terminal state
84
- if (updates.status === 'pending' || updates.status === 'active') {
85
- if (updates.cancelledAt === undefined)
86
- updateRow.cancelledAt = null;
87
- if (updates.completedAt === undefined)
88
- updateRow.completedAt = null;
88
+ return inTaskStoreScope(cwd, async (cwd) => {
89
+ if (updates.id !== undefined && updates.id !== taskId) {
90
+ throw new CleoError(ExitCode.INVALID_INPUT, 'A task update cannot change its identity');
89
91
  }
90
- }
91
- if (updates.priority !== undefined)
92
- updateRow.priority = updates.priority;
93
- if (updates.type !== undefined)
94
- updateRow.type = updates.type;
95
- if (updates.parentId !== undefined)
96
- updateRow.parentId = updates.parentId;
97
- if (updates.phase !== undefined)
98
- updateRow.phase = updates.phase;
99
- if (updates.size !== undefined)
100
- updateRow.size = updates.size;
101
- if (updates.position !== undefined)
102
- updateRow.position = updates.position;
103
- if (updates.labels !== undefined)
104
- updateRow.labelsJson = JSON.stringify(updates.labels);
105
- if (updates.notes !== undefined)
106
- updateRow.notesJson = JSON.stringify(updates.notes);
107
- if (updates.acceptance !== undefined)
108
- updateRow.acceptanceJson = JSON.stringify(updates.acceptance);
109
- if (updates.files !== undefined)
110
- updateRow.filesJson = JSON.stringify(updates.files);
111
- if (updates.origin !== undefined)
112
- updateRow.origin = updates.origin;
113
- if (updates.blockedBy !== undefined)
114
- updateRow.blockedBy = updates.blockedBy;
115
- if (updates.epicLifecycle !== undefined)
116
- updateRow.epicLifecycle = updates.epicLifecycle;
117
- if (updates.completedAt !== undefined)
118
- updateRow.completedAt = updates.completedAt;
119
- if (updates.cancelledAt !== undefined)
120
- updateRow.cancelledAt = updates.cancelledAt;
121
- if (updates.cancellationReason !== undefined)
122
- updateRow.cancellationReason = updates.cancellationReason;
123
- if (updates.verification !== undefined)
124
- updateRow.verificationJson = JSON.stringify(updates.verification);
125
- if (updates.assignee !== undefined)
126
- updateRow.assignee = updates.assignee;
127
- db.update(schema.tasks).set(updateRow).where(eq(schema.tasks.id, taskId)).run();
128
- // Update dependencies if provided
129
- if (updates.depends !== undefined) {
130
- db.delete(schema.taskDependencies).where(eq(schema.taskDependencies.taskId, taskId)).run();
131
- for (const depId of updates.depends) {
132
- db.insert(schema.taskDependencies).values({ taskId, dependsOn: depId }).run();
92
+ if (updates.gates !== undefined || updates.abortReason !== undefined) {
93
+ throw new CleoError(ExitCode.INVALID_INPUT, 'gates and abortReason are not persisted task fields');
133
94
  }
134
- }
135
- // T11356: keep the task_labels junction in sync when labels change.
136
- if (updates.labels !== undefined) {
137
- await updateTaskLabels(db, taskId, parseLabels(updateRow.labelsJson));
138
- }
139
- return getTask(taskId, cwd);
95
+ const accessor = await createSqliteDataAccessor(cwd);
96
+ return accessor.transaction(async (tx) => {
97
+ const existing = await getTask(taskId, cwd);
98
+ if (!existing)
99
+ return null;
100
+ const provided = { ...updates };
101
+ for (const [key, value] of Object.entries(provided)) {
102
+ if (value === undefined)
103
+ Reflect.deleteProperty(provided, key);
104
+ }
105
+ const updated = {
106
+ ...existing,
107
+ ...provided,
108
+ id: taskId,
109
+ updatedAt: updates.updatedAt ?? new Date().toISOString(),
110
+ };
111
+ if (updates.status === 'pending' || updates.status === 'active') {
112
+ if (updates.cancelledAt === undefined)
113
+ updated.cancelledAt = undefined;
114
+ if (updates.completedAt === undefined)
115
+ updated.completedAt = undefined;
116
+ }
117
+ // The canonical Task converter is shared with add and rich update. Never
118
+ // maintain another partial field list that silently drops accepted values.
119
+ await tx.upsertSingleTask(updated);
120
+ if (updates.acceptance !== undefined) {
121
+ await applyAcPlan(tx, taskId, planAcUpdate(taskId, await tx.getAcRows(taskId), updates.acceptance));
122
+ }
123
+ if (updates.relates !== undefined) {
124
+ await tx.clearRelations(taskId);
125
+ for (const relation of updates.relates) {
126
+ await tx.addRelation(taskId, relation.taskId, relation.type, relation.reason);
127
+ }
128
+ }
129
+ return getTask(taskId, cwd);
130
+ });
131
+ });
140
132
  }
141
133
  /** Delete a task by ID. */
142
134
  export async function deleteTask(taskId, cwd) {
143
- const db = await getDb(cwd);
144
- const existing = await db
145
- .select({ id: schema.tasks.id })
146
- .from(schema.tasks)
147
- .where(eq(schema.tasks.id, taskId))
148
- .all();
149
- if (existing.length === 0)
150
- return false;
151
- db.delete(schema.tasks).where(eq(schema.tasks.id, taskId)).run();
152
- // T033 Part 4: Cross-DB cleanup — nullify brain.db soft FK refs to this task.
153
- // Runs after deletion to avoid blocking the task delete path on brain errors.
154
- void cleanupBrainRefsOnTaskDelete(taskId, cwd);
155
- return true;
135
+ return inTaskStoreScope(cwd, async (cwd) => {
136
+ const db = await getDb(cwd);
137
+ const existing = await db
138
+ .select({ id: schema.tasks.id })
139
+ .from(schema.tasks)
140
+ .where(eq(schema.tasks.id, taskId))
141
+ .all();
142
+ if (existing.length === 0)
143
+ return false;
144
+ db.delete(schema.tasks).where(eq(schema.tasks.id, taskId)).run();
145
+ // T033 Part 4: Cross-DB cleanup — nullify brain.db soft FK refs to this task.
146
+ // Runs after deletion to avoid blocking the task delete path on brain errors.
147
+ void cleanupBrainRefsOnTaskDelete(taskId, cwd);
148
+ return true;
149
+ });
156
150
  }
157
151
  /** List tasks with optional filters. */
158
152
  export async function listTasks(filters, cwd) {
159
- const db = await getDb(cwd);
160
- const conditions = [];
161
- // Exclude archived by default
162
- conditions.push(ne(schema.tasks.status, 'archived'));
163
- if (filters?.status)
164
- conditions.push(eq(schema.tasks.status, filters.status));
165
- if (filters?.parentId !== undefined) {
166
- if (filters.parentId === null) {
167
- conditions.push(isNull(schema.tasks.parentId));
168
- }
169
- else {
170
- conditions.push(eq(schema.tasks.parentId, filters.parentId));
153
+ return inTaskStoreScope(cwd, async (cwd) => {
154
+ const db = await getDb(cwd);
155
+ const conditions = [];
156
+ // Exclude archived by default
157
+ conditions.push(ne(schema.tasks.status, 'archived'));
158
+ if (filters?.status)
159
+ conditions.push(eq(schema.tasks.status, filters.status));
160
+ if (filters?.parentId !== undefined) {
161
+ if (filters.parentId === null) {
162
+ conditions.push(isNull(schema.tasks.parentId));
163
+ }
164
+ else {
165
+ conditions.push(eq(schema.tasks.parentId, filters.parentId));
166
+ }
171
167
  }
172
- }
173
- if (filters?.type)
174
- conditions.push(eq(schema.tasks.type, filters.type));
175
- if (filters?.phase)
176
- conditions.push(eq(schema.tasks.phase, filters.phase));
177
- const query = db
178
- .select()
179
- .from(schema.tasks)
180
- .where(conditions.length > 0 ? and(...conditions) : undefined)
181
- .orderBy(asc(schema.tasks.position), asc(schema.tasks.createdAt));
182
- const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
183
- // Load dependencies for all tasks
184
- const tasks = rows.map(rowToTask);
185
- await loadDependencies(tasks, cwd);
186
- return tasks;
168
+ if (filters?.type)
169
+ conditions.push(eq(schema.tasks.type, filters.type));
170
+ if (filters?.phase)
171
+ conditions.push(eq(schema.tasks.phase, filters.phase));
172
+ const query = db
173
+ .select()
174
+ .from(schema.tasks)
175
+ .where(conditions.length > 0 ? and(...conditions) : undefined)
176
+ .orderBy(asc(schema.tasks.position), asc(schema.tasks.createdAt));
177
+ const rows = filters?.limit ? await query.limit(filters.limit).all() : await query.all();
178
+ // Load dependencies for all tasks
179
+ const tasks = rows.map(rowToTask);
180
+ await loadDependencies(tasks, cwd);
181
+ return tasks;
182
+ });
187
183
  }
188
184
  /** Find tasks by fuzzy text search. */
189
185
  export async function findTasks(query, limit = 20, cwd) {
190
- const db = await getDb(cwd);
191
- const pattern = `%${query}%`;
192
- const rows = await db
193
- .select()
194
- .from(schema.tasks)
195
- .where(and(ne(schema.tasks.status, 'archived'), sql `(${schema.tasks.id} LIKE ${pattern} OR ${schema.tasks.title} LIKE ${pattern} OR ${schema.tasks.description} LIKE ${pattern})`))
196
- .limit(limit)
197
- .all();
198
- return rows.map(rowToTask);
186
+ return inTaskStoreScope(cwd, async (cwd) => {
187
+ const db = await getDb(cwd);
188
+ const pattern = `%${query}%`;
189
+ const rows = await db
190
+ .select()
191
+ .from(schema.tasks)
192
+ .where(and(ne(schema.tasks.status, 'archived'), sql `(${schema.tasks.id} LIKE ${pattern} OR ${schema.tasks.title} LIKE ${pattern} OR ${schema.tasks.description} LIKE ${pattern})`))
193
+ .limit(limit)
194
+ .all();
195
+ return rows.map(rowToTask);
196
+ });
199
197
  }
200
198
  /**
201
199
  * Archive a task (sets status to 'archived' with metadata).
@@ -207,58 +205,60 @@ export async function findTasks(query, limit = 20, cwd) {
207
205
  * to `'completed-unverified'` to preserve forward compat.
208
206
  */
209
207
  export async function archiveTask(taskId, reason, cwd) {
210
- const db = await getDb(cwd);
211
- const task = await getTask(taskId, cwd);
212
- if (!task)
213
- return false;
214
- const now = new Date().toISOString();
215
- const cycleTime = task.createdAt
216
- ? Math.floor((Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60 * 24))
217
- : null;
218
- // Normalize any caller-supplied legacy reason ('completed', 'deleted',
219
- // arbitrary strings) into the T1408 enum. NULL stays NULL via undefined.
220
- //
221
- // T1409: enforce the tombstone guard. Direct callers MAY NOT write the
222
- // tombstone value `'completed-unverified'` unless the migration-backfill
223
- // env flag is set. The fallback when no reason is supplied still maps to
224
- // the tombstone (since DB CHECK requires one of the 6 enum values), but
225
- // explicit caller-supplied tombstones from non-migration code are rejected.
226
- // T11578 · AC1: the consolidated `tasks_tasks.archive_reason` column is
227
- // CHECK-backed by the T1408 enum, so the writer must produce a value typed as
228
- // `ArchiveReasonValue` (the prefixed schema narrows the column type). The
229
- // normalization already only ever yields canonical enum values; the explicit
230
- // return type makes that guarantee visible to the drizzle `.set()` overload.
231
- const normalizedReason = (() => {
232
- if (!reason)
208
+ return inTaskStoreScope(cwd, async (cwd) => {
209
+ const db = await getDb(cwd);
210
+ const task = await getTask(taskId, cwd);
211
+ if (!task)
212
+ return false;
213
+ const now = new Date().toISOString();
214
+ const cycleTime = task.createdAt
215
+ ? Math.floor((Date.now() - new Date(task.createdAt).getTime()) / (1000 * 60 * 60 * 24))
216
+ : null;
217
+ // Normalize any caller-supplied legacy reason ('completed', 'deleted',
218
+ // arbitrary strings) into the T1408 enum. NULL stays NULL via undefined.
219
+ //
220
+ // T1409: enforce the tombstone guard. Direct callers MAY NOT write the
221
+ // tombstone value `'completed-unverified'` unless the migration-backfill
222
+ // env flag is set. The fallback when no reason is supplied still maps to
223
+ // the tombstone (since DB CHECK requires one of the 6 enum values), but
224
+ // explicit caller-supplied tombstones from non-migration code are rejected.
225
+ // T11578 · AC1: the consolidated `tasks_tasks.archive_reason` column is
226
+ // CHECK-backed by the T1408 enum, so the writer must produce a value typed as
227
+ // `ArchiveReasonValue` (the prefixed schema narrows the column type). The
228
+ // normalization already only ever yields canonical enum values; the explicit
229
+ // return type makes that guarantee visible to the drizzle `.set()` overload.
230
+ const normalizedReason = (() => {
231
+ if (!reason)
232
+ return ARCHIVE_REASON_TOMBSTONE;
233
+ const valid = new Set([
234
+ 'verified',
235
+ 'reconciled',
236
+ 'superseded',
237
+ 'shadowed',
238
+ 'cancelled',
239
+ ARCHIVE_REASON_TOMBSTONE,
240
+ ]);
241
+ if (reason === ARCHIVE_REASON_TOMBSTONE && !isArchiveTombstoneAllowed()) {
242
+ throw new ArchiveReasonTombstoneError(taskId);
243
+ }
244
+ if (valid.has(reason))
245
+ return reason;
246
+ if (reason === 'deleted')
247
+ return 'cancelled';
233
248
  return ARCHIVE_REASON_TOMBSTONE;
234
- const valid = new Set([
235
- 'verified',
236
- 'reconciled',
237
- 'superseded',
238
- 'shadowed',
239
- 'cancelled',
240
- ARCHIVE_REASON_TOMBSTONE,
241
- ]);
242
- if (reason === ARCHIVE_REASON_TOMBSTONE && !isArchiveTombstoneAllowed()) {
243
- throw new ArchiveReasonTombstoneError(taskId);
244
- }
245
- if (valid.has(reason))
246
- return reason;
247
- if (reason === 'deleted')
248
- return 'cancelled';
249
- return ARCHIVE_REASON_TOMBSTONE;
250
- })();
251
- db.update(schema.tasks)
252
- .set({
253
- status: 'archived',
254
- archivedAt: now,
255
- archiveReason: normalizedReason,
256
- cycleTimeDays: cycleTime,
257
- updatedAt: now,
258
- })
259
- .where(eq(schema.tasks.id, taskId))
260
- .run();
261
- return true;
249
+ })();
250
+ db.update(schema.tasks)
251
+ .set({
252
+ status: 'archived',
253
+ archivedAt: now,
254
+ archiveReason: normalizedReason,
255
+ cycleTimeDays: cycleTime,
256
+ updatedAt: now,
257
+ })
258
+ .where(eq(schema.tasks.id, taskId))
259
+ .run();
260
+ return true;
261
+ });
262
262
  }
263
263
  // === DEPENDENCY & RELATION OPERATIONS ===
264
264
  /** Load dependencies for a list of tasks. */
@@ -287,63 +287,74 @@ async function loadDependencies(tasks, cwd) {
287
287
  }
288
288
  /** Add a dependency between tasks. */
289
289
  export async function addDependency(taskId, dependsOn, cwd) {
290
- const db = await getDb(cwd);
291
- db.insert(schema.taskDependencies).values({ taskId, dependsOn }).onConflictDoNothing().run();
290
+ return inTaskStoreScope(cwd, async (cwd) => {
291
+ const db = await getDb(cwd);
292
+ db.insert(schema.taskDependencies).values({ taskId, dependsOn }).onConflictDoNothing().run();
293
+ });
292
294
  }
293
295
  /** Remove a dependency. */
294
296
  export async function removeDependency(taskId, dependsOn, cwd) {
295
- const db = await getDb(cwd);
296
- db.delete(schema.taskDependencies)
297
- .where(and(eq(schema.taskDependencies.taskId, taskId), eq(schema.taskDependencies.dependsOn, dependsOn)))
298
- .run();
297
+ return inTaskStoreScope(cwd, async (cwd) => {
298
+ const db = await getDb(cwd);
299
+ db.delete(schema.taskDependencies)
300
+ .where(and(eq(schema.taskDependencies.taskId, taskId), eq(schema.taskDependencies.dependsOn, dependsOn)))
301
+ .run();
302
+ });
299
303
  }
300
304
  /** Add a relation between tasks. */
301
305
  export async function addRelation(taskId, relatedTo, relationType = 'related', cwd, reason) {
302
- const db = await getDb(cwd);
303
- await db
304
- .insert(schema.taskRelations)
305
- .values({ taskId, relatedTo, relationType, reason: reason ?? null })
306
- .onConflictDoNothing()
307
- .run();
306
+ return inTaskStoreScope(cwd, async (cwd) => {
307
+ const db = await getDb(cwd);
308
+ await db
309
+ .insert(schema.taskRelations)
310
+ .values({ taskId, relatedTo, relationType, reason: reason ?? null })
311
+ .onConflictDoNothing()
312
+ .run();
313
+ });
308
314
  }
309
315
  /** Remove a relation between tasks. */
310
316
  export async function removeRelation(taskId, relatedTo, relationType, cwd) {
311
- const db = await getDb(cwd);
312
- const conditions = [
313
- eq(schema.taskRelations.taskId, taskId),
314
- eq(schema.taskRelations.relatedTo, relatedTo),
315
- ];
316
- if (relationType !== undefined) {
317
- conditions.push(eq(schema.taskRelations.relationType, relationType));
318
- }
319
- await db
320
- .delete(schema.taskRelations)
321
- .where(and(...conditions))
322
- .run();
317
+ return inTaskStoreScope(cwd, async (cwd) => {
318
+ const db = await getDb(cwd);
319
+ const conditions = [
320
+ eq(schema.taskRelations.taskId, taskId),
321
+ eq(schema.taskRelations.relatedTo, relatedTo),
322
+ ];
323
+ if (relationType !== undefined) {
324
+ conditions.push(eq(schema.taskRelations.relationType, relationType));
325
+ }
326
+ await db
327
+ .delete(schema.taskRelations)
328
+ .where(and(...conditions))
329
+ .run();
330
+ });
323
331
  }
324
332
  /** Get relations for a task. */
325
333
  export async function getRelations(taskId, cwd) {
326
- const db = await getDb(cwd);
327
- const rows = await db
328
- .select()
329
- .from(schema.taskRelations)
330
- .where(eq(schema.taskRelations.taskId, taskId))
331
- .all();
332
- return rows.map((r) => ({
333
- relatedTo: r.relatedTo,
334
- type: r.relationType,
335
- reason: r.reason ?? undefined,
336
- }));
334
+ return inTaskStoreScope(cwd, async (cwd) => {
335
+ const db = await getDb(cwd);
336
+ const rows = await db
337
+ .select()
338
+ .from(schema.taskRelations)
339
+ .where(eq(schema.taskRelations.taskId, taskId))
340
+ .all();
341
+ return rows.map((r) => ({
342
+ relatedTo: r.relatedTo,
343
+ type: r.relationType,
344
+ reason: r.reason ?? undefined,
345
+ }));
346
+ });
337
347
  }
338
348
  // === GRAPH OPERATIONS ===
339
349
  /** Get the dependency chain (blockers) for a task using recursive CTE. */
340
350
  export async function getBlockerChain(taskId, cwd) {
341
- await getDb(cwd);
342
- const nativeDb = getNativeDb(cwd);
343
- if (!nativeDb)
344
- return [];
345
- const result = nativeDb
346
- .prepare(`
351
+ return inTaskStoreScope(cwd, async (cwd) => {
352
+ await getDb(cwd);
353
+ const nativeDb = getNativeDb(cwd);
354
+ if (!nativeDb)
355
+ return [];
356
+ const result = nativeDb
357
+ .prepare(`
347
358
  WITH RECURSIVE blocker_chain(id) AS (
348
359
  SELECT depends_on FROM tasks_task_dependencies WHERE task_id = ?
349
360
  UNION
@@ -352,86 +363,105 @@ export async function getBlockerChain(taskId, cwd) {
352
363
  )
353
364
  SELECT id FROM blocker_chain
354
365
  `)
355
- .all(taskId);
356
- return result.map((r) => r.id);
366
+ .all(taskId);
367
+ return result.map((r) => r.id);
368
+ });
357
369
  }
358
370
  /** Get children of a task (hierarchy). */
359
371
  export async function getChildren(parentId, cwd) {
360
- const db = await getDb(cwd);
361
- const rows = await db
362
- .select()
363
- .from(schema.tasks)
364
- .where(eq(schema.tasks.parentId, parentId))
365
- .orderBy(asc(schema.tasks.position), asc(schema.tasks.createdAt))
366
- .all();
367
- return rows.map(rowToTask);
372
+ return inTaskStoreScope(cwd, async (cwd) => {
373
+ const db = await getDb(cwd);
374
+ const rows = await db
375
+ .select()
376
+ .from(schema.tasks)
377
+ .where(eq(schema.tasks.parentId, parentId))
378
+ .orderBy(asc(schema.tasks.position), asc(schema.tasks.createdAt))
379
+ .all();
380
+ return rows.map(rowToTask);
381
+ });
368
382
  }
369
383
  /** Build a tree from a root task using recursive CTE. */
370
384
  export async function getSubtree(rootId, cwd) {
371
- await getDb(cwd);
372
- const nativeDb = getNativeDb(cwd);
373
- if (!nativeDb)
374
- return [];
375
- const rows = nativeDb
376
- .prepare(`
385
+ return inTaskStoreScope(cwd, async (cwd) => {
386
+ await getDb(cwd);
387
+ const nativeDb = getNativeDb(cwd);
388
+ if (!nativeDb)
389
+ return [];
390
+ const rows = nativeDb
391
+ .prepare(`
392
+ -- T12307: UNION, not UNION ALL — see getAncestorChain in
393
+ -- sqlite-data-accessor.ts. A self-parented row recurses forever under
394
+ -- UNION ALL; every column repeats verbatim on a revisit, so the dedupe
395
+ -- terminates it without dropping any legitimate descendant.
377
396
  WITH RECURSIVE subtree AS (
378
397
  SELECT * FROM tasks_tasks WHERE id = ?
379
- UNION ALL
398
+ UNION
380
399
  SELECT t.* FROM tasks_tasks t
381
400
  JOIN subtree s ON t.parent_id = s.id
382
401
  )
383
402
  SELECT * FROM subtree
384
403
  `)
385
- .all(rootId);
386
- return rows.map(rowToTask);
404
+ .all(rootId);
405
+ return rows.map(rowToTask);
406
+ });
387
407
  }
388
408
  /** Count tasks by status. */
389
409
  export async function countByStatus(cwd) {
390
- const db = await getDb(cwd);
391
- const rows = await db
392
- .select({
393
- status: schema.tasks.status,
394
- count: count(),
395
- })
396
- .from(schema.tasks)
397
- .where(ne(schema.tasks.status, 'archived'))
398
- .groupBy(schema.tasks.status)
399
- .all();
400
- const result = {};
401
- for (const row of rows) {
402
- result[row.status] = row.count;
403
- }
404
- return result;
410
+ return inTaskStoreScope(cwd, async (cwd) => {
411
+ const db = await getDb(cwd);
412
+ const rows = await db
413
+ .select({
414
+ status: schema.tasks.status,
415
+ count: count(),
416
+ })
417
+ .from(schema.tasks)
418
+ .where(ne(schema.tasks.status, 'archived'))
419
+ .groupBy(schema.tasks.status)
420
+ .all();
421
+ const result = {};
422
+ for (const row of rows) {
423
+ result[row.status] = row.count;
424
+ }
425
+ return result;
426
+ });
405
427
  }
406
428
  /** Get total task count (excluding archived). */
407
429
  export async function countTasks(cwd) {
408
- const db = await getDb(cwd);
409
- const result = await db
410
- .select({ count: count() })
411
- .from(schema.tasks)
412
- .where(ne(schema.tasks.status, 'archived'))
413
- .get();
414
- return result?.count ?? 0;
430
+ return inTaskStoreScope(cwd, async (cwd) => {
431
+ const db = await getDb(cwd);
432
+ const result = await db
433
+ .select({ count: count() })
434
+ .from(schema.tasks)
435
+ .where(ne(schema.tasks.status, 'archived'))
436
+ .get();
437
+ return result?.count ?? 0;
438
+ });
415
439
  }
416
440
  /**
417
441
  * Create a task with full safety protections.
418
442
  * Includes: collision detection, write verification, sequence validation, auto-checkpoint.
419
443
  */
420
444
  export async function createTask(task, cwd, config) {
421
- return safeCreateTask(() => insertTaskRow(task, cwd), task, cwd, config);
445
+ return inTaskStoreScope(cwd, async (cwd) => {
446
+ return safeCreateTask(() => insertTaskRow(task, cwd), task, cwd, config);
447
+ });
422
448
  }
423
449
  /**
424
450
  * Update a task with full safety protections.
425
451
  * Includes: write verification, auto-checkpoint.
426
452
  */
427
453
  export async function updateTaskSafe(taskId, updates, cwd, config) {
428
- return safeUpdateTask(() => updateTask(taskId, updates, cwd), taskId, updates, cwd, config);
454
+ return inTaskStoreScope(cwd, async (cwd) => {
455
+ return safeUpdateTask(() => updateTask(taskId, updates, cwd), taskId, updates, cwd, config);
456
+ });
429
457
  }
430
458
  /**
431
459
  * Delete a task with full safety protections.
432
460
  * Includes: delete verification, auto-checkpoint.
433
461
  */
434
462
  export async function deleteTaskSafe(taskId, cwd, config) {
435
- return safeDeleteTask(() => deleteTask(taskId, cwd), taskId, cwd, config);
463
+ return inTaskStoreScope(cwd, async (cwd) => {
464
+ return safeDeleteTask(() => deleteTask(taskId, cwd), taskId, cwd, config);
465
+ });
436
466
  }
437
467
  //# sourceMappingURL=tasks-sqlite.js.map