@cleocode/core 2026.9.22 → 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 (316) hide show
  1. package/dist/build-provenance.json +6 -0
  2. package/dist/decide/audit.d.ts +7 -1
  3. package/dist/decide/audit.d.ts.map +1 -1
  4. package/dist/decide/audit.js.map +1 -1
  5. package/dist/decide/client.d.ts +46 -4
  6. package/dist/decide/client.d.ts.map +1 -1
  7. package/dist/decide/client.js +328 -33
  8. package/dist/decide/client.js.map +1 -1
  9. package/dist/decide/credentials.d.ts +28 -4
  10. package/dist/decide/credentials.d.ts.map +1 -1
  11. package/dist/decide/credentials.js +50 -12
  12. package/dist/decide/credentials.js.map +1 -1
  13. package/dist/decide/index.d.ts +10 -4
  14. package/dist/decide/index.d.ts.map +1 -1
  15. package/dist/decide/index.js +10 -4
  16. package/dist/decide/index.js.map +1 -1
  17. package/dist/decide/jev-wire.d.ts +100 -8
  18. package/dist/decide/jev-wire.d.ts.map +1 -1
  19. package/dist/decide/jev-wire.js +402 -55
  20. package/dist/decide/jev-wire.js.map +1 -1
  21. package/dist/decide/operations.d.ts +97 -20
  22. package/dist/decide/operations.d.ts.map +1 -1
  23. package/dist/decide/operations.js +180 -28
  24. package/dist/decide/operations.js.map +1 -1
  25. package/dist/decide/provider-state.d.ts +89 -0
  26. package/dist/decide/provider-state.d.ts.map +1 -0
  27. package/dist/decide/provider-state.js +134 -0
  28. package/dist/decide/provider-state.js.map +1 -0
  29. package/dist/decide/provider.d.ts +26 -5
  30. package/dist/decide/provider.d.ts.map +1 -1
  31. package/dist/decide/provider.js.map +1 -1
  32. package/dist/decide/providers.d.ts +58 -0
  33. package/dist/decide/providers.d.ts.map +1 -0
  34. package/dist/decide/providers.js +69 -0
  35. package/dist/decide/providers.js.map +1 -0
  36. package/dist/decide/site.d.ts +2 -2
  37. package/dist/decide/site.d.ts.map +1 -1
  38. package/dist/decide/site.js +2 -0
  39. package/dist/decide/site.js.map +1 -1
  40. package/dist/decide/sites/list.d.ts +46 -0
  41. package/dist/decide/sites/list.d.ts.map +1 -0
  42. package/dist/decide/sites/list.js +206 -0
  43. package/dist/decide/sites/list.js.map +1 -0
  44. package/dist/decide/sites/registry.d.ts +130 -0
  45. package/dist/decide/sites/registry.d.ts.map +1 -0
  46. package/dist/decide/sites/registry.js +375 -0
  47. package/dist/decide/sites/registry.js.map +1 -0
  48. package/dist/decide/spend.d.ts +196 -0
  49. package/dist/decide/spend.d.ts.map +1 -0
  50. package/dist/decide/spend.js +387 -0
  51. package/dist/decide/spend.js.map +1 -0
  52. package/dist/decide/wizard.d.ts +53 -0
  53. package/dist/decide/wizard.d.ts.map +1 -0
  54. package/dist/decide/wizard.js +144 -0
  55. package/dist/decide/wizard.js.map +1 -0
  56. package/dist/docs/docs-audit.d.ts.map +1 -1
  57. package/dist/docs/docs-audit.js +1 -2
  58. package/dist/docs/docs-audit.js.map +1 -1
  59. package/dist/docs/export-document.js +775 -415
  60. package/dist/docs/export-document.js.map +3 -3
  61. package/dist/index.d.ts +2 -2
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +1 -1
  64. package/dist/index.js.map +1 -1
  65. package/dist/init/scaffold-workflows.d.ts.map +1 -1
  66. package/dist/init/scaffold-workflows.js +6 -3
  67. package/dist/init/scaffold-workflows.js.map +1 -1
  68. package/dist/init/upgrade-workflows.d.ts.map +1 -1
  69. package/dist/init/upgrade-workflows.js +6 -3
  70. package/dist/init/upgrade-workflows.js.map +1 -1
  71. package/dist/internal.d.ts +1 -1
  72. package/dist/internal.d.ts.map +1 -1
  73. package/dist/internal.js +1 -1
  74. package/dist/internal.js.map +1 -1
  75. package/dist/llm/plugin-facade.js +886 -526
  76. package/dist/llm/plugin-facade.js.map +3 -3
  77. package/dist/memory/decision-contradiction.d.ts +3 -3
  78. package/dist/memory/decision-contradiction.d.ts.map +1 -1
  79. package/dist/memory/decision-contradiction.js +4 -3
  80. package/dist/memory/decision-contradiction.js.map +1 -1
  81. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  82. package/dist/memory/graph-memory-bridge.js +2 -0
  83. package/dist/memory/graph-memory-bridge.js.map +1 -1
  84. package/dist/memory/observation-type-decision.d.ts +2 -2
  85. package/dist/memory/observation-type-decision.d.ts.map +1 -1
  86. package/dist/memory/observation-type-decision.js +3 -2
  87. package/dist/memory/observation-type-decision.js.map +1 -1
  88. package/dist/memory/pipeline-manifest-sqlite.d.ts +111 -0
  89. package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
  90. package/dist/memory/pipeline-manifest-sqlite.js +230 -2
  91. package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
  92. package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
  93. package/dist/nexus/migrations/M-split-graph.js +4 -0
  94. package/dist/nexus/migrations/M-split-graph.js.map +1 -1
  95. package/dist/nexus/store.d.ts.map +1 -1
  96. package/dist/nexus/store.js +2 -0
  97. package/dist/nexus/store.js.map +1 -1
  98. package/dist/orchestrate/pivot.d.ts.map +1 -1
  99. package/dist/orchestrate/pivot.js +13 -8
  100. package/dist/orchestrate/pivot.js.map +1 -1
  101. package/dist/orchestrate/plan.d.ts.map +1 -1
  102. package/dist/orchestrate/plan.js +3 -0
  103. package/dist/orchestrate/plan.js.map +1 -1
  104. package/dist/orchestration/lead-rollup.js +14 -2
  105. package/dist/orchestration/lead-rollup.js.map +1 -1
  106. package/dist/orchestration/owner-decision-readiness.d.ts +2 -2
  107. package/dist/orchestration/owner-decision-readiness.d.ts.map +1 -1
  108. package/dist/orchestration/owner-decision-readiness.js +3 -2
  109. package/dist/orchestration/owner-decision-readiness.js.map +1 -1
  110. package/dist/orchestration/validate-spawn.d.ts.map +1 -1
  111. package/dist/orchestration/validate-spawn.js +2 -0
  112. package/dist/orchestration/validate-spawn.js.map +1 -1
  113. package/dist/project-scope.d.ts +16 -0
  114. package/dist/project-scope.d.ts.map +1 -1
  115. package/dist/project-scope.js +38 -2
  116. package/dist/project-scope.js.map +1 -1
  117. package/dist/release/github-pr.d.ts.map +1 -1
  118. package/dist/release/github-pr.js +2 -1
  119. package/dist/release/github-pr.js.map +1 -1
  120. package/dist/routing/capability-matrix.d.ts.map +1 -1
  121. package/dist/routing/capability-matrix.js +7 -0
  122. package/dist/routing/capability-matrix.js.map +1 -1
  123. package/dist/selfimprove/fix-gen.js +895 -535
  124. package/dist/selfimprove/fix-gen.js.map +3 -3
  125. package/dist/sessions/briefing.d.ts.map +1 -1
  126. package/dist/sessions/briefing.js +23 -62
  127. package/dist/sessions/briefing.js.map +1 -1
  128. package/dist/sessions/focus-state-store.d.ts +6 -1
  129. package/dist/sessions/focus-state-store.d.ts.map +1 -1
  130. package/dist/sessions/focus-state-store.js +5 -2
  131. package/dist/sessions/focus-state-store.js.map +1 -1
  132. package/dist/setup/config-json-merge.d.ts +28 -0
  133. package/dist/setup/config-json-merge.d.ts.map +1 -1
  134. package/dist/setup/config-json-merge.js +51 -0
  135. package/dist/setup/config-json-merge.js.map +1 -1
  136. package/dist/setup/index.d.ts +13 -10
  137. package/dist/setup/index.d.ts.map +1 -1
  138. package/dist/setup/index.js +15 -10
  139. package/dist/setup/index.js.map +1 -1
  140. package/dist/setup/sections/llm.js +1 -1
  141. package/dist/setup/sections/llm.js.map +1 -1
  142. package/dist/setup/sections/system-one.d.ts +28 -0
  143. package/dist/setup/sections/system-one.d.ts.map +1 -0
  144. package/dist/setup/sections/system-one.js +53 -0
  145. package/dist/setup/sections/system-one.js.map +1 -0
  146. package/dist/setup/wizard.d.ts +15 -1
  147. package/dist/setup/wizard.d.ts.map +1 -1
  148. package/dist/setup/wizard.js +15 -0
  149. package/dist/setup/wizard.js.map +1 -1
  150. package/dist/skills/prune-bundled.d.ts +40 -1
  151. package/dist/skills/prune-bundled.d.ts.map +1 -1
  152. package/dist/skills/prune-bundled.js +117 -1
  153. package/dist/skills/prune-bundled.js.map +1 -1
  154. package/dist/store/agent-registry-accessor.d.ts.map +1 -1
  155. package/dist/store/agent-registry-accessor.js +2 -0
  156. package/dist/store/agent-registry-accessor.js.map +1 -1
  157. package/dist/store/backup-pack.js +1 -1
  158. package/dist/store/backup-pack.js.map +1 -1
  159. package/dist/store/backup.d.ts +15 -1
  160. package/dist/store/backup.d.ts.map +1 -1
  161. package/dist/store/backup.js +18 -2
  162. package/dist/store/backup.js.map +1 -1
  163. package/dist/store/conduit-sqlite.d.ts.map +1 -1
  164. package/dist/store/conduit-sqlite.js +3 -0
  165. package/dist/store/conduit-sqlite.js.map +1 -1
  166. package/dist/store/credential-transfer.d.ts.map +1 -1
  167. package/dist/store/credential-transfer.js +2 -0
  168. package/dist/store/credential-transfer.js.map +1 -1
  169. package/dist/store/cross-db-cleanup.d.ts.map +1 -1
  170. package/dist/store/cross-db-cleanup.js +2 -0
  171. package/dist/store/cross-db-cleanup.js.map +1 -1
  172. package/dist/store/dual-scope-db.d.ts.map +1 -1
  173. package/dist/store/dual-scope-db.js +13 -2
  174. package/dist/store/dual-scope-db.js.map +1 -1
  175. package/dist/store/migrate-signaldock-to-conduit.d.ts.map +1 -1
  176. package/dist/store/migrate-signaldock-to-conduit.js +3 -0
  177. package/dist/store/migrate-signaldock-to-conduit.js.map +1 -1
  178. package/dist/store/migration-manager.d.ts.map +1 -1
  179. package/dist/store/migration-manager.js +37 -3
  180. package/dist/store/migration-manager.js.map +1 -1
  181. package/dist/store/migration-sqlite.d.ts.map +1 -1
  182. package/dist/store/migration-sqlite.js +2 -0
  183. package/dist/store/migration-sqlite.js.map +1 -1
  184. package/dist/store/nexus-sqlite.d.ts.map +1 -1
  185. package/dist/store/nexus-sqlite.js +3 -0
  186. package/dist/store/nexus-sqlite.js.map +1 -1
  187. package/dist/store/open-cleo-db.d.ts.map +1 -1
  188. package/dist/store/open-cleo-db.js +3 -0
  189. package/dist/store/open-cleo-db.js.map +1 -1
  190. package/dist/store/portable-bundle-import.d.ts.map +1 -1
  191. package/dist/store/portable-bundle-import.js +2 -0
  192. package/dist/store/portable-bundle-import.js.map +1 -1
  193. package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
  194. package/dist/store/portable-bundle-relocate.js +2 -0
  195. package/dist/store/portable-bundle-relocate.js.map +1 -1
  196. package/dist/store/portable-bundle-scan.js +1 -1
  197. package/dist/store/portable-bundle-scan.js.map +1 -1
  198. package/dist/store/ports/domain-binding.d.ts.map +1 -1
  199. package/dist/store/ports/domain-binding.js +5 -0
  200. package/dist/store/ports/domain-binding.js.map +1 -1
  201. package/dist/store/split-brain-import.d.ts.map +1 -1
  202. package/dist/store/split-brain-import.js +2 -0
  203. package/dist/store/split-brain-import.js.map +1 -1
  204. package/dist/store/sqlite-data-accessor.js +7 -0
  205. package/dist/store/sqlite-data-accessor.js.map +1 -1
  206. package/dist/store/sqlite-native.d.ts.map +1 -1
  207. package/dist/store/sqlite-native.js +1 -0
  208. package/dist/store/sqlite-native.js.map +1 -1
  209. package/dist/store/sqlite.d.ts.map +1 -1
  210. package/dist/store/sqlite.js +5 -0
  211. package/dist/store/sqlite.js.map +1 -1
  212. package/dist/store/worktree-build-guard.d.ts +191 -0
  213. package/dist/store/worktree-build-guard.d.ts.map +1 -0
  214. package/dist/store/worktree-build-guard.js +486 -0
  215. package/dist/store/worktree-build-guard.js.map +1 -0
  216. package/dist/store/worktree-isolation-guard.d.ts +27 -0
  217. package/dist/store/worktree-isolation-guard.d.ts.map +1 -1
  218. package/dist/store/worktree-isolation-guard.js +67 -1
  219. package/dist/store/worktree-isolation-guard.js.map +1 -1
  220. package/dist/store/writer-lease.d.ts.map +1 -1
  221. package/dist/store/writer-lease.js +2 -0
  222. package/dist/store/writer-lease.js.map +1 -1
  223. package/dist/system/backup.d.ts +6 -2
  224. package/dist/system/backup.d.ts.map +1 -1
  225. package/dist/system/backup.js +6 -3
  226. package/dist/system/backup.js.map +1 -1
  227. package/dist/task-tools/index.d.ts +4 -2
  228. package/dist/task-tools/index.d.ts.map +1 -1
  229. package/dist/task-tools/index.js +3 -2
  230. package/dist/task-tools/index.js.map +1 -1
  231. package/dist/task-tools/score-task-priority.d.ts +93 -18
  232. package/dist/task-tools/score-task-priority.d.ts.map +1 -1
  233. package/dist/task-tools/score-task-priority.js +193 -81
  234. package/dist/task-tools/score-task-priority.js.map +1 -1
  235. package/dist/tasks/affected-packages.d.ts +5 -1
  236. package/dist/tasks/affected-packages.d.ts.map +1 -1
  237. package/dist/tasks/affected-packages.js +21 -3
  238. package/dist/tasks/affected-packages.js.map +1 -1
  239. package/dist/tasks/analyze.d.ts +29 -1
  240. package/dist/tasks/analyze.d.ts.map +1 -1
  241. package/dist/tasks/analyze.js +45 -34
  242. package/dist/tasks/analyze.js.map +1 -1
  243. package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
  244. package/dist/tasks/backfill-child-projections.js +4 -1
  245. package/dist/tasks/backfill-child-projections.js.map +1 -1
  246. package/dist/tasks/change-set.d.ts.map +1 -1
  247. package/dist/tasks/change-set.js +16 -3
  248. package/dist/tasks/change-set.js.map +1 -1
  249. package/dist/tasks/command-line.d.ts +54 -0
  250. package/dist/tasks/command-line.d.ts.map +1 -0
  251. package/dist/tasks/command-line.js +151 -0
  252. package/dist/tasks/command-line.js.map +1 -0
  253. package/dist/tasks/component-pr.d.ts.map +1 -1
  254. package/dist/tasks/component-pr.js +97 -12
  255. package/dist/tasks/component-pr.js.map +1 -1
  256. package/dist/tasks/delete.d.ts.map +1 -1
  257. package/dist/tasks/delete.js +20 -0
  258. package/dist/tasks/delete.js.map +1 -1
  259. package/dist/tasks/duplicate-detector.d.ts +3 -3
  260. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  261. package/dist/tasks/duplicate-detector.js +4 -3
  262. package/dist/tasks/duplicate-detector.js.map +1 -1
  263. package/dist/tasks/engine-wrap-ops.d.ts +29 -0
  264. package/dist/tasks/engine-wrap-ops.d.ts.map +1 -1
  265. package/dist/tasks/engine-wrap-ops.js +40 -0
  266. package/dist/tasks/engine-wrap-ops.js.map +1 -1
  267. package/dist/tasks/engine-wrap.d.ts +1 -1
  268. package/dist/tasks/engine-wrap.d.ts.map +1 -1
  269. package/dist/tasks/engine-wrap.js +1 -1
  270. package/dist/tasks/engine-wrap.js.map +1 -1
  271. package/dist/tasks/evidence.d.ts +2 -0
  272. package/dist/tasks/evidence.d.ts.map +1 -1
  273. package/dist/tasks/evidence.js +30 -4
  274. package/dist/tasks/evidence.js.map +1 -1
  275. package/dist/tasks/gate-runner.d.ts.map +1 -1
  276. package/dist/tasks/gate-runner.js +48 -12
  277. package/dist/tasks/gate-runner.js.map +1 -1
  278. package/dist/tasks/index.d.ts +1 -1
  279. package/dist/tasks/index.d.ts.map +1 -1
  280. package/dist/tasks/index.js +1 -1
  281. package/dist/tasks/index.js.map +1 -1
  282. package/dist/tasks/ops.d.ts +1 -0
  283. package/dist/tasks/ops.d.ts.map +1 -1
  284. package/dist/tasks/ranking-audit.d.ts +122 -0
  285. package/dist/tasks/ranking-audit.d.ts.map +1 -0
  286. package/dist/tasks/ranking-audit.js +193 -0
  287. package/dist/tasks/ranking-audit.js.map +1 -0
  288. package/dist/tasks/task-analyze.d.ts.map +1 -1
  289. package/dist/tasks/task-analyze.js +19 -32
  290. package/dist/tasks/task-analyze.js.map +1 -1
  291. package/dist/tasks/task-next.d.ts +44 -2
  292. package/dist/tasks/task-next.d.ts.map +1 -1
  293. package/dist/tasks/task-next.js +80 -102
  294. package/dist/tasks/task-next.js.map +1 -1
  295. package/dist/tasks/task-ops.d.ts +1 -1
  296. package/dist/tasks/task-ops.d.ts.map +1 -1
  297. package/dist/tasks/task-ops.js +1 -1
  298. package/dist/tasks/task-ops.js.map +1 -1
  299. package/dist/tasks/tool-resolver.d.ts +7 -1
  300. package/dist/tasks/tool-resolver.d.ts.map +1 -1
  301. package/dist/tasks/tool-resolver.js +24 -10
  302. package/dist/tasks/tool-resolver.js.map +1 -1
  303. package/dist/tasks/update.d.ts +8 -2
  304. package/dist/tasks/update.d.ts.map +1 -1
  305. package/dist/tasks/update.js +28 -1
  306. package/dist/tasks/update.js.map +1 -1
  307. package/dist/telemetry/sqlite.d.ts.map +1 -1
  308. package/dist/telemetry/sqlite.js +2 -0
  309. package/dist/telemetry/sqlite.js.map +1 -1
  310. package/dist/validation/doctor/checks.d.ts.map +1 -1
  311. package/dist/validation/doctor/checks.js +2 -2
  312. package/dist/validation/doctor/checks.js.map +1 -1
  313. package/package.json +14 -14
  314. package/schemas/config.schema.json +13 -0
  315. package/templates/CLEO-INJECTION.md +1 -1
  316. package/templates/CLEO-REFERENCE.md +5 -1
@@ -344,7 +344,7 @@ var init_acceptance_gate_schema = __esm({
344
344
  message: "Result cannot precede input capture"
345
345
  });
346
346
  const executable = ["test", "command", "lint"].includes(result.kind);
