@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
@@ -17,11 +17,41 @@
17
17
  import * as readline from 'node:readline';
18
18
  import * as path from 'node:path';
19
19
  import YAML from 'yaml';
20
- import { createWUParser } from '@lumenflow/core';
21
20
  import { createFile } from './init-scaffolding.js';
22
21
  import { runCLI } from './cli-entry-point.js';
23
22
  export const LOG_PREFIX = '[workspace:init]';
24
- const WORKSPACE_FILENAME = 'workspace.yaml';
23
+ export const WORKSPACE_FILENAME = 'workspace.yaml';
24
+ export const DEFAULT_WORKSPACE_ID = 'default';
25
+ export const DEFAULT_WORKSPACE_NAME = 'My Project';
26
+ export const DEFAULT_PROJECT_NAME = 'my-project';
27
+ export const DEFAULT_LANE_TITLE = 'Default';
28
+ export const DEFAULT_NAMESPACE = DEFAULT_WORKSPACE_ID;
29
+ export const CANONICAL_BOOTSTRAP_COMMAND = 'npx lumenflow';
30
+ const LEGACY_WORKSPACE_INIT_ENTRYPOINT = 'workspace-init';
31
+ const LEGACY_ENTRYPOINT_MARKER = 'legacy';
32
+ const LEGACY_ENTRYPOINT_MESSAGE_PREFIX = `${LOG_PREFIX} ${LEGACY_ENTRYPOINT_MARKER} entrypoint`;
33
+ export const DEFAULT_DENY_OVERLAYS = ['~/.ssh', '~/.aws', '~/.gnupg', '.env'];
34
+ export const DEFAULT_DENY_OVERLAYS_PROMPT = DEFAULT_DENY_OVERLAYS.join(', ');
35
+ export const SANDBOX_NETWORK_PROFILE = {
36
+ OFF: 'off',
37
+ FULL: 'full',
38
+ };
39
+ export const DEFAULT_SANDBOX_NETWORK_PROFILE = SANDBOX_NETWORK_PROFILE.OFF;
40
+ export const CLOUD_CONNECT_RESPONSE = {
41
+ YES: 'yes',
42
+ NO: 'no',
43
+ SHORT_YES: 'y',
44
+ BOOLEAN_TRUE: 'true',
45
+ };
46
+ const CLOUD_CONNECT_TRUTHY = new Set([
47
+ CLOUD_CONNECT_RESPONSE.YES,
48
+ CLOUD_CONNECT_RESPONSE.SHORT_YES,
49
+ CLOUD_CONNECT_RESPONSE.BOOLEAN_TRUE,
50
+ ]);
51
+ const EMPTY_SOFTWARE_DELIVERY_CONFIG = Object.freeze({});
52
+ function createEmptySoftwareDeliveryConfig() {
53
+ return { ...EMPTY_SOFTWARE_DELIVERY_CONFIG };
54
+ }
25
55
  /**
26
56
  * AC1: 5 interactive questions for workspace configuration
27
57
  */
@@ -29,29 +59,33 @@ export const WORKSPACE_QUESTIONS = [
29
59
  {
30
60
  name: 'projectName',
31
61
  prompt: 'Project name',
32
- defaultValue: 'my-project',
62
+ defaultValue: DEFAULT_PROJECT_NAME,
33
63
  },
34
64
  {
35
65
  name: 'lanes',
36
66
  prompt: 'Work lanes (comma-separated, e.g., Backend, Frontend, DevOps)',
37
- defaultValue: 'Default',
67
+ defaultValue: DEFAULT_LANE_TITLE,
38
68
  },
39
69
  {
40
70
  name: 'sandboxProfile',
41
71
  prompt: 'Sandbox network profile (off | full)',
42
- defaultValue: 'off',
72
+ defaultValue: DEFAULT_SANDBOX_NETWORK_PROFILE,
43
73
  },
44
74
  {
45
75
  name: 'deniedPaths',
46
76
  prompt: 'Denied paths (comma-separated, e.g., ~/.ssh, ~/.aws, .env)',
47
- defaultValue: '~/.ssh, ~/.aws, ~/.gnupg, .env',
77
+ defaultValue: DEFAULT_DENY_OVERLAYS_PROMPT,
48
78
  },
49
79
  {
50
80
  name: 'cloudConnect',
51
81
  prompt: 'Enable cloud agent support? (yes | no)',
52
- defaultValue: 'no',
82
+ defaultValue: CLOUD_CONNECT_RESPONSE.NO,
53
83
  },
54
84
  ];
