@lumenflow/cli 5.4.0 → 5.7.12

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 (227) hide show
  1. package/README.md +42 -40
  2. package/dist/db-journal-recover.js +400 -0
  3. package/dist/db-journal-recover.js.map +1 -0
  4. package/dist/docs-sync.js +8 -3
  5. package/dist/docs-sync.js.map +1 -1
  6. package/dist/gate-defaults.js +191 -9
  7. package/dist/gate-defaults.js.map +1 -1
  8. package/dist/gate-registry.js.map +1 -1
  9. package/dist/gates/monolithic-file-contention-guard.js +167 -0
  10. package/dist/gates/monolithic-file-contention-guard.js.map +1 -0
  11. package/dist/gates/prod-migration-drift.js +207 -0
  12. package/dist/gates/prod-migration-drift.js.map +1 -0
  13. package/dist/gates/test-over-deletion-guard.js +255 -0
  14. package/dist/gates/test-over-deletion-guard.js.map +1 -0
  15. package/dist/gates-runners.js +401 -2
  16. package/dist/gates-runners.js.map +1 -1
  17. package/dist/gates.js +349 -4
  18. package/dist/gates.js.map +1 -1
  19. package/dist/lumenflow-setup.js +144 -0
  20. package/dist/lumenflow-setup.js.map +1 -0
  21. package/dist/lumenflow-upgrade.js +2 -1
  22. package/dist/lumenflow-upgrade.js.map +1 -1
  23. package/dist/mem-create.js +10 -1
  24. package/dist/mem-create.js.map +1 -1
  25. package/dist/mem-signal.js +21 -4
  26. package/dist/mem-signal.js.map +1 -1
  27. package/dist/metrics-cli.js +19 -2
  28. package/dist/metrics-cli.js.map +1 -1
  29. package/dist/metrics-snapshot.js +25 -2
  30. package/dist/metrics-snapshot.js.map +1 -1
  31. package/dist/orchestrate-initiative.js +28 -3
  32. package/dist/orchestrate-initiative.js.map +1 -1
  33. package/dist/public-manifest.js +17 -0
  34. package/dist/public-manifest.js.map +1 -1
  35. package/dist/release.js +53 -18
  36. package/dist/release.js.map +1 -1
  37. package/dist/wu-done-gates.js +121 -8
  38. package/dist/wu-done-gates.js.map +1 -1
  39. package/dist/wu-done.js +30 -6
  40. package/dist/wu-done.js.map +1 -1
  41. package/dist/wu-edit-operations.js +74 -0
  42. package/dist/wu-edit-operations.js.map +1 -1
  43. package/dist/wu-edit-validators.js +58 -0
  44. package/dist/wu-edit-validators.js.map +1 -1
  45. package/dist/wu-edit.js +106 -4
  46. package/dist/wu-edit.js.map +1 -1
  47. package/dist/wu-prep.js +132 -8
  48. package/dist/wu-prep.js.map +1 -1
  49. package/dist/wu-recover.js +6 -0
  50. package/dist/wu-recover.js.map +1 -1
  51. package/dist/wu-release.js +120 -2
  52. package/dist/wu-release.js.map +1 -1
  53. package/dist/wu-sizing-validation.js +47 -17
  54. package/dist/wu-sizing-validation.js.map +1 -1
  55. package/dist/wu-status.js +33 -0
  56. package/dist/wu-status.js.map +1 -1
  57. package/package.json +13 -11
  58. package/packs/agent-runtime/package.json +1 -1
  59. package/packs/sidekick/package.json +1 -1
  60. package/packs/software-delivery/package.json +1 -1
  61. package/templates/core/AGENTS.md.template +162 -26
  62. package/templates/core/LUMENFLOW.md.template +381 -70
  63. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +0 -5
  64. package/templates/core/ai/onboarding/agent-safety-card.md.template +63 -17
  65. package/templates/core/ai/onboarding/initiative-orchestration.md.template +4 -0
  66. package/templates/core/ai/onboarding/release-process.md.template +7 -7
  67. package/templates/core/ai/onboarding/vendor-support.md.template +74 -10
  68. package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +1 -1
  69. package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +28 -0
  70. package/packs/agent-runtime/agent-heartbeat.ts +0 -163
  71. package/packs/agent-runtime/auto-session-integration.ts +0 -888
  72. package/packs/agent-runtime/capability-factory.ts +0 -104
  73. package/packs/agent-runtime/constants.ts +0 -21
  74. package/packs/agent-runtime/delegation-registry-schema.ts +0 -220
  75. package/packs/agent-runtime/delegation-registry-store.ts +0 -269
  76. package/packs/agent-runtime/delegation-tree.ts +0 -328
  77. package/packs/agent-runtime/index.ts +0 -20
  78. package/packs/agent-runtime/manifest.ts +0 -348
  79. package/packs/agent-runtime/memory-coordination-contract.ts +0 -86
  80. package/packs/agent-runtime/orchestration.ts +0 -2027
  81. package/packs/agent-runtime/pack-registration.ts +0 -110
  82. package/packs/agent-runtime/policy-factory.ts +0 -165
  83. package/packs/agent-runtime/remote-controls/index.ts +0 -7
  84. package/packs/agent-runtime/remote-controls/operations.ts +0 -405
  85. package/packs/agent-runtime/remote-controls/port.ts +0 -48
  86. package/packs/agent-runtime/remote-controls/state-store.ts +0 -258
  87. package/packs/agent-runtime/remote-controls/types.ts +0 -105
  88. package/packs/agent-runtime/session-schema.ts +0 -467
  89. package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +0 -793
  90. package/packs/agent-runtime/tool-impl/index.ts +0 -6
  91. package/packs/agent-runtime/tool-impl/provider-adapters.ts +0 -1245
  92. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +0 -256
  93. package/packs/agent-runtime/tool-impl/remote-controls.ts +0 -273
  94. package/packs/agent-runtime/tools/index.ts +0 -4
  95. package/packs/agent-runtime/tools/types.ts +0 -47
  96. package/packs/agent-runtime/turn-lifecycle-events.ts +0 -590
  97. package/packs/agent-runtime/types.ts +0 -128
  98. package/packs/agent-runtime/vitest.config.ts +0 -11
  99. package/packs/sidekick/channel-ingress.ts +0 -137
  100. package/packs/sidekick/constants.ts +0 -10
  101. package/packs/sidekick/index.ts +0 -8
  102. package/packs/sidekick/manifest-schema.ts +0 -49
  103. package/packs/sidekick/manifest.ts +0 -512
  104. package/packs/sidekick/pack-registration.ts +0 -110
  105. package/packs/sidekick/policy-factory.ts +0 -38
  106. package/packs/sidekick/sidekick-events.ts +0 -694
  107. package/packs/sidekick/src/adapters/cloud-queue.ts +0 -101
  108. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +0 -386
  109. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +0 -228
  110. package/packs/sidekick/src/domain/channel.types.ts +0 -64
  111. package/packs/sidekick/src/ports/channel-bridge.port.ts +0 -92
  112. package/packs/sidekick/src/routines/commit.ts +0 -74
  113. package/packs/sidekick/tool-impl/channel-tools.ts +0 -577
  114. package/packs/sidekick/tool-impl/channel-transports.ts +0 -75
  115. package/packs/sidekick/tool-impl/index.ts +0 -29
  116. package/packs/sidekick/tool-impl/memory-tools.ts +0 -290
  117. package/packs/sidekick/tool-impl/routine-commit.ts +0 -102
  118. package/packs/sidekick/tool-impl/routine-tools.ts +0 -440
  119. package/packs/sidekick/tool-impl/runtime-context.ts +0 -28
  120. package/packs/sidekick/tool-impl/shared.ts +0 -125
  121. package/packs/sidekick/tool-impl/storage.ts +0 -325
  122. package/packs/sidekick/tool-impl/system-tools.ts +0 -160
  123. package/packs/sidekick/tool-impl/task-tools.ts +0 -506
  124. package/packs/sidekick/tools/channel-tools.ts +0 -53
  125. package/packs/sidekick/tools/index.ts +0 -9
  126. package/packs/sidekick/tools/memory-tools.ts +0 -53
  127. package/packs/sidekick/tools/routine-tools.ts +0 -53
  128. package/packs/sidekick/tools/system-tools.ts +0 -47
  129. package/packs/sidekick/tools/task-tools.ts +0 -61
  130. package/packs/sidekick/tools/types.ts +0 -57
  131. package/packs/sidekick/vitest.config.ts +0 -11
  132. package/packs/software-delivery/constants.ts +0 -10
  133. package/packs/software-delivery/extensions.ts +0 -140
  134. package/packs/software-delivery/gate-policies.ts +0 -134
  135. package/packs/software-delivery/index.ts +0 -8
  136. package/packs/software-delivery/manifest-schema.ts +0 -268
  137. package/packs/software-delivery/manifest.ts +0 -657
  138. package/packs/software-delivery/pack-registration.ts +0 -113
  139. package/packs/software-delivery/src/commands/index.ts +0 -5
  140. package/packs/software-delivery/src/config/delivery-review-contract.ts +0 -256
  141. package/packs/software-delivery/src/config/env-accessors.ts +0 -66
  142. package/packs/software-delivery/src/config/index.ts +0 -8
  143. package/packs/software-delivery/src/config/normalize-config-keys.ts +0 -9
  144. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +0 -460
  145. package/packs/software-delivery/src/config/workspace-reader.ts +0 -375
  146. package/packs/software-delivery/src/constants/backlog-patterns.ts +0 -31
  147. package/packs/software-delivery/src/constants/client-ids.ts +0 -19
  148. package/packs/software-delivery/src/constants/config-contract.ts +0 -7
  149. package/packs/software-delivery/src/constants/docs-layout-presets.ts +0 -50
  150. package/packs/software-delivery/src/constants/duration-constants.ts +0 -20
  151. package/packs/software-delivery/src/constants/gate-constants.ts +0 -32
  152. package/packs/software-delivery/src/constants/index.ts +0 -29
  153. package/packs/software-delivery/src/constants/lock-constants.ts +0 -35
  154. package/packs/software-delivery/src/constants/object-guards.ts +0 -12
  155. package/packs/software-delivery/src/constants/section-headings.ts +0 -107
  156. package/packs/software-delivery/src/constants/wu-cli-constants.ts +0 -488
  157. package/packs/software-delivery/src/constants/wu-domain-constants.ts +0 -466
  158. package/packs/software-delivery/src/constants/wu-git-constants.ts +0 -7
  159. package/packs/software-delivery/src/constants/wu-id-format.ts +0 -327
  160. package/packs/software-delivery/src/constants/wu-paths-constants.ts +0 -384
  161. package/packs/software-delivery/src/constants/wu-statuses.ts +0 -287
  162. package/packs/software-delivery/src/constants/wu-type-helpers.ts +0 -67
  163. package/packs/software-delivery/src/constants/wu-ui-constants.ts +0 -267
  164. package/packs/software-delivery/src/constants/wu-validation-constants.ts +0 -73
  165. package/packs/software-delivery/src/domain/index.ts +0 -5
  166. package/packs/software-delivery/src/domain/orchestration.constants.ts +0 -166
  167. package/packs/software-delivery/src/domain/orchestration.schemas.ts +0 -238
  168. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -176
  169. package/packs/software-delivery/src/methodology/incremental-test.ts +0 -122
  170. package/packs/software-delivery/src/methodology/index.ts +0 -6
  171. package/packs/software-delivery/src/methodology/manual-test-validator.ts +0 -292
  172. package/packs/software-delivery/src/policy/coverage-gate.ts +0 -270
  173. package/packs/software-delivery/src/policy/gates-agent-mode.ts +0 -223
  174. package/packs/software-delivery/src/policy/gates-config-internal.ts +0 -121
  175. package/packs/software-delivery/src/policy/gates-config.ts +0 -300
  176. package/packs/software-delivery/src/policy/gates-coverage.ts +0 -356
  177. package/packs/software-delivery/src/policy/gates-presets.ts +0 -134
  178. package/packs/software-delivery/src/policy/gates-schemas.ts +0 -173
  179. package/packs/software-delivery/src/policy/index.ts +0 -22
  180. package/packs/software-delivery/src/policy/package-manager-resolver.ts +0 -319
  181. package/packs/software-delivery/src/policy/resolve-policy.ts +0 -601
  182. package/packs/software-delivery/src/ports/config.ports.ts +0 -90
  183. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +0 -125
  184. package/packs/software-delivery/src/ports/index.ts +0 -10
  185. package/packs/software-delivery/src/ports/sync-validator.ports.ts +0 -59
  186. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +0 -168
  187. package/packs/software-delivery/src/ports/wu-state.ports.ts +0 -241
  188. package/packs/software-delivery/src/primitives/index.ts +0 -5
  189. package/packs/software-delivery/src/runtime/index.ts +0 -6
  190. package/packs/software-delivery/src/runtime/work-classifier.ts +0 -561
  191. package/packs/software-delivery/src/sandbox/index.ts +0 -10
  192. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +0 -118
  193. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +0 -88
  194. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +0 -154
  195. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +0 -47
  196. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +0 -153
  197. package/packs/software-delivery/src/schemas/index.ts +0 -5
  198. package/packs/software-delivery/src/state/date-utils.ts +0 -158
  199. package/packs/software-delivery/src/state/index.ts +0 -15
  200. package/packs/software-delivery/src/state/state-machine.ts +0 -119
  201. package/packs/software-delivery/src/state/wu-doc-types.ts +0 -51
  202. package/packs/software-delivery/src/state/wu-paths.ts +0 -381
  203. package/packs/software-delivery/src/state/wu-schema.ts +0 -1139
  204. package/packs/software-delivery/src/state/wu-state-schema.ts +0 -255
  205. package/packs/software-delivery/src/state/wu-yaml.ts +0 -338
  206. package/packs/software-delivery/tool-impl/agent-tools.ts +0 -263
  207. package/packs/software-delivery/tool-impl/delegation-tools.ts +0 -66
  208. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +0 -219
  209. package/packs/software-delivery/tool-impl/git-runner.ts +0 -113
  210. package/packs/software-delivery/tool-impl/git-tools.ts +0 -316
  211. package/packs/software-delivery/tool-impl/index.ts +0 -15
  212. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +0 -720
  213. package/packs/software-delivery/tool-impl/lane-lock.ts +0 -246
  214. package/packs/software-delivery/tool-impl/memory-tools.ts +0 -470
  215. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +0 -21
  216. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +0 -329
  217. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +0 -687
  218. package/packs/software-delivery/tool-impl/worker-loader.ts +0 -52
  219. package/packs/software-delivery/tool-impl/worktree-tools.ts +0 -46
  220. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +0 -807
  221. package/packs/software-delivery/tools/delegation-tools.ts +0 -23
  222. package/packs/software-delivery/tools/git-tools.ts +0 -55
  223. package/packs/software-delivery/tools/index.ts +0 -8
  224. package/packs/software-delivery/tools/lane-lock-tool.ts +0 -37
  225. package/packs/software-delivery/tools/types.ts +0 -71
  226. package/packs/software-delivery/tools/worktree-tools.ts +0 -49
  227. package/packs/software-delivery/vitest.config.ts +0 -11
