@lumenflow/core 1.0.0

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 (263) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +119 -0
  3. package/dist/active-wu-detector.d.ts +33 -0
  4. package/dist/active-wu-detector.js +106 -0
  5. package/dist/adapters/filesystem-metrics.adapter.d.ts +108 -0
  6. package/dist/adapters/filesystem-metrics.adapter.js +519 -0
  7. package/dist/adapters/terminal-renderer.adapter.d.ts +106 -0
  8. package/dist/adapters/terminal-renderer.adapter.js +337 -0
  9. package/dist/arg-parser.d.ts +63 -0
  10. package/dist/arg-parser.js +560 -0
  11. package/dist/backlog-editor.d.ts +98 -0
  12. package/dist/backlog-editor.js +179 -0
  13. package/dist/backlog-generator.d.ts +111 -0
  14. package/dist/backlog-generator.js +381 -0
  15. package/dist/backlog-parser.d.ts +45 -0
  16. package/dist/backlog-parser.js +102 -0
  17. package/dist/backlog-sync-validator.d.ts +78 -0
  18. package/dist/backlog-sync-validator.js +294 -0
  19. package/dist/branch-drift.d.ts +34 -0
  20. package/dist/branch-drift.js +51 -0
  21. package/dist/cleanup-install-config.d.ts +33 -0
  22. package/dist/cleanup-install-config.js +37 -0
  23. package/dist/cleanup-lock.d.ts +139 -0
  24. package/dist/cleanup-lock.js +313 -0
  25. package/dist/code-path-validator.d.ts +146 -0
  26. package/dist/code-path-validator.js +537 -0
  27. package/dist/code-paths-overlap.d.ts +55 -0
  28. package/dist/code-paths-overlap.js +245 -0
  29. package/dist/commands-logger.d.ts +77 -0
  30. package/dist/commands-logger.js +254 -0
  31. package/dist/commit-message-utils.d.ts +25 -0
  32. package/dist/commit-message-utils.js +41 -0
  33. package/dist/compliance-parser.d.ts +150 -0
  34. package/dist/compliance-parser.js +507 -0
  35. package/dist/constants/backlog-patterns.d.ts +20 -0
  36. package/dist/constants/backlog-patterns.js +23 -0
  37. package/dist/constants/dora-constants.d.ts +49 -0
  38. package/dist/constants/dora-constants.js +53 -0
  39. package/dist/constants/gate-constants.d.ts +15 -0
  40. package/dist/constants/gate-constants.js +15 -0
  41. package/dist/constants/linter-constants.d.ts +16 -0
  42. package/dist/constants/linter-constants.js +16 -0
  43. package/dist/constants/tokenizer-constants.d.ts +15 -0
  44. package/dist/constants/tokenizer-constants.js +15 -0
  45. package/dist/core/scope-checker.d.ts +97 -0
  46. package/dist/core/scope-checker.js +163 -0
  47. package/dist/core/tool-runner.d.ts +161 -0
  48. package/dist/core/tool-runner.js +393 -0
  49. package/dist/core/tool.constants.d.ts +105 -0
  50. package/dist/core/tool.constants.js +101 -0
  51. package/dist/core/tool.schemas.d.ts +226 -0
  52. package/dist/core/tool.schemas.js +226 -0
  53. package/dist/core/worktree-guard.d.ts +130 -0
  54. package/dist/core/worktree-guard.js +242 -0
  55. package/dist/coverage-gate.d.ts +108 -0
  56. package/dist/coverage-gate.js +196 -0
  57. package/dist/date-utils.d.ts +75 -0
  58. package/dist/date-utils.js +140 -0
  59. package/dist/dependency-graph.d.ts +142 -0
  60. package/dist/dependency-graph.js +550 -0
  61. package/dist/dependency-guard.d.ts +54 -0
  62. package/dist/dependency-guard.js +142 -0
  63. package/dist/dependency-validator.d.ts +105 -0
  64. package/dist/dependency-validator.js +154 -0
  65. package/dist/docs-path-validator.d.ts +36 -0
  66. package/dist/docs-path-validator.js +95 -0
  67. package/dist/domain/orchestration.constants.d.ts +99 -0
  68. package/dist/domain/orchestration.constants.js +97 -0
  69. package/dist/domain/orchestration.schemas.d.ts +280 -0
  70. package/dist/domain/orchestration.schemas.js +211 -0
  71. package/dist/domain/orchestration.types.d.ts +133 -0
  72. package/dist/domain/orchestration.types.js +12 -0
  73. package/dist/error-handler.d.ts +116 -0
  74. package/dist/error-handler.js +136 -0
  75. package/dist/file-classifiers.d.ts +62 -0
  76. package/dist/file-classifiers.js +108 -0
  77. package/dist/gates-agent-mode.d.ts +81 -0
  78. package/dist/gates-agent-mode.js +94 -0
  79. package/dist/generate-traceability.d.ts +107 -0
  80. package/dist/generate-traceability.js +411 -0
  81. package/dist/git-adapter.d.ts +395 -0
  82. package/dist/git-adapter.js +649 -0
  83. package/dist/git-staged-validator.d.ts +32 -0
  84. package/dist/git-staged-validator.js +48 -0
  85. package/dist/hardcoded-strings.d.ts +61 -0
  86. package/dist/hardcoded-strings.js +270 -0
  87. package/dist/incremental-lint.d.ts +78 -0
  88. package/dist/incremental-lint.js +129 -0
  89. package/dist/incremental-test.d.ts +39 -0
  90. package/dist/incremental-test.js +61 -0
  91. package/dist/index.d.ts +42 -0
  92. package/dist/index.js +61 -0
  93. package/dist/invariants/check-automated-tests.d.ts +50 -0
  94. package/dist/invariants/check-automated-tests.js +166 -0
  95. package/dist/invariants-runner.d.ts +103 -0
  96. package/dist/invariants-runner.js +527 -0
  97. package/dist/lane-checker.d.ts +50 -0
  98. package/dist/lane-checker.js +319 -0
  99. package/dist/lane-inference.d.ts +39 -0
  100. package/dist/lane-inference.js +195 -0
  101. package/dist/lane-lock.d.ts +211 -0
  102. package/dist/lane-lock.js +474 -0
  103. package/dist/lane-validator.d.ts +48 -0
  104. package/dist/lane-validator.js +114 -0
  105. package/dist/logs-lib.d.ts +104 -0
  106. package/dist/logs-lib.js +207 -0
  107. package/dist/lumenflow-config-schema.d.ts +272 -0
  108. package/dist/lumenflow-config-schema.js +207 -0
  109. package/dist/lumenflow-config.d.ts +95 -0
  110. package/dist/lumenflow-config.js +236 -0
  111. package/dist/manual-test-validator.d.ts +80 -0
  112. package/dist/manual-test-validator.js +200 -0
  113. package/dist/merge-lock.d.ts +115 -0
  114. package/dist/merge-lock.js +251 -0
  115. package/dist/micro-worktree.d.ts +159 -0
  116. package/dist/micro-worktree.js +427 -0
  117. package/dist/migration-deployer.d.ts +69 -0
  118. package/dist/migration-deployer.js +151 -0
  119. package/dist/orchestration-advisory-loader.d.ts +28 -0
  120. package/dist/orchestration-advisory-loader.js +87 -0
  121. package/dist/orchestration-advisory.d.ts +58 -0
  122. package/dist/orchestration-advisory.js +94 -0
  123. package/dist/orchestration-di.d.ts +48 -0
  124. package/dist/orchestration-di.js +57 -0
  125. package/dist/orchestration-rules.d.ts +57 -0
  126. package/dist/orchestration-rules.js +201 -0
  127. package/dist/orphan-detector.d.ts +131 -0
  128. package/dist/orphan-detector.js +226 -0
  129. package/dist/path-classifiers.d.ts +57 -0
  130. package/dist/path-classifiers.js +93 -0
  131. package/dist/piped-command-detector.d.ts +34 -0
  132. package/dist/piped-command-detector.js +64 -0
  133. package/dist/ports/dashboard-renderer.port.d.ts +112 -0
  134. package/dist/ports/dashboard-renderer.port.js +25 -0
  135. package/dist/ports/metrics-collector.port.d.ts +132 -0
  136. package/dist/ports/metrics-collector.port.js +26 -0
  137. package/dist/process-detector.d.ts +84 -0
  138. package/dist/process-detector.js +172 -0
  139. package/dist/prompt-linter.d.ts +72 -0
  140. package/dist/prompt-linter.js +312 -0
  141. package/dist/prompt-monitor.d.ts +15 -0
  142. package/dist/prompt-monitor.js +205 -0
  143. package/dist/rebase-artifact-cleanup.d.ts +145 -0
  144. package/dist/rebase-artifact-cleanup.js +433 -0
  145. package/dist/retry-strategy.d.ts +189 -0
  146. package/dist/retry-strategy.js +283 -0
  147. package/dist/risk-detector.d.ts +108 -0
  148. package/dist/risk-detector.js +252 -0
  149. package/dist/rollback-utils.d.ts +76 -0
  150. package/dist/rollback-utils.js +104 -0
  151. package/dist/section-headings.d.ts +43 -0
  152. package/dist/section-headings.js +49 -0
  153. package/dist/spawn-escalation.d.ts +90 -0
  154. package/dist/spawn-escalation.js +253 -0
  155. package/dist/spawn-monitor.d.ts +229 -0
  156. package/dist/spawn-monitor.js +672 -0
  157. package/dist/spawn-recovery.d.ts +82 -0
  158. package/dist/spawn-recovery.js +298 -0
  159. package/dist/spawn-registry-schema.d.ts +98 -0
  160. package/dist/spawn-registry-schema.js +108 -0
  161. package/dist/spawn-registry-store.d.ts +146 -0
  162. package/dist/spawn-registry-store.js +273 -0
  163. package/dist/spawn-tree.d.ts +121 -0
  164. package/dist/spawn-tree.js +285 -0
  165. package/dist/stamp-status-validator.d.ts +84 -0
  166. package/dist/stamp-status-validator.js +134 -0
  167. package/dist/stamp-utils.d.ts +100 -0
  168. package/dist/stamp-utils.js +229 -0
  169. package/dist/state-machine.d.ts +26 -0
  170. package/dist/state-machine.js +83 -0
  171. package/dist/system-map-validator.d.ts +80 -0
  172. package/dist/system-map-validator.js +272 -0
  173. package/dist/telemetry.d.ts +80 -0
  174. package/dist/telemetry.js +213 -0
  175. package/dist/token-counter.d.ts +51 -0
  176. package/dist/token-counter.js +145 -0
  177. package/dist/usecases/get-dashboard-data.usecase.d.ts +52 -0
  178. package/dist/usecases/get-dashboard-data.usecase.js +61 -0
  179. package/dist/usecases/get-suggestions.usecase.d.ts +100 -0
  180. package/dist/usecases/get-suggestions.usecase.js +153 -0
  181. package/dist/user-normalizer.d.ts +41 -0
  182. package/dist/user-normalizer.js +141 -0
  183. package/dist/validators/phi-constants.d.ts +97 -0
  184. package/dist/validators/phi-constants.js +152 -0
  185. package/dist/validators/phi-scanner.d.ts +58 -0
  186. package/dist/validators/phi-scanner.js +215 -0
  187. package/dist/worktree-ownership.d.ts +50 -0
  188. package/dist/worktree-ownership.js +74 -0
  189. package/dist/worktree-scanner.d.ts +103 -0
  190. package/dist/worktree-scanner.js +168 -0
  191. package/dist/worktree-symlink.d.ts +99 -0
  192. package/dist/worktree-symlink.js +359 -0
  193. package/dist/wu-backlog-updater.d.ts +17 -0
  194. package/dist/wu-backlog-updater.js +37 -0
  195. package/dist/wu-checkpoint.d.ts +124 -0
  196. package/dist/wu-checkpoint.js +233 -0
  197. package/dist/wu-claim-helpers.d.ts +26 -0
  198. package/dist/wu-claim-helpers.js +63 -0
  199. package/dist/wu-claim-resume.d.ts +106 -0
  200. package/dist/wu-claim-resume.js +276 -0
  201. package/dist/wu-consistency-checker.d.ts +95 -0
  202. package/dist/wu-consistency-checker.js +567 -0
  203. package/dist/wu-constants.d.ts +1275 -0
  204. package/dist/wu-constants.js +1382 -0
  205. package/dist/wu-create-validators.d.ts +42 -0
  206. package/dist/wu-create-validators.js +93 -0
  207. package/dist/wu-done-branch-only.d.ts +63 -0
  208. package/dist/wu-done-branch-only.js +191 -0
  209. package/dist/wu-done-messages.d.ts +119 -0
  210. package/dist/wu-done-messages.js +185 -0
  211. package/dist/wu-done-pr.d.ts +72 -0
  212. package/dist/wu-done-pr.js +174 -0
  213. package/dist/wu-done-retry-helpers.d.ts +85 -0
  214. package/dist/wu-done-retry-helpers.js +172 -0
  215. package/dist/wu-done-ui.d.ts +37 -0
  216. package/dist/wu-done-ui.js +69 -0
  217. package/dist/wu-done-validators.d.ts +411 -0
  218. package/dist/wu-done-validators.js +1229 -0
  219. package/dist/wu-done-worktree.d.ts +182 -0
  220. package/dist/wu-done-worktree.js +1097 -0
  221. package/dist/wu-helpers.d.ts +128 -0
  222. package/dist/wu-helpers.js +248 -0
  223. package/dist/wu-lint.d.ts +70 -0
  224. package/dist/wu-lint.js +234 -0
  225. package/dist/wu-paths.d.ts +171 -0
  226. package/dist/wu-paths.js +178 -0
  227. package/dist/wu-preflight-validators.d.ts +86 -0
  228. package/dist/wu-preflight-validators.js +251 -0
  229. package/dist/wu-recovery.d.ts +138 -0
  230. package/dist/wu-recovery.js +341 -0
  231. package/dist/wu-repair-core.d.ts +131 -0
  232. package/dist/wu-repair-core.js +669 -0
  233. package/dist/wu-schema-normalization.d.ts +17 -0
  234. package/dist/wu-schema-normalization.js +82 -0
  235. package/dist/wu-schema.d.ts +793 -0
  236. package/dist/wu-schema.js +881 -0
  237. package/dist/wu-spawn-helpers.d.ts +121 -0
  238. package/dist/wu-spawn-helpers.js +271 -0
  239. package/dist/wu-spawn.d.ts +158 -0
  240. package/dist/wu-spawn.js +1306 -0
  241. package/dist/wu-state-schema.d.ts +213 -0
  242. package/dist/wu-state-schema.js +156 -0
  243. package/dist/wu-state-store.d.ts +264 -0
  244. package/dist/wu-state-store.js +691 -0
  245. package/dist/wu-status-transition.d.ts +63 -0
  246. package/dist/wu-status-transition.js +382 -0
  247. package/dist/wu-status-updater.d.ts +25 -0
  248. package/dist/wu-status-updater.js +116 -0
  249. package/dist/wu-transaction-collectors.d.ts +116 -0
  250. package/dist/wu-transaction-collectors.js +272 -0
  251. package/dist/wu-transaction.d.ts +170 -0
  252. package/dist/wu-transaction.js +273 -0
  253. package/dist/wu-validation-constants.d.ts +60 -0
  254. package/dist/wu-validation-constants.js +66 -0
  255. package/dist/wu-validation.d.ts +118 -0
  256. package/dist/wu-validation.js +243 -0
  257. package/dist/wu-validator.d.ts +62 -0
  258. package/dist/wu-validator.js +325 -0
  259. package/dist/wu-yaml-fixer.d.ts +97 -0
  260. package/dist/wu-yaml-fixer.js +264 -0
  261. package/dist/wu-yaml.d.ts +86 -0
  262. package/dist/wu-yaml.js +222 -0
  263. package/package.json +114 -0
