@lumenflow/cli 2.18.3 → 2.19.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 (104) hide show
  1. package/README.md +42 -41
  2. package/dist/delegation-list.js +140 -0
  3. package/dist/delegation-list.js.map +1 -0
  4. package/dist/doctor.js +35 -99
  5. package/dist/doctor.js.map +1 -1
  6. package/dist/gates-plan-resolvers.js +150 -0
  7. package/dist/gates-plan-resolvers.js.map +1 -0
  8. package/dist/gates-runners.js +533 -0
  9. package/dist/gates-runners.js.map +1 -0
  10. package/dist/gates-types.js +3 -0
  11. package/dist/gates-types.js.map +1 -1
  12. package/dist/gates-utils.js +316 -0
  13. package/dist/gates-utils.js.map +1 -0
  14. package/dist/gates.js +44 -1016
  15. package/dist/gates.js.map +1 -1
  16. package/dist/hooks/enforcement-generator.js +16 -880
  17. package/dist/hooks/enforcement-generator.js.map +1 -1
  18. package/dist/hooks/enforcement-sync.js +1 -4
  19. package/dist/hooks/enforcement-sync.js.map +1 -1
  20. package/dist/hooks/generators/auto-checkpoint.js +123 -0
  21. package/dist/hooks/generators/auto-checkpoint.js.map +1 -0
  22. package/dist/hooks/generators/enforce-worktree.js +188 -0
  23. package/dist/hooks/generators/enforce-worktree.js.map +1 -0
  24. package/dist/hooks/generators/index.js +16 -0
  25. package/dist/hooks/generators/index.js.map +1 -0
  26. package/dist/hooks/generators/pre-compact-checkpoint.js +134 -0
  27. package/dist/hooks/generators/pre-compact-checkpoint.js.map +1 -0
  28. package/dist/hooks/generators/require-wu.js +115 -0
  29. package/dist/hooks/generators/require-wu.js.map +1 -0
  30. package/dist/hooks/generators/session-start-recovery.js +101 -0
  31. package/dist/hooks/generators/session-start-recovery.js.map +1 -0
  32. package/dist/hooks/generators/signal-utils.js +52 -0
  33. package/dist/hooks/generators/signal-utils.js.map +1 -0
  34. package/dist/hooks/generators/warn-incomplete.js +65 -0
  35. package/dist/hooks/generators/warn-incomplete.js.map +1 -0
  36. package/dist/init-detection.js +228 -0
  37. package/dist/init-detection.js.map +1 -0
  38. package/dist/init-scaffolding.js +146 -0
  39. package/dist/init-scaffolding.js.map +1 -0
  40. package/dist/init-templates.js +1928 -0
  41. package/dist/init-templates.js.map +1 -0
  42. package/dist/init.js +136 -2425
  43. package/dist/init.js.map +1 -1
  44. package/dist/initiative-edit.js +42 -11
  45. package/dist/initiative-edit.js.map +1 -1
  46. package/dist/initiative-remove-wu.js +0 -0
  47. package/dist/initiative-status.js +29 -2
  48. package/dist/initiative-status.js.map +1 -1
  49. package/dist/mem-context.js +22 -9
  50. package/dist/mem-context.js.map +1 -1
  51. package/dist/orchestrate-init-status.js +32 -1
  52. package/dist/orchestrate-init-status.js.map +1 -1
  53. package/dist/orchestrate-monitor.js +38 -38
  54. package/dist/orchestrate-monitor.js.map +1 -1
  55. package/dist/public-manifest.js +12 -5
  56. package/dist/public-manifest.js.map +1 -1
  57. package/dist/shared-validators.js +1 -0
  58. package/dist/shared-validators.js.map +1 -1
  59. package/dist/spawn-list.js +0 -0
  60. package/dist/wu-claim-branch.js +121 -0
  61. package/dist/wu-claim-branch.js.map +1 -0
  62. package/dist/wu-claim-output.js +83 -0
  63. package/dist/wu-claim-output.js.map +1 -0
  64. package/dist/wu-claim-resume-handler.js +85 -0
  65. package/dist/wu-claim-resume-handler.js.map +1 -0
  66. package/dist/wu-claim-state.js +572 -0
  67. package/dist/wu-claim-state.js.map +1 -0
  68. package/dist/wu-claim-validation.js +439 -0
  69. package/dist/wu-claim-validation.js.map +1 -0
  70. package/dist/wu-claim-worktree.js +221 -0
  71. package/dist/wu-claim-worktree.js.map +1 -0
  72. package/dist/wu-claim.js +54 -1402
  73. package/dist/wu-claim.js.map +1 -1
  74. package/dist/wu-create-content.js +254 -0
  75. package/dist/wu-create-content.js.map +1 -0
  76. package/dist/wu-create-readiness.js +57 -0
  77. package/dist/wu-create-readiness.js.map +1 -0
  78. package/dist/wu-create-validation.js +149 -0
  79. package/dist/wu-create-validation.js.map +1 -0
  80. package/dist/wu-create.js +39 -441
  81. package/dist/wu-create.js.map +1 -1
  82. package/dist/wu-done.js +144 -249
  83. package/dist/wu-done.js.map +1 -1
  84. package/dist/wu-edit-operations.js +432 -0
  85. package/dist/wu-edit-operations.js.map +1 -0
  86. package/dist/wu-edit-validators.js +280 -0
  87. package/dist/wu-edit-validators.js.map +1 -0
  88. package/dist/wu-edit.js +27 -713
  89. package/dist/wu-edit.js.map +1 -1
  90. package/dist/wu-prep.js +32 -2
  91. package/dist/wu-prep.js.map +1 -1
  92. package/dist/wu-repair.js +1 -1
  93. package/dist/wu-repair.js.map +1 -1
  94. package/dist/wu-spawn-prompt-builders.js +1123 -0
  95. package/dist/wu-spawn-prompt-builders.js.map +1 -0
  96. package/dist/wu-spawn-strategy-resolver.js +314 -0
  97. package/dist/wu-spawn-strategy-resolver.js.map +1 -0
  98. package/dist/wu-spawn.js +9 -1398
  99. package/dist/wu-spawn.js.map +1 -1
  100. package/package.json +10 -7
  101. package/templates/core/LUMENFLOW.md.template +29 -99
  102. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
  103. package/templates/core/ai/onboarding/quick-ref-commands.md.template +29 -4
  104. package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +8 -8
package/dist/init.js CHANGED
@@ -6,17 +6,17 @@
6
6
  * WU-1085: Added createWUParser for proper --help support
7
7
  * WU-1171: Added --merge mode, --client flag, AGENTS.md, updated vendor paths
8
8
  * WU-1362: Added branch guard to check branch before writing tracked files
9
+ * WU-1643: Extracted template constants into init-templates.ts
10
+ * WU-1644: Extracted detection helpers into init-detection.ts,
11
+ * scaffolding helpers into init-scaffolding.ts
9
12
  */
10
13
  import * as fs from 'node:fs';
11
14
  import * as path from 'node:path';
12
15
  import * as yaml from 'yaml';
13
16
  import { execFileSync } from 'node:child_process';
14
- import { fileURLToPath } from 'node:url';
15
17
  import { getDefaultConfig, createWUParser, WU_OPTIONS, CLAUDE_HOOKS, LUMENFLOW_CLIENT_IDS, } from '@lumenflow/core';
16
18
  // WU-1067: Import GATE_PRESETS for --preset support
17
19
  import { GATE_PRESETS } from '@lumenflow/core/gates-config';
18
- // WU-1171: Import merge block utilities
19
- import { updateMergeBlock } from './merge-block.js';
20
20
  // WU-1362: Import worktree guard utilities for branch checking
21
21
  import { isMainBranch, isInWorktree } from '@lumenflow/core/core/worktree-guard';
22
22
  // WU-1386: Import doctor for auto-run after init
@@ -28,6 +28,14 @@ import { integrateClaudeCode } from './commands/integrate.js';
28
28
  // WU-1433: Import public manifest to derive scripts (no hardcoded subset)
29
29
  import { getPublicManifest } from './public-manifest.js';
30
30
  import { runCLI } from './cli-entry-point.js';