347
- if (executable && !binding.invocation)
347
+ if (executable && !binding.invocation && result.result !== "error")
348
348
  context.addIssue({
349
349
  code: "custom",
350
350
  path: ["binding", "invocation"],
@@ -3086,12 +3086,21 @@ var init_operations_registry = __esm({
3086
3086
  gateway: "query",
3087
3087
  domain: "tasks",
3088
3088
  operation: "history",
3089
- description: "Show task work history (time tracked per task)",
3089
+ description: "Show task work history; with taskId, the task audit trail; with ranking, who changed its priority/severity/kind/depends and why (T12693)",
3090
3090
  tier: 1,
3091
3091
  idempotent: true,
3092
3092
  sessionRequired: false,
3093
3093
  requiredParams: [],
3094
- params: []
3094
+ params: [
3095
+ { name: "taskId", type: "string", required: false, description: "Task to show history for" },
3096
+ { name: "limit", type: "number", required: false, description: "Maximum entries" },
3097
+ {
3098
+ name: "ranking",
3099
+ type: "boolean",
3100
+ required: false,
3101
+ description: "Only ranking-input changes (actor, session, reason, before/after)"
3102
+ }
3103
+ ]
3095
3104
  },
3096
3105
  {
3097
3106
  gateway: "query",
@@ -5586,6 +5595,32 @@ var init_operations_registry = __esm({
5586
5595
  ],
5587
5596
  outputSchema: OUTPUT_CONTRACTS["tasks.assignee"]
5588
5597
  },
5598
+ {
5599
+ gateway: "mutate",
5600
+ domain: "tasks",
5601
+ operation: "ranking.revert",
5602
+ description: "tasks.ranking.revert (mutate) \u2014 undo one recorded ranking change (priority/severity/kind/depends) as a new audited change (T12693, D11161)",
5603
+ tier: 1,
5604
+ idempotent: false,
5605
+ sessionRequired: false,
5606
+ requiredParams: ["entryId"],
5607
+ params: [
5608
+ {
5609
+ name: "entryId",
5610
+ type: "string",
5611
+ required: true,
5612
+ description: "ranking_changed audit row id (cleo history ranking <taskId>)",
5613
+ cli: { positional: true }
5614
+ },
5615
+ { name: "reason", type: "string", required: false, description: "Why it is reverted" },
5616
+ {
5617
+ name: "force",
5618
+ type: "boolean",
5619
+ required: false,
5620
+ description: "Revert even though a field changed again since"
5621
+ }
5622
+ ]
5623
+ },
5589
5624
  {
5590
5625
  gateway: "mutate",
5591
5626
  domain: "tasks",
@@ -13053,7 +13088,10 @@ var init_evidence_atom_schema = __esm({
13053
13088
  ["commit", "note"],
13054
13089
  ["decision", "files"],
13055
13090
  ["decision", "note"],
13056
- ["pr", "files"]
13091
+ ["pr", "files"],
13092
+ // T12689: a deletion-only PR (no bytes to hash). Contextual validation
13093
+ // accepts this only when every change the PR made is a deletion.
13094
+ ["pr", "note"]
13057
13095
  ]
13058
13096
  },
13059
13097
  testsPassed: { oneOf: [["test-run"], ["tool"], ["ci"]] },
@@ -16955,7 +16993,7 @@ var init_collection_keys = __esm({
16955
16993
 
16956
16994
  // packages/contracts/src/decide.ts
16957
16995
  import { z as z24 } from "zod";
16958
- 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;
16996
+ 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;
16959
16997
  var init_decide = __esm({
16960
16998
  "packages/contracts/src/decide.ts"() {
16961
16999
  "use strict";
@@ -16979,6 +17017,7 @@ var init_decide = __esm({
16979
17017
  /** Maximum number of levels on a `score` question's scale. */
16980
17018
  maxScoreLevels: 10
16981
17019
  };
17020
+ DECISION_PROVIDER_KINDS = ["layahost", "jev"];
16982
17021
  decisionQuestionTypeSchema = z24.enum(DECISION_QUESTION_TYPES);
16983
17022
  decisionOutcomeSourceSchema = z24.enum(DECISION_OUTCOME_SOURCES);
16984
17023
  decisionInstructionsSchema = z24.union([z24.string(), z24.record(z24.string(), z24.json())]);
@@ -17016,6 +17055,8 @@ var init_decide = __esm({
17016
17055
  ]);
17017
17056
  decisionRequestSchema = z24.object({
17018
17057
  model: z24.string().min(1).optional(),
17058
+ lang: z24.string().regex(/^[a-z]{2,3}(-[A-Za-z0-9]{2,8})?$/).optional(),
17059
+ cache: z24.boolean().optional(),
17019
17060
  state: decisionStateSchema,
17020
17061
  questions: z24.record(z24.string().min(1), decisionQuestionSchema).refine(
17021
17062
  (questions) => {
@@ -17056,14 +17097,26 @@ var init_decide = __esm({
17056
17097
  requestId: z24.string().min(1).optional(),
17057
17098
  latencyMs: z24.number().nonnegative(),
17058
17099
  costUsd: z24.number().nonnegative().optional(),
17100
+ costMicros: z24.number().int().nonnegative().optional(),
17101
+ balanceMicros: z24.number().int().optional(),
17102
+ checkpoint: z24.string().min(1).optional(),
17059
17103
  inputTokens: z24.number().int().nonnegative().optional()
17060
17104
  });
17105
+ decisionProviderKindSchema = z24.enum(DECISION_PROVIDER_KINDS);
17061
17106
  decisionProviderConfigSchema = z24.object({
17062
- baseUrl: z24.url()
17107
+ baseUrl: z24.url(),
17108
+ provider: decisionProviderKindSchema.optional()
17063
17109
  });
17064
17110
  }
17065
17111
  });
17066
17112
 
17113
+ // packages/contracts/src/decide-sites.ts
17114
+ var init_decide_sites = __esm({
17115
+ "packages/contracts/src/decide-sites.ts"() {
17116
+ "use strict";
17117
+ }
17118
+ });
17119
+
17067
17120
  // packages/contracts/src/task-id.ts
17068
17121
  var init_task_id = __esm({
17069
17122
  "packages/contracts/src/task-id.ts"() {
@@ -17145,6 +17198,7 @@ var init_src = __esm({
17145
17198
  init_caamp_markers();
17146
17199
  init_collection_keys();
17147
17200
  init_decide();
17201
+ init_decide_sites();
17148
17202
  init_task_id();
17149
17203
  }
17150
17204
  });
@@ -18644,7 +18698,10 @@ function linkedWorktreeMainRoot(dir) {
18644
18698
  }
18645
18699
  function describeWorktreeOwner(dir) {
18646
18700
  const mainRoot = linkedWorktreeMainRoot(dir);
18647
- if (mainRoot === null) return "owning repository unknown (unreadable gitlink)";
18701
+ if (mainRoot === null) {
18702
+ const bare = bareRepositoryOfWorktree(dir);
18703
+ 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`;
18704
+ }
18648
18705
  let projectId = null;
18649
18706
  try {
18650
18707
  const parsed = JSON.parse(
@@ -18658,6 +18715,18 @@ function describeWorktreeOwner(dir) {
18658
18715
  }
18659
18716
  return projectId === null ? `owning repository ${mainRoot} (not an initialised CLEO project)` : `owning project ${mainRoot} (projectId ${projectId})`;
18660
18717
  }
18718
+ function bareRepositoryOfWorktree(dir) {
18719
+ const gitdir = readGitlinkTarget(dir);
18720
+ if (!gitdir || basename2(dirname2(gitdir)) !== "worktrees") return null;
18721
+ const commonDir = dirname2(dirname2(gitdir));
18722
+ try {
18723
+ const config = readFileSync2(join3(commonDir, "config"), "utf-8");
18724
+ const core = /^\[core\][^[]*/m.exec(config)?.[0] ?? "";
18725
+ return /^\s*bare\s*=\s*true\s*$/im.test(core) ? commonDir : null;
18726
+ } catch {
18727
+ return null;
18728
+ }
18729
+ }
18661
18730
  function readCoreWorktree(gitDir) {
18662
18731
  try {
18663
18732
  const config = readFileSync2(join3(gitDir, "config"), "utf-8");
@@ -19107,13 +19176,13 @@ function captureWriteFence(input) {
19107
19176
  return writeFence;
19108
19177
  }
19109
19178
  function observeOperation(context, work) {
19110
- return new Promise((resolve14) => {
19179
+ return new Promise((resolve16) => {
19111
19180
  let observed = false;
19112
19181
  const finish = (result) => {
19113
19182
  if (observed) return;
19114
19183
  observed = true;
19115
19184
  context.signal.removeEventListener("abort", abort);
19116
- resolve14(result);
19185
+ resolve16(result);
19117
19186
  };
19118
19187
  const abort = () => {
19119
19188
  const reason = context.signal.reason;
@@ -19747,7 +19816,7 @@ var init_sql = __esm({
19747
19816
  return new SQL([new StringChunk(str)]);
19748
19817
  }
19749
19818
  _sql.raw = raw;
19750
- function join35(chunks, separator) {
19819
+ function join36(chunks, separator) {
19751
19820
  const result = [];
19752
19821
  for (const [i, chunk] of chunks.entries()) {
19753
19822
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -19755,7 +19824,7 @@ var init_sql = __esm({
19755
19824
  }
19756
19825
  return new SQL(result);
19757
19826
  }
19758
- _sql.join = join35;
19827
+ _sql.join = join36;
19759
19828
  function identifier2(value) {
19760
19829
  return new Name(value);
19761
19830
  }
@@ -21770,7 +21839,7 @@ var init_select = __esm({
21770
21839
  const baseTableName = this.tableName;
21771
21840
  const tableName = getTableLikeName(table);
21772
21841
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
21773
- if (typeof tableName === "string" && this.config.joins?.some((join35) => join35.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
21842
+ if (typeof tableName === "string" && this.config.joins?.some((join36) => join36.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
21774
21843
  if (!this.isPartialSelect) {
21775
21844
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
21776
21845
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -23367,7 +23436,7 @@ var init_dialect = __esm({
23367
23436
  if (!joins2) return;
23368
23437
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
23369
23438
  if (!withEntries.length) return;
23370
- return sql.join(withEntries.map(([k, join35]) => {
23439
+ return sql.join(withEntries.map(([k, join36]) => {
23371
23440
  const relation = tableConfig.relations[k];
23372
23441
  const isSingle2 = is(relation, One);
23373
23442
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -23378,7 +23447,7 @@ var init_dialect = __esm({
23378
23447
  table: targetTable,
23379
23448
  mode: isSingle2 ? "first" : "many",
23380
23449
  schema,
23381
- queryConfig: join35,
23450
+ queryConfig: join36,
23382
23451
  tableConfig: schema[relation.targetTableName],
23383
23452
  relationWhere: filter,
23384
23453
  isNested: true,
@@ -23392,7 +23461,7 @@ var init_dialect = __esm({
23392
23461
  key: k,
23393
23462
  selection: innerQuery.selection,
23394
23463
  isArray: !isSingle2,
23395
- isOptional: (relation.optional ?? false) || join35 !== true && !!join35.where
23464
+ isOptional: (relation.optional ?? false) || join36 !== true && !!join36.where
23396
23465
  });
23397
23466
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
23398
23467
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -23814,7 +23883,7 @@ var init_update = __esm({
23814
23883
  createJoin(joinType) {
23815
23884
  return ((table, on) => {
23816
23885
  const tableName = getTableLikeName(table);
23817
- if (typeof tableName === "string" && this.config.joins.some((join35) => join35.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
23886
+ if (typeof tableName === "string" && this.config.joins.some((join36) => join36.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
23818
23887
  if (typeof on === "function") {
23819
23888
  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;
23820
23889
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -24970,7 +25039,7 @@ async function withWriteRetry(fn, opts = {}) {
24970
25039
  throw contentionErr;
24971
25040
  }
24972
25041
  function sleep(ms) {
24973
- return new Promise((resolve14) => setTimeout(resolve14, ms));
25042
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
24974
25043
  }
24975
25044
  var DEFAULT_MAX_ATTEMPTS, DEFAULT_BASE_DELAY_MS, DEFAULT_JITTER_MS;
24976
25045
  var init_with_retry = __esm({
@@ -24982,9 +25051,250 @@ var init_with_retry = __esm({
24982
25051
  }
24983
25052
  });
24984
25053
 
25054
+ // packages/core/src/store/worktree-build-guard.ts
25055
+ import { existsSync as existsSync4, readFileSync as readFileSync3, realpathSync as realpathSync3 } from "node:fs";
25056
+ import { createRequire } from "node:module";
25057
+ import { dirname as dirname3, isAbsolute as isAbsolute3, join as join5, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
25058
+ import { fileURLToPath } from "node:url";
25059
+ function realOrResolved(path2) {
25060
+ try {
25061
+ return realpathSync3(path2);
25062
+ } catch {
25063
+ return resolve2(path2);
25064
+ }
25065
+ }
25066
+ function isWithin(root, path2) {
25067
+ const local = relative2(root, path2);
25068
+ return local === "" || !isAbsolute3(local) && local !== ".." && !local.startsWith(`..${sep2}`);
25069
+ }
25070
+ function insideGitCheckout(dir) {
25071
+ let current = dir;
25072
+ for (; ; ) {
25073
+ if (existsSync4(join5(current, ".git"))) return true;
25074
+ const parent = dirname3(current);
25075
+ if (parent === current) return false;
25076
+ current = parent;
25077
+ }
25078
+ }
25079
+ function insideTestSandbox(path2) {
25080
+ let dir = dirname3(path2);
25081
+ for (; ; ) {
25082
+ if (existsSync4(join5(dir, TEST_SANDBOX_MARKER))) return !insideGitCheckout(dir);
25083
+ const parent = dirname3(dir);
25084
+ if (parent === dir) return false;
25085
+ dir = parent;
25086
+ }
25087
+ }
25088
+ function linkedWorktreeRootOf(path2) {
25089
+ let dir = realOrResolved(path2);
25090
+ for (; ; ) {
25091
+ if (isGitLinkedCheckout(dir)) return dir;
25092
+ if (existsSync4(join5(dir, ".git"))) return null;
25093
+ const parent = dirname3(dir);
25094
+ if (parent === dir) return null;
25095
+ dir = parent;
25096
+ }
25097
+ }
25098
+ function readBuildProvenance(codePath) {
25099
+ let dir = dirname3(codePath);
25100
+ for (; ; ) {
25101
+ const stamp = join5(dir, "build-provenance.json");
25102
+ if (existsSync4(stamp)) {
25103
+ try {
25104
+ const parsed = JSON.parse(readFileSync3(stamp, "utf8"));
25105
+ if (typeof parsed === "object" && parsed !== null && "linkedWorktree" in parsed) {
25106
+ const value = parsed.linkedWorktree;
25107
+ if (value === null || typeof value === "string") return { linkedWorktree: value };
25108
+ }
25109
+ } catch {
25110
+ }
25111
+ return null;
25112
+ }
25113
+ if (existsSync4(join5(dir, "package.json"))) return null;
25114
+ const parent = dirname3(dir);
25115
+ if (parent === dir) return null;
25116
+ dir = parent;
25117
+ }
25118
+ }
25119
+ function devBuildWorktree(options = {}) {
25120
+ const codePath = options.codePath ?? overrides?.codePath ?? fileURLToPath(import.meta.url);
25121
+ const provenance = options.provenance !== void 0 ? options.provenance : overrides?.provenance !== void 0 ? overrides.provenance : readBuildProvenance(codePath);
25122
+ if (provenance) return provenance.linkedWorktree;
25123
+ if (codePath.split(/[\\/]/).includes("node_modules")) return null;
25124
+ return linkedWorktreeRootOf(codePath);
25125
+ }
25126
+ function schemaWriteRefusal(dbPath, options = {}) {
25127
+ const env = options.env ?? overrides?.env ?? process.env;
25128
+ const buildWorktree = devBuildWorktree(options);
25129
+ if (buildWorktree === null) return null;
25130
+ const store = realOrResolved(dbPath);
25131
+ if (isWithin(realOrResolved(buildWorktree), store)) return null;
25132
+ if (env["VITEST"]) return null;
25133
+ const honourTestSandbox = options.honourTestSandbox ?? overrides?.honourTestSandbox ?? true;
25134
+ if (honourTestSandbox && insideTestSandbox(store)) return null;
25135
+ if (env[ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV] === "1") return null;
25136
+ 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).`;
25137
+ }
25138
+ function decisionFor(dbPath) {
25139
+ const key = realOrResolved(dbPath);
25140
+ if (!decisions.has(key)) decisions.set(key, schemaWriteRefusal(key));
25141
+ return decisions.get(key) ?? null;
25142
+ }
25143
+ function isWorktreeBuildSchemaError(error) {
25144
+ return error instanceof Error && error.message.includes(E_WORKTREE_BUILD_SCHEMA);
25145
+ }
25146
+ function codes() {
25147
+ if (authorizerCodes) return authorizerCodes;
25148
+ const sqlite = createRequire(import.meta.url)("node:sqlite").constants;
25149
+ authorizerCodes = {
25150
+ sqlite,
25151
+ creates: /* @__PURE__ */ new Map([
25152
+ [sqlite.SQLITE_CREATE_TABLE, "table"],
25153
+ [sqlite.SQLITE_CREATE_VTABLE, "table"],
25154
+ [sqlite.SQLITE_CREATE_INDEX, "index"],
25155
+ [sqlite.SQLITE_CREATE_TRIGGER, "trigger"],
25156
+ [sqlite.SQLITE_CREATE_VIEW, "view"]
25157
+ ]),
25158
+ changes: /* @__PURE__ */ new Set([
25159
+ sqlite.SQLITE_ALTER_TABLE,
25160
+ sqlite.SQLITE_DROP_TABLE,
25161
+ sqlite.SQLITE_DROP_INDEX,
25162
+ sqlite.SQLITE_DROP_TRIGGER,
25163
+ sqlite.SQLITE_DROP_VIEW,
25164
+ sqlite.SQLITE_DROP_VTABLE
25165
+ ])
25166
+ };
25167
+ return authorizerCodes;
25168
+ }
25169
+ function attachRefusal(name2) {
25170
+ if (name2 === "" || name2 === ":memory:") return null;
25171
+ if (typeof name2 !== "string" || /^file:/i.test(name2) || name2.includes("?")) {
25172
+ return UNKNOWN_ATTACH_REFUSAL;
25173
+ }
25174
+ return decisionFor(name2);
25175
+ }
25176
+ function readSchemas(nativeDb) {
25177
+ const schemas = /* @__PURE__ */ new Map();
25178
+ const list = nativeDb.prepare("PRAGMA database_list").all();
25179
+ for (const { name: name2, file } of list) {
25180
+ if (name2 === "temp") continue;
25181
+ const rows = nativeDb.prepare(`SELECT type, name FROM "${name2.replaceAll('"', '""')}".sqlite_master`).all();
25182
+ schemas.set(name2.toLowerCase(), {
25183
+ refusal: file ? decisionFor(file) : null,
25184
+ // '' = in-memory
25185
+ objects: new Set(rows.map((r) => `${r.type}:${r.name}`))
25186
+ });
25187
+ }
25188
+ return schemas;
25189
+ }
25190
+ function guardActive() {
25191
+ const env = overrides?.env ?? process.env;
25192
+ if (env["VITEST"]) return false;
25193
+ if (overrides) return devBuildWorktree() !== null;
25194
+ if (processBuildWorktree === void 0) processBuildWorktree = devBuildWorktree();
25195
+ return processBuildWorktree !== null;
25196
+ }
25197
+ function installSchemaWriteGuard(nativeDb) {
25198
+ if (!guardActive()) return false;
25199
+ const location = nativeDb.location();
25200
+ const mainRefusal = location ? decisionFor(location) : null;
25201
+ if (typeof nativeDb.setAuthorizer !== "function") {
25202
+ if (mainRefusal) throw new WorktreeBuildSchemaError(mainRefusal);
25203
+ return false;
25204
+ }
25205
+ const state = {
25206
+ schemas: readSchemas(nativeDb),
25207
+ unmappedAttachRefusal: null,
25208
+ stale: false,
25209
+ lastDenied: null
25210
+ };
25211
+ guards.set(nativeDb, state);
25212
+ const { sqlite, creates, changes } = codes();
25213
+ nativeDb.setAuthorizer((action, arg1, arg2, dbName) => {
25214
+ if (action === sqlite.SQLITE_ATTACH) {
25215
+ const refusal2 = attachRefusal(arg1);
25216
+ if (refusal2 && !state.unmappedAttachRefusal) state.unmappedAttachRefusal = refusal2;
25217
+ return sqlite.SQLITE_OK;
25218
+ }
25219
+ if (action === sqlite.SQLITE_DETACH) {
25220
+ state.stale = true;
25221
+ return sqlite.SQLITE_OK;
25222
+ }
25223
+ const createType = creates.get(action);
25224
+ if (createType === void 0 && !changes.has(action)) return sqlite.SQLITE_OK;
25225
+ const schema = ((action === sqlite.SQLITE_ALTER_TABLE ? arg1 : dbName) ?? "main").toLowerCase();
25226
+ if (schema === "temp") return sqlite.SQLITE_OK;
25227
+ const mapped = state.schemas.get(schema);
25228
+ const policy = state.stale ? void 0 : mapped;
25229
+ const refusal = policy ? policy.refusal : (mapped?.refusal ?? null) || state.unmappedAttachRefusal;
25230
+ if (refusal === null) return sqlite.SQLITE_OK;
25231
+ if (createType !== void 0 && policy?.objects.has(`${createType}:${arg1}`)) {
25232
+ return sqlite.SQLITE_OK;
25233
+ }
25234
+ state.lastDenied = {
25235
+ what: createType !== void 0 ? `CREATE ${createType} ${schema}.${arg1}` : `schema change on ${schema}.${(action === sqlite.SQLITE_ALTER_TABLE ? arg2 : arg1) ?? ""}`,
25236
+ refusal
25237
+ };
25238
+ return sqlite.SQLITE_DENY;
25239
+ });
25240
+ return mainRefusal !== null;
25241
+ }
25242
+ function refreshSchemaWriteGuard(nativeDb) {
25243
+ const state = guards.get(nativeDb);
25244
+ if (!state) return;
25245
+ state.schemas = readSchemas(nativeDb);
25246
+ state.unmappedAttachRefusal = null;
25247
+ state.stale = false;
25248
+ }
25249
+ function explainSchemaWriteDenial(nativeDb, error) {
25250
+ if (!(error instanceof Error) || !/not authorized/i.test(error.message)) return error;
25251
+ const denied = guards.get(nativeDb)?.lastDenied;
25252
+ if (!denied) return error;
25253
+ return new WorktreeBuildSchemaError(`${denied.refusal} Denied: ${denied.what}.`);
25254
+ }
25255
+ function pendingMigrations(nativeDb, migrations) {
25256
+ const hasJournal = nativeDb.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '__drizzle_migrations'").get();
25257
+ const applied = hasJournal ? new Set(
25258
+ nativeDb.prepare('SELECT hash FROM main."__drizzle_migrations"').all().map((row) => row.hash)
25259
+ ) : /* @__PURE__ */ new Set();
25260
+ return migrations.filter((m) => !applied.has(m.hash)).map((m) => m.name ?? m.hash);
25261
+ }
25262
+ function assertNoPendingMigrationsForWorktreeBuild(nativeDb, migrations) {
25263
+ const dbPath = nativeDb.location();
25264
+ if (!dbPath) return;
25265
+ const refusal = decisionFor(dbPath);
25266
+ if (refusal === null) return;
25267
+ const pending = pendingMigrations(nativeDb, migrations);
25268
+ if (pending.length === 0) return;
25269
+ throw new WorktreeBuildSchemaError(`${refusal} Pending migrations: ${pending.join(", ")}.`);
25270
+ }
25271
+ var ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV, TEST_SANDBOX_MARKER, E_WORKTREE_BUILD_SCHEMA, overrides, decisions, WorktreeBuildSchemaError, authorizerCodes, guards, UNKNOWN_ATTACH_REFUSAL, processBuildWorktree;
25272
+ var init_worktree_build_guard = __esm({
25273
+ "packages/core/src/store/worktree-build-guard.ts"() {
25274
+ "use strict";
25275
+ init_src();
25276
+ init_errors2();
25277
+ init_project_scope();
25278
+ ALLOW_WORKTREE_BUILD_MIGRATIONS_ENV = "CLEO_ALLOW_WORKTREE_BUILD_MIGRATIONS";
25279
+ TEST_SANDBOX_MARKER = ".cleo-test-sandbox";
25280
+ E_WORKTREE_BUILD_SCHEMA = "E_WORKTREE_BUILD_SCHEMA";
25281
+ overrides = null;
25282
+ decisions = /* @__PURE__ */ new Map();
25283
+ WorktreeBuildSchemaError = class extends CleoError {
25284
+ constructor(message) {
25285
+ super(8 /* CONFIG_ERROR */, `${E_WORKTREE_BUILD_SCHEMA}: ${message}`, {
25286
+ 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.`
25287
+ });
25288
+ }
25289
+ };
25290
+ guards = /* @__PURE__ */ new WeakMap();
25291
+ 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";
25292
+ }
25293
+ });
25294
+
24985
25295
  // packages/core/src/store/migration-manager.ts
24986
- import { copyFileSync, existsSync as existsSync4 } from "node:fs";
24987
- import { dirname as dirname3, join as join5 } from "node:path";
25296
+ import { copyFileSync, existsSync as existsSync5 } from "node:fs";
25297
+ import { dirname as dirname4, join as join6 } from "node:path";
24988
25298
  function stripSqlComments(sql32) {
24989
25299
  return sql32.replace(/--[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
24990
25300
  }
@@ -25023,10 +25333,10 @@ function computeEliminatedTables(migrations) {
25023
25333
  return eliminated;
25024
25334
  }
25025
25335
  function resolveConsolidationCutoverPrefix(migrationsFolder) {
25026
- const parent = dirname3(migrationsFolder);
25336
+ const parent = dirname4(migrationsFolder);
25027
25337
  for (const setName of ["drizzle-cleo-project", "drizzle-cleo-global"]) {
25028
- const folder = join5(parent, setName);
25029
- if (!existsSync4(folder)) continue;
25338
+ const folder = join6(parent, setName);
25339
+ if (!existsSync5(folder)) continue;
25030
25340
  try {
25031
25341
  const consolidation = readMigrationFiles({ migrationsFolder: folder }).find(
25032
25342
  (m) => /-consolidation-cleo-/.test(m.name ?? "")
@@ -25050,7 +25360,7 @@ function tableExists(nativeDb, tableName) {
25050
25360
  }
25051
25361
  function createSafetyBackup(dbPath) {
25052
25362
  const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
25053
- if (!existsSync4(backupPath)) {
25363
+ if (!existsSync5(backupPath)) {
25054
25364
  try {
25055
25365
  copyFileSync(dbPath, backupPath);
25056
25366
  } catch {
@@ -25168,6 +25478,16 @@ function readSiblingMigrationHashes(siblingFolder) {
25168
25478
  return /* @__PURE__ */ new Set();
25169
25479
  }
25170
25480
  }
25481
+ function readSiblingNewestMillis(siblingFolder) {
25482
+ try {
25483
+ return Math.max(
25484
+ 0,
25485
+ ...readMigrationFiles({ migrationsFolder: siblingFolder }).map((m) => m.folderMillis)
25486
+ );
25487
+ } catch {
25488
+ return 0;
25489
+ }
25490
+ }
25171
25491
  function ensureJournalHashUnique(nativeDb) {
25172
25492
  if (!tableExists(nativeDb, "__drizzle_migrations")) return;
25173
25493
  try {
@@ -25216,6 +25536,7 @@ function upgradeSharedJournalFormat(nativeDb, lineageFolders) {
25216
25536
  return { named, unnamed: rows.length - named };
25217
25537
  }
25218
25538
  function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsystem, siblingMigrationsFolders = []) {
25539
+ assertNoPendingMigrationsForWorktreeBuild(nativeDb, readMigrationFiles({ migrationsFolder }));
25219
25540
  const eliminatedTables = computeEliminatedTables(readMigrationFiles({ migrationsFolder }));
25220
25541
  const cutoverPrefix = resolveConsolidationCutoverPrefix(migrationsFolder);
25221
25542
  if (siblingMigrationsFolders.length > 0)
@@ -25247,8 +25568,15 @@ function reconcileJournal(nativeDb, migrationsFolder, existenceTable2, logSubsys
25247
25568
  knownHashes.add(m);
25248
25569
  }
25249
25570
  }
25250
- const dbEntries = nativeDb.prepare('SELECT id, hash FROM "__drizzle_migrations"').all();
25251
- const orphanedEntries = dbEntries.filter((e) => !knownHashes.has(e.hash));
25571
+ const newestKnownMillis = Math.max(
25572
+ 0,
25573
+ ...localMigrations.map((m) => m.folderMillis),
25574
+ ...siblingMigrationsFolders.filter((folder) => folder !== migrationsFolder).map(readSiblingNewestMillis)
25575
+ );
25576
+ const dbEntries = nativeDb.prepare('SELECT id, hash, created_at FROM "__drizzle_migrations"').all();
25577
+ const orphanedEntries = dbEntries.filter(
25578
+ (e) => !knownHashes.has(e.hash) && !(Number(e.created_at) > newestKnownMillis)
25579
+ );
25252
25580
  const hasOrphanedEntries = orphanedEntries.length > 0;
25253
25581
  if (hasOrphanedEntries) {
25254
25582
  const dbHashes = new Set(dbEntries.map((e) => e.hash));
@@ -25490,6 +25818,8 @@ function sanitizeMigrationStatements(migrations) {
25490
25818
  }
25491
25819
  function migrateSanitized(db, config) {
25492
25820
  const raw = readMigrationFiles(config);
25821
+ const client = db.$client;
25822
+ if (client) assertNoPendingMigrationsForWorktreeBuild(client, raw);
25493
25823
  const sanitized = sanitizeMigrationStatements(raw);
25494
25824
  migrateSync(sanitized, db._.session, config);
25495
25825
  }
@@ -25553,6 +25883,7 @@ var init_migration_manager = __esm({
25553
25883
  init_sqlite_core();
25554
25884
  init_logger2();
25555
25885
  init_with_retry();
25886
+ init_worktree_build_guard();
25556
25887
  MAX_MIGRATION_RETRIES = 5;
25557
25888
  MIGRATION_RETRY_BASE_DELAY_MS = 100;
25558
25889
  MIGRATION_RETRY_MAX_DELAY_MS = 2e3;
@@ -25562,13 +25893,13 @@ var init_migration_manager = __esm({
25562
25893
  });
25563
25894
 
25564
25895
  // packages/core/src/store/relocated-store-guard.ts
25565
- import { existsSync as existsSync5, realpathSync as realpathSync3 } from "node:fs";
25566
- import { createRequire } from "node:module";
25567
- import { basename as basename3, dirname as dirname4 } from "node:path";
25896
+ import { existsSync as existsSync6, realpathSync as realpathSync4 } from "node:fs";
25897
+ import { createRequire as createRequire2 } from "node:module";
25898
+ import { basename as basename3, dirname as dirname5 } from "node:path";
25568
25899
  import { readDeclaredProjectIdentity as readDeclaredProjectIdentity2, readPortableProjectId } from "@cleocode/paths";
25569
25900
  function real2(p) {
25570
25901
  try {
25571
- return realpathSync3(p);
25902
+ return realpathSync4(p);
25572
25903
  } catch {
25573
25904
  return p;
25574
25905
  }
@@ -25585,7 +25916,7 @@ function liveElsewhere(globalDbPath, projectId, root) {
25585
25916
  "SELECT project_path AS projectPath FROM nexus_project_registry WHERE project_id = ?"
25586
25917
  ).get(projectId);
25587
25918
  const live = row?.projectPath;
25588
- if (!live || paths.has(live) || !existsSync5(live)) return null;
25919
+ if (!live || paths.has(live) || !existsSync6(live)) return null;
25589
25920
  if (!isStrictlyInsideDir(root, live)) return null;
25590
25921
  return readDeclaredProjectIdentity2(live)?.projectId === projectId ? live : null;
25591
25922
  } catch {
@@ -25599,14 +25930,14 @@ function detectRelocatedRoot(root, globalDbPath) {
25599
25930
  if (tombstone)
25600
25931
  return { projectId: tombstone.projectId, movedTo: tombstone.movedTo, via: "tombstone" };
25601
25932
  const declared = readPortableProjectId(root);
25602
- if (declared.status !== "valid" || !existsSync5(globalDbPath)) return null;
25933
+ if (declared.status !== "valid" || !existsSync6(globalDbPath)) return null;
25603
25934
  const movedTo = liveElsewhere(globalDbPath, declared.projectId, root);
25604
25935
  return movedTo ? { projectId: declared.projectId, movedTo, via: "registry" } : null;
25605
25936
  }
25606
25937
  function assertStoreNotRelocated(dbPath, globalDbPath) {
25607
- if (basename3(dbPath) !== "cleo.db" || basename3(dirname4(dbPath)) !== ".cleo") return;
25608
- if (existsSync5(dbPath) || globalDbPath === dbPath) return;
25609
- const root = dirname4(dirname4(dbPath));
25938
+ if (basename3(dbPath) !== "cleo.db" || basename3(dirname5(dbPath)) !== ".cleo") return;
25939
+ if (existsSync6(dbPath) || globalDbPath === dbPath) return;
25940
+ const root = dirname5(dirname5(dbPath));
25610
25941
  if (_adopted.has(root)) return;
25611
25942
  const moved = detectRelocatedRoot(root, globalDbPath);
25612
25943
  if (moved) throw projectMovedError(root, moved, void 0, moved.via);
@@ -25616,17 +25947,17 @@ var init_relocated_store_guard = __esm({
25616
25947
  "packages/core/src/store/relocated-store-guard.ts"() {
25617
25948
  "use strict";
25618
25949
  init_project_tombstone();
25619
- _require = createRequire(import.meta.url);
25950
+ _require = createRequire2(import.meta.url);
25620
25951
  _adopted = /* @__PURE__ */ new Set();
25621
25952
  }
25622
25953
  });
25623
25954
 
25624
25955
  // packages/core/src/store/resolve-migrations-folder.ts
25625
- import { createRequire as createRequire2 } from "node:module";
25626
- import { dirname as dirname5, join as join6 } from "node:path";
25627
- import { fileURLToPath } from "node:url";
25956
+ import { createRequire as createRequire3 } from "node:module";
25957
+ import { dirname as dirname6, join as join7 } from "node:path";
25958
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
25628
25959
  function coreRootFromEntry(entryPath) {
25629
- return dirname5(dirname5(entryPath));
25960
+ return dirname6(dirname6(entryPath));
25630
25961
  }
25631
25962
  function resolveConsolidatedJournalSiblings(ownSetName) {
25632
25963
  return CONSOLIDATED_JOURNAL_LINEAGES.filter((name2) => name2 !== ownSetName).map(
@@ -25636,14 +25967,14 @@ function resolveConsolidatedJournalSiblings(ownSetName) {
25636
25967
  function resolveCorePackageMigrationsFolder(setName) {
25637
25968
  try {
25638
25969
  const resolved = import.meta.resolve("@cleocode/core", import.meta.url);
25639
- const entryPath = fileURLToPath(resolved);
25640
- return join6(coreRootFromEntry(entryPath), "migrations", setName);
25970
+ const entryPath = fileURLToPath2(resolved);
25971
+ return join7(coreRootFromEntry(entryPath), "migrations", setName);
25641
25972
  } catch {
25642
25973
  }
25643
- const _require7 = createRequire2(import.meta.url);
25974
+ const _require7 = createRequire3(import.meta.url);
25644
25975
  try {
25645
25976
  const entryPath = _require7.resolve("@cleocode/core");
25646
- return join6(coreRootFromEntry(entryPath), "migrations", setName);
25977
+ return join7(coreRootFromEntry(entryPath), "migrations", setName);
25647
25978
  } catch (err) {
25648
25979
  throw new Error(
25649
25980
  `resolveCorePackageMigrationsFolder("${setName}"): cannot locate @cleocode/core from "${import.meta.url}". Ensure @cleocode/core is installed (workspace or npm). Original error: ${err.message}`
@@ -25753,11 +26084,11 @@ var init_sqlite_pragmas = __esm({
25753
26084
  });
25754
26085
 
25755
26086
  // packages/core/src/store/worktree-isolation-guard.ts
25756
- import { basename as basename4, dirname as dirname6, join as join7 } from "node:path";
26087
+ import { basename as basename4, dirname as dirname7, join as join8, resolve as resolve3 } from "node:path";
25757
26088
  function assertStorePathIsNotWorktreeResident(role, dbPath) {
25758
- const cleoDir = dirname6(dbPath);
26089
+ const cleoDir = dirname7(dbPath);
25759
26090
  if (basename4(cleoDir) !== ".cleo") return;
25760
- const projectRoot = dirname6(cleoDir);
26091
+ const projectRoot = dirname7(cleoDir);
25761
26092
  if (!isGitLinkedCheckout(projectRoot)) return;
25762
26093
  if (process.env["CLEO_ALLOW_WORKTREE_DB_CREATE"] === "1") {
25763
26094
  process.stderr.write(
@@ -25782,7 +26113,7 @@ function assertDbPathIsNotWorktreeResident(role, cwd) {
25782
26113
  } catch {
25783
26114
  return;
25784
26115
  }
25785
- assertStorePathIsNotWorktreeResident(role, join7(cleoDir, PROJECT_STORE_FILENAME2));
26116
+ assertStorePathIsNotWorktreeResident(role, join8(cleoDir, PROJECT_STORE_FILENAME2));
25786
26117
  }
25787
26118
  var PROJECT_STORE_FILENAME2;
25788
26119
  var init_worktree_isolation_guard = __esm({
@@ -25802,10 +26133,10 @@ __export(sqlite_native_exports, {
25802
26133
  getDbSyncConstructor: () => getDbSyncConstructor,
25803
26134
  openNativeDatabase: () => openNativeDatabase
25804
26135
  });
25805
- import { realpathSync as realpathSync4 } from "node:fs";
25806
- import { createRequire as createRequire3 } from "node:module";
26136
+ import { realpathSync as realpathSync5 } from "node:fs";
26137
+ import { createRequire as createRequire4 } from "node:module";
25807
26138
  import { tmpdir as tmpdir2 } from "node:os";
25808
- import { delimiter, dirname as dirname7, isAbsolute as isAbsolute3, join as join8, resolve as resolve2, sep as sep2 } from "node:path";
26139
+ import { delimiter, dirname as dirname8, isAbsolute as isAbsolute4, join as join9, resolve as resolve4, sep as sep3 } from "node:path";
25809
26140
  function getDbSyncConstructor() {
25810
26141
  if (_ctor === null) {
25811
26142
  const mod = _require2("node:sqlite");
@@ -25814,19 +26145,19 @@ function getDbSyncConstructor() {
25814
26145
  return _ctor;
25815
26146
  }
25816
26147
  function resolveAbsoluteSafe(p) {
25817
- const abs = isAbsolute3(p) ? p : resolve2(p);
26148
+ const abs = isAbsolute4(p) ? p : resolve4(p);
25818
26149
  try {
25819
- return realpathSync4(abs);
26150
+ return realpathSync5(abs);
25820
26151
  } catch {
25821
26152
  const missingParts = [];
25822
26153
  let cursor = abs;
25823
26154
  while (true) {
25824
- const parent = dirname7(cursor);
26155
+ const parent = dirname8(cursor);
25825
26156
  if (parent === cursor) return abs;
25826
- missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep2) ? 0 : 1)));
26157
+ missingParts.unshift(cursor.slice(parent.length + (parent.endsWith(sep3) ? 0 : 1)));
25827
26158
  cursor = parent;
25828
26159
  try {
25829
- return join8(realpathSync4(cursor), ...missingParts);
26160
+ return join9(realpathSync5(cursor), ...missingParts);
25830
26161
  } catch {
25831
26162
  }
25832
26163
  }
@@ -25834,7 +26165,7 @@ function resolveAbsoluteSafe(p) {
25834
26165
  }
25835
26166
  function isPathUnder(child, parent) {
25836
26167
  if (child === parent) return true;
25837
- const withSep = parent.endsWith(sep2) ? parent : parent + sep2;
26168
+ const withSep = parent.endsWith(sep3) ? parent : parent + sep3;
25838
26169
  return child.startsWith(withSep);
25839
26170
  }
25840
26171
  function assertVitestSafePath(path2) {
@@ -25857,6 +26188,7 @@ function openNativeDatabase(path2, options) {
25857
26188
  assertVitestSafePath(path2);
25858
26189
  const DatabaseSyncCtor = getDbSyncConstructor();
25859
26190
  const db = new DatabaseSyncCtor(path2, {
26191
+ // schema-guard-exempt: the native chokepoint; every writable caller installs the guard
25860
26192
  enableForeignKeyConstraints: true,
25861
26193
  readOnly: options?.readonly ?? false,
25862
26194
  // Default handle-open lock timeout mirrors the SSoT busy_timeout
@@ -25908,7 +26240,7 @@ var init_sqlite_native = __esm({
25908
26240
  "packages/core/src/store/sqlite-native.ts"() {
25909
26241
  "use strict";
25910
26242
  init_sqlite_pragmas();
25911
- _require2 = createRequire3(import.meta.url);
26243
+ _require2 = createRequire4(import.meta.url);
25912
26244
  _ctor = null;
25913
26245
  }
25914
26246
  });
@@ -25982,7 +26314,7 @@ var init_writer_lease_schema = __esm({
25982
26314
  // packages/core/src/store/writer-lease.ts
25983
26315
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "node:async_hooks";
25984
26316
  import { randomUUID } from "node:crypto";
25985
- import { realpathSync as realpathSync5, statSync as statSync2 } from "node:fs";
26317
+ import { realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
25986
26318
  import { resolve as resolvePath } from "node:path";
25987
26319
  function log() {
25988
26320
  if (_log === null) _log = getLogger("writer-lease");
@@ -26072,7 +26404,7 @@ function resolveDbIdentity(db) {
26072
26404
  return identity;
26073
26405
  }
26074
26406
  function sleepAsync(ms) {
26075
- return new Promise((resolve14) => setTimeout(resolve14, Math.max(0, Math.round(ms))));
26407
+ return new Promise((resolve16) => setTimeout(resolve16, Math.max(0, Math.round(ms))));
26076
26408
  }
26077
26409
  function isPidAlive(pid) {
26078
26410
  try {
@@ -26411,7 +26743,7 @@ function assertColdOpenFile(frame) {
26411
26743
  async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
26412
26744
  opts.execution?.assertActive();
26413
26745
  const captured = opts.requiredIdentity;
26414
- const path2 = realpathSync5(captured.dbPath);
26746
+ const path2 = realpathSync6(captured.dbPath);
26415
26747
  const identity = statSync2(path2, { bigint: true });
26416
26748
  if (captured.scope !== scope || captured.fileDevice !== String(identity.dev) || captured.fileInode !== String(identity.ino)) {
26417
26749
  throw new LeaseUnavailableError(
@@ -26444,6 +26776,7 @@ async function withRequiredColdOpenLease(scope, nativeDb, fn, opts) {
26444
26776
  }
26445
26777
  const remaining = opts.execution ? Math.max(1, opts.execution.deadlineAt - Date.now()) : ACQUIRE_DEADLINE_MS;
26446
26778
  const owned = openNativeDatabase(path2, { timeout: Math.min(ACQUIRE_DEADLINE_MS, remaining) });
26779
+ installSchemaWriteGuard(owned);
26447
26780
  try {
26448
26781
  opts.execution?.assertActive();
26449
26782
  const afterOpen = statSync2(path2, { bigint: true });
@@ -26637,6 +26970,7 @@ var init_writer_lease = __esm({
26637
26970
  init_background_ops();
26638
26971
  init_dual_scope_db();
26639
26972
  init_sqlite_native();
26973
+ init_worktree_build_guard();
26640
26974
  init_writer_lease_schema();
26641
26975
  DEFAULT_TTL_MS = 3e4;
26642
26976
  DEFAULT_PRIORITY = 100;
@@ -27179,10 +27513,10 @@ var init_monitor = __esm({
27179
27513
 
27180
27514
  // packages/core/src/resources/supervisor-admit.ts
27181
27515
  import { connect } from "node:net";
27182
- import { join as join9 } from "node:path";
27516
+ import { join as join10 } from "node:path";
27183
27517
  import { getCleoHome as getCleoHome2 } from "@cleocode/paths";
27184
27518
  function resolveSupervisorSocketPath() {
27185
- return process.env.CLEO_SUPERVISOR_SOCKET ?? join9(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
27519
+ return process.env.CLEO_SUPERVISOR_SOCKET ?? join10(getCleoHome2(), SUPERVISOR_SOCKET_NAME);
27186
27520
  }
27187
27521
  async function sendResourceAdmit(socketPath, cls, holderId, budget) {
27188
27522
  const result = await sendLeaseRequest(
@@ -27205,7 +27539,7 @@ async function sendResourceRelease(socketPath, cls, holderId) {
27205
27539
  return { unavailable: true, reason: `unexpected response kind: ${result.kind}` };
27206
27540
  }
27207
27541
  function sendLeaseRequest(socketPath, request, expectedKind) {
27208
- return new Promise((resolve14) => {
27542
+ return new Promise((resolve16) => {
27209
27543
  const id = `ra-${process.pid}-${request.kind}`;
27210
27544
  const envelope = LeaseIpcRequestEnvelopeSchema.parse({
27211
27545
  protocol_version: LEASE_IPC_PROTOCOL_VERSION,
@@ -27223,7 +27557,7 @@ function sendLeaseRequest(socketPath, request, expectedKind) {
27223
27557
  settled = true;
27224
27558
  socket.removeAllListeners();
27225
27559
  socket.destroy();
27226
- resolve14(value);
27560
+ resolve16(value);
27227
27561
  };
27228
27562
  const degrade = (reason) => done({ unavailable: true, reason });
27229
27563
  socket.setTimeout(REQUEST_TIMEOUT_MS);
@@ -27294,9 +27628,9 @@ __export(governor_exports, {
27294
27628
  resolveGovernorMode: () => resolveGovernorMode,
27295
27629
  slotFileCount: () => slotFileCount
27296
27630
  });
27297
- import { existsSync as existsSync6, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
27631
+ import { existsSync as existsSync7, mkdirSync, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "node:fs";
27298
27632
  import { availableParallelism, totalmem } from "node:os";
27299
- import { join as join10 } from "node:path";
27633
+ import { join as join11 } from "node:path";
27300
27634
  import lockfile from "proper-lockfile";
27301
27635
  function log2() {
27302
27636
  if (_log2 === null) _log2 = getLogger("resource-governor");
@@ -27365,14 +27699,14 @@ function clamp(lo, v, hi) {
27365
27699
  return Math.max(lo, Math.min(v, hi));
27366
27700
  }
27367
27701
  function governorSlotDir(cls) {
27368
- return join10(getCleoHome(), "locks", `resource-${cls}`);
27702
+ return join11(getCleoHome(), "locks", `resource-${cls}`);
27369
27703
  }
27370
27704
  function ensureSlotFiles(dir, count) {
27371
- if (!existsSync6(dir)) mkdirSync(dir, { recursive: true });
27705
+ if (!existsSync7(dir)) mkdirSync(dir, { recursive: true });
27372
27706
  const paths = [];
27373
27707
  for (let i = 0; i < count; i++) {
27374
- const p = join10(dir, `slot-${i}.lock`);
27375
- if (!existsSync6(p)) writeFileSync3(p, "", { flag: "a" });
27708
+ const p = join11(dir, `slot-${i}.lock`);
27709
+ if (!existsSync7(p)) writeFileSync3(p, "", { flag: "a" });
27376
27710
  paths.push(p);
27377
27711
  }
27378
27712
  return paths;
@@ -27412,7 +27746,7 @@ function shuffledIndices(n) {
27412
27746
  }
27413
27747
  async function countHeldSlots(cls, budget) {
27414
27748
  const dir = governorSlotDir(cls);
27415
- if (!existsSync6(dir)) return 0;
27749
+ if (!existsSync7(dir)) return 0;
27416
27750
  const slots = ensureSlotFiles(dir, budget);
27417
27751
  let held = 0;
27418
27752
  for (const path2 of slots) {
@@ -27427,7 +27761,7 @@ async function countHeldSlots(cls, budget) {
27427
27761
  }
27428
27762
  function slotFileCount(cls) {
27429
27763
  const dir = governorSlotDir(cls);
27430
- if (!existsSync6(dir)) return 0;
27764
+ if (!existsSync7(dir)) return 0;
27431
27765
  return readdirSync2(dir).filter((f) => f.startsWith("slot-") && f.endsWith(".lock")).length;
27432
27766
  }
27433
27767
  var _log2, _cachedMode2, _supervisorDegradeLogged, MB, STALE_MS, _supervisorHolderSeq, ResourceGovernor, governor;
@@ -27627,11 +27961,11 @@ var init_lock = __esm({
27627
27961
 
27628
27962
  // packages/core/src/store/atomic.ts
27629
27963
  import { mkdir, readFile as readFile2, rename, unlink } from "node:fs/promises";
27630
- import { dirname as dirname8 } from "node:path";
27964
+ import { dirname as dirname9 } from "node:path";
27631
27965
  import writeFileAtomic from "write-file-atomic";
27632
27966
  async function atomicWrite(filePath, data, options) {
27633
27967
  try {
27634
- await mkdir(dirname8(filePath), { recursive: true });
27968
+ await mkdir(dirname9(filePath), { recursive: true });
27635
27969
  await writeFileAtomic(filePath, data, {
27636
27970
  encoding: options?.encoding ?? "utf8",
27637
27971
  mode: options?.mode
@@ -27664,7 +27998,7 @@ var init_atomic = __esm({
27664
27998
 
27665
27999
  // packages/core/src/store/backup.ts
27666
28000
  import { copyFile, rename as fsRename, mkdir as mkdir2, readdir, stat as stat2, unlink as unlink2 } from "node:fs/promises";
27667
- import { basename as basename5, join as join11 } from "node:path";
28001
+ import { basename as basename5, dirname as dirname10, join as join12 } from "node:path";
27668
28002
  async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUPS) {
27669
28003
  try {
27670
28004
  await mkdir2(backupDir, { recursive: true });
@@ -27675,14 +28009,14 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
27675
28009
  throw new CleoError(3 /* FILE_ERROR */, `Cannot backup: source file not found: ${filePath}`);
27676
28010
  }
27677
28011
  for (let i = maxBackups; i >= 1; i--) {
27678
- const current = join11(backupDir, `${fileName}.${i}`);
28012
+ const current = join12(backupDir, `${fileName}.${i}`);
27679
28013
  if (i === maxBackups) {
27680
28014
  try {
27681
28015
  await unlink2(current);
27682
28016
  } catch {
27683
28017
  }
27684
28018
  } else {
27685
- const next = join11(backupDir, `${fileName}.${i + 1}`);
28019
+ const next = join12(backupDir, `${fileName}.${i + 1}`);
27686
28020
  try {
27687
28021
  await stat2(current);
27688
28022
  await fsRename(current, next);
@@ -27690,7 +28024,7 @@ async function createBackup(filePath, backupDir, maxBackups = DEFAULT_MAX_BACKUP
27690
28024
  }
27691
28025
  }
27692
28026
  }
27693
- const backupPath = join11(backupDir, `${fileName}.1`);
28027
+ const backupPath = join12(backupDir, `${fileName}.1`);
27694
28028
  await copyFile(filePath, backupPath);
27695
28029
  return backupPath;
27696
28030
  } catch (err) {
@@ -27704,6 +28038,7 @@ var init_backup = __esm({
27704
28038
  "use strict";
27705
28039
  init_src();
27706
28040
  init_errors2();
28041
+ init_worktree_isolation_guard();
27707
28042
  DEFAULT_MAX_BACKUPS = 5;
27708
28043
  }
27709
28044
  });
@@ -27988,7 +28323,7 @@ __export(identity_exports, {
27988
28323
  import { execFile } from "node:child_process";
27989
28324
  import { createHash as createHash2 } from "node:crypto";
27990
28325
  import { readFile as readFile3 } from "node:fs/promises";
27991
- import { join as join12, resolve as resolve3 } from "node:path";
28326
+ import { join as join13, resolve as resolve5 } from "node:path";
27992
28327
  import { promisify } from "node:util";
27993
28328
  import { legacyProjectId } from "@cleocode/paths";
27994
28329
  import { legacyProjectId as legacyProjectId2 } from "@cleocode/paths";
@@ -27996,14 +28331,14 @@ async function findGitRoot(fromPath, execution) {
27996
28331
  execution?.assertActive();
27997
28332
  try {
27998
28333
  const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], {
27999
- cwd: resolve3(fromPath),
28334
+ cwd: resolve5(fromPath),
28000
28335
  signal: execution?.signal,
28001
28336
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28002
28337
  killSignal: "SIGKILL",
28003
28338
  maxBuffer: 64 * 1024
28004
28339
  });
28005
28340
  execution?.assertActive();
28006
- return resolve3(stdout.trim());
28341
+ return resolve5(stdout.trim());
28007
28342
  } catch {
28008
28343
  execution?.assertActive();
28009
28344
  return null;
@@ -28013,7 +28348,7 @@ async function findGitRemoteUrl(fromPath, execution) {
28013
28348
  execution?.assertActive();
28014
28349
  try {
28015
28350
  const { stdout } = await execFileAsync("git", ["remote", "get-url", "origin"], {
28016
- cwd: resolve3(fromPath),
28351
+ cwd: resolve5(fromPath),
28017
28352
  signal: execution?.signal,
28018
28353
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28019
28354
  killSignal: "SIGKILL",
@@ -28043,7 +28378,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
28043
28378
  try {
28044
28379
  const args = ["--no-replace-objects", "rev-list", "--max-parents=0", "HEAD"];
28045
28380
  const { stdout } = await execFileAsync("git", args, {
28046
- cwd: resolve3(fromPath),
28381
+ cwd: resolve5(fromPath),
28047
28382
  signal: execution?.signal,
28048
28383
  timeout: execution ? Math.max(1, execution.remainingMs()) : void 0,
28049
28384
  killSignal: "SIGKILL",
@@ -28066,7 +28401,7 @@ async function collectCheckoutEvidence(fromPath, execution) {
28066
28401
  async function readProjectInfoName(repoRoot, execution) {
28067
28402
  execution?.assertActive();
28068
28403
  try {
28069
- const raw = await readFile3(join12(repoRoot, ".cleo", "project-info.json"), {
28404
+ const raw = await readFile3(join13(repoRoot, ".cleo", "project-info.json"), {
28070
28405
  encoding: "utf8",
28071
28406
  signal: execution?.signal
28072
28407
  });
@@ -28081,7 +28416,7 @@ async function readProjectInfoName(repoRoot, execution) {
28081
28416
  }
28082
28417
  async function projectPathFingerprint(repoPath, execution) {
28083
28418
  execution?.assertActive();
28084
- const realRepoPath = resolve3(repoPath);
28419
+ const realRepoPath = resolve5(repoPath);
28085
28420
  const results = await Promise.allSettled([
28086
28421
  findGitRoot(realRepoPath, execution),
28087
28422
  findGitRemoteUrl(realRepoPath, execution)
@@ -28105,9 +28440,9 @@ async function projectPathFingerprint(repoPath, execution) {
28105
28440
  }
28106
28441
  function computeLegacyAliases(repoPath, additionalPaths) {
28107
28442
  const aliases = /* @__PURE__ */ new Set();
28108
- aliases.add(legacyProjectId(resolve3(repoPath)));
28443
+ aliases.add(legacyProjectId(resolve5(repoPath)));
28109
28444
  for (const p of additionalPaths ?? []) {
28110
- aliases.add(legacyProjectId(resolve3(p)));
28445
+ aliases.add(legacyProjectId(resolve5(p)));
28111
28446
  }
28112
28447
  return [...aliases];
28113
28448
  }
@@ -28141,17 +28476,17 @@ var init_project_identity = __esm({
28141
28476
  });
28142
28477
 
28143
28478
  // packages/core/src/scaffold/ensure-config.ts
28144
- import { existsSync as existsSync7, readFileSync as readFileSync3 } from "node:fs";
28145
- import { basename as basename6, dirname as dirname9, join as join13, resolve as resolve4 } from "node:path";
28146
- import { fileURLToPath as fileURLToPath2 } from "node:url";
28479
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
28480
+ import { basename as basename6, dirname as dirname11, join as join14, resolve as resolve6 } from "node:path";
28481
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
28147
28482
  function getPackageRoot() {
28148
- const thisFile = fileURLToPath2(import.meta.url);
28149
- return resolve4(dirname9(thisFile), "..", "..");
28483
+ const thisFile = fileURLToPath3(import.meta.url);
28484
+ return resolve6(dirname11(thisFile), "..", "..");
28150
28485
  }
28151
28486
  function getCleoVersion() {
28152
28487
  try {
28153
- const pkgPath = join13(getPackageRoot(), "package.json");
28154
- const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
28488
+ const pkgPath = join14(getPackageRoot(), "package.json");
28489
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
28155
28490
  return pkg.version ?? "0.0.0";
28156
28491
  } catch {
28157
28492
  return "0.0.0";
@@ -28510,25 +28845,25 @@ var init_recovery = __esm({
28510
28845
  // packages/core/src/store/exodus/archive.ts
28511
28846
  import {
28512
28847
  copyFileSync as copyFileSync2,
28513
- existsSync as existsSync8,
28848
+ existsSync as existsSync9,
28514
28849
  mkdirSync as mkdirSync2,
28515
- readFileSync as readFileSync4,
28850
+ readFileSync as readFileSync5,
28516
28851
  renameSync as renameSync3,
28517
28852
  unlinkSync,
28518
28853
  writeFileSync as writeFileSync4
28519
28854
  } from "node:fs";
28520
- import { basename as basename7, dirname as dirname10, join as join14, resolve as resolve5 } from "node:path";
28855
+ import { basename as basename7, dirname as dirname12, join as join15, resolve as resolve7 } from "node:path";
28521
28856
  import { z as z26 } from "zod";
28522
28857
  function scopeBaseDir(scope, cwd, targetDbPath) {
28523
- if (targetDbPath !== void 0) return dirname10(targetDbPath);
28858
+ if (targetDbPath !== void 0) return dirname12(targetDbPath);
28524
28859
  return scope === "project" ? resolveCleoDir(cwd) : getCleoHome();
28525
28860
  }
28526
28861
  function exodusArchiveDir(scope, cwd, targetDbPath) {
28527
- return join14(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
28862
+ return join15(scopeBaseDir(scope, cwd, targetDbPath), ARCHIVE_DIR_NAME);
28528
28863
  }
28529
28864
  function exodusMarkerPath(scope, cwd, targetDbPath) {
28530
28865
  const marker = targetDbPath !== void 0 && basename7(targetDbPath) !== "cleo.db" ? `${basename7(targetDbPath)}.${MARKER_FILENAME_BY_SCOPE[scope]}` : MARKER_FILENAME_BY_SCOPE[scope];
28531
- return join14(scopeBaseDir(scope, cwd, targetDbPath), marker);
28866
+ return join15(scopeBaseDir(scope, cwd, targetDbPath), marker);
28532
28867
  }
28533
28868
  function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
28534
28869
  let markerPath;
@@ -28538,13 +28873,13 @@ function hasExodusCompleteMarker(scope, cwd, targetDbPath, nativeDb) {
28538
28873
  if (targetDbPath) throw error;
28539
28874
  return false;
28540
28875
  }
28541
- if (!existsSync8(markerPath)) return false;
28542
- const marker = markerIdentity.parse(JSON.parse(readFileSync4(markerPath, "utf8")));
28876
+ if (!existsSync9(markerPath)) return false;
28877
+ const marker = markerIdentity.parse(JSON.parse(readFileSync5(markerPath, "utf8")));
28543
28878
  if (nativeDb && (!marker.databaseIdentity || !hasExodusDatabaseIdentity(nativeDb, marker.databaseIdentity)))
28544
28879
  throw new Error(
28545
28880
  "Exodus completion marker does not certify this database generation; assessment required"
28546
28881
  );
28547
- return marker.scope === scope && (!targetDbPath || !marker.targetDbPath || resolve5(marker.targetDbPath) === resolve5(targetDbPath));
28882
+ return marker.scope === scope && (!targetDbPath || !marker.targetDbPath || resolve7(marker.targetDbPath) === resolve7(targetDbPath));
28548
28883
  }
28549
28884
  function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, databaseIdentity) {
28550
28885
  const markerPath = exodusMarkerPath(scope, cwd, targetDbPath);
@@ -28556,7 +28891,7 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
28556
28891
  cleoVersion: getCleoVersion(),
28557
28892
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
28558
28893
  archivedSources: [...archivedSources],
28559
- targetDbPath: resolve5(targetDbPath ?? join14(baseDir, "cleo.db")),
28894
+ targetDbPath: resolve7(targetDbPath ?? join15(baseDir, "cleo.db")),
28560
28895
  ...databaseIdentity ? { databaseIdentity } : {}
28561
28896
  };
28562
28897
  const tmpPath = `${markerPath}.tmp`;
@@ -28567,10 +28902,10 @@ function writeExodusCompleteMarker(scope, archivedSources, cwd, targetDbPath, da
28567
28902
  }
28568
28903
  function moveFileInto(srcPath, destDir) {
28569
28904
  mkdirSync2(destDir, { recursive: true });
28570
- let dest = join14(destDir, basename7(srcPath));
28571
- if (existsSync8(dest)) {
28905
+ let dest = join15(destDir, basename7(srcPath));
28906
+ if (existsSync9(dest)) {
28572
28907
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "").replace(/Z$/, "Z");
28573
- dest = join14(destDir, `${basename7(srcPath)}.${stamp}`);
28908
+ dest = join15(destDir, `${basename7(srcPath)}.${stamp}`);
28574
28909
  }
28575
28910
  try {
28576
28911
  renameSync3(srcPath, dest);
@@ -28581,14 +28916,14 @@ function moveFileInto(srcPath, destDir) {
28581
28916
  return dest;
28582
28917
  }
28583
28918
  function archiveSourceDb(source, cwd, targetDbPath) {
28584
- if (!existsSync8(source.path)) {
28919
+ if (!existsSync9(source.path)) {
28585
28920
  return { name: source.name, sourcePath: source.path, archivedTo: null, action: "absent" };
28586
28921
  }
28587
28922
  const destDir = exodusArchiveDir(source.targetScope, cwd, targetDbPath);
28588
28923
  const archivedTo = moveFileInto(source.path, destDir);
28589
28924
  for (const suffix of SIDECAR_SUFFIXES) {
28590
28925
  const sidecar = `${source.path}${suffix}`;
28591
- if (existsSync8(sidecar)) {
28926
+ if (existsSync9(sidecar)) {
28592
28927
  try {
28593
28928
  moveFileInto(sidecar, destDir);
28594
28929
  } catch (err) {
@@ -28636,7 +28971,7 @@ function detectStrandedResidue(sources, cwd) {
28636
28971
  const stranded = [];
28637
28972
  for (const source of sources) {
28638
28973
  if (!markedScopes.has(source.targetScope)) continue;
28639
- if (existsSync8(source.path)) {
28974
+ if (existsSync9(source.path)) {
28640
28975
  stranded.push({ name: source.name, path: source.path, scope: source.targetScope });
28641
28976
  }
28642
28977
  }
@@ -28701,7 +29036,7 @@ __export(open_cleo_db_exports, {
28701
29036
  openCleoDbSnapshot: () => openCleoDbSnapshot,
28702
29037
  validateProjectIdConsistency: () => validateProjectIdConsistency
28703
29038
  });
28704
- import { createRequire as createRequire4 } from "node:module";
29039
+ import { createRequire as createRequire5 } from "node:module";
28705
29040
  function unwrapNativeSqliteDb(db) {
28706
29041
  if (db && typeof db === "object" && "$client" in db) {
28707
29042
  return db.$client ?? db;
@@ -28765,9 +29100,10 @@ async function openCleoDb(role, cwd) {
28765
29100
  }
28766
29101
  function openCleoDbSnapshot(path2, options = {}) {
28767
29102
  const { readOnly = true, applyPragmas = true } = options;
28768
- const _require7 = createRequire4(import.meta.url);
29103
+ const _require7 = createRequire5(import.meta.url);
28769
29104
  const { DatabaseSync: DatabaseSyncCtor } = _require7("node:sqlite");
28770
29105
  const db = new DatabaseSyncCtor(path2, { readOnly });
29106
+ if (!readOnly) installSchemaWriteGuard(db);
28771
29107
  if (applyPragmas) {
28772
29108
  applyPerfPragmas(db, { enableWal: !readOnly });
28773
29109
  }
@@ -28795,6 +29131,7 @@ var init_open_cleo_db = __esm({
28795
29131
  init_project_info();
28796
29132
  init_dual_scope_db();
28797
29133
  init_sqlite_pragmas();
29134
+ init_worktree_build_guard();
28798
29135
  init_worktree_isolation_guard();
28799
29136
  PROJECT_ID_TRACKING_ROLES = /* @__PURE__ */ new Set(["global"]);
28800
29137
  }
@@ -29134,7 +29471,7 @@ var init_table_name_map = __esm({
29134
29471
  });
29135
29472
 
29136
29473
  // packages/core/src/store/exodus/count-parity.ts
29137
- import { existsSync as existsSync9 } from "node:fs";
29474
+ import { existsSync as existsSync10 } from "node:fs";
29138
29475
  function listTables(db) {
29139
29476
  return db.prepare(
29140
29477
  "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '__drizzle_%' ORDER BY name"
@@ -29155,14 +29492,14 @@ function rowCount(db, tableName) {
29155
29492
  function computeCountParity(sources, projectDbPath, globalDbPath) {
29156
29493
  const entries = [];
29157
29494
  let skipped = 0;
29158
- if (!existsSync9(projectDbPath) || !existsSync9(globalDbPath)) {
29495
+ if (!existsSync10(projectDbPath) || !existsSync10(globalDbPath)) {
29159
29496
  return { ok: false, entries: [], deficits: [], checked: 0, skipped: 0 };
29160
29497
  }
29161
29498
  const projectSnap = openCleoDbSnapshot(projectDbPath, { readOnly: true });
29162
29499
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
29163
29500
  try {
29164
29501
  for (const src of sources) {
29165
- if (!existsSync9(src.path)) continue;
29502
+ if (!existsSync10(src.path)) continue;
29166
29503
  const srcSnap = openCleoDbSnapshot(src.path, { readOnly: true });
29167
29504
  try {
29168
29505
  for (const legacyTable of listTables(srcSnap.db)) {
@@ -29220,8 +29557,8 @@ var init_count_parity = __esm({
29220
29557
  });
29221
29558
 
29222
29559
  // packages/core/src/store/exodus/plan.ts
29223
- import { existsSync as existsSync10, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
29224
- import { join as join15 } from "node:path";
29560
+ import { existsSync as existsSync11, readdirSync as readdirSync3, statfsSync, statSync as statSync3 } from "node:fs";
29561
+ import { join as join16 } from "node:path";
29225
29562
  function computeRequiredBytes(totalSourceBytes, largestSourceBytes) {
29226
29563
  return Math.ceil(STAGING_HEADROOM_FACTOR * largestSourceBytes) + totalSourceBytes;
29227
29564
  }
@@ -29232,33 +29569,33 @@ function buildSourceDescriptors(cwd) {
29232
29569
  // Project-tier — go into consolidated project-scope cleo.db
29233
29570
  {
29234
29571
  name: "tasks",
29235
- path: join15(cleoDir, "tasks.db"),
29572
+ path: join16(cleoDir, "tasks.db"),
29236
29573
  targetScope: "project"
29237
29574
  },
29238
29575
  {
29239
29576
  name: "brain (project)",
29240
- path: join15(cleoDir, "brain.db"),
29577
+ path: join16(cleoDir, "brain.db"),
29241
29578
  targetScope: "project"
29242
29579
  },
29243
29580
  {
29244
29581
  name: "conduit",
29245
- path: join15(cleoDir, "conduit.db"),
29582
+ path: join16(cleoDir, "conduit.db"),
29246
29583
  targetScope: "project"
29247
29584
  },
29248
29585
  // Global-tier — go into consolidated global-scope cleo.db
29249
29586
  {
29250
29587
  name: "nexus",
29251
- path: join15(cleoHome, "nexus.db"),
29588
+ path: join16(cleoHome, "nexus.db"),
29252
29589
  targetScope: "global"
29253
29590
  },
29254
29591
  {
29255
29592
  name: "signaldock",
29256
- path: join15(cleoHome, "signaldock.db"),
29593
+ path: join16(cleoHome, "signaldock.db"),
29257
29594
  targetScope: "global"
29258
29595
  },
29259
29596
  {
29260
29597
  name: "skills",
29261
- path: join15(cleoHome, "skills.db"),
29598
+ path: join16(cleoHome, "skills.db"),
29262
29599
  targetScope: "global"
29263
29600
  }
29264
29601
  ];
@@ -29287,7 +29624,7 @@ function findExistingStaging(cleoDir) {
29287
29624
  const entries = readdirSync3(cleoDir, { withFileTypes: true });
29288
29625
  const stagingDirs = entries.filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => e.name).sort().reverse();
29289
29626
  if (stagingDirs.length > 0) {
29290
- return join15(cleoDir, stagingDirs[0]);
29627
+ return join16(cleoDir, stagingDirs[0]);
29291
29628
  }
29292
29629
  } catch {
29293
29630
  }
@@ -29303,7 +29640,7 @@ function buildExodusPlan(cwd) {
29303
29640
  const availableBytes = getAvailableBytes(cleoDir);
29304
29641
  const diskPreflight = totalSourceBytes === 0 || availableBytes >= requiredBytes;
29305
29642
  const existingStaging = findExistingStaging(cleoDir);
29306
- const stagingDir = existingStaging ?? join15(cleoDir, deriveStagingDirName());
29643
+ const stagingDir = existingStaging ?? join16(cleoDir, deriveStagingDirName());
29307
29644
  const resumeFromStaging = existingStaging !== null;
29308
29645
  const projectDbPath = resolveDualScopeDbPath("project", cwd);
29309
29646
  const globalDbPath = resolveDualScopeDbPath("global");
@@ -29322,7 +29659,7 @@ function buildExodusPlan(cwd) {
29322
29659
  };
29323
29660
  }
29324
29661
  function sourcesPresent(sources) {
29325
- return sources.some((s) => existsSync10(s.path));
29662
+ return sources.some((s) => existsSync11(s.path));
29326
29663
  }
29327
29664
  var STAGING_HEADROOM_FACTOR, STAGING_COPY_SKIP_THRESHOLD_BYTES;
29328
29665
  var init_plan2 = __esm({
@@ -29336,18 +29673,18 @@ var init_plan2 = __esm({
29336
29673
  });
29337
29674
 
29338
29675
  // packages/core/src/store/exodus/health.ts
29339
- import { existsSync as existsSync11, statSync as statSync4 } from "node:fs";
29676
+ import { existsSync as existsSync12, statSync as statSync4 } from "node:fs";
29340
29677
  function buildExodusHealth(cwd) {
29341
29678
  const plan = buildExodusPlan(cwd);
29342
- const anyLegacyPresent = plan.sources.some((s) => existsSync11(s.path));
29679
+ const anyLegacyPresent = plan.sources.some((s) => existsSync12(s.path));
29343
29680
  const parity = anyLegacyPresent ? computeCountParity(plan.sources, plan.projectDbPath, plan.globalDbPath) : { ok: true, entries: [], deficits: [], checked: 0, skipped: 0 };
29344
29681
  const consolidatedExistsByScope = {
29345
- project: existsSync11(plan.projectDbPath),
29346
- global: existsSync11(plan.globalDbPath)
29682
+ project: existsSync12(plan.projectDbPath),
29683
+ global: existsSync12(plan.globalDbPath)
29347
29684
  };
29348
29685
  const buildScope = (scope) => {
29349
29686
  const sources = plan.sources.filter((s) => s.targetScope === scope).map((s) => {
29350
- const present = existsSync11(s.path);
29687
+ const present = existsSync12(s.path);
29351
29688
  let bytes = 0;
29352
29689
  if (present) {
29353
29690
  try {
@@ -29699,8 +30036,8 @@ var init_types = __esm({
29699
30036
  });
29700
30037
 
29701
30038
  // packages/core/src/store/backup-sidecar.ts
29702
- import { existsSync as existsSync12, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
29703
- import { join as join16 } from "node:path";
30039
+ import { existsSync as existsSync13, readdirSync as readdirSync4, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync5 } from "node:fs";
30040
+ import { join as join17 } from "node:path";
29704
30041
  function formatBackupTimestamp(d) {
29705
30042
  const pad = (n, len = 2) => String(n).padStart(len, "0");
29706
30043
  return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}${pad(d.getSeconds())}`;
@@ -29711,8 +30048,8 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29711
30048
  const ownedPattern = new RegExp(`\\.${escapedType}-`);
29712
30049
  const files = readdirSync4(backupDir).filter((f) => !f.endsWith(".meta.json") && !f.endsWith(".tmp") && ownedPattern.test(f)).map((f) => ({
29713
30050
  name: f,
29714
- path: join16(backupDir, f),
29715
- mtimeMs: statSync5(join16(backupDir, f)).mtimeMs
30051
+ path: join17(backupDir, f),
30052
+ mtimeMs: statSync5(join17(backupDir, f)).mtimeMs
29716
30053
  })).sort((a, b) => a.mtimeMs - b.mtimeMs);
29717
30054
  while (files.length > maxSnapshots) {
29718
30055
  const oldest = files.shift();
@@ -29720,7 +30057,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29720
30057
  try {
29721
30058
  unlinkSync2(oldest.path);
29722
30059
  const metaPath = `${oldest.path}.meta.json`;
29723
- if (existsSync12(metaPath)) unlinkSync2(metaPath);
30060
+ if (existsSync13(metaPath)) unlinkSync2(metaPath);
29724
30061
  } catch {
29725
30062
  }
29726
30063
  }
@@ -29728,7 +30065,7 @@ function rotateBackupDir(backupDir, maxSnapshots, backupType) {
29728
30065
  }
29729
30066
  }
29730
30067
  function writeBackupSidecar(backupDir, sidecar) {
29731
- const dest = join16(backupDir, `${sidecar.backupId}.meta.json`);
30068
+ const dest = join17(backupDir, `${sidecar.backupId}.meta.json`);
29732
30069
  const tmp = `${dest}.${process.pid}.${Date.now()}.tmp`;
29733
30070
  writeFileSync5(tmp, JSON.stringify(sidecar, null, 2));
29734
30071
  renameSync4(tmp, dest);
@@ -29740,23 +30077,23 @@ var init_backup_sidecar = __esm({
29740
30077
  });
29741
30078
 
29742
30079
  // packages/core/src/store/pre-repair-snapshot.ts
29743
- import { existsSync as existsSync13, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
29744
- import { dirname as dirname11, join as join17 } from "node:path";
30080
+ import { existsSync as existsSync14, mkdirSync as mkdirSync3, statfsSync as statfsSync2 } from "node:fs";
30081
+ import { dirname as dirname13, join as join18 } from "node:path";
29745
30082
  function writePreRepairSnapshot(nativeDb, dbPath, label) {
29746
30083
  const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
29747
- const backupDir = join17(dirname11(dbPath), "backups");
30084
+ const backupDir = join18(dirname13(dbPath), "backups");
29748
30085
  mkdirSync3(backupDir, { recursive: true });
29749
- const snapshotPath = join17(backupDir, `cleo-pre-${label}-${stamp}.db`);
30086
+ const snapshotPath = join18(backupDir, `cleo-pre-${label}-${stamp}.db`);
29750
30087
  nativeDb.exec(`VACUUM INTO '${snapshotPath.replace(/'/g, "''")}'`);
29751
30088
  return snapshotPath;
29752
30089
  }
29753
30090
  function existingAncestor(path2) {
29754
30091
  let p = path2;
29755
- while (!existsSync13(p) && dirname11(p) !== p) p = dirname11(p);
30092
+ while (!existsSync14(p) && dirname13(p) !== p) p = dirname13(p);
29756
30093
  return p;
29757
30094
  }
29758
30095
  function planMigrationSnapshot(nativeDb, dbPath) {
29759
- const backupDir = join17(dirname11(dbPath), "backups", "sqlite");
30096
+ const backupDir = join18(dirname13(dbPath), "backups", "sqlite");
29760
30097
  const pragma = (name2) => Number(nativeDb.prepare(`PRAGMA main.${name2}`).get()[name2] ?? 0);
29761
30098
  const liveBytes = (pragma("page_count") - pragma("freelist_count")) * pragma("page_size");
29762
30099
  let availableBytes = null;
@@ -29768,13 +30105,13 @@ function planMigrationSnapshot(nativeDb, dbPath) {
29768
30105
  }
29769
30106
  const base = `migration-${formatBackupTimestamp(/* @__PURE__ */ new Date())}`;
29770
30107
  let backupId = base;
29771
- for (let n = 2; existsSync13(join17(backupDir, `${backupId}.meta.json`)); n++) {
30108
+ for (let n = 2; existsSync14(join18(backupDir, `${backupId}.meta.json`)); n++) {
29772
30109
  backupId = `${base}-${n}`;
29773
30110
  }
29774
30111
  return {
29775
30112
  backupDir,
29776
30113
  backupId,
29777
- snapshotPath: join17(backupDir, `cleo.db.${backupId}`),
30114
+ snapshotPath: join18(backupDir, `cleo.db.${backupId}`),
29778
30115
  requiredBytes: liveBytes + SNAPSHOT_HEADROOM_BYTES,
29779
30116
  availableBytes
29780
30117
  };
@@ -30014,7 +30351,7 @@ var init_legacy_tasks_lineage = __esm({
30014
30351
 
30015
30352
  // packages/core/src/store/ports/domain-binding.ts
30016
30353
  import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
30017
- import { resolve as resolve6 } from "node:path";
30354
+ import { resolve as resolve8 } from "node:path";
30018
30355
  function getCleoRuntime() {
30019
30356
  if (!_runtime) {
30020
30357
  _runtime = createCleoRuntime();
@@ -30082,6 +30419,8 @@ async function bindAgainst(key, store, establish) {
30082
30419
  () => establish(native, store)
30083
30420
  );
30084
30421
  return { store, native, db };
30422
+ } catch (error) {
30423
+ throw explainSchemaWriteDenial(native, error);
30085
30424
  } finally {
30086
30425
  membership.active = false;
30087
30426
  }
@@ -30131,7 +30470,7 @@ async function bindLive(scope, key, dbPath, openStore, establish) {
30131
30470
  );
30132
30471
  }
30133
30472
  async function bindProjectDomain(domain, cwd, establish) {
30134
- const dbPath = resolve6(resolveDualScopeDbPath("project", cwd));
30473
+ const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
30135
30474
  const row = await bindLive(
30136
30475
  "project",
30137
30476
  bindingKey("project", dbPath, domain),
@@ -30142,7 +30481,7 @@ async function bindProjectDomain(domain, cwd, establish) {
30142
30481
  return row;
30143
30482
  }
30144
30483
  async function bindGlobalDomain(domain, establish, cwd) {
30145
- const dbPath = resolve6(resolveDualScopeDbPath("global"));
30484
+ const dbPath = resolve8(resolveDualScopeDbPath("global"));
30146
30485
  const row = await bindLive(
30147
30486
  "global",
30148
30487
  bindingKey("global", dbPath, domain),
@@ -30153,7 +30492,7 @@ async function bindGlobalDomain(domain, establish, cwd) {
30153
30492
  return row;
30154
30493
  }
30155
30494
  async function bindGlobalDomainAtPath(domain, dbPath, establish) {
30156
- const normalized = resolve6(dbPath);
30495
+ const normalized = resolve8(dbPath);
30157
30496
  const row = await bindLive(
30158
30497
  "global",
30159
30498
  bindingKey("global", normalized, domain),
@@ -30164,7 +30503,7 @@ async function bindGlobalDomainAtPath(domain, dbPath, establish) {
30164
30503
  return row;
30165
30504
  }
30166
30505
  function peekDomainAtPath(scope, dbPath, domain) {
30167
- const row = _bindings.get(bindingKey(scope, resolve6(dbPath), domain));
30506
+ const row = _bindings.get(bindingKey(scope, resolve8(dbPath), domain));
30168
30507
  if (!row?.native.isOpen) return null;
30169
30508
  return row;
30170
30509
  }
@@ -30173,12 +30512,12 @@ function releaseDomainBindings(filter) {
30173
30512
  _bindings.clear();
30174
30513
  return;
30175
30514
  }
30176
- const wantPath = filter.dbPath === void 0 ? void 0 : resolve6(filter.dbPath);
30515
+ const wantPath = filter.dbPath === void 0 ? void 0 : resolve8(filter.dbPath);
30177
30516
  for (const key of [..._bindings.keys()]) {
30178
- const sep5 = key.indexOf("::");
30517
+ const sep6 = key.indexOf("::");
30179
30518
  const lastSep = key.lastIndexOf("::");
30180
- const scope = key.slice(0, sep5);
30181
- const dbPath = key.slice(sep5 + 2, lastSep);
30519
+ const scope = key.slice(0, sep6);
30520
+ const dbPath = key.slice(sep6 + 2, lastSep);
30182
30521
  const domain = key.slice(lastSep + 2);
30183
30522
  if (filter.scope !== void 0 && scope !== filter.scope) continue;
30184
30523
  if (wantPath !== void 0 && dbPath !== wantPath) continue;
@@ -30193,7 +30532,7 @@ function boundProjectNative(domain, cwd) {
30193
30532
  return peekProjectDomain(domain, cwd)?.native ?? null;
30194
30533
  }
30195
30534
  function peekProjectDomain(domain, cwd) {
30196
- const dbPath = resolve6(resolveDualScopeDbPath("project", cwd));
30535
+ const dbPath = resolve8(resolveDualScopeDbPath("project", cwd));
30197
30536
  const row = _bindings.get(bindingKey("project", dbPath, domain));
30198
30537
  if (row?.native.isOpen) return row;
30199
30538
  if (cwd !== void 0) return null;
@@ -30208,7 +30547,7 @@ function peekProjectDomain(domain, cwd) {
30208
30547
  return sole ?? null;
30209
30548
  }
30210
30549
  function peekGlobalDomain(domain) {
30211
- const dbPath = resolve6(resolveDualScopeDbPath("global"));
30550
+ const dbPath = resolve8(resolveDualScopeDbPath("global"));
30212
30551
  const row = _bindings.get(bindingKey("global", dbPath, domain));
30213
30552
  if (!row || !row.native.isOpen) return null;
30214
30553
  return row;
@@ -30219,6 +30558,7 @@ var init_domain_binding = __esm({
30219
30558
  "use strict";
30220
30559
  init_project_scope();
30221
30560
  init_dual_scope_db();
30561
+ init_worktree_build_guard();
30222
30562
  _runtime = null;
30223
30563
  _bindings = /* @__PURE__ */ new Map();
30224
30564
  _inflight = /* @__PURE__ */ new Map();
@@ -30229,9 +30569,9 @@ var init_domain_binding = __esm({
30229
30569
 
30230
30570
  // packages/core/src/telemetry/sqlite.ts
30231
30571
  import { mkdirSync as mkdirSync4 } from "node:fs";
30232
- import { dirname as dirname12, join as join18 } from "node:path";
30572
+ import { dirname as dirname14, join as join19 } from "node:path";
30233
30573
  function getTelemetryDbPath() {
30234
- return join18(getCleoHome(), DB_FILENAME);
30574
+ return join19(getCleoHome(), DB_FILENAME);
30235
30575
  }
30236
30576
  function resolveTelemetryMigrationsFolder() {
30237
30577
  return resolveCorePackageMigrationsFolder("drizzle-telemetry");
@@ -30279,8 +30619,9 @@ async function getTelemetryDb() {
30279
30619
  _initPromise = (async () => {
30280
30620
  const dbPath = requestedPath;
30281
30621
  _dbPath = dbPath;
30282
- mkdirSync4(dirname12(dbPath), { recursive: true });
30622
+ mkdirSync4(dirname14(dbPath), { recursive: true });
30283
30623
  const nativeDb = openNativeDatabase(dbPath);
30624
+ installSchemaWriteGuard(nativeDb);
30284
30625
  _nativeDb = nativeDb;
30285
30626
  const db = drizzle({ client: nativeDb });
30286
30627
  runTelemetryMigrations(nativeDb, db);
@@ -30301,6 +30642,7 @@ var init_sqlite2 = __esm({
30301
30642
  init_migration_manager();
30302
30643
  init_resolve_migrations_folder();
30303
30644
  init_sqlite3();
30645
+ init_worktree_build_guard();
30304
30646
  DB_FILENAME = "telemetry.db";
30305
30647
  TELEMETRY_SCHEMA_VERSION = "1.0.0";
30306
30648
  _db = null;
@@ -30311,11 +30653,11 @@ var init_sqlite2 = __esm({
30311
30653
  });
30312
30654
 
30313
30655
  // packages/core/src/store/agent-registry-store.ts
30314
- import { existsSync as existsSync14 } from "node:fs";
30315
- import { join as join19 } from "node:path";
30656
+ import { existsSync as existsSync15 } from "node:fs";
30657
+ import { join as join20 } from "node:path";
30316
30658
  function getGlobalAgentRegistryDbPath() {
30317
30659
  const cleoHome = getCleoHome();
30318
- const dbPath = join19(cleoHome, "cleo.db");
30660
+ const dbPath = join20(cleoHome, "cleo.db");
30319
30661
  if (!dbPath.startsWith(cleoHome)) {
30320
30662
  throw new Error(
30321
30663
  `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.`
@@ -30382,7 +30724,7 @@ function establishAgentRegistrySchema(native) {
30382
30724
  }
30383
30725
  async function ensureGlobalAgentRegistryDb() {
30384
30726
  const dbPath = getGlobalAgentRegistryDbPath();
30385
- const alreadyExists = existsSync14(dbPath);
30727
+ const alreadyExists = existsSync15(dbPath);
30386
30728
  let created = false;
30387
30729
  const { native: nativeDb } = await bindGlobalDomainAtPath(
30388
30730
  AGENT_REGISTRY_DOMAIN,
@@ -30427,8 +30769,8 @@ var init_agent_registry_store = __esm({
30427
30769
  });
30428
30770
 
30429
30771
  // packages/core/src/store/conduit-sqlite.ts
30430
- import { existsSync as existsSync15 } from "node:fs";
30431
- import { createRequire as createRequire5 } from "node:module";
30772
+ import { existsSync as existsSync16 } from "node:fs";
30773
+ import { createRequire as createRequire6 } from "node:module";
30432
30774
  function _getDrizzle() {
30433
30775
  if (_drizzle === null) {
30434
30776
  const mod = _require3("drizzle-orm/node-sqlite");
@@ -30456,7 +30798,7 @@ function runConduitMigrations(nativeDb) {
30456
30798
  }
30457
30799
  async function ensureConduitDb(projectRoot) {
30458
30800
  const dbPath = getConduitDbPath(projectRoot);
30459
- const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync15(dbPath);
30801
+ const alreadyExists = peekProjectDomain("conduit", projectRoot) !== null || existsSync16(dbPath);
30460
30802
  await bindConduitDomain(projectRoot);
30461
30803
  return { action: alreadyExists ? "exists" : "created", path: dbPath };
30462
30804
  }
@@ -30482,7 +30824,8 @@ var init_conduit_sqlite = __esm({
30482
30824
  init_domain_binding();
30483
30825
  init_resolve_migrations_folder();
30484
30826
  init_sqlite_pragmas();
30485
- _require3 = createRequire5(import.meta.url);
30827
+ init_worktree_build_guard();
30828
+ _require3 = createRequire6(import.meta.url);
30486
30829
  ({ DatabaseSync: DatabaseSync2 } = _require3("node:sqlite"));
30487
30830
  _drizzle = null;
30488
30831
  CONDUIT_SCHEMA_VERSION = "2026.4.23";
@@ -32954,7 +33297,7 @@ __export(config_exports, {
32954
33297
  parseConfigValue: () => parseConfigValue,
32955
33298
  setConfigValue: () => setConfigValue
32956
33299
  });
32957
- import { existsSync as existsSync16 } from "node:fs";
33300
+ import { existsSync as existsSync17 } from "node:fs";
32958
33301
  function getNestedValue(obj, path2) {
32959
33302
  const parts = path2.split(".");
32960
33303
  let current = obj;
@@ -33076,7 +33419,7 @@ function parseConfigValue(value) {
33076
33419
  }
33077
33420
  async function setConfigValue(key, value, cwd, opts) {
33078
33421
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
33079
- if (!existsSync16(configPath)) {
33422
+ if (!existsSync17(configPath)) {
33080
33423
  await atomicWriteJson(configPath, {});
33081
33424
  }
33082
33425
  const config = await readJson(configPath) ?? {};
@@ -33088,7 +33431,7 @@ async function setConfigValue(key, value, cwd, opts) {
33088
33431
  async function applyStrictnessPreset(preset, cwd, opts) {
33089
33432
  const definition = STRICTNESS_PRESETS[preset];
33090
33433
  const configPath = opts?.global ? getGlobalConfigPath() : getConfigPath(cwd);
33091
- if (!existsSync16(configPath)) {
33434
+ if (!existsSync17(configPath)) {
33092
33435
  await atomicWriteJson(configPath, {});
33093
33436
  }
33094
33437
  const config = await readJson(configPath) ?? {};
@@ -33665,6 +34008,7 @@ var init_cross_db_cleanup = __esm({
33665
34008
  "use strict";
33666
34009
  init_memory_sqlite();
33667
34010
  init_memory_schema();
34011
+ init_worktree_build_guard();
33668
34012
  }
33669
34013
  });
33670
34014
 
@@ -38357,7 +38701,7 @@ __export(sqlite_data_accessor_exports, {
38357
38701
  setMetaValue: () => setMetaValue
38358
38702
  });
38359
38703
  import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
38360
- import { resolve as resolve7 } from "node:path";
38704
+ import { resolve as resolve9 } from "node:path";
38361
38705
  import {
38362
38706
  and as and5,
38363
38707
  eq as eq6,
@@ -38466,7 +38810,7 @@ function bindTaskAccessorScope(accessor, scope) {
38466
38810
  }
38467
38811
  async function createSqliteDataAccessor(cwd) {
38468
38812
  const scope = captureProjectScope(
38469
- resolve7(cwd ?? getProjectRoot()),
38813
+ resolve9(cwd ?? getProjectRoot()),
38470
38814
  worktreeScope.getStore()
38471
38815
  );
38472
38816
  return worktreeScope.run(
@@ -38581,7 +38925,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38581
38925
  actor: entry.actor ?? "system",
38582
38926
  detailsJson: entry.details ? JSON.stringify(entry.details) : "{}",
38583
38927
  beforeJson: entry.before ? JSON.stringify(entry.before) : null,
38584
- afterJson: entry.after ? JSON.stringify(entry.after) : null
38928
+ afterJson: entry.after ? JSON.stringify(entry.after) : null,
38929
+ // T12693: the session a ranking change ran in.
38930
+ sessionId: typeof entry.sessionId === "string" ? entry.sessionId : null
38585
38931
  }).run()
38586
38932
  );
38587
38933
  });
@@ -38589,6 +38935,9 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38589
38935
  async queryAuditLog(query) {
38590
38936
  const db = await getDb(cwd);
38591
38937
  const conditions = [];
38938
+ if (query.ids && query.ids.length > 0) {
38939
+ conditions.push(inArray4(tasksAuditLog.id, [...query.ids]));
38940
+ }
38592
38941
  if (query.taskIds && query.taskIds.length > 0) {
38593
38942
  conditions.push(inArray4(tasksAuditLog.taskId, [...query.taskIds]));
38594
38943
  }
@@ -38607,7 +38956,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38607
38956
  actor: tasksAuditLog.actor,
38608
38957
  detailsJson: tasksAuditLog.detailsJson,
38609
38958
  beforeJson: tasksAuditLog.beforeJson,
38610
- afterJson: tasksAuditLog.afterJson
38959
+ afterJson: tasksAuditLog.afterJson,
38960
+ sessionId: tasksAuditLog.sessionId
38611
38961
  }).from(tasksAuditLog).where(conditions.length > 0 ? and5(...conditions) : void 0).orderBy(sql26`${tasksAuditLog.timestamp} DESC`).limit(limit).all();
38612
38962
  return rows.map((row) => ({
38613
38963
  id: row.id,
@@ -38617,7 +38967,8 @@ async function createOwnedSqliteDataAccessor(cwd, accessorScope) {
38617
38967
  actor: row.actor,
38618
38968
  detailsJson: row.detailsJson ?? null,
38619
38969
  beforeJson: row.beforeJson ?? null,
38620
- afterJson: row.afterJson ?? null
38970
+ afterJson: row.afterJson ?? null,
38971
+ sessionId: row.sessionId ?? null
38621
38972
  }));
38622
38973
  },
38623
38974
  // ---- Fine-grained task operations (T5034) ----
@@ -39455,13 +39806,13 @@ var init_sqlite_data_accessor = __esm({
39455
39806
  });
39456
39807
 
39457
39808
  // packages/core/src/sequence/index.ts
39458
- import { existsSync as existsSync17, readFileSync as readFileSync5, renameSync as renameSync5 } from "node:fs";
39459
- import { join as join20 } from "node:path";
39809
+ import { existsSync as existsSync18, readFileSync as readFileSync6, renameSync as renameSync5 } from "node:fs";
39810
+ import { join as join21 } from "node:path";
39460
39811
  function getLegacySequenceJsonPath(cwd) {
39461
- return join20(resolveOrCwd(cwd), ".cleo", ".sequence.json");
39812
+ return join21(resolveOrCwd(cwd), ".cleo", ".sequence.json");
39462
39813
  }
39463
39814
  function getLegacySequencePath(cwd) {
39464
- return join20(resolveOrCwd(cwd), ".cleo", ".sequence");
39815
+ return join21(resolveOrCwd(cwd), ".cleo", ".sequence");
39465
39816
  }
39466
39817
  function isValidSequenceState(value) {
39467
39818
  if (!value || typeof value !== "object") return false;
@@ -39472,19 +39823,19 @@ function isSeedSequence(value) {
39472
39823
  return value.counter === 0 && value.lastId === "T000" && value.checksum === "seed";
39473
39824
  }
39474
39825
  function readLegacySequenceFile(path2) {
39475
- if (!existsSync17(path2)) return null;
39826
+ if (!existsSync18(path2)) return null;
39476
39827
  try {
39477
- const parsed = JSON.parse(readFileSync5(path2, "utf-8"));
39828
+ const parsed = JSON.parse(readFileSync6(path2, "utf-8"));
39478
39829
  return isValidSequenceState(parsed) ? parsed : null;
39479
39830
  } catch {
39480
39831
  return null;
39481
39832
  }
39482
39833
  }
39483
39834
  function renameLegacyFile(path2) {
39484
- if (!existsSync17(path2)) return;
39835
+ if (!existsSync18(path2)) return;
39485
39836
  const migratedPath = `${path2}.migrated`;
39486
39837
  try {
39487
- if (!existsSync17(migratedPath)) {
39838
+ if (!existsSync18(migratedPath)) {
39488
39839
  renameSync5(path2, migratedPath);
39489
39840
  return;
39490
39841
  }
@@ -39636,9 +39987,9 @@ var init_sequence = __esm({
39636
39987
  });
39637
39988
 
39638
39989
  // packages/core/src/store/checkpoint-git-dir.ts
39639
- import { join as join21 } from "node:path";
39990
+ import { join as join22 } from "node:path";
39640
39991
  function checkpointGitDir(cleoDir) {
39641
- return join21(cleoDir, CHECKPOINT_GIT_DIRNAME);
39992
+ return join22(cleoDir, CHECKPOINT_GIT_DIRNAME);
39642
39993
  }
39643
39994
  var CHECKPOINT_GIT_DIRNAME;
39644
39995
  var init_checkpoint_git_dir = __esm({
@@ -39650,12 +40001,12 @@ var init_checkpoint_git_dir = __esm({
39650
40001
 
39651
40002
  // packages/core/src/store/git-checkpoint.ts
39652
40003
  import { execFile as execFile2 } from "node:child_process";
39653
- import { existsSync as existsSync18 } from "node:fs";
40004
+ import { existsSync as existsSync19 } from "node:fs";
39654
40005
  import { readFile as readFile4, writeFile } from "node:fs/promises";
39655
- import { join as join22, resolve as resolve8 } from "node:path";
40006
+ import { join as join23, resolve as resolve10 } from "node:path";
39656
40007
  import { promisify as promisify2 } from "node:util";
39657
40008
  function makeCleoGitEnv(cleoDir) {
39658
- const abs = resolve8(cleoDir);
40009
+ const abs = resolve10(cleoDir);
39659
40010
  return {
39660
40011
  ...process.env,
39661
40012
  GIT_DIR: checkpointGitDir(abs),
@@ -39665,7 +40016,7 @@ function makeCleoGitEnv(cleoDir) {
39665
40016
  async function cleoGitCommand(args, cleoDir) {
39666
40017
  try {
39667
40018
  const result = await execFileAsync2("git", args, {
39668
- cwd: resolve8(cleoDir),
40019
+ cwd: resolve10(cleoDir),
39669
40020
  // absolute cwd so relative paths in args resolve correctly
39670
40021
  env: makeCleoGitEnv(cleoDir),
39671
40022
  timeout: 1e4
@@ -39676,7 +40027,7 @@ async function cleoGitCommand(args, cleoDir) {
39676
40027
  }
39677
40028
  }
39678
40029
  function isCleoGitInitialized(cleoDir) {
39679
- return existsSync18(join22(checkpointGitDir(cleoDir), "HEAD"));
40030
+ return existsSync19(join23(checkpointGitDir(cleoDir), "HEAD"));
39680
40031
  }
39681
40032
  async function loadStateFileAllowlist(cwd) {
39682
40033
  try {
@@ -39720,25 +40071,25 @@ async function isCleoGitRepo(cleoDir) {
39720
40071
  return result.success && (result.stdout === "true" || isCleoGitInitialized(cleoDir));
39721
40072
  }
39722
40073
  function isMergeInProgress(cleoDir) {
39723
- return existsSync18(join22(checkpointGitDir(cleoDir), "MERGE_HEAD"));
40074
+ return existsSync19(join23(checkpointGitDir(cleoDir), "MERGE_HEAD"));
39724
40075
  }
39725
40076
  async function isDetachedHead(cleoDir) {
39726
40077
  const result = await cleoGitCommand(["symbolic-ref", "HEAD"], cleoDir);
39727
40078
  return !result.success;
39728
40079
  }
39729
40080
  function isRebaseInProgress(cleoDir) {
39730
- return existsSync18(join22(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync18(join22(checkpointGitDir(cleoDir), "rebase-apply"));
40081
+ return existsSync19(join23(checkpointGitDir(cleoDir), "rebase-merge")) || existsSync19(join23(checkpointGitDir(cleoDir), "rebase-apply"));
39731
40082
  }
39732
40083
  async function recordCheckpointTime(cleoDir) {
39733
40084
  try {
39734
- const stateFile = join22(cleoDir, CHECKPOINT_STATE_FILE);
40085
+ const stateFile = join23(cleoDir, CHECKPOINT_STATE_FILE);
39735
40086
  await writeFile(stateFile, String(Math.floor(Date.now() / 1e3)));
39736
40087
  } catch {
39737
40088
  }
39738
40089
  }
39739
40090
  async function getLastCheckpointTime(cleoDir) {
39740
40091
  try {
39741
- const stateFile = join22(cleoDir, CHECKPOINT_STATE_FILE);
40092
+ const stateFile = join23(cleoDir, CHECKPOINT_STATE_FILE);
39742
40093
  const content = await readFile4(stateFile, "utf-8");
39743
40094
  const epoch = parseInt(content.trim(), 10);
39744
40095
  return Number.isNaN(epoch) ? 0 : epoch;
@@ -39750,8 +40101,8 @@ async function getChangedStateFiles(cleoDir, cwd) {
39750
40101
  const changed = [];
39751
40102
  const allStateFiles = await getAllStateFiles(cwd);
39752
40103
  for (const stateFile of allStateFiles) {
39753
- const fullPath = join22(cleoDir, stateFile);
39754
- if (!existsSync18(fullPath)) continue;
40104
+ const fullPath = join23(cleoDir, stateFile);
40105
+ if (!existsSync19(fullPath)) continue;
39755
40106
  const diffResult = await cleoGitCommand(["diff", "--quiet", "--", stateFile], cleoDir);
39756
40107
  const cachedResult = await cleoGitCommand(
39757
40108
  ["diff", "--cached", "--quiet", "--", stateFile],
@@ -39778,7 +40129,7 @@ async function shouldCheckpoint(options) {
39778
40129
  const config = await loadCheckpointConfig(cwd);
39779
40130
  if (!config.enabled) return false;
39780
40131
  const cleoDir = getCleoDir(cwd);
39781
- if (!existsSync18(cleoDir)) return false;
40132
+ if (!existsSync19(cleoDir)) return false;
39782
40133
  if (!isCleoGitInitialized(cleoDir)) return false;
39783
40134
  if (!await isCleoGitRepo(cleoDir)) return false;
39784
40135
  if (isMergeInProgress(cleoDir)) return false;
@@ -39852,7 +40203,7 @@ var init_git_checkpoint = __esm({
39852
40203
  });
39853
40204
 
39854
40205
  // packages/core/src/store/snapshot-gate.ts
39855
- import { join as join23 } from "node:path";
40206
+ import { join as join24 } from "node:path";
39856
40207
  function readGateState(db) {
39857
40208
  const row = db.prepare("SELECT value FROM tasks_schema_meta WHERE key = ?").get(SNAPSHOT_GATE_META_KEY);
39858
40209
  const state = { generation: 0, prefixes: {} };
@@ -39917,7 +40268,7 @@ async function runGatedSnapshot(opts, snapshot) {
39917
40268
  return none("debounced");
39918
40269
  }
39919
40270
  }
39920
- const lockPath2 = join23(opts.backupDir, GATE_LOCK_BASENAME);
40271
+ const lockPath2 = join24(opts.backupDir, GATE_LOCK_BASENAME);
39921
40272
  let release;
39922
40273
  try {
39923
40274
  release = await acquireLock(lockPath2, {
@@ -40473,7 +40824,7 @@ __export(data_accessor_exports, {
40473
40824
  getAccessorDb: () => getAccessorDb,
40474
40825
  getTaskAccessor: () => getTaskAccessor
40475
40826
  });
40476
- import { resolve as resolve9 } from "node:path";
40827
+ import { resolve as resolve11 } from "node:path";
40477
40828
  function assertTestEnv(dbPath) {
40478
40829
  const testMode = process.env["CLEO_TEST_MODE"];
40479
40830
  if (testMode !== "1") return;
@@ -40494,7 +40845,7 @@ function assertTestEnv(dbPath) {
40494
40845
  }
40495
40846
  }
40496
40847
  async function createDataAccessor(cwd) {
40497
- const root = resolve9(cwd ?? getProjectRoot());
40848
+ const root = resolve11(cwd ?? getProjectRoot());
40498
40849
  const inherited = worktreeScope.getStore();
40499
40850
  const captured = inherited ? { ...inherited } : void 0;
40500
40851
  captured?.execution?.assertActive();
@@ -40538,7 +40889,7 @@ __export(memory_sqlite_exports, {
40538
40889
  resetBrainDbState: () => resetBrainDbState,
40539
40890
  resolveBrainMigrationsFolder: () => resolveBrainMigrationsFolder
40540
40891
  });
40541
- import { createRequire as createRequire6 } from "node:module";
40892
+ import { createRequire as createRequire7 } from "node:module";
40542
40893
  function _getDrizzle2() {
40543
40894
  if (_drizzle2 === null) {
40544
40895
  const mod = _require4("drizzle-orm/node-sqlite");
@@ -40675,7 +41026,7 @@ var init_memory_sqlite = __esm({
40675
41026
  init_resolve_migrations_folder();
40676
41027
  init_memory_schema();
40677
41028
  init_twin_collapse();
40678
- _require4 = createRequire6(import.meta.url);
41029
+ _require4 = createRequire7(import.meta.url);
40679
41030
  _drizzle2 = null;
40680
41031
  BRAIN_SCHEMA_VERSION = "1.0.0";
40681
41032
  CONSOLIDATED_BRAIN_TABLES = [
@@ -40863,11 +41214,11 @@ var init_skills_schema = __esm({
40863
41214
  });
40864
41215
 
40865
41216
  // packages/core/src/store/skills-db.ts
40866
- import { join as join24 } from "node:path";
41217
+ import { join as join25 } from "node:path";
40867
41218
  import { and as and6, eq as eq8 } from "drizzle-orm";
40868
41219
  function getDefaultSkillsDbPath() {
40869
41220
  const cleoHome = getCleoHome();
40870
- const dbPath = join24(cleoHome, "cleo.db");
41221
+ const dbPath = join25(cleoHome, "cleo.db");
40871
41222
  if (!dbPath.startsWith(cleoHome)) {
40872
41223
  throw new Error(
40873
41224
  `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.`
@@ -40915,19 +41266,19 @@ import {
40915
41266
  chmodSync,
40916
41267
  closeSync,
40917
41268
  copyFileSync as copyFileSync3,
40918
- existsSync as existsSync19,
41269
+ existsSync as existsSync20,
40919
41270
  fsyncSync,
40920
41271
  linkSync,
40921
41272
  mkdirSync as mkdirSync5,
40922
41273
  openSync,
40923
41274
  readdirSync as readdirSync5,
40924
- realpathSync as realpathSync6,
41275
+ realpathSync as realpathSync7,
40925
41276
  renameSync as renameSync6,
40926
41277
  rmSync,
40927
41278
  statSync as statSync6,
40928
41279
  unlinkSync as unlinkSync3
40929
41280
  } from "node:fs";
40930
- import { dirname as dirname13, join as join25, sep as sep3 } from "node:path";
41281
+ import { dirname as dirname15, join as join26, sep as sep4 } from "node:path";
40931
41282
  function resolveInventoryPath(entry, cwd) {
40932
41283
  try {
40933
41284
  if (entry.tier === "global") {
@@ -40963,8 +41314,8 @@ async function openAgentRegistryDbForSnapshot() {
40963
41314
  }
40964
41315
  async function openTelemetryDbForSnapshot() {
40965
41316
  try {
40966
- const path2 = join25(getCleoHome(), "telemetry.db");
40967
- if (!existsSync19(path2)) return null;
41317
+ const path2 = join26(getCleoHome(), "telemetry.db");
41318
+ if (!existsSync20(path2)) return null;
40968
41319
  } catch {
40969
41320
  return null;
40970
41321
  }
@@ -41076,7 +41427,7 @@ function rotateSnapshots(backupDir, prefix, justWritten) {
41076
41427
  for (const name2 of names) {
41077
41428
  if (keep.has(name2)) continue;
41078
41429
  try {
41079
- unlinkSync3(join25(backupDir, name2));
41430
+ unlinkSync3(join26(backupDir, name2));
41080
41431
  } catch {
41081
41432
  }
41082
41433
  }
@@ -41098,7 +41449,7 @@ async function snapshotProjectTargetsGated(targets, opts) {
41098
41449
  let backupDir;
41099
41450
  try {
41100
41451
  const cleoDir = getCleoDir(cwd);
41101
- backupDir = join25(cleoDir, "backups", "sqlite");
41452
+ backupDir = join26(cleoDir, "backups", "sqlite");
41102
41453
  mkdirSync5(backupDir, { recursive: true });
41103
41454
  } catch {
41104
41455
  return null;
@@ -41130,7 +41481,7 @@ function sourceFileOf(db) {
41130
41481
  const location = db.location();
41131
41482
  if (!location) return null;
41132
41483
  try {
41133
- return realpathSync6(location);
41484
+ return realpathSync7(location);
41134
41485
  } catch {
41135
41486
  return location;
41136
41487
  }
@@ -41141,10 +41492,10 @@ function hasLocation(db) {
41141
41492
  function assertOwnedByProject(source, prefix, cwd) {
41142
41493
  let cleoDir = getCleoDir(cwd);
41143
41494
  try {
41144
- cleoDir = realpathSync6(cleoDir);
41495
+ cleoDir = realpathSync7(cleoDir);
41145
41496
  } catch {
41146
41497
  }
41147
- if (!source.startsWith(cleoDir + sep3)) {
41498
+ if (!source.startsWith(cleoDir + sep4)) {
41148
41499
  throw new Error(
41149
41500
  `refusing to snapshot ${prefix}: its database ${source} is not inside ${cleoDir}`
41150
41501
  );
@@ -41173,7 +41524,7 @@ function commitSnapshotFile(tmp, dest) {
41173
41524
  }
41174
41525
  renameSync6(tmp, dest);
41175
41526
  try {
41176
- const dirFd = openSync(dirname13(dest), "r");
41527
+ const dirFd = openSync(dirname15(dest), "r");
41177
41528
  try {
41178
41529
  fsyncSync(dirFd);
41179
41530
  } finally {
@@ -41196,7 +41547,7 @@ function removeDeadTempSnapshots(backupDir) {
41196
41547
  const m = TEMP_SNAPSHOT_RE.exec(name2);
41197
41548
  if (!m) continue;
41198
41549
  const pid = Number(m[1]);
41199
- const path2 = join25(backupDir, name2);
41550
+ const path2 = join26(backupDir, name2);
41200
41551
  const stale = pid !== process.pid && (!isPidAlive2(pid) || Date.now() - statSync6(path2).mtimeMs > TEMP_SNAPSHOT_MAX_AGE_MS);
41201
41552
  if (stale) rmSync(path2, { force: true });
41202
41553
  }
@@ -41206,7 +41557,7 @@ function removeDeadTempSnapshots(backupDir) {
41206
41557
  async function freeSnapshotName(backupDir, prefix) {
41207
41558
  for (let attempt = 0; attempt < SNAPSHOT_NAME_ATTEMPTS; attempt++) {
41208
41559
  const name2 = `${prefix}-${formatTimestamp(/* @__PURE__ */ new Date())}.db`;
41209
- if (!existsSync19(join25(backupDir, name2))) return name2;
41560
+ if (!existsSync20(join26(backupDir, name2))) return name2;
41210
41561
  await new Promise((r) => setTimeout(r, 1e3 - Date.now() % 1e3 + 5));
41211
41562
  }
41212
41563
  throw new Error(`no free snapshot filename for ${prefix} in ${backupDir}`);
@@ -41234,7 +41585,7 @@ async function snapshotOne(target, backupDir, writtenBySource, cwd) {
41234
41585
  if (opened && target.closeDb) target.closeDb(opened);
41235
41586
  throw err;
41236
41587
  }
41237
- const dest = join25(backupDir, destName);
41588
+ const dest = join26(backupDir, destName);
41238
41589
  removeDeadTempSnapshots(backupDir);
41239
41590
  const existing = source !== null ? writtenBySource.get(source) : void 0;
41240
41591
  if (existing !== void 0) {
@@ -41288,13 +41639,13 @@ async function vacuumIntoBackup(opts = {}) {
41288
41639
  function listSqliteBackupsForPrefix(prefix, cwd) {
41289
41640
  try {
41290
41641
  const cleoDir = getCleoDir(cwd);
41291
- const backupDir = join25(cleoDir, "backups", "sqlite");
41292
- if (!existsSync19(backupDir)) return [];
41642
+ const backupDir = join26(cleoDir, "backups", "sqlite");
41643
+ if (!existsSync20(backupDir)) return [];
41293
41644
  const pattern = snapshotPattern(prefix);
41294
41645
  return readdirSync5(backupDir).filter((f) => pattern.test(f)).map((f) => ({
41295
41646
  name: f,
41296
- path: join25(backupDir, f),
41297
- mtimeMs: statSync6(join25(backupDir, f)).mtimeMs
41647
+ path: join26(backupDir, f),
41648
+ mtimeMs: statSync6(join26(backupDir, f)).mtimeMs
41298
41649
  })).sort((a, b) => b.mtimeMs - a.mtimeMs);
41299
41650
  } catch {
41300
41651
  return [];
@@ -41367,13 +41718,13 @@ __export(sqlite_exports, {
41367
41718
  seedTasksMeta: () => seedTasksMeta,
41368
41719
  worktreeRecoveryRefusal: () => worktreeRecoveryRefusal
41369
41720
  });
41370
- import { copyFileSync as copyFileSync4, existsSync as existsSync20, realpathSync as realpathSync7, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
41371
- import { createRequire as createRequire7 } from "node:module";
41372
- import { basename as basename8, dirname as dirname14, resolve as resolve10 } from "node:path";
41721
+ import { copyFileSync as copyFileSync4, existsSync as existsSync21, realpathSync as realpathSync8, renameSync as renameSync7, unlinkSync as unlinkSync4 } from "node:fs";
41722
+ import { createRequire as createRequire8 } from "node:module";
41723
+ import { basename as basename8, dirname as dirname16, resolve as resolve12 } from "node:path";
41373
41724
  import { eq as eq9 } from "drizzle-orm";
41374
41725
  function _getDrizzle3() {
41375
41726
  if (_drizzle3 === null) {
41376
- const _require7 = createRequire7(import.meta.url);
41727
+ const _require7 = createRequire8(import.meta.url);
41377
41728
  const mod = _require7("drizzle-orm/node-sqlite");
41378
41729
  _drizzle3 = mod.drizzle;
41379
41730
  }
@@ -41409,16 +41760,16 @@ function countBackupTasks(backupDb) {
41409
41760
  return 0;
41410
41761
  }
41411
41762
  function isSameDirectory(a, b) {
41412
- if (resolve10(a) === resolve10(b)) return true;
41763
+ if (resolve12(a) === resolve12(b)) return true;
41413
41764
  try {
41414
- return realpathSync7(a) === realpathSync7(b);
41765
+ return realpathSync8(a) === realpathSync8(b);
41415
41766
  } catch {
41416
41767
  return false;
41417
41768
  }
41418
41769
  }
41419
41770
  function worktreeRecoveryRefusal(dbPath) {
41420
- const storeCleoDir = dirname14(dbPath);
41421
- const root = dirname14(storeCleoDir);
41771
+ const storeCleoDir = dirname16(dbPath);
41772
+ const root = dirname16(storeCleoDir);
41422
41773
  if (basename8(storeCleoDir) !== ".cleo" || !isGitLinkedCheckout(root)) return null;
41423
41774
  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).`;
41424
41775
  }
@@ -41430,7 +41781,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
41430
41781
  const countResult = nativeDb.prepare("SELECT COUNT(*) as cnt FROM tasks_tasks").get();
41431
41782
  const taskCount = countResult?.cnt ?? 0;
41432
41783
  if (taskCount > 0) return false;
41433
- const storeCleoDir = dirname14(dbPath);
41784
+ const storeCleoDir = dirname16(dbPath);
41434
41785
  const worktreeRefusal = worktreeRecoveryRefusal(dbPath);
41435
41786
  if (worktreeRefusal !== null) {
41436
41787
  log15.warn({ dbPath }, worktreeRefusal);
@@ -41441,7 +41792,7 @@ async function autoRecoverFromBackup(nativeDb, dbPath, cwd) {
41441
41792
  return false;
41442
41793
  }
41443
41794
  const newestBackup = backups[0];
41444
- const backupCleoDir = dirname14(dirname14(dirname14(newestBackup.path)));
41795
+ const backupCleoDir = dirname16(dirname16(dirname16(newestBackup.path)));
41445
41796
  if (!isSameDirectory(backupCleoDir, storeCleoDir)) {
41446
41797
  log15.warn(
41447
41798
  { dbPath, backupPath: newestBackup.path },
@@ -41563,6 +41914,7 @@ function runMigrations(nativeDb, db, dbPath) {
41563
41914
  try {
41564
41915
  migrateWithRetry(db, migrationsFolder, nativeDb, "tasks", "sqlite");
41565
41916
  } catch (error) {
41917
+ if (isWorktreeBuildSchemaError(error)) throw error;
41566
41918
  if (isSqliteBusy(error) || !tableExists(nativeDb, "tasks_tasks")) throw error;
41567
41919
  try {
41568
41920
  rebuildLegacyTasksLineage(
@@ -41604,7 +41956,7 @@ async function getSchemaVersion(cwd) {
41604
41956
  return result[0]?.value ?? null;
41605
41957
  }
41606
41958
  function dbExists(cwd) {
41607
- return existsSync20(resolveDualScopeDbPath("project", cwd));
41959
+ return existsSync21(resolveDualScopeDbPath("project", cwd));
41608
41960
  }
41609
41961
  function getNativeDb(cwd) {
41610
41962
  return boundProjectNative("tasks", cwd);
@@ -41640,6 +41992,7 @@ var init_sqlite3 = __esm({
41640
41992
  init_resolve_migrations_folder();
41641
41993
  init_sqlite_backup();
41642
41994
  init_twin_collapse();
41995
+ init_worktree_build_guard();
41643
41996
  init_worktree_isolation_guard();
41644
41997
  init_sqlite_native();
41645
41998
  init_tasks_schema();
@@ -41668,15 +42021,15 @@ var init_sqlite3 = __esm({
41668
42021
  // packages/core/src/store/exodus/migrate.ts
41669
42022
  import {
41670
42023
  copyFileSync as copyFileSync5,
41671
- existsSync as existsSync21,
42024
+ existsSync as existsSync22,
41672
42025
  mkdirSync as mkdirSync6,
41673
- readFileSync as readFileSync6,
42026
+ readFileSync as readFileSync7,
41674
42027
  renameSync as renameSync8,
41675
42028
  statSync as statSync7,
41676
42029
  unlinkSync as unlinkSync5,
41677
42030
  writeFileSync as writeFileSync6
41678
42031
  } from "node:fs";
41679
- import { join as join26 } from "node:path";
42032
+ import { join as join27 } from "node:path";
41680
42033
  function getSqliteVersion(db) {
41681
42034
  try {
41682
42035
  const row = db.prepare("SELECT sqlite_version() AS v").get();
@@ -41707,24 +42060,24 @@ function restoreGrandfatheredGuards(db, suspended) {
41707
42060
  }
41708
42061
  }
41709
42062
  function writeJournal(stagingDir, journal) {
41710
- const journalPath = join26(stagingDir, JOURNAL_FILENAME);
42063
+ const journalPath = join27(stagingDir, JOURNAL_FILENAME);
41711
42064
  const tmpPath = `${journalPath}.tmp`;
41712
42065
  writeFileSync6(tmpPath, JSON.stringify(journal, null, 2) + "\n", "utf8");
41713
42066
  renameSync8(tmpPath, journalPath);
41714
42067
  }
41715
42068
  function readJournal(stagingDir) {
41716
- const journalPath = join26(stagingDir, JOURNAL_FILENAME);
41717
- if (!existsSync21(journalPath)) return null;
42069
+ const journalPath = join27(stagingDir, JOURNAL_FILENAME);
42070
+ if (!existsSync22(journalPath)) return null;
41718
42071
  try {
41719
- return JSON.parse(readFileSync6(journalPath, "utf8"));
42072
+ return JSON.parse(readFileSync7(journalPath, "utf8"));
41720
42073
  } catch {
41721
42074
  return null;
41722
42075
  }
41723
42076
  }
41724
42077
  function clearExodusJournal(stagingDir) {
41725
- const journalPath = join26(stagingDir, JOURNAL_FILENAME);
42078
+ const journalPath = join27(stagingDir, JOURNAL_FILENAME);
41726
42079
  try {
41727
- if (!existsSync21(journalPath)) return false;
42080
+ if (!existsSync22(journalPath)) return false;
41728
42081
  unlinkSync5(journalPath);
41729
42082
  log10.info(
41730
42083
  { stagingDir },
@@ -42020,7 +42373,7 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42020
42373
  mkdirSync6(stagingDir, { recursive: true });
42021
42374
  let sqliteVersion = "unknown";
42022
42375
  for (const src of sources) {
42023
- if (existsSync21(src.path)) {
42376
+ if (existsSync22(src.path)) {
42024
42377
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
42025
42378
  sqliteVersion = getSqliteVersion(snap.db);
42026
42379
  snap.close();
@@ -42050,15 +42403,15 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42050
42403
  let reseedProject = null;
42051
42404
  try {
42052
42405
  for (const src of sources) {
42053
- if (!existsSync21(src.path)) continue;
42054
- const backupDest = join26(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
42406
+ if (!existsSync22(src.path)) continue;
42407
+ const backupDest = join27(stagingDir, `${src.name.replace(/[^a-z0-9-]/g, "_")}-backup.db`);
42055
42408
  const srcBytes = safeStatBytes(src.path);
42056
42409
  const skipStagingCopy = srcBytes > plan.stagingCopyThresholdBytes;
42057
42410
  if (skipStagingCopy) {
42058
42411
  onProgress?.(
42059
42412
  `Skipping full staging copy of ${src.name} (${srcBytes} bytes > ${plan.stagingCopyThresholdBytes} threshold) \u2014 source is archived, not deleted, on success.`
42060
42413
  );
42061
- } else if (!existsSync21(backupDest)) {
42414
+ } else if (!existsSync22(backupDest)) {
42062
42415
  onProgress?.(`Backing up ${src.name} \u2192 staging dir\u2026`);
42063
42416
  copyFileSync5(src.path, backupDest);
42064
42417
  backupPaths.push(backupDest);
@@ -42091,8 +42444,8 @@ async function runExodusMigrate(plan, forceCrossVersion = false, onProgress, opt
42091
42444
  }
42092
42445
  prepareExodusRecovery(projectNative, stagingDir);
42093
42446
  if (globalNative !== null) prepareExodusRecovery(globalNative, stagingDir);
42094
- const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync21(s.path));
42095
- const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync21(s.path));
42447
+ const projectSources = sources.filter((s) => s.targetScope === "project" && existsSync22(s.path));
42448
+ const globalSources = sources.filter((s) => s.targetScope === "global" && existsSync22(s.path));
42096
42449
  if (globalNative === null && globalSources.length > 0)
42097
42450
  throw new Error("A projectOnly exodus run was given global-scope sources");
42098
42451
  await migrateScope(
@@ -42400,9 +42753,9 @@ __export(reconcile_exports, {
42400
42753
  reconcileSupersededStores: () => reconcileSupersededStores,
42401
42754
  unmigratedBareSources: () => unmigratedBareSources
42402
42755
  });
42403
- import { copyFileSync as copyFileSync6, existsSync as existsSync22, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
42756
+ import { copyFileSync as copyFileSync6, existsSync as existsSync23, mkdirSync as mkdirSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
42404
42757
  import { tmpdir as tmpdir3 } from "node:os";
42405
- import { basename as basename9, join as join27 } from "node:path";
42758
+ import { basename as basename9, join as join28 } from "node:path";
42406
42759
  function ident2(name2) {
42407
42760
  return `"${name2.replace(/"/g, '""')}"`;
42408
42761
  }
@@ -42471,7 +42824,7 @@ function assessSupersededProjectStores(liveStorePath, sources, resolveTarget = r
42471
42824
  }
42472
42825
  function legacySourcesHoldRows(sources) {
42473
42826
  for (const src of sources) {
42474
- if (!existsSync22(src.path)) continue;
42827
+ if (!existsSync23(src.path)) continue;
42475
42828
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
42476
42829
  try {
42477
42830
  for (const table of orderTablesForCopy(snap.db)) {
@@ -42502,8 +42855,8 @@ async function bareTaskCoreSource(liveStorePath, resolveTarget, outDir) {
42502
42855
  live.close();
42503
42856
  }
42504
42857
  if (tables.length === 0) return null;
42505
- const seedPath = await buildFreshProjectStore(join27(outDir, "fresh-project-seed.db"));
42506
- const path2 = join27(outDir, "cleo-bare-task-core.db");
42858
+ const seedPath = await buildFreshProjectStore(join28(outDir, "fresh-project-seed.db"));
42859
+ const path2 = join28(outDir, "cleo-bare-task-core.db");
42507
42860
  const snap = openCleoDbSnapshot(path2, { readOnly: false });
42508
42861
  let kept = 0;
42509
42862
  try {
@@ -42551,7 +42904,7 @@ async function buildFreshProjectStore(path2) {
42551
42904
  }
42552
42905
  function snapshotFresherBareRows(barePath, legacyTasksPath, stagingDir) {
42553
42906
  if (legacyTasksPath === void 0) return null;
42554
- const path2 = join27(stagingDir, "cleo-bare-task-core-fresher.db");
42907
+ const path2 = join28(stagingDir, "cleo-bare-task-core-fresher.db");
42555
42908
  const snap = openCleoDbSnapshot(barePath, { readOnly: true });
42556
42909
  try {
42557
42910
  snap.db.exec(`VACUUM INTO '${path2.replace(/'/g, "''")}'`);
@@ -42702,7 +43055,7 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
42702
43055
  const additive = options.additive === true;
42703
43056
  const plan = buildExodusPlan(projectRoot);
42704
43057
  const resolveTarget = await buildRuntimeTargetResolver();
42705
- const scratch = mkdtempSync(join27(tmpdir3(), "cleo-reconcile-"));
43058
+ const scratch = mkdtempSync(join28(tmpdir3(), "cleo-reconcile-"));
42706
43059
  try {
42707
43060
  return await reconcileWithScratch(
42708
43061
  projectRoot,
@@ -42718,8 +43071,8 @@ async function reconcileSuppressed(projectRoot, options, liveStorePath) {
42718
43071
  }
42719
43072
  }
42720
43073
  async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath, plan, resolveTarget, scratch) {
42721
- const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync22(s.path));
42722
- const bare = !additive && existsSync22(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
43074
+ const fileSources = plan.sources.filter((s) => s.targetScope === "project" && existsSync23(s.path));
43075
+ const bare = !additive && existsSync23(liveStorePath) ? await bareTaskCoreSource(liveStorePath, resolveTarget, scratch) : null;
42723
43076
  const copyResolver = additive ? (sourceName, legacyTable) => {
42724
43077
  const r = resolveTarget(sourceName, legacyTable);
42725
43078
  return r.kind !== "skip" && isLiveAuthoritative(sourceName, legacyTable, r.targetName) ? { kind: "skip", reason: "additive: live-authoritative task graph" } : r;
@@ -42738,7 +43091,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42738
43091
  stagingDir: null,
42739
43092
  receiptPath: null
42740
43093
  };
42741
- if (sources.length === 0 || !existsSync22(liveStorePath)) {
43094
+ if (sources.length === 0 || !existsSync23(liveStorePath)) {
42742
43095
  return {
42743
43096
  ...base,
42744
43097
  outcome: "nothing-to-reconcile",
@@ -42778,11 +43131,11 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42778
43131
  };
42779
43132
  }
42780
43133
  const iso = (/* @__PURE__ */ new Date()).toISOString().replace(/[:]/g, "").replace(/\..+Z$/, "Z");
42781
- const stagingDir = join27(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
43134
+ const stagingDir = join28(resolveCleoDir(projectRoot), `${RECONCILE_DIR_PREFIX}${iso}`);
42782
43135
  mkdirSync7(stagingDir, { recursive: true });
42783
43136
  const copySources = sources.map((s) => {
42784
43137
  if (s !== bare) return s;
42785
- const kept = join27(stagingDir, basename9(s.path));
43138
+ const kept = join28(stagingDir, basename9(s.path));
42786
43139
  copyFileSync6(s.path, kept);
42787
43140
  return { ...s, path: kept };
42788
43141
  });
@@ -42802,7 +43155,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42802
43155
  const result = await withLock(
42803
43156
  `${liveStorePath}.exodus-on-open.lock`,
42804
43157
  async () => {
42805
- const liveBefore = join27(scratch, "live-before.db");
43158
+ const liveBefore = join28(scratch, "live-before.db");
42806
43159
  snapshotLive(liveStorePath, liveBefore);
42807
43160
  const migrated = await runExodusMigrate(reconcilePlan, false, (msg) => log11.debug(msg), {
42808
43161
  projectOnly: true,
@@ -42852,7 +43205,7 @@ async function reconcileWithScratch(projectRoot, dryRun, additive, liveStorePath
42852
43205
  },
42853
43206
  { stale: 6e5, retries: 30 }
42854
43207
  );
42855
- const receiptPath = join27(stagingDir, RECEIPT_FILENAME);
43208
+ const receiptPath = join28(stagingDir, RECEIPT_FILENAME);
42856
43209
  const receipt2 = { ...result, receiptPath };
42857
43210
  writeFileSync7(receiptPath, `${JSON.stringify(receipt2, null, 2)}
42858
43211
  `, "utf8");
@@ -42929,20 +43282,20 @@ var init_seal = __esm({
42929
43282
  });
42930
43283
 
42931
43284
  // packages/core/src/store/exodus/status.ts
42932
- import { existsSync as existsSync23, readdirSync as readdirSync6, readFileSync as readFileSync7, statSync as statSync8 } from "node:fs";
42933
- import { join as join28 } from "node:path";
43285
+ import { existsSync as existsSync24, readdirSync as readdirSync6, readFileSync as readFileSync8, statSync as statSync8 } from "node:fs";
43286
+ import { join as join29 } from "node:path";
42934
43287
  function readJournal2(stagingDir) {
42935
- const p = join28(stagingDir, JOURNAL_FILENAME2);
42936
- if (!existsSync23(p)) return null;
43288
+ const p = join29(stagingDir, JOURNAL_FILENAME2);
43289
+ if (!existsSync24(p)) return null;
42937
43290
  try {
42938
- return JSON.parse(readFileSync7(p, "utf8"));
43291
+ return JSON.parse(readFileSync8(p, "utf8"));
42939
43292
  } catch {
42940
43293
  return null;
42941
43294
  }
42942
43295
  }
42943
43296
  function findStagingDirs(cleoDir) {
42944
43297
  try {
42945
- return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join28(cleoDir, e.name)).sort().reverse();
43298
+ return readdirSync6(cleoDir, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name.startsWith("exodus-staging-")).map((e) => join29(cleoDir, e.name)).sort().reverse();
42946
43299
  } catch {
42947
43300
  return [];
42948
43301
  }
@@ -42965,15 +43318,15 @@ function runExodusStatus(cwd) {
42965
43318
  const sourcesInfo = plan.sources.map((s) => ({
42966
43319
  name: s.name,
42967
43320
  path: s.path,
42968
- exists: existsSync23(s.path),
43321
+ exists: existsSync24(s.path),
42969
43322
  bytes: safeBytes(s.path)
42970
43323
  }));
42971
43324
  return {
42972
43325
  hasStaging: latestStaging !== null,
42973
43326
  stagingDir: latestStaging,
42974
43327
  journal,
42975
- projectDbExists: existsSync23(projectDbPath),
42976
- globalDbExists: existsSync23(globalDbPath),
43328
+ projectDbExists: existsSync24(projectDbPath),
43329
+ globalDbExists: existsSync24(globalDbPath),
42977
43330
  sourcesPresent: sourcesInfo.some((s) => s.exists),
42978
43331
  sources: sourcesInfo
42979
43332
  };
@@ -42990,8 +43343,8 @@ var init_status = __esm({
42990
43343
  });
42991
43344
 
42992
43345
  // packages/core/src/store/exodus/verify-migration.ts
42993
- import { existsSync as existsSync24 } from "node:fs";
42994
- import { createRequire as createRequire8 } from "node:module";
43346
+ import { existsSync as existsSync25 } from "node:fs";
43347
+ import { createRequire as createRequire9 } from "node:module";
42995
43348
  function orderByClause(db, tableName) {
42996
43349
  try {
42997
43350
  const pragma = db.prepare(`PRAGMA table_info("${tableName}")`).all();
@@ -43255,7 +43608,7 @@ function orphanAlreadyInSource(targetDb, fk, sources, resolveTarget = resolveCon
43255
43608
  const anyFeeder = (targetTable, probe) => {
43256
43609
  for (const feeder of feedersOf(targetTable)) {
43257
43610
  const src = sources.find((s) => s.name === feeder.sourceName);
43258
- if (src === void 0 || !existsSync24(src.path)) continue;
43611
+ if (src === void 0 || !existsSync25(src.path)) continue;
43259
43612
  const snap = openCleoDbSnapshot(src.path, { readOnly: true });
43260
43613
  try {
43261
43614
  if (!tableExists3(snap.db, feeder.legacyTable)) continue;
@@ -43310,7 +43663,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43310
43663
  const preExistingForeignKeyViolations = [];
43311
43664
  const failureLines = [];
43312
43665
  const sourceOrphanSigs = /* @__PURE__ */ new Set();
43313
- if (!existsSync24(projectDbPath)) {
43666
+ if (!existsSync25(projectDbPath)) {
43314
43667
  return {
43315
43668
  ok: false,
43316
43669
  tables: [],
@@ -43321,7 +43674,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43321
43674
  error: `Consolidated project cleo.db not found at ${projectDbPath}. Run 'cleo exodus migrate' first.`
43322
43675
  };
43323
43676
  }
43324
- if (!existsSync24(globalDbPath)) {
43677
+ if (!existsSync25(globalDbPath)) {
43325
43678
  return {
43326
43679
  ok: false,
43327
43680
  tables: [],
@@ -43336,7 +43689,7 @@ function verifyMigration(sources, projectDbPath, globalDbPath, onProgress, resol
43336
43689
  const globalSnap = openCleoDbSnapshot(globalDbPath, { readOnly: true });
43337
43690
  try {
43338
43691
  for (const src of sources) {
43339
- if (!existsSync24(src.path)) {
43692
+ if (!existsSync25(src.path)) {
43340
43693
  onProgress?.(`Skipping ${src.name} (not present)`);
43341
43694
  continue;
43342
43695
  }
@@ -43531,7 +43884,7 @@ var init_verify_migration = __esm({
43531
43884
  init_column_transforms();
43532
43885
  init_table_name_map();
43533
43886
  log13 = getLogger("verify-migration");
43534
- _require5 = createRequire8(import.meta.url);
43887
+ _require5 = createRequire9(import.meta.url);
43535
43888
  CHECK_ENUM_REGEX = /CHECK\s*\(\s*"([^"]+)"\s+(?:IS\s+NULL\s+OR\s+"[^"]+"\s+)?IN\s*\(([^)]*)\)\s*\)/gi;
43536
43889
  }
43537
43890
  });
@@ -43627,11 +43980,11 @@ __export(on_open_exports, {
43627
43980
  maybeRunExodusOnOpen: () => maybeRunExodusOnOpen,
43628
43981
  withExodusOnOpenSuppressed: () => withExodusOnOpenSuppressed
43629
43982
  });
43630
- import { existsSync as existsSync25, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
43983
+ import { existsSync as existsSync26, mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
43631
43984
  import { tmpdir as tmpdir4 } from "node:os";
43632
- import { join as join29, resolve as resolve11 } from "node:path";
43985
+ import { join as join30, resolve as resolve13 } from "node:path";
43633
43986
  async function withExodusOnOpenSuppressed(dbPath, fn) {
43634
- const key = resolve11(dbPath);
43987
+ const key = resolve13(dbPath);
43635
43988
  _reconcileInProgress.set(key, (_reconcileInProgress.get(key) ?? 0) + 1);
43636
43989
  try {
43637
43990
  return await fn();
@@ -43669,7 +44022,7 @@ function remedyFor(scope) {
43669
44022
  }
43670
44023
  async function strandedLegacySources(scope, cwd) {
43671
44024
  const { buildExodusPlan: buildExodusPlan2, legacySourcesHoldRows: legacySourcesHoldRows2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
43672
- return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync25(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
44025
+ return buildExodusPlan2(cwd).sources.filter((s) => s.targetScope === scope && existsSync26(s.path)).filter((s) => legacySourcesHoldRows2([s])).map((s) => s.name);
43673
44026
  }
43674
44027
  async function rollbackBothScopes(plan) {
43675
44028
  const { getDualScopeNativeDb: getDualScopeNativeDb2, openDualScopeDbAtPath: openDualScopeDbAtPath2 } = await Promise.resolve().then(() => (init_dual_scope_db(), dual_scope_db_exports));
@@ -43747,7 +44100,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43747
44100
  if (_exodusInProgress) {
43748
44101
  return { outcome: "skipped", reason: "re-entrant open during active migration" };
43749
44102
  }
43750
- if (_reconcileInProgress.has(resolve11(dbPath))) {
44103
+ if (_reconcileInProgress.has(resolve13(dbPath))) {
43751
44104
  return {
43752
44105
  outcome: "skipped",
43753
44106
  reason: "an explicit superseded-store reconcile of this store is in progress"
@@ -43780,14 +44133,14 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43780
44133
  const { buildExodusPlan: buildExodusPlan2, runExodusMigrate: runExodusMigrate2, verifyMigration: verifyMigration2, clearExodusJournal: clearExodusJournal2 } = await Promise.resolve().then(() => (init_exodus(), exodus_exports));
43781
44134
  const plan = buildExodusPlan2(cwd);
43782
44135
  const plannedTarget = scope === "project" ? plan.projectDbPath : plan.globalDbPath;
43783
- if (resolve11(plannedTarget) !== resolve11(dbPath)) {
44136
+ if (resolve13(plannedTarget) !== resolve13(dbPath)) {
43784
44137
  return {
43785
44138
  outcome: "aborted",
43786
44139
  reason: `migration plan target ${plannedTarget} does not match opened database ${dbPath}; no migration applied`
43787
44140
  };
43788
44141
  }
43789
44142
  const scopeSources = plan.sources.filter((s) => s.targetScope === scope);
43790
- if (!scopeSources.some((s) => existsSync25(s.path))) {
44143
+ if (!scopeSources.some((s) => existsSync26(s.path))) {
43791
44144
  return {
43792
44145
  outcome: "skipped",
43793
44146
  reason: `no legacy ${scope}-scope source DBs present (fresh install or cross-scope-only)`
@@ -43804,12 +44157,12 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43804
44157
  {
43805
44158
  scope,
43806
44159
  dbPath,
43807
- sources: plan.sources.filter((s) => existsSync25(s.path)).map((s) => s.name)
44160
+ sources: plan.sources.filter((s) => existsSync26(s.path)).map((s) => s.name)
43808
44161
  },
43809
44162
  "exodus-on-open: consolidated cleo.db is empty and legacy data present \u2014 auto-migrating"
43810
44163
  );
43811
44164
  _exodusInProgress = true;
43812
- const bareScratch = mkdtempSync2(join29(tmpdir4(), "cleo-exodus-bare-"));
44165
+ const bareScratch = mkdtempSync2(join30(tmpdir4(), "cleo-exodus-bare-"));
43813
44166
  try {
43814
44167
  const { buildRuntimeTargetResolver: buildRuntimeTargetResolver2 } = await Promise.resolve().then(() => (init_runtime_targets(), runtime_targets_exports));
43815
44168
  const resolveTarget = await buildRuntimeTargetResolver2();
@@ -43817,7 +44170,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43817
44170
  const bare = scope === "project" ? await unmigratedBareSources2(
43818
44171
  dbPath,
43819
44172
  resolveTarget,
43820
- plan.sources.find((s) => s.name === "tasks" && existsSync25(s.path))?.path,
44173
+ plan.sources.find((s) => s.name === "tasks" && existsSync26(s.path))?.path,
43821
44174
  bareScratch
43822
44175
  ) : { first: [], last: [] };
43823
44176
  const migratePlan = { ...plan, sources: [...bare.first, ...plan.sources, ...bare.last] };
@@ -43881,7 +44234,7 @@ async function runExodusOnOpen(scope, dbPath, nativeDb, cwd) {
43881
44234
  "exodus-on-open: parity verified \u2014 legacy data migrated into consolidated cleo.db"
43882
44235
  );
43883
44236
  try {
43884
- const consumed = plan.sources.filter((s) => existsSync25(s.path));
44237
+ const consumed = plan.sources.filter((s) => existsSync26(s.path));
43885
44238
  const identities = await sealTargets(plan, consumed);
43886
44239
  const archiveResult = archiveMigratedSources(consumed, cwd, plan, identities);
43887
44240
  log14.info(
@@ -43956,9 +44309,9 @@ __export(dual_scope_db_exports, {
43956
44309
  upsertIdempotent: () => upsertIdempotent,
43957
44310
  withStoreSchemaOwnership: () => withStoreSchemaOwnership
43958
44311
  });
43959
- import { existsSync as existsSync26, mkdirSync as mkdirSync8 } from "node:fs";
43960
- import { createRequire as createRequire9 } from "node:module";
43961
- import { dirname as dirname15, join as join30, resolve as resolve12 } from "node:path";
44312
+ import { existsSync as existsSync27, mkdirSync as mkdirSync8 } from "node:fs";
44313
+ import { createRequire as createRequire10 } from "node:module";
44314
+ import { dirname as dirname17, join as join31, resolve as resolve14 } from "node:path";
43962
44315
  function getDualScopeNativeDb(handle) {
43963
44316
  const db = handle.db;
43964
44317
  if ("$client" in db && db.$client instanceof getDatabaseSyncCtor()) return db.$client;
@@ -43980,9 +44333,9 @@ function cacheKey(scope, dbPath) {
43980
44333
  }
43981
44334
  function resolveDualScopeDbPath(scope, cwd, capturedGlobalHome) {
43982
44335
  if (scope === "project") {
43983
- return join30(resolveCleoDir(cwd), "cleo.db");
44336
+ return join31(resolveCleoDir(cwd), "cleo.db");
43984
44337
  }
43985
- return join30(capturedGlobalHome ?? getCleoHome(), "cleo.db");
44338
+ return join31(capturedGlobalHome ?? getCleoHome(), "cleo.db");
43986
44339
  }
43987
44340
  function migrationsSetName(scope) {
43988
44341
  return scope === "project" ? "drizzle-cleo-project" : "drizzle-cleo-global";
@@ -44032,8 +44385,8 @@ async function openDualScopeDb(scope, cwd, options) {
44032
44385
  async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44033
44386
  execution?.assertActive();
44034
44387
  log15.debug({ scope, dbPath }, "opening DEDICATED (non-cached) dual-scope cleo.db (T11782 FIX D)");
44035
- const dir = dirname15(dbPath);
44036
- if (!existsSync26(dir)) {
44388
+ const dir = dirname17(dbPath);
44389
+ if (!existsSync27(dir)) {
44037
44390
  mkdirSync8(dir, { recursive: true });
44038
44391
  }
44039
44392
  execution?.assertActive();
@@ -44041,6 +44394,7 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44041
44394
  const nativeDb = new DatabaseSyncCtor(dbPath, { allowExtension: true });
44042
44395
  try {
44043
44396
  applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
44397
+ installSchemaWriteGuard(nativeDb);
44044
44398
  const drizzle2 = getDrizzle();
44045
44399
  const db = drizzle2({ client: nativeDb });
44046
44400
  const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
@@ -44089,11 +44443,12 @@ async function openDedicatedDualScopeDb(scope, dbPath, log15, execution) {
44089
44443
  execution?.assertActive();
44090
44444
  return handle;
44091
44445
  } catch (err) {
44446
+ const explained = explainSchemaWriteDenial(nativeDb, err);
44092
44447
  try {
44093
44448
  nativeDb.close();
44094
44449
  } catch {
44095
44450
  }
44096
- throw err;
44451
+ throw explained;
44097
44452
  }
44098
44453
  }
44099
44454
  async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
@@ -44114,7 +44469,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44114
44469
  );
44115
44470
  }
44116
44471
  const dedicated = options?.dedicated === true;
44117
- const normalizedPath = resolve12(dbPath);
44472
+ const normalizedPath = resolve14(dbPath);
44118
44473
  const key = cacheKey(scope, normalizedPath);
44119
44474
  if (!dedicated) {
44120
44475
  const existing = _cache.get(key);
@@ -44151,8 +44506,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44151
44506
  }
44152
44507
  let initResolve = null;
44153
44508
  let initReject = null;
44154
- const initPromise = new Promise((resolve14, reject) => {
44155
- initResolve = resolve14;
44509
+ const initPromise = new Promise((resolve16, reject) => {
44510
+ initResolve = resolve16;
44156
44511
  initReject = reject;
44157
44512
  });
44158
44513
  _cache.set(key, {
@@ -44173,8 +44528,8 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44173
44528
  try {
44174
44529
  execution?.assertActive();
44175
44530
  log15.debug({ scope, dbPath: normalizedPath }, "opening dual-scope cleo.db");
44176
- const dir = dirname15(normalizedPath);
44177
- if (!existsSync26(dir)) {
44531
+ const dir = dirname17(normalizedPath);
44532
+ if (!existsSync27(dir)) {
44178
44533
  mkdirSync8(dir, { recursive: true });
44179
44534
  }
44180
44535
  execution?.assertActive();
@@ -44182,6 +44537,7 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44182
44537
  const nativeDb = new DatabaseSyncCtor(normalizedPath, { allowExtension: true });
44183
44538
  openingNative = nativeDb;
44184
44539
  applyPerfPragmas(nativeDb, memoryBoundedPragmaOverrides());
44540
+ installSchemaWriteGuard(nativeDb);
44185
44541
  const drizzle2 = getDrizzle();
44186
44542
  const db = drizzle2({ client: nativeDb });
44187
44543
  const migrationsFolder = resolveCorePackageMigrationsFolder(migrationsSetName(scope));
@@ -44312,12 +44668,13 @@ async function openDualScopeDbAtPath(scope, dbPath, exodusCwd, options) {
44312
44668
  execution?.assertActive();
44313
44669
  initResolve(finalHandle);
44314
44670
  } catch (err) {
44671
+ const explained = openingNative ? explainSchemaWriteDenial(openingNative, err) : err;
44315
44672
  try {
44316
44673
  if (!published && openingNative?.isOpen) openingNative.close();
44317
44674
  } catch (closeError) {
44318
44675
  log15.warn({ closeError }, "failed to close unpublished database initializer");
44319
44676
  }
44320
- initReject(err);
44677
+ initReject(explained);
44321
44678
  }
44322
44679
  })();
44323
44680
  return initPromise;
@@ -44390,6 +44747,7 @@ var init_dual_scope_db = __esm({
44390
44747
  init_relocated_store_guard();
44391
44748
  init_resolve_migrations_folder();
44392
44749
  init_sqlite_pragmas();
44750
+ init_worktree_build_guard();
44393
44751
  init_worktree_isolation_guard();
44394
44752
  init_writer_lease();
44395
44753
  ExodusAbortWriteUnsafeError = class extends Error {
@@ -44412,7 +44770,7 @@ var init_dual_scope_db = __esm({
44412
44770
  }
44413
44771
  };
44414
44772
  _cache = /* @__PURE__ */ new Map();
44415
- _require6 = createRequire9(import.meta.url);
44773
+ _require6 = createRequire10(import.meta.url);
44416
44774
  _drizzle4 = null;
44417
44775
  _DatabaseSyncCtor = null;
44418
44776
  EntryCancelledError = class extends Error {
@@ -44443,7 +44801,7 @@ var init_dual_scope_db = __esm({
44443
44801
  }
44444
44802
  /** @inheritdoc */
44445
44803
  async openProject(dbPath, options) {
44446
- const normalized = resolve12(dbPath);
44804
+ const normalized = resolve14(dbPath);
44447
44805
  if (options?.dedicated) {
44448
44806
  const handle = await openDualScopeDbAtPath("project", normalized, options?.exodusCwd, {
44449
44807
  dedicated: true
@@ -44455,7 +44813,7 @@ var init_dual_scope_db = __esm({
44455
44813
  /** @inheritdoc */
44456
44814
  async openGlobal(options) {
44457
44815
  const dbPath = resolveDualScopeDbPath("global");
44458
- const normalized = resolve12(dbPath);
44816
+ const normalized = resolve14(dbPath);
44459
44817
  if (options?.dedicated) {
44460
44818
  const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
44461
44819
  dedicated: true
@@ -44466,7 +44824,7 @@ var init_dual_scope_db = __esm({
44466
44824
  }
44467
44825
  /** @inheritdoc */
44468
44826
  async openGlobalAt(dbPath, options) {
44469
- const normalized = resolve12(dbPath);
44827
+ const normalized = resolve14(dbPath);
44470
44828
  if (options?.dedicated) {
44471
44829
  const handle = await openDualScopeDbAtPath("global", normalized, options?.exodusCwd, {
44472
44830
  dedicated: true
@@ -44477,7 +44835,7 @@ var init_dual_scope_db = __esm({
44477
44835
  }
44478
44836
  /** @inheritdoc */
44479
44837
  closeProject(dbPath) {
44480
- const normalized = resolve12(dbPath);
44838
+ const normalized = resolve14(dbPath);
44481
44839
  this.closeEntry("project", normalized);
44482
44840
  }
44483
44841
  /** @inheritdoc */
@@ -44514,8 +44872,8 @@ var init_dual_scope_db = __esm({
44514
44872
  const entryId = ++this._nextId;
44515
44873
  let initResolve;
44516
44874
  let initReject;
44517
- const initPromise = new Promise((resolve14, reject) => {
44518
- initResolve = resolve14;
44875
+ const initPromise = new Promise((resolve16, reject) => {
44876
+ initResolve = resolve16;
44519
44877
  initReject = reject;
44520
44878
  });
44521
44879
  this._registry.set(key, { id: entryId, store: null, initPromise });
@@ -45308,8 +45666,8 @@ __export(nexus_sqlite_exports, {
45308
45666
  resetNexusDbState: () => resetNexusDbState,
45309
45667
  resolveNexusMigrationsFolder: () => resolveNexusMigrationsFolder
45310
45668
  });
45311
- import { copyFileSync as copyFileSync7, existsSync as existsSync27 } from "node:fs";
45312
- import { join as join31 } from "node:path";
45669
+ import { copyFileSync as copyFileSync7, existsSync as existsSync28 } from "node:fs";
45670
+ import { join as join32 } from "node:path";
45313
45671
  function getNexusDbPath(cwd) {
45314
45672
  return resolveDualScopeDbPath("project", cwd);
45315
45673
  }
@@ -45345,12 +45703,13 @@ function ensureGlobalRegistryAttached(nativeDb) {
45345
45703
  }
45346
45704
  }
45347
45705
  nativeDb.exec(`ATTACH DATABASE '${escaped}' AS ${NEXUS_GLOBAL_ATTACH_ALIAS}`);
45706
+ refreshSchemaWriteGuard(nativeDb);
45348
45707
  }
45349
45708
  function resolveNexusMigrationsFolder() {
45350
45709
  return resolveCorePackageMigrationsFolder("drizzle-nexus");
45351
45710
  }
45352
45711
  function getNestedNexusSentinelPath() {
45353
- return join31(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
45712
+ return join32(getCleoHome(), "nexus", NESTED_NEXUS_SENTINEL);
45354
45713
  }
45355
45714
  function detectAndWarnOnNestedNexus() {
45356
45715
  let nestedPath;
@@ -45359,7 +45718,7 @@ function detectAndWarnOnNestedNexus() {
45359
45718
  } catch {
45360
45719
  return false;
45361
45720
  }
45362
- if (!existsSync27(nestedPath)) return false;
45721
+ if (!existsSync28(nestedPath)) return false;
45363
45722
  if (_warnedNestedPaths.has(nestedPath)) return false;
45364
45723
  _warnedNestedPaths.add(nestedPath);
45365
45724
  const canonicalPath = getNexusDbPath();
@@ -45518,7 +45877,7 @@ function runNexusMigrations(nativeDb, db, dbPath) {
45518
45877
  const migrationsFolder = resolveNexusMigrationsFolder();
45519
45878
  if (tableExists4(nativeDb, "nexus_nodes")) {
45520
45879
  const backupPath = dbPath.replace(/\.db$/, "-pre-cleo.db.bak");
45521
- if (!existsSync27(backupPath)) {
45880
+ if (!existsSync28(backupPath)) {
45522
45881
  try {
45523
45882
  copyFileSync7(dbPath, backupPath);
45524
45883
  } catch {
@@ -45613,6 +45972,7 @@ var init_nexus_sqlite = __esm({
45613
45972
  init_resolve_migrations_folder();
45614
45973
  init_nexus_schema();
45615
45974
  init_with_retry();
45975
+ init_worktree_build_guard();
45616
45976
  NEXUS_SCHEMA_VERSION = "1.0.0";
45617
45977
  NEXUS_GLOBAL_ATTACH_ALIAS = "nexus_global";
45618
45978
  NESTED_NEXUS_SENTINEL = "nexus.db";
@@ -45647,15 +46007,15 @@ var init_legacy_alias = __esm({
45647
46007
 
45648
46008
  // packages/core/src/llm/stable-device-id.ts
45649
46009
  import { randomUUID as randomUUID3 } from "node:crypto";
45650
- import { existsSync as existsSync28, mkdirSync as mkdirSync9, readFileSync as readFileSync8, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
45651
- import { dirname as dirname16 } from "node:path";
46010
+ import { existsSync as existsSync29, mkdirSync as mkdirSync9, readFileSync as readFileSync9, renameSync as renameSync9, writeFileSync as writeFileSync8 } from "node:fs";
46011
+ import { dirname as dirname18 } from "node:path";
45652
46012
  import { resolveStableDeviceIdPath } from "@cleocode/paths";
45653
46013
  function getStableDeviceId() {
45654
46014
  if (_cachedDeviceId !== null) return _cachedDeviceId;
45655
46015
  const path2 = resolveStableDeviceIdPath();
45656
- if (existsSync28(path2)) {
46016
+ if (existsSync29(path2)) {
45657
46017
  try {
45658
- const raw = readFileSync8(path2, "utf-8").trim();
46018
+ const raw = readFileSync9(path2, "utf-8").trim();
45659
46019
  if (raw.length > 0) {
45660
46020
  _cachedDeviceId = raw;
45661
46021
  return raw;
@@ -45665,8 +46025,8 @@ function getStableDeviceId() {
45665
46025
  }
45666
46026
  const fresh = randomUUID3();
45667
46027
  try {
45668
- const dir = dirname16(path2);
45669
- if (!existsSync28(dir)) {
46028
+ const dir = dirname18(path2);
46029
+ if (!existsSync29(dir)) {
45670
46030
  mkdirSync9(dir, { recursive: true });
45671
46031
  }
45672
46032
  const tmpPath = `${path2}.tmp.${process.pid}`;
@@ -45703,8 +46063,8 @@ var init_registry_roots = __esm({
45703
46063
  // packages/core/src/nexus/projects-scan.ts
45704
46064
  async function withinBudget(promise, ms) {
45705
46065
  let timer;
45706
- const expiry = new Promise((resolve14) => {
45707
- timer = setTimeout(() => resolve14("timeout"), ms);
46066
+ const expiry = new Promise((resolve16) => {
46067
+ timer = setTimeout(() => resolve16("timeout"), ms);
45708
46068
  timer.unref();
45709
46069
  });
45710
46070
  try {
@@ -45742,9 +46102,9 @@ __export(path_map_exports, {
45742
46102
  supersededRegistryPath: () => supersededRegistryPath,
45743
46103
  touchProjectLocation: () => touchProjectLocation
45744
46104
  });
45745
- import { existsSync as existsSync29, lstatSync, readdirSync as readdirSync7 } from "node:fs";
46105
+ import { existsSync as existsSync30, lstatSync, readdirSync as readdirSync7 } from "node:fs";
45746
46106
  import { lstat, readdir as readdir2 } from "node:fs/promises";
45747
- import { isAbsolute as isAbsolute4, join as join32, relative as relative2, sep as sep4 } from "node:path";
46107
+ import { isAbsolute as isAbsolute5, join as join33, relative as relative3, sep as sep5 } from "node:path";
45748
46108
  import { canonicalizePath as canonicalizePath3, readDeclaredProjectIdentity as readDeclaredProjectIdentity3 } from "@cleocode/paths";
45749
46109
  import { and as and7, desc as desc3, eq as eq11, inArray as inArray5, ne as ne3 } from "drizzle-orm";
45750
46110
  function holdingKey(projectId, path2) {
@@ -45760,7 +46120,7 @@ function isSupersededRegistryPath(projectPath) {
45760
46120
  return projectPath.startsWith(SUPERSEDED_PATH_PREFIX);
45761
46121
  }
45762
46122
  function projectHolding(path2, projectId) {
45763
- const cleoDir = join32(path2, ".cleo");
46123
+ const cleoDir = join33(path2, ".cleo");
45764
46124
  try {
45765
46125
  lstatSync(cleoDir);
45766
46126
  readdirSync7(cleoDir);
@@ -45772,7 +46132,7 @@ function projectHolding(path2, projectId) {
45772
46132
  return declared === null || declared.projectId === projectId ? "yes" : "no";
45773
46133
  }
45774
46134
  async function probeProjectHolding(path2, projectId, timeoutMs) {
45775
- const cleoDir = join32(path2, ".cleo");
46135
+ const cleoDir = join33(path2, ".cleo");
45776
46136
  const probe = async () => {
45777
46137
  try {
45778
46138
  await lstat(cleoDir);
@@ -45790,8 +46150,8 @@ async function probeProjectHolding(path2, projectId, timeoutMs) {
45790
46150
  return declared === null || declared.projectId === projectId ? "yes" : "no";
45791
46151
  }
45792
46152
  function isStrictlyInside(outer, inner) {
45793
- const rel = relative2(canonicalizePath3(outer), canonicalizePath3(inner));
45794
- return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep4}`) && !isAbsolute4(rel);
46153
+ const rel = relative3(canonicalizePath3(outer), canonicalizePath3(inner));
46154
+ return rel.length > 0 && rel !== ".." && !rel.startsWith(`..${sep5}`) && !isAbsolute5(rel);
45795
46155
  }
45796
46156
  function locationKey(projectId, deviceId, path2) {
45797
46157
  return and7(
@@ -45953,7 +46313,7 @@ function hasOtherLiveLocation(db, record, deviceId) {
45953
46313
  ne3(projectLocations.path, record.projectPath)
45954
46314
  )
45955
46315
  ).all().some(
45956
- (location) => isStrictlyInside(record.projectPath, location.path) && existsSync29(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record.projectId
46316
+ (location) => isStrictlyInside(record.projectPath, location.path) && existsSync30(location.path) && readDeclaredProjectIdentity3(location.path)?.projectId === record.projectId
45957
46317
  );
45958
46318
  }
45959
46319
  function demoteProjectLocation(db, record, state) {
@@ -46004,7 +46364,7 @@ function rehomeDisplacedRows(db, projectId, projectPath, deviceId, probed) {
46004
46364
  ).orderBy(desc3(projectLocations.lastSeen)).all();
46005
46365
  const present = (path2) => {
46006
46366
  const holding = probed?.get(holdingKey(row.projectId, path2));
46007
- return holding === void 0 ? existsSync29(path2) : holding === "yes";
46367
+ return holding === void 0 ? existsSync30(path2) : holding === "yes";
46008
46368
  };
46009
46369
  const home = candidates.find(
46010
46370
  (c) => present(c.path) && db.select({ projectId: projectRegistry.projectId }).from(projectRegistry).where(eq11(projectRegistry.projectPath, c.path)).all().length === 0
@@ -46033,7 +46393,7 @@ async function listProjectCheckouts(projectId, opts = {}) {
46033
46393
  projectHash: generateProjectHash(row.path),
46034
46394
  firstSeen: row.firstSeen,
46035
46395
  lastSeen: row.lastSeen,
46036
- exists: local && existsSync29(row.path),
46396
+ exists: local && existsSync30(row.path),
46037
46397
  deviceId: local ? deviceId : row.deviceId,
46038
46398
  state: row.state
46039
46399
  });
@@ -46062,13 +46422,13 @@ __export(checkout_nonce_exports, {
46062
46422
  readCheckoutNonce: () => readCheckoutNonce
46063
46423
  });
46064
46424
  import { randomBytes as randomBytes2 } from "node:crypto";
46065
- import { existsSync as existsSync30, readFileSync as readFileSync9, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
46066
- import { join as join33 } from "node:path";
46425
+ import { existsSync as existsSync31, readFileSync as readFileSync10, renameSync as renameSync10, writeFileSync as writeFileSync9 } from "node:fs";
46426
+ import { join as join34 } from "node:path";
46067
46427
  function readInfo(projectRoot) {
46068
- const path2 = join33(projectRoot, ".cleo", "project-info.json");
46069
- if (!existsSync30(path2)) return null;
46428
+ const path2 = join34(projectRoot, ".cleo", "project-info.json");
46429
+ if (!existsSync31(path2)) return null;
46070
46430
  try {
46071
- const parsed = JSON.parse(readFileSync9(path2, "utf-8"));
46431
+ const parsed = JSON.parse(readFileSync10(path2, "utf-8"));
46072
46432
  return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
46073
46433
  } catch {
46074
46434
  return null;
@@ -46084,7 +46444,7 @@ function ensureCheckoutNonce(projectRoot) {
46084
46444
  const info = readInfo(projectRoot);
46085
46445
  if (!info) return null;
46086
46446
  const nonce = randomBytes2(16).toString("hex");
46087
- const path2 = join33(projectRoot, ".cleo", "project-info.json");
46447
+ const path2 = join34(projectRoot, ".cleo", "project-info.json");
46088
46448
  const temp = `${path2}.${randomBytes2(6).toString("hex")}.tmp`;
46089
46449
  writeFileSync9(temp, `${JSON.stringify({ ...info, [CHECKOUT_NONCE_FIELD]: nonce }, null, 2)}
46090
46450
  `);
@@ -46159,10 +46519,10 @@ __export(paths_exports, {
46159
46519
  validateProjectRoot: () => validateProjectRoot,
46160
46520
  worktreeScope: () => worktreeScope
46161
46521
  });
46162
- import { existsSync as existsSync31, readFileSync as readFileSync10, statSync as statSync9 } from "node:fs";
46163
- import { createRequire as createRequire10 } from "node:module";
46522
+ import { existsSync as existsSync32, readFileSync as readFileSync11, statSync as statSync9 } from "node:fs";
46523
+ import { createRequire as createRequire11 } from "node:module";
46164
46524
  import { homedir as homedir2 } from "node:os";
46165
- import { basename as basename10, dirname as dirname17, join as join34, resolve as resolve13 } from "node:path";
46525
+ import { basename as basename10, dirname as dirname19, join as join35, resolve as resolve15 } from "node:path";
46166
46526
  import {
46167
46527
  getCanonicalTemplatesTildePath as _getCanonicalTemplatesTildePath,
46168
46528
  getCleoTemplatesTildePath as _getCleoTemplatesTildePath,
@@ -46172,7 +46532,7 @@ import {
46172
46532
  resolveCanonicalCleoDir as _resolveCanonicalCleoDir
46173
46533
  } from "@cleocode/paths";
46174
46534
  function _getDatabaseSyncCtor() {
46175
- const _require7 = createRequire10(import.meta.url);
46535
+ const _require7 = createRequire11(import.meta.url);
46176
46536
  const mod = _require7("node:sqlite");
46177
46537
  return mod.DatabaseSync;
46178
46538
  }
@@ -46184,20 +46544,20 @@ function runWithWorktreeScopeFromEnv(fn) {
46184
46544
  }
46185
46545
  function isProjectInitialized(projectRoot) {
46186
46546
  const root = projectRoot ?? getProjectRoot();
46187
- const cleoDir = join34(root, ".cleo");
46188
- return existsSync31(cleoDir) && existsSync31(join34(cleoDir, "tasks.db"));
46547
+ const cleoDir = join35(root, ".cleo");
46548
+ return existsSync32(cleoDir) && existsSync32(join35(cleoDir, "tasks.db"));
46189
46549
  }
46190
46550
  function getCleoHome() {
46191
46551
  return getPlatformPaths().data;
46192
46552
  }
46193
46553
  function getCleoTemplatesDir() {
46194
- return join34(getCleoHome(), "templates");
46554
+ return join35(getCleoHome(), "templates");
46195
46555
  }
46196
46556
  function getCleoSchemasDir() {
46197
- return join34(getCleoHome(), "schemas");
46557
+ return join35(getCleoHome(), "schemas");
46198
46558
  }
46199
46559
  function getCleoDocsDir() {
46200
- return join34(getCleoHome(), "docs");
46560
+ return join35(getCleoHome(), "docs");
46201
46561
  }
46202
46562
  function getCleoDir(cwd) {
46203
46563
  if (cwd) {
@@ -46246,24 +46606,24 @@ function getCleoDirAbsolute(cwd, opts) {
46246
46606
  try {
46247
46607
  const projectRoot = getProjectRoot(cwd);
46248
46608
  const canonical = _resolveCanonicalCleoDir(project.projectId);
46249
- if (canonical !== null && canonical === resolve13(projectRoot, cleoDir)) {
46609
+ if (canonical !== null && canonical === resolve15(projectRoot, cleoDir)) {
46250
46610
  return canonical;
46251
46611
  }
46252
- return resolve13(projectRoot, cleoDir);
46612
+ return resolve15(projectRoot, cleoDir);
46253
46613
  } catch {
46254
- return resolve13(project.projectRoot, cleoDir);
46614
+ return resolve15(project.projectRoot, cleoDir);
46255
46615
  }
46256
46616
  }
46257
46617
  try {
46258
- return resolve13(getProjectRoot(cwd), cleoDir);
46618
+ return resolve15(getProjectRoot(cwd), cleoDir);
46259
46619
  } catch (err) {
46260
46620
  if (opts?.bootstrap) {
46261
- return resolve13(cwd ?? process.cwd(), cleoDir);
46621
+ return resolve15(cwd ?? process.cwd(), cleoDir);
46262
46622
  }
46263
46623
  if (_cwdHasGitAncestor(cwd)) {
46264
46624
  throw err;
46265
46625
  }
46266
- return resolve13(cwd ?? process.cwd(), cleoDir);
46626
+ return resolve15(cwd ?? process.cwd(), cleoDir);
46267
46627
  }
46268
46628
  }
46269
46629
  function resolveCanonicalCleoDir(projectId) {
@@ -46290,9 +46650,9 @@ function resolveCanonicalCleoDir(projectId) {
46290
46650
  function _resolveProjectByCwdFromNexus(cwd) {
46291
46651
  try {
46292
46652
  const cleoHome = getCleoHome();
46293
- const globalDbPath = join34(cleoHome, "cleo.db");
46294
- if (!existsSync31(globalDbPath)) return null;
46295
- const start = resolve13(cwd ?? process.cwd());
46653
+ const globalDbPath = join35(cleoHome, "cleo.db");
46654
+ if (!existsSync32(globalDbPath)) return null;
46655
+ const start = resolve15(cwd ?? process.cwd());
46296
46656
  let current = start;
46297
46657
  const DatabaseSync3 = _getDatabaseSyncCtor();
46298
46658
  const db = new DatabaseSync3(globalDbPath, { readOnly: true });
@@ -46305,7 +46665,7 @@ function _resolveProjectByCwdFromNexus(cwd) {
46305
46665
  if (row && typeof row.project_id === "string" && row.project_id.length > 0) {
46306
46666
  return row.project_id;
46307
46667
  }
46308
- const parent = dirname17(current);
46668
+ const parent = dirname19(current);
46309
46669
  if (parent === current) break;
46310
46670
  current = parent;
46311
46671
  }
@@ -46325,18 +46685,18 @@ function _cleoDirEnvOverride() {
46325
46685
  }
46326
46686
  function _findCleoDirRoot(cwd) {
46327
46687
  const homeRoot = homedir2();
46328
- let current = resolve13(cwd ?? process.cwd());
46688
+ let current = resolve15(cwd ?? process.cwd());
46329
46689
  while (true) {
46330
46690
  const isDangerousRoot = current === homeRoot || current === "/" || current === "";
46331
46691
  if (!isDangerousRoot) {
46332
46692
  try {
46333
- if (statSync9(join34(current, ".cleo")).isDirectory()) {
46693
+ if (statSync9(join35(current, ".cleo")).isDirectory()) {
46334
46694
  return current;
46335
46695
  }
46336
46696
  } catch {
46337
46697
  }
46338
46698
  }
46339
- const parent = dirname17(current);
46699
+ const parent = dirname19(current);
46340
46700
  if (parent === current) break;
46341
46701
  current = parent;
46342
46702
  }
@@ -46355,7 +46715,7 @@ function resolveProjectByCwd(cwd) {
46355
46715
  if (pathsResult !== null) {
46356
46716
  return pathsResult.projectId;
46357
46717
  }
46358
- const start = resolve13(from ?? process.cwd());
46718
+ const start = resolve15(from ?? process.cwd());
46359
46719
  let current = start;
46360
46720
  while (true) {
46361
46721
  const mainRepo = _resolveMainRepoFromGitlink(current);
@@ -46366,7 +46726,7 @@ function resolveProjectByCwd(cwd) {
46366
46726
  }
46367
46727
  break;
46368
46728
  }
46369
- const parent = dirname17(current);
46729
+ const parent = dirname19(current);
46370
46730
  if (parent === current) break;
46371
46731
  current = parent;
46372
46732
  }
@@ -46385,7 +46745,7 @@ function resolveProjectByCwd(cwd) {
46385
46745
  function resolveCleoDir(cwd) {
46386
46746
  const scope = worktreeScope.getStore();
46387
46747
  if (scope !== void 0) {
46388
- return join34(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
46748
+ return join35(resolveStoreOwnerRoot(scope.worktreeRoot), ".cleo");
46389
46749
  }
46390
46750
  const override = _cleoDirEnvOverride();
46391
46751
  if (override !== null) {
@@ -46393,16 +46753,16 @@ function resolveCleoDir(cwd) {
46393
46753
  }
46394
46754
  const root = _findCleoDirRoot(cwd);
46395
46755
  if (root !== null) {
46396
- return join34(resolveStoreOwnerRoot(root), ".cleo");
46756
+ return join35(resolveStoreOwnerRoot(root), ".cleo");
46397
46757
  }
46398
- const start = resolve13(cwd ?? process.cwd());
46758
+ const start = resolve15(cwd ?? process.cwd());
46399
46759
  let current = start;
46400
46760
  while (true) {
46401
46761
  const mainRepo = _resolveMainRepoFromGitlink(current);
46402
46762
  if (mainRepo !== null) {
46403
- return join34(mainRepo, ".cleo");
46763
+ return join35(mainRepo, ".cleo");
46404
46764
  }
46405
- const parent = dirname17(current);
46765
+ const parent = dirname19(current);
46406
46766
  if (parent === current) {
46407
46767
  break;
46408
46768
  }
@@ -46441,25 +46801,25 @@ function _resolveCleoDir(cwd) {
46441
46801
  const project = _pathsResolveProjectByCwd(cwd);
46442
46802
  if (project !== null) {
46443
46803
  try {
46444
- return resolve13(getProjectRoot(cwd), cleoDir);
46804
+ return resolve15(getProjectRoot(cwd), cleoDir);
46445
46805
  } catch {
46446
- return resolve13(project.projectRoot, cleoDir);
46806
+ return resolve15(project.projectRoot, cleoDir);
46447
46807
  }
46448
46808
  }
46449
46809
  return getCleoDirAbsolute(cwd);
46450
46810
  }
46451
46811
  function _cwdHasGitAncestor(cwd) {
46452
- const start = resolve13(cwd ?? process.cwd());
46812
+ const start = resolve15(cwd ?? process.cwd());
46453
46813
  let current = start;
46454
46814
  while (true) {
46455
- const gitMarker = join34(current, ".git");
46815
+ const gitMarker = join35(current, ".git");
46456
46816
  try {
46457
- if (existsSync31(gitMarker)) {
46817
+ if (existsSync32(gitMarker)) {
46458
46818
  return true;
46459
46819
  }
46460
46820
  } catch {
46461
46821
  }
46462
- const parent = dirname17(current);
46822
+ const parent = dirname19(current);
46463
46823
  if (parent === current) return false;
46464
46824
  current = parent;
46465
46825
  }
@@ -46486,55 +46846,55 @@ function resolveProjectPath(relativePath, cwd) {
46486
46846
  return relativePath;
46487
46847
  }
46488
46848
  if (relativePath.startsWith("~/") || relativePath.startsWith("~\\") || relativePath === "~") {
46489
- return resolve13(homedir2(), relativePath.slice(2));
46849
+ return resolve15(homedir2(), relativePath.slice(2));
46490
46850
  }
46491
- return resolve13(getProjectRoot(cwd), relativePath);
46851
+ return resolve15(getProjectRoot(cwd), relativePath);
46492
46852
  }
46493
46853
  function getTaskPath(cwd) {
46494
- return join34(_resolveCleoDir(cwd), "tasks.db");
46854
+ return join35(_resolveCleoDir(cwd), "tasks.db");
46495
46855
  }
46496
46856
  function getConfigPath(cwd) {
46497
- return join34(_resolveCleoDir(cwd), "config.json");
46857
+ return join35(_resolveCleoDir(cwd), "config.json");
46498
46858
  }
46499
46859
  function getSessionsPath(cwd) {
46500
- return join34(_resolveCleoDir(cwd), "sessions.json");
46860
+ return join35(_resolveCleoDir(cwd), "sessions.json");
46501
46861
  }
46502
46862
  function getArchivePath(cwd) {
46503
- return join34(_resolveCleoDir(cwd), "tasks-archive.json");
46863
+ return join35(_resolveCleoDir(cwd), "tasks-archive.json");
46504
46864
  }
46505
46865
  function getLogPath(cwd) {
46506
- return join34(_resolveCleoDir(cwd), "logs", "cleo.log");
46866
+ return join35(_resolveCleoDir(cwd), "logs", "cleo.log");
46507
46867
  }
46508
46868
  function getBackupDir(cwd) {
46509
- return join34(_resolveCleoDir(cwd), "backups", "operational");
46869
+ return join35(_resolveCleoDir(cwd), "backups", "operational");
46510
46870
  }
46511
46871
  function getGlobalConfigPath() {
46512
- return join34(getCleoHome(), "config.json");
46872
+ return join35(getCleoHome(), "config.json");
46513
46873
  }
46514
46874
  function getCleoGlobalRecipesDir() {
46515
- return join34(getCleoHome(), "global-recipes");
46875
+ return join35(getCleoHome(), "global-recipes");
46516
46876
  }
46517
46877
  function getCleoGlobalJustfilePath() {
46518
- return join34(getCleoGlobalRecipesDir(), "justfile");
46878
+ return join35(getCleoGlobalRecipesDir(), "justfile");
46519
46879
  }
46520
46880
  function getCleoPiExtensionsDir() {
46521
- return join34(getCleoHome(), "pi-extensions");
46881
+ return join35(getCleoHome(), "pi-extensions");
46522
46882
  }
46523
46883
  function getCleoCantWorkflowsDir() {
46524
- return join34(getCleoHome(), "cant-workflows");
46884
+ return join35(getCleoHome(), "cant-workflows");
46525
46885
  }
46526
46886
  function getCleoGlobalAgentsDir() {
46527
- return join34(getCleoHome(), "agents");
46887
+ return join35(getCleoHome(), "agents");
46528
46888
  }
46529
46889
  function getCleoGlobalCantAgentsDir() {
46530
- return join34(getCleoHome(), "cant", "agents");
46890
+ return join35(getCleoHome(), "cant", "agents");
46531
46891
  }
46532
46892
  function getAgentOutputsDir(cwd) {
46533
46893
  const projectRoot = getProjectRoot(cwd);
46534
- const configPath = join34(projectRoot, ".cleo", "config.json");
46535
- if (existsSync31(configPath)) {
46894
+ const configPath = join35(projectRoot, ".cleo", "config.json");
46895
+ if (existsSync32(configPath)) {
46536
46896
  try {
46537
- const config = JSON.parse(readFileSync10(configPath, "utf-8"));
46897
+ const config = JSON.parse(readFileSync11(configPath, "utf-8"));
46538
46898
  if (typeof config.agentOutputs === "object" && config.agentOutputs?.directory) {
46539
46899
  return config.agentOutputs.directory;
46540
46900
  }
@@ -46557,17 +46917,17 @@ function getAgentOutputsAbsolute(cwd) {
46557
46917
  if (isAbsolutePath2(dir)) {
46558
46918
  return dir;
46559
46919
  }
46560
- return resolve13(getProjectRoot(cwd), dir);
46920
+ return resolve15(getProjectRoot(cwd), dir);
46561
46921
  }
46562
46922
  function getManifestPath(cwd) {
46563
46923
  const outputDir = getAgentOutputsDir(cwd);
46564
46924
  const projectRoot = getProjectRoot(cwd);
46565
- const configPath = join34(projectRoot, ".cleo", "config.json");
46925
+ const configPath = join35(projectRoot, ".cleo", "config.json");
46566
46926
  const legacyFileName = ["MANIFEST", "jsonl"].join(".");
46567
46927
  let manifestFile = legacyFileName;
46568
- if (existsSync31(configPath)) {
46928
+ if (existsSync32(configPath)) {
46569
46929
  try {
46570
- const config = JSON.parse(readFileSync10(configPath, "utf-8"));
46930
+ const config = JSON.parse(readFileSync11(configPath, "utf-8"));
46571
46931
  const customFile = config.agentOutputs?.manifestFile ?? config.research?.manifestFile;
46572
46932
  if (customFile) {
46573
46933
  manifestFile = customFile;
@@ -46575,12 +46935,12 @@ function getManifestPath(cwd) {
46575
46935
  } catch {
46576
46936
  }
46577
46937
  }
46578
- return resolve13(projectRoot, outputDir, manifestFile);
46938
+ return resolve15(projectRoot, outputDir, manifestFile);
46579
46939
  }
46580
46940
  function getManifestArchivePath(cwd) {
46581
46941
  const outputDir = getAgentOutputsDir(cwd);
46582
46942
  const projectRoot = getProjectRoot(cwd);
46583
- return resolve13(projectRoot, outputDir, "MANIFEST.archive.jsonl");
46943
+ return resolve15(projectRoot, outputDir, "MANIFEST.archive.jsonl");
46584
46944
  }
46585
46945
  function isAbsolutePath2(path2) {
46586
46946
  return _isAbsolutePath(path2);
@@ -46604,24 +46964,24 @@ function getCanonicalTemplatesTildePath() {
46604
46964
  return _getCanonicalTemplatesTildePath();
46605
46965
  }
46606
46966
  function getAgentsHome() {
46607
- return process.env["AGENTS_HOME"] ?? join34(homedir2(), ".agents");
46967
+ return process.env["AGENTS_HOME"] ?? join35(homedir2(), ".agents");
46608
46968
  }
46609
46969
  function getClaudeAgentsDir() {
46610
- const claudeDir = process.env["CLAUDE_HOME"] ?? join34(homedir2(), ".claude");
46611
- return join34(claudeDir, "agents");
46970
+ const claudeDir = process.env["CLAUDE_HOME"] ?? join35(homedir2(), ".claude");
46971
+ return join35(claudeDir, "agents");
46612
46972
  }
46613
46973
  function getClaudeMemDbPath() {
46614
- return process.env["CLAUDE_MEM_DB"] ?? join34(homedir2(), ".claude-mem", "claude-mem.db");
46974
+ return process.env["CLAUDE_MEM_DB"] ?? join35(homedir2(), ".claude-mem", "claude-mem.db");
46615
46975
  }
46616
46976
  function resolveWorktreeRouting(cwdOverride) {
46617
- const cwd = resolve13(cwdOverride ?? process.cwd());
46977
+ const cwd = resolve15(cwdOverride ?? process.cwd());
46618
46978
  const home = homedir2();
46619
46979
  let worktreePath;
46620
46980
  let current = cwd;
46621
46981
  while (current !== home && current !== "/" && current !== "") {
46622
- const gitPath = join34(current, ".git");
46982
+ const gitPath = join35(current, ".git");
46623
46983
  try {
46624
- if (existsSync31(gitPath)) {
46984
+ if (existsSync32(gitPath)) {
46625
46985
  const stat3 = statSync9(gitPath);
46626
46986
  if (stat3.isFile()) {
46627
46987
  worktreePath = current;
@@ -46633,7 +46993,7 @@ function resolveWorktreeRouting(cwdOverride) {
46633
46993
  }
46634
46994
  } catch {
46635
46995
  }
46636
- const parent = dirname17(current);
46996
+ const parent = dirname19(current);
46637
46997
  if (parent === current) break;
46638
46998
  current = parent;
46639
46999
  }
@@ -46650,17 +47010,17 @@ function resolveWorktreeRouting(cwdOverride) {
46650
47010
  }
46651
47011
  function resolveWorktreeFilePath(filePath, routing) {
46652
47012
  if (!routing.isWorktree || routing.worktreePath === void 0) {
46653
- return resolve13(filePath);
47013
+ return resolve15(filePath);
46654
47014
  }
46655
- return resolve13(routing.cwd, filePath);
47015
+ return resolve15(routing.cwd, filePath);
46656
47016
  }
46657
47017
  function detectStrayCleoDb(routing) {
46658
47018
  if (!routing.isWorktree || routing.worktreePath === void 0) {
46659
47019
  return void 0;
46660
47020
  }
46661
- const tasksDbPath = join34(routing.worktreePath, ".cleo", "tasks.db");
47021
+ const tasksDbPath = join35(routing.worktreePath, ".cleo", "tasks.db");
46662
47022
  try {
46663
- if (existsSync31(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
47023
+ if (existsSync32(tasksDbPath) && statSync9(tasksDbPath).isFile()) {
46664
47024
  return tasksDbPath;
46665
47025
  }
46666
47026
  } catch {
@@ -46670,7 +47030,7 @@ function detectStrayCleoDb(routing) {
46670
47030
  async function resolveProjectById(projectId) {
46671
47031
  try {
46672
47032
  const { getNexusDb: getNexusDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
46673
- if (!existsSync31(getNexusRegistryDbPath2())) return null;
47033
+ if (!existsSync32(getNexusRegistryDbPath2())) return null;
46674
47034
  const { eq: eq14 } = await import("drizzle-orm");
46675
47035
  const { projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
46676
47036
  const db = await getNexusDb2();
@@ -46705,9 +47065,9 @@ function _rowToRegistryEntry(row) {
46705
47065
  };
46706
47066
  }
46707
47067
  function _readProjectNameFromInfo(projectRoot) {
46708
- const infoPath = join34(projectRoot, ".cleo", "project-info.json");
46709
- if (!existsSync31(infoPath)) return void 0;
46710
- const raw = readFileSync10(infoPath, "utf-8");
47068
+ const infoPath = join35(projectRoot, ".cleo", "project-info.json");
47069
+ if (!existsSync32(infoPath)) return void 0;
47070
+ const raw = readFileSync11(infoPath, "utf-8");
46711
47071
  const data = JSON.parse(raw);
46712
47072
  return typeof data.name === "string" && data.name.length > 0 ? data.name : void 0;
46713
47073
  }
@@ -46758,7 +47118,7 @@ async function recordProjectEncounter(cwd) {
46758
47118
  if (!shouldAutoRegisterProject(project.projectRoot, cleoHome)) return "ephemeral";
46759
47119
  const checkout = captureProjectScope(project.projectRoot, worktreeScope.getStore()).worktreeRoot;
46760
47120
  const { getNexusRegistryDb: getNexusRegistryDb2, getNexusRegistryDbPath: getNexusRegistryDbPath2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
46761
- if (existsSync31(getNexusRegistryDbPath2(cleoHome))) {
47121
+ if (existsSync32(getNexusRegistryDbPath2(cleoHome))) {
46762
47122
  const { and: and10, eq: eq14 } = await import("drizzle-orm");
46763
47123
  const { projectLocations: projectLocations2, projectRegistry: projectRegistry2 } = await Promise.resolve().then(() => (init_nexus_schema(), nexus_schema_exports));
46764
47124
  const { currentDeviceId: currentDeviceId2 } = await Promise.resolve().then(() => (init_path_map(), path_map_exports));