@@ -0,0 +1,560 @@
1
+ import { Command } from 'commander';
2
+ import { createError, ErrorCodes } from './error-handler.js';
3
+ import { EXIT_CODES } from './wu-constants.js';
4
+ /**
5
+ * Collector function for Commander.js repeatable options.
6
+ * Accumulates multiple flag values into an array.
7
+ *
8
+ * @param {string} value - New value from CLI
9
+ * @param {string[]} previous - Previously accumulated values
10
+ * @returns {string[]} Updated array with new value appended
11
+ * @see https://github.com/tj/commander.js#custom-option-processing
12
+ */
13
+ function collectRepeatable(value, previous) {
14
+ return previous.concat([value]);
15
+ }
16
+ export const WU_OPTIONS = {
17
+ // String options (require values)
18
+ id: {
19
+ name: 'id',
20
+ flags: '-i, --id <wuId>',
21
+ description: 'Work Unit ID (e.g., WU-123)',
22
+ },
23
+ wu: {
24
+ name: 'wu',
25
+ flags: '--wu <wuId>',
26
+ description: 'Work Unit ID to link (e.g., WU-123)',
27
+ },
28
+ lane: {
29
+ name: 'lane',
30
+ flags: '-l, --lane <lane>',
31
+ description: 'Lane name (e.g., "Operations: Tooling")',
32
+ },
33
+ title: {
34
+ name: 'title',
35
+ flags: '-t, --title <title>',
36
+ description: 'Work Unit title',
37
+ },
38
+ priority: {
39
+ name: 'priority',
40
+ flags: '-p, --priority <priority>',
41
+ description: 'Priority level (P0, P1, P2, P3)',
42
+ },
43
+ type: {
44
+ name: 'type',
45
+ flags: '--type <type>',
46
+ description: 'WU type (feature, bug, refactor, documentation)',
47
+ },
48
+ reason: {
49
+ name: 'reason',
50
+ flags: '-r, --reason <reason>',
51
+ description: 'Reason for action (required with --skip-gates, --override-owner)',
52
+ },
53
+ worktree: {
54
+ name: 'worktree',
55
+ flags: '-w, --worktree <path>',
56
+ description: 'Override worktree path',
57
+ },
58
+ branch: {
59
+ name: 'branch',
60
+ flags: '-b, --branch <branch>',
61
+ description: 'Override branch name',
62
+ },
63
+ fixWu: {
64
+ name: 'fixWu',
65
+ flags: '--fix-wu <wuId>',
66
+ description: 'WU ID that will fix the failures (required with --skip-gates)',
67
+ },
68
+ // Boolean options
69
+ noAuto: {
70
+ name: 'noAuto',
71
+ flags: '--no-auto',
72
+ description: 'Skip auto-updating YAML/backlog/status',
73
+ isNegated: true, // Commander treats --no-* specially
74
+ },
75
+ force: {
76
+ name: 'force',
77
+ flags: '-f, --force',
78
+ description: 'Force operation',
79
+ },
80
+ branchOnly: {
81
+ name: 'branchOnly',
82
+ flags: '--branch-only',
83
+ description: 'Use branch-only mode (no worktree)',
84
+ },
85
+ prMode: {
86
+ name: 'prMode',
87
+ flags: '--pr-mode',
88
+ description: 'Use PR mode (create PR instead of auto-merge)',
89
+ },
90
+ removeWorktree: {
91
+ name: 'removeWorktree',
92
+ flags: '--remove-worktree',
93
+ description: 'Remove worktree when blocking',
94
+ },
95
+ createWorktree: {
96
+ name: 'createWorktree',
97
+ flags: '--create-worktree',
98
+ description: 'Create worktree when unblocking',
99
+ },
100
+ deleteBranch: {
101
+ name: 'deleteBranch',
102
+ flags: '--delete-branch',
103
+ description: 'Delete lane branch after merge',
104
+ },
105
+ noRemove: {
106
+ name: 'noRemove',
107
+ flags: '--no-remove',
108
+ description: 'Skip worktree removal after completion',
109
+ isNegated: true,
110
+ },
111
+ noMerge: {
112
+ name: 'noMerge',
113
+ flags: '--no-merge',
114
+ description: 'Skip auto-merging lane branch to main',
115
+ isNegated: true,
116
+ },
117
+ help: {
118
+ name: 'help',
119
+ flags: '-h, --help',
120
+ description: 'Display help',
121
+ },
122
+ skipGates: {
123
+ name: 'skipGates',
124
+ flags: '--skip-gates',
125
+ description: 'Skip gates check (requires --reason and --fix-wu)',
126
+ },
127
+ allowTodo: {
128
+ name: 'allowTodo',
129
+ flags: '--allow-todo',
130
+ description: 'Allow TODO comments in code',
131
+ },
132
+ skipExposureCheck: {
133
+ name: 'skipExposureCheck',
134
+ flags: '--skip-exposure-check',
135
+ description: 'Skip exposure validation warnings (WU-1999)',
136
+ },
137
+ skipAccessibilityCheck: {
138
+ name: 'skipAccessibilityCheck',
139
+ flags: '--skip-accessibility-check',
140
+ description: 'Skip UI feature accessibility validation (WU-2022, not recommended)',
141
+ },
142
+ allowIncomplete: {
143
+ name: 'allowIncomplete',
144
+ flags: '--allow-incomplete',
145
+ description: 'Allow claiming with incomplete spec (bypasses spec completeness, NOT schema errors)',
146
+ },
147
+ forceOverlap: {
148
+ name: 'forceOverlap',
149
+ flags: '--force-overlap',
150
+ description: 'Force claiming despite overlap (requires --reason)',
151
+ },
152
+ fix: {
153
+ name: 'fix',
154
+ flags: '--fix',
155
+ description: 'Auto-fix common YAML validation issues (WU-1359)',
156
+ },
157
+ createPr: {
158
+ name: 'createPr',
159
+ flags: '--create-pr',
160
+ description: 'Create PR instead of auto-merge',
161
+ },
162
+ overrideOwner: {
163
+ name: 'overrideOwner',
164
+ flags: '--override-owner',
165
+ description: 'Override ownership check (requires --reason)',
166
+ },
167
+ noAutoRebase: {
168
+ name: 'noAutoRebase',
169
+ flags: '--no-auto-rebase',
170
+ description: 'Disable auto-rebase on branch divergence (WU-1303)',
171
+ isNegated: true,
172
+ },
173
+ // Initiative system options (WU-1247)
174
+ initiative: {
175
+ name: 'initiative',
176
+ flags: '--initiative <ref>',
177
+ description: 'Parent initiative (INIT-XXX or slug)',
178
+ },
179
+ phase: {
180
+ name: 'phase',
181
+ flags: '--phase <number>',
182
+ description: 'Phase number within initiative',
183
+ },
184
+ blockedBy: {
185
+ name: 'blockedBy',
186
+ flags: '--blocked-by <wuIds>',
187
+ description: 'Comma-separated WU IDs that block this WU',
188
+ },
189
+ blocks: {
190
+ name: 'blocks',
191
+ flags: '--blocks <wuIds>',
192
+ description: 'Comma-separated WU IDs this WU blocks',
193
+ },
194
+ labels: {
195
+ name: 'labels',
196
+ flags: '--labels <labels>',
197
+ description: 'Comma-separated labels',
198
+ },
199
+ slug: {
200
+ name: 'slug',
201
+ flags: '-s, --slug <slug>',
202
+ description: 'Initiative slug (kebab-case)',
203
+ },
204
+ initId: {
205
+ name: 'initId',
206
+ flags: '--init-id <initId>',
207
+ description: 'Initiative ID (e.g., INIT-001)',
208
+ },
209
+ owner: {
210
+ name: 'owner',
211
+ flags: '-o, --owner <owner>',
212
+ description: 'Initiative owner (team or individual)',
213
+ },
214
+ targetDate: {
215
+ name: 'targetDate',
216
+ flags: '--target-date <date>',
217
+ description: 'Target completion date (YYYY-MM-DD)',
218
+ },
219
+ format: {
220
+ name: 'format',
221
+ flags: '--format <format>',
222
+ description: 'Output format (table, json, ascii, mermaid)',
223
+ },
224
+ color: {
225
+ name: 'color',
226
+ flags: '--color',
227
+ description: 'Enable colored output',
228
+ },
229
+ status: {
230
+ name: 'status',
231
+ flags: '--status <status>',
232
+ description: 'Filter by status',
233
+ },
234
+ depth: {
235
+ name: 'depth',
236
+ flags: '-d, --depth <number>',
237
+ description: 'Maximum traversal depth',
238
+ },
239
+ direction: {
240
+ name: 'direction',
241
+ flags: '--direction <dir>',
242
+ description: 'Graph direction (up, down, both)',
243
+ },
244
+ assignedTo: {
245
+ name: 'assignedTo',
246
+ flags: '--assigned-to <email>',
247
+ description: 'Override assigned_to (defaults to git config user.email)',
248
+ },
249
+ // Bulk tooling options (WU-1614)
250
+ config: {
251
+ name: 'config',
252
+ flags: '--config <path>',
253
+ description: 'Path to config file (tool-specific)',
254
+ },
255
+ apply: {
256
+ name: 'apply',
257
+ flags: '--apply',
258
+ description: 'Apply changes (default is dry-run)',
259
+ },
260
+ syncFromInitiative: {
261
+ name: 'syncFromInitiative',
262
+ flags: '--sync-from-initiative',
263
+ description: 'Ensure WU initiative fields exist for WUs listed in initiatives',
264
+ },
265
+ reconcileInitiative: {
266
+ name: 'reconcileInitiative',
267
+ flags: '--reconcile-initiative <initId>',
268
+ description: 'Reconcile initiative `wus:` from WU initiative fields (repeatable)',
269
+ isRepeatable: true,
270
+ },
271
+ // WU-1364: Full spec inline options for wu:create
272
+ description: {
273
+ name: 'description',
274
+ flags: '--description <text>',
275
+ description: 'WU description text (Context/Problem/Solution)',
276
+ },
277
+ acceptance: {
278
+ name: 'acceptance',
279
+ flags: '--acceptance <criterion>',
280
+ description: 'Acceptance criterion (repeatable, use multiple times)',
281
+ isRepeatable: true,
282
+ },
283
+ codePaths: {
284
+ name: 'codePaths',
285
+ flags: '--code-paths <paths>',
286
+ description: 'Code paths (comma-separated)',
287
+ },
288
+ testPathsManual: {
289
+ name: 'testPathsManual',
290
+ flags: '--test-paths-manual <tests>',
291
+ description: 'Manual test descriptions (comma-separated)',
292
+ },
293
+ testPathsUnit: {
294
+ name: 'testPathsUnit',
295
+ flags: '--test-paths-unit <paths>',
296
+ description: 'Unit test file paths (comma-separated)',
297
+ },
298
+ testPathsE2e: {
299
+ name: 'testPathsE2e',
300
+ flags: '--test-paths-e2e <paths>',
301
+ description: 'E2E test file paths (comma-separated)',
302
+ },
303
+ validate: {
304
+ name: 'validate',
305
+ flags: '--validate',
306
+ description: 'Validate spec completeness (requires description, acceptance, test paths)',
307
+ },
308
+ // WU-2320: Spec reference for feature WUs
309
+ specRefs: {
310
+ name: 'specRefs',
311
+ flags: '--spec-refs <paths>',
312
+ description: 'Spec/plan references (comma-separated paths to docs, required for type: feature)',
313
+ },
314
+ // WU-1998: Exposure field options
315
+ exposure: {
316
+ name: 'exposure',
317
+ flags: '--exposure <type>',
318
+ description: 'Exposure level (ui, api, backend-only, documentation)',
319
+ },
320
+ userJourney: {
321
+ name: 'userJourney',
322
+ flags: '--user-journey <text>',
323
+ description: 'User journey description (recommended for ui/api exposure)',
324
+ },
325
+ uiPairingWus: {
326
+ name: 'uiPairingWus',
327
+ flags: '--ui-pairing-wus <wuIds>',
328
+ description: 'Comma-separated UI WU IDs that consume this API (for api exposure)',
329
+ },
330
+ // WU-1577: Thinking mode options for wu:spawn
331
+ thinking: {
332
+ name: 'thinking',
333
+ flags: '--thinking',
334
+ description: 'Enable extended thinking for sub-agent WU execution',
335
+ },
336
+ noThinking: {
337
+ name: 'noThinking',
338
+ flags: '--no-thinking',
339
+ description: 'Explicitly disable extended thinking (default behavior)',
340
+ isNegated: true,
341
+ },
342
+ budget: {
343
+ name: 'budget',
344
+ flags: '--budget <tokens>',
345
+ description: 'Token budget for extended thinking (requires --thinking)',
346
+ },
347
+ // WU-1912: Codex/GPT-friendly output mode for wu:spawn
348
+ codex: {
349
+ name: 'codex',
350
+ flags: '--codex',
351
+ description: 'Output a Codex/GPT-friendly Markdown prompt (instead of Claude Task antml)',
352
+ },
353
+ // WU-1945: Parent WU for spawn registry tracking
354
+ parentWu: {
355
+ name: 'parentWu',
356
+ flags: '--parent-wu <wuId>',
357
+ description: 'Parent WU ID for orchestrator context (e.g., WU-1000)',
358
+ },
359
+ // WU-1542: Mandatory agent enforcement for wu:done
360
+ requireAgents: {
361
+ name: 'requireAgents',
362
+ flags: '--require-agents',
363
+ description: 'Block wu:done if mandatory agents (security-auditor, beacon-guardian) were not invoked for WUs touching their trigger paths',
364
+ },
365
+ // WU-2411: Agent handoff for crashed/killed agents
366
+ resume: {
367
+ name: 'resume',
368
+ flags: '--resume',
369
+ description: 'Resume a WU from a crashed/killed agent (handoff) by taking over the existing worktree and updating the lock with new PID. Fails if original PID is still running (safety) or worktree does not exist.',
370
+ },
371
+ };
372
+ /**
373
+ * Negated options that commander handles specially.
374
+ * --no-foo creates opts.foo = false. We convert to noFoo = true.
375
+ */
376
+ const NEGATED_OPTIONS = ['auto', 'remove', 'merge', 'autoRebase'];
377
+ /**
378
+ * Post-process commander opts to handle negated boolean options.
379
+ * Commander's --no-* flags create opts.foo = false.
380
+ * For backward compat, we convert to noFoo = true.
381
+ *
382
+ * @param {object} opts - Commander parsed options
383
+ * @returns {object} Processed options with noFoo properties
384
+ */
385
+ function processNegatedOptions(opts) {
386
+ const result = { ...opts };
387
+ for (const key of NEGATED_OPTIONS) {
388
+ // Commander sets the property to false when --no-foo is used
389
+ // and undefined when not specified
390
+ if (key in result && result[key] === false) {
391
+ // Convert: auto=false → noAuto=true
392
+ const camelKey = `no${key.charAt(0).toUpperCase()}${key.slice(1)}`;
393
+ result[camelKey] = true;
394
+ delete result[key];
395
+ }
396
+ else if (key in result && result[key] === true) {
397
+ // Default value (not negated) - remove it
398
+ delete result[key];
399
+ }
400
+ }
401
+ return result;
402
+ }
403
+ /**
404
+ * Create a commander-based CLI parser for a WU script.
405
+ *
406
+ * @param {object} config - Parser configuration
407
+ * @param {string} config.name - Script name (e.g., 'wu-claim')
408
+ * @param {string} config.description - Script description for help text
409
+ * @param {Array<object>} config.options - Array of option objects from WU_OPTIONS
410
+ * @param {Array<string>} [config.required=[]] - Array of option names that are required
411
+ * @param {boolean} [config.allowPositionalId=false] - Allow first positional arg as WU ID
412
+ * @param {string} [config.version='1.0.0'] - Script version
413
+ * @returns {object} Parsed options object (camelCase keys)
414
+ *
415
+ * @example
416
+ * const opts = createWUParser({
417
+ * name: 'wu-claim',
418
+ * description: 'Claim a work unit for a lane',
419
+ * options: [WU_OPTIONS.id, WU_OPTIONS.lane, WU_OPTIONS.branchOnly],
420
+ * required: ['id', 'lane'],
421
+ * });
422
+ * console.log(opts.id); // 'WU-123'
423
+ * console.log(opts.branchOnly); // true
424
+ */
425
+ export function createWUParser(config) {
426
+ const { name, description, options = [], required = [], allowPositionalId = false, version = '1.0.0', } = config;
427
+ // Filter out pnpm's `--` separator from argv
428
+ const filteredArgv = process.argv.filter((arg) => arg !== '--');
429
+ const program = new Command()
430
+ .name(name)
431
+ .description(description)
432
+ .version(version)
433
+ .allowExcessArguments(allowPositionalId) // Allow positional args if needed
434
+ .exitOverride(); // Throw instead of process.exit for testability
435
+ // Register options
436
+ for (const opt of options) {
437
+ if (opt.isRepeatable) {
438
+ // Repeatable options use collect function with empty array default
439
+ // This allows: --flag "A" --flag "B" → ["A", "B"]
440
+ program.option(opt.flags, opt.description, collectRepeatable, []);
441
+ }
442
+ else if (required.includes(opt.name)) {
443
+ program.requiredOption(opt.flags, opt.description, opt.default);
444
+ }
445
+ else {
446
+ program.option(opt.flags, opt.description, opt.default);
447
+ }
448
+ }
449
+ try {
450
+ program.parse(filteredArgv);
451
+ }
452
+ catch (err) {
453
+ // Commander throws on help/version display - exit gracefully
454
+ if (err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {
455
+ process.exit(EXIT_CODES.SUCCESS);
456
+ }
457
+ // Commander throws on missing required options
458
+ if (err.code === 'commander.missingMandatoryOptionValue' ||
459
+ err.code === 'commander.missingArgument') {
460
+ throw createError(ErrorCodes.VALIDATION_ERROR, err.message, {
461
+ originalError: err.message,
462
+ code: err.code,
463
+ });
464
+ }
465
+ // Re-throw other errors
466
+ throw err;
467
+ }
468
+ let opts = program.opts();
469
+ // Process negated options for backward compat
470
+ opts = processNegatedOptions(opts);
471
+ // WU-1578: Handle --no-thinking explicitly via argv check
472
+ // Commander's handling of negated booleans varies, so we check argv directly
473
+ // when both --thinking and --no-thinking are registered as options
474
+ if (filteredArgv.includes('--no-thinking')) {
475
+ opts.noThinking = true;
476
+ delete opts.thinking;
477
+ }
478
+ // Handle positional argument as WU ID fallback
479
+ if (allowPositionalId && program.args.length > 0 && !opts.id) {
480
+ opts.id = program.args[0];
481
+ }
482
+ return opts;
483
+ }
484
+ /**
485
+ * Backward-compatible unified argument parser for WU management scripts.
486
+ * Uses commander internally but maintains the same return format.
487
+ *
488
+ * @deprecated Use createWUParser() for new scripts to get better help text.
489
+ *
490
+ * @param {string[]} argv - Process arguments (typically process.argv)
491
+ * @returns {object} Parsed arguments object (camelCase keys)
492
+ * @throws {Error} If unknown flag or missing required value
493
+ *
494
+ * @example
495
+ * const args = parseWUArgs(process.argv);
496
+ * console.log(args.id); // 'WU-123'
497
+ * console.log(args.branchOnly); // true
498
+ */
499
+ export function parseWUArgs(argv) {
500
+ // Filter out pnpm's `--` separator before parsing
501
+ const filteredArgv = argv.filter((arg) => arg !== '--');
502
+ const program = new Command()
503
+ .name('wu-script')
504
+ .description('WU management script')
505
+ .allowUnknownOption(false) // Strict mode - throw on unknown options
506
+ .allowExcessArguments(true) // Allow positional arguments
507
+ .exitOverride(); // Throw instead of process.exit
508
+ // Register all options for backward compatibility
509
+ const allOptions = [
510
+ WU_OPTIONS.id,
511
+ WU_OPTIONS.lane,
512
+ WU_OPTIONS.title,
513
+ WU_OPTIONS.priority,
514
+ WU_OPTIONS.type,
515
+ WU_OPTIONS.reason,
516
+ WU_OPTIONS.worktree,
517
+ WU_OPTIONS.branch,
518
+ WU_OPTIONS.fixWu,
519
+ WU_OPTIONS.noAuto,
520
+ WU_OPTIONS.force,
521
+ WU_OPTIONS.branchOnly,
522
+ WU_OPTIONS.prMode,
523
+ WU_OPTIONS.removeWorktree,
524
+ WU_OPTIONS.createWorktree,
525
+ WU_OPTIONS.deleteBranch,
526
+ WU_OPTIONS.noRemove,
527
+ WU_OPTIONS.noMerge,
528
+ WU_OPTIONS.help,
529
+ WU_OPTIONS.skipGates,
530
+ WU_OPTIONS.allowTodo,
531
+ WU_OPTIONS.skipExposureCheck,
532
+ WU_OPTIONS.skipAccessibilityCheck,
533
+ WU_OPTIONS.forceOverlap,
534
+ WU_OPTIONS.createPr,
535
+ WU_OPTIONS.overrideOwner,
536
+ WU_OPTIONS.noAutoRebase,
537
+ WU_OPTIONS.requireAgents,
538
+ ];
539
+ for (const opt of allOptions) {
540
+ program.option(opt.flags, opt.description, opt.default);
541
+ }
542
+ try {
543
+ program.parse(filteredArgv);
544
+ }
545
+ catch (err) {
546
+ // Re-throw with structured error for unknown options
547
+ throw createError(ErrorCodes.VALIDATION_ERROR, err.message, {
548
+ originalError: err.message,
549
+ argv: filteredArgv,
550
+ });
551
+ }
552
+ let opts = program.opts();
553
+ // Process negated options for backward compat
554
+ opts = processNegatedOptions(opts);
555
+ // Handle positional argument as WU ID fallback
556
+ if (program.args.length > 0 && !opts.id) {
557
+ opts.id = program.args[0];
558
+ }
559
+ return opts;
560
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Backlog/Status file editor module.
3
+ *
4
+ * Abstracts section movements and bullet manipulation to eliminate ~350 duplicate lines
5
+ * across wu-claim, wu-done, wu-block, wu-unblock, wu-cleanup, and wu-create.
6
+ *
7
+ * Core primitives:
8
+ * - readBacklogFile: Read file with frontmatter parsing
9
+ * - writeBacklogFile: Write file preserving frontmatter
10
+ * - findSectionBounds: Locate section start/end indices
11
+ * - removeBulletFromSection: Remove bullet from section
12
+ * - addBulletToSection: Add bullet to section
13
+ * - moveBullet: Atomic move operation (remove + add)
14
+ *
15
+ * @example
16
+ * import { moveBullet } from './lib/backlog-editor.js';
17
+ *
18
+ * moveBullet('docs/04-operations/tasks/backlog.md', {
19
+ * fromSection: '## Ready',
20
+ * toSection: '## In Progress',
21
+ * bulletPattern: 'WU-123',
22
+ * newBullet: '- [WU-123 — Title](link)',
23
+ * });
24
+ */
25
+ /**
26
+ * Read backlog/status file and separate frontmatter from content.
27
+ *
28
+ * @param {string} filePath - Path to file
29
+ * @returns {{ frontmatter: string, lines: string[] }} Frontmatter and content lines
30
+ */
31
+ export declare function readBacklogFile(filePath: any): {
32
+ frontmatter: string;
33
+ lines: string[];
34
+ };
35
+ /**
36
+ * Write backlog/status file with frontmatter and content.
37
+ *
38
+ * @param {string} filePath - Path to file
39
+ * @param {string} frontmatter - Frontmatter text (including --- markers)
40
+ * @param {string[]} lines - Content lines
41
+ */
42
+ export declare function writeBacklogFile(filePath: any, frontmatter: any, lines: any): void;
43
+ /**
44
+ * Find section boundaries in lines array.
45
+ *
46
+ * Finds the section starting with the given heading and returns its start/end indices.
47
+ * Section ends at the next ## heading or end of file.
48
+ *
49
+ * @param {string[]} lines - Content lines
50
+ * @param {string} heading - Section heading (e.g., '## Ready')
51
+ * @returns {{ start: number, end: number } | null} Section bounds or null if not found
52
+ */
53
+ export declare function findSectionBounds(lines: any, heading: any): {
54
+ start: any;
55
+ end: any;
56
+ };
57
+ /**
58
+ * Remove bullet matching pattern from section.
59
+ *
60
+ * Modifies lines array in-place, removing all bullets that contain the given pattern.
61
+ *
62
+ * @param {string[]} lines - Content lines (modified in-place)
63
+ * @param {number} sectionStart - Section start index
64
+ * @param {number} sectionEnd - Section end index
65
+ * @param {string} bulletPattern - Pattern to match (e.g., 'WU-123' or link path)
66
+ */
67
+ export declare function removeBulletFromSection(lines: any, sectionStart: any, sectionEnd: any, bulletPattern: any): void;
68
+ /**
69
+ * Add bullet to section.
70
+ *
71
+ * Inserts bullet after section header, replacing "(No items...)" marker if present.
72
+ * Modifies lines array in-place.
73
+ *
74
+ * @param {string[]} lines - Content lines (modified in-place)
75
+ * @param {number} sectionStart - Section start index
76
+ * @param {string} bullet - Bullet text to add (e.g., '- [WU-123 — Title](link)')
77
+ */
78
+ export declare function addBulletToSection(lines: any, sectionStart: any, bullet: any): void;
79
+ /**
80
+ * Move bullet from one section to another (atomic operation).
81
+ *
82
+ * Reads file, removes bullet from source section, adds bullet to target section,
83
+ * writes file back. Preserves frontmatter.
84
+ *
85
+ * @param {string} filePath - Path to backlog/status file
86
+ * @param {object} options - Move options
87
+ * @param {string} options.fromSection - Source section heading (e.g., '## Ready')
88
+ * @param {string} options.toSection - Target section heading (e.g., '## In Progress')
89
+ * @param {string} options.bulletPattern - Pattern to match for removal (e.g., 'WU-123')
90
+ * @param {string} options.newBullet - Bullet text to add (e.g., '- [WU-123 — Title](link)')
91
+ * @throws {Error} If file not found or sections not found
92
+ */
93
+ export declare function moveBullet(filePath: any, { fromSection, toSection, bulletPattern, newBullet }: {
94
+ fromSection: any;
95
+ toSection: any;
96
+ bulletPattern: any;
97
+ newBullet: any;
98
+ }): void;