@lumenflow/cli 2.7.0 → 2.9.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 (84) hide show
  1. package/README.md +121 -105
  2. package/dist/__tests__/agent-spawn-coordination.test.js +451 -0
  3. package/dist/__tests__/commands/integrate.test.js +165 -0
  4. package/dist/__tests__/commands.test.js +75 -0
  5. package/dist/__tests__/doctor.test.js +510 -0
  6. package/dist/__tests__/gates-config.test.js +0 -1
  7. package/dist/__tests__/hooks/enforcement.test.js +279 -0
  8. package/dist/__tests__/init-greenfield.test.js +247 -0
  9. package/dist/__tests__/init-quick-ref.test.js +0 -1
  10. package/dist/__tests__/init-template-portability.test.js +0 -1
  11. package/dist/__tests__/init.test.js +249 -0
  12. package/dist/__tests__/initiative-e2e.test.js +442 -0
  13. package/dist/__tests__/initiative-plan-replacement.test.js +0 -1
  14. package/dist/__tests__/memory-integration.test.js +333 -0
  15. package/dist/__tests__/release.test.js +1 -1
  16. package/dist/__tests__/safe-git.test.js +0 -1
  17. package/dist/__tests__/state-doctor.test.js +54 -0
  18. package/dist/__tests__/sync-templates.test.js +255 -0
  19. package/dist/__tests__/wu-create-required-fields.test.js +121 -0
  20. package/dist/__tests__/wu-done-auto-cleanup.test.js +135 -0
  21. package/dist/__tests__/wu-lifecycle-integration.test.js +388 -0
  22. package/dist/backlog-prune.js +0 -1
  23. package/dist/cli-entry-point.js +0 -1
  24. package/dist/commands/integrate.js +229 -0
  25. package/dist/commands.js +171 -0
  26. package/dist/docs-sync.js +46 -0
  27. package/dist/doctor.js +479 -10
  28. package/dist/gates.js +0 -7
  29. package/dist/hooks/enforcement-checks.js +209 -0
  30. package/dist/hooks/enforcement-generator.js +365 -0
  31. package/dist/hooks/enforcement-sync.js +243 -0
  32. package/dist/hooks/index.js +7 -0
  33. package/dist/init.js +502 -17
  34. package/dist/initiative-add-wu.js +0 -2
  35. package/dist/initiative-create.js +0 -3
  36. package/dist/initiative-edit.js +0 -5
  37. package/dist/initiative-plan.js +0 -1
  38. package/dist/initiative-remove-wu.js +0 -2
  39. package/dist/lane-health.js +0 -2
  40. package/dist/lane-suggest.js +0 -1
  41. package/dist/mem-checkpoint.js +0 -2
  42. package/dist/mem-cleanup.js +0 -2
  43. package/dist/mem-context.js +0 -3
  44. package/dist/mem-create.js +0 -2
  45. package/dist/mem-delete.js +0 -3
  46. package/dist/mem-inbox.js +0 -2
  47. package/dist/mem-index.js +0 -1
  48. package/dist/mem-init.js +0 -2
  49. package/dist/mem-profile.js +0 -1
  50. package/dist/mem-promote.js +0 -1
  51. package/dist/mem-ready.js +0 -2
  52. package/dist/mem-signal.js +0 -2
  53. package/dist/mem-start.js +0 -2
  54. package/dist/mem-summarize.js +0 -2
  55. package/dist/metrics-cli.js +1 -1
  56. package/dist/metrics-snapshot.js +1 -1
  57. package/dist/onboarding-smoke-test.js +0 -5
  58. package/dist/orchestrate-init-status.js +0 -1
  59. package/dist/orchestrate-initiative.js +0 -1
  60. package/dist/orchestrate-monitor.js +0 -1
  61. package/dist/plan-create.js +0 -2
  62. package/dist/plan-edit.js +0 -2
  63. package/dist/plan-link.js +0 -2
  64. package/dist/plan-promote.js +0 -2
  65. package/dist/signal-cleanup.js +0 -4
  66. package/dist/state-bootstrap.js +0 -1
  67. package/dist/state-cleanup.js +0 -4
  68. package/dist/state-doctor-fix.js +5 -8
  69. package/dist/state-doctor.js +0 -11
  70. package/dist/sync-templates.js +188 -34
  71. package/dist/wu-block.js +100 -48
  72. package/dist/wu-claim.js +1 -22
  73. package/dist/wu-cleanup.js +0 -1
  74. package/dist/wu-create.js +0 -2
  75. package/dist/wu-done-auto-cleanup.js +139 -0
  76. package/dist/wu-done.js +11 -4
  77. package/dist/wu-edit.js +0 -12
  78. package/dist/wu-preflight.js +0 -1
  79. package/dist/wu-prep.js +0 -1
  80. package/dist/wu-proto.js +0 -1
  81. package/dist/wu-spawn.js +0 -3
  82. package/dist/wu-unblock.js +0 -2
  83. package/dist/wu-validate.js +0 -1
  84. package/package.json +9 -7
package/dist/init.js CHANGED
@@ -5,6 +5,7 @@
5
5
  * WU-1028: Vendor-agnostic core + vendor overlays
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
+ * WU-1362: Added branch guard to check branch before writing tracked files
8
9
  */
9
10
  import * as fs from 'node:fs';
