@cleocode/core 2026.9.21 → 2026.9.23

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 (491) hide show
  1. package/dist/agents/scaffold.d.ts.map +1 -1
  2. package/dist/agents/scaffold.js +0 -1
  3. package/dist/agents/scaffold.js.map +1 -1
  4. package/dist/bootstrap.d.ts.map +1 -1
  5. package/dist/bootstrap.js +4 -0
  6. package/dist/bootstrap.js.map +1 -1
  7. package/dist/build-provenance.json +6 -0
  8. package/dist/decide/audit.d.ts +7 -1
  9. package/dist/decide/audit.d.ts.map +1 -1
  10. package/dist/decide/audit.js.map +1 -1
  11. package/dist/decide/client.d.ts +46 -4
  12. package/dist/decide/client.d.ts.map +1 -1
  13. package/dist/decide/client.js +328 -33
  14. package/dist/decide/client.js.map +1 -1
  15. package/dist/decide/credentials.d.ts +28 -4
  16. package/dist/decide/credentials.d.ts.map +1 -1
  17. package/dist/decide/credentials.js +50 -12
  18. package/dist/decide/credentials.js.map +1 -1
  19. package/dist/decide/index.d.ts +10 -4
  20. package/dist/decide/index.d.ts.map +1 -1
  21. package/dist/decide/index.js +10 -4
  22. package/dist/decide/index.js.map +1 -1
  23. package/dist/decide/jev-wire.d.ts +100 -8
  24. package/dist/decide/jev-wire.d.ts.map +1 -1
  25. package/dist/decide/jev-wire.js +402 -55
  26. package/dist/decide/jev-wire.js.map +1 -1
  27. package/dist/decide/operations.d.ts +97 -20
  28. package/dist/decide/operations.d.ts.map +1 -1
  29. package/dist/decide/operations.js +180 -28
  30. package/dist/decide/operations.js.map +1 -1
  31. package/dist/decide/provider-state.d.ts +89 -0
  32. package/dist/decide/provider-state.d.ts.map +1 -0
  33. package/dist/decide/provider-state.js +134 -0
  34. package/dist/decide/provider-state.js.map +1 -0
  35. package/dist/decide/provider.d.ts +26 -5
  36. package/dist/decide/provider.d.ts.map +1 -1
  37. package/dist/decide/provider.js.map +1 -1
  38. package/dist/decide/providers.d.ts +58 -0
  39. package/dist/decide/providers.d.ts.map +1 -0
  40. package/dist/decide/providers.js +69 -0
  41. package/dist/decide/providers.js.map +1 -0
  42. package/dist/decide/site.d.ts +2 -2
  43. package/dist/decide/site.d.ts.map +1 -1
  44. package/dist/decide/site.js +2 -0
  45. package/dist/decide/site.js.map +1 -1
  46. package/dist/decide/sites/list.d.ts +46 -0
  47. package/dist/decide/sites/list.d.ts.map +1 -0
  48. package/dist/decide/sites/list.js +206 -0
  49. package/dist/decide/sites/list.js.map +1 -0
  50. package/dist/decide/sites/registry.d.ts +130 -0
  51. package/dist/decide/sites/registry.d.ts.map +1 -0
  52. package/dist/decide/sites/registry.js +375 -0
  53. package/dist/decide/sites/registry.js.map +1 -0
  54. package/dist/decide/spend.d.ts +196 -0
  55. package/dist/decide/spend.d.ts.map +1 -0
  56. package/dist/decide/spend.js +387 -0
  57. package/dist/decide/spend.js.map +1 -0
  58. package/dist/decide/wizard.d.ts +53 -0
  59. package/dist/decide/wizard.d.ts.map +1 -0
  60. package/dist/decide/wizard.js +144 -0
  61. package/dist/decide/wizard.js.map +1 -0
  62. package/dist/dispatch/mutate-projection.d.ts.map +1 -1
  63. package/dist/dispatch/mutate-projection.js +5 -0
  64. package/dist/dispatch/mutate-projection.js.map +1 -1
  65. package/dist/docs/docs-audit.d.ts.map +1 -1
  66. package/dist/docs/docs-audit.js +1 -2
  67. package/dist/docs/docs-audit.js.map +1 -1
  68. package/dist/docs/docs-update.d.ts.map +1 -1
  69. package/dist/docs/docs-update.js +25 -9
  70. package/dist/docs/docs-update.js.map +1 -1
  71. package/dist/docs/export-document.js +1073 -628
  72. package/dist/docs/export-document.js.map +3 -3
  73. package/dist/doctor/knowledge.d.ts +16 -1
  74. package/dist/doctor/knowledge.d.ts.map +1 -1
  75. package/dist/doctor/knowledge.js +53 -17
  76. package/dist/doctor/knowledge.js.map +1 -1
  77. package/dist/engine/engine-ops.d.ts +36 -6
  78. package/dist/engine/engine-ops.d.ts.map +1 -1
  79. package/dist/engine/engine-ops.js +115 -14
  80. package/dist/engine/engine-ops.js.map +1 -1
  81. package/dist/gateway-client/generated/types.gen.d.ts +1 -1
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +1 -0
  85. package/dist/index.js.map +1 -1
  86. package/dist/init/scaffold-workflows.d.ts.map +1 -1
  87. package/dist/init/scaffold-workflows.js +6 -3
  88. package/dist/init/scaffold-workflows.js.map +1 -1
  89. package/dist/init/upgrade-workflows.d.ts.map +1 -1
  90. package/dist/init/upgrade-workflows.js +6 -3
  91. package/dist/init/upgrade-workflows.js.map +1 -1
  92. package/dist/init.d.ts.map +1 -1
  93. package/dist/init.js +51 -11
  94. package/dist/init.js.map +1 -1
  95. package/dist/inject/index.d.ts.map +1 -1
  96. package/dist/inject/index.js +8 -3
  97. package/dist/inject/index.js.map +1 -1
  98. package/dist/internal.d.ts +3 -3
  99. package/dist/internal.d.ts.map +1 -1
  100. package/dist/internal.js +2 -2
  101. package/dist/internal.js.map +1 -1
  102. package/dist/llm/plugin-facade.js +1184 -739
  103. package/dist/llm/plugin-facade.js.map +3 -3
  104. package/dist/memory/attention.d.ts.map +1 -1
  105. package/dist/memory/attention.js +2 -2
  106. package/dist/memory/attention.js.map +1 -1
  107. package/dist/memory/decision-contradiction.d.ts +3 -3
  108. package/dist/memory/decision-contradiction.d.ts.map +1 -1
  109. package/dist/memory/decision-contradiction.js +4 -3
  110. package/dist/memory/decision-contradiction.js.map +1 -1
  111. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  112. package/dist/memory/graph-memory-bridge.js +2 -0
  113. package/dist/memory/graph-memory-bridge.js.map +1 -1
  114. package/dist/memory/observation-type-decision.d.ts +2 -2
  115. package/dist/memory/observation-type-decision.d.ts.map +1 -1
  116. package/dist/memory/observation-type-decision.js +3 -2
  117. package/dist/memory/observation-type-decision.js.map +1 -1
  118. package/dist/memory/pipeline-manifest-sqlite.d.ts +111 -0
  119. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  120. package/dist/memory/pipeline-manifest-sqlite.js +230 -2
  121. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  122. package/dist/nexus/analyze-orchestrator.d.ts +38 -0
  123. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  124. package/dist/nexus/analyze-orchestrator.js +96 -21
  125. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  126. package/dist/nexus/knowledge.d.ts.map +1 -1
  127. package/dist/nexus/knowledge.js +15 -4
  128. package/dist/nexus/knowledge.js.map +1 -1
  129. package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
  130. package/dist/nexus/migrations/M-split-graph.js +4 -0
  131. package/dist/nexus/migrations/M-split-graph.js.map +1 -1
  132. package/dist/nexus/store.d.ts.map +1 -1
  133. package/dist/nexus/store.js +2 -0
  134. package/dist/nexus/store.js.map +1 -1
  135. package/dist/nexus/stored-roots.d.ts +65 -0
  136. package/dist/nexus/stored-roots.d.ts.map +1 -1
  137. package/dist/nexus/stored-roots.js +73 -0
  138. package/dist/nexus/stored-roots.js.map +1 -1
  139. package/dist/orchestrate/lifecycle-ops.d.ts.map +1 -1
  140. package/dist/orchestrate/lifecycle-ops.js +4 -1
  141. package/dist/orchestrate/lifecycle-ops.js.map +1 -1
  142. package/dist/orchestrate/pivot.d.ts.map +1 -1
  143. package/dist/orchestrate/pivot.js +13 -8
  144. package/dist/orchestrate/pivot.js.map +1 -1
  145. package/dist/orchestrate/plan.d.ts.map +1 -1
  146. package/dist/orchestrate/plan.js +8 -2
  147. package/dist/orchestrate/plan.js.map +1 -1
  148. package/dist/orchestrate/query-ops.d.ts +7 -2
  149. package/dist/orchestrate/query-ops.d.ts.map +1 -1
  150. package/dist/orchestrate/query-ops.js +17 -6
  151. package/dist/orchestrate/query-ops.js.map +1 -1
  152. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  153. package/dist/orchestrate/spawn-ops.js +5 -14
  154. package/dist/orchestrate/spawn-ops.js.map +1 -1
  155. package/dist/orchestration/bootstrap.d.ts.map +1 -1
  156. package/dist/orchestration/bootstrap.js +4 -2
  157. package/dist/orchestration/bootstrap.js.map +1 -1
  158. package/dist/orchestration/index.d.ts +1 -0
  159. package/dist/orchestration/index.d.ts.map +1 -1
  160. package/dist/orchestration/index.js +4 -3
  161. package/dist/orchestration/index.js.map +1 -1
  162. package/dist/orchestration/lead-rollup.d.ts +8 -5
  163. package/dist/orchestration/lead-rollup.d.ts.map +1 -1
  164. package/dist/orchestration/lead-rollup.js +46 -17
  165. package/dist/orchestration/lead-rollup.js.map +1 -1
  166. package/dist/orchestration/owner-decision-readiness.d.ts +2 -2
  167. package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -1
  168. package/dist/orchestration/owner-decision-readiness.js +3 -2
  169. package/dist/orchestration/owner-decision-readiness.js.map +1 -1
  170. package/dist/orchestration/parallel.d.ts.map +1 -1
  171. package/dist/orchestration/parallel.js +10 -17
  172. package/dist/orchestration/parallel.js.map +1 -1
  173. package/dist/orchestration/spawn-prompt.d.ts +4 -1
  174. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  175. package/dist/orchestration/spawn-prompt.js +3 -2
  176. package/dist/orchestration/spawn-prompt.js.map +1 -1
  177. package/dist/orchestration/status.d.ts +8 -3
  178. package/dist/orchestration/status.d.ts.map +1 -1
  179. package/dist/orchestration/status.js +9 -6
  180. package/dist/orchestration/status.js.map +1 -1
  181. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  182. package/dist/orchestration/validate-spawn.js +2 -0
  183. package/dist/orchestration/validate-spawn.js.map +1 -1
  184. package/dist/orchestration/wave-topic.d.ts +54 -0
  185. package/dist/orchestration/wave-topic.d.ts.map +1 -0
  186. package/dist/orchestration/wave-topic.js +68 -0
  187. package/dist/orchestration/wave-topic.js.map +1 -0
  188. package/dist/orchestration/waves.d.ts +47 -8
  189. package/dist/orchestration/waves.d.ts.map +1 -1
  190. package/dist/orchestration/waves.js +152 -43
  191. package/dist/orchestration/waves.js.map +1 -1
  192. package/dist/phases/index.d.ts.map +1 -1
  193. package/dist/phases/index.js +6 -2
  194. package/dist/phases/index.js.map +1 -1
  195. package/dist/project-scope.d.ts +34 -0
  196. package/dist/project-scope.d.ts.map +1 -1
  197. package/dist/project-scope.js +73 -0
  198. package/dist/project-scope.js.map +1 -1
  199. package/dist/release/ci-evidence.d.ts +10 -0
  200. package/dist/release/ci-evidence.d.ts.map +1 -1
  201. package/dist/release/ci-evidence.js +23 -7
  202. package/dist/release/ci-evidence.js.map +1 -1
  203. package/dist/release/github-pr.d.ts +30 -0
  204. package/dist/release/github-pr.d.ts.map +1 -1
  205. package/dist/release/github-pr.js +42 -1
  206. package/dist/release/github-pr.js.map +1 -1
  207. package/dist/release/plan.d.ts.map +1 -1
  208. package/dist/release/plan.js +6 -3
  209. package/dist/release/plan.js.map +1 -1
  210. package/dist/release/pr-evidence.d.ts.map +1 -1
  211. package/dist/release/pr-evidence.js +12 -4
  212. package/dist/release/pr-evidence.js.map +1 -1
  213. package/dist/routing/capability-matrix.d.ts.map +1 -1
  214. package/dist/routing/capability-matrix.js +7 -0
  215. package/dist/routing/capability-matrix.js.map +1 -1
  216. package/dist/security/input-sanitization.d.ts.map +1 -1
  217. package/dist/security/input-sanitization.js +9 -2
  218. package/dist/security/input-sanitization.js.map +1 -1
  219. package/dist/selfimprove/fix-gen.js +1193 -748
  220. package/dist/selfimprove/fix-gen.js.map +3 -3
  221. package/dist/session/engine-ops.d.ts +6 -0
  222. package/dist/session/engine-ops.d.ts.map +1 -1
  223. package/dist/session/engine-ops.js +36 -4
  224. package/dist/session/engine-ops.js.map +1 -1
  225. package/dist/sessions/briefing.d.ts +17 -0
  226. package/dist/sessions/briefing.d.ts.map +1 -1
  227. package/dist/sessions/briefing.js +68 -68
  228. package/dist/sessions/briefing.js.map +1 -1
  229. package/dist/sessions/drift-watchdog.d.ts.map +1 -1
  230. package/dist/sessions/drift-watchdog.js +4 -3
  231. package/dist/sessions/drift-watchdog.js.map +1 -1
  232. package/dist/sessions/focus-state-store.d.ts +94 -1
  233. package/dist/sessions/focus-state-store.d.ts.map +1 -1
  234. package/dist/sessions/focus-state-store.js +100 -1
  235. package/dist/sessions/focus-state-store.js.map +1 -1
  236. package/dist/sessions/index.d.ts +2 -2
  237. package/dist/sessions/index.d.ts.map +1 -1
  238. package/dist/sessions/index.js +1 -1
  239. package/dist/sessions/index.js.map +1 -1
  240. package/dist/sessions/session-drift.d.ts.map +1 -1
  241. package/dist/sessions/session-drift.js +4 -3
  242. package/dist/sessions/session-drift.js.map +1 -1
  243. package/dist/setup/config-json-merge.d.ts +28 -0
  244. package/dist/setup/config-json-merge.d.ts.map +1 -1
  245. package/dist/setup/config-json-merge.js +51 -0
  246. package/dist/setup/config-json-merge.js.map +1 -1
  247. package/dist/setup/index.d.ts +13 -10
  248. package/dist/setup/index.d.ts.map +1 -1
  249. package/dist/setup/index.js +15 -10
  250. package/dist/setup/index.js.map +1 -1
  251. package/dist/setup/sections/llm.js +1 -1
  252. package/dist/setup/sections/llm.js.map +1 -1
  253. package/dist/setup/sections/system-one.d.ts +28 -0
  254. package/dist/setup/sections/system-one.d.ts.map +1 -0
  255. package/dist/setup/sections/system-one.js +53 -0
  256. package/dist/setup/sections/system-one.js.map +1 -0
  257. package/dist/setup/wizard.d.ts +15 -1
  258. package/dist/setup/wizard.d.ts.map +1 -1
  259. package/dist/setup/wizard.js +15 -0
  260. package/dist/setup/wizard.js.map +1 -1
  261. package/dist/skills/discovery.d.ts +12 -1
  262. package/dist/skills/discovery.d.ts.map +1 -1
  263. package/dist/skills/discovery.js +27 -2
  264. package/dist/skills/discovery.js.map +1 -1
  265. package/dist/skills/orchestrator/startup.d.ts.map +1 -1
  266. package/dist/skills/orchestrator/startup.js +10 -5
  267. package/dist/skills/orchestrator/startup.js.map +1 -1
  268. package/dist/skills/prune-bundled.d.ts +306 -0
  269. package/dist/skills/prune-bundled.d.ts.map +1 -0
  270. package/dist/skills/prune-bundled.js +652 -0
  271. package/dist/skills/prune-bundled.js.map +1 -0
  272. package/dist/skills/types.d.ts +9 -1
  273. package/dist/skills/types.d.ts.map +1 -1
  274. package/dist/skills/types.js +17 -34
  275. package/dist/skills/types.js.map +1 -1
  276. package/dist/spawn/branch-lock.d.ts.map +1 -1
  277. package/dist/spawn/branch-lock.js +26 -2
  278. package/dist/spawn/branch-lock.js.map +1 -1
  279. package/dist/stats/index.d.ts.map +1 -1
  280. package/dist/stats/index.js +4 -2
  281. package/dist/stats/index.js.map +1 -1
  282. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  283. package/dist/store/agent-registry-accessor.js +2 -0
  284. package/dist/store/agent-registry-accessor.js.map +1 -1
  285. package/dist/store/backup-pack.js +1 -1
  286. package/dist/store/backup-pack.js.map +1 -1
  287. package/dist/store/backup.d.ts +15 -1
  288. package/dist/store/backup.d.ts.map +1 -1
  289. package/dist/store/backup.js +18 -2
  290. package/dist/store/backup.js.map +1 -1
  291. package/dist/store/conduit-sqlite.d.ts.map +1 -1
  292. package/dist/store/conduit-sqlite.js +3 -0
  293. package/dist/store/conduit-sqlite.js.map +1 -1
  294. package/dist/store/credential-transfer.d.ts.map +1 -1
  295. package/dist/store/credential-transfer.js +2 -0
  296. package/dist/store/credential-transfer.js.map +1 -1
  297. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  298. package/dist/store/cross-db-cleanup.js +2 -0
  299. package/dist/store/cross-db-cleanup.js.map +1 -1
  300. package/dist/store/dual-scope-db.d.ts.map +1 -1
  301. package/dist/store/dual-scope-db.js +13 -2
  302. package/dist/store/dual-scope-db.js.map +1 -1
  303. package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
  304. package/dist/store/migrate-signaldock-to-conduit.js +3 -0
  305. package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
  306. package/dist/store/migration-manager.d.ts.map +1 -1
  307. package/dist/store/migration-manager.js +37 -3
  308. package/dist/store/migration-manager.js.map +1 -1
  309. package/dist/store/migration-sqlite.d.ts.map +1 -1
  310. package/dist/store/migration-sqlite.js +2 -0
  311. package/dist/store/migration-sqlite.js.map +1 -1
  312. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  313. package/dist/store/nexus-sqlite.js +3 -0
  314. package/dist/store/nexus-sqlite.js.map +1 -1
  315. package/dist/store/open-cleo-db.d.ts.map +1 -1
  316. package/dist/store/open-cleo-db.js +3 -0
  317. package/dist/store/open-cleo-db.js.map +1 -1
  318. package/dist/store/portable-bundle-import.d.ts.map +1 -1
  319. package/dist/store/portable-bundle-import.js +2 -0
  320. package/dist/store/portable-bundle-import.js.map +1 -1
  321. package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
  322. package/dist/store/portable-bundle-relocate.js +2 -0
  323. package/dist/store/portable-bundle-relocate.js.map +1 -1
  324. package/dist/store/portable-bundle-scan.js +1 -1
  325. package/dist/store/portable-bundle-scan.js.map +1 -1
  326. package/dist/store/ports/domain-binding.d.ts.map +1 -1
  327. package/dist/store/ports/domain-binding.js +5 -0
  328. package/dist/store/ports/domain-binding.js.map +1 -1
  329. package/dist/store/skills-db.d.ts +17 -0
  330. package/dist/store/skills-db.d.ts.map +1 -1
  331. package/dist/store/skills-db.js +30 -0
  332. package/dist/store/skills-db.js.map +1 -1
  333. package/dist/store/snapshot-gate.d.ts.map +1 -1
  334. package/dist/store/snapshot-gate.js +3 -0
  335. package/dist/store/snapshot-gate.js.map +1 -1
  336. package/dist/store/split-brain-import.d.ts.map +1 -1
  337. package/dist/store/split-brain-import.js +2 -0
  338. package/dist/store/split-brain-import.js.map +1 -1
  339. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  340. package/dist/store/sqlite-data-accessor.js +19 -2
  341. package/dist/store/sqlite-data-accessor.js.map +1 -1
  342. package/dist/store/sqlite-native.d.ts.map +1 -1
  343. package/dist/store/sqlite-native.js +1 -0
  344. package/dist/store/sqlite-native.js.map +1 -1
  345. package/dist/store/sqlite.d.ts +14 -0
  346. package/dist/store/sqlite.d.ts.map +1 -1
  347. package/dist/store/sqlite.js +31 -4
  348. package/dist/store/sqlite.js.map +1 -1
  349. package/dist/store/twin-collapse.d.ts +46 -1
  350. package/dist/store/twin-collapse.d.ts.map +1 -1
  351. package/dist/store/twin-collapse.js +131 -5
  352. package/dist/store/twin-collapse.js.map +1 -1
  353. package/dist/store/worktree-build-guard.d.ts +191 -0
  354. package/dist/store/worktree-build-guard.d.ts.map +1 -0
  355. package/dist/store/worktree-build-guard.js +486 -0
  356. package/dist/store/worktree-build-guard.js.map +1 -0
  357. package/dist/store/worktree-isolation-guard.d.ts +27 -0
  358. package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
  359. package/dist/store/worktree-isolation-guard.js +71 -3
  360. package/dist/store/worktree-isolation-guard.js.map +1 -1
  361. package/dist/store/writer-lease.d.ts.map +1 -1
  362. package/dist/store/writer-lease.js +2 -0
  363. package/dist/store/writer-lease.js.map +1 -1
  364. package/dist/system/backup.d.ts +6 -2
  365. package/dist/system/backup.d.ts.map +1 -1
  366. package/dist/system/backup.js +6 -3
  367. package/dist/system/backup.js.map +1 -1
  368. package/dist/system/inject-generate.d.ts.map +1 -1
  369. package/dist/system/inject-generate.js +4 -4
  370. package/dist/system/inject-generate.js.map +1 -1
  371. package/dist/task-tools/index.d.ts +4 -2
  372. package/dist/task-tools/index.d.ts.map +1 -1
  373. package/dist/task-tools/index.js +3 -2
  374. package/dist/task-tools/index.js.map +1 -1
  375. package/dist/task-tools/score-task-priority.d.ts +93 -18
  376. package/dist/task-tools/score-task-priority.d.ts.map +1 -1
  377. package/dist/task-tools/score-task-priority.js +193 -81
  378. package/dist/task-tools/score-task-priority.js.map +1 -1
  379. package/dist/task-work/index.d.ts +6 -0
  380. package/dist/task-work/index.d.ts.map +1 -1
  381. package/dist/task-work/index.js +6 -3
  382. package/dist/task-work/index.js.map +1 -1
  383. package/dist/tasks/affected-packages.d.ts +62 -13
  384. package/dist/tasks/affected-packages.d.ts.map +1 -1
  385. package/dist/tasks/affected-packages.js +158 -33
  386. package/dist/tasks/affected-packages.js.map +1 -1
  387. package/dist/tasks/affected-scope.d.ts +59 -0
  388. package/dist/tasks/affected-scope.d.ts.map +1 -0
  389. package/dist/tasks/affected-scope.js +81 -0
  390. package/dist/tasks/affected-scope.js.map +1 -0
  391. package/dist/tasks/analyze.d.ts +29 -1
  392. package/dist/tasks/analyze.d.ts.map +1 -1
  393. package/dist/tasks/analyze.js +52 -36
  394. package/dist/tasks/analyze.js.map +1 -1
  395. package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
  396. package/dist/tasks/backfill-child-projections.js +4 -1
  397. package/dist/tasks/backfill-child-projections.js.map +1 -1
  398. package/dist/tasks/change-set.d.ts +24 -0
  399. package/dist/tasks/change-set.d.ts.map +1 -1
  400. package/dist/tasks/change-set.js +143 -11
  401. package/dist/tasks/change-set.js.map +1 -1
  402. package/dist/tasks/command-line.d.ts +54 -0
  403. package/dist/tasks/command-line.d.ts.map +1 -0
  404. package/dist/tasks/command-line.js +151 -0
  405. package/dist/tasks/command-line.js.map +1 -0
  406. package/dist/tasks/complete.d.ts +10 -0
  407. package/dist/tasks/complete.d.ts.map +1 -1
  408. package/dist/tasks/complete.js +49 -0
  409. package/dist/tasks/complete.js.map +1 -1
  410. package/dist/tasks/component-pr.d.ts +106 -0
  411. package/dist/tasks/component-pr.d.ts.map +1 -0
  412. package/dist/tasks/component-pr.js +275 -0
  413. package/dist/tasks/component-pr.js.map +1 -0
  414. package/dist/tasks/delete.d.ts.map +1 -1
  415. package/dist/tasks/delete.js +20 -0
  416. package/dist/tasks/delete.js.map +1 -1
  417. package/dist/tasks/done-plan.d.ts +21 -1
  418. package/dist/tasks/done-plan.d.ts.map +1 -1
  419. package/dist/tasks/done-plan.js +170 -15
  420. package/dist/tasks/done-plan.js.map +1 -1
  421. package/dist/tasks/done-record.d.ts.map +1 -1
  422. package/dist/tasks/done-record.js +9 -80
  423. package/dist/tasks/done-record.js.map +1 -1
  424. package/dist/tasks/duplicate-detector.d.ts +3 -3
  425. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  426. package/dist/tasks/duplicate-detector.js +4 -3
  427. package/dist/tasks/duplicate-detector.js.map +1 -1
  428. package/dist/tasks/engine-wrap-ops.d.ts +29 -0
  429. package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
  430. package/dist/tasks/engine-wrap-ops.js +40 -0
  431. package/dist/tasks/engine-wrap-ops.js.map +1 -1
  432. package/dist/tasks/engine-wrap.d.ts +1 -1
  433. package/dist/tasks/engine-wrap.d.ts.map +1 -1
  434. package/dist/tasks/engine-wrap.js +1 -1
  435. package/dist/tasks/engine-wrap.js.map +1 -1
  436. package/dist/tasks/evidence.d.ts +49 -2
  437. package/dist/tasks/evidence.d.ts.map +1 -1
  438. package/dist/tasks/evidence.js +85 -9
  439. package/dist/tasks/evidence.js.map +1 -1
  440. package/dist/tasks/gate-runner.d.ts.map +1 -1
  441. package/dist/tasks/gate-runner.js +48 -12
  442. package/dist/tasks/gate-runner.js.map +1 -1
  443. package/dist/tasks/index.d.ts +1 -1
  444. package/dist/tasks/index.d.ts.map +1 -1
  445. package/dist/tasks/index.js +1 -1
  446. package/dist/tasks/index.js.map +1 -1
  447. package/dist/tasks/ops.d.ts +1 -0
  448. package/dist/tasks/ops.d.ts.map +1 -1
  449. package/dist/tasks/ranking-audit.d.ts +122 -0
  450. package/dist/tasks/ranking-audit.d.ts.map +1 -0
  451. package/dist/tasks/ranking-audit.js +193 -0
  452. package/dist/tasks/ranking-audit.js.map +1 -0
  453. package/dist/tasks/task-analyze.d.ts.map +1 -1
  454. package/dist/tasks/task-analyze.js +19 -32
  455. package/dist/tasks/task-analyze.js.map +1 -1
  456. package/dist/tasks/task-next.d.ts +48 -2
  457. package/dist/tasks/task-next.d.ts.map +1 -1
  458. package/dist/tasks/task-next.js +84 -102
  459. package/dist/tasks/task-next.js.map +1 -1
  460. package/dist/tasks/task-ops.d.ts +1 -1
  461. package/dist/tasks/task-ops.d.ts.map +1 -1
  462. package/dist/tasks/task-ops.js +1 -1
  463. package/dist/tasks/task-ops.js.map +1 -1
  464. package/dist/tasks/tool-resolver.d.ts +7 -1
  465. package/dist/tasks/tool-resolver.d.ts.map +1 -1
  466. package/dist/tasks/tool-resolver.js +24 -10
  467. package/dist/tasks/tool-resolver.js.map +1 -1
  468. package/dist/tasks/update.d.ts +8 -2
  469. package/dist/tasks/update.d.ts.map +1 -1
  470. package/dist/tasks/update.js +28 -1
  471. package/dist/tasks/update.js.map +1 -1
  472. package/dist/telemetry/sqlite.d.ts.map +1 -1
  473. package/dist/telemetry/sqlite.js +2 -0
  474. package/dist/telemetry/sqlite.js.map +1 -1
  475. package/dist/validation/doctor/checks.d.ts.map +1 -1
  476. package/dist/validation/doctor/checks.js +2 -2
  477. package/dist/validation/doctor/checks.js.map +1 -1
  478. package/dist/validation/engine-ops.d.ts +9 -1
  479. package/dist/validation/engine-ops.d.ts.map +1 -1
  480. package/dist/validation/engine-ops.js +24 -1
  481. package/dist/validation/engine-ops.js.map +1 -1
  482. package/dist/validation/validate-ops.d.ts.map +1 -1
  483. package/dist/validation/validate-ops.js +9 -3
  484. package/dist/validation/validate-ops.js.map +1 -1
  485. package/dist/worktree/worktree-adopt.d.ts.map +1 -1
  486. package/dist/worktree/worktree-adopt.js +5 -2
  487. package/dist/worktree/worktree-adopt.js.map +1 -1
  488. package/package.json +14 -14
  489. package/schemas/config.schema.json +13 -0
  490. package/templates/CLEO-INJECTION.md +1 -1
  491. package/templates/CLEO-REFERENCE.md +5 -1
@@ -102,9 +102,9 @@ function getLogDir() {
102
102
  return currentLogDir;
103
103
  }