31
+ // WU-1643: Import template constants from dedicated data module
32
+ import { DEFAULT_LANE_DEFINITIONS, AGENTS_MD_TEMPLATE, LUMENFLOW_MD_TEMPLATE, CONSTRAINTS_MD_TEMPLATE, CLAUDE_MD_TEMPLATE, CLAUDE_SETTINGS_TEMPLATE, CURSOR_RULES_TEMPLATE, WINDSURF_RULES_TEMPLATE, CLINE_RULES_TEMPLATE, AIDER_CONF_TEMPLATE, MCP_JSON_TEMPLATE, BACKLOG_TEMPLATE, STATUS_TEMPLATE, WU_TEMPLATE_YAML, FRAMEWORK_HINT_TEMPLATE, FRAMEWORK_OVERLAY_TEMPLATE, QUICK_REF_COMMANDS_TEMPLATE, FIRST_WU_MISTAKES_TEMPLATE, TROUBLESHOOTING_WU_DONE_TEMPLATE, AGENT_SAFETY_CARD_TEMPLATE, LANE_INFERENCE_TEMPLATE, STARTING_PROMPT_TEMPLATE, WU_CREATE_CHECKLIST_TEMPLATE, FIRST_15_MINS_TEMPLATE, LOCAL_ONLY_TEMPLATE, LANE_INFERENCE_DOC_TEMPLATE, WU_SIZING_GUIDE_TEMPLATE, WU_LIFECYCLE_SKILL_TEMPLATE, WORKTREE_DISCIPLINE_SKILL_TEMPLATE, LUMENFLOW_GATES_SKILL_TEMPLATE, GITIGNORE_TEMPLATE, PRETTIERIGNORE_TEMPLATE, SAFE_GIT_TEMPLATE, PRE_COMMIT_TEMPLATE, GATE_STUB_SCRIPTS, SCRIPT_ARG_OVERRIDES, } from './init-templates.js';
33
+ // WU-1644: Import detection helpers from dedicated module
34
+ import { checkPrerequisites, getDocsPath, detectDocsStructure, detectDefaultClient, isGitRepo, hasGitCommits, detectGitStateConfig, } from './init-detection.js';
35
+ // WU-1644: Re-export detection functions for backwards compatibility
36
+ export { detectIDEEnvironment, checkPrerequisites, getDocsPath, detectDocsStructure, } from './init-detection.js';
37
+ // WU-1644: Import scaffolding helpers from dedicated module
38
+ import { processTemplate, loadTemplate, createFile, createDirectory, createExecutableScript, } from './init-scaffolding.js';
31
39
  /**
32
40
  * WU-1085: CLI option definitions for init command
33
41
  * WU-1171: Added --merge and --client options
@@ -103,2084 +111,132 @@ export function parseInitOptions() {
103
111
  };
104
112
  }
105
113
  const DEFAULT_CLIENT_CLAUDE = LUMENFLOW_CLIENT_IDS.CLAUDE_CODE;
106
- /**
107
- * WU-1309: Get docs paths based on structure type
108
- */
109
- export function getDocsPath(structure) {
110
- if (structure === 'simple') {
111
- return {
112
- operations: 'docs',
113
- tasks: 'docs/tasks',
114
- onboarding: 'docs/_frameworks/lumenflow/agent/onboarding',
115
- quickRefLink: 'docs/_frameworks/lumenflow/agent/onboarding/quick-ref-commands.md',
116
- };
117
- }
118
- // arc42 structure
119
- return {
120
- operations: 'docs/04-operations',
121
- tasks: 'docs/04-operations/tasks',
122
- onboarding: 'docs/04-operations/_frameworks/lumenflow/agent/onboarding',
123
- quickRefLink: 'docs/04-operations/_frameworks/lumenflow/agent/onboarding/quick-ref-commands.md',
124
- };
125
- }
126
- /**
127
- * WU-1309: Detect existing docs structure or return default
128
- * Auto-detects arc42 when docs/04-operations or any numbered dir (01-*, 02-*, etc.) exists
129
- */
130
- export function detectDocsStructure(targetDir) {
131
- const docsDir = path.join(targetDir, 'docs');
132
- if (!fs.existsSync(docsDir)) {
133
- return 'simple';
134
- }
135
- // Check for arc42 numbered directories (01-*, 02-*, ..., 04-operations, etc.)
136
- const entries = fs.readdirSync(docsDir);
137
- const hasNumberedDir = entries.some((entry) => /^\d{2}-/.test(entry));
138
- if (hasNumberedDir) {
139
- return 'arc42';
140
- }
141
- return 'simple';
142
- }
143
- const CONFIG_FILE_NAME = '.lumenflow.config.yaml';
144
- const FRAMEWORK_HINT_FILE = '.lumenflow.framework.yaml';
145
- const LUMENFLOW_DIR = '.lumenflow';
146
- const LUMENFLOW_AGENTS_DIR = `${LUMENFLOW_DIR}/agents`;
147
- const CLAUDE_DIR = '.claude';
148
- const CLAUDE_AGENTS_DIR = path.join(CLAUDE_DIR, 'agents');
149
- /**
150
- * WU-1362: Check branch guard before writing tracked files
151
- *
152
- * Warns (but does not block) if:
153
- * - On main branch AND
154
- * - Not in a worktree directory AND
155
- * - Git repository exists (has .git)
156
- *
157
- * This prevents accidental main branch pollution during init operations.
158
- * Uses warning instead of error to allow initial project setup.
159
- *
160
- * @param targetDir - Directory where files will be written
161
- * @param result - ScaffoldResult to add warnings to
162
- */
163
- async function checkBranchGuard(targetDir, result) {
164
- result.warnings = result.warnings ?? [];
165
- // Only check if target is a git repository
166
- const gitDir = path.join(targetDir, '.git');
167
- if (!fs.existsSync(gitDir)) {
168
- // Not a git repo - allow scaffold (initial setup)
169
- return;
170
- }
171
- // Check if we're in a worktree (always allow)
172
- if (isInWorktree({ cwd: targetDir })) {
173
- return;
174
- }
175
- // Check if on main branch
176
- try {
177
- const onMain = await isMainBranch();
178
- if (onMain) {
179
- result.warnings.push('Running init on main branch in main checkout. ' +
180
- 'Consider using a worktree for changes to tracked files.');
181
- }
182
- }
183
- catch {
184
- // Git error (e.g., not initialized) - silently allow
185
- }
186
- }
187
- /**
188
- * WU-1177: Detect IDE environment from environment variables
189
- * Auto-detects which AI coding assistant is running
190
- */
191
- export function detectIDEEnvironment() {
192
- // Claude Code detection (highest priority - most specific)
193
- if (process.env.CLAUDE_PROJECT_DIR || process.env.CLAUDE_CODE) {
194
- return 'claude';
195
- }
196
- // Cursor detection
197
- const cursorVars = Object.keys(process.env).filter((key) => key.startsWith('CURSOR_'));
198
- if (cursorVars.length > 0) {
199
- return 'cursor';
200
- }
201
- // Windsurf detection
202
- const windsurfVars = Object.keys(process.env).filter((key) => key.startsWith('WINDSURF_'));
203
- if (windsurfVars.length > 0) {
204
- return 'windsurf';
205
- }
206
- // VS Code detection (lowest priority - most generic)
207
- const vscodeVars = Object.keys(process.env).filter((key) => key.startsWith('VSCODE_'));
208
- if (vscodeVars.length > 0) {
209
- return 'vscode';
210
- }
211
- return undefined;
212
- }
213
- /**
214
- * Get command version safely using execFileSync
215
- */
216
- function getCommandVersion(command, args) {
217
- try {
218
- const output = execFileSync(command, args, {
219
- encoding: 'utf-8',
220
- stdio: ['pipe', 'pipe', 'pipe'],
221
- }).trim();
222
- return output;
223
- }
224
- catch {
225
- return 'not found';
226
- }
227
- }
228
- /**
229
- * Parse semver version string to compare
230
- */
231
- function parseVersion(versionStr) {
232
- // Extract version numbers using a non-backtracking pattern
233
- // eslint-disable-next-line security/detect-unsafe-regex -- static semver pattern; no backtracking risk
234
- const match = /^v?(\d+)\.(\d+)(?:\.(\d+))?/.exec(versionStr);
235
- if (!match) {
236
- return [0, 0, 0];
237
- }
238
- return [parseInt(match[1], 10), parseInt(match[2], 10), parseInt(match[3] || '0', 10)];
239
- }
240
- /**
241
- * Compare versions: returns true if actual >= required
242
- */
243
- function compareVersions(actual, required) {
244
- const actualParts = parseVersion(actual);
245
- const requiredParts = parseVersion(required);
246
- for (let i = 0; i < 3; i++) {
247
- if (actualParts[i] > requiredParts[i]) {
248
- return true;
249
- }
250
- if (actualParts[i] < requiredParts[i]) {
251
- return false;
252
- }
253
- }
254
- return true;
255
- }
256
- /**
257
- * WU-1177: Check prerequisite versions
258
- * Non-blocking - returns results but doesn't fail init
259
- */
260
- export function checkPrerequisites() {
261
- const nodeVersion = getCommandVersion('node', ['--version']);
262
- const pnpmVersion = getCommandVersion('pnpm', ['--version']);
263
- const gitVersion = getCommandVersion('git', ['--version']);
264
- const requiredNode = '22.0.0';
265
- const requiredPnpm = '9.0.0';
266
- const requiredGit = '2.0.0';
267
- const nodeOk = nodeVersion !== 'not found' && compareVersions(nodeVersion, requiredNode);
268
- const pnpmOk = pnpmVersion !== 'not found' && compareVersions(pnpmVersion, requiredPnpm);
269
- const gitOk = gitVersion !== 'not found' && compareVersions(gitVersion, requiredGit);
270
- return {
271
- node: {
272
- passed: nodeOk,
273
- version: nodeVersion,
274
- required: `>=${requiredNode}`,
275
- message: nodeOk ? undefined : `Node.js ${requiredNode}+ required`,
276
- },
277
- pnpm: {
278
- passed: pnpmOk,
279
- version: pnpmVersion,
280
- required: `>=${requiredPnpm}`,
281
- message: pnpmOk ? undefined : `pnpm ${requiredPnpm}+ required`,
282
- },
283
- git: {
284
- passed: gitOk,
285
- version: gitVersion,
286
- required: `>=${requiredGit}`,
287
- message: gitOk ? undefined : `Git ${requiredGit}+ required`,
288
- },
289
- };
290
- }
291
- /**
292
- * WU-1307: Default lane definitions for config generation
293
- * These lanes match the parent lanes used in onboarding documentation.
294
- */
295
- // WU-1576: Lane definitions must have zero overlapping code_paths.
296
- // Each path must appear in exactly one lane to avoid doctor warnings.
297
- const DEFAULT_LANE_DEFINITIONS = [
298
- {
299
- name: 'Framework: Core',
300
- wip_limit: 1,
301
- code_paths: ['packages/**/core/**', 'src/core/**', 'lib/**'],
302
- },
303
- {
304
- name: 'Framework: CLI',
305
- wip_limit: 1,
306
- code_paths: ['packages/**/cli/**', 'src/cli/**', 'bin/**'],
307
- },
308
- {
309
- name: 'Experience: Web',
310
- wip_limit: 1,
311
- code_paths: ['apps/web/**', 'web/**', 'src/components/**', 'src/pages/**', 'src/app/**'],
312
- },
313
- {
314
- name: 'Operations: Infrastructure',
315
- wip_limit: 1,
316
- code_paths: ['infrastructure/**', 'deploy/**'],
317
- },
318
- {
319
- name: 'Operations: CI/CD',
320
- wip_limit: 1,
321
- code_paths: ['.github/workflows/**', '.github/actions/**', '.circleci/**'],
322
- },
323
- {
324
- name: 'Content: Documentation',
325
- wip_limit: 1,
326
- code_paths: ['docs/**', '*.md'],
327
- },
328
- ];
329
- /**
330
- * Generate YAML configuration with header comment
331
- * WU-1067: Supports --preset option for config-driven gates
332
- * WU-1307: Includes default lane definitions for onboarding
333
- * WU-1364: Supports git config overrides (requireRemote)
334
- * WU-1383: Adds enforcement hooks config for Claude client by default
335
- */
336
- function generateLumenflowConfigYaml(gatePreset, gitConfigOverride, client) {
337
- // WU-1382: Add managed file header to prevent manual edits
338
- const header = `# ============================================================================
339
- # LUMENFLOW MANAGED FILE - DO NOT EDIT MANUALLY
340
- # ============================================================================
341
- # Generated by: lumenflow init
342
- # Regenerate with: pnpm exec lumenflow init --force
343
- #
344
- # This file is managed by LumenFlow tooling. Manual edits may be overwritten.
345
- # To customize, use the CLI commands or edit the appropriate source templates.
346
- # ============================================================================
347
-
348
- # LumenFlow Configuration
349
- # Customize paths based on your project structure
350
-
351
- `;
352
- const config = getDefaultConfig();
353
- config.directories.agentsDir = LUMENFLOW_AGENTS_DIR;
354
- // WU-1067: Add gates.execution section with preset if specified
355
- if (gatePreset && GATE_PRESETS[gatePreset]) {
356
- const presetConfig = GATE_PRESETS[gatePreset];
357
- config.gates.execution = {
358
- preset: gatePreset,
359
- ...presetConfig,
360
- };
361
- }
362
- // WU-1307: Add default lane definitions
363
- config.lanes = {
364
- definitions: DEFAULT_LANE_DEFINITIONS,
365
- };
366
- // WU-1364: Add git config overrides (e.g., requireRemote: false for local-only)
367
- if (gitConfigOverride) {
368
- config.git = {
369
- requireRemote: gitConfigOverride.requireRemote,
370
- };
371
- }
372
- // WU-1383: Add enforcement hooks for Claude client by default
373
- // This prevents agents from working on main and editing config files manually
374
- if (client === 'claude') {
375
- config.agents = {
376
- clients: {
377
- [DEFAULT_CLIENT_CLAUDE]: {
378
- enforcement: {
379
- hooks: true,
380
- block_outside_worktree: true,
381
- require_wu_for_edits: true,
382
- warn_on_stop_without_wu_done: true,
383
- },
384
- },
385
- },
386
- };
387
- }
388
- return header + yaml.stringify(config);
389
- }
390
- /**
391
- * Get current date in YYYY-MM-DD format
392
- */
393
- function getCurrentDate() {
394
- return new Date().toISOString().split('T')[0];
395
- }
396
- /**
397
- * Normalize a framework name into display + slug
398
- */
399
- function normalizeFrameworkName(framework) {
400
- const name = framework.trim();
401
- const slug = name
402
- .toLowerCase()
403
- .replace(/[^a-z0-9_-]+/g, '-')
404
- // Remove leading dashes and trailing dashes separately (explicit precedence)
405
- .replace(/^-+/, '')
406
- .replace(/-+$/, '');
407
- if (!slug) {
408
- throw new Error(`Invalid framework name: "${framework}"`);
409
- }
410
- return { name, slug };
411
- }
412
- /**
413
- * Process template content by replacing placeholders
414
- */
415
- function processTemplate(content, tokens) {
416
- let output = content;
417
- for (const [key, value] of Object.entries(tokens)) {
418
- // eslint-disable-next-line security/detect-non-literal-regexp -- key is from internal token map, not user input
419
- output = output.replace(new RegExp(`\\{\\{${key}\\}\\}`, 'g'), value);
420
- }
421
- return output;
422
- }
423
- function getRelativePath(targetDir, filePath) {
424
- return path.relative(targetDir, filePath).split(path.sep).join('/');
425
- }
426
- // WU-1171: Template for AGENTS.md (universal entry point)
427
- // WU-1300: Updated quick-ref link to correct path
428
- // WU-1309: Use {{QUICK_REF_LINK}} and <project-root> placeholder for portability
429
- const AGENTS_MD_TEMPLATE = `# Universal Agent Instructions
430
-
431
- **Last updated:** {{DATE}}
432
-
433
- This project uses LumenFlow workflow. For complete documentation, see [LUMENFLOW.md](LUMENFLOW.md).
434
-
435
- ---
436
-
437
- ## Quick Start
438
-
439
- \`\`\`bash
440
- # 1. Claim a WU
441
- pnpm wu:claim --id WU-XXXX --lane <Lane>
442
- cd worktrees/<lane>-wu-xxxx
443
-
444
- # 2. Work in worktree, run gates
445
- pnpm gates
446
-
447
- # 3. Complete (ALWAYS run this!)
448
- cd <project-root>
449
- pnpm wu:done --id WU-XXXX
450
- \`\`\`
451
-
452
- > **Complete CLI reference:** See [quick-ref-commands.md]({{QUICK_REF_LINK}})
453
-
454
- ---
455
-
456
- ## Critical: Always wu:done
457
-
458
- After completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\` from the main checkout.
459
-
460
- This is the single most forgotten step. See [LUMENFLOW.md](LUMENFLOW.md) for details.
461
-
462
- ---
463
-
464
- ## Core Principles
465
-
466
- 1. **TDD**: Write tests first, then implementation
467
- 2. **Worktree Discipline**: After \`wu:claim\`, work ONLY in the worktree
468
- 3. **Gates Before Done**: Run \`pnpm gates\` before \`wu:done\`
469
- 4. **Never Bypass Hooks**: No \`--no-verify\`
470
-
471
- ---
472
-
473
- ## Forbidden Commands
474
-
475
- - \`git reset --hard\`
476
- - \`git push --force\`
477
- - \`git stash\` (on main)
478
- - \`--no-verify\`
479
-
480
- ---
481
-
482
- ## Vendor-Specific Overlays
483
-
484
- This file provides universal guidance for all AI agents. Additional vendor-specific configuration:
485
-
486
- - **Claude Code**: See \`CLAUDE.md\` (if present)
487
- - **Cursor**: See \`.cursor/rules/lumenflow.md\` (if present)
488
- - **Windsurf**: See \`.windsurf/rules/lumenflow.md\` (if present)
489
- `;
490
- // Template for LUMENFLOW.md (main entry point)
491
- // WU-1309: Use <project-root> placeholder for portability
492
- // WU-1364: Added initiative workflow section
493
- const LUMENFLOW_MD_TEMPLATE = `# LumenFlow Workflow Guide\n\n**Last updated:** {{DATE}}\n\nLumenFlow is a vendor-agnostic workflow framework for AI-native software development.\n\n---\n\n## Critical Rule: ALWAYS Run wu:done\n\n**After completing work on a WU, you MUST run \`pnpm wu:done --id WU-XXXX\` from the main checkout.**\n\nThis is the single most forgotten step. Do NOT:\n- Write "To Complete: pnpm wu:done" and stop\n- Ask if you should run wu:done\n- Forget to run wu:done\n\n**DO**: Run \`pnpm wu:done --id WU-XXXX\` immediately after gates pass.\n\n---\n\n## When to Use Initiatives\n\nUse **Initiatives** for multi-phase work spanning multiple WUs:\n\n- **Product visions**: "Build a task management app"\n- **Larger features**: Work requiring multiple WUs across lanes\n- **Complex projects**: Anything that needs phased delivery\n\n\`\`\`bash\n# Create an initiative for multi-phase work\npnpm initiative:create --id INIT-001 --title "Feature Name" \\\\\n --description "..." --phase "Phase 1: MVP" --phase "Phase 2: Polish"\n\n# Add WUs to the initiative\npnpm initiative:add-wu --initiative INIT-001 --wu WU-XXX --phase 1\n\n# Track progress\npnpm initiative:status --id INIT-001\n\`\`\`\n\n**Skip initiatives** for: single-file bug fixes, small docs updates, isolated refactoring.\n\n---\n\n## Quick Start\n\n\`\`\`bash\n# 1. Create a WU\npnpm wu:create --id WU-XXXX --lane <Lane> --title "Title"\n\n# 2. Edit WU spec with acceptance criteria, then claim:\npnpm wu:claim --id WU-XXXX --lane <Lane>\ncd worktrees/<lane>-wu-xxxx\n\n# 3. Implement in worktree\n\n# 4. Run gates\npnpm gates --docs-only # for docs changes\npnpm gates # for code changes\n\n# 5. Complete (from main checkout)\ncd <project-root>\npnpm wu:done --id WU-XXXX\n\`\`\`\n\n---\n\n## Core Principles\n\n1. **TDD**: Failing test -> implementation -> passing test (>=90% coverage on new code)\n2. **Library-First**: Search existing libraries before custom code\n3. **DRY/SOLID/KISS/YAGNI**: No magic numbers, no hardcoded strings\n4. **Worktree Discipline**: After \`wu:claim\`, work ONLY in the worktree\n5. **Gates Before Done**: All gates must pass before \`wu:done\`\n6. **Do Not Bypass Hooks**: No \`--no-verify\`, fix issues properly\n7. **Always wu:done**: Complete every WU by running \`pnpm wu:done\`\n\n---\n\n## Documentation Structure\n\n### Core (Vendor-Agnostic)\n\n- **LUMENFLOW.md** - This file, main entry point\n- **.lumenflow/constraints.md** - Non-negotiable workflow constraints\n- **.lumenflow/agents/** - Agent instructions (vendor-agnostic)\n- **.lumenflow.config.yaml** - Workflow configuration\n\n### Optional Overlays\n\n- **CLAUDE.md + .claude/agents/** - Claude Code overlay (auto if Claude Code detected)\n- **{{DOCS_TASKS_PATH}}** - Task boards and WU storage (\`lumenflow init --full\`)\n- **{{DOCS_ONBOARDING_PATH}}** - Agent onboarding docs\n- **.lumenflow.framework.yaml** - Framework hint file (created with \`--framework\`)\n\n---\n\n## Worktree Discipline (IMMUTABLE LAW)\n\nAfter claiming a WU, you MUST work in its worktree:\n\n\`\`\`bash\n# 1. Claim creates worktree\npnpm wu:claim --id WU-XXX --lane <lane>\n\n# 2. IMMEDIATELY cd to worktree\ncd worktrees/<lane>-wu-xxx\n\n# 3. ALL work happens here\n\n# 4. Return to main ONLY to complete\ncd <project-root>\npnpm wu:done --id WU-XXX\n\`\`\`\n\n---\n\n## Definition of Done\n\n- Acceptance criteria satisfied\n- Gates green (\`pnpm gates\` or \`pnpm gates --docs-only\`)\n- WU YAML status = \`done\`\n- \`wu:done\` has been run\n\n---\n\n## Commands Reference\n\n| Command | Description |\n| ----------------- | ----------------------------------- |\n| \`pnpm wu:create\` | Create new WU spec |\n| \`pnpm wu:claim\` | Claim WU and create worktree |\n| \`pnpm wu:done\` | Complete WU (merge, stamp, cleanup) |\n| \`pnpm gates\` | Run quality gates |\n| \`pnpm initiative:create\` | Create multi-phase initiative |\n| \`pnpm initiative:status\` | View initiative progress |\n\n---\n\n## Constraints\n\nSee [.lumenflow/constraints.md](.lumenflow/constraints.md) for the 6 non-negotiable rules.\n\n---\n\n## Agent Onboarding\n\n- Start with **CLAUDE.md** if present (Claude Code overlay).\n- Add vendor-agnostic guidance in **.lumenflow/agents/**.\n- Check the onboarding docs in **{{DOCS_ONBOARDING_PATH}}** for detailed guidance.\n`;
494
- // Template for .lumenflow/constraints.md
495
- const CONSTRAINTS_MD_TEMPLATE = `# LumenFlow Constraints Capsule\n\n**Version:** 1.0\n**Last updated:** {{DATE}}\n\n## The 6 Non-Negotiable Constraints\n\n### 1. Worktree Discipline and Git Safety\nWork only in worktrees, treat main as read-only, never run destructive git commands on main.\n\n### 2. WUs Are Specs, Not Code\nRespect code_paths boundaries, no feature creep, no code blocks in WU YAML files.\n\n### 3. Docs-Only vs Code WUs\nDocumentation WUs use \`--docs-only\` gates, code WUs run full gates.\n\n### 4. LLM-First, Zero-Fallback Inference\nUse LLMs for semantic tasks, fall back to safe defaults (never regex/keywords).\n\n### 5. Gates and Skip-Gates\nComplete via \`pnpm wu:done\`; skip-gates only for pre-existing failures with \`--reason\` and \`--fix-wu\`.\n\n### 6. Safety and Governance\nRespect privacy rules, approved sources, security policies; when uncertain, choose safer path.\n\n---\n\n## Mini Audit Checklist\n\nBefore running \`wu:done\`, verify:\n\n- [ ] Working in worktree (not main)\n- [ ] Only modified files in \`code_paths\`\n- [ ] Gates pass\n- [ ] No forbidden git commands used\n- [ ] Acceptance criteria satisfied\n\n---\n\n## Escalation Triggers\n\nStop and ask a human when:\n- Same error repeats 3 times\n- Auth or permissions changes required\n- PII/PHI/safety issues discovered\n- Cloud spend or secrets involved\n`;
496
- // Template for root CLAUDE.md
497
- // WU-1309: Use <project-root> placeholder for portability
498
- // WU-1382: Expanded with CLI commands table and warning about manual YAML editing
499
- const CLAUDE_MD_TEMPLATE = `# Claude Code Instructions
500
-
501
- **Last updated:** {{DATE}}
502
-
503
- This project uses LumenFlow workflow. For workflow documentation, see [LUMENFLOW.md](LUMENFLOW.md).
504
-
505
- ---
506
-
507
- ## Quick Start
508
-
509
- \`\`\`bash
510
- # 1. Claim a WU
511
- pnpm wu:claim --id WU-XXXX --lane <Lane>
512
- cd worktrees/<lane>-wu-xxxx
513
-
514
- # 2. Work in worktree, run gates
515
- pnpm gates
516
-
517
- # 3. Complete (ALWAYS run this!)
518
- cd <project-root>
519
- pnpm wu:done --id WU-XXXX
520
- \`\`\`
521
-
522
- ---
523
-
524
- ## CLI Commands Reference
525
-
526
- ### WU Lifecycle
527
-
528
- | Command | Description |
529
- | ----------------------------------------- | ---------------------------------------- |
530
- | \`pnpm wu:status --id WU-XXX\` | Show WU status, location, valid commands |
531
- | \`pnpm wu:claim --id WU-XXX --lane <Lane>\` | Claim WU and create worktree |
532
- | \`pnpm wu:prep --id WU-XXX\` | Run gates in worktree, prep for wu:done |
533
- | \`pnpm wu:done --id WU-XXX\` | Complete WU (from main checkout) |
534
- | \`pnpm wu:block --id WU-XXX --reason "..."\`| Block WU with reason |
535
- | \`pnpm wu:unblock --id WU-XXX\` | Unblock WU |
536
-
537
- ### Gates & Quality
538
-
539
- | Command | Description |
540
- | ------------------------ | -------------------------- |
541
- | \`pnpm gates\` | Run all quality gates |
542
- | \`pnpm gates --docs-only\` | Run gates for docs changes |
543
- | \`pnpm format\` | Format all files |
544
- | \`pnpm lint\` | Run linter |
545
- | \`pnpm typecheck\` | Run TypeScript check |
546
- | \`pnpm test\` | Run tests |
547
-
548
- ---
549
-
550
- ## Critical: Always wu:done
551
-
552
- After completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\` from the main checkout.
553
-
554
- See [LUMENFLOW.md](LUMENFLOW.md) for full workflow documentation.
555
-
556
- ---
557
-
558
- ## Warning: Do Not Edit WU YAML Files Manually
559
-
560
- **Never manually edit WU YAML files** in \`docs/.../tasks/wu/WU-XXX.yaml\`.
561
-
562
- Use CLI commands instead:
563
-
564
- - \`pnpm wu:create ...\` to create new WUs
565
- - \`pnpm wu:edit --id WU-XXX ...\` to modify WU fields
566
- - \`pnpm wu:claim\` / \`wu:block\` / \`wu:done\` for status changes
567
-
568
- Manual edits bypass validation and can corrupt workflow state.
569
- `;
570
- // Template for .claude/settings.json
571
- const CLAUDE_SETTINGS_TEMPLATE = `{
572
- "$schema": "https://json.schemastore.org/claude-code-settings.json",
573
- "permissions": {
574
- "allow": [
575
- "Bash",
576
- "Read",
577
- "Write",
578
- "Edit",
579
- "WebFetch",
580
- "WebSearch"
581
- ],
582
- "deny": [
583
- "Read(./.env)",
584
- "Read(./.env.*)",
585
- "Write(./.env*)",
586
- "Bash(git reset --hard *)",
587
- "Bash(git stash *)",
588
- "Bash(git clean -fd *)",
589
- "Bash(git push --force *)",
590
- "Bash(git push -f *)",
591
- "Bash(git commit --no-verify *)",
592
- "Bash(HUSKY=0 *)",
593
- "Bash(rm -rf /*)",
594
- "Bash(sudo *)",
595
- "Bash(git worktree remove *)",
596
- "Bash(git worktree prune *)"
597
- ]
598
- }
599
- }
600
- `;
601
- // WU-1171: Template for .cursor/rules/lumenflow.md (updated path)
602
- // WU-1309: Use <project-root> placeholder for portability
603
- const CURSOR_RULES_TEMPLATE = `# Cursor LumenFlow Rules
604
-
605
- This project uses LumenFlow workflow. See [LUMENFLOW.md](../../LUMENFLOW.md).
606
-
607
- ## Critical Rules
608
-
609
- 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
610
- 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
611
- 3. **Never bypass hooks** - No \`--no-verify\`
612
- 4. **TDD** - Write tests first
613
-
614
- ## Forbidden Commands
615
-
616
- - \`git reset --hard\`
617
- - \`git push --force\`
618
- - \`git stash\` (on main)
619
- - \`--no-verify\`
620
-
621
- ## Quick Reference
622
-
623
- \`\`\`bash
624
- # Claim WU
625
- pnpm wu:claim --id WU-XXX --lane <Lane>
626
- cd worktrees/<lane>-wu-xxx
627
-
628
- # Run gates
629
- pnpm gates
630
-
631
- # Complete (from main)
632
- cd <project-root>
633
- pnpm wu:done --id WU-XXX
634
- \`\`\`
635
- `;
636
- // WU-1171: Template for .windsurf/rules/lumenflow.md
637
- // WU-1309: Use <project-root> placeholder for portability
638
- const WINDSURF_RULES_TEMPLATE = `# Windsurf LumenFlow Rules
639
-
640
- This project uses LumenFlow workflow. See [LUMENFLOW.md](../../LUMENFLOW.md).
641
-
642
- ## Critical Rules
643
-
644
- 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
645
- 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
646
- 3. **Never bypass hooks** - No \`--no-verify\`
647
- 4. **TDD** - Write tests first
648
-
649
- ## Forbidden Commands
650
-
651
- - \`git reset --hard\`
652
- - \`git push --force\`
653
- - \`git stash\` (on main)
654
- - \`--no-verify\`
655
-
656
- ## Quick Reference
657
-
658
- \`\`\`bash
659
- # Claim WU
660
- pnpm wu:claim --id WU-XXX --lane <Lane>
661
- cd worktrees/<lane>-wu-xxx
662
-
663
- # Run gates
664
- pnpm gates
665
-
666
- # Complete (from main)
667
- cd <project-root>
668
- pnpm wu:done --id WU-XXX
669
- \`\`\`
670
- `;
671
- // WU-1177: Template for .clinerules (Cline AI assistant)
672
- // WU-1309: Use <project-root> placeholder for portability
673
- const CLINE_RULES_TEMPLATE = `# Cline LumenFlow Rules
674
-
675
- This project uses LumenFlow workflow. See [LUMENFLOW.md](LUMENFLOW.md).
676
-
677
- ## Critical Rules
678
-
679
- 1. **Always run wu:done** - After gates pass, run \`pnpm wu:done --id WU-XXX\`
680
- 2. **Work in worktrees** - After \`wu:claim\`, work only in the worktree
681
- 3. **Never bypass hooks** - No \`--no-verify\`
682
- 4. **TDD** - Write tests first
683
-
684
- ## Forbidden Commands
685
-
686
- - \`git reset --hard\`
687
- - \`git push --force\`
688
- - \`git stash\` (on main)
689
- - \`--no-verify\`
690
-
691
- ## Quick Reference
692
-
693
- \`\`\`bash
694
- # Claim WU
695
- pnpm wu:claim --id WU-XXX --lane <Lane>
696
- cd worktrees/<lane>-wu-xxx
697
-
698
- # Run gates
699
- pnpm gates
700
-
701
- # Complete (from main)
702
- cd <project-root>
703
- pnpm wu:done --id WU-XXX
704
- \`\`\`
705
- `;
706
- // Template for .aider.conf.yml
707
- const AIDER_CONF_TEMPLATE = `# Aider Configuration for LumenFlow Projects\n# See LUMENFLOW.md for workflow documentation\n\nmodel: gpt-4-turbo\nauto-commits: false\ndirty-commits: false\n\nread:\n - LUMENFLOW.md\n - .lumenflow/constraints.md\n`;
708
- // WU-1413: Template for .mcp.json (MCP server configuration for Claude Code)
709
- const MCP_JSON_TEMPLATE = `{
710
- "mcpServers": {
711
- "lumenflow": {
712
- "command": "npx",
713
- "args": ["@lumenflow/mcp"]
714
- }
715
- }
716
- }
717
- `;
718
- // Template for docs/04-operations/tasks/backlog.md
719
- const BACKLOG_TEMPLATE = `---\nsections:\n ready:\n heading: '## 🚀 Ready (pull from here)'\n insertion: after_heading_blank_line\n in_progress:\n heading: '## 🔧 In progress'\n insertion: after_heading_blank_line\n blocked:\n heading: '## ⛔ Blocked'\n insertion: after_heading_blank_line\n done:\n heading: '## ✅ Done'\n insertion: after_heading_blank_line\n---\n\n# Backlog (single source of truth)\n\n## 🚀 Ready (pull from here)\n\n(No items ready)\n\n## 🔧 In progress\n\n(No items in progress)\n\n## ⛔ Blocked\n\n(No items blocked)\n\n## ✅ Done\n\n(No items completed yet)\n`;
720
- // Template for docs/04-operations/tasks/status.md
721
- const STATUS_TEMPLATE = `# Status (active work)\n\n## In Progress\n\n(No items in progress)\n\n## Blocked\n\n(No items blocked)\n\n## Completed\n\n(No items completed yet)\n`;
722
- // Template for docs tasks WU template YAML (scaffolded to {{DOCS_TASKS_PATH}}/templates/wu-template.yaml)
723
- const WU_TEMPLATE_YAML = `# Work Unit Template (LumenFlow WU Schema)\n#\n# Copy this template when creating new WUs. Fill in all required fields and\n# remove optional fields if not needed.\n#\n# If you used "lumenflow init --full", this template lives at:\n# {{DOCS_TASKS_PATH}}/templates/wu-template.yaml\n\n# Required: Unique work unit identifier (format: WU-NNN)\nid: WU-XXX\n\n# Required: Short, descriptive title (max 80 chars)\ntitle: 'Your WU title here'\n\n# Required: Lane (Parent: Sublane format)\nlane: '<Parent: Sublane>'\n\n# Required: Type of work\ntype: 'feature' # feature | bug | documentation | process | tooling | chore | refactor\n\n# Required: Current status\nstatus: 'ready' # ready | in_progress | blocked | done | cancelled\n\n# Required: Priority\npriority: P2 # P0 | P1 | P2 | P3\n\n# Required: Creation date (YYYY-MM-DD)\ncreated: {{DATE}}\n\n# Required: Owner/assignee (email)\nassigned_to: 'unassigned@example.com'\n\n# Required: Description\ndescription: |\n Context: ...\n Problem: ...\n Solution: ...\n\n# Required: Acceptance criteria (testable, binary)\nacceptance:\n - Criterion 1 (specific, measurable, testable)\n - Criterion 2 (binary pass/fail)\n - Documentation updated\n\n# Required: References to plans/specs (required for type: feature)\n# Tip: use pnpm wu:create --plan to generate a plan stub at lumenflow://plans/WU-XXX-plan.md\nspec_refs:\n - lumenflow://plans/WU-XXX-plan.md\n\n# Required: Code files changed or created (empty only for docs/process WUs)\n# Docs-only WUs should use docs/ or *.md paths to avoid docs-only gate failures.\ncode_paths:\n - path/to/file.ts\n\n# Required: Test paths (at least one of manual/unit/e2e/integration for non-doc WUs)\ntests:\n manual:\n - Manual check: Verify behavior or docs output\n unit:\n - path/to/test.test.ts\n e2e: []\n integration: []\n\n# Required: Exposure level\nexposure: 'backend-only' # ui | api | backend-only | documentation\n\n# Optional: User journey (recommended for ui/api)\n# user_journey: |\n# User navigates to ...\n# User performs ...\n\n# Optional: UI pairing WUs (for api exposure)\n# ui_pairing_wus:\n# - WU-1234\n\n# Optional: Navigation path (required when exposure=ui and no page file)\n# navigation_path: '/settings'\n\n# Required: Deliverable artifacts (stamps, docs, etc.)\nartifacts:\n - .lumenflow/stamps/WU-XXX.done\n\n# Optional: Dependencies (other WUs that must complete first)\ndependencies: []\n\n# Optional: Risks\nrisks:\n - Risk 1\n\n# Optional: Notes (required by spec linter)\nnotes: 'Implementation notes, rollout context, or plan summary.'\n\n# Optional: Requires human review\nrequires_review: false\n\n# Optional: Claimed mode (worktree or branch-only)\n# Automatically set by wu:claim, usually don't need to specify\n# claimed_mode: worktree\n\n# Optional: Assigned to (email of current claimant)\n# Automatically set by wu:claim\n# assigned_to: engineer@example.com\n\n# Optional: Locked status (prevents concurrent edits)\n# Automatically set by wu:claim and wu:done\n# locked: false\n\n# Optional: Completion date (ISO 8601 format)\n# Automatically set by wu:done\n# completed: 2025-10-23\n\n# Optional: Completion notes (added by wu:done)\n# completion_notes: |\n# Additional notes added during wu:done.\n# Any deviations from original plan.\n# Lessons learned.\n\n# ============================================================================\n# GOVERNANCE BLOCK (WU Schema v2.0)\n# ============================================================================\n# Optional: COS governance rules that apply to this WU\n# Only include if this WU needs specific governance enforcement\n\n# governance:\n# # Rules that apply to this WU (evaluated during cos:gates)\n# rules:\n# - rule_id: UPAIN-01\n# satisfied: false # Initially false, set true when evidence provided\n# evidence:\n# - type: link\n# value: docs/product/voc/feature-user-pain.md\n# description: "Voice of Customer analysis showing user pain"\n# notes: |\n# VOC analysis shows 40% of support tickets request this feature.\n# Average time wasted: 15min/user/week.\n#\n# - rule_id: CASH-03\n# satisfied: false\n# evidence:\n# - type: link\n# value: docs/finance/spend-reviews/2025-10-cloud-infra.md\n# description: "Spend review for £1200/month cloud infrastructure"\n# - type: approval\n# value: owner@example.com\n# description: "Owner approval for spend commitment"\n# notes: |\n# New cloud infrastructure commitment: £1200/month for 12 months.\n# ROI: Reduces latency by 50%, improves user retention.\n#\n# # Gate checks (enforced by cos-gates.ts)\n# gates:\n# narrative: "pending" # Status: pending, passed, skipped, failed\n# finance: "pending"\n#\n# # Exemptions (only if rule doesn't apply)\n# exemptions:\n# - rule_id: FAIR-01\n# reason: "No user-facing pricing changes in this WU"\n# approved_by: product-owner@example.com\n# approved_at: 2025-10-23\n\n# ============================================================================\n# USAGE NOTES\n# ============================================================================\n#\n# 1. Remove this entire governance block if no COS rules apply to your WU\n# 2. Only include rules that require enforcement (not all rules apply to all WUs)\n# 3. Evidence types: link:, metric:, screenshot:, approval:\n# 4. Gates are checked during wu:done (before merge)\n# 5. Exemptions require approval from rule owner\n#\n# For more details, see:\n# - {{DOCS_OPERATIONS_PATH}}/_frameworks/cos/system-prompt-v1.3.md\n# - {{DOCS_OPERATIONS_PATH}}/_frameworks/cos/evidence-format.md\n`;
724
- // Template for .lumenflow.framework.yaml
725
- const FRAMEWORK_HINT_TEMPLATE = `# LumenFlow Framework Hint\n# Generated by: lumenflow init --framework {{FRAMEWORK_NAME}}\n\nframework: "{{FRAMEWORK_NAME}}"\nslug: "{{FRAMEWORK_SLUG}}"\n`;
726
- // Template for docs/04-operations/_frameworks/<framework>/README.md
727
- const FRAMEWORK_OVERLAY_TEMPLATE = `# {{FRAMEWORK_NAME}} Framework Overlay\n\n**Last updated:** {{DATE}}\n\nThis overlay captures framework-specific conventions, constraints, and references for {{FRAMEWORK_NAME}} projects.\n\n## Scope\n\n- Project structure conventions\n- Framework-specific testing guidance\n- Common pitfalls and mitigations\n\n## References\n\n- Add official docs links here\n`;
728
- // WU-1083: Agent onboarding docs templates
729
- // WU-1309: Updated quick-ref with --docs-structure and complete wu:create example
730
- const QUICK_REF_COMMANDS_TEMPLATE = `# Quick Reference: LumenFlow Commands
731
-
732
- **Last updated:** {{DATE}}
733
-
734
- ---
735
-
736
- ## Project Setup
737
-
738
- | Command | Description |
739
- | ---------------------------------------------------- | ----------------------------------------- |
740
- | \`pnpm exec lumenflow init\` | Scaffold minimal LumenFlow core |
741
- | \`pnpm exec lumenflow init --full\` | Add docs + agent onboarding scaffolding |
742
- | \`pnpm exec lumenflow init --docs-structure simple\` | Use simple docs structure (docs/tasks) |
743
- | \`pnpm exec lumenflow init --docs-structure arc42\` | Use arc42 structure (docs/04-operations) |
744
- | \`pnpm exec lumenflow init --framework <name>\` | Add framework hint + overlay docs |
745
- | \`pnpm exec lumenflow init --client <type>\` | Add client overlay (claude, cursor, etc.) |
746
- | \`pnpm exec lumenflow init --force\` | Overwrite existing files |
747
-
748
- ---
749
-
750
- ## WU Management
751
-
752
- | Command | Description |
753
- | ----------------------------------------- | ------------------------------- |
754
- | \`pnpm wu:create ...\` (see example below) | Create new WU |
755
- | \`pnpm wu:claim --id WU-XXX --lane <Lane>\`| Claim WU (creates worktree) |
756
- | \`pnpm wu:done --id WU-XXX\` | Complete WU (merge, stamp) |
757
- | \`pnpm wu:block --id WU-XXX --reason "..."\`| Block a WU |
758
- | \`pnpm wu:unblock --id WU-XXX\` | Unblock a WU |
759
- | \`pnpm wu:status --id WU-XXX\` | Check WU status and location |
760
-
761
- ---
762
-
763
- ## Complete wu:create Example
764
-
765
- \`\`\`bash
766
- pnpm wu:create \\
767
- --id WU-001 \\
768
- --lane "Framework: Core" \\
769
- --title "Add validation feature" \\
770
- --description "Context: Users need input validation. Problem: No validation exists. Solution: Add Zod-based validation." \\
771
- --acceptance "Validation rejects invalid input" \\
772
- --acceptance "Unit tests cover edge cases with >90% coverage" \\
773
- --acceptance "Documentation updated" \\
774
- --code-paths "packages/@lumenflow/core/src/validation.ts" \\
775
- --test-paths-unit "packages/@lumenflow/core/src/__tests__/validation.test.ts" \\
776
- --exposure backend-only \\
777
- --spec-refs "lumenflow://plans/WU-001-plan.md"
778
- \`\`\`
779
-
780
- **Required fields for code WUs:**
781
- - \`--lane\`: Format is "Parent: Sublane" (e.g., "Framework: Core")
782
- - \`--title\`: Short descriptive title
783
- - \`--description\`: Context, Problem, Solution
784
- - \`--acceptance\`: At least one (repeatable)
785
- - \`--code-paths\`: Files to modify (repeatable)
786
- - \`--test-paths-unit\` or \`--test-paths-e2e\`: Test files
787
- - \`--exposure\`: ui | api | backend-only | documentation
788
- - \`--spec-refs\`: Required for type: feature
789
-
790
- ---
791
-
792
- ## Gates
793
-
794
- | Command | Description |
795
- | ------------------------ | -------------------------- |
796
- | \`pnpm gates\` | Run all quality gates |
797
- | \`pnpm gates --docs-only\` | Run gates for docs changes |
798
- | \`pnpm format\` | Format all files |
799
- | \`pnpm lint\` | Run linter |
800
- | \`pnpm typecheck\` | Run TypeScript check |
801
- | \`pnpm test\` | Run tests |
802
-
803
- ---
804
-
805
- ## Git (Safe Operations)
806
-
807
- | Command | Description |
808
- | ------------------------------------ | ------------------------- |
809
- | \`git status\` | Check working tree status |
810
- | \`git add .\` | Stage all changes |
811
- | \`git commit -m "type: message"\` | Commit with message |
812
- | \`git push origin lane/<lane>/wu-xxx\` | Push to remote |
813
-
814
- ---
815
-
816
- ## Navigation
817
-
818
- \`\`\`bash
819
- # After claiming, go to worktree
820
- cd worktrees/<lane>-wu-xxx
821
-
822
- # Return to main for wu:done
823
- cd <project-root>
824
- \`\`\`
825
-
826
- ---
827
-
828
- ## Workflow Sequence
829
-
830
- \`\`\`bash
831
- # 1. Create (see complete example above)
832
- pnpm wu:create --id WU-001 --lane "Framework: Core" --title "Add feature" \\
833
- --description "Context: ... Problem: ... Solution: ..." \\
834
- --acceptance "Feature works" --acceptance "Tests pass" \\
835
- --code-paths "src/feature.ts" \\
836
- --test-paths-unit "src/__tests__/feature.test.ts" \\
837
- --exposure backend-only \\
838
- --spec-refs "lumenflow://plans/WU-001-plan.md"
839
-
840
- # 2. Claim
841
- pnpm wu:claim --id WU-001 --lane "Framework: Core"
842
- cd worktrees/framework-core-wu-001
843
-
844
- # 3. Work (TDD)
845
- # ... write tests first, then code ...
846
-
847
- # 4. Commit
848
- git add .
849
- git commit -m "feat: add feature"
850
- git push origin lane/framework-core/wu-001
851
-
852
- # 5. Gates
853
- pnpm gates
854
-
855
- # 6. Complete (from main checkout)
856
- cd <project-root>
857
- pnpm wu:done --id WU-001
858
- \`\`\`
859
-
860
- ---
861
-
862
- ## File Paths
863
-
864
- | Path | Description |
865
- | ------------------------------------ | -------------------- |
866
- | \`{{DOCS_TASKS_PATH}}/wu/WU-XXX.yaml\` | WU specification |
867
- | \`{{DOCS_TASKS_PATH}}/status.md\` | Current status board |
868
- | \`.lumenflow/stamps/WU-XXX.done\` | Completion stamp |
869
- | \`worktrees/<lane>-wu-xxx/\` | Worktree directory |
870
- `;
871
- const FIRST_WU_MISTAKES_TEMPLATE = `# First WU Mistakes
872
-
873
- **Last updated:** {{DATE}}
874
-
875
- Common mistakes agents make on their first WU, and how to avoid them.
876
-
877
- ---
878
-
879
- ## Mistake 1: Not Using Worktrees
880
-
881
- ### Wrong
882
-
883
- \`\`\`bash
884
- # Working directly in main
885
- vim src/feature.ts
886
- git commit -m "feat: add feature"
887
- git push origin main
888
- \`\`\`
889
-
890
- ### Right
891
-
892
- \`\`\`bash
893
- # Claim first, then work in worktree
894
- pnpm wu:claim --id WU-123 --lane Core
895
- cd worktrees/core-wu-123
896
- vim src/feature.ts
897
- git commit -m "feat: add feature"
898
- git push origin lane/core/wu-123
899
- cd /path/to/main
900
- pnpm wu:done --id WU-123
901
- \`\`\`
902
-
903
- ---
904
-
905
- ## Mistake 2: Forgetting to Run wu:done
906
-
907
- See [troubleshooting-wu-done.md](troubleshooting-wu-done.md) for the full explanation.
908
-
909
- **TL;DR:** After gates pass, ALWAYS run \`pnpm wu:done --id WU-XXX\`.
910
-
911
- ---
912
-
913
- ## Mistake 3: Working Outside code_paths
914
-
915
- ### Wrong
916
-
917
- The WU says \`code_paths: [src/api/**]\` but you edit \`src/ui/component.ts\`.
918
-
919
- ### Right
920
-
921
- Only edit files within the specified \`code_paths\`. If you need to edit other files, that's a different WU.
922
-
923
- ---
924
-
925
- ## Mistake 4: Skipping TDD
926
-
927
- ### Wrong
928
-
929
- \`\`\`
930
- 1. Write the feature
931
- 2. Maybe write tests later
932
- 3. Tests are hard, skip them
933
- \`\`\`
934
-
935
- ### Right
936
-
937
- \`\`\`
938
- 1. Write failing test
939
- 2. Run test (confirm RED)
940
- 3. Write minimum code
941
- 4. Run test (confirm GREEN)
942
- 5. Refactor if needed
943
- \`\`\`
944
-
945
- ---
946
-
947
- ## Mistake 5: Using Forbidden Git Commands
948
-
949
- ### Wrong
950
-
951
- \`\`\`bash
952
- git reset --hard HEAD
953
- git push --force
954
- git commit --no-verify
955
- \`\`\`
956
-
957
- ### Right
958
-
959
- \`\`\`bash
960
- git add .
961
- git commit -m "feat: description"
962
- git push origin lane/core/wu-123
963
- \`\`\`
964
-
965
- ---
966
-
967
- ## Mistake 6: Ignoring Gate Failures
968
-
969
- ### Wrong
970
-
971
- \`\`\`
972
- Gates failed but I think the code is fine.
973
- Let me use --skip-gates.
974
- \`\`\`
975
-
976
- ### Right
977
-
978
- \`\`\`
979
- Gates failed. Let me read the error:
980
- - TypeScript error in src/api/handler.ts
981
- - Missing return type
982
-
983
- Fix: Add the return type.
984
- Re-run: pnpm gates
985
- \`\`\`
986
-
987
- ---
988
-
989
- ## Quick Checklist
990
-
991
- Before starting any WU:
992
-
993
- - [ ] Read the full WU spec
994
- - [ ] Understand acceptance criteria
995
- - [ ] Claim the WU with \`pnpm wu:claim\`
996
- - [ ] cd to the worktree IMMEDIATELY
997
- - [ ] Work only in the worktree
998
- - [ ] Stay within code_paths
999
- - [ ] Follow TDD
1000
- - [ ] Run gates before wu:done
1001
- - [ ] ALWAYS run wu:done
1002
- `;
1003
- const TROUBLESHOOTING_WU_DONE_TEMPLATE = `# Troubleshooting: wu:done Not Run
1004
-
1005
- **Last updated:** {{DATE}}
1006
-
1007
- This is the most common mistake agents make. This document explains why it happens and how to fix it.
1008
-
1009
- ---
1010
-
1011
- ## The Problem
1012
-
1013
- Agents complete their work, write "To Complete: pnpm wu:done --id WU-XXX" in their response, and then **stop without actually running the command**.
1014
-
1015
- ### Why This Happens
1016
-
1017
- 1. **Confusion about scope**: Agent thinks completion is a "next step" for the human
1018
- 2. **Fear of overstepping**: Agent hesitates to take "final" actions
1019
- 3. **Missing context**: Agent doesn't realize wu:done is expected to be run immediately
1020
- 4. **Token limits**: Agent runs out of context and summarizes remaining steps
1021
-
1022
- ---
1023
-
1024
- ## The Fix
1025
-
1026
- ### Rule: ALWAYS Run wu:done
1027
-
1028
- After gates pass, you MUST run:
1029
-
1030
- \`\`\`bash
1031
- cd /path/to/main
1032
- pnpm wu:done --id WU-XXX
1033
- \`\`\`
1034
-
1035
- Do NOT:
1036
-
1037
- - Ask "Should I run wu:done?"
1038
- - Write "To Complete: pnpm wu:done"
1039
- - Wait for permission
1040
- - Treat it as a "future step"
1041
-
1042
- ---
1043
-
1044
- ## Correct Completion Flow
1045
-
1046
- \`\`\`bash
1047
- # 1. In worktree, run gates
1048
- pnpm gates
1049
-
1050
- # 2. If gates pass, return to main
1051
- cd /path/to/main
1052
-
1053
- # 3. IMMEDIATELY run wu:done
1054
- pnpm wu:done --id WU-XXX
1055
-
1056
- # 4. Report success with the wu:done output
1057
- \`\`\`
1058
-
1059
- ---
1060
-
1061
- ## What wu:done Does
1062
-
1063
- When you run \`pnpm wu:done --id WU-XXX\`:
1064
-
1065
- 1. Validates the worktree exists and has commits
1066
- 2. Runs gates in the worktree (not main)
1067
- 3. Fast-forward merges to main
1068
- 4. Creates the done stamp
1069
- 5. Updates status and backlog docs
1070
- 6. Removes the worktree
1071
- 7. Pushes to origin
1072
-
1073
- **This is the ONLY way to complete a WU.** Manual steps will leave things in an inconsistent state.
1074
-
1075
- ---
1076
-
1077
- ## Symptoms of Incomplete WU
1078
-
1079
- If wu:done wasn't run, you'll see:
1080
-
1081
- - Worktree still exists: \`ls worktrees/\`
1082
- - No stamp: \`ls .lumenflow/stamps/WU-XXX.done\` returns nothing
1083
- - Status unchanged: WU still shows as \`in_progress\`
1084
- - Branch not merged: Changes only on lane branch
1085
-
1086
- ---
1087
-
1088
- ## Recovery
1089
-
1090
- If a previous agent forgot to run wu:done:
1091
-
1092
- \`\`\`bash
1093
- # 1. Check worktree exists
1094
- ls worktrees/
1095
-
1096
- # 2. If it does, run wu:done
1097
- pnpm wu:done --id WU-XXX
1098
- \`\`\`
1099
-
1100
- ---
1101
-
1102
- ## Checklist Before Ending Session
1103
-
1104
- - [ ] Did I run \`pnpm gates\` in the worktree?
1105
- - [ ] Did gates pass?
1106
- - [ ] Did I \`cd\` back to main?
1107
- - [ ] Did I run \`pnpm wu:done --id WU-XXX\`?
1108
- - [ ] Did wu:done complete successfully?
1109
-
1110
- If any answer is "no", you're not done yet.
1111
- `;
1112
- const AGENT_SAFETY_CARD_TEMPLATE = `# Agent Safety Card
1113
-
1114
- **Last updated:** {{DATE}}
1115
-
1116
- Quick reference for AI agents working in LumenFlow projects.
1117
-
1118
- ---
1119
-
1120
- ## Stop and Ask When
1121
-
1122
- - Same error repeats 3 times
1123
- - Auth or permissions changes needed
1124
- - PII/PHI/secrets involved
1125
- - Cloud spend decisions
1126
- - Policy changes required
1127
- - Anything feels irreversible
1128
-
1129
- ---
1130
-
1131
- ## Never Do
1132
-
1133
- | Action | Why |
1134
- | ------------------------ | ---------------- |
1135
- | \`git reset --hard\` | Data loss |
1136
- | \`git push --force\` | History rewrite |
1137
- | \`--no-verify\` | Bypasses safety |
1138
- | \`git stash\` (on main) | Hides work |
1139
- | \`git clean -fd\` | Deletes files |
1140
- | Work in main after claim | Breaks isolation |
1141
- | Skip wu:done | Incomplete WU |
1142
-
1143
- ---
1144
-
1145
- ## Always Do
1146
-
1147
- | Action | Why |
1148
- | -------------------------- | ---------------- |
1149
- | Read WU spec first | Understand scope |
1150
- | cd to worktree after claim | Isolation |
1151
- | Write tests before code | TDD |
1152
- | Run gates before wu:done | Quality |
1153
- | Run wu:done | Complete WU |
1154
- | Stay within code_paths | Scope discipline |
1155
-
1156
- ---
1157
-
1158
- ## Error Handling
1159
-
1160
- ### Max 3 Attempts
1161
-
1162
- If same error happens 3 times:
1163
-
1164
- 1. Stop trying
1165
- 2. Document what happened
1166
- 3. Ask for help
1167
-
1168
- ### Gate Failures
1169
-
1170
- 1. Read the error message
1171
- 2. Fix the underlying issue
1172
- 3. Re-run gates
1173
- 4. Never use \`--skip-gates\` for new failures
1174
-
1175
- ---
1176
-
1177
- ## Quick Commands
1178
-
1179
- \`\`\`bash
1180
- # Check lane availability
1181
- cat {{DOCS_TASKS_PATH}}/status.md
1182
-
1183
- # Claim a WU
1184
- pnpm wu:claim --id WU-XXX --lane <Lane>
1185
-
1186
- # Work in worktree
1187
- cd worktrees/<lane>-wu-xxx
1188
-
1189
- # Run gates
1190
- pnpm gates # Code changes
1191
- pnpm gates --docs-only # Docs changes
1192
-
1193
- # Complete WU
1194
- cd /path/to/main
1195
- pnpm wu:done --id WU-XXX
1196
- \`\`\`
1197
-
1198
- ---
1199
-
1200
- ## Completion Checklist
1201
-
1202
- - [ ] Gates pass
1203
- - [ ] cd to main
1204
- - [ ] Run wu:done
1205
- - [ ] Verify success output
1206
- - [ ] Report completion
1207
-
1208
- ---
1209
-
1210
- ## When Uncertain
1211
-
1212
- Choose the safer path:
1213
-
1214
- - Don't modify files outside code_paths
1215
- - Don't bypass hooks
1216
- - Don't skip gates
1217
- - Ask rather than assume
1218
- `;
1219
- // WU-1307: Lane inference configuration template (hierarchical Parent→Sublane format)
1220
- // WU-1364: Added Core and Feature as parent lanes for intuitive naming
1221
- // WU-1382: Added managed file header to prevent manual edits
1222
- // This format is required by lane-inference.ts and lane-checker.ts
1223
- const LANE_INFERENCE_TEMPLATE = `# ============================================================================
1224
- # LUMENFLOW MANAGED FILE - DO NOT EDIT MANUALLY
1225
- # ============================================================================
1226
- # Generated by: lumenflow init
1227
- # Regenerate with: pnpm exec lumenflow init --force
1228
- #
1229
- # This file is managed by LumenFlow tooling. Manual edits may be overwritten.
1230
- # To customize lanes, use: pnpm lane:suggest --output .lumenflow.lane-inference.yaml
1231
- # ============================================================================
1232
-
1233
- # Lane Inference Configuration
1234
- #
1235
- # Hierarchical format: Parent -> Sublane -> { code_paths, keywords }
1236
- # This format is required by lane-inference.ts for proper sub-lane suggestion.
1237
- #
1238
- # Common parent lanes: Core, Feature, Framework, Experience, Operations, Content
1239
-
1240
- # Core Lane: Platform foundations, shared libraries, base infrastructure
1241
- Core:
1242
- Platform:
1243
- description: 'Core platform: shared utilities, base infrastructure, common libraries'
1244
- code_paths:
1245
- - 'packages/**/core/**'
1246
- - 'src/core/**'
1247
- - 'src/lib/**'
1248
- - 'lib/**'
1249
- keywords:
1250
- - 'platform'
1251
- - 'core'
1252
- - 'infrastructure'
1253
- - 'foundation'
1254
-
1255
- Library:
1256
- description: 'Shared libraries and utilities'
1257
- code_paths:
1258
- - 'packages/**/lib/**'
1259
- - 'src/utils/**'
1260
- - 'src/helpers/**'
1261
- keywords:
1262
- - 'library'
1263
- - 'utility'
1264
- - 'helper'
1265
- - 'shared'
1266
-
1267
- # Feature Lane: Product features and user-facing functionality
1268
- Feature:
1269
- Backend:
1270
- description: 'Backend features: APIs, services, business logic'
1271
- code_paths:
1272
- - 'src/api/**'
1273
- - 'src/services/**'
1274
- - 'packages/**/api/**'
1275
- keywords:
1276
- - 'api'
1277
- - 'service'
1278
- - 'backend'
1279
- - 'business logic'
1280
-
1281
- Frontend:
1282
- description: 'Frontend features: UI, components, pages'
1283
- code_paths:
1284
- - 'src/components/**'
1285
- - 'src/pages/**'
1286
- - 'src/app/**'
1287
- - 'apps/web/**'
1288
- keywords:
1289
- - 'frontend'
1290
- - 'ui'
1291
- - 'component'
1292
- - 'page'
1293
-
1294
- # Framework Lane: Framework-specific code and tooling
1295
- Framework:
1296
- Core:
1297
- description: 'Core framework: business logic, domain models, utilities'
1298
- code_paths:
1299
- - 'packages/**/core/**'
1300
- - 'src/core/**'
1301
- - 'lib/**'
1302
- keywords:
1303
- - 'core library'
1304
- - 'business logic'
1305
- - 'domain'
1306
- - 'utility'
1307
-
1308
- CLI:
1309
- description: 'CLI commands and tooling'
1310
- code_paths:
1311
- - 'packages/**/cli/**'
1312
- - 'src/cli/**'
1313
- - 'bin/**'
1314
- keywords:
1315
- - 'cli command'
1316
- - 'command line'
1317
- - 'tooling'
1318
-
1319
- # Experience Lane: User-facing frontend work
1320
- Experience:
1321
- UI:
1322
- description: 'User interface components and pages'
1323
- code_paths:
1324
- - 'apps/web/**'
1325
- - 'src/components/**'
1326
- - 'src/pages/**'
1327
- - 'src/app/**'
1328
- keywords:
1329
- - 'ui'
1330
- - 'component'
1331
- - 'page'
1332
- - 'frontend'
1333
- - 'user interface'
1334
-
1335
- Web:
1336
- description: 'Web application features'
1337
- code_paths:
1338
- - 'apps/web/**'
1339
- - 'web/**'
1340
- keywords:
1341
- - 'web'
1342
- - 'browser'
1343
- - 'frontend'
1344
-
1345
- # Operations Lane: Infrastructure and CI/CD
1346
- Operations:
1347
- Infrastructure:
1348
- description: 'Apps, deployment, hosting configuration'
1349
- code_paths:
1350
- - 'apps/**'
1351
- - 'infrastructure/**'
1352
- - 'deploy/**'
1353
- - 'turbo.json'
1354
- - 'pnpm-workspace.yaml'
1355
- keywords:
1356
- - 'infrastructure'
1357
- - 'deployment'
1358
- - 'hosting'
1359
- - 'monorepo'
1360
-
1361
- CI/CD:
1362
- description: 'GitHub Actions, workflows, build pipelines'
1363
- code_paths:
1364
- - '.github/workflows/**'
1365
- - '.github/actions/**'
1366
- - '.github/**'
1367
- - '.circleci/**'
1368
- keywords:
1369
- - 'ci'
1370
- - 'cd'
1371
- - 'github actions'
1372
- - 'workflow'
1373
- - 'pipeline'
1374
-
1375
- # Content Lane: Documentation
1376
- Content:
1377
- Documentation:
1378
- description: 'All documentation: guides, references, specs'
1379
- code_paths:
1380
- - 'docs/**'
1381
- - '*.md'
1382
- - 'README.md'
1383
- keywords:
1384
- - 'documentation'
1385
- - 'docs'
1386
- - 'guide'
1387
- - 'readme'
1388
- - 'markdown'
1389
- {{FRAMEWORK_LANES}}
1390
- `;
1391
- // WU-1300: Starting prompt template for agent onboarding
1392
- // WU-1364: Added "When Starting From Product Vision" section for initiative-first workflow
1393
- const STARTING_PROMPT_TEMPLATE = `# Starting Prompt for LumenFlow Agents
1394
-
1395
- **Last updated:** {{DATE}}
1396
-
1397
- This document provides the initial context for AI agents working on this project.
1398
-
1399
- ---
1400
-
1401
- ## When Starting From Product Vision
1402
-
1403
- If you are starting a new project or feature from a product vision (e.g., "Build a task management app"), **do NOT create standalone WUs immediately**. Instead, follow the initiative-first workflow:
1404
-
1405
- ### 4-Step Initiative Workflow
1406
-
1407
- 1. **Create an Initiative**: Capture the vision as an initiative
1408
- \`\`\`bash
1409
- pnpm initiative:create --id INIT-001 --title "Task Management App" \\
1410
- --description "Build a task management application with..." \\
1411
- --phase "Phase 1: Core MVP" --phase "Phase 2: Collaboration"
1412
- \`\`\`
1413
-
1414
- 2. **Define Phases**: Break the vision into logical phases (MVP, iteration, polish)
1415
-
1416
- 3. **Create WUs under the Initiative**: Each WU belongs to a phase
1417
- \`\`\`bash
1418
- pnpm wu:create --lane "Core: Platform" --title "Add task model" \\
1419
- --description "..." --acceptance "..." --code-paths "..." \\
1420
- && pnpm initiative:add-wu --initiative INIT-001 --wu WU-XXX --phase 1
1421
- \`\`\`
1422
-
1423
- 4. **Track Progress**: Use \`pnpm initiative:status --id INIT-001\` to see overall progress
1424
-
1425
- ### Why Initiatives Matter
1426
-
1427
- - **Avoid orphan WUs**: Without initiative structure, agents create disconnected WUs that lack coherent scope
1428
- - **Better coordination**: Phases enable parallel work across lanes
1429
- - **Clear completion criteria**: The initiative tracks when all phases are done
1430
- - **Visibility**: Stakeholders can see multi-phase progress
1431
-
1432
- ### When to Skip Initiatives
1433
-
1434
- Only skip initiatives for:
1435
- - Single-file bug fixes
1436
- - Small documentation updates
1437
- - Isolated refactoring tasks
1438
-
1439
- If work spans multiple WUs or multiple days, create an initiative first.
1440
-
1441
- ---
1442
-
1443
- ## Step 1: Read Core Documentation
1444
-
1445
- Before starting any work, read these documents in order:
1446
-
1447
- 1. **[LUMENFLOW.md](../../../../../../LUMENFLOW.md)** - Main workflow documentation
1448
- 2. **[constraints.md](../../../../../../.lumenflow/constraints.md)** - Non-negotiable rules
1449
- 3. **This file** - Onboarding context
1450
-
1451
- ---
1452
-
1453
- ## Step 2: Understand the Workflow
1454
-
1455
- LumenFlow uses Work Units (WUs) to track all changes:
1456
-
1457
- 1. **Claim a WU**: \`pnpm wu:claim --id WU-XXX --lane <Lane>\`
1458
- 2. **Work in worktree**: \`cd worktrees/<lane>-wu-xxx\`
1459
- 3. **Run gates**: \`pnpm gates\`
1460
- 4. **Complete WU**: \`pnpm wu:done --id WU-XXX\` (from main checkout)
1461
-
1462
- ---
1463
-
1464
- ## Step 3: Key Constraints
1465
-
1466
- 1. **Worktree Discipline**: Never work in main after claiming a WU
1467
- 2. **TDD**: Write tests first, then implementation
1468
- 3. **Gates**: Must pass before \`wu:done\`
1469
- 4. **Always wu:done**: Never skip the completion step
1470
-
1471
- ---
1472
-
1473
- ## Step 4: Common Commands
1474
-
1475
- | Command | Description |
1476
- | ------- | ----------- |
1477
- | \`pnpm wu:claim --id WU-XXX --lane <Lane>\` | Claim a WU |
1478
- | \`pnpm gates\` | Run quality gates |
1479
- | \`pnpm wu:done --id WU-XXX\` | Complete WU |
1480
- | \`pnpm wu:status --id WU-XXX\` | Check WU status |
1481
- | \`pnpm initiative:create ...\` | Create a new initiative |
1482
- | \`pnpm initiative:status --id INIT-XXX\` | Check initiative progress |
1483
-
1484
- ---
1485
-
1486
- ## Step 5: When Stuck
1487
-
1488
- 1. Read the WU spec at \`{{DOCS_TASKS_PATH}}/wu/WU-XXX.yaml\`
1489
- 2. Check [troubleshooting-wu-done.md](troubleshooting-wu-done.md)
1490
- 3. Review [first-wu-mistakes.md](first-wu-mistakes.md)
1491
-
1492
- ---
1493
-
1494
- ## Additional Resources
1495
-
1496
- - [quick-ref-commands.md](quick-ref-commands.md) - Complete command reference
1497
- - [agent-safety-card.md](agent-safety-card.md) - Safety guidelines
1498
- - [wu-create-checklist.md](wu-create-checklist.md) - WU creation guide
1499
- - [wu-sizing-guide.md](wu-sizing-guide.md) - WU complexity and context management
1500
- `;
1501
- const WU_CREATE_CHECKLIST_TEMPLATE = `# WU Creation Checklist
1502
-
1503
- **Last updated:** {{DATE}}
1504
-
1505
- Before running \`pnpm wu:create\`, verify these items.
1506
-
1507
- ---
1508
-
1509
- ## Step 1: Check Valid Lanes
1510
-
1511
- \`\`\`bash
1512
- grep -A 30 "lanes:" .lumenflow.config.yaml
1513
- \`\`\`
1514
-
1515
- **Format:** \`"Parent: Sublane"\` (colon + single space)
1516
-
1517
- Examples:
1518
- - \`"Framework: CLI"\`
1519
- - \`"Framework: Core"\`
1520
- - \`"Operations: CI/CD"\`
1521
- - \`"Content: Documentation"\`
1522
-
1523
- ---
1524
-
1525
- ## Step 2: Required Fields
1526
-
1527
- | Field | Required For | Example |
1528
- |-------|--------------|---------|
1529
- | \`--id\` | All | \`WU-1234\` |
1530
- | \`--lane\` | All | \`"Experience: Chat"\` |
1531
- | \`--title\` | All | \`"Add feature"\` |
1532
- | \`--description\` | All | \`"Context: ... Problem: ... Solution: ..."\` |
1533
- | \`--acceptance\` | All | \`--acceptance "Works"\` (repeatable) |
1534
- | \`--exposure\` | All | \`ui\`, \`api\`, \`backend-only\`, \`documentation\` |
1535
- | \`--code-paths\` | Code WUs | \`"src/a.ts,src/b.ts"\` |
1536
- | \`--test-paths-unit\` | Code WUs | \`"src/__tests__/a.test.ts"\` |
1537
- | \`--spec-refs\` | Feature WUs | \`"~/.lumenflow/plans/WU-XXX.md"\` |
1538
-
1539
- ---
1540
-
1541
- ## Step 3: Plan Storage
1542
-
1543
- Plans go in \`~/.lumenflow/plans/\` (NOT in project):
1544
-
1545
- \`\`\`bash
1546
- mkdir -p ~/.lumenflow/plans
1547
- # Create your plan
1548
- vim ~/.lumenflow/plans/WU-XXX-plan.md
1549
- \`\`\`
1550
-
1551
- Reference in wu:create:
1552
- \`\`\`bash
1553
- --spec-refs "~/.lumenflow/plans/WU-XXX-plan.md"
1554
- \`\`\`
1555
-
1556
- ---
1557
-
1558
- ## Step 4: Validate First
1559
-
1560
- \`\`\`bash
1561
- pnpm wu:create --id WU-XXX ... --validate
1562
- \`\`\`
1563
-
1564
- Fix errors, then remove \`--validate\` to create.
1565
-
1566
- ---
1567
-
1568
- ## Complete Example
1569
-
1570
- \`\`\`bash
1571
- pnpm wu:create \\
1572
- --id WU-1234 \\
1573
- --lane "Framework: CLI" \\
1574
- --title "Add feature X" \\
1575
- --description "Context: Users need X. Problem: X doesn't exist. Solution: Add X." \\
1576
- --acceptance "Feature X works as specified" \\
1577
- --acceptance "Unit tests pass with >90% coverage" \\
1578
- --code-paths "packages/@lumenflow/cli/src/x.ts" \\
1579
- --test-paths-unit "packages/@lumenflow/cli/__tests__/x.test.ts" \\
1580
- --exposure backend-only \\
1581
- --spec-refs "~/.lumenflow/plans/WU-1234-plan.md"
1582
- \`\`\`
1583
-
1584
- ---
1585
-
1586
- ## Common Errors
1587
-
1588
- ### "Lane format invalid"
1589
-
1590
- **Cause:** Missing colon or space in lane format.
1591
-
1592
- **Fix:** Use \`"Parent: Sublane"\` format (colon + space).
1593
-
1594
- ### "Missing required field"
1595
-
1596
- **Cause:** Required field not provided.
1597
-
1598
- **Fix:** Add the missing \`--field\` argument.
1599
-
1600
- ### "WU already exists"
1601
-
1602
- **Cause:** WU with this ID already exists.
1603
-
1604
- **Fix:** Use a different ID or check existing WUs.
1605
-
1606
- ---
1607
-
1608
- ## After Creation
1609
-
1610
- 1. Review the created YAML: \`cat {{DOCS_TASKS_PATH}}/wu/WU-XXX.yaml\`
1611
- 2. Claim the WU: \`pnpm wu:claim --id WU-XXX --lane "Lane"\`
1612
- 3. cd to worktree: \`cd worktrees/<lane>-wu-xxx\`
1613
- `;
1614
- // WU-1309: First 15 Minutes template
1615
- const FIRST_15_MINS_TEMPLATE = `# First 15 Minutes with LumenFlow
1616
-
1617
- **Last updated:** {{DATE}}
1618
-
1619
- A quick-start guide for your first session with LumenFlow.
1620
-
1621
- ---
1622
-
1623
- ## Minute 0-2: Verify Setup
1624
-
1625
- \`\`\`bash
1626
- # Check LumenFlow is configured
1627
- ls LUMENFLOW.md AGENTS.md .lumenflow.config.yaml
1628
-
1629
- # Run doctor to verify safety components
1630
- pnpm exec lumenflow doctor
1631
- \`\`\`
1632
-
1633
- ---
1634
-
1635
- ## Minute 2-5: Read Essential Docs
1636
-
1637
- 1. Open **LUMENFLOW.md** - Main workflow guide
1638
- 2. Scan **AGENTS.md** - Quick reference for commands
1639
- 3. Review **.lumenflow/constraints.md** - The 6 rules you must follow
1640
-
1641
- ---
1642
-
1643
- ## Minute 5-8: Find a WU to Work On
1644
-
1645
- \`\`\`bash
1646
- # Check status board
1647
- cat {{DOCS_TASKS_PATH}}/status.md
1648
-
1649
- # List ready WUs
1650
- ls {{DOCS_TASKS_PATH}}/wu/*.yaml | head -5
1651
- \`\`\`
1652
-
1653
- ---
1654
-
1655
- ## Minute 8-12: Claim and Start
1656
-
1657
- \`\`\`bash
1658
- # Claim a WU
1659
- pnpm wu:claim --id WU-XXX --lane "Framework: Core"
1660
-
1661
- # IMPORTANT: cd to worktree immediately
1662
- cd worktrees/framework-core-wu-xxx
1663
-
1664
- # Verify you're in the right place
1665
- pwd # Should end with worktrees/...
1666
- \`\`\`
1667
-
1668
- ---
1669
-
1670
- ## Minute 12-15: Begin TDD Cycle
1671
-
1672
- \`\`\`bash
1673
- # 1. Write a failing test
1674
- # 2. Run it to confirm RED
1675
- pnpm test -- --run
1676
-
1677
- # 3. Write minimal code to pass
1678
- # 4. Run test again for GREEN
1679
- pnpm test -- --run
1680
-
1681
- # 5. Run gates to check everything
1682
- pnpm gates
1683
- \`\`\`
1684
-
1685
- ---
1686
-
1687
- ## Key Reminders
1688
-
1689
- - **Stay in the worktree** after claiming
1690
- - **TDD**: Test first, then code
1691
- - **Gates before done**: Always run \`pnpm gates\`
1692
- - **Always wu:done**: Never forget to complete
1693
-
1694
- ---
1695
-
1696
- ## When Done
1697
-
1698
- \`\`\`bash
1699
- # From worktree: run gates
1700
- pnpm gates
1701
-
1702
- # From main: complete WU
1703
- cd <project-root>
1704
- pnpm wu:done --id WU-XXX
1705
- \`\`\`
1706
- `;
1707
- // WU-1309: Local-only / no remote template
1708
- const LOCAL_ONLY_TEMPLATE = `# Local-Only Development
1709
-
1710
- **Last updated:** {{DATE}}
1711
-
1712
- Configure LumenFlow for local development without a remote repository.
1713
-
1714
- ---
1715
-
1716
- ## When to Use
1717
-
1718
- - Air-gapped environments
1719
- - Testing/evaluation
1720
- - Pre-remote development (haven't pushed to GitHub yet)
1721
- - Offline development
1722
-
1723
- ---
1724
-
1725
- ## Configuration
1726
-
1727
- Add this to \`.lumenflow.config.yaml\`:
1728
-
1729
- \`\`\`yaml
1730
- git:
1731
- requireRemote: false
1732
- \`\`\`
1733
-
1734
- ---
1735
-
1736
- ## Behavior Changes
1737
-
1738
- When \`requireRemote: false\`:
1739
-
1740
- | Command | Default Behavior | Local-Only Behavior |
1741
- |---------|------------------|---------------------|
1742
- | \`wu:create\` | Fetches origin/main | Skips remote fetch |
1743
- | \`wu:claim\` | Pushes lane branch | Creates local branch only |
1744
- | \`wu:done\` | Pushes to origin | Commits to local main |
1745
-
1746
- ---
1747
-
1748
- ## Warnings
1749
-
1750
- With local-only mode:
1751
-
1752
- 1. **No remote visibility** - Team members can't see your WUs
1753
- 2. **No backup** - Work is only on your machine
1754
- 3. **Manual sync required** - When adding a remote later
1755
-
1756
- ---
1757
-
1758
- ## Transitioning to Remote
1759
-
1760
- When you add an origin remote:
1761
-
1762
- 1. Update config: \`git.requireRemote: true\` or remove the setting
1763
- 2. Push your main branch: \`git push -u origin main\`
1764
- 3. Resume normal workflow
1765
-
1766
- ---
1767
-
1768
- ## Troubleshooting
1769
-
1770
- ### "No origin remote configured"
1771
-
1772
- **Cause:** \`requireRemote: true\` (default) but no origin exists.
1773
-
1774
- **Fix:** Add remote or set \`requireRemote: false\`:
1775
-
1776
- \`\`\`bash
1777
- # Option 1: Add remote
1778
- git remote add origin <url>
1779
-
1780
- # Option 2: Enable local-only mode
1781
- echo "git:\\n requireRemote: false" >> .lumenflow.config.yaml
1782
- \`\`\`
1783
- `;
1784
- // WU-1309: Lane Inference template
1785
- const LANE_INFERENCE_DOC_TEMPLATE = `# Lane Inference
1786
-
1787
- **Last updated:** {{DATE}}
1788
-
1789
- How LumenFlow determines which lane a WU belongs to.
1790
-
1791
- ---
1792
-
1793
- ## Lane Format
1794
-
1795
- LumenFlow uses hierarchical lanes: \`"Parent: Sublane"\`
1796
-
1797
- Examples:
1798
- - \`"Framework: Core"\`
1799
- - \`"Framework: CLI"\`
1800
- - \`"Experience: UI"\`
1801
- - \`"Operations: CI/CD"\`
1802
- - \`"Content: Documentation"\`
1803
-
1804
- ---
1805
-
1806
- ## Lane Taxonomy File
1807
-
1808
- Lanes are defined in \`.lumenflow.lane-inference.yaml\`:
1809
-
1810
- \`\`\`yaml
1811
- Framework:
1812
- Core:
1813
- description: 'Core library'
1814
- code_paths:
1815
- - 'packages/**/core/**'
1816
- keywords:
1817
- - 'core'
1818
- - 'library'
1819
-
1820
- CLI:
1821
- description: 'CLI commands'
1822
- code_paths:
1823
- - 'packages/**/cli/**'
1824
- - 'bin/**'
1825
- keywords:
1826
- - 'cli'
1827
- - 'command'
1828
- \`\`\`
1829
-
1830
- ---
1831
-
1832
- ## Auto-Inference
1833
-
1834
- Use \`wu:infer-lane\` to suggest a lane based on code paths:
1835
-
1836
- \`\`\`bash
1837
- # Infer from WU code_paths
1838
- pnpm wu:infer-lane --id WU-XXX
1839
-
1840
- # Infer from manual inputs
1841
- pnpm wu:infer-lane --paths "packages/@lumenflow/cli/**" --desc "Add CLI command"
1842
- \`\`\`
1843
-
1844
- ---
1845
-
1846
- ## Generating Lane Taxonomy
1847
-
1848
- If no taxonomy exists, generate one:
1849
-
1850
- \`\`\`bash
1851
- pnpm lane:suggest --output .lumenflow.lane-inference.yaml
1852
- \`\`\`
1853
-
1854
- ---
1855
-
1856
- ## Common Issues
1857
-
1858
- ### "Lane format invalid"
1859
-
1860
- **Cause:** Missing colon or space.
1861
-
1862
- **Fix:** Use \`"Parent: Sublane"\` format (colon + space).
1863
-
1864
- ### "Sub-lane validation failed"
1865
-
1866
- **Cause:** No \`.lumenflow.lane-inference.yaml\` file.
1867
-
1868
- **Fix:** Create the file or generate it:
1869
-
1870
- \`\`\`bash
1871
- pnpm lane:suggest --output .lumenflow.lane-inference.yaml
1872
- \`\`\`
1873
-
1874
- ---
1875
-
1876
- ## Lane Health
1877
-
1878
- Check lane configuration for issues:
1879
-
1880
- \`\`\`bash
1881
- pnpm lane:health
1882
- \`\`\`
1883
-
1884
- This detects:
1885
- - Overlapping code paths between lanes
1886
- - Code files not covered by any lane
1887
- `;
1888
- // WU-1385: WU sizing guide template for agent onboarding
1889
- const WU_SIZING_GUIDE_TEMPLATE = `# Work Unit Sizing & Strategy Guide
1890
-
1891
- **Last updated:** {{DATE}}
1892
-
1893
- **Purpose:** Decision framework for agents to determine execution strategy based on task complexity.
1894
-
1895
- **Status:** Active — Thresholds are **mandatory limits**, not guidelines.
1896
-
1897
- ---
1898
-
1899
- ## Complexity Assessment Matrix
1900
-
1901
- Before claiming a WU, estimate its "weight" using these heuristics.
1902
-
1903
- | Complexity | Files | Tool Calls | Context Budget | Strategy |
1904
- | :------------ | :---- | :--------- | :------------- | :------------------------------------------- |
1905
- | **Simple** | <20 | <50 | <30% | **Single Session** (Tier 2 Context) |
1906
- | **Medium** | 20-50 | 50-100 | 30-50% | **Checkpoint-Resume** (Standard Handoff) |
1907
- | **Complex** | 50+ | 100+ | >50% | **Orchestrator-Worker** OR **Decomposition** |
1908
- | **Oversized** | 100+ | 200+ | — | **MUST Split** (See Patterns below) |
1909
-
1910
- **These thresholds are mandatory.** Exceeding them leads to context exhaustion and rule loss. Agents operate in context windows and tool calls, not clock time.
1911
-
1912
- ---
1913
-
1914
- ## Context Safety Triggers
1915
-
1916
- If you hit ANY of these triggers during a session, you MUST checkpoint and spawn fresh:
1917
-
1918
- - **Token Limit:** Context usage hits **50% (Warning)** or **80% (Critical)**.
1919
- - **Tool Volume:** **50+ tool calls** in current session.
1920
- - **File Volume:** **20+ files** modified in \`git status\`.
1921
- - **Session Staleness:** Repeated redundant queries or forgotten context.
1922
-
1923
- ---
1924
-
1925
- ## Spawn Fresh, Don't Continue
1926
-
1927
- **When approaching context limits, spawn a fresh agent instead of continuing after compaction.**
1928
-
1929
- Context compaction causes agents to lose critical rules. The disciplined approach:
1930
-
1931
- 1. Checkpoint your progress: \`pnpm mem:checkpoint --wu WU-XXX\`
1932
- 2. Commit and push work
1933
- 3. Generate fresh agent prompt: \`pnpm wu:brief --id WU-XXX --client claude-code\`
1934
- 4. EXIT current session (do NOT continue after compaction)
1935
-
1936
- ---
1937
-
1938
- ## Splitting Patterns
1939
-
1940
- When a WU is Oversized or Complex, split it using approved patterns:
1941
-
1942
- - **Tracer Bullet**: WU-1 proves skeleton works, WU-2 implements real logic
1943
- - **Layer Split**: WU-1 for ports/application, WU-2 for infrastructure
1944
- - **UI/Logic Split**: WU-1 for backend, WU-2 for frontend
1945
- - **Feature Flag**: WU-1 behind flag, WU-2 removes flag
1946
-
1947
- ---
1948
-
1949
- ## Quick Reference
1950
-
1951
- | Scenario | Strategy | Action |
1952
- | :---------------------------------- | :------------------ | :------------------------------------------- |
1953
- | Bug fix, single file, <20 calls | Simple | Claim, fix, commit, \`wu:done\` |
1954
- | Feature 50-100 calls, clear phases | Checkpoint-Resume | Phase 1 → checkpoint → Phase 2 → done |
1955
- | Multi-domain, must land atomically | Orchestrator-Worker | Main agent coordinates, spawns sub-agents |
1956
- | Large refactor 100+ calls | Feature Flag Split | WU-A: New behind flag → WU-B: Remove flag |
1957
-
1958
- ---
1959
-
1960
- ## Documentation-Only Exception
1961
-
1962
- Documentation WUs (\`type: documentation\`) have relaxed file count thresholds:
1963
-
1964
- | Complexity | Files (docs) | Tool Calls | Strategy |
1965
- | :--------- | :----------- | :--------- | :---------------- |
1966
- | **Simple** | <40 | <50 | Single Session |
1967
- | **Medium** | 40-80 | 50-100 | Checkpoint-Resume |
1968
-
1969
- **Applies when ALL true:**
1970
- - WU \`type: documentation\`
1971
- - Only modifies: \`docs/**\`, \`*.md\`
1972
- - Does NOT touch code paths
1973
-
1974
- ---
1975
-
1976
- For complete sizing guidance, see the canonical [wu-sizing-guide.md](https://lumenflow.dev/reference/wu-sizing-guide/) documentation.
1977
- `;
1978
- // WU-1083: Claude skills templates
1979
- const WU_LIFECYCLE_SKILL_TEMPLATE = `---
1980
- name: wu-lifecycle
1981
- description: Work Unit claim/block/done workflow automation.
1982
- version: 1.0.0
1983
- ---
1984
-
1985
- # WU Lifecycle Skill
1986
-
1987
- ## When to Use
1988
-
1989
- Activate this skill when:
1990
-
1991
- - Claiming a WU (\`pnpm wu:claim\`)
1992
- - Blocking/unblocking WUs due to dependencies
1993
- - Running \`wu:done\` completion workflow
1994
- - Understanding WU state machine transitions
1995
-
1996
- ## State Machine
1997
-
1998
- \`\`\`
1999
- ready -> in_progress -> waiting/blocked -> done
2000
- \`\`\`
2001
-
2002
- ## Core Commands
2003
-
2004
- \`\`\`bash
2005
- # Claim WU
2006
- pnpm wu:claim --id WU-XXX --lane <lane>
2007
- cd worktrees/<lane>-wu-xxx # IMMEDIATELY
2008
-
2009
- # Complete WU (from main)
2010
- cd ../..
2011
- pnpm wu:done --id WU-XXX
2012
-
2013
- # Block/Unblock
2014
- pnpm wu:block --id WU-XXX --reason "..."
2015
- pnpm wu:unblock --id WU-XXX
2016
-
2017
- # Create (full spec)
2018
- pnpm wu:create --id WU-999 --lane "Operations" --title "Add feature" \\
2019
- --description "Context: ... Problem: ... Solution: ..." \\
2020
- --acceptance "Feature works" --code-paths "src/a.ts" --validate
2021
- \`\`\`
2022
-
2023
- ## wu:done Workflow
2024
-
2025
- 1. Runs gates in worktree
2026
- 2. Fast-forward merge to main
2027
- 3. Creates \`.lumenflow/stamps/WU-XXX.done\`
2028
- 4. Updates backlog.md + status.md
2029
- 5. Removes worktree
2030
-
2031
- ## Worktree Discipline
2032
-
2033
- After \`wu:claim\`:
2034
-
2035
- - \`cd worktrees/<lane>-wu-xxx\` immediately
2036
- - Use relative paths (never absolute)
2037
- - Main is read-only
2038
- `;
2039
- const WORKTREE_DISCIPLINE_SKILL_TEMPLATE = `---
2040
- name: worktree-discipline
2041
- description: Prevents the "absolute path trap" in Write/Edit/Read tools.
2042
- version: 1.0.0
2043
- ---
2044
-
2045
- # Worktree Discipline: Absolute Path Trap Prevention
2046
-
2047
- **Purpose**: Prevent AI agents from bypassing worktree isolation via absolute file paths.
2048
-
2049
- ## The Absolute Path Trap
2050
-
2051
- **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.
2052
-
2053
- ### Example
2054
-
2055
- \`\`\`typescript
2056
- // Shell: cd worktrees/operations-wu-427
2057
-
2058
- // WRONG - Absolute path bypasses worktree
2059
- Write({
2060
- file_path: '/<user-home>/source/project/apps/web/src/validator.ts',
2061
- content: '...',
2062
- });
2063
- // Result: Written to MAIN checkout, not worktree!
2064
-
2065
- // RIGHT - Relative path respects worktree
2066
- Write({
2067
- file_path: 'apps/web/src/validator.ts',
2068
- content: '...',
2069
- });
2070
- // Result: Written to worktree correctly
2071
- \`\`\`
2072
-
2073
- ## Pre-Operation Checklist
2074
-
2075
- **Before ANY Write/Edit/Read operation:**
2076
-
2077
- 1. **Verify working directory**:
2078
-
2079
- \`\`\`bash
2080
- pwd
2081
- # Must show: .../worktrees/<lane>-wu-xxx
2082
- \`\`\`
2083
-
2084
- 2. **Check file path format**:
2085
-
2086
- | Pattern | Safe? | Example |
2087
- | --------------------------------- | ----- | --------------------------- |
2088
- | Starts with \`/<user-home>/\` | NO | \`/<user-home>/.../file.ts\` |
2089
- | Contains full repo path | NO | \`/source/project/...\` |
2090
- | Starts with package name | YES | \`apps/web/src/...\` |
2091
- | Starts with \`./\` or \`../\` | YES | \`./src/lib/...\` |
2092
- | Just filename | YES | \`README.md\` |
2093
-
2094
- 3. **Use relative paths for ALL file operations**
2095
-
2096
- ## Golden Rules
2097
-
2098
- 1. **Always verify pwd** before file operations
2099
- 2. **Never use absolute paths** in Write/Edit/Read tools
2100
- 3. **When in doubt, use relative paths**
2101
- `;
2102
- const LUMENFLOW_GATES_SKILL_TEMPLATE = `---
2103
- name: lumenflow-gates
2104
- description: Quality gates troubleshooting (format, lint, typecheck, tests).
2105
- version: 1.0.0
2106
- ---
2107
-
2108
- # LumenFlow Gates Skill
2109
-
2110
- ## When to Use
2111
-
2112
- Activate this skill when:
2113
-
2114
- - \`pnpm gates\` fails with format, lint, or typecheck errors
2115
- - Need to determine if failure is from your changes vs pre-existing
2116
- - Debugging test failures or coverage issues
2117
- - Deciding whether to use \`--skip-gates\` (emergency only)
2118
-
2119
- ## Gate Sequence
2120
-
2121
- \`\`\`
2122
- pnpm gates = format:check -> lint -> typecheck -> spec:linter -> tests
2123
- \`\`\`
2124
-
2125
- ## Fix Patterns
2126
-
2127
- | Gate | Auto-fix | Manual |
2128
- | --------- | --------------- | ----------------------------------- |
2129
- | Format | \`pnpm format\` | - |
2130
- | Lint | \`pnpm lint:fix\` | Fix reported issues |
2131
- | Typecheck | - | Fix type errors (first error first) |
2132
- | Tests | - | Debug, fix mocks, update snapshots |
2133
-
2134
- ## Decision Tree
2135
-
2136
- **Gate failed. Is it from YOUR changes?**
2137
-
2138
- \`\`\`bash
2139
- git checkout main && pnpm gates # Check main
2140
- # Pass on main -> Your change caused it -> Fix it
2141
- # Fail on main -> Pre-existing -> Consider --skip-gates
2142
- \`\`\`
2143
-
2144
- **Can you fix it?**
2145
-
2146
- - In your \`code_paths\`, <=10 lines -> Fix in place
2147
- - Different paths, >10 lines -> Create Bug WU
2148
-
2149
- ## Skip Gates (Emergency)
2150
-
2151
- Only when pre-existing failures:
2152
-
2153
- \`\`\`bash
2154
- pnpm wu:done --id WU-XXX --skip-gates --reason "Pre-existing" --fix-wu WU-YYY
2155
- \`\`\`
2156
-
2157
- ## Common Lint Fixes
2158
-
2159
- \`\`\`
2160
- no-explicit-any -> Add proper types
2161
- no-unused-vars -> Remove or prefix with _
2162
- no-restricted-paths -> Check hex boundaries
2163
- exhaustive-deps -> Add missing dependencies
2164
- \`\`\`
114
+ const CONFIG_FILE_NAME = '.lumenflow.config.yaml';
115
+ const FRAMEWORK_HINT_FILE = '.lumenflow.framework.yaml';
116
+ const LUMENFLOW_DIR = '.lumenflow';
117
+ const LUMENFLOW_AGENTS_DIR = `${LUMENFLOW_DIR}/agents`;
118
+ const CLAUDE_DIR = '.claude';
119
+ const CLAUDE_AGENTS_DIR = path.join(CLAUDE_DIR, 'agents');
120
+ /**
121
+ * WU-1362: Check branch guard before writing tracked files
122
+ *
123
+ * Warns (but does not block) if:
124
+ * - On main branch AND
125
+ * - Not in a worktree directory AND
126
+ * - Git repository exists (has .git)
127
+ *
128
+ * This prevents accidental main branch pollution during init operations.
129
+ * Uses warning instead of error to allow initial project setup.
130
+ *
131
+ * @param targetDir - Directory where files will be written
132
+ * @param result - ScaffoldResult to add warnings to
133
+ */
134
+ async function checkBranchGuard(targetDir, result) {
135
+ result.warnings = result.warnings ?? [];
136
+ // Only check if target is a git repository
137
+ const gitDir = path.join(targetDir, '.git');
138
+ if (!fs.existsSync(gitDir)) {
139
+ // Not a git repo - allow scaffold (initial setup)
140
+ return;
141
+ }
142
+ // Check if we're in a worktree (always allow)
143
+ if (isInWorktree({ cwd: targetDir })) {
144
+ return;
145
+ }
146
+ // Check if on main branch
147
+ try {
148
+ const onMain = await isMainBranch();
149
+ if (onMain) {
150
+ result.warnings.push('Running init on main branch in main checkout. ' +
151
+ 'Consider using a worktree for changes to tracked files.');
152
+ }
153
+ }
154
+ catch {
155
+ // Git error (e.g., not initialized) - silently allow
156
+ }
157
+ }
158
+ /**
159
+ * Generate YAML configuration with header comment
160
+ * WU-1067: Supports --preset option for config-driven gates
161
+ * WU-1307: Includes default lane definitions for onboarding
162
+ * WU-1364: Supports git config overrides (requireRemote)
163
+ * WU-1383: Adds enforcement hooks config for Claude client by default
164
+ */
165
+ function generateLumenflowConfigYaml(gatePreset, gitConfigOverride, client) {
166
+ // WU-1382: Add managed file header to prevent manual edits
167
+ const header = `# ============================================================================
168
+ # LUMENFLOW MANAGED FILE - DO NOT EDIT MANUALLY
169
+ # ============================================================================
170
+ # Generated by: lumenflow init
171
+ # Regenerate with: pnpm exec lumenflow init --force
172
+ #
173
+ # This file is managed by LumenFlow tooling. Manual edits may be overwritten.
174
+ # To customize, use the CLI commands or edit the appropriate source templates.
175
+ # ============================================================================
2165
176
 
