@lumenflow/cli 2.15.2 → 2.17.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.
Files changed (232) hide show
  1. package/dist/agent-issues-query.js +5 -5
  2. package/dist/agent-issues-query.js.map +1 -1
  3. package/dist/agent-log-issue.js +5 -4
  4. package/dist/agent-log-issue.js.map +1 -1
  5. package/dist/agent-session-end.js +3 -2
  6. package/dist/agent-session-end.js.map +1 -1
  7. package/dist/agent-session.js +3 -2
  8. package/dist/agent-session.js.map +1 -1
  9. package/dist/backlog-prune.js +5 -5
  10. package/dist/backlog-prune.js.map +1 -1
  11. package/dist/cli-entry-point.js +56 -3
  12. package/dist/cli-entry-point.js.map +1 -1
  13. package/dist/commands/integrate.js +29 -26
  14. package/dist/commands/integrate.js.map +1 -1
  15. package/dist/commands.js +10 -1
  16. package/dist/commands.js.map +1 -1
  17. package/dist/deps-add.js +65 -24
  18. package/dist/deps-add.js.map +1 -1
  19. package/dist/deps-remove.js +19 -11
  20. package/dist/deps-remove.js.map +1 -1
  21. package/dist/docs-sync.js +3 -2
  22. package/dist/docs-sync.js.map +1 -1
  23. package/dist/doctor.js +9 -4
  24. package/dist/doctor.js.map +1 -1
  25. package/dist/file-delete.js +1 -1
  26. package/dist/file-delete.js.map +1 -1
  27. package/dist/file-edit.js +1 -1
  28. package/dist/file-edit.js.map +1 -1
  29. package/dist/file-read.js +1 -1
  30. package/dist/file-read.js.map +1 -1
  31. package/dist/file-write.js +2 -2
  32. package/dist/file-write.js.map +1 -1
  33. package/dist/flow-bottlenecks.js +5 -6
  34. package/dist/flow-bottlenecks.js.map +1 -1
  35. package/dist/flow-report.js +4 -5
  36. package/dist/flow-report.js.map +1 -1
  37. package/dist/gate-defaults.js +149 -0
  38. package/dist/gate-defaults.js.map +1 -0
  39. package/dist/gate-registry.js +82 -0
  40. package/dist/gate-registry.js.map +1 -0
  41. package/dist/gates-types.js +10 -0
  42. package/dist/gates-types.js.map +1 -0
  43. package/dist/gates.js +161 -234
  44. package/dist/gates.js.map +1 -1
  45. package/dist/git-branch.js +1 -1
  46. package/dist/git-branch.js.map +1 -1
  47. package/dist/git-diff.js +1 -1
  48. package/dist/git-diff.js.map +1 -1
  49. package/dist/git-log.js +1 -1
  50. package/dist/git-log.js.map +1 -1
  51. package/dist/git-status.js +1 -1
  52. package/dist/git-status.js.map +1 -1
  53. package/dist/guard-locked.js +6 -7
  54. package/dist/guard-locked.js.map +1 -1
  55. package/dist/guard-main-branch.js +3 -2
  56. package/dist/guard-main-branch.js.map +1 -1
  57. package/dist/guard-worktree-commit.js +4 -5
  58. package/dist/guard-worktree-commit.js.map +1 -1
  59. package/dist/hooks/enforcement-generator.js +1 -1
  60. package/dist/hooks/enforcement-generator.js.map +1 -1
  61. package/dist/init.js +70 -16
  62. package/dist/init.js.map +1 -1
  63. package/dist/initiative-add-wu.js +12 -12
  64. package/dist/initiative-add-wu.js.map +1 -1
  65. package/dist/initiative-bulk-assign-wus.js +8 -9
  66. package/dist/initiative-bulk-assign-wus.js.map +1 -1
  67. package/dist/initiative-create.js +11 -11
  68. package/dist/initiative-create.js.map +1 -1
  69. package/dist/initiative-edit.js +9 -9
  70. package/dist/initiative-edit.js.map +1 -1
  71. package/dist/initiative-list.js +4 -4
  72. package/dist/initiative-list.js.map +1 -1
  73. package/dist/initiative-plan.js +12 -12
  74. package/dist/initiative-plan.js.map +1 -1
  75. package/dist/initiative-remove-wu.js +11 -11
  76. package/dist/initiative-remove-wu.js.map +1 -1
  77. package/dist/initiative-status.js +6 -6
  78. package/dist/initiative-status.js.map +1 -1
  79. package/dist/lane-health.js +2 -2
  80. package/dist/lane-health.js.map +1 -1
  81. package/dist/lane-suggest.js +2 -2
  82. package/dist/lane-suggest.js.map +1 -1
  83. package/dist/lifecycle-regression-harness.js +5 -5
  84. package/dist/lifecycle-regression-harness.js.map +1 -1
  85. package/dist/lumenflow-upgrade.js +4 -4
  86. package/dist/lumenflow-upgrade.js.map +1 -1
  87. package/dist/mem-checkpoint.js +8 -7
  88. package/dist/mem-checkpoint.js.map +1 -1
  89. package/dist/mem-cleanup.js +12 -14
  90. package/dist/mem-cleanup.js.map +1 -1
  91. package/dist/mem-context.js +8 -7
  92. package/dist/mem-context.js.map +1 -1
  93. package/dist/mem-create.js +9 -8
  94. package/dist/mem-create.js.map +1 -1
  95. package/dist/mem-delete.js +8 -7
  96. package/dist/mem-delete.js.map +1 -1
  97. package/dist/mem-export.js +9 -8
  98. package/dist/mem-export.js.map +1 -1
  99. package/dist/mem-inbox.js +40 -16
  100. package/dist/mem-inbox.js.map +1 -1
  101. package/dist/mem-index.js +8 -7
  102. package/dist/mem-index.js.map +1 -1
  103. package/dist/mem-init.js +8 -7
  104. package/dist/mem-init.js.map +1 -1
  105. package/dist/mem-profile.js +8 -7
  106. package/dist/mem-profile.js.map +1 -1
  107. package/dist/mem-promote.js +8 -7
  108. package/dist/mem-promote.js.map +1 -1
  109. package/dist/mem-ready.js +9 -8
  110. package/dist/mem-ready.js.map +1 -1
  111. package/dist/mem-recover.js +8 -7
  112. package/dist/mem-recover.js.map +1 -1
  113. package/dist/mem-signal.js +9 -8
  114. package/dist/mem-signal.js.map +1 -1
  115. package/dist/mem-start.js +8 -7
  116. package/dist/mem-start.js.map +1 -1
  117. package/dist/mem-summarize.js +8 -7
  118. package/dist/mem-summarize.js.map +1 -1
  119. package/dist/mem-triage.js +8 -7
  120. package/dist/mem-triage.js.map +1 -1
  121. package/dist/metrics-cli.js +5 -6
  122. package/dist/metrics-cli.js.map +1 -1
  123. package/dist/metrics-snapshot.js +6 -6
  124. package/dist/metrics-snapshot.js.map +1 -1
  125. package/dist/onboarding-smoke-test.js +3 -0
  126. package/dist/onboarding-smoke-test.js.map +1 -1
  127. package/dist/orchestrate-init-status.js +2 -2
  128. package/dist/orchestrate-init-status.js.map +1 -1
  129. package/dist/orchestrate-initiative.js +2 -2
  130. package/dist/orchestrate-initiative.js.map +1 -1
  131. package/dist/orchestrate-monitor.js +8 -1
  132. package/dist/orchestrate-monitor.js.map +1 -1
  133. package/dist/plan-create.js +8 -8
  134. package/dist/plan-create.js.map +1 -1
  135. package/dist/plan-edit.js +7 -7
  136. package/dist/plan-edit.js.map +1 -1
  137. package/dist/plan-link.js +9 -9
  138. package/dist/plan-link.js.map +1 -1
  139. package/dist/plan-promote.js +8 -8
  140. package/dist/plan-promote.js.map +1 -1
  141. package/dist/release.js +10 -9
  142. package/dist/release.js.map +1 -1
  143. package/dist/rotate-progress.js +4 -3
  144. package/dist/rotate-progress.js.map +1 -1
  145. package/dist/session-coordinator.js +2 -2
  146. package/dist/session-coordinator.js.map +1 -1
  147. package/dist/signal-cleanup.js +10 -13
  148. package/dist/signal-cleanup.js.map +1 -1
  149. package/dist/spawn-list.js +9 -10
  150. package/dist/spawn-list.js.map +1 -1
  151. package/dist/state-bootstrap.js +3 -3
  152. package/dist/state-bootstrap.js.map +1 -1
  153. package/dist/state-cleanup.js +13 -16
  154. package/dist/state-cleanup.js.map +1 -1
  155. package/dist/state-doctor-fix.js +14 -20
  156. package/dist/state-doctor-fix.js.map +1 -1
  157. package/dist/state-doctor-stamps.js +21 -0
  158. package/dist/state-doctor-stamps.js.map +1 -0
  159. package/dist/state-doctor.js +17 -26
  160. package/dist/state-doctor.js.map +1 -1
  161. package/dist/strict-progress.js +253 -0
  162. package/dist/strict-progress.js.map +1 -0
  163. package/dist/sync-templates.js +1 -0
  164. package/dist/sync-templates.js.map +1 -1
  165. package/dist/trace-gen.js +74 -10
  166. package/dist/trace-gen.js.map +1 -1
  167. package/dist/validate-agent-skills.js +6 -5
  168. package/dist/validate-agent-skills.js.map +1 -1
  169. package/dist/validate-agent-sync.js +4 -5
  170. package/dist/validate-agent-sync.js.map +1 -1
  171. package/dist/validate-backlog-sync.js +5 -6
  172. package/dist/validate-backlog-sync.js.map +1 -1
  173. package/dist/validate-skills-spec.js +6 -5
  174. package/dist/validate-skills-spec.js.map +1 -1
  175. package/dist/validate.js +6 -7
  176. package/dist/validate.js.map +1 -1
  177. package/dist/validator-defaults.js +119 -0
  178. package/dist/validator-defaults.js.map +1 -0
  179. package/dist/validator-registry.js +81 -0
  180. package/dist/validator-registry.js.map +1 -0
  181. package/dist/wu-block.js +20 -19
  182. package/dist/wu-block.js.map +1 -1
  183. package/dist/wu-claim-mode.js +1 -1
  184. package/dist/wu-claim-mode.js.map +1 -1
  185. package/dist/wu-claim.js +33 -32
  186. package/dist/wu-claim.js.map +1 -1
  187. package/dist/wu-cleanup.js +11 -11
  188. package/dist/wu-cleanup.js.map +1 -1
  189. package/dist/wu-create.js +27 -27
  190. package/dist/wu-create.js.map +1 -1
  191. package/dist/wu-delete.js +16 -17
  192. package/dist/wu-delete.js.map +1 -1
  193. package/dist/wu-deps.js +7 -7
  194. package/dist/wu-deps.js.map +1 -1
  195. package/dist/wu-done-auto-cleanup.js +19 -20
  196. package/dist/wu-done-auto-cleanup.js.map +1 -1
  197. package/dist/wu-done-check.js +3 -2
  198. package/dist/wu-done-check.js.map +1 -1
  199. package/dist/wu-done-decay.js +3 -7
  200. package/dist/wu-done-decay.js.map +1 -1
  201. package/dist/wu-done.js +124 -63
  202. package/dist/wu-done.js.map +1 -1
  203. package/dist/wu-edit.js +22 -23
  204. package/dist/wu-edit.js.map +1 -1
  205. package/dist/wu-infer-lane.js +6 -6
  206. package/dist/wu-infer-lane.js.map +1 -1
  207. package/dist/wu-preflight.js +7 -7
  208. package/dist/wu-preflight.js.map +1 -1
  209. package/dist/wu-prep.js +10 -8
  210. package/dist/wu-prep.js.map +1 -1
  211. package/dist/wu-proto.js +14 -14
  212. package/dist/wu-proto.js.map +1 -1
  213. package/dist/wu-prune.js +7 -7
  214. package/dist/wu-prune.js.map +1 -1
  215. package/dist/wu-recover.js +13 -13
  216. package/dist/wu-recover.js.map +1 -1
  217. package/dist/wu-release.js +17 -16
  218. package/dist/wu-release.js.map +1 -1
  219. package/dist/wu-repair.js +4 -4
  220. package/dist/wu-repair.js.map +1 -1
  221. package/dist/wu-spawn.js +20 -20
  222. package/dist/wu-spawn.js.map +1 -1
  223. package/dist/wu-status.js +5 -5
  224. package/dist/wu-status.js.map +1 -1
  225. package/dist/wu-unblock.js +23 -22
  226. package/dist/wu-unblock.js.map +1 -1
  227. package/dist/wu-unlock-lane.js +5 -5
  228. package/dist/wu-unlock-lane.js.map +1 -1
  229. package/dist/wu-validate.js +8 -8
  230. package/dist/wu-validate.js.map +1 -1
  231. package/package.json +7 -6
  232. 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 { VERSION as LUMENFLOW_VERSION } from '@lumenflow/core';
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/dist/git-adapter.js';
44
- import { die } from '@lumenflow/core/dist/error-handler.js';
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/dist/context/location-resolver.js';
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/dist/code-path-validator.js';
50
+ import { validateWUCodePaths } from '@lumenflow/core/code-path-validator';
51
51
  // WU-1983: Migration deployment utilities
