@lumenflow/cli 2.15.1 → 2.16.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/dist/agent-issues-query.js +5 -5
- package/dist/agent-issues-query.js.map +1 -1
- package/dist/agent-log-issue.js +5 -4
- package/dist/agent-log-issue.js.map +1 -1
- package/dist/agent-session-end.js +3 -2
- package/dist/agent-session-end.js.map +1 -1
- package/dist/agent-session.js +3 -2
- package/dist/agent-session.js.map +1 -1
- package/dist/backlog-prune.js +5 -5
- package/dist/backlog-prune.js.map +1 -1
- package/dist/cli-entry-point.js +56 -3
- package/dist/cli-entry-point.js.map +1 -1
- package/dist/commands/integrate.js +4 -5
- package/dist/commands/integrate.js.map +1 -1
- package/dist/commands.js +1 -1
- package/dist/commands.js.map +1 -1
- package/dist/deps-add.js +65 -24
- package/dist/deps-add.js.map +1 -1
- package/dist/deps-remove.js +19 -11
- package/dist/deps-remove.js.map +1 -1
- package/dist/docs-sync.js +3 -2
- package/dist/docs-sync.js.map +1 -1
- package/dist/doctor.js +9 -4
- package/dist/doctor.js.map +1 -1
- package/dist/file-delete.js +1 -1
- package/dist/file-delete.js.map +1 -1
- package/dist/file-edit.js +1 -1
- package/dist/file-edit.js.map +1 -1
- package/dist/file-read.js +1 -1
- package/dist/file-read.js.map +1 -1
- package/dist/file-write.js +2 -2
- package/dist/file-write.js.map +1 -1
- package/dist/flow-bottlenecks.js +5 -6
- package/dist/flow-bottlenecks.js.map +1 -1
- package/dist/flow-report.js +4 -5
- package/dist/flow-report.js.map +1 -1
- package/dist/gate-defaults.js +149 -0
- package/dist/gate-defaults.js.map +1 -0
- package/dist/gate-registry.js +82 -0
- package/dist/gate-registry.js.map +1 -0
- package/dist/gates-types.js +10 -0
- package/dist/gates-types.js.map +1 -0
- package/dist/gates.js +163 -230
- package/dist/gates.js.map +1 -1
- package/dist/git-branch.js +1 -1
- package/dist/git-branch.js.map +1 -1
- package/dist/git-diff.js +1 -1
- package/dist/git-diff.js.map +1 -1
- package/dist/git-log.js +1 -1
- package/dist/git-log.js.map +1 -1
- package/dist/git-status.js +1 -1
- package/dist/git-status.js.map +1 -1
- package/dist/guard-locked.js +6 -7
- package/dist/guard-locked.js.map +1 -1
- package/dist/guard-main-branch.js +3 -2
- package/dist/guard-main-branch.js.map +1 -1
- package/dist/guard-worktree-commit.js +4 -5
- package/dist/guard-worktree-commit.js.map +1 -1
- package/dist/hooks/enforcement-generator.js +1 -1
- package/dist/hooks/enforcement-generator.js.map +1 -1
- package/dist/init.js +14 -6
- package/dist/init.js.map +1 -1
- package/dist/initiative-add-wu.js +12 -12
- package/dist/initiative-add-wu.js.map +1 -1
- package/dist/initiative-bulk-assign-wus.js +8 -9
- package/dist/initiative-bulk-assign-wus.js.map +1 -1
- package/dist/initiative-create.js +11 -11
- package/dist/initiative-create.js.map +1 -1
- package/dist/initiative-edit.js +9 -9
- package/dist/initiative-edit.js.map +1 -1
- package/dist/initiative-list.js +4 -4
- package/dist/initiative-list.js.map +1 -1
- package/dist/initiative-plan.js +12 -12
- package/dist/initiative-plan.js.map +1 -1
- package/dist/initiative-remove-wu.js +11 -11
- package/dist/initiative-remove-wu.js.map +1 -1
- package/dist/initiative-status.js +6 -6
- package/dist/initiative-status.js.map +1 -1
- package/dist/lane-health.js +2 -2
- package/dist/lane-health.js.map +1 -1
- package/dist/lane-suggest.js +2 -2
- package/dist/lane-suggest.js.map +1 -1
- package/dist/lifecycle-regression-harness.js +5 -5
- package/dist/lifecycle-regression-harness.js.map +1 -1
- package/dist/lumenflow-upgrade.js +4 -4
- package/dist/lumenflow-upgrade.js.map +1 -1
- package/dist/mem-checkpoint.js +8 -7
- package/dist/mem-checkpoint.js.map +1 -1
- package/dist/mem-cleanup.js +12 -14
- package/dist/mem-cleanup.js.map +1 -1
- package/dist/mem-context.js +8 -7
- package/dist/mem-context.js.map +1 -1
- package/dist/mem-create.js +9 -8
- package/dist/mem-create.js.map +1 -1
- package/dist/mem-delete.js +8 -7
- package/dist/mem-delete.js.map +1 -1
- package/dist/mem-export.js +9 -8
- package/dist/mem-export.js.map +1 -1
- package/dist/mem-inbox.js +40 -16
- package/dist/mem-inbox.js.map +1 -1
- package/dist/mem-index.js +8 -7
- package/dist/mem-index.js.map +1 -1
- package/dist/mem-init.js +8 -7
- package/dist/mem-init.js.map +1 -1
- package/dist/mem-profile.js +8 -7
- package/dist/mem-profile.js.map +1 -1
- package/dist/mem-promote.js +8 -7
- package/dist/mem-promote.js.map +1 -1
- package/dist/mem-ready.js +9 -8
- package/dist/mem-ready.js.map +1 -1
- package/dist/mem-recover.js +8 -7
- package/dist/mem-recover.js.map +1 -1
- package/dist/mem-signal.js +9 -8
- package/dist/mem-signal.js.map +1 -1
- package/dist/mem-start.js +8 -7
- package/dist/mem-start.js.map +1 -1
- package/dist/mem-summarize.js +8 -7
- package/dist/mem-summarize.js.map +1 -1
- package/dist/mem-triage.js +8 -7
- package/dist/mem-triage.js.map +1 -1
- package/dist/metrics-cli.js +5 -6
- package/dist/metrics-cli.js.map +1 -1
- package/dist/metrics-snapshot.js +6 -6
- package/dist/metrics-snapshot.js.map +1 -1
- package/dist/onboarding-smoke-test.js +3 -0
- package/dist/onboarding-smoke-test.js.map +1 -1
- package/dist/orchestrate-init-status.js +2 -2
- package/dist/orchestrate-init-status.js.map +1 -1
- package/dist/orchestrate-initiative.js +2 -2
- package/dist/orchestrate-initiative.js.map +1 -1
- package/dist/orchestrate-monitor.js +8 -1
- package/dist/orchestrate-monitor.js.map +1 -1
- package/dist/plan-create.js +8 -8
- package/dist/plan-create.js.map +1 -1
- package/dist/plan-edit.js +7 -7
- package/dist/plan-edit.js.map +1 -1
- package/dist/plan-link.js +9 -9
- package/dist/plan-link.js.map +1 -1
- package/dist/plan-promote.js +8 -8
- package/dist/plan-promote.js.map +1 -1
- package/dist/release.js +10 -9
- package/dist/release.js.map +1 -1
- package/dist/rotate-progress.js +4 -3
- package/dist/rotate-progress.js.map +1 -1
- package/dist/session-coordinator.js +2 -2
- package/dist/session-coordinator.js.map +1 -1
- package/dist/signal-cleanup.js +10 -13
- package/dist/signal-cleanup.js.map +1 -1
- package/dist/spawn-list.js +9 -10
- package/dist/spawn-list.js.map +1 -1
- package/dist/state-bootstrap.js +3 -3
- package/dist/state-bootstrap.js.map +1 -1
- package/dist/state-cleanup.js +13 -16
- package/dist/state-cleanup.js.map +1 -1
- package/dist/state-doctor-fix.js +14 -20
- package/dist/state-doctor-fix.js.map +1 -1
- package/dist/state-doctor-stamps.js +21 -0
- package/dist/state-doctor-stamps.js.map +1 -0
- package/dist/state-doctor.js +17 -26
- package/dist/state-doctor.js.map +1 -1
- package/dist/sync-templates.js +1 -0
- package/dist/sync-templates.js.map +1 -1
- package/dist/trace-gen.js +74 -10
- package/dist/trace-gen.js.map +1 -1
- package/dist/validate-agent-skills.js +6 -5
- package/dist/validate-agent-skills.js.map +1 -1
- package/dist/validate-agent-sync.js +4 -5
- package/dist/validate-agent-sync.js.map +1 -1
- package/dist/validate-backlog-sync.js +5 -6
- package/dist/validate-backlog-sync.js.map +1 -1
- package/dist/validate-skills-spec.js +6 -5
- package/dist/validate-skills-spec.js.map +1 -1
- package/dist/validate.js +6 -7
- package/dist/validate.js.map +1 -1
- package/dist/validator-defaults.js +119 -0
- package/dist/validator-defaults.js.map +1 -0
- package/dist/validator-registry.js +81 -0
- package/dist/validator-registry.js.map +1 -0
- package/dist/wu-block.js +20 -19
- package/dist/wu-block.js.map +1 -1
- package/dist/wu-claim-mode.js +1 -1
- package/dist/wu-claim-mode.js.map +1 -1
- package/dist/wu-claim.js +33 -32
- package/dist/wu-claim.js.map +1 -1
- package/dist/wu-cleanup.js +11 -11
- package/dist/wu-cleanup.js.map +1 -1
- package/dist/wu-create.js +27 -27
- package/dist/wu-create.js.map +1 -1
- package/dist/wu-delete.js +16 -17
- package/dist/wu-delete.js.map +1 -1
- package/dist/wu-deps.js +7 -7
- package/dist/wu-deps.js.map +1 -1
- package/dist/wu-done-auto-cleanup.js +46 -21
- package/dist/wu-done-auto-cleanup.js.map +1 -1
- package/dist/wu-done-check.js +3 -2
- package/dist/wu-done-check.js.map +1 -1
- package/dist/wu-done-decay.js +3 -7
- package/dist/wu-done-decay.js.map +1 -1
- package/dist/wu-done.js +132 -66
- package/dist/wu-done.js.map +1 -1
- package/dist/wu-edit.js +22 -23
- package/dist/wu-edit.js.map +1 -1
- package/dist/wu-infer-lane.js +6 -6
- package/dist/wu-infer-lane.js.map +1 -1
- package/dist/wu-preflight.js +7 -7
- package/dist/wu-preflight.js.map +1 -1
- package/dist/wu-prep.js +10 -8
- package/dist/wu-prep.js.map +1 -1
- package/dist/wu-proto.js +14 -14
- package/dist/wu-proto.js.map +1 -1
- package/dist/wu-prune.js +7 -7
- package/dist/wu-prune.js.map +1 -1
- package/dist/wu-recover.js +13 -13
- package/dist/wu-recover.js.map +1 -1
- package/dist/wu-release.js +17 -16
- package/dist/wu-release.js.map +1 -1
- package/dist/wu-repair.js +4 -4
- package/dist/wu-repair.js.map +1 -1
- package/dist/wu-spawn.js +20 -20
- package/dist/wu-spawn.js.map +1 -1
- package/dist/wu-status.js +5 -5
- package/dist/wu-status.js.map +1 -1
- package/dist/wu-unblock.js +23 -22
- package/dist/wu-unblock.js.map +1 -1
- package/dist/wu-unlock-lane.js +5 -5
- package/dist/wu-unlock-lane.js.map +1 -1
- package/dist/wu-validate.js +8 -8
- package/dist/wu-validate.js.map +1 -1
- package/package.json +7 -6
- package/templates/core/ai/onboarding/docs-generation.md.template +1 -1
package/dist/wu-done.js
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
* Full migration to thin shim pending @lumenflow/core CLI export implementation.
|
|
33
33
|
*/
|
|
34
34
|
// WU-2542: Import from @lumenflow/core to establish shim layer dependency
|
|
35
|
-
import
|
|
35
|
+
import '@lumenflow/core';
|
|
36
36
|
// WU-1153: wu:done guard for uncommitted code_paths is implemented in core package
|
|
37
37
|
// The guard runs in executeWorktreeCompletion() before metadata transaction
|
|
38
38
|
// See: packages/@lumenflow/core/src/wu-done-validation.ts
|
|
@@ -40,19 +40,19 @@ import { execSync } from 'node:child_process';
|
|
|
40
40
|
import prettyMs from 'pretty-ms';
|
|
41
41
|
import { runGates } from './gates.js';
|
|
42
42
|
import { buildClaimRepairCommand } from './wu-claim-repair-guidance.js';
|
|
43
|
-
import { getGitForCwd } from '@lumenflow/core/
|
|
44
|
-
import { die } from '@lumenflow/core/
|
|
43
|
+
import { getGitForCwd, createGitForPath } from '@lumenflow/core/git-adapter';
|
|
44
|
+
import { die } from '@lumenflow/core/error-handler';
|
|
45
45
|
// WU-1223: Location detection for worktree check
|
|
46
|
-
import { resolveLocation } from '@lumenflow/core/
|
|
46
|
+
import { resolveLocation } from '@lumenflow/core/context/location-resolver';
|
|
47
47
|
import { existsSync, readFileSync, mkdirSync, appendFileSync, unlinkSync, statSync } from 'node:fs';
|
|
48
48
|
import path from 'node:path';
|
|
49
49
|
// WU-1825: Import from unified code-path-validator (consolidates 3 validators)
|
|
50
|
-
import { validateWUCodePaths } from '@lumenflow/core/
|
|
50
|
+
import { validateWUCodePaths } from '@lumenflow/core/code-path-validator';
|
|
51
51
|
// WU-1983: Migration deployment utilities
|
|
52
|
-
import { discoverLocalMigrations, hasMigrationChanges
|
|
53
|
-
import { validateDocsOnly, getAllowedPathsDescription
|
|
54
|
-
import { scanLogForViolations, rotateLog } from '@lumenflow/core/
|
|
55
|
-
import { rollbackFiles } from '@lumenflow/core/
|
|
52
|
+
import { discoverLocalMigrations, hasMigrationChanges } from '@lumenflow/core/migration-deployer';
|
|
53
|
+
import { validateDocsOnly, getAllowedPathsDescription } from '@lumenflow/core/docs-path-validator';
|
|
54
|
+
import { scanLogForViolations, rotateLog } from '@lumenflow/core/commands-logger';
|
|
55
|
+
import { rollbackFiles } from '@lumenflow/core/rollback-utils';
|
|
56
56
|
import { validateInputs, detectModeAndPaths, defaultBranchFrom, runCleanup, validateSpecCompleteness, runPreflightTasksValidation, buildPreflightErrorMessage,
|
|
57
57
|
// WU-1805: Preflight code_paths validation before gates
|
|
58
58
|
executePreflightCodePathValidation, buildPreflightCodePathErrorMessage,
|
|
@@ -61,47 +61,47 @@ validateAllPreCommitHooks,
|
|
|
61
61
|
// WU-2310: Type vs code_paths preflight validation
|
|
62
62
|
validateTypeVsCodePathsPreflight, buildTypeVsCodePathsErrorMessage,
|
|
63
63
|
// WU-1503: Dirty-main pre-merge guard
|
|
64
|
-
validateDirtyMain, buildDirtyMainErrorMessage, } from '@lumenflow/core/
|
|
64
|
+
validateDirtyMain, buildDirtyMainErrorMessage, } from '@lumenflow/core/wu-done-validators';
|
|
65
65
|
// WU-1825: validateCodePathsExist moved to unified code-path-validator
|
|
66
|
-
import { validateCodePathsExist } from '@lumenflow/core/
|
|
67
|
-
import { BRANCHES, REMOTES, PATTERNS, DEFAULTS, LOG_PREFIX, EMOJI, GIT, SESSION, WU_STATUS, WU_EXPOSURE, PKG_MANAGER, SCRIPTS, CLI_FLAGS, FILE_SYSTEM,
|
|
66
|
+
import { validateCodePathsExist } from '@lumenflow/core/code-path-validator';
|
|
67
|
+
import { BRANCHES, REMOTES, PATTERNS, DEFAULTS, LOG_PREFIX, EMOJI, GIT, SESSION, WU_STATUS, WU_EXPOSURE, PKG_MANAGER, SCRIPTS, CLI_FLAGS, FILE_SYSTEM, EXIT_CODES, STRING_LITERALS, MICRO_WORKTREE_OPERATIONS, TELEMETRY_STEPS, SKIP_GATES_REASONS, CHECKPOINT_MESSAGES, LUMENFLOW_PATHS,
|
|
68
68
|
// WU-1223: Location types for worktree detection
|
|
69
|
-
CONTEXT_VALIDATION, } from '@lumenflow/core/
|
|
70
|
-
import { isDocumentationType } from '@lumenflow/core/
|
|
71
|
-
import { printGateFailureBox, printStatusPreview } from '@lumenflow/core/
|
|
72
|
-
import { ensureOnMain } from '@lumenflow/core/
|
|
73
|
-
import { WU_PATHS
|
|
74
|
-
import { getConfig } from '@lumenflow/core/
|
|
75
|
-
import { writeWU, appendNote, parseYAML } from '@lumenflow/core/
|
|
76
|
-
import { PLACEHOLDER_SENTINEL, validateWU, validateDoneWU, validateApprovalGates, } from '@lumenflow/core/
|
|
77
|
-
import { validateBacklogSync } from '@lumenflow/core/
|
|
69
|
+
CONTEXT_VALIDATION, } from '@lumenflow/core/wu-constants';
|
|
70
|
+
import { isDocumentationType } from '@lumenflow/core/wu-type-helpers';
|
|
71
|
+
import { printGateFailureBox, printStatusPreview } from '@lumenflow/core/wu-done-ui';
|
|
72
|
+
import { ensureOnMain } from '@lumenflow/core/wu-helpers';
|
|
73
|
+
import { WU_PATHS } from '@lumenflow/core/wu-paths';
|
|
74
|
+
import { getConfig } from '@lumenflow/core/config';
|
|
75
|
+
import { writeWU, appendNote, parseYAML } from '@lumenflow/core/wu-yaml';
|
|
76
|
+
import { PLACEHOLDER_SENTINEL, validateWU, validateDoneWU, validateApprovalGates, } from '@lumenflow/core/wu-schema';
|
|
77
|
+
import { validateBacklogSync } from '@lumenflow/core/backlog-sync-validator';
|
|
78
78
|
import { executeBranchOnlyCompletion,
|
|
79
79
|
// WU-1492: Import branch-pr completion path
|
|
80
|
-
executeBranchPRCompletion, } from '@lumenflow/core/
|
|
81
|
-
import { executeWorktreeCompletion, autoRebaseBranch
|
|
82
|
-
import { checkWUConsistency } from '@lumenflow/core/
|
|
80
|
+
executeBranchPRCompletion, } from '@lumenflow/core/wu-done-branch-only';
|
|
81
|
+
import { executeWorktreeCompletion, autoRebaseBranch } from '@lumenflow/core/wu-done-worktree';
|
|
82
|
+
import { checkWUConsistency } from '@lumenflow/core/wu-consistency-checker';
|
|
83
83
|
// WU-1542: Use blocking mode compliance check (replaces non-blocking checkMandatoryAgentsCompliance)
|
|
84
|
-
import { checkMandatoryAgentsComplianceBlocking } from '@lumenflow/core/
|
|
85
|
-
import { endSessionForWU } from '@lumenflow/agent/
|
|
86
|
-
import { runBackgroundProcessCheck } from '@lumenflow/core/
|
|
87
|
-
import { WUStateStore } from '@lumenflow/core/
|
|
84
|
+
import { checkMandatoryAgentsComplianceBlocking } from '@lumenflow/core/orchestration-rules';
|
|
85
|
+
import { endSessionForWU } from '@lumenflow/agent/auto-session';
|
|
86
|
+
import { runBackgroundProcessCheck } from '@lumenflow/core/process-detector';
|
|
87
|
+
import { WUStateStore } from '@lumenflow/core/wu-state-store';
|
|
88
88
|
// WU-1588: INIT-007 memory layer integration
|
|
89
|
-
import { createCheckpoint } from '@lumenflow/memory/
|
|
90
|
-
import { createSignal, loadSignals } from '@lumenflow/memory/
|
|
89
|
+
import { createCheckpoint } from '@lumenflow/memory/checkpoint';
|
|
90
|
+
import { createSignal, loadSignals } from '@lumenflow/memory/signal';
|
|
91
91
|
// WU-1763: Memory store for loading discoveries (lifecycle nudges)
|
|
92
|
-
import { loadMemory, queryByWu } from '@lumenflow/memory/
|
|
92
|
+
import { loadMemory, queryByWu } from '@lumenflow/memory/store';
|
|
93
93
|
// WU-1943: Checkpoint warning helper
|
|
94
|
-
import { hasSessionCheckpoints } from '@lumenflow/core/
|
|
94
|
+
import { hasSessionCheckpoints } from '@lumenflow/core/wu-done-worktree';
|
|
95
95
|
// WU-1603: Atomic lane locking - release lock on WU completion
|
|
96
|
-
import { releaseLaneLock } from '@lumenflow/core/
|
|
96
|
+
import { releaseLaneLock } from '@lumenflow/core/lane-lock';
|
|
97
97
|
// WU-1747: Checkpoint and lock for concurrent load resilience
|
|
98
|
-
import { createPreGatesCheckpoint as createWU1747Checkpoint, markGatesPassed, canSkipGates, clearCheckpoint, } from '@lumenflow/core/
|
|
98
|
+
import { createPreGatesCheckpoint as createWU1747Checkpoint, markGatesPassed, canSkipGates, clearCheckpoint, } from '@lumenflow/core/wu-checkpoint';
|
|
99
99
|
// WU-1946: Spawn registry for tracking sub-agent spawns
|
|
100
|
-
import { SpawnRegistryStore } from '@lumenflow/core/
|
|
101
|
-
import { SpawnStatus } from '@lumenflow/core/
|
|
100
|
+
import { SpawnRegistryStore } from '@lumenflow/core/spawn-registry-store';
|
|
101
|
+
import { SpawnStatus } from '@lumenflow/core/spawn-registry-schema';
|
|
102
102
|
// WU-1999: Exposure validation for UI pairing
|
|
103
103
|
// WU-2022: Feature accessibility validation (blocking)
|
|
104
|
-
import { validateExposure, validateFeatureAccessibility
|
|
104
|
+
import { validateExposure, validateFeatureAccessibility } from '@lumenflow/core/wu-validation';
|
|
105
105
|
import { ensureCleanWorktree } from './wu-done-check.js';
|
|
106
106
|
// WU-1366: Auto cleanup after wu:done success
|
|
107
107
|
// WU-1533: commitCleanupChanges auto-commits dirty state files after cleanup
|
|
@@ -120,8 +120,7 @@ const MEMORY_CHECKPOINT_NOTES = {
|
|
|
120
120
|
PRE_GATES: 'Pre-gates checkpoint for recovery if gates fail',
|
|
121
121
|
};
|
|
122
122
|
const MEMORY_SIGNAL_WINDOW_MS = 60 * 60 * 1000; // 1 hour for recent signals
|
|
123
|
-
//
|
|
124
|
-
const WU_EVENTS_PATH = '.lumenflow/state/wu-events.jsonl';
|
|
123
|
+
// WU-1539: Use centralized LUMENFLOW_PATHS.WU_EVENTS instead of local constant
|
|
125
124
|
/**
|
|
126
125
|
* WU-1804: Preflight validation for claim metadata before gates.
|
|
127
126
|
*
|
|
@@ -146,7 +145,7 @@ async function validateClaimMetadataBeforeGates(id, worktreePath, yamlStatus) {
|
|
|
146
145
|
// Check 2: State store must show WU as in_progress
|
|
147
146
|
const resolvedWorktreePath = path.resolve(worktreePath);
|
|
148
147
|
const stateDir = path.join(resolvedWorktreePath, '.lumenflow', 'state');
|
|
149
|
-
const eventsPath = path.join(resolvedWorktreePath,
|
|
148
|
+
const eventsPath = path.join(resolvedWorktreePath, LUMENFLOW_PATHS.WU_EVENTS);
|
|
150
149
|
try {
|
|
151
150
|
const store = new WUStateStore(stateDir);
|
|
152
151
|
await store.load();
|
|
@@ -273,10 +272,10 @@ export function buildGatesCommand(options) {
|
|
|
273
272
|
}
|
|
274
273
|
return `${PKG_MANAGER} ${SCRIPTS.GATES}`;
|
|
275
274
|
}
|
|
276
|
-
async function
|
|
275
|
+
async function _assertWorktreeWUInProgressInStateStore(id, worktreePath) {
|
|
277
276
|
const resolvedWorktreePath = path.resolve(worktreePath);
|
|
278
277
|
const stateDir = path.join(resolvedWorktreePath, '.lumenflow', 'state');
|
|
279
|
-
const eventsPath = path.join(resolvedWorktreePath,
|
|
278
|
+
const eventsPath = path.join(resolvedWorktreePath, LUMENFLOW_PATHS.WU_EVENTS);
|
|
280
279
|
const store = new WUStateStore(stateDir);
|
|
281
280
|
try {
|
|
282
281
|
await store.load();
|
|
@@ -475,7 +474,7 @@ export async function isBranchAlreadyMerged(branch) {
|
|
|
475
474
|
// WU-1281: isDocsOnlyByPaths removed - use shouldSkipWebTests from path-classifiers.ts
|
|
476
475
|
// The validators already use shouldSkipWebTests via detectDocsOnlyByPaths wrapper.
|
|
477
476
|
// Keeping the export for backward compatibility but re-exporting the canonical function.
|
|
478
|
-
export { shouldSkipWebTests as isDocsOnlyByPaths } from '@lumenflow/core/
|
|
477
|
+
export { shouldSkipWebTests as isDocsOnlyByPaths } from '@lumenflow/core/path-classifiers';
|
|
479
478
|
/**
|
|
480
479
|
* WU-1234: Pre-flight check for backlog state consistency
|
|
481
480
|
* Fails fast if the WU appears in both Done and In Progress sections.
|
|
@@ -543,7 +542,7 @@ function getCommitHeaderLimit() {
|
|
|
543
542
|
* Context: WU-635 (multi-agent coordination)
|
|
544
543
|
* See: CLAUDE.md §2.2
|
|
545
544
|
*/
|
|
546
|
-
async function
|
|
545
|
+
async function _ensureCleanWorkingTree() {
|
|
547
546
|
const status = await getGitForCwd().getStatus();
|
|
548
547
|
if (status.trim()) {
|
|
549
548
|
die(`Working tree is not clean. Cannot proceed with wu:done.\n\n` +
|
|
@@ -567,6 +566,17 @@ const INTERNAL_LIFECYCLE_DIRTY_FILES = new Set([
|
|
|
567
566
|
'.lumenflow/skip-gates-audit.log',
|
|
568
567
|
'.lumenflow/skip-cos-gates-audit.log',
|
|
569
568
|
]);
|
|
569
|
+
/**
|
|
570
|
+
* WU-1554: Prefixes for metadata files that wu:done manages.
|
|
571
|
+
* These files may be dirty after merge+rebase when wu:claim used push-only mode
|
|
572
|
+
* or when concurrent agents advance origin/main. Instead of blocking wu:done,
|
|
573
|
+
* these are auto-committed by the caller.
|
|
574
|
+
*/
|
|
575
|
+
const METADATA_LIFECYCLE_PREFIXES = [
|
|
576
|
+
'.lumenflow/state/',
|
|
577
|
+
'.lumenflow/stamps/',
|
|
578
|
+
'.lumenflow/archive/',
|
|
579
|
+
];
|
|
570
580
|
function parsePorcelainPath(line) {
|
|
571
581
|
if (line.length < 4)
|
|
572
582
|
return null;
|
|
@@ -579,6 +589,20 @@ function parsePorcelainPath(line) {
|
|
|
579
589
|
}
|
|
580
590
|
return pathPart;
|
|
581
591
|
}
|
|
592
|
+
/**
|
|
593
|
+
* WU-1554: Check if a file is a metadata lifecycle file.
|
|
594
|
+
* Metadata files are managed by wu:done (wu-events.jsonl, status.md, backlog.md,
|
|
595
|
+
* WU YAML, stamps, archives) and may be dirty after merge+rebase.
|
|
596
|
+
*/
|
|
597
|
+
function isMetadataLifecycleFile(filePath, metadataDir) {
|
|
598
|
+
if (METADATA_LIFECYCLE_PREFIXES.some((prefix) => filePath.startsWith(prefix))) {
|
|
599
|
+
return true;
|
|
600
|
+
}
|
|
601
|
+
if (metadataDir && filePath.startsWith(metadataDir + '/')) {
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
582
606
|
/**
|
|
583
607
|
* WU-1084: Check for uncommitted changes on main after merge completes.
|
|
584
608
|
*
|
|
@@ -586,26 +610,34 @@ function parsePorcelainPath(line) {
|
|
|
586
610
|
* outside the WU's code_paths during worktree work. These changes survive
|
|
587
611
|
* the merge and would be silently left behind when the worktree is removed.
|
|
588
612
|
*
|
|
613
|
+
* WU-1554: Added metadataDir parameter and metadataFiles return field.
|
|
614
|
+
* Metadata files (wu-events.jsonl, status.md, backlog.md, WU YAML, stamps)
|
|
615
|
+
* may be dirty after merge+rebase when wu:claim used push-only mode.
|
|
616
|
+
* These are returned separately for auto-commit by the caller.
|
|
617
|
+
*
|
|
589
618
|
* @param gitStatus - Output from git status (porcelain format)
|
|
590
619
|
* @param wuId - The WU ID for error messaging
|
|
591
|
-
* @
|
|
620
|
+
* @param metadataDir - Optional task directory prefix for metadata file detection
|
|
621
|
+
* @returns Object with isDirty flag, file categories, and optional error message
|
|
592
622
|
*/
|
|
593
|
-
export function checkPostMergeDirtyState(gitStatus, wuId) {
|
|
623
|
+
export function checkPostMergeDirtyState(gitStatus, wuId, metadataDir) {
|
|
594
624
|
// WU-1522: Split before trimming to preserve leading spaces in porcelain format.
|
|
595
625
|
// Porcelain lines like ' M .lumenflow/flow.log' use the leading space as a status
|
|
596
626
|
// indicator (working tree vs staging area). Trimming the whole string first strips
|
|
597
627
|
// the leading space from the first line, corrupting parsePorcelainPath output.
|
|
598
628
|
const lines = gitStatus.split('\n').filter((line) => line.length >= 4);
|
|
599
629
|
if (lines.length === 0) {
|
|
600
|
-
return { isDirty: false, internalOnlyFiles: [], unrelatedFiles: [] };
|
|
630
|
+
return { isDirty: false, internalOnlyFiles: [], metadataFiles: [], unrelatedFiles: [] };
|
|
601
631
|
}
|
|
602
632
|
const dirtyFiles = lines
|
|
603
633
|
.map((line) => parsePorcelainPath(line))
|
|
604
634
|
.filter((value) => Boolean(value));
|
|
635
|
+
// WU-1554: Three-category classification
|
|
605
636
|
const internalOnlyFiles = dirtyFiles.filter((file) => INTERNAL_LIFECYCLE_DIRTY_FILES.has(file));
|
|
606
|
-
const
|
|
637
|
+
const metadataFiles = dirtyFiles.filter((file) => !INTERNAL_LIFECYCLE_DIRTY_FILES.has(file) && isMetadataLifecycleFile(file, metadataDir));
|
|
638
|
+
const unrelatedFiles = dirtyFiles.filter((file) => !INTERNAL_LIFECYCLE_DIRTY_FILES.has(file) && !isMetadataLifecycleFile(file, metadataDir));
|
|
607
639
|
if (unrelatedFiles.length === 0) {
|
|
608
|
-
return { isDirty: false, internalOnlyFiles, unrelatedFiles: [] };
|
|
640
|
+
return { isDirty: false, internalOnlyFiles, metadataFiles, unrelatedFiles: [] };
|
|
609
641
|
}
|
|
610
642
|
const displayStatus = gitStatus.trim();
|
|
611
643
|
const error = `Main branch has uncommitted changes after merge:\n\n${displayStatus}\n\n` +
|
|
@@ -616,7 +648,7 @@ export function checkPostMergeDirtyState(gitStatus, wuId) {
|
|
|
616
648
|
` 1. Review and commit the changes: git add . && git commit -m "format: fix formatting"\n` +
|
|
617
649
|
` 2. Discard if unwanted: git checkout -- .\n` +
|
|
618
650
|
` 3. Then re-run: pnpm wu:done --id ${wuId} --skip-worktree-completion`;
|
|
619
|
-
return { isDirty: true, internalOnlyFiles, unrelatedFiles, error };
|
|
651
|
+
return { isDirty: true, internalOnlyFiles, metadataFiles, unrelatedFiles, error };
|
|
620
652
|
}
|
|
621
653
|
/**
|
|
622
654
|
* Extract completed WU IDs from git log output.
|
|
@@ -828,9 +860,10 @@ function runTripwireCheck() {
|
|
|
828
860
|
rotateLog();
|
|
829
861
|
process.exit(EXIT_CODES.ERROR);
|
|
830
862
|
}
|
|
831
|
-
async function listStaged() {
|
|
832
|
-
// WU-
|
|
833
|
-
|
|
863
|
+
async function listStaged(gitAdapter) {
|
|
864
|
+
// WU-1541: Use explicit gitAdapter if provided, otherwise fall back to getGitForCwd()
|
|
865
|
+
// WU-1235: getGitForCwd() captures current directory (legacy behavior)
|
|
866
|
+
const gitCwd = gitAdapter ?? getGitForCwd();
|
|
834
867
|
const raw = await gitCwd.raw(['diff', '--cached', '--name-only']);
|
|
835
868
|
return raw ? raw.split(/\r?\n/).filter(Boolean) : [];
|
|
836
869
|
}
|
|
@@ -1018,8 +1051,9 @@ async function runGatesInWorktree(worktreePath, id, options = {}) {
|
|
|
1018
1051
|
die(`Gates failed in ${worktreePath}. Fix issues in the worktree and try again.`);
|
|
1019
1052
|
}
|
|
1020
1053
|
}
|
|
1021
|
-
async function validateStagedFiles(id, isDocsOnly = false) {
|
|
1022
|
-
|
|
1054
|
+
async function validateStagedFiles(id, isDocsOnly = false, gitAdapter, options = {}) {
|
|
1055
|
+
// WU-1541: Accept optional gitAdapter to avoid process.chdir dependency
|
|
1056
|
+
const staged = await listStaged(gitAdapter);
|
|
1023
1057
|
// WU-1311: Use config-based paths instead of hardcoded docs/04-operations paths
|
|
1024
1058
|
const config = getConfig();
|
|
1025
1059
|
const wuPath = `${config.directories.wuDir}/${id}.yaml`;
|
|
@@ -1028,8 +1062,10 @@ async function validateStagedFiles(id, isDocsOnly = false) {
|
|
|
1028
1062
|
wuPath,
|
|
1029
1063
|
config.directories.statusPath,
|
|
1030
1064
|
config.directories.backlogPath,
|
|
1031
|
-
|
|
1065
|
+
LUMENFLOW_PATHS.WU_EVENTS,
|
|
1032
1066
|
];
|
|
1067
|
+
const metadataAllowlist = (options.metadataAllowlist ?? []).filter((file) => typeof file === 'string' && file.length > 0);
|
|
1068
|
+
const whitelistSet = new Set([...whitelist, ...metadataAllowlist]);
|
|
1033
1069
|
if (isDocsOnly) {
|
|
1034
1070
|
// For docs-only WUs, validate that all staged files are in allowed paths
|
|
1035
1071
|
const docsResult = validateDocsOnly(staged);
|
|
@@ -1041,10 +1077,10 @@ async function validateStagedFiles(id, isDocsOnly = false) {
|
|
|
1041
1077
|
}
|
|
1042
1078
|
const unexpected = staged.filter((file) => {
|
|
1043
1079
|
// Whitelist exact matches
|
|
1044
|
-
if (
|
|
1080
|
+
if (whitelistSet.has(file))
|
|
1045
1081
|
return false;
|
|
1046
|
-
// Whitelist
|
|
1047
|
-
if (file.startsWith(
|
|
1082
|
+
// Whitelist stamps directory pattern
|
|
1083
|
+
if (file.startsWith(`${LUMENFLOW_PATHS.STAMPS_DIR}/`))
|
|
1048
1084
|
return false;
|
|
1049
1085
|
// WU-1072: Whitelist apps/docs/**/*.mdx for auto-generated docs from turbo docs:generate
|
|
1050
1086
|
if (file.startsWith('apps/docs/') && file.endsWith('.mdx'))
|
|
@@ -1054,13 +1090,14 @@ async function validateStagedFiles(id, isDocsOnly = false) {
|
|
|
1054
1090
|
if (unexpected.length > 0) {
|
|
1055
1091
|
// WU-1311: Use config-based pattern for WU YAML detection
|
|
1056
1092
|
const wuDirPattern = config.directories.wuDir.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1093
|
+
// eslint-disable-next-line security/detect-non-literal-regexp -- config path escaped for regex; not user input
|
|
1057
1094
|
const wuYamlRegex = new RegExp(`^${wuDirPattern}/WU-\\d+\\.yaml$`);
|
|
1058
1095
|
const otherWuYamlOnly = unexpected.every((f) => wuYamlRegex.test(f));
|
|
1059
1096
|
if (otherWuYamlOnly) {
|
|
1060
1097
|
console.warn(`${LOG_PREFIX.DONE} Warning: other WU YAMLs are staged; proceeding and committing only current WU files.`);
|
|
1061
1098
|
}
|
|
1062
1099
|
else {
|
|
1063
|
-
die(`Unexpected files staged (only current WU
|
|
1100
|
+
die(`Unexpected files staged (only current WU metadata, current parent initiative YAML, and .lumenflow/stamps/<id>.done allowed):\n ${unexpected.join(`${STRING_LITERALS.NEWLINE} `)}`);
|
|
1064
1101
|
}
|
|
1065
1102
|
}
|
|
1066
1103
|
}
|
|
@@ -1579,6 +1616,16 @@ async function executePreFlightChecks({ id, args, isBranchOnly, isDocsOnly, docM
|
|
|
1579
1616
|
}
|
|
1580
1617
|
else if (dirtyResult.relatedFiles.length > 0) {
|
|
1581
1618
|
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} WU-1503: ${dirtyResult.relatedFiles.length} related dirty file(s) on main (allowed)`);
|
|
1619
|
+
// WU-1554: Auto-restore related dirty files so ff-only merge can proceed.
|
|
1620
|
+
// These files will be overwritten by the merge commit anyway.
|
|
1621
|
+
// Without this, git merge --ff-only refuses to overwrite dirty tracked files.
|
|
1622
|
+
try {
|
|
1623
|
+
await gitAdapter.raw(['checkout', '--', ...dirtyResult.relatedFiles]);
|
|
1624
|
+
console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} WU-1554: Auto-restored ${dirtyResult.relatedFiles.length} related file(s) for clean merge`);
|
|
1625
|
+
}
|
|
1626
|
+
catch (restoreErr) {
|
|
1627
|
+
console.warn(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} WU-1554: Could not auto-restore related files: ${restoreErr.message}`);
|
|
1628
|
+
}
|
|
1582
1629
|
}
|
|
1583
1630
|
}
|
|
1584
1631
|
}
|
|
@@ -1589,7 +1636,7 @@ async function executePreFlightChecks({ id, args, isBranchOnly, isDocsOnly, docM
|
|
|
1589
1636
|
// which causes the auto-rebase to fail with "You have unstaged changes"
|
|
1590
1637
|
if (derivedWorktree) {
|
|
1591
1638
|
try {
|
|
1592
|
-
execSync(`git -C "${derivedWorktree}" restore "${
|
|
1639
|
+
execSync(`git -C "${derivedWorktree}" restore "${LUMENFLOW_PATHS.WU_EVENTS}"`);
|
|
1593
1640
|
}
|
|
1594
1641
|
catch {
|
|
1595
1642
|
// Non-fatal: file might not exist or already clean
|
|
@@ -1812,7 +1859,7 @@ async function executeGates({ id, args, isBranchOnly, isDocsOnly, worktreePath,
|
|
|
1812
1859
|
// This restores the file to HEAD state - checkpoint data is preserved in memory store
|
|
1813
1860
|
if (worktreePath) {
|
|
1814
1861
|
try {
|
|
1815
|
-
execSync(`git -C "${worktreePath}" restore "${
|
|
1862
|
+
execSync(`git -C "${worktreePath}" restore "${LUMENFLOW_PATHS.WU_EVENTS}"`);
|
|
1816
1863
|
}
|
|
1817
1864
|
catch {
|
|
1818
1865
|
// Non-fatal: file might not exist or already clean
|
|
@@ -1825,7 +1872,7 @@ async function executeGates({ id, args, isBranchOnly, isDocsOnly, worktreePath,
|
|
|
1825
1872
|
const invariantsBaseDir = worktreePath || process.cwd();
|
|
1826
1873
|
console.log(`\n${LOG_PREFIX.DONE} Running invariants check (non-bypassable)...`);
|
|
1827
1874
|
console.log(`${LOG_PREFIX.DONE} Checking invariants in: ${invariantsBaseDir}`);
|
|
1828
|
-
const { runInvariants } = await import('@lumenflow/core/
|
|
1875
|
+
const { runInvariants } = await import('@lumenflow/core/invariants-runner');
|
|
1829
1876
|
const invariantsResult = runInvariants({ baseDir: invariantsBaseDir, silent: false, wuId: id });
|
|
1830
1877
|
if (!invariantsResult.success) {
|
|
1831
1878
|
emitTelemetry({
|
|
@@ -2175,9 +2222,12 @@ async function main() {
|
|
|
2175
2222
|
else {
|
|
2176
2223
|
// Worktree mode: update in worktree, commit, then merge or create PR
|
|
2177
2224
|
// WU-1369: Uses atomic transaction pattern
|
|
2225
|
+
// WU-1541: Create worktree-aware validateStagedFiles to avoid process.chdir dependency
|
|
2226
|
+
const worktreeGitForValidation = createGitForPath(worktreePath);
|
|
2178
2227
|
const worktreeContext = {
|
|
2179
2228
|
...baseContext,
|
|
2180
2229
|
worktreePath,
|
|
2230
|
+
validateStagedFiles: (wuId, docsOnly, options) => validateStagedFiles(wuId, docsOnly, worktreeGitForValidation, options),
|
|
2181
2231
|
};
|
|
2182
2232
|
completionResult = await executeWorktreeCompletion(worktreeContext);
|
|
2183
2233
|
}
|
|
@@ -2219,9 +2269,10 @@ async function main() {
|
|
|
2219
2269
|
await ensureNoAutoStagedOrNoop([WU_PATH, STATUS_PATH, BACKLOG_PATH, STAMPS_DIR]);
|
|
2220
2270
|
}
|
|
2221
2271
|
// WU-1084: Check for uncommitted changes on main after merge
|
|
2222
|
-
//
|
|
2272
|
+
// WU-1554: Pass metadataDir so metadata files are classified separately
|
|
2273
|
+
const metadataDir = path.dirname(STATUS_PATH);
|
|
2223
2274
|
const postMergeStatus = await getGitForCwd().getStatus();
|
|
2224
|
-
const dirtyCheck = checkPostMergeDirtyState(postMergeStatus, id);
|
|
2275
|
+
const dirtyCheck = checkPostMergeDirtyState(postMergeStatus, id, metadataDir);
|
|
2225
2276
|
if (dirtyCheck.internalOnlyFiles.length > 0) {
|
|
2226
2277
|
const gitMain = getGitForCwd();
|
|
2227
2278
|
try {
|
|
@@ -2232,6 +2283,21 @@ async function main() {
|
|
|
2232
2283
|
console.warn(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Could not auto-restore internal lifecycle files: ${restoreErr.message}`);
|
|
2233
2284
|
}
|
|
2234
2285
|
}
|
|
2286
|
+
// WU-1554: Auto-commit metadata files left dirty after merge+rebase
|
|
2287
|
+
// This handles push-only claim mode and concurrent agent advancement
|
|
2288
|
+
if (dirtyCheck.metadataFiles.length > 0) {
|
|
2289
|
+
const gitMain = getGitForCwd();
|
|
2290
|
+
try {
|
|
2291
|
+
await gitMain.add(dirtyCheck.metadataFiles);
|
|
2292
|
+
await gitMain.commit(`chore: post-merge metadata sync for ${id} [skip ci]`);
|
|
2293
|
+
await gitMain.raw(['pull', '--rebase', '--autostash', 'origin', 'main']);
|
|
2294
|
+
await gitMain.push('origin', 'main');
|
|
2295
|
+
console.log(`${LOG_PREFIX.DONE} ${EMOJI.SUCCESS} Auto-committed post-merge metadata: ${dirtyCheck.metadataFiles.join(', ')}`);
|
|
2296
|
+
}
|
|
2297
|
+
catch (commitErr) {
|
|
2298
|
+
console.warn(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Could not auto-commit metadata files: ${commitErr.message}`);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2235
2301
|
if (dirtyCheck.isDirty) {
|
|
2236
2302
|
die(dirtyCheck.error);
|
|
2237
2303
|
}
|
|
@@ -2454,6 +2520,6 @@ async function detectChangedDocPaths(worktreePath, baseBranch) {
|
|
|
2454
2520
|
// path but import.meta.url resolves to the real path - they never match
|
|
2455
2521
|
import { runCLI } from './cli-entry-point.js';
|
|
2456
2522
|
if (import.meta.main) {
|
|
2457
|
-
runCLI(main);
|
|
2523
|
+
void runCLI(main);
|
|
2458
2524
|
}
|
|
2459
2525
|
//# sourceMappingURL=wu-done.js.map
|