@lumenflow/cli 4.21.0 → 4.23.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 +30 -27
- package/dist/delegation-list.js +86 -53
- package/dist/delegation-list.js.map +1 -1
- package/dist/gates-plan-resolvers.js +24 -1
- package/dist/gates-plan-resolvers.js.map +1 -1
- package/dist/init-templates.js +13 -0
- package/dist/init-templates.js.map +1 -1
- package/dist/initiative-create.js +1 -1
- package/dist/orchestrate-init-status.js +24 -31
- package/dist/orchestrate-init-status.js.map +1 -1
- package/dist/orchestrate-initiative.js +48 -3
- package/dist/orchestrate-initiative.js.map +1 -1
- package/dist/orchestrate-integrity.js +133 -0
- package/dist/orchestrate-integrity.js.map +1 -0
- package/dist/orchestrate-monitor.js +488 -1
- package/dist/orchestrate-monitor.js.map +1 -1
- package/dist/public-manifest.js +4 -4
- package/dist/public-manifest.js.map +1 -1
- package/package.json +8 -8
- package/packs/agent-runtime/.turbo/turbo-build.log +1 -1
- package/packs/agent-runtime/package.json +1 -1
- package/packs/sidekick/.turbo/turbo-build.log +1 -1
- package/packs/sidekick/package.json +1 -1
- package/packs/software-delivery/.turbo/turbo-build.log +1 -1
- package/packs/software-delivery/package.json +1 -1
- package/templates/core/LUMENFLOW.md.template +5 -3
- package/templates/core/ai/onboarding/first-wu-mistakes.md.template +2 -2
- package/templates/core/ai/onboarding/initiative-orchestration.md.template +83 -27
- package/templates/core/ai/onboarding/quick-ref-commands.md.template +5 -5
- package/templates/core/ai/onboarding/starting-prompt.md.template +1 -1
- package/templates/core/ai/onboarding/vendor-support.md.template +13 -0
|
@@ -16,12 +16,32 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { Command } from 'commander';
|
|
18
18
|
import chalk from 'chalk';
|
|
19
|
-
import { loadInitiativeWUs, loadMultipleInitiatives, buildExecutionPlanWithLockPolicy, resolveLaneConfigsFromConfig, formatExecutionPlan, formatExecutionPlanWithEmbeddedSpawns, calculateProgress, formatProgress, buildCheckpointWave, formatCheckpointOutput, validateCheckpointFlags, resolveCheckpointModeAsync, LOG_PREFIX, } from '@lumenflow/initiatives';
|
|
19
|
+
import { loadInitiativeWUs, loadMultipleInitiatives, buildExecutionPlanWithLockPolicy, resolveLaneConfigsFromConfig, formatExecutionPlan, formatExecutionPlanWithEmbeddedSpawns, calculateProgress, formatProgress, buildCheckpointWave, formatCheckpointOutput, writeExecutionPlanArtifacts, validateCheckpointFlags, resolveCheckpointModeAsync, LOG_PREFIX, } from '@lumenflow/initiatives';
|
|
20
20
|
import { EXIT_CODES } from '@lumenflow/core/wu-constants';
|
|
21
21
|
import { getConfig } from '@lumenflow/core/config';
|
|
22
22
|
import { getErrorMessage, ProcessExitError } from '@lumenflow/core/error-handler';
|
|
23
|
+
import { ORCHESTRATION_STATUS_VALUES } from '@lumenflow/control-plane-sdk';
|
|
23
24
|
import { runCLI } from './cli-entry-point.js';
|
|
25
|
+
import { loadInitiativeExecutionSummary, } from './orchestrate-monitor.js';
|
|
26
|
+
import { readMaxActiveWorkersFromConfig, readStallThresholdMs } from './orchestrate-integrity.js';
|
|
24
27
|
const VALID_CLIENTS = ['claude-code', 'codex-cli', 'gemini-cli', 'cursor', 'windsurf'];
|
|
28
|
+
export function mapExecutionSummaryToCheckpointEvidence(summary) {
|
|
29
|
+
return summary.wus.map((wu) => ({
|
|
30
|
+
wuId: wu.wuId,
|
|
31
|
+
handoffEmitted: wu.state === ORCHESTRATION_STATUS_VALUES.HANDOFF_EMITTED || wu.launchReceipt !== undefined,
|
|
32
|
+
active: wu.state === ORCHESTRATION_STATUS_VALUES.ACTIVE,
|
|
33
|
+
workerReturned: wu.state === ORCHESTRATION_STATUS_VALUES.WORKER_RETURNED,
|
|
34
|
+
stampPresent: wu.stampPresent,
|
|
35
|
+
worktreePresent: wu.worktreePresent,
|
|
36
|
+
logicalWave: wu.logicalWave,
|
|
37
|
+
launchAttempt: wu.launchAttempt,
|
|
38
|
+
blockedReason: wu.state === ORCHESTRATION_STATUS_VALUES.BLOCKED ? wu.reason : undefined,
|
|
39
|
+
readyForFinish: wu.state === ORCHESTRATION_STATUS_VALUES.WORKER_RETURNED && wu.worktreePresent,
|
|
40
|
+
needsRelaunch: wu.state === ORCHESTRATION_STATUS_VALUES.WORKER_RETURNED && !wu.worktreePresent,
|
|
41
|
+
contaminatedPaths: wu.contaminatedPaths,
|
|
42
|
+
stalled: wu.stalled,
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
25
45
|
const program = new Command()
|
|
26
46
|
.name('orchestrate-initiative')
|
|
27
47
|
.description('Orchestrate initiative execution with parallel agent spawning')
|
|
@@ -31,8 +51,15 @@ const program = new Command()
|
|
|
31
51
|
.option('-c, --checkpoint-per-wave', 'Spawn next wave then exit (no polling)')
|
|
32
52
|
.option('--no-checkpoint', 'Force polling mode')
|
|
33
53
|
.option('--client <name>', 'Agent client (claude-code, codex-cli, gemini-cli, cursor, windsurf)')
|
|
54
|
+
.option('--max-active-workers <count>', 'Cap concurrent active workers; overrides software_delivery.orchestration.max_active_workers', (value) => {
|
|
55
|
+
const parsed = Number.parseInt(value, 10);
|
|
56
|
+
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
57
|
+
throw new Error(`Invalid --max-active-workers: expected a non-negative integer`);
|
|
58
|
+
}
|
|
59
|
+
return parsed;
|
|
60
|
+
})
|
|
34
61
|
.action(async (options) => {
|
|
35
|
-
const { initiative: initIds, dryRun, progress: progressOnly, checkpointPerWave, checkpoint, client: clientArg, } = options;
|
|
62
|
+
const { initiative: initIds, dryRun, progress: progressOnly, checkpointPerWave, checkpoint, client: clientArg, maxActiveWorkers: maxActiveWorkersFlag, } = options;
|
|
36
63
|
const noCheckpoint = checkpoint === false;
|
|
37
64
|
try {
|
|
38
65
|
validateCheckpointFlags({ checkpointPerWave, dryRun, noCheckpoint });
|
|
@@ -91,7 +118,18 @@ const program = new Command()
|
|
|
91
118
|
console.error(chalk.red(message));
|
|
92
119
|
throw new ProcessExitError(message, EXIT_CODES.ERROR);
|
|
93
120
|
}
|
|
94
|
-
const
|
|
121
|
+
const stallThresholdMs = readStallThresholdMs(config);
|
|
122
|
+
const executionSummary = await loadInitiativeExecutionSummary(process.cwd(), initIds[0], wus, { stallThresholdMs });
|
|
123
|
+
const checkpointEvidence = mapExecutionSummaryToCheckpointEvidence(executionSummary);
|
|
124
|
+
const maxActiveWorkers = typeof maxActiveWorkersFlag === 'number'
|
|
125
|
+
? maxActiveWorkersFlag
|
|
126
|
+
: readMaxActiveWorkersFromConfig(config);
|
|
127
|
+
const waveData = buildCheckpointWave(initIds[0], {
|
|
128
|
+
dryRun,
|
|
129
|
+
clientName,
|
|
130
|
+
executionEvidence: checkpointEvidence,
|
|
131
|
+
maxActiveWorkers,
|
|
132
|
+
});
|
|
95
133
|
if (!waveData) {
|
|
96
134
|
console.log(chalk.green(`${LOG_PREFIX} All WUs are complete! Nothing to spawn.`));
|
|
97
135
|
return;
|
|
@@ -150,6 +188,13 @@ const program = new Command()
|
|
|
150
188
|
}
|
|
151
189
|
// WU-1202: Output spawn content for actual execution (not dry-run)
|
|
152
190
|
// WU-2375: Format varies by client capability (XML for Claude, markdown for others)
|
|
191
|
+
if (initIds.length === 1) {
|
|
192
|
+
const launchArtifacts = writeExecutionPlanArtifacts(initIds[0], wus, plan, { clientName });
|
|
193
|
+
console.log(chalk.cyan(`${LOG_PREFIX} Wrote plan/launch/status artifacts for launch attempt ${launchArtifacts.launchAttempt}`));
|
|
194
|
+
console.log(` Plan: ${launchArtifacts.planPath}`);
|
|
195
|
+
console.log(` Launch: ${launchArtifacts.launchPath}`);
|
|
196
|
+
console.log(` Status: ${launchArtifacts.statusPath}`);
|
|
197
|
+
}
|
|
153
198
|
console.log('');
|
|
154
199
|
console.log(chalk.bold('Spawn Commands:'));
|
|
155
200
|
console.log(formatExecutionPlanWithEmbeddedSpawns(plan, clientName));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orchestrate-initiative.js","sourceRoot":"","sources":["../src/orchestrate-initiative.ts"],"names":[],"mappings":";AACA,iCAAiC;AACjC,yCAAyC;AAEzC;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,gCAAgC,EAChC,4BAA4B,EAC5B,mBAAmB,EACnB,qCAAqC,EACrC,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,uBAAuB,EACvB,0BAA0B,EAC1B,UAAU,GAGX,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"orchestrate-initiative.js","sourceRoot":"","sources":["../src/orchestrate-initiative.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
// Copyright (c) 2026 Hellmai Ltd
|
|
2
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
3
|
+
/**
|
|
4
|
+
* Orchestration integrity detectors (WU-2634 / INIT-056 Phase 5).
|
|
5
|
+
*
|
|
6
|
+
* Pure helpers that turn raw execution evidence into the
|
|
7
|
+
* `contaminatedPaths` and `stalled` signals consumed by
|
|
8
|
+
* {@link @lumenflow/initiatives/orchestrator#reconcileInitiativeExecution}.
|
|
9
|
+
*
|
|
10
|
+
* These functions are intentionally side-effect-free so callers can inject
|
|
11
|
+
* test fixtures without spawning `git` or mutating the real filesystem.
|
|
12
|
+
* The thin `getMainDirtyPaths` helper is the one place we shell out, and it
|
|
13
|
+
* is exported separately so tests can substitute their own dirty list.
|
|
14
|
+
*
|
|
15
|
+
* @module orchestrate-integrity
|
|
16
|
+
*/
|
|
17
|
+
import { execFileSync } from 'node:child_process';
|
|
18
|
+
export const DEFAULT_STALL_THRESHOLD_MS = 4 * 60 * 60 * 1000; // 4 hours
|
|
19
|
+
function getOrchestrationConfig(config) {
|
|
20
|
+
if (typeof config !== 'object' || config === null) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const sd = config.software_delivery;
|
|
24
|
+
if (typeof sd !== 'object' || sd === null) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const orch = sd.orchestration;
|
|
28
|
+
return typeof orch === 'object' && orch !== null ? orch : undefined;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Read `software_delivery.orchestration.max_active_workers` from the resolved
|
|
32
|
+
* workspace config, defaulting to undefined (no capacity ceiling).
|
|
33
|
+
*/
|
|
34
|
+
export function readMaxActiveWorkersFromConfig(config) {
|
|
35
|
+
const raw = getOrchestrationConfig(config)?.max_active_workers;
|
|
36
|
+
if (typeof raw === 'number' && Number.isInteger(raw) && raw >= 0) {
|
|
37
|
+
return raw;
|
|
38
|
+
}
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Read `software_delivery.orchestration.stall_threshold_hours` from the resolved
|
|
43
|
+
* workspace config. Falls back to {@link DEFAULT_STALL_THRESHOLD_MS}.
|
|
44
|
+
*/
|
|
45
|
+
export function readStallThresholdMs(config) {
|
|
46
|
+
const raw = getOrchestrationConfig(config)?.stall_threshold_hours;
|
|
47
|
+
if (typeof raw === 'number' && Number.isFinite(raw) && raw > 0) {
|
|
48
|
+
return raw * 60 * 60 * 1000;
|
|
49
|
+
}
|
|
50
|
+
return DEFAULT_STALL_THRESHOLD_MS;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Return the set of dirty paths in the main checkout at `baseDir`. Uses
|
|
54
|
+
* `git status --porcelain=v1` so the output is stable. Returns [] when the
|
|
55
|
+
* command fails or the directory is not a git repository — callers should
|
|
56
|
+
* treat a missing result as "no contamination detected" rather than fatal.
|
|
57
|
+
*/
|
|
58
|
+
export function getMainDirtyPaths(baseDir) {
|
|
59
|
+
try {
|
|
60
|
+
// `git` is a first-class LumenFlow runtime dependency; other CLI entry
|
|
61
|
+
// points resolve it from PATH the same way.
|
|
62
|
+
// eslint-disable-next-line sonarjs/no-os-command-from-path
|
|
63
|
+
const raw = execFileSync('git', ['status', '--porcelain=v1'], {
|
|
64
|
+
cwd: baseDir,
|
|
65
|
+
encoding: 'utf8',
|
|
66
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
67
|
+
});
|
|
68
|
+
return raw
|
|
69
|
+
.split('\n')
|
|
70
|
+
.map((line) => line.trim())
|
|
71
|
+
.filter((line) => line.length > 0)
|
|
72
|
+
.map((line) => {
|
|
73
|
+
// Porcelain format: "XY path" or "XY orig -> new" for renames.
|
|
74
|
+
const withoutStatus = line.slice(2).trim();
|
|
75
|
+
const arrowIdx = withoutStatus.indexOf(' -> ');
|
|
76
|
+
return arrowIdx >= 0 ? withoutStatus.slice(arrowIdx + 4) : withoutStatus;
|
|
77
|
+
})
|
|
78
|
+
.filter((path) => path.length > 0);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Return the subset of `wuCodePaths` whose path (or any prefix directory)
|
|
86
|
+
* appears in `dirtyPaths`. Matching is exact-string; glob expansion is the
|
|
87
|
+
* caller's responsibility because code_paths in WU specs may already use
|
|
88
|
+
* shell patterns that the orchestrator does not expand on its own.
|
|
89
|
+
*/
|
|
90
|
+
export function detectContaminatedCodePaths(dirtyPaths, wuCodePaths) {
|
|
91
|
+
if (!wuCodePaths || wuCodePaths.length === 0 || dirtyPaths.length === 0) {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
const dirtySet = new Set(dirtyPaths);
|
|
95
|
+
const contaminated = [];
|
|
96
|
+
for (const codePath of wuCodePaths) {
|
|
97
|
+
if (dirtySet.has(codePath)) {
|
|
98
|
+
contaminated.push(codePath);
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// If a WU declares a directory, any dirty file under it counts as contamination.
|
|
102
|
+
const dirPrefix = codePath.endsWith('/') ? codePath : `${codePath}/`;
|
|
103
|
+
if (dirtyPaths.some((dirty) => dirty.startsWith(dirPrefix))) {
|
|
104
|
+
contaminated.push(codePath);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return contaminated;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A claimed worktree is stalled when it has been claimed but no checkpoint
|
|
111
|
+
* or signal activity has been recorded within the threshold. Never returns
|
|
112
|
+
* `true` for WUs that have no worktree — those are classified as
|
|
113
|
+
* needs_relaunch via the worker-returned path, not stall.
|
|
114
|
+
*/
|
|
115
|
+
export function isWorktreeStalled(evidence, thresholdMs, now = new Date()) {
|
|
116
|
+
if (!evidence.worktreePresent) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const nowMs = now.getTime();
|
|
120
|
+
const latestActivityMs = Math.max(parseTimestamp(evidence.latestCheckpointAt), parseTimestamp(evidence.latestSignalAt), parseTimestamp(evidence.claimedAt));
|
|
121
|
+
if (latestActivityMs === 0) {
|
|
122
|
+
return false; // No evidence at all — can't make a stall claim.
|
|
123
|
+
}
|
|
124
|
+
return nowMs - latestActivityMs > thresholdMs;
|
|
125
|
+
}
|
|
126
|
+
function parseTimestamp(value) {
|
|
127
|
+
if (!value) {
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
const parsed = Date.parse(value);
|
|
131
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=orchestrate-integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrate-integrity.js","sourceRoot":"","sources":["../src/orchestrate-integrity.ts"],"names":[],"mappings":"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"}
|