@lumenflow/cli 3.14.0 → 3.16.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 (143) hide show
  1. package/dist/chunk-2D2VOCA4.js +37 -0
  2. package/dist/chunk-2D5KFYGX.js +284 -0
  3. package/dist/chunk-2GXVIN57.js +14072 -0
  4. package/dist/chunk-2MQ7HZWZ.js +26 -0
  5. package/dist/chunk-2UFQ3A3C.js +643 -0
  6. package/dist/chunk-3RG5ZIWI.js +10 -0
  7. package/dist/chunk-4N74J3UT.js +15 -0
  8. package/dist/chunk-5GTOXFYR.js +392 -0
  9. package/dist/chunk-5VY6MQMC.js +240 -0
  10. package/dist/chunk-67XVPMRY.js +1297 -0
  11. package/dist/chunk-6HO4GWJE.js +164 -0
  12. package/dist/chunk-6W5XHWYV.js +1890 -0
  13. package/dist/chunk-6X4EMYJQ.js +64 -0
  14. package/dist/chunk-6XYXI2NQ.js +772 -0
  15. package/dist/chunk-7ANSOV6Q.js +285 -0
  16. package/dist/chunk-A624LFLB.js +1380 -0
  17. package/dist/chunk-ADN5NHG4.js +126 -0
  18. package/dist/chunk-B7YJYJKG.js +33 -0
  19. package/dist/chunk-CCLHCPKG.js +210 -0
  20. package/dist/chunk-CK36VROC.js +1584 -0
  21. package/dist/chunk-D3UOFRSB.js +81 -0
  22. package/dist/chunk-DFR4DJBM.js +230 -0
  23. package/dist/chunk-DSYBDHYH.js +79 -0
  24. package/dist/chunk-DWMLTXKQ.js +1176 -0
  25. package/dist/chunk-E3REJTAJ.js +28 -0
  26. package/dist/chunk-EA3IVO64.js +633 -0
  27. package/dist/chunk-EK2AKZKD.js +55 -0
  28. package/dist/chunk-ELD7JTTT.js +343 -0
  29. package/dist/chunk-EX6TT2XI.js +195 -0
  30. package/dist/chunk-EXINSFZE.js +82 -0
  31. package/dist/chunk-EZ6ZBYBM.js +510 -0
  32. package/dist/chunk-FBKAPTJ2.js +16 -0
  33. package/dist/chunk-FVLV5RYH.js +1118 -0
  34. package/dist/chunk-GDNSBQVK.js +2485 -0
  35. package/dist/chunk-GPQHMBNN.js +278 -0
  36. package/dist/chunk-GTFJB67L.js +68 -0
  37. package/dist/chunk-HANJXVKW.js +1127 -0
  38. package/dist/chunk-HEVS5YLD.js +269 -0
  39. package/dist/chunk-HMEVZKPQ.js +9 -0
  40. package/dist/chunk-HRGSYNLM.js +3511 -0
  41. package/dist/chunk-ISZR5N4K.js +60 -0
  42. package/dist/chunk-J6SUPR2C.js +226 -0
  43. package/dist/chunk-JERYVEIZ.js +244 -0
  44. package/dist/chunk-JHHWGL2N.js +87 -0
  45. package/dist/chunk-JONWQUB5.js +775 -0
  46. package/dist/chunk-K2DIWWDM.js +1766 -0
  47. package/dist/chunk-KY4PGL5V.js +969 -0
  48. package/dist/chunk-L737LQ4C.js +1285 -0
  49. package/dist/chunk-LFTWYIB2.js +497 -0
  50. package/dist/chunk-LV47RFNJ.js +41 -0
  51. package/dist/chunk-MKSAITI7.js +15 -0
  52. package/dist/chunk-MZ7RKIX4.js +212 -0
  53. package/dist/chunk-NAP6CFSO.js +84 -0
  54. package/dist/chunk-ND6MY37M.js +16 -0
  55. package/dist/chunk-NMG736UR.js +683 -0
  56. package/dist/chunk-NRAXROED.js +32 -0
  57. package/dist/chunk-NRIZR3A7.js +690 -0
  58. package/dist/chunk-NX43BG3M.js +233 -0
  59. package/dist/chunk-O645XLSI.js +297 -0
  60. package/dist/chunk-OMJD6A3S.js +235 -0
  61. package/dist/chunk-QB6SJD4T.js +430 -0
  62. package/dist/chunk-QFSTL4J3.js +276 -0
  63. package/dist/chunk-QLGDFMFX.js +212 -0
  64. package/dist/chunk-RIAAGL2E.js +13 -0
  65. package/dist/chunk-RWO5XMZ6.js +86 -0
  66. package/dist/chunk-RXRKBBSM.js +149 -0
  67. package/dist/chunk-RZOZMML6.js +363 -0
  68. package/dist/chunk-U7I7FS7T.js +113 -0
  69. package/dist/chunk-UI42RODY.js +717 -0
  70. package/dist/chunk-UTVMVSCO.js +519 -0
  71. package/dist/chunk-V6OJGLBA.js +1746 -0
  72. package/dist/chunk-W2JHVH7D.js +152 -0
  73. package/dist/chunk-WD3Y7VQN.js +280 -0
  74. package/dist/chunk-WOCTQ5MS.js +303 -0
  75. package/dist/chunk-WZR3ZUNN.js +696 -0
  76. package/dist/chunk-XGI665H7.js +150 -0
  77. package/dist/chunk-XKY65P2T.js +304 -0
  78. package/dist/chunk-Y4CQZY65.js +57 -0
  79. package/dist/chunk-YFEXKLVE.js +194 -0
  80. package/dist/chunk-YHO3HS5X.js +287 -0
  81. package/dist/chunk-YLS7AZSX.js +738 -0
  82. package/dist/chunk-ZE473AO6.js +49 -0
  83. package/dist/chunk-ZF747T3O.js +644 -0
  84. package/dist/chunk-ZHCZHZH3.js +43 -0
  85. package/dist/chunk-ZZNZX2XY.js +87 -0
  86. package/dist/constants-7QAP3VQ4.js +23 -0
  87. package/dist/dist-IY3UUMWK.js +33 -0
  88. package/dist/docs-sync.js +60 -25
  89. package/dist/docs-sync.js.map +1 -1
  90. package/dist/gates-runners.js +43 -2
  91. package/dist/gates-runners.js.map +1 -1
  92. package/dist/init-templates.js +26 -219
  93. package/dist/init-templates.js.map +1 -1
  94. package/dist/invariants-runner-W5RGHCSU.js +27 -0
  95. package/dist/lane-lock-6J36HD5O.js +35 -0
  96. package/dist/lumenflow-upgrade.js +60 -0
  97. package/dist/lumenflow-upgrade.js.map +1 -1
  98. package/dist/mem-checkpoint-core-EANG2GVN.js +14 -0
  99. package/dist/mem-signal-core-2LZ2WYHW.js +19 -0
  100. package/dist/memory-store-OLB5FO7K.js +18 -0
  101. package/dist/plan-edit.js +19 -24
  102. package/dist/plan-edit.js.map +1 -1
  103. package/dist/plan-promote.js +15 -23
  104. package/dist/plan-promote.js.map +1 -1
  105. package/dist/plan-resolve.js +111 -0
  106. package/dist/plan-resolve.js.map +1 -0
  107. package/dist/public-manifest.js +2 -2
  108. package/dist/public-manifest.js.map +1 -1
  109. package/dist/service-6BYCOCO5.js +13 -0
  110. package/dist/spawn-policy-resolver-NTSZYQ6R.js +17 -0
  111. package/dist/spawn-task-builder-R4E2BHSW.js +22 -0
  112. package/dist/sync-templates.js +12 -0
  113. package/dist/sync-templates.js.map +1 -1
  114. package/dist/wu-claim-validation.js +9 -1
  115. package/dist/wu-claim-validation.js.map +1 -1
  116. package/dist/wu-done-pr-WLFFFEPJ.js +25 -0
  117. package/dist/wu-done-validation-3J5E36FE.js +30 -0
  118. package/dist/wu-done.js +42 -1
  119. package/dist/wu-done.js.map +1 -1
  120. package/dist/wu-duplicate-id-detector-5S7JHELK.js +232 -0
  121. package/dist/wu-edit-operations.js +7 -6
  122. package/dist/wu-edit-operations.js.map +1 -1
  123. package/dist/wu-edit.js +23 -3
  124. package/dist/wu-edit.js.map +1 -1
  125. package/dist/wu-spawn-prompt-builders.js +38 -1
  126. package/dist/wu-spawn-prompt-builders.js.map +1 -1
  127. package/package.json +8 -8
  128. package/packs/sidekick/.turbo/turbo-build.log +1 -1
  129. package/packs/sidekick/.turbo/turbo-typecheck.log +4 -0
  130. package/packs/sidekick/package.json +1 -1
  131. package/packs/software-delivery/.turbo/turbo-build.log +1 -1
  132. package/packs/software-delivery/.turbo/turbo-typecheck.log +4 -0
  133. package/packs/software-delivery/package.json +1 -1
  134. package/templates/core/AGENTS.md.template +19 -0
  135. package/templates/core/LUMENFLOW.md.template +13 -2
  136. package/templates/core/UPGRADING.md.template +6 -6
  137. package/templates/core/ai/onboarding/first-15-mins.md.template +1 -1
  138. package/templates/core/ai/onboarding/first-wu-mistakes.md.template +10 -0
  139. package/templates/core/ai/onboarding/quick-ref-commands.md.template +11 -8
  140. package/templates/core/ai/onboarding/starting-prompt.md.template +1 -1
  141. package/templates/core/ai/onboarding/wu-sizing-guide.md.template +11 -2
  142. package/templates/vendors/cursor/.cursor/rules/lumenflow.md.template +9 -1
  143. package/templates/vendors/windsurf/.windsurf/rules/lumenflow.md.template +9 -1
