@yemi33/minions 0.1.2383 → 0.1.2385
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/dashboard/js/refresh.js +2 -1
- package/dashboard/js/settings.js +1 -1
- package/dashboard.js +133 -46
- package/docs/keep-processes.md +7 -2
- package/docs/live-checkout-mode.md +7 -7
- package/docs/managed-spawn.md +14 -1
- package/docs/runtime-adapters.md +7 -4
- package/docs/worktree-lifecycle.md +22 -0
- package/engine/acp-transport.js +216 -29
- package/engine/agent-worker-pool.js +268 -51
- package/engine/cc-worker-pool.js +8 -1
- package/engine/cleanup.js +15 -11
- package/engine/cli.js +47 -27
- package/engine/create-pr-worktree.js +57 -79
- package/engine/keep-process-sweep.js +131 -9
- package/engine/lifecycle.js +1 -1
- package/engine/live-checkout.js +4 -2
- package/engine/managed-spawn.js +112 -5
- package/engine/pooled-agent-process.js +486 -21
- package/engine/pr-action.js +6 -8
- package/engine/process-utils.js +154 -18
- package/engine/runtimes/copilot.js +22 -4
- package/engine/shared.js +254 -61
- package/engine/spawn-agent.js +6 -3
- package/engine/timeout.js +14 -10
- package/engine/worktree-gc.js +55 -46
- package/engine.js +237 -134
- package/package.json +1 -1
- package/playbooks/shared-rules.md +2 -2
- package/prompts/cc-system.md +11 -11
package/engine/worktree-gc.js
CHANGED
|
@@ -41,6 +41,32 @@ function _managedSpawn() {
|
|
|
41
41
|
|
|
42
42
|
const _noopLog = () => {};
|
|
43
43
|
|
|
44
|
+
function _collectAnchoredCwds(listManagedSpecs, listKeepProcessCwds) {
|
|
45
|
+
const out = [];
|
|
46
|
+
try {
|
|
47
|
+
for (const rec of (listManagedSpecs() || [])) {
|
|
48
|
+
if (!rec || typeof rec.cwd !== 'string' || !rec.cwd) continue;
|
|
49
|
+
try { out.push(shared.realPathForComparison(rec.cwd)); } catch {}
|
|
50
|
+
}
|
|
51
|
+
} catch {}
|
|
52
|
+
try {
|
|
53
|
+
for (const cwd of (listKeepProcessCwds() || [])) {
|
|
54
|
+
if (typeof cwd !== 'string' || !cwd) continue;
|
|
55
|
+
try { out.push(shared.realPathForComparison(cwd)); } catch {}
|
|
56
|
+
}
|
|
57
|
+
} catch {}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function _isWorktreeCwdAnchored(worktreePath, anchoredCwds) {
|
|
62
|
+
for (const cwd of anchoredCwds) {
|
|
63
|
+
try {
|
|
64
|
+
if (shared.isPathInsideOrEqual(cwd, worktreePath)) return true;
|
|
65
|
+
} catch {}
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
44
70
|
// ── Stuck-dir escalation (Layer 4 of W-mq5o6bvy000x7191) ─────────────────────
|
|
45
71
|
// In-memory ring of paths that have failed removal N consecutive times. After
|
|
46
72
|
// escalation we (a) write a dedup'd inbox note, (b) suppress repeat per-tick
|
|
@@ -608,13 +634,11 @@ function shouldGcDispatchWorktree(opts) {
|
|
|
608
634
|
? listManagedSpecs
|
|
609
635
|
: _managedSpawn().listManagedSpecs;
|
|
610
636
|
const specs = fn() || [];
|
|
611
|
-
const wtAbs = path.resolve(worktreePath);
|
|
612
|
-
const wtPrefix = wtAbs + path.sep;
|
|
613
637
|
for (const rec of specs) {
|
|
614
638
|
if (!rec || typeof rec.cwd !== 'string' || rec.cwd.length === 0) continue;
|
|
615
|
-
let
|
|
616
|
-
try {
|
|
617
|
-
if (
|
|
639
|
+
let anchored = false;
|
|
640
|
+
try { anchored = shared.isPathInsideOrEqual(rec.cwd, worktreePath); } catch {}
|
|
641
|
+
if (anchored) {
|
|
618
642
|
return { gc: false, reason: 'managed-spawn-anchored' };
|
|
619
643
|
}
|
|
620
644
|
}
|
|
@@ -744,6 +768,12 @@ function pruneOrphanWorktrees(opts) {
|
|
|
744
768
|
try { return _managedSpawn().listManagedSpecs(); }
|
|
745
769
|
catch (_e) { return []; }
|
|
746
770
|
});
|
|
771
|
+
const _listKeepProcessCwds = typeof opts.listKeepProcessCwds === 'function'
|
|
772
|
+
? opts.listKeepProcessCwds
|
|
773
|
+
: (() => {
|
|
774
|
+
try { return _keepProcessSweep().getActiveKeepProcessCwds(); }
|
|
775
|
+
catch (_e) { return []; }
|
|
776
|
+
});
|
|
747
777
|
|
|
748
778
|
// Pool-known paths (idle + borrowed + any stale entry still on disk). The
|
|
749
779
|
// worktree-pool's own pruneStale() runs FIRST in cli boot so this snapshot
|
|
@@ -768,7 +798,11 @@ function pruneOrphanWorktrees(opts) {
|
|
|
768
798
|
// review — Issue 2)
|
|
769
799
|
const globalLiveDirNames = new Set();
|
|
770
800
|
for (const d of [...(dispatchSnap.active || []), ...(dispatchSnap.pending || [])]) {
|
|
771
|
-
if (!d || !d.id
|
|
801
|
+
if (!d || !d.id) continue;
|
|
802
|
+
if (d.worktreePath) {
|
|
803
|
+
try { globalLiveDirNames.add(path.basename(path.resolve(d.worktreePath))); } catch {}
|
|
804
|
+
}
|
|
805
|
+
if (!d.meta || !d.meta.branch) continue;
|
|
772
806
|
const dispatchProject = typeof d.meta.project === 'string'
|
|
773
807
|
? d.meta.project
|
|
774
808
|
: (d.meta.project?.name || 'default');
|
|
@@ -781,17 +815,7 @@ function pruneOrphanWorktrees(opts) {
|
|
|
781
815
|
} catch (_e) { /* defensive */ }
|
|
782
816
|
}
|
|
783
817
|
|
|
784
|
-
|
|
785
|
-
// reject GC of any dir that contains (or equals) a live service's cwd.
|
|
786
|
-
// (PR #2627 review — Issue 1)
|
|
787
|
-
const managedSpawnCwds = [];
|
|
788
|
-
try {
|
|
789
|
-
for (const rec of (_listManagedSpecs() || [])) {
|
|
790
|
-
if (!rec || typeof rec.cwd !== 'string' || rec.cwd.length === 0) continue;
|
|
791
|
-
try { managedSpawnCwds.push(path.resolve(rec.cwd)); }
|
|
792
|
-
catch (_e) { /* malformed cwd — skip */ }
|
|
793
|
-
}
|
|
794
|
-
} catch (_e) { /* optional */ }
|
|
818
|
+
const anchoredCwds = _collectAnchoredCwds(_listManagedSpecs, _listKeepProcessCwds);
|
|
795
819
|
|
|
796
820
|
const result = { scanned: 0, kept: 0, evicted: 0, failed: 0, perProject: {} };
|
|
797
821
|
|
|
@@ -836,18 +860,10 @@ function pruneOrphanWorktrees(opts) {
|
|
|
836
860
|
projStats.kept++; result.kept++;
|
|
837
861
|
continue;
|
|
838
862
|
}
|
|
839
|
-
// 3. managed_spawn cwd anchor protection.
|
|
840
|
-
if (
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
let anchored = false;
|
|
844
|
-
for (const cwd of managedSpawnCwds) {
|
|
845
|
-
if (cwd === wtPathNorm || cwd.startsWith(wtPrefix)) { anchored = true; break; }
|
|
846
|
-
}
|
|
847
|
-
if (anchored) {
|
|
848
|
-
projStats.kept++; result.kept++;
|
|
849
|
-
continue;
|
|
850
|
-
}
|
|
863
|
+
// 3. managed_spawn / keep_processes cwd anchor protection.
|
|
864
|
+
if (_isWorktreeCwdAnchored(wtPath, anchoredCwds)) {
|
|
865
|
+
projStats.kept++; result.kept++;
|
|
866
|
+
continue;
|
|
851
867
|
}
|
|
852
868
|
|
|
853
869
|
// P-c7e2b405 — route the slow-retry gate, ownership-marker gate (now
|
|
@@ -938,6 +954,12 @@ function pruneOrphanWorktreesFromGitRegistry(opts) {
|
|
|
938
954
|
try { return _managedSpawn().listManagedSpecs(); }
|
|
939
955
|
catch (_e) { return []; }
|
|
940
956
|
});
|
|
957
|
+
const _listKeepProcessCwds = typeof opts.listKeepProcessCwds === 'function'
|
|
958
|
+
? opts.listKeepProcessCwds
|
|
959
|
+
: (() => {
|
|
960
|
+
try { return _keepProcessSweep().getActiveKeepProcessCwds(); }
|
|
961
|
+
catch (_e) { return []; }
|
|
962
|
+
});
|
|
941
963
|
const _execSilent = typeof opts.execSilent === 'function'
|
|
942
964
|
? opts.execSilent
|
|
943
965
|
: shared.execSilent;
|
|
@@ -986,15 +1008,7 @@ function pruneOrphanWorktreesFromGitRegistry(opts) {
|
|
|
986
1008
|
for (const p of opts.extraPoolPaths) poolPaths.add(worktreePool._normalizePath(p));
|
|
987
1009
|
}
|
|
988
1010
|
|
|
989
|
-
|
|
990
|
-
const managedSpawnCwds = [];
|
|
991
|
-
try {
|
|
992
|
-
for (const rec of (_listManagedSpecs() || [])) {
|
|
993
|
-
if (!rec || typeof rec.cwd !== 'string' || rec.cwd.length === 0) continue;
|
|
994
|
-
try { managedSpawnCwds.push(path.resolve(rec.cwd)); }
|
|
995
|
-
catch (_e) { /* malformed cwd — skip */ }
|
|
996
|
-
}
|
|
997
|
-
} catch (_e) { /* optional */ }
|
|
1011
|
+
const anchoredCwds = _collectAnchoredCwds(_listManagedSpecs, _listKeepProcessCwds);
|
|
998
1012
|
|
|
999
1013
|
const result = { scanned: 0, kept: 0, evicted: 0, failed: 0, prunedRegistry: 0, perProject: {} };
|
|
1000
1014
|
const _seenAbs = new Set(); // dedup across projects sharing a parent
|
|
@@ -1058,14 +1072,9 @@ function pruneOrphanWorktreesFromGitRegistry(opts) {
|
|
|
1058
1072
|
if (poolPaths.has(normPath)) {
|
|
1059
1073
|
projStats.kept++; result.kept++; continue;
|
|
1060
1074
|
}
|
|
1061
|
-
// managed_spawn anchor protection
|
|
1062
|
-
if (
|
|
1063
|
-
|
|
1064
|
-
let anchored = false;
|
|
1065
|
-
for (const cwd of managedSpawnCwds) {
|
|
1066
|
-
if (cwd === wtAbs || cwd.startsWith(wtPrefix)) { anchored = true; break; }
|
|
1067
|
-
}
|
|
1068
|
-
if (anchored) { projStats.kept++; result.kept++; continue; }
|
|
1075
|
+
// managed_spawn / keep_processes cwd anchor protection.
|
|
1076
|
+
if (_isWorktreeCwdAnchored(wtAbs, anchoredCwds)) {
|
|
1077
|
+
projStats.kept++; result.kept++; continue;
|
|
1069
1078
|
}
|
|
1070
1079
|
|
|
1071
1080
|
// P-c7e2b405 — ownership-marker gate, slow-retry gate, remove, escalate,
|