@lumenflow/cli 2.18.2 → 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.
- package/README.md +42 -41
- package/dist/delegation-list.js +140 -0
- package/dist/delegation-list.js.map +1 -0
- package/dist/doctor.js +35 -99
- package/dist/doctor.js.map +1 -1
- package/dist/gates-plan-resolvers.js +150 -0
- package/dist/gates-plan-resolvers.js.map +1 -0
- package/dist/gates-runners.js +533 -0
- package/dist/gates-runners.js.map +1 -0
- package/dist/gates-types.js +3 -0
- package/dist/gates-types.js.map +1 -1
- package/dist/gates-utils.js +316 -0
- package/dist/gates-utils.js.map +1 -0
- package/dist/gates.js +44 -1016
- package/dist/gates.js.map +1 -1
- package/dist/hooks/enforcement-generator.js +16 -880
- package/dist/hooks/enforcement-generator.js.map +1 -1
- package/dist/hooks/enforcement-sync.js +1 -4
- package/dist/hooks/enforcement-sync.js.map +1 -1
- package/dist/hooks/generators/auto-checkpoint.js +123 -0
- package/dist/hooks/generators/auto-checkpoint.js.map +1 -0
- package/dist/hooks/generators/enforce-worktree.js +188 -0
- package/dist/hooks/generators/enforce-worktree.js.map +1 -0
- package/dist/hooks/generators/index.js +16 -0
- package/dist/hooks/generators/index.js.map +1 -0
- package/dist/hooks/generators/pre-compact-checkpoint.js +134 -0
- package/dist/hooks/generators/pre-compact-checkpoint.js.map +1 -0
- package/dist/hooks/generators/require-wu.js +115 -0
- package/dist/hooks/generators/require-wu.js.map +1 -0
- package/dist/hooks/generators/session-start-recovery.js +101 -0
- package/dist/hooks/generators/session-start-recovery.js.map +1 -0
- package/dist/hooks/generators/signal-utils.js +52 -0
- package/dist/hooks/generators/signal-utils.js.map +1 -0
- package/dist/hooks/generators/warn-incomplete.js +65 -0
- package/dist/hooks/generators/warn-incomplete.js.map +1 -0
- package/dist/init-detection.js +228 -0
- package/dist/init-detection.js.map +1 -0
- package/dist/init-scaffolding.js +146 -0
- package/dist/init-scaffolding.js.map +1 -0
- package/dist/init-templates.js +1928 -0
- package/dist/init-templates.js.map +1 -0
- package/dist/init.js +136 -2425
- package/dist/init.js.map +1 -1
- package/dist/initiative-edit.js +42 -11
- package/dist/initiative-edit.js.map +1 -1
- package/dist/initiative-remove-wu.js +0 -0
- package/dist/initiative-status.js +29 -2
- package/dist/initiative-status.js.map +1 -1
- package/dist/mem-context.js +22 -9
- package/dist/mem-context.js.map +1 -1
- package/dist/orchestrate-init-status.js +32 -1
- package/dist/orchestrate-init-status.js.map +1 -1
- package/dist/orchestrate-monitor.js +38 -38
- package/dist/orchestrate-monitor.js.map +1 -1
- package/dist/public-manifest.js +12 -5
- package/dist/public-manifest.js.map +1 -1
- package/dist/shared-validators.js +1 -0
- package/dist/shared-validators.js.map +1 -1
- package/dist/spawn-list.js +0 -0
- package/dist/wu-claim-branch.js +121 -0
- package/dist/wu-claim-branch.js.map +1 -0
- package/dist/wu-claim-output.js +83 -0
- package/dist/wu-claim-output.js.map +1 -0
- package/dist/wu-claim-resume-handler.js +85 -0
- package/dist/wu-claim-resume-handler.js.map +1 -0
- package/dist/wu-claim-state.js +572 -0
- package/dist/wu-claim-state.js.map +1 -0
- package/dist/wu-claim-validation.js +439 -0
- package/dist/wu-claim-validation.js.map +1 -0
- package/dist/wu-claim-worktree.js +221 -0
- package/dist/wu-claim-worktree.js.map +1 -0
- package/dist/wu-claim.js +54 -1402
- package/dist/wu-claim.js.map +1 -1
- package/dist/wu-create-content.js +254 -0
- package/dist/wu-create-content.js.map +1 -0
- package/dist/wu-create-readiness.js +57 -0
- package/dist/wu-create-readiness.js.map +1 -0
- package/dist/wu-create-validation.js +149 -0
- package/dist/wu-create-validation.js.map +1 -0
- package/dist/wu-create.js +39 -441
- package/dist/wu-create.js.map +1 -1
- package/dist/wu-done.js +144 -249
- package/dist/wu-done.js.map +1 -1
- package/dist/wu-edit-operations.js +432 -0
- package/dist/wu-edit-operations.js.map +1 -0
- package/dist/wu-edit-validators.js +280 -0
- package/dist/wu-edit-validators.js.map +1 -0
- package/dist/wu-edit.js +27 -713
- package/dist/wu-edit.js.map +1 -1
- package/dist/wu-prep.js +32 -2
- package/dist/wu-prep.js.map +1 -1
- package/dist/wu-repair.js +1 -1
- package/dist/wu-repair.js.map +1 -1
- package/dist/wu-spawn-prompt-builders.js +1123 -0
- package/dist/wu-spawn-prompt-builders.js.map +1 -0
- package/dist/wu-spawn-strategy-resolver.js +314 -0
- package/dist/wu-spawn-strategy-resolver.js.map +1 -0
- package/dist/wu-spawn.js +9 -1398
- package/dist/wu-spawn.js.map +1 -1
- package/package.json +10 -7
- package/templates/core/LUMENFLOW.md.template +29 -99
- package/templates/core/ai/onboarding/agent-invocation-guide.md.template +1 -1
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +29 -4
- 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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* -
|
|
154
|
-
* -
|
|
155
|
-
* -
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
226
|
+
* Normalize a framework name into display + slug
|
|
2178
227
|
*/
|
|
2179
|
-
function
|
|
2180
|
-
|
|
2181
|
-
|
|
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
|
|
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
|
|
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 Parent
|
|
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(`
|
|
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
|
|
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
|
|
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):');
|