@yemi33/minions 0.1.2350 → 0.1.2351
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/engine/live-checkout.js +80 -0
- package/package.json +1 -1
package/engine/live-checkout.js
CHANGED
|
@@ -389,6 +389,45 @@ function _defaultWriteInboxNote(slug, content) {
|
|
|
389
389
|
return require('./dispatch').writeInboxAlert(slug, content);
|
|
390
390
|
}
|
|
391
391
|
|
|
392
|
+
// Best-effort, side-effect-light resolution of `mainRef` as a restore target
|
|
393
|
+
// when a captured originalRef is found to be contaminated (see
|
|
394
|
+
// ENGINE_DISPATCH_BRANCH_PATTERN above). Mirrors the STALE-BASE GUARD's
|
|
395
|
+
// local-main / auto-base-repair fallback (Step 4d) but never switches HEAD
|
|
396
|
+
// itself — it only materializes a local `<mainRef>` branch (a plain ref op,
|
|
397
|
+
// no checkout, no fetch, issue #226 preserved) when auto-base-repair is
|
|
398
|
+
// enabled and no local ref already exists. Returns `{ ref, type }` on success
|
|
399
|
+
// or `{ ref: null, type: null }` when mainRef cannot be resolved without a
|
|
400
|
+
// fetch and auto-base-repair is disabled or unavailable.
|
|
401
|
+
async function _resolveMainRefForRestore({ git, baseOpts, mainRef, autoBaseRepair, _resolveAutoBaseRepair, localPath, logFn }) {
|
|
402
|
+
try {
|
|
403
|
+
await git(['rev-parse', '--verify', '--quiet', `refs/heads/${mainRef}`], baseOpts);
|
|
404
|
+
return { ref: mainRef, type: 'branch' };
|
|
405
|
+
} catch { /* fall through to auto-repair */ }
|
|
406
|
+
|
|
407
|
+
let wantBaseRepair = false;
|
|
408
|
+
if (typeof autoBaseRepair === 'boolean') {
|
|
409
|
+
wantBaseRepair = autoBaseRepair;
|
|
410
|
+
} else {
|
|
411
|
+
const resolver = (typeof _resolveAutoBaseRepair === 'function') ? _resolveAutoBaseRepair : _defaultResolveAutoBaseRepair;
|
|
412
|
+
try { wantBaseRepair = !!resolver(localPath); } catch { wantBaseRepair = false; }
|
|
413
|
+
}
|
|
414
|
+
if (!wantBaseRepair) return { ref: null, type: null };
|
|
415
|
+
|
|
416
|
+
try {
|
|
417
|
+
await git(['rev-parse', '--verify', '--quiet', `refs/remotes/origin/${mainRef}`], baseOpts);
|
|
418
|
+
} catch {
|
|
419
|
+
return { ref: null, type: null };
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
await git(['branch', '--no-track', mainRef, `refs/remotes/origin/${mainRef}`], baseOpts);
|
|
423
|
+
logFn('info',
|
|
424
|
+
`live-checkout: materialized local '${mainRef}' from 'origin/${mainRef}' (no fetch, issue #226 preserved) to correct a contaminated originalRef.`);
|
|
425
|
+
return { ref: mainRef, type: 'branch' };
|
|
426
|
+
} catch {
|
|
427
|
+
return { ref: null, type: null };
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
392
431
|
async function prepareLiveCheckout(opts = {}) {
|
|
393
432
|
const {
|
|
394
433
|
localPath,
|
|
@@ -842,6 +881,32 @@ async function prepareLiveCheckout(opts = {}) {
|
|
|
842
881
|
// Plain checkout — NO --force, NO -B, NO pull. Operator owns local commits.
|
|
843
882
|
const failed = await runCheckout(['checkout', branchName], { creating: false });
|
|
844
883
|
if (failed) return failed;
|
|
884
|
+
// ── originalRef contamination invariant (W-mrb6an8300058fd8). ──────────
|
|
885
|
+
// originalRef was captured at Step 3 BEFORE this checkout, from whatever
|
|
886
|
+
// HEAD happened to be. If it itself looks like a prior dispatch's own
|
|
887
|
+
// engine-managed branch (`_looksLikeAgentBranch` — the same `work/<id>`
|
|
888
|
+
// check issue #608's dirty-tree self-heal uses above) — and this isn't an
|
|
889
|
+
// explicit PR-continuation (allowNonMainBase) — it is never a sane restore
|
|
890
|
+
// target: prefer mainRef instead, while still surfacing the anomaly via
|
|
891
|
+
// logFn rather than silently swallowing it.
|
|
892
|
+
if (!allowNonMainBase && originalRefType === 'branch' && originalRef && originalRef !== mainRef &&
|
|
893
|
+
_looksLikeAgentBranch(originalRef)) {
|
|
894
|
+
logFn(
|
|
895
|
+
`[live-checkout] originalRef anomaly: HEAD was on engine-managed branch '${originalRef}' before checking out '${branchName}' — ` +
|
|
896
|
+
`this looks like leftover contamination from an earlier dispatch, not a sane restore target. Attempting to correct to '${mainRef}'.`,
|
|
897
|
+
'warn'
|
|
898
|
+
);
|
|
899
|
+
const corrected = await _resolveMainRefForRestore({ git, baseOpts, mainRef, autoBaseRepair, _resolveAutoBaseRepair, localPath, logFn });
|
|
900
|
+
if (corrected.ref) {
|
|
901
|
+
originalRef = corrected.ref;
|
|
902
|
+
originalRefType = corrected.type;
|
|
903
|
+
} else {
|
|
904
|
+
logFn(
|
|
905
|
+
`[live-checkout] originalRef anomaly: could not resolve '${mainRef}' as a corrected restore target (no local ref, auto-base-repair disabled, or 'origin/${mainRef}' missing) — leaving originalRef as the contaminated '${originalRef}'; a human should verify the operator checkout manually.`,
|
|
906
|
+
'warn'
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
845
910
|
return { ok: true, branch: branchName, created: false, originalRef, originalRefType };
|
|
846
911
|
}
|
|
847
912
|
|
|
@@ -983,6 +1048,21 @@ async function prepareLiveCheckout(opts = {}) {
|
|
|
983
1048
|
}
|
|
984
1049
|
logFn('info',
|
|
985
1050
|
`live-checkout: HEAD was on '${headBranch}' (not base '${mainRef}') — switched to local '${mainRef}' before forking '${branchName}' (no fetch, issue #226 preserved)`);
|
|
1051
|
+
// ── originalRef correction (W-mrb6an8300058fd8). ─────────────────────
|
|
1052
|
+
// originalRef/originalRefType were captured at Step 3 from the STALE
|
|
1053
|
+
// headBranch, BEFORE this self-heal ran. The tree has now been switched
|
|
1054
|
+
// to the CORRECTED mainRef, so the value returned to the caller (and
|
|
1055
|
+
// persisted on the dispatch record — engine.js spawnAgent ~line
|
|
1056
|
+
// 3106-3122) must reflect mainRef, not the stale branch. Otherwise
|
|
1057
|
+
// restoreLiveCheckoutAtDispatchEnd would put the operator checkout BACK
|
|
1058
|
+
// onto the stale branch at dispatch end, propagating the contamination
|
|
1059
|
+
// into every subsequent live-mode dispatch that captures HEAD (the
|
|
1060
|
+
// exact recurrence observed on minions-opg 2026-07-07: HEAD landed on
|
|
1061
|
+
// 'main' via this self-heal, but the persisted originalRef still said
|
|
1062
|
+
// 'work/sched-daily-remove-merged-prs-…', so the dispatch-end restore
|
|
1063
|
+
// switched the operator checkout back onto that stale branch).
|
|
1064
|
+
originalRef = mainRef;
|
|
1065
|
+
originalRefType = 'branch';
|
|
986
1066
|
}
|
|
987
1067
|
}
|
|
988
1068
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2351",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|