52
- import { discoverLocalMigrations, hasMigrationChanges, formatMigrationReport, } from '@lumenflow/core/dist/migration-deployer.js';
53
- import { validateDocsOnly, getAllowedPathsDescription, } from '@lumenflow/core/dist/docs-path-validator.js';
54
- import { scanLogForViolations, rotateLog } from '@lumenflow/core/dist/commands-logger.js';
55
- import { rollbackFiles } from '@lumenflow/core/dist/rollback-utils.js';
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/dist/wu-done-validators.js';
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/dist/code-path-validator.js';
67
- import { BRANCHES, REMOTES, PATTERNS, DEFAULTS, LOG_PREFIX, EMOJI, GIT, SESSION, WU_STATUS, WU_EXPOSURE, PKG_MANAGER, SCRIPTS, CLI_FLAGS, FILE_SYSTEM, STDIO, EXIT_CODES, STRING_LITERALS, MICRO_WORKTREE_OPERATIONS, TELEMETRY_STEPS, SKIP_GATES_REASONS, CHECKPOINT_MESSAGES,
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/dist/wu-constants.js';
70
- import { isDocumentationType } from '@lumenflow/core/dist/wu-type-helpers.js';
71
- import { printGateFailureBox, printStatusPreview } from '@lumenflow/core/dist/wu-done-ui.js';
72
- import { ensureOnMain } from '@lumenflow/core/dist/wu-helpers.js';
73
- import { WU_PATHS, createWuPaths } from '@lumenflow/core/dist/wu-paths.js';
74
- import { getConfig } from '@lumenflow/core/dist/lumenflow-config.js';
75
- import { writeWU, appendNote, parseYAML } from '@lumenflow/core/dist/wu-yaml.js';
76
- import { PLACEHOLDER_SENTINEL, validateWU, validateDoneWU, validateApprovalGates, } from '@lumenflow/core/dist/wu-schema.js';
77
- import { validateBacklogSync } from '@lumenflow/core/dist/backlog-sync-validator.js';
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/dist/wu-done-branch-only.js';
81
- import { executeWorktreeCompletion, autoRebaseBranch, } from '@lumenflow/core/dist/wu-done-worktree.js';
82
- import { checkWUConsistency } from '@lumenflow/core/dist/wu-consistency-checker.js';
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/dist/orchestration-rules.js';
85
- import { endSessionForWU } from '@lumenflow/agent/dist/auto-session-integration.js';
86
- import { runBackgroundProcessCheck } from '@lumenflow/core/dist/process-detector.js';
87
- import { WUStateStore } from '@lumenflow/core/dist/wu-state-store.js';
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/dist/mem-checkpoint-core.js';
90
- import { createSignal, loadSignals } from '@lumenflow/memory/dist/mem-signal-core.js';
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/dist/memory-store.js';
92
+ import { loadMemory, queryByWu } from '@lumenflow/memory/store';
93
93
  // WU-1943: Checkpoint warning helper
94
- import { hasSessionCheckpoints } from '@lumenflow/core/dist/wu-done-worktree.js';
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/dist/lane-lock.js';
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/dist/wu-checkpoint.js';
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/dist/spawn-registry-store.js';
101
- import { SpawnStatus } from '@lumenflow/core/dist/spawn-registry-schema.js';
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, } from '@lumenflow/core/dist/wu-validation.js';
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
- // Path constant for wu-events.jsonl (used in multiple places)
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, WU_EVENTS_PATH);
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 assertWorktreeWUInProgressInStateStore(id, worktreePath) {
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, WU_EVENTS_PATH);
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/dist/path-classifiers.js';
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 ensureCleanWorkingTree() {
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
- * @returns Object with isDirty flag and optional error message
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 unrelatedFiles = dirtyFiles.filter((file) => !INTERNAL_LIFECYCLE_DIRTY_FILES.has(file));
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
- WU_EVENTS_PATH,
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 (whitelist.includes(file))
1080
+ if (whitelistSet.has(file))
1047
1081
  return false;
1048
- // Whitelist .lumenflow/stamps/** pattern
1049
- if (file.startsWith('.lumenflow/stamps/'))
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 YAML, status.md, backlog.md, .lumenflow/stamps/<id>.done allowed):\n ${unexpected.join(`${STRING_LITERALS.NEWLINE} `)}`);
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 "${WU_EVENTS_PATH}"`);
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 "${WU_EVENTS_PATH}"`);
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/dist/invariants-runner.js');
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
- // This catches cases where pnpm format touched files outside code_paths
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