@cleocode/core 2026.9.26 → 2026.10.2

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 (410) hide show
  1. package/dist/build-provenance.json +2 -2
  2. package/dist/cloud/journal.d.ts +9 -5
  3. package/dist/cloud/journal.d.ts.map +1 -1
  4. package/dist/cloud/journal.js +29 -8
  5. package/dist/cloud/journal.js.map +1 -1
  6. package/dist/cloud/manifest-check.d.ts +140 -4
  7. package/dist/cloud/manifest-check.d.ts.map +1 -1
  8. package/dist/cloud/manifest-check.js +309 -10
  9. package/dist/cloud/manifest-check.js.map +1 -1
  10. package/dist/cloud/nexus-attach.d.ts +119 -0
  11. package/dist/cloud/nexus-attach.d.ts.map +1 -0
  12. package/dist/cloud/nexus-attach.js +267 -0
  13. package/dist/cloud/nexus-attach.js.map +1 -0
  14. package/dist/cloud/nexus-auth.d.ts +15 -3
  15. package/dist/cloud/nexus-auth.d.ts.map +1 -1
  16. package/dist/cloud/nexus-auth.js +90 -6
  17. package/dist/cloud/nexus-auth.js.map +1 -1
  18. package/dist/cloud/nexus-cloud-activity.d.ts +37 -0
  19. package/dist/cloud/nexus-cloud-activity.d.ts.map +1 -0
  20. package/dist/cloud/nexus-cloud-activity.js +79 -0
  21. package/dist/cloud/nexus-cloud-activity.js.map +1 -0
  22. package/dist/cloud/nexus-cloud-status.d.ts +132 -0
  23. package/dist/cloud/nexus-cloud-status.d.ts.map +1 -0
  24. package/dist/cloud/nexus-cloud-status.js +476 -0
  25. package/dist/cloud/nexus-cloud-status.js.map +1 -0
  26. package/dist/cloud/nexus-cloud.d.ts +179 -0
  27. package/dist/cloud/nexus-cloud.d.ts.map +1 -0
  28. package/dist/cloud/nexus-cloud.js +296 -0
  29. package/dist/cloud/nexus-cloud.js.map +1 -0
  30. package/dist/cloud/nexus-device.d.ts +32 -7
  31. package/dist/cloud/nexus-device.d.ts.map +1 -1
  32. package/dist/cloud/nexus-device.js +54 -7
  33. package/dist/cloud/nexus-device.js.map +1 -1
  34. package/dist/cloud/nexus-enrol.d.ts +35 -4
  35. package/dist/cloud/nexus-enrol.d.ts.map +1 -1
  36. package/dist/cloud/nexus-enrol.js +192 -47
  37. package/dist/cloud/nexus-enrol.js.map +1 -1
  38. package/dist/cloud/nexus-home.d.ts +74 -0
  39. package/dist/cloud/nexus-home.d.ts.map +1 -0
  40. package/dist/cloud/nexus-home.js +97 -0
  41. package/dist/cloud/nexus-home.js.map +1 -0
  42. package/dist/cloud/nexus-link.d.ts +8 -1
  43. package/dist/cloud/nexus-link.d.ts.map +1 -1
  44. package/dist/cloud/nexus-link.js +138 -11
  45. package/dist/cloud/nexus-link.js.map +1 -1
  46. package/dist/cloud/nexus-logout.d.ts +114 -0
  47. package/dist/cloud/nexus-logout.d.ts.map +1 -0
  48. package/dist/cloud/nexus-logout.js +429 -0
  49. package/dist/cloud/nexus-logout.js.map +1 -0
  50. package/dist/cloud/nexus-vault-keys.d.ts +129 -0
  51. package/dist/cloud/nexus-vault-keys.d.ts.map +1 -0
  52. package/dist/cloud/nexus-vault-keys.js +277 -0
  53. package/dist/cloud/nexus-vault-keys.js.map +1 -0
  54. package/dist/cloud/nexus-vault-state.d.ts +121 -0
  55. package/dist/cloud/nexus-vault-state.d.ts.map +1 -0
  56. package/dist/cloud/nexus-vault-state.js +274 -0
  57. package/dist/cloud/nexus-vault-state.js.map +1 -0
  58. package/dist/cloud/nexus-vault.d.ts +160 -0
  59. package/dist/cloud/nexus-vault.d.ts.map +1 -0
  60. package/dist/cloud/nexus-vault.js +1733 -0
  61. package/dist/cloud/nexus-vault.js.map +1 -0
  62. package/dist/cloud/signing.d.ts +24 -8
  63. package/dist/cloud/signing.d.ts.map +1 -1
  64. package/dist/cloud/signing.js +61 -15
  65. package/dist/cloud/signing.js.map +1 -1
  66. package/dist/docs/export-document.js +8341 -3317
  67. package/dist/docs/export-document.js.map +3 -3
  68. package/dist/doctor/migrations.d.ts +75 -0
  69. package/dist/doctor/migrations.d.ts.map +1 -0
  70. package/dist/doctor/migrations.js +136 -0
  71. package/dist/doctor/migrations.js.map +1 -0
  72. package/dist/doctor/sync-sealer.d.ts +48 -0
  73. package/dist/doctor/sync-sealer.d.ts.map +1 -0
  74. package/dist/doctor/sync-sealer.js +109 -0
  75. package/dist/doctor/sync-sealer.js.map +1 -0
  76. package/dist/doctor/sync-triggers.d.ts +53 -0
  77. package/dist/doctor/sync-triggers.d.ts.map +1 -0
  78. package/dist/doctor/sync-triggers.js +157 -0
  79. package/dist/doctor/sync-triggers.js.map +1 -0
  80. package/dist/init.d.ts.map +1 -1
  81. package/dist/init.js +5 -1
  82. package/dist/init.js.map +1 -1
  83. package/dist/internal.d.ts +1 -1
  84. package/dist/internal.d.ts.map +1 -1
  85. package/dist/internal.js +1 -1
  86. package/dist/internal.js.map +1 -1
  87. package/dist/llm/plugin-facade.js +8668 -3644
  88. package/dist/llm/plugin-facade.js.map +3 -3
  89. package/dist/nexus/projects-clean.d.ts +3 -0
  90. package/dist/nexus/projects-clean.d.ts.map +1 -1
  91. package/dist/nexus/projects-clean.js +9 -3
  92. package/dist/nexus/projects-clean.js.map +1 -1
  93. package/dist/nexus/registry-roots.d.ts +3 -1
  94. package/dist/nexus/registry-roots.d.ts.map +1 -1
  95. package/dist/nexus/registry-roots.js +5 -2
  96. package/dist/nexus/registry-roots.js.map +1 -1
  97. package/dist/nexus/registry.d.ts +8 -1
  98. package/dist/nexus/registry.d.ts.map +1 -1
  99. package/dist/nexus/registry.js +24 -10
  100. package/dist/nexus/registry.js.map +1 -1
  101. package/dist/nexus/workspace.d.ts +4 -1
  102. package/dist/nexus/workspace.d.ts.map +1 -1
  103. package/dist/nexus/workspace.js +10 -4
  104. package/dist/nexus/workspace.js.map +1 -1
  105. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  106. package/dist/orchestrate/spawn-ops.js +7 -2
  107. package/dist/orchestrate/spawn-ops.js.map +1 -1
  108. package/dist/orchestrate/worker-verify.d.ts +121 -12
  109. package/dist/orchestrate/worker-verify.d.ts.map +1 -1
  110. package/dist/orchestrate/worker-verify.js +172 -21
  111. package/dist/orchestrate/worker-verify.js.map +1 -1
  112. package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
  113. package/dist/orchestration/spawn-prompt.js +15 -9
  114. package/dist/orchestration/spawn-prompt.js.map +1 -1
  115. package/dist/release/ci-evidence.d.ts +9 -0
  116. package/dist/release/ci-evidence.d.ts.map +1 -1
  117. package/dist/release/ci-evidence.js +9 -2
  118. package/dist/release/ci-evidence.js.map +1 -1
  119. package/dist/resources/backend.d.ts +15 -3
  120. package/dist/resources/backend.d.ts.map +1 -1
  121. package/dist/resources/backend.js +7 -3
  122. package/dist/resources/backend.js.map +1 -1
  123. package/dist/resources/darwin-backend.d.ts +142 -0
  124. package/dist/resources/darwin-backend.d.ts.map +1 -0
  125. package/dist/resources/darwin-backend.js +288 -0
  126. package/dist/resources/darwin-backend.js.map +1 -0
  127. package/dist/resources/governor.d.ts +44 -1
  128. package/dist/resources/governor.d.ts.map +1 -1
  129. package/dist/resources/governor.js +100 -36
  130. package/dist/resources/governor.js.map +1 -1
  131. package/dist/resources/heavy-command.d.ts +132 -0
  132. package/dist/resources/heavy-command.d.ts.map +1 -0
  133. package/dist/resources/heavy-command.js +768 -0
  134. package/dist/resources/heavy-command.js.map +1 -0
  135. package/dist/resources/monitor.d.ts +50 -1
  136. package/dist/resources/monitor.d.ts.map +1 -1
  137. package/dist/resources/monitor.js +83 -1
  138. package/dist/resources/monitor.js.map +1 -1
  139. package/dist/resources/run-admission.d.ts +303 -0
  140. package/dist/resources/run-admission.d.ts.map +1 -0
  141. package/dist/resources/run-admission.js +648 -0
  142. package/dist/resources/run-admission.js.map +1 -0
  143. package/dist/resources/run-class.d.ts +111 -0
  144. package/dist/resources/run-class.d.ts.map +1 -0
  145. package/dist/resources/run-class.js +658 -0
  146. package/dist/resources/run-class.js.map +1 -0
  147. package/dist/resources/run-governed.d.ts +158 -0
  148. package/dist/resources/run-governed.d.ts.map +1 -0
  149. package/dist/resources/run-governed.js +406 -0
  150. package/dist/resources/run-governed.js.map +1 -0
  151. package/dist/resources/slot-holder.d.ts +267 -0
  152. package/dist/resources/slot-holder.d.ts.map +1 -0
  153. package/dist/resources/slot-holder.js +505 -0
  154. package/dist/resources/slot-holder.js.map +1 -0
  155. package/dist/resources/tool-groups.d.ts +74 -0
  156. package/dist/resources/tool-groups.d.ts.map +1 -0
  157. package/dist/resources/tool-groups.js +118 -0
  158. package/dist/resources/tool-groups.js.map +1 -0
  159. package/dist/routing/build-command-groups.d.ts.map +1 -1
  160. package/dist/routing/build-command-groups.js +1 -0
  161. package/dist/routing/build-command-groups.js.map +1 -1
  162. package/dist/selfimprove/fix-gen.js +8676 -3652
  163. package/dist/selfimprove/fix-gen.js.map +3 -3
  164. package/dist/sentient/cross-project-hygiene.d.ts +3 -2
  165. package/dist/sentient/cross-project-hygiene.d.ts.map +1 -1
  166. package/dist/sentient/cross-project-hygiene.js +5 -2
  167. package/dist/sentient/cross-project-hygiene.js.map +1 -1
  168. package/dist/sentient/state.d.ts +7 -0
  169. package/dist/sentient/state.d.ts.map +1 -1
  170. package/dist/sentient/state.js.map +1 -1
  171. package/dist/sentient/tick.d.ts +14 -2
  172. package/dist/sentient/tick.d.ts.map +1 -1
  173. package/dist/sentient/tick.js +63 -4
  174. package/dist/sentient/tick.js.map +1 -1
  175. package/dist/setup/sections/nexus-account.d.ts +8 -6
  176. package/dist/setup/sections/nexus-account.d.ts.map +1 -1
  177. package/dist/setup/sections/nexus-account.js +53 -9
  178. package/dist/setup/sections/nexus-account.js.map +1 -1
  179. package/dist/store/backup-recover.d.ts.map +1 -1
  180. package/dist/store/backup-recover.js +5 -0
  181. package/dist/store/backup-recover.js.map +1 -1
  182. package/dist/store/data-accessor.d.ts +1 -0
  183. package/dist/store/data-accessor.d.ts.map +1 -1
  184. package/dist/store/data-accessor.js +7 -0
  185. package/dist/store/data-accessor.js.map +1 -1
  186. package/dist/store/dual-scope-db.d.ts +23 -1
  187. package/dist/store/dual-scope-db.d.ts.map +1 -1
  188. package/dist/store/dual-scope-db.js +126 -36
  189. package/dist/store/dual-scope-db.js.map +1 -1
  190. package/dist/store/exodus/recovery.d.ts.map +1 -1
  191. package/dist/store/exodus/recovery.js +15 -0
  192. package/dist/store/exodus/recovery.js.map +1 -1
  193. package/dist/store/legacy-tasks-lineage.d.ts.map +1 -1
  194. package/dist/store/legacy-tasks-lineage.js +5 -0
  195. package/dist/store/legacy-tasks-lineage.js.map +1 -1
  196. package/dist/store/lock.d.ts +8 -1
  197. package/dist/store/lock.d.ts.map +1 -1
  198. package/dist/store/lock.js +10 -2
  199. package/dist/store/lock.js.map +1 -1
  200. package/dist/store/migration-manager.d.ts +5 -0
  201. package/dist/store/migration-manager.d.ts.map +1 -1
  202. package/dist/store/migration-manager.js +11 -0
  203. package/dist/store/migration-manager.js.map +1 -1
  204. package/dist/store/migration-runner.d.ts +158 -0
  205. package/dist/store/migration-runner.d.ts.map +1 -0
  206. package/dist/store/migration-runner.js +493 -0
  207. package/dist/store/migration-runner.js.map +1 -0
  208. package/dist/store/portable-bundle-import.d.ts +15 -1
  209. package/dist/store/portable-bundle-import.d.ts.map +1 -1
  210. package/dist/store/portable-bundle-import.js +24 -4
  211. package/dist/store/portable-bundle-import.js.map +1 -1
  212. package/dist/store/portable-bundle-relocate.d.ts +43 -0
  213. package/dist/store/portable-bundle-relocate.d.ts.map +1 -1
  214. package/dist/store/portable-bundle-relocate.js +79 -5
  215. package/dist/store/portable-bundle-relocate.js.map +1 -1
  216. package/dist/store/portable-bundle-scan.d.ts +20 -0
  217. package/dist/store/portable-bundle-scan.d.ts.map +1 -1
  218. package/dist/store/portable-bundle-scan.js +38 -3
  219. package/dist/store/portable-bundle-scan.js.map +1 -1
  220. package/dist/store/portable-bundle.d.ts +33 -0
  221. package/dist/store/portable-bundle.d.ts.map +1 -1
  222. package/dist/store/portable-bundle.js +34 -7
  223. package/dist/store/portable-bundle.js.map +1 -1
  224. package/dist/store/row-identity-registry.d.ts +137 -7
  225. package/dist/store/row-identity-registry.d.ts.map +1 -1
  226. package/dist/store/row-identity-registry.js +364 -9
  227. package/dist/store/row-identity-registry.js.map +1 -1
  228. package/dist/store/row-identity.d.ts.map +1 -1
  229. package/dist/store/row-identity.js +9 -10
  230. package/dist/store/row-identity.js.map +1 -1
  231. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  232. package/dist/store/sqlite-data-accessor.js +10 -0
  233. package/dist/store/sqlite-data-accessor.js.map +1 -1
  234. package/dist/store/sqlite.d.ts +31 -0
  235. package/dist/store/sqlite.d.ts.map +1 -1
  236. package/dist/store/sqlite.js +5 -1
  237. package/dist/store/sqlite.js.map +1 -1
  238. package/dist/store/sync/capture.d.ts +203 -0
  239. package/dist/store/sync/capture.d.ts.map +1 -0
  240. package/dist/store/sync/capture.js +562 -0
  241. package/dist/store/sync/capture.js.map +1 -0
  242. package/dist/store/sync/clock-store.d.ts.map +1 -1
  243. package/dist/store/sync/clock-store.js +2 -0
  244. package/dist/store/sync/clock-store.js.map +1 -1
  245. package/dist/store/sync/fk-orphans.d.ts +133 -0
  246. package/dist/store/sync/fk-orphans.d.ts.map +1 -0
  247. package/dist/store/sync/fk-orphans.js +265 -0
  248. package/dist/store/sync/fk-orphans.js.map +1 -0
  249. package/dist/store/sync/flags.d.ts +7 -0
  250. package/dist/store/sync/flags.d.ts.map +1 -1
  251. package/dist/store/sync/flags.js +16 -0
  252. package/dist/store/sync/flags.js.map +1 -1
  253. package/dist/store/sync/hlc.d.ts.map +1 -1
  254. package/dist/store/sync/hlc.js +4 -0
  255. package/dist/store/sync/hlc.js.map +1 -1
  256. package/dist/store/sync/identity-fill.d.ts +45 -0
  257. package/dist/store/sync/identity-fill.d.ts.map +1 -0
  258. package/dist/store/sync/identity-fill.js +85 -0
  259. package/dist/store/sync/identity-fill.js.map +1 -0
  260. package/dist/store/sync/machinery.d.ts +27 -0
  261. package/dist/store/sync/machinery.d.ts.map +1 -0
  262. package/dist/store/sync/machinery.js +44 -0
  263. package/dist/store/sync/machinery.js.map +1 -0
  264. package/dist/store/sync/netting.d.ts +120 -0
  265. package/dist/store/sync/netting.d.ts.map +1 -0
  266. package/dist/store/sync/netting.js +336 -0
  267. package/dist/store/sync/netting.js.map +1 -0
  268. package/dist/store/sync/replica.d.ts +59 -3
  269. package/dist/store/sync/replica.d.ts.map +1 -1
  270. package/dist/store/sync/replica.js +84 -3
  271. package/dist/store/sync/replica.js.map +1 -1
  272. package/dist/store/sync/schema.d.ts +18 -3
  273. package/dist/store/sync/schema.d.ts.map +1 -1
  274. package/dist/store/sync/schema.js +27 -3
  275. package/dist/store/sync/schema.js.map +1 -1
  276. package/dist/store/sync/seal-backlog.d.ts +21 -0
  277. package/dist/store/sync/seal-backlog.d.ts.map +1 -0
  278. package/dist/store/sync/seal-backlog.js +24 -0
  279. package/dist/store/sync/seal-backlog.js.map +1 -0
  280. package/dist/store/sync/sealer-values.d.ts +34 -0
  281. package/dist/store/sync/sealer-values.d.ts.map +1 -0
  282. package/dist/store/sync/sealer-values.js +53 -0
  283. package/dist/store/sync/sealer-values.js.map +1 -0
  284. package/dist/store/sync/sealer.d.ts +145 -0
  285. package/dist/store/sync/sealer.d.ts.map +1 -0
  286. package/dist/store/sync/sealer.js +906 -0
  287. package/dist/store/sync/sealer.js.map +1 -0
  288. package/dist/store/sync/structural.d.ts +63 -0
  289. package/dist/store/sync/structural.d.ts.map +1 -0
  290. package/dist/store/sync/structural.js +180 -0
  291. package/dist/store/sync/structural.js.map +1 -0
  292. package/dist/store/sync/timestamps.d.ts +92 -0
  293. package/dist/store/sync/timestamps.d.ts.map +1 -0
  294. package/dist/store/sync/timestamps.js +228 -0
  295. package/dist/store/sync/timestamps.js.map +1 -0
  296. package/dist/store/sync/tombstones.d.ts +75 -0
  297. package/dist/store/sync/tombstones.d.ts.map +1 -0
  298. package/dist/store/sync/tombstones.js +103 -0
  299. package/dist/store/sync/tombstones.js.map +1 -0
  300. package/dist/store/sync/trigger-classes.d.ts +221 -0
  301. package/dist/store/sync/trigger-classes.d.ts.map +1 -0
  302. package/dist/store/sync/trigger-classes.js +441 -0
  303. package/dist/store/sync/trigger-classes.js.map +1 -0
  304. package/dist/store/sync/trigger-suspend-at-path.d.ts +23 -0
  305. package/dist/store/sync/trigger-suspend-at-path.d.ts.map +1 -0
  306. package/dist/store/sync/trigger-suspend-at-path.js +44 -0
  307. package/dist/store/sync/trigger-suspend-at-path.js.map +1 -0
  308. package/dist/store/sync/writer-version.d.ts +43 -0
  309. package/dist/store/sync/writer-version.d.ts.map +1 -0
  310. package/dist/store/sync/writer-version.js +90 -0
  311. package/dist/store/sync/writer-version.js.map +1 -0
  312. package/dist/store/table-classification.d.ts.map +1 -1
  313. package/dist/store/table-classification.js +102 -0
  314. package/dist/store/table-classification.js.map +1 -1
  315. package/dist/store/trigger-suspend-schema.d.ts +44 -0
  316. package/dist/store/trigger-suspend-schema.d.ts.map +1 -0
  317. package/dist/store/trigger-suspend-schema.js +25 -0
  318. package/dist/store/trigger-suspend-schema.js.map +1 -0
  319. package/dist/store/vault-manifest.d.ts +365 -0
  320. package/dist/store/vault-manifest.d.ts.map +1 -0
  321. package/dist/store/vault-manifest.js +812 -0
  322. package/dist/store/vault-manifest.js.map +1 -0
  323. package/dist/store/writer-lease.d.ts +31 -0
  324. package/dist/store/writer-lease.d.ts.map +1 -1
  325. package/dist/store/writer-lease.js +65 -2
  326. package/dist/store/writer-lease.js.map +1 -1
  327. package/dist/system/health.d.ts.map +1 -1
  328. package/dist/system/health.js +21 -0
  329. package/dist/system/health.js.map +1 -1
  330. package/dist/system/project-health.d.ts.map +1 -1
  331. package/dist/system/project-health.js +3 -1
  332. package/dist/system/project-health.js.map +1 -1
  333. package/dist/tasks/affected-packages.d.ts +58 -0
  334. package/dist/tasks/affected-packages.d.ts.map +1 -1
  335. package/dist/tasks/affected-packages.js +75 -6
  336. package/dist/tasks/affected-packages.js.map +1 -1
  337. package/dist/tasks/affected-scope.d.ts +150 -23
  338. package/dist/tasks/affected-scope.d.ts.map +1 -1
  339. package/dist/tasks/affected-scope.js +320 -32
  340. package/dist/tasks/affected-scope.js.map +1 -1
  341. package/dist/tasks/change-set.d.ts +96 -0
  342. package/dist/tasks/change-set.d.ts.map +1 -1
  343. package/dist/tasks/change-set.js +169 -4
  344. package/dist/tasks/change-set.js.map +1 -1
  345. package/dist/tasks/complete-ci.d.ts +115 -0
  346. package/dist/tasks/complete-ci.d.ts.map +1 -0
  347. package/dist/tasks/complete-ci.js +171 -0
  348. package/dist/tasks/complete-ci.js.map +1 -0
  349. package/dist/tasks/complete.d.ts.map +1 -1
  350. package/dist/tasks/complete.js +50 -17
  351. package/dist/tasks/complete.js.map +1 -1
  352. package/dist/tasks/compute-task-view.d.ts.map +1 -1
  353. package/dist/tasks/compute-task-view.js +7 -0
  354. package/dist/tasks/compute-task-view.js.map +1 -1
  355. package/dist/tasks/done-plan.d.ts.map +1 -1
  356. package/dist/tasks/done-plan.js +51 -30
  357. package/dist/tasks/done-plan.js.map +1 -1
  358. package/dist/tasks/done-record.d.ts +6 -0
  359. package/dist/tasks/done-record.d.ts.map +1 -1
  360. package/dist/tasks/done-record.js +9 -3
  361. package/dist/tasks/done-record.js.map +1 -1
  362. package/dist/tasks/evidence.d.ts +3 -2
  363. package/dist/tasks/evidence.d.ts.map +1 -1
  364. package/dist/tasks/evidence.js +143 -12
  365. package/dist/tasks/evidence.js.map +1 -1
  366. package/dist/tasks/gate-notes.d.ts +22 -0
  367. package/dist/tasks/gate-notes.d.ts.map +1 -0
  368. package/dist/tasks/gate-notes.js +33 -0
  369. package/dist/tasks/gate-notes.js.map +1 -0
  370. package/dist/tasks/index.d.ts +2 -1
  371. package/dist/tasks/index.d.ts.map +1 -1
  372. package/dist/tasks/index.js +2 -1
  373. package/dist/tasks/index.js.map +1 -1
  374. package/dist/tasks/test-run-binding.d.ts +117 -0
  375. package/dist/tasks/test-run-binding.d.ts.map +1 -0
  376. package/dist/tasks/test-run-binding.js +365 -0
  377. package/dist/tasks/test-run-binding.js.map +1 -0
  378. package/dist/tasks/tool-cache-env.d.ts +123 -0
  379. package/dist/tasks/tool-cache-env.d.ts.map +1 -0
  380. package/dist/tasks/tool-cache-env.js +287 -0
  381. package/dist/tasks/tool-cache-env.js.map +1 -0
  382. package/dist/tasks/tool-cache-failed-first.d.ts +155 -0
  383. package/dist/tasks/tool-cache-failed-first.d.ts.map +1 -0
  384. package/dist/tasks/tool-cache-failed-first.js +285 -0
  385. package/dist/tasks/tool-cache-failed-first.js.map +1 -0
  386. package/dist/tasks/tool-cache.d.ts +375 -55
  387. package/dist/tasks/tool-cache.d.ts.map +1 -1
  388. package/dist/tasks/tool-cache.js +912 -303
  389. package/dist/tasks/tool-cache.js.map +1 -1
  390. package/dist/tasks/tool-resolver.d.ts +4 -3
  391. package/dist/tasks/tool-resolver.d.ts.map +1 -1
  392. package/dist/tasks/tool-resolver.js +15 -4
  393. package/dist/tasks/tool-resolver.js.map +1 -1
  394. package/dist/tasks/tool-semaphore.d.ts +67 -7
  395. package/dist/tasks/tool-semaphore.d.ts.map +1 -1
  396. package/dist/tasks/tool-semaphore.js +134 -56
  397. package/dist/tasks/tool-semaphore.js.map +1 -1
  398. package/dist/upgrade.d.ts.map +1 -1
  399. package/dist/upgrade.js +4 -0
  400. package/dist/upgrade.js.map +1 -1
  401. package/dist/validation/engine-ops.d.ts +6 -0
  402. package/dist/validation/engine-ops.d.ts.map +1 -1
  403. package/dist/validation/engine-ops.js +8 -0
  404. package/dist/validation/engine-ops.js.map +1 -1
  405. package/migrations/drizzle-cleo-project/20260930170000_t12819-trigger-suspend-clause/migration.sql +367 -0
  406. package/migrations/sync-journal/20260930120000_t12343-capture/migration.sql +47 -0
  407. package/migrations/sync-journal/20261001170000_t12984-sealer/migration.sql +101 -0
  408. package/package.json +13 -13
  409. package/templates/CLEO-INJECTION.md +5 -5
  410. package/templates/CLEO-REFERENCE.md +8 -4
