@lumenflow/cli 3.1.2 → 3.1.3

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 (389) hide show
  1. package/README.md +36 -35
  2. package/dist/agent-issues-query.js +13 -8
  3. package/dist/agent-log-issue.js +15 -4
  4. package/dist/agent-session-end.js +15 -4
  5. package/dist/agent-session.js +18 -6
  6. package/dist/backlog-prune.js +1 -1
  7. package/dist/commands/integrate.js +32 -18
  8. package/dist/config-get.js +27 -15
  9. package/dist/config-set.js +104 -37
  10. package/dist/delegation-list.js +1 -1
  11. package/dist/doctor.js +19 -13
  12. package/dist/file-delete.js +1 -1
  13. package/dist/file-edit.js +1 -1
  14. package/dist/file-read.js +1 -1
  15. package/dist/file-write.js +1 -1
  16. package/dist/flow-bottlenecks.js +1 -1
  17. package/dist/flow-report.js +10 -9
  18. package/dist/gates.js +3 -2
  19. package/dist/git-branch.js +1 -1
  20. package/dist/git-diff.js +1 -1
  21. package/dist/git-log.js +1 -1
  22. package/dist/init.js +238 -42
  23. package/dist/initiative-add-wu.js +1 -1
  24. package/dist/initiative-bulk-assign-wus.js +1 -1
  25. package/dist/initiative-create.js +2 -2
  26. package/dist/initiative-edit.js +1 -1
  27. package/dist/initiative-list.js +1 -1
  28. package/dist/initiative-plan.js +1 -3
  29. package/dist/initiative-status.js +47 -6
  30. package/dist/lane-edit.js +19 -10
  31. package/dist/lane-health.js +13 -24
  32. package/dist/lane-lock.js +4 -5
  33. package/dist/lane-setup.js +5 -5
  34. package/dist/lane-status.js +4 -5
  35. package/dist/lane-suggest.js +9 -7
  36. package/dist/lane-validate.js +4 -5
  37. package/dist/lumenflow-upgrade.js +17 -11
  38. package/dist/mem-checkpoint.js +1 -1
  39. package/dist/mem-cleanup.js +6 -23
  40. package/dist/mem-context.js +1 -1
  41. package/dist/mem-create.js +1 -1
  42. package/dist/mem-delete.js +1 -1
  43. package/dist/mem-export.js +1 -1
  44. package/dist/mem-inbox.js +1 -1
  45. package/dist/mem-init.js +1 -1
  46. package/dist/mem-ready.js +1 -1
  47. package/dist/mem-recover.js +1 -1
  48. package/dist/mem-signal.js +1 -1
  49. package/dist/mem-start.js +1 -1
  50. package/dist/mem-summarize.js +8 -7
  51. package/dist/mem-triage.js +7 -5
  52. package/dist/metrics-cli.js +1 -1
  53. package/dist/metrics-snapshot.js +1 -1
  54. package/dist/onboard.js +295 -120
  55. package/dist/orchestrate-init-status.js +12 -7
  56. package/dist/orchestrate-initiative.js +23 -12
  57. package/dist/orchestrate-monitor.js +20 -8
  58. package/dist/pack-scaffold.js +1 -1
  59. package/dist/plan-create.js +1 -3
  60. package/dist/plan-edit.js +1 -3
  61. package/dist/plan-link.js +1 -3
  62. package/dist/plan-promote.js +1 -3
  63. package/dist/release.js +1 -3
  64. package/dist/signal-cleanup.js +4 -18
  65. package/dist/state-bootstrap.js +11 -8
  66. package/dist/state-cleanup.js +5 -19
  67. package/dist/state-doctor.js +213 -9
  68. package/dist/task-claim.js +1 -1
  69. package/dist/validate.js +1 -1
  70. package/dist/workspace-init.js +61 -61
  71. package/dist/wu-block.js +1 -1
  72. package/dist/wu-brief.js +1 -1
  73. package/dist/wu-claim.js +1 -1
  74. package/dist/wu-cleanup.js +1 -1
  75. package/dist/wu-create.js +3 -3
  76. package/dist/wu-delegate.js +1 -1
  77. package/dist/wu-deps.js +1 -1
  78. package/dist/wu-done.js +66 -34
  79. package/dist/wu-edit.js +1 -1
  80. package/dist/wu-infer-lane.js +1 -1
  81. package/dist/wu-preflight.js +1 -1
  82. package/dist/wu-prep.js +1 -1
  83. package/dist/wu-proto.js +1 -1
  84. package/dist/wu-prune.js +1 -1
  85. package/dist/wu-recover.js +1 -1
  86. package/dist/wu-release.js +1 -1
  87. package/dist/wu-repair.js +1 -1
  88. package/dist/wu-sandbox.js +40 -27
  89. package/dist/wu-status.js +1 -1
  90. package/dist/wu-unblock.js +1 -1
  91. package/dist/wu-unlock-lane.js +1 -1
  92. package/dist/wu-validate.js +1 -1
  93. package/package.json +12 -8
  94. package/packs/software-delivery/constants.ts +10 -0
  95. package/packs/software-delivery/extensions.ts +140 -0
  96. package/packs/software-delivery/gate-policies.ts +134 -0
  97. package/packs/software-delivery/index.ts +8 -0
  98. package/packs/software-delivery/manifest-schema.ts +236 -0
  99. package/packs/software-delivery/manifest.ts +417 -0
  100. package/packs/software-delivery/manifest.yaml +711 -0
  101. package/packs/software-delivery/pack-registration.ts +113 -0
  102. package/packs/software-delivery/tool-impl/agent-tools.ts +263 -0
  103. package/packs/software-delivery/tool-impl/delegation-tools.ts +66 -0
  104. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +219 -0
  105. package/packs/software-delivery/tool-impl/git-runner.ts +113 -0
  106. package/packs/software-delivery/tool-impl/git-tools.ts +316 -0
  107. package/packs/software-delivery/tool-impl/index.ts +15 -0
  108. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +720 -0
  109. package/packs/software-delivery/tool-impl/lane-lock.ts +246 -0
  110. package/packs/software-delivery/tool-impl/memory-tools.ts +415 -0
  111. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +21 -0
  112. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +328 -0
  113. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +687 -0
  114. package/packs/software-delivery/tool-impl/worker-loader.ts +52 -0
  115. package/packs/software-delivery/tool-impl/worktree-tools.ts +46 -0
  116. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +759 -0
  117. package/packs/software-delivery/tools/delegation-tools.ts +23 -0
  118. package/packs/software-delivery/tools/git-tools.ts +55 -0
  119. package/packs/software-delivery/tools/index.ts +8 -0
  120. package/packs/software-delivery/tools/lane-lock-tool.ts +37 -0
  121. package/packs/software-delivery/tools/types.ts +71 -0
  122. package/packs/software-delivery/tools/worktree-tools.ts +49 -0
  123. package/templates/core/LUMENFLOW.md.template +3 -3
  124. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
  125. package/templates/core/ai/onboarding/lumenflow-force-usage.md.template +1 -1
  126. package/templates/core/ai/onboarding/quick-ref-commands.md.template +5 -5
  127. package/templates/core/ai/onboarding/starting-prompt.md.template +3 -3
  128. package/templates/core/ai/onboarding/vendor-support.md.template +1 -1
  129. package/templates/core/ai/onboarding/wu-create-checklist.md.template +1 -1
  130. package/dist/agent-issues-query.js.map +0 -1
  131. package/dist/agent-log-issue.js.map +0 -1
  132. package/dist/agent-session-end.js.map +0 -1
  133. package/dist/agent-session.js.map +0 -1
  134. package/dist/backlog-prune.js.map +0 -1
  135. package/dist/cli-entry-point.js +0 -149
  136. package/dist/cli-entry-point.js.map +0 -1
  137. package/dist/commands/integrate.js.map +0 -1
  138. package/dist/commands.js.map +0 -1
  139. package/dist/config-get.js.map +0 -1
  140. package/dist/config-set.js.map +0 -1
  141. package/dist/delegation-list.js.map +0 -1
  142. package/dist/deps-add.js +0 -259
  143. package/dist/deps-add.js.map +0 -1
  144. package/dist/deps-remove.js +0 -105
  145. package/dist/deps-remove.js.map +0 -1
  146. package/dist/docs-sync.js.map +0 -1
  147. package/dist/doctor.js.map +0 -1
  148. package/dist/file-delete.js.map +0 -1
  149. package/dist/file-edit.js.map +0 -1
  150. package/dist/file-read.js.map +0 -1
  151. package/dist/file-write.js.map +0 -1
  152. package/dist/flow-bottlenecks.js.map +0 -1
  153. package/dist/flow-report.js.map +0 -1
  154. package/dist/formatters.js +0 -151
  155. package/dist/formatters.js.map +0 -1
  156. package/dist/gate-defaults.js +0 -131
  157. package/dist/gate-defaults.js.map +0 -1
  158. package/dist/gate-registry.js +0 -73
  159. package/dist/gate-registry.js.map +0 -1
  160. package/dist/gates-graceful-degradation.js +0 -153
  161. package/dist/gates-graceful-degradation.js.map +0 -1
  162. package/dist/gates-plan-resolvers.js +0 -152
  163. package/dist/gates-plan-resolvers.js.map +0 -1
  164. package/dist/gates-runners.js +0 -509
  165. package/dist/gates-runners.js.map +0 -1
  166. package/dist/gates-types.js +0 -4
  167. package/dist/gates-types.js.map +0 -1
  168. package/dist/gates-utils.js +0 -323
  169. package/dist/gates-utils.js.map +0 -1
  170. package/dist/gates.js.map +0 -1
  171. package/dist/git-branch.js.map +0 -1
  172. package/dist/git-diff.js.map +0 -1
  173. package/dist/git-log.js.map +0 -1
  174. package/dist/git-status.js.map +0 -1
  175. package/dist/guard-locked.js +0 -172
  176. package/dist/guard-locked.js.map +0 -1
  177. package/dist/guard-main-branch.js +0 -217
  178. package/dist/guard-main-branch.js.map +0 -1
  179. package/dist/guard-worktree-commit.js +0 -163
  180. package/dist/guard-worktree-commit.js.map +0 -1
  181. package/dist/hooks/auto-checkpoint-utils.js +0 -54
  182. package/dist/hooks/auto-checkpoint-utils.js.map +0 -1
  183. package/dist/hooks/enforcement-checks.js +0 -399
  184. package/dist/hooks/enforcement-checks.js.map +0 -1
  185. package/dist/hooks/enforcement-generator.js +0 -139
  186. package/dist/hooks/enforcement-generator.js.map +0 -1
  187. package/dist/hooks/enforcement-sync.js +0 -385
  188. package/dist/hooks/enforcement-sync.js.map +0 -1
  189. package/dist/hooks/generators/auto-checkpoint.js +0 -125
  190. package/dist/hooks/generators/auto-checkpoint.js.map +0 -1
  191. package/dist/hooks/generators/enforce-worktree.js +0 -190
  192. package/dist/hooks/generators/enforce-worktree.js.map +0 -1
  193. package/dist/hooks/generators/index.js +0 -18
  194. package/dist/hooks/generators/index.js.map +0 -1
  195. package/dist/hooks/generators/pre-compact-checkpoint.js +0 -136
  196. package/dist/hooks/generators/pre-compact-checkpoint.js.map +0 -1
  197. package/dist/hooks/generators/require-wu.js +0 -117
  198. package/dist/hooks/generators/require-wu.js.map +0 -1
  199. package/dist/hooks/generators/session-start-recovery.js +0 -103
  200. package/dist/hooks/generators/session-start-recovery.js.map +0 -1
  201. package/dist/hooks/generators/signal-utils.js +0 -54
  202. package/dist/hooks/generators/signal-utils.js.map +0 -1
  203. package/dist/hooks/generators/warn-incomplete.js +0 -67
  204. package/dist/hooks/generators/warn-incomplete.js.map +0 -1
  205. package/dist/hooks/index.js +0 -10
  206. package/dist/hooks/index.js.map +0 -1
  207. package/dist/index.js.map +0 -1
  208. package/dist/init-detection.js +0 -232
  209. package/dist/init-detection.js.map +0 -1
  210. package/dist/init-lane-validation.js +0 -143
  211. package/dist/init-lane-validation.js.map +0 -1
  212. package/dist/init-scaffolding.js +0 -158
  213. package/dist/init-scaffolding.js.map +0 -1
  214. package/dist/init-templates.js +0 -1982
  215. package/dist/init-templates.js.map +0 -1
  216. package/dist/init.js.map +0 -1
  217. package/dist/initiative-add-wu.js.map +0 -1
  218. package/dist/initiative-bulk-assign-wus.js.map +0 -1
  219. package/dist/initiative-create.js.map +0 -1
  220. package/dist/initiative-edit.js.map +0 -1
  221. package/dist/initiative-list.js.map +0 -1
  222. package/dist/initiative-plan.js.map +0 -1
  223. package/dist/initiative-remove-wu.js.map +0 -1
  224. package/dist/initiative-status.js.map +0 -1
  225. package/dist/lane-edit.js.map +0 -1
  226. package/dist/lane-health.js.map +0 -1
  227. package/dist/lane-lifecycle-process.js +0 -366
  228. package/dist/lane-lifecycle-process.js.map +0 -1
  229. package/dist/lane-lock.js.map +0 -1
  230. package/dist/lane-setup.js.map +0 -1
  231. package/dist/lane-status.js.map +0 -1
  232. package/dist/lane-suggest.js.map +0 -1
  233. package/dist/lane-validate.js.map +0 -1
  234. package/dist/lifecycle-regression-harness.js +0 -181
  235. package/dist/lifecycle-regression-harness.js.map +0 -1
  236. package/dist/lumenflow-upgrade.js.map +0 -1
  237. package/dist/mem-checkpoint.js.map +0 -1
  238. package/dist/mem-cleanup.js.map +0 -1
  239. package/dist/mem-context.js.map +0 -1
  240. package/dist/mem-create.js.map +0 -1
  241. package/dist/mem-delete.js.map +0 -1
  242. package/dist/mem-export.js.map +0 -1
  243. package/dist/mem-inbox.js.map +0 -1
  244. package/dist/mem-index.js +0 -214
  245. package/dist/mem-index.js.map +0 -1
  246. package/dist/mem-init.js.map +0 -1
  247. package/dist/mem-profile.js +0 -210
  248. package/dist/mem-profile.js.map +0 -1
  249. package/dist/mem-promote.js +0 -257
  250. package/dist/mem-promote.js.map +0 -1
  251. package/dist/mem-ready.js.map +0 -1
  252. package/dist/mem-recover.js.map +0 -1
  253. package/dist/mem-signal.js.map +0 -1
  254. package/dist/mem-start.js.map +0 -1
  255. package/dist/mem-summarize.js.map +0 -1
  256. package/dist/mem-triage.js.map +0 -1
  257. package/dist/merge-block.js +0 -225
  258. package/dist/merge-block.js.map +0 -1
  259. package/dist/metrics-cli.js.map +0 -1
  260. package/dist/metrics-snapshot.js.map +0 -1
  261. package/dist/onboard.js.map +0 -1
  262. package/dist/onboarding-smoke-test.js +0 -418
  263. package/dist/onboarding-smoke-test.js.map +0 -1
  264. package/dist/orchestrate-init-status.js.map +0 -1
  265. package/dist/orchestrate-initiative.js.map +0 -1
  266. package/dist/orchestrate-monitor.js.map +0 -1
  267. package/dist/pack-author.js.map +0 -1
  268. package/dist/pack-hash.js.map +0 -1
  269. package/dist/pack-install.js.map +0 -1
  270. package/dist/pack-publish.js.map +0 -1
  271. package/dist/pack-scaffold.js.map +0 -1
  272. package/dist/pack-search.js.map +0 -1
  273. package/dist/pack-validate.js.map +0 -1
  274. package/dist/plan-create.js.map +0 -1
  275. package/dist/plan-edit.js.map +0 -1
  276. package/dist/plan-link.js.map +0 -1
  277. package/dist/plan-promote.js.map +0 -1
  278. package/dist/public-manifest.js +0 -920
  279. package/dist/public-manifest.js.map +0 -1
  280. package/dist/release.js.map +0 -1
  281. package/dist/rotate-progress.js +0 -253
  282. package/dist/rotate-progress.js.map +0 -1
  283. package/dist/session-coordinator.js +0 -303
  284. package/dist/session-coordinator.js.map +0 -1
  285. package/dist/shared-validators.js +0 -81
  286. package/dist/shared-validators.js.map +0 -1
  287. package/dist/signal-cleanup.js.map +0 -1
  288. package/dist/state-bootstrap.js.map +0 -1
  289. package/dist/state-cleanup.js.map +0 -1
  290. package/dist/state-doctor-fix.js +0 -226
  291. package/dist/state-doctor-fix.js.map +0 -1
  292. package/dist/state-doctor-stamps.js +0 -23
  293. package/dist/state-doctor-stamps.js.map +0 -1
  294. package/dist/state-doctor.js.map +0 -1
  295. package/dist/strict-progress.js +0 -255
  296. package/dist/strict-progress.js.map +0 -1
  297. package/dist/sync-templates.js.map +0 -1
  298. package/dist/task-claim.js.map +0 -1
  299. package/dist/trace-gen.js +0 -401
  300. package/dist/trace-gen.js.map +0 -1
  301. package/dist/validate-agent-skills.js +0 -223
  302. package/dist/validate-agent-skills.js.map +0 -1
  303. package/dist/validate-agent-sync.js +0 -151
  304. package/dist/validate-agent-sync.js.map +0 -1
  305. package/dist/validate-backlog-sync.js +0 -77
  306. package/dist/validate-backlog-sync.js.map +0 -1
  307. package/dist/validate-skills-spec.js +0 -211
  308. package/dist/validate-skills-spec.js.map +0 -1
  309. package/dist/validate.js.map +0 -1
  310. package/dist/validator-defaults.js +0 -107
  311. package/dist/validator-defaults.js.map +0 -1
  312. package/dist/validator-registry.js +0 -71
  313. package/dist/validator-registry.js.map +0 -1
  314. package/dist/workspace-init.js.map +0 -1
  315. package/dist/wu-block.js.map +0 -1
  316. package/dist/wu-brief.js.map +0 -1
  317. package/dist/wu-claim-branch.js +0 -123
  318. package/dist/wu-claim-branch.js.map +0 -1
  319. package/dist/wu-claim-cloud.js +0 -79
  320. package/dist/wu-claim-cloud.js.map +0 -1
  321. package/dist/wu-claim-mode.js +0 -82
  322. package/dist/wu-claim-mode.js.map +0 -1
  323. package/dist/wu-claim-output.js +0 -85
  324. package/dist/wu-claim-output.js.map +0 -1
  325. package/dist/wu-claim-repair-guidance.js +0 -12
  326. package/dist/wu-claim-repair-guidance.js.map +0 -1
  327. package/dist/wu-claim-resume-handler.js +0 -87
  328. package/dist/wu-claim-resume-handler.js.map +0 -1
  329. package/dist/wu-claim-state.js +0 -581
  330. package/dist/wu-claim-state.js.map +0 -1
  331. package/dist/wu-claim-validation.js +0 -457
  332. package/dist/wu-claim-validation.js.map +0 -1
  333. package/dist/wu-claim-worktree.js +0 -223
  334. package/dist/wu-claim-worktree.js.map +0 -1
  335. package/dist/wu-claim.js.map +0 -1
  336. package/dist/wu-cleanup-cloud.js +0 -78
  337. package/dist/wu-cleanup-cloud.js.map +0 -1
  338. package/dist/wu-cleanup.js.map +0 -1
  339. package/dist/wu-code-path-coverage.js +0 -83
  340. package/dist/wu-code-path-coverage.js.map +0 -1
  341. package/dist/wu-create-cloud.js +0 -30
  342. package/dist/wu-create-cloud.js.map +0 -1
  343. package/dist/wu-create-content.js +0 -264
  344. package/dist/wu-create-content.js.map +0 -1
  345. package/dist/wu-create-readiness.js +0 -59
  346. package/dist/wu-create-readiness.js.map +0 -1
  347. package/dist/wu-create-validation.js +0 -128
  348. package/dist/wu-create-validation.js.map +0 -1
  349. package/dist/wu-create.js.map +0 -1
  350. package/dist/wu-delegate.js.map +0 -1
  351. package/dist/wu-delete.js.map +0 -1
  352. package/dist/wu-deps.js.map +0 -1
  353. package/dist/wu-done-auto-cleanup.js +0 -203
  354. package/dist/wu-done-auto-cleanup.js.map +0 -1
  355. package/dist/wu-done-check.js +0 -38
  356. package/dist/wu-done-check.js.map +0 -1
  357. package/dist/wu-done-cloud.js +0 -48
  358. package/dist/wu-done-cloud.js.map +0 -1
  359. package/dist/wu-done-decay.js +0 -86
  360. package/dist/wu-done-decay.js.map +0 -1
  361. package/dist/wu-done.js.map +0 -1
  362. package/dist/wu-edit-operations.js +0 -399
  363. package/dist/wu-edit-operations.js.map +0 -1
  364. package/dist/wu-edit-validators.js +0 -282
  365. package/dist/wu-edit-validators.js.map +0 -1
  366. package/dist/wu-edit.js.map +0 -1
  367. package/dist/wu-infer-lane.js.map +0 -1
  368. package/dist/wu-preflight.js.map +0 -1
  369. package/dist/wu-prep.js.map +0 -1
  370. package/dist/wu-proto.js.map +0 -1
  371. package/dist/wu-prune.js.map +0 -1
  372. package/dist/wu-recover.js.map +0 -1
  373. package/dist/wu-release.js.map +0 -1
  374. package/dist/wu-repair.js.map +0 -1
  375. package/dist/wu-sandbox.js.map +0 -1
  376. package/dist/wu-spawn-completion.js +0 -33
  377. package/dist/wu-spawn-completion.js.map +0 -1
  378. package/dist/wu-spawn-prompt-builders.js +0 -1197
  379. package/dist/wu-spawn-prompt-builders.js.map +0 -1
  380. package/dist/wu-spawn-strategy-resolver.js +0 -322
  381. package/dist/wu-spawn-strategy-resolver.js.map +0 -1
  382. package/dist/wu-spawn.js +0 -59
  383. package/dist/wu-spawn.js.map +0 -1
  384. package/dist/wu-state-cloud.js +0 -41
  385. package/dist/wu-state-cloud.js.map +0 -1
  386. package/dist/wu-status.js.map +0 -1
  387. package/dist/wu-unblock.js.map +0 -1
  388. package/dist/wu-unlock-lane.js.map +0 -1
  389. package/dist/wu-validate.js.map +0 -1