@@ -0,0 +1,1297 @@
1
+ import {
2
+ DIRECTORIES,
3
+ FILE_SYSTEM,
4
+ LUMENFLOW_PATHS
5
+ } from "./chunk-DWMLTXKQ.js";
6
+ import {
7
+ WORKSPACE_CONFIG_FILE_NAME,
8
+ WORKSPACE_V2_KEYS,
9
+ getConfig
10
+ } from "./chunk-V6OJGLBA.js";
11
+
12
+ // src/init-templates.ts
13
+ var DEFAULT_WORKTREES_DIR = DIRECTORIES.WORKTREES;
14
+ var DEFAULT_WORKTREES_PATTERN = DEFAULT_WORKTREES_DIR.endsWith("/") ? DEFAULT_WORKTREES_DIR.slice(0, -1) : DEFAULT_WORKTREES_DIR;
15
+ var DEFAULT_STATE_DIR_IGNORE = LUMENFLOW_PATHS.STATE_DIR.endsWith("/") ? LUMENFLOW_PATHS.STATE_DIR : `${LUMENFLOW_PATHS.STATE_DIR}/`;
16
+ var DEFAULT_LANE_DEFINITIONS = [
17
+ {
18
+ name: "Framework: Core",
19
+ wip_limit: 1,
20
+ code_paths: ["packages/**/core/**", "src/core/**", "lib/**"]
21
+ },
22
+ {
23
+ name: "Framework: CLI",
24
+ wip_limit: 1,
25
+ code_paths: ["packages/**/cli/**", "src/cli/**", "bin/**"]
26
+ },
27
+ {
28
+ name: "Experience: Web",
29
+ wip_limit: 1,
30
+ code_paths: ["apps/web/**", "web/**", "src/components/**", "src/pages/**", "src/app/**"]
31
+ },
32
+ {
33
+ name: "Operations: Infrastructure",
34
+ wip_limit: 1,
35
+ code_paths: ["infrastructure/**", "deploy/**"]
36
+ },
37
+ {
38
+ name: "Operations: CI/CD",
39
+ wip_limit: 1,
40
+ code_paths: [".github/workflows/**", ".github/actions/**", ".circleci/**"]
41
+ },
42
+ {
43
+ name: "Content: Documentation",
44
+ wip_limit: 1,
45
+ code_paths: ["docs/**", "*.md"]
46
+ }
47
+ ];
48
+ var AGENTS_MD_TEMPLATE = `# Universal Agent Instructions
49
+
50
+ **Last updated:** {{DATE}}
51
+
52
+ This project uses LumenFlow workflow. For complete documentation, see [LUMENFLOW.md](LUMENFLOW.md).
53
+
54
+ ---
55
+
56
+ ## Quick Start
57
+
58
+ \`\`\`bash
59
+ # First-time lane setup (once per project)
60
+ pnpm lane:setup
61
+ pnpm lane:validate
62
+ pnpm lane:lock
63
+ \`\`\`
64
+
65
+ \`\`\`bash
66
+ # 1. Claim a WU
67
+ pnpm wu:claim --id WU-XXXX --lane <Lane>
68
+ cd worktrees/<lane>-wu-xxxx
69
+
70
+ # 2. Work in worktree, run gates
71
+ pnpm gates
72
+
73
+ # 3. Complete (ALWAYS run this!)
74
+ cd <project-root>
75
+ pnpm wu:done --id WU-XXXX
76
+ \`\`\`
77
+
78
+ > **Complete CLI reference:** See [quick-ref-commands.md]({{QUICK_REF_LINK}})
79
+
80
+ ---
81
+
82
+ ## Critical: Always wu:done
83
+
84
+ After completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\` from the main checkout.
85
+
86
+ This is the single most forgotten step. See [LUMENFLOW.md](LUMENFLOW.md) for details.
87
+
88
+ ---
89
+
90
+ ## Core Principles
91
+
92
+ 1. **Fit-For-Surface Verification**: Choose the least brittle verification that gives strong confidence. Prefer TDD for runtime logic when policy requires it; avoid brittle UI implementation-detail tests.
93
+ 2. **Worktree Discipline**: After \`wu:claim\`, work ONLY in the worktree
94
+ 3. **Gates Before Done**: Run \`pnpm gates\` before \`wu:done\`
95
+ 4. **Never Bypass Hooks**: No \`--no-verify\`
96
+
97
+ ---
98
+
99
+ ## Forbidden Commands
100
+
101
+ - \`git reset --hard\`
102
+ - \`git push --force\`
103
+ - \`git stash\` (on main)
104
+ - \`--no-verify\`
105
+
106
+ ---
107
+
108
+ ## Vendor-Specific Overlays
109
+
110
+ This file provides universal guidance for all AI agents. Additional vendor-specific configuration:
111
+
112
+ - **Claude Code**: See \`CLAUDE.md\` (if present)
113
+ - **Cursor**: See \`.cursor/rules/lumenflow.md\` (if present)
114
+ - **Windsurf**: See \`.windsurf/rules/lumenflow.md\` (if present)
115
+ `;
116
+ var CLAUDE_MD_TEMPLATE = `# Claude Code Instructions
117
+
118
+ **Last updated:** {{DATE}}
119
+
120
+ This project uses LumenFlow workflow. For workflow documentation, see [LUMENFLOW.md](LUMENFLOW.md).
121
+
122
+ ---
123
+
124
+ ## Quick Start
125
+
126
+ \`\`\`bash
127
+ # 1. Claim a WU
128
+ pnpm wu:claim --id WU-XXXX --lane <Lane>
129
+ cd worktrees/<lane>-wu-xxxx
130
+
131
+ # 2. Work in worktree, run gates
132
+ pnpm gates
133
+
134
+ # 3. Complete (ALWAYS run this!)
135
+ cd <project-root>
136
+ pnpm wu:done --id WU-XXXX
137
+ \`\`\`
138
+
139
+ ---
140
+
141
+ ## CLI Commands Reference
142
+
143
+ ### WU Lifecycle
144
+
145
+ | Command | Description |
146
+ | ----------------------------------------- | ---------------------------------------- |
147
+ | \`pnpm wu:status --id WU-XXX\` | Show WU status, location, valid commands |
148
+ | \`pnpm wu:claim --id WU-XXX --lane <Lane>\` | Claim WU and create worktree |
149
+ | \`pnpm wu:prep --id WU-XXX\` | Run gates in worktree, prep for wu:done |
150
+ | \`pnpm wu:done --id WU-XXX\` | Complete WU (from main checkout) |
151
+ | \`pnpm wu:block --id WU-XXX --reason "..."\`| Block WU with reason |
152
+ | \`pnpm wu:unblock --id WU-XXX\` | Unblock WU |
153
+
154
+ ### Gates & Quality
155
+
156
+ | Command | Description |
157
+ | ------------------------ | -------------------------- |
158
+ | \`pnpm gates\` | Run all quality gates |
159
+ | \`pnpm gates --docs-only\` | Run gates for docs changes |
160
+ | \`pnpm format\` | Format all files |
161
+ | \`pnpm lint\` | Run linter |
162
+ | \`pnpm typecheck\` | Run TypeScript check |
163
+ | \`pnpm test\` | Run tests |
164
+
165
+ ---
166
+
167
+ ## Critical: Always wu:done
168
+
169
+ After completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\` from the main checkout.
170
+
171
+ See [LUMENFLOW.md](LUMENFLOW.md) for full workflow documentation.
172
+
173
+ ---
174
+
175
+ ## Warning: Do Not Edit WU YAML Files Manually
176
+
177
+ **Never manually edit WU YAML files** in \`docs/.../tasks/wu/WU-XXX.yaml\`.
178
+
179
+ Use CLI commands instead:
180
+
181
+ - \`pnpm wu:create ...\` to create new WUs
182
+ - \`pnpm wu:edit --id WU-XXX ...\` to modify WU fields
183
+ - \`pnpm wu:claim\` / \`wu:block\` / \`wu:done\` for status changes
184
+
185
+ Manual edits bypass validation and can corrupt workflow state.
186
+ `;
187
+ var CLAUDE_SETTINGS_TEMPLATE = `{
188
+ "$schema": "https://json.schemastore.org/claude-code-settings.json",
189
+ "permissions": {
190
+ "allow": [
191
+ "Bash",
192
+ "Read",
193
+ "Write",
194
+ "Edit",
195
+ "WebFetch",
196
+ "WebSearch"
197
+ ],
198
+ "deny": [
199
+ "Read(./.env)",
200
+ "Read(./.env.*)",
201
+ "Write(./.env*)",
202
+ "Bash(git reset --hard *)",
203
+ "Bash(git stash *)",
204
+ "Bash(git clean -fd *)",
205
+ "Bash(git push --force *)",
206
+ "Bash(git push -f *)",
207
+ "Bash(git commit --no-verify *)",
208
+ "Bash(HUSKY=0 *)",
209
+ "Bash(rm -rf /*)",
210
+ "Bash(sudo *)",
211
+ "Bash(git worktree remove *)",
212
+ "Bash(git worktree prune *)"
213
+ ]
214
+ }
215
+ }
216
+ `;
217
+ var CURSOR_RULES_TEMPLATE = `# Cursor LumenFlow Rules
218
+
219
+ This project uses LumenFlow workflow. See [LUMENFLOW.md](../../LUMENFLOW.md).
220
+
221
+ ## Critical Rules
222
+
223
+ 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
224
+ 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
225
+ 3. **Never bypass hooks** - No \`--no-verify\`
226
+ 4. **TDD** - Write tests first
227
+
228
+ ## Forbidden Commands
229
+
230
+ - \`git reset --hard\`
231
+ - \`git push --force\`
232
+ - \`git stash\` (on main)
233
+ - \`--no-verify\`
234
+
235
+ ## Quick Reference
236
+
237
+ \`\`\`bash
238
+ # Claim WU
239
+ pnpm wu:claim --id WU-XXX --lane <Lane>
240
+ cd worktrees/<lane>-wu-xxx
241
+
242
+ # Run gates
243
+ pnpm gates
244
+
245
+ # Complete (from main)
246
+ cd <project-root>
247
+ pnpm wu:done --id WU-XXX
248
+ \`\`\`
249
+ `;
250
+ var WINDSURF_RULES_TEMPLATE = `# Windsurf LumenFlow Rules
251
+
252
+ This project uses LumenFlow workflow. See [LUMENFLOW.md](../../LUMENFLOW.md).
253
+
254
+ ## Critical Rules
255
+
256
+ 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
257
+ 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
258
+ 3. **Never bypass hooks** - No \`--no-verify\`
259
+ 4. **TDD** - Write tests first
260
+
261
+ ## Forbidden Commands
262
+
263
+ - \`git reset --hard\`
264
+ - \`git push --force\`
265
+ - \`git stash\` (on main)
266
+ - \`--no-verify\`
267
+
268
+ ## Quick Reference
269
+
270
+ \`\`\`bash
271
+ # Claim WU
272
+ pnpm wu:claim --id WU-XXX --lane <Lane>
273
+ cd worktrees/<lane>-wu-xxx
274
+
275
+ # Run gates
276
+ pnpm gates
277
+
278
+ # Complete (from main)
279
+ cd <project-root>
280
+ pnpm wu:done --id WU-XXX
281
+ \`\`\`
282
+ `;
283
+ var CLINE_RULES_TEMPLATE = `# Cline LumenFlow Rules
284
+
285
+ This project uses LumenFlow workflow. See [LUMENFLOW.md](LUMENFLOW.md).
286
+
287
+ ## Critical Rules
288
+
289
+ 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
290
+ 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
291
+ 3. **Never bypass hooks** - No \`--no-verify\`
292
+ 4. **TDD** - Write tests first
293
+
294
+ ## Forbidden Commands
295
+
296
+ - \`git reset --hard\`
297
+ - \`git push --force\`
298
+ - \`git stash\` (on main)
299
+ - \`--no-verify\`
300
+
301
+ ## Quick Reference
302
+
303
+ \`\`\`bash
304
+ # Claim WU
305
+ pnpm wu:claim --id WU-XXX --lane <Lane>
306
+ cd worktrees/<lane>-wu-xxx
307
+
308
+ # Run gates
309
+ pnpm gates
310
+
311
+ # Complete (from main)
312
+ cd <project-root>
313
+ pnpm wu:done --id WU-XXX
314
+ \`\`\`
315
+ `;
316
+ var AIDER_CONF_TEMPLATE = `# Aider Configuration for LumenFlow Projects
317
+ # See LUMENFLOW.md for workflow documentation
318
+
319
+ model: gpt-4-turbo
320
+ auto-commits: false
321
+ dirty-commits: false
322
+
323
+ read:
324
+ - LUMENFLOW.md
325
+ - .lumenflow/constraints.md
326
+ `;
327
+ var MCP_JSON_TEMPLATE = `{
328
+ "mcpServers": {
329
+ "lumenflow": {
330
+ "command": "npx",
331
+ "args": ["@lumenflow/mcp"]
332
+ }
333
+ }
334
+ }
335
+ `;
336
+ var BACKLOG_TEMPLATE = `---
337
+ sections:
338
+ ready:
339
+ heading: '## \u{1F680} Ready (pull from here)'
340
+ insertion: after_heading_blank_line
341
+ in_progress:
342
+ heading: '## \u{1F527} In progress'
343
+ insertion: after_heading_blank_line
344
+ blocked:
345
+ heading: '## \u26D4 Blocked'
346
+ insertion: after_heading_blank_line
347
+ done:
348
+ heading: '## \u2705 Done'
349
+ insertion: after_heading_blank_line
350
+ ---
351
+
352
+ # Backlog (single source of truth)
353
+
354
+ ## \u{1F680} Ready (pull from here)
355
+
356
+ (No items ready)
357
+
358
+ ## \u{1F527} In progress
359
+
360
+ (No items in progress)
361
+
362
+ ## \u26D4 Blocked
363
+
364
+ (No items blocked)
365
+
366
+ ## \u2705 Done
367
+
368
+ (No items completed yet)
369
+ `;
370
+ var STATUS_TEMPLATE = `# Status (active work)
371
+
372
+ ## In Progress
373
+
374
+ (No items in progress)
375
+
376
+ ## Blocked
377
+
378
+ (No items blocked)
379
+
380
+ ## Completed
381
+
382
+ (No items completed yet)
383
+ `;
384
+ var WU_TEMPLATE_YAML = `# Work Unit Template (LumenFlow WU Schema)
385
+ #
386
+ # Copy this template when creating new WUs. Fill in all required fields and
387
+ # remove optional fields if not needed.
388
+ #
389
+ # If you used "lumenflow init --full", this template lives at:
390
+ # {{DOCS_TASKS_PATH}}/templates/wu-template.yaml
391
+
392
+ # Required: Unique work unit identifier (format: WU-NNN)
393
+ id: WU-XXX
394
+
395
+ # Required: Short, descriptive title (max 80 chars)
396
+ title: 'Your WU title here'
397
+
398
+ # Required: Lane (Parent: Sublane format)
399
+ lane: '<Parent: Sublane>'
400
+
401
+ # Required: Type of work
402
+ type: 'feature' # feature | bug | documentation | process | tooling | chore | refactor
403
+
404
+ # Required: Current status
405
+ status: 'ready' # ready | in_progress | blocked | done | cancelled
406
+
407
+ # Required: Priority
408
+ priority: P2 # P0 | P1 | P2 | P3
409
+
410
+ # Required: Creation date (YYYY-MM-DD)
411
+ created: {{DATE}}
412
+
413
+ # Required: Owner/assignee (email)
414
+ assigned_to: 'unassigned@example.com'
415
+
416
+ # Required: Description
417
+ description: |
418
+ Context: ...
419
+ Problem: ...
420
+ Solution: ...
421
+
422
+ # Required: Acceptance criteria (testable, binary)
423
+ acceptance:
424
+ - Criterion 1 (specific, measurable, testable)
425
+ - Criterion 2 (binary pass/fail)
426
+ - Documentation updated
427
+
428
+ # Required: References to plans/specs (required for type: feature)
429
+ # Tip: use pnpm wu:create --plan to generate a plan stub at lumenflow://plans/WU-XXX-plan.md
430
+ spec_refs:
431
+ - lumenflow://plans/WU-XXX-plan.md
432
+
433
+ # Required: Code files changed or created (empty only for docs/process WUs)
434
+ # Docs-only WUs should use docs/ or *.md paths to avoid docs-only gate failures.
435
+ code_paths:
436
+ - path/to/file.ts
437
+
438
+ # Required: Test paths (at least one of manual/unit/e2e/integration for non-doc WUs)
439
+ tests:
440
+ manual:
441
+ - Manual check: Verify behavior or docs output
442
+ unit:
443
+ - path/to/test.test.ts
444
+ e2e: []
445
+ integration: []
446
+
447
+ # Required: Exposure level
448
+ exposure: 'backend-only' # ui | api | backend-only | documentation
449
+
450
+ # Optional: User journey (recommended for ui/api)
451
+ # user_journey: |
452
+ # User navigates to ...
453
+ # User performs ...
454
+
455
+ # Optional: UI pairing WUs (for api exposure)
456
+ # ui_pairing_wus:
457
+ # - WU-1234
458
+
459
+ # Optional: Navigation path (required when exposure=ui and no page file)
460
+ # navigation_path: '/settings'
461
+
462
+ # Required: Deliverable artifacts (stamps, docs, etc.)
463
+ artifacts:
464
+ - .lumenflow/stamps/WU-XXX.done
465
+
466
+ # Optional: Dependencies (other WUs that must complete first)
467
+ dependencies: []
468
+
469
+ # Optional: Risks
470
+ risks:
471
+ - Risk 1
472
+
473
+ # Optional: Notes (required by spec linter)
474
+ notes: 'Implementation notes, rollout context, or plan summary.'
475
+
476
+ # Optional: Requires human review
477
+ requires_review: false
478
+
479
+ # Optional: Claimed mode (worktree or branch-only)
480
+ # Automatically set by wu:claim, usually don't need to specify
481
+ # claimed_mode: worktree
482
+
483
+ # Optional: Assigned to (email of current claimant)
484
+ # Automatically set by wu:claim
485
+ # assigned_to: engineer@example.com
486
+
487
+ # Optional: Locked status (prevents concurrent edits)
488
+ # Automatically set by wu:claim and wu:done
489
+ # locked: false
490
+
491
+ # Optional: Completion date (ISO 8601 format)
492
+ # Automatically set by wu:done
493
+ # completed: 2025-10-23
494
+
495
+ # Optional: Completion notes (added by wu:done)
496
+ # completion_notes: |
497
+ # Additional notes added during wu:done.
498
+ # Any deviations from original plan.
499
+ # Lessons learned.
500
+
501
+ # ============================================================================
502
+ # GOVERNANCE BLOCK (WU Schema v2.0)
503
+ # ============================================================================
504
+ # Optional: COS governance rules that apply to this WU
505
+ # Only include if this WU needs specific governance enforcement
506
+
507
+ # governance:
508
+ # # Rules that apply to this WU (evaluated during cos:gates)
509
+ # rules:
510
+ # - rule_id: UPAIN-01
511
+ # satisfied: false # Initially false, set true when evidence provided
512
+ # evidence:
513
+ # - type: link
514
+ # value: docs/product/voc/feature-user-pain.md
515
+ # description: "Voice of Customer analysis showing user pain"
516
+ # notes: |
517
+ # VOC analysis shows 40% of support tickets request this feature.
518
+ # Average time wasted: 15min/user/week.
519
+ #
520
+ # - rule_id: CASH-03
521
+ # satisfied: false
522
+ # evidence:
523
+ # - type: link
524
+ # value: docs/finance/spend-reviews/2025-10-cloud-infra.md
525
+ # description: "Spend review for \xA31200/month cloud infrastructure"
526
+ # - type: approval
527
+ # value: owner@example.com
528
+ # description: "Owner approval for spend commitment"
529
+ # notes: |
530
+ # New cloud infrastructure commitment: \xA31200/month for 12 months.
531
+ # ROI: Reduces latency by 50%, improves user retention.
532
+ #
533
+ # # Gate checks (enforced by cos-gates.ts)
534
+ # gates:
535
+ # narrative: "pending" # Status: pending, passed, skipped, failed
536
+ # finance: "pending"
537
+ #
538
+ # # Exemptions (only if rule doesn't apply)
539
+ # exemptions:
540
+ # - rule_id: FAIR-01
541
+ # reason: "No user-facing pricing changes in this WU"
542
+ # approved_by: product-owner@example.com
543
+ # approved_at: 2025-10-23
544
+
545
+ # ============================================================================
546
+ # USAGE NOTES
547
+ # ============================================================================
548
+ #
549
+ # 1. Remove this entire governance block if no COS rules apply to your WU
550
+ # 2. Only include rules that require enforcement (not all rules apply to all WUs)
551
+ # 3. Evidence types: link:, metric:, screenshot:, approval:
552
+ # 4. Gates are checked during wu:done (before merge)
553
+ # 5. Exemptions require approval from rule owner
554
+ #
555
+ # For more details, see:
556
+ # - {{DOCS_OPERATIONS_PATH}}/_frameworks/cos/system-prompt-v1.3.md
557
+ # - {{DOCS_OPERATIONS_PATH}}/_frameworks/cos/evidence-format.md
558
+ `;
559
+ var FRAMEWORK_HINT_TEMPLATE = `# LumenFlow Framework Hint
560
+ # Generated by: lumenflow init --framework {{FRAMEWORK_NAME}}
561
+
562
+ framework: "{{FRAMEWORK_NAME}}"
563
+ slug: "{{FRAMEWORK_SLUG}}"
564
+ `;
565
+ var FRAMEWORK_OVERLAY_TEMPLATE = `# {{FRAMEWORK_NAME}} Framework Overlay
566
+
567
+ **Last updated:** {{DATE}}
568
+
569
+ This overlay captures framework-specific conventions, constraints, and references for {{FRAMEWORK_NAME}} projects.
570
+
571
+ ## Scope
572
+
573
+ - Project structure conventions
574
+ - Framework-specific testing guidance
575
+ - Common pitfalls and mitigations
576
+
577
+ ## References
578
+
579
+ - Add official docs links here
580
+ `;
581
+ var WU_LIFECYCLE_SKILL_TEMPLATE = `---
582
+ name: wu-lifecycle
583
+ description: Work Unit claim/block/done workflow automation.
584
+ version: 1.0.0
585
+ ---
586
+
587
+ # WU Lifecycle Skill
588
+
589
+ ## When to Use
590
+
591
+ Activate this skill when:
592
+
593
+ - Claiming a WU (\`pnpm wu:claim\`)
594
+ - Blocking/unblocking WUs due to dependencies
595
+ - Running \`wu:done\` completion workflow
596
+ - Understanding WU state machine transitions
597
+
598
+ ## State Machine
599
+
600
+ \`\`\`
601
+ ready -> in_progress -> waiting/blocked -> done
602
+ \`\`\`
603
+
604
+ ## Core Commands
605
+
606
+ \`\`\`bash
607
+ # Claim WU
608
+ pnpm wu:claim --id WU-XXX --lane <lane>
609
+ cd worktrees/<lane>-wu-xxx # IMMEDIATELY
610
+
611
+ # Complete WU (from main)
612
+ cd ../..
613
+ pnpm wu:done --id WU-XXX
614
+
615
+ # Block/Unblock
616
+ pnpm wu:block --id WU-XXX --reason "..."
617
+ pnpm wu:unblock --id WU-XXX
618
+
619
+ # Create (full spec)
620
+ pnpm wu:create --id WU-999 --lane "Operations" --title "Add feature" \\
621
+ --description "Context: ... Problem: ... Solution: ..." \\
622
+ --acceptance "Feature works" --code-paths "src/a.ts" --validate
623
+ \`\`\`
624
+
625
+ ## wu:done Workflow
626
+
627
+ 1. Runs gates in worktree
628
+ 2. Fast-forward merge to main
629
+ 3. Creates \`.lumenflow/stamps/WU-XXX.done\`
630
+ 4. Updates backlog.md + status.md
631
+ 5. Removes worktree
632
+
633
+ ## Worktree Discipline
634
+
635
+ After \`wu:claim\`:
636
+
637
+ - \`cd worktrees/<lane>-wu-xxx\` immediately
638
+ - Use relative paths (never absolute)
639
+ - Main is read-only
640
+ `;
641
+ var WORKTREE_DISCIPLINE_SKILL_TEMPLATE = `---
642
+ name: worktree-discipline
643
+ description: Prevents the "absolute path trap" in Write/Edit/Read tools.
644
+ version: 1.0.0
645
+ ---
646
+
647
+ # Worktree Discipline: Absolute Path Trap Prevention
648
+
649
+ **Purpose**: Prevent AI agents from bypassing worktree isolation via absolute file paths.
650
+
651
+ ## The Absolute Path Trap
652
+
653
+ **Problem**: AI agents using Write/Edit/Read tools can bypass worktree isolation by passing absolute paths. Even when your shell is in the worktree, absolute paths target the main checkout.
654
+
655
+ ### Example
656
+
657
+ \`\`\`typescript
658
+ // Shell: cd worktrees/operations-wu-427
659
+
660
+ // WRONG - Absolute path bypasses worktree
661
+ Write({
662
+ file_path: '/<user-home>/source/project/apps/web/src/validator.ts',
663
+ content: '...',
664
+ });
665
+ // Result: Written to MAIN checkout, not worktree!
666
+
667
+ // RIGHT - Relative path respects worktree
668
+ Write({
669
+ file_path: 'apps/web/src/validator.ts',
670
+ content: '...',
671
+ });
672
+ // Result: Written to worktree correctly
673
+ \`\`\`
674
+
675
+ ## Pre-Operation Checklist
676
+
677
+ **Before ANY Write/Edit/Read operation:**
678
+
679
+ 1. **Verify working directory**:
680
+
681
+ \`\`\`bash
682
+ pwd
683
+ # Must show: .../worktrees/<lane>-wu-xxx
684
+ \`\`\`
685
+
686
+ 2. **Check file path format**:
687
+
688
+ | Pattern | Safe? | Example |
689
+ | --------------------------------- | ----- | --------------------------- |
690
+ | Starts with \`/<user-home>/\` | NO | \`/<user-home>/.../file.ts\` |
691
+ | Contains full repo path | NO | \`/source/project/...\` |
692
+ | Starts with package name | YES | \`apps/web/src/...\` |
693
+ | Starts with \`./\` or \`../\` | YES | \`./src/lib/...\` |
694
+ | Just filename | YES | \`README.md\` |
695
+
696
+ 3. **Use relative paths for ALL file operations**
697
+
698
+ ## Golden Rules
699
+
700
+ 1. **Always verify pwd** before file operations
701
+ 2. **Never use absolute paths** in Write/Edit/Read tools
702
+ 3. **When in doubt, use relative paths**
703
+ `;
704
+ var LUMENFLOW_GATES_SKILL_TEMPLATE = `---
705
+ name: lumenflow-gates
706
+ description: Quality gates troubleshooting (format, lint, typecheck, tests).
707
+ version: 1.0.0
708
+ ---
709
+
710
+ # LumenFlow Gates Skill
711
+
712
+ ## When to Use
713
+
714
+ Activate this skill when:
715
+
716
+ - \`pnpm gates\` fails with format, lint, or typecheck errors
717
+ - Need to determine if failure is from your changes vs pre-existing
718
+ - Debugging test failures or coverage issues
719
+ - Deciding whether to use \`--skip-gates\` (emergency only)
720
+
721
+ ## Gate Sequence
722
+
723
+ \`\`\`
724
+ pnpm gates = format:check -> lint -> typecheck -> spec:linter -> tests
725
+ \`\`\`
726
+
727
+ ## Fix Patterns
728
+
729
+ | Gate | Auto-fix | Manual |
730
+ | --------- | --------------- | ----------------------------------- |
731
+ | Format | \`pnpm format\` | - |
732
+ | Lint | \`pnpm lint:fix\` | Fix reported issues |
733
+ | Typecheck | - | Fix type errors (first error first) |
734
+ | Tests | - | Debug, fix mocks, update snapshots |
735
+
736
+ ## Decision Tree
737
+
738
+ **Gate failed. Is it from YOUR changes?**
739
+
740
+ \`\`\`bash
741
+ git checkout main && pnpm gates # Check main
742
+ # Pass on main -> Your change caused it -> Fix it
743
+ # Fail on main -> Pre-existing -> Consider --skip-gates
744
+ \`\`\`
745
+
746
+ **Can you fix it?**
747
+
748
+ - In your \`code_paths\`, <=10 lines -> Fix in place
749
+ - Different paths, >10 lines -> Create Bug WU
750
+
751
+ ## Skip Gates (Emergency)
752
+
753
+ Only when pre-existing failures:
754
+
755
+ \`\`\`bash
756
+ pnpm wu:done --id WU-XXX --skip-gates --reason "Pre-existing" --fix-wu WU-YYY
757
+ \`\`\`
758
+
759
+ ## Common Lint Fixes
760
+
761
+ \`\`\`
762
+ no-explicit-any -> Add proper types
763
+ no-unused-vars -> Remove or prefix with _
764
+ no-restricted-paths -> Check hex boundaries
765
+ exhaustive-deps -> Add missing dependencies
766
+ \`\`\`
767
+
768
+ ## Validation Commands
769
+
770
+ \`\`\`bash
771
+ pnpm gates # All gates
772
+ pnpm gates -- --docs-only # Docs WUs
773
+ pnpm format # Fix formatting
774
+ pnpm lint:fix # Fix lint issues
775
+ pnpm typecheck # Check types
776
+ \`\`\`
777
+ `;
778
+ var REQUIRED_GITIGNORE_EXCLUSIONS = [
779
+ { pattern: "node_modules", line: "node_modules/" },
780
+ { pattern: ".lumenflow/telemetry", line: ".lumenflow/telemetry/" },
781
+ { pattern: ".lumenflow/flow.log", line: ".lumenflow/flow.log" },
782
+ { pattern: ".lumenflow/commands.log", line: ".lumenflow/commands.log" },
783
+ { pattern: ".lumenflow/sessions/", line: ".lumenflow/sessions/" },
784
+ { pattern: ".lumenflow/memory/", line: ".lumenflow/memory/" },
785
+ // WU-2180: Ephemeral paths that were missing, causing wu:done clean-tree failures
786
+ { pattern: ".lumenflow/checkpoints/", line: ".lumenflow/checkpoints/" },
787
+ { pattern: ".lumenflow/locks/", line: ".lumenflow/locks/" },
788
+ { pattern: ".lumenflow/artifacts/", line: ".lumenflow/artifacts/" },
789
+ {
790
+ pattern: ".lumenflow/state/spawn-registry.jsonl",
791
+ line: ".lumenflow/state/spawn-registry.jsonl"
792
+ },
793
+ { pattern: ".logs/", line: ".logs/" },
794
+ { pattern: DEFAULT_WORKTREES_PATTERN, line: DEFAULT_WORKTREES_DIR }
795
+ ];
796
+ var GITIGNORE_TEMPLATE = `# Dependencies
797
+ node_modules/
798
+
799
+ # LumenFlow runtime state (local only, not shared)
800
+ .lumenflow/telemetry/
801
+ .lumenflow/flow.log
802
+ .lumenflow/commands.log
803
+ .lumenflow/sessions/
804
+ .lumenflow/memory/
805
+ .lumenflow/checkpoints/
806
+ .lumenflow/locks/
807
+ .lumenflow/artifacts/
808
+ .lumenflow/state/spawn-registry.jsonl
809
+
810
+ # WU-1852: Gates output logs (generated by wu:done/wu:prep)
811
+ .logs/
812
+
813
+ # Worktrees (isolated parallel work directories)
814
+ ${DEFAULT_WORKTREES_DIR}
815
+
816
+ # Build output
817
+ dist/
818
+ *.tsbuildinfo
819
+
820
+ # Turbo
821
+ .turbo/
822
+
823
+ # Environment files
824
+ .env
825
+ .env.local
826
+ .env.*.local
827
+
828
+ # IDE
829
+ .idea/
830
+ .vscode/
831
+ *.swp
832
+ *.swo
833
+
834
+ # OS files
835
+ .DS_Store
836
+ Thumbs.db
837
+ `;
838
+ var PRETTIERIGNORE_TEMPLATE = `# Dependencies
839
+ node_modules/
840
+
841
+ # Build output
842
+ dist/
843
+ *.tsbuildinfo
844
+
845
+ # Coverage reports
846
+ coverage/
847
+
848
+ # Turbo
849
+ .turbo/
850
+
851
+ # LumenFlow state (local only)
852
+ ${DEFAULT_STATE_DIR_IGNORE}
853
+
854
+ # Worktrees
855
+ ${DEFAULT_WORKTREES_DIR}
856
+
857
+ # Lockfiles (auto-generated)
858
+ pnpm-lock.yaml
859
+ package-lock.json
860
+ yarn.lock
861
+
862
+ # Environment files
863
+ .env
864
+ .env.local
865
+ .env.*.local
866
+ `;
867
+ var SCRIPT_ARG_OVERRIDES = {
868
+ "gates:docs": "gates --docs-only"
869
+ };
870
+ var SAFE_GIT_TEMPLATE = `#!/bin/sh
871
+ #
872
+ # safe-git - LumenFlow safety wrapper for git
873
+ #
874
+ # Blocks dangerous operations that can corrupt agent state.
875
+ # For all other commands, passes through to system git.
876
+ #
877
+
878
+ set -e
879
+
880
+ # Block 'worktree remove'
881
+ if [ "$1" = "worktree" ] && [ "$2" = "remove" ]; then
882
+ echo "" >&2
883
+ echo "=== LUMENFLOW SAFETY BLOCK ===" >&2
884
+ echo "" >&2
885
+ echo "BLOCKED: Manual 'git worktree remove' is unsafe in this environment." >&2
886
+ echo "" >&2
887
+ echo "REASON: Manual removal leaves orphan directories and corrupts agent state." >&2
888
+ echo "" >&2
889
+ echo "USE INSTEAD:" >&2
890
+ echo " pnpm wu:done --id <ID> (To complete a task)" >&2
891
+ echo " pnpm wu:cleanup --id <ID> (To discard a task)" >&2
892
+ echo "==============================" >&2
893
+ exit 1
894
+ fi
895
+
896
+ # Pass through to real git
897
+ exec git "$@"
898
+ `;
899
+ var PRE_COMMIT_TEMPLATE = `#!/bin/sh
900
+ #
901
+ # LumenFlow Pre-Commit Hook
902
+ #
903
+ # Enforces worktree discipline by blocking direct commits to main/master.
904
+ # Does NOT assume pnpm test or UnsafeAny other commands exist.
905
+ #
906
+ # Rules:
907
+ # 1. BLOCK commits to main/master (use WU workflow instead)
908
+ # 2. ALLOW commits on lane branches (lane/*/wu-*)
909
+ # 3. ALLOW commits on tmp/* branches (CLI micro-worktrees)
910
+ #
911
+
912
+ # Skip on tmp/* branches (CLI micro-worktrees)
913
+ BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
914
+ case "$BRANCH" in tmp/*) exit 0 ;; esac
915
+
916
+ # Check for force bypass
917
+ if [ "$LUMENFLOW_FORCE" = "1" ]; then
918
+ exit 0
919
+ fi
920
+
921
+ # Block direct commits to main/master
922
+ case "$BRANCH" in
923
+ main|master)
924
+ echo "" >&2
925
+ echo "=== DIRECT COMMIT TO \${BRANCH} BLOCKED ===" >&2
926
+ echo "" >&2
927
+ echo "LumenFlow protects main from direct commits." >&2
928
+ echo "" >&2
929
+ echo "USE INSTEAD:" >&2
930
+ echo " pnpm wu:claim --id WU-XXXX --lane \\"<Lane>\\"" >&2
931
+ echo " cd worktrees/<lane>-wu-xxxx" >&2
932
+ echo " # Make commits in the worktree" >&2
933
+ echo "" >&2
934
+ echo "EMERGENCY BYPASS (logged):" >&2
935
+ echo " LUMENFLOW_FORCE=1 git commit ..." >&2
936
+ echo "==========================================" >&2
937
+ exit 1
938
+ ;;
939
+ esac
940
+
941
+ # Allow commits on other branches
942
+ exit 0
943
+ `;
944
+ var GATE_STUB_SCRIPTS = {
945
+ "spec:linter": 'echo "[lumenflow] spec:linter stub -- install a WU spec linter or replace this script" && exit 0',
946
+ lint: 'echo "[lumenflow] lint stub -- add ESLint or your preferred linter to enable this gate (e.g. eslint .)" && exit 0',
947
+ typecheck: 'echo "[lumenflow] typecheck stub -- add TypeScript or your type checker to enable this gate (e.g. tsc --noEmit)" && exit 0',
948
+ // WU-1747: format and format:check stubs that auto-detect prettier availability.
949
+ // When prettier is installed (after pnpm install), they run prettier directly.
950
+ // When prettier is not installed, they exit 0 with guidance -- matching other gate stubs.
951
+ format: 'if command -v prettier >/dev/null 2>&1; then prettier --write .; else echo "[lumenflow] format stub -- install prettier to enable formatting (pnpm install)"; fi',
952
+ "format:check": 'if command -v prettier >/dev/null 2>&1; then prettier --check .; else echo "[lumenflow] format:check stub -- install prettier to enable this gate (pnpm install)"; fi',
953
+ // WU-1852: cos:gates no-op stub so fresh projects can complete wu:done without manual setup.
954
+ // wu:done unconditionally runs `pnpm cos:gates`; without this stub the command fails.
955
+ "cos:gates": 'echo "[lumenflow] cos:gates stub -- add COS governance rules or replace this script" && exit 0'
956
+ };
957
+
958
+ // src/lane-lifecycle-process.ts
959
+ import { existsSync, readdirSync, readFileSync, writeFileSync } from "fs";
960
+ import path from "path";
961
+ import YAML from "yaml";
962
+ var LANE_CONFIG_KEY = "lanes";
963
+ var LANE_DEFINITIONS_KEY = "definitions";
964
+ var LANE_LIFECYCLE_KEY = "lifecycle";
965
+ var LANE_LIFECYCLE_STATUS_KEY = "status";
966
+ var LANE_LIFECYCLE_UPDATED_AT_KEY = "updated_at";
967
+ var LANE_LIFECYCLE_MIGRATED_AT_KEY = "migrated_at";
968
+ var LANE_LIFECYCLE_MIGRATION_REASON_KEY = "migration_reason";
969
+ var EMPTY_OBJECT = "{}";
970
+ var NEWLINE = "\n";
971
+ var WU_CREATE_PREFIX = "[wu:create]";
972
+ var INITIATIVE_CREATE_PREFIX = "[initiative:create]";
973
+ var INIT_PREFIX = "[lumenflow init]";
974
+ var LANE_SETUP_COMMAND = "pnpm lane:setup";
975
+ var LANE_LOCK_COMMAND = "pnpm lane:lock";
976
+ var LANE_READY_SENTINEL = "lanes ready";
977
+ var SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
978
+ var LANE_LIFECYCLE_STATUS = {
979
+ UNCONFIGURED: "unconfigured",
980
+ DRAFT: "draft",
981
+ LOCKED: "locked"
982
+ };
983
+ function asRecord(value) {
984
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
985
+ }
986
+ function toIsoTimestamp() {
987
+ return (/* @__PURE__ */ new Date()).toISOString();
988
+ }
989
+ function isLaneLifecycleStatus(value) {
990
+ return value === LANE_LIFECYCLE_STATUS.UNCONFIGURED || value === LANE_LIFECYCLE_STATUS.DRAFT || value === LANE_LIFECYCLE_STATUS.LOCKED;
991
+ }
992
+ function getConfigPath(projectRoot) {
993
+ return path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
994
+ }
995
+ function readWorkspaceDoc(projectRoot) {
996
+ const configPath = getConfigPath(projectRoot);
997
+ if (!existsSync(configPath)) {
998
+ return {};
999
+ }
1000
+ try {
1001
+ const content = readFileSync(configPath, FILE_SYSTEM.UTF8);
1002
+ const parsed = asRecord(YAML.parse(content));
1003
+ return parsed ?? {};
1004
+ } catch {
1005
+ return {};
1006
+ }
1007
+ }
1008
+ function readConfigDoc(projectRoot) {
1009
+ const workspace = readWorkspaceDoc(projectRoot);
1010
+ const softwareDelivery = asRecord(workspace[SOFTWARE_DELIVERY_KEY]);
1011
+ return softwareDelivery ?? {};
1012
+ }
1013
+ function writeConfigDoc(projectRoot, config) {
1014
+ const configPath = getConfigPath(projectRoot);
1015
+ const workspace = readWorkspaceDoc(projectRoot);
1016
+ workspace[SOFTWARE_DELIVERY_KEY] = config;
1017
+ const nextContent = YAML.stringify(workspace);
1018
+ writeFileSync(
1019
+ configPath,
1020
+ nextContent || EMPTY_OBJECT + NEWLINE,
1021
+ FILE_SYSTEM.UTF8
1022
+ );
1023
+ }
1024
+ function getLifecycleStatusFromDoc(config) {
1025
+ const status = config?.lanes?.lifecycle?.status;
1026
+ return isLaneLifecycleStatus(status) ? status : null;
1027
+ }
1028
+ function ensureLanesDoc(config) {
1029
+ if (!config[LANE_CONFIG_KEY] || typeof config[LANE_CONFIG_KEY] !== "object") {
1030
+ config[LANE_CONFIG_KEY] = {};
1031
+ }
1032
+ return config[LANE_CONFIG_KEY];
1033
+ }
1034
+ function setLifecycleStatusInDoc(config, status, migrationReason) {
1035
+ const lanes = ensureLanesDoc(config);
1036
+ const existingLifecycle = lanes[LANE_LIFECYCLE_KEY] && typeof lanes[LANE_LIFECYCLE_KEY] === "object" ? lanes[LANE_LIFECYCLE_KEY] : {};
1037
+ const now = toIsoTimestamp();
1038
+ const lifecycle = {
1039
+ ...existingLifecycle,
1040
+ [LANE_LIFECYCLE_STATUS_KEY]: status,
1041
+ [LANE_LIFECYCLE_UPDATED_AT_KEY]: now
1042
+ };
1043
+ if (migrationReason) {
1044
+ lifecycle[LANE_LIFECYCLE_MIGRATED_AT_KEY] = now;
1045
+ lifecycle[LANE_LIFECYCLE_MIGRATION_REASON_KEY] = migrationReason;
1046
+ }
1047
+ lanes[LANE_LIFECYCLE_KEY] = lifecycle;
1048
+ }
1049
+ function hasLaneDefinitions(config) {
1050
+ const definitions = config?.lanes?.definitions;
1051
+ return Array.isArray(definitions) && definitions.length > 0;
1052
+ }
1053
+ function deepCloneDefaultLaneDefinitions() {
1054
+ return JSON.parse(JSON.stringify(DEFAULT_LANE_DEFINITIONS));
1055
+ }
1056
+ function classifyLaneLifecycleForProject(projectRoot) {
1057
+ const config = readConfigDoc(projectRoot);
1058
+ const configuredStatus = getLifecycleStatusFromDoc(config);
1059
+ if (configuredStatus) {
1060
+ return {
1061
+ status: configuredStatus,
1062
+ source: "config",
1063
+ migrationReason: null,
1064
+ persisted: false
1065
+ };
1066
+ }
1067
+ const definitionsPresent = hasLaneDefinitions(config);
1068
+ if (!definitionsPresent) {
1069
+ return {
1070
+ status: LANE_LIFECYCLE_STATUS.UNCONFIGURED,
1071
+ source: "migration",
1072
+ migrationReason: "no lane definitions",
1073
+ persisted: false
1074
+ };
1075
+ }
1076
+ return {
1077
+ status: LANE_LIFECYCLE_STATUS.LOCKED,
1078
+ source: "migration",
1079
+ migrationReason: "lane definitions detected",
1080
+ persisted: false
1081
+ };
1082
+ }
1083
+ function ensureLaneLifecycleForProject(projectRoot, options = {}) {
1084
+ const persist = options.persist ?? true;
1085
+ const classification = classifyLaneLifecycleForProject(projectRoot);
1086
+ if (!persist || classification.source === "config") {
1087
+ return classification;
1088
+ }
1089
+ const config = readConfigDoc(projectRoot);
1090
+ setLifecycleStatusInDoc(
1091
+ config,
1092
+ classification.status,
1093
+ classification.migrationReason ?? void 0
1094
+ );
1095
+ writeConfigDoc(projectRoot, config);
1096
+ return {
1097
+ ...classification,
1098
+ persisted: true
1099
+ };
1100
+ }
1101
+ function setLaneLifecycleStatus(projectRoot, status) {
1102
+ const config = readConfigDoc(projectRoot);
1103
+ setLifecycleStatusInDoc(config, status);
1104
+ writeConfigDoc(projectRoot, config);
1105
+ }
1106
+ function recommendLaneLifecycleNextStep(status) {
1107
+ if (status === LANE_LIFECYCLE_STATUS.UNCONFIGURED) {
1108
+ return LANE_SETUP_COMMAND;
1109
+ }
1110
+ if (status === LANE_LIFECYCLE_STATUS.DRAFT) {
1111
+ return LANE_LOCK_COMMAND;
1112
+ }
1113
+ return LANE_READY_SENTINEL;
1114
+ }
1115
+ function buildWuCreateLaneLifecycleMessage(status) {
1116
+ return [
1117
+ `${WU_CREATE_PREFIX} Lane lifecycle status: ${status}`,
1118
+ "Cannot create delivery WU until lanes are locked.",
1119
+ `Next step: ${recommendLaneLifecycleNextStep(status)}`
1120
+ ].join(NEWLINE);
1121
+ }
1122
+ function buildInitiativeCreateLaneLifecycleMessage(status) {
1123
+ return [
1124
+ `${INITIATIVE_CREATE_PREFIX} Lane lifecycle: ${status}`,
1125
+ "Initiative creation is allowed before lane setup.",
1126
+ `When ready for delivery WUs, run: ${recommendLaneLifecycleNextStep(status)}`
1127
+ ].join(NEWLINE);
1128
+ }
1129
+ function buildInitLaneLifecycleMessage(status) {
1130
+ return [
1131
+ `${INIT_PREFIX} Lane lifecycle: ${status}`,
1132
+ "Lanes are configured after project context is defined (plan/architecture).",
1133
+ `Next step: ${recommendLaneLifecycleNextStep(status)}`
1134
+ ].join(NEWLINE);
1135
+ }
1136
+ function detectWorkspaceLanes(projectRoot) {
1137
+ const lanes = [];
1138
+ const pnpmWorkspacePath = path.join(projectRoot, "pnpm-workspace.yaml");
1139
+ let workspacePatterns = [];
1140
+ if (existsSync(pnpmWorkspacePath)) {
1141
+ try {
1142
+ const content = readFileSync(pnpmWorkspacePath, FILE_SYSTEM.ENCODING);
1143
+ const parsed = YAML.parse(content);
1144
+ workspacePatterns = parsed?.packages ?? [];
1145
+ } catch {
1146
+ }
1147
+ }
1148
+ if (workspacePatterns.length === 0) {
1149
+ const pkgJsonPath = path.join(projectRoot, "package.json");
1150
+ if (existsSync(pkgJsonPath)) {
1151
+ try {
1152
+ const content = readFileSync(pkgJsonPath, FILE_SYSTEM.ENCODING);
1153
+ const parsed = JSON.parse(content);
1154
+ if (Array.isArray(parsed?.workspaces)) {
1155
+ workspacePatterns = parsed.workspaces;
1156
+ } else if (parsed?.workspaces?.packages) {
1157
+ workspacePatterns = parsed.workspaces.packages;
1158
+ }
1159
+ } catch {
1160
+ }
1161
+ }
1162
+ }
1163
+ if (workspacePatterns.length === 0) {
1164
+ return deepCloneDefaultLaneDefinitions();
1165
+ }
1166
+ for (const pattern of workspacePatterns) {
1167
+ const baseDir = pattern.replace(/\/?\*$/, "");
1168
+ const fullPath = path.join(projectRoot, baseDir);
1169
+ if (!existsSync(fullPath)) continue;
1170
+ try {
1171
+ const entries = readdirSync(fullPath, { withFileTypes: true });
1172
+ for (const entry of entries) {
1173
+ if (!entry.isDirectory()) continue;
1174
+ const pkgPath = path.join(fullPath, entry.name, "package.json");
1175
+ if (!existsSync(pkgPath)) continue;
1176
+ const isApp = baseDir.includes("app");
1177
+ const category = isApp ? "Experience" : "Framework";
1178
+ const displayName = entry.name.replace(/^@[^/]+\//, "");
1179
+ lanes.push({
1180
+ name: `${category}: ${displayName.charAt(0).toUpperCase() + displayName.slice(1)}`,
1181
+ wip_limit: 1,
1182
+ code_paths: [`${baseDir}/${entry.name}/**`]
1183
+ });
1184
+ }
1185
+ } catch {
1186
+ }
1187
+ }
1188
+ const docsDir = getConfig({ projectRoot }).directories.docs.replace(/\/+$/, "");
1189
+ if (existsSync(path.join(projectRoot, docsDir))) {
1190
+ lanes.push({
1191
+ name: "Content: Documentation",
1192
+ wip_limit: 1,
1193
+ code_paths: [`${docsDir}/**`, "*.md"]
1194
+ });
1195
+ }
1196
+ if (existsSync(path.join(projectRoot, ".github"))) {
1197
+ lanes.push({
1198
+ name: "Operations: CI/CD",
1199
+ wip_limit: 1,
1200
+ code_paths: [".github/workflows/**", ".github/actions/**"]
1201
+ });
1202
+ }
1203
+ return lanes.length > 0 ? lanes : deepCloneDefaultLaneDefinitions();
1204
+ }
1205
+ function ensureDraftLaneArtifacts(projectRoot) {
1206
+ const config = readConfigDoc(projectRoot);
1207
+ const lanes = ensureLanesDoc(config);
1208
+ let createdDefinitions = false;
1209
+ if (!hasLaneDefinitions(config)) {
1210
+ lanes[LANE_DEFINITIONS_KEY] = detectWorkspaceLanes(projectRoot);
1211
+ createdDefinitions = true;
1212
+ }
1213
+ setLifecycleStatusInDoc(config, LANE_LIFECYCLE_STATUS.DRAFT);
1214
+ writeConfigDoc(projectRoot, config);
1215
+ return {
1216
+ createdDefinitions,
1217
+ status: LANE_LIFECYCLE_STATUS.DRAFT
1218
+ };
1219
+ }
1220
+ function validateLaneArtifacts(projectRoot) {
1221
+ const configPath = getConfigPath(projectRoot);
1222
+ const warnings = [];
1223
+ const invalidLanes = [];
1224
+ if (!existsSync(configPath)) {
1225
+ warnings.push(`Missing ${WORKSPACE_CONFIG_FILE_NAME}. Run: ${LANE_SETUP_COMMAND}`);
1226
+ return {
1227
+ warnings,
1228
+ invalidLanes,
1229
+ missingDefinitions: true
1230
+ };
1231
+ }
1232
+ try {
1233
+ getConfig({
1234
+ projectRoot,
1235
+ reload: true,
1236
+ strictWorkspace: true
1237
+ });
1238
+ } catch (error) {
1239
+ warnings.push(
1240
+ `Invalid ${WORKSPACE_CONFIG_FILE_NAME}: ${error instanceof Error ? error.message : String(error)}`
1241
+ );
1242
+ return {
1243
+ warnings,
1244
+ invalidLanes,
1245
+ missingDefinitions: true
1246
+ };
1247
+ }
1248
+ const config = readConfigDoc(projectRoot);
1249
+ const missingDefinitions = !hasLaneDefinitions(config);
1250
+ if (missingDefinitions) {
1251
+ warnings.push(
1252
+ `No lane definitions found in ${WORKSPACE_CONFIG_FILE_NAME} (${SOFTWARE_DELIVERY_KEY}.lanes). Run: ${LANE_SETUP_COMMAND}`
1253
+ );
1254
+ }
1255
+ return {
1256
+ warnings,
1257
+ invalidLanes,
1258
+ missingDefinitions
1259
+ };
1260
+ }
1261
+
1262
+ export {
1263
+ DEFAULT_LANE_DEFINITIONS,
1264
+ AGENTS_MD_TEMPLATE,
1265
+ CLAUDE_MD_TEMPLATE,
1266
+ CLAUDE_SETTINGS_TEMPLATE,
1267
+ CURSOR_RULES_TEMPLATE,
1268
+ WINDSURF_RULES_TEMPLATE,
1269
+ CLINE_RULES_TEMPLATE,
1270
+ AIDER_CONF_TEMPLATE,
1271
+ MCP_JSON_TEMPLATE,
1272
+ BACKLOG_TEMPLATE,
1273
+ STATUS_TEMPLATE,
1274
+ WU_TEMPLATE_YAML,
1275
+ FRAMEWORK_HINT_TEMPLATE,
1276
+ FRAMEWORK_OVERLAY_TEMPLATE,
1277
+ WU_LIFECYCLE_SKILL_TEMPLATE,
1278
+ WORKTREE_DISCIPLINE_SKILL_TEMPLATE,
1279
+ LUMENFLOW_GATES_SKILL_TEMPLATE,
1280
+ REQUIRED_GITIGNORE_EXCLUSIONS,
1281
+ GITIGNORE_TEMPLATE,
1282
+ PRETTIERIGNORE_TEMPLATE,
1283
+ SCRIPT_ARG_OVERRIDES,
1284
+ SAFE_GIT_TEMPLATE,
1285
+ PRE_COMMIT_TEMPLATE,
1286
+ GATE_STUB_SCRIPTS,
1287
+ LANE_LIFECYCLE_STATUS,
1288
+ classifyLaneLifecycleForProject,
1289
+ ensureLaneLifecycleForProject,
1290
+ setLaneLifecycleStatus,
1291
+ recommendLaneLifecycleNextStep,
1292
+ buildWuCreateLaneLifecycleMessage,
1293
+ buildInitiativeCreateLaneLifecycleMessage,
1294
+ buildInitLaneLifecycleMessage,
1295
+ ensureDraftLaneArtifacts,
1296
+ validateLaneArtifacts
1297
+ };