@integrity-labs/agt-cli 0.28.54 → 0.28.56

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.
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-YSE6OUM6.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-T6VRODM5.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-XU7GFFQH.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-LDE4CJO5.js.map
@@ -27,7 +27,7 @@ import {
27
27
  requireHost,
28
28
  safeWriteJsonAtomic,
29
29
  setConfigHash
30
- } from "../chunk-SACN4YP6.js";
30
+ } from "../chunk-OLP3LORD.js";
31
31
  import {
32
32
  getProjectDir as getProjectDir2,
33
33
  getReadyTasks,
@@ -65,7 +65,7 @@ import {
65
65
  takeWatchdogGiveUpCount,
66
66
  takeZombieDetection,
67
67
  transcriptActivityAgeSeconds
68
- } from "../chunk-QK4EU3TC.js";
68
+ } from "../chunk-ATK3HBK6.js";
69
69
  import {
70
70
  FLAGS_SCHEMA_VERSION,
71
71
  FLAG_REGISTRY,
@@ -96,7 +96,7 @@ import {
96
96
  resolveDmTarget,
97
97
  sumTranscriptUsageInWindow,
98
98
  wrapScheduledTaskPrompt
99
- } from "../chunk-WBZFCFU6.js";
99
+ } from "../chunk-TMTSBVPP.js";
100
100
  import {
101
101
  parsePsRows,
102
102
  reapOrphanChannelMcps
@@ -444,6 +444,12 @@ function reapStaleMcpChildren(args) {
444
444
  import { execFileSync as execFileSync2 } from "child_process";
445
445
  var DEFAULT_COLD_START_GRACE_MS = 9e4;
446
446
  var MAX_PRESENCE_RESTART_ATTEMPTS = 3;
447
+ var BACKOFF_AFTER_RESTARTS = MAX_PRESENCE_RESTART_ATTEMPTS;
448
+ var BACKOFF_BASE_MS = 6e4;
449
+ var BACKOFF_MAX_MS = 30 * 6e4;
450
+ var BACKOFF_WINDOW_MS = 60 * 6e4;
451
+ var BACKOFF_GIVE_UP_RESTARTS = 2 * MAX_PRESENCE_RESTART_ATTEMPTS;
452
+ var BACKOFF_STABLE_RESET_MS = 5 * 6e4;
447
453
  var presenceReaperState = /* @__PURE__ */ new Map();
448
454
  function stateKey(codeName, serverKey) {
449
455
  return `${codeName}\0${serverKey}`;
@@ -463,7 +469,7 @@ function givenUpMcpServerKeys(codeName) {
463
469
  const prefix = `${codeName}\0`;
464
470
  const out = /* @__PURE__ */ new Set();
465
471
  for (const [key, st] of presenceReaperState) {
466
- if (key.startsWith(prefix) && st.attempts >= MAX_PRESENCE_RESTART_ATTEMPTS) {
472
+ if (key.startsWith(prefix) && (st.gaveUp || st.attempts >= MAX_PRESENCE_RESTART_ATTEMPTS)) {
467
473
  out.add(key.slice(prefix.length));
468
474
  }
469
475
  }
@@ -565,6 +571,11 @@ function reapMissingMcpSessions(args) {
565
571
  state7.gaveUpLogged = false;
566
572
  state7.firstMissingAt = null;
567
573
  state7.quarantineLogged = false;
574
+ state7.gaveUp = false;
575
+ if (state7.stableLiveSince === null) state7.stableLiveSince = now();
576
+ if (now() - state7.stableLiveSince >= BACKOFF_STABLE_RESET_MS) {
577
+ state7.restartHistory = [];
578
+ }
568
579
  }
569
580
  }
570
581
  if (missing.length === 0) {
@@ -578,6 +589,8 @@ function reapMissingMcpSessions(args) {
578
589
  const nowMs = now();
579
590
  const givenUp = [];
580
591
  const active = [];
592
+ const backingOff = [];
593
+ const newGenerationKeys = /* @__PURE__ */ new Set();
581
594
  const quarantined = [];
582
595
  const wouldQuarantine = [];
583
596
  for (const key of missing) {
@@ -588,19 +601,30 @@ function reapMissingMcpSessions(args) {
588
601
  lastAttemptedSessionStartedAt: null,
589
602
  gaveUpLogged: false,
590
603
  firstMissingAt: null,
591
- quarantineLogged: false
604
+ quarantineLogged: false,
605
+ restartHistory: [],
606
+ stableLiveSince: null,
607
+ gaveUp: false
592
608
  };
593
609
  if (state7.firstMissingAt === null) state7.firstMissingAt = nowMs;
610
+ state7.stableLiveSince = null;
594
611
  if (state7.lastAttemptedSessionStartedAt !== sessionStartedAt) {
595
612
  state7.attempts += 1;
596
613
  state7.lastAttemptedSessionStartedAt = sessionStartedAt;
614
+ newGenerationKeys.add(key);
597
615
  }
616
+ state7.restartHistory = state7.restartHistory.filter((t) => nowMs - t < BACKOFF_WINDOW_MS);
617
+ const restartsInWindow = state7.restartHistory.length;
598
618
  presenceReaperState.set(sk, state7);
599
- if (state7.attempts > MAX_PRESENCE_RESTART_ATTEMPTS) {
619
+ const overAttemptsCap = state7.attempts > MAX_PRESENCE_RESTART_ATTEMPTS;
620
+ const overRateCap = restartsInWindow >= BACKOFF_GIVE_UP_RESTARTS;
621
+ if (overAttemptsCap || overRateCap) {
600
622
  givenUp.push(key);
623
+ state7.gaveUp = true;
601
624
  if (!state7.gaveUpLogged) {
625
+ const cause = overAttemptsCap ? `${MAX_PRESENCE_RESTART_ATTEMPTS} consecutive failed restarts \u2014 declared but never recovers (likely orphaned config; see ENG-5279)` : `${restartsInWindow} restarts within ${Math.round(BACKOFF_WINDOW_MS / 6e4)}m \u2014 persistently flapping (crash-loop; ENG-6480)`;
602
626
  log2(
603
- `[mcp-presence-reaper] giving up on '${codeName}:${key}' after ${MAX_PRESENCE_RESTART_ATTEMPTS} consecutive failed restarts \u2014 declared but never recovers (likely orphaned config; see ENG-5279)`
627
+ `[mcp-presence-reaper] giving up on '${codeName}:${key}' after ${cause}`
604
628
  );
605
629
  state7.gaveUpLogged = true;
606
630
  if (onGiveUp) {
@@ -640,15 +664,31 @@ function reapMissingMcpSessions(args) {
640
664
  }
641
665
  }
642
666
  } else {
643
- active.push(key);
667
+ const backoffMs = restartsInWindow < BACKOFF_AFTER_RESTARTS ? 0 : Math.min(
668
+ BACKOFF_BASE_MS * 2 ** (restartsInWindow - BACKOFF_AFTER_RESTARTS),
669
+ BACKOFF_MAX_MS
670
+ );
671
+ const lastRestartAt = state7.restartHistory[state7.restartHistory.length - 1] ?? null;
672
+ if (lastRestartAt !== null && nowMs - lastRestartAt < backoffMs) {
673
+ backingOff.push(key);
674
+ } else {
675
+ active.push(key);
676
+ }
644
677
  }
645
678
  }
646
679
  if (active.length === 0) {
680
+ const reason = backingOff.length > 0 ? "backoff" : "all-keys-over-cap";
681
+ if (backingOff.length > 0) {
682
+ log2(
683
+ `[mcp-presence-reaper] '${codeName}': holding off restart for [${backingOff.join(", ")}] \u2014 escalating backoff interval not yet elapsed (ENG-6480)${givenUp.length > 0 ? ` (given up: [${givenUp.join(", ")}])` : ""}`
684
+ );
685
+ }
647
686
  return {
648
687
  missing,
649
688
  restarted: false,
650
- reason: "all-keys-over-cap",
689
+ reason,
651
690
  givenUp,
691
+ backingOff: backingOff.length > 0 ? backingOff : void 0,
652
692
  rotationGraced: rotationGraced.length > 0 ? rotationGraced : void 0,
653
693
  quarantined: quarantined.length > 0 ? quarantined : void 0,
654
694
  wouldQuarantine: wouldQuarantine.length > 0 ? wouldQuarantine : void 0
@@ -675,10 +715,16 @@ function reapMissingMcpSessions(args) {
675
715
  }
676
716
  }
677
717
  stopSession(codeName, { activeKeys: active });
718
+ for (const key of active) {
719
+ if (!newGenerationKeys.has(key)) continue;
720
+ const st = presenceReaperState.get(stateKey(codeName, key));
721
+ if (st) st.restartHistory.push(nowMs);
722
+ }
678
723
  return {
679
724
  missing,
680
725
  restarted: true,
681
726
  givenUp: givenUp.length > 0 ? givenUp : void 0,
727
+ backingOff: backingOff.length > 0 ? backingOff : void 0,
682
728
  rotationGraced: rotationGraced.length > 0 ? rotationGraced : void 0,
683
729
  quarantined: quarantined.length > 0 ? quarantined : void 0,
684
730
  wouldQuarantine: wouldQuarantine.length > 0 ? wouldQuarantine : void 0
@@ -6634,7 +6680,7 @@ var cachedMaintenanceWindow = null;
6634
6680
  var lastVersionCheckAt = 0;
6635
6681
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6636
6682
  var lastResponsivenessProbeAt = 0;
6637
- var agtCliVersion = true ? "0.28.54" : "dev";
6683
+ var agtCliVersion = true ? "0.28.56" : "dev";
6638
6684
  function resolveBrewPath(execFileSync4) {
6639
6685
  try {
6640
6686
  const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -7742,7 +7788,7 @@ async function pollCycle() {
7742
7788
  }
7743
7789
  try {
7744
7790
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
7745
- const { collectDiagnostics } = await import("../persistent-session-YSE6OUM6.js");
7791
+ const { collectDiagnostics } = await import("../persistent-session-T6VRODM5.js");
7746
7792
  const diagCodeNames = [...agentState.persistentSessionAgents];
7747
7793
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
7748
7794
  let tailscaleHostname;
@@ -7843,7 +7889,7 @@ async function pollCycle() {
7843
7889
  const {
7844
7890
  collectResponsivenessProbes,
7845
7891
  getResponsivenessIntervalMs
7846
- } = await import("../responsiveness-probe-4BU75QQV.js");
7892
+ } = await import("../responsiveness-probe-NI26NQJO.js");
7847
7893
  const probeIntervalMs = getResponsivenessIntervalMs();
7848
7894
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
7849
7895
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -7875,7 +7921,7 @@ async function pollCycle() {
7875
7921
  collectResponsivenessProbes,
7876
7922
  livePendingInboundOldestAgeSeconds,
7877
7923
  parkPendingInbound
7878
- } = await import("../responsiveness-probe-4BU75QQV.js");
7924
+ } = await import("../responsiveness-probe-NI26NQJO.js");
7879
7925
  const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
7880
7926
  const wedgeNow = /* @__PURE__ */ new Date();
7881
7927
  const liveAgents = agentState.persistentSessionAgents;
@@ -11285,7 +11331,7 @@ async function processClaudePairSessions(agents) {
11285
11331
  killPairSession,
11286
11332
  pairTmuxSession,
11287
11333
  finalizeClaudePairOnboarding
11288
- } = await import("../claude-pair-runtime-XU7GFFQH.js");
11334
+ } = await import("../claude-pair-runtime-LDE4CJO5.js");
11289
11335
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
11290
11336
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
11291
11337
  const killed = await killPairSession(pairTmuxSession(pairId));