@@ -1,172 +0,0 @@
1
- #!/usr/bin/env node
2
- // Copyright (c) 2026 Hellmai Ltd
3
- // SPDX-License-Identifier: AGPL-3.0-only
4
- /**
5
- * @file guard-locked.ts
6
- * @description Guard that prevents changes to locked WUs (WU-1111)
7
- *
8
- * Validates that a WU is not locked before allowing modifications.
9
- * Used by git hooks and wu: commands to enforce workflow discipline.
10
- *
11
- * Usage:
12
- * guard-locked WU-123 # Check if WU-123 is locked
13
- * guard-locked --wu WU-123 # Same with explicit flag
14
- *
15
- * Exit codes:
16
- * 0 - WU is not locked (safe to proceed)
17
- * 1 - WU is locked (block operation)
18
- *
19
- * @see {@link docs/04-operations/_frameworks/lumenflow/lumenflow-complete.md} - WU lifecycle
20
- */
21
- import { existsSync, readFileSync } from 'node:fs';
22
- import path from 'node:path';
23
- import { parseYAML } from '@lumenflow/core/wu-yaml';
24
- import { WU_PATHS } from '@lumenflow/core/wu-paths';
25
- import { PATTERNS, FILE_SYSTEM } from '@lumenflow/core/wu-constants';
26
- import { runCLI } from './cli-entry-point.js';
27
- const LOG_PREFIX = '[guard-locked]';
28
- /**
29
- * Check if a WU is locked
30
- *
31
- * @param wuPath - Path to WU YAML file
32
- * @returns true if WU has locked: true, false otherwise
33
- * @throws Error if WU file does not exist or cannot be parsed
34
- *
35
- * @example
36
- * if (isWULocked('/path/to/WU-123.yaml')) {
37
- * console.log('WU is locked, cannot modify');
38
- * }
39
- */
40
- export function isWULocked(wuPath) {
41
- if (!existsSync(wuPath)) {
42
- throw new Error(`WU file not found: ${wuPath}`);
43
- }
44
- const content = readFileSync(wuPath, { encoding: FILE_SYSTEM.UTF8 });
45
- const doc = parseYAML(content);
46
- return doc.locked === true;
47
- }
48
- /**
49
- * Assert that a WU is not locked
50
- *
51
- * @param wuPath - Path to WU YAML file
52
- * @throws Error if WU is locked, with actionable fix instructions
53
- *
54
- * @example
55
- * try {
56
- * assertWUNotLocked('/path/to/WU-123.yaml');
57
- * // Safe to modify
58
- * } catch (error) {
59
- * console.error(error.message);
60
- * process.exit(1);
61
- * }
62
- */
63
- export function assertWUNotLocked(wuPath) {
64
- if (!existsSync(wuPath)) {
65
- throw new Error(`WU file not found: ${wuPath}`);
66
- }
67
- const content = readFileSync(wuPath, { encoding: FILE_SYSTEM.UTF8 });
68
- const doc = parseYAML(content);
69
- if (doc.locked === true) {
70
- const wuId = doc.id || path.basename(wuPath, '.yaml');
71
- throw new Error(`${LOG_PREFIX} WU ${wuId} is locked.
72
-
73
- Locked WUs cannot be modified. This prevents accidental changes to completed work.
74
-
75
- If you need to modify this WU:
76
- 1. Check if modification is really necessary (locked WUs are done)
77
- 2. Use wu:unlock to unlock the WU first:
78
- pnpm wu:unlock --id ${wuId} --reason "reason for unlocking"
79
-
80
- For more information:
81
- See docs/04-operations/_frameworks/lumenflow/lumenflow-complete.md
82
- `);
83
- }
84
- }
85
- /**
86
- * Check if a WU ID is locked by looking up the YAML file
87
- *
88
- * @param wuId - WU ID (e.g., "WU-123")
89
- * @returns true if WU has locked: true, false otherwise
90
- * @throws Error if WU file does not exist
91
- */
92
- export function isWUIdLocked(wuId) {
93
- const wuPath = WU_PATHS.WU(wuId);
94
- return isWULocked(wuPath);
95
- }
96
- /**
97
- * Assert that a WU ID is not locked
98
- *
99
- * @param wuId - WU ID (e.g., "WU-123")
100
- * @throws Error if WU is locked
101
- */
102
- export function assertWUIdNotLocked(wuId) {
103
- const wuPath = WU_PATHS.WU(wuId);
104
- assertWUNotLocked(wuPath);
105
- }
106
- /**
107
- * Main CLI entry point
108
- */
109
- async function main() {
110
- const args = process.argv.slice(2);
111
- // Parse arguments
112
- let wuId;
113
- for (let i = 0; i < args.length; i++) {
114
- const arg = args[i];
115
- if (arg === '--wu' || arg === '--id') {
116
- wuId = args[++i];
117
- }
118
- else if (arg === '--help' || arg === '-h') {
119
- console.log(`Usage: guard-locked [--wu] WU-XXX
120
-
121
- Check if a WU is locked. Exits with code 1 if locked.
122
-
123
- Options:
124
- --wu, --id WU-XXX WU ID to check
125
- -h, --help Show this help message
126
-
127
- Examples:
128
- guard-locked WU-123
129
- guard-locked --wu WU-123
130
- `);
131
- process.exit(0);
132
- }
133
- else if (PATTERNS.WU_ID.test(arg.toUpperCase())) {
134
- wuId = arg.toUpperCase();
135
- }
136
- }
137
- if (!wuId) {
138
- console.error(`${LOG_PREFIX} Error: WU ID required`);
139
- console.error('Usage: guard-locked [--wu] WU-XXX');
140
- process.exit(1);
141
- }
142
- // Normalize WU ID
143
- wuId = wuId.toUpperCase();
144
- if (!PATTERNS.WU_ID.test(wuId)) {
145
- console.error(`${LOG_PREFIX} Invalid WU ID: ${wuId}`);
146
- console.error('Expected format: WU-123');
147
- process.exit(1);
148
- }
149
- try {
150
- if (isWUIdLocked(wuId)) {
151
- console.error(`${LOG_PREFIX} ${wuId} is locked`);
152
- console.error('');
153
- console.error('Locked WUs cannot be modified.');
154
- console.error(`To unlock: pnpm wu:unlock --id ${wuId} --reason "your reason"`);
155
- process.exit(1);
156
- }
157
- console.log(`${LOG_PREFIX} ${wuId} is not locked (OK)`);
158
- process.exit(0);
159
- }
160
- catch (error) {
161
- console.error(`${LOG_PREFIX} Error: ${error.message}`);
162
- process.exit(1);
163
- }
164
- }
165
- // WU-1181: Use import.meta.main instead of process.argv[1] comparison
166
- // The old pattern fails with pnpm symlinks because process.argv[1] is the symlink
167
- // path but import.meta.url resolves to the real path - they never match
168
- // WU-1537: Use import.meta.main + runCLI for consistent EPIPE and error handling
169
- if (import.meta.main) {
170
- void runCLI(main);
171
- }
172
- //# sourceMappingURL=guard-locked.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guard-locked.js","sourceRoot":"","sources":["../src/guard-locked.ts"],"names":[],"mappings":"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"}
@@ -1,217 +0,0 @@
1
- #!/usr/bin/env node
2
- // Copyright (c) 2026 Hellmai Ltd
3
- // SPDX-License-Identifier: AGPL-3.0-only
4
- /**
5
- * Guard Main Branch CLI Tool
6
- *
7
- * Provides branch protection checks for WU workflow:
8
- * - Blocks operations on main/master branches
9
- * - Blocks operations on lane branches (require worktree)
10
- * - Optionally allows agent branches
11
- *
12
- * Usage:
13
- * node guard-main-branch.js [--allow-agent-branch] [--strict]
14
- *
15
- * WU-1109: INIT-003 Phase 4b - Migrate git operations
16
- */
17
- import { createGitForPath, getGitForCwd, isAgentBranch, getConfig } from '@lumenflow/core';
18
- import { isInWorktree } from '@lumenflow/core/core/worktree-guard';
19
- /**
20
- * Parse command line arguments for guard-main-branch
21
- */
22
- export function parseGuardMainBranchArgs(argv) {
23
- const args = {};
24
- // Skip node and script name
25
- const cliArgs = argv.slice(2);
26
- for (let i = 0; i < cliArgs.length; i++) {
27
- const arg = cliArgs[i];
28
- if (arg === '--help' || arg === '-h') {
29
- args.help = true;
30
- }
31
- else if (arg === '--allow-agent-branch') {
32
- args.allowAgentBranch = true;
33
- }
34
- else if (arg === '--strict') {
35
- args.strict = true;
36
- }
37
- else if (arg === '--base-dir') {
38
- args.baseDir = cliArgs[++i];
39
- }
40
- }
41
- return args;
42
- }
43
- /**
44
- * Get lane branch pattern from config
45
- */
46
- function getLaneBranchPattern() {
47
- const config = getConfig();
48
- const prefix = config?.git?.laneBranchPrefix ?? 'lane/';
49
- const escaped = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
50
- // eslint-disable-next-line security/detect-non-literal-regexp -- prefix from config file, not user input; escaped for safety
51
- return new RegExp(`^${escaped}`);
52
- }
53
- /**
54
- * Get protected branches from config
55
- */
56
- function getProtectedBranches() {
57
- const config = getConfig();
58
- const mainBranch = config?.git?.mainBranch ?? 'main';
59
- // Always include master for legacy compatibility
60
- const protectedSet = new Set([mainBranch, 'master']);
61
- return Array.from(protectedSet);
62
- }
63
- /**
64
- * Check if a branch is a lane branch (requires worktree)
65
- */
66
- function isLaneBranch(branch) {
67
- return getLaneBranchPattern().test(branch);
68
- }
69
- /**
70
- * Guard against operations on protected branches
71
- */
72
- export async function guardMainBranch(args) {
73
- try {
74
- const git = args.baseDir ? createGitForPath(args.baseDir) : getGitForCwd();
75
- const currentBranch = await git.getCurrentBranch();
76
- // Handle detached HEAD
77
- if (currentBranch === 'HEAD' || !currentBranch) {
78
- return {
79
- success: true,
80
- isProtected: true,
81
- currentBranch: 'HEAD (detached)',
82
- reason: 'Detached HEAD state is protected - checkout a branch',
83
- };
84
- }
85
- const protectedBranches = getProtectedBranches();
86
- // Check if on main/master
87
- if (protectedBranches.includes(currentBranch)) {
88
- return {
89
- success: true,
90
- isProtected: true,
91
- currentBranch,
92
- reason: `Branch '${currentBranch}' is protected - use a worktree for WU work`,
93
- };
94
- }
95
- // Check if on a lane branch (requires worktree discipline)
96
- if (isLaneBranch(currentBranch)) {
97
- // If we're actually in a worktree, allow the operation (WU-1130)
98
- const cwd = args.baseDir ?? process.cwd();
99
- if (isInWorktree({ cwd })) {
100
- return {
101
- success: true,
102
- isProtected: false,
103
- currentBranch,
104
- };
105
- }
106
- // On lane branch but not in worktree - block
107
- return {
108
- success: true,
109
- isProtected: true,
110
- currentBranch,
111
- reason: `Lane branch '${currentBranch}' requires worktree - use 'pnpm wu:claim' to create worktree`,
112
- };
113
- }
114
- // Check agent branch if not explicitly allowed
115
- if (!args.allowAgentBranch) {
116
- const isAgent = await isAgentBranch(currentBranch);
117
- if (isAgent) {
118
- // Agent branches are allowed by default (unless --strict)
119
- if (args.strict) {
120
- return {
121
- success: true,
122
- isProtected: true,
123
- currentBranch,
124
- reason: `Agent branch '${currentBranch}' is protected in strict mode`,
125
- };
126
- }
127
- // Allow agent branch
128
- return {
129
- success: true,
130
- isProtected: false,
131
- currentBranch,
132
- };
133
- }
134
- }
135
- // Branch is not protected
136
- return {
137
- success: true,
138
- isProtected: false,
139
- currentBranch,
140
- };
141
- }
142
- catch (error) {
143
- const errorMessage = error instanceof Error ? error.message : String(error);
144
- return {
145
- success: false,
146
- isProtected: true, // Fail-closed
147
- error: errorMessage,
148
- };
149
- }
150
- }
151
- /**
152
- * Print help message
153
- */
154
- /* istanbul ignore next -- CLI entry point tested via subprocess */
155
- function printHelp() {
156
- console.log(`
157
- Usage: guard-main-branch [options]
158
-
159
- Check if current branch is protected and block operations.
160
-
161
- Options:
162
- --base-dir <dir> Base directory for git operations
163
- --allow-agent-branch Allow operations on agent branches
164
- --strict Block all protected branches (including agent)
165
- -h, --help Show this help message
166
-
167
- Exit codes:
168
- 0 - Branch is not protected (safe to proceed)
169
- 1 - Branch is protected (operation blocked)
170
-
171
- Protected branches:
172
- - main/master: Always protected
173
- - lane/*: Requires worktree (use wu:claim)
174
- - Agent branches: Allowed unless --strict
175
-
176
- Examples:
177
- guard-main-branch
178
- guard-main-branch --allow-agent-branch
179
- guard-main-branch --strict
180
- `);
181
- }
182
- /**
183
- * Main entry point
184
- */
185
- /* istanbul ignore next -- CLI entry point tested via subprocess */
186
- async function main() {
187
- const args = parseGuardMainBranchArgs(process.argv);
188
- if (args.help) {
189
- printHelp();
190
- process.exit(0);
191
- }
192
- const result = await guardMainBranch(args);
193
- if (result.success) {
194
- if (result.isProtected) {
195
- console.error(`[guard-main-branch] BLOCKED: ${result.reason}`);
196
- console.error(`Current branch: ${result.currentBranch}`);
197
- process.exit(1);
198
- }
199
- else {
200
- // Silent success in normal mode
201
- if (process.env.DEBUG) {
202
- console.log(`[guard-main-branch] OK: Branch '${result.currentBranch}' is not protected`);
203
- }
204
- process.exit(0);
205
- }
206
- }
207
- else {
208
- console.error(`Error: ${result.error}`);
209
- process.exit(1);
210
- }
211
- }
212
- // Run main if executed directly
213
- import { runCLI } from './cli-entry-point.js';
214
- if (import.meta.main) {
215
- void runCLI(main);
216
- }
217
- //# sourceMappingURL=guard-main-branch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guard-main-branch.js","sourceRoot":"","sources":["../src/guard-main-branch.ts"],"names":[],"mappings":"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"}
@@ -1,163 +0,0 @@
1
- #!/usr/bin/env node
2
- // Copyright (c) 2026 Hellmai Ltd
3
- // SPDX-License-Identifier: AGPL-3.0-only
4
- /**
5
- * @file guard-worktree-commit.ts
6
- * @description Guard that prevents WU commits from main checkout (WU-1111)
7
- *
8
- * Validates that WU-related commits are only made from worktrees, not main.
9
- * Used by git commit-msg hooks to enforce worktree discipline.
10
- *
11
- * Usage:
12
- * guard-worktree-commit "commit message"
13
- * guard-worktree-commit --message "commit message"
14
- *
15
- * Exit codes:
16
- * 0 - Commit allowed
17
- * 1 - Commit blocked (WU commit from main)
18
- *
19
- * @see {@link docs/04-operations/_frameworks/lumenflow/lumenflow-complete.md} - Worktree discipline
20
- */
21
- import { isInWorktree, isMainBranch } from '@lumenflow/core/core/worktree-guard';
22
- import { runCLI } from './cli-entry-point.js';
23
- const LOG_PREFIX = '[guard-worktree-commit]';
24
- /**
25
- * Patterns that indicate a WU-related commit message
26
- */
27
- const WU_COMMIT_PATTERNS = [
28
- /^wu\(/i, // wu(WU-123): message
29
- /\(wu-\d+\)/i, // feat(WU-123): message
30
- /\(WU-\d+\)/i, // Same with uppercase
31
- /^WU-\d+:/i, // WU-123: message
32
- /^wu-\d+:/i, // wu-123: message
33
- ];
34
- /**
35
- * Check if a commit should be blocked
36
- *
37
- * @param options - Check options
38
- * @param options.commitMessage - The commit message
39
- * @param options.isMainCheckout - Whether in main checkout
40
- * @param options.isInWorktree - Whether in a worktree
41
- * @returns Whether commit should be blocked and why
42
- *
43
- * @example
44
- * const result = shouldBlockCommit({
45
- * commitMessage: 'wu(WU-123): add feature',
46
- * isMainCheckout: true,
47
- * isInWorktree: false,
48
- * });
49
- * if (result.blocked) {
50
- * console.error(result.reason);
51
- * process.exit(1);
52
- * }
53
- */
54
- export function shouldBlockCommit(options) {
55
- const { commitMessage, isMainCheckout, isInWorktree } = options;
56
- // Allow all commits from worktrees
57
- if (isInWorktree) {
58
- return { blocked: false };
59
- }
60
- // Check if commit message indicates WU work
61
- const isWUCommit = WU_COMMIT_PATTERNS.some((pattern) => pattern.test(commitMessage));
62
- // Block WU commits from main checkout
63
- if (isWUCommit && isMainCheckout) {
64
- return {
65
- blocked: true,
66
- reason: `${LOG_PREFIX} BLOCKED: WU commits must be made from a worktree.
67
-
68
- You are attempting to commit WU work from the main checkout.
69
-
70
- To fix:
71
- 1. Navigate to your worktree:
72
- cd worktrees/<lane>-wu-xxx/
73
-
74
- 2. Make your commit there:
75
- git add . && git commit -m "${commitMessage}"
76
-
77
- 3. Complete the WU from main:
78
- cd ../.. && pnpm wu:done --id WU-XXX
79
-
80
- For more information:
81
- See docs/04-operations/_frameworks/lumenflow/lumenflow-complete.md
82
- See .claude/skills/worktree-discipline/SKILL.md
83
- `,
84
- };
85
- }
86
- // Allow non-WU commits from anywhere
87
- return { blocked: false };
88
- }
89
- /**
90
- * Check if a commit message is WU-related
91
- *
92
- * @param message - Commit message to check
93
- * @returns true if message indicates WU work
94
- */
95
- export function isWUCommitMessage(message) {
96
- return WU_COMMIT_PATTERNS.some((pattern) => pattern.test(message));
97
- }
98
- /**
99
- * Main CLI entry point
100
- */
101
- async function main() {
102
- const args = process.argv.slice(2);
103
- // Parse arguments
104
- let commitMessage;
105
- for (let i = 0; i < args.length; i++) {
106
- const arg = args[i];
107
- if (arg === '--message' || arg === '-m') {
108
- commitMessage = args[++i];
109
- }
110
- else if (arg === '--help' || arg === '-h') {
111
- console.log(`Usage: guard-worktree-commit [--message] "commit message"
112
-
113
- Check if a WU commit should be blocked from main checkout.
114
-
115
- Options:
116
- --message, -m MSG Commit message to check
117
- -h, --help Show this help message
118
-
119
- Examples:
120
- guard-worktree-commit "wu(WU-123): add feature"
121
- guard-worktree-commit --message "chore: update deps"
122
- `);
123
- process.exit(0);
124
- }
125
- else if (!commitMessage) {
126
- commitMessage = arg;
127
- }
128
- }
129
- if (!commitMessage) {
130
- console.error(`${LOG_PREFIX} Error: Commit message required`);
131
- console.error('Usage: guard-worktree-commit [--message] "commit message"');
132
- process.exit(1);
133
- }
134
- // Check context
135
- const inWorktree = isInWorktree();
136
- let onMain;
137
- try {
138
- onMain = await isMainBranch();
139
- }
140
- catch {
141
- // If we can't determine branch, be conservative and allow
142
- onMain = false;
143
- }
144
- const result = shouldBlockCommit({
145
- commitMessage,
146
- isMainCheckout: onMain && !inWorktree,
147
- isInWorktree: inWorktree,
148
- });
149
- if (result.blocked) {
150
- console.error(result.reason);
151
- process.exit(1);
152
- }
153
- console.log(`${LOG_PREFIX} Commit allowed`);
154
- process.exit(0);
155
- }
156
- // WU-1181: Use import.meta.main instead of process.argv[1] comparison
157
- // The old pattern fails with pnpm symlinks because process.argv[1] is the symlink
158
- // path but import.meta.url resolves to the real path - they never match
159
- // WU-1537: Use import.meta.main + runCLI for consistent EPIPE and error handling
160
- if (import.meta.main) {
161
- void runCLI(main);
162
- }
163
- //# sourceMappingURL=guard-worktree-commit.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"guard-worktree-commit.js","sourceRoot":"","sources":["../src/guard-worktree-commit.ts"],"names":[],"mappings":"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"}
@@ -1,54 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: AGPL-3.0-only
3
- /**
4
- * @file auto-checkpoint-utils.ts
5
- * Utilities for auto-checkpoint enforcement hooks (WU-1471)
6
- *
7
- * Provides:
8
- * - checkAutoCheckpointWarning: Detects config mismatch (policy enabled, hooks disabled)
9
- * - cleanupHookCounters: Removes per-WU counter files on wu:done completion
10
- */
11
- import { existsSync, unlinkSync } from 'node:fs';
12
- import { join } from 'node:path';
13
- import { LUMENFLOW_PATHS } from '@lumenflow/core';
14
- /**
15
- * WU-1471 AC5: Check if auto-checkpoint policy is enabled but hooks master switch is disabled.
16
- * When this mismatch exists, tooling should emit a warning that enforcement is advisory-only.
17
- *
18
- * @param params - Configuration state
19
- * @param params.hooksEnabled - Whether the hooks master switch is enabled
20
- * @param params.autoCheckpointEnabled - Whether auto_checkpoint.enabled is true
21
- * @returns Warning result with message if applicable
22
- */
23
- export function checkAutoCheckpointWarning(params) {
24
- if (params.autoCheckpointEnabled && !params.hooksEnabled) {
25
- return {
26
- warning: true,
27
- message: 'Auto-checkpoint policy is enabled but hooks master switch is disabled. ' +
28
- 'Checkpointing remains advisory-only. Enable agents.clients.claude-code.enforcement.hooks ' +
29
- 'to activate automatic checkpointing.',
30
- };
31
- }
32
- return { warning: false };
33
- }
34
- /**
35
- * WU-1471 AC4: Remove per-WU hook counter file on wu:done completion.
36
- * Called during wu:done cleanup to remove .lumenflow/state/hook-counters/<WU_ID>.json.
37
- *
38
- * Fail-safe: does not throw if the file or directory does not exist.
39
- *
40
- * @param projectDir - Project root directory
41
- * @param wuId - WU identifier (e.g., 'WU-1471')
42
- */
43
- export function cleanupHookCounters(projectDir, wuId) {
44
- try {
45
- const counterFile = join(projectDir, LUMENFLOW_PATHS.HOOK_COUNTERS_DIR, `${wuId}.json`);
46
- if (existsSync(counterFile)) {
47
- unlinkSync(counterFile);
48
- }
49
- }
50
- catch {
51
- // Fail-safe: counter cleanup failure should never block wu:done
52
- }
53
- }
54
- //# sourceMappingURL=auto-checkpoint-utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-checkpoint-utils.js","sourceRoot":"","sources":["../../src/hooks/auto-checkpoint-utils.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,yCAAyC;AAEzC;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAG1C;IACC,IAAI,MAAM,CAAC,qBAAqB,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;QACzD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EACL,yEAAyE;gBACzE,2FAA2F;gBAC3F,sCAAsC;SACzC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,IAAY;IAClE,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,iBAAiB,EAAE,GAAG,IAAI,OAAO,CAAC,CAAC;QACxF,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,UAAU,CAAC,WAAW,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC"}