@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.
- package/dist/active-wu-detector.d.ts +1 -1
- package/dist/active-wu-detector.js +1 -1
- package/dist/arg-parser.js +51 -18
- package/dist/backlog-generator.d.ts +4 -4
- package/dist/backlog-generator.js +4 -4
- package/dist/backlog-sync-validator.js +1 -1
- package/dist/cleanup-lock.d.ts +9 -2
- package/dist/cleanup-lock.js +17 -7
- package/dist/code-path-validator.d.ts +3 -3
- package/dist/code-path-validator.js +3 -3
- package/dist/compliance-parser.d.ts +1 -1
- package/dist/compliance-parser.js +1 -1
- package/dist/constants/backlog-patterns.d.ts +1 -1
- package/dist/constants/backlog-patterns.js +1 -1
- package/dist/constants/dora-constants.d.ts +1 -1
- package/dist/constants/dora-constants.js +1 -1
- package/dist/constants/gate-constants.d.ts +1 -1
- package/dist/constants/gate-constants.js +1 -1
- package/dist/constants/linter-constants.d.ts +1 -1
- package/dist/constants/linter-constants.js +1 -1
- package/dist/constants/tokenizer-constants.d.ts +1 -1
- package/dist/constants/tokenizer-constants.js +1 -1
- package/dist/context/location-resolver.js +2 -1
- package/dist/context-validation-integration.d.ts +1 -0
- package/dist/core/scope-checker.d.ts +3 -3
- package/dist/core/scope-checker.js +3 -3
- package/dist/core/tool-runner.d.ts +5 -5
- package/dist/core/tool-runner.js +5 -5
- package/dist/core/tool.constants.d.ts +1 -1
- package/dist/core/tool.constants.js +1 -1
- package/dist/core/tool.schemas.d.ts +2 -2
- package/dist/core/tool.schemas.js +1 -1
- package/dist/core/worktree-guard.d.ts +1 -1
- package/dist/core/worktree-guard.js +1 -1
- package/dist/coverage-gate.d.ts +12 -3
- package/dist/coverage-gate.js +15 -8
- package/dist/date-utils.d.ts +4 -4
- package/dist/date-utils.js +4 -4
- package/dist/dependency-graph.d.ts +6 -0
- package/dist/dependency-graph.js +43 -2
- package/dist/dependency-guard.d.ts +2 -2
- package/dist/dependency-guard.js +3 -3
- package/dist/dependency-validator.d.ts +4 -4
- package/dist/dependency-validator.js +4 -7
- package/dist/domain/orchestration.constants.d.ts +31 -10
- package/dist/domain/orchestration.constants.js +45 -16
- package/dist/domain/orchestration.schemas.d.ts +54 -28
- package/dist/domain/orchestration.schemas.js +2 -2
- package/dist/domain/orchestration.types.d.ts +2 -2
- package/dist/domain/orchestration.types.js +2 -2
- package/dist/error-handler.d.ts +10 -10
- package/dist/error-handler.js +10 -10
- package/dist/file-classifiers.d.ts +6 -6
- package/dist/file-classifiers.js +6 -6
- package/dist/gates-config.d.ts +74 -0
- package/dist/gates-config.js +209 -2
- package/dist/git-adapter.d.ts +11 -11
- package/dist/git-adapter.js +11 -11
- package/dist/git-context-extractor.d.ts +112 -0
- package/dist/git-context-extractor.js +559 -0
- package/dist/hardcoded-strings.d.ts +1 -1
- package/dist/hardcoded-strings.js +1 -1
- package/dist/incremental-lint.d.ts +1 -1
- package/dist/incremental-lint.js +2 -2
- package/dist/incremental-test.d.ts +1 -1
- package/dist/incremental-test.js +1 -1
- package/dist/index.d.ts +13 -0
- package/dist/index.js +25 -0
- package/dist/invariants/check-automated-tests.d.ts +2 -2
- package/dist/invariants/check-automated-tests.js +3 -3
- package/dist/lane-checker.d.ts +28 -7
- package/dist/lane-checker.js +316 -159
- package/dist/lane-suggest-prompt.d.ts +108 -0
- package/dist/lane-suggest-prompt.js +359 -0
- package/dist/lane-validator.d.ts +3 -3
- package/dist/lane-validator.js +3 -3
- package/dist/logs-lib.d.ts +1 -1
- package/dist/logs-lib.js +1 -1
- package/dist/lumenflow-config-schema.d.ts +162 -0
- package/dist/lumenflow-config-schema.js +180 -0
- package/dist/manual-test-validator.d.ts +2 -2
- package/dist/manual-test-validator.js +3 -3
- package/dist/merge-lock.d.ts +8 -1
- package/dist/merge-lock.js +16 -7
- package/dist/micro-worktree.d.ts +81 -13
- package/dist/micro-worktree.js +98 -17
- package/dist/migration-deployer.d.ts +1 -1
- package/dist/migration-deployer.js +1 -1
- package/dist/orchestration-advisory-loader.d.ts +2 -2
- package/dist/orchestration-advisory-loader.js +10 -6
- package/dist/orchestration-advisory.d.ts +3 -3
- package/dist/orchestration-advisory.js +4 -4
- package/dist/orchestration-di.d.ts +4 -4
- package/dist/orchestration-di.js +4 -4
- package/dist/orchestration-rules.d.ts +4 -4
- package/dist/orchestration-rules.js +18 -10
- package/dist/orphan-detector.d.ts +3 -3
- package/dist/orphan-detector.js +3 -3
- package/dist/patrol-loop.d.ts +170 -0
- package/dist/patrol-loop.js +186 -0
- package/dist/process-detector.d.ts +5 -5
- package/dist/process-detector.js +5 -5
- package/dist/rebase-artifact-cleanup.d.ts +3 -3
- package/dist/rebase-artifact-cleanup.js +3 -3
- package/dist/resolve-policy.d.ts +195 -0
- package/dist/resolve-policy.js +203 -0
- package/dist/risk-detector.d.ts +2 -2
- package/dist/risk-detector.js +2 -2
- package/dist/rollback-utils.d.ts +1 -1
- package/dist/rollback-utils.js +1 -1
- package/dist/section-headings.d.ts +1 -1
- package/dist/section-headings.js +1 -1
- package/dist/spawn-escalation.d.ts +4 -4
- package/dist/spawn-escalation.js +3 -3
- package/dist/spawn-monitor.d.ts +4 -4
- package/dist/spawn-monitor.js +4 -4
- package/dist/spawn-recovery.d.ts +3 -3
- package/dist/spawn-recovery.js +3 -3
- package/dist/spawn-registry-schema.d.ts +2 -2
- package/dist/spawn-registry-schema.js +2 -2
- package/dist/spawn-registry-store.d.ts +2 -2
- package/dist/spawn-registry-store.js +2 -2
- package/dist/spawn-strategy.d.ts +17 -11
- package/dist/spawn-strategy.js +47 -44
- package/dist/spawn-tree.d.ts +3 -3
- package/dist/spawn-tree.js +3 -3
- package/dist/state-cleanup-core.d.ts +205 -0
- package/dist/state-cleanup-core.js +240 -0
- package/dist/state-doctor-core.d.ts +168 -0
- package/dist/state-doctor-core.js +251 -0
- package/dist/stream-error-handler.d.ts +67 -0
- package/dist/stream-error-handler.js +94 -0
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.js +1 -1
- package/dist/template-loader.d.ts +162 -0
- package/dist/template-loader.js +372 -0
- package/dist/test-baseline.d.ts +176 -0
- package/dist/test-baseline.js +282 -0
- package/dist/usecases/get-suggestions.usecase.d.ts +1 -1
- package/dist/validation/command-registry.js +37 -0
- package/dist/validators/backlog-sync.js +4 -2
- package/dist/worktree-scanner.d.ts +1 -1
- package/dist/worktree-scanner.js +1 -1
- package/dist/worktree-symlink.d.ts +3 -3
- package/dist/worktree-symlink.js +3 -3
- package/dist/wu-backlog-updater.d.ts +1 -1
- package/dist/wu-backlog-updater.js +1 -1
- package/dist/wu-claim-helpers.d.ts +1 -1
- package/dist/wu-claim-helpers.js +1 -1
- package/dist/wu-claim-resume.d.ts +1 -1
- package/dist/wu-claim-resume.js +1 -1
- package/dist/wu-consistency-checker.d.ts +1 -1
- package/dist/wu-consistency-checker.js +17 -11
- package/dist/wu-constants.d.ts +73 -21
- package/dist/wu-constants.js +65 -22
- package/dist/wu-done-branch-only.d.ts +1 -1
- package/dist/wu-done-branch-only.js +1 -1
- package/dist/wu-done-docs-generate.d.ts +1 -1
- package/dist/wu-done-docs-generate.js +1 -1
- package/dist/wu-done-messages.d.ts +2 -2
- package/dist/wu-done-messages.js +2 -2
- package/dist/wu-done-metadata.d.ts +3 -3
- package/dist/wu-done-metadata.js +3 -3
- package/dist/wu-done-pr.d.ts +1 -1
- package/dist/wu-done-pr.js +4 -2
- package/dist/wu-done-preflight.d.ts +8 -0
- package/dist/wu-done-preflight.js +18 -2
- package/dist/wu-done-ui.d.ts +3 -3
- package/dist/wu-done-ui.js +3 -3
- package/dist/wu-done-validation.d.ts +30 -0
- package/dist/wu-done-validation.js +106 -1
- package/dist/wu-done-worktree.d.ts +1 -1
- package/dist/wu-done-worktree.js +11 -1
- package/dist/wu-events-cleanup.d.ts +148 -0
- package/dist/wu-events-cleanup.js +401 -0
- package/dist/wu-helpers.d.ts +2 -2
- package/dist/wu-helpers.js +2 -2
- package/dist/wu-id-generator.d.ts +58 -0
- package/dist/wu-id-generator.js +103 -0
- package/dist/wu-lint.js +1 -1
- package/dist/wu-preflight-validators.d.ts +13 -1
- package/dist/wu-preflight-validators.js +56 -1
- package/dist/wu-recovery.d.ts +2 -2
- package/dist/wu-recovery.js +4 -4
- package/dist/wu-repair-core.d.ts +5 -5
- package/dist/wu-repair-core.js +6 -6
- package/dist/wu-schema-normalization.d.ts +1 -1
- package/dist/wu-schema-normalization.js +1 -1
- package/dist/wu-schema.d.ts +7 -7
- package/dist/wu-schema.js +8 -8
- package/dist/wu-spawn-context.d.ts +87 -0
- package/dist/wu-spawn-context.js +175 -0
- package/dist/wu-spawn-helpers.d.ts +1 -1
- package/dist/wu-spawn-helpers.js +1 -1
- package/dist/wu-spawn.d.ts +177 -4
- package/dist/wu-spawn.js +694 -72
- package/dist/wu-state-schema.d.ts +1 -1
- package/dist/wu-state-schema.js +1 -1
- package/dist/wu-state-store.d.ts +3 -3
- package/dist/wu-state-store.js +3 -3
- package/dist/wu-status-transition.d.ts +1 -1
- package/dist/wu-status-transition.js +1 -1
- package/dist/wu-status-updater.d.ts +3 -3
- package/dist/wu-status-updater.js +3 -3
- package/dist/wu-validation-constants.d.ts +2 -2
- package/dist/wu-validation-constants.js +2 -2
- package/dist/wu-validation.d.ts +3 -3
- package/dist/wu-validation.js +3 -3
- package/dist/wu-yaml-fixer.d.ts +2 -2
- package/dist/wu-yaml-fixer.js +3 -3
- package/dist/wu-yaml.d.ts +23 -0
- package/dist/wu-yaml.js +76 -2
- package/package.json +5 -2
package/dist/micro-worktree.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Micro-Worktree Operations
|
|
3
3
|
*
|
|
4
|
-
* Race-safe micro-worktree isolation pattern extracted from wu-create.
|
|
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
|
|
27
|
-
* @see {@link
|
|
28
|
-
* @see {@link
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: ${
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
476
|
-
|
|
477
|
-
|
|
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
|
}
|
|
@@ -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.
|
|
9
|
-
* @see {@link ./domain/orchestration.constants.
|
|
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.
|
|
9
|
-
* @see {@link ./domain/orchestration.constants.
|
|
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.
|
|
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
|
-
|
|
19
|
-
|
|
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:
|
|
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.
|
|
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.
|
|
9
|
-
* @see {@link ./domain/orchestration.constants.
|
|
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.
|
|
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.
|
|
9
|
-
* @see {@link ./domain/orchestration.constants.
|
|
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:
|
|
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.
|
|
10
|
-
* @see {@link ./ports/dashboard-renderer.port.
|
|
11
|
-
* @see {@link ./adapters/filesystem-metrics.adapter.
|
|
12
|
-
* @see {@link ./adapters/terminal-renderer.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';
|
package/dist/orchestration-di.js
CHANGED
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
* implementations are coupled.
|
|
7
7
|
*
|
|
8
8
|
* @module orchestration-di
|
|
9
|
-
* @see {@link ./ports/metrics-collector.port.
|
|
10
|
-
* @see {@link ./ports/dashboard-renderer.port.
|
|
11
|
-
* @see {@link ./adapters/filesystem-metrics.adapter.
|
|
12
|
-
* @see {@link ./adapters/terminal-renderer.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.
|
|
9
|
-
* @see {@link
|
|
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:
|
|
50
|
+
missing: any[];
|
|
51
51
|
errorMessage?: undefined;
|
|
52
52
|
} | {
|
|
53
53
|
compliant: boolean;
|
|
54
54
|
blocking: boolean;
|
|
55
|
-
missing:
|
|
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.
|
|
9
|
-
* @see {@link
|
|
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
|
-
|
|
78
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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(
|
|
160
|
-
lines.push(' 3.
|
|
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 (
|
|
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:
|
|
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
|
|
18
|
-
* @see {@link
|
|
19
|
-
* @see {@link
|
|
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
|
/**
|
package/dist/orphan-detector.js
CHANGED
|
@@ -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
|
|
18
|
-
* @see {@link
|
|
19
|
-
* @see {@link
|
|
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
|
+
}
|