@lumenflow/cli 3.12.5 → 3.12.6
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.
- package/dist/chunk-2D2VOCA4.js +37 -0
- package/dist/chunk-2D5KFYGX.js +284 -0
- package/dist/chunk-2GXVIN57.js +14072 -0
- package/dist/chunk-2MQ7HZWZ.js +26 -0
- package/dist/chunk-2UFQ3A3C.js +643 -0
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/chunk-4N74J3UT.js +15 -0
- package/dist/chunk-5GTOXFYR.js +392 -0
- package/dist/chunk-5VY6MQMC.js +240 -0
- package/dist/chunk-67XVPMRY.js +1297 -0
- package/dist/chunk-6HO4GWJE.js +164 -0
- package/dist/chunk-6W5XHWYV.js +1890 -0
- package/dist/chunk-6X4EMYJQ.js +64 -0
- package/dist/chunk-6XYXI2NQ.js +772 -0
- package/dist/chunk-7ANSOV6Q.js +285 -0
- package/dist/chunk-A624LFLB.js +1380 -0
- package/dist/chunk-ADN5NHG4.js +126 -0
- package/dist/chunk-B7YJYJKG.js +33 -0
- package/dist/chunk-CCLHCPKG.js +210 -0
- package/dist/chunk-CK36VROC.js +1584 -0
- package/dist/chunk-D3UOFRSB.js +81 -0
- package/dist/chunk-DFR4DJBM.js +230 -0
- package/dist/chunk-DSYBDHYH.js +79 -0
- package/dist/chunk-DWMLTXKQ.js +1176 -0
- package/dist/chunk-E3REJTAJ.js +28 -0
- package/dist/chunk-EA3IVO64.js +633 -0
- package/dist/chunk-EK2AKZKD.js +55 -0
- package/dist/chunk-ELD7JTTT.js +343 -0
- package/dist/chunk-EX6TT2XI.js +195 -0
- package/dist/chunk-EXINSFZE.js +82 -0
- package/dist/chunk-EZ6ZBYBM.js +510 -0
- package/dist/chunk-FBKAPTJ2.js +16 -0
- package/dist/chunk-FVLV5RYH.js +1118 -0
- package/dist/chunk-GDNSBQVK.js +2485 -0
- package/dist/chunk-GPQHMBNN.js +278 -0
- package/dist/chunk-GTFJB67L.js +68 -0
- package/dist/chunk-HANJXVKW.js +1127 -0
- package/dist/chunk-HEVS5YLD.js +269 -0
- package/dist/chunk-HMEVZKPQ.js +9 -0
- package/dist/chunk-HRGSYNLM.js +3511 -0
- package/dist/chunk-ISZR5N4K.js +60 -0
- package/dist/chunk-J6SUPR2C.js +226 -0
- package/dist/chunk-JERYVEIZ.js +244 -0
- package/dist/chunk-JHHWGL2N.js +87 -0
- package/dist/chunk-JONWQUB5.js +775 -0
- package/dist/chunk-K2DIWWDM.js +1766 -0
- package/dist/chunk-KY4PGL5V.js +969 -0
- package/dist/chunk-L737LQ4C.js +1285 -0
- package/dist/chunk-LFTWYIB2.js +497 -0
- package/dist/chunk-LV47RFNJ.js +41 -0
- package/dist/chunk-MKSAITI7.js +15 -0
- package/dist/chunk-MZ7RKIX4.js +212 -0
- package/dist/chunk-NAP6CFSO.js +84 -0
- package/dist/chunk-ND6MY37M.js +16 -0
- package/dist/chunk-NMG736UR.js +683 -0
- package/dist/chunk-NRAXROED.js +32 -0
- package/dist/chunk-NRIZR3A7.js +690 -0
- package/dist/chunk-NX43BG3M.js +233 -0
- package/dist/chunk-O645XLSI.js +297 -0
- package/dist/chunk-OMJD6A3S.js +235 -0
- package/dist/chunk-QB6SJD4T.js +430 -0
- package/dist/chunk-QFSTL4J3.js +276 -0
- package/dist/chunk-QLGDFMFX.js +212 -0
- package/dist/chunk-RIAAGL2E.js +13 -0
- package/dist/chunk-RWO5XMZ6.js +86 -0
- package/dist/chunk-RXRKBBSM.js +149 -0
- package/dist/chunk-RZOZMML6.js +363 -0
- package/dist/chunk-U7I7FS7T.js +113 -0
- package/dist/chunk-UI42RODY.js +717 -0
- package/dist/chunk-UTVMVSCO.js +519 -0
- package/dist/chunk-V6OJGLBA.js +1746 -0
- package/dist/chunk-W2JHVH7D.js +152 -0
- package/dist/chunk-WD3Y7VQN.js +280 -0
- package/dist/chunk-WOCTQ5MS.js +303 -0
- package/dist/chunk-WZR3ZUNN.js +696 -0
- package/dist/chunk-XGI665H7.js +150 -0
- package/dist/chunk-XKY65P2T.js +304 -0
- package/dist/chunk-Y4CQZY65.js +57 -0
- package/dist/chunk-YFEXKLVE.js +194 -0
- package/dist/chunk-YHO3HS5X.js +287 -0
- package/dist/chunk-YLS7AZSX.js +738 -0
- package/dist/chunk-ZE473AO6.js +49 -0
- package/dist/chunk-ZF747T3O.js +644 -0
- package/dist/chunk-ZHCZHZH3.js +43 -0
- package/dist/chunk-ZZNZX2XY.js +87 -0
- package/dist/constants-7QAP3VQ4.js +23 -0
- package/dist/dist-IY3UUMWK.js +33 -0
- package/dist/init-templates.js +9 -9
- package/dist/invariants-runner-W5RGHCSU.js +27 -0
- package/dist/lane-lock-6J36HD5O.js +35 -0
- package/dist/mem-checkpoint-core-EANG2GVN.js +14 -0
- package/dist/mem-signal-core-2LZ2WYHW.js +19 -0
- package/dist/memory-store-OLB5FO7K.js +18 -0
- package/dist/service-6BYCOCO5.js +13 -0
- package/dist/spawn-policy-resolver-NTSZYQ6R.js +17 -0
- package/dist/spawn-task-builder-R4E2BHSW.js +22 -0
- package/dist/wu-claim.js +2 -2
- package/dist/wu-claim.js.map +1 -1
- package/dist/wu-done-gates.js +25 -4
- package/dist/wu-done-gates.js.map +1 -1
- package/dist/wu-done-ownership.js +6 -1
- package/dist/wu-done-ownership.js.map +1 -1
- package/dist/wu-done-pr-WLFFFEPJ.js +25 -0
- package/dist/wu-done-validation-3J5E36FE.js +30 -0
- package/dist/wu-done.js +6 -6
- package/dist/wu-done.js.map +1 -1
- package/dist/wu-duplicate-id-detector-5S7JHELK.js +232 -0
- package/dist/wu-edit-operations.js +58 -17
- package/dist/wu-edit-operations.js.map +1 -1
- package/dist/wu-edit-validators.js +104 -28
- package/dist/wu-edit-validators.js.map +1 -1
- package/dist/wu-edit.js +1 -1
- package/dist/wu-edit.js.map +1 -1
- package/dist/wu-spawn-prompt-builders.js +8 -7
- package/dist/wu-spawn-prompt-builders.js.map +1 -1
- package/package.json +8 -8
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/LUMENFLOW.md.template +1 -1
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +3 -3
- package/templates/core/ai/onboarding/starting-prompt.md.template +11 -11
|
@@ -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
|
+
};
|