2166
- ## Validation Commands
177
+ # LumenFlow Configuration
178
+ # Customize paths based on your project structure
2167
179
 
2168
- \`\`\`bash
2169
- pnpm gates # All gates
2170
- pnpm gates -- --docs-only # Docs WUs
2171
- pnpm format # Fix formatting
2172
- pnpm lint:fix # Fix lint issues
2173
- pnpm typecheck # Check types
2174
- \`\`\`
2175
180
  `;
181
+ const config = getDefaultConfig();
182
+ config.directories.agentsDir = LUMENFLOW_AGENTS_DIR;
183
+ // WU-1067: Add gates.execution section with preset if specified
184
+ if (gatePreset && GATE_PRESETS[gatePreset]) {
185
+ const presetConfig = GATE_PRESETS[gatePreset];
186
+ config.gates.execution = {
187
+ preset: gatePreset,
188
+ ...presetConfig,
189
+ };
190
+ }
191
+ // WU-1307: Add default lane definitions
192
+ config.lanes = {
193
+ definitions: DEFAULT_LANE_DEFINITIONS,
194
+ };
195
+ // WU-1364: Add git config overrides (e.g., requireRemote: false for local-only)
196
+ if (gitConfigOverride) {
197
+ config.git = {
198
+ requireRemote: gitConfigOverride.requireRemote,
199
+ };
200
+ }
201
+ // WU-1383: Add enforcement hooks for Claude client by default
202
+ // This prevents agents from working on main and editing config files manually
203
+ if (client === 'claude') {
204
+ config.agents = {
205
+ clients: {
206
+ [DEFAULT_CLIENT_CLAUDE]: {
207
+ enforcement: {
208
+ hooks: true,
209
+ block_outside_worktree: true,
210
+ require_wu_for_edits: true,
211
+ warn_on_stop_without_wu_done: true,
212
+ },
213
+ },
214
+ },
215
+ };
216
+ }
217
+ return header + yaml.stringify(config);
218
+ }
219
+ /**
220
+ * Get current date in YYYY-MM-DD format
221
+ */
222
+ function getCurrentDate() {
223
+ return new Date().toISOString().split('T')[0];
224
+ }
2176
225
  /**
2177
- * Detect default client from environment
226
+ * Normalize a framework name into display + slug
2178
227
  */
2179
- function detectDefaultClient() {
2180
- if (process.env.CLAUDE_PROJECT_DIR || process.env.CLAUDE_CODE) {
2181
- return DEFAULT_CLIENT_CLAUDE;
228
+ function normalizeFrameworkName(framework) {
229
+ const name = framework.trim();
230
+ const slug = name
231
+ .toLowerCase()
232
+ .replace(/[^a-z0-9_-]+/g, '-')
233
+ // Remove leading dashes and trailing dashes separately (explicit precedence)
234
+ .replace(/^-+/, '')
235
+ .replace(/-+$/, '');
236
+ if (!slug) {
237
+ throw new Error(`Invalid framework name: "${framework}"`);
2182
238
  }
2183
- return 'none';
239
+ return { name, slug };
2184
240
  }
2185
241
  /**
2186
242
  * WU-1171: Resolve client type from options
@@ -2209,55 +265,6 @@ function getFileMode(options) {
2209
265
  }
2210
266
  return 'skip';
2211
267
  }
2212
- /**
2213
- * WU-1364: Check if directory is a git repository
2214
- */
2215
- function isGitRepo(targetDir) {
2216
- try {
2217
- // eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
2218
- execFileSync('git', ['rev-parse', '--git-dir'], {
2219
- cwd: targetDir,
2220
- stdio: 'pipe',
2221
- });
2222
- return true;
2223
- }
2224
- catch {
2225
- return false;
2226
- }
2227
- }
2228
- /**
2229
- * WU-1364: Check if git repo has any commits
2230
- */
2231
- function hasGitCommits(targetDir) {
2232
- try {
2233
- // eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
2234
- execFileSync('git', ['rev-parse', 'HEAD'], {
2235
- cwd: targetDir,
2236
- stdio: 'pipe',
2237
- });
2238
- return true;
2239
- }
2240
- catch {
2241
- return false;
2242
- }
2243
- }
2244
- /**
2245
- * WU-1364: Check if git repo has an origin remote
2246
- */
2247
- function hasOriginRemote(targetDir) {
2248
- try {
2249
- // eslint-disable-next-line sonarjs/no-os-command-from-path -- git resolved from PATH; CLI tool requires git
2250
- const result = execFileSync('git', ['remote', 'get-url', 'origin'], {
2251
- cwd: targetDir,
2252
- encoding: 'utf-8',
2253
- stdio: 'pipe',
2254
- });
2255
- return result.trim().length > 0;
2256
- }
2257
- catch {
2258
- return false;
2259
- }
2260
- }
2261
268
  const CLIENT_INTEGRATIONS = {
2262
269
  [LUMENFLOW_CLIENT_IDS.CLAUDE_CODE]: {
2263
270
  run: (projectDir, enforcement) => integrateClaudeCode(projectDir, { enforcement }),
@@ -2275,7 +282,7 @@ async function runClientIntegrations(targetDir, result) {
2275
282
  config = yaml.parse(content);
2276
283
  }
2277
284
  catch {
2278
- return integrationFiles; // Config unreadable skip silently
285
+ return integrationFiles; // Config unreadable -- skip silently
2279
286
  }
2280
287
  if (!config)
2281
288
  return integrationFiles;
@@ -2354,42 +361,6 @@ export function renameMasterToMainIfNeeded(targetDir) {
2354
361
  return false;
2355
362
  }
2356
363
  }
2357
- function detectGitStateConfig(targetDir) {
2358
- // If not a git repo, default to local-only mode for safety
2359
- if (!isGitRepo(targetDir)) {
2360
- return { requireRemote: false };
2361
- }
2362
- // If git repo but no origin remote, set requireRemote: false
2363
- if (!hasOriginRemote(targetDir)) {
2364
- return { requireRemote: false };
2365
- }
2366
- // Has origin remote - use default (requireRemote: true)
2367
- return null;
2368
- }
2369
- /**
2370
- * WU-1171: Get templates directory path
2371
- */
2372
- function getTemplatesDir() {
2373
- const __filename = fileURLToPath(import.meta.url);
2374
- const __dirname = path.dirname(__filename);
2375
- // Check for dist/templates (production) or ../templates (development)
2376
- const distTemplates = path.join(__dirname, '..', 'templates');
2377
- if (fs.existsSync(distTemplates)) {
2378
- return distTemplates;
2379
- }
2380
- throw new Error(`Templates directory not found at ${distTemplates}`);
2381
- }
2382
- /**
2383
- * WU-1171: Load a template file
2384
- */
2385
- function loadTemplate(templatePath) {
2386
- const templatesDir = getTemplatesDir();
2387
- const fullPath = path.join(templatesDir, templatePath);
2388
- if (!fs.existsSync(fullPath)) {
2389
- throw new Error(`Template not found: ${templatePath}`);
2390
- }
2391
- return fs.readFileSync(fullPath, 'utf-8');
2392
- }
2393
364
  /**
2394
365
  * Scaffold a new LumenFlow project
2395
366
  * WU-1171: Added AGENTS.md, --merge mode, updated vendor/client handling
@@ -2495,39 +466,6 @@ export async function scaffoldProject(targetDir, options) {
2495
466
  }
2496
467
  return result;
2497
468
  }
2498
- /**
2499
- * WU-1342: .gitignore template with required exclusions
2500
- * WU-1519: Removed .lumenflow/state/ (must be tracked for wu-events.jsonl)
2501
- * Includes node_modules, .lumenflow/telemetry, and worktrees
2502
- */
2503
- const GITIGNORE_TEMPLATE = `# Dependencies
2504
- node_modules/
2505
-
2506
- # LumenFlow telemetry (local only, not shared)
2507
- .lumenflow/telemetry/
2508
-
2509
- # Worktrees (isolated parallel work directories)
2510
- worktrees/
2511
-
2512
- # Build output
2513
- dist/
2514
- *.tsbuildinfo
2515
-
2516
- # Environment files
2517
- .env
2518
- .env.local
2519
- .env.*.local
2520
-
2521
- # IDE
2522
- .idea/
2523
- .vscode/
2524
- *.swp
2525
- *.swo
2526
-
2527
- # OS files
2528
- .DS_Store
2529
- Thumbs.db
2530
- `;
2531
469
  /** Gitignore file name constant to avoid duplicate string lint error */
2532
470
  const GITIGNORE_FILE_NAME = '.gitignore';
2533
471
  /**
@@ -2570,37 +508,6 @@ ${linesToAdd.join('\n')}
2570
508
  // Skip or force mode
2571
509
  await createFile(gitignorePath, GITIGNORE_TEMPLATE, fileMode, result, targetDir);
2572
510
  }
2573
- /**
2574
- * WU-1517: .prettierignore template with sane defaults
2575
- * Ensures format:check passes immediately after init by excluding
2576
- * generated files, build artifacts, and lockfiles.
2577
- */
2578
- const PRETTIERIGNORE_TEMPLATE = `# Dependencies
2579
- node_modules/
2580
-
2581
- # Build output
2582
- dist/
2583
- *.tsbuildinfo
2584
-
2585
- # Coverage reports
2586
- coverage/
2587
-
2588
- # LumenFlow state (local only)
2589
- .lumenflow/state/
2590
-
2591
- # Worktrees
2592
- worktrees/
2593
-
2594
- # Lockfiles (auto-generated)
2595
- pnpm-lock.yaml
2596
- package-lock.json
2597
- yarn.lock
2598
-
2599
- # Environment files
2600
- .env
2601
- .env.local
2602
- .env.*.local
2603
- `;
2604
511
  /** Prettierignore file name constant to avoid duplicate string lint error */
2605
512
  const PRETTIERIGNORE_FILE_NAME = '.prettierignore';
2606
513
  /**
@@ -2613,14 +520,6 @@ async function scaffoldPrettierignore(targetDir, options, result) {
2613
520
  const fileMode = getFileMode(options);
2614
521
  await createFile(prettierignorePath, PRETTIERIGNORE_TEMPLATE, fileMode, result, targetDir);
2615
522
  }
2616
- /**
2617
- * WU-1433: Script argument overrides for commands that need extra flags.
2618
- * Most commands map simply to their binName, but some aliases need arguments.
2619
- * Key = command name (colon notation), Value = full script command string.
2620
- */
2621
- const SCRIPT_ARG_OVERRIDES = {
2622
- 'gates:docs': 'gates --docs-only',
2623
- };
2624
523
  /**
2625
524
  * WU-1307: LumenFlow scripts to inject into package.json
2626
525
  * WU-1342: Expanded to include essential commands
@@ -2675,89 +574,6 @@ async function scaffoldSafetyScripts(targetDir, options, result) {
2675
574
  await createExecutableScript(preCommitPath, PRE_COMMIT_TEMPLATE, fileMode, result, targetDir);
2676
575
  }
2677
576
  }
2678
- /**
2679
- * WU-1408: Fallback safe-git template
2680
- * Blocks dangerous git operations in LumenFlow environment
2681
- */
2682
- const SAFE_GIT_TEMPLATE = `#!/bin/sh
2683
- #
2684
- # safe-git - LumenFlow safety wrapper for git
2685
- #
2686
- # Blocks dangerous operations that can corrupt agent state.
2687
- # For all other commands, passes through to system git.
2688
- #
2689
-
2690
- set -e
2691
-
2692
- # Block 'worktree remove'
2693
- if [ "$1" = "worktree" ] && [ "$2" = "remove" ]; then
2694
- echo "" >&2
2695
- echo "=== LUMENFLOW SAFETY BLOCK ===" >&2
2696
- echo "" >&2
2697
- echo "BLOCKED: Manual 'git worktree remove' is unsafe in this environment." >&2
2698
- echo "" >&2
2699
- echo "REASON: Manual removal leaves orphan directories and corrupts agent state." >&2
2700
- echo "" >&2
2701
- echo "USE INSTEAD:" >&2
2702
- echo " pnpm wu:done --id <ID> (To complete a task)" >&2
2703
- echo " pnpm wu:cleanup --id <ID> (To discard a task)" >&2
2704
- echo "==============================" >&2
2705
- exit 1
2706
- fi
2707
-
2708
- # Pass through to real git
2709
- exec git "$@"
2710
- `;
2711
- /**
2712
- * WU-1408: Fallback pre-commit template
2713
- * Blocks direct commits to main/master, allows commits on lane branches
2714
- * Does NOT run pnpm test (which fails on new projects)
2715
- */
2716
- const PRE_COMMIT_TEMPLATE = `#!/bin/sh
2717
- #
2718
- # LumenFlow Pre-Commit Hook
2719
- #
2720
- # Enforces worktree discipline by blocking direct commits to main/master.
2721
- # Does NOT assume pnpm test or any other commands exist.
2722
- #
2723
- # Rules:
2724
- # 1. BLOCK commits to main/master (use WU workflow instead)
2725
- # 2. ALLOW commits on lane branches (lane/*/wu-*)
2726
- # 3. ALLOW commits on tmp/* branches (CLI micro-worktrees)
2727
- #
2728
-
2729
- # Skip on tmp/* branches (CLI micro-worktrees)
2730
- BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
2731
- case "$BRANCH" in tmp/*) exit 0 ;; esac
2732
-
2733
- # Check for force bypass
2734
- if [ "$LUMENFLOW_FORCE" = "1" ]; then
2735
- exit 0
2736
- fi
2737
-
2738
- # Block direct commits to main/master
2739
- case "$BRANCH" in
2740
- main|master)
2741
- echo "" >&2
2742
- echo "=== DIRECT COMMIT TO \${BRANCH} BLOCKED ===" >&2
2743
- echo "" >&2
2744
- echo "LumenFlow protects main from direct commits." >&2
2745
- echo "" >&2
2746
- echo "USE INSTEAD:" >&2
2747
- echo " pnpm wu:claim --id WU-XXXX --lane \\"<Lane>\\"" >&2
2748
- echo " cd worktrees/<lane>-wu-xxxx" >&2
2749
- echo " # Make commits in the worktree" >&2
2750
- echo "" >&2
2751
- echo "EMERGENCY BYPASS (logged):" >&2
2752
- echo " LUMENFLOW_FORCE=1 git commit ..." >&2
2753
- echo "==========================================" >&2
2754
- exit 1
2755
- ;;
2756
- esac
2757
-
2758
- # Allow commits on other branches
2759
- exit 0
2760
- `;
2761
577
  /**
2762
578
  * WU-1517: Prettier version to add to devDependencies.
2763
579
  * Uses caret range to allow minor/patch updates.
@@ -2771,16 +587,6 @@ const FORMAT_CHECK_SCRIPT_NAME = 'format:check';
2771
587
  /** WU-1517: Format script commands using prettier */
2772
588
  const FORMAT_SCRIPT_COMMAND = 'prettier --write .';
2773
589
  const FORMAT_CHECK_SCRIPT_COMMAND = 'prettier --check .';
2774
- /**
2775
- * WU-1518: Gate stub scripts for projects that don't have their own lint/typecheck/spec-linter.
2776
- * These stubs log a clear message and exit 0 so `pnpm gates` passes on a fresh project.
2777
- * Projects should replace them with real tooling when ready.
2778
- */
2779
- const GATE_STUB_SCRIPTS = {
2780
- 'spec:linter': 'echo "[lumenflow] spec:linter stub -- install a WU spec linter or replace this script" && exit 0',
2781
- lint: 'echo "[lumenflow] lint stub -- add ESLint or your preferred linter to enable this gate (e.g. eslint .)" && exit 0',
2782
- typecheck: 'echo "[lumenflow] typecheck stub -- add TypeScript or your type checker to enable this gate (e.g. tsc --noEmit)" && exit 0',
2783
- };
2784
590
  /**
2785
591
  * WU-1300: Inject LumenFlow scripts into package.json
2786
592
  * WU-1517: Also adds prettier devDependency and format/format:check scripts
@@ -2885,7 +691,7 @@ async function scaffoldFullDocs(targetDir, options, result, tokens) {
2885
691
  }
2886
692
  /**
2887
693
  * WU-1307: Scaffold lane inference configuration
2888
- * Uses hierarchical ParentSublane format required by lane-inference.ts
694
+ * Uses hierarchical Parent->Sublane format required by lane-inference.ts
2889
695
  */
2890
696
  async function scaffoldLaneInference(targetDir, options, result, tokens) {
2891
697
  // WU-1307: Add framework-specific lanes in hierarchical format if framework is provided
@@ -3066,101 +872,6 @@ async function scaffoldClientFiles(targetDir, options, result, tokens, client) {
3066
872
  await createFile(path.join(targetDir, '.aider.conf.yml'), AIDER_CONF_TEMPLATE, fileMode, result, targetDir);
3067
873
  }
3068
874
  }
3069
- /**
3070
- * Create a directory if missing
3071
- */
3072
- async function createDirectory(dirPath, result, targetDir) {
3073
- if (!fs.existsSync(dirPath)) {
3074
- fs.mkdirSync(dirPath, { recursive: true });
3075
- result.created.push(getRelativePath(targetDir, dirPath));
3076
- }
3077
- }
3078
- /**
3079
- * WU-1171: Create a file with support for skip, merge, and force modes
3080
- *
3081
- * @param filePath - Path to the file to create
3082
- * @param content - Content to write (or merge block content in merge mode)
3083
- * @param mode - 'skip' (default), 'merge', or 'force'
3084
- * @param result - ScaffoldResult to track created/skipped/merged files
3085
- * @param targetDir - Target directory for relative path calculation
3086
- */
3087
- async function createFile(filePath, content, mode, result, targetDir) {
3088
- const relativePath = getRelativePath(targetDir, filePath);
3089
- // Handle boolean for backwards compatibility (true = force, false = skip)
3090
- const resolvedMode = resolveBooleanToFileMode(mode);
3091
- // Ensure merged/warnings arrays exist
3092
- result.merged = result.merged ?? [];
3093
- result.warnings = result.warnings ?? [];
3094
- const fileExists = fs.existsSync(filePath);
3095
- if (fileExists && resolvedMode === 'skip') {
3096
- result.skipped.push(relativePath);
3097
- return;
3098
- }
3099
- if (fileExists && resolvedMode === 'merge') {
3100
- handleMergeMode(filePath, content, result, relativePath);
3101
- return;
3102
- }
3103
- // Force mode or file doesn't exist: write new content
3104
- writeNewFile(filePath, content, result, relativePath);
3105
- }
3106
- /**
3107
- * Convert boolean or FileMode to FileMode
3108
- */
3109
- function resolveBooleanToFileMode(mode) {
3110
- if (typeof mode === 'boolean') {
3111
- return mode ? 'force' : 'skip';
3112
- }
3113
- return mode;
3114
- }
3115
- /**
3116
- * Handle merge mode file update
3117
- */
3118
- function handleMergeMode(filePath, content, result, relativePath) {
3119
- const existingContent = fs.readFileSync(filePath, 'utf-8');
3120
- const mergeResult = updateMergeBlock(existingContent, content);
3121
- if (mergeResult.unchanged) {
3122
- result.skipped.push(relativePath);
3123
- return;
3124
- }
3125
- if (mergeResult.warning) {
3126
- result.warnings?.push(`${relativePath}: ${mergeResult.warning}`);
3127
- }
3128
- fs.writeFileSync(filePath, mergeResult.content);
3129
- result.merged?.push(relativePath);
3130
- }
3131
- /**
3132
- * Write a new file, creating parent directories if needed
3133
- */
3134
- function writeNewFile(filePath, content, result, relativePath) {
3135
- const parentDir = path.dirname(filePath);
3136
- if (!fs.existsSync(parentDir)) {
3137
- fs.mkdirSync(parentDir, { recursive: true });
3138
- }
3139
- fs.writeFileSync(filePath, content);
3140
- result.created.push(relativePath);
3141
- }
3142
- /**
3143
- * WU-1394: Create an executable script file with proper permissions
3144
- * Similar to createFile but sets 0o755 mode for shell scripts
3145
- */
3146
- async function createExecutableScript(filePath, content, mode, result, targetDir) {
3147
- const relativePath = getRelativePath(targetDir, filePath);
3148
- const resolvedMode = resolveBooleanToFileMode(mode);
3149
- result.merged = result.merged ?? [];
3150
- result.warnings = result.warnings ?? [];
3151
- const fileExists = fs.existsSync(filePath);
3152
- if (fileExists && resolvedMode === 'skip') {
3153
- result.skipped.push(relativePath);
3154
- return;
3155
- }
3156
- // Write file with executable permissions
3157
- const parentDir = path.dirname(filePath);
3158
- if (!fs.existsSync(parentDir)) {
3159
- fs.mkdirSync(parentDir, { recursive: true });
3160
- }
3161
- fs.writeFileSync(filePath, content, { mode: 0o755 });
3162
- result.created.push(relativePath);
3163
- }
3164
875
  /**
3165
876
  * CLI entry point
3166
877
  * WU-1085: Updated to use parseInitOptions for proper --help support
@@ -3218,7 +929,7 @@ export async function main() {
3218
929
  }
3219
930
  if (result.warnings && result.warnings.length > 0) {
3220
931
  console.log('\nWarnings:');
3221
- result.warnings.forEach((w) => console.log(` ${w}`));
932
+ result.warnings.forEach((w) => console.log(` \u26A0 ${w}`));
3222
933
  }
3223
934
  // WU-1386: Run doctor auto-check (non-blocking)
3224
935
  // This provides feedback on workflow health without failing init
@@ -3234,12 +945,12 @@ export async function main() {
3234
945
  }
3235
946
  // WU-1359: Show complete lifecycle with auto-ID (no --id flag required)
3236
947
  // WU-1364: Added initiative-first guidance for product visions
3237
- // WU-1576: Show enforcement hooks status vendor-agnostic (any adapter that produced files)
948
+ // WU-1576: Show enforcement hooks status -- vendor-agnostic (any adapter that produced files)
3238
949
  console.log('\n[lumenflow init] Done! Next steps:');
3239
950
  console.log(' 1. Review AGENTS.md and LUMENFLOW.md for workflow documentation');
3240
951
  console.log(` 2. Edit ${CONFIG_FILE_NAME} to match your project structure`);
3241
952
  if (result.integrationFiles && result.integrationFiles.length > 0) {
3242
- console.log(' \u2713 Enforcement hooks installed regenerate with: pnpm lumenflow:integrate');
953
+ console.log(' \u2713 Enforcement hooks installed -- regenerate with: pnpm lumenflow:integrate');
3243
954
  }
3244
955
  console.log('');
3245
956
  console.log(' For a product vision (multi-phase work):');