package/README.md CHANGED
@@ -171,46 +171,48 @@ This package provides CLI commands for the LumenFlow workflow framework, includi
171
171
 
172
172
  ### System & Setup
173
173
 
174
- | Command | Description |
175
- | -------------------------- | --------------------------------------------------------------------------- |
176
- | `backlog-prune` | Clean stale backlog entries |
177
- | `cloud-connect` | Connect workspace.yaml to cloud control plane |
178
- | `config-get` | Read and display a value from workspace.yaml software_delivery |
179
- | `config-set` | Safely update workspace.yaml software_delivery via micro-worktree |
180
- | `distribution-preflight` | Audit consumer repos for @lumenflow/\* privatization readiness |
181
- | `init-plan` | Link plan to initiative (alias) |
182
- | `lumenflow` | Initialize LumenFlow in a project |
183
- | `lumenflow-commands` | List all available CLI commands |
184
- | `lumenflow-disable` | Flip enforcement flags to false and regenerate hooks as no-ops (reversible) |
185
- | `lumenflow-docs-sync` | Refresh core docs, onboarding docs, and supported vendor assets (alias) |
186
- | `lumenflow-doctor` | Diagnose LumenFlow configuration |
187
- | `lumenflow-enable` | Re-enable enforcement after lumenflow:disable (restores prior state) |
188
- | `lumenflow-init` | Initialize LumenFlow in a project (alias) |
189
- | `lumenflow-integrate` | Generate enforcement hooks for client |
190
- | `lumenflow-onboard` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
191
- | `lumenflow-release` | Run release workflow |
192
- | `lumenflow-sync-templates` | Sync templates to project |
193
- | `lumenflow-uninstall` | Remove LumenFlow-generated files (dry-run by default; requires --confirm) |
194
- | `lumenflow-upgrade` | Upgrade LumenFlow packages |
195
- | `onboard` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
196
- | `pack-author` | Author a secure domain pack from templates |
197
- | `pack-hash` | Compute integrity hash for a domain pack |
198
- | `pack-install` | Install a domain pack into workspace |
199
- | `pack-publish` | Publish a domain pack to a registry |
200
- | `pack-scaffold` | Scaffold a new domain pack |
201
- | `pack-search` | Search for domain packs in a registry |
202
- | `pack-validate` | Validate a domain pack for integrity |
203
- | `plan-create` | Create a new plan |
204
- | `plan-edit` | Edit plan content |
205
- | `plan-link` | Link plan to WU or initiative |
206
- | `plan-promote` | Promote plan to WU |
207
- | `state-bootstrap` | Bootstrap state store |
208
- | `state-cleanup` | Clean up stale state data |
209
- | `state-doctor` | Diagnose state store issues |
210
- | `state-emit` | Emit corrective event to state store (WU-2241) |
211
- | `sync-templates` | Sync templates to project (alias) |
212
- | `templates-sync` | Sync templates to project (alias) |
213
- | `workspace-init` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
174
+ | Command | Description |
175
+ | -------------------------- | ---------------------------------------------------------------------------------------------------------- |
176
+ | `backlog-prune` | Clean stale backlog entries |
177
+ | `cloud-connect` | Connect workspace.yaml to cloud control plane |
178
+ | `config-get` | Read and display a value from workspace.yaml software_delivery |
179
+ | `config-set` | Safely update workspace.yaml software_delivery via micro-worktree |
180
+ | `db-journal-recover` | Detect drizzle journal collisions and offer a safe-resequence path (dry-run by default; --confirm applies) |
181
+ | `distribution-preflight` | Audit consumer repos for @lumenflow/\* privatization readiness |
182
+ | `init-plan` | Link plan to initiative (alias) |
183
+ | `lumenflow` | Initialize LumenFlow in a project |
184
+ | `lumenflow-commands` | List all available CLI commands |
185
+ | `lumenflow-disable` | Flip enforcement flags to false and regenerate hooks as no-ops (reversible) |
186
+ | `lumenflow-docs-sync` | Refresh core docs, onboarding docs, and supported vendor assets (alias) |
187
+ | `lumenflow-doctor` | Diagnose LumenFlow configuration |
188
+ | `lumenflow-enable` | Re-enable enforcement after lumenflow:disable (restores prior state) |
189
+ | `lumenflow-init` | Initialize LumenFlow in a project (alias) |
190
+ | `lumenflow-integrate` | Generate enforcement hooks for client |
191
+ | `lumenflow-onboard` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
192
+ | `lumenflow-release` | Run release workflow |
193
+ | `lumenflow-setup-prereqs` | Surface external prerequisites (e.g. Supabase CLI) at end of pnpm setup |
194
+ | `lumenflow-sync-templates` | Sync templates to project |
195
+ | `lumenflow-uninstall` | Remove LumenFlow-generated files (dry-run by default; requires --confirm) |
196
+ | `lumenflow-upgrade` | Upgrade LumenFlow packages |
197
+ | `onboard` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
198
+ | `pack-author` | Author a secure domain pack from templates |
199
+ | `pack-hash` | Compute integrity hash for a domain pack |
200
+ | `pack-install` | Install a domain pack into workspace |
201
+ | `pack-publish` | Publish a domain pack to a registry |
202
+ | `pack-scaffold` | Scaffold a new domain pack |
203
+ | `pack-search` | Search for domain packs in a registry |
204
+ | `pack-validate` | Validate a domain pack for integrity |
205
+ | `plan-create` | Create a new plan |
206
+ | `plan-edit` | Edit plan content |
207
+ | `plan-link` | Link plan to WU or initiative |
208
+ | `plan-promote` | Promote plan to WU |
209
+ | `state-bootstrap` | Bootstrap state store |
210
+ | `state-cleanup` | Clean up stale state data |
211
+ | `state-doctor` | Diagnose state store issues |
212
+ | `state-emit` | Emit corrective event to state store (WU-2241) |
213
+ | `sync-templates` | Sync templates to project (alias) |
214
+ | `templates-sync` | Sync templates to project (alias) |
215
+ | `workspace-init` | Legacy entrypoint; use "npx lumenflow" for bootstrap-all onboarding |
214
216
 
