@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.
- package/README.md +121 -105
- package/dist/__tests__/agent-spawn-coordination.test.js +451 -0
- package/dist/__tests__/commands/integrate.test.js +165 -0
- package/dist/__tests__/commands.test.js +75 -0
- package/dist/__tests__/doctor.test.js +510 -0
- package/dist/__tests__/gates-config.test.js +0 -1
- package/dist/__tests__/hooks/enforcement.test.js +279 -0
- package/dist/__tests__/init-greenfield.test.js +247 -0
- package/dist/__tests__/init-quick-ref.test.js +0 -1
- package/dist/__tests__/init-template-portability.test.js +0 -1
- package/dist/__tests__/init.test.js +249 -0
- package/dist/__tests__/initiative-e2e.test.js +442 -0
- package/dist/__tests__/initiative-plan-replacement.test.js +0 -1
- package/dist/__tests__/memory-integration.test.js +333 -0
- package/dist/__tests__/release.test.js +1 -1
- package/dist/__tests__/safe-git.test.js +0 -1
- package/dist/__tests__/state-doctor.test.js +54 -0
- package/dist/__tests__/sync-templates.test.js +255 -0
- package/dist/__tests__/wu-create-required-fields.test.js +121 -0
- package/dist/__tests__/wu-done-auto-cleanup.test.js +135 -0
- package/dist/__tests__/wu-lifecycle-integration.test.js +388 -0
- package/dist/backlog-prune.js +0 -1
- package/dist/cli-entry-point.js +0 -1
- package/dist/commands/integrate.js +229 -0
- package/dist/commands.js +171 -0
- package/dist/docs-sync.js +46 -0
- package/dist/doctor.js +479 -10
- package/dist/gates.js +0 -7
- package/dist/hooks/enforcement-checks.js +209 -0
- package/dist/hooks/enforcement-generator.js +365 -0
- package/dist/hooks/enforcement-sync.js +243 -0
- package/dist/hooks/index.js +7 -0
- package/dist/init.js +502 -17
- package/dist/initiative-add-wu.js +0 -2
- package/dist/initiative-create.js +0 -3
- package/dist/initiative-edit.js +0 -5
- package/dist/initiative-plan.js +0 -1
- package/dist/initiative-remove-wu.js +0 -2
- package/dist/lane-health.js +0 -2
- package/dist/lane-suggest.js +0 -1
- package/dist/mem-checkpoint.js +0 -2
- package/dist/mem-cleanup.js +0 -2
- package/dist/mem-context.js +0 -3
- package/dist/mem-create.js +0 -2
- package/dist/mem-delete.js +0 -3
- package/dist/mem-inbox.js +0 -2
- package/dist/mem-index.js +0 -1
- package/dist/mem-init.js +0 -2
- package/dist/mem-profile.js +0 -1
- package/dist/mem-promote.js +0 -1
- package/dist/mem-ready.js +0 -2
- package/dist/mem-signal.js +0 -2
- package/dist/mem-start.js +0 -2
- package/dist/mem-summarize.js +0 -2
- package/dist/metrics-cli.js +1 -1
- package/dist/metrics-snapshot.js +1 -1
- package/dist/onboarding-smoke-test.js +0 -5
- package/dist/orchestrate-init-status.js +0 -1
- package/dist/orchestrate-initiative.js +0 -1
- package/dist/orchestrate-monitor.js +0 -1
- package/dist/plan-create.js +0 -2
- package/dist/plan-edit.js +0 -2
- package/dist/plan-link.js +0 -2
- package/dist/plan-promote.js +0 -2
- package/dist/signal-cleanup.js +0 -4
- package/dist/state-bootstrap.js +0 -1
- package/dist/state-cleanup.js +0 -4
- package/dist/state-doctor-fix.js +5 -8
- package/dist/state-doctor.js +0 -11
- package/dist/sync-templates.js +188 -34
- package/dist/wu-block.js +100 -48
- package/dist/wu-claim.js +1 -22
- package/dist/wu-cleanup.js +0 -1
- package/dist/wu-create.js +0 -2
- package/dist/wu-done-auto-cleanup.js +139 -0
- package/dist/wu-done.js +11 -4
- package/dist/wu-edit.js +0 -12
- package/dist/wu-preflight.js +0 -1
- package/dist/wu-prep.js +0 -1
- package/dist/wu-proto.js +0 -1
- package/dist/wu-spawn.js +0 -3
- package/dist/wu-unblock.js +0 -2
- package/dist/wu-validate.js +0 -1
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 = `#
|
|
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:
|
|
1278
|
+
# Framework Lane: Framework-specific code and tooling
|
|
1057
1279
|
Framework:
|
|
1058
1280
|
Core:
|
|
1059
|
-
description: 'Core
|
|
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
|
-
|
|
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
|
-
|
|
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('
|
|
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('
|
|
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
|
});
|