@lumenflow/cli 5.5.0 → 5.7.14

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 (229) hide show
  1. package/README.md +41 -40
  2. package/dist/db-journal-recover.js +400 -0
  3. package/dist/db-journal-recover.js.map +1 -0
  4. package/dist/docs-sync.js +8 -3
  5. package/dist/docs-sync.js.map +1 -1
  6. package/dist/doctor.js +11 -0
  7. package/dist/doctor.js.map +1 -1
  8. package/dist/gate-defaults.js +37 -0
  9. package/dist/gate-defaults.js.map +1 -1
  10. package/dist/gates/monolithic-file-contention-guard.js +167 -0
  11. package/dist/gates/monolithic-file-contention-guard.js.map +1 -0
  12. package/dist/gates/prod-migration-drift.js +207 -0
  13. package/dist/gates/prod-migration-drift.js.map +1 -0
  14. package/dist/gates/test-over-deletion-guard.js +280 -0
  15. package/dist/gates/test-over-deletion-guard.js.map +1 -0
  16. package/dist/gates-runners.js +44 -3
  17. package/dist/gates-runners.js.map +1 -1
  18. package/dist/gates.js +3 -2
  19. package/dist/gates.js.map +1 -1
  20. package/dist/hooks/config-resolver.js +16 -1
  21. package/dist/hooks/config-resolver.js.map +1 -1
  22. package/dist/hooks/dirty-guard.js +43 -2
  23. package/dist/hooks/dirty-guard.js.map +1 -1
  24. package/dist/hooks/git-status-parser.js +22 -8
  25. package/dist/hooks/git-status-parser.js.map +1 -1
  26. package/dist/init-templates.js +241 -0
  27. package/dist/init-templates.js.map +1 -1
  28. package/dist/init.js +122 -16
  29. package/dist/init.js.map +1 -1
  30. package/dist/lumenflow-setup.js +144 -0
  31. package/dist/lumenflow-setup.js.map +1 -0
  32. package/dist/lumenflow-upgrade.js +43 -1
  33. package/dist/lumenflow-upgrade.js.map +1 -1
  34. package/dist/mem-create.js +10 -1
  35. package/dist/mem-create.js.map +1 -1
  36. package/dist/mem-signal.js +21 -4
  37. package/dist/mem-signal.js.map +1 -1
  38. package/dist/orchestrate-initiative.js +28 -3
  39. package/dist/orchestrate-initiative.js.map +1 -1
  40. package/dist/public-manifest.js +17 -7
  41. package/dist/public-manifest.js.map +1 -1
  42. package/dist/release.js +53 -18
  43. package/dist/release.js.map +1 -1
  44. package/dist/wu-done-gates.js +13 -9
  45. package/dist/wu-done-gates.js.map +1 -1
  46. package/dist/wu-done.js +14 -2
  47. package/dist/wu-done.js.map +1 -1
  48. package/dist/wu-edit-operations.js +74 -0
  49. package/dist/wu-edit-operations.js.map +1 -1
  50. package/dist/wu-edit-validators.js +58 -0
  51. package/dist/wu-edit-validators.js.map +1 -1
  52. package/dist/wu-edit.js +106 -4
  53. package/dist/wu-edit.js.map +1 -1
  54. package/dist/wu-prep.js +57 -9
  55. package/dist/wu-prep.js.map +1 -1
  56. package/dist/wu-recover.js +6 -0
  57. package/dist/wu-recover.js.map +1 -1
  58. package/dist/wu-release.js +120 -2
  59. package/dist/wu-release.js.map +1 -1
  60. package/dist/wu-sizing-validation.js +47 -17
  61. package/dist/wu-sizing-validation.js.map +1 -1
  62. package/dist/wu-status.js +33 -0
  63. package/dist/wu-status.js.map +1 -1
  64. package/package.json +13 -12
  65. package/packs/agent-runtime/package.json +1 -1
  66. package/packs/sidekick/package.json +1 -1
  67. package/packs/software-delivery/package.json +1 -1
  68. package/templates/core/AGENTS.md.template +67 -3
  69. package/templates/core/LUMENFLOW.md.template +196 -47
  70. package/dist/distribution-preflight.js +0 -230
  71. package/dist/distribution-preflight.js.map +0 -1
  72. package/packs/agent-runtime/agent-heartbeat.ts +0 -163
  73. package/packs/agent-runtime/auto-session-integration.ts +0 -888
  74. package/packs/agent-runtime/capability-factory.ts +0 -104
  75. package/packs/agent-runtime/constants.ts +0 -21
  76. package/packs/agent-runtime/delegation-registry-schema.ts +0 -220
  77. package/packs/agent-runtime/delegation-registry-store.ts +0 -269
  78. package/packs/agent-runtime/delegation-tree.ts +0 -328
  79. package/packs/agent-runtime/index.ts +0 -20
  80. package/packs/agent-runtime/manifest.ts +0 -348
  81. package/packs/agent-runtime/memory-coordination-contract.ts +0 -86
  82. package/packs/agent-runtime/orchestration.ts +0 -2027
  83. package/packs/agent-runtime/pack-registration.ts +0 -110
  84. package/packs/agent-runtime/policy-factory.ts +0 -165
  85. package/packs/agent-runtime/remote-controls/index.ts +0 -7
  86. package/packs/agent-runtime/remote-controls/operations.ts +0 -405
  87. package/packs/agent-runtime/remote-controls/port.ts +0 -48
  88. package/packs/agent-runtime/remote-controls/state-store.ts +0 -258
  89. package/packs/agent-runtime/remote-controls/types.ts +0 -105
  90. package/packs/agent-runtime/session-schema.ts +0 -467
  91. package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +0 -793
  92. package/packs/agent-runtime/tool-impl/index.ts +0 -6
  93. package/packs/agent-runtime/tool-impl/provider-adapters.ts +0 -1245
  94. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +0 -256
  95. package/packs/agent-runtime/tool-impl/remote-controls.ts +0 -273
  96. package/packs/agent-runtime/tools/index.ts +0 -4
  97. package/packs/agent-runtime/tools/types.ts +0 -47
  98. package/packs/agent-runtime/turn-lifecycle-events.ts +0 -590
  99. package/packs/agent-runtime/types.ts +0 -128
  100. package/packs/agent-runtime/vitest.config.ts +0 -11
  101. package/packs/sidekick/channel-ingress.ts +0 -137
  102. package/packs/sidekick/constants.ts +0 -10
  103. package/packs/sidekick/index.ts +0 -8
  104. package/packs/sidekick/manifest-schema.ts +0 -49
  105. package/packs/sidekick/manifest.ts +0 -512
  106. package/packs/sidekick/pack-registration.ts +0 -110
  107. package/packs/sidekick/policy-factory.ts +0 -38
  108. package/packs/sidekick/sidekick-events.ts +0 -694
  109. package/packs/sidekick/src/adapters/cloud-queue.ts +0 -101
  110. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +0 -386
  111. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +0 -228
  112. package/packs/sidekick/src/domain/channel.types.ts +0 -64
  113. package/packs/sidekick/src/ports/channel-bridge.port.ts +0 -92
  114. package/packs/sidekick/src/routines/commit.ts +0 -74
  115. package/packs/sidekick/tool-impl/channel-tools.ts +0 -577
  116. package/packs/sidekick/tool-impl/channel-transports.ts +0 -75
  117. package/packs/sidekick/tool-impl/index.ts +0 -29
  118. package/packs/sidekick/tool-impl/memory-tools.ts +0 -290
  119. package/packs/sidekick/tool-impl/routine-commit.ts +0 -102
  120. package/packs/sidekick/tool-impl/routine-tools.ts +0 -440
  121. package/packs/sidekick/tool-impl/runtime-context.ts +0 -28
  122. package/packs/sidekick/tool-impl/shared.ts +0 -125
  123. package/packs/sidekick/tool-impl/storage.ts +0 -325
  124. package/packs/sidekick/tool-impl/system-tools.ts +0 -160
  125. package/packs/sidekick/tool-impl/task-tools.ts +0 -506
  126. package/packs/sidekick/tools/channel-tools.ts +0 -53
  127. package/packs/sidekick/tools/index.ts +0 -9
  128. package/packs/sidekick/tools/memory-tools.ts +0 -53
  129. package/packs/sidekick/tools/routine-tools.ts +0 -53
  130. package/packs/sidekick/tools/system-tools.ts +0 -47
  131. package/packs/sidekick/tools/task-tools.ts +0 -61
  132. package/packs/sidekick/tools/types.ts +0 -57
  133. package/packs/sidekick/vitest.config.ts +0 -11
  134. package/packs/software-delivery/constants.ts +0 -10
  135. package/packs/software-delivery/extensions.ts +0 -140
  136. package/packs/software-delivery/gate-policies.ts +0 -134
  137. package/packs/software-delivery/index.ts +0 -8
  138. package/packs/software-delivery/manifest-schema.ts +0 -268
  139. package/packs/software-delivery/manifest.ts +0 -657
  140. package/packs/software-delivery/pack-registration.ts +0 -113
  141. package/packs/software-delivery/src/commands/index.ts +0 -5
  142. package/packs/software-delivery/src/config/delivery-review-contract.ts +0 -256
  143. package/packs/software-delivery/src/config/env-accessors.ts +0 -66
  144. package/packs/software-delivery/src/config/index.ts +0 -8
  145. package/packs/software-delivery/src/config/normalize-config-keys.ts +0 -9
  146. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +0 -460
  147. package/packs/software-delivery/src/config/workspace-reader.ts +0 -375
  148. package/packs/software-delivery/src/constants/backlog-patterns.ts +0 -31
  149. package/packs/software-delivery/src/constants/client-ids.ts +0 -19
  150. package/packs/software-delivery/src/constants/config-contract.ts +0 -7
  151. package/packs/software-delivery/src/constants/docs-layout-presets.ts +0 -50
  152. package/packs/software-delivery/src/constants/duration-constants.ts +0 -20
  153. package/packs/software-delivery/src/constants/gate-constants.ts +0 -32
  154. package/packs/software-delivery/src/constants/index.ts +0 -29
  155. package/packs/software-delivery/src/constants/lock-constants.ts +0 -35
  156. package/packs/software-delivery/src/constants/object-guards.ts +0 -12
  157. package/packs/software-delivery/src/constants/section-headings.ts +0 -107
  158. package/packs/software-delivery/src/constants/wu-cli-constants.ts +0 -500
  159. package/packs/software-delivery/src/constants/wu-domain-constants.ts +0 -466
  160. package/packs/software-delivery/src/constants/wu-git-constants.ts +0 -7
  161. package/packs/software-delivery/src/constants/wu-id-format.ts +0 -327
  162. package/packs/software-delivery/src/constants/wu-paths-constants.ts +0 -384
  163. package/packs/software-delivery/src/constants/wu-statuses.ts +0 -287
  164. package/packs/software-delivery/src/constants/wu-type-helpers.ts +0 -67
  165. package/packs/software-delivery/src/constants/wu-ui-constants.ts +0 -267
  166. package/packs/software-delivery/src/constants/wu-validation-constants.ts +0 -73
  167. package/packs/software-delivery/src/domain/index.ts +0 -5
  168. package/packs/software-delivery/src/domain/orchestration.constants.ts +0 -166
  169. package/packs/software-delivery/src/domain/orchestration.schemas.ts +0 -238
  170. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -176
  171. package/packs/software-delivery/src/methodology/incremental-test.ts +0 -122
  172. package/packs/software-delivery/src/methodology/index.ts +0 -6
  173. package/packs/software-delivery/src/methodology/manual-test-validator.ts +0 -292
  174. package/packs/software-delivery/src/policy/coverage-gate.ts +0 -270
  175. package/packs/software-delivery/src/policy/gates-agent-mode.ts +0 -223
  176. package/packs/software-delivery/src/policy/gates-config-internal.ts +0 -121
  177. package/packs/software-delivery/src/policy/gates-config.ts +0 -300
  178. package/packs/software-delivery/src/policy/gates-coverage.ts +0 -356
  179. package/packs/software-delivery/src/policy/gates-presets.ts +0 -134
  180. package/packs/software-delivery/src/policy/gates-schemas.ts +0 -173
  181. package/packs/software-delivery/src/policy/index.ts +0 -22
  182. package/packs/software-delivery/src/policy/package-manager-resolver.ts +0 -319
  183. package/packs/software-delivery/src/policy/resolve-policy.ts +0 -601
  184. package/packs/software-delivery/src/ports/config.ports.ts +0 -90
  185. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +0 -125
  186. package/packs/software-delivery/src/ports/index.ts +0 -10
  187. package/packs/software-delivery/src/ports/sync-validator.ports.ts +0 -59
  188. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +0 -168
  189. package/packs/software-delivery/src/ports/wu-state.ports.ts +0 -241
  190. package/packs/software-delivery/src/primitives/index.ts +0 -5
  191. package/packs/software-delivery/src/runtime/index.ts +0 -6
  192. package/packs/software-delivery/src/runtime/work-classifier.ts +0 -561
  193. package/packs/software-delivery/src/sandbox/index.ts +0 -10
  194. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +0 -118
  195. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +0 -88
  196. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +0 -154
  197. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +0 -47
  198. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +0 -153
  199. package/packs/software-delivery/src/schemas/index.ts +0 -5
  200. package/packs/software-delivery/src/state/date-utils.ts +0 -158
  201. package/packs/software-delivery/src/state/index.ts +0 -15
  202. package/packs/software-delivery/src/state/state-machine.ts +0 -119
  203. package/packs/software-delivery/src/state/wu-doc-types.ts +0 -51
  204. package/packs/software-delivery/src/state/wu-paths.ts +0 -381
  205. package/packs/software-delivery/src/state/wu-schema.ts +0 -1139
  206. package/packs/software-delivery/src/state/wu-state-schema.ts +0 -255
  207. package/packs/software-delivery/src/state/wu-yaml.ts +0 -338
  208. package/packs/software-delivery/tool-impl/agent-tools.ts +0 -263
  209. package/packs/software-delivery/tool-impl/delegation-tools.ts +0 -66
  210. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +0 -219
  211. package/packs/software-delivery/tool-impl/git-runner.ts +0 -113
  212. package/packs/software-delivery/tool-impl/git-tools.ts +0 -316
  213. package/packs/software-delivery/tool-impl/index.ts +0 -15
  214. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +0 -720
  215. package/packs/software-delivery/tool-impl/lane-lock.ts +0 -246
  216. package/packs/software-delivery/tool-impl/memory-tools.ts +0 -470
  217. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +0 -21
  218. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +0 -329
  219. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +0 -687
  220. package/packs/software-delivery/tool-impl/worker-loader.ts +0 -52
  221. package/packs/software-delivery/tool-impl/worktree-tools.ts +0 -46
  222. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +0 -807
  223. package/packs/software-delivery/tools/delegation-tools.ts +0 -23
  224. package/packs/software-delivery/tools/git-tools.ts +0 -55
  225. package/packs/software-delivery/tools/index.ts +0 -8
  226. package/packs/software-delivery/tools/lane-lock-tool.ts +0 -37
  227. package/packs/software-delivery/tools/types.ts +0 -71
  228. package/packs/software-delivery/tools/worktree-tools.ts +0 -49
  229. package/packs/software-delivery/vitest.config.ts +0 -11
@@ -1,223 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
-
4
- import path from 'node:path';
5
- import { existsSync, unlinkSync, symlinkSync } from 'node:fs';
6
-
7
- /**
8
- * Options for agent mode detection
9
- */
10
- interface GatesAgentModeOptions {
11
- /** Command line arguments */
12
- argv?: string[];
13
- /** Environment variables */
14
- env?: Record<string, string | undefined>;
15
- /** stdout stream */
16
- stdout?: { isTTY?: boolean };
17
- }
18
-
19
- /**
20
- * Options for log path functions
21
- */
22
- interface GatesLogOptions {
23
- /** Working directory */
24
- cwd: string;
25
- /** Environment variables */
26
- env?: Record<string, string | undefined>;
27
- }
28
-
29
- /**
30
- * Options for building gate log path
31
- */
32
- interface BuildGatesLogPathOptions extends GatesLogOptions {
33
- /** WU ID */
34
- wuId?: string;
35
- /** Lane name */
36
- lane?: string;
37
- /** Current timestamp */
38
- now?: Date;
39
- }
40
-
41
- /**
42
- * Options for updating symlink
43
- */
44
- interface UpdateGatesLatestSymlinkOptions extends GatesLogOptions {
45
- /** Path to the actual gate log file */
46
- logPath: string;
47
- }
48
-
49
- /**
50
- * Determine whether gates should run in low-noise "agent mode".
51
- *
52
- * Agent mode is intended for Claude Code sessions, where tool output is injected into the
53
- * conversation context and can trigger "prompt too long".
54
- *
55
- * Detection strategy (WU-1827):
56
- * 1. --verbose flag always forces full output (returns false)
57
- * 2. CLAUDE_PROJECT_DIR env var is a strong hint (returns true if set)
58
- * 3. TTY check: non-TTY + non-CI = likely agent mode (returns true)
59
- * 4. Interactive TTY = human user (returns false)
60
- *
61
- * @param {GatesAgentModeOptions} options
62
- * @returns {boolean} True if gates should run in agent mode
63
- */
64
- export function shouldUseGatesAgentMode({ argv, env, stdout }: GatesAgentModeOptions = {}) {
65
- // --verbose flag always forces full output
66
- const isVerbose = Array.isArray(argv) && argv.includes('--verbose');
67
- if (isVerbose) {
68
- return false;
69
- }
70
-
71
- // CLAUDE_PROJECT_DIR is a strong hint that we're in Claude Code
72
- const hasClaudeProjectDir = Boolean(env?.CLAUDE_PROJECT_DIR);
73
- if (hasClaudeProjectDir) {
74
- return true;
75
- }
76
-
77
- // CI environments should get full output for debugging
78
- const isCI = Boolean(env?.CI);
79
- if (isCI) {
80
- return false;
81
- }
82
-
83
- // Use provided stdout or fall back to process.stdout
84
- const stdoutStream = stdout ?? process.stdout;
85
-
86
- // TTY check: non-TTY = likely agent mode (Claude Code Bash tool doesn't have TTY)
87
- // If stdout is undefined or isTTY is falsy, assume agent mode (safer default)
88
- const isTTY = stdoutStream?.isTTY ?? false;
89
-
90
- // Non-TTY + non-CI = likely agent mode
91
- return !isTTY;
92
- }
93
-
94
- export function getGatesLogDir({ cwd, env }: GatesLogOptions) {
95
- const configured = env?.LUMENFLOW_LOG_DIR;
96
- return path.resolve(cwd, configured || '.logs');
97
- }
98
-
99
- export function buildGatesLogPath({
100
- cwd,
101
- env,
102
- wuId,
103
- lane,
104
- now = new Date(),
105
- }: BuildGatesLogPathOptions) {
106
- const logDir = getGatesLogDir({ cwd, env });
107
- const safeLane = (lane || 'unknown').toLowerCase().replace(/[^a-z0-9]+/g, '-');
108
- const safeWu = (wuId || 'unknown').toLowerCase().replace(/[^a-z0-9]+/g, '-');
109
- const stamp = now.toISOString().replace(/[:.]/g, '-');
110
- return path.join(logDir, `gates-${safeLane}-${safeWu}-${stamp}.log`);
111
- }
112
-
113
- /**
114
- * Get the path to the gates-latest.log symlink (WU-2064)
115
- *
116
- * @param {Object} options
117
- * @param {string} options.cwd - Working directory
118
- * @param {Object} [options.env] - Environment variables
119
- * @returns {string} Path to the symlink
120
- */
121
- export function getGatesLatestSymlinkPath({ cwd, env }: GatesLogOptions) {
122
- const logDir = getGatesLogDir({ cwd, env });
123
- return path.join(logDir, 'gates-latest.log');
124
- }
125
-
126
- /**
127
- * Create or update the gates-latest.log symlink to point to the most recent gate run (WU-2064)
128
- *
129
- * This provides a stable path for agents to access the most recent gate log
130
- * without needing to know the timestamp-based filename.
131
- *
132
- * @param {Object} options
133
- * @param {string} options.logPath - Path to the actual gate log file
134
- * @param {string} options.cwd - Working directory
135
- * @param {Object} [options.env] - Environment variables
136
- * @returns {boolean} True if symlink was created/updated successfully
137
- */
138
- export function updateGatesLatestSymlink({ logPath, cwd, env }: UpdateGatesLatestSymlinkOptions) {
139
- const symlinkPath = getGatesLatestSymlinkPath({ cwd, env });
140
-
141
- try {
142
- // Remove existing symlink if present
143
- if (existsSync(symlinkPath)) {
144
- unlinkSync(symlinkPath);
145
- }
146
-
147
- // Create relative symlink (so it works regardless of absolute path)
148
- const logDir = path.dirname(symlinkPath);
149
- const relativePath = path.relative(logDir, logPath);
150
- symlinkSync(relativePath, symlinkPath);
151
-
152
- return true;
153
- } catch {
154
- // Symlink creation is best-effort, don't fail gates
155
- return false;
156
- }
157
- }
158
-
159
- export const WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS = {
160
- SKIP_GATES_FLAG: 'skip-gates-flag',
161
- REUSE_STEP_ZERO: 'reuse-step-zero',
162
- REUSE_CHECKPOINT: 'reuse-checkpoint',
163
- RUN_REQUIRED: 'run-required',
164
- } as const;
165
-
166
- export type WuDonePreCommitGateDecisionReason =
167
- (typeof WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS)[keyof typeof WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS];
168
-
169
- export interface WuDonePreCommitGateDecisionInput {
170
- skipGates: boolean;
171
- fullGatesRanInCurrentRun: boolean;
172
- skippedByCheckpoint: boolean;
173
- checkpointId?: string | null;
174
- }
175
-
176
- export interface WuDonePreCommitGateDecision {
177
- runPreCommitFullSuite: boolean;
178
- reason: WuDonePreCommitGateDecisionReason;
179
- message: string;
180
- }
181
-
182
- /**
183
- * Decide whether wu:done pre-flight hook validation should rerun full gates.
184
- *
185
- * WU-1659: Avoid duplicate full-suite execution when Step 0 already ran gates
186
- * (or reused a valid checkpoint), while keeping operator-visible reasoning.
187
- */
188
- export function resolveWuDonePreCommitGateDecision(
189
- input: WuDonePreCommitGateDecisionInput,
190
- ): WuDonePreCommitGateDecision {
191
- if (input.skipGates) {
192
- return {
193
- runPreCommitFullSuite: false,
194
- reason: WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS.SKIP_GATES_FLAG,
195
- message: 'Pre-flight hook validation skipped because --skip-gates is active.',
196
- };
197
- }
198
-
199
- if (input.fullGatesRanInCurrentRun) {
200
- return {
201
- runPreCommitFullSuite: false,
202
- reason: WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS.REUSE_STEP_ZERO,
203
- message:
204
- 'Pre-flight hook validation reuses Step 0 gate results; duplicate full-suite run skipped.',
205
- };
206
- }
207
-
208
- if (input.skippedByCheckpoint) {
209
- const checkpointSuffix = input.checkpointId ? ` (${input.checkpointId})` : '';
210
- return {
211
- runPreCommitFullSuite: false,
212
- reason: WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS.REUSE_CHECKPOINT,
213
- message: `Pre-flight hook validation reuses checkpoint gate attestation${checkpointSuffix}; duplicate full-suite run skipped.`,
214
- };
215
- }
216
-
217
- return {
218
- runPreCommitFullSuite: true,
219
- reason: WU_DONE_PRE_COMMIT_GATE_DECISION_REASONS.RUN_REQUIRED,
220
- message:
221
- 'No gate attestation found for this wu:done run; executing pre-flight hook gate suite.',
222
- };
223
- }
@@ -1,121 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
-
4
- /**
5
- * Gates Configuration Internals
6
- *
7
- * WU-2037: Shared infrastructure for gates modules
8
- *
9
- * Contains runtime defaults, field-name constants, and config-loading helpers
10
- * used by gates-config.ts, gates-coverage.ts, and package-manager-resolver.ts.
11
- *
12
- * This module exists to break circular imports between the facade (gates-config.ts)
13
- * and its extracted sub-modules.
14
- *
15
- * @module gates-config-internal
16
- */
17
-
18
- import * as fs from 'node:fs';
19
- import * as path from 'node:path';
20
- import * as yaml from 'yaml';
21
- import { WORKSPACE_CONFIG_FILE_NAME, WORKSPACE_V2_KEYS } from '../constants/config-contract.js';
22
- import { asRecord } from '../constants/object-guards.js';
23
- import { getDefaultPolicy } from './resolve-policy.js';
24
-
25
- // ---------------------------------------------------------------------------
26
- // Runtime defaults
27
- // ---------------------------------------------------------------------------
28
-
29
- const DEFAULT_POLICY = getDefaultPolicy();
30
-
31
- export const GATES_RUNTIME_DEFAULTS = {
32
- COMMAND_TIMEOUT_MS: 120000,
33
- MAX_ESLINT_WARNINGS: 100,
34
- DEFAULT_MIN_COVERAGE: DEFAULT_POLICY.coverage_threshold,
35
- DEFAULT_ENABLE_COVERAGE: true,
36
- DEFAULT_PACKAGE_MANAGER: 'pnpm',
37
- DEFAULT_TEST_RUNNER: 'vitest',
38
- } as const;
39
-
40
- // ---------------------------------------------------------------------------
41
- // Field-name constants (avoid magic strings across modules)
42
- // ---------------------------------------------------------------------------
43
-
44
- const SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
45
-
46
- export const SOFTWARE_DELIVERY_FIELDS = {
47
- GATES: 'gates',
48
- METHODOLOGY: 'methodology',
49
- PACKAGE_MANAGER: 'package_manager',
50
- PACKAGE_MANAGER_CAMEL: 'packageManager',
51
- TEST_RUNNER: 'test_runner',
52
- TEST_RUNNER_CAMEL: 'testRunner',
53
- BUILD_COMMAND: 'build_command',
54
- BUILD_COMMAND_CAMEL: 'buildCommand',
55
- } as const;
56
-
57
- export const GATES_FIELDS = {
58
- EXECUTION: 'execution',
59
- LANE_HEALTH: 'lane_health',
60
- LANE_HEALTH_CAMEL: 'laneHealth',
61
- TDD_DIFF_EVIDENCE: 'tdd_diff_evidence',
62
- TDD_ORDERING: 'tdd_ordering',
63
- MIN_COVERAGE: 'minCoverage',
64
- MIN_COVERAGE_SNAKE: 'min_coverage',
65
- ENABLE_COVERAGE: 'enableCoverage',
66
- ENABLE_COVERAGE_SNAKE: 'enable_coverage',
67
- COMMANDS: 'commands',
68
- } as const;
69
-
70
- export const GATES_COMMAND_FIELDS = {
71
- TEST_FULL: 'test_full',
72
- TEST_DOCS_ONLY: 'test_docs_only',
73
- TEST_INCREMENTAL: 'test_incremental',
74
- LINT: 'lint',
75
- TYPECHECK: 'typecheck',
76
- FORMAT: 'format',
77
- MIGRATION_VERIFY: 'migration_verify',
78
- } as const;
79
-
80
- // ---------------------------------------------------------------------------
81
- // Config loading helpers
82
- // ---------------------------------------------------------------------------
83
-
84
- /**
85
- * Load the software_delivery section from workspace.yaml
86
- *
87
- * @param projectRoot - Project root directory
88
- * @returns Parsed software_delivery record, or null
89
- */
90
- export function loadSoftwareDeliveryConfig(projectRoot: string): Record<string, unknown> | null {
91
- const configPath = path.join(projectRoot, WORKSPACE_CONFIG_FILE_NAME);
92
-
93
- if (!fs.existsSync(configPath)) {
94
- return null;
95
- }
96
-
97
- try {
98
- const content = fs.readFileSync(configPath, 'utf8');
99
- const data = asRecord(yaml.parse(content));
100
- if (!data) {
101
- return null;
102
- }
103
- return asRecord(data[SOFTWARE_DELIVERY_KEY]);
104
- } catch {
105
- return null;
106
- }
107
- }
108
-
109
- /**
110
- * Load the gates sub-section from workspace.yaml software_delivery
111
- *
112
- * @param projectRoot - Project root directory
113
- * @returns Parsed gates record, or null
114
- */
115
- export function getGatesSection(projectRoot: string): Record<string, unknown> | null {
116
- const softwareDelivery = loadSoftwareDeliveryConfig(projectRoot);
117
- if (!softwareDelivery) {
118
- return null;
119
- }
120
- return asRecord(softwareDelivery[SOFTWARE_DELIVERY_FIELDS.GATES]);
121
- }
@@ -1,300 +0,0 @@
1
- // Copyright (c) 2026 Hellmai Ltd
2
- // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
-
4
- /**
5
- * Gates Configuration Facade
6
- *
7
- * WU-1067: Config-driven gates execution
8
- * WU-2037: Decomposed into focused sub-modules
9
- *
10
- * This module is the public entry point for gates configuration.
11
- * It re-exports from the extracted sub-modules and retains the
12
- * config-loading, parsing, and lane-health functions that depend
13
- * on the shared infrastructure.
14
- *
15
- * Sub-modules:
16
- * - gates-schemas.ts Zod schemas, types, interfaces
17
- * - gates-presets.ts Preset definitions and expansion
18
- * - gates-coverage.ts Coverage and test policy resolution
19
- * - package-manager-resolver.ts PM, TR, build, commands, ignore
20
- * - gates-config-internal.ts Shared helpers and constants
21
- *
22
- * @module gates-config
23
- */
24
-
25
- import { isString } from '../constants/object-guards.js';
26
- import { WORKSPACE_CONFIG_FILE_NAME, WORKSPACE_V2_KEYS } from '../constants/config-contract.js';
27
- import {
28
- GatesExecutionConfigSchema,
29
- LaneHealthModeSchema,
30
- DEFAULT_LANE_HEALTH_MODE,
31
- } from './gates-schemas.js';
32
- import type {
33
- GateCommandConfig,
34
- GatesExecutionConfig,
35
- ParsedGateCommand,
36
- LaneHealthMode,
37
- } from './gates-schemas.js';
38
- import { expandPreset } from './gates-presets.js';
39
- import { GATES_RUNTIME_DEFAULTS, GATES_FIELDS, getGatesSection } from './gates-config-internal.js';
40
-
41
- // ---------------------------------------------------------------------------
42
- // Re-exports: schemas, types, and interfaces
43
- // ---------------------------------------------------------------------------
44
-
45
- export type {
46
- GateCommandConfig,
47
- GatesExecutionConfig,
48
- ParsedGateCommand,
49
- LaneHealthMode,
50
- CoverageConfig,
51
- CoveragePolicy,
52
- TestRunnerPolicy,
53
- TestPolicy,
54
- GatesCommands,
55
- } from './gates-schemas.js';
56
- export type { TddDiffEvidencePolicy, TddOrderingPolicy } from './resolve-policy.js';
57
-
58
- export type { ScopedUnitTestExecutionPlan } from './package-manager-resolver.js';
59
-
60
- export {
61
- GateCommandConfigSchema,
62
- GatesExecutionConfigSchema,
63
- LaneHealthModeSchema,
64
- DEFAULT_LANE_HEALTH_MODE,
65
- } from './gates-schemas.js';
66
-
67
- // Re-export presets
68
- // WU-2547: PRESET_FIX_COMMANDS and getFormatFixCommand added for preset-aware
69
- // onboarding template rendering in @lumenflow/cli/src/init.ts.
70
- export {
71
- GATE_PRESETS,
72
- expandPreset,
73
- PRESET_FIX_COMMANDS,
74
- getFormatFixCommand,
75
- } from './gates-presets.js';
76
-
77
- // Re-export coverage/test policy resolution
78
- export {
79
- resolveCoverageConfig,
80
- resolveTestPolicy,
81
- resolveTddDiffEvidencePolicy,
82
- resolveTddOrderingPolicy,
83
- evaluateTddDiffEvidenceWaiver,
84
- isPathExemptByTddDiffEvidence,
85
- } from './gates-coverage.js';
86
- export type { TddDiffEvidenceWaiver, TddDiffEvidenceWaiverReason } from './gates-coverage.js';
87
-
88
- // Re-export package manager / test runner resolution
89
- export {
90
- resolvePackageManager,
91
- resolveTestRunner,
92
- resolveBuildCommand,
93
- resolveGatesCommands,
94
- getIgnorePatterns,
95
- resolveGatePreset,
96
- resolveScopedUnitTestExecutionPlan,
97
- formatScopedUnitTestFallbackMessage,
98
- } from './package-manager-resolver.js';
99
-
100
- // Re-export shared infrastructure (consumed by child modules and external callers)
101
- export {
102
- GATES_RUNTIME_DEFAULTS,
103
- SOFTWARE_DELIVERY_FIELDS,
104
- GATES_FIELDS,
105
- GATES_COMMAND_FIELDS,
106
- loadSoftwareDeliveryConfig,
107
- getGatesSection,
108
- } from './gates-config-internal.js';
109
-
110
- // ---------------------------------------------------------------------------
111
- // Config loading / gate parsing / lane health (facade-owned)
112
- // ---------------------------------------------------------------------------
113
-
114
- const SOFTWARE_DELIVERY_KEY = WORKSPACE_V2_KEYS.SOFTWARE_DELIVERY;
115
-
116
- /**
117
- * Parse a gate command configuration into executable form
118
- *
119
- * @param config - Gate command configuration (string or object)
120
- * @returns Parsed command with defaults applied, or null if undefined
121
- */
122
- export function parseGateCommand(config: GateCommandConfig | undefined): ParsedGateCommand | null {
123
- if (config === undefined) {
124
- return null;
125
- }
126
-
127
- if (isString(config)) {
128
- return {
129
- command: config,
130
- continueOnError: false,
131
- timeout: GATES_RUNTIME_DEFAULTS.COMMAND_TIMEOUT_MS,
132
- };
133
- }
134
-
135
- return {
136
- command: config.command,
137
- continueOnError: config.continueOnError ?? false,
138
- timeout: config.timeout ?? GATES_RUNTIME_DEFAULTS.COMMAND_TIMEOUT_MS,
139
- };
140
- }
141
-
142
- /**
143
- * Load gates configuration from workspace.yaml software_delivery.gates.execution
144
- *
145
- * @param projectRoot - Project root directory
146
- * @returns Gates execution config, or null if not configured
147
- */
148
- export function loadGatesConfig(projectRoot: string): GatesExecutionConfig | null {
149
- const gates = getGatesSection(projectRoot);
150
- if (!gates) {
151
- return null;
152
- }
153
-
154
- try {
155
- // Check if gates.execution section exists
156
- const executionConfig = gates[GATES_FIELDS.EXECUTION];
157
- if (!executionConfig) {
158
- return null;
159
- }
160
-
161
- // Validate the config
162
- const result = GatesExecutionConfigSchema.safeParse(executionConfig);
163
- if (!result.success) {
164
- // eslint-disable-next-line no-console -- operator-facing config validation warning
165
- console.warn('Warning: Invalid gates.execution config:', result.error.message);
166
- return null;
167
- }
168
-
169
- // Expand preset and merge with explicit config (explicit wins)
170
- const presetDefaults = expandPreset(result.data.preset);
171
- const merged: GatesExecutionConfig = {
172
- ...presetDefaults,
173
- ...result.data,
174
- };
175
-
176
- return merged;
177
- } catch (error) {
178
- // eslint-disable-next-line no-console -- operator-facing config parse warning
179
- console.warn(
180
- `Warning: Failed to parse ${WORKSPACE_CONFIG_FILE_NAME} ${SOFTWARE_DELIVERY_KEY}.gates.execution:`,
181
- error instanceof Error ? error.message : String(error),
182
- );
183
- return null;
184
- }
185
- }
186
-
187
- /**
188
- * Get default gates configuration for auto-detection fallback
189
- *
190
- * Used when no gates config is present in workspace.yaml software_delivery.
191
- * These are generic commands that work across common setups.
192
- *
193
- * @returns Default gates configuration
194
- */
195
- export function getDefaultGatesConfig(): GatesExecutionConfig {
196
- return {
197
- format:
198
- 'npm run format:check 2>/dev/null || npx prettier --check . 2>/dev/null || echo "No formatter configured"',
199
- lint: 'npm run lint 2>/dev/null || npx eslint . 2>/dev/null || echo "No linter configured"',
200
- typecheck:
201
- 'npm run typecheck 2>/dev/null || npx tsc --noEmit 2>/dev/null || echo "No type checker configured"',
202
- test: 'npm test 2>/dev/null || echo "No test command configured"',
203
- };
204
- }
205
-
206
- /**
207
- * Resolve the effective gates configuration
208
- *
209
- * Priority order:
210
- * 1. Explicit config from workspace.yaml software_delivery
211
- * 2. Preset defaults (if preset specified)
212
- * 3. Auto-detection defaults
213
- *
214
- * @param projectRoot - Project root directory
215
- * @returns Resolved gates configuration
216
- */
217
- export function resolveGatesConfig(projectRoot: string): GatesExecutionConfig {
218
- const config = loadGatesConfig(projectRoot);
219
-
220
- if (config) {
221
- return config;
222
- }
223
-
224
- // Fall back to defaults for auto-detection
225
- return getDefaultGatesConfig();
226
- }
227
-
228
- /**
229
- * Check if a specific gate should be skipped
230
- *
231
- * @param gateName - Name of the gate (format, lint, typecheck, test)
232
- * @param config - Gates execution configuration
233
- * @param skipFlags - Map of skip flags from CLI/Action inputs
234
- * @returns True if the gate should be skipped
235
- */
236
- export function shouldSkipGate(
237
- gateName: keyof Omit<GatesExecutionConfig, 'preset' | 'coverage'>,
238
- config: GatesExecutionConfig,
239
- skipFlags: Record<string, boolean>,
240
- ): boolean {
241
- // Check if skip flag is set
242
- const skipFlagName = `skip-${gateName}`;
243
- if (skipFlags[skipFlagName] || skipFlags[gateName]) {
244
- return true;
245
- }
246
-
247
- // Check if gate is configured (undefined means skip)
248
- if (config[gateName] === undefined) {
249
- return true;
250
- }
251
-
252
- return false;
253
- }
254
-
255
- /**
256
- * WU-1191: Load lane health configuration from workspace.yaml software_delivery
257
- *
258
- * Configuration format:
259
- * ```yaml
260
- * gates:
261
- * lane_health: warn|error|off
262
- * ```
263
- *
264
- * @param projectRoot - Project root directory
265
- * @returns Lane health mode ('warn', 'error', or 'off'), defaults to 'warn'
266
- */
267
- export function loadLaneHealthConfig(projectRoot: string): LaneHealthMode {
268
- const gates = getGatesSection(projectRoot);
269
- if (!gates) {
270
- return DEFAULT_LANE_HEALTH_MODE;
271
- }
272
-
273
- try {
274
- // Check if gates.lane_health is configured
275
- const laneHealthConfig =
276
- gates[GATES_FIELDS.LANE_HEALTH] ?? gates[GATES_FIELDS.LANE_HEALTH_CAMEL];
277
- if (laneHealthConfig === undefined) {
278
- return DEFAULT_LANE_HEALTH_MODE;
279
- }
280
-
281
- // Validate the config value
282
- const result = LaneHealthModeSchema.safeParse(laneHealthConfig);
283
- if (!result.success) {
284
- // eslint-disable-next-line no-console -- operator-facing config validation warning
285
- console.warn(
286
- `Warning: Invalid gates.lane_health value '${laneHealthConfig}', expected 'warn', 'error', or 'off'. Using default 'warn'.`,
287
- );
288
- return DEFAULT_LANE_HEALTH_MODE;
289
- }
290
-
291
- return result.data;
292
- } catch (error) {
293
- // eslint-disable-next-line no-console -- operator-facing config parse warning
294
- console.warn(
295
- `Warning: Failed to parse ${WORKSPACE_CONFIG_FILE_NAME} ${SOFTWARE_DELIVERY_KEY}.gates.lane_health:`,
296
- error instanceof Error ? error.message : String(error),
297
- );
298
- return DEFAULT_LANE_HEALTH_MODE;
299
- }
300
- }