85
+ export function buildLegacyWorkspaceInitGuidance(entrypoint = LEGACY_WORKSPACE_INIT_ENTRYPOINT) {
86
+ return (`${LEGACY_ENTRYPOINT_MESSAGE_PREFIX} "${entrypoint}" is retired. ` +
87
+ `Use "${CANONICAL_BOOTSTRAP_COMMAND}" for bootstrap-all onboarding.`);
88
+ }
55
89
  /**
56
90
  * Parse raw string answers from interactive prompts into typed config inputs.
57
91
  */
@@ -66,10 +100,10 @@ export function parseAnswers(answers) {
66
100
  .map((p) => p.trim())
67
101
  .filter(Boolean)
68
102
  : [];
69
- const cloudConnect = answers.cloudConnect.toLowerCase() === 'yes' ||
70
- answers.cloudConnect.toLowerCase() === 'y' ||
71
- answers.cloudConnect.toLowerCase() === 'true';
72
- const sandboxProfile = answers.sandboxProfile === 'full' ? 'full' : 'off';
103
+ const cloudConnect = CLOUD_CONNECT_TRUTHY.has(answers.cloudConnect.toLowerCase());
104
+ const sandboxProfile = answers.sandboxProfile === SANDBOX_NETWORK_PROFILE.FULL
105
+ ? SANDBOX_NETWORK_PROFILE.FULL
106
+ : SANDBOX_NETWORK_PROFILE.OFF;
73
107
  return {
74
108
  projectName: answers.projectName,
75
109
  lanes,
@@ -94,24 +128,25 @@ function toKebabCase(title) {
94
128
  */
95
129
  export function getDefaultWorkspaceConfig() {
96
130
  return {
97
- id: 'default',
98
- name: 'My Project',
131
+ id: DEFAULT_WORKSPACE_ID,
132
+ name: DEFAULT_WORKSPACE_NAME,
99
133
  packs: [],
100
134
  lanes: [
101
135
  {
102
- id: 'default',
103
- title: 'Default',
136
+ id: DEFAULT_WORKSPACE_ID,
137
+ title: DEFAULT_LANE_TITLE,
104
138
  allowed_scopes: [],
105
139
  },
106
140
  ],
107
141
  policies: {},
108
142
  security: {
109
143
  allowed_scopes: [],
110
- network_default: 'off',
111
- deny_overlays: ['~/.ssh', '~/.aws', '~/.gnupg', '.env'],
144
+ network_default: DEFAULT_SANDBOX_NETWORK_PROFILE,
145
+ deny_overlays: [...DEFAULT_DENY_OVERLAYS],
112
146
  },
113
- memory_namespace: 'default',
114
- event_namespace: 'default',
147
+ software_delivery: createEmptySoftwareDeliveryConfig(),
148
+ memory_namespace: DEFAULT_NAMESPACE,
149
+ event_namespace: DEFAULT_NAMESPACE,
115
150
  };
116
151
  }
117
152
  /**
@@ -134,6 +169,7 @@ export function buildWorkspaceConfig(input) {
134
169
  network_default: input.sandboxProfile,
135
170
  deny_overlays: input.deniedPaths,
136
171
  },
172
+ software_delivery: createEmptySoftwareDeliveryConfig(),
137
173
  memory_namespace: toKebabCase(input.projectName),
138
174
  event_namespace: toKebabCase(input.projectName),
139
175
  };
@@ -172,7 +208,7 @@ export function generateWorkspaceYaml(config) {
172
208
  lines.push('security:');
173
209
  lines.push(' # Workspace-level scope restrictions');
174
210
  lines.push(` allowed_scopes: ${YAML.stringify(config.security.allowed_scopes).trim()}`);
175
- lines.push(' # Network access default for sandbox (off = no network, full = unrestricted)');
211
+ lines.push(` # Network access default for sandbox (${SANDBOX_NETWORK_PROFILE.OFF} = no network, ${SANDBOX_NETWORK_PROFILE.FULL} = unrestricted)`);
176
212
  lines.push(` network_default: ${config.security.network_default}`);
177
213
  lines.push(' # Paths denied to agent sandbox via deny overlays');
178
214
  lines.push(' deny_overlays:');
@@ -186,6 +222,9 @@ export function generateWorkspaceYaml(config) {
186
222
  }
187
223
  }
188
224
  lines.push('');
225
+ lines.push('# Software delivery config extensions (required workspace v2 block)');
226
+ lines.push(`software_delivery: ${YAML.stringify(config.software_delivery).trim()}`);
227
+ lines.push('');
189
228
  lines.push('# Memory namespace for session tracking and context recovery');
190
229
  lines.push(`memory_namespace: ${YAML.stringify(config.memory_namespace).trim()}`);
191
230
  lines.push('');
@@ -270,51 +309,12 @@ export async function runInteractive(targetDir, force = false) {
270
309
  }
271
310
  }
272
311
  // --- CLI entry point ---
273
- const WORKSPACE_INIT_OPTIONS = {
274
- yes: {
275
- name: 'yes',
276
- flags: '--yes, -y',
277
- description: 'Accept all defaults non-interactively',
278
- },
279
- output: {
280
- name: 'output',
281
- flags: '--output, -o <dir>',
282
- description: 'Output directory (default: current directory)',
283
- },
284
- force: {
285
- name: 'force',
286
- flags: '--force, -f',
287
- description: 'Overwrite existing workspace.yaml',
288
- },
289
- };
290
312
  /**
291
313
  * CLI main entry point for workspace:init
292
314
  */
293
315
  export async function main() {
294
- const opts = createWUParser({
295
- name: 'workspace-init',
296
- description: 'Initialize a LumenFlow workspace configuration (workspace.yaml)',
297
- options: [
298
- WORKSPACE_INIT_OPTIONS.yes,
299
- WORKSPACE_INIT_OPTIONS.output,
300
- WORKSPACE_INIT_OPTIONS.force,
301
- ],
302
- });
303
- const targetDir = opts.output ?? process.cwd();
304
- const force = Boolean(opts.force);
305
- const useDefaults = Boolean(opts.yes);
306
- if (useDefaults) {
307
- const result = await runNonInteractive(targetDir, force);
308
- if (result.created.length > 0) {
309
- console.log(`${LOG_PREFIX} Created ${WORKSPACE_FILENAME} with default settings`);
310
- }
311
- else if (result.skipped.length > 0) {
312
- console.log(`${LOG_PREFIX} ${WORKSPACE_FILENAME} already exists. Use --force to overwrite.`);
313
- }
314
- }
315
- else {
316
- await runInteractive(targetDir, force);
317
- }
316
+ const invokedEntryPoint = path.basename(process.argv[1] ?? LEGACY_WORKSPACE_INIT_ENTRYPOINT, '.js');
317
+ console.warn(buildLegacyWorkspaceInitGuidance(invokedEntryPoint));
318
318
  }
319
319
  // Run if executed directly
320
320
  if (import.meta.main) {
package/dist/wu-block.js CHANGED
@@ -178,7 +178,7 @@ async function handleWorktreeRemoval(args, doc) {
178
178
  console.warn(`${LOG_PREFIX.BLOCK} No worktree path specified; skipping removal`);
179
179
  }
180
180
  }
181
- async function main() {
181
+ export async function main() {
182
182
  const args = createWUParser({
183
183
  name: 'wu-block',
184
184
  description: 'Block a work unit and move it from in-progress to blocked status',
package/dist/wu-brief.js CHANGED
@@ -26,7 +26,7 @@ const BRIEF_LOG_PREFIX = '[wu:brief]';
26
26
  /**
27
27
  * Main entry point for wu:brief (canonical command)
28
28
  */
29
- async function main() {
29
+ export async function main() {
30
30
  await runBriefLogic({
31
31
  parserConfig: {
32
32
  name: 'wu-brief',
package/dist/wu-claim.js CHANGED
@@ -127,7 +127,7 @@ export async function maybeLaunchClaimSandboxSession(input, deps = {}) {
127
127
  // Main orchestrator
128
128
  // ============================================================================
129
129
  // eslint-disable-next-line sonarjs/cognitive-complexity -- main() orchestrates multi-step claim workflow
130
- async function main() {
130
+ export async function main() {
131
131
  const args = createWUParser({
132
132
  name: 'wu-claim',
133
133
  description: 'Claim a work unit by creating a worktree/branch and updating status',
@@ -180,7 +180,7 @@ function hasStampFile(wuId) {
180
180
  const stampPath = path.join(process.cwd(), WU_PATHS.STAMP(wuId));
181
181
  return existsSync(stampPath);
182
182
  }
183
- async function main() {
183
+ export async function main() {
184
184
  const args = createWUParser({
185
185
  name: 'wu-cleanup',
186
186
  description: 'Clean up worktree and branch after PR merge (PR-based completion workflow)',
package/dist/wu-create.js CHANGED
@@ -124,7 +124,7 @@ export function warnIfBetterLaneExists(providedLane, codePathsArray, title, desc
124
124
  * Resolve lane lifecycle classification for wu:create without mutating config.
125
125
  *
126
126
  * WU-1751: wu:create must not persist lifecycle migration side effects to
127
- * .lumenflow.config.yaml on main.
127
+ * workspace.yaml on main.
128
128
  */
129
129
  export function resolveLaneLifecycleForWuCreate(projectRoot) {
130
130
  return ensureLaneLifecycleForProject(projectRoot, { persist: false });
@@ -182,7 +182,7 @@ async function getDefaultAssignedTo() {
182
182
  return '';
183
183
  }
184
184
  }
185
- async function main() {
185
+ export async function main() {
186
186
  const args = createWUParser({
187
187
  name: 'wu-create',
188
188
  description: 'Create a new Work Unit with micro-worktree isolation (race-safe)',
@@ -267,7 +267,7 @@ async function main() {
267
267
  ` - Single colon with EXACTLY one space after (e.g., "Parent: Subdomain")\n` +
268
268
  ` - No spaces before colon\n` +
269
269
  ` - No multiple colons\n\n` +
270
- `See .lumenflow.config.yaml for valid parent lanes.`);
270
+ `See workspace.yaml software_delivery.lanes.definitions for valid parent lanes.`);
271
271
  }
272
272
  // WU-2330: Warn if a more specific sub-lane matches code_paths or description
273
273
  warnIfBetterLaneExists(args.lane, args.codePaths, args.title, args.description);
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { runBriefLogic } from './wu-spawn.js';
10
10
  import { runCLI } from './cli-entry-point.js';
11
- async function main() {
11
+ export async function main() {
12
12
  await runBriefLogic({
13
13
  mode: 'delegate',
14
14
  parserConfig: {
package/dist/wu-deps.js CHANGED
@@ -18,7 +18,7 @@ import { buildDependencyGraphAsync, renderASCII, renderMermaid, validateGraph, }
18
18
  import { OUTPUT_FORMATS } from '@lumenflow/initiatives/constants';
19
19
  import { PATTERNS } from '@lumenflow/core/wu-constants';
20
20
  import { getConfig } from '@lumenflow/core/config';
21
- async function main() {
21
+ export async function main() {
22
22
  const args = createWUParser({
23
23
  name: 'wu-deps',
24
24
  description: 'Visualize WU dependency graph',
package/dist/wu-done.js CHANGED
@@ -126,6 +126,63 @@ const MEMORY_CHECKPOINT_NOTES = {
126
126
  PRE_GATES: 'Pre-gates checkpoint for recovery if gates fail',
127
127
  };
128
128
  const MEMORY_SIGNAL_WINDOW_MS = 60 * 60 * 1000; // 1 hour for recent signals
129
+ export const CHECKPOINT_GATE_MODES = {
130
+ OFF: 'off',
131
+ WARN: 'warn',
132
+ BLOCK: 'block',
133
+ };
134
+ const CHECKPOINT_GATE_CONFIG = {
135
+ PATH: 'memory.enforcement.require_checkpoint_for_done',
136
+ COMMAND_PREFIX: 'pnpm mem:checkpoint --wu',
137
+ WARN_TAG: 'WU-1998',
138
+ };
139
+ function buildCheckpointGateBlockMessage(id) {
140
+ return (`${STRING_LITERALS.NEWLINE}${LOG_PREFIX.DONE} ${EMOJI.FAILURE} No checkpoints found for ${id} session.${STRING_LITERALS.NEWLINE}` +
141
+ `${LOG_PREFIX.DONE} ${CHECKPOINT_GATE_CONFIG.PATH} is set to '${CHECKPOINT_GATE_MODES.BLOCK}'.${STRING_LITERALS.NEWLINE}` +
142
+ `${LOG_PREFIX.DONE} Create a checkpoint before completing: ${CHECKPOINT_GATE_CONFIG.COMMAND_PREFIX} ${id}${STRING_LITERALS.NEWLINE}`);
143
+ }
144
+ function buildCheckpointGateWarnMessages(id) {
145
+ return [
146
+ `${STRING_LITERALS.NEWLINE}${LOG_PREFIX.DONE} ${EMOJI.INFO} ${CHECKPOINT_GATE_CONFIG.WARN_TAG}: No prior checkpoints recorded for ${id} in this session.`,
147
+ `${LOG_PREFIX.DONE} A pre-gates checkpoint will be created automatically by wu:done.`,
148
+ `${LOG_PREFIX.DONE} For earlier crash recovery, run '${CHECKPOINT_GATE_CONFIG.COMMAND_PREFIX} ${id}' after each acceptance criterion, before gates, or every 30 tool calls.${STRING_LITERALS.NEWLINE}`,
149
+ ];
150
+ }
151
+ export function resolveCheckpointGateMode(mode) {
152
+ if (mode === CHECKPOINT_GATE_MODES.OFF) {
153
+ return CHECKPOINT_GATE_MODES.OFF;
154
+ }
155
+ if (mode === CHECKPOINT_GATE_MODES.BLOCK) {
156
+ return CHECKPOINT_GATE_MODES.BLOCK;
157
+ }
158
+ return CHECKPOINT_GATE_MODES.WARN;
159
+ }
160
+ export async function enforceCheckpointGateForDone({ id, workspacePath, mode, queryByWuFn = queryByWu, hasSessionCheckpointsFn = hasSessionCheckpoints, log = console.log, blocker = (message) => {
161
+ die(message);
162
+ }, }) {
163
+ if (mode === CHECKPOINT_GATE_MODES.OFF) {
164
+ return;
165
+ }
166
+ let wuNodes;
167
+ try {
168
+ wuNodes = await queryByWuFn(workspacePath, id);
169
+ if (hasSessionCheckpointsFn(id, wuNodes)) {
170
+ return;
171
+ }
172
+ }
173
+ catch {
174
+ // Fail-open: checkpoint discovery issues should not block wu:done.
175
+ return;
176
+ }
177
+ if (mode === CHECKPOINT_GATE_MODES.BLOCK) {
178
+ blocker(buildCheckpointGateBlockMessage(id));
179
+ return;
180
+ }
181
+ const warnMessages = buildCheckpointGateWarnMessages(id);
182
+ for (const message of warnMessages) {
183
+ log(message);
184
+ }
185
+ }
129
186
  function normalizeWUDocLike(doc) {
130
187
  if (!doc || typeof doc !== 'object') {
131
188
  return {};
@@ -2078,7 +2135,7 @@ function printStateHUD({ id, docMain, isBranchOnly, isDocsOnly, derivedWorktree,
2078
2135
  console.log(`\n${LOG_PREFIX.DONE} HUD: WU=${id} status=${yamlStatus} stamp=${stampExists} locked=${yamlLocked} mode=${mode} branch=${branch} worktree=${worktreeDisplay}`);
2079
2136
  }
2080
2137
  // eslint-disable-next-line sonarjs/cognitive-complexity -- Pre-existing complexity, refactor tracked separately
2081
- async function main() {
2138
+ export async function main() {
2082
2139
  // Allow pre-push hook to recognize wu:done automation (WU-1030)
2083
2140
  process.env.LUMENFLOW_WU_TOOL = 'wu-done';
2084
2141
  // Validate CLI arguments and WU ID format (extracted to wu-done-validators.ts)
@@ -2198,39 +2255,14 @@ async function main() {
2198
2255
  });
2199
2256
  // Step 0: Run gates (WU-1215: extracted to executeGates function)
2200
2257
  const worktreePath = effectiveWorktreePath;
2201
- // WU-1471 AC3: Config-driven checkpoint gate (replaces WU-1943 hardcoded warn)
2202
- // Reads memory.enforcement.require_checkpoint_for_done from config:
2203
- // 'off' - skip checkpoint check entirely
2204
- // 'warn' - warn but allow wu:done (default, fail-open)
2205
- // 'block' - fail wu:done if no checkpoints found
2206
- try {
2207
- const checkpointGateConfig = getConfig();
2208
- const requireCheckpoint = checkpointGateConfig.memory?.enforcement?.require_checkpoint_for_done ?? 'warn';
2209
- if (requireCheckpoint !== 'off') {
2210
- const wuNodes = await queryByWu(worktreePath || mainCheckoutPath, id);
2211
- if (!hasSessionCheckpoints(id, wuNodes)) {
2212
- if (requireCheckpoint === 'block') {
2213
- die(`\n${LOG_PREFIX.DONE} ${EMOJI.FAILURE} No checkpoints found for ${id} session.\n` +
2214
- `${LOG_PREFIX.DONE} memory.enforcement.require_checkpoint_for_done is set to 'block'.\n` +
2215
- `${LOG_PREFIX.DONE} Create a checkpoint before completing: pnpm mem:checkpoint --wu ${id}\n`);
2216
- }
2217
- else {
2218
- // 'warn' mode (default)
2219
- console.log(`\n${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-1943: No checkpoints found for ${id} session.`);
2220
- console.log(`${LOG_PREFIX.DONE} Consider using 'pnpm mem:checkpoint --wu ${id}' periodically for crash recovery.`);
2221
- console.log(`${LOG_PREFIX.DONE} Checkpoint triggers: after each acceptance criterion, before gates, every 30 tool calls.\n`);
2222
- }
2223
- }
2224
- }
2225
- }
2226
- catch (checkpointErr) {
2227
- // Non-blocking in 'warn' mode: checkpoint check failure should not block wu:done
2228
- // In 'block' mode, die() already exited, so this only catches non-die errors
2229
- if (checkpointErr instanceof Error && checkpointErr.message?.includes('No checkpoints found')) {
2230
- throw checkpointErr; // Re-throw die() errors
2231
- }
2232
- // Otherwise silently allow - fail-open
2233
- }
2258
+ // WU-1471 AC3 + WU-1998: Config-driven checkpoint gate with accurate warn-mode messaging.
2259
+ const checkpointGateConfig = getConfig();
2260
+ const requireCheckpoint = resolveCheckpointGateMode(checkpointGateConfig.memory?.enforcement?.require_checkpoint_for_done);
2261
+ await enforceCheckpointGateForDone({
2262
+ id,
2263
+ workspacePath: worktreePath || mainCheckoutPath,
2264
+ mode: requireCheckpoint,
2265
+ });
2234
2266
  // WU-1663: Preparation complete - transition to gating state
2235
2267
  pipelineActor.send({ type: WU_DONE_EVENTS.PREPARATION_COMPLETE });
2236
2268
  // WU-1663: Wrap gates in try/catch to send pipeline failure event
package/dist/wu-edit.js CHANGED
@@ -247,7 +247,7 @@ async function ensureCleanWorkingTree() {
247
247
  * Main entry point
248
248
  */
249
249
  // eslint-disable-next-line sonarjs/cognitive-complexity -- Pre-existing complexity, refactor tracked separately
250
- async function main() {
250
+ export async function main() {
251
251
  const opts = parseArgs();
252
252
  const { id } = opts;
253
253
  console.log(`${PREFIX} Starting WU edit for ${id}`);
@@ -97,7 +97,7 @@ function loadWuYaml(id) {
97
97
  ` 2. Fix YAML errors manually and retry`);
98
98
  }
99
99
  }
100
- async function main() {
100
+ export async function main() {
101
101
  const args = parseArgs(process.argv);
102
102
  let codePaths = [];
103
103
  let description = '';
@@ -54,7 +54,7 @@ function detectWorktreePath(id) {
54
54
  /**
55
55
  * Main entry point
56
56
  */
57
- async function main() {
57
+ export async function main() {
58
58
  const PREFIX = LOG_PREFIX.PREFLIGHT;
59
59
  // WU-1180: Use createWUParser for proper Commander help output
60
60
  const args = createWUParser({
package/dist/wu-prep.js CHANGED
@@ -317,7 +317,7 @@ function printSuccessMessage(wuId, mainCheckout) {
317
317
  /**
318
318
  * Main entry point.
319
319
  */
320
- async function main() {
320
+ export async function main() {
321
321
  // Parse arguments
322
322
  const args = createWUParser({
323
323
  name: 'wu-prep',
package/dist/wu-proto.js CHANGED
@@ -220,7 +220,7 @@ function claimWU(wuId, lane) {
220
220
  die(`Failed to claim WU: ${error.message}`);
221
221
  }
222
222
  }
223
- async function main() {
223
+ export async function main() {
224
224
  const args = createWUParser({
225
225
  name: 'wu-proto',
226
226
  description: 'Create and claim a prototype WU with relaxed validation (rapid prototyping)',
package/dist/wu-prune.js CHANGED
@@ -123,7 +123,7 @@ async function validateWorktree(wt) {
123
123
  }
124
124
  return { valid: true, warnings, errors };
125
125
  }
126
- async function main() {
126
+ export async function main() {
127
127
  const args = parseArgs(process.argv);
128
128
  const PREFIX = LOG_PREFIX.PRUNE;
129
129
  if (args.help) {
@@ -473,7 +473,7 @@ export async function executeRecoveryAction(action, wuId) {
473
473
  /**
474
474
  * Main entry point
475
475
  */
476
- async function main() {
476
+ export async function main() {
477
477
  const args = createWUParser({
478
478
  name: 'wu-recover',
479
479
  description: 'Analyze and fix WU state inconsistencies (WU-1090)',
@@ -47,7 +47,7 @@ export function clearClaimMetadataOnRelease(doc) {
47
47
  export function shouldUseBranchPrReleasePath(doc) {
48
48
  return shouldUseBranchPrStatePath(doc);
49
49
  }
50
- async function main() {
50
+ export async function main() {
51
51
  const args = createWUParser({
52
52
  name: 'wu-release',
53
53
  description: 'Release an orphaned WU from in_progress back to ready state for reclaiming',
package/dist/wu-repair.js CHANGED
@@ -212,7 +212,7 @@ async function routeToRepairMode(options) {
212
212
  }
213
213
  return runConsistencyRepairMode(options);
214
214
  }
215
- async function main() {
215
+ export async function main() {
216
216
  const options = createProgram();
217
217
  validateOptions(options);
218
218
  validateModeRequirements(options);
@@ -11,14 +11,14 @@ import { existsSync, readFileSync } from 'node:fs';
11
11
  import path from 'node:path';
12
12
  import { spawn } from 'node:child_process';
13
13
  import { parse as parseYaml } from 'yaml';
14
- import { createWUParser, WU_OPTIONS, resolveLocation, readWURaw, buildSandboxProfile, resolveSandboxBackendForPlatform, SANDBOX_BACKEND_IDS, createLinuxSandboxBackend, createMacosSandboxBackend, createWindowsSandboxBackend, } from '@lumenflow/core';
14
+ import { createWUParser, WU_OPTIONS, resolveLocation, readWURaw, buildSandboxProfile, resolveSandboxBackendForPlatform, SANDBOX_BACKEND_IDS, createLinuxSandboxBackend, createMacosSandboxBackend, createWindowsSandboxBackend, WORKSPACE_CONFIG_FILE_NAME, WORKSPACE_V2_KEYS, } from '@lumenflow/core';
15
15
  import { WU_PATHS, defaultWorktreeFrom } from '@lumenflow/core/wu-paths';
16
16
  import { die } from '@lumenflow/core/error-handler';
17
17
  import { LOG_PREFIX, EXIT_CODES } from '@lumenflow/core/wu-constants';
18
18
  import { runCLI } from './cli-entry-point.js';
19
19
  const PREFIX = LOG_PREFIX.CLAIM.replace('wu-claim', 'wu:sandbox');
20
- const CONFIG_FILE = '.lumenflow.config.yaml';
21
20
  const DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR = 'LUMENFLOW_SANDBOX_ALLOW_UNSANDBOXED';
21
+ const SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
22
22
  function toNormalizedAbsolute(targetPath) {
23
23
  const normalized = path.resolve(targetPath);
24
24
  return normalized.length > 1 && normalized.endsWith(path.sep)
@@ -36,41 +36,54 @@ function parsePolicyConfig(value) {
36
36
  }
37
37
  return value;
38
38
  }
39
- export function readSandboxPolicy(projectRoot) {
40
- const configPath = path.join(projectRoot, CONFIG_FILE);
39
+ function readWorkspaceSoftwareDelivery(projectRoot) {
40
+ const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
41
41
  if (!existsSync(configPath)) {
42
- return {
43
- allowUnsandboxedEnvVar: DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR,
44
- extraWritableRoots: [],
45
- denyWritableRoots: [],
46
- };
42
+ return null;
47
43
  }
48
44
  try {
49
- const raw = parseYaml(readFileSync(configPath, 'utf8'));
50
- const sandbox = parsePolicyConfig(raw?.sandbox);
51
- const allowUnsandboxedEnvVar = typeof sandbox.allow_unsandboxed_fallback_env === 'string' &&
52
- sandbox.allow_unsandboxed_fallback_env.trim() !== ''
53
- ? sandbox.allow_unsandboxed_fallback_env.trim()
54
- : DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR;
55
- const extraWritableRoots = Array.isArray(sandbox.extra_writable_roots)
56
- ? sandbox.extra_writable_roots.filter((value) => typeof value === 'string')
57
- : [];
58
- const denyWritableRoots = Array.isArray(sandbox.deny_writable_roots)
59
- ? sandbox.deny_writable_roots.filter((value) => typeof value === 'string')
60
- : [];
61
- return {
62
- allowUnsandboxedEnvVar,
63
- extraWritableRoots,
64
- denyWritableRoots,
65
- };
45
+ const parsed = parseYaml(readFileSync(configPath, 'utf8'));
46
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
47
+ return null;
48
+ }
49
+ const workspace = parsed;
50
+ const softwareDelivery = workspace[SOFTWARE_DELIVERY_KEY];
51
+ if (!softwareDelivery ||
52
+ typeof softwareDelivery !== 'object' ||
53
+ Array.isArray(softwareDelivery)) {
54
+ return null;
55
+ }
56
+ return softwareDelivery;
66
57
  }
67
58
  catch {
59
+ return null;
60
+ }
61
+ }
62
+ export function readSandboxPolicy(projectRoot) {
63
+ const softwareDelivery = readWorkspaceSoftwareDelivery(projectRoot);
64
+ if (!softwareDelivery) {
68
65
  return {
69
66
  allowUnsandboxedEnvVar: DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR,
70
67
  extraWritableRoots: [],
71
68
  denyWritableRoots: [],
72
69
  };
73
70
  }
71
+ const sandbox = parsePolicyConfig(softwareDelivery.sandbox);
72
+ const allowUnsandboxedEnvVar = typeof sandbox.allow_unsandboxed_fallback_env === 'string' &&
73
+ sandbox.allow_unsandboxed_fallback_env.trim() !== ''
74
+ ? sandbox.allow_unsandboxed_fallback_env.trim()
75
+ : DEFAULT_ALLOW_UNSANDBOXED_ENV_VAR;
76
+ const extraWritableRoots = Array.isArray(sandbox.extra_writable_roots)
77
+ ? sandbox.extra_writable_roots.filter((value) => typeof value === 'string')
78
+ : [];
79
+ const denyWritableRoots = Array.isArray(sandbox.deny_writable_roots)
80
+ ? sandbox.deny_writable_roots.filter((value) => typeof value === 'string')
81
+ : [];
82
+ return {
83
+ allowUnsandboxedEnvVar,
84
+ extraWritableRoots,
85
+ denyWritableRoots,
86
+ };
74
87
  }
75
88
  export function extractSandboxCommandFromArgv(argv) {
76
89
  const separator = argv.indexOf('--');
@@ -244,7 +257,7 @@ export async function runWuSandbox(input) {
244
257
  }
245
258
  return runCommand(commandToRun, commandArgs, worktreePath);
246
259
  }
247
- async function main() {
260
+ export async function main() {
248
261
  const options = parseWuSandboxOptions(process.argv);
249
262
  const exitCode = await runWuSandbox(options);
250
263
  process.exit(exitCode);
package/dist/wu-status.js CHANGED
@@ -152,7 +152,7 @@ export function getStatusExitCode(context) {
152
152
  /**
153
153
  * Main entry point
154
154
  */
155
- async function main() {
155
+ export async function main() {
156
156
  const args = createWUParser({
157
157
  name: 'wu-status',
158
158
  description: 'Show WU status, location, and valid commands (WU-1090)',
@@ -114,7 +114,7 @@ function handleWorktreeCreation(args, doc) {
114
114
  }
115
115
  createWorktree(doc, worktreePath, branchName);
116
116
  }
117
- async function main() {
117
+ export async function main() {
118
118
  const args = createWUParser({
119
119
  name: 'wu-unblock',
120
120
  description: 'Unblock a work unit and move it from blocked to in-progress status',
@@ -96,7 +96,7 @@ function showLaneStatus(lane) {
96
96
  console.log(` pnpm wu:unlock-lane --lane "${lane}" --reason "<explanation>" --force`);
97
97
  }
98
98
  }
99
- async function main() {
99
+ export async function main() {
100
100
  const args = createWUParser({
101
101
  name: 'wu-unlock-lane',
102
102
  description: 'Safely unlock a lane lock with audit logging',
@@ -139,7 +139,7 @@ function validateAllWUs({ strict = true } = {}) {
139
139
  /**
140
140
  * Main entry point
141
141
  */
142
- async function main() {
142
+ export async function main() {
143
143
  const args = createWUParser({
144
144
  name: 'wu-validate',
145
145
  description: 'Validate WU YAML files against schema (strict mode by default, WU-1329)',