@lumenflow/cli 2.2.2 → 2.3.2
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 +147 -57
- package/dist/__tests__/agent-log-issue.test.js +56 -0
- package/dist/__tests__/cli-entry-point.test.js +66 -17
- package/dist/__tests__/cli-subprocess.test.js +25 -0
- package/dist/__tests__/init.test.js +298 -0
- package/dist/__tests__/initiative-plan.test.js +340 -0
- package/dist/__tests__/mem-cleanup-execution.test.js +19 -0
- package/dist/__tests__/merge-block.test.js +220 -0
- package/dist/__tests__/release.test.js +61 -0
- package/dist/__tests__/safe-git.test.js +191 -0
- package/dist/__tests__/state-doctor.test.js +274 -0
- package/dist/__tests__/wu-done.test.js +36 -0
- package/dist/__tests__/wu-edit.test.js +119 -0
- package/dist/__tests__/wu-prep.test.js +108 -0
- package/dist/agent-issues-query.js +4 -3
- package/dist/agent-log-issue.js +25 -4
- package/dist/backlog-prune.js +5 -4
- package/dist/cli-entry-point.js +11 -1
- package/dist/doctor.js +368 -0
- package/dist/flow-bottlenecks.js +6 -5
- package/dist/flow-report.js +4 -3
- package/dist/gates.js +356 -101
- package/dist/guard-locked.js +4 -3
- package/dist/guard-worktree-commit.js +4 -3
- package/dist/init.js +517 -86
- package/dist/initiative-add-wu.js +4 -3
- package/dist/initiative-bulk-assign-wus.js +8 -5
- package/dist/initiative-create.js +73 -37
- package/dist/initiative-edit.js +37 -21
- package/dist/initiative-list.js +4 -3
- package/dist/initiative-plan.js +337 -0
- package/dist/initiative-status.js +4 -3
- package/dist/lane-health.js +377 -0
- package/dist/lane-suggest.js +382 -0
- package/dist/mem-checkpoint.js +2 -2
- package/dist/mem-cleanup.js +2 -2
- package/dist/mem-context.js +306 -0
- package/dist/mem-create.js +2 -2
- package/dist/mem-delete.js +293 -0
- package/dist/mem-inbox.js +2 -2
- package/dist/mem-index.js +211 -0
- package/dist/mem-init.js +1 -1
- package/dist/mem-profile.js +207 -0
- package/dist/mem-promote.js +254 -0
- package/dist/mem-ready.js +2 -2
- package/dist/mem-signal.js +2 -2
- package/dist/mem-start.js +2 -2
- package/dist/mem-summarize.js +2 -2
- package/dist/mem-triage.js +2 -2
- package/dist/merge-block.js +222 -0
- package/dist/metrics-cli.js +7 -4
- package/dist/metrics-snapshot.js +4 -3
- package/dist/orchestrate-initiative.js +10 -4
- package/dist/orchestrate-monitor.js +379 -31
- package/dist/release.js +69 -29
- package/dist/signal-cleanup.js +296 -0
- package/dist/spawn-list.js +6 -5
- package/dist/state-bootstrap.js +5 -4
- package/dist/state-cleanup.js +360 -0
- package/dist/state-doctor-fix.js +196 -0
- package/dist/state-doctor.js +501 -0
- package/dist/validate-agent-skills.js +4 -3
- package/dist/validate-agent-sync.js +4 -3
- package/dist/validate-backlog-sync.js +4 -3
- package/dist/validate-skills-spec.js +4 -3
- package/dist/validate.js +4 -3
- package/dist/wu-block.js +3 -3
- package/dist/wu-claim.js +208 -98
- package/dist/wu-cleanup.js +5 -4
- package/dist/wu-create.js +71 -46
- package/dist/wu-delete.js +88 -60
- package/dist/wu-deps.js +6 -5
- package/dist/wu-done-check.js +34 -0
- package/dist/wu-done.js +39 -12
- package/dist/wu-edit.js +63 -28
- package/dist/wu-infer-lane.js +7 -6
- package/dist/wu-preflight.js +23 -81
- package/dist/wu-prep.js +125 -0
- package/dist/wu-prune.js +4 -3
- package/dist/wu-recover.js +88 -22
- package/dist/wu-repair.js +7 -6
- package/dist/wu-spawn.js +226 -270
- package/dist/wu-status.js +4 -3
- package/dist/wu-unblock.js +5 -5
- package/dist/wu-unlock-lane.js +4 -3
- package/dist/wu-validate.js +5 -4
- package/package.json +16 -7
- package/templates/core/.lumenflow/constraints.md.template +192 -0
- package/templates/core/.lumenflow/rules/git-safety.md.template +27 -0
- package/templates/core/.lumenflow/rules/wu-workflow.md.template +48 -0
- package/templates/core/AGENTS.md.template +60 -0
- package/templates/core/LUMENFLOW.md.template +255 -0
- package/templates/core/UPGRADING.md.template +121 -0
- package/templates/core/ai/onboarding/agent-safety-card.md.template +106 -0
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +198 -0
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +186 -0
- package/templates/core/ai/onboarding/release-process.md.template +362 -0
- package/templates/core/ai/onboarding/troubleshooting-wu-done.md.template +159 -0
- package/templates/core/ai/onboarding/wu-create-checklist.md.template +117 -0
- package/templates/vendors/aider/.aider.conf.yml.template +27 -0
- package/templates/vendors/claude/.claude/CLAUDE.md.template +52 -0
- package/templates/vendors/claude/.claude/settings.json.template +49 -0
- package/templates/vendors/claude/.claude/skills/bug-classification/SKILL.md.template +192 -0
- package/templates/vendors/claude/.claude/skills/code-quality/SKILL.md.template +152 -0
- package/templates/vendors/claude/.claude/skills/context-management/SKILL.md.template +155 -0
- package/templates/vendors/claude/.claude/skills/execution-memory/SKILL.md.template +304 -0
- package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +131 -0
- package/templates/vendors/claude/.claude/skills/initiative-management/SKILL.md.template +164 -0
- package/templates/vendors/claude/.claude/skills/library-first/SKILL.md.template +98 -0
- package/templates/vendors/claude/.claude/skills/lumenflow-gates/SKILL.md.template +87 -0
- package/templates/vendors/claude/.claude/skills/multi-agent-coordination/SKILL.md.template +84 -0
- package/templates/vendors/claude/.claude/skills/ops-maintenance/SKILL.md.template +254 -0
- package/templates/vendors/claude/.claude/skills/orchestration/SKILL.md.template +189 -0
- package/templates/vendors/claude/.claude/skills/tdd-workflow/SKILL.md.template +139 -0
- package/templates/vendors/claude/.claude/skills/worktree-discipline/SKILL.md.template +138 -0
- package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +106 -0
- package/templates/vendors/cline/.clinerules.template +53 -0
- package/templates/vendors/cursor/.cursor/rules/lumenflow.md.template +34 -0
- package/templates/vendors/cursor/.cursor/rules.md.template +28 -0
- package/templates/vendors/windsurf/.windsurf/rules/lumenflow.md.template +34 -0
package/dist/wu-spawn.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/* eslint-disable no-console -- CLI tool requires console output */
|
|
2
3
|
/**
|
|
3
4
|
* WU Spawn Helper
|
|
4
5
|
*
|
|
@@ -25,7 +26,7 @@
|
|
|
25
26
|
* Codex Mode:
|
|
26
27
|
* When --codex is used, outputs a Codex/GPT-friendly Markdown prompt (no antml/XML escaping).
|
|
27
28
|
*
|
|
28
|
-
* @see {@link
|
|
29
|
+
* @see {@link https://lumenflow.dev/reference/agent-invocation-guide/} - Context loading templates
|
|
29
30
|
*/
|
|
30
31
|
import { existsSync, readFileSync } from 'node:fs';
|
|
31
32
|
import path from 'node:path';
|
|
@@ -43,38 +44,31 @@ import { validateSpawnArgs, generateExecutionModeSection, generateThinkToolGuida
|
|
|
43
44
|
import { SpawnStrategyFactory } from '@lumenflow/core/dist/spawn-strategy.js';
|
|
44
45
|
import { getConfig } from '@lumenflow/core/dist/lumenflow-config.js';
|
|
45
46
|
import { generateClientSkillsGuidance, generateSkillsSelectionSection, resolveClientConfig, } from '@lumenflow/core/dist/wu-spawn-skills.js';
|
|
47
|
+
// WU-1253: Template loader for extracted prompt templates
|
|
48
|
+
import { loadTemplatesWithOverrides, replaceTokens } from '@lumenflow/core/dist/template-loader.js';
|
|
46
49
|
import { validateSpawnDependencies, formatDependencyError, } from '@lumenflow/core/dist/dependency-validator.js';
|
|
50
|
+
// WU-1192: Import prompt generation from Core (single source of truth)
|
|
51
|
+
// WU-1203: Import generateAgentCoordinationSection from core for config-driven progress signals
|
|
52
|
+
// WU-1288: Import policy-based test guidance and mandatory standards generators
|
|
53
|
+
import { TRUNCATION_WARNING_BANNER, SPAWN_END_SENTINEL, generateTestGuidance, generateAgentCoordinationSection, generatePolicyBasedTestGuidance, generateMandatoryStandards, generateEnforcementSummary, } from '@lumenflow/core/dist/wu-spawn.js';
|
|
54
|
+
// WU-1288: Import resolvePolicy for methodology policy resolution
|
|
55
|
+
import { resolvePolicy } from '@lumenflow/core/dist/resolve-policy.js';
|
|
56
|
+
// WU-1240: Import memory context integration for spawn prompts
|
|
57
|
+
import { generateMemoryContextSection, checkMemoryLayerInitialized, getMemoryContextMaxSize, } from '@lumenflow/core/dist/wu-spawn-context.js';
|
|
58
|
+
// Re-export for backwards compatibility
|
|
59
|
+
export { TRUNCATION_WARNING_BANNER, SPAWN_END_SENTINEL, generateTestGuidance, generateAgentCoordinationSection, };
|
|
47
60
|
/**
|
|
48
61
|
* Mandatory agent trigger patterns.
|
|
49
|
-
* Mirrors MANDATORY_TRIGGERS from orchestration
|
|
62
|
+
* Mirrors MANDATORY_TRIGGERS from orchestration.constants.ts.
|
|
63
|
+
*
|
|
64
|
+
* Note: For LumenFlow framework development, this is empty since we don't have
|
|
65
|
+
* application-specific concerns like PHI, auth, or RLS. Projects using LumenFlow
|
|
66
|
+
* should configure their own triggers based on their domain requirements.
|
|
50
67
|
*/
|
|
51
68
|
const MANDATORY_TRIGGERS = {
|
|
52
|
-
|
|
53
|
-
'beacon-guardian': ['**/prompts/**', '**/classification/**', '**/detector/**', '**/llm/**'],
|
|
69
|
+
// No mandatory triggers for LumenFlow framework development.
|
|
54
70
|
};
|
|
55
71
|
const LOG_PREFIX = '[wu:spawn]';
|
|
56
|
-
/**
|
|
57
|
-
* WU-1131: Truncation prevention constants
|
|
58
|
-
*
|
|
59
|
-
* These constants help detect when spawn output has been truncated during
|
|
60
|
-
* copy-paste operations or context loading. The warning banner alerts users
|
|
61
|
-
* to the truncation risk, and the end sentinel allows verification that
|
|
62
|
-
* the full output was received.
|
|
63
|
-
*/
|
|
64
|
-
export const TRUNCATION_WARNING_BANNER = `<!-- LUMENFLOW_TRUNCATION_WARNING -->
|
|
65
|
-
<!--
|
|
66
|
-
⚠️ CRITICAL: DO NOT TRUNCATE THIS OUTPUT
|
|
67
|
-
|
|
68
|
-
This spawn prompt MUST be copied verbatim. Truncation causes:
|
|
69
|
-
- Missing constraints (agents ignore safety rules)
|
|
70
|
-
- Missing TDD directives (agents skip tests)
|
|
71
|
-
- Degraded agent performance
|
|
72
|
-
|
|
73
|
-
VERIFICATION: The output MUST end with: <!-- LUMENFLOW_SPAWN_END -->
|
|
74
|
-
If you don't see that sentinel at the end, the output was truncated.
|
|
75
|
-
-->
|
|
76
|
-
`;
|
|
77
|
-
export const SPAWN_END_SENTINEL = '<!-- LUMENFLOW_SPAWN_END -->';
|
|
78
72
|
/**
|
|
79
73
|
* Detect mandatory agents based on code paths.
|
|
80
74
|
*
|
|
@@ -142,15 +136,6 @@ function formatManualTests(manualTests) {
|
|
|
142
136
|
}
|
|
143
137
|
return manualTests.map((test) => `- [ ] ${test}`).join('\n');
|
|
144
138
|
}
|
|
145
|
-
/**
|
|
146
|
-
* Generate implementation context section (WU-1833)
|
|
147
|
-
*
|
|
148
|
-
* Includes spec_refs, notes, risks, and tests.manual if present.
|
|
149
|
-
* Sections with no content are omitted to keep prompts lean.
|
|
150
|
-
*
|
|
151
|
-
* @param {object} doc - WU YAML document
|
|
152
|
-
* @returns {string} Implementation context section or empty string
|
|
153
|
-
*/
|
|
154
139
|
function generateImplementationContext(doc) {
|
|
155
140
|
const sections = [];
|
|
156
141
|
// References (spec_refs)
|
|
@@ -216,14 +201,16 @@ function formatInvariantForOutput(inv) {
|
|
|
216
201
|
lines.push(`**Path:** \`${inv.path}\``);
|
|
217
202
|
}
|
|
218
203
|
if (inv.paths) {
|
|
219
|
-
|
|
204
|
+
const formattedPaths = inv.paths.map((p) => `\`${p}\``).join(', ');
|
|
205
|
+
lines.push(`**Paths:** ${formattedPaths}`);
|
|
220
206
|
}
|
|
221
207
|
// WU-2254: forbidden-import specific fields
|
|
222
208
|
if (inv.from) {
|
|
223
209
|
lines.push(`**From:** \`${inv.from}\``);
|
|
224
210
|
}
|
|
225
211
|
if (inv.cannot_import && Array.isArray(inv.cannot_import)) {
|
|
226
|
-
|
|
212
|
+
const formattedImports = inv.cannot_import.map((m) => `\`${m}\``).join(', ');
|
|
213
|
+
lines.push(`**Cannot Import:** ${formattedImports}`);
|
|
227
214
|
}
|
|
228
215
|
// WU-2254: required-pattern specific fields
|
|
229
216
|
if (inv.pattern &&
|
|
@@ -232,7 +219,8 @@ function formatInvariantForOutput(inv) {
|
|
|
232
219
|
lines.push(`**Pattern:** \`${inv.pattern}\``);
|
|
233
220
|
}
|
|
234
221
|
if (inv.scope && Array.isArray(inv.scope)) {
|
|
235
|
-
|
|
222
|
+
const formattedScope = inv.scope.map((s) => `\`${s}\``).join(', ');
|
|
223
|
+
lines.push(`**Scope:** ${formattedScope}`);
|
|
236
224
|
}
|
|
237
225
|
lines.push('');
|
|
238
226
|
return lines;
|
|
@@ -281,107 +269,8 @@ function generateInvariantsPriorArtSection(codePaths) {
|
|
|
281
269
|
];
|
|
282
270
|
return lines.join('\n');
|
|
283
271
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
*/
|
|
287
|
-
const TDD_REQUIRED_TYPES = ['feature', 'bug', 'tooling', 'enhancement'];
|
|
288
|
-
/**
|
|
289
|
-
* WU types that require existing tests to pass (no new tests mandated)
|
|
290
|
-
*/
|
|
291
|
-
const EXISTING_TESTS_TYPES = ['refactor'];
|
|
292
|
-
/**
|
|
293
|
-
* WU types that require smoke tests + manual QA
|
|
294
|
-
*/
|
|
295
|
-
const SMOKE_TEST_TYPES = ['visual', 'design', 'ui'];
|
|
296
|
-
/**
|
|
297
|
-
* WU types that only need format checks (no TDD)
|
|
298
|
-
*/
|
|
299
|
-
const DOCS_ONLY_TYPES = ['documentation', 'docs', 'config'];
|
|
300
|
-
/**
|
|
301
|
-
* Generate type-aware test guidance (WU-1142)
|
|
302
|
-
*
|
|
303
|
-
* Returns appropriate test guidance based on WU type:
|
|
304
|
-
* - feature/bug/tooling: Full TDD directive
|
|
305
|
-
* - documentation: Format check only
|
|
306
|
-
* - visual/design: Smoke test + manual QA
|
|
307
|
-
* - refactor: Existing tests must pass
|
|
308
|
-
*
|
|
309
|
-
* @param {string} wuType - WU type from YAML
|
|
310
|
-
* @returns {string} Test guidance section
|
|
311
|
-
*/
|
|
312
|
-
export function generateTestGuidance(wuType) {
|
|
313
|
-
const type = (wuType || 'feature').toLowerCase();
|
|
314
|
-
// Documentation WUs - no TDD, just format checks
|
|
315
|
-
if (DOCS_ONLY_TYPES.includes(type)) {
|
|
316
|
-
return `## Documentation Standards
|
|
317
|
-
|
|
318
|
-
**Format check only** - No TDD required for documentation WUs.
|
|
319
|
-
|
|
320
|
-
### Requirements
|
|
321
|
-
|
|
322
|
-
1. Run \`pnpm gates --docs-only\` before completion
|
|
323
|
-
2. Ensure markdown formatting is correct
|
|
324
|
-
3. Verify links are valid
|
|
325
|
-
4. Check spelling and grammar`;
|
|
326
|
-
}
|
|
327
|
-
// Visual/Design WUs - smoke tests + manual QA
|
|
328
|
-
if (SMOKE_TEST_TYPES.includes(type)) {
|
|
329
|
-
return `## Visual/Design Testing
|
|
330
|
-
|
|
331
|
-
**Smoke test + manual QA** - Visual WUs require different verification.
|
|
332
|
-
|
|
333
|
-
### Requirements
|
|
334
|
-
|
|
335
|
-
1. Create smoke test for component rendering (if applicable)
|
|
336
|
-
2. Verify visual appearance manually
|
|
337
|
-
3. Test responsive behavior across breakpoints
|
|
338
|
-
4. Check accessibility (keyboard navigation, screen reader)
|
|
339
|
-
5. Document manual QA results in completion notes`;
|
|
340
|
-
}
|
|
341
|
-
// Refactor WUs - existing tests must pass
|
|
342
|
-
if (EXISTING_TESTS_TYPES.includes(type)) {
|
|
343
|
-
return `## Refactor Testing
|
|
344
|
-
|
|
345
|
-
**Existing tests must pass** - Refactoring must not break current behavior.
|
|
346
|
-
|
|
347
|
-
### Requirements
|
|
348
|
-
|
|
349
|
-
1. Run all existing tests BEFORE refactoring
|
|
350
|
-
2. Run all existing tests AFTER refactoring
|
|
351
|
-
3. No new tests required unless behavior changes
|
|
352
|
-
4. If tests fail after refactor, the refactor introduced a bug`;
|
|
353
|
-
}
|
|
354
|
-
// Default: TDD required (feature, bug, tooling, enhancement)
|
|
355
|
-
return generateTDDDirective();
|
|
356
|
-
}
|
|
357
|
-
/**
|
|
358
|
-
* Generate the TDD directive section (WU-1585)
|
|
359
|
-
*
|
|
360
|
-
* Positioned immediately after </task> preamble per "Lost in the Middle" research.
|
|
361
|
-
* Critical instructions at START and END of prompt improve adherence.
|
|
362
|
-
*
|
|
363
|
-
* @returns {string} TDD directive section
|
|
364
|
-
*/
|
|
365
|
-
function generateTDDDirective() {
|
|
366
|
-
return `## ⛔ TDD DIRECTIVE — READ BEFORE CODING
|
|
367
|
-
|
|
368
|
-
**IF YOU WRITE IMPLEMENTATION CODE BEFORE A FAILING TEST, YOU HAVE FAILED THIS WU.**
|
|
369
|
-
|
|
370
|
-
### Test-First Workflow (MANDATORY)
|
|
371
|
-
|
|
372
|
-
1. Write a failing test for the acceptance criteria
|
|
373
|
-
2. Run the test to confirm it fails (RED)
|
|
374
|
-
3. Implement the minimum code to pass the test
|
|
375
|
-
4. Run the test to confirm it passes (GREEN)
|
|
376
|
-
5. Refactor if needed, keeping tests green
|
|
377
|
-
|
|
378
|
-
### Why This Matters
|
|
379
|
-
|
|
380
|
-
- Tests document expected behavior BEFORE implementation
|
|
381
|
-
- Prevents scope creep and over-engineering
|
|
382
|
-
- Ensures every feature has verification
|
|
383
|
-
- Failing tests prove the test actually tests something`;
|
|
384
|
-
}
|
|
272
|
+
// WU-1192: generateTestGuidance and related constants moved to @lumenflow/core
|
|
273
|
+
// See imports from '@lumenflow/core/dist/wu-spawn.js' above
|
|
385
274
|
/**
|
|
386
275
|
* Generate the context loading preamble
|
|
387
276
|
*
|
|
@@ -438,7 +327,7 @@ CRITICAL RULES - ENFORCE BEFORE EVERY ACTION:
|
|
|
438
327
|
- For ordinary errors: fix and retry autonomously (up to 3 attempts)
|
|
439
328
|
|
|
440
329
|
4. VERIFY COMPLETION before reporting success
|
|
441
|
-
- Run: node
|
|
330
|
+
- Run: node packages/@lumenflow/agent/dist/agent-verification.js ${id} (from shared checkout)
|
|
442
331
|
- Exit 0 = passed, Exit 1 = INCOMPLETE
|
|
443
332
|
- Never report "done" if verification fails
|
|
444
333
|
|
|
@@ -471,7 +360,7 @@ function generateCodexConstraints(id) {
|
|
|
471
360
|
|
|
472
361
|
1. **TDD checkpoint**: tests BEFORE implementation; never skip RED
|
|
473
362
|
2. **Stop on errors**: if any command fails, report BLOCKED (never DONE) with the error
|
|
474
|
-
3. **Verify before success**: run \`pnpm gates\` in the worktree, then run \`node
|
|
363
|
+
3. **Verify before success**: run \`pnpm gates\` in the worktree, then run \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\` (from the shared checkout)
|
|
475
364
|
4. **No fabrication**: if blockers remain or verification fails, report INCOMPLETE
|
|
476
365
|
5. **Git workflow**: avoid merge commits; let \`pnpm wu:done\` handle completion
|
|
477
366
|
6. **Scope discipline**: stay within \`code_paths\`; capture out-of-scope issues via \`pnpm mem:create\`
|
|
@@ -481,10 +370,10 @@ function generateCodexConstraints(id) {
|
|
|
481
370
|
* Generate mandatory agent advisory section
|
|
482
371
|
*
|
|
483
372
|
* @param {string[]} mandatoryAgents - Array of mandatory agent names
|
|
484
|
-
* @param {string}
|
|
373
|
+
* @param {string} _id - WU ID (reserved for future use)
|
|
485
374
|
* @returns {string} Mandatory agent section or empty string
|
|
486
375
|
*/
|
|
487
|
-
function generateMandatoryAgentSection(mandatoryAgents,
|
|
376
|
+
function generateMandatoryAgentSection(mandatoryAgents, _id) {
|
|
488
377
|
if (mandatoryAgents.length === 0) {
|
|
489
378
|
return '';
|
|
490
379
|
}
|
|
@@ -496,7 +385,7 @@ Based on code_paths, the following agents MUST be invoked:
|
|
|
496
385
|
|
|
497
386
|
${agentList}
|
|
498
387
|
|
|
499
|
-
Run: pnpm orchestrate:
|
|
388
|
+
Run: pnpm orchestrate:monitor to check agent status
|
|
500
389
|
`;
|
|
501
390
|
}
|
|
502
391
|
/**
|
|
@@ -613,54 +502,8 @@ When finishing, provide structured output:
|
|
|
613
502
|
|
|
614
503
|
This format enables orchestrator to track progress across waves.`;
|
|
615
504
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
*
|
|
619
|
-
* Provides guidance on mem:signal for parallel agent coordination,
|
|
620
|
-
* orchestrate:status for dashboard checks, and abandoned WU handling.
|
|
621
|
-
*
|
|
622
|
-
* @param {string} id - WU ID
|
|
623
|
-
* @returns {string} Agent coordination section
|
|
624
|
-
*/
|
|
625
|
-
export function generateAgentCoordinationSection(id) {
|
|
626
|
-
return `## Agent Coordination (Parallel Work)
|
|
627
|
-
|
|
628
|
-
### ⚠️ CRITICAL: Use mem:signal, NOT TaskOutput
|
|
629
|
-
|
|
630
|
-
**DO NOT** use TaskOutput to check agent progress - it returns full transcripts
|
|
631
|
-
and causes "prompt too long" errors. Always use the memory layer instead:
|
|
632
|
-
|
|
633
|
-
\`\`\`bash
|
|
634
|
-
# ✅ CORRECT: Compact signals (~6 lines)
|
|
635
|
-
pnpm mem:inbox --since 30m
|
|
636
|
-
|
|
637
|
-
# ❌ WRONG: Full transcripts (context explosion)
|
|
638
|
-
# TaskOutput with block=false <-- NEVER DO THIS FOR MONITORING
|
|
639
|
-
\`\`\`
|
|
640
|
-
|
|
641
|
-
### Automatic Completion Signals
|
|
642
|
-
|
|
643
|
-
\`wu:done\` automatically broadcasts completion signals. You do not need to
|
|
644
|
-
manually signal completion - just run \`wu:done\` and orchestrators will
|
|
645
|
-
see your signal via \`mem:inbox\`.
|
|
646
|
-
|
|
647
|
-
### Progress Signals (Optional)
|
|
648
|
-
|
|
649
|
-
For long-running work, send progress signals at milestones:
|
|
650
|
-
|
|
651
|
-
\`\`\`bash
|
|
652
|
-
pnpm mem:signal "50% complete: tests passing, implementing adapter" --wu ${id}
|
|
653
|
-
pnpm mem:signal "Blocked: waiting for WU-XXX dependency" --wu ${id}
|
|
654
|
-
\`\`\`
|
|
655
|
-
|
|
656
|
-
### Checking Status
|
|
657
|
-
|
|
658
|
-
\`\`\`bash
|
|
659
|
-
pnpm orchestrate:init-status -i INIT-XXX # Initiative progress (compact)
|
|
660
|
-
pnpm mem:inbox --since 1h # Recent signals from all agents
|
|
661
|
-
pnpm mem:inbox --lane "Experience: Web" # Lane-specific signals
|
|
662
|
-
\`\`\``;
|
|
663
|
-
}
|
|
505
|
+
// WU-1203: generateAgentCoordinationSection is now imported from @lumenflow/core
|
|
506
|
+
// The core version reads config and generates dynamic guidance based on progress_signals settings
|
|
664
507
|
/**
|
|
665
508
|
* Generate quick fix commands section (WU-1987)
|
|
666
509
|
*
|
|
@@ -698,7 +541,7 @@ If you encounter a "worktree required" or "commit blocked" error:
|
|
|
698
541
|
1. **Check existing worktrees**: \`git worktree list\`
|
|
699
542
|
2. **Navigate to the worktree**: \`cd ${worktreePath || 'worktrees/<lane>-wu-xxx'}\`
|
|
700
543
|
3. **Retry your operation** from within the worktree
|
|
701
|
-
4. **Use relative paths only** (never absolute paths
|
|
544
|
+
4. **Use relative paths only** (never absolute paths starting with /)
|
|
702
545
|
|
|
703
546
|
### Common Causes
|
|
704
547
|
|
|
@@ -850,7 +693,7 @@ pnpm mem:triage --wu ${id} # List discoveries for this WU
|
|
|
850
693
|
pnpm mem:triage --promote <node-id> --lane "<lane>" # Create Bug WU (human action)
|
|
851
694
|
\`\`\`
|
|
852
695
|
|
|
853
|
-
See:
|
|
696
|
+
See: https://lumenflow.dev/reference/agent-invocation-guide/ §Bug Discovery`;
|
|
854
697
|
}
|
|
855
698
|
/**
|
|
856
699
|
* Generate lane-specific guidance
|
|
@@ -949,6 +792,57 @@ pnpm wu:done --id ${id}
|
|
|
949
792
|
|
|
950
793
|
**Do not ask** "should I run wu:done?" — just run it when gates pass.`;
|
|
951
794
|
}
|
|
795
|
+
/**
|
|
796
|
+
* WU-1253: Try to load templates for spawn prompt sections.
|
|
797
|
+
*
|
|
798
|
+
* Implements shadow mode: tries templates first, returns empty map
|
|
799
|
+
* if templates aren't available (caller uses hardcoded fallback).
|
|
800
|
+
*
|
|
801
|
+
* @param clientName - Client name for overrides (e.g., 'claude-code', 'cursor')
|
|
802
|
+
* @param context - Token values for replacement
|
|
803
|
+
* @returns Map of template id to processed content, empty if templates unavailable
|
|
804
|
+
*/
|
|
805
|
+
function tryLoadTemplates(clientName, context) {
|
|
806
|
+
const result = new Map();
|
|
807
|
+
try {
|
|
808
|
+
const baseDir = process.cwd();
|
|
809
|
+
const templates = loadTemplatesWithOverrides(baseDir, clientName);
|
|
810
|
+
// Process each template: replace tokens
|
|
811
|
+
for (const [id, template] of templates) {
|
|
812
|
+
const processed = replaceTokens(template.content, context);
|
|
813
|
+
result.set(id, processed);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
catch {
|
|
817
|
+
// Template loading failed - return empty map for hardcoded fallback
|
|
818
|
+
}
|
|
819
|
+
return result;
|
|
820
|
+
}
|
|
821
|
+
/**
|
|
822
|
+
* WU-1253: Build template context from WU document.
|
|
823
|
+
*
|
|
824
|
+
* @param doc - WU YAML document
|
|
825
|
+
* @param id - WU ID
|
|
826
|
+
* @returns Context for template token replacement
|
|
827
|
+
*/
|
|
828
|
+
function buildSpawnTemplateContext(doc, id) {
|
|
829
|
+
const lane = doc.lane || '';
|
|
830
|
+
const laneParent = lane.split(':')[0]?.trim() || '';
|
|
831
|
+
const type = (doc.type || 'feature').toLowerCase();
|
|
832
|
+
return {
|
|
833
|
+
WU_ID: id,
|
|
834
|
+
LANE: lane,
|
|
835
|
+
TYPE: type,
|
|
836
|
+
TITLE: doc.title || '',
|
|
837
|
+
DESCRIPTION: doc.description || '',
|
|
838
|
+
WORKTREE_PATH: doc.worktree_path || '',
|
|
839
|
+
laneParent,
|
|
840
|
+
// Lowercase aliases for condition evaluation
|
|
841
|
+
type,
|
|
842
|
+
lane,
|
|
843
|
+
worktreePath: doc.worktree_path || '',
|
|
844
|
+
};
|
|
845
|
+
}
|
|
952
846
|
function generateClientBlocksSection(clientContext) {
|
|
953
847
|
if (!clientContext?.config?.blocks?.length)
|
|
954
848
|
return '';
|
|
@@ -972,38 +866,63 @@ function generateClientBlocksSection(clientContext) {
|
|
|
972
866
|
export function generateTaskInvocation(doc, id, strategy, options = {}) {
|
|
973
867
|
const codePaths = doc.code_paths || [];
|
|
974
868
|
const mandatoryAgents = detectMandatoryAgents(codePaths);
|
|
869
|
+
// WU-1253: Try loading templates (shadow mode - falls back to hardcoded if unavailable)
|
|
870
|
+
const clientName = options.client?.name || 'claude-code';
|
|
871
|
+
const templateContext = buildSpawnTemplateContext(doc, id);
|
|
872
|
+
const templates = tryLoadTemplates(clientName, templateContext);
|
|
975
873
|
const preamble = generatePreamble(id, strategy);
|
|
976
|
-
// WU-1142: Use type-aware test guidance instead of hardcoded TDD directive
|
|
977
|
-
const testGuidance = generateTestGuidance(doc.type);
|
|
978
874
|
const clientContext = options.client;
|
|
979
875
|
const config = options.config || getConfig();
|
|
876
|
+
// WU-1288: Resolve methodology policy from config
|
|
877
|
+
const policy = resolvePolicy(config);
|
|
878
|
+
// WU-1142: Use type-aware test guidance instead of hardcoded TDD directive
|
|
879
|
+
// WU-1288: Use policy-based test guidance that respects methodology.testing config
|
|
880
|
+
// WU-1253: Try template first, fall back to policy-based guidance
|
|
881
|
+
const testGuidance = templates.get('tdd-directive') || generatePolicyBasedTestGuidance(doc.type, policy);
|
|
882
|
+
// WU-1288: Generate enforcement summary from resolved policy
|
|
883
|
+
const enforcementSummary = generateEnforcementSummary(policy);
|
|
884
|
+
// WU-1288: Generate mandatory standards based on resolved policy
|
|
885
|
+
const mandatoryStandards = generateMandatoryStandards(policy);
|
|
980
886
|
// WU-1142: Pass lane to get byLane skills
|
|
981
887
|
const clientSkillsGuidance = generateClientSkillsGuidance(clientContext, doc.lane);
|
|
982
|
-
|
|
983
|
-
|
|
888
|
+
// WU-1253: Try template for skills-selection, build skills section
|
|
889
|
+
const skillsTemplateContent = templates.get('skills-selection');
|
|
890
|
+
const skillsGuidanceSuffix = clientSkillsGuidance ? '\n' + clientSkillsGuidance : '';
|
|
891
|
+
const skillsBaseContent = skillsTemplateContent || generateSkillsSelectionSection(doc, config, clientContext?.name);
|
|
892
|
+
const skillsSection = skillsBaseContent + skillsGuidanceSuffix;
|
|
984
893
|
const clientBlocks = generateClientBlocksSection(clientContext);
|
|
985
894
|
const mandatorySection = generateMandatoryAgentSection(mandatoryAgents, id);
|
|
986
895
|
const laneGuidance = generateLaneGuidance(doc.lane);
|
|
987
|
-
|
|
988
|
-
const
|
|
896
|
+
// WU-1253: Try template for bug-discovery
|
|
897
|
+
const bugDiscoverySection = templates.get('bug-discovery') || generateBugDiscoverySection(id);
|
|
898
|
+
// WU-1253: Try template for constraints
|
|
899
|
+
const constraints = templates.get('constraints') || generateConstraints(id);
|
|
989
900
|
const implementationContext = generateImplementationContext(doc);
|
|
990
901
|
// WU-2252: Generate invariants/prior-art section for code_paths
|
|
991
902
|
const invariantsPriorArt = generateInvariantsPriorArtSection(codePaths);
|
|
992
903
|
// WU-1986: Anthropic multi-agent best practices sections
|
|
993
|
-
|
|
994
|
-
const
|
|
995
|
-
const
|
|
996
|
-
const
|
|
904
|
+
// WU-1253: Try templates for these sections
|
|
905
|
+
const effortScaling = templates.get('effort-scaling') || generateEffortScalingRules();
|
|
906
|
+
const parallelToolCalls = templates.get('parallel-tool-calls') || generateParallelToolCallGuidance();
|
|
907
|
+
const searchHeuristics = templates.get('search-heuristics') || generateIterativeSearchHeuristics();
|
|
908
|
+
const tokenBudget = templates.get('token-budget') || generateTokenBudgetAwareness(id);
|
|
997
909
|
const completionFormat = generateCompletionFormat(id);
|
|
998
910
|
// WU-1987: Agent coordination and quick fix sections
|
|
999
911
|
const agentCoordination = generateAgentCoordinationSection(id);
|
|
1000
|
-
|
|
912
|
+
// WU-1253: Try template for quick-fix-commands
|
|
913
|
+
const quickFix = templates.get('quick-fix-commands') || generateQuickFixCommands();
|
|
1001
914
|
// WU-2107: Lane selection guidance
|
|
1002
|
-
|
|
915
|
+
// WU-1253: Try template for lane-selection
|
|
916
|
+
const laneSelection = templates.get('lane-selection') || generateLaneSelectionSection();
|
|
1003
917
|
// WU-2362: Worktree path guidance for sub-agents
|
|
1004
918
|
const worktreeGuidance = generateWorktreePathGuidance(doc.worktree_path);
|
|
1005
919
|
// WU-1134: Worktree block recovery guidance
|
|
1006
|
-
|
|
920
|
+
// WU-1253: Try template for worktree-recovery
|
|
921
|
+
const worktreeBlockRecovery = templates.get('worktree-recovery') || generateWorktreeBlockRecoverySection(doc.worktree_path);
|
|
922
|
+
// WU-1240: Memory context section
|
|
923
|
+
// Include if explicitly enabled and not disabled via noContext
|
|
924
|
+
const shouldIncludeMemoryContext = options.includeMemoryContext && !options.noContext;
|
|
925
|
+
const memoryContextSection = shouldIncludeMemoryContext ? options.memoryContextContent || '' : '';
|
|
1007
926
|
// Generate thinking mode sections if applicable
|
|
1008
927
|
const executionModeSection = generateExecutionModeSection(options);
|
|
1009
928
|
const thinkToolGuidance = generateThinkToolGuidance(options);
|
|
@@ -1049,19 +968,13 @@ ${codePaths.length > 0 ? codePaths.map((p) => `- ${p}`).join('\n') : '- No code
|
|
|
1049
968
|
${mandatorySection}${invariantsPriorArt ? `---\n\n${invariantsPriorArt}\n\n` : ''}${implementationContext ? `---\n\n${implementationContext}\n\n` : ''}---
|
|
1050
969
|
|
|
1051
970
|
${thinkingBlock}${skillsSection}
|
|
1052
|
-
---
|
|
971
|
+
${memoryContextSection ? `---\n\n${memoryContextSection}\n\n` : ''}---
|
|
972
|
+
|
|
973
|
+
${mandatoryStandards}
|
|
1053
974
|
|
|
1054
|
-
|
|
975
|
+
---
|
|
1055
976
|
|
|
1056
|
-
|
|
1057
|
-
- **TDD**: Failing test first, then implementation, then passing test. 90%+ coverage on new application code
|
|
1058
|
-
- **Hexagonal Architecture**: Ports-first design. No application -> infrastructure imports
|
|
1059
|
-
- **SOLID/DRY/YAGNI/KISS**: No over-engineering, no premature abstraction
|
|
1060
|
-
- **Library-First**: Search context7 before writing custom code. No reinventing wheels
|
|
1061
|
-
- **Code Quality**: No string literals, no magic numbers, no brittle regexes when libraries exist
|
|
1062
|
-
- **Worktree Discipline**: ALWAYS use \`pnpm wu:claim\` to create worktrees (never \`git worktree add\` directly). Work ONLY in the worktree, never edit main
|
|
1063
|
-
- **Documentation**: Update tooling docs if changing tools. Keep docs in sync with code
|
|
1064
|
-
- **Sub-agents**: Use Explore agent for codebase investigation. Activate mandatory agents (security-auditor for PHI/auth, beacon-guardian for LLM/prompts)
|
|
977
|
+
${enforcementSummary}
|
|
1065
978
|
|
|
1066
979
|
${clientBlocks ? `---\n\n${clientBlocks}\n\n` : ''}${worktreeGuidance ? `---\n\n${worktreeGuidance}\n\n` : ''}---
|
|
1067
980
|
|
|
@@ -1161,6 +1074,9 @@ export function generateCodexPrompt(doc, id, strategy, options = {}) {
|
|
|
1161
1074
|
const thinkingBlock = thinkingSections ? `${thinkingSections}\n\n---\n\n` : '';
|
|
1162
1075
|
// WU-1134: Worktree block recovery guidance
|
|
1163
1076
|
const worktreeBlockRecovery = generateWorktreeBlockRecoverySection(doc.worktree_path);
|
|
1077
|
+
// WU-1240: Memory context section
|
|
1078
|
+
const shouldIncludeMemoryContext = options.includeMemoryContext && !options.noContext;
|
|
1079
|
+
const memoryContextSection = shouldIncludeMemoryContext ? options.memoryContextContent || '' : '';
|
|
1164
1080
|
// WU-1131: Warning banner at start, end sentinel after constraints
|
|
1165
1081
|
// WU-1142: Type-aware test guidance
|
|
1166
1082
|
return `${TRUNCATION_WARNING_BANNER}# ${id}: ${doc.title || 'Untitled'}
|
|
@@ -1200,8 +1116,7 @@ ${formatAcceptance(doc.acceptance)}
|
|
|
1200
1116
|
---
|
|
1201
1117
|
|
|
1202
1118
|
${skillsSection}
|
|
1203
|
-
|
|
1204
|
-
---
|
|
1119
|
+
${memoryContextSection ? `---\n\n${memoryContextSection}\n\n` : ''}---
|
|
1205
1120
|
|
|
1206
1121
|
## Action
|
|
1207
1122
|
|
|
@@ -1212,7 +1127,7 @@ ${action}
|
|
|
1212
1127
|
## Verification
|
|
1213
1128
|
|
|
1214
1129
|
- Run in worktree: \`pnpm gates\`
|
|
1215
|
-
- From shared checkout: \`node
|
|
1130
|
+
- From shared checkout: \`node packages/@lumenflow/agent/dist/agent-verification.js ${id}\`
|
|
1216
1131
|
|
|
1217
1132
|
---
|
|
1218
1133
|
|
|
@@ -1256,16 +1171,7 @@ export function generateLaneOccupationWarning(lockMetadata, targetWuId, options
|
|
|
1256
1171
|
warning += ` 3. Block ${lockMetadata.wuId} if work is stalled: pnpm wu:block --id ${lockMetadata.wuId}`;
|
|
1257
1172
|
return warning;
|
|
1258
1173
|
}
|
|
1259
|
-
|
|
1260
|
-
* Main entry point
|
|
1261
|
-
*/
|
|
1262
|
-
async function main() {
|
|
1263
|
-
// WU-2202: Validate dependencies BEFORE any other operation
|
|
1264
|
-
// This prevents false lane occupancy reports when yaml package is missing
|
|
1265
|
-
const depResult = await validateSpawnDependencies();
|
|
1266
|
-
if (!depResult.valid) {
|
|
1267
|
-
die(formatDependencyError('wu:spawn', depResult.missing));
|
|
1268
|
-
}
|
|
1174
|
+
function parseAndValidateArgs() {
|
|
1269
1175
|
const args = createWUParser({
|
|
1270
1176
|
name: 'wu-spawn',
|
|
1271
1177
|
description: 'Generate Task tool invocation for sub-agent WU execution',
|
|
@@ -1278,6 +1184,7 @@ async function main() {
|
|
|
1278
1184
|
WU_OPTIONS.parentWu, // WU-1945: Parent WU for spawn registry tracking
|
|
1279
1185
|
WU_OPTIONS.client,
|
|
1280
1186
|
WU_OPTIONS.vendor,
|
|
1187
|
+
WU_OPTIONS.noContext, // WU-1240: Skip memory context injection
|
|
1281
1188
|
],
|
|
1282
1189
|
required: ['id'],
|
|
1283
1190
|
allowPositionalId: true,
|
|
@@ -1289,42 +1196,92 @@ async function main() {
|
|
|
1289
1196
|
catch (e) {
|
|
1290
1197
|
die(e.message);
|
|
1291
1198
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1199
|
+
return args;
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* Load and validate WU document from YAML file
|
|
1203
|
+
*/
|
|
1204
|
+
function loadWUDocument(id, wuPath) {
|
|
1297
1205
|
// Check if WU file exists
|
|
1298
|
-
if (!existsSync(
|
|
1299
|
-
die(`WU file not found: ${
|
|
1206
|
+
if (!existsSync(wuPath)) {
|
|
1207
|
+
die(`WU file not found: ${wuPath}\n\n` +
|
|
1300
1208
|
`Cannot spawn a sub-agent for a WU that doesn't exist.\n\n` +
|
|
1301
1209
|
`Options:\n` +
|
|
1302
1210
|
` 1. Create the WU first: pnpm wu:create --id ${id} --lane <lane> --title "..."\n` +
|
|
1303
1211
|
` 2. Check if the WU ID is correct`);
|
|
1304
1212
|
}
|
|
1305
|
-
// Read
|
|
1306
|
-
let doc;
|
|
1213
|
+
// Read WU file
|
|
1307
1214
|
let text;
|
|
1308
1215
|
try {
|
|
1309
|
-
text = readFileSync(
|
|
1216
|
+
text = readFileSync(wuPath, { encoding: FILE_SYSTEM.UTF8 });
|
|
1310
1217
|
}
|
|
1311
1218
|
catch (e) {
|
|
1312
|
-
die(`Failed to read WU file: ${
|
|
1219
|
+
die(`Failed to read WU file: ${wuPath}\n\n` +
|
|
1313
1220
|
`Error: ${e.message}\n\n` +
|
|
1314
1221
|
`Options:\n` +
|
|
1315
|
-
` 1. Check file permissions: ls -la ${
|
|
1222
|
+
` 1. Check file permissions: ls -la ${wuPath}\n` +
|
|
1316
1223
|
` 2. Ensure the file exists and is readable`);
|
|
1317
1224
|
}
|
|
1225
|
+
// Parse YAML
|
|
1318
1226
|
try {
|
|
1319
|
-
|
|
1227
|
+
return parseYAML(text);
|
|
1320
1228
|
}
|
|
1321
1229
|
catch (e) {
|
|
1322
|
-
die(`Failed to parse WU YAML ${
|
|
1230
|
+
die(`Failed to parse WU YAML ${wuPath}\n\n` +
|
|
1323
1231
|
`Error: ${e.message}\n\n` +
|
|
1324
1232
|
`Options:\n` +
|
|
1325
1233
|
` 1. Validate YAML syntax: pnpm wu:validate --id ${id}\n` +
|
|
1326
1234
|
` 2. Fix YAML errors manually and retry`);
|
|
1327
1235
|
}
|
|
1236
|
+
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Resolve the client name from args and config
|
|
1239
|
+
*/
|
|
1240
|
+
function resolveClientName(args, config) {
|
|
1241
|
+
let clientName = args.client;
|
|
1242
|
+
if (!clientName && args.vendor) {
|
|
1243
|
+
console.warn(`${LOG_PREFIX} ${EMOJI.WARNING} Warning: --vendor is deprecated. Use --client.`);
|
|
1244
|
+
clientName = args.vendor;
|
|
1245
|
+
}
|
|
1246
|
+
// Codex handling (deprecated legacy flag)
|
|
1247
|
+
if (args.codex && !clientName) {
|
|
1248
|
+
console.warn(`${LOG_PREFIX} ${EMOJI.WARNING} Warning: --codex is deprecated. Use --client codex-cli.`);
|
|
1249
|
+
clientName = 'codex-cli';
|
|
1250
|
+
}
|
|
1251
|
+
return clientName || config.agents.defaultClient || 'claude-code';
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Check lane occupation and warn if occupied by a different WU
|
|
1255
|
+
*/
|
|
1256
|
+
async function checkAndWarnLaneOccupation(lane, id) {
|
|
1257
|
+
if (!lane)
|
|
1258
|
+
return;
|
|
1259
|
+
const existingLock = checkLaneOccupation(lane);
|
|
1260
|
+
if (existingLock && existingLock.wuId !== id) {
|
|
1261
|
+
// Lane is occupied by a different WU
|
|
1262
|
+
const { isLockStale } = await import('@lumenflow/core/dist/lane-lock.js');
|
|
1263
|
+
const isStale = isLockStale(existingLock);
|
|
1264
|
+
const warning = generateLaneOccupationWarning(existingLock, id, { isStale });
|
|
1265
|
+
console.warn(`${LOG_PREFIX} ${EMOJI.WARNING}\n${warning}\n`);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Main entry point
|
|
1270
|
+
*/
|
|
1271
|
+
async function main() {
|
|
1272
|
+
// WU-2202: Validate dependencies BEFORE any other operation
|
|
1273
|
+
// This prevents false lane occupancy reports when yaml package is missing
|
|
1274
|
+
const depResult = await validateSpawnDependencies();
|
|
1275
|
+
if (!depResult.valid) {
|
|
1276
|
+
die(formatDependencyError('wu:spawn', depResult.missing));
|
|
1277
|
+
}
|
|
1278
|
+
const args = parseAndValidateArgs();
|
|
1279
|
+
const id = args.id.toUpperCase();
|
|
1280
|
+
if (!PATTERNS.WU_ID.test(id)) {
|
|
1281
|
+
die(`Invalid WU id '${args.id}'. Expected format WU-123`);
|
|
1282
|
+
}
|
|
1283
|
+
const wuPath = WU_PATHS.WU(id);
|
|
1284
|
+
const doc = loadWUDocument(id, wuPath);
|
|
1328
1285
|
// Warn if WU is not in ready or in_progress status
|
|
1329
1286
|
const validStatuses = [WU_STATUS.READY, WU_STATUS.IN_PROGRESS];
|
|
1330
1287
|
if (!validStatuses.includes(doc.status)) {
|
|
@@ -1333,17 +1290,7 @@ async function main() {
|
|
|
1333
1290
|
console.warn('');
|
|
1334
1291
|
}
|
|
1335
1292
|
// WU-1603: Check if lane is already occupied and warn
|
|
1336
|
-
|
|
1337
|
-
if (lane) {
|
|
1338
|
-
const existingLock = checkLaneOccupation(lane);
|
|
1339
|
-
if (existingLock && existingLock.wuId !== id) {
|
|
1340
|
-
// Lane is occupied by a different WU
|
|
1341
|
-
const { isLockStale } = await import('@lumenflow/core/dist/lane-lock.js');
|
|
1342
|
-
const isStale = isLockStale(existingLock);
|
|
1343
|
-
const warning = generateLaneOccupationWarning(existingLock, id, { isStale });
|
|
1344
|
-
console.warn(`${LOG_PREFIX} ${EMOJI.WARNING}\n${warning}\n`);
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1293
|
+
await checkAndWarnLaneOccupation(doc.lane, id);
|
|
1347
1294
|
// Build thinking mode options for task invocation
|
|
1348
1295
|
const thinkingOptions = {
|
|
1349
1296
|
thinking: args.thinking,
|
|
@@ -1352,21 +1299,25 @@ async function main() {
|
|
|
1352
1299
|
};
|
|
1353
1300
|
// Client Resolution
|
|
1354
1301
|
const config = getConfig();
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
if (
|
|
1363
|
-
|
|
1364
|
-
|
|
1302
|
+
const clientName = resolveClientName(args, config);
|
|
1303
|
+
// WU-1240: Generate memory context if not skipped
|
|
1304
|
+
const baseDir = process.cwd();
|
|
1305
|
+
let memoryContextContent = '';
|
|
1306
|
+
const shouldIncludeMemoryContext = !args.noContext;
|
|
1307
|
+
if (shouldIncludeMemoryContext) {
|
|
1308
|
+
const isMemoryInitialized = await checkMemoryLayerInitialized(baseDir);
|
|
1309
|
+
if (isMemoryInitialized) {
|
|
1310
|
+
const maxSize = getMemoryContextMaxSize(config);
|
|
1311
|
+
memoryContextContent = await generateMemoryContextSection(baseDir, {
|
|
1312
|
+
wuId: id,
|
|
1313
|
+
lane: doc.lane,
|
|
1314
|
+
maxSize,
|
|
1315
|
+
});
|
|
1316
|
+
if (memoryContextContent) {
|
|
1317
|
+
console.log(`${LOG_PREFIX} Memory context loaded (${memoryContextContent.length} bytes)`);
|
|
1318
|
+
}
|
|
1365
1319
|
}
|
|
1366
1320
|
}
|
|
1367
|
-
if (!clientName) {
|
|
1368
|
-
clientName = config.agents.defaultClient || 'claude-code';
|
|
1369
|
-
}
|
|
1370
1321
|
// Create strategy
|
|
1371
1322
|
const strategy = SpawnStrategyFactory.create(clientName);
|
|
1372
1323
|
const clientContext = { name: clientName, config: resolveClientConfig(config, clientName) };
|
|
@@ -1386,6 +1337,11 @@ async function main() {
|
|
|
1386
1337
|
...thinkingOptions,
|
|
1387
1338
|
client: clientContext,
|
|
1388
1339
|
config,
|
|
1340
|
+
// WU-1240: Include memory context in spawn prompt
|
|
1341
|
+
baseDir,
|
|
1342
|
+
includeMemoryContext: shouldIncludeMemoryContext && memoryContextContent.length > 0,
|
|
1343
|
+
memoryContextContent,
|
|
1344
|
+
noContext: args.noContext,
|
|
1389
1345
|
});
|
|
1390
1346
|
console.log(`${LOG_PREFIX} Generated Task tool invocation for ${id}`);
|
|
1391
1347
|
console.log(`${LOG_PREFIX} Copy the block below to spawn a sub-agent:\n`);
|
|
@@ -1409,5 +1365,5 @@ async function main() {
|
|
|
1409
1365
|
// path but import.meta.url resolves to the real path - they never match
|
|
1410
1366
|
import { runCLI } from './cli-entry-point.js';
|
|
1411
1367
|
if (import.meta.main) {
|
|
1412
|
-
runCLI(main);
|
|
1368
|
+
void runCLI(main);
|
|
1413
1369
|
}
|