@@ -0,0 +1,158 @@
1
+ /**
2
+ * The bracketed migration runner (journal spec §2.3a rules 1–3; T12774,
3
+ * T12781, T12785, T12786, T12795, T12796, T12797, T12809).
4
+ *
5
+ * Drizzle's `migrateSync` runs every pending migration in ONE transaction of
6
+ * its own, with `PRAGMA foreign_keys` left ON (the PRAGMA is a no-op inside a
7
+ * transaction). A table rebuild's `DROP TABLE` therefore cascade-deletes
8
+ * child rows, and nothing can run inside its transaction. This runner keeps
9
+ * drizzle's journal byte-for-byte and replaces the transaction discipline:
10
+ *
11
+ * - **Journal-identical (R5-3).** Pending migrations are selected by NAME
12
+ * (drizzle's `getMigrationsToRun`), each row is written with the RAW file's
13
+ * sha256, `created_at = folderMillis`, `name` and `applied_at`, exactly as
14
+ * `migrateSync` writes it. `reconcileJournal` and drizzle's own
15
+ * `upgradeSyncIfNeeded` run inside the leading bracket, in today's order.
16
+ * Statements run one per `prepare()`, as drizzle's session does.
17
+ * - **One bracket per migration FILE (R6-6).** Each file gets its own
18
+ * `BEGIN IMMEDIATE … COMMIT` and its own journal row.
19
+ * - **FK discipline (A, NEW-1, R5-2, R5-4, NEW-6).** `foreign_keys` is turned
20
+ * OFF before `BEGIN` only for a file that rebuilds a table. For such a file
21
+ * the runner snapshots the FK violations of its scope (rebuilt and
22
+ * DML-touched tables plus their FK children) as a rowid-free multiset,
23
+ * re-checks after the statements, and rolls back on any NEW violation.
24
+ * Pre-existing orphans never block a migration. `finally` restores
25
+ * `foreign_keys`, reads it back and asserts no transaction is open.
26
+ * - **Recovery kept.** A duplicate-column or table-exists error re-runs
27
+ * `reconcileJournal` once and retries, as `migrateWithRetry` does; a BUSY
28
+ * error retries the whole bracket with backoff, never mid-bracket.
29
+ * - **Hooks (D4, NEW-8).** `beforeMigrations` runs before the first bracket
30
+ * (the sealer's pending work and the repair diff for suspect tables, S3);
31
+ * `suspendCapture` / `reinstallCapture` run inside each bracket around the
32
+ * statements (the capture triggers, S2); `afterMigration` runs after each
33
+ * commit (the `chash` re-baseline, S3). All are optional.
34
+ *
35
+ * Drizzle is pinned to {@link PINNED_DRIZZLE_VERSION}; a test fails when the
36
+ * installed version differs, so an upgrade must re-run the parity suite.
37
+ *
38
+ * @task T12796
39
+ * @task T12809
40
+ * @module store/migration-runner
41
+ */
42
+ import type { DatabaseSync } from 'node:sqlite';
43
+ import type { NodeSQLiteDatabase } from 'drizzle-orm/node-sqlite';
44
+ /** The drizzle-orm version the runner's journal parity was proven against. */
45
+ export declare const PINNED_DRIZZLE_VERSION = "1.0.0-rc.4";
46
+ /** The journal table drizzle uses by default. */
47
+ export declare const MIGRATIONS_TABLE = "__drizzle_migrations";
48
+ /** Optional work around the brackets (D4 ordering). */
49
+ export interface MigrationBracketHooks {
50
+ /** Before the first bracket: seal pending captures, repair suspect tables (S3). */
51
+ beforeMigrations?(db: DatabaseSync): void;
52
+ /** Inside each bracket, before the statements: drop the capture triggers (S2). */
53
+ suspendCapture?(db: DatabaseSync): void;
54
+ /** Inside each bracket, after the statements: reinstall the capture triggers (S2). */
55
+ reinstallCapture?(db: DatabaseSync): void;
56
+ /** After each committed bracket: re-baseline `chash` for the file's tables (S3). */
57
+ afterMigration?(db: DatabaseSync, migration: {
58
+ name: string;
59
+ hash: string;
60
+ }): void;
61
+ }
62
+ /** One migration lineage sharing the store's journal. */
63
+ export interface MigrationLineage {
64
+ readonly folder: string;
65
+ /** Run `reconcileJournal` for this lineage first (as the callers do today). */
66
+ readonly reconcile?: {
67
+ readonly existenceTable: string;
68
+ readonly logSubsystem: string;
69
+ readonly siblings?: readonly string[];
70
+ };
71
+ }
72
+ /**
73
+ * Legacy lineages the runner refuses by folder name (cleo-dev ruling on the
74
+ * S2 runner scope, 2026-09-30). They keep `migrateWithRetry` in their own
75
+ * binders (`sqlite.ts`, `memory-sqlite.ts`, `nexus-sqlite.ts`,
76
+ * `conduit-sqlite.ts`, …); only the consolidated `cleo.db` lineages run
77
+ * bracketed.
78
+ */
79
+ export declare const LEGACY_LINEAGES: ReadonlySet<string>;
80
+ /** A legacy lineage was handed to the runner. */
81
+ export declare class LegacyLineageRefusedError extends Error {
82
+ readonly lineage: string;
83
+ readonly code = "E_MIGRATION_RUNNER_LEGACY_LINEAGE";
84
+ constructor(lineage: string);
85
+ }
86
+ /** What {@link runBracketedMigrations} did. */
87
+ export interface MigrationRunReport {
88
+ /** Names of the migrations applied, in order. */
89
+ readonly applied: string[];
90
+ /** Names of the files that ran with `foreign_keys = OFF` (rebuilds). */
91
+ readonly rebuilds: string[];
92
+ }
93
+ /** A migration file that introduced a foreign-key violation (rolled back). */
94
+ export declare class MigrationForeignKeyError extends Error {
95
+ readonly migration: string;
96
+ readonly violations: readonly string[];
97
+ readonly code = "E_MIGRATION_FK_VIOLATION";
98
+ constructor(migration: string, violations: readonly string[]);
99
+ }
100
+ /** `foreign_keys` could not be restored on a handle after a bracket. */
101
+ export declare class ForeignKeysNotRestoredError extends Error {
102
+ readonly code = "E_STORE_FK_OFF";
103
+ constructor(expected: number, actual: number);
104
+ }
105
+ /**
106
+ * The tables a migration file rebuilds or drops: `CREATE TABLE __new_x`
107
+ * (→ `x`), `DROP TABLE x`, `ALTER TABLE x RENAME TO y` (→ `x`, `y`).
108
+ * Empty for a file that rebuilds nothing.
109
+ */
110
+ export declare function rebuiltTables(statements: readonly string[]): string[];
111
+ /**
112
+ * Where each table a migration file renames ends up: every `ALTER TABLE a RENAME TO b`, in statement
113
+ * order and composed, so `a → b` then `b → c` gives `a → c` (T13027). Unrenamed tables are absent.
114
+ */
115
+ export declare function renamedTables(statements: readonly string[]): Map<string, string>;
116
+ /** The tables a migration's DML writes (INSERT / UPDATE / DELETE / REPLACE). */
117
+ export declare function dmlTables(statements: readonly string[]): string[];
118
+ /**
119
+ * The FK scope of a rebuild file: the given tables plus every table with a
120
+ * foreign key to one of them (children), restricted to tables that exist.
121
+ */
122
+ export declare function foreignKeyScope(db: DatabaseSync, tables: readonly string[]): string[];
123
+ /**
124
+ * The foreign-key violations of `tables`, as a multiset keyed by rowid-free
125
+ * identity (R5-2): (table, the child's primary-key values normalized by
126
+ * column affinity — or the whole row for a table without a declared PK,
127
+ * parent table, the child's FK values). Duplicates count.
128
+ *
129
+ * FK column NAMES are not part of the key: a rebuild may rename an FK column
130
+ * while the violation stays the same row and value (T13027). Two orphaned
131
+ * FKs of one row with equal values are still counted twice.
132
+ */
133
+ export declare function foreignKeyViolations(db: DatabaseSync, tables: readonly string[]): Map<string, number>;
134
+ /**
135
+ * A before-snapshot re-keyed to the names its tables have after a file's
136
+ * renames (T13027): child and parent tables move through `renames` when the
137
+ * new name exists afterwards. A table renamed away and dropped (`x → __old_x`
138
+ * in a rebuild) keeps its name, since its rows now live under the old name.
139
+ */
140
+ export declare function renameViolations(before: Map<string, number>, renames: ReadonlyMap<string, string>, exists: (table: string) => boolean): Map<string, number>;
141
+ /** Keys whose count in `after` exceeds their count in `before`. */
142
+ export declare function newViolations(before: Map<string, number>, after: Map<string, number>): string[];
143
+ /**
144
+ * Apply every pending migration of each lineage, in order, with the journal
145
+ * `migrateSync` would leave, one bracket per file.
146
+ *
147
+ * @param nativeDb - The store handle.
148
+ * @param db - The drizzle wrapper of `nativeDb` (for drizzle's journal upgrade).
149
+ * @param lineages - The lineages sharing the journal, in apply order.
150
+ * @param hooks - Optional D4 hooks.
151
+ */
152
+ export declare function runBracketedMigrations(nativeDb: DatabaseSync, db: NodeSQLiteDatabase<any>, lineages: readonly MigrationLineage[], hooks?: MigrationBracketHooks): MigrationRunReport;
153
+ /**
154
+ * Same as {@link runBracketedMigrations} for one lineage, in the shape the
155
+ * callers of `reconcileJournal` + `migrateWithRetry` use today.
156
+ */
157
+ export declare function migrateBracketed(db: NodeSQLiteDatabase<any>, nativeDb: DatabaseSync, migrationsFolder: string, existenceTable: string, logSubsystem: string, siblings?: readonly string[], hooks?: MigrationBracketHooks): MigrationRunReport;
158
+ //# sourceMappingURL=migration-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-runner.d.ts","sourceRoot":"","sources":["../../src/store/migration-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,493 @@
1
+ /**
2
+ * The bracketed migration runner (journal spec §2.3a rules 1–3; T12774,
3
+ * T12781, T12785, T12786, T12795, T12796, T12797, T12809).
4
+ *
5
+ * Drizzle's `migrateSync` runs every pending migration in ONE transaction of
6
+ * its own, with `PRAGMA foreign_keys` left ON (the PRAGMA is a no-op inside a
7
+ * transaction). A table rebuild's `DROP TABLE` therefore cascade-deletes
8
+ * child rows, and nothing can run inside its transaction. This runner keeps
9
+ * drizzle's journal byte-for-byte and replaces the transaction discipline:
10
+ *
11
+ * - **Journal-identical (R5-3).** Pending migrations are selected by NAME
12
+ * (drizzle's `getMigrationsToRun`), each row is written with the RAW file's
13
+ * sha256, `created_at = folderMillis`, `name` and `applied_at`, exactly as
14
+ * `migrateSync` writes it. `reconcileJournal` and drizzle's own
15
+ * `upgradeSyncIfNeeded` run inside the leading bracket, in today's order.
16
+ * Statements run one per `prepare()`, as drizzle's session does.
17
+ * - **One bracket per migration FILE (R6-6).** Each file gets its own
18
+ * `BEGIN IMMEDIATE … COMMIT` and its own journal row.
19
+ * - **FK discipline (A, NEW-1, R5-2, R5-4, NEW-6).** `foreign_keys` is turned
20
+ * OFF before `BEGIN` only for a file that rebuilds a table. For such a file
21
+ * the runner snapshots the FK violations of its scope (rebuilt and
22
+ * DML-touched tables plus their FK children) as a rowid-free multiset,
23
+ * re-checks after the statements, and rolls back on any NEW violation.
24
+ * Pre-existing orphans never block a migration. `finally` restores
25
+ * `foreign_keys`, reads it back and asserts no transaction is open.
26
+ * - **Recovery kept.** A duplicate-column or table-exists error re-runs
27
+ * `reconcileJournal` once and retries, as `migrateWithRetry` does; a BUSY
28
+ * error retries the whole bracket with backoff, never mid-bracket.
29
+ * - **Hooks (D4, NEW-8).** `beforeMigrations` runs before the first bracket
30
+ * (the sealer's pending work and the repair diff for suspect tables, S3);
31
+ * `suspendCapture` / `reinstallCapture` run inside each bracket around the
32
+ * statements (the capture triggers, S2); `afterMigration` runs after each
33
+ * commit (the `chash` re-baseline, S3). All are optional.
34
+ *
35
+ * Drizzle is pinned to {@link PINNED_DRIZZLE_VERSION}; a test fails when the
36
+ * installed version differs, so an upgrade must re-run the parity suite.
37
+ *
38
+ * @task T12796
39
+ * @task T12809
40
+ * @module store/migration-runner
41
+ */
42
+ import { basename } from 'node:path';
43
+ import { readMigrationFiles } from 'drizzle-orm/migrator';
44
+ import { getMigrationsToRun } from 'drizzle-orm/migrator.utils';
45
+ import { sql } from 'drizzle-orm/sql';
46
+ import { upgradeSyncIfNeeded } from 'drizzle-orm/up-migrations/sqlite';
47
+ import { getLogger } from '../logger.js';
48
+ import { isDuplicateColumnError, isTableAlreadyExistsError, reconcileJournal, sanitizeMigrationStatements, } from './migration-manager.js';
49
+ import { isSqliteBusy } from './with-retry.js';
50
+ import { assertNoPendingMigrationsForWorktreeBuild } from './worktree-build-guard.js';
51
+ /** The drizzle-orm version the runner's journal parity was proven against. */
52
+ export const PINNED_DRIZZLE_VERSION = '1.0.0-rc.4';
53
+ /** The journal table drizzle uses by default. */
54
+ export const MIGRATIONS_TABLE = '__drizzle_migrations';
55
+ const MAX_BUSY_RETRIES = 5;
56
+ const BUSY_BASE_DELAY_MS = 100;
57
+ const BUSY_MAX_DELAY_MS = 2000;
58
+ /**
59
+ * Legacy lineages the runner refuses by folder name (cleo-dev ruling on the
60
+ * S2 runner scope, 2026-09-30). They keep `migrateWithRetry` in their own
61
+ * binders (`sqlite.ts`, `memory-sqlite.ts`, `nexus-sqlite.ts`,
62
+ * `conduit-sqlite.ts`, …); only the consolidated `cleo.db` lineages run
63
+ * bracketed.
64
+ */
65
+ export const LEGACY_LINEAGES = new Set([
66
+ 'drizzle-tasks',
67
+ 'drizzle-brain',
68
+ 'drizzle-nexus',
69
+ 'drizzle-conduit',
70
+ 'drizzle-agent-registry',
71
+ 'drizzle-skills',
72
+ 'drizzle-telemetry',
73
+ 'drizzle-signaldock',
74
+ ]);
75
+ /** A legacy lineage was handed to the runner. */
76
+ export class LegacyLineageRefusedError extends Error {
77
+ lineage;
78
+ code = 'E_MIGRATION_RUNNER_LEGACY_LINEAGE';
79
+ constructor(lineage) {
80
+ super(`The bracketed migration runner runs only the consolidated cleo.db lineages; refusing legacy lineage ${lineage}`);
81
+ this.lineage = lineage;
82
+ this.name = 'LegacyLineageRefusedError';
83
+ }
84
+ }
85
+ /** A migration file that introduced a foreign-key violation (rolled back). */
86
+ export class MigrationForeignKeyError extends Error {
87
+ migration;
88
+ violations;
89
+ code = 'E_MIGRATION_FK_VIOLATION';
90
+ constructor(migration, violations) {
91
+ super(`Migration ${migration} would leave ${violations.length} new foreign-key violation(s); ` +
92
+ `rolled back. First: ${violations.slice(0, 3).join('; ')}`);
93
+ this.migration = migration;
94
+ this.violations = violations;
95
+ this.name = 'MigrationForeignKeyError';
96
+ }
97
+ }
98
+ /** `foreign_keys` could not be restored on a handle after a bracket. */
99
+ export class ForeignKeysNotRestoredError extends Error {
100
+ code = 'E_STORE_FK_OFF';
101
+ constructor(expected, actual) {
102
+ super(`PRAGMA foreign_keys is ${actual} after a migration bracket; expected ${expected}`);
103
+ this.name = 'ForeignKeysNotRestoredError';
104
+ }
105
+ }
106
+ const IDENT = String.raw `[\`"[]?(\w+)[\`"\]]?`;
107
+ /** Strip `--` comments so prose never looks like DDL. */
108
+ function code(stmt) {
109
+ return stmt.replace(/--[^\n]*/g, '');
110
+ }
111
+ /**
112
+ * The tables a migration file rebuilds or drops: `CREATE TABLE __new_x`
113
+ * (→ `x`), `DROP TABLE x`, `ALTER TABLE x RENAME TO y` (→ `x`, `y`).
114
+ * Empty for a file that rebuilds nothing.
115
+ */
116
+ export function rebuiltTables(statements) {
117
+ const out = new Set();
118
+ const final = (t) => t.replace(/^__new_/, '');
119
+ for (const s of statements.map(code)) {
120
+ for (const m of s.matchAll(new RegExp(String.raw `\bCREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?${IDENT}`, 'gi'))) {
121
+ if (m[1].startsWith('__new_'))
122
+ out.add(final(m[1]));
123
+ }
124
+ for (const m of s.matchAll(new RegExp(String.raw `\bDROP\s+TABLE\s+(?:IF\s+EXISTS\s+)?${IDENT}`, 'gi'))) {
125
+ out.add(final(m[1]));
126
+ }
127
+ for (const m of s.matchAll(new RegExp(String.raw `\bALTER\s+TABLE\s+${IDENT}\s+RENAME\s+TO\s+${IDENT}`, 'gi'))) {
128
+ out.add(final(m[1]));
129
+ out.add(final(m[2]));
130
+ }
131
+ }
132
+ return [...out].sort();
133
+ }
134
+ /**
135
+ * Where each table a migration file renames ends up: every `ALTER TABLE a RENAME TO b`, in statement
136
+ * order and composed, so `a → b` then `b → c` gives `a → c` (T13027). Unrenamed tables are absent.
137
+ */
138
+ export function renamedTables(statements) {
139
+ const out = new Map();
140
+ // Anchored: only a statement that IS the rename counts, never text inside a
141
+ // string literal or another statement's body.
142
+ const rename = new RegExp(String.raw `^\s*ALTER\s+TABLE\s+${IDENT}\s+RENAME\s+TO\s+${IDENT}\s*;?\s*$`, 'i');
143
+ for (const s of statements.map(code)) {
144
+ const m = rename.exec(s);
145
+ if (!m)
146
+ continue;
147
+ const from = m[1];
148
+ const to = m[2];
149
+ const original = [...out.entries()].find(([, now]) => now === from)?.[0] ?? from;
150
+ out.set(original, to);
151
+ }
152
+ return out;
153
+ }
154
+ /** The tables a migration's DML writes (INSERT / UPDATE / DELETE / REPLACE). */
155
+ export function dmlTables(statements) {
156
+ const out = new Set();
157
+ for (const s of statements.map(code)) {
158
+ for (const m of s.matchAll(new RegExp(String.raw `\b(?:INSERT(?:\s+OR\s+\w+)?\s+INTO|REPLACE\s+INTO|UPDATE(?:\s+OR\s+\w+)?|DELETE\s+FROM)\s+${IDENT}`, 'gi'))) {
159
+ out.add(m[1].replace(/^__new_/, ''));
160
+ }
161
+ }
162
+ return [...out].sort();
163
+ }
164
+ function listTables(db) {
165
+ return db
166
+ .prepare("SELECT name FROM main.sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name")
167
+ .all().map((r) => r.name);
168
+ }
169
+ function foreignKeys(db, table) {
170
+ return db.prepare(`PRAGMA main.foreign_key_list("${table}")`).all();
171
+ }
172
+ /**
173
+ * The FK scope of a rebuild file: the given tables plus every table with a
174
+ * foreign key to one of them (children), restricted to tables that exist.
175
+ */
176
+ export function foreignKeyScope(db, tables) {
177
+ const all = listTables(db);
178
+ const existing = new Set(all);
179
+ const scope = new Set(tables.filter((t) => existing.has(t)));
180
+ const parents = new Set(tables);
181
+ for (const t of all) {
182
+ if (foreignKeys(db, t).some((fk) => parents.has(fk.table)))
183
+ scope.add(t);
184
+ }
185
+ return [...scope].sort();
186
+ }
187
+ /** SQLite's affinity for a declared column type (§3.1 of the datatype doc). */
188
+ function affinity(declared) {
189
+ const t = declared.toUpperCase();
190
+ if (t.includes('INT'))
191
+ return 'INTEGER';
192
+ if (/CHAR|CLOB|TEXT/.test(t))
193
+ return 'TEXT';
194
+ if (t === '' || t.includes('BLOB'))
195
+ return 'BLOB';
196
+ if (/REAL|FLOA|DOUB/.test(t))
197
+ return 'REAL';
198
+ return 'NUMERIC';
199
+ }
200
+ /**
201
+ * The foreign-key violations of `tables`, as a multiset keyed by rowid-free
202
+ * identity (R5-2): (table, the child's primary-key values normalized by
203
+ * column affinity — or the whole row for a table without a declared PK,
204
+ * parent table, the child's FK values). Duplicates count.
205
+ *
206
+ * FK column NAMES are not part of the key: a rebuild may rename an FK column
207
+ * while the violation stays the same row and value (T13027). Two orphaned
208
+ * FKs of one row with equal values are still counted twice.
209
+ */
210
+ export function foreignKeyViolations(db, tables) {
211
+ const out = new Map();
212
+ for (const table of tables) {
213
+ const rows = db.prepare(`PRAGMA main.foreign_key_check("${table}")`).all();
214
+ if (rows.length === 0)
215
+ continue;
216
+ const cols = db.prepare(`PRAGMA main.table_info("${table}")`).all();
217
+ const pkCols = cols.filter((c) => c.pk > 0).sort((a, b) => a.pk - b.pk);
218
+ const keyCols = pkCols.length > 0 ? pkCols : cols;
219
+ const fks = foreignKeys(db, table);
220
+ const seenNoRowid = new Set();
221
+ const enc = (c, alias) => {
222
+ const a = affinity(c.type);
223
+ const ref = `${alias}"${c.name}"`;
224
+ return a === 'BLOB' ? `quote(${ref})` : `quote(CAST(${ref} AS ${a}))`;
225
+ };
226
+ const keySql = (alias) => `json_array(${keyCols.map((c) => enc(c, alias)).join(', ')})`;
227
+ for (const v of rows) {
228
+ const fkCols = fks.filter((f) => f.id === v.fkid).sort((a, b) => a.seq - b.seq);
229
+ const fkSql = (alias) => `json_array(${fkCols.map((f) => `quote(${alias}"${f.from}")`).join(', ')})`;
230
+ let identities;
231
+ if (v.rowid !== null && v.rowid !== undefined) {
232
+ identities = db
233
+ .prepare(`SELECT ${keySql('')} AS k, ${fkSql('')} AS f FROM main."${table}" WHERE rowid = ?`)
234
+ .all(v.rowid);
235
+ }
236
+ else {
237
+ // WITHOUT ROWID: no rowid to point at; list this FK's violating rows.
238
+ const parentPk = db.prepare(`PRAGMA main.table_info("${v.parent}")`).all()
239
+ .filter((c) => c.pk > 0)
240
+ .sort((a, b) => a.pk - b.pk)
241
+ .map((c) => c.name);
242
+ const match = fkCols
243
+ .map((f, i) => `p."${f.to ?? parentPk[i] ?? f.from}" = c."${f.from}"`)
244
+ .join(' AND ');
245
+ identities = db
246
+ .prepare(`SELECT ${keySql('c.')} AS k, ${fkSql('c.')} AS f FROM main."${table}" c ` +
247
+ `WHERE ${fkCols.map((f) => `c."${f.from}" IS NOT NULL`).join(' AND ')} ` +
248
+ `AND NOT EXISTS (SELECT 1 FROM main."${v.parent}" p WHERE ${match})`)
249
+ .all();
250
+ // foreign_key_check lists one row per violation; this query lists them
251
+ // all at once, so take it for the first report of this FK only.
252
+ if (seenNoRowid.has(v.fkid))
253
+ identities = [];
254
+ seenNoRowid.add(v.fkid);
255
+ }
256
+ for (const id of identities) {
257
+ const key = JSON.stringify([table, id.k, v.parent, id.f]);
258
+ out.set(key, (out.get(key) ?? 0) + 1);
259
+ }
260
+ }
261
+ }
262
+ return out;
263
+ }
264
+ /**
265
+ * A before-snapshot re-keyed to the names its tables have after a file's
266
+ * renames (T13027): child and parent tables move through `renames` when the
267
+ * new name exists afterwards. A table renamed away and dropped (`x → __old_x`
268
+ * in a rebuild) keeps its name, since its rows now live under the old name.
269
+ */
270
+ export function renameViolations(before, renames, exists) {
271
+ if (renames.size === 0)
272
+ return before;
273
+ const to = (t) => {
274
+ const r = renames.get(t);
275
+ return r !== undefined && exists(r) ? r : t;
276
+ };
277
+ const out = new Map();
278
+ for (const [k, n] of before) {
279
+ const [table, pk, parent, values] = JSON.parse(k);
280
+ const key = JSON.stringify([to(table), pk, to(parent), values]);
281
+ out.set(key, (out.get(key) ?? 0) + n);
282
+ }
283
+ return out;
284
+ }
285
+ /** Keys whose count in `after` exceeds their count in `before`. */
286
+ export function newViolations(before, after) {
287
+ const out = [];
288
+ for (const [k, n] of after) {
289
+ const extra = n - (before.get(k) ?? 0);
290
+ for (let i = 0; i < extra; i++)
291
+ out.push(k);
292
+ }
293
+ return out;
294
+ }
295
+ function sleepMs(ms) {
296
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, Math.round(ms));
297
+ }
298
+ /** Run `fn`, retrying the whole thing on SQLITE_BUSY with backoff. */
299
+ function withBusyRetry(fn) {
300
+ for (let attempt = 1;; attempt++) {
301
+ try {
302
+ return fn();
303
+ }
304
+ catch (err) {
305
+ if (!isSqliteBusy(err) || attempt >= MAX_BUSY_RETRIES)
306
+ throw err;
307
+ sleepMs(Math.min(BUSY_BASE_DELAY_MS * 2 ** (attempt - 1) * (1 + Math.random() * 0.5), BUSY_MAX_DELAY_MS));
308
+ }
309
+ }
310
+ }
311
+ function readForeignKeys(db) {
312
+ return Number(db.prepare('PRAGMA foreign_keys').get().foreign_keys);
313
+ }
314
+ /**
315
+ * The leading bracket of a lineage: reconcile (when configured), then
316
+ * drizzle's journal-format upgrade, then create the journal table on a new
317
+ * store. Returns the names already journaled.
318
+ */
319
+ function leadingBracket(nativeDb,
320
+ // biome-ignore lint/suspicious/noExplicitAny: drizzle's session type is generic over the schema
321
+ db, lineage, migrations) {
322
+ withBusyRetry(() => {
323
+ nativeDb.exec('BEGIN IMMEDIATE');
324
+ try {
325
+ if (lineage.reconcile) {
326
+ reconcileJournal(nativeDb, lineage.folder, lineage.reconcile.existenceTable, lineage.reconcile.logSubsystem, lineage.reconcile.siblings ?? []);
327
+ }
328
+ // Drizzle's own upgrade, with its inner transaction folded into ours.
329
+ const session = db._.session;
330
+ const inBracket = new Proxy(session, {
331
+ get(target, prop, receiver) {
332
+ if (prop === 'transaction')
333
+ return (fn) => fn(receiver);
334
+ return Reflect.get(target, prop, receiver);
335
+ },
336
+ });
337
+ const { newDb } = upgradeSyncIfNeeded(MIGRATIONS_TABLE, inBracket, migrations);
338
+ if (newDb) {
339
+ session.run(sql `
340
+ CREATE TABLE IF NOT EXISTS ${sql.identifier(MIGRATIONS_TABLE)} (
341
+ id INTEGER PRIMARY KEY,
342
+ hash text NOT NULL,
343
+ created_at numeric,
344
+ name text,
345
+ applied_at TEXT
346
+ )`);
347
+ }
348
+ nativeDb.exec('COMMIT');
349
+ }
350
+ catch (err) {
351
+ if (nativeDb.isTransaction)
352
+ nativeDb.exec('ROLLBACK');
353
+ throw err;
354
+ }
355
+ });
356
+ }
357
+ function journalRows(nativeDb) {
358
+ return nativeDb
359
+ .prepare(`SELECT id, hash, created_at, name FROM main."${MIGRATIONS_TABLE}"`)
360
+ .all();
361
+ }
362
+ /**
363
+ * Apply one migration file in its own bracket. Returns whether it ran with
364
+ * foreign keys off.
365
+ */
366
+ function migrationBracket(nativeDb, migration, hooks) {
367
+ const statements = migration.sql;
368
+ const rebuilt = rebuiltTables(statements);
369
+ const rebuild = rebuilt.length > 0;
370
+ const prev = readForeignKeys(nativeDb);
371
+ let failure;
372
+ let committed = false;
373
+ try {
374
+ if (rebuild)
375
+ nativeDb.exec('PRAGMA foreign_keys = OFF');
376
+ nativeDb.exec('BEGIN IMMEDIATE');
377
+ const scopeTables = [...rebuilt, ...dmlTables(statements)];
378
+ const before = rebuild
379
+ ? foreignKeyViolations(nativeDb, foreignKeyScope(nativeDb, scopeTables))
380
+ : new Map();
381
+ hooks.suspendCapture?.(nativeDb);
382
+ for (const stmt of statements)
383
+ nativeDb.prepare(stmt).run();
384
+ nativeDb
385
+ .prepare(`INSERT INTO main."${MIGRATIONS_TABLE}" ("hash", "created_at", "name", "applied_at") values(?, ?, ?, ?)`)
386
+ .run(migration.hash, migration.folderMillis, migration.name ?? null, new Date().toISOString());
387
+ if (rebuild) {
388
+ // Re-scope after the statements: the rebuild may have created tables.
389
+ const after = foreignKeyViolations(nativeDb, foreignKeyScope(nativeDb, scopeTables));
390
+ // A renamed table keeps its pre-existing orphans: compare under the new names (T13027).
391
+ const live = new Set(listTables(nativeDb));
392
+ const renamed = renameViolations(before, renamedTables(statements), (t) => live.has(t));
393
+ const added = newViolations(renamed, after);
394
+ // @sync-invariant none:local-only a migration that adds FK violations is refused locally before commit; schema, not synced rows
395
+ if (added.length > 0)
396
+ throw new MigrationForeignKeyError(migration.name ?? '', added);
397
+ }
398
+ hooks.reinstallCapture?.(nativeDb);
399
+ nativeDb.exec('COMMIT');
400
+ committed = true;
401
+ }
402
+ catch (err) {
403
+ failure = err;
404
+ }
405
+ // NEW-6: never leave a pooled handle inside a transaction or with FK off.
406
+ if (nativeDb.isTransaction)
407
+ nativeDb.exec('ROLLBACK');
408
+ nativeDb.exec(`PRAGMA foreign_keys = ${prev}`);
409
+ const now = readForeignKeys(nativeDb);
410
+ if (now !== prev || nativeDb.isTransaction) {
411
+ // @sync-invariant none:local-only the migration runner restores this handle's FK mode; local schema pass
412
+ throw Object.assign(new ForeignKeysNotRestoredError(prev, now), { cause: failure });
413
+ }
414
+ if (!committed)
415
+ throw failure;
416
+ return rebuild;
417
+ }
418
+ /**
419
+ * Apply every pending migration of each lineage, in order, with the journal
420
+ * `migrateSync` would leave, one bracket per file.
421
+ *
422
+ * @param nativeDb - The store handle.
423
+ * @param db - The drizzle wrapper of `nativeDb` (for drizzle's journal upgrade).
424
+ * @param lineages - The lineages sharing the journal, in apply order.
425
+ * @param hooks - Optional D4 hooks.
426
+ */
427
+ export function runBracketedMigrations(nativeDb,
428
+ // biome-ignore lint/suspicious/noExplicitAny: drizzle's session type is generic over the schema
429
+ db, lineages, hooks = {}) {
430
+ const applied = [];
431
+ const rebuilds = [];
432
+ let hooked = false;
433
+ for (const lineage of lineages) {
434
+ const name = basename(lineage.folder.replace(/[\\/]+$/, ''));
435
+ // @sync-invariant none:local-only refuses a retired migration lineage on this store; local schema pass
436
+ if (LEGACY_LINEAGES.has(name))
437
+ throw new LegacyLineageRefusedError(name);
438
+ }
439
+ for (const lineage of lineages) {
440
+ const raw = readMigrationFiles({ migrationsFolder: lineage.folder });
441
+ // T12687: a worktree build never applies its migrations to a foreign store.
442
+ assertNoPendingMigrationsForWorktreeBuild(nativeDb, raw);
443
+ const migrations = sanitizeMigrationStatements(raw);
444
+ let reconciledDuplicate = false;
445
+ let reconciledExists = false;
446
+ leadingBracket(nativeDb, db, lineage, migrations);
447
+ for (;;) {
448
+ const pending = getMigrationsToRun({
449
+ localMigrations: migrations,
450
+ dbMigrations: journalRows(nativeDb),
451
+ });
452
+ if (pending.length === 0)
453
+ break;
454
+ if (!hooked) {
455
+ hooks.beforeMigrations?.(nativeDb);
456
+ hooked = true;
457
+ }
458
+ const next = pending[0];
459
+ try {
460
+ const rebuild = withBusyRetry(() => migrationBracket(nativeDb, next, hooks));
461
+ applied.push(next.name ?? '');
462
+ if (rebuild)
463
+ rebuilds.push(next.name ?? '');
464
+ hooks.afterMigration?.(nativeDb, { name: next.name ?? '', hash: next.hash });
465
+ }
466
+ catch (err) {
467
+ const dup = isDuplicateColumnError(err) && !reconciledDuplicate;
468
+ const exists = isTableAlreadyExistsError(err) && !reconciledExists;
469
+ if (lineage.reconcile && (dup || exists)) {
470
+ if (dup)
471
+ reconciledDuplicate = true;
472
+ if (exists)
473
+ reconciledExists = true;
474
+ getLogger(lineage.reconcile.logSubsystem).warn({ migration: next.name, message: err.message }, 'Migration hit an already-applied DDL target; reconciling the journal and retrying');
475
+ leadingBracket(nativeDb, db, lineage, migrations);
476
+ continue;
477
+ }
478
+ throw err;
479
+ }
480
+ }
481
+ }
482
+ return { applied, rebuilds };
483
+ }
484
+ /**
485
+ * Same as {@link runBracketedMigrations} for one lineage, in the shape the
486
+ * callers of `reconcileJournal` + `migrateWithRetry` use today.
487
+ */
488
+ export function migrateBracketed(
489
+ // biome-ignore lint/suspicious/noExplicitAny: drizzle's session type is generic over the schema
490
+ db, nativeDb, migrationsFolder, existenceTable, logSubsystem, siblings = [], hooks = {}) {
491
+ return runBracketedMigrations(nativeDb, db, [{ folder: migrationsFolder, reconcile: { existenceTable, logSubsystem, siblings } }], hooks);
492
+ }
493
+ //# sourceMappingURL=migration-runner.js.map