215
217
  ### File & Git Operations
216
218
 
@@ -0,0 +1,400 @@
1
+ #!/usr/bin/env node
2
+ // Copyright (c) 2026 Hellmai Ltd
3
+ // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
4
+ /**
5
+ * @file db-journal-recover.ts
6
+ * WU-2945: First-class CLI command for drizzle journal collision recovery.
7
+ *
8
+ * Background: cloud INIT-105 hit drizzle journal collisions in 4+ WUs where
9
+ * two snapshots shared the same prevId (chain fork). drizzle-kit generate has
10
+ * no recovery story; agents resorted to manual journal surgery and skip-gates.
11
+ * This command surfaces the recovery as a documented, scriptable, idempotent
12
+ * primitive.
13
+ *
14
+ * Detection: parses drizzle/meta/_journal.json + snapshot files. Reports a
15
+ * collision when two or more snapshots share a prevId OR when journal entries
16
+ * have duplicate idx values.
17
+ *
18
+ * Recovery: re-links snapshots in sorted-idx order so each snapshot's prevId
19
+ * equals the previous snapshot's id; re-emits journal entries with sequential
20
+ * idx values. Idempotent: re-running on a healthy chain is a no-op.
21
+ *
22
+ * Safety: dry-run is the default. --confirm is required to write to disk.
23
+ * Every actual rewrite emits an audit log under .lumenflow/db-recovery/.
24
+ *
25
+ * Usage:
26
+ * pnpm db:journal-recover # dry-run (default), prints plan
27
+ * pnpm db:journal-recover --confirm # apply plan, write audit log
28
+ * pnpm db:journal-recover --drizzle-dir <path> # custom drizzle dir
29
+ * pnpm db:journal-recover --help
30
+ */
31
+ import { readFile, writeFile, mkdir, readdir } from 'node:fs/promises';
32
+ import { existsSync } from 'node:fs';
33
+ import path from 'node:path';
34
+ import { findProjectRoot } from '@lumenflow/core/config';
35
+ import { die, createError, ErrorCodes } from '@lumenflow/core/error-handler';
36
+ import { runCLI } from './cli-entry-point.js';
37
+ const LOG_PREFIX = '[db:journal-recover]';
38
+ const ARG_HELP = '--help';
39
+ const ARG_DRY_RUN = '--dry-run';
40
+ const ARG_CONFIRM = '--confirm';
41
+ const ARG_JSON = '--json';
42
+ const ARG_DRIZZLE_DIR = '--drizzle-dir';
43
+ const DEFAULT_DRIZZLE_DIR = 'drizzle';
44
+ const META_DIR = 'meta';
45
+ const JOURNAL_FILENAME = '_journal.json';
46
+ const SNAPSHOT_SUFFIX = '_snapshot.json';
47
+ const AUDIT_LOG_DIR = '.lumenflow/db-recovery';
48
+ const SNAPSHOT_NAME_PATTERN = /^(\d+)_snapshot\.json$/;
49
+ export function parseJournalRecoverArgs(argv) {
50
+ const help = argv.includes(ARG_HELP);
51
+ const json = argv.includes(ARG_JSON);
52
+ // dry-run is default; --confirm switches to write mode.
53
+ const confirm = argv.includes(ARG_CONFIRM);
54
+ const dirIdx = argv.indexOf(ARG_DRIZZLE_DIR);
55
+ const drizzleDir = dirIdx >= 0 && dirIdx + 1 < argv.length ? argv[dirIdx + 1] : DEFAULT_DRIZZLE_DIR;
56
+ // --dry-run is accepted as an explicit no-op for clarity in scripts.
57
+ void argv.includes(ARG_DRY_RUN);
58
+ return { help, json, confirm, drizzleDir };
59
+ }
60
+ export function getJournalRecoverHelpText() {
61
+ return `Usage: pnpm db:journal-recover [options]
62
+
63
+ Detect drizzle journal collisions and offer a safe-resequence path.
64
+
65
+ A collision is two or more snapshots sharing the same prevId (chain fork) or
66
+ journal entries sharing the same idx. Recovery re-links snapshots in sorted-idx
67
+ order so each snapshot's prevId matches the previous snapshot's id, and
68
+ re-emits journal entries with sequential idx values.
69
+
70
+ Default mode is dry-run (no files modified). Use --confirm to apply the plan;
71
+ an audit log is written under ${AUDIT_LOG_DIR}/<timestamp>.log.
72
+
73
+ Idempotent: re-running on a healthy chain is a no-op.
74
+
75
+ Options:
76
+ ${ARG_DRIZZLE_DIR} <path> Drizzle directory (default: ${DEFAULT_DRIZZLE_DIR})
77
+ ${ARG_DRY_RUN} Show planned resequence without writing (default)
78
+ ${ARG_CONFIRM} Apply plan, write files, emit audit log
79
+ ${ARG_JSON} Emit machine-readable JSON instead of text
80
+ ${ARG_HELP} Show this help text and exit
81
+
82
+ Examples:
83
+ pnpm db:journal-recover
84
+ pnpm db:journal-recover --drizzle-dir packages/db/drizzle
85
+ pnpm db:journal-recover --confirm
86
+ `;
87
+ }
88
+ /**
89
+ * Parse the numeric idx prefix from a snapshot filename.
90
+ * Returns null if filename doesn't match the expected pattern.
91
+ */
92
+ export function parseSnapshotIdx(filename) {
93
+ const match = SNAPSHOT_NAME_PATTERN.exec(filename);
94
+ if (!match)
95
+ return null;
96
+ return Number.parseInt(match[1], 10);
97
+ }
98
+ /**
99
+ * Detect collisions in a snapshot/journal pair.
100
+ * Pure function: takes parsed inputs, returns a CollisionReport.
101
+ */
102
+ export function detectCollisions(snapshots, journal) {
103
+ const prevIdGroups = new Map();
104
+ const snapshotIdxGroups = new Map();
105
+ for (const snap of snapshots) {
106
+ const list = prevIdGroups.get(snap.doc.prevId) ?? [];
107
+ list.push(snap.filename);
108
+ prevIdGroups.set(snap.doc.prevId, list);
109
+ const idxList = snapshotIdxGroups.get(snap.idx) ?? [];
110
+ idxList.push(snap.filename);
111
+ snapshotIdxGroups.set(snap.idx, idxList);
112
+ }
113
+ const duplicatePrevIds = [];
114
+ for (const [prevId, filenames] of prevIdGroups) {
115
+ if (filenames.length > 1)
116
+ duplicatePrevIds.push({ prevId, filenames });
117
+ }
118
+ const duplicateSnapshotIdx = [];
119
+ for (const [idx, filenames] of snapshotIdxGroups) {
120
+ if (filenames.length > 1)
121
+ duplicateSnapshotIdx.push({ idx, filenames });
122
+ }
123
+ const duplicateIdx = [];
124
+ if (journal) {
125
+ const journalIdxGroups = new Map();
126
+ for (const entry of journal.entries) {
127
+ const tags = journalIdxGroups.get(entry.idx) ?? [];
128
+ tags.push(entry.tag);
129
+ journalIdxGroups.set(entry.idx, tags);
130
+ }
131
+ for (const [idx, tags] of journalIdxGroups) {
132
+ if (tags.length > 1)
133
+ duplicateIdx.push({ idx, tags });
134
+ }
135
+ }
136
+ return { duplicatePrevIds, duplicateIdx, duplicateSnapshotIdx };
137
+ }
138
+ /**
139
+ * Build a recovery plan from snapshots + journal.
140
+ *
141
+ * Strategy: sort snapshots by numeric idx, then re-link prevId so each
142
+ * snapshot's prevId equals the previous snapshot's id (or the canonical
143
+ * empty-uuid for idx=0 if no first prevId is set). The first snapshot's
144
+ * prevId is preserved (it points at drizzle's initial empty-uuid sentinel).
145
+ */
146
+ export function buildRecoveryPlan(snapshots, journal) {
147
+ const collisions = detectCollisions(snapshots, journal);
148
+ const sorted = [...snapshots].sort((a, b) => a.idx - b.idx);
149
+ const steps = [];
150
+ let previousId = null;
151
+ for (const snap of sorted) {
152
+ const prevIdBefore = snap.doc.prevId;
153
+ // First snapshot keeps its existing prevId (drizzle's empty-uuid sentinel).
154
+ const prevIdAfter = previousId === null ? prevIdBefore : previousId;
155
+ steps.push({
156
+ filename: snap.filename,
157
+ idx: snap.idx,
158
+ prevIdBefore,
159
+ prevIdAfter,
160
+ changed: prevIdBefore !== prevIdAfter,
161
+ });
162
+ previousId = snap.doc.id;
163
+ }
164
+ const journalRewriteRequired = collisions.duplicateIdx.length > 0 ||
165
+ (journal !== null && needsJournalResequence(journal, sorted));
166
+ const alreadyHealthy = collisions.duplicatePrevIds.length === 0 &&
167
+ collisions.duplicateIdx.length === 0 &&
168
+ collisions.duplicateSnapshotIdx.length === 0 &&
169
+ steps.every((s) => !s.changed) &&
170
+ !journalRewriteRequired;
171
+ return { collisions, steps, journalRewriteRequired, alreadyHealthy };
172
+ }
173
+ function needsJournalResequence(journal, sorted) {
174
+ if (journal.entries.length !== sorted.length)
175
+ return true;
176
+ for (let i = 0; i < sorted.length; i++) {
177
+ if (journal.entries[i].idx !== i)
178
+ return true;
179
+ }
180
+ return false;
181
+ }
182
+ /**
183
+ * Re-emit the journal with sequential idx values (0..n-1) preserving the
184
+ * existing tag order matched against the sorted snapshots by tag prefix.
185
+ */
186
+ export function resequenceJournal(journal, sorted) {
187
+ // Map snapshot filename prefix (e.g. '0023') to journal entry by tag prefix.
188
+ const taggedByPrefix = new Map();
189
+ for (const entry of journal.entries) {
190
+ const prefix = entry.tag.split('_')[0];
191
+ taggedByPrefix.set(prefix, entry);
192
+ }
193
+ const newEntries = sorted.map((snap, idx) => {
194
+ const prefix = snap.filename.split('_')[0];
195
+ const original = taggedByPrefix.get(prefix);
196
+ if (!original) {
197
+ throw createError(ErrorCodes.VALIDATION_ERROR, `${LOG_PREFIX} Cannot rebuild journal: snapshot ${snap.filename} has no matching journal entry. ` +
198
+ `Run drizzle-kit generate to regenerate the journal, then retry.`, { filename: snap.filename });
199
+ }
200
+ return { ...original, idx };
201
+ });
202
+ return { ...journal, entries: newEntries };
203
+ }
204
+ /**
205
+ * Format a recovery plan as a human-readable string.
206
+ */
207
+ export function formatPlan(plan, drizzleDirRel) {
208
+ const lines = [];
209
+ lines.push(`${LOG_PREFIX} Drizzle directory: ${drizzleDirRel}`);
210
+ if (plan.alreadyHealthy) {
211
+ lines.push(`${LOG_PREFIX} ✅ Journal is healthy. Nothing to do.`);
212
+ return lines.join('\n');
213
+ }
214
+ if (plan.collisions.duplicatePrevIds.length > 0) {
215
+ lines.push('');
216
+ lines.push('Collisions: snapshots sharing the same prevId:');
217
+ for (const entry of plan.collisions.duplicatePrevIds) {
218
+ lines.push(` prevId=${entry.prevId}`);
219
+ for (const file of entry.filenames)
220
+ lines.push(` - ${file}`);
221
+ }
222
+ }
223
+ if (plan.collisions.duplicateIdx.length > 0) {
224
+ lines.push('');
225
+ lines.push('Collisions: journal entries with duplicate idx:');
226
+ for (const entry of plan.collisions.duplicateIdx) {
227
+ lines.push(` idx=${entry.idx} tags=${entry.tags.join(', ')}`);
228
+ }
229
+ }
230
+ if (plan.collisions.duplicateSnapshotIdx.length > 0) {
231
+ lines.push('');
232
+ lines.push('Collisions: snapshot files with duplicate numeric idx:');
233
+ for (const entry of plan.collisions.duplicateSnapshotIdx) {
234
+ lines.push(` idx=${entry.idx}`);
235
+ for (const file of entry.filenames)
236
+ lines.push(` - ${file}`);
237
+ }
238
+ }
239
+ const changed = plan.steps.filter((s) => s.changed);
240
+ if (changed.length > 0) {
241
+ lines.push('');
242
+ lines.push('Planned snapshot prevId rewrites:');
243
+ for (const step of changed) {
244
+ lines.push(` ${step.filename}: ${step.prevIdBefore} -> ${step.prevIdAfter}`);
245
+ }
246
+ }
247
+ if (plan.journalRewriteRequired) {
248
+ lines.push('');
249
+ lines.push(`Planned journal rewrite: idx values will be resequenced 0..${plan.steps.length - 1}`);
250
+ }
251
+ lines.push('');
252
+ lines.push('Run with --confirm to apply. Audit log will be written to');
253
+ lines.push(` ${AUDIT_LOG_DIR}/<timestamp>.log`);
254
+ return lines.join('\n');
255
+ }
256
+ /**
257
+ * Read snapshot files from the drizzle meta directory.
258
+ */
259
+ export async function loadSnapshots(metaDir) {
260
+ if (!existsSync(metaDir))
261
+ return [];
262
+ const entries = await readdir(metaDir);
263
+ const snapshotFiles = entries.filter((e) => e.endsWith(SNAPSHOT_SUFFIX));
264
+ const result = [];
265
+ for (const filename of snapshotFiles) {
266
+ const idx = parseSnapshotIdx(filename);
267
+ if (idx === null)
268
+ continue;
269
+ const raw = await readFile(path.join(metaDir, filename), 'utf8');
270
+ const doc = JSON.parse(raw);
271
+ if (typeof doc.id !== 'string' || typeof doc.prevId !== 'string') {
272
+ throw createError(ErrorCodes.VALIDATION_ERROR, `${LOG_PREFIX} ${filename} is missing id/prevId fields. ` +
273
+ `Expected drizzle snapshot shape; got: ${Object.keys(doc).join(', ')}`, { filename, keys: Object.keys(doc) });
274
+ }
275
+ result.push({ filename, idx, doc });
276
+ }
277
+ return result;
278
+ }
279
+ /**
280
+ * Read the journal file from the drizzle meta directory.
281
+ */
282
+ export async function loadJournal(metaDir) {
283
+ const journalPath = path.join(metaDir, JOURNAL_FILENAME);
284
+ if (!existsSync(journalPath))
285
+ return null;
286
+ const raw = await readFile(journalPath, 'utf8');
287
+ return JSON.parse(raw);
288
+ }
289
+ /**
290
+ * Apply a recovery plan to disk. Idempotent: if the plan changes nothing,
291
+ * no files are touched and no audit log is written.
292
+ *
293
+ * Returns the list of files that were written.
294
+ */
295
+ export async function applyRecoveryPlan(params) {
296
+ const { metaDir, snapshots, journal, plan, auditDir, now } = params;
297
+ if (plan.alreadyHealthy)
298
+ return [];
299
+ const written = [];
300
+ // Rewrite snapshots that need their prevId updated.
301
+ const snapByFilename = new Map(snapshots.map((s) => [s.filename, s]));
302
+ for (const step of plan.steps) {
303
+ if (!step.changed)
304
+ continue;
305
+ const snap = snapByFilename.get(step.filename);
306
+ if (!snap)
307
+ continue;
308
+ const newDoc = { ...snap.doc, prevId: step.prevIdAfter };
309
+ const filePath = path.join(metaDir, step.filename);
310
+ await writeFile(filePath, `${JSON.stringify(newDoc, null, 2)}\n`, 'utf8');
311
+ written.push(filePath);
312
+ }
313
+ // Resequence journal if needed.
314
+ if (plan.journalRewriteRequired && journal) {
315
+ const sorted = [...snapshots].sort((a, b) => a.idx - b.idx);
316
+ const newJournal = resequenceJournal(journal, sorted);
317
+ const journalPath = path.join(metaDir, JOURNAL_FILENAME);
318
+ await writeFile(journalPath, `${JSON.stringify(newJournal, null, 2)}\n`, 'utf8');
319
+ written.push(journalPath);
320
+ }
321
+ // Audit log.
322
+ const timestamp = (now ? now() : new Date()).toISOString().replace(/[:.]/g, '-');
323
+ await mkdir(auditDir, { recursive: true });
324
+ const auditPath = path.join(auditDir, `${timestamp}.log`);
325
+ await writeFile(auditPath, formatAuditLog(plan, written), 'utf8');
326
+ written.push(auditPath);
327
+ return written;
328
+ }
329
+ export function formatAuditLog(plan, writtenFiles) {
330
+ const lines = [];
331
+ lines.push(`db:journal-recover audit log`);
332
+ lines.push(`generated: ${new Date().toISOString()}`);
333
+ lines.push('');
334
+ lines.push('Collisions detected:');
335
+ lines.push(` duplicatePrevIds: ${plan.collisions.duplicatePrevIds.length}`);
336
+ lines.push(` duplicateIdx: ${plan.collisions.duplicateIdx.length}`);
337
+ lines.push(` duplicateSnapshotIdx: ${plan.collisions.duplicateSnapshotIdx.length}`);
338
+ lines.push('');
339
+ lines.push('Steps:');
340
+ for (const step of plan.steps) {
341
+ if (!step.changed)
342
+ continue;
343
+ lines.push(` ${step.filename}: prevId ${step.prevIdBefore} -> ${step.prevIdAfter}`);
344
+ }
345
+ if (plan.journalRewriteRequired) {
346
+ lines.push(' journal: idx resequenced');
347
+ }
348
+ lines.push('');
349
+ lines.push('Files written:');
350
+ for (const file of writtenFiles)
351
+ lines.push(` ${file}`);
352
+ return `${lines.join('\n')}\n`;
353
+ }
354
+ async function main() {
355
+ const args = parseJournalRecoverArgs(process.argv.slice(2));
356
+ if (args.help) {
357
+ console.log(getJournalRecoverHelpText());
358
+ return;
359
+ }
360
+ const projectRoot = findProjectRoot();
361
+ const drizzleDirAbs = path.isAbsolute(args.drizzleDir)
362
+ ? args.drizzleDir
363
+ : path.join(projectRoot, args.drizzleDir);
364
+ const metaDir = path.join(drizzleDirAbs, META_DIR);
365
+ if (!existsSync(metaDir)) {
366
+ die(`${LOG_PREFIX} No drizzle meta directory at ${metaDir}.\n\n` +
367
+ `Expected ${args.drizzleDir}/${META_DIR}/${JOURNAL_FILENAME}. ` +
368
+ `Pass ${ARG_DRIZZLE_DIR} <path> if your drizzle output lives elsewhere.`);
369
+ }
370
+ const snapshots = await loadSnapshots(metaDir);
371
+ const journal = await loadJournal(metaDir);
372
+ const plan = buildRecoveryPlan(snapshots, journal);
373
+ if (args.json) {
374
+ console.log(JSON.stringify(plan, null, 2));
375
+ }
376
+ else {
377
+ const drizzleDirRel = path.relative(projectRoot, drizzleDirAbs) || args.drizzleDir;
378
+ console.log(formatPlan(plan, drizzleDirRel));
379
+ }
380
+ if (!args.confirm)
381
+ return;
382
+ if (plan.alreadyHealthy)
383
+ return;
384
+ const auditDir = path.join(projectRoot, AUDIT_LOG_DIR);
385
+ const written = await applyRecoveryPlan({
386
+ metaDir,
387
+ snapshots,
388
+ journal,
389
+ plan,
390
+ auditDir,
391
+ });
392
+ console.log('');
393
+ console.log(`${LOG_PREFIX} ✅ Wrote ${written.length} file(s):`);
394
+ for (const file of written)
395
+ console.log(` ${path.relative(projectRoot, file)}`);
396
+ }
397
+ if (import.meta.main) {
398
+ void runCLI(main);
399
+ }
400
+ //# sourceMappingURL=db-journal-recover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-journal-recover.js","sourceRoot":"","sources":["../src/db-journal-recover.ts"],"names":[],"mappings":"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"}
package/dist/docs-sync.js CHANGED
@@ -337,11 +337,16 @@ const SKILL_TEMPLATE_PATHS = {
337
337
  * User-created skills outside this list are never touched.
338
338
  */
339
339
  export const RESERVED_SKILL_NAMES = Object.keys(SKILL_TEMPLATE_PATHS);
340
+ function unwrapBootstrapBlockContent(processedContent) {
341
+ const extraction = extractMergeBlock(processedContent);
342
+ return extraction.found ? (extraction.content ?? '') : processedContent;
343
+ }
340
344
  function mergeBootstrapContent(filePath, processedContent, targetDir, result) {
341
345
  const relativePath = path.relative(targetDir, filePath).split(path.sep).join('/');
346
+ const blockContent = unwrapBootstrapBlockContent(processedContent);
342
347
  if (fs.existsSync(filePath)) {
343
348
  const existingContent = fs.readFileSync(filePath, 'utf-8');
344
- const migratedLegacyContent = migrateLegacyBootstrapScaffold(existingContent, processedContent);
349
+ const migratedLegacyContent = migrateLegacyBootstrapScaffold(existingContent, blockContent);
345
350
  if (migratedLegacyContent !== null) {
346
351
  if (migratedLegacyContent === existingContent) {
347
352
  result.skipped.push(relativePath);
@@ -352,7 +357,7 @@ function mergeBootstrapContent(filePath, processedContent, targetDir, result) {
352
357
  }
353
358
  return;
354
359
  }
355
- const mergeResult = updateMergeBlock(existingContent, processedContent);
360
+ const mergeResult = updateMergeBlock(existingContent, blockContent);
356
361
  if (mergeResult.updated) {
357
362
  fs.writeFileSync(filePath, mergeResult.content);
358
363
  result.created.push(relativePath);
@@ -366,7 +371,7 @@ function mergeBootstrapContent(filePath, processedContent, targetDir, result) {
366
371
  }
367
372
  return;
368
373
  }
369
- const wrappedContent = `${MARKERS.START}\n${processedContent}\n${MARKERS.END}\n`;
374
+ const wrappedContent = `${MARKERS.START}\n${blockContent}\n${MARKERS.END}\n`;
370
375
  const parentDir = path.dirname(filePath);
371
376
  if (!fs.existsSync(parentDir)) {
372
377
  fs.mkdirSync(parentDir, { recursive: true });