104
104
  function closeLogger() {
105
- return new Promise((resolve15) => {
105
+ return new Promise((resolve17) => {
106
106
  if (!rootLogger) {
107
- resolve15();
107
+ resolve17();
108
108
  return;
109
109
  }
110
110
  const logger8 = rootLogger;
@@ -116,7 +116,7 @@ function closeLogger() {
116
116
  rootLogger = null;
117
117
  currentLogDir = null;
118
118
  currentTransport = null;
119
- resolve15();
119
+ resolve17();
120
120
  };
121
121
  logger8.flush(() => {
122
122
  if (transport && typeof transport.end === "function") {
@@ -479,7 +479,7 @@ var init_acceptance_gate_schema = __esm({
479
479
  message: "Result cannot precede input capture"
480
480
  });
481
481
  const executable = ["test", "command", "lint"].includes(result.kind);
482
- if (executable && !binding.invocation)
482
+ if (executable && !binding.invocation && result.result !== "error")
483
483
  context.addIssue({
484
484
  code: "custom",
485
485
  path: ["binding", "invocation"],
@@ -3245,12 +3245,21 @@ var init_operations_registry = __esm({
3245
3245
  gateway: "query",
3246
3246
  domain: "tasks",
3247
3247
  operation: "history",
3248
- description: "Show task work history (time tracked per task)",
3248
+ description: "Show task work history; with taskId, the task audit trail; with ranking, who changed its priority/severity/kind/depends and why (T12693)",
3249
3249
  tier: 1,
3250
3250
  idempotent: true,
3251
3251
  sessionRequired: false,
3252
3252
  requiredParams: [],
3253
- params: []
3253
+ params: [
3254
+ { name: "taskId", type: "string", required: false, description: "Task to show history for" },
3255
+ { name: "limit", type: "number", required: false, description: "Maximum entries" },
3256
+ {
3257
+ name: "ranking",
3258
+ type: "boolean",
3259
+ required: false,
3260
+ description: "Only ranking-input changes (actor, session, reason, before/after)"
3261
+ }
3262
+ ]
3254
3263
  },
3255
3264
  {
3256
3265
  gateway: "query",
@@ -5745,6 +5754,32 @@ var init_operations_registry = __esm({
5745
5754
  ],
5746
5755
  outputSchema: OUTPUT_CONTRACTS["tasks.assignee"]
5747
5756
  },
5757
+ {
5758
+ gateway: "mutate",
5759
+ domain: "tasks",
5760
+ operation: "ranking.revert",
5761
+ description: "tasks.ranking.revert (mutate) \u2014 undo one recorded ranking change (priority/severity/kind/depends) as a new audited change (T12693, D11161)",
5762
+ tier: 1,
5763
+ idempotent: false,
5764
+ sessionRequired: false,
5765
+ requiredParams: ["entryId"],
5766
+ params: [
5767
+ {
5768
+ name: "entryId",
5769
+ type: "string",
5770
+ required: true,
5771
+ description: "ranking_changed audit row id (cleo history ranking <taskId>)",
5772
+ cli: { positional: true }
5773
+ },
5774
+ { name: "reason", type: "string", required: false, description: "Why it is reverted" },
5775
+ {
5776
+ name: "force",
5777
+ type: "boolean",
5778
+ required: false,
5779
+ description: "Revert even though a field changed again since"
5780
+ }
5781
+ ]
5782
+ },
5748
5783
  {
5749
5784
  gateway: "mutate",
5750
5785
  domain: "tasks",
@@ -10668,7 +10703,7 @@ var init_operations_registry = __esm({
10668
10703
  type: "string",
10669
10704
  required: false,
10670
10705
  enum: DOCS_LIFECYCLE_STATUSES,
10671
- description: `Override the new lifecycle status. Defaults to "draft" on every update. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
10706
+ description: `Override the new lifecycle status. Defaults to "draft" on every update. Alone (no file or content) it changes only the lifecycle status. Valid: ${DOCS_LIFECYCLE_STATUSES.join("|")}.`
10672
10707
  },
10673
10708
  {
10674
10709
  name: "dryRun",
@@ -13155,11 +13190,13 @@ var init_evidence_atom_schema = __esm({
13155
13190
  });
13156
13191
  prAtomSchema = z10.object({
13157
13192
  kind: z10.literal("pr"),
13158
- prNumber: z10.number().int().positive("pr atom requires a positive integer PR number")
13193
+ prNumber: z10.number().int().positive("pr atom requires a positive integer PR number"),
13194
+ componentPrNumber: z10.number().int().positive().optional()
13159
13195
  });
13160
13196
  ciAtomSchema = z10.object({
13161
13197
  kind: z10.literal("ci"),
13162
- prNumber: z10.number().int().positive("ci atom requires a positive integer PR number")
13198
+ prNumber: z10.number().int().positive("ci atom requires a positive integer PR number"),
13199
+ componentPrNumber: z10.number().int().positive().optional()
13163
13200
  });
13164
13201
  locDropAtomSchema = z10.object({
13165
13202
  kind: z10.literal("loc-drop"),
@@ -13210,7 +13247,10 @@ var init_evidence_atom_schema = __esm({
13210
13247
  ["commit", "note"],
13211
13248
  ["decision", "files"],
13212
13249
  ["decision", "note"],
13213
- ["pr", "files"]
13250
+ ["pr", "files"],
13251
+ // T12689: a deletion-only PR (no bytes to hash). Contextual validation
13252
+ // accepts this only when every change the PR made is a deletion.
13253
+ ["pr", "note"]
13214
13254
  ]
13215
13255
  },
13216
13256
  testsPassed: { oneOf: [["test-run"], ["tool"], ["ci"]] },
@@ -17124,7 +17164,7 @@ var init_collection_keys = __esm({
17124
17164
 
17125
17165
  // packages/contracts/src/decide.ts
17126
17166
  import { z as z24 } from "zod";
17127
- var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderConfigSchema;
17167
+ var DECISION_QUESTION_TYPES, DECISION_OUTCOME_SOURCES, DECISION_REQUEST_LIMITS, DECISION_PROVIDER_KINDS, decisionQuestionTypeSchema, decisionOutcomeSourceSchema, decisionInstructionsSchema, unitIntervalSchema, decisionStateSchema, noulDecisionQuestionSchema, choiceDecisionQuestionSchema, scoreDecisionQuestionSchema, decisionQuestionSchema, decisionRequestSchema, noulDecisionAnswerSchema, choiceDecisionAnswerSchema, scoreDecisionAnswerSchema, decisionAnswerSchema, decisionOutcomeSchema, decisionProviderKindSchema, decisionProviderConfigSchema;
17128
17168
  var init_decide = __esm({
17129
17169
  "packages/contracts/src/decide.ts"() {
17130
17170
  "use strict";
@@ -17148,6 +17188,7 @@ var init_decide = __esm({
17148
17188
  /** Maximum number of levels on a `score` question's scale. */
17149
17189
  maxScoreLevels: 10
17150
17190
  };
17191
+ DECISION_PROVIDER_KINDS = ["layahost", "jev"];
17151
17192
  decisionQuestionTypeSchema = z24.enum(DECISION_QUESTION_TYPES);
17152
17193
  decisionOutcomeSourceSchema = z24.enum(DECISION_OUTCOME_SOURCES);
17153
17194
  decisionInstructionsSchema = z24.union([z24.string(), z24.record(z24.string(), z24.json())]);
@@ -17185,6 +17226,8 @@ var init_decide = __esm({
17185
17226
  ]);
17186
17227
  decisionRequestSchema = z24.object({
17187
17228
  model: z24.string().min(1).optional(),
17229
+ lang: z24.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/).optional(),
17230
+ cache: z24.boolean().optional(),
17188
17231
  state: decisionStateSchema,
17189
17232
  questions: z24.record(z24.string().min(1), decisionQuestionSchema).refine(
17190
17233
  (questions) => {
@@ -17225,14 +17268,26 @@ var init_decide = __esm({
17225
17268
  requestId: z24.string().min(1).optional(),
17226
17269
  latencyMs: z24.number().nonnegative(),
17227
17270
  costUsd: z24.number().nonnegative().optional(),
17271
+ costMicros: z24.number().int().nonnegative().optional(),
17272
+ balanceMicros: z24.number().int().optional(),
17273
+ checkpoint: z24.string().min(1).optional(),
17228
17274
  inputTokens: z24.number().int().nonnegative().optional()
17229
17275
  });
17276
+ decisionProviderKindSchema = z24.enum(DECISION_PROVIDER_KINDS);
17230
17277
  decisionProviderConfigSchema = z24.object({
17231
- baseUrl: z24.url()
17278
+ baseUrl: z24.url(),
17279
+ provider: decisionProviderKindSchema.optional()
17232
17280
  });
17233
17281
  }
17234
17282
  });
17235
17283
 
17284
+ // packages/contracts/src/decide-sites.ts
17285
+ var init_decide_sites = __esm({
17286
+ "packages/contracts/src/decide-sites.ts"() {
17287
+ "use strict";
17288
+ }
17289
+ });
17290
+
17236
17291
  // packages/contracts/src/task-id.ts
17237
17292
  var init_task_id = __esm({
17238
17293
  "packages/contracts/src/task-id.ts"() {
@@ -17314,6 +17369,7 @@ var init_src = __esm({
17314
17369
  init_caamp_markers();
17315
17370
  init_collection_keys();
17316
17371
  init_decide();
17372
+ init_decide_sites();
17317
17373
  init_task_id();
17318
17374
  }
17319
17375
  });
@@ -18928,6 +18984,37 @@ function linkedWorktreeMainRoot(dir) {
18928
18984
  if (basename2(commonDir) === ".git") return dirname3(commonDir);
18929
18985
  return readCoreWorktree(commonDir);
18930
18986
  }
18987
+ function describeWorktreeOwner(dir) {
18988
+ const mainRoot = linkedWorktreeMainRoot(dir);
18989
+ if (mainRoot === null) {
18990
+ const bare = bareRepositoryOfWorktree(dir);
18991
+ return bare === null ? "owning repository unknown (unreadable gitlink)" : `owning repository ${bare} is a bare git repository with no main checkout to hold a CLEO store; clone it to a regular checkout, run \`cleo init\` there, and create worktrees from that checkout`;
18992
+ }
18993
+ let projectId = null;
18994
+ try {
18995
+ const parsed = JSON.parse(
18996
+ readFileSync3(join5(mainRoot, ".cleo", "project-info.json"), "utf-8")
18997
+ );
18998
+ if (typeof parsed === "object" && parsed !== null && "projectId" in parsed) {
18999
+ const value = parsed.projectId;
19000
+ if (typeof value === "string" && value !== "") projectId = value;
19001
+ }
19002
+ } catch {
19003
+ }
19004
+ return projectId === null ? `owning repository ${mainRoot} (not an initialised CLEO project)` : `owning project ${mainRoot} (projectId ${projectId})`;
19005
+ }
19006
+ function bareRepositoryOfWorktree(dir) {
19007
+ const gitdir = readGitlinkTarget(dir);
19008
+ if (!gitdir || basename2(dirname3(gitdir)) !== "worktrees") return null;
19009
+ const commonDir = dirname3(dirname3(gitdir));
19010
+ try {
19011
+ const config2 = readFileSync3(join5(commonDir, "config"), "utf-8");
19012
+ const core = /^\[core\][^[]*/m.exec(config2)?.[0] ?? "";
19013
+ return /^\s*bare\s*=\s*true\s*$/im.test(core) ? commonDir : null;
19014
+ } catch {
19015
+ return null;
19016
+ }
19017
+ }
18931
19018
  function readCoreWorktree(gitDir) {
18932
19019
  try {
18933
19020
  const config2 = readFileSync3(join5(gitDir, "config"), "utf-8");
@@ -19377,13 +19464,13 @@ function captureWriteFence(input) {
19377
19464
  return writeFence;
19378
19465
  }
19379
19466
  function observeOperation(context, work) {
19380
- return new Promise((resolve15) => {
19467
+ return new Promise((resolve17) => {
19381
19468
  let observed = false;
19382
19469
  const finish = (result) => {
19383
19470
  if (observed) return;
19384
19471
  observed = true;
19385
19472
  context.signal.removeEventListener("abort", abort);
19386
- resolve15(result);
19473
+ resolve17(result);
19387
19474
  };
19388
19475
  const abort = () => {
19389
19476
  const reason = context.signal.reason;
@@ -20017,7 +20104,7 @@ var init_sql = __esm({
20017
20104
  return new SQL([new StringChunk(str)]);
20018
20105
  }
20019
20106
  _sql.raw = raw;
20020
- function join53(chunks, separator) {
20107
+ function join54(chunks, separator) {
20021
20108
  const result = [];
20022
20109
  for (const [i, chunk] of chunks.entries()) {
20023
20110
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -20025,7 +20112,7 @@ var init_sql = __esm({
20025
20112
  }
20026
20113
  return new SQL(result);
20027
20114
  }
20028
- _sql.join = join53;
20115
+ _sql.join = join54;
20029
20116
  function identifier2(value) {
20030
20117
  return new Name(value);
20031
20118
  }
@@ -22040,7 +22127,7 @@ var init_select = __esm({
22040
22127
  const baseTableName = this.tableName;
22041
22128
  const tableName = getTableLikeName(table);
22042
22129
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
22043
- if (typeof tableName === "string" && this.config.joins?.some((join53) => join53.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
22130
+ if (typeof tableName === "string" && this.config.joins?.some((join54) => join54.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
22044
22131
  if (!this.isPartialSelect) {
22045
22132
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
22046
22133
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -23637,7 +23724,7 @@ var init_dialect = __esm({
23637
23724
  if (!joins2) return;
23638
23725
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
23639
23726
  if (!withEntries.length) return;
23640
- return sql.join(withEntries.map(([k, join53]) => {
23727
+ return sql.join(withEntries.map(([k, join54]) => {
23641
23728
  const relation = tableConfig.relations[k];
23642
23729
  const isSingle2 = is(relation, One);
23643
23730
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -23648,7 +23735,7 @@ var init_dialect = __esm({
23648
23735
  table: targetTable,
23649
23736
  mode: isSingle2 ? "first" : "many",
23650
23737
  schema,
23651
- queryConfig: join53,
23738
+ queryConfig: join54,
23652
23739
  tableConfig: schema[relation.targetTableName],
23653
23740
  relationWhere: filter2,
23654
23741
  isNested: true,
@@ -23662,7 +23749,7 @@ var init_dialect = __esm({
23662
23749
  key: k,
23663
23750
  selection: innerQuery.selection,
23664
23751
  isArray: !isSingle2,
23665
- isOptional: (relation.optional ?? false) || join53 !== true && !!join53.where
23752
+ isOptional: (relation.optional ?? false) || join54 !== true && !!join54.where
23666
23753
  });
23667
23754
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
23668
23755
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -24084,7 +24171,7 @@ var init_update = __esm({
24084
24171
  createJoin(joinType) {
24085
24172
  return ((table, on) => {
24086
24173
  const tableName = getTableLikeName(table);
24087
- if (typeof tableName === "string" && this.config.joins.some((join53) => join53.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24174
+ if (typeof tableName === "string" && this.config.joins.some((join54) => join54.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
24088
24175
  if (typeof on === "function") {
24089
24176
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
24090
24177
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -25209,7 +25296,7 @@ async function withWriteRetry(fn, opts = {}) {
25209
25296
  throw contentionErr;
25210
25297
  }
25211
25298
  function sleep(ms) {
25212
- return new Promise((resolve15) => setTimeout(resolve15, ms));
25299
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
25213
25300
  }
25214
25301
  var DEFAULT_MAX_ATTEMPTS, DEFAULT_BASE_DELAY_MS, DEFAULT_JITTER_MS;
25215
25302
  var init_with_retry = __esm({
@@ -25221,9 +25308,250 @@ var init_with_retry = __esm({
25221
25308
  }
25222
25309
  });
25223
25310
 
25311
+ // packages/core/src/store/worktree-build-guard.ts
25312
+ import { existsSync as existsSync5, readFileSync as readFileSync4, realpathSync as realpathSync3 } from "node:fs";
25313
+ import { createRequire } from "node:module";
25314
+ import { dirname as dirname4, isAbsolute as isAbsolute3, join as join7, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
25315
+ import { fileURLToPath } from "node:url";
25316
+ function realOrResolved(path) {
25317
+ try {
25318
+ return realpathSync3(path);
25319
+ } catch {
25320
+ return resolve2(path);
25321
+ }
25322
+ }
25323
+ function isWithin(root, path) {
25324
+ const local = relative2(root, path);
25325
+ return local === "" || !isAbsolute3(local) && local !== ".." && !local.startsWith(`..${sep2}`);
25326
+ }
25327
+ function insideGitCheckout(dir) {
25328
+ let current = dir;
25329
+ for (; ; ) {
25330
+ if (existsSync5(join7(current, ".git"))) return true;
25331
+ const parent = dirname4(current);
25332
+ if (parent === current) return false;
25333
+ current = parent;
25334
+ }
25335
+ }
25336
+ function insideTestSandbox(path) {
25337
+ let dir = dirname4(path);
25338
+ for (; ; ) {
25339
+ if (existsSync5(join7(dir, TEST_SANDBOX_MARKER))) return !insideGitCheckout(dir);
25340
+ const parent = dirname4(dir);
25341
+ if (parent === dir) return false;
25342
+ dir = parent;
25343
+ }
25344
+ }
25345
+ function linkedWorktreeRootOf(path) {
25346
+ let dir = realOrResolved(path);
25347
+ for (; ; ) {
25348
+ if (isGitLinkedCheckout(dir)) return dir;
25349
+ if (existsSync5(join7(dir, ".git"))) return null;
25350
+ const parent = dirname4(dir);
25351
+ if (parent === dir) return null;
25352
+ dir = parent;
25353
+ }
25354
+ }
25355
+ function readBuildProvenance(codePath) {
25356
+ let dir = dirname4(codePath);
25357
+ for (; ; ) {
25358
+ const stamp = join7(dir, "build-provenance.json");
25359
+ if (existsSync5(stamp)) {
25360
+ try {
25361
+ const parsed = JSON.parse(readFileSync4(stamp, "utf8"));
25362
+ if (typeof parsed === "object" && parsed !== null && "linkedWorktree" in parsed) {
25363
+ const value = parsed.linkedWorktree;
25364
+ if (value === null || typeof value === "string") return { linkedWorktree: value };
25365
+ }
25366
+ } catch {
25367
+ }
25368
+ return null;
25369
+ }
25370
+ if (existsSync5(join7(dir, "package.json"))) return null;
25371
+ const parent = dirname4(dir);
25372
+ if (parent === dir) return null;
25373
+ dir = parent;
25374
+ }
25375
+ }
25376
+ function devBuildWorktree(options = {}) {
25377
+ const codePath = options.codePath ?? overrides?.codePath ?? fileURLToPath(import.meta.url);
25378
+ const provenance = options.provenance !== void 0 ? options.provenance : overrides?.provenance !== void 0 ? overrides.provenance : readBuildProvenance(codePath);
25379
+ if (provenance) return provenance.linkedWorktree;
25380
+ if (codePath.split(/[\\/]/).includes("node_modules")) return null;
25381
+ return linkedWorktreeRootOf(codePath);
25382
+ }
25383
+ function schemaWriteRefusal(dbPath, options = {}) {
25384
+ const env = options.env ?? overrides?.env ?? process.env;
25385
+ const buildWorktree = devBuildWorktree(options);
25386
+ if (buildWorktree === null) return null;
25387
+ const store = realOrResolved(dbPath);
25388
+ if (isWithin(realOrResolved(buildWorktree), store)) return null;
25389
+ if (env["VITEST"]) return null;
25390
+ const honourTestSandbox = options.honourTestSandbox ?? overrides?.honourTestSandbox ?? true;
25391
+ if (honourTestSandbox && insideTestSandbox(store)) return null;
25392
+ if (env[ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV] === "1") return null;
25393
+ return `Refusing to change the schema of ${store}: this CLI was built inside the git worktree ${buildWorktree}, and its schema may be unreleased. Run the released \`cleo\` against this store, or opt in with ${ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV}=1 (T12687).`;
25394
+ }
25395
+ function decisionFor(dbPath) {
25396
+ const key = realOrResolved(dbPath);
25397
+ if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
25398
+ return decisions.get(key) ?? null;
25399
+ }
25400
+ function isWorktreeBuildSchemaError(error48) {
25401
+ return error48 instanceof Error && error48.message.includes(E_WORKTREE_BUILD_SCHEMA);
25402
+ }
25403
+ function codes() {
25404
+ if (authorizerCodes) return authorizerCodes;
25405
+ const sqlite = createRequire(import.meta.url)("node:sqlite").constants;
25406
+ authorizerCodes = {
25407
+ sqlite,
25408
+ creates: /* @__PURE__ */ new Map([
25409
+ [sqlite.SQLITE_CREATE_TABLE, "table"],
25410
+ [sqlite.SQLITE_CREATE_VTABLE, "table"],
25411
+ [sqlite.SQLITE_CREATE_INDEX, "index"],
25412
+ [sqlite.SQLITE_CREATE_TRIGGER, "trigger"],
25413
+ [sqlite.SQLITE_CREATE_VIEW, "view"]
25414
+ ]),
25415
+ changes: /* @__PURE__ */ new Set([
25416
+ sqlite.SQLITE_ALTER_TABLE,
25417
+ sqlite.SQLITE_DROP_TABLE,
25418
+ sqlite.SQLITE_DROP_INDEX,
25419
+ sqlite.SQLITE_DROP_TRIGGER,
25420
+ sqlite.SQLITE_DROP_VIEW,
25421
+ sqlite.SQLITE_DROP_VTABLE
25422
+ ])
25423
+ };
25424
+ return authorizerCodes;
25425
+ }
25426
+ function attachRefusal(name15) {
25427
+ if (name15 === "" || name15 === ":memory:") return null;
25428
+ if (typeof name15 !== "string" || /^file:/i.test(name15) || name15.includes("?")) {
25429
+ return UNKNOWN_ATTACH_REFUSAL;
25430
+ }
25431
+ return decisionFor(name15);
25432
+ }
25433
+ function readSchemas(nativeDb) {
25434
+ const schemas = /* @__PURE__ */ new Map();
25435
+ const list = nativeDb.prepare("PRAGMA database_list").all();
25436
+ for (const { name: name15, file: file2 } of list) {
25437
+ if (name15 === "temp") continue;
25438
+ const rows = nativeDb.prepare(`SELECT type, name FROM "${name15.replaceAll('"', '""')}".sqlite_master`).all();
25439
+ schemas.set(name15.toLowerCase(), {
25440
+ refusal: file2 ? decisionFor(file2) : null,
25441
+ // '' = in-memory
25442
+ objects: new Set(rows.map((r) => `${r.type}:${r.name}`))
25443
+ });
25444
+ }
25445
+ return schemas;
25446
+ }
25447
+ function guardActive() {
25448
+ const env = overrides?.env ?? process.env;
25449
+ if (env["VITEST"]) return false;
25450
+ if (overrides) return devBuildWorktree() !== null;
25451
+ if (processBuildWorktree === void 0) processBuildWorktree = devBuildWorktree();
25452
+ return processBuildWorktree !== null;
25453
+ }
25454
+ function installSchemaWriteGuard(nativeDb) {
25455
+ if (!guardActive()) return false;
25456
+ const location = nativeDb.location();
25457
+ const mainRefusal = location ? decisionFor(location) : null;
25458
+ if (typeof nativeDb.setAuthorizer !== "function") {
25459
+ if (mainRefusal) throw new WorktreeBuildSchemaError(mainRefusal);
25460
+ return false;
25461
+ }
25462
+ const state = {
25463
+ schemas: readSchemas(nativeDb),
25464
+ unmappedAttachRefusal: null,
25465
+ stale: false,
25466
+ lastDenied: null
25467
+ };
25468
+ guards.set(nativeDb, state);
25469
+ const { sqlite, creates, changes } = codes();
25470
+ nativeDb.setAuthorizer((action, arg1, arg2, dbName) => {
25471
+ if (action === sqlite.SQLITE_ATTACH) {
25472
+ const refusal2 = attachRefusal(arg1);
25473
+ if (refusal2 && !state.unmappedAttachRefusal) state.unmappedAttachRefusal = refusal2;
25474
+ return sqlite.SQLITE_OK;
25475
+ }
25476
+ if (action === sqlite.SQLITE_DETACH) {
25477
+ state.stale = true;
25478
+ return sqlite.SQLITE_OK;
25479
+ }
25480
+ const createType = creates.get(action);
25481
+ if (createType === void 0 && !changes.has(action)) return sqlite.SQLITE_OK;
25482
+ const schema = ((action === sqlite.SQLITE_ALTER_TABLE ? arg1 : dbName) ?? "main").toLowerCase();
25483
+ if (schema === "temp") return sqlite.SQLITE_OK;
25484
+ const mapped = state.schemas.get(schema);
25485
+ const policy = state.stale ? void 0 : mapped;
25486
+ const refusal = policy ? policy.refusal : (mapped?.refusal ?? null) || state.unmappedAttachRefusal;
25487
+ if (refusal === null) return sqlite.SQLITE_OK;
25488
+ if (createType !== void 0 && policy?.objects.has(`${createType}:${arg1}`)) {
25489
+ return sqlite.SQLITE_OK;
25490
+ }
25491
+ state.lastDenied = {
25492
+ what: createType !== void 0 ? `CREATE ${createType} ${schema}.${arg1}` : `schema change on ${schema}.${(action === sqlite.SQLITE_ALTER_TABLE ? arg2 : arg1) ?? ""}`,
25493
+ refusal
25494
+ };
25495
+ return sqlite.SQLITE_DENY;
25496
+ });
25497
+ return mainRefusal !== null;
25498
+ }
25499
+ function refreshSchemaWriteGuard(nativeDb) {
25500
+ const state = guards.get(nativeDb);
25501
+ if (!state) return;
25502
+ state.schemas = readSchemas(nativeDb);
25503
+ state.unmappedAttachRefusal = null;
25504
+ state.stale = false;
25505
+ }
25506
+ function explainSchemaWriteDenial(nativeDb, error48) {
25507
+ if (!(error48 instanceof Error) || !/not authorized/i.test(error48.message)) return error48;
25508
+ const denied = guards.get(nativeDb)?.lastDenied;
25509
+ if (!denied) return error48;
25510
+ return new WorktreeBuildSchemaError(`${denied.refusal} Denied: ${denied.what}.`);
25511
+ }
25512
+ function pendingMigrations(nativeDb, migrations) {
25513
+ const hasJournal = nativeDb.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '__drizzle_migrations'").get();
25514
+ const applied = hasJournal ? new Set(
25515
+ nativeDb.prepare('SELECT hash FROM main."__drizzle_migrations"').all().map((row) => row.hash)
25516
+ ) : /* @__PURE__ */ new Set();
25517
+ return migrations.filter((m) => !applied.has(m.hash)).map((m) => m.name ?? m.hash);
25518
+ }
25519
+ function assertNoPendingMigrationsForWorktreeBuild(nativeDb, migrations) {
25520
+ const dbPath = nativeDb.location();
25521
+ if (!dbPath) return;
25522
+ const refusal = decisionFor(dbPath);
25523
+ if (refusal === null) return;
25524
+ const pending = pendingMigrations(nativeDb, migrations);
25525
+ if (pending.length === 0) return;
25526
+ throw new WorktreeBuildSchemaError(`${refusal} Pending migrations: ${pending.join(", ")}.`);
25527
+ }
25528
+ var ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV, TEST_SANDBOX_MARKER, E_WORKTREE_BUILD_SCHEMA, overrides, decisions, WorktreeBuildSchemaError, authorizerCodes, guards, UNKNOWN_ATTACH_REFUSAL, processBuildWorktree;
25529
+ var init_worktree_build_guard = __esm({
25530
+ "packages/core/src/store/worktree-build-guard.ts"() {
25531
+ "use strict";
25532
+ init_src();
25533
+ init_errors2();
25534
+ init_project_scope();
25535
+ ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV = "CLEO_ALLOW_WORKTREE_BUILD_MIGRATIONS";
25536
+ TEST_SANDBOX_MARKER = ".cleo-test-sandbox";
25537
+ E_WORKTREE_BUILD_SCHEMA = "E_WORKTREE_BUILD_SCHEMA";
25538
+ overrides = null;
25539
+ decisions = /* @__PURE__ */ new Map();
25540
+ WorktreeBuildSchemaError = class extends CleoError {
25541
+ constructor(message) {
25542
+ super(8 /* CONFIG_ERROR */, `${E_WORKTREE_BUILD_SCHEMA}: ${message}`, {
25543
+ fix: `Use the released \`cleo\` for this store, run the build against a store inside its own worktree, or set ${ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV}=1 to accept the schema change.`
25544
+ });
25545
+ }
25546
+ };
25547
+ guards = /* @__PURE__ */ new WeakMap();
25548
+ UNKNOWN_ATTACH_REFUSAL = "a store was ATTACHed by a bound, computed or URI filename, so this build cannot tell whose store it is; schema changes on unmapped schemas are refused until the guard is refreshed";
25549
+ }
25550
+ });
25551
+
25224
25552
  // packages/core/src/store/migration-manager.ts
25225
- import { copyFileSync, existsSync as existsSync5 } from "node:fs";
25226
- import { dirname as dirname4, join as join7 } from "node:path";
25553
+ import { copyFileSync, existsSync as existsSync6 } from "node:fs";
25554
+ import { dirname as dirname5, join as join8 } from "node:path";
25227
25555
  function stripSqlComments(sql30) {
25228
25556
  return sql30.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
25229
25557
  }
@@ -25262,10 +25590,10 @@ function computeEliminatedTables(migrations) {
25262
25590
  return eliminated;
25263
25591
  }
25264
25592
  function resolveConsolidationCutoverPrefix(migrationsFolder) {
25265
- const parent = dirname4(migrationsFolder);
25593
+ const parent = dirname5(migrationsFolder);
25266
25594
  for (const setName of ["drizzle-cleo-project", "drizzle-cleo-global"]) {
25267
- const folder = join7(parent, setName);
25268
- if (!existsSync5(folder)) continue;
25595
+ const folder = join8(parent, setName);
25596
+ if (!existsSync6(folder)) continue;
25269
25597
  try {
25270
25598
  const consolidation = readMigrationFiles({ migrationsFolder: folder }).find(
25271
25599
  (m) => /-consolidation-cleo-/.test(m.name ?? "")
@@ -25289,7 +25617,7 @@ function tableExists(nativeDb, tableName) {
25289
25617
  }
25290
25618
  function createSafetyBackup(dbPath) {
25291
25619
  const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
25292
- if (!existsSync5(backupPath)) {
25620
+ if (!existsSync6(backupPath)) {
25293
25621
  try {
25294
25622
  copyFileSync(dbPath, backupPath);
25295
25623
  } catch {
@@ -25407,6 +25735,16 @@ function readSiblingMigrationHashes(siblingFolder) {
25407
25735
  return /* @__PURE__ */ new Set();
25408
25736
  }
25409
25737
  }
25738
+ function readSiblingNewestMillis(siblingFolder) {
25739
+ try {
25740
+ return Math.max(
25741
+ 0,
25742
+ ...readMigrationFiles({ migrationsFolder: siblingFolder }).map((m) => m.folderMillis)
25743
+ );
25744
+ } catch {
25745
+ return 0;
25746
+ }
25747
+ }
25410
25748
  function ensureJournalHashUnique(nativeDb) {
25411
25749
  if (!tableExists(nativeDb, "__drizzle_migrations")) return;
25412
25750
  try {
@@ -25455,6 +25793,7 @@ function upgradeSharedJournalFormat(nativeDb, lineageFolders) {
25455
25793
  return { named, unnamed: rows.length - named };
25456
25794
  }
25457
25795
  function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsystem, siblingMigrationsFolders = []) {
25796
+ assertNoPendingMigrationsForWorktreeBuild(nativeDb, readMigrationFiles({ migrationsFolder }));
25458
25797
  const eliminatedTables = computeEliminatedTables(readMigrationFiles({ migrationsFolder }));
25459
25798
  const cutoverPrefix = resolveConsolidationCutoverPrefix(migrationsFolder);
25460
25799
  if (siblingMigrationsFolders.length > 0)
@@ -25486,8 +25825,15 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25486
25825
  knownHashes.add(m);
25487
25826
  }
25488
25827
  }
25489
- const dbEntries = nativeDb.prepare('SELECT id, hash FROM "__drizzle_migrations"').all();
25490
- const orphanedEntries = dbEntries.filter((e) => !knownHashes.has(e.hash));
25828
+ const newestKnownMillis = Math.max(
25829
+ 0,
25830
+ ...localMigrations.map((m) => m.folderMillis),
25831
+ ...siblingMigrationsFolders.filter((folder) => folder !== migrationsFolder).map(readSiblingNewestMillis)
25832
+ );
25833
+ const dbEntries = nativeDb.prepare('SELECT id, hash, created_at FROM "__drizzle_migrations"').all();
25834
+ const orphanedEntries = dbEntries.filter(
25835
+ (e) => !knownHashes.has(e.hash) && !(Number(e.created_at) > newestKnownMillis)
25836
+ );
25491
25837
  const hasOrphanedEntries = orphanedEntries.length > 0;
25492
25838
  if (hasOrphanedEntries) {
25493
25839
  const dbHashes = new Set(dbEntries.map((e) => e.hash));
@@ -25729,6 +26075,8 @@ function sanitizeMigrationStatements(migrations) {
25729
26075
  }
25730
26076
  function migrateSanitized(db, config2) {
25731
26077
  const raw = readMigrationFiles(config2);
26078
+ const client = db.$client;
26079
+ if (client) assertNoPendingMigrationsForWorktreeBuild(client, raw);
25732
26080
  const sanitized = sanitizeMigrationStatements(raw);
25733
26081
  migrateSync(sanitized, db._.session, config2);
25734
26082
  }
@@ -25792,6 +26140,7 @@ var init_migration_manager = __esm({
25792
26140
  init_sqlite_core();
25793
26141
  init_logger();
25794
26142
  init_with_retry();
26143
+ init_worktree_build_guard();
25795
26144
  MAX_MIGRATION_RETRIES = 5;
25796
26145
  MIGRATION_RETRY_BASE_DELAY_MS = 100;
25797
26146
  MIGRATION_RETRY_MAX_DELAY_MS = 2e3;
@@ -25801,13 +26150,13 @@ var init_migration_manager = __esm({
25801
26150
  });
25802
26151
 
25803
26152
  // packages/core/src/store/relocated-store-guard.ts
25804
- import { existsSync as existsSync6, realpathSync as realpathSync3 } from "node:fs";
25805
- import { createRequire } from "node:module";
25806
- import { basename as basename3, dirname as dirname5 } from "node:path";
26153
+ import { existsSync as existsSync7, realpathSync as realpathSync4 } from "node:fs";
26154
+ import { createRequire as createRequire2 } from "node:module";
26155
+ import { basename as basename3, dirname as dirname6 } from "node:path";
25807
26156
  import { readDeclaredProjectIdentity as readDeclaredProjectIdentity2, readPortableProjectId } from "@cleocode/paths";
25808
26157
  function real2(p) {
25809
26158
  try {
25810
- return realpathSync3(p);
26159
+ return realpathSync4(p);
25811
26160
  } catch {
25812
26161
  return p;
25813
26162
  }
@@ -25824,7 +26173,7 @@ function liveElsewhere(globalDbPath, projectId, root) {
25824
26173
  "SELECT project_path AS projectPath FROM nexus_project_registry WHERE project_id = ?"
25825
26174
  ).get(projectId);
25826
26175
  const live = row?.projectPath;
25827
- if (!live || paths.has(live) || !existsSync6(live)) return null;
26176
+ if (!live || paths.has(live) || !existsSync7(live)) return null;
25828
26177
  if (!isStrictlyInsideDir(root, live)) return null;
25829
26178
  return readDeclaredProjectIdentity2(live)?.projectId === projectId ? live : null;
25830
26179
  } catch {
@@ -25838,14 +26187,14 @@ function detectRelocatedRoot(root, globalDbPath) {
25838
26187
  if (tombstone)
25839
26188
  return { projectId: tombstone.projectId, movedTo: tombstone.movedTo, via: "tombstone" };
25840
26189
  const declared = readPortableProjectId(root);
25841
- if (declared.status !== "valid" || !existsSync6(globalDbPath)) return null;
26190
+ if (declared.status !== "valid" || !existsSync7(globalDbPath)) return null;
25842
26191
  const movedTo = liveElsewhere(globalDbPath, declared.projectId, root);
25843
26192
  return movedTo ? { projectId: declared.projectId, movedTo, via: "registry" } : null;
25844
26193
  }
25845
26194
  function assertStoreNotRelocated(dbPath, globalDbPath) {
25846
- if (basename3(dbPath) !== "cleo.db" || basename3(dirname5(dbPath)) !== ".cleo") return;
25847
- if (existsSync6(dbPath) || globalDbPath === dbPath) return;
25848
- const root = dirname5(dirname5(dbPath));
26195
+ if (basename3(dbPath) !== "cleo.db" || basename3(dirname6(dbPath)) !== ".cleo") return;
26196
+ if (existsSync7(dbPath) || globalDbPath === dbPath) return;
26197
+ const root = dirname6(dirname6(dbPath));
25849
26198
  if (_adopted.has(root)) return;
25850
26199
  const moved = detectRelocatedRoot(root, globalDbPath);
25851
26200
  if (moved) throw projectMovedError(root, moved, void 0, moved.via);
@@ -25855,17 +26204,17 @@ var init_relocated_store_guard = __esm({
25855
26204
  "packages/core/src/store/relocated-store-guard.ts"() {
25856
26205
  "use strict";
25857
26206
  init_project_tombstone();
25858
- _require = createRequire(import.meta.url);
26207
+ _require = createRequire2(import.meta.url);
25859
26208
  _adopted = /* @__PURE__ */ new Set();
25860
26209
  }
25861
26210
  });
25862
26211
 
25863
26212
  // packages/core/src/store/resolve-migrations-folder.ts
25864
- import { createRequire as createRequire2 } from "node:module";
25865
- import { dirname as dirname6, join as join8 } from "node:path";
25866
- import { fileURLToPath } from "node:url";
26213
+ import { createRequire as createRequire3 } from "node:module";
26214
+ import { dirname as dirname7, join as join9 } from "node:path";
26215
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
25867
26216
  function coreRootFromEntry(entryPath) {
25868
- return dirname6(dirname6(entryPath));
26217
+ return dirname7(dirname7(entryPath));
25869
26218
  }
25870
26219
  function resolveConsolidatedJournalSiblings(ownSetName) {
25871
26220
  return CONSOLIDATED_JOURNAL_LINEAGES.filter((name15) => name15 !== ownSetName).map(
@@ -25875,14 +26224,14 @@ function resolveConsolidatedJournalSiblings(ownSetName) {
25875
26224
  function resolveCorePackageMigrationsFolder(setName) {
25876
26225
  try {
25877
26226
  const resolved = import.meta.resolve("@cleocode/core", import.meta.url);
25878
- const entryPath = fileURLToPath(resolved);
25879
- return join8(coreRootFromEntry(entryPath), "migrations", setName);
26227
+ const entryPath = fileURLToPath2(resolved);
26228
+ return join9(coreRootFromEntry(entryPath), "migrations", setName);
25880
26229
  } catch {
25881
26230
  }
25882
- const _require7 = createRequire2(import.meta.url);
26231
+ const _require7 = createRequire3(import.meta.url);
25883
26232
  try {
25884
26233
  const entryPath = _require7.resolve("@cleocode/core");
25885
- return join8(coreRootFromEntry(entryPath), "migrations", setName);
26234
+ return join9(coreRootFromEntry(entryPath), "migrations", setName);
25886
26235
  } catch (err) {
25887
26236
  throw new Error(
25888
26237
  `resolveCorePackageMigrationsFolder("${setName}"): cannot locate @cleocode/core from "${import.meta.url}". Ensure @cleocode/core is installed (workspace or npm). Original error: ${err.message}`
@@ -25978,11 +26327,11 @@ var init_sqlite_pragmas = __esm({
25978
26327
  });
25979
26328
 
25980
26329
  // packages/core/src/store/worktree-isolation-guard.ts
25981
- import { basename as basename4, dirname as dirname7, join as join9 } from "node:path";
26330
+ import { basename as basename4, dirname as dirname8, join as join10, resolve as resolve3 } from "node:path";
25982
26331
  function assertStorePathIsNotWorktreeResident(role, dbPath) {
25983
- const cleoDir = dirname7(dbPath);
26332
+ const cleoDir = dirname8(dbPath);
25984
26333
  if (basename4(cleoDir) !== ".cleo") return;
25985
- const projectRoot = dirname7(cleoDir);
26334
+ const projectRoot = dirname8(cleoDir);
25986
26335
  if (!isGitLinkedCheckout(projectRoot)) return;
25987
26336
  if (process.env["CLEO_ALLOW_WORKTREE_DB_CREATE"] === "1") {
25988
26337
  process.stderr.write(
@@ -25991,9 +26340,10 @@ function assertStorePathIsNotWorktreeResident(role, dbPath) {
25991
26340
  );
25992
26341
  return;
25993
26342
  }
26343
+ const owner = describeWorktreeOwner(projectRoot);
25994
26344
  throw new CleoError(
25995
26345
  8 /* CONFIG_ERROR */,
25996
- `E_WT_DB_ISOLATION_VIOLATION: refusing to open '${role}' DB at ${dbPath} \u2014 parent ${projectRoot} is a git worktree (gitlink). DBs must open against the canonical project root.`,
26346
+ `E_WT_DB_ISOLATION_VIOLATION: refusing to open '${role}' DB at ${dbPath} \u2014 parent ${projectRoot} is a git worktree (gitlink); ${owner}. DBs must open against the canonical project root.`,
25997
26347
  {
25998
26348
  fix: `Run from the canonical project root, or make sure the worktree's main repository is an initialised CLEO project so it resolves there. Inspect stranded worktree stores with \`cleo doctor worktree-stores\`. Emergency override (audited): CLEO_ALLOW_WORKTREE_DB_CREATE=1.`
25999
26349
  }
@@ -26006,7 +26356,7 @@ function assertDbPathIsNotWorktreeResident(role, cwd) {
26006
26356
  } catch {
26007
26357
  return;
26008
26358
  }
26009
- assertStorePathIsNotWorktreeResident(role, join9(cleoDir, PROJECT_STORE_FILENAME2));
26359
+ assertStorePathIsNotWorktreeResident(role, join10(cleoDir, PROJECT_STORE_FILENAME2));
26010
26360
  }
26011
26361
  var PROJECT_STORE_FILENAME2;
26012
26362
  var init_worktree_isolation_guard = __esm({
@@ -26026,10 +26376,10 @@ __export(sqlite_native_exports, {
26026
26376
  getDbSyncConstructor: () => getDbSyncConstructor,
26027
26377
  openNativeDatabase: () => openNativeDatabase
26028
26378
  });
26029
- import { realpathSync as realpathSync4 } from "node:fs";
26030
- import { createRequire as createRequire3 } from "node:module";
26379
+ import { realpathSync as realpathSync5 } from "node:fs";
26380
+ import { createRequire as createRequire4 } from "node:module";
26031
26381
  import { tmpdir as tmpdir2 } from "node:os";
26032
- import { delimiter, dirname as dirname8, isAbsolute as isAbsolute3, join as join10, resolve as resolve2, sep as sep2 } from "node:path";
26382
+ import { delimiter, dirname as dirname9, isAbsolute as isAbsolute4, join as join11, resolve as resolve4, sep as sep3 } from "node:path";
26033
26383
  function getDbSyncConstructor() {
26034
26384
  if (_ctor === null) {
26035
26385
  const mod = _require2("node:sqlite");
@@ -26038,19 +26388,19 @@ function getDbSyncConstructor() {
26038
26388
  return _ctor;
26039
26389
  }
26040
26390
  function resolveAbsoluteSafe(p) {
26041
- const abs = isAbsolute3(p) ? p : resolve2(p);
26391
+ const abs = isAbsolute4(p) ? p : resolve4(p);
26042
26392
  try {
26043
- return realpathSync4(abs);
26393
+ return realpathSync5(abs);
26044
26394
  } catch {
26045
26395
  const missingParts = [];
26046
26396
  let cursor = abs;
26047
26397
  while (true) {
26048
- const parent = dirname8(cursor);
26398
+ const parent = dirname9(cursor);
26049
26399
  if (parent === cursor) return abs;
26050
- missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep2) ? 0 : 1)));
26400
+ missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep3) ? 0 : 1)));
26051
26401
  cursor = parent;
26052
26402
  try {
26053
- return join10(realpathSync4(cursor), ...missingParts);
26403
+ return join11(realpathSync5(cursor), ...missingParts);
26054
26404
  } catch {
26055
26405
  }
26056
26406
  }
@@ -26058,7 +26408,7 @@ function resolveAbsoluteSafe(p) {
26058
26408
  }
26059
26409
  function isPathUnder(child, parent) {
26060
26410
  if (child === parent) return true;
26061
- const withSep = parent.endsWith(sep2) ? parent : parent + sep2;
26411
+ const withSep = parent.endsWith(sep3) ? parent : parent + sep3;
26062
26412
  return child.startsWith(withSep);
26063
26413
  }
26064
26414
  function assertVitestSafePath(path) {
@@ -26081,6 +26431,7 @@ function openNativeDatabase(path, options) {
26081
26431
  assertVitestSafePath(path);
26082
26432
  const DatabaseSyncCtor = getDbSyncConstructor();
26083
26433
  const db = new DatabaseSyncCtor(path, {
26434
+ // schema-guard-exempt: the native chokepoint; every writable caller installs the guard
26084
26435
  enableForeignKeyConstraints: true,
26085
26436
  readOnly: options?.readonly ?? false,
26086
26437
  // Default handle-open lock timeout mirrors the SSoT busy_timeout
@@ -26132,7 +26483,7 @@ var init_sqlite_native = __esm({
26132
26483
  "packages/core/src/store/sqlite-native.ts"() {
26133
26484
  "use strict";
26134
26485
  init_sqlite_pragmas();
26135
- _require2 = createRequire3(import.meta.url);
26486
+ _require2 = createRequire4(import.meta.url);
26136
26487
  _ctor = null;
26137
26488
  }
26138
26489
  });
@@ -26206,7 +26557,7 @@ var init_writer_lease_schema = __esm({
26206
26557
  // packages/core/src/store/writer-lease.ts
26207
26558
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
26208
26559
  import { randomUUID } from "node:crypto";
26209
- import { realpathSync as realpathSync5, statSync as statSync2 } from "node:fs";
26560
+ import { realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
26210
26561
  import { resolve as resolvePath } from "node:path";
26211
26562
  function log() {
26212
26563
  if (_log === null) _log = getLogger("writer-lease");
@@ -26296,7 +26647,7 @@ function resolveDbIdentity(db) {
26296
26647
  return identity;
26297
26648
  }
26298
26649
  function sleepAsync(ms) {
26299
- return new Promise((resolve15) => setTimeout(resolve15, Math.max(0, Math.round(ms))));
26650
+ return new Promise((resolve17) => setTimeout(resolve17, Math.max(0, Math.round(ms))));
26300
26651
  }
26301
26652
  function isPidAlive(pid) {
26302
26653
  try {
@@ -26635,7 +26986,7 @@ function assertColdOpenFile(frame) {
26635
26986
  async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
26636
26987
  opts.execution?.assertActive();
26637
26988
  const captured = opts.requiredIdentity;
26638
- const path = realpathSync5(captured.dbPath);
26989
+ const path = realpathSync6(captured.dbPath);
26639
26990
  const identity = statSync2(path, { bigint: true });
26640
26991
  if (captured.scope !== scope || captured.fileDevice !== String(identity.dev) || captured.fileInode !== String(identity.ino)) {
26641
26992
  throw new LeaseUnavailableError(
@@ -26668,6 +27019,7 @@ async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
26668
27019
  }
26669
27020
  const remaining = opts.execution ? Math.max(1, opts.execution.deadlineAt - Date.now()) : ACQUIRE_DEADLINE_MS;
26670
27021
  const owned = openNativeDatabase(path, { timeout: Math.min(ACQUIRE_DEADLINE_MS, remaining) });
27022
+ installSchemaWriteGuard(owned);
26671
27023
  try {
26672
27024
  opts.execution?.assertActive();
26673
27025
  const afterOpen = statSync2(path, { bigint: true });
@@ -26861,6 +27213,7 @@ var init_writer_lease = __esm({
26861
27213
  init_background_ops();
26862
27214
  init_dual_scope_db();
26863
27215
  init_sqlite_native();
27216
+ init_worktree_build_guard();
26864
27217
  init_writer_lease_schema();
26865
27218
  DEFAULT_TTL_MS = 3e4;
26866
27219
  DEFAULT_PRIORITY = 100;
@@ -27403,10 +27756,10 @@ var init_monitor = __esm({
27403
27756
 
27404
27757
  // packages/core/src/resources/supervisor-admit.ts
27405
27758
  import { connect } from "node:net";
27406
- import { join as join11 } from "node:path";
27759
+ import { join as join12 } from "node:path";
27407
27760
  import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
27408
27761
  function resolveSupervisorSocketPath() {
27409
- return process.env.CLEO_SUPERVISOR_SOCKET ?? join11(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
27762
+ return process.env.CLEO_SUPERVISOR_SOCKET ?? join12(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
27410
27763
  }
27411
27764
  async function sendResourceAdmit(socketPath, cls, holderId, budget) {
27412
27765
  const result = await sendLeaseRequest(
@@ -27429,7 +27782,7 @@ async function sendResourceRelease(socketPath, cls, holderId) {
27429
27782
  return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
27430
27783
  }
27431
27784
  function sendLeaseRequest(socketPath, request, expectedKind) {
27432
- return new Promise((resolve15) => {
27785
+ return new Promise((resolve17) => {
27433
27786
  const id = `ra-${process.pid}-${request.kind}`;
27434
27787
  const envelope = LeaseIpcRequestEnvelopeSchema.parse({
27435
27788
  protocol_version: LEASE_IPC_PROTOCOL_VERSION,
@@ -27447,7 +27800,7 @@ function sendLeaseRequest(socketPath, request, expectedKind) {
27447
27800
  settled = true;
27448
27801
  socket.removeAllListeners();
27449
27802
  socket.destroy();
27450
- resolve15(value);
27803
+ resolve17(value);
27451
27804
  };
27452
27805
  const degrade = (reason) => done({ unavailable: true, reason });
27453
27806
  socket.setTimeout(REQUEST_TIMEOUT_MS);
@@ -27518,9 +27871,9 @@ __export(governor_exports, {
27518
27871
  resolveGovernorMode: () => resolveGovernorMode,
27519
27872
  slotFileCount: () => slotFileCount
27520
27873
  });
27521
- import { existsSync as existsSync7, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
27874
+ import { existsSync as existsSync8, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
27522
27875
  import { availableParallelism, totalmem } from "node:os";
27523
- import { join as join12 } from "node:path";
27876
+ import { join as join13 } from "node:path";
27524
27877
  import lockfile from "proper-lockfile";
27525
27878
  function log2() {
27526
27879
  if (_log2 === null) _log2 = getLogger("resource-governor");
@@ -27589,14 +27942,14 @@ function clamp2(lo, v, hi) {
27589
27942
  return Math.max(lo, Math.min(v, hi));
27590
27943
  }
27591
27944
  function governorSlotDir(cls) {
27592
- return join12(getCleoHome(), "locks", `resource-${cls}`);
27945
+ return join13(getCleoHome(), "locks", `resource-${cls}`);
27593
27946
  }
27594
27947
  function ensureSlotFiles(dir, count) {
27595
- if (!existsSync7(dir)) mkdirSync(dir, { recursive: true });
27948
+ if (!existsSync8(dir)) mkdirSync(dir, { recursive: true });
27596
27949
  const paths = [];
27597
27950
  for (let i = 0; i < count; i++) {
27598
- const p = join12(dir, `slot-${i}.lock`);
27599
- if (!existsSync7(p)) writeFileSync3(p, "", { flag: "a" });
27951
+ const p = join13(dir, `slot-${i}.lock`);
27952
+ if (!existsSync8(p)) writeFileSync3(p, "", { flag: "a" });
27600
27953
  paths.push(p);
27601
27954
  }
27602
27955
  return paths;
@@ -27636,7 +27989,7 @@ function shuffledIndices(n) {
27636
27989
  }
27637
27990
  async function countHeldSlots(cls, budget) {
27638
27991
  const dir = governorSlotDir(cls);
27639
- if (!existsSync7(dir)) return 0;
27992
+ if (!existsSync8(dir)) return 0;
27640
27993
  const slots = ensureSlotFiles(dir, budget);
27641
27994
  let held = 0;
27642
27995
  for (const path of slots) {
@@ -27651,7 +28004,7 @@ async function countHeldSlots(cls, budget) {
27651
28004
  }
27652
28005
  function slotFileCount(cls) {
27653
28006
  const dir = governorSlotDir(cls);
27654
- if (!existsSync7(dir)) return 0;
28007
+ if (!existsSync8(dir)) return 0;
27655
28008
  return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
27656
28009
  }
27657
28010
  var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
@@ -27851,11 +28204,11 @@ var init_lock = __esm({
27851
28204
 
27852
28205
  // packages/core/src/store/atomic.ts
27853
28206
  import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
27854
- import { dirname as dirname9 } from "node:path";
28207
+ import { dirname as dirname10 } from "node:path";
27855
28208
  import writeFileAtomic from "write-file-atomic";
27856
28209
  async function atomicWrite(filePath, data, options) {
27857
28210
  try {
27858
- await mkdir(dirname9(filePath), { recursive: true });
28211
+ await mkdir(dirname10(filePath), { recursive: true });
27859
28212
  await writeFileAtomic(filePath, data, {
27860
28213
  encoding: options?.encoding ?? "utf8",
27861
28214
  mode: options?.mode
@@ -27888,7 +28241,7 @@ var init_atomic = __esm({
27888
28241
 
27889
28242
  // packages/core/src/store/backup.ts
27890
28243
  import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
27891
- import { basename as basename5, join as join13 } from "node:path";
28244
+ import { basename as basename5, dirname as dirname11, join as join14 } from "node:path";
27892
28245
  async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
27893
28246
  try {
27894
28247
  await mkdir2(backupDir, { recursive: true });
@@ -27899,14 +28252,14 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
27899
28252
  throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
27900
28253
  }
27901
28254
  for (let i = maxBackups; i >= 1; i--) {
27902
- const current = join13(backupDir, `${fileName}.${i}`);
28255
+ const current = join14(backupDir, `${fileName}.${i}`);
27903
28256
  if (i === maxBackups) {
27904
28257
  try {
27905
28258
  await unlink2(current);
27906
28259
  } catch {
27907
28260
  }
27908
28261
  } else {
27909
- const next = join13(backupDir, `${fileName}.${i + 1}`);
28262
+ const next = join14(backupDir, `${fileName}.${i + 1}`);
27910
28263
  try {
27911
28264
  await stat2(current);
27912
28265
  await fsRename(current, next);
@@ -27914,7 +28267,7 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
27914
28267
  }
27915
28268
  }
27916
28269
  }
27917
- const backupPath = join13(backupDir, `${fileName}.1`);
28270
+ const backupPath = join14(backupDir, `${fileName}.1`);
27918
28271
  await copyFile(filePath, backupPath);
27919
28272
  return backupPath;
27920
28273
  } catch (err) {
@@ -27928,6 +28281,7 @@ var init_backup = __esm({
27928
28281
  "use strict";
27929
28282
  init_src();
27930
28283
  init_errors2();
28284
+ init_worktree_isolation_guard();
27931
28285
  DEFAULT_MAX_BACKUPS = 5;
27932
28286
  }
27933
28287
  });
@@ -28212,7 +28566,7 @@ __export(identity_exports, {
28212
28566
  import { execFile } from "node:child_process";
28213
28567
  import { createHash as createHash2 } from "node:crypto";
28214
28568
  import { readFile as readFile3 } from "node:fs/promises";
28215
- import { join as join14, resolve as resolve3 } from "node:path";
28569
+ import { join as join15, resolve as resolve5 } from "node:path";
28216
28570
  import { promisify } from "node:util";
28217
28571
  import { legacyProjectId } from "@cleocode/paths";
28218
28572
  import { legacyProjectId as legacyProjectId2 } from "@cleocode/paths";
@@ -28220,14 +28574,14 @@ async function findGitRoot(fromPath, execution) {
28220
28574
  execution?.assertActive();
28221
28575
  try {
28222
28576
  const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
28223
- cwd: resolve3(fromPath),
28577
+ cwd: resolve5(fromPath),
28224
28578
  signal: execution?.signal,
28225
28579
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28226
28580
  killSignal: "SIGKILL",
28227
28581
  maxBuffer: 64 * 1024
28228
28582
  });
28229
28583
  execution?.assertActive();
28230
- return resolve3(stdout.trim());
28584
+ return resolve5(stdout.trim());
28231
28585
  } catch {
28232
28586
  execution?.assertActive();
28233
28587
  return null;
@@ -28237,7 +28591,7 @@ async function findGitRemoteUrl(fromPath, execution) {
28237
28591
  execution?.assertActive();
28238
28592
  try {
28239
28593
  const { stdout } = await execFileAsync("git", ["remote", "get-url", "origin"], {
28240
- cwd: resolve3(fromPath),
28594
+ cwd: resolve5(fromPath),
28241
28595
  signal: execution?.signal,
28242
28596
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28243
28597
  killSignal: "SIGKILL",
@@ -28267,7 +28621,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
28267
28621
  try {
28268
28622
  const args = ["--no-replace-objects", "rev-list", "--max-parents=0", "HEAD"];
28269
28623
  const { stdout } = await execFileAsync("git", args, {
28270
- cwd: resolve3(fromPath),
28624
+ cwd: resolve5(fromPath),
28271
28625
  signal: execution?.signal,
28272
28626
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28273
28627
  killSignal: "SIGKILL",
@@ -28290,7 +28644,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
28290
28644
  async function readProjectInfoName(repoRoot, execution) {
28291
28645
  execution?.assertActive();
28292
28646
  try {
28293
- const raw = await readFile3(join14(repoRoot, ".cleo", "project-info.json"), {
28647
+ const raw = await readFile3(join15(repoRoot, ".cleo", "project-info.json"), {
28294
28648
  encoding: "utf8",
28295
28649
  signal: execution?.signal
28296
28650
  });
@@ -28305,7 +28659,7 @@ async function readProjectInfoName(repoRoot, execution) {
28305
28659
  }
28306
28660
  async function projectPathFingerprint(repoPath, execution) {
28307
28661
  execution?.assertActive();
28308
- const realRepoPath = resolve3(repoPath);
28662
+ const realRepoPath = resolve5(repoPath);
28309
28663
  const results = await Promise.allSettled([
28310
28664
  findGitRoot(realRepoPath, execution),
28311
28665
  findGitRemoteUrl(realRepoPath, execution)
@@ -28329,9 +28683,9 @@ async function projectPathFingerprint(repoPath, execution) {
28329
28683
  }
28330
28684
  function computeLegacyAliases(repoPath, additionalPaths) {
28331
28685
  const aliases = /* @__PURE__ */ new Set();
28332
- aliases.add(legacyProjectId(resolve3(repoPath)));
28686
+ aliases.add(legacyProjectId(resolve5(repoPath)));
28333
28687
  for (const p of additionalPaths ?? []) {
28334
- aliases.add(legacyProjectId(resolve3(p)));
28688
+ aliases.add(legacyProjectId(resolve5(p)));
28335
28689
  }
28336
28690
  return [...aliases];
28337
28691
  }
@@ -28365,17 +28719,17 @@ var init_project_identity = __esm({
28365
28719
  });
28366
28720
 
28367
28721
  // packages/core/src/scaffold/ensure-config.ts
28368
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
28369
- import { basename as basename6, dirname as dirname10, join as join15, resolve as resolve4 } from "node:path";
28370
- import { fileURLToPath as fileURLToPath2 } from "node:url";
28722
+ import { existsSync as existsSync9, readFileSync as readFileSync5 } from "node:fs";
28723
+ import { basename as basename6, dirname as dirname12, join as join16, resolve as resolve6 } from "node:path";
28724
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
28371
28725
  function getPackageRoot() {
28372
- const thisFile = fileURLToPath2(import.meta.url);
28373
- return resolve4(dirname10(thisFile), "..", "..");
28726
+ const thisFile = fileURLToPath3(import.meta.url);
28727
+ return resolve6(dirname12(thisFile), "..", "..");
28374
28728
  }
28375
28729
  function getCleoVersion() {
28376
28730
  try {
28377
- const pkgPath = join15(getPackageRoot(), "package.json");
28378
- const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
28731
+ const pkgPath = join16(getPackageRoot(), "package.json");
28732
+ const pkg = JSON.parse(readFileSync5(pkgPath, "utf-8"));
28379
28733
  return pkg.version ?? "0.0.0";
28380
28734
  } catch {
28381
28735
  return "0.0.0";
@@ -28734,25 +29088,25 @@ var init_recovery = __esm({
28734
29088
  // packages/core/src/store/exodus/archive.ts
28735
29089
  import {
28736
29090
  copyFileSync as copyFileSync2,
28737
- existsSync as existsSync9,
29091
+ existsSync as existsSync10,
28738
29092
  mkdirSync as mkdirSync2,
28739
- readFileSync as readFileSync5,
29093
+ readFileSync as readFileSync6,
28740
29094
  renameSync as renameSync3,
28741
29095
  unlinkSync,
28742
29096
  writeFileSync as writeFileSync4
28743
29097
  } from "node:fs";
28744
- import { basename as basename7, dirname as dirname11, join as join16, resolve as resolve5 } from "node:path";
29098
+ import { basename as basename7, dirname as dirname13, join as join17, resolve as resolve7 } from "node:path";
28745
29099
  import { z as z26 } from "zod";
28746
29100
  function scopeBaseDir(scope, cwd, targetDbPath) {
28747
- if (targetDbPath !== void 0) return dirname11(targetDbPath);
29101
+ if (targetDbPath !== void 0) return dirname13(targetDbPath);
28748
29102
  return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
28749
29103
  }
28750
29104
  function exodusArchiveDir(scope, cwd, targetDbPath) {
28751
- return join16(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
29105
+ return join17(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
28752
29106
  }
28753
29107
  function exodusMarkerPath(scope, cwd, targetDbPath) {
28754
29108
  const marker16 = targetDbPath !== void 0 && basename7(targetDbPath) !== "cleo.db" ? `${basename7(targetDbPath)}.${MARKER_FILENAME_BY_SCOPE[scope]}` : MARKER_FILENAME_BY_SCOPE[scope];
28755
- return join16(scopeBaseDir(scope, cwd, targetDbPath), marker16);
29109
+ return join17(scopeBaseDir(scope, cwd, targetDbPath), marker16);
28756
29110
  }
28757
29111
  function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
28758
29112
  let markerPath;
@@ -28762,13 +29116,13 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
28762
29116
  if (targetDbPath) throw error48;
28763
29117
  return false;
28764
29118
  }
28765
- if (!existsSync9(markerPath)) return false;
28766
- const marker16 = markerIdentity.parse(JSON.parse(readFileSync5(markerPath, "utf8")));
29119
+ if (!existsSync10(markerPath)) return false;
29120
+ const marker16 = markerIdentity.parse(JSON.parse(readFileSync6(markerPath, "utf8")));
28767
29121
  if (nativeDb && (!marker16.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker16.databaseIdentity)))
28768
29122
  throw new Error(
28769
29123
  "Exodus completion marker does not certify this database generation; assessment required"
28770
29124
  );
28771
- return marker16.scope === scope && (!targetDbPath || !marker16.targetDbPath || resolve5(marker16.targetDbPath) === resolve5(targetDbPath));
29125
+ return marker16.scope === scope && (!targetDbPath || !marker16.targetDbPath || resolve7(marker16.targetDbPath) === resolve7(targetDbPath));
28772
29126
  }
28773
29127
  function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, databaseIdentity) {
28774
29128
  const markerPath = exodusMarkerPath(scope, cwd, targetDbPath);
@@ -28780,7 +29134,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
28780
29134
  cleoVersion: getCleoVersion(),
28781
29135
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
28782
29136
  archivedSources: [...archivedSources],
28783
- targetDbPath: resolve5(targetDbPath ?? join16(baseDir, "cleo.db")),
29137
+ targetDbPath: resolve7(targetDbPath ?? join17(baseDir, "cleo.db")),
28784
29138
  ...databaseIdentity ? { databaseIdentity } : {}
28785
29139
  };
28786
29140
  const tmpPath = `${markerPath}.tmp`;
@@ -28791,10 +29145,10 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
28791
29145
  }
28792
29146
  function moveFileInto(srcPath, destDir) {
28793
29147
  mkdirSync2(destDir, { recursive: true });
28794
- let dest = join16(destDir, basename7(srcPath));
28795
- if (existsSync9(dest)) {
29148
+ let dest = join17(destDir, basename7(srcPath));
29149
+ if (existsSync10(dest)) {
28796
29150
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
28797
- dest = join16(destDir, `${basename7(srcPath)}.${stamp}`);
29151
+ dest = join17(destDir, `${basename7(srcPath)}.${stamp}`);
28798
29152
  }
28799
29153
  try {
28800
29154
  renameSync3(srcPath, dest);
@@ -28805,14 +29159,14 @@ function moveFileInto(srcPath, destDir) {
28805
29159
  return dest;
28806
29160
  }
28807
29161
  function archiveSourceDb(source, cwd, targetDbPath) {
28808
- if (!existsSync9(source.path)) {
29162
+ if (!existsSync10(source.path)) {
28809
29163
  return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
28810
29164
  }
28811
29165
  const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
28812
29166
  const archivedTo = moveFileInto(source.path, destDir);
28813
29167
  for (const suffix of SIDECAR_SUFFIXES) {
28814
29168
  const sidecar = `${source.path}${suffix}`;
28815
- if (existsSync9(sidecar)) {
29169
+ if (existsSync10(sidecar)) {
28816
29170
  try {
28817
29171
  moveFileInto(sidecar, destDir);
28818
29172
  } catch (err) {
@@ -28860,7 +29214,7 @@ function detectStrandedResidue(sources, cwd) {
28860
29214
  const stranded = [];
28861
29215
  for (const source of sources) {
28862
29216
  if (!markedScopes.has(source.targetScope)) continue;
28863
- if (existsSync9(source.path)) {
29217
+ if (existsSync10(source.path)) {
28864
29218
  stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
28865
29219
  }
28866
29220
  }
@@ -28925,7 +29279,7 @@ __export(open_cleo_db_exports, {
28925
29279
  openCleoDbSnapshot: () => openCleoDbSnapshot,
28926
29280
  validateProjectIdConsistency: () => validateProjectIdConsistency
28927
29281
  });
28928
- import { createRequire as createRequire4 } from "node:module";
29282
+ import { createRequire as createRequire5 } from "node:module";
28929
29283
  function unwrapNativeSqliteDb(db) {
28930
29284
  if (db && typeof db === "object" && "$client" in db) {
28931
29285
  return db.$client ?? db;
@@ -28989,9 +29343,10 @@ async function openCleoDb(role, cwd) {
28989
29343
  }
28990
29344
  function openCleoDbSnapshot(path, options = {}) {
28991
29345
  const { readOnly = true, applyPragmas = true } = options;
28992
- const _require7 = createRequire4(import.meta.url);
29346
+ const _require7 = createRequire5(import.meta.url);
28993
29347
  const { DatabaseSync: DatabaseSyncCtor } = _require7("node:sqlite");
28994
29348
  const db = new DatabaseSyncCtor(path, { readOnly });
29349
+ if (!readOnly) installSchemaWriteGuard(db);
28995
29350
  if (applyPragmas) {
28996
29351
  applyPerfPragmas(db, { enableWal: !readOnly });
28997
29352
  }
@@ -29019,6 +29374,7 @@ var init_open_cleo_db = __esm({
29019
29374
  init_project_info();
29020
29375
  init_dual_scope_db();
29021
29376
  init_sqlite_pragmas();
29377
+ init_worktree_build_guard();
29022
29378
  init_worktree_isolation_guard();
29023
29379
  PROJECT_ID_TRACKING_ROLES = /* @__PURE__ */ new Set(["global"]);
29024
29380
  }
@@ -29358,7 +29714,7 @@ var init_table_name_map = __esm({
29358
29714
  });
29359
29715
 
29360
29716
  // packages/core/src/store/exodus/count-parity.ts
29361
- import { existsSync as existsSync10 } from "node:fs";
29717
+ import { existsSync as existsSync11 } from "node:fs";
29362
29718
  function listTables(db) {
29363
29719
  return db.prepare(
29364
29720
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
@@ -29379,14 +29735,14 @@ function rowCount(db, tableName) {
29379
29735
  function computeCountParity(sources, projectDbPath, globalDbPath) {
29380
29736
  const entries = [];
29381
29737
  let skipped = 0;
29382
- if (!existsSync10(projectDbPath) || !existsSync10(globalDbPath)) {
29738
+ if (!existsSync11(projectDbPath) || !existsSync11(globalDbPath)) {
29383
29739
  return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
29384
29740
  }
29385
29741
  const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
29386
29742
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
29387
29743
  try {
29388
29744
  for (const src of sources) {
29389
- if (!existsSync10(src.path)) continue;
29745
+ if (!existsSync11(src.path)) continue;
29390
29746
  const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
29391
29747
  try {
29392
29748
  for (const legacyTable of listTables(srcSnap.db)) {
@@ -29444,8 +29800,8 @@ var init_count_parity = __esm({
29444
29800
  });
29445
29801
 
29446
29802
  // packages/core/src/store/exodus/plan.ts
29447
- import { existsSync as existsSync11, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
29448
- import { join as join17 } from "node:path";
29803
+ import { existsSync as existsSync12, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
29804
+ import { join as join18 } from "node:path";
29449
29805
  function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
29450
29806
  return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
29451
29807
  }
@@ -29456,33 +29812,33 @@ function buildSourceDescriptors(cwd) {
29456
29812
  // Project-tier — go into consolidated project-scope cleo.db
29457
29813
  {
29458
29814
  name: "tasks",
29459
- path: join17(cleoDir, "tasks.db"),
29815
+ path: join18(cleoDir, "tasks.db"),
29460
29816
  targetScope: "project"
29461
29817
  },
29462
29818
  {
29463
29819
  name: "brain (project)",
29464
- path: join17(cleoDir, "brain.db"),
29820
+ path: join18(cleoDir, "brain.db"),
29465
29821
  targetScope: "project"
29466
29822
  },
29467
29823
  {
29468
29824
  name: "conduit",
29469
- path: join17(cleoDir, "conduit.db"),
29825
+ path: join18(cleoDir, "conduit.db"),
29470
29826
  targetScope: "project"
29471
29827
  },
29472
29828
  // Global-tier — go into consolidated global-scope cleo.db
29473
29829
  {
29474
29830
  name: "nexus",
29475
- path: join17(cleoHome, "nexus.db"),
29831
+ path: join18(cleoHome, "nexus.db"),
29476
29832
  targetScope: "global"
29477
29833
  },
29478
29834
  {
29479
29835
  name: "signaldock",
29480
- path: join17(cleoHome, "signaldock.db"),
29836
+ path: join18(cleoHome, "signaldock.db"),
29481
29837
  targetScope: "global"
29482
29838
  },
29483
29839
  {
29484
29840
  name: "skills",
29485
- path: join17(cleoHome, "skills.db"),
29841
+ path: join18(cleoHome, "skills.db"),
29486
29842
  targetScope: "global"
29487
29843
  }
29488
29844
  ];
@@ -29511,7 +29867,7 @@ function findExistingStaging(cleoDir) {
29511
29867
  const entries = readdirSync3(cleoDir, { withFileTypes: true });
29512
29868
  const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
29513
29869
  if (stagingDirs.length > 0) {
29514
- return join17(cleoDir, stagingDirs[0]);
29870
+ return join18(cleoDir, stagingDirs[0]);
29515
29871
  }
29516
29872
  } catch {
29517
29873
  }
@@ -29527,7 +29883,7 @@ function buildExodusPlan(cwd) {
29527
29883
  const availableBytes = getAvailableBytes(cleoDir);
29528
29884
  const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
29529
29885
  const existingStaging = findExistingStaging(cleoDir);
29530
- const stagingDir = existingStaging ?? join17(cleoDir, deriveStagingDirName());
29886
+ const stagingDir = existingStaging ?? join18(cleoDir, deriveStagingDirName());
29531
29887
  const resumeFromStaging = existingStaging !== null;
29532
29888
  const projectDbPath = resolveDualScopeDbPath("project", cwd);
29533
29889
  const globalDbPath = resolveDualScopeDbPath("global");
@@ -29546,7 +29902,7 @@ function buildExodusPlan(cwd) {
29546
29902
  };
29547
29903
  }
29548
29904
  function sourcesPresent(sources) {
29549
- return sources.some((s) => existsSync11(s.path));
29905
+ return sources.some((s) => existsSync12(s.path));
29550
29906
  }
29551
29907
  var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
29552
29908
  var init_plan2 = __esm({
@@ -29560,18 +29916,18 @@ var init_plan2 = __esm({
29560
29916
  });
29561
29917
 
29562
29918
  // packages/core/src/store/exodus/health.ts
29563
- import { existsSync as existsSync12, statSync as statSync4 } from "node:fs";
29919
+ import { existsSync as existsSync13, statSync as statSync4 } from "node:fs";
29564
29920
  function buildExodusHealth(cwd) {
29565
29921
  const plan = buildExodusPlan(cwd);
29566
- const anyLegacyPresent = plan.sources.some((s) => existsSync12(s.path));
29922
+ const anyLegacyPresent = plan.sources.some((s) => existsSync13(s.path));
29567
29923
  const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
29568
29924
  const consolidatedExistsByScope = {
29569
- project: existsSync12(plan.projectDbPath),
29570
- global: existsSync12(plan.globalDbPath)
29925
+ project: existsSync13(plan.projectDbPath),
29926
+ global: existsSync13(plan.globalDbPath)
29571
29927
  };
29572
29928
  const buildScope = (scope) => {
29573
29929
  const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
29574
- const present = existsSync12(s.path);
29930
+ const present = existsSync13(s.path);
29575
29931
  let bytes = 0;
29576
29932
  if (present) {
29577
29933
  try {
@@ -29923,8 +30279,8 @@ var init_types = __esm({
29923
30279
  });
29924
30280
 
29925
30281
  // packages/core/src/store/backup-sidecar.ts
29926
- import { existsSync as existsSync13, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
29927
- import { join as join18 } from "node:path";
30282
+ import { existsSync as existsSync14, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
30283
+ import { join as join19 } from "node:path";
29928
30284
  function formatBackupTimestamp(d) {
29929
30285
  const pad = (n, len = 2) => String(n).padStart(len, "0");
29930
30286
  return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
@@ -29935,8 +30291,8 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29935
30291
  const ownedPattern = new RegExp(`\\.${escapedType}-`);
29936
30292
  const files = readdirSync4(backupDir).filter((f) => !f.endsWith(".meta.json") && !f.endsWith(".tmp") && ownedPattern.test(f)).map((f) => ({
29937
30293
  name: f,
29938
- path: join18(backupDir, f),
29939
- mtimeMs: statSync5(join18(backupDir, f)).mtimeMs
30294
+ path: join19(backupDir, f),
30295
+ mtimeMs: statSync5(join19(backupDir, f)).mtimeMs
29940
30296
  })).sort((a, b) => a.mtimeMs - b.mtimeMs);
29941
30297
  while (files.length > maxSnapshots) {
29942
30298
  const oldest = files.shift();
@@ -29944,7 +30300,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29944
30300
  try {
29945
30301
  unlinkSync2(oldest.path);
29946
30302
  const metaPath = `${oldest.path}.meta.json`;
29947
- if (existsSync13(metaPath)) unlinkSync2(metaPath);
30303
+ if (existsSync14(metaPath)) unlinkSync2(metaPath);
29948
30304
  } catch {
29949
30305
  }
29950
30306
  }
@@ -29952,7 +30308,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29952
30308
  }
29953
30309
  }
29954
30310
  function writeBackupSidecar(backupDir, sidecar) {
29955
- const dest = join18(backupDir, `${sidecar.backupId}.meta.json`);
30311
+ const dest = join19(backupDir, `${sidecar.backupId}.meta.json`);
29956
30312
  const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
29957
30313
  writeFileSync5(tmp, JSON.stringify(sidecar, null, 2));
29958
30314
  renameSync4(tmp, dest);
@@ -29964,23 +30320,23 @@ var init_backup_sidecar = __esm({
29964
30320
  });
29965
30321
 
29966
30322
  // packages/core/src/store/pre-repair-snapshot.ts
29967
- import { existsSync as existsSync14, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
29968
- import { dirname as dirname12, join as join19 } from "node:path";
30323
+ import { existsSync as existsSync15, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
30324
+ import { dirname as dirname14, join as join20 } from "node:path";
29969
30325
  function writePreRepairSnapshot(nativeDb, dbPath, label) {
29970
30326
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
29971
- const backupDir = join19(dirname12(dbPath), "backups");
30327
+ const backupDir = join20(dirname14(dbPath), "backups");
29972
30328
  mkdirSync3(backupDir, { recursive: true });
29973
- const snapshotPath = join19(backupDir, `cleo-pre-${label}-${stamp}.db`);
30329
+ const snapshotPath = join20(backupDir, `cleo-pre-${label}-${stamp}.db`);
29974
30330
  nativeDb.exec(`VACUUM INTO '${snapshotPath.replace(/'/g, "''")}'`);
29975
30331
  return snapshotPath;
29976
30332
  }
29977
30333
  function existingAncestor(path) {
29978
30334
  let p = path;
29979
- while (!existsSync14(p) && dirname12(p) !== p) p = dirname12(p);
30335
+ while (!existsSync15(p) && dirname14(p) !== p) p = dirname14(p);
29980
30336
  return p;
29981
30337
  }
29982
30338
  function planMigrationSnapshot(nativeDb, dbPath) {
29983
- const backupDir = join19(dirname12(dbPath), "backups", "sqlite");
30339
+ const backupDir = join20(dirname14(dbPath), "backups", "sqlite");
29984
30340
  const pragma = (name15) => Number(nativeDb.prepare(`PRAGMA main.${name15}`).get()[name15] ?? 0);
29985
30341
  const liveBytes = (pragma("page_count") - pragma("freelist_count")) * pragma("page_size");
29986
30342
  let availableBytes = null;
@@ -29992,13 +30348,13 @@ function planMigrationSnapshot(nativeDb, dbPath) {
29992
30348
  }
29993
30349
  const base = `migration-${formatBackupTimestamp(/* @__PURE__ */ new Date())}`;
29994
30350
  let backupId = base;
29995
- for (let n = 2; existsSync14(join19(backupDir, `${backupId}.meta.json`)); n++) {
30351
+ for (let n = 2; existsSync15(join20(backupDir, `${backupId}.meta.json`)); n++) {
29996
30352
  backupId = `${base}-${n}`;
29997
30353
  }
29998
30354
  return {
29999
30355
  backupDir,
30000
30356
  backupId,
30001
- snapshotPath: join19(backupDir, `cleo.db.${backupId}`),
30357
+ snapshotPath: join20(backupDir, `cleo.db.${backupId}`),
30002
30358
  requiredBytes: liveBytes + SNAPSHOT_HEADROOM_BYTES,
30003
30359
  availableBytes
30004
30360
  };
@@ -30238,7 +30594,7 @@ var init_legacy_tasks_lineage = __esm({
30238
30594
 
30239
30595
  // packages/core/src/store/ports/domain-binding.ts
30240
30596
  import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
30241
- import { resolve as resolve6 } from "node:path";
30597
+ import { resolve as resolve8 } from "node:path";
30242
30598
  function getCleoRuntime() {
30243
30599
  if (!_runtime) {
30244
30600
  _runtime = createCleoRuntime();
@@ -30306,6 +30662,8 @@ async function bindAgainst(key, store, establish) {
30306
30662
  () => establish(native, store)
30307
30663
  );
30308
30664
  return { store, native, db };
30665
+ } catch (error48) {
30666
+ throw explainSchemaWriteDenial(native, error48);
30309
30667
  } finally {
30310
30668
  membership.active = false;
30311
30669
  }
@@ -30355,7 +30713,7 @@ async function bindLive(scope, key, dbPath, openStore, establish) {
30355
30713
  );
30356
30714
  }
30357
30715
  async function bindProjectDomain(domain2, cwd, establish) {
30358
- const dbPath = resolve6(resolveDualScopeDbPath("project", cwd));
30716
+ const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
30359
30717
  const row = await bindLive(
30360
30718
  "project",
30361
30719
  bindingKey("project", dbPath, domain2),
@@ -30366,7 +30724,7 @@ async function bindProjectDomain(domain2, cwd, establish) {
30366
30724
  return row;
30367
30725
  }
30368
30726
  async function bindGlobalDomain(domain2, establish, cwd) {
30369
- const dbPath = resolve6(resolveDualScopeDbPath("global"));
30727
+ const dbPath = resolve8(resolveDualScopeDbPath("global"));
30370
30728
  const row = await bindLive(
30371
30729
  "global",
30372
30730
  bindingKey("global", dbPath, domain2),
@@ -30377,7 +30735,7 @@ async function bindGlobalDomain(domain2, establish, cwd) {
30377
30735
  return row;
30378
30736
  }
30379
30737
  async function bindGlobalDomainAtPath(domain2, dbPath, establish) {
30380
- const normalized = resolve6(dbPath);
30738
+ const normalized = resolve8(dbPath);
30381
30739
  const row = await bindLive(
30382
30740
  "global",
30383
30741
  bindingKey("global", normalized, domain2),
@@ -30388,7 +30746,7 @@ async function bindGlobalDomainAtPath(domain2, dbPath, establish) {
30388
30746
  return row;
30389
30747
  }
30390
30748
  function peekDomainAtPath(scope, dbPath, domain2) {
30391
- const row = _bindings.get(bindingKey(scope, resolve6(dbPath), domain2));
30749
+ const row = _bindings.get(bindingKey(scope, resolve8(dbPath), domain2));
30392
30750
  if (!row?.native.isOpen) return null;
30393
30751
  return row;
30394
30752
  }
@@ -30397,12 +30755,12 @@ function releaseDomainBindings(filter2) {
30397
30755
  _bindings.clear();
30398
30756
  return;
30399
30757
  }
30400
- const wantPath = filter2.dbPath === void 0 ? void 0 : resolve6(filter2.dbPath);
30758
+ const wantPath = filter2.dbPath === void 0 ? void 0 : resolve8(filter2.dbPath);
30401
30759
  for (const key of [..._bindings.keys()]) {
30402
- const sep5 = key.indexOf("::");
30760
+ const sep6 = key.indexOf("::");
30403
30761
  const lastSep = key.lastIndexOf("::");
30404
- const scope = key.slice(0, sep5);
30405
- const dbPath = key.slice(sep5 + 2, lastSep);
30762
+ const scope = key.slice(0, sep6);
30763
+ const dbPath = key.slice(sep6 + 2, lastSep);
30406
30764
  const domain2 = key.slice(lastSep + 2);
30407
30765
  if (filter2.scope !== void 0 && scope !== filter2.scope) continue;
30408
30766
  if (wantPath !== void 0 && dbPath !== wantPath) continue;
@@ -30417,7 +30775,7 @@ function boundProjectNative(domain2, cwd) {
30417
30775
  return peekProjectDomain(domain2, cwd)?.native ?? null;
30418
30776
  }
30419
30777
  function peekProjectDomain(domain2, cwd) {
30420
- const dbPath = resolve6(resolveDualScopeDbPath("project", cwd));
30778
+ const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
30421
30779
  const row = _bindings.get(bindingKey("project", dbPath, domain2));
30422
30780
  if (row?.native.isOpen) return row;
30423
30781
  if (cwd !== void 0) return null;
@@ -30432,7 +30790,7 @@ function peekProjectDomain(domain2, cwd) {
30432
30790
  return sole ?? null;
30433
30791
  }
30434
30792
  function peekGlobalDomain(domain2) {
30435
- const dbPath = resolve6(resolveDualScopeDbPath("global"));
30793
+ const dbPath = resolve8(resolveDualScopeDbPath("global"));
30436
30794
  const row = _bindings.get(bindingKey("global", dbPath, domain2));
30437
30795
  if (!row || !row.native.isOpen) return null;
30438
30796
  return row;
@@ -30443,6 +30801,7 @@ var init_domain_binding = __esm({
30443
30801
  "use strict";
30444
30802
  init_project_scope();
30445
30803
  init_dual_scope_db();
30804
+ init_worktree_build_guard();
30446
30805
  _runtime = null;
30447
30806
  _bindings = /* @__PURE__ */ new Map();
30448
30807
  _inflight = /* @__PURE__ */ new Map();
@@ -30453,9 +30812,9 @@ var init_domain_binding = __esm({
30453
30812
 
30454
30813
  // packages/core/src/telemetry/sqlite.ts
30455
30814
  import { mkdirSync as mkdirSync4 } from "node:fs";
30456
- import { dirname as dirname13, join as join20 } from "node:path";
30815
+ import { dirname as dirname15, join as join21 } from "node:path";
30457
30816
  function getTelemetryDbPath() {
30458
- return join20(getCleoHome(), DB_FILENAME);
30817
+ return join21(getCleoHome(), DB_FILENAME);
30459
30818
  }
30460
30819
  function resolveTelemetryMigrationsFolder() {
30461
30820
  return resolveCorePackageMigrationsFolder("drizzle-telemetry");
@@ -30503,8 +30862,9 @@ async function getTelemetryDb() {
30503
30862
  _initPromise = (async () => {
30504
30863
  const dbPath = requestedPath;
30505
30864
  _dbPath = dbPath;
30506
- mkdirSync4(dirname13(dbPath), { recursive: true });
30865
+ mkdirSync4(dirname15(dbPath), { recursive: true });
30507
30866
  const nativeDb = openNativeDatabase(dbPath);
30867
+ installSchemaWriteGuard(nativeDb);
30508
30868
  _nativeDb = nativeDb;
30509
30869
  const db = drizzle({ client: nativeDb });
30510
30870
  runTelemetryMigrations(nativeDb, db);
@@ -30525,6 +30885,7 @@ var init_sqlite2 = __esm({
30525
30885
  init_migration_manager();
30526
30886
  init_resolve_migrations_folder();
30527
30887
  init_sqlite3();
30888
+ init_worktree_build_guard();
30528
30889
  DB_FILENAME = "telemetry.db";
30529
30890
  TELEMETRY_SCHEMA_VERSION = "1.0.0";
30530
30891
  _db = null;
@@ -30535,11 +30896,11 @@ var init_sqlite2 = __esm({
30535
30896
  });
30536
30897
 
30537
30898
  // packages/core/src/store/agent-registry-store.ts
30538
- import { existsSync as existsSync15 } from "node:fs";
30539
- import { join as join21 } from "node:path";
30899
+ import { existsSync as existsSync16 } from "node:fs";
30900
+ import { join as join22 } from "node:path";
30540
30901
  function getGlobalAgentRegistryDbPath() {
30541
30902
  const cleoHome = getCleoHome();
30542
- const dbPath = join21(cleoHome, "cleo.db");
30903
+ const dbPath = join22(cleoHome, "cleo.db");
30543
30904
  if (!dbPath.startsWith(cleoHome)) {
30544
30905
  throw new Error(
30545
30906
  `BUG: getGlobalAgentRegistryDbPath() resolved to "${dbPath}" which is NOT under getCleoHome() ("${cleoHome}"). The Agent Registry is global-only per ADR-037. This indicates a code path that bypasses path resolution \u2014 fix the caller, do not suppress this error.`
@@ -30606,7 +30967,7 @@ function establishAgentRegistrySchema(native) {
30606
30967
  }
30607
30968
  async function ensureGlobalAgentRegistryDb() {
30608
30969
  const dbPath = getGlobalAgentRegistryDbPath();
30609
- const alreadyExists = existsSync15(dbPath);
30970
+ const alreadyExists = existsSync16(dbPath);
30610
30971
  let created = false;
30611
30972
  const { native: nativeDb } = await bindGlobalDomainAtPath(
30612
30973
  AGENT_REGISTRY_DOMAIN,
@@ -30651,8 +31012,8 @@ var init_agent_registry_store = __esm({
30651
31012
  });
30652
31013
 
30653
31014
  // packages/core/src/store/conduit-sqlite.ts
30654
- import { existsSync as existsSync16 } from "node:fs";
30655
- import { createRequire as createRequire5 } from "node:module";
31015
+ import { existsSync as existsSync17 } from "node:fs";
31016
+ import { createRequire as createRequire6 } from "node:module";
30656
31017
  function _getDrizzle() {
30657
31018
  if (_drizzle === null) {
30658
31019
  const mod = _require3("drizzle-orm/node-sqlite");
@@ -30680,7 +31041,7 @@ function runConduitMigrations(nativeDb) {
30680
31041
  }
30681
31042
  async function ensureConduitDb(projectRoot) {
30682
31043
  const dbPath = getConduitDbPath(projectRoot);
30683
- const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync16(dbPath);
31044
+ const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync17(dbPath);
30684
31045
  await bindConduitDomain(projectRoot);
30685
31046
  return { action: alreadyExists ? "exists" : "created", path: dbPath };
30686
31047
  }
@@ -30706,7 +31067,8 @@ var init_conduit_sqlite = __esm({
30706
31067
  init_domain_binding();
30707
31068
  init_resolve_migrations_folder();
30708
31069
  init_sqlite_pragmas();
30709
- _require3 = createRequire5(import.meta.url);
31070
+ init_worktree_build_guard();
31071
+ _require3 = createRequire6(import.meta.url);
30710
31072
  ({ DatabaseSync: DatabaseSync2 } = _require3("node:sqlite"));
30711
31073
  _drizzle = null;
30712
31074
  CONDUIT_SCHEMA_VERSION = "2026.4.23";
@@ -32580,216 +32942,6 @@ var init_memory_schema = __esm({
32580
32942
  }
32581
32943
  });
32582
32944
 
32583
- // packages/core/src/store/snapshot-gate.ts
32584
- import { join as join22 } from "node:path";
32585
- function readGateState(db) {
32586
- const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
32587
- const state = { generation: 0, prefixes: {} };
32588
- if (!row) return state;
32589
- try {
32590
- const parsed = JSON.parse(row.value);
32591
- if (parsed === null || typeof parsed !== "object") return state;
32592
- if (typeof parsed.generation === "number" && Number.isSafeInteger(parsed.generation)) {
32593
- state.generation = parsed.generation;
32594
- }
32595
- for (const [prefix, e] of Object.entries(parsed.prefixes ?? {})) {
32596
- if (e && typeof e.generation === "number" && typeof e.startedAt === "number" && typeof e.completedAt === "number") {
32597
- state.prefixes[prefix] = {
32598
- generation: e.generation,
32599
- startedAt: e.startedAt,
32600
- completedAt: e.completedAt
32601
- };
32602
- }
32603
- }
32604
- } catch {
32605
- }
32606
- return state;
32607
- }
32608
- function writeGateState(db, state) {
32609
- db.prepare(
32610
- "INSERT INTO tasks_schema_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
32611
- ).run(SNAPSHOT_GATE_META_KEY, JSON.stringify(state));
32612
- }
32613
- function tryReadGateState(db) {
32614
- if (!db) return null;
32615
- try {
32616
- return readGateState(db);
32617
- } catch {
32618
- return null;
32619
- }
32620
- }
32621
- function needsSnapshot(entry, mode, nowMs, seenGeneration) {
32622
- if (!entry) return true;
32623
- if (mode === "required") return seenGeneration === null || entry.generation <= seenGeneration;
32624
- const elapsed = nowMs - entry.startedAt;
32625
- return elapsed < 0 || elapsed >= SNAPSHOT_DEBOUNCE_MS;
32626
- }
32627
- async function runGatedSnapshot(opts, snapshot) {
32628
- const now = opts.now ?? Date.now;
32629
- const mode = opts.mode ?? "routine";
32630
- const db = opts.stateDb;
32631
- const none = (skipped, error48) => ({
32632
- snapshotted: [],
32633
- linked: [],
32634
- absent: [],
32635
- failed: [],
32636
- skipped,
32637
- ...error48 !== void 0 && { error: error48 }
32638
- });
32639
- const entryState = tryReadGateState(db);
32640
- const seenGeneration = mode === "required" ? opts.seenGeneration ?? entryState?.generation ?? null : null;
32641
- if (mode === "routine") {
32642
- if (!entryState) return none("state-unavailable");
32643
- const nowMs = now();
32644
- if (!opts.prefixes.some((p) => needsSnapshot(entryState.prefixes[p], mode, nowMs, null))) {
32645
- return none("debounced");
32646
- }
32647
- }
32648
- const lockPath2 = join22(opts.backupDir, GATE_LOCK_BASENAME);
32649
- let release;
32650
- try {
32651
- release = await acquireLock(lockPath2, {
32652
- retries: mode === "required" ? opts.lockWaitRetries ?? SNAPSHOT_LOCK_WAIT_RETRIES : 0,
32653
- stale: SNAPSHOT_LOCK_STALE_MS,
32654
- // A compromised lock (e.g. the backup dir was removed) must not throw
32655
- // from a timer and crash the host process.
32656
- onCompromised: () => {
32657
- }
32658
- });
32659
- } catch {
32660
- if (mode === "routine") return none("in-flight");
32661
- return none(
32662
- "lock-timeout",
32663
- `Snapshot lock ${lockPath2}.lock is still held after waiting. Another snapshot is running, or a crashed process left the lock (it expires after ${SNAPSHOT_LOCK_STALE_MS / 6e4} minutes). Remove it if no snapshot is running.`
32664
- );
32665
- }
32666
- try {
32667
- try {
32668
- opts.onLockAcquired?.();
32669
- } catch {
32670
- }
32671
- const state = tryReadGateState(db);
32672
- if (!state && mode === "routine") return none("state-unavailable");
32673
- const startMs = now();
32674
- const admitted = mode === "required" && opts.alwaysSnapshot === true ? [...opts.prefixes] : opts.prefixes.filter(
32675
- (p) => needsSnapshot(state?.prefixes[p], mode, startMs, seenGeneration)
32676
- );
32677
- if (admitted.length === 0) return none(mode === "routine" ? "debounced" : "covered");
32678
- const generation = (state?.generation ?? 0) + 1;
32679
- let claimed = false;
32680
- if (db && state) {
32681
- try {
32682
- writeGateState(db, { ...state, generation });
32683
- claimed = true;
32684
- } catch {
32685
- }
32686
- }
32687
- const snapshotted = [];
32688
- const linked = [];
32689
- const absent = [];
32690
- const failed = [];
32691
- for (const prefix of admitted) {
32692
- try {
32693
- const outcome = await snapshot(prefix);
32694
- if (outcome === "absent") absent.push(prefix);
32695
- else {
32696
- snapshotted.push(prefix);
32697
- if (outcome === "linked") linked.push(prefix);
32698
- }
32699
- } catch {
32700
- failed.push(prefix);
32701
- }
32702
- }
32703
- const satisfied = [...snapshotted, ...absent];
32704
- if (db && claimed && satisfied.length > 0) {
32705
- try {
32706
- const latest = readGateState(db);
32707
- const completedAt = now();
32708
- latest.generation = Math.max(latest.generation, generation);
32709
- for (const p of satisfied) {
32710
- latest.prefixes[p] = { generation, startedAt: startMs, completedAt };
32711
- }
32712
- writeGateState(db, latest);
32713
- } catch {
32714
- }
32715
- }
32716
- return { snapshotted, linked, absent, failed, skipped: null };
32717
- } finally {
32718
- await release().catch(() => {
32719
- });
32720
- }
32721
- }
32722
- function isValidStamp(ymd, hms) {
32723
- const y = Number(ymd.slice(0, 4));
32724
- const mo = Number(ymd.slice(4, 6));
32725
- const d = Number(ymd.slice(6, 8));
32726
- const h = Number(hms.slice(0, 2));
32727
- const mi = Number(hms.slice(2, 4));
32728
- const se = Number(hms.slice(4, 6));
32729
- if (mo < 1 || mo > 12 || d < 1 || h > 23 || mi > 59 || se > 59) return false;
32730
- const probe = new Date(Date.UTC(y, mo - 1, d));
32731
- return probe.getUTCFullYear() === y && probe.getUTCMonth() === mo - 1 && probe.getUTCDate() === d;
32732
- }
32733
- function selectSnapshotsToKeep(names, ctx = {}) {
32734
- const policy = ctx.policy ?? DEFAULT_SNAPSHOT_RETENTION;
32735
- const keep = /* @__PURE__ */ new Set();
32736
- const stamped = [];
32737
- for (const name15 of names) {
32738
- const m = STAMP_PATTERN.exec(name15);
32739
- const ymd = m?.[1];
32740
- const hms = m?.[2];
32741
- if (!ymd || !hms || !isValidStamp(ymd, hms)) {
32742
- keep.add(name15);
32743
- continue;
32744
- }
32745
- const stamp = `${ymd}-${hms}`;
32746
- if (ctx.nowStamp !== void 0 && stamp > ctx.nowStamp) {
32747
- keep.add(name15);
32748
- continue;
32749
- }
32750
- stamped.push({ name: name15, stamp });
32751
- }
32752
- if (ctx.pinned !== void 0 && names.includes(ctx.pinned)) keep.add(ctx.pinned);
32753
- stamped.sort((a, b) => a.stamp < b.stamp ? 1 : a.stamp > b.stamp ? -1 : 0);
32754
- for (const s of stamped.slice(0, policy.latest)) keep.add(s.name);
32755
- const keepNewestPerBucket = (bucketOf, slots) => {
32756
- const seen = /* @__PURE__ */ new Set();
32757
- for (const s of stamped) {
32758
- const bucket = bucketOf(s.stamp);
32759
- if (seen.has(bucket)) continue;
32760
- if (seen.size >= slots) break;
32761
- seen.add(bucket);
32762
- keep.add(s.name);
32763
- }
32764
- };
32765
- keepNewestPerBucket(
32766
- (stamp) => `${stamp.slice(0, 11)}q${Math.floor(Number(stamp.slice(11, 13)) / 15)}`,
32767
- policy.quarterHourly
32768
- );
32769
- keepNewestPerBucket((stamp) => stamp.slice(0, 11), policy.hourly);
32770
- keepNewestPerBucket((stamp) => stamp.slice(0, 8), policy.daily);
32771
- return keep;
32772
- }
32773
- var SNAPSHOT_DEBOUNCE_MS, SNAPSHOT_LOCK_STALE_MS, SNAPSHOT_LOCK_WAIT_RETRIES, SNAPSHOT_GATE_META_KEY, GATE_LOCK_BASENAME, DEFAULT_SNAPSHOT_RETENTION, STAMP_PATTERN;
32774
- var init_snapshot_gate = __esm({
32775
- "packages/core/src/store/snapshot-gate.ts"() {
32776
- "use strict";
32777
- init_lock();
32778
- SNAPSHOT_DEBOUNCE_MS = 5 * 6e4;
32779
- SNAPSHOT_LOCK_STALE_MS = 10 * 6e4;
32780
- SNAPSHOT_LOCK_WAIT_RETRIES = 90;
32781
- SNAPSHOT_GATE_META_KEY = "sqlite_snapshot_gate";
32782
- GATE_LOCK_BASENAME = ".snapshot-gate";
32783
- DEFAULT_SNAPSHOT_RETENTION = {
32784
- latest: 1,
32785
- quarterHourly: 3,
32786
- hourly: 3,
32787
- daily: 3
32788
- };
32789
- STAMP_PATTERN = /-(\d{8})-(\d{6})\.db$/;
32790
- }
32791
- });
32792
-
32793
32945
  // packages/core/src/store/twin-collapse.ts
32794
32946
  import { createHash as createHash3 } from "node:crypto";
32795
32947
  function hasMainTable(db, name15) {
@@ -32866,6 +33018,22 @@ function mergeSchemaMetaValue(key, bare, twin) {
32866
33018
  const field = SCHEMA_META_COUNTER_FIELDS[key];
32867
33019
  return field === void 0 ? bare : withMaxCounter(bare, twin, field);
32868
33020
  }
33021
+ function mirrorCounterToBare(db, key) {
33022
+ if (SCHEMA_META_COUNTER_FIELDS[key] === void 0) return;
33023
+ if (!hasMainTable(db, "schema_meta")) return;
33024
+ const twin = readKv(db, "tasks_schema_meta", key);
33025
+ if (twin === void 0) return;
33026
+ const bare = readKv(db, "schema_meta", key);
33027
+ const next = bare === void 0 ? twin : mergeSchemaMetaValue(key, bare, twin);
33028
+ if (next === null || next === bare) return;
33029
+ writeKv(db, "schema_meta", key, next);
33030
+ }
33031
+ function bareCounterOf(db, key) {
33032
+ const name15 = SCHEMA_META_COUNTER_FIELDS[key];
33033
+ if (name15 === void 0 || !hasMainTable(db, "schema_meta")) return 0;
33034
+ const bare = readKv(db, "schema_meta", key);
33035
+ return (bare === void 0 ? void 0 : counterOf(bare, name15)) ?? 0;
33036
+ }
32869
33037
  function kvRows(db, table, schema = "main") {
32870
33038
  const rows = db.prepare(`SELECT key, value FROM ${schema}.${table}`).all();
32871
33039
  return new Map(rows.map((r) => [r.key, r.value]));
@@ -32998,6 +33166,39 @@ function applyStickyRows(db, schema, plan) {
32998
33166
  }
32999
33167
  return { inserted, replaced: 0, deleted };
33000
33168
  }
33169
+ function tagsOf(tagsJson) {
33170
+ if (!tagsJson) return [];
33171
+ try {
33172
+ const parsed = JSON.parse(tagsJson);
33173
+ if (!Array.isArray(parsed)) return [];
33174
+ return [...new Set(parsed.filter((t) => typeof t === "string" && t.length > 0))];
33175
+ } catch {
33176
+ return [];
33177
+ }
33178
+ }
33179
+ function syncStickyJunction(db, schema) {
33180
+ const notes = db.prepare("SELECT id, tags_json FROM main.brain_sticky_notes").all();
33181
+ const have = /* @__PURE__ */ new Map();
33182
+ for (const r of db.prepare(`SELECT sticky_id, tag FROM ${schema}.brain_sticky_tags`).all()) {
33183
+ const set2 = have.get(r.sticky_id) ?? /* @__PURE__ */ new Set();
33184
+ set2.add(r.tag);
33185
+ have.set(r.sticky_id, set2);
33186
+ }
33187
+ const insert = db.prepare(
33188
+ `INSERT OR IGNORE INTO ${schema}.brain_sticky_tags (sticky_id, tag) VALUES (?, ?)`
33189
+ );
33190
+ const del = db.prepare(`DELETE FROM ${schema}.brain_sticky_tags WHERE sticky_id = ? AND tag = ?`);
33191
+ let inserted = 0;
33192
+ let deleted = 0;
33193
+ for (const note of notes) {
33194
+ const want = new Set(tagsOf(note.tags_json));
33195
+ const current = have.get(note.id) ?? /* @__PURE__ */ new Set();
33196
+ for (const tag of want)
33197
+ if (!current.has(tag)) inserted += Number(insert.run(note.id, tag).changes);
33198
+ for (const tag of current) if (!want.has(tag)) deleted += Number(del.run(note.id, tag).changes);
33199
+ }
33200
+ return { inserted, deleted };
33201
+ }
33001
33202
  function twinCollapseFailureOf(db) {
33002
33203
  return degraded.get(db);
33003
33204
  }
@@ -33207,7 +33408,7 @@ function collapseTwinTables(nativeDb, dbPath, options = {}) {
33207
33408
  }
33208
33409
  return inOrder();
33209
33410
  }
33210
- var log6, TWIN_COLLAPSE_MARKER_PREFIX, TWIN_COLLAPSE_FAILURE_PREFIX, SCHEMA_META_COUNTER_FIELDS, SCHEMA_META_NEVER_DELETED, MAX_CONFLICTS, sha, ABSENT, hashMap, emptyPlan, SCHEMA_META, hashSets, EMPTY_SET, STICKY_TAGS, PAIRS, degraded, SHADOW_WRITE_REFUSED, SHADOW_WRITE_OPS;
33411
+ var log6, TWIN_COLLAPSE_MARKER_PREFIX, TWIN_COLLAPSE_FAILURE_PREFIX, SNAPSHOT_GATE_KEY, SCHEMA_META_COUNTER_FIELDS, SCHEMA_META_NEVER_DELETED, MAX_CONFLICTS, sha, ABSENT, hashMap, emptyPlan, SCHEMA_META, hashSets, EMPTY_SET, STICKY_TAGS, PAIRS, degraded, SHADOW_WRITE_REFUSED, SHADOW_WRITE_OPS;
33211
33412
  var init_twin_collapse = __esm({
33212
33413
  "packages/core/src/store/twin-collapse.ts"() {
33213
33414
  "use strict";
@@ -33215,18 +33416,18 @@ var init_twin_collapse = __esm({
33215
33416
  init_errors2();
33216
33417
  init_logger();
33217
33418
  init_pre_repair_snapshot();
33218
- init_snapshot_gate();
33219
33419
  log6 = getLogger("twin-collapse");
33220
33420
  TWIN_COLLAPSE_MARKER_PREFIX = "twin_collapse:";
33221
33421
  TWIN_COLLAPSE_FAILURE_PREFIX = "twin_collapse_failed:";
33422
+ SNAPSHOT_GATE_KEY = "sqlite_snapshot_gate";
33222
33423
  SCHEMA_META_COUNTER_FIELDS = {
33223
33424
  task_id_sequence: "counter",
33224
- [SNAPSHOT_GATE_META_KEY]: "generation",
33425
+ [SNAPSHOT_GATE_KEY]: "generation",
33225
33426
  file_meta: "generation"
33226
33427
  };
33227
33428
  SCHEMA_META_NEVER_DELETED = /* @__PURE__ */ new Set([
33228
33429
  "task_id_sequence",
33229
- SNAPSHOT_GATE_META_KEY
33430
+ SNAPSHOT_GATE_KEY
33230
33431
  ]);
33231
33432
  MAX_CONFLICTS = 50;
33232
33433
  sha = (value) => createHash3("sha256").update(value).digest("hex");
@@ -33291,7 +33492,12 @@ var init_twin_collapse = __esm({
33291
33492
  throw new Error(
33292
33493
  `sticky_tags collapse did not verify: ${missing} missing, ${lingering} not removed`
33293
33494
  );
33294
- return counts;
33495
+ const synced = syncStickyJunction(db, "main");
33496
+ return {
33497
+ inserted: counts.inserted + synced.inserted,
33498
+ replaced: 0,
33499
+ deleted: counts.deleted + synced.deleted
33500
+ };
33295
33501
  },
33296
33502
  shadow(db, plan) {
33297
33503
  db.exec(
@@ -33302,6 +33508,7 @@ var init_twin_collapse = __esm({
33302
33508
  "INSERT INTO temp.brain_sticky_tags (sticky_id, tag) SELECT sticky_id, tag FROM main.brain_sticky_tags"
33303
33509
  );
33304
33510
  applyStickyRows(db, "temp", plan);
33511
+ syncStickyJunction(db, "temp");
33305
33512
  }
33306
33513
  };
33307
33514
  PAIRS = [SCHEMA_META, STICKY_TAGS];
@@ -33333,7 +33540,7 @@ __export(config_exports, {
33333
33540
  parseConfigValue: () => parseConfigValue,
33334
33541
  setConfigValue: () => setConfigValue
33335
33542
  });
33336
- import { existsSync as existsSync17 } from "node:fs";
33543
+ import { existsSync as existsSync18 } from "node:fs";
33337
33544
  function getNestedValue(obj, path) {
33338
33545
  const parts = path.split(".");
33339
33546
  let current = obj;
@@ -33455,7 +33662,7 @@ function parseConfigValue(value) {
33455
33662
  }
33456
33663
  async function setConfigValue(key, value, cwd, opts) {
33457
33664
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
33458
- if (!existsSync17(configPath)) {
33665
+ if (!existsSync18(configPath)) {
33459
33666
  await atomicWriteJson(configPath, {});
33460
33667
  }
33461
33668
  const config2 = await readJson(configPath) ?? {};
@@ -33467,7 +33674,7 @@ async function setConfigValue(key, value, cwd, opts) {
33467
33674
  async function applyStrictnessPreset(preset, cwd, opts) {
33468
33675
  const definition = STRICTNESS_PRESETS[preset];
33469
33676
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
33470
- if (!existsSync17(configPath)) {
33677
+ if (!existsSync18(configPath)) {
33471
33678
  await atomicWriteJson(configPath, {});
33472
33679
  }
33473
33680
  const config2 = await readJson(configPath) ?? {};
@@ -34044,6 +34251,7 @@ var init_cross_db_cleanup = __esm({
34044
34251
  "use strict";
34045
34252
  init_memory_sqlite();
34046
34253
  init_memory_schema();
34254
+ init_worktree_build_guard();
34047
34255
  }
34048
34256
  });
34049
34257
 
@@ -38736,7 +38944,7 @@ __export(sqlite_data_accessor_exports, {
38736
38944
  setMetaValue: () => setMetaValue
38737
38945
  });
38738
38946
  import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
38739
- import { resolve as resolve7 } from "node:path";
38947
+ import { resolve as resolve9 } from "node:path";
38740
38948
  import {
38741
38949
  and as and5,
38742
38950
  eq as eq6,
@@ -38776,9 +38984,12 @@ async function writeMetaValue(cwd, key, value) {
38776
38984
  target: tasksSchemaMeta.key,
38777
38985
  set: { value: json2 }
38778
38986
  }).run();
38987
+ const native = getNativeTasksDb(cwd);
38988
+ if (native) mirrorCounterToBare(native, key);
38779
38989
  }
38780
38990
  function advanceTaskIdSequence(nativeDb, floor) {
38781
38991
  assertTwinCollapseWritable(nativeDb);
38992
+ const lowest = Math.max(floor, bareCounterOf(nativeDb, "task_id_sequence"));
38782
38993
  nativeDb.prepare(`
38783
38994
  UPDATE tasks_schema_meta
38784
38995
  SET value = json_set(value,
@@ -38787,7 +38998,8 @@ function advanceTaskIdSequence(nativeDb, floor) {
38787
38998
  '$.checksum', 'alloc-' || strftime('%s','now')
38788
38999
  )
38789
39000
  WHERE key = 'task_id_sequence'
38790
- `).run(floor, floor);
39001
+ `).run(lowest, lowest);
39002
+ mirrorCounterToBare(nativeDb, "task_id_sequence");
38791
39003
  const row = nativeDb.prepare(`
38792
39004
  SELECT json_extract(value, '$.counter') AS counter
38793
39005
  FROM tasks_schema_meta WHERE key = 'task_id_sequence'
@@ -38841,7 +39053,7 @@ function bindTaskAccessorScope(accessor, scope) {
38841
39053
  }
38842
39054
  async function createSqliteDataAccessor(cwd) {
38843
39055
  const scope = captureProjectScope(
38844
- resolve7(cwd ?? getProjectRoot()),
39056
+ resolve9(cwd ?? getProjectRoot()),
38845
39057
  worktreeScope.getStore()
38846
39058
  );
38847
39059
  return worktreeScope.run(
@@ -38956,7 +39168,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38956
39168
  actor: entry.actor ?? "system",
38957
39169
  detailsJson: entry.details ? JSON.stringify(entry.details) : "{}",
38958
39170
  beforeJson: entry.before ? JSON.stringify(entry.before) : null,
38959
- afterJson: entry.after ? JSON.stringify(entry.after) : null
39171
+ afterJson: entry.after ? JSON.stringify(entry.after) : null,
39172
+ // T12693: the session a ranking change ran in.
39173
+ sessionId: typeof entry.sessionId === "string" ? entry.sessionId : null
38960
39174
  }).run()
38961
39175
  );
38962
39176
  });
@@ -38964,6 +39178,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38964
39178
  async queryAuditLog(query) {
38965
39179
  const db = await getDb(cwd);
38966
39180
  const conditions = [];
39181
+ if (query.ids && query.ids.length > 0) {
39182
+ conditions.push(inArray4(tasksAuditLog.id, [...query.ids]));
39183
+ }
38967
39184
  if (query.taskIds && query.taskIds.length > 0) {
38968
39185
  conditions.push(inArray4(tasksAuditLog.taskId, [...query.taskIds]));
38969
39186
  }
@@ -38982,7 +39199,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38982
39199
  actor: tasksAuditLog.actor,
38983
39200
  detailsJson: tasksAuditLog.detailsJson,
38984
39201
  beforeJson: tasksAuditLog.beforeJson,
38985
- afterJson: tasksAuditLog.afterJson
39202
+ afterJson: tasksAuditLog.afterJson,
39203
+ sessionId: tasksAuditLog.sessionId
38986
39204
  }).from(tasksAuditLog).where(conditions.length > 0 ? and5(...conditions) : void 0).orderBy(sql26`${tasksAuditLog.timestamp} DESC`).limit(limit).all();
38987
39205
  return rows.map((row) => ({
38988
39206
  id: row.id,
@@ -38992,7 +39210,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38992
39210
  actor: row.actor,
38993
39211
  detailsJson: row.detailsJson ?? null,
38994
39212
  beforeJson: row.beforeJson ?? null,
38995
- afterJson: row.afterJson ?? null
39213
+ afterJson: row.afterJson ?? null,
39214
+ sessionId: row.sessionId ?? null
38996
39215
  }));
38997
39216
  },
38998
39217
  // ---- Fine-grained task operations (T5034) ----
@@ -39830,7 +40049,7 @@ var init_sqlite_data_accessor = __esm({
39830
40049
  });
39831
40050
 
39832
40051
  // packages/core/src/sequence/index.ts
39833
- import { existsSync as existsSync18, readFileSync as readFileSync6, renameSync as renameSync5 } from "node:fs";
40052
+ import { existsSync as existsSync19, readFileSync as readFileSync7, renameSync as renameSync5 } from "node:fs";
39834
40053
  import { join as join23 } from "node:path";
39835
40054
  function getLegacySequenceJsonPath(cwd) {
39836
40055
  return join23(resolveOrCwd(cwd), ".cleo", ".sequence.json");
@@ -39847,19 +40066,19 @@ function isSeedSequence(value) {
39847
40066
  return value.counter === 0 && value.lastId === "T000" && value.checksum === "seed";
39848
40067
  }
39849
40068
  function readLegacySequenceFile(path) {
39850
- if (!existsSync18(path)) return null;
40069
+ if (!existsSync19(path)) return null;
39851
40070
  try {
39852
- const parsed = JSON.parse(readFileSync6(path, "utf-8"));
40071
+ const parsed = JSON.parse(readFileSync7(path, "utf-8"));
39853
40072
  return isValidSequenceState(parsed) ? parsed : null;
39854
40073
  } catch {
39855
40074
  return null;
39856
40075
  }
39857
40076
  }
39858
40077
  function renameLegacyFile(path) {
39859
- if (!existsSync18(path)) return;
40078
+ if (!existsSync19(path)) return;
39860
40079
  const migratedPath = `${path}.migrated`;
39861
40080
  try {
39862
- if (!existsSync18(migratedPath)) {
40081
+ if (!existsSync19(migratedPath)) {
39863
40082
  renameSync5(path, migratedPath);
39864
40083
  return;
39865
40084
  }
@@ -40025,12 +40244,12 @@ var init_checkpoint_git_dir = __esm({
40025
40244
 
40026
40245
  // packages/core/src/store/git-checkpoint.ts
40027
40246
  import { execFile as execFile2 } from "node:child_process";
40028
- import { existsSync as existsSync19 } from "node:fs";
40247
+ import { existsSync as existsSync20 } from "node:fs";
40029
40248
  import { readFile as readFile4, writeFile } from "node:fs/promises";
40030
- import { join as join25, resolve as resolve8 } from "node:path";
40249
+ import { join as join25, resolve as resolve10 } from "node:path";
40031
40250
  import { promisify as promisify2 } from "node:util";
40032
40251
  function makeCleoGitEnv(cleoDir) {
40033
- const abs = resolve8(cleoDir);
40252
+ const abs = resolve10(cleoDir);
40034
40253
  return {
40035
40254
  ...process.env,
40036
40255
  GIT_DIR: checkpointGitDir(abs),
@@ -40040,7 +40259,7 @@ function makeCleoGitEnv(cleoDir) {
40040
40259
  async function cleoGitCommand(args, cleoDir) {
40041
40260
  try {
40042
40261
  const result = await execFileAsync2("git", args, {
40043
- cwd: resolve8(cleoDir),
40262
+ cwd: resolve10(cleoDir),
40044
40263
  // absolute cwd so relative paths in args resolve correctly
40045
40264
  env: makeCleoGitEnv(cleoDir),
40046
40265
  timeout: 1e4
@@ -40051,7 +40270,7 @@ async function cleoGitCommand(args, cleoDir) {
40051
40270
  }
40052
40271
  }
40053
40272
  function isCleoGitInitialized(cleoDir) {
40054
- return existsSync19(join25(checkpointGitDir(cleoDir), "HEAD"));
40273
+ return existsSync20(join25(checkpointGitDir(cleoDir), "HEAD"));
40055
40274
  }
40056
40275
  async function loadStateFileAllowlist(cwd) {
40057
40276
  try {
@@ -40095,14 +40314,14 @@ async function isCleoGitRepo(cleoDir) {
40095
40314
  return result.success && (result.stdout === "true" || isCleoGitInitialized(cleoDir));
40096
40315
  }
40097
40316
  function isMergeInProgress(cleoDir) {
40098
- return existsSync19(join25(checkpointGitDir(cleoDir), "MERGE_HEAD"));
40317
+ return existsSync20(join25(checkpointGitDir(cleoDir), "MERGE_HEAD"));
40099
40318
  }
40100
40319
  async function isDetachedHead(cleoDir) {
40101
40320
  const result = await cleoGitCommand(["symbolic-ref", "HEAD"], cleoDir);
40102
40321
  return !result.success;
40103
40322
  }
40104
40323
  function isRebaseInProgress(cleoDir) {
40105
- return existsSync19(join25(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync19(join25(checkpointGitDir(cleoDir), "rebase-apply"));
40324
+ return existsSync20(join25(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync20(join25(checkpointGitDir(cleoDir), "rebase-apply"));
40106
40325
  }
40107
40326
  async function recordCheckpointTime(cleoDir) {
40108
40327
  try {
@@ -40126,7 +40345,7 @@ async function getChangedStateFiles(cleoDir, cwd) {
40126
40345
  const allStateFiles = await getAllStateFiles(cwd);
40127
40346
  for (const stateFile of allStateFiles) {
40128
40347
  const fullPath = join25(cleoDir, stateFile);
40129
- if (!existsSync19(fullPath)) continue;
40348
+ if (!existsSync20(fullPath)) continue;
40130
40349
  const diffResult = await cleoGitCommand(["diff", "--quiet", "--", stateFile], cleoDir);
40131
40350
  const cachedResult = await cleoGitCommand(
40132
40351
  ["diff", "--cached", "--quiet", "--", stateFile],
@@ -40153,7 +40372,7 @@ async function shouldCheckpoint(options) {
40153
40372
  const config2 = await loadCheckpointConfig(cwd);
40154
40373
  if (!config2.enabled) return false;
40155
40374
  const cleoDir = getCleoDir(cwd);
40156
- if (!existsSync19(cleoDir)) return false;
40375
+ if (!existsSync20(cleoDir)) return false;
40157
40376
  if (!isCleoGitInitialized(cleoDir)) return false;
40158
40377
  if (!await isCleoGitRepo(cleoDir)) return false;
40159
40378
  if (isMergeInProgress(cleoDir)) return false;
@@ -40226,6 +40445,218 @@ var init_git_checkpoint = __esm({
40226
40445
  }
40227
40446
  });
40228
40447
 
40448
+ // packages/core/src/store/snapshot-gate.ts
40449
+ import { join as join26 } from "node:path";
40450
+ function readGateState(db) {
40451
+ const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
40452
+ const state = { generation: 0, prefixes: {} };
40453
+ if (!row) return state;
40454
+ try {
40455
+ const parsed = JSON.parse(row.value);
40456
+ if (parsed === null || typeof parsed !== "object") return state;
40457
+ if (typeof parsed.generation === "number" && Number.isSafeInteger(parsed.generation)) {
40458
+ state.generation = parsed.generation;
40459
+ }
40460
+ for (const [prefix, e] of Object.entries(parsed.prefixes ?? {})) {
40461
+ if (e && typeof e.generation === "number" && typeof e.startedAt === "number" && typeof e.completedAt === "number") {
40462
+ state.prefixes[prefix] = {
40463
+ generation: e.generation,
40464
+ startedAt: e.startedAt,
40465
+ completedAt: e.completedAt
40466
+ };
40467
+ }
40468
+ }
40469
+ } catch {
40470
+ }
40471
+ return state;
40472
+ }
40473
+ function writeGateState(db, state) {
40474
+ db.prepare(
40475
+ "INSERT INTO tasks_schema_meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value"
40476
+ ).run(SNAPSHOT_GATE_META_KEY, JSON.stringify(state));
40477
+ mirrorCounterToBare(db, SNAPSHOT_GATE_META_KEY);
40478
+ }
40479
+ function tryReadGateState(db) {
40480
+ if (!db) return null;
40481
+ try {
40482
+ return readGateState(db);
40483
+ } catch {
40484
+ return null;
40485
+ }
40486
+ }
40487
+ function needsSnapshot(entry, mode, nowMs, seenGeneration) {
40488
+ if (!entry) return true;
40489
+ if (mode === "required") return seenGeneration === null || entry.generation <= seenGeneration;
40490
+ const elapsed = nowMs - entry.startedAt;
40491
+ return elapsed < 0 || elapsed >= SNAPSHOT_DEBOUNCE_MS;
40492
+ }
40493
+ async function runGatedSnapshot(opts, snapshot) {
40494
+ const now = opts.now ?? Date.now;
40495
+ const mode = opts.mode ?? "routine";
40496
+ const db = opts.stateDb;
40497
+ const none = (skipped, error48) => ({
40498
+ snapshotted: [],
40499
+ linked: [],
40500
+ absent: [],
40501
+ failed: [],
40502
+ skipped,
40503
+ ...error48 !== void 0 && { error: error48 }
40504
+ });
40505
+ const entryState = tryReadGateState(db);
40506
+ const seenGeneration = mode === "required" ? opts.seenGeneration ?? entryState?.generation ?? null : null;
40507
+ if (mode === "routine") {
40508
+ if (!entryState) return none("state-unavailable");
40509
+ const nowMs = now();
40510
+ if (!opts.prefixes.some((p) => needsSnapshot(entryState.prefixes[p], mode, nowMs, null))) {
40511
+ return none("debounced");
40512
+ }
40513
+ }
40514
+ const lockPath2 = join26(opts.backupDir, GATE_LOCK_BASENAME);
40515
+ let release;
40516
+ try {
40517
+ release = await acquireLock(lockPath2, {
40518
+ retries: mode === "required" ? opts.lockWaitRetries ?? SNAPSHOT_LOCK_WAIT_RETRIES : 0,
40519
+ stale: SNAPSHOT_LOCK_STALE_MS,
40520
+ // A compromised lock (e.g. the backup dir was removed) must not throw
40521
+ // from a timer and crash the host process.
40522
+ onCompromised: () => {
40523
+ }
40524
+ });
40525
+ } catch {
40526
+ if (mode === "routine") return none("in-flight");
40527
+ return none(
40528
+ "lock-timeout",
40529
+ `Snapshot lock ${lockPath2}.lock is still held after waiting. Another snapshot is running, or a crashed process left the lock (it expires after ${SNAPSHOT_LOCK_STALE_MS / 6e4} minutes). Remove it if no snapshot is running.`
40530
+ );
40531
+ }
40532
+ try {
40533
+ try {
40534
+ opts.onLockAcquired?.();
40535
+ } catch {
40536
+ }
40537
+ const state = tryReadGateState(db);
40538
+ if (!state && mode === "routine") return none("state-unavailable");
40539
+ const startMs = now();
40540
+ const admitted = mode === "required" && opts.alwaysSnapshot === true ? [...opts.prefixes] : opts.prefixes.filter(
40541
+ (p) => needsSnapshot(state?.prefixes[p], mode, startMs, seenGeneration)
40542
+ );
40543
+ if (admitted.length === 0) return none(mode === "routine" ? "debounced" : "covered");
40544
+ const generation = (state?.generation ?? 0) + 1;
40545
+ let claimed = false;
40546
+ if (db && state) {
40547
+ try {
40548
+ writeGateState(db, { ...state, generation });
40549
+ claimed = true;
40550
+ } catch {
40551
+ }
40552
+ }
40553
+ const snapshotted = [];
40554
+ const linked = [];
40555
+ const absent = [];
40556
+ const failed = [];
40557
+ for (const prefix of admitted) {
40558
+ try {
40559
+ const outcome = await snapshot(prefix);
40560
+ if (outcome === "absent") absent.push(prefix);
40561
+ else {
40562
+ snapshotted.push(prefix);
40563
+ if (outcome === "linked") linked.push(prefix);
40564
+ }
40565
+ } catch {
40566
+ failed.push(prefix);
40567
+ }
40568
+ }
40569
+ const satisfied = [...snapshotted, ...absent];
40570
+ if (db && claimed && satisfied.length > 0) {
40571
+ try {
40572
+ const latest = readGateState(db);
40573
+ const completedAt = now();
40574
+ latest.generation = Math.max(latest.generation, generation);
40575
+ for (const p of satisfied) {
40576
+ latest.prefixes[p] = { generation, startedAt: startMs, completedAt };
40577
+ }
40578
+ writeGateState(db, latest);
40579
+ } catch {
40580
+ }
40581
+ }
40582
+ return { snapshotted, linked, absent, failed, skipped: null };
40583
+ } finally {
40584
+ await release().catch(() => {
40585
+ });
40586
+ }
40587
+ }
40588
+ function isValidStamp(ymd, hms) {
40589
+ const y = Number(ymd.slice(0, 4));
40590
+ const mo = Number(ymd.slice(4, 6));
40591
+ const d = Number(ymd.slice(6, 8));
40592
+ const h = Number(hms.slice(0, 2));
40593
+ const mi = Number(hms.slice(2, 4));
40594
+ const se = Number(hms.slice(4, 6));
40595
+ if (mo < 1 || mo > 12 || d < 1 || h > 23 || mi > 59 || se > 59) return false;
40596
+ const probe = new Date(Date.UTC(y, mo - 1, d));
40597
+ return probe.getUTCFullYear() === y && probe.getUTCMonth() === mo - 1 && probe.getUTCDate() === d;
40598
+ }
40599
+ function selectSnapshotsToKeep(names, ctx = {}) {
40600
+ const policy = ctx.policy ?? DEFAULT_SNAPSHOT_RETENTION;
40601
+ const keep = /* @__PURE__ */ new Set();
40602
+ const stamped = [];
40603
+ for (const name15 of names) {
40604
+ const m = STAMP_PATTERN.exec(name15);
40605
+ const ymd = m?.[1];
40606
+ const hms = m?.[2];
40607
+ if (!ymd || !hms || !isValidStamp(ymd, hms)) {
40608
+ keep.add(name15);
40609
+ continue;
40610
+ }
40611
+ const stamp = `${ymd}-${hms}`;
40612
+ if (ctx.nowStamp !== void 0 && stamp > ctx.nowStamp) {
40613
+ keep.add(name15);
40614
+ continue;
40615
+ }
40616
+ stamped.push({ name: name15, stamp });
40617
+ }
40618
+ if (ctx.pinned !== void 0 && names.includes(ctx.pinned)) keep.add(ctx.pinned);
40619
+ stamped.sort((a, b) => a.stamp < b.stamp ? 1 : a.stamp > b.stamp ? -1 : 0);
40620
+ for (const s of stamped.slice(0, policy.latest)) keep.add(s.name);
40621
+ const keepNewestPerBucket = (bucketOf, slots) => {
40622
+ const seen = /* @__PURE__ */ new Set();
40623
+ for (const s of stamped) {
40624
+ const bucket = bucketOf(s.stamp);
40625
+ if (seen.has(bucket)) continue;
40626
+ if (seen.size >= slots) break;
40627
+ seen.add(bucket);
40628
+ keep.add(s.name);
40629
+ }
40630
+ };
40631
+ keepNewestPerBucket(
40632
+ (stamp) => `${stamp.slice(0, 11)}q${Math.floor(Number(stamp.slice(11, 13)) / 15)}`,
40633
+ policy.quarterHourly
40634
+ );
40635
+ keepNewestPerBucket((stamp) => stamp.slice(0, 11), policy.hourly);
40636
+ keepNewestPerBucket((stamp) => stamp.slice(0, 8), policy.daily);
40637
+ return keep;
40638
+ }
40639
+ var SNAPSHOT_DEBOUNCE_MS, SNAPSHOT_LOCK_STALE_MS, SNAPSHOT_LOCK_WAIT_RETRIES, SNAPSHOT_GATE_META_KEY, GATE_LOCK_BASENAME, DEFAULT_SNAPSHOT_RETENTION, STAMP_PATTERN;
40640
+ var init_snapshot_gate = __esm({
40641
+ "packages/core/src/store/snapshot-gate.ts"() {
40642
+ "use strict";
40643
+ init_lock();
40644
+ init_twin_collapse();
40645
+ SNAPSHOT_DEBOUNCE_MS = 5 * 6e4;
40646
+ SNAPSHOT_LOCK_STALE_MS = 10 * 6e4;
40647
+ SNAPSHOT_LOCK_WAIT_RETRIES = 90;
40648
+ SNAPSHOT_GATE_META_KEY = "sqlite_snapshot_gate";
40649
+ GATE_LOCK_BASENAME = ".snapshot-gate";
40650
+ DEFAULT_SNAPSHOT_RETENTION = {
40651
+ latest: 1,
40652
+ quarterHourly: 3,
40653
+ hourly: 3,
40654
+ daily: 3
40655
+ };
40656
+ STAMP_PATTERN = /-(\d{8})-(\d{6})\.db$/;
40657
+ }
40658
+ });
40659
+
40229
40660
  // packages/core/src/store/data-safety-central.ts
40230
40661
  import { eq as eq7 } from "drizzle-orm";
40231
40662
  function inSafetyScope(cwd, operation) {
@@ -40636,7 +41067,7 @@ __export(data_accessor_exports, {
40636
41067
  getAccessorDb: () => getAccessorDb,
40637
41068
  getTaskAccessor: () => getTaskAccessor
40638
41069
  });
40639
- import { resolve as resolve9 } from "node:path";
41070
+ import { resolve as resolve11 } from "node:path";
40640
41071
  function assertTestEnv(dbPath) {
40641
41072
  const testMode = process.env["CLEO_TEST_MODE"];
40642
41073
  if (testMode !== "1") return;
@@ -40657,7 +41088,7 @@ function assertTestEnv(dbPath) {
40657
41088
  }
40658
41089
  }
40659
41090
  async function createDataAccessor(cwd) {
40660
- const root = resolve9(cwd ?? getProjectRoot());
41091
+ const root = resolve11(cwd ?? getProjectRoot());
40661
41092
  const inherited = worktreeScope.getStore();
40662
41093
  const captured = inherited ? { ...inherited } : void 0;
40663
41094
  captured?.execution?.assertActive();
@@ -40701,7 +41132,7 @@ __export(memory_sqlite_exports, {
40701
41132
  resetBrainDbState: () => resetBrainDbState,
40702
41133
  resolveBrainMigrationsFolder: () => resolveBrainMigrationsFolder
40703
41134
  });
40704
- import { createRequire as createRequire6 } from "node:module";
41135
+ import { createRequire as createRequire7 } from "node:module";
40705
41136
  function _getDrizzle2() {
40706
41137
  if (_drizzle2 === null) {
40707
41138
  const mod = _require4("drizzle-orm/node-sqlite");
@@ -40838,7 +41269,7 @@ var init_memory_sqlite = __esm({
40838
41269
  init_resolve_migrations_folder();
40839
41270
  init_memory_schema();
40840
41271
  init_twin_collapse();
40841
- _require4 = createRequire6(import.meta.url);
41272
+ _require4 = createRequire7(import.meta.url);
40842
41273
  _drizzle2 = null;
40843
41274
  BRAIN_SCHEMA_VERSION = "1.0.0";
40844
41275
  CONSOLIDATED_BRAIN_TABLES = [
@@ -41026,11 +41457,11 @@ var init_skills_schema = __esm({
41026
41457
  });
41027
41458
 
41028
41459
  // packages/core/src/store/skills-db.ts
41029
- import { join as join26 } from "node:path";
41460
+ import { join as join27 } from "node:path";
41030
41461
  import { and as and6, eq as eq8 } from "drizzle-orm";
41031
41462
  function getDefaultSkillsDbPath() {
41032
41463
  const cleoHome = getCleoHome();
41033
- const dbPath = join26(cleoHome, "cleo.db");
41464
+ const dbPath = join27(cleoHome, "cleo.db");
41034
41465
  if (!dbPath.startsWith(cleoHome)) {
41035
41466
  throw new Error(
41036
41467
  `BUG: getDefaultSkillsDbPath() resolved to "${dbPath}" which is NOT under getCleoHome() ("${cleoHome}"). The skills registry is global-only per SG-CLEO-SKILLS-architecture-v3.md \xA74. Fix the caller, do not suppress.`
@@ -41078,19 +41509,19 @@ import {
41078
41509
  chmodSync,
41079
41510
  closeSync,
41080
41511
  copyFileSync as copyFileSync3,
41081
- existsSync as existsSync20,
41512
+ existsSync as existsSync21,
41082
41513
  fsyncSync,
41083
41514
  linkSync,
41084
41515
  mkdirSync as mkdirSync5,
41085
41516
  openSync,
41086
41517
  readdirSync as readdirSync5,
41087
- realpathSync as realpathSync6,
41518
+ realpathSync as realpathSync7,
41088
41519
  renameSync as renameSync6,
41089
41520
  rmSync,
41090
41521
  statSync as statSync6,
41091
41522
  unlinkSync as unlinkSync3
41092
41523
  } from "node:fs";
41093
- import { dirname as dirname14, join as join27, sep as sep3 } from "node:path";
41524
+ import { dirname as dirname16, join as join28, sep as sep4 } from "node:path";
41094
41525
  function resolveInventoryPath(entry, cwd) {
41095
41526
  try {
41096
41527
  if (entry.tier === "global") {
@@ -41126,8 +41557,8 @@ async function openAgentRegistryDbForSnapshot() {
41126
41557
  }
41127
41558
  async function openTelemetryDbForSnapshot() {
41128
41559
  try {
41129
- const path = join27(getCleoHome(), "telemetry.db");
41130
- if (!existsSync20(path)) return null;
41560
+ const path = join28(getCleoHome(), "telemetry.db");
41561
+ if (!existsSync21(path)) return null;
41131
41562
  } catch {
41132
41563
  return null;
41133
41564
  }
@@ -41239,7 +41670,7 @@ function rotateSnapshots(backupDir, prefix, justWritten) {
41239
41670
  for (const name15 of names) {
41240
41671
  if (keep.has(name15)) continue;
41241
41672
  try {
41242
- unlinkSync3(join27(backupDir, name15));
41673
+ unlinkSync3(join28(backupDir, name15));
41243
41674
  } catch {
41244
41675
  }
41245
41676
  }
@@ -41261,7 +41692,7 @@ async function snapshotProjectTargetsGated(targets, opts) {
41261
41692
  let backupDir;
41262
41693
  try {
41263
41694
  const cleoDir = getCleoDir(cwd);
41264
- backupDir = join27(cleoDir, "backups", "sqlite");
41695
+ backupDir = join28(cleoDir, "backups", "sqlite");
41265
41696
  mkdirSync5(backupDir, { recursive: true });
41266
41697
  } catch {
41267
41698
  return null;
@@ -41293,7 +41724,7 @@ function sourceFileOf(db) {
41293
41724
  const location = db.location();
41294
41725
  if (!location) return null;
41295
41726
  try {
41296
- return realpathSync6(location);
41727
+ return realpathSync7(location);
41297
41728
  } catch {
41298
41729
  return location;
41299
41730
  }
@@ -41304,10 +41735,10 @@ function hasLocation(db) {
41304
41735
  function assertOwnedByProject(source, prefix, cwd) {
41305
41736
  let cleoDir = getCleoDir(cwd);
41306
41737
  try {
41307
- cleoDir = realpathSync6(cleoDir);
41738
+ cleoDir = realpathSync7(cleoDir);
41308
41739
  } catch {
41309
41740
  }
41310
- if (!source.startsWith(cleoDir + sep3)) {
41741
+ if (!source.startsWith(cleoDir + sep4)) {
41311
41742
  throw new Error(
41312
41743
  `refusing to snapshot ${prefix}: its database ${source} is not inside ${cleoDir}`
41313
41744
  );
@@ -41336,7 +41767,7 @@ function commitSnapshotFile(tmp, dest) {
41336
41767
  }
41337
41768
  renameSync6(tmp, dest);
41338
41769
  try {
41339
- const dirFd = openSync(dirname14(dest), "r");
41770
+ const dirFd = openSync(dirname16(dest), "r");
41340
41771
  try {
41341
41772
  fsyncSync(dirFd);
41342
41773
  } finally {
@@ -41359,7 +41790,7 @@ function removeDeadTempSnapshots(backupDir) {
41359
41790
  const m = TEMP_SNAPSHOT_RE.exec(name15);
41360
41791
  if (!m) continue;
41361
41792
  const pid = Number(m[1]);
41362
- const path = join27(backupDir, name15);
41793
+ const path = join28(backupDir, name15);
41363
41794
  const stale = pid !== process.pid && (!isPidAlive2(pid) || Date.now() - statSync6(path).mtimeMs > TEMP_SNAPSHOT_MAX_AGE_MS);
41364
41795
  if (stale) rmSync(path, { force: true });
41365
41796
  }
@@ -41369,7 +41800,7 @@ function removeDeadTempSnapshots(backupDir) {
41369
41800
  async function freeSnapshotName(backupDir, prefix) {
41370
41801
  for (let attempt = 0; attempt < SNAPSHOT_NAME_ATTEMPTS; attempt++) {
41371
41802
  const name15 = `${prefix}-${formatTimestamp(/* @__PURE__ */ new Date())}.db`;
41372
- if (!existsSync20(join27(backupDir, name15))) return name15;
41803
+ if (!existsSync21(join28(backupDir, name15))) return name15;
41373
41804
  await new Promise((r) => setTimeout(r, 1e3 - Date.now() % 1e3 + 5));
41374
41805
  }
41375
41806
  throw new Error(`no free snapshot filename for ${prefix} in ${backupDir}`);
@@ -41397,7 +41828,7 @@ async function snapshotOne(target, backupDir, writtenBySource, cwd) {
41397
41828
  if (opened && target.closeDb) target.closeDb(opened);
41398
41829
  throw err;
41399
41830
  }
41400
- const dest = join27(backupDir, destName);
41831
+ const dest = join28(backupDir, destName);
41401
41832
  removeDeadTempSnapshots(backupDir);
41402
41833
  const existing = source !== null ? writtenBySource.get(source) : void 0;
41403
41834
  if (existing !== void 0) {
@@ -41451,13 +41882,13 @@ async function vacuumIntoBackup(opts = {}) {
41451
41882
  function listSqliteBackupsForPrefix(prefix, cwd) {
41452
41883
  try {
41453
41884
  const cleoDir = getCleoDir(cwd);
41454
- const backupDir = join27(cleoDir, "backups", "sqlite");
41455
- if (!existsSync20(backupDir)) return [];
41885
+ const backupDir = join28(cleoDir, "backups", "sqlite");
41886
+ if (!existsSync21(backupDir)) return [];
41456
41887
  const pattern = snapshotPattern(prefix);
41457
41888
  return readdirSync5(backupDir).filter((f) => pattern.test(f)).map((f) => ({
41458
41889
  name: f,
41459
- path: join27(backupDir, f),
41460
- mtimeMs: statSync6(join27(backupDir, f)).mtimeMs
41890
+ path: join28(backupDir, f),
41891
+ mtimeMs: statSync6(join28(backupDir, f)).mtimeMs
41461
41892
  })).sort((a, b) => b.mtimeMs - a.mtimeMs);
41462
41893
  } catch {
41463
41894
  return [];
@@ -41527,15 +41958,16 @@ __export(sqlite_exports, {
41527
41958
  resetDbState: () => resetDbState,
41528
41959
  resolveMigrationsFolder: () => resolveMigrationsFolder,
41529
41960
  schema: () => tasks_schema_exports,
41530
- seedTasksMeta: () => seedTasksMeta
41961
+ seedTasksMeta: () => seedTasksMeta,
41962
+ worktreeRecoveryRefusal: () => worktreeRecoveryRefusal
41531
41963
  });
41532
- import { copyFileSync as copyFileSync4, existsSync as existsSync21, realpathSync as realpathSync7, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
41533
- import { createRequire as createRequire7 } from "node:module";
41534
- import { basename as basename8, dirname as dirname15, resolve as resolve10 } from "node:path";
41964
+ import { copyFileSync as copyFileSync4, existsSync as existsSync22, realpathSync as realpathSync8, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
41965
+ import { createRequire as createRequire8 } from "node:module";
41966
+ import { basename as basename8, dirname as dirname17, resolve as resolve12 } from "node:path";
41535
41967
  import { eq as eq9 } from "drizzle-orm";
41536
41968
  function _getDrizzle3() {
41537
41969
  if (_drizzle3 === null) {
41538
- const _require7 = createRequire7(import.meta.url);
41970
+ const _require7 = createRequire8(import.meta.url);
41539
41971
  const mod = _require7("drizzle-orm/node-sqlite");
41540
41972
  _drizzle3 = mod.drizzle;
41541
41973
  }
@@ -41571,13 +42003,19 @@ function countBackupTasks(backupDb) {
41571
42003
  return 0;
41572
42004
  }
41573
42005
  function isSameDirectory(a, b) {
41574
- if (resolve10(a) === resolve10(b)) return true;
42006
+ if (resolve12(a) === resolve12(b)) return true;
41575
42007
  try {
41576
- return realpathSync7(a) === realpathSync7(b);
42008
+ return realpathSync8(a) === realpathSync8(b);
41577
42009
  } catch {
41578
42010
  return false;
41579
42011
  }
41580
42012
  }
42013
+ function worktreeRecoveryRefusal(dbPath) {
42014
+ const storeCleoDir = dirname17(dbPath);
42015
+ const root = dirname17(storeCleoDir);
42016
+ if (basename8(storeCleoDir) !== ".cleo" || !isGitLinkedCheckout(root)) return null;
42017
+ return `Auto-recovery refused: ${dbPath} lives inside the git worktree ${root}; ${describeWorktreeOwner(root)}. A worktree uses its owning project's store and never receives a restored copy (T12460, T12677).`;
42018
+ }
41581
42019
  async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
41582
42020
  const { openNativeDatabase: openNativeDatabase2 } = await Promise.resolve().then(() => (init_sqlite_native(), sqlite_native_exports));
41583
42021
  const log15 = getLogger("sqlite");
@@ -41586,12 +42024,10 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
41586
42024
  const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks_tasks").get();
41587
42025
  const taskCount = countResult?.cnt ?? 0;
41588
42026
  if (taskCount > 0) return false;
41589
- const storeCleoDir = dirname15(dbPath);
41590
- if (basename8(storeCleoDir) === ".cleo" && isGitLinkedCheckout(dirname15(storeCleoDir))) {
41591
- log15.warn(
41592
- { dbPath },
41593
- "Auto-recovery refused: the empty store lives inside a git worktree (T12460). Worktrees must resolve the parent project store."
41594
- );
42027
+ const storeCleoDir = dirname17(dbPath);
42028
+ const worktreeRefusal = worktreeRecoveryRefusal(dbPath);
42029
+ if (worktreeRefusal !== null) {
42030
+ log15.warn({ dbPath }, worktreeRefusal);
41595
42031
  return false;
41596
42032
  }
41597
42033
  const backups = listSqliteBackups(cwd);
@@ -41599,7 +42035,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
41599
42035
  return false;
41600
42036
  }
41601
42037
  const newestBackup = backups[0];
41602
- const backupCleoDir = dirname15(dirname15(dirname15(newestBackup.path)));
42038
+ const backupCleoDir = dirname17(dirname17(dirname17(newestBackup.path)));
41603
42039
  if (!isSameDirectory(backupCleoDir, storeCleoDir)) {
41604
42040
  log15.warn(
41605
42041
  { dbPath, backupPath: newestBackup.path },
@@ -41721,6 +42157,7 @@ function runMigrations(nativeDb, db, dbPath) {
41721
42157
  try {
41722
42158
  migrateWithRetry(db, migrationsFolder, nativeDb, "tasks", "sqlite");
41723
42159
  } catch (error48) {
42160
+ if (isWorktreeBuildSchemaError(error48)) throw error48;
41724
42161
  if (isSqliteBusy(error48) || !tableExists(nativeDb, "tasks_tasks")) throw error48;
41725
42162
  try {
41726
42163
  rebuildLegacyTasksLineage(
@@ -41762,7 +42199,7 @@ async function getSchemaVersion(cwd) {
41762
42199
  return result[0]?.value ?? null;
41763
42200
  }
41764
42201
  function dbExists(cwd) {
41765
- return existsSync21(resolveDualScopeDbPath("project", cwd));
42202
+ return existsSync22(resolveDualScopeDbPath("project", cwd));
41766
42203
  }
41767
42204
  function getNativeDb(cwd) {
41768
42205
  return boundProjectNative("tasks", cwd);
@@ -41798,6 +42235,7 @@ var init_sqlite3 = __esm({
41798
42235
  init_resolve_migrations_folder();
41799
42236
  init_sqlite_backup();
41800
42237
  init_twin_collapse();
42238
+ init_worktree_build_guard();
41801
42239
  init_worktree_isolation_guard();
41802
42240
  init_sqlite_native();
41803
42241
  init_tasks_schema();
@@ -41826,15 +42264,15 @@ var init_sqlite3 = __esm({
41826
42264
  // packages/core/src/store/exodus/migrate.ts
41827
42265
  import {
41828
42266
  copyFileSync as copyFileSync5,
41829
- existsSync as existsSync22,
42267
+ existsSync as existsSync23,
41830
42268
  mkdirSync as mkdirSync6,
41831
- readFileSync as readFileSync7,
42269
+ readFileSync as readFileSync8,
41832
42270
  renameSync as renameSync8,
41833
42271
  statSync as statSync7,
41834
42272
  unlinkSync as unlinkSync5,
41835
42273
  writeFileSync as writeFileSync6
41836
42274
  } from "node:fs";
41837
- import { join as join28 } from "node:path";
42275
+ import { join as join29 } from "node:path";
41838
42276
  function getSqliteVersion(db) {
41839
42277
  try {
41840
42278
  const row = db.prepare("SELECT sqlite_version() AS v").get();
@@ -41865,24 +42303,24 @@ function restoreGrandfatheredGuards(db, suspended) {
41865
42303
  }
41866
42304
  }
41867
42305
  function writeJournal(stagingDir, journal) {
41868
- const journalPath = join28(stagingDir, JOURNAL_FILENAME);
42306
+ const journalPath = join29(stagingDir, JOURNAL_FILENAME);
41869
42307
  const tmpPath = `${journalPath}.tmp`;
41870
42308
  writeFileSync6(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
41871
42309
  renameSync8(tmpPath, journalPath);
41872
42310
  }
41873
42311
  function readJournal(stagingDir) {
41874
- const journalPath = join28(stagingDir, JOURNAL_FILENAME);
41875
- if (!existsSync22(journalPath)) return null;
42312
+ const journalPath = join29(stagingDir, JOURNAL_FILENAME);
42313
+ if (!existsSync23(journalPath)) return null;
41876
42314
  try {
41877
- return JSON.parse(readFileSync7(journalPath, "utf8"));
42315
+ return JSON.parse(readFileSync8(journalPath, "utf8"));
41878
42316
  } catch {
41879
42317
  return null;
41880
42318
  }
41881
42319
  }
41882
42320
  function clearExodusJournal(stagingDir) {
41883
- const journalPath = join28(stagingDir, JOURNAL_FILENAME);
42321
+ const journalPath = join29(stagingDir, JOURNAL_FILENAME);
41884
42322
  try {
41885
- if (!existsSync22(journalPath)) return false;
42323
+ if (!existsSync23(journalPath)) return false;
41886
42324
  unlinkSync5(journalPath);
41887
42325
  log10.info(
41888
42326
  { stagingDir },
@@ -42178,7 +42616,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42178
42616
  mkdirSync6(stagingDir, { recursive: true });
42179
42617
  let sqliteVersion = "unknown";
42180
42618
  for (const src of sources) {
42181
- if (existsSync22(src.path)) {
42619
+ if (existsSync23(src.path)) {
42182
42620
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
42183
42621
  sqliteVersion = getSqliteVersion(snap.db);
42184
42622
  snap.close();
@@ -42208,15 +42646,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42208
42646
  let reseedProject = null;
42209
42647
  try {
42210
42648
  for (const src of sources) {
42211
- if (!existsSync22(src.path)) continue;
42212
- const backupDest = join28(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
42649
+ if (!existsSync23(src.path)) continue;
42650
+ const backupDest = join29(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
42213
42651
  const srcBytes = safeStatBytes(src.path);
42214
42652
  const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
42215
42653
  if (skipStagingCopy) {
42216
42654
  onProgress?.(
42217
42655
  `Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
42218
42656
  );
42219
- } else if (!existsSync22(backupDest)) {
42657
+ } else if (!existsSync23(backupDest)) {
42220
42658
  onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
42221
42659
  copyFileSync5(src.path, backupDest);
42222
42660
  backupPaths.push(backupDest);
@@ -42249,8 +42687,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42249
42687
  }
42250
42688
  prepareExodusRecovery(projectNative, stagingDir);
42251
42689
  if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
42252
- const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync22(s.path));
42253
- const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync22(s.path));
42690
+ const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync23(s.path));
42691
+ const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync23(s.path));
42254
42692
  if (globalNative === null && globalSources.length > 0)
42255
42693
  throw new Error("A projectOnly exodus run was given global-scope sources");
42256
42694
  await migrateScope(
@@ -42558,9 +42996,9 @@ __export(reconcile_exports, {
42558
42996
  reconcileSupersededStores: () => reconcileSupersededStores,
42559
42997
  unmigratedBareSources: () => unmigratedBareSources
42560
42998
  });
42561
- import { copyFileSync as copyFileSync6, existsSync as existsSync23, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
42999
+ import { copyFileSync as copyFileSync6, existsSync as existsSync24, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
42562
43000
  import { tmpdir as tmpdir3 } from "node:os";
42563
- import { basename as basename9, join as join29 } from "node:path";
43001
+ import { basename as basename9, join as join30 } from "node:path";
42564
43002
  function ident2(name15) {
42565
43003
  return `"${name15.replace(/"/g, '""')}"`;
42566
43004
  }
@@ -42629,7 +43067,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
42629
43067
  }
42630
43068
  function legacySourcesHoldRows(sources) {
42631
43069
  for (const src of sources) {
42632
- if (!existsSync23(src.path)) continue;
43070
+ if (!existsSync24(src.path)) continue;
42633
43071
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
42634
43072
  try {
42635
43073
  for (const table of orderTablesForCopy(snap.db)) {
@@ -42660,8 +43098,8 @@ async function bareTaskCoreSource(liveStorePath, resolveTarget, outDir) {
42660
43098
  live.close();
42661
43099
  }
42662
43100
  if (tables.length === 0) return null;
42663
- const seedPath = await buildFreshProjectStore(join29(outDir, "fresh-project-seed.db"));
42664
- const path = join29(outDir, "cleo-bare-task-core.db");
43101
+ const seedPath = await buildFreshProjectStore(join30(outDir, "fresh-project-seed.db"));
43102
+ const path = join30(outDir, "cleo-bare-task-core.db");
42665
43103
  const snap = openCleoDbSnapshot(path, { readOnly: false });
42666
43104
  let kept = 0;
42667
43105
  try {
@@ -42709,7 +43147,7 @@ async function buildFreshProjectStore(path) {
42709
43147
  }
42710
43148
  function snapshotFresherBareRows(barePath, legacyTasksPath, stagingDir) {
42711
43149
  if (legacyTasksPath === void 0) return null;
42712
- const path = join29(stagingDir, "cleo-bare-task-core-fresher.db");
43150
+ const path = join30(stagingDir, "cleo-bare-task-core-fresher.db");
42713
43151
  const snap = openCleoDbSnapshot(barePath, { readOnly: true });
42714
43152
  try {
42715
43153
  snap.db.exec(`VACUUM INTO '${path.replace(/'/g, "''")}'`);
@@ -42860,7 +43298,7 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
42860
43298
  const additive = options.additive === true;
42861
43299
  const plan = buildExodusPlan(projectRoot);
42862
43300
  const resolveTarget = await buildRuntimeTargetResolver();
42863
- const scratch = mkdtempSync(join29(tmpdir3(), "cleo-reconcile-"));
43301
+ const scratch = mkdtempSync(join30(tmpdir3(), "cleo-reconcile-"));
42864
43302
  try {
42865
43303
  return await reconcileWithScratch(
42866
43304
  projectRoot,
@@ -42876,8 +43314,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
42876
43314
  }
42877
43315
  }
42878
43316
  async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
42879
- const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync23(s.path));
42880
- const bare = !additive && existsSync23(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
43317
+ const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync24(s.path));
43318
+ const bare = !additive && existsSync24(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
42881
43319
  const copyResolver = additive ? (sourceName, legacyTable) => {
42882
43320
  const r = resolveTarget(sourceName, legacyTable);
42883
43321
  return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
@@ -42896,7 +43334,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42896
43334
  stagingDir: null,
42897
43335
  receiptPath: null
42898
43336
  };
42899
- if (sources.length === 0 || !existsSync23(liveStorePath)) {
43337
+ if (sources.length === 0 || !existsSync24(liveStorePath)) {
42900
43338
  return {
42901
43339
  ...base,
42902
43340
  outcome: "nothing-to-reconcile",
@@ -42936,11 +43374,11 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42936
43374
  };
42937
43375
  }
42938
43376
  const iso = (/* @__PURE__ */ new Date()).toISOString().replace(/[:]/g, "").replace(/\..+Z$/, "Z");
42939
- const stagingDir = join29(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
43377
+ const stagingDir = join30(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
42940
43378
  mkdirSync7(stagingDir, { recursive: true });
42941
43379
  const copySources = sources.map((s) => {
42942
43380
  if (s !== bare) return s;
42943
- const kept = join29(stagingDir, basename9(s.path));
43381
+ const kept = join30(stagingDir, basename9(s.path));
42944
43382
  copyFileSync6(s.path, kept);
42945
43383
  return { ...s, path: kept };
42946
43384
  });
@@ -42960,7 +43398,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42960
43398
  const result = await withLock(
42961
43399
  `${liveStorePath}.exodus-on-open.lock`,
42962
43400
  async () => {
42963
- const liveBefore = join29(scratch, "live-before.db");
43401
+ const liveBefore = join30(scratch, "live-before.db");
42964
43402
  snapshotLive(liveStorePath, liveBefore);
42965
43403
  const migrated = await runExodusMigrate(reconcilePlan, false, (msg) => log11.debug(msg), {
42966
43404
  projectOnly: true,
@@ -43010,7 +43448,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
43010
43448
  },
43011
43449
  { stale: 6e5, retries: 30 }
43012
43450
  );
43013
- const receiptPath = join29(stagingDir, RECEIPT_FILENAME);
43451
+ const receiptPath = join30(stagingDir, RECEIPT_FILENAME);
43014
43452
  const receipt2 = { ...result, receiptPath };
43015
43453
  writeFileSync7(receiptPath, `${JSON.stringify(receipt2, null, 2)}
43016
43454
  `, "utf8");
@@ -43087,20 +43525,20 @@ var init_seal = __esm({
43087
43525
  });
43088
43526
 
43089
43527
  // packages/core/src/store/exodus/status.ts
43090
- import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync8, statSync as statSync8 } from "node:fs";
43091
- import { join as join30 } from "node:path";
43528
+ import { existsSync as existsSync25, readdirSync as readdirSync6, readFileSync as readFileSync9, statSync as statSync8 } from "node:fs";
43529
+ import { join as join31 } from "node:path";
43092
43530
  function readJournal2(stagingDir) {
43093
- const p = join30(stagingDir, JOURNAL_FILENAME2);
43094
- if (!existsSync24(p)) return null;
43531
+ const p = join31(stagingDir, JOURNAL_FILENAME2);
43532
+ if (!existsSync25(p)) return null;
43095
43533
  try {
43096
- return JSON.parse(readFileSync8(p, "utf8"));
43534
+ return JSON.parse(readFileSync9(p, "utf8"));
43097
43535
  } catch {
43098
43536
  return null;
43099
43537
  }
43100
43538
  }
43101
43539
  function findStagingDirs(cleoDir) {
43102
43540
  try {
43103
- return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join30(cleoDir, e.name)).sort().reverse();
43541
+ return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join31(cleoDir, e.name)).sort().reverse();
43104
43542
  } catch {
43105
43543
  return [];
43106
43544
  }
@@ -43123,15 +43561,15 @@ function runExodusStatus(cwd) {
43123
43561
  const sourcesInfo = plan.sources.map((s) => ({
43124
43562
  name: s.name,
43125
43563
  path: s.path,
43126
- exists: existsSync24(s.path),
43564
+ exists: existsSync25(s.path),
43127
43565
  bytes: safeBytes(s.path)
43128
43566
  }));
43129
43567
  return {
43130
43568
  hasStaging: latestStaging !== null,
43131
43569
  stagingDir: latestStaging,
43132
43570
  journal,
43133
- projectDbExists: existsSync24(projectDbPath),
43134
- globalDbExists: existsSync24(globalDbPath),
43571
+ projectDbExists: existsSync25(projectDbPath),
43572
+ globalDbExists: existsSync25(globalDbPath),
43135
43573
  sourcesPresent: sourcesInfo.some((s) => s.exists),
43136
43574
  sources: sourcesInfo
43137
43575
  };
@@ -43148,8 +43586,8 @@ var init_status = __esm({
43148
43586
  });
43149
43587
 
43150
43588
  // packages/core/src/store/exodus/verify-migration.ts
43151
- import { existsSync as existsSync25 } from "node:fs";
43152
- import { createRequire as createRequire8 } from "node:module";
43589
+ import { existsSync as existsSync26 } from "node:fs";
43590
+ import { createRequire as createRequire9 } from "node:module";
43153
43591
  function orderByClause(db, tableName) {
43154
43592
  try {
43155
43593
  const pragma = db.prepare(`PRAGMA table_info("${tableName}")`).all();
@@ -43413,7 +43851,7 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
43413
43851
  const anyFeeder = (targetTable, probe) => {
43414
43852
  for (const feeder of feedersOf(targetTable)) {
43415
43853
  const src = sources.find((s) => s.name === feeder.sourceName);
43416
- if (src === void 0 || !existsSync25(src.path)) continue;
43854
+ if (src === void 0 || !existsSync26(src.path)) continue;
43417
43855
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
43418
43856
  try {
43419
43857
  if (!tableExists3(snap.db, feeder.legacyTable)) continue;
@@ -43468,7 +43906,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43468
43906
  const preExistingForeignKeyViolations = [];
43469
43907
  const failureLines = [];
43470
43908
  const sourceOrphanSigs = /* @__PURE__ */ new Set();
43471
- if (!existsSync25(projectDbPath)) {
43909
+ if (!existsSync26(projectDbPath)) {
43472
43910
  return {
43473
43911
  ok: false,
43474
43912
  tables: [],
@@ -43479,7 +43917,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43479
43917
  error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
43480
43918
  };
43481
43919
  }
43482
- if (!existsSync25(globalDbPath)) {
43920
+ if (!existsSync26(globalDbPath)) {
43483
43921
  return {
43484
43922
  ok: false,
43485
43923
  tables: [],
@@ -43494,7 +43932,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43494
43932
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
43495
43933
  try {
43496
43934
  for (const src of sources) {
43497
- if (!existsSync25(src.path)) {
43935
+ if (!existsSync26(src.path)) {
43498
43936
  onProgress?.(`Skipping ${src.name} (not present)`);
43499
43937
  continue;
43500
43938
  }
@@ -43689,7 +44127,7 @@ var init_verify_migration = __esm({
43689
44127
  init_column_transforms();
43690
44128
  init_table_name_map();
43691
44129
  log13 = getLogger("verify-migration");
43692
- _require5 = createRequire8(import.meta.url);
44130
+ _require5 = createRequire9(import.meta.url);
43693
44131
  CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
43694
44132
  }
43695
44133
  });
@@ -43785,11 +44223,11 @@ __export(on_open_exports, {
43785
44223
  maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
43786
44224
  withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
43787
44225
  });
43788
- import { existsSync as existsSync26, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
44226
+ import { existsSync as existsSync27, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
43789
44227
  import { tmpdir as tmpdir4 } from "node:os";
43790
- import { join as join31, resolve as resolve11 } from "node:path";
44228
+ import { join as join32, resolve as resolve13 } from "node:path";
43791
44229
  async function withExodusOnOpenSuppressed(dbPath, fn) {
43792
- const key = resolve11(dbPath);
44230
+ const key = resolve13(dbPath);
43793
44231
  _reconcileInProgress.set(key, (_reconcileInProgress.get(key) ?? 0) + 1);
43794
44232
  try {
43795
44233
  return await fn();
@@ -43827,7 +44265,7 @@ function remedyFor(scope) {
43827
44265
  }
43828
44266
  async function strandedLegacySources(scope, cwd) {
43829
44267
  const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
43830
- return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync26(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
44268
+ return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync27(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
43831
44269
  }
43832
44270
  async function rollbackBothScopes(plan) {
43833
44271
  const { getDualScopeNativeDb: getDualScopeNativeDb2, openDualScopeDbAtPath: openDualScopeDbAtPath2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
@@ -43905,7 +44343,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43905
44343
  if (_exodusInProgress) {
43906
44344
  return { outcome: "skipped", reason: "re-entrant open during active migration" };
43907
44345
  }
43908
- if (_reconcileInProgress.has(resolve11(dbPath))) {
44346
+ if (_reconcileInProgress.has(resolve13(dbPath))) {
43909
44347
  return {
43910
44348
  outcome: "skipped",
43911
44349
  reason: "an explicit superseded-store reconcile of this store is in progress"
@@ -43938,14 +44376,14 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43938
44376
  const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
43939
44377
  const plan = buildExodusPlan2(cwd);
43940
44378
  const plannedTarget = scope === "project" ? plan.projectDbPath : plan.globalDbPath;
43941
- if (resolve11(plannedTarget) !== resolve11(dbPath)) {
44379
+ if (resolve13(plannedTarget) !== resolve13(dbPath)) {
43942
44380
  return {
43943
44381
  outcome: "aborted",
43944
44382
  reason: `migration plan target ${plannedTarget} does not match opened database ${dbPath}; no migration applied`
43945
44383
  };
43946
44384
  }
43947
44385
  const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
43948
- if (!scopeSources.some((s) => existsSync26(s.path))) {
44386
+ if (!scopeSources.some((s) => existsSync27(s.path))) {
43949
44387
  return {
43950
44388
  outcome: "skipped",
43951
44389
  reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
@@ -43962,12 +44400,12 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43962
44400
  {
43963
44401
  scope,
43964
44402
  dbPath,
43965
- sources: plan.sources.filter((s) => existsSync26(s.path)).map((s) => s.name)
44403
+ sources: plan.sources.filter((s) => existsSync27(s.path)).map((s) => s.name)
43966
44404
  },
43967
44405
  "exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
43968
44406
  );
43969
44407
  _exodusInProgress = true;
43970
- const bareScratch = mkdtempSync2(join31(tmpdir4(), "cleo-exodus-bare-"));
44408
+ const bareScratch = mkdtempSync2(join32(tmpdir4(), "cleo-exodus-bare-"));
43971
44409
  try {
43972
44410
  const { buildRuntimeTargetResolver: buildRuntimeTargetResolver2 } = await Promise.resolve().then(() => (init_runtime_targets(), runtime_targets_exports));
43973
44411
  const resolveTarget = await buildRuntimeTargetResolver2();
@@ -43975,7 +44413,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43975
44413
  const bare = scope === "project" ? await unmigratedBareSources2(
43976
44414
  dbPath,
43977
44415
  resolveTarget,
43978
- plan.sources.find((s) => s.name === "tasks" && existsSync26(s.path))?.path,
44416
+ plan.sources.find((s) => s.name === "tasks" && existsSync27(s.path))?.path,
43979
44417
  bareScratch
43980
44418
  ) : { first: [], last: [] };
43981
44419
  const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
@@ -44039,7 +44477,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
44039
44477
  "exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
44040
44478
  );
44041
44479
  try {
44042
- const consumed = plan.sources.filter((s) => existsSync26(s.path));
44480
+ const consumed = plan.sources.filter((s) => existsSync27(s.path));
44043
44481
  const identities = await sealTargets(plan, consumed);
44044
44482
  const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
44045
44483
  log14.info(
@@ -44114,9 +44552,9 @@ __export(dual_scope_db_exports, {
44114
44552
  upsertIdempotent: () => upsertIdempotent,
44115
44553
  withStoreSchemaOwnership: () => withStoreSchemaOwnership
44116
44554
  });
44117
- import { existsSync as existsSync27, mkdirSync as mkdirSync8 } from "node:fs";
44118
- import { createRequire as createRequire9 } from "node:module";
44119
- import { dirname as dirname16, join as join32, resolve as resolve12 } from "node:path";
44555
+ import { existsSync as existsSync28, mkdirSync as mkdirSync8 } from "node:fs";
44556
+ import { createRequire as createRequire10 } from "node:module";
44557
+ import { dirname as dirname18, join as join33, resolve as resolve14 } from "node:path";
44120
44558
  function getDualScopeNativeDb(handle) {
44121
44559
  const db = handle.db;
44122
44560
  if ("$client" in db && db.$client instanceof getDatabaseSyncCtor()) return db.$client;
@@ -44138,9 +44576,9 @@ function cacheKey(scope, dbPath) {
44138
44576
  }
44139
44577
  function resolveDualScopeDbPath(scope, cwd, capturedGlobalHome) {
44140
44578
  if (scope === "project") {
44141
- return join32(resolveCleoDir(cwd), "cleo.db");
44579
+ return join33(resolveCleoDir(cwd), "cleo.db");
44142
44580
  }
44143
- return join32(capturedGlobalHome ?? getCleoHome(), "cleo.db");
44581
+ return join33(capturedGlobalHome ?? getCleoHome(), "cleo.db");
44144
44582
  }
44145
44583
  function migrationsSetName(scope) {
44146
44584
  return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
@@ -44190,8 +44628,8 @@ async function openDualScopeDb(scope, cwd, options) {
44190
44628
  async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44191
44629
  execution?.assertActive();
44192
44630
  log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
44193
- const dir = dirname16(dbPath);
44194
- if (!existsSync27(dir)) {
44631
+ const dir = dirname18(dbPath);
44632
+ if (!existsSync28(dir)) {
44195
44633
  mkdirSync8(dir, { recursive: true });
44196
44634
  }
44197
44635
  execution?.assertActive();
@@ -44199,6 +44637,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44199
44637
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
44200
44638
  try {
44201
44639
  applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
44640
+ installSchemaWriteGuard(nativeDb);
44202
44641
  const drizzle2 = getDrizzle();
44203
44642
  const db = drizzle2({ client: nativeDb });
44204
44643
  const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
@@ -44247,11 +44686,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44247
44686
  execution?.assertActive();
44248
44687
  return handle;
44249
44688
  } catch (err) {
44689
+ const explained = explainSchemaWriteDenial(nativeDb, err);
44250
44690
  try {
44251
44691
  nativeDb.close();
44252
44692
  } catch {
44253
44693
  }
44254
- throw err;
44694
+ throw explained;
44255
44695
  }
44256
44696
  }
44257
44697
  async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
@@ -44272,7 +44712,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44272
44712
  );
44273
44713
  }
44274
44714
  const dedicated = options?.dedicated === true;
44275
- const normalizedPath = resolve12(dbPath);
44715
+ const normalizedPath = resolve14(dbPath);
44276
44716
  const key = cacheKey(scope, normalizedPath);
44277
44717
  if (!dedicated) {
44278
44718
  const existing = _cache.get(key);
@@ -44309,8 +44749,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44309
44749
  }
44310
44750
  let initResolve = null;
44311
44751
  let initReject = null;
44312
- const initPromise = new Promise((resolve15, reject) => {
44313
- initResolve = resolve15;
44752
+ const initPromise = new Promise((resolve17, reject) => {
44753
+ initResolve = resolve17;
44314
44754
  initReject = reject;
44315
44755
  });
44316
44756
  _cache.set(key, {
@@ -44331,8 +44771,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44331
44771
  try {
44332
44772
  execution?.assertActive();
44333
44773
  log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
44334
- const dir = dirname16(normalizedPath);
44335
- if (!existsSync27(dir)) {
44774
+ const dir = dirname18(normalizedPath);
44775
+ if (!existsSync28(dir)) {
44336
44776
  mkdirSync8(dir, { recursive: true });
44337
44777
  }
44338
44778
  execution?.assertActive();
@@ -44340,6 +44780,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44340
44780
  const nativeDb = new DatabaseSyncCtor(normalizedPath, { allowExtension: true });
44341
44781
  openingNative = nativeDb;
44342
44782
  applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
44783
+ installSchemaWriteGuard(nativeDb);
44343
44784
  const drizzle2 = getDrizzle();
44344
44785
  const db = drizzle2({ client: nativeDb });
44345
44786
  const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
@@ -44470,12 +44911,13 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44470
44911
  execution?.assertActive();
44471
44912
  initResolve(finalHandle);
44472
44913
  } catch (err) {
44914
+ const explained = openingNative ? explainSchemaWriteDenial(openingNative, err) : err;
44473
44915
  try {
44474
44916
  if (!published && openingNative?.isOpen) openingNative.close();
44475
44917
  } catch (closeError) {
44476
44918
  log15.warn({ closeError }, "failed to close unpublished database initializer");
44477
44919
  }
44478
- initReject(err);
44920
+ initReject(explained);
44479
44921
  }
44480
44922
  })();
44481
44923
  return initPromise;
@@ -44548,6 +44990,7 @@ var init_dual_scope_db = __esm({
44548
44990
  init_relocated_store_guard();
44549
44991
  init_resolve_migrations_folder();
44550
44992
  init_sqlite_pragmas();
44993
+ init_worktree_build_guard();
44551
44994
  init_worktree_isolation_guard();
44552
44995
  init_writer_lease();
44553
44996
  ExodusAbortWriteUnsafeError = class extends Error {
@@ -44570,7 +45013,7 @@ var init_dual_scope_db = __esm({
44570
45013
  }
44571
45014
  };
44572
45015
  _cache = /* @__PURE__ */ new Map();
44573
- _require6 = createRequire9(import.meta.url);
45016
+ _require6 = createRequire10(import.meta.url);
44574
45017
  _drizzle4 = null;
44575
45018
  _DatabaseSyncCtor = null;
44576
45019
  EntryCancelledError = class extends Error {
@@ -44601,7 +45044,7 @@ var init_dual_scope_db = __esm({
44601
45044
  }
44602
45045
  /** @inheritdoc */
44603
45046
  async openProject(dbPath, options) {
44604
- const normalized = resolve12(dbPath);
45047
+ const normalized = resolve14(dbPath);
44605
45048
  if (options?.dedicated) {
44606
45049
  const handle = await openDualScopeDbAtPath("project", normalized, options?.exodusCwd, {
44607
45050
  dedicated: true
@@ -44613,7 +45056,7 @@ var init_dual_scope_db = __esm({
44613
45056
  /** @inheritdoc */
44614
45057
  async openGlobal(options) {
44615
45058
  const dbPath = resolveDualScopeDbPath("global");
44616
- const normalized = resolve12(dbPath);
45059
+ const normalized = resolve14(dbPath);
44617
45060
  if (options?.dedicated) {
44618
45061
  const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
44619
45062
  dedicated: true
@@ -44624,7 +45067,7 @@ var init_dual_scope_db = __esm({
44624
45067
  }
44625
45068
  /** @inheritdoc */
44626
45069
  async openGlobalAt(dbPath, options) {
44627
- const normalized = resolve12(dbPath);
45070
+ const normalized = resolve14(dbPath);
44628
45071
  if (options?.dedicated) {
44629
45072
  const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
44630
45073
  dedicated: true
@@ -44635,7 +45078,7 @@ var init_dual_scope_db = __esm({
44635
45078
  }
44636
45079
  /** @inheritdoc */
44637
45080
  closeProject(dbPath) {
44638
- const normalized = resolve12(dbPath);
45081
+ const normalized = resolve14(dbPath);
44639
45082
  this.closeEntry("project", normalized);
44640
45083
  }
44641
45084
  /** @inheritdoc */
@@ -44672,8 +45115,8 @@ var init_dual_scope_db = __esm({
44672
45115
  const entryId = ++this._nextId;
44673
45116
  let initResolve;
44674
45117
  let initReject;
44675
- const initPromise = new Promise((resolve15, reject) => {
44676
- initResolve = resolve15;
45118
+ const initPromise = new Promise((resolve17, reject) => {
45119
+ initResolve = resolve17;
44677
45120
  initReject = reject;
44678
45121
  });
44679
45122
  this._registry.set(key, { id: entryId, store: null, initPromise });
@@ -45466,8 +45909,8 @@ __export(nexus_sqlite_exports, {
45466
45909
  resetNexusDbState: () => resetNexusDbState,
45467
45910
  resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
45468
45911
  });
45469
- import { copyFileSync as copyFileSync7, existsSync as existsSync28 } from "node:fs";
45470
- import { join as join33 } from "node:path";
45912
+ import { copyFileSync as copyFileSync7, existsSync as existsSync29 } from "node:fs";
45913
+ import { join as join34 } from "node:path";
45471
45914
  function getNexusDbPath(cwd) {
45472
45915
  return resolveDualScopeDbPath("project", cwd);
45473
45916
  }
@@ -45503,12 +45946,13 @@ function ensureGlobalRegistryAttached(nativeDb) {
45503
45946
  }
45504
45947
  }
45505
45948
  nativeDb.exec(`ATTACH DATABASE '${escaped}' AS ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
45949
+ refreshSchemaWriteGuard(nativeDb);
45506
45950
  }
45507
45951
  function resolveNexusMigrationsFolder() {
45508
45952
  return resolveCorePackageMigrationsFolder("drizzle-nexus");
45509
45953
  }
45510
45954
  function getNestedNexusSentinelPath() {
45511
- return join33(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
45955
+ return join34(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
45512
45956
  }
45513
45957
  function detectAndWarnOnNestedNexus() {
45514
45958
  let nestedPath;
@@ -45517,7 +45961,7 @@ function detectAndWarnOnNestedNexus() {
45517
45961
  } catch {
45518
45962
  return false;
45519
45963
  }
45520
- if (!existsSync28(nestedPath)) return false;
45964
+ if (!existsSync29(nestedPath)) return false;
45521
45965
  if (_warnedNestedPaths.has(nestedPath)) return false;
45522
45966
  _warnedNestedPaths.add(nestedPath);
45523
45967
  const canonicalPath = getNexusDbPath();
@@ -45676,7 +46120,7 @@ function runNexusMigrations(nativeDb, db, dbPath) {
45676
46120
  const migrationsFolder = resolveNexusMigrationsFolder();
45677
46121
  if (tableExists4(nativeDb, "nexus_nodes")) {
45678
46122
  const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
45679
- if (!existsSync28(backupPath)) {
46123
+ if (!existsSync29(backupPath)) {
45680
46124
  try {
45681
46125
  copyFileSync7(dbPath, backupPath);
45682
46126
  } catch {
@@ -45771,6 +46215,7 @@ var init_nexus_sqlite = __esm({
45771
46215
  init_resolve_migrations_folder();
45772
46216
  init_nexus_schema();
45773
46217
  init_with_retry();
46218
+ init_worktree_build_guard();
45774
46219
  NEXUS_SCHEMA_VERSION = "1.0.0";
45775
46220
  NEXUS_GLOBAL_ATTACH_ALIAS = "nexus_global";
45776
46221
  NESTED_NEXUS_SENTINEL = "nexus.db";
@@ -45805,15 +46250,15 @@ var init_legacy_alias = __esm({
45805
46250
 
45806
46251
  // packages/core/src/llm/stable-device-id.ts
45807
46252
  import { randomUUID as randomUUID3 } from "node:crypto";
45808
- import { existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync9, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
45809
- import { dirname as dirname17 } from "node:path";
46253
+ import { existsSync as existsSync30, mkdirSync as mkdirSync9, readFileSync as readFileSync10, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
46254
+ import { dirname as dirname19 } from "node:path";
45810
46255
  import { resolveStableDeviceIdPath } from "@cleocode/paths";
45811
46256
  function getStableDeviceId() {
45812
46257
  if (_cachedDeviceId !== null) return _cachedDeviceId;
45813
46258
  const path = resolveStableDeviceIdPath();
45814
- if (existsSync29(path)) {
46259
+ if (existsSync30(path)) {
45815
46260
  try {
45816
- const raw = readFileSync9(path, "utf-8").trim();
46261
+ const raw = readFileSync10(path, "utf-8").trim();
45817
46262
  if (raw.length > 0) {
45818
46263
  _cachedDeviceId = raw;
45819
46264
  return raw;
@@ -45823,8 +46268,8 @@ function getStableDeviceId() {
45823
46268
  }
45824
46269
  const fresh = randomUUID3();
45825
46270
  try {
45826
- const dir = dirname17(path);
45827
- if (!existsSync29(dir)) {
46271
+ const dir = dirname19(path);
46272
+ if (!existsSync30(dir)) {
45828
46273
  mkdirSync9(dir, { recursive: true });
45829
46274
  }
45830
46275
  const tmpPath = `${path}.tmp.${process.pid}`;
@@ -45861,8 +46306,8 @@ var init_registry_roots = __esm({
45861
46306
  // packages/core/src/nexus/projects-scan.ts
45862
46307
  async function withinBudget(promise2, ms) {
45863
46308
  let timer;
45864
- const expiry = new Promise((resolve15) => {
45865
- timer = setTimeout(() => resolve15("timeout"), ms);
46309
+ const expiry = new Promise((resolve17) => {
46310
+ timer = setTimeout(() => resolve17("timeout"), ms);
45866
46311
  timer.unref();
45867
46312
  });
45868
46313
  try {
@@ -45900,9 +46345,9 @@ __export(path_map_exports, {
45900
46345
  supersededRegistryPath: () => supersededRegistryPath,
45901
46346
  touchProjectLocation: () => touchProjectLocation
45902
46347
  });
45903
- import { existsSync as existsSync30, lstatSync, readdirSync as readdirSync7 } from "node:fs";
46348
+ import { existsSync as existsSync31, lstatSync, readdirSync as readdirSync7 } from "node:fs";
45904
46349
  import { lstat, readdir as readdir2 } from "node:fs/promises";
45905
- import { isAbsolute as isAbsolute4, join as join34, relative as relative2, sep as sep4 } from "node:path";
46350
+ import { isAbsolute as isAbsolute5, join as join35, relative as relative3, sep as sep5 } from "node:path";
45906
46351
  import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity3 } from "@cleocode/paths";
45907
46352
  import { and as and7, desc as desc3, eq as eq11, inArray as inArray5, ne as ne3 } from "drizzle-orm";
45908
46353
  function holdingKey(projectId, path) {
@@ -45918,7 +46363,7 @@ function isSupersededRegistryPath(projectPath) {
45918
46363
  return projectPath.startsWith(SUPERSEDED_PATH_PREFIX);
45919
46364
  }
45920
46365
  function projectHolding(path, projectId) {
45921
- const cleoDir = join34(path, ".cleo");
46366
+ const cleoDir = join35(path, ".cleo");
45922
46367
  try {
45923
46368
  lstatSync(cleoDir);
45924
46369
  readdirSync7(cleoDir);
@@ -45930,7 +46375,7 @@ function projectHolding(path, projectId) {
45930
46375
  return declared === null || declared.projectId === projectId ? "yes" : "no";
45931
46376
  }
45932
46377
  async function probeProjectHolding(path, projectId, timeoutMs) {
45933
- const cleoDir = join34(path, ".cleo");
46378
+ const cleoDir = join35(path, ".cleo");
45934
46379
  const probe = async () => {
45935
46380
  try {
45936
46381
  await lstat(cleoDir);
@@ -45948,8 +46393,8 @@ async function probeProjectHolding(path, projectId, timeoutMs) {
45948
46393
  return declared === null || declared.projectId === projectId ? "yes" : "no";
45949
46394
  }
45950
46395
  function isStrictlyInside(outer, inner) {
45951
- const rel = relative2(canonicalizePath3(outer), canonicalizePath3(inner));
45952
- return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep4}`) && !isAbsolute4(rel);
46396
+ const rel = relative3(canonicalizePath3(outer), canonicalizePath3(inner));
46397
+ return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep5}`) && !isAbsolute5(rel);
45953
46398
  }
45954
46399
  function locationKey(projectId, deviceId, path) {
45955
46400
  return and7(
@@ -46111,7 +46556,7 @@ function hasOtherLiveLocation(db, record2, deviceId) {
46111
46556
  ne3(projectLocations.path, record2.projectPath)
46112
46557
  )
46113
46558
  ).all().some(
46114
- (location) => isStrictlyInside(record2.projectPath, location.path) && existsSync30(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record2.projectId
46559
+ (location) => isStrictlyInside(record2.projectPath, location.path) && existsSync31(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record2.projectId
46115
46560
  );
46116
46561
  }
46117
46562
  function demoteProjectLocation(db, record2, state) {
@@ -46162,7 +46607,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
46162
46607
  ).orderBy(desc3(projectLocations.lastSeen)).all();
46163
46608
  const present = (path) => {
46164
46609
  const holding = probed?.get(holdingKey(row.projectId, path));
46165
- return holding === void 0 ? existsSync30(path) : holding === "yes";
46610
+ return holding === void 0 ? existsSync31(path) : holding === "yes";
46166
46611
  };
46167
46612
  const home = candidates.find(
46168
46613
  (c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq11(projectRegistry.projectPath, c.path)).all().length === 0
@@ -46191,7 +46636,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
46191
46636
  projectHash: generateProjectHash(row.path),
46192
46637
  firstSeen: row.firstSeen,
46193
46638
  lastSeen: row.lastSeen,
46194
- exists: local && existsSync30(row.path),
46639
+ exists: local && existsSync31(row.path),
46195
46640
  deviceId: local ? deviceId : row.deviceId,
46196
46641
  state: row.state
46197
46642
  });
@@ -46220,13 +46665,13 @@ __export(checkout_nonce_exports, {
46220
46665
  readCheckoutNonce: () => readCheckoutNonce
46221
46666
  });
46222
46667
  import { randomBytes as randomBytes2 } from "node:crypto";
46223
- import { existsSync as existsSync31, readFileSync as readFileSync10, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
46224
- import { join as join35 } from "node:path";
46668
+ import { existsSync as existsSync32, readFileSync as readFileSync11, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
46669
+ import { join as join36 } from "node:path";
46225
46670
  function readInfo(projectRoot) {
46226
- const path = join35(projectRoot, ".cleo", "project-info.json");
46227
- if (!existsSync31(path)) return null;
46671
+ const path = join36(projectRoot, ".cleo", "project-info.json");
46672
+ if (!existsSync32(path)) return null;
46228
46673
  try {
46229
- const parsed = JSON.parse(readFileSync10(path, "utf-8"));
46674
+ const parsed = JSON.parse(readFileSync11(path, "utf-8"));
46230
46675
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
46231
46676
  } catch {
46232
46677
  return null;
@@ -46242,7 +46687,7 @@ function ensureCheckoutNonce(projectRoot) {
46242
46687
  const info = readInfo(projectRoot);
46243
46688
  if (!info) return null;
46244
46689
  const nonce = randomBytes2(16).toString("hex");
46245
- const path = join35(projectRoot, ".cleo", "project-info.json");
46690
+ const path = join36(projectRoot, ".cleo", "project-info.json");
46246
46691
  const temp = `${path}.${randomBytes2(6).toString("hex")}.tmp`;
46247
46692
  writeFileSync9(temp, `${JSON.stringify({ ...info, [CHECKOUT_NONCE_FIELD]: nonce }, null, 2)}
46248
46693
  `);
@@ -46317,10 +46762,10 @@ __export(paths_exports, {
46317
46762
  validateProjectRoot: () => validateProjectRoot,
46318
46763
  worktreeScope: () => worktreeScope
46319
46764
  });
46320
- import { existsSync as existsSync32, readFileSync as readFileSync11, statSync as statSync9 } from "node:fs";
46321
- import { createRequire as createRequire10 } from "node:module";
46765
+ import { existsSync as existsSync33, readFileSync as readFileSync12, statSync as statSync9 } from "node:fs";
46766
+ import { createRequire as createRequire11 } from "node:module";
46322
46767
  import { homedir as homedir2 } from "node:os";
46323
- import { basename as basename10, dirname as dirname18, join as join36, resolve as resolve13 } from "node:path";
46768
+ import { basename as basename10, dirname as dirname20, join as join37, resolve as resolve15 } from "node:path";
46324
46769
  import {
46325
46770
  getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
46326
46771
  getCleoTemplatesTildePath as _getCleoTemplatesTildePath,
@@ -46330,7 +46775,7 @@ import {
46330
46775
  resolveCanonicalCleoDir as _resolveCanonicalCleoDir
46331
46776
  } from "@cleocode/paths";
46332
46777
  function _getDatabaseSyncCtor() {
46333
- const _require7 = createRequire10(import.meta.url);
46778
+ const _require7 = createRequire11(import.meta.url);
46334
46779
  const mod = _require7("node:sqlite");
46335
46780
  return mod.DatabaseSync;
46336
46781
  }
@@ -46342,20 +46787,20 @@ function runWithWorktreeScopeFromEnv(fn) {
46342
46787
  }
46343
46788
  function isProjectInitialized(projectRoot) {
46344
46789
  const root = projectRoot ?? getProjectRoot();
46345
- const cleoDir = join36(root, ".cleo");
46346
- return existsSync32(cleoDir) && existsSync32(join36(cleoDir, "tasks.db"));
46790
+ const cleoDir = join37(root, ".cleo");
46791
+ return existsSync33(cleoDir) && existsSync33(join37(cleoDir, "tasks.db"));
46347
46792
  }
46348
46793
  function getCleoHome() {
46349
46794
  return getPlatformPaths().data;
46350
46795
  }
46351
46796
  function getCleoTemplatesDir() {
46352
- return join36(getCleoHome(), "templates");
46797
+ return join37(getCleoHome(), "templates");
46353
46798
  }
46354
46799
  function getCleoSchemasDir() {
46355
- return join36(getCleoHome(), "schemas");
46800
+ return join37(getCleoHome(), "schemas");
46356
46801
  }
46357
46802
  function getCleoDocsDir() {
46358
- return join36(getCleoHome(), "docs");
46803
+ return join37(getCleoHome(), "docs");
46359
46804
  }
46360
46805
  function getCleoDir(cwd) {
46361
46806
  if (cwd) {
@@ -46404,24 +46849,24 @@ function getCleoDirAbsolute(cwd, opts) {
46404
46849
  try {
46405
46850
  const projectRoot = getProjectRoot(cwd);
46406
46851
  const canonical = _resolveCanonicalCleoDir(project.projectId);
46407
- if (canonical !== null && canonical === resolve13(projectRoot, cleoDir)) {
46852
+ if (canonical !== null && canonical === resolve15(projectRoot, cleoDir)) {
46408
46853
  return canonical;
46409
46854
  }
46410
- return resolve13(projectRoot, cleoDir);
46855
+ return resolve15(projectRoot, cleoDir);
46411
46856
  } catch {
46412
- return resolve13(project.projectRoot, cleoDir);
46857
+ return resolve15(project.projectRoot, cleoDir);
46413
46858
  }
46414
46859
  }
46415
46860
  try {
46416
- return resolve13(getProjectRoot(cwd), cleoDir);
46861
+ return resolve15(getProjectRoot(cwd), cleoDir);
46417
46862
  } catch (err) {
46418
46863
  if (opts?.bootstrap) {
46419
- return resolve13(cwd ?? process.cwd(), cleoDir);
46864
+ return resolve15(cwd ?? process.cwd(), cleoDir);
46420
46865
  }
46421
46866
  if (_cwdHasGitAncestor(cwd)) {
46422
46867
  throw err;
46423
46868
  }
46424
- return resolve13(cwd ?? process.cwd(), cleoDir);
46869
+ return resolve15(cwd ?? process.cwd(), cleoDir);
46425
46870
  }
46426
46871
  }
46427
46872
  function resolveCanonicalCleoDir(projectId) {
@@ -46448,9 +46893,9 @@ function resolveCanonicalCleoDir(projectId) {
46448
46893
  function _resolveProjectByCwdFromNexus(cwd) {
46449
46894
  try {
46450
46895
  const cleoHome = getCleoHome();
46451
- const globalDbPath = join36(cleoHome, "cleo.db");
46452
- if (!existsSync32(globalDbPath)) return null;
46453
- const start = resolve13(cwd ?? process.cwd());
46896
+ const globalDbPath = join37(cleoHome, "cleo.db");
46897
+ if (!existsSync33(globalDbPath)) return null;
46898
+ const start = resolve15(cwd ?? process.cwd());
46454
46899
  let current = start;
46455
46900
  const DatabaseSync3 = _getDatabaseSyncCtor();
46456
46901
  const db = new DatabaseSync3(globalDbPath, { readOnly: true });
@@ -46463,7 +46908,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
46463
46908
  if (row && typeof row.project_id === "string" && row.project_id.length > 0) {
46464
46909
  return row.project_id;
46465
46910
  }
46466
- const parent = dirname18(current);
46911
+ const parent = dirname20(current);
46467
46912
  if (parent === current) break;
46468
46913
  current = parent;
46469
46914
  }
@@ -46483,18 +46928,18 @@ function _cleoDirEnvOverride() {
46483
46928
  }
46484
46929
  function _findCleoDirRoot(cwd) {
46485
46930
  const homeRoot = homedir2();
46486
- let current = resolve13(cwd ?? process.cwd());
46931
+ let current = resolve15(cwd ?? process.cwd());
46487
46932
  while (true) {
46488
46933
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
46489
46934
  if (!isDangerousRoot) {
46490
46935
  try {
46491
- if (statSync9(join36(current, ".cleo")).isDirectory()) {
46936
+ if (statSync9(join37(current, ".cleo")).isDirectory()) {
46492
46937
  return current;
46493
46938
  }
46494
46939
  } catch {
46495
46940
  }
46496
46941
  }
46497
- const parent = dirname18(current);
46942
+ const parent = dirname20(current);
46498
46943
  if (parent === current) break;
46499
46944
  current = parent;
46500
46945
  }
@@ -46513,7 +46958,7 @@ function resolveProjectByCwd(cwd) {
46513
46958
  if (pathsResult !== null) {
46514
46959
  return pathsResult.projectId;
46515
46960
  }
46516
- const start = resolve13(from ?? process.cwd());
46961
+ const start = resolve15(from ?? process.cwd());
46517
46962
  let current = start;
46518
46963
  while (true) {
46519
46964
  const mainRepo = _resolveMainRepoFromGitlink(current);
@@ -46524,7 +46969,7 @@ function resolveProjectByCwd(cwd) {
46524
46969
  }
46525
46970
  break;
46526
46971
  }
46527
- const parent = dirname18(current);
46972
+ const parent = dirname20(current);
46528
46973
  if (parent === current) break;
46529
46974
  current = parent;
46530
46975
  }
@@ -46543,7 +46988,7 @@ function resolveProjectByCwd(cwd) {
46543
46988
  function resolveCleoDir(cwd) {
46544
46989
  const scope = worktreeScope.getStore();
46545
46990
  if (scope !== void 0) {
46546
- return join36(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
46991
+ return join37(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
46547
46992
  }
46548
46993
  const override = _cleoDirEnvOverride();
46549
46994
  if (override !== null) {
@@ -46551,16 +46996,16 @@ function resolveCleoDir(cwd) {
46551
46996
  }
46552
46997
  const root = _findCleoDirRoot(cwd);
46553
46998
  if (root !== null) {
46554
- return join36(resolveStoreOwnerRoot(root), ".cleo");
46999
+ return join37(resolveStoreOwnerRoot(root), ".cleo");
46555
47000
  }
46556
- const start = resolve13(cwd ?? process.cwd());
47001
+ const start = resolve15(cwd ?? process.cwd());
46557
47002
  let current = start;
46558
47003
  while (true) {
46559
47004
  const mainRepo = _resolveMainRepoFromGitlink(current);
46560
47005
  if (mainRepo !== null) {
46561
- return join36(mainRepo, ".cleo");
47006
+ return join37(mainRepo, ".cleo");
46562
47007
  }
46563
- const parent = dirname18(current);
47008
+ const parent = dirname20(current);
46564
47009
  if (parent === current) {
46565
47010
  break;
46566
47011
  }
@@ -46599,25 +47044,25 @@ function _resolveCleoDir(cwd) {
46599
47044
  const project = _pathsResolveProjectByCwd(cwd);
46600
47045
  if (project !== null) {
46601
47046
  try {
46602
- return resolve13(getProjectRoot(cwd), cleoDir);
47047
+ return resolve15(getProjectRoot(cwd), cleoDir);
46603
47048
  } catch {
46604
- return resolve13(project.projectRoot, cleoDir);
47049
+ return resolve15(project.projectRoot, cleoDir);
46605
47050
  }
46606
47051
  }
46607
47052
  return getCleoDirAbsolute(cwd);
46608
47053
  }
46609
47054
  function _cwdHasGitAncestor(cwd) {
46610
- const start = resolve13(cwd ?? process.cwd());
47055
+ const start = resolve15(cwd ?? process.cwd());
46611
47056
  let current = start;
46612
47057
  while (true) {
46613
- const gitMarker = join36(current, ".git");
47058
+ const gitMarker = join37(current, ".git");
46614
47059
  try {
46615
- if (existsSync32(gitMarker)) {
47060
+ if (existsSync33(gitMarker)) {
46616
47061
  return true;
46617
47062
  }
46618
47063
  } catch {
46619
47064
  }
46620
- const parent = dirname18(current);
47065
+ const parent = dirname20(current);
46621
47066
  if (parent === current) return false;
46622
47067
  current = parent;
46623
47068
  }
@@ -46644,55 +47089,55 @@ function resolveProjectPath(relativePath, cwd) {
46644
47089
  return relativePath;
46645
47090
  }
46646
47091
  if (relativePath.startsWith("~/") || relativePath.startsWith("~\\") || relativePath === "~") {
46647
- return resolve13(homedir2(), relativePath.slice(2));
47092
+ return resolve15(homedir2(), relativePath.slice(2));
46648
47093
  }
46649
- return resolve13(getProjectRoot(cwd), relativePath);
47094
+ return resolve15(getProjectRoot(cwd), relativePath);
46650
47095
  }
46651
47096
  function getTaskPath(cwd) {
46652
- return join36(_resolveCleoDir(cwd), "tasks.db");
47097
+ return join37(_resolveCleoDir(cwd), "tasks.db");
46653
47098
  }
46654
47099
  function getConfigPath(cwd) {
46655
- return join36(_resolveCleoDir(cwd), "config.json");
47100
+ return join37(_resolveCleoDir(cwd), "config.json");
46656
47101
  }
46657
47102
  function getSessionsPath(cwd) {
46658
- return join36(_resolveCleoDir(cwd), "sessions.json");
47103
+ return join37(_resolveCleoDir(cwd), "sessions.json");
46659
47104
  }
46660
47105
  function getArchivePath(cwd) {
46661
- return join36(_resolveCleoDir(cwd), "tasks-archive.json");
47106
+ return join37(_resolveCleoDir(cwd), "tasks-archive.json");
46662
47107
  }
46663
47108
  function getLogPath(cwd) {
46664
- return join36(_resolveCleoDir(cwd), "logs", "cleo.log");
47109
+ return join37(_resolveCleoDir(cwd), "logs", "cleo.log");
46665
47110
  }
46666
47111
  function getBackupDir(cwd) {
46667
- return join36(_resolveCleoDir(cwd), "backups", "operational");
47112
+ return join37(_resolveCleoDir(cwd), "backups", "operational");
46668
47113
  }
46669
47114
  function getGlobalConfigPath() {
46670
- return join36(getCleoHome(), "config.json");
47115
+ return join37(getCleoHome(), "config.json");
46671
47116
  }
46672
47117
  function getCleoGlobalRecipesDir() {
46673
- return join36(getCleoHome(), "global-recipes");
47118
+ return join37(getCleoHome(), "global-recipes");
46674
47119
  }
46675
47120
  function getCleoGlobalJustfilePath() {
46676
- return join36(getCleoGlobalRecipesDir(), "justfile");
47121
+ return join37(getCleoGlobalRecipesDir(), "justfile");
46677
47122
  }
46678
47123
  function getCleoPiExtensionsDir() {
46679
- return join36(getCleoHome(), "pi-extensions");
47124
+ return join37(getCleoHome(), "pi-extensions");
46680
47125
  }
46681
47126
  function getCleoCantWorkflowsDir() {
46682
- return join36(getCleoHome(), "cant-workflows");
47127
+ return join37(getCleoHome(), "cant-workflows");
46683
47128
  }
46684
47129
  function getCleoGlobalAgentsDir() {
46685
- return join36(getCleoHome(), "agents");
47130
+ return join37(getCleoHome(), "agents");
46686
47131
  }
46687
47132
  function getCleoGlobalCantAgentsDir() {
46688
- return join36(getCleoHome(), "cant", "agents");
47133
+ return join37(getCleoHome(), "cant", "agents");
46689
47134
  }
46690
47135
  function getAgentOutputsDir(cwd) {
46691
47136
  const projectRoot = getProjectRoot(cwd);
46692
- const configPath = join36(projectRoot, ".cleo", "config.json");
46693
- if (existsSync32(configPath)) {
47137
+ const configPath = join37(projectRoot, ".cleo", "config.json");
47138
+ if (existsSync33(configPath)) {
46694
47139
  try {
46695
- const config2 = JSON.parse(readFileSync11(configPath, "utf-8"));
47140
+ const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
46696
47141
  if (typeof config2.agentOutputs === "object" && config2.agentOutputs?.directory) {
46697
47142
  return config2.agentOutputs.directory;
46698
47143
  }
@@ -46715,17 +47160,17 @@ function getAgentOutputsAbsolute(cwd) {
46715
47160
  if (isAbsolutePath2(dir)) {
46716
47161
  return dir;
46717
47162
  }
46718
- return resolve13(getProjectRoot(cwd), dir);
47163
+ return resolve15(getProjectRoot(cwd), dir);
46719
47164
  }
46720
47165
  function getManifestPath(cwd) {
46721
47166
  const outputDir = getAgentOutputsDir(cwd);
46722
47167
  const projectRoot = getProjectRoot(cwd);
46723
- const configPath = join36(projectRoot, ".cleo", "config.json");
47168
+ const configPath = join37(projectRoot, ".cleo", "config.json");
46724
47169
  const legacyFileName = ["MANIFEST", "jsonl"].join(".");
46725
47170
  let manifestFile = legacyFileName;
46726
- if (existsSync32(configPath)) {
47171
+ if (existsSync33(configPath)) {
46727
47172
  try {
46728
- const config2 = JSON.parse(readFileSync11(configPath, "utf-8"));
47173
+ const config2 = JSON.parse(readFileSync12(configPath, "utf-8"));
46729
47174
  const customFile = config2.agentOutputs?.manifestFile ?? config2.research?.manifestFile;
46730
47175
  if (customFile) {
46731
47176
  manifestFile = customFile;
@@ -46733,12 +47178,12 @@ function getManifestPath(cwd) {
46733
47178
  } catch {
46734
47179
  }
46735
47180
  }
46736
- return resolve13(projectRoot, outputDir, manifestFile);
47181
+ return resolve15(projectRoot, outputDir, manifestFile);
46737
47182
  }
46738
47183
  function getManifestArchivePath(cwd) {
46739
47184
  const outputDir = getAgentOutputsDir(cwd);
46740
47185
  const projectRoot = getProjectRoot(cwd);
46741
- return resolve13(projectRoot, outputDir, "MANIFEST.archive.jsonl");
47186
+ return resolve15(projectRoot, outputDir, "MANIFEST.archive.jsonl");
46742
47187
  }
46743
47188
  function isAbsolutePath2(path) {
46744
47189
  return _isAbsolutePath(path);
@@ -46762,24 +47207,24 @@ function getCanonicalTemplatesTildePath() {
46762
47207
  return _getCanonicalTemplatesTildePath();
46763
47208
  }
46764
47209
  function getAgentsHome() {
46765
- return process.env["AGENTS_HOME"] ?? join36(homedir2(), ".agents");
47210
+ return process.env["AGENTS_HOME"] ?? join37(homedir2(), ".agents");
46766
47211
  }
46767
47212
  function getClaudeAgentsDir() {
46768
- const claudeDir = process.env["CLAUDE_HOME"] ?? join36(homedir2(), ".claude");
46769
- return join36(claudeDir, "agents");
47213
+ const claudeDir = process.env["CLAUDE_HOME"] ?? join37(homedir2(), ".claude");
47214
+ return join37(claudeDir, "agents");
46770
47215
  }
46771
47216
  function getClaudeMemDbPath() {
46772
- return process.env["CLAUDE_MEM_DB"] ?? join36(homedir2(), ".claude-mem", "claude-mem.db");
47217
+ return process.env["CLAUDE_MEM_DB"] ?? join37(homedir2(), ".claude-mem", "claude-mem.db");
46773
47218
  }
46774
47219
  function resolveWorktreeRouting(cwdOverride) {
46775
- const cwd = resolve13(cwdOverride ?? process.cwd());
47220
+ const cwd = resolve15(cwdOverride ?? process.cwd());
46776
47221
  const home = homedir2();
46777
47222
  let worktreePath;
46778
47223
  let current = cwd;
46779
47224
  while (current !== home && current !== "/" && current !== "") {
46780
- const gitPath = join36(current, ".git");
47225
+ const gitPath = join37(current, ".git");
46781
47226
  try {
46782
- if (existsSync32(gitPath)) {
47227
+ if (existsSync33(gitPath)) {
46783
47228
  const stat3 = statSync9(gitPath);
46784
47229
  if (stat3.isFile()) {
46785
47230
  worktreePath = current;
@@ -46791,7 +47236,7 @@ function resolveWorktreeRouting(cwdOverride) {
46791
47236
  }
46792
47237
  } catch {
46793
47238
  }
46794
- const parent = dirname18(current);
47239
+ const parent = dirname20(current);
46795
47240
  if (parent === current) break;
46796
47241
  current = parent;
46797
47242
  }
@@ -46808,17 +47253,17 @@ function resolveWorktreeRouting(cwdOverride) {
46808
47253
  }
46809
47254
  function resolveWorktreeFilePath(filePath, routing) {
46810
47255
  if (!routing.isWorktree || routing.worktreePath === void 0) {
46811
- return resolve13(filePath);
47256
+ return resolve15(filePath);
46812
47257
  }
46813
- return resolve13(routing.cwd, filePath);
47258
+ return resolve15(routing.cwd, filePath);
46814
47259
  }
46815
47260
  function detectStrayCleoDb(routing) {
46816
47261
  if (!routing.isWorktree || routing.worktreePath === void 0) {
46817
47262
  return void 0;
46818
47263
  }
46819
- const tasksDbPath = join36(routing.worktreePath, ".cleo", "tasks.db");
47264
+ const tasksDbPath = join37(routing.worktreePath, ".cleo", "tasks.db");
46820
47265
  try {
46821
- if (existsSync32(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
47266
+ if (existsSync33(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
46822
47267
  return tasksDbPath;
46823
47268
  }
46824
47269
  } catch {
@@ -46828,7 +47273,7 @@ function detectStrayCleoDb(routing) {
46828
47273
  async function resolveProjectById(projectId) {
46829
47274
  try {
46830
47275
  const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
46831
- if (!existsSync32(getNexusRegistryDbPath2())) return null;
47276
+ if (!existsSync33(getNexusRegistryDbPath2())) return null;
46832
47277
  const { eq: eq12 } = await import("drizzle-orm");
46833
47278
  const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
46834
47279
  const db = await getNexusDb2();
@@ -46863,9 +47308,9 @@ function _rowToRegistryEntry(row) {
46863
47308
  };
46864
47309
  }
46865
47310
  function _readProjectNameFromInfo(projectRoot) {
46866
- const infoPath = join36(projectRoot, ".cleo", "project-info.json");
46867
- if (!existsSync32(infoPath)) return void 0;
46868
- const raw = readFileSync11(infoPath, "utf-8");
47311
+ const infoPath = join37(projectRoot, ".cleo", "project-info.json");
47312
+ if (!existsSync33(infoPath)) return void 0;
47313
+ const raw = readFileSync12(infoPath, "utf-8");
46869
47314
  const data = JSON.parse(raw);
46870
47315
  return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
46871
47316
  }
@@ -46916,7 +47361,7 @@ async function recordProjectEncounter(cwd) {
46916
47361
  if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
46917
47362
  const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
46918
47363
  const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
46919
- if (existsSync32(getNexusRegistryDbPath2(cleoHome))) {
47364
+ if (existsSync33(getNexusRegistryDbPath2(cleoHome))) {
46920
47365
  const { and: and8, eq: eq12 } = await import("drizzle-orm");
46921
47366
  const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
46922
47367
  const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));
@@ -47174,42 +47619,42 @@ var init_api_mode = __esm({
47174
47619
  // packages/core/src/store/file-utils.ts
47175
47620
  import { randomBytes as randomBytes3 } from "node:crypto";
47176
47621
  import {
47177
- existsSync as existsSync33,
47622
+ existsSync as existsSync34,
47178
47623
  mkdirSync as mkdirSync10,
47179
47624
  readdirSync as readdirSync8,
47180
- readFileSync as readFileSync12,
47625
+ readFileSync as readFileSync13,
47181
47626
  renameSync as renameSync11,
47182
47627
  unlinkSync as unlinkSync6,
47183
47628
  writeFileSync as writeFileSync10
47184
47629
  } from "node:fs";
47185
- import { basename as basename11, dirname as dirname19, join as join37 } from "node:path";
47630
+ import { basename as basename11, dirname as dirname21, join as join38 } from "node:path";
47186
47631
  import * as lockfile3 from "proper-lockfile";
47187
47632
  function rotateBackup(filePath, mode) {
47188
- const dir = dirname19(filePath);
47633
+ const dir = dirname21(filePath);
47189
47634
  const name15 = basename11(filePath);
47190
- const backupDir = join37(dir, ".backups");
47635
+ const backupDir = join38(dir, ".backups");
47191
47636
  const dirMode = typeof mode === "number" ? modeToDirMode(mode) : void 0;
47192
- if (!existsSync33(backupDir)) {
47637
+ if (!existsSync34(backupDir)) {
47193
47638
  mkdirSync10(backupDir, { recursive: true, mode: dirMode });
47194
47639
  }
47195
47640
  for (let i = MAX_BACKUPS; i >= 1; i--) {
47196
- const current = join37(backupDir, `${name15}.${i}`);
47641
+ const current = join38(backupDir, `${name15}.${i}`);
47197
47642
  if (i === MAX_BACKUPS) {
47198
47643
  try {
47199
47644
  unlinkSync6(current);
47200
47645
  } catch {
47201
47646
  }
47202
47647
  } else {
47203
- const next = join37(backupDir, `${name15}.${i + 1}`);
47648
+ const next = join38(backupDir, `${name15}.${i + 1}`);
47204
47649
  try {
47205
- if (existsSync33(current)) renameSync11(current, next);
47650
+ if (existsSync34(current)) renameSync11(current, next);
47206
47651
  } catch {
47207
47652
  }
47208
47653
  }
47209
47654
  }
47210
47655
  try {
47211
- const content = readFileSync12(filePath, "utf-8");
47212
- const backupPath = join37(backupDir, `${name15}.1`);
47656
+ const content = readFileSync13(filePath, "utf-8");
47657
+ const backupPath = join38(backupDir, `${name15}.1`);
47213
47658
  if (typeof mode === "number") {
47214
47659
  writeFileSync10(backupPath, content, { encoding: "utf-8", mode });
47215
47660
  } else {
@@ -47229,8 +47674,8 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
47229
47674
  const opts = typeof optsOrIndent === "number" ? { indent: optsOrIndent } : optsOrIndent;
47230
47675
  const indent = opts.indent ?? 2;
47231
47676
  const mode = opts.mode;
47232
- const dir = dirname19(filePath);
47233
- const tempPath = join37(dir, `.${basename11(filePath)}.${randomBytes3(6).toString("hex")}.tmp`);
47677
+ const dir = dirname21(filePath);
47678
+ const tempPath = join38(dir, `.${basename11(filePath)}.${randomBytes3(6).toString("hex")}.tmp`);
47234
47679
  const content = JSON.stringify(data, null, indent) + "\n";
47235
47680
  if (typeof mode === "number") {
47236
47681
  writeFileSync10(tempPath, content, { encoding: "utf-8", mode });
@@ -47238,7 +47683,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
47238
47683
  writeFileSync10(tempPath, content, "utf-8");
47239
47684
  }
47240
47685
  try {
47241
- if (existsSync33(filePath)) {
47686
+ if (existsSync34(filePath)) {
47242
47687
  rotateBackup(filePath, mode);
47243
47688
  }
47244
47689
  renameSync11(tempPath, filePath);
@@ -47252,7 +47697,7 @@ function writeJsonFileAtomic(filePath, data, optsOrIndent = 2) {
47252
47697
  }
47253
47698
  function readJsonFile(filePath) {
47254
47699
  try {
47255
- const content = readFileSync12(filePath, "utf-8");
47700
+ const content = readFileSync13(filePath, "utf-8");
47256
47701
  return JSON.parse(content);
47257
47702
  } catch (error48) {
47258
47703
  if (error48.code === "ENOENT") {
@@ -47262,12 +47707,12 @@ function readJsonFile(filePath) {
47262
47707
  }
47263
47708
  }
47264
47709
  async function withLock2(filePath, transform2, opts = {}) {
47265
- const dir = dirname19(filePath);
47710
+ const dir = dirname21(filePath);
47266
47711
  const dirMode = typeof opts.mode === "number" ? modeToDirMode(opts.mode) : void 0;
47267
- if (!existsSync33(dir)) {
47712
+ if (!existsSync34(dir)) {
47268
47713
  mkdirSync10(dir, { recursive: true, mode: dirMode });
47269
47714
  }
47270
- if (!existsSync33(filePath)) {
47715
+ if (!existsSync34(filePath)) {
47271
47716
  if (typeof opts.mode === "number") {
47272
47717
  writeFileSync10(filePath, "", { encoding: "utf-8", mode: opts.mode });
47273
47718
  } else {
@@ -47288,11 +47733,11 @@ async function withLock2(filePath, transform2, opts = {}) {
47288
47733
  }
47289
47734
  }
47290
47735
  async function withFileLock(filePath, operation) {
47291
- const dir = dirname19(filePath);
47292
- if (!existsSync33(dir)) {
47736
+ const dir = dirname21(filePath);
47737
+ if (!existsSync34(dir)) {
47293
47738
  mkdirSync10(dir, { recursive: true });
47294
47739
  }
47295
- if (!existsSync33(filePath)) {
47740
+ if (!existsSync34(filePath)) {
47296
47741
  writeFileSync10(filePath, "", "utf-8");
47297
47742
  }
47298
47743
  let release;
@@ -47326,7 +47771,7 @@ var init_file_utils = __esm({
47326
47771
 
47327
47772
  // packages/core/src/llm/credential-removal.ts
47328
47773
  import { unlinkSync as unlinkSync7 } from "node:fs";
47329
- import { join as join38 } from "node:path";
47774
+ import { join as join39 } from "node:path";
47330
47775
  import { getCleoHome as getCleoHome4 } from "@cleocode/paths";
47331
47776
  function buildBuiltinRemovalRegistry() {
47332
47777
  const registry2 = new RemovalRegistry();
@@ -47418,7 +47863,7 @@ var init_credential_removal = __esm({
47418
47863
  sourceId: "cleo-pkce",
47419
47864
  description: "Delete CLEO-issued PKCE token at <CLEO_HOME>/anthropic-oauth.json",
47420
47865
  async remove() {
47421
- const path = join38(getCleoHome4(), "anthropic-oauth.json");
47866
+ const path = join39(getCleoHome4(), "anthropic-oauth.json");
47422
47867
  const cleaned = [];
47423
47868
  try {
47424
47869
  unlinkSync7(path);
@@ -47476,12 +47921,12 @@ var init_credential_removal = __esm({
47476
47921
  });
47477
47922
 
47478
47923
  // packages/core/src/llm/credential-seeders/claude-code-seeder.ts
47479
- import { readFileSync as readFileSync13 } from "node:fs";
47924
+ import { readFileSync as readFileSync14 } from "node:fs";
47480
47925
  import { homedir as homedir3 } from "node:os";
47481
- import { join as join39 } from "node:path";
47926
+ import { join as join40 } from "node:path";
47482
47927
  function defaultReadCredentialFile() {
47483
47928
  try {
47484
- return readFileSync13(join39(homedir3(), ".claude", ".credentials.json"), "utf-8");
47929
+ return readFileSync14(join40(homedir3(), ".claude", ".credentials.json"), "utf-8");
47485
47930
  } catch {
47486
47931
  return null;
47487
47932
  }
@@ -47575,14 +48020,14 @@ var init_claude_code_seeder = __esm({
47575
48020
  });
47576
48021
 
47577
48022
  // packages/core/src/llm/credential-seeders/cleo-pkce-seeder.ts
47578
- import { readFileSync as readFileSync14 } from "node:fs";
47579
- import { join as join40 } from "node:path";
48023
+ import { readFileSync as readFileSync15 } from "node:fs";
48024
+ import { join as join41 } from "node:path";
47580
48025
  function defaultCleoPkcePath() {
47581
- return join40(getCleoHome(), "anthropic-oauth.json");
48026
+ return join41(getCleoHome(), "anthropic-oauth.json");
47582
48027
  }
47583
48028
  function defaultReadCredentialFile2() {
47584
48029
  try {
47585
- return readFileSync14(defaultCleoPkcePath(), "utf-8");
48030
+ return readFileSync15(defaultCleoPkcePath(), "utf-8");
47586
48031
  } catch {
47587
48032
  return null;
47588
48033
  }
@@ -47649,13 +48094,13 @@ var init_cleo_pkce_seeder = __esm({
47649
48094
  });
47650
48095
 
47651
48096
  // packages/core/src/llm/credential-seeders/codex-cli-seeder.ts
47652
- import { existsSync as existsSync34, readFileSync as readFileSync15 } from "node:fs";
48097
+ import { existsSync as existsSync35, readFileSync as readFileSync16 } from "node:fs";
47653
48098
  import { homedir as homedir4 } from "node:os";
47654
- import { join as join41 } from "node:path";
48099
+ import { join as join42 } from "node:path";
47655
48100
  function getCodexAuthPath() {
47656
48101
  const codexHome = (process.env["CODEX_HOME"] ?? "").trim();
47657
- const root = codexHome || join41(homedir4(), ".codex");
47658
- return join41(root, "auth.json");
48102
+ const root = codexHome || join42(homedir4(), ".codex");
48103
+ return join42(root, "auth.json");
47659
48104
  }
47660
48105
  var CodexCliSeeder, codexCliSeeder;
47661
48106
  var init_codex_cli_seeder = __esm({
@@ -47674,12 +48119,12 @@ var init_codex_cli_seeder = __esm({
47674
48119
  */
47675
48120
  async seed() {
47676
48121
  const authPath = getCodexAuthPath();
47677
- if (!existsSync34(authPath)) {
48122
+ if (!existsSync35(authPath)) {
47678
48123
  return { entries: [] };
47679
48124
  }
47680
48125
  let raw;
47681
48126
  try {
47682
- raw = readFileSync15(authPath, "utf-8");
48127
+ raw = readFileSync16(authPath, "utf-8");
47683
48128
  } catch (err) {
47684
48129
  return {
47685
48130
  entries: [],
@@ -47869,11 +48314,11 @@ var init_google_pkce = __esm({
47869
48314
  });
47870
48315
 
47871
48316
  // packages/core/src/llm/credential-seeders/gemini-cli-seeder.ts
47872
- import { existsSync as existsSync35, readFileSync as readFileSync16 } from "node:fs";
47873
- import { join as join42 } from "node:path";
48317
+ import { existsSync as existsSync36, readFileSync as readFileSync17 } from "node:fs";
48318
+ import { join as join43 } from "node:path";
47874
48319
  import { getCleoHome as getCleoHome5 } from "@cleocode/paths";
47875
48320
  function getGoogleOauthPath() {
47876
- return join42(getCleoHome5(), "google_oauth.json");
48321
+ return join43(getCleoHome5(), "google_oauth.json");
47877
48322
  }
47878
48323
  function parseGoogleOauthFile(raw) {
47879
48324
  let json2;
@@ -47918,12 +48363,12 @@ var init_gemini_cli_seeder = __esm({
47918
48363
  */
47919
48364
  async seed() {
47920
48365
  const path = getGoogleOauthPath();
47921
- if (!existsSync35(path)) {
48366
+ if (!existsSync36(path)) {
47922
48367
  return { entries: [] };
47923
48368
  }
47924
48369
  let raw;
47925
48370
  try {
47926
- raw = readFileSync16(path, "utf-8");
48371
+ raw = readFileSync17(path, "utf-8");
47927
48372
  } catch (err) {
47928
48373
  return {
47929
48374
  entries: [],
@@ -48143,23 +48588,23 @@ var init_credential_seeders = __esm({
48143
48588
 
48144
48589
  // packages/core/src/llm/global-config-migration.ts
48145
48590
  import {
48146
- existsSync as existsSync36,
48591
+ existsSync as existsSync37,
48147
48592
  mkdirSync as mkdirSync11,
48148
- readFileSync as readFileSync17,
48593
+ readFileSync as readFileSync18,
48149
48594
  renameSync as renameSync12,
48150
48595
  unlinkSync as unlinkSync8,
48151
48596
  writeFileSync as writeFileSync11
48152
48597
  } from "node:fs";
48153
- import { join as join43 } from "node:path";
48598
+ import { join as join44 } from "node:path";
48154
48599
  import { getCleoHome as getCleoHome6, getCleoPlatformPaths as getCleoPlatformPaths2 } from "@cleocode/paths";
48155
48600
  function configDirGlobalConfigPath() {
48156
- return join43(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
48601
+ return join44(getCleoPlatformPaths2().config, GLOBAL_CONFIG_FILENAME);
48157
48602
  }
48158
48603
  function legacyGlobalConfigPath() {
48159
- return join43(getCleoHome6(), GLOBAL_CONFIG_FILENAME);
48604
+ return join44(getCleoHome6(), GLOBAL_CONFIG_FILENAME);
48160
48605
  }
48161
48606
  function migrationMarkerPath() {
48162
- return join43(getCleoHome6(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
48607
+ return join44(getCleoHome6(), MIGRATIONS_SUBDIR, MIGRATION_MARKER);
48163
48608
  }
48164
48609
  function tempTargetPath() {
48165
48610
  return `${configDirGlobalConfigPath()}.tmp`;
@@ -48169,17 +48614,17 @@ function migrateGlobalConfigToConfigDir() {
48169
48614
  const source = legacyGlobalConfigPath();
48170
48615
  const target = configDirGlobalConfigPath();
48171
48616
  const marker16 = migrationMarkerPath();
48172
- if (existsSync36(marker16)) return false;
48173
- if (!existsSync36(source)) {
48617
+ if (existsSync37(marker16)) return false;
48618
+ if (!existsSync37(source)) {
48174
48619
  stampMarker(marker16);
48175
48620
  return false;
48176
48621
  }
48177
- if (existsSync36(target)) {
48622
+ if (existsSync37(target)) {
48178
48623
  backupSourceQuiet(source);
48179
48624
  stampMarker(marker16);
48180
48625
  return false;
48181
48626
  }
48182
- const raw = readFileSync17(source, "utf-8");
48627
+ const raw = readFileSync18(source, "utf-8");
48183
48628
  try {
48184
48629
  JSON.parse(raw);
48185
48630
  } catch (err) {
@@ -48207,7 +48652,7 @@ function migrateGlobalConfigToConfigDir() {
48207
48652
  } catch (err) {
48208
48653
  try {
48209
48654
  const temp = tempTargetPath();
48210
- if (existsSync36(temp)) unlinkSync8(temp);
48655
+ if (existsSync37(temp)) unlinkSync8(temp);
48211
48656
  } catch {
48212
48657
  }
48213
48658
  console.error(
@@ -48218,7 +48663,7 @@ function migrateGlobalConfigToConfigDir() {
48218
48663
  }
48219
48664
  function stampMarker(markerPath) {
48220
48665
  try {
48221
- mkdirSync11(join43(getCleoHome6(), MIGRATIONS_SUBDIR), { recursive: true });
48666
+ mkdirSync11(join44(getCleoHome6(), MIGRATIONS_SUBDIR), { recursive: true });
48222
48667
  writeFileSync11(markerPath, `${(/* @__PURE__ */ new Date()).toISOString()}
48223
48668
  `, { mode: 420 });
48224
48669
  } catch {
@@ -48227,7 +48672,7 @@ function stampMarker(markerPath) {
48227
48672
  function backupSourceQuiet(source) {
48228
48673
  try {
48229
48674
  const backup = `${source}${BACKUP_SUFFIX}`;
48230
- if (existsSync36(backup)) return;
48675
+ if (existsSync37(backup)) return;
48231
48676
  renameSync12(source, backup);
48232
48677
  } catch {
48233
48678
  }
@@ -48250,15 +48695,15 @@ var init_global_config_migration = __esm({
48250
48695
  });
48251
48696
 
48252
48697
  // packages/core/src/llm/legacy-flat-key-import.ts
48253
- import { existsSync as existsSync37, readFileSync as readFileSync18, renameSync as renameSync13, writeFileSync as writeFileSync12 } from "node:fs";
48254
- import { join as join44 } from "node:path";
48698
+ import { existsSync as existsSync38, readFileSync as readFileSync19, renameSync as renameSync13, writeFileSync as writeFileSync12 } from "node:fs";
48699
+ import { join as join45 } from "node:path";
48255
48700
  import { getCleoHome as getCleoHome7 } from "@cleocode/paths";
48256
48701
  function migrationPaths() {
48257
48702
  const home = getCleoHome7();
48258
48703
  return {
48259
- flatPath: join44(home, "anthropic-key"),
48260
- bakPath: join44(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
48261
- markerPath: join44(home, LEGACY_FLAT_KEY_MARKER)
48704
+ flatPath: join45(home, "anthropic-key"),
48705
+ bakPath: join45(home, `anthropic-key${LEGACY_FLAT_KEY_BAK_SUFFIX}`),
48706
+ markerPath: join45(home, LEGACY_FLAT_KEY_MARKER)
48262
48707
  };
48263
48708
  }
48264
48709
  function writeMarker(markerPath) {
@@ -48279,8 +48724,8 @@ function writeMarker(markerPath) {
48279
48724
  }
48280
48725
  function readFlatKey(flatPath) {
48281
48726
  try {
48282
- if (!existsSync37(flatPath)) return null;
48283
- const raw = readFileSync18(flatPath, "utf-8").trim();
48727
+ if (!existsSync38(flatPath)) return null;
48728
+ const raw = readFileSync19(flatPath, "utf-8").trim();
48284
48729
  return raw || null;
48285
48730
  } catch (err) {
48286
48731
  logger.warn(
@@ -48292,7 +48737,7 @@ function readFlatKey(flatPath) {
48292
48737
  }
48293
48738
  async function importLegacyFlatAnthropicKey() {
48294
48739
  const { flatPath, bakPath, markerPath } = migrationPaths();
48295
- if (existsSync37(markerPath)) {
48740
+ if (existsSync38(markerPath)) {
48296
48741
  return { status: "marker-present", flatPath, bakPath: null, markerPath };
48297
48742
  }
48298
48743
  let existing = null;
@@ -48309,7 +48754,7 @@ async function importLegacyFlatAnthropicKey() {
48309
48754
  writeMarker(markerPath);
48310
48755
  return { status: "already-imported", flatPath, bakPath: null, markerPath };
48311
48756
  }
48312
- if (!existsSync37(flatPath)) {
48757
+ if (!existsSync38(flatPath)) {
48313
48758
  writeMarker(markerPath);
48314
48759
  return { status: "no-flat-file", flatPath, bakPath: null, markerPath };
48315
48760
  }
@@ -48371,15 +48816,15 @@ var init_legacy_flat_key_import = __esm({
48371
48816
  });
48372
48817
 
48373
48818
  // packages/core/src/llm/credentials.ts
48374
- import { existsSync as existsSync38, mkdirSync as mkdirSync12, readFileSync as readFileSync19, writeFileSync as writeFileSync13 } from "node:fs";
48375
- import { join as join45 } from "node:path";
48819
+ import { existsSync as existsSync39, mkdirSync as mkdirSync12, readFileSync as readFileSync20, writeFileSync as writeFileSync13 } from "node:fs";
48820
+ import { join as join46 } from "node:path";
48376
48821
  import { getCleoHome as getCleoHome8 } from "@cleocode/paths";
48377
48822
  function globalConfigPath() {
48378
48823
  return configDirGlobalConfigPath();
48379
48824
  }
48380
48825
  function projectConfigPath(projectRoot) {
48381
48826
  const cleoDir = process.env["CLEO_DIR"] ?? ".cleo";
48382
- return join45(projectRoot, cleoDir, "config.json");
48827
+ return join46(projectRoot, cleoDir, "config.json");
48383
48828
  }
48384
48829
  function readGlobalProviderKey(provider) {
48385
48830
  ensureGlobalConfigMigrated();
@@ -48389,9 +48834,9 @@ function readGlobalProviderKey(provider) {
48389
48834
  }
48390
48835
  function readFlatAnthropicKey() {
48391
48836
  try {
48392
- const keyFile = join45(getCleoHome8(), "anthropic-key");
48393
- if (!existsSync38(keyFile)) return null;
48394
- const stored = readFileSync19(keyFile, "utf-8").trim();
48837
+ const keyFile = join46(getCleoHome8(), "anthropic-key");
48838
+ if (!existsSync39(keyFile)) return null;
48839
+ const stored = readFileSync20(keyFile, "utf-8").trim();
48395
48840
  return stored || null;
48396
48841
  } catch {
48397
48842
  return null;
@@ -48399,8 +48844,8 @@ function readFlatAnthropicKey() {
48399
48844
  }
48400
48845
  function readProviderKeyFromConfig(configFile, provider) {
48401
48846
  try {
48402
- if (!existsSync38(configFile)) return null;
48403
- const raw = readFileSync19(configFile, "utf-8");
48847
+ if (!existsSync39(configFile)) return null;
48848
+ const raw = readFileSync20(configFile, "utf-8");
48404
48849
  const config2 = JSON.parse(raw);
48405
48850
  const llm = config2["llm"];
48406
48851
  if (!llm || typeof llm !== "object") return null;
@@ -48539,16 +48984,16 @@ __export(credentials_store_exports, {
48539
48984
  pickCredentialForProviderSync: () => pickCredentialForProviderSync,
48540
48985
  removeCredential: () => removeCredential
48541
48986
  });
48542
- import { chmodSync as chmodSync2, existsSync as existsSync39, mkdirSync as mkdirSync13, readFileSync as readFileSync20, statSync as statSync10, writeFileSync as writeFileSync14 } from "node:fs";
48543
- import { dirname as dirname20, join as join46 } from "node:path";
48987
+ import { chmodSync as chmodSync2, existsSync as existsSync40, mkdirSync as mkdirSync13, readFileSync as readFileSync21, statSync as statSync10, writeFileSync as writeFileSync14 } from "node:fs";
48988
+ import { dirname as dirname22, join as join47 } from "node:path";
48544
48989
  import { getCleoHome as getCleoHome9 } from "@cleocode/paths";
48545
48990
  function credentialsStorePath() {
48546
- return join46(getCleoHome9(), "llm-credentials.json");
48991
+ return join47(getCleoHome9(), "llm-credentials.json");
48547
48992
  }
48548
48993
  function ensureFileInitialized(path) {
48549
- if (existsSync39(path)) return;
48550
- const dir = dirname20(path);
48551
- if (!existsSync39(dir)) {
48994
+ if (existsSync40(path)) return;
48995
+ const dir = dirname22(path);
48996
+ if (!existsSync40(dir)) {
48552
48997
  mkdirSync13(dir, { recursive: true, mode: 448 });
48553
48998
  } else {
48554
48999
  try {
@@ -48592,7 +49037,7 @@ function readStoreSync() {
48592
49037
  const path = credentialsStorePath();
48593
49038
  let raw;
48594
49039
  try {
48595
- raw = readFileSync20(path, "utf-8");
49040
+ raw = readFileSync21(path, "utf-8");
48596
49041
  } catch {
48597
49042
  return emptyStore();
48598
49043
  }
@@ -49181,13 +49626,13 @@ var init_xai = __esm({
49181
49626
 
49182
49627
  // packages/core/src/llm/provider-registry/loader.ts
49183
49628
  import { readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
49184
- import { join as join47 } from "node:path";
49629
+ import { join as join48 } from "node:path";
49185
49630
  import { pathToFileURL } from "node:url";
49186
49631
  function isPluginFile(filename) {
49187
49632
  return PLUGIN_EXTENSIONS.some((ext) => filename.endsWith(ext));
49188
49633
  }
49189
49634
  function getPluginDir() {
49190
- return join47(getCleoHome(), "plugins", "model-providers");
49635
+ return join48(getCleoHome(), "plugins", "model-providers");
49191
49636
  }
49192
49637
  async function loadOnePlugin(absPath, api) {
49193
49638
  let mod;
@@ -49235,13 +49680,13 @@ async function scanAndLoadPlugins(pluginDir, api) {
49235
49680
  }
49236
49681
  const pluginFiles = entries.filter((name15) => !name15.startsWith(".") && isPluginFile(name15)).filter((name15) => {
49237
49682
  try {
49238
- return statSync11(join47(pluginDir, name15)).isFile();
49683
+ return statSync11(join48(pluginDir, name15)).isFile();
49239
49684
  } catch {
49240
49685
  return false;
49241
49686
  }
49242
49687
  }).sort();
49243
49688
  for (const filename of pluginFiles) {
49244
- await loadOnePlugin(join47(pluginDir, filename), api);
49689
+ await loadOnePlugin(join48(pluginDir, filename), api);
49245
49690
  }
49246
49691
  }
49247
49692
  async function runDiscovery(registerProvider2, builtins) {
@@ -49344,15 +49789,15 @@ var init_provider_registry = __esm({
49344
49789
  });
49345
49790
 
49346
49791
  // packages/core/src/llm/rate-limit-guard.ts
49347
- import { existsSync as existsSync40, mkdirSync as mkdirSync14, unlinkSync as unlinkSync9 } from "node:fs";
49348
- import { join as join48 } from "node:path";
49792
+ import { existsSync as existsSync41, mkdirSync as mkdirSync14, unlinkSync as unlinkSync9 } from "node:fs";
49793
+ import { join as join49 } from "node:path";
49349
49794
  import { getCleoHome as getCleoHome10 } from "@cleocode/paths";
49350
49795
  function sanitize(value) {
49351
49796
  return value.replace(/[^a-zA-Z0-9_-]/g, "_");
49352
49797
  }
49353
49798
  function rateLimitStatePath(provider, label) {
49354
- const dir = join48(getCleoHome10(), "rate-limit-state");
49355
- return join48(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
49799
+ const dir = join49(getCleoHome10(), "rate-limit-state");
49800
+ return join49(dir, `${sanitize(provider)}-${sanitize(label)}.json`);
49356
49801
  }
49357
49802
  function parseResetFromHeaders(headers) {
49358
49803
  const get = (k) => {
@@ -49399,8 +49844,8 @@ async function recordRateLimit(provider, label, opts) {
49399
49844
  source = "default";
49400
49845
  }
49401
49846
  const filePath = rateLimitStatePath(provider, label);
49402
- const dir = join48(getCleoHome10(), "rate-limit-state");
49403
- if (!existsSync40(dir)) {
49847
+ const dir = join49(getCleoHome10(), "rate-limit-state");
49848
+ if (!existsSync41(dir)) {
49404
49849
  mkdirSync14(dir, { recursive: true });
49405
49850
  }
49406
49851
  const state = { resetAt, recordedAt: now, source };
@@ -49985,31 +50430,31 @@ var init_local_inference_probe = __esm({
49985
50430
 
49986
50431
  // packages/core/src/llm/catalog-cache.ts
49987
50432
  import {
49988
- existsSync as existsSync41,
50433
+ existsSync as existsSync42,
49989
50434
  mkdirSync as mkdirSync15,
49990
50435
  readdirSync as readdirSync10,
49991
- readFileSync as readFileSync21,
50436
+ readFileSync as readFileSync22,
49992
50437
  statSync as statSync12,
49993
50438
  symlinkSync,
49994
50439
  unlinkSync as unlinkSync10,
49995
50440
  writeFileSync as writeFileSync15
49996
50441
  } from "node:fs";
49997
- import { join as join49 } from "node:path";
50442
+ import { join as join50 } from "node:path";
49998
50443
  import { getCleoHome as getCleoHome11 } from "@cleocode/paths";
49999
50444
  function getCatalogDir() {
50000
50445
  if (process.env["CLEO_DATA_DIR"]) {
50001
- return join49(process.env["CLEO_DATA_DIR"], "llm-catalog");
50446
+ return join50(process.env["CLEO_DATA_DIR"], "llm-catalog");
50002
50447
  }
50003
- return join49(getCleoHome11(), "llm-catalog");
50448
+ return join50(getCleoHome11(), "llm-catalog");
50004
50449
  }
50005
50450
  function findLatestCacheFile(dir) {
50006
- if (!existsSync41(dir)) return null;
50007
- const files = readdirSync10(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync12(join49(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
50008
- return files.length > 0 ? join49(dir, files[0].name) : null;
50451
+ if (!existsSync42(dir)) return null;
50452
+ const files = readdirSync10(dir).filter((f) => f.endsWith("-models.json")).map((f) => ({ name: f, mtime: statSync12(join50(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
50453
+ return files.length > 0 ? join50(dir, files[0].name) : null;
50009
50454
  }
50010
50455
  function readCacheFile(filePath) {
50011
50456
  try {
50012
- const raw = readFileSync21(filePath, "utf-8");
50457
+ const raw = readFileSync22(filePath, "utf-8");
50013
50458
  return JSON.parse(raw);
50014
50459
  } catch {
50015
50460
  return null;
@@ -50788,9 +51233,9 @@ __export(catalog_resolver_exports, {
50788
51233
  openCatalogAtPath: () => openCatalogAtPath,
50789
51234
  resolveCatalogEntry: () => resolveCatalogEntry
50790
51235
  });
50791
- import { readFileSync as readFileSync22 } from "node:fs";
50792
- import { dirname as dirname21, join as join50 } from "node:path";
50793
- import { fileURLToPath as fileURLToPath3 } from "node:url";
51236
+ import { readFileSync as readFileSync23 } from "node:fs";
51237
+ import { dirname as dirname23, join as join51 } from "node:path";
51238
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
50794
51239
  async function openCatalogAtPath(dbPath) {
50795
51240
  const handle = await openDualScopeDbAtPath("global", dbPath);
50796
51241
  return handle.db;
@@ -50798,9 +51243,9 @@ async function openCatalogAtPath(dbPath) {
50798
51243
  function loadShippedSeed() {
50799
51244
  if (_seed !== void 0) return _seed;
50800
51245
  try {
50801
- const thisDir = dirname21(fileURLToPath3(import.meta.url));
50802
- const jsonPath = join50(thisDir, "curated-catalog.json");
50803
- _seed = JSON.parse(readFileSync22(jsonPath, "utf-8"));
51246
+ const thisDir = dirname23(fileURLToPath4(import.meta.url));
51247
+ const jsonPath = join51(thisDir, "curated-catalog.json");
51248
+ _seed = JSON.parse(readFileSync23(jsonPath, "utf-8"));
50804
51249
  } catch (err) {
50805
51250
  logger5.warn(
50806
51251
  { err: err instanceof Error ? err.message : String(err) },
@@ -51223,16 +51668,16 @@ var init_message_utils = __esm({
51223
51668
  });
51224
51669
 
51225
51670
  // packages/core/src/llm/model-metadata.ts
51226
- import { readFileSync as readFileSync23 } from "node:fs";
51227
- import { dirname as dirname22, join as join51 } from "node:path";
51228
- import { fileURLToPath as fileURLToPath4 } from "node:url";
51671
+ import { readFileSync as readFileSync24 } from "node:fs";
51672
+ import { dirname as dirname24, join as join52 } from "node:path";
51673
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
51229
51674
  function getCuratedTable() {
51230
51675
  if (_curated !== void 0) {
51231
51676
  return _curated;
51232
51677
  }
51233
- const thisDir = dirname22(fileURLToPath4(import.meta.url));
51234
- const jsonPath = join51(thisDir, "curated-models.json");
51235
- const raw = JSON.parse(readFileSync23(jsonPath, "utf-8"));
51678
+ const thisDir = dirname24(fileURLToPath5(import.meta.url));
51679
+ const jsonPath = join52(thisDir, "curated-models.json");
51680
+ const raw = JSON.parse(readFileSync24(jsonPath, "utf-8"));
51236
51681
  _curated = raw.models;
51237
51682
  return _curated;
51238
51683
  }
@@ -51311,7 +51756,7 @@ function storedToResolved(stored) {
51311
51756
  };
51312
51757
  }
51313
51758
  function sleep3(ms) {
51314
- return new Promise((resolve15) => setTimeout(resolve15, ms));
51759
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
51315
51760
  }
51316
51761
  function backoffMs(policy, attempt) {
51317
51762
  const base = policy.baseDelayMs * 2 ** attempt;
@@ -55133,7 +55578,7 @@ function normalizeOllamaToolCall(tc) {
55133
55578
  };
55134
55579
  }
55135
55580
  function sleep4(ms) {
55136
- return new Promise((resolve15) => setTimeout(resolve15, ms));
55581
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
55137
55582
  }
55138
55583
  var OLLAMA_DEFAULT_BASE_URL, MAX_RETRIES, INITIAL_BACKOFF_MS, RETRYABLE_STATUS_CODES, OllamaTransport;
55139
55584
  var init_ollama2 = __esm({
@@ -75647,7 +76092,7 @@ function createProviderToolFactoryWithOutputSchema({
75647
76092
  supportsDeferredResults
75648
76093
  });
75649
76094
  }
75650
- async function resolve14(value) {
76095
+ async function resolve16(value) {
75651
76096
  if (typeof value === "function") {
75652
76097
  value = value();
75653
76098
  }
@@ -79681,14 +80126,14 @@ var init_dist4 = __esm({
79681
80126
  headers
79682
80127
  }) {
79683
80128
  return combineHeaders(
79684
- await resolve14(this.config.headers),
80129
+ await resolve16(this.config.headers),
79685
80130
  headers,
79686
80131
  betas.size > 0 ? { "anthropic-beta": Array.from(betas).join(",") } : {}
79687
80132
  );
79688
80133
  }
79689
80134
  async getBetasFromHeaders(requestHeaders) {
79690
80135
  var _a17, _b16;
79691
- const configHeaders = await resolve14(this.config.headers);
80136
+ const configHeaders = await resolve16(this.config.headers);
79692
80137
  const configBetaHeader = (_a17 = configHeaders["anthropic-beta"]) != null ? _a17 : "";
79693
80138
  const requestBetaHeader = (_b16 = requestHeaders == null ? void 0 : requestHeaders["anthropic-beta"]) != null ? _b16 : "";
79694
80139
  return new Set(
@@ -83276,7 +83721,7 @@ var init_model_runner = __esm({
83276
83721
 
83277
83722
  // packages/core/src/selfimprove/fix-gen.ts
83278
83723
  import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync16 } from "node:fs";
83279
- import { dirname as dirname23, join as join52, resolve as resolvePath2 } from "node:path";
83724
+ import { dirname as dirname25, join as join53, resolve as resolvePath2 } from "node:path";
83280
83725
  import { cwd as processCwd } from "node:process";
83281
83726
 
83282
83727
  // packages/utils/src/redact.ts
@@ -83540,7 +83985,7 @@ var FIXGEN_SYSTEM = "task-executor";
83540
83985
  var UNIFIED_DIFF_MARKERS = ["diff --git ", "--- ", "+++ ", "@@ "];
83541
83986
  function fixPatchPath(scenario, cwd) {
83542
83987
  const safeScenario = scenario.replace(/[^a-z0-9-]/gi, "-");
83543
- return resolvePath2(cwd ?? processCwd(), join52(".cleo", "selfimprove", `${safeScenario}.patch`));
83988
+ return resolvePath2(cwd ?? processCwd(), join53(".cleo", "selfimprove", `${safeScenario}.patch`));
83544
83989
  }
83545
83990
  function looksLikeUnifiedDiff(text2) {
83546
83991
  if (text2.trim().length === 0) return false;
@@ -83625,7 +84070,7 @@ async function generateFixPatch(opts) {
83625
84070
  }
83626
84071
  const diff = output.diff.endsWith("\n") ? output.diff : `${output.diff}
83627
84072
  `;
83628
- mkdirSync16(dirname23(patchPath), { recursive: true });
84073
+ mkdirSync16(dirname25(patchPath), { recursive: true });
83629
84074
  writeFileSync16(patchPath, diff, "utf8");
83630
84075
  const bytes = Buffer.byteLength(diff, "utf8");
83631
84076
  logger8.info(