10
11
  import * as path from 'node:path';
@@ -16,6 +17,10 @@ import { getDefaultConfig, createWUParser, WU_OPTIONS } from '@lumenflow/core';
16
17
  import { GATE_PRESETS } from '@lumenflow/core/dist/gates-config.js';
17
18
  // WU-1171: Import merge block utilities
18
19
  import { updateMergeBlock } from './merge-block.js';
20
+ // WU-1362: Import worktree guard utilities for branch checking
21
+ import { isMainBranch, isInWorktree } from '@lumenflow/core/dist/core/worktree-guard.js';
22
+ // WU-1386: Import doctor for auto-run after init
23
+ import { runDoctorForInit } from './doctor.js';
19
24
  /**
20
25
  * WU-1085: CLI option definitions for init command
21
26
  * WU-1171: Added --merge and --client options
@@ -67,9 +72,12 @@ const INIT_OPTIONS = {
67
72
  * Provides proper --help, --version, and option parsing
68
73
  */
69
74
  export function parseInitOptions() {
75
+ // WU-1378: Description includes subcommand hint
70
76
  const opts = createWUParser({
71
77
  name: 'lumenflow-init',
72
- description: 'Initialize LumenFlow in a project',
78
+ description: 'Initialize LumenFlow in a project\n\n' +
79
+ 'Subcommands:\n' +
80
+ ' lumenflow commands List all available CLI commands',
73
81
  options: Object.values(INIT_OPTIONS),
74
82
  });
75
83
  // WU-1171: --client takes precedence, --vendor is alias
@@ -131,6 +139,44 @@ const LUMENFLOW_DIR = '.lumenflow';
131
139
  const LUMENFLOW_AGENTS_DIR = `${LUMENFLOW_DIR}/agents`;
132
140
  const CLAUDE_DIR = '.claude';
133
141
  const CLAUDE_AGENTS_DIR = path.join(CLAUDE_DIR, 'agents');
142
+ /**
143
+ * WU-1362: Check branch guard before writing tracked files
144
+ *
145
+ * Warns (but does not block) if:
146
+ * - On main branch AND
147
+ * - Not in a worktree directory AND
148
+ * - Git repository exists (has .git)
149
+ *
150
+ * This prevents accidental main branch pollution during init operations.
151
+ * Uses warning instead of error to allow initial project setup.
152
+ *
153
+ * @param targetDir - Directory where files will be written
154
+ * @param result - ScaffoldResult to add warnings to
155
+ */
156
+ async function checkBranchGuard(targetDir, result) {
157
+ result.warnings = result.warnings ?? [];
158
+ // Only check if target is a git repository
159
+ const gitDir = path.join(targetDir, '.git');
160
+ if (!fs.existsSync(gitDir)) {
161
+ // Not a git repo - allow scaffold (initial setup)
162
+ return;
163
+ }
164
+ // Check if we're in a worktree (always allow)
165
+ if (isInWorktree({ cwd: targetDir })) {
166
+ return;
167
+ }
168
+ // Check if on main branch
169
+ try {
170
+ const onMain = await isMainBranch();
171
+ if (onMain) {
172
+ result.warnings.push('Running init on main branch in main checkout. ' +
173
+ 'Consider using a worktree for changes to tracked files.');
174
+ }
175
+ }
176
+ catch {
177
+ // Git error (e.g., not initialized) - silently allow
178
+ }
179
+ }
134
180
  /**
135
181
  * WU-1177: Detect IDE environment from environment variables
136
182
  * Auto-detects which AI coding assistant is running
@@ -279,9 +325,25 @@ const DEFAULT_LANE_DEFINITIONS = [
279
325
  * Generate YAML configuration with header comment
280
326
  * WU-1067: Supports --preset option for config-driven gates
281
327
  * WU-1307: Includes default lane definitions for onboarding
328
+ * WU-1364: Supports git config overrides (requireRemote)
329
+ * WU-1383: Adds enforcement hooks config for Claude client by default
282
330
  */
283
- function generateLumenflowConfigYaml(gatePreset) {
284
- const header = `# LumenFlow Configuration\n# Generated by: lumenflow init\n# Customize paths based on your project structure\n\n`;
331
+ function generateLumenflowConfigYaml(gatePreset, gitConfigOverride, client) {
332
+ // WU-1382: Add managed file header to prevent manual edits
333
+ const header = `# ============================================================================
334
+ # LUMENFLOW MANAGED FILE - DO NOT EDIT MANUALLY
335
+ # ============================================================================
336
+ # Generated by: lumenflow init
337
+ # Regenerate with: pnpm exec lumenflow init --force
338
+ #
339
+ # This file is managed by LumenFlow tooling. Manual edits may be overwritten.
340
+ # To customize, use the CLI commands or edit the appropriate source templates.
341
+ # ============================================================================
342
+
343
+ # LumenFlow Configuration
344
+ # Customize paths based on your project structure
345
+
346
+ `;
285
347
  const config = getDefaultConfig();
286
348
  config.directories.agentsDir = LUMENFLOW_AGENTS_DIR;
287
349
  // WU-1067: Add gates.execution section with preset if specified
@@ -296,6 +358,28 @@ function generateLumenflowConfigYaml(gatePreset) {
296
358
  config.lanes = {
297
359
  definitions: DEFAULT_LANE_DEFINITIONS,
298
360
  };
361
+ // WU-1364: Add git config overrides (e.g., requireRemote: false for local-only)
362
+ if (gitConfigOverride) {
363
+ config.git = {
364
+ requireRemote: gitConfigOverride.requireRemote,
365
+ };
366
+ }
367
+ // WU-1383: Add enforcement hooks for Claude client by default
368
+ // This prevents agents from working on main and editing config files manually
369
+ if (client === 'claude') {
370
+ config.agents = {
371
+ clients: {
372
+ 'claude-code': {
373
+ enforcement: {
374
+ hooks: true,
375
+ block_outside_worktree: true,
376
+ require_wu_for_edits: true,
377
+ warn_on_stop_without_wu_done: true,
378
+ },
379
+ },
380
+ },
381
+ };
382
+ }
299
383
  return header + yaml.stringify(config);
300
384
  }
301
385
  /**
@@ -314,7 +398,6 @@ function normalizeFrameworkName(framework) {
314
398
  .replace(/[^a-z0-9_-]+/g, '-')
315
399
  // Remove leading dashes and trailing dashes separately (explicit precedence)
316
400
  .replace(/^-+/, '')
317
- // eslint-disable-next-line sonarjs/slow-regex -- Simple pattern, no catastrophic backtracking risk
318
401
  .replace(/-+$/, '');
319
402
  if (!slug) {
320
403
  throw new Error(`Invalid framework name: "${framework}"`);
@@ -400,12 +483,84 @@ This file provides universal guidance for all AI agents. Additional vendor-speci
400
483
  `;
401
484
  // Template for LUMENFLOW.md (main entry point)
402
485
  // WU-1309: Use <project-root> placeholder for portability
403
- 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## 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\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`;
486
+ // WU-1364: Added initiative workflow section
487
+ 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`;
404
488
  // Template for .lumenflow/constraints.md
405
489
  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`;
406
490
  // Template for root CLAUDE.md
407
491
  // WU-1309: Use <project-root> placeholder for portability
408
- const CLAUDE_MD_TEMPLATE = `# Claude Code Instructions\n\n**Last updated:** {{DATE}}\n\nThis project uses LumenFlow workflow. For workflow documentation, see [LUMENFLOW.md](LUMENFLOW.md).\n\n---\n\n## Quick Start\n\n\`\`\`bash\n# 1. Claim a WU\npnpm wu:claim --id WU-XXXX --lane <Lane>\ncd worktrees/<lane>-wu-xxxx\n\n# 2. Work in worktree, run gates\npnpm gates\n\n# 3. Complete (ALWAYS run this!)\ncd <project-root>\npnpm wu:done --id WU-XXXX\n\`\`\`\n\n---\n\n## Critical: Always wu:done\n\nAfter completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\`.\n\nSee [LUMENFLOW.md](LUMENFLOW.md) for full workflow documentation.\n`;
492
+ // WU-1382: Expanded with CLI commands table and warning about manual YAML editing
493
+ const CLAUDE_MD_TEMPLATE = `# Claude Code Instructions
494
+
495
+ **Last updated:** {{DATE}}
496
+
497
+ This project uses LumenFlow workflow. For workflow documentation, see [LUMENFLOW.md](LUMENFLOW.md).
498
+
499
+ ---
500
+
501
+ ## Quick Start
502
+
503
+ \`\`\`bash
504
+ # 1. Claim a WU
505
+ pnpm wu:claim --id WU-XXXX --lane <Lane>
506
+ cd worktrees/<lane>-wu-xxxx
507
+
508
+ # 2. Work in worktree, run gates
509
+ pnpm gates
510
+
511
+ # 3. Complete (ALWAYS run this!)
512
+ cd <project-root>
513
+ pnpm wu:done --id WU-XXXX
514
+ \`\`\`
515
+
516
+ ---
517
+
518
+ ## CLI Commands Reference
519
+
520
+ ### WU Lifecycle
521
+
522
+ | Command | Description |
523
+ | ----------------------------------------- | ---------------------------------------- |
524
+ | \`pnpm wu:status --id WU-XXX\` | Show WU status, location, valid commands |
525
+ | \`pnpm wu:claim --id WU-XXX --lane <Lane>\` | Claim WU and create worktree |
526
+ | \`pnpm wu:prep --id WU-XXX\` | Run gates in worktree, prep for wu:done |
527
+ | \`pnpm wu:done --id WU-XXX\` | Complete WU (from main checkout) |
528
+ | \`pnpm wu:block --id WU-XXX --reason "..."\`| Block WU with reason |
529
+ | \`pnpm wu:unblock --id WU-XXX\` | Unblock WU |
530
+
531
+ ### Gates & Quality
532
+
533
+ | Command | Description |
534
+ | ------------------------ | -------------------------- |
535
+ | \`pnpm gates\` | Run all quality gates |
536
+ | \`pnpm gates --docs-only\` | Run gates for docs changes |
537
+ | \`pnpm format\` | Format all files |
538
+ | \`pnpm lint\` | Run linter |
539
+ | \`pnpm typecheck\` | Run TypeScript check |
540
+ | \`pnpm test\` | Run tests |
541
+
542
+ ---
543
+
544
+ ## Critical: Always wu:done
545
+
546
+ After completing work, ALWAYS run \`pnpm wu:done --id WU-XXXX\` from the main checkout.
547
+
548
+ See [LUMENFLOW.md](LUMENFLOW.md) for full workflow documentation.
549
+
550
+ ---
551
+
552
+ ## Warning: Do Not Edit WU YAML Files Manually
553
+
554
+ **Never manually edit WU YAML files** in \`docs/.../tasks/wu/WU-XXX.yaml\`.
555
+
556
+ Use CLI commands instead:
557
+
558
+ - \`pnpm wu:create ...\` to create new WUs
559
+ - \`pnpm wu:edit --id WU-XXX ...\` to modify WU fields
560
+ - \`pnpm wu:claim\` / \`wu:block\` / \`wu:done\` for status changes
561
+
562
+ Manual edits bypass validation and can corrupt workflow state.
563
+ `;
409
564
  // Template for .claude/settings.json
410
565
  const CLAUDE_SETTINGS_TEMPLATE = `{
411
566
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
@@ -1046,17 +1201,84 @@ Choose the safer path:
1046
1201
  - Ask rather than assume
1047
1202
  `;
1048
1203
  // WU-1307: Lane inference configuration template (hierarchical Parent→Sublane format)
1204
+ // WU-1364: Added Core and Feature as parent lanes for intuitive naming
1205
+ // WU-1382: Added managed file header to prevent manual edits
1049
1206
  // This format is required by lane-inference.ts and lane-checker.ts
1050
- const LANE_INFERENCE_TEMPLATE = `# Lane Inference Configuration
1207
+ const LANE_INFERENCE_TEMPLATE = `# ============================================================================
1208
+ # LUMENFLOW MANAGED FILE - DO NOT EDIT MANUALLY
1209
+ # ============================================================================
1051
1210
  # Generated by: lumenflow init
1211
+ # Regenerate with: pnpm exec lumenflow init --force
1212
+ #
1213
+ # This file is managed by LumenFlow tooling. Manual edits may be overwritten.
1214
+ # To customize lanes, use: pnpm lane:suggest --output .lumenflow.lane-inference.yaml
1215
+ # ============================================================================
1216
+
1217
+ # Lane Inference Configuration
1052
1218
  #
1053
1219
  # Hierarchical format: Parent -> Sublane -> { code_paths, keywords }
1054
1220
  # This format is required by lane-inference.ts for proper sub-lane suggestion.
1221
+ #
1222
+ # Common parent lanes: Core, Feature, Framework, Experience, Operations, Content
1223
+
1224
+ # Core Lane: Platform foundations, shared libraries, base infrastructure
1225
+ Core:
1226
+ Platform:
1227
+ description: 'Core platform: shared utilities, base infrastructure, common libraries'
1228
+ code_paths:
1229
+ - 'packages/**/core/**'
1230
+ - 'src/core/**'
1231
+ - 'src/lib/**'
1232
+ - 'lib/**'
1233
+ keywords:
1234
+ - 'platform'
1235
+ - 'core'
1236
+ - 'infrastructure'
1237
+ - 'foundation'
1238
+
1239
+ Library:
1240
+ description: 'Shared libraries and utilities'
1241
+ code_paths:
1242
+ - 'packages/**/lib/**'
1243
+ - 'src/utils/**'
1244
+ - 'src/helpers/**'
1245
+ keywords:
1246
+ - 'library'
1247
+ - 'utility'
1248
+ - 'helper'
1249
+ - 'shared'
1250
+
1251
+ # Feature Lane: Product features and user-facing functionality
1252
+ Feature:
1253
+ Backend:
1254
+ description: 'Backend features: APIs, services, business logic'
1255
+ code_paths:
1256
+ - 'src/api/**'
1257
+ - 'src/services/**'
1258
+ - 'packages/**/api/**'
1259
+ keywords:
1260
+ - 'api'
1261
+ - 'service'
1262
+ - 'backend'
1263
+ - 'business logic'
1264
+
1265
+ Frontend:
1266
+ description: 'Frontend features: UI, components, pages'
1267
+ code_paths:
1268
+ - 'src/components/**'
1269
+ - 'src/pages/**'
1270
+ - 'src/app/**'
1271
+ - 'apps/web/**'
1272
+ keywords:
1273
+ - 'frontend'
1274
+ - 'ui'
1275
+ - 'component'
1276
+ - 'page'
1055
1277
 
1056
- # Framework Lane: Core packages and libraries
1278
+ # Framework Lane: Framework-specific code and tooling
1057
1279
  Framework:
1058
1280
  Core:
1059
- description: 'Core library: business logic, domain models, utilities'
1281
+ description: 'Core framework: business logic, domain models, utilities'
1060
1282
  code_paths:
1061
1283
  - 'packages/**/core/**'
1062
1284
  - 'src/core/**'
@@ -1151,6 +1373,7 @@ Content:
1151
1373
  {{FRAMEWORK_LANES}}
1152
1374
  `;
1153
1375
  // WU-1300: Starting prompt template for agent onboarding
1376
+ // WU-1364: Added "When Starting From Product Vision" section for initiative-first workflow
1154
1377
  const STARTING_PROMPT_TEMPLATE = `# Starting Prompt for LumenFlow Agents
1155
1378
 
1156
1379
  **Last updated:** {{DATE}}
@@ -1159,6 +1382,48 @@ This document provides the initial context for AI agents working on this project
1159
1382
 
1160
1383
  ---
1161
1384
 
1385
+ ## When Starting From Product Vision
1386
+
1387
+ 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:
1388
+
1389
+ ### 4-Step Initiative Workflow
1390
+
1391
+ 1. **Create an Initiative**: Capture the vision as an initiative
1392
+ \`\`\`bash
1393
+ pnpm initiative:create --id INIT-001 --title "Task Management App" \\
1394
+ --description "Build a task management application with..." \\
1395
+ --phase "Phase 1: Core MVP" --phase "Phase 2: Collaboration"
1396
+ \`\`\`
1397
+
1398
+ 2. **Define Phases**: Break the vision into logical phases (MVP, iteration, polish)
1399
+
1400
+ 3. **Create WUs under the Initiative**: Each WU belongs to a phase
1401
+ \`\`\`bash
1402
+ pnpm wu:create --lane "Core: Platform" --title "Add task model" \\
1403
+ --description "..." --acceptance "..." --code-paths "..." \\
1404
+ && pnpm initiative:add-wu --initiative INIT-001 --wu WU-XXX --phase 1
1405
+ \`\`\`
1406
+
1407
+ 4. **Track Progress**: Use \`pnpm initiative:status --id INIT-001\` to see overall progress
1408
+
1409
+ ### Why Initiatives Matter
1410
+
1411
+ - **Avoid orphan WUs**: Without initiative structure, agents create disconnected WUs that lack coherent scope
1412
+ - **Better coordination**: Phases enable parallel work across lanes
1413
+ - **Clear completion criteria**: The initiative tracks when all phases are done
1414
+ - **Visibility**: Stakeholders can see multi-phase progress
1415
+
1416
+ ### When to Skip Initiatives
1417
+
1418
+ Only skip initiatives for:
1419
+ - Single-file bug fixes
1420
+ - Small documentation updates
1421
+ - Isolated refactoring tasks
1422
+
1423
+ If work spans multiple WUs or multiple days, create an initiative first.
1424
+
1425
+ ---
1426
+
1162
1427
  ## Step 1: Read Core Documentation
1163
1428
 
1164
1429
  Before starting any work, read these documents in order:
@@ -1197,6 +1462,8 @@ LumenFlow uses Work Units (WUs) to track all changes:
1197
1462
  | \`pnpm gates\` | Run quality gates |
1198
1463
  | \`pnpm wu:done --id WU-XXX\` | Complete WU |
1199
1464
  | \`pnpm wu:status --id WU-XXX\` | Check WU status |
1465
+ | \`pnpm initiative:create ...\` | Create a new initiative |
1466
+ | \`pnpm initiative:status --id INIT-XXX\` | Check initiative progress |
1200
1467
 
1201
1468
  ---
1202
1469
 
@@ -1213,6 +1480,7 @@ LumenFlow uses Work Units (WUs) to track all changes:
1213
1480
  - [quick-ref-commands.md](quick-ref-commands.md) - Complete command reference
1214
1481
  - [agent-safety-card.md](agent-safety-card.md) - Safety guidelines
1215
1482
  - [wu-create-checklist.md](wu-create-checklist.md) - WU creation guide
1483
+ - [wu-sizing-guide.md](wu-sizing-guide.md) - WU complexity and context management
1216
1484
  `;
1217
1485
  const WU_CREATE_CHECKLIST_TEMPLATE = `# WU Creation Checklist
1218
1486
 
@@ -1601,6 +1869,96 @@ This detects:
1601
1869
  - Overlapping code paths between lanes
1602
1870
  - Code files not covered by any lane
1603
1871
  `;
1872
+ // WU-1385: WU sizing guide template for agent onboarding
1873
+ const WU_SIZING_GUIDE_TEMPLATE = `# Work Unit Sizing & Strategy Guide
1874
+
1875
+ **Last updated:** {{DATE}}
1876
+
1877
+ **Purpose:** Decision framework for agents to determine execution strategy based on task complexity.
1878
+
1879
+ **Status:** Active — Thresholds are **mandatory limits**, not guidelines.
1880
+
1881
+ ---
1882
+
1883
+ ## Complexity Assessment Matrix
1884
+
1885
+ Before claiming a WU, estimate its "weight" using these heuristics.
1886
+
1887
+ | Complexity | Files | Tool Calls | Context Budget | Strategy |
1888
+ | :------------ | :---- | :--------- | :------------- | :------------------------------------------- |
1889
+ | **Simple** | <20 | <50 | <30% | **Single Session** (Tier 2 Context) |
1890
+ | **Medium** | 20-50 | 50-100 | 30-50% | **Checkpoint-Resume** (Standard Handoff) |
1891
+ | **Complex** | 50+ | 100+ | >50% | **Orchestrator-Worker** OR **Decomposition** |
1892
+ | **Oversized** | 100+ | 200+ | — | **MUST Split** (See Patterns below) |
1893
+
1894
+ **These thresholds are mandatory.** Exceeding them leads to context exhaustion and rule loss. Agents operate in context windows and tool calls, not clock time.
1895
+
1896
+ ---
1897
+
1898
+ ## Context Safety Triggers
1899
+
1900
+ If you hit ANY of these triggers during a session, you MUST checkpoint and spawn fresh:
1901
+
1902
+ - **Token Limit:** Context usage hits **50% (Warning)** or **80% (Critical)**.
1903
+ - **Tool Volume:** **50+ tool calls** in current session.
1904
+ - **File Volume:** **20+ files** modified in \`git status\`.
1905
+ - **Session Staleness:** Repeated redundant queries or forgotten context.
1906
+
1907
+ ---
1908
+
1909
+ ## Spawn Fresh, Don't Continue
1910
+
1911
+ **When approaching context limits, spawn a fresh agent instead of continuing after compaction.**
1912
+
1913
+ Context compaction causes agents to lose critical rules. The disciplined approach:
1914
+
1915
+ 1. Checkpoint your progress: \`pnpm mem:checkpoint --wu WU-XXX\`
1916
+ 2. Commit and push work
1917
+ 3. Generate fresh agent prompt: \`pnpm wu:spawn --id WU-XXX\`
1918
+ 4. EXIT current session (do NOT continue after compaction)
1919
+
1920
+ ---
1921
+
1922
+ ## Splitting Patterns
1923
+
1924
+ When a WU is Oversized or Complex, split it using approved patterns:
1925
+
1926
+ - **Tracer Bullet**: WU-1 proves skeleton works, WU-2 implements real logic
1927
+ - **Layer Split**: WU-1 for ports/application, WU-2 for infrastructure
1928
+ - **UI/Logic Split**: WU-1 for backend, WU-2 for frontend
1929
+ - **Feature Flag**: WU-1 behind flag, WU-2 removes flag
1930
+
1931
+ ---
1932
+
1933
+ ## Quick Reference
1934
+
1935
+ | Scenario | Strategy | Action |
1936
+ | :---------------------------------- | :------------------ | :------------------------------------------- |
1937
+ | Bug fix, single file, <20 calls | Simple | Claim, fix, commit, \`wu:done\` |
1938
+ | Feature 50-100 calls, clear phases | Checkpoint-Resume | Phase 1 → checkpoint → Phase 2 → done |
1939
+ | Multi-domain, must land atomically | Orchestrator-Worker | Main agent coordinates, spawns sub-agents |
1940
+ | Large refactor 100+ calls | Feature Flag Split | WU-A: New behind flag → WU-B: Remove flag |
1941
+
1942
+ ---
1943
+
1944
+ ## Documentation-Only Exception
1945
+
1946
+ Documentation WUs (\`type: documentation\`) have relaxed file count thresholds:
1947
+
1948
+ | Complexity | Files (docs) | Tool Calls | Strategy |
1949
+ | :--------- | :----------- | :--------- | :---------------- |
1950
+ | **Simple** | <40 | <50 | Single Session |
1951
+ | **Medium** | 40-80 | 50-100 | Checkpoint-Resume |
1952
+
1953
+ **Applies when ALL true:**
1954
+ - WU \`type: documentation\`
1955
+ - Only modifies: \`docs/**\`, \`*.md\`
1956
+ - Does NOT touch code paths
1957
+
1958
+ ---
1959
+
1960
+ For complete sizing guidance, see the canonical [wu-sizing-guide.md](https://lumenflow.dev/reference/wu-sizing-guide/) documentation.
1961
+ `;
1604
1962
  // WU-1083: Claude skills templates
1605
1963
  const WU_LIFECYCLE_SKILL_TEMPLATE = `---
1606
1964
  name: wu-lifecycle
@@ -1835,6 +2193,85 @@ function getFileMode(options) {
1835
2193
  }
1836
2194
  return 'skip';
1837
2195
  }
2196
+ /**
2197
+ * WU-1364: Check if directory is a git repository
2198
+ */
2199
+ function isGitRepo(targetDir) {
2200
+ try {
2201
+ execFileSync('git', ['rev-parse', '--git-dir'], {
2202
+ cwd: targetDir,
2203
+ stdio: 'pipe',
2204
+ });
2205
+ return true;
2206
+ }
2207
+ catch {
2208
+ return false;
2209
+ }
2210
+ }
2211
+ /**
2212
+ * WU-1364: Check if git repo has any commits
2213
+ */
2214
+ function hasGitCommits(targetDir) {
2215
+ try {
2216
+ execFileSync('git', ['rev-parse', 'HEAD'], {
2217
+ cwd: targetDir,
2218
+ stdio: 'pipe',
2219
+ });
2220
+ return true;
2221
+ }
2222
+ catch {
2223
+ return false;
2224
+ }
2225
+ }
2226
+ /**
2227
+ * WU-1364: Check if git repo has an origin remote
2228
+ */
2229
+ function hasOriginRemote(targetDir) {
2230
+ try {
2231
+ const result = execFileSync('git', ['remote', 'get-url', 'origin'], {
2232
+ cwd: targetDir,
2233
+ encoding: 'utf-8',
2234
+ stdio: 'pipe',
2235
+ });
2236
+ return result.trim().length > 0;
2237
+ }
2238
+ catch {
2239
+ return false;
2240
+ }
2241
+ }
2242
+ /**
2243
+ * WU-1364: Create initial commit if git repo has no commits
2244
+ */
2245
+ function createInitialCommitIfNeeded(targetDir) {
2246
+ if (!isGitRepo(targetDir) || hasGitCommits(targetDir)) {
2247
+ return false;
2248
+ }
2249
+ try {
2250
+ // Stage all files
2251
+ execFileSync('git', ['add', '.'], { cwd: targetDir, stdio: 'pipe' });
2252
+ // Create initial commit
2253
+ execFileSync('git', ['commit', '-m', 'chore: initialize LumenFlow project'], {
2254
+ cwd: targetDir,
2255
+ stdio: 'pipe',
2256
+ });
2257
+ return true;
2258
+ }
2259
+ catch {
2260
+ return false;
2261
+ }
2262
+ }
2263
+ function detectGitStateConfig(targetDir) {
2264
+ // If not a git repo, default to local-only mode for safety
2265
+ if (!isGitRepo(targetDir)) {
2266
+ return { requireRemote: false };
2267
+ }
2268
+ // If git repo but no origin remote, set requireRemote: false
2269
+ if (!hasOriginRemote(targetDir)) {
2270
+ return { requireRemote: false };
2271
+ }
2272
+ // Has origin remote - use default (requireRemote: true)
2273
+ return null;
2274
+ }
1838
2275
  /**
1839
2276
  * WU-1171: Get templates directory path
1840
2277
  */
@@ -1862,6 +2299,7 @@ function loadTemplate(templatePath) {
1862
2299
  /**
1863
2300
  * Scaffold a new LumenFlow project
1864
2301
  * WU-1171: Added AGENTS.md, --merge mode, updated vendor/client handling
2302
+ * WU-1362: Added branch guard to prevent main branch pollution
1865
2303
  */
1866
2304
  export async function scaffoldProject(targetDir, options) {
1867
2305
  const result = {
@@ -1870,9 +2308,12 @@ export async function scaffoldProject(targetDir, options) {
1870
2308
  merged: [],
1871
2309
  warnings: [],
1872
2310
  };
2311
+ // WU-1362: Check branch before writing tracked files
2312
+ // Only block if we're on main branch AND not in a worktree
2313
+ // This allows scaffold to run in worktrees and during initial setup
2314
+ await checkBranchGuard(targetDir, result);
1873
2315
  const defaultClient = options.defaultClient ?? detectDefaultClient();
1874
2316
  // WU-1171: Use resolveClientType with both client and vendor (vendor is deprecated but kept for backwards compat)
1875
- // eslint-disable-next-line sonarjs/deprecation -- Intentional backwards compatibility
1876
2317
  const client = resolveClientType(options.client, options.vendor, defaultClient);
1877
2318
  const fileMode = getFileMode(options);
1878
2319
  // Ensure target directory exists
@@ -1882,6 +2323,8 @@ export async function scaffoldProject(targetDir, options) {
1882
2323
  // WU-1309: Detect or use specified docs structure
1883
2324
  const docsStructure = options.docsStructure ?? detectDocsStructure(targetDir);
1884
2325
  const docsPaths = getDocsPath(docsStructure);
2326
+ // WU-1364: Detect git state for config generation
2327
+ const gitConfigOverride = detectGitStateConfig(targetDir);
1885
2328
  const tokenDefaults = {
1886
2329
  DATE: getCurrentDate(),
1887
2330
  PROJECT_ROOT: '<project-root>', // WU-1309: Use portable placeholder
@@ -1891,8 +2334,18 @@ export async function scaffoldProject(targetDir, options) {
1891
2334
  DOCS_ONBOARDING_PATH: docsPaths.onboarding,
1892
2335
  };
1893
2336
  // Create .lumenflow.config.yaml (WU-1067: includes gate preset if specified)
2337
+ // WU-1364: Includes git config overrides (e.g., requireRemote: false for local-only)
2338
+ // WU-1383: Includes enforcement hooks for Claude client
1894
2339
  // Note: Config files don't use merge mode (always skip or force)
1895
- await createFile(path.join(targetDir, CONFIG_FILE_NAME), generateLumenflowConfigYaml(options.gatePreset), options.force ? 'force' : 'skip', result, targetDir);
2340
+ const configPath = path.join(targetDir, CONFIG_FILE_NAME);
2341
+ // WU-1383: Warn if config already exists to discourage manual editing
2342
+ if (fs.existsSync(configPath) && !options.force) {
2343
+ result.warnings = result.warnings ?? [];
2344
+ result.warnings.push(`${CONFIG_FILE_NAME} already exists. ` +
2345
+ 'To modify configuration, use CLI commands (e.g., pnpm lumenflow:init --force) ' +
2346
+ 'instead of manual editing.');
2347
+ }
2348
+ await createFile(configPath, generateLumenflowConfigYaml(options.gatePreset, gitConfigOverride, client), options.force ? 'force' : 'skip', result, targetDir);
1896
2349
  // WU-1171: Create AGENTS.md (universal entry point for all agents)
1897
2350
  try {
1898
2351
  const agentsTemplate = loadTemplate('core/AGENTS.md.template');
@@ -1925,6 +2378,12 @@ export async function scaffoldProject(targetDir, options) {
1925
2378
  if (options.full) {
1926
2379
  await injectPackageJsonScripts(targetDir, options, result);
1927
2380
  }
2381
+ // WU-1364: Create initial commit if git repo has no commits
2382
+ // This must be done after all files are created
2383
+ const createdInitialCommit = createInitialCommitIfNeeded(targetDir);
2384
+ if (createdInitialCommit) {
2385
+ result.created.push('Initial git commit');
2386
+ }
1928
2387
  return result;
1929
2388
  }
1930
2389
  /**
@@ -2140,6 +2599,8 @@ async function scaffoldAgentOnboardingDocs(targetDir, options, result, tokens) {
2140
2599
  await createFile(path.join(onboardingDir, 'troubleshooting-wu-done.md'), processTemplate(TROUBLESHOOTING_WU_DONE_TEMPLATE, tokens), options.force, result, targetDir);
2141
2600
  await createFile(path.join(onboardingDir, 'agent-safety-card.md'), processTemplate(AGENT_SAFETY_CARD_TEMPLATE, tokens), options.force, result, targetDir);
2142
2601
  await createFile(path.join(onboardingDir, 'wu-create-checklist.md'), processTemplate(WU_CREATE_CHECKLIST_TEMPLATE, tokens), options.force, result, targetDir);
2602
+ // WU-1385: Add wu-sizing-guide.md to onboarding docs
2603
+ await createFile(path.join(onboardingDir, 'wu-sizing-guide.md'), processTemplate(WU_SIZING_GUIDE_TEMPLATE, tokens), options.force, result, targetDir);
2143
2604
  }
2144
2605
  /**
2145
2606
  * WU-1083: Scaffold Claude skills
@@ -2317,9 +2778,19 @@ function writeNewFile(filePath, content, result, relativePath) {
2317
2778
  * CLI entry point
2318
2779
  * WU-1085: Updated to use parseInitOptions for proper --help support
2319
2780
  * WU-1171: Added --merge and --client support
2781
+ * WU-1378: Added subcommand routing for 'commands' subcommand
2320
2782
  */
2321
2783
  export async function main() {
2322
- /* eslint-disable no-console -- CLI tool requires console output for user feedback */
2784
+ // WU-1378: Check for subcommands before parsing init options
2785
+ const subcommand = process.argv[2];
2786
+ if (subcommand === 'commands') {
2787
+ // Route to commands subcommand
2788
+ const { main: commandsMain } = await import('./commands.js');
2789
+ // Remove 'commands' from argv so the subcommand parser sees clean args
2790
+ process.argv.splice(2, 1);
2791
+ await commandsMain();
2792
+ return;
2793
+ }
2323
2794
  const opts = parseInitOptions();
2324
2795
  const targetDir = process.cwd();
2325
2796
  console.log('[lumenflow init] Scaffolding LumenFlow project...');
@@ -2362,13 +2833,29 @@ export async function main() {
2362
2833
  console.log('\nWarnings:');
2363
2834
  result.warnings.forEach((w) => console.log(` ⚠ ${w}`));
2364
2835
  }
2836
+ // WU-1386: Run doctor auto-check (non-blocking)
2837
+ // This provides feedback on workflow health without failing init
2838
+ try {
2839
+ const doctorResult = await runDoctorForInit(targetDir);
2840
+ if (doctorResult.output) {
2841
+ console.log('');
2842
+ console.log(doctorResult.output);
2843
+ }
2844
+ }
2845
+ catch {
2846
+ // Doctor check is non-blocking - if it fails, continue with init
2847
+ }
2365
2848
  // WU-1359: Show complete lifecycle with auto-ID (no --id flag required)
2849
+ // WU-1364: Added initiative-first guidance for product visions
2366
2850
  console.log('\n[lumenflow init] Done! Next steps:');
2367
2851
  console.log(' 1. Review AGENTS.md and LUMENFLOW.md for workflow documentation');
2368
2852
  console.log(` 2. Edit ${CONFIG_FILE_NAME} to match your project structure`);
2369
- console.log(' 3. Start your first WU:');
2370
2853
  console.log('');
2371
- console.log(' # Create (auto-generates ID):');
2854
+ console.log(' For a product vision (multi-phase work):');
2855
+ console.log(' pnpm initiative:create --id INIT-001 --title "Project Name" \\');
2856
+ console.log(' --phase "Phase 1: MVP" --phase "Phase 2: Polish"');
2857
+ console.log('');
2858
+ console.log(' For a single WU:');
2372
2859
  console.log(' pnpm wu:create --lane <lane> --title "First WU" \\');
2373
2860
  console.log(' --description "Context: ... Problem: ... Solution: ..." \\');
2374
2861
  console.log(' --acceptance "Criterion 1" --code-paths "src/..." --exposure backend-only');
@@ -2376,14 +2863,12 @@ export async function main() {
2376
2863
  console.log(' # Or for rapid prototyping (minimal validation):');
2377
2864
  console.log(' pnpm wu:proto --lane <lane> --title "Quick experiment"');
2378
2865
  console.log('');
2379
- console.log(' 4. Full lifecycle: wu:create -> wu:claim -> wu:prep -> wu:done');
2380
- /* eslint-enable no-console */
2866
+ console.log(' Full lifecycle: wu:create -> wu:claim -> wu:prep -> wu:done');
2381
2867
  }
2382
2868
  // WU-1297: Use import.meta.main instead of exporting main() without calling it
2383
2869
  // This ensures main() runs when the script is executed as a CLI entry point
2384
2870
  if (import.meta.main) {
2385
2871
  main().catch((err) => {
2386
- // eslint-disable-next-line no-console -- CLI error output
2387
2872
  console.error('[lumenflow init] Error:', err instanceof Error ? err.message : String(err));
2388
2873
  process.exit(1);
2389
2874
  });