@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.
@@ -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 cwdAbs;
616
- try { cwdAbs = path.resolve(rec.cwd); } catch { continue; }
617
- if (cwdAbs === wtAbs || cwdAbs.startsWith(wtPrefix)) {
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 || !d.meta || !d.meta.branch) continue;
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
- // Resolved managed-spawn cwds (per-cwd → resolved abs path). Used to
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 (managedSpawnCwds.length > 0) {
841
- const wtPathNorm = path.resolve(wtPath);
842
- const wtPrefix = wtPathNorm + path.sep;
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
- // managed_spawn cwds.
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 (managedSpawnCwds.length > 0) {
1063
- const wtPrefix = wtAbs + path.sep;
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,