omegon 0.8.3 → 0.8.4
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.
|
@@ -352,7 +352,7 @@ async function checkpointRelatedChanges(
|
|
|
352
352
|
* Prevents infinite loops when the agent repeatedly picks actions
|
|
353
353
|
* that don't resolve the dirty tree.
|
|
354
354
|
*/
|
|
355
|
-
const MAX_PREFLIGHT_ATTEMPTS = 3;
|
|
355
|
+
export const MAX_PREFLIGHT_ATTEMPTS = 3;
|
|
356
356
|
|
|
357
357
|
/**
|
|
358
358
|
* Verify the tree is clean after an action. If only volatile files remain,
|
|
@@ -435,12 +435,23 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
435
435
|
throw new Error(summary + "\n\nInteractive input is unavailable, so cleave cannot resolve the dirty tree automatically.");
|
|
436
436
|
}
|
|
437
437
|
|
|
438
|
-
// Mutable classification — refreshed after each action
|
|
438
|
+
// Mutable classification — refreshed after each resolution action.
|
|
439
439
|
let currentClassification = classification;
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
440
|
+
// Only resolution actions (checkpoint, stash) increment this counter.
|
|
441
|
+
// Invalid input, empty guards, cancel, and proceed-without-cleave do NOT
|
|
442
|
+
// consume attempts — they are navigational, not resolution attempts.
|
|
443
|
+
let resolutionAttempts = 0;
|
|
444
|
+
|
|
445
|
+
// Outer safety cap: total loop iterations including non-resolution turns.
|
|
446
|
+
// Prevents truly pathological loops (e.g. select always returning garbage).
|
|
447
|
+
const MAX_TOTAL_ITERATIONS = MAX_PREFLIGHT_ATTEMPTS * 3;
|
|
448
|
+
let totalIterations = 0;
|
|
449
|
+
|
|
450
|
+
while (resolutionAttempts < MAX_PREFLIGHT_ATTEMPTS) {
|
|
451
|
+
totalIterations++;
|
|
452
|
+
if (totalIterations > MAX_TOTAL_ITERATIONS) {
|
|
453
|
+
break; // Fall through to the exhaustion error below
|
|
454
|
+
}
|
|
444
455
|
|
|
445
456
|
let answer: string | undefined;
|
|
446
457
|
if (hasSelect) {
|
|
@@ -458,6 +469,7 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
458
469
|
try {
|
|
459
470
|
switch (answer) {
|
|
460
471
|
case "checkpoint": {
|
|
472
|
+
resolutionAttempts++;
|
|
461
473
|
const currentCheckpointPlan = buildCheckpointPlan(currentClassification, { changeName, openspecContext });
|
|
462
474
|
await checkpointRelatedChanges(pi, options.repoPath, currentClassification, currentCheckpointPlan.message, options.ui);
|
|
463
475
|
|
|
@@ -493,6 +505,7 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
493
505
|
});
|
|
494
506
|
break;
|
|
495
507
|
}
|
|
508
|
+
resolutionAttempts++;
|
|
496
509
|
await stashPaths(pi, options.repoPath, "cleave-preflight-unrelated", toStash);
|
|
497
510
|
const { clean, classification: postClassification } = await verifyCleanAfterAction(
|
|
498
511
|
pi, options.repoPath, changeName, openspecContext, options.onUpdate,
|
|
@@ -509,6 +522,7 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
509
522
|
});
|
|
510
523
|
break;
|
|
511
524
|
}
|
|
525
|
+
resolutionAttempts++;
|
|
512
526
|
await stashPaths(pi, options.repoPath, "cleave-preflight-volatile", currentClassification.volatile);
|
|
513
527
|
const { clean, classification: postClassification } = await verifyCleanAfterAction(
|
|
514
528
|
pi, options.repoPath, changeName, openspecContext, options.onUpdate,
|
|
@@ -529,6 +543,8 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
529
543
|
});
|
|
530
544
|
}
|
|
531
545
|
} catch (error) {
|
|
546
|
+
// Resolution action threw (e.g. git commit failed) — still counts
|
|
547
|
+
// as a resolution attempt since work was attempted.
|
|
532
548
|
const message = error instanceof Error ? error.message : String(error);
|
|
533
549
|
options.onUpdate?.({
|
|
534
550
|
content: [{ type: "text", text: `Preflight action failed: ${message}` }],
|
|
@@ -537,7 +553,7 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
537
553
|
}
|
|
538
554
|
}
|
|
539
555
|
|
|
540
|
-
// Exhausted attempts — report remaining dirty files and bail.
|
|
556
|
+
// Exhausted resolution attempts — report remaining dirty files and bail.
|
|
541
557
|
const remaining = [
|
|
542
558
|
...currentClassification.related,
|
|
543
559
|
...currentClassification.unrelated,
|
|
@@ -545,7 +561,7 @@ export async function runDirtyTreePreflight(pi: ExtensionAPI, options: DirtyTree
|
|
|
545
561
|
...currentClassification.volatile,
|
|
546
562
|
];
|
|
547
563
|
throw new Error(
|
|
548
|
-
`Dirty tree not resolved after ${
|
|
564
|
+
`Dirty tree not resolved after ${resolutionAttempts} resolution attempt(s). Remaining files:\n` +
|
|
549
565
|
remaining.map((f) => ` • ${f.path}`).join("\n") +
|
|
550
566
|
"\n\nResolve manually (git commit/stash/checkout) and retry /cleave.",
|
|
551
567
|
);
|
|
@@ -432,6 +432,9 @@ export function computeAssessmentSnapshot(repoPath: string, changeName: string):
|
|
|
432
432
|
// assessment.json (which lives in-repo) changes HEAD, which invalidates
|
|
433
433
|
// the fingerprint, making the assessment permanently stale.
|
|
434
434
|
// Git HEAD is stored separately in the snapshot for informational use.
|
|
435
|
+
// The `dirty` flag still captures uncommitted-change state, which is
|
|
436
|
+
// the meaningful signal — it detects when scoped files have been
|
|
437
|
+
// modified since the last commit without requiring HEAD identity.
|
|
435
438
|
const fingerprintSeed = JSON.stringify({
|
|
436
439
|
changeName,
|
|
437
440
|
dirty,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omegon",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"description": "Omegon — an opinionated distribution of pi (by Mario Zechner) with extensions for lifecycle management, memory, orchestration, and visualization",
|
|
5
5
|
"bin": {
|
|
6
6
|
"omegon": "bin/omegon.mjs",
|