@lumenflow/core 2.2.2 → 2.3.1

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 (213) hide show
  1. package/dist/active-wu-detector.d.ts +1 -1
  2. package/dist/active-wu-detector.js +1 -1
  3. package/dist/arg-parser.js +51 -18
  4. package/dist/backlog-generator.d.ts +4 -4
  5. package/dist/backlog-generator.js +4 -4
  6. package/dist/backlog-sync-validator.js +1 -1
  7. package/dist/cleanup-lock.d.ts +9 -2
  8. package/dist/cleanup-lock.js +17 -7
  9. package/dist/code-path-validator.d.ts +3 -3
  10. package/dist/code-path-validator.js +3 -3
  11. package/dist/compliance-parser.d.ts +1 -1
  12. package/dist/compliance-parser.js +1 -1
  13. package/dist/constants/backlog-patterns.d.ts +1 -1
  14. package/dist/constants/backlog-patterns.js +1 -1
  15. package/dist/constants/dora-constants.d.ts +1 -1
  16. package/dist/constants/dora-constants.js +1 -1
  17. package/dist/constants/gate-constants.d.ts +1 -1
  18. package/dist/constants/gate-constants.js +1 -1
  19. package/dist/constants/linter-constants.d.ts +1 -1
  20. package/dist/constants/linter-constants.js +1 -1
  21. package/dist/constants/tokenizer-constants.d.ts +1 -1
  22. package/dist/constants/tokenizer-constants.js +1 -1
  23. package/dist/context/location-resolver.js +2 -1
  24. package/dist/context-validation-integration.d.ts +1 -0
  25. package/dist/core/scope-checker.d.ts +3 -3
  26. package/dist/core/scope-checker.js +3 -3
  27. package/dist/core/tool-runner.d.ts +5 -5
  28. package/dist/core/tool-runner.js +5 -5
  29. package/dist/core/tool.constants.d.ts +1 -1
  30. package/dist/core/tool.constants.js +1 -1
  31. package/dist/core/tool.schemas.d.ts +2 -2
  32. package/dist/core/tool.schemas.js +1 -1
  33. package/dist/core/worktree-guard.d.ts +1 -1
  34. package/dist/core/worktree-guard.js +1 -1
  35. package/dist/coverage-gate.d.ts +12 -3
  36. package/dist/coverage-gate.js +15 -8
  37. package/dist/date-utils.d.ts +4 -4
  38. package/dist/date-utils.js +4 -4
  39. package/dist/dependency-graph.d.ts +6 -0
  40. package/dist/dependency-graph.js +43 -2
  41. package/dist/dependency-guard.d.ts +2 -2
  42. package/dist/dependency-guard.js +3 -3
  43. package/dist/dependency-validator.d.ts +4 -4
  44. package/dist/dependency-validator.js +4 -7
  45. package/dist/domain/orchestration.constants.d.ts +31 -10
  46. package/dist/domain/orchestration.constants.js +45 -16
  47. package/dist/domain/orchestration.schemas.d.ts +54 -28
  48. package/dist/domain/orchestration.schemas.js +2 -2
  49. package/dist/domain/orchestration.types.d.ts +2 -2
  50. package/dist/domain/orchestration.types.js +2 -2
  51. package/dist/error-handler.d.ts +10 -10
  52. package/dist/error-handler.js +10 -10
  53. package/dist/file-classifiers.d.ts +6 -6
  54. package/dist/file-classifiers.js +6 -6
  55. package/dist/gates-config.d.ts +74 -0
  56. package/dist/gates-config.js +209 -2
  57. package/dist/git-adapter.d.ts +11 -11
  58. package/dist/git-adapter.js +11 -11
  59. package/dist/git-context-extractor.d.ts +112 -0
  60. package/dist/git-context-extractor.js +559 -0
  61. package/dist/hardcoded-strings.d.ts +1 -1
  62. package/dist/hardcoded-strings.js +1 -1
  63. package/dist/incremental-lint.d.ts +1 -1
  64. package/dist/incremental-lint.js +2 -2
  65. package/dist/incremental-test.d.ts +1 -1
  66. package/dist/incremental-test.js +1 -1
  67. package/dist/index.d.ts +13 -0
  68. package/dist/index.js +25 -0
  69. package/dist/invariants/check-automated-tests.d.ts +2 -2
  70. package/dist/invariants/check-automated-tests.js +3 -3
  71. package/dist/lane-checker.d.ts +28 -7
  72. package/dist/lane-checker.js +316 -159
  73. package/dist/lane-suggest-prompt.d.ts +108 -0
  74. package/dist/lane-suggest-prompt.js +359 -0
  75. package/dist/lane-validator.d.ts +3 -3
  76. package/dist/lane-validator.js +3 -3
  77. package/dist/logs-lib.d.ts +1 -1
  78. package/dist/logs-lib.js +1 -1
  79. package/dist/lumenflow-config-schema.d.ts +162 -0
  80. package/dist/lumenflow-config-schema.js +180 -0
  81. package/dist/manual-test-validator.d.ts +2 -2
  82. package/dist/manual-test-validator.js +3 -3
  83. package/dist/merge-lock.d.ts +8 -1
  84. package/dist/merge-lock.js +16 -7
  85. package/dist/micro-worktree.d.ts +81 -13
  86. package/dist/micro-worktree.js +98 -17
  87. package/dist/migration-deployer.d.ts +1 -1
  88. package/dist/migration-deployer.js +1 -1
  89. package/dist/orchestration-advisory-loader.d.ts +2 -2
  90. package/dist/orchestration-advisory-loader.js +10 -6
  91. package/dist/orchestration-advisory.d.ts +3 -3
  92. package/dist/orchestration-advisory.js +4 -4
  93. package/dist/orchestration-di.d.ts +4 -4
  94. package/dist/orchestration-di.js +4 -4
  95. package/dist/orchestration-rules.d.ts +4 -4
  96. package/dist/orchestration-rules.js +18 -10
  97. package/dist/orphan-detector.d.ts +3 -3
  98. package/dist/orphan-detector.js +3 -3
  99. package/dist/patrol-loop.d.ts +170 -0
  100. package/dist/patrol-loop.js +186 -0
  101. package/dist/process-detector.d.ts +5 -5
  102. package/dist/process-detector.js +5 -5
  103. package/dist/rebase-artifact-cleanup.d.ts +3 -3
  104. package/dist/rebase-artifact-cleanup.js +3 -3
  105. package/dist/resolve-policy.d.ts +195 -0
  106. package/dist/resolve-policy.js +203 -0
  107. package/dist/risk-detector.d.ts +2 -2
  108. package/dist/risk-detector.js +2 -2
  109. package/dist/rollback-utils.d.ts +1 -1
  110. package/dist/rollback-utils.js +1 -1
  111. package/dist/section-headings.d.ts +1 -1
  112. package/dist/section-headings.js +1 -1
  113. package/dist/spawn-escalation.d.ts +4 -4
  114. package/dist/spawn-escalation.js +3 -3
  115. package/dist/spawn-monitor.d.ts +4 -4
  116. package/dist/spawn-monitor.js +4 -4
  117. package/dist/spawn-recovery.d.ts +3 -3
  118. package/dist/spawn-recovery.js +3 -3
  119. package/dist/spawn-registry-schema.d.ts +2 -2
  120. package/dist/spawn-registry-schema.js +2 -2
  121. package/dist/spawn-registry-store.d.ts +2 -2
  122. package/dist/spawn-registry-store.js +2 -2
  123. package/dist/spawn-strategy.d.ts +17 -11
  124. package/dist/spawn-strategy.js +47 -44
  125. package/dist/spawn-tree.d.ts +3 -3
  126. package/dist/spawn-tree.js +3 -3
  127. package/dist/state-cleanup-core.d.ts +205 -0
  128. package/dist/state-cleanup-core.js +240 -0
  129. package/dist/state-doctor-core.d.ts +168 -0
  130. package/dist/state-doctor-core.js +251 -0
  131. package/dist/stream-error-handler.d.ts +67 -0
  132. package/dist/stream-error-handler.js +94 -0
  133. package/dist/telemetry.d.ts +1 -1
  134. package/dist/telemetry.js +1 -1
  135. package/dist/template-loader.d.ts +162 -0
  136. package/dist/template-loader.js +372 -0
  137. package/dist/test-baseline.d.ts +176 -0
  138. package/dist/test-baseline.js +282 -0
  139. package/dist/usecases/get-suggestions.usecase.d.ts +1 -1
  140. package/dist/validation/command-registry.js +37 -0
  141. package/dist/validators/backlog-sync.js +4 -2
  142. package/dist/worktree-scanner.d.ts +1 -1
  143. package/dist/worktree-scanner.js +1 -1
  144. package/dist/worktree-symlink.d.ts +3 -3
  145. package/dist/worktree-symlink.js +3 -3
  146. package/dist/wu-backlog-updater.d.ts +1 -1
  147. package/dist/wu-backlog-updater.js +1 -1
  148. package/dist/wu-claim-helpers.d.ts +1 -1
  149. package/dist/wu-claim-helpers.js +1 -1
  150. package/dist/wu-claim-resume.d.ts +1 -1
  151. package/dist/wu-claim-resume.js +1 -1
  152. package/dist/wu-consistency-checker.d.ts +1 -1
  153. package/dist/wu-consistency-checker.js +17 -11
  154. package/dist/wu-constants.d.ts +73 -21
  155. package/dist/wu-constants.js +65 -22
  156. package/dist/wu-done-branch-only.d.ts +1 -1
  157. package/dist/wu-done-branch-only.js +1 -1
  158. package/dist/wu-done-docs-generate.d.ts +1 -1
  159. package/dist/wu-done-docs-generate.js +1 -1
  160. package/dist/wu-done-messages.d.ts +2 -2
  161. package/dist/wu-done-messages.js +2 -2
  162. package/dist/wu-done-metadata.d.ts +3 -3
  163. package/dist/wu-done-metadata.js +3 -3
  164. package/dist/wu-done-pr.d.ts +1 -1
  165. package/dist/wu-done-pr.js +4 -2
  166. package/dist/wu-done-preflight.d.ts +8 -0
  167. package/dist/wu-done-preflight.js +18 -2
  168. package/dist/wu-done-ui.d.ts +3 -3
  169. package/dist/wu-done-ui.js +3 -3
  170. package/dist/wu-done-validation.d.ts +30 -0
  171. package/dist/wu-done-validation.js +106 -1
  172. package/dist/wu-done-worktree.d.ts +1 -1
  173. package/dist/wu-done-worktree.js +11 -1
  174. package/dist/wu-events-cleanup.d.ts +148 -0
  175. package/dist/wu-events-cleanup.js +401 -0
  176. package/dist/wu-helpers.d.ts +2 -2
  177. package/dist/wu-helpers.js +2 -2
  178. package/dist/wu-id-generator.d.ts +58 -0
  179. package/dist/wu-id-generator.js +103 -0
  180. package/dist/wu-lint.js +1 -1
  181. package/dist/wu-preflight-validators.d.ts +13 -1
  182. package/dist/wu-preflight-validators.js +56 -1
  183. package/dist/wu-recovery.d.ts +2 -2
  184. package/dist/wu-recovery.js +4 -4
  185. package/dist/wu-repair-core.d.ts +5 -5
  186. package/dist/wu-repair-core.js +6 -6
  187. package/dist/wu-schema-normalization.d.ts +1 -1
  188. package/dist/wu-schema-normalization.js +1 -1
  189. package/dist/wu-schema.d.ts +7 -7
  190. package/dist/wu-schema.js +8 -8
  191. package/dist/wu-spawn-context.d.ts +87 -0
  192. package/dist/wu-spawn-context.js +175 -0
  193. package/dist/wu-spawn-helpers.d.ts +1 -1
  194. package/dist/wu-spawn-helpers.js +1 -1
  195. package/dist/wu-spawn.d.ts +177 -4
  196. package/dist/wu-spawn.js +694 -72
  197. package/dist/wu-state-schema.d.ts +1 -1
  198. package/dist/wu-state-schema.js +1 -1
  199. package/dist/wu-state-store.d.ts +3 -3
  200. package/dist/wu-state-store.js +3 -3
  201. package/dist/wu-status-transition.d.ts +1 -1
  202. package/dist/wu-status-transition.js +1 -1
  203. package/dist/wu-status-updater.d.ts +3 -3
  204. package/dist/wu-status-updater.js +3 -3
  205. package/dist/wu-validation-constants.d.ts +2 -2
  206. package/dist/wu-validation-constants.js +2 -2
  207. package/dist/wu-validation.d.ts +3 -3
  208. package/dist/wu-validation.js +3 -3
  209. package/dist/wu-yaml-fixer.d.ts +2 -2
  210. package/dist/wu-yaml-fixer.js +3 -3
  211. package/dist/wu-yaml.d.ts +23 -0
  212. package/dist/wu-yaml.js +76 -2
  213. package/package.json +5 -2
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Micro-Worktree Operations
3
3
  *
4
- * Race-safe micro-worktree isolation pattern extracted from wu-create.mjs (WU-1262).
4
+ * Race-safe micro-worktree isolation pattern extracted from wu-create.ts (WU-1262).
5
5
  * Provides shared infrastructure for commands that need to modify main branch
6
6
  * atomically without switching checkout.
7
7
  *
@@ -23,9 +23,9 @@
23
23
  * - Cleanup guaranteed even on failure
24
24
  *
25
25
  * Consumers:
26
- * @see {@link tools/wu-create.mjs} - WU creation (WU-1262, WU-1439)
27
- * @see {@link tools/wu-edit.mjs} - Spec edits (WU-1274)
28
- * @see {@link tools/initiative-create.mjs} - Initiative creation (WU-1439)
26
+ * @see {@link packages/@lumenflow/cli/src/wu-create.ts} - WU creation (WU-1262, WU-1439)
27
+ * @see {@link packages/@lumenflow/cli/src/wu-edit.ts} - Spec edits (WU-1274)
28
+ * @see {@link packages/@lumenflow/cli/src/initiative-create.ts} - Initiative creation (WU-1439)
29
29
  */
30
30
  import { getGitForCwd, createGitForPath } from './git-adapter.js';
31
31
  import { existsSync, rmSync, mkdtempSync } from 'node:fs';
@@ -40,6 +40,14 @@ import { BRANCHES, REMOTES, GIT_REFS, PKG_MANAGER, SCRIPTS, PRETTIER_FLAGS, STDI
40
40
  * concurrently. Each retry fetches latest main and rebases.
41
41
  */
42
42
  export const MAX_MERGE_RETRIES = 3;
43
+ /**
44
+ * Maximum retry attempts for push when origin/main advances
45
+ *
46
+ * WU-1179: When push fails due to race condition (origin advanced while we
47
+ * were working), rollback local main to origin/main and retry.
48
+ * Each retry: fetch -> rebase temp branch -> re-merge -> push.
49
+ */
50
+ export const MAX_PUSH_RETRIES = 3;
43
51
  /**
44
52
  * Environment variable name for LUMENFLOW_FORCE bypass
45
53
  *
@@ -136,7 +144,8 @@ export async function cleanupOrphanedMicroWorktree(operation, id, gitAdapter, lo
136
144
  cleanedWorktree = true;
137
145
  }
138
146
  catch (err) {
139
- console.warn(`${logPrefix} ⚠️ Could not remove orphaned worktree: ${err.message}`);
147
+ const errMsg = err instanceof Error ? err.message : String(err);
148
+ console.warn(`${logPrefix} ⚠️ Could not remove orphaned worktree: ${errMsg}`);
140
149
  // Try filesystem cleanup as fallback
141
150
  tryFilesystemCleanup(orphanWorktreePath);
142
151
  cleanedWorktree = true;
@@ -144,7 +153,8 @@ export async function cleanupOrphanedMicroWorktree(operation, id, gitAdapter, lo
144
153
  }
145
154
  }
146
155
  catch (err) {
147
- console.warn(`${logPrefix} ⚠️ Could not check worktree list: ${err.message}`);
156
+ const errMsg = err instanceof Error ? err.message : String(err);
157
+ console.warn(`${logPrefix} ⚠️ Could not check worktree list: ${errMsg}`);
148
158
  }
149
159
  // Step 2: Check if the temp branch exists and delete it
150
160
  try {
@@ -157,7 +167,8 @@ export async function cleanupOrphanedMicroWorktree(operation, id, gitAdapter, lo
157
167
  }
158
168
  }
159
169
  catch (err) {
160
- console.warn(`${logPrefix} ⚠️ Could not delete orphaned branch: ${err.message}`);
170
+ const errMsg = err instanceof Error ? err.message : String(err);
171
+ console.warn(`${logPrefix} ⚠️ Could not delete orphaned branch: ${errMsg}`);
161
172
  }
162
173
  return { cleanedWorktree, cleanedBranch };
163
174
  }
@@ -198,7 +209,8 @@ async function removeWorktreeSafe(gitAdapter, worktreePath, logPrefix, contextLa
198
209
  }
199
210
  }
200
211
  catch (err) {
201
- console.warn(`${logPrefix} ⚠️ Could not remove${label} worktree: ${err.message}`);
212
+ const errMsg = err instanceof Error ? err.message : String(err);
213
+ console.warn(`${logPrefix} ⚠️ Could not remove${label} worktree: ${errMsg}`);
202
214
  tryFilesystemCleanup(worktreePath);
203
215
  }
204
216
  }
@@ -249,7 +261,8 @@ async function cleanupRegisteredWorktreeForBranch(gitAdapter, branchName, expect
249
261
  }
250
262
  }
251
263
  catch (err) {
252
- console.warn(`${logPrefix} ⚠️ Could not check worktree list: ${err.message}`);
264
+ const errMsg = err instanceof Error ? err.message : String(err);
265
+ console.warn(`${logPrefix} ⚠️ Could not check worktree list: ${errMsg}`);
253
266
  }
254
267
  }
255
268
  /**
@@ -269,7 +282,8 @@ async function deleteBranchSafe(gitAdapter, branchName, logPrefix) {
269
282
  }
270
283
  }
271
284
  catch (err) {
272
- console.warn(`${logPrefix} ⚠️ Could not delete branch: ${err.message}`);
285
+ const errMsg = err instanceof Error ? err.message : String(err);
286
+ console.warn(`${logPrefix} ⚠️ Could not delete branch: ${errMsg}`);
273
287
  }
274
288
  }
275
289
  /**
@@ -307,6 +321,7 @@ export async function formatFiles(files, worktreePath, logPrefix = DEFAULT_LOG_P
307
321
  const absolutePaths = files.map((f) => join(worktreePath, f));
308
322
  const pathArgs = absolutePaths.map((p) => JSON.stringify(p)).join(' ');
309
323
  try {
324
+ // eslint-disable-next-line sonarjs/os-command -- CLI tool executing known safe prettier command with validated paths
310
325
  execSync(`${PKG_MANAGER} ${SCRIPTS.PRETTIER} ${PRETTIER_FLAGS.WRITE} ${pathArgs}`, {
311
326
  encoding: 'utf-8',
312
327
  stdio: STDIO_MODES.PIPE,
@@ -316,7 +331,8 @@ export async function formatFiles(files, worktreePath, logPrefix = DEFAULT_LOG_P
316
331
  }
317
332
  catch (err) {
318
333
  // Log warning but don't fail - some files may not need formatting
319
- console.warn(`${logPrefix} ⚠️ Formatting warning: ${err.message}`);
334
+ const errMsg = err instanceof Error ? err.message : String(err);
335
+ console.warn(`${logPrefix} ⚠️ Formatting warning: ${errMsg}`);
320
336
  }
321
337
  }
322
338
  /**
@@ -349,9 +365,64 @@ export async function mergeWithRetry(tempBranchName, microWorktreePath, logPrefi
349
365
  await gitWorktree.rebase(BRANCHES.MAIN);
350
366
  }
351
367
  else {
368
+ const errMsg = mergeErr instanceof Error ? mergeErr.message : String(mergeErr);
352
369
  throw new Error(`FF-only merge failed after ${MAX_MERGE_RETRIES} attempts. ` +
353
370
  `Main branch may have significant divergence.\n` +
354
- `Error: ${mergeErr.message}`);
371
+ `Error: ${errMsg}`);
372
+ }
373
+ }
374
+ }
375
+ }
376
+ /**
377
+ * Push to origin/main with retry logic for race conditions
378
+ *
379
+ * WU-1179: When push fails because origin/main advanced (race condition with
380
+ * parallel agents), this function rolls back local main to origin/main and
381
+ * retries the full sequence: fetch -> rebase temp branch -> re-merge -> push.
382
+ *
383
+ * This prevents the scenario where local main is left diverged from origin
384
+ * after a push failure.
385
+ *
386
+ * @param {Object} mainGit - GitAdapter instance for main checkout
387
+ * @param {Object} worktreeGit - GitAdapter instance for micro-worktree
388
+ * @param {string} remote - Remote name (e.g., 'origin')
389
+ * @param {string} branch - Branch name (e.g., 'main')
390
+ * @param {string} tempBranchName - Temp branch that was merged (for rebase)
391
+ * @param {string} logPrefix - Log prefix for console output
392
+ * @throws {Error} If push fails after all retries
393
+ */
394
+ export async function pushWithRetry(mainGit, worktreeGit, remote, branch, tempBranchName, logPrefix = DEFAULT_LOG_PREFIX) {
395
+ for (let attempt = 1; attempt <= MAX_PUSH_RETRIES; attempt++) {
396
+ try {
397
+ console.log(`${logPrefix} Pushing to ${remote}/${branch} (attempt ${attempt}/${MAX_PUSH_RETRIES})...`);
398
+ await mainGit.push(remote, branch);
399
+ console.log(`${logPrefix} ✅ Pushed to ${remote}/${branch}`);
400
+ return;
401
+ }
402
+ catch (pushErr) {
403
+ if (attempt < MAX_PUSH_RETRIES) {
404
+ console.log(`${logPrefix} ⚠️ Push failed (origin moved). Rolling back and retrying...`);
405
+ // Step 1: Rollback local main to origin/main
406
+ console.log(`${logPrefix} Rolling back local ${branch} to ${remote}/${branch}...`);
407
+ await mainGit.reset(`${remote}/${branch}`, { hard: true });
408
+ // Step 2: Fetch latest origin/main
409
+ console.log(`${logPrefix} Fetching ${remote}/${branch}...`);
410
+ await mainGit.fetch(remote, branch);
411
+ // Step 3: Update local main to match origin/main (ff-only)
412
+ console.log(`${logPrefix} Updating local ${branch}...`);
413
+ await mainGit.merge(`${remote}/${branch}`, { ffOnly: true });
414
+ // Step 4: Rebase temp branch onto updated main
415
+ console.log(`${logPrefix} Rebasing temp branch onto ${branch}...`);
416
+ await worktreeGit.rebase(branch);
417
+ // Step 5: Re-merge temp branch to local main
418
+ console.log(`${logPrefix} Re-merging temp branch to ${branch}...`);
419
+ await mainGit.merge(tempBranchName, { ffOnly: true });
420
+ }
421
+ else {
422
+ const errMsg = pushErr instanceof Error ? pushErr.message : String(pushErr);
423
+ throw new Error(`Push failed after ${MAX_PUSH_RETRIES} attempts. ` +
424
+ `Origin ${branch} may have significant traffic.\n` +
425
+ `Error: ${errMsg}`);
355
426
  }
356
427
  }
357
428
  }
@@ -388,13 +459,13 @@ export async function pushRefspecWithForce(gitAdapter, remote, localRef, remoteR
388
459
  finally {
389
460
  // Restore original env values
390
461
  if (originalForce === undefined) {
391
- delete process.env[LUMENFLOW_FORCE_ENV];
462
+ Reflect.deleteProperty(process.env, LUMENFLOW_FORCE_ENV);
392
463
  }
393
464
  else {
394
465
  process.env[LUMENFLOW_FORCE_ENV] = originalForce;
395
466
  }
396
467
  if (originalReason === undefined) {
397
- delete process.env[LUMENFLOW_FORCE_REASON_ENV];
468
+ Reflect.deleteProperty(process.env, LUMENFLOW_FORCE_REASON_ENV);
398
469
  }
399
470
  else {
400
471
  process.env[LUMENFLOW_FORCE_REASON_ENV] = originalReason;
@@ -428,6 +499,15 @@ export async function withMicroWorktree(options) {
428
499
  // WU-2237: Clean up any orphaned temp branch/worktree from previous interrupted operations
429
500
  // This makes the operation idempotent - a retry after crash/timeout will succeed
430
501
  await cleanupOrphanedMicroWorktree(operation, id, mainGit, logPrefix);
502
+ // WU-1179: Fetch origin/main before starting to minimize race condition window
503
+ // This ensures we start from the latest origin state, reducing push failures
504
+ if (!pushOnly) {
505
+ console.log(`${logPrefix} Fetching ${REMOTES.ORIGIN}/${BRANCHES.MAIN} before starting...`);
506
+ await mainGit.fetch(REMOTES.ORIGIN, BRANCHES.MAIN);
507
+ // Update local main to match origin/main
508
+ await mainGit.merge(`${REMOTES.ORIGIN}/${BRANCHES.MAIN}`, { ffOnly: true });
509
+ console.log(`${logPrefix} ✅ Local main synced with ${REMOTES.ORIGIN}/${BRANCHES.MAIN}`);
510
+ }
431
511
  const tempBranchName = getTempBranchName(operation, id);
432
512
  const microWorktreePath = createMicroWorktreeDir(`${operation}-`);
433
513
  console.log(`${logPrefix} Using micro-worktree isolation (WU-1262)`);
@@ -471,10 +551,11 @@ export async function withMicroWorktree(options) {
471
551
  }
472
552
  else {
473
553
  // Standard path: merge to local main, then push
554
+ const gitWorktree = createGitForPath(microWorktreePath);
474
555
  await mergeWithRetry(tempBranchName, microWorktreePath, logPrefix);
475
- console.log(`${logPrefix} Pushing to ${REMOTES.ORIGIN}/${BRANCHES.MAIN}...`);
476
- await mainGit.push(REMOTES.ORIGIN, BRANCHES.MAIN);
477
- console.log(`${logPrefix} Pushed to ${REMOTES.ORIGIN}/${BRANCHES.MAIN}`);
556
+ // WU-1179: Use pushWithRetry to handle race conditions
557
+ // On push failure, rollback local main and retry with rebase
558
+ await pushWithRetry(mainGit, gitWorktree, REMOTES.ORIGIN, BRANCHES.MAIN, tempBranchName, logPrefix);
478
559
  return { ...result, ref: BRANCHES.MAIN };
479
560
  }
480
561
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @file migration-deployer.mjs
2
+ * @file migration-deployer.ts
3
3
  * @description Migration deployment utilities for Supabase schema sync
4
4
  * WU-1983: Sync production schema and establish migration deployment workflow
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @file migration-deployer.mjs
2
+ * @file migration-deployer.ts
3
3
  * @description Migration deployment utilities for Supabase schema sync
4
4
  * WU-1983: Sync production schema and establish migration deployment workflow
5
5
  *
@@ -5,8 +5,8 @@
5
5
  * Uses minimatch for glob pattern matching (same as TypeScript version).
6
6
  *
7
7
  * @module orchestration-advisory-loader
8
- * @see {@link ./orchestration-advisory.mjs} - TypeScript version for tests
9
- * @see {@link ./domain/orchestration.constants.mjs} - Pattern definitions
8
+ * @see {@link ./orchestration-advisory.ts} - TypeScript version for tests
9
+ * @see {@link ./domain/orchestration.constants.ts} - Pattern definitions
10
10
  */
11
11
  /**
12
12
  * Emit mandatory agent advisory based on code paths.
@@ -5,18 +5,22 @@
5
5
  * Uses minimatch for glob pattern matching (same as TypeScript version).
6
6
  *
7
7
  * @module orchestration-advisory-loader
8
- * @see {@link ./orchestration-advisory.mjs} - TypeScript version for tests
9
- * @see {@link ./domain/orchestration.constants.mjs} - Pattern definitions
8
+ * @see {@link ./orchestration-advisory.ts} - TypeScript version for tests
9
+ * @see {@link ./domain/orchestration.constants.ts} - Pattern definitions
10
10
  */
11
11
  import { minimatch } from 'minimatch';
12
12
  import picocolors from 'picocolors';
13
13
  /**
14
14
  * Mandatory agent trigger patterns.
15
- * Mirrors MANDATORY_TRIGGERS from orchestration.constants.mjs.
15
+ * Mirrors MANDATORY_TRIGGERS from orchestration.constants.ts.
16
+ *
17
+ * Note: For LumenFlow framework development, this is empty since we don't have
18
+ * application-specific concerns like PHI, auth, or RLS. Projects using LumenFlow
19
+ * should configure their own triggers based on their domain requirements.
16
20
  */
17
21
  const MANDATORY_TRIGGERS = {
18
- 'security-auditor': ['supabase/migrations/**', '**/auth/**', '**/rls/**', '**/permissions/**'],
19
- 'beacon-guardian': ['**/prompts/**', '**/classification/**', '**/detector/**', '**/llm/**'],
22
+ // No mandatory triggers for LumenFlow framework development.
23
+ // Projects should configure their own triggers based on their domain.
20
24
  };
21
25
  /**
22
26
  * Detect mandatory agents based on code paths.
@@ -64,7 +68,7 @@ export function emitMandatoryAgentAdvisory(codePaths, wuId) {
64
68
  console.log(picocolors.cyan(` • ${agent}`));
65
69
  }
66
70
  console.log('');
67
- console.log(picocolors.gray(`Run: pnpm orchestrate:suggest --wu ${wuId}`));
71
+ console.log(picocolors.gray(`Run: pnpm orchestrate:monitor to check agent status`));
68
72
  console.log(picocolors.yellow(horizontalLine));
69
73
  console.log('');
70
74
  }
@@ -2,11 +2,11 @@
2
2
  * Orchestration Advisory Emitter
3
3
  *
4
4
  * Utility functions for emitting mandatory agent advisories and checking compliance.
5
- * Used by wu-claim.mjs (emit advisory) and wu-done.mjs (check compliance).
5
+ * Used by wu-claim.ts (emit advisory) and wu-done.ts (check compliance).
6
6
  *
7
7
  * @module orchestration-advisory
8
- * @see {@link ./orchestration-rules.mjs} - detectMandatoryAgents function
9
- * @see {@link ./domain/orchestration.constants.mjs} - MANDATORY_TRIGGERS patterns
8
+ * @see {@link ./orchestration-rules.ts} - detectMandatoryAgents function
9
+ * @see {@link ./domain/orchestration.constants.ts} - MANDATORY_TRIGGERS patterns
10
10
  */
11
11
  import type { MandatoryAgentName } from './domain/orchestration.types.js';
12
12
  /**
@@ -2,11 +2,11 @@
2
2
  * Orchestration Advisory Emitter
3
3
  *
4
4
  * Utility functions for emitting mandatory agent advisories and checking compliance.
5
- * Used by wu-claim.mjs (emit advisory) and wu-done.mjs (check compliance).
5
+ * Used by wu-claim.ts (emit advisory) and wu-done.ts (check compliance).
6
6
  *
7
7
  * @module orchestration-advisory
8
- * @see {@link ./orchestration-rules.mjs} - detectMandatoryAgents function
9
- * @see {@link ./domain/orchestration.constants.mjs} - MANDATORY_TRIGGERS patterns
8
+ * @see {@link ./orchestration-rules.ts} - detectMandatoryAgents function
9
+ * @see {@link ./domain/orchestration.constants.ts} - MANDATORY_TRIGGERS patterns
10
10
  */
11
11
  import picocolors from 'picocolors';
12
12
  import { detectMandatoryAgents } from './orchestration-rules.js';
@@ -59,7 +59,7 @@ export function emitMandatoryAgentAdvisory(codePaths, wuId) {
59
59
  console.log(picocolors.cyan(` ${BOX_CHARS.BULLET} ${agent}`));
60
60
  }
61
61
  console.log('');
62
- console.log(picocolors.gray(`Run: pnpm orchestrate:suggest --wu ${wuId}`));
62
+ console.log(picocolors.gray(`Run: pnpm orchestrate:monitor to check agent status`));
63
63
  console.log(picocolors.yellow(horizontalLine));
64
64
  console.log('');
65
65
  }
@@ -6,10 +6,10 @@
6
6
  * implementations are coupled.
7
7
  *
8
8
  * @module orchestration-di
9
- * @see {@link ./ports/metrics-collector.port.mjs} - Input port
10
- * @see {@link ./ports/dashboard-renderer.port.mjs} - Output port
11
- * @see {@link ./adapters/filesystem-metrics.adapter.mjs} - Input adapter
12
- * @see {@link ./adapters/terminal-renderer.adapter.mjs} - Output adapter
9
+ * @see {@link ./ports/metrics-collector.port.ts} - Input port
10
+ * @see {@link ./ports/dashboard-renderer.port.ts} - Output port
11
+ * @see {@link ./adapters/filesystem-metrics.adapter.ts} - Input adapter
12
+ * @see {@link ./adapters/terminal-renderer.adapter.ts} - Output adapter
13
13
  */
14
14
  import { GetDashboardDataUseCase } from './usecases/get-dashboard-data.usecase.js';
15
15
  import { GetSuggestionsUseCase } from './usecases/get-suggestions.usecase.js';
@@ -6,10 +6,10 @@
6
6
  * implementations are coupled.
7
7
  *
8
8
  * @module orchestration-di
9
- * @see {@link ./ports/metrics-collector.port.mjs} - Input port
10
- * @see {@link ./ports/dashboard-renderer.port.mjs} - Output port
11
- * @see {@link ./adapters/filesystem-metrics.adapter.mjs} - Input adapter
12
- * @see {@link ./adapters/terminal-renderer.adapter.mjs} - Output adapter
9
+ * @see {@link ./ports/metrics-collector.port.ts} - Input port
10
+ * @see {@link ./ports/dashboard-renderer.port.ts} - Output port
11
+ * @see {@link ./adapters/filesystem-metrics.adapter.ts} - Input adapter
12
+ * @see {@link ./adapters/terminal-renderer.adapter.ts} - Output adapter
13
13
  */
14
14
  import { FileSystemMetricsCollector } from './adapters/filesystem-metrics.adapter.js';
15
15
  import { TerminalDashboardRenderer } from './adapters/terminal-renderer.adapter.js';
@@ -5,8 +5,8 @@
5
5
  * Uses minimatch for glob pattern matching (NOT regex).
6
6
  *
7
7
  * @module orchestration-rules
8
- * @see {@link ./domain/orchestration.constants.mjs} - MANDATORY_TRIGGERS patterns
9
- * @see {@link ../../../docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-selection-guide.md} - Agent selection rules
8
+ * @see {@link ./domain/orchestration.constants.ts} - MANDATORY_TRIGGERS patterns
9
+ * @see {@link https://lumenflow.dev/reference/agent-selection-guide/} - Agent selection rules
10
10
  */
11
11
  import { type MandatoryAgentName } from './domain/orchestration.constants.js';
12
12
  /**
@@ -47,11 +47,11 @@ export declare function buildMandatoryAgentsErrorMessage(wuId: any, missingAgent
47
47
  export declare function checkMandatoryAgentsComplianceBlocking(codePaths: any, wuId: any, options: any): {
48
48
  compliant: boolean;
49
49
  blocking: boolean;
50
- missing: ("security-auditor" | "beacon-guardian")[];
50
+ missing: any[];
51
51
  errorMessage?: undefined;
52
52
  } | {
53
53
  compliant: boolean;
54
54
  blocking: boolean;
55
- missing: ("security-auditor" | "beacon-guardian")[];
55
+ missing: never[];
56
56
  errorMessage: string;
57
57
  };
@@ -5,8 +5,8 @@
5
5
  * Uses minimatch for glob pattern matching (NOT regex).
6
6
  *
7
7
  * @module orchestration-rules
8
- * @see {@link ./domain/orchestration.constants.mjs} - MANDATORY_TRIGGERS patterns
9
- * @see {@link ../../../docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-selection-guide.md} - Agent selection rules
8
+ * @see {@link ./domain/orchestration.constants.ts} - MANDATORY_TRIGGERS patterns
9
+ * @see {@link https://lumenflow.dev/reference/agent-selection-guide/} - Agent selection rules
10
10
  */
11
11
  import { minimatch } from 'minimatch';
12
12
  import { MANDATORY_TRIGGERS } from './domain/orchestration.constants.js';
@@ -74,8 +74,10 @@ export function generateSuggestions(wuProgress, _agentHistory) {
74
74
  function generateWUSuggestions(wu, nextId) {
75
75
  const suggestions = [];
76
76
  // Check for pending mandatory agents (HIGH priority)
77
- const mandatoryAgents = ['security-auditor', 'beacon-guardian'];
78
- for (const agentName of mandatoryAgents) {
77
+ // Note: For LumenFlow framework development, MANDATORY_TRIGGERS is empty.
78
+ // Projects using LumenFlow can configure their own mandatory agents.
79
+ const mandatoryAgentNames = Object.keys(MANDATORY_TRIGGERS);
80
+ for (const agentName of mandatoryAgentNames) {
79
81
  if (wu.agents[agentName] === 'pending') {
80
82
  suggestions.push({
81
83
  id: `sug-${nextId().toString().padStart(3, '0')}`,
@@ -116,10 +118,16 @@ function generateWUSuggestions(wu, nextId) {
116
118
  /**
117
119
  * WU-1542: Agent trigger descriptions for error messages.
118
120
  * Maps agent names to human-readable descriptions of their trigger patterns.
121
+ *
122
+ * Note: For LumenFlow framework development, this is empty since we don't have
123
+ * application-specific mandatory agents. Projects using LumenFlow should
124
+ * configure their own trigger descriptions based on their domain requirements.
119
125
  */
120
126
  const AGENT_TRIGGER_DESCRIPTIONS = {
121
- 'security-auditor': 'supabase/migrations/**, **/auth/**, **/rls/**, **/permissions/**',
122
- 'beacon-guardian': '**/prompts/**, **/classification/**, **/detector/**, **/llm/**',
127
+ // No mandatory agent triggers for LumenFlow framework development.
128
+ // Example for application-specific triggers:
129
+ // 'security-auditor': 'supabase/migrations/**, auth/**, rls/**',
130
+ // 'beacon-guardian': 'prompts/**, llm/**',
123
131
  };
124
132
  /**
125
133
  * WU-1542: Build a formatted error message for mandatory agent enforcement failures.
@@ -156,13 +164,13 @@ export function buildMandatoryAgentsErrorMessage(wuId, missingAgents, codePaths)
156
164
  lines.push('');
157
165
  lines.push('Required action:');
158
166
  lines.push(' 1. Invoke the required agents BEFORE calling wu:done');
159
- lines.push(' 2. For security-auditor: Review PHI/auth/RLS implications');
160
- lines.push(' 3. For beacon-guardian: Validate LLM/prompt compliance');
167
+ lines.push(" 2. Check your project's mandatory agent configuration");
168
+ lines.push(' 3. Consult agent documentation for compliance requirements');
161
169
  lines.push('');
162
- lines.push('To bypass (NOT RECOMMENDED for PHI/auth work):');
170
+ lines.push('To bypass (only if appropriate for your project):');
163
171
  lines.push(' Remove --require-agents flag from wu:done command');
164
172
  lines.push('');
165
- lines.push('See: docs/04-operations/_frameworks/lumenflow/agent/onboarding/agent-selection-guide.md for agent invocation guidance');
173
+ lines.push('See: https://lumenflow.dev/reference/agent-selection-guide/ for agent invocation guidance');
166
174
  lines.push('='.repeat(70));
167
175
  return lines.join('\n');
168
176
  }
@@ -14,9 +14,9 @@
14
14
  * - Layer 3: Pre-flight check in wu:claim
15
15
  * - Layer 4: Manual utility wu:cleanup-orphans
16
16
  *
17
- * @see {@link tools/wu-prune.mjs} - Primary consumer
18
- * @see {@link tools/wu-claim.mjs} - Pre-flight orphan check
19
- * @see {@link tools/lib/git-adapter.mjs} - worktreeRemove with cleanup
17
+ * @see {@link packages/@lumenflow/cli/src/wu-prune.ts} - Primary consumer
18
+ * @see {@link packages/@lumenflow/cli/src/wu-claim.ts} - Pre-flight orphan check
19
+ * @see {@link packages/@lumenflow/cli/src/lib/git-adapter.ts} - worktreeRemove with cleanup
20
20
  */
21
21
  import { existsSync } from 'node:fs';
22
22
  /**
@@ -14,9 +14,9 @@
14
14
  * - Layer 3: Pre-flight check in wu:claim
15
15
  * - Layer 4: Manual utility wu:cleanup-orphans
16
16
  *
17
- * @see {@link tools/wu-prune.mjs} - Primary consumer
18
- * @see {@link tools/wu-claim.mjs} - Pre-flight orphan check
19
- * @see {@link tools/lib/git-adapter.mjs} - worktreeRemove with cleanup
17
+ * @see {@link packages/@lumenflow/cli/src/wu-prune.ts} - Primary consumer
18
+ * @see {@link packages/@lumenflow/cli/src/wu-claim.ts} - Pre-flight orphan check
19
+ * @see {@link packages/@lumenflow/cli/src/lib/git-adapter.ts} - worktreeRemove with cleanup
20
20
  */
21
21
  import { readdirSync, statSync, existsSync, rmSync } from 'node:fs';
22
22
  import path from 'node:path';
@@ -0,0 +1,170 @@
1
+ /**
2
+ * Patrol Loop Module (WU-1242)
3
+ *
4
+ * Continuous patrol loop for monitoring spawn health.
5
+ * The 'Witness patrol' pattern - keeps the spawn fleet healthy by
6
+ * checking status at configurable intervals with exponential backoff
7
+ * on repeated failures.
8
+ *
9
+ * Features:
10
+ * - Configurable patrol interval (default 5min)
11
+ * - Exponential backoff on failures (max 1hr)
12
+ * - Graceful shutdown support
13
+ * - Cycle callbacks for status reporting
14
+ * - Error handling with continuation
15
+ *
16
+ * @see {@link packages/@lumenflow/cli/src/orchestrate-monitor.ts} - CLI integration
17
+ * @see {@link packages/@lumenflow/core/src/__tests__/patrol-loop.test.ts} - Tests
18
+ */
19
+ /**
20
+ * Default patrol interval (5 minutes in milliseconds)
21
+ */
22
+ export declare const DEFAULT_PATROL_INTERVAL_MS: number;
23
+ /**
24
+ * Maximum backoff interval (1 hour in milliseconds)
25
+ */
26
+ export declare const MAX_BACKOFF_MS: number;
27
+ /**
28
+ * Result of a patrol check
29
+ */
30
+ export interface PatrolCheckResult {
31
+ /** Whether the spawn fleet is healthy (no stuck spawns or zombies) */
32
+ healthy: boolean;
33
+ /** Number of stuck spawns detected */
34
+ stuckCount: number;
35
+ /** Number of zombie locks detected */
36
+ zombieCount: number;
37
+ /** Optional suggestions for recovery */
38
+ suggestions?: string[];
39
+ }
40
+ /**
41
+ * Metadata passed to cycle callbacks
42
+ */
43
+ export interface CycleMetadata {
44
+ /** The cycle number (1-indexed) */
45
+ cycleNumber: number;
46
+ /** Current interval in milliseconds */
47
+ intervalMs: number;
48
+ /** Number of consecutive failures */
49
+ consecutiveFailures: number;
50
+ /** Timestamp of the cycle */
51
+ timestamp: Date;
52
+ }
53
+ /**
54
+ * Callback invoked on each patrol cycle
55
+ */
56
+ export type OnCycleCallback = (result: PatrolCheckResult, meta: CycleMetadata) => void;
57
+ /**
58
+ * Callback invoked when an error occurs
59
+ */
60
+ export type OnErrorCallback = (error: Error, cycleNumber: number) => void;
61
+ /**
62
+ * Options for creating a PatrolLoop
63
+ */
64
+ export interface PatrolLoopOptions {
65
+ /**
66
+ * Function to check spawn health
67
+ */
68
+ checkFn: () => Promise<PatrolCheckResult>;
69
+ /**
70
+ * Patrol interval in milliseconds (default: 5 minutes)
71
+ */
72
+ intervalMs?: number;
73
+ /**
74
+ * Callback invoked after each patrol cycle
75
+ */
76
+ onCycle?: OnCycleCallback;
77
+ /**
78
+ * Callback invoked when checkFn throws an error
79
+ */
80
+ onError?: OnErrorCallback;
81
+ }
82
+ /**
83
+ * Calculates the backoff interval based on consecutive failures.
84
+ * Uses exponential backoff with a maximum of 1 hour.
85
+ *
86
+ * Backoff formula: baseInterval * 2^(failures-1), capped at MAX_BACKOFF_MS
87
+ *
88
+ * @param consecutiveFailures - Number of consecutive failures (1-indexed)
89
+ * @param baseIntervalMs - Base interval in milliseconds
90
+ * @returns Backoff interval in milliseconds
91
+ *
92
+ * @example
93
+ * calculateBackoff(1, 5*60*1000) // 5 minutes (no backoff yet)
94
+ * calculateBackoff(2, 5*60*1000) // 10 minutes (2x)
95
+ * calculateBackoff(3, 5*60*1000) // 20 minutes (4x)
96
+ */
97
+ export declare function calculateBackoff(consecutiveFailures: number, baseIntervalMs: number): number;
98
+ /**
99
+ * Patrol loop for continuous spawn monitoring.
100
+ *
101
+ * @example
102
+ * const patrol = new PatrolLoop({
103
+ * checkFn: async () => {
104
+ * const result = await runMonitor();
105
+ * return {
106
+ * healthy: result.stuckSpawns.length === 0,
107
+ * stuckCount: result.stuckSpawns.length,
108
+ * zombieCount: result.zombieLocks.length,
109
+ * };
110
+ * },
111
+ * intervalMs: 5 * 60 * 1000, // 5 minutes
112
+ * onCycle: (result, meta) => {
113
+ * console.log(`Cycle ${meta.cycleNumber}: ${result.healthy ? 'healthy' : 'issues detected'}`);
114
+ * },
115
+ * });
116
+ *
117
+ * patrol.start();
118
+ * // Later...
119
+ * patrol.stop();
120
+ */
121
+ export declare class PatrolLoop {
122
+ private readonly checkFn;
123
+ private readonly baseIntervalMs;
124
+ private readonly onCycle?;
125
+ private readonly onError?;
126
+ private timer;
127
+ private running;
128
+ private failures;
129
+ private cycles;
130
+ /**
131
+ * Creates a new PatrolLoop instance.
132
+ *
133
+ * @param options - Patrol loop configuration
134
+ */
135
+ constructor(options: PatrolLoopOptions);
136
+ /**
137
+ * The configured base interval in milliseconds.
138
+ */
139
+ get intervalMs(): number;
140
+ /**
141
+ * Whether the patrol loop is currently running.
142
+ */
143
+ get isRunning(): boolean;
144
+ /**
145
+ * Number of consecutive failures (resets on success).
146
+ */
147
+ get consecutiveFailures(): number;
148
+ /**
149
+ * Total number of completed patrol cycles.
150
+ */
151
+ get totalCycles(): number;
152
+ /**
153
+ * Starts the patrol loop.
154
+ * Does nothing if already running.
155
+ */
156
+ start(): void;
157
+ /**
158
+ * Stops the patrol loop.
159
+ * Safe to call even if not running.
160
+ */
161
+ stop(): void;
162
+ /**
163
+ * Schedules the next patrol cycle.
164
+ */
165
+ private scheduleNextCycle;
166
+ /**
167
+ * Runs a single patrol cycle.
168
+ */
169
+ private runCycle;
170
+ }