@lumenflow/cli 2.15.2 → 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 +161 -234
- 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 +19 -20
- 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 +124 -63
- 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, createGitForPath } 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.
|
|
@@ -1019,7 +1051,7 @@ async function runGatesInWorktree(worktreePath, id, options = {}) {
|
|
|
1019
1051
|
die(`Gates failed in ${worktreePath}. Fix issues in the worktree and try again.`);
|
|
1020
1052
|
}
|
|
1021
1053
|
}
|
|
1022
|
-
async function validateStagedFiles(id, isDocsOnly = false, gitAdapter) {
|
|
1054
|
+
async function validateStagedFiles(id, isDocsOnly = false, gitAdapter, options = {}) {
|
|
1023
1055
|
// WU-1541: Accept optional gitAdapter to avoid process.chdir dependency
|
|
1024
1056
|
const staged = await listStaged(gitAdapter);
|
|
1025
1057
|
// WU-1311: Use config-based paths instead of hardcoded docs/04-operations paths
|
|
@@ -1030,8 +1062,10 @@ async function validateStagedFiles(id, isDocsOnly = false, gitAdapter) {
|
|
|
1030
1062
|
wuPath,
|
|
1031
1063
|
config.directories.statusPath,
|
|
1032
1064
|
config.directories.backlogPath,
|
|
1033
|
-
|
|
1065
|
+
LUMENFLOW_PATHS.WU_EVENTS,
|
|
1034
1066
|
];
|
|
1067
|
+
const metadataAllowlist = (options.metadataAllowlist ?? []).filter((file) => typeof file === 'string' && file.length > 0);
|
|
1068
|
+
const whitelistSet = new Set([...whitelist, ...metadataAllowlist]);
|
|
1035
1069
|
if (isDocsOnly) {
|
|
1036
1070
|
// For docs-only WUs, validate that all staged files are in allowed paths
|
|
1037
1071
|
const docsResult = validateDocsOnly(staged);
|
|
@@ -1043,10 +1077,10 @@ async function validateStagedFiles(id, isDocsOnly = false, gitAdapter) {
|
|
|
1043
1077
|
}
|
|
1044
1078
|
const unexpected = staged.filter((file) => {
|
|
1045
1079
|
// Whitelist exact matches
|
|
1046
|
-
if (
|
|
1080
|
+
if (whitelistSet.has(file))
|
|
1047
1081
|
return false;
|
|
1048
|
-
// Whitelist
|
|
1049
|
-
if (file.startsWith(
|
|
1082
|
+
// Whitelist stamps directory pattern
|
|
1083
|
+
if (file.startsWith(`${LUMENFLOW_PATHS.STAMPS_DIR}/`))
|
|
1050
1084
|
return false;
|
|
1051
1085
|
// WU-1072: Whitelist apps/docs/**/*.mdx for auto-generated docs from turbo docs:generate
|
|
1052
1086
|
if (file.startsWith('apps/docs/') && file.endsWith('.mdx'))
|
|
@@ -1056,13 +1090,14 @@ async function validateStagedFiles(id, isDocsOnly = false, gitAdapter) {
|
|
|
1056
1090
|
if (unexpected.length > 0) {
|
|
1057
1091
|
// WU-1311: Use config-based pattern for WU YAML detection
|
|
1058
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
|
|
1059
1094
|
const wuYamlRegex = new RegExp(`^${wuDirPattern}/WU-\\d+\\.yaml$`);
|
|
1060
1095
|
const otherWuYamlOnly = unexpected.every((f) => wuYamlRegex.test(f));
|
|
1061
1096
|
if (otherWuYamlOnly) {
|
|
1062
1097
|
console.warn(`${LOG_PREFIX.DONE} Warning: other WU YAMLs are staged; proceeding and committing only current WU files.`);
|
|
1063
1098
|
}
|
|
1064
1099
|
else {
|
|
1065
|
-
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} `)}`);
|
|
1066
1101
|
}
|
|
1067
1102
|
}
|
|
1068
1103
|
}
|
|
@@ -1581,6 +1616,16 @@ async function executePreFlightChecks({ id, args, isBranchOnly, isDocsOnly, docM
|
|
|
1581
1616
|
}
|
|
1582
1617
|
else if (dirtyResult.relatedFiles.length > 0) {
|
|
1583
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
|
+
}
|
|
1584
1629
|
}
|
|
1585
1630
|
}
|
|
1586
1631
|
}
|
|
@@ -1591,7 +1636,7 @@ async function executePreFlightChecks({ id, args, isBranchOnly, isDocsOnly, docM
|
|
|
1591
1636
|
// which causes the auto-rebase to fail with "You have unstaged changes"
|
|
1592
1637
|
if (derivedWorktree) {
|
|
1593
1638
|
try {
|
|
1594
|
-
execSync(`git -C "${derivedWorktree}" restore "${
|
|
1639
|
+
execSync(`git -C "${derivedWorktree}" restore "${LUMENFLOW_PATHS.WU_EVENTS}"`);
|
|
1595
1640
|
}
|
|
1596
1641
|
catch {
|
|
1597
1642
|
// Non-fatal: file might not exist or already clean
|
|
@@ -1814,7 +1859,7 @@ async function executeGates({ id, args, isBranchOnly, isDocsOnly, worktreePath,
|
|
|
1814
1859
|
// This restores the file to HEAD state - checkpoint data is preserved in memory store
|
|
1815
1860
|
if (worktreePath) {
|
|
1816
1861
|
try {
|
|
1817
|
-
execSync(`git -C "${worktreePath}" restore "${
|
|
1862
|
+
execSync(`git -C "${worktreePath}" restore "${LUMENFLOW_PATHS.WU_EVENTS}"`);
|
|
1818
1863
|
}
|
|
1819
1864
|
catch {
|
|
1820
1865
|
// Non-fatal: file might not exist or already clean
|
|
@@ -1827,7 +1872,7 @@ async function executeGates({ id, args, isBranchOnly, isDocsOnly, worktreePath,
|
|
|
1827
1872
|
const invariantsBaseDir = worktreePath || process.cwd();
|
|
1828
1873
|
console.log(`\n${LOG_PREFIX.DONE} Running invariants check (non-bypassable)...`);
|
|
1829
1874
|
console.log(`${LOG_PREFIX.DONE} Checking invariants in: ${invariantsBaseDir}`);
|
|
1830
|
-
const { runInvariants } = await import('@lumenflow/core/
|
|
1875
|
+
const { runInvariants } = await import('@lumenflow/core/invariants-runner');
|
|
1831
1876
|
const invariantsResult = runInvariants({ baseDir: invariantsBaseDir, silent: false, wuId: id });
|
|
1832
1877
|
if (!invariantsResult.success) {
|
|
1833
1878
|
emitTelemetry({
|
|
@@ -2182,7 +2227,7 @@ async function main() {
|
|
|
2182
2227
|
const worktreeContext = {
|
|
2183
2228
|
...baseContext,
|
|
2184
2229
|
worktreePath,
|
|
2185
|
-
validateStagedFiles: (wuId, docsOnly) => validateStagedFiles(wuId, docsOnly, worktreeGitForValidation),
|
|
2230
|
+
validateStagedFiles: (wuId, docsOnly, options) => validateStagedFiles(wuId, docsOnly, worktreeGitForValidation, options),
|
|
2186
2231
|
};
|
|
2187
2232
|
completionResult = await executeWorktreeCompletion(worktreeContext);
|
|
2188
2233
|
}
|
|
@@ -2224,9 +2269,10 @@ async function main() {
|
|
|
2224
2269
|
await ensureNoAutoStagedOrNoop([WU_PATH, STATUS_PATH, BACKLOG_PATH, STAMPS_DIR]);
|
|
2225
2270
|
}
|
|
2226
2271
|
// WU-1084: Check for uncommitted changes on main after merge
|
|
2227
|
-
//
|
|
2272
|
+
// WU-1554: Pass metadataDir so metadata files are classified separately
|
|
2273
|
+
const metadataDir = path.dirname(STATUS_PATH);
|
|
2228
2274
|
const postMergeStatus = await getGitForCwd().getStatus();
|
|
2229
|
-
const dirtyCheck = checkPostMergeDirtyState(postMergeStatus, id);
|
|
2275
|
+
const dirtyCheck = checkPostMergeDirtyState(postMergeStatus, id, metadataDir);
|
|
2230
2276
|
if (dirtyCheck.internalOnlyFiles.length > 0) {
|
|
2231
2277
|
const gitMain = getGitForCwd();
|
|
2232
2278
|
try {
|
|
@@ -2237,6 +2283,21 @@ async function main() {
|
|
|
2237
2283
|
console.warn(`${LOG_PREFIX.DONE} ${EMOJI.WARNING} Could not auto-restore internal lifecycle files: ${restoreErr.message}`);
|
|
2238
2284
|
}
|
|
2239
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
|
+
}
|
|
2240
2301
|
if (dirtyCheck.isDirty) {
|
|
2241
2302
|
die(dirtyCheck.error);
|
|
2242
2303
|
}
|
|
@@ -2459,6 +2520,6 @@ async function detectChangedDocPaths(worktreePath, baseBranch) {
|
|
|
2459
2520
|
// path but import.meta.url resolves to the real path - they never match
|
|
2460
2521
|
import { runCLI } from './cli-entry-point.js';
|
|
2461
2522
|
if (import.meta.main) {
|
|
2462
|
-
runCLI(main);
|
|
2523
|
+
void runCLI(main);
|
|
2463
2524
|
}
|
|
2464
2525
|
//# sourceMappingURL=wu-done.js.map
|