@integrity-labs/agt-cli 0.28.717 → 0.28.718

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.
Files changed (25) hide show
  1. package/dist/bin/agt.js +5 -5
  2. package/dist/{chunk-KVR5KNED.js → chunk-7LH3SVAD.js} +7 -2
  3. package/dist/chunk-7LH3SVAD.js.map +1 -0
  4. package/dist/{chunk-XSBRGOGL.js → chunk-EEZHSNQ2.js} +4 -4
  5. package/dist/{chunk-JN4D7534.js → chunk-FNALM4HG.js} +120 -19
  6. package/dist/chunk-FNALM4HG.js.map +1 -0
  7. package/dist/{claude-pair-runtime-KWBCSCZO.js → claude-pair-runtime-PDG74SAT.js} +2 -2
  8. package/dist/lib/manager-worker.js +78 -16
  9. package/dist/lib/manager-worker.js.map +1 -1
  10. package/dist/mcp/direct-chat-channel.js +6 -1
  11. package/dist/mcp/index.js +6 -1
  12. package/dist/mcp/origami.js +6 -1
  13. package/dist/mcp/slack-channel.js +6 -1
  14. package/dist/mcp/telegram-channel.js +6 -1
  15. package/dist/{persistent-session-GB3D5OIA.js → persistent-session-2AWYIUCX.js} +7 -3
  16. package/dist/{responsiveness-probe-TDZDQXBU.js → responsiveness-probe-JQS4WA2L.js} +3 -3
  17. package/dist/{session-auth-dead-CPY4UZI7.js → session-auth-dead-VBMZW4GG.js} +2 -2
  18. package/package.json +1 -1
  19. package/dist/chunk-JN4D7534.js.map +0 -1
  20. package/dist/chunk-KVR5KNED.js.map +0 -1
  21. /package/dist/{chunk-XSBRGOGL.js.map → chunk-EEZHSNQ2.js.map} +0 -0
  22. /package/dist/{claude-pair-runtime-KWBCSCZO.js.map → claude-pair-runtime-PDG74SAT.js.map} +0 -0
  23. /package/dist/{persistent-session-GB3D5OIA.js.map → persistent-session-2AWYIUCX.js.map} +0 -0
  24. /package/dist/{responsiveness-probe-TDZDQXBU.js.map → responsiveness-probe-JQS4WA2L.js.map} +0 -0
  25. /package/dist/{session-auth-dead-CPY4UZI7.js.map → session-auth-dead-VBMZW4GG.js.map} +0 -0
@@ -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-GB3D5OIA.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-2AWYIUCX.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-KWBCSCZO.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-PDG74SAT.js.map
@@ -57,7 +57,7 @@ import {
57
57
  safeWriteJsonAtomic,
58
58
  setConfigHash,
59
59
  tripClass
60
- } from "../chunk-XSBRGOGL.js";
60
+ } from "../chunk-EEZHSNQ2.js";
61
61
  import {
62
62
  getProjectDir as getProjectDir2,
63
63
  getReadyTasks,
@@ -115,7 +115,7 @@ import {
115
115
  takeZombieDetection,
116
116
  toOpencodeModel,
117
117
  writeEgressAllowlist
118
- } from "../chunk-JN4D7534.js";
118
+ } from "../chunk-FNALM4HG.js";
119
119
  import {
120
120
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
121
121
  AnchorSessionClient,
@@ -200,7 +200,7 @@ import {
200
200
  subagentActivityAgeSeconds,
201
201
  sumTranscriptUsageInWindow,
202
202
  transcriptActivityAgeSeconds
203
- } from "../chunk-KVR5KNED.js";
203
+ } from "../chunk-7LH3SVAD.js";
204
204
  import {
205
205
  reapOrphanChannelMcps
206
206
  } from "../chunk-XWVM4KPK.js";
@@ -10641,13 +10641,58 @@ function refreshSlackRestartContextHints(codeNames, opts = {}) {
10641
10641
 
10642
10642
  // src/lib/persistent-session-stuck-tracker.ts
10643
10643
  var DEFAULT_STUCK_WARN_THRESHOLD = 3;
10644
+ var DEFAULT_SPAWN_LOOP_WARN_THRESHOLD = 3;
10644
10645
  var PersistentSessionStuckTracker = class {
10645
10646
  counts = /* @__PURE__ */ new Map();
10646
10647
  warned = /* @__PURE__ */ new Set();
10647
10648
  threshold;
10648
- constructor(threshold = DEFAULT_STUCK_WARN_THRESHOLD) {
10649
+ /**
10650
+ * ENG-9614 — the second streak, held separately because it answers a
10651
+ * DIFFERENT question and must not inherit the first one's reset rule.
10652
+ *
10653
+ * `counts` above resets whenever `spawnAttempted` is true, which is correct
10654
+ * for its own question (ENG-5116/Vigil: unhealthy and nobody even TRIED).
10655
+ * But it makes the tracker structurally blind to the inverse: the scratch/tmp
10656
+ * collision attempted a spawn on EVERY tick, so `counts` was deleted on every
10657
+ * tick, `shouldWarn` could never fire, and an agent looped unrecoverably for
10658
+ * 3m48s without this class emitting a single line.
10659
+ *
10660
+ * Folding both into one counter was considered and rejected - a shared
10661
+ * counter would have to pick one reset rule, and either choice makes the
10662
+ * other question unanswerable. Two questions, two counters.
10663
+ */
10664
+ spawnLoopCounts = /* @__PURE__ */ new Map();
10665
+ spawnLoopWarned = /* @__PURE__ */ new Set();
10666
+ spawnLoopThreshold;
10667
+ constructor(threshold = DEFAULT_STUCK_WARN_THRESHOLD, spawnLoopThreshold = DEFAULT_SPAWN_LOOP_WARN_THRESHOLD) {
10649
10668
  if (threshold < 1) throw new Error("stuck-tracker threshold must be >= 1");
10669
+ if (spawnLoopThreshold < 1) throw new Error("stuck-tracker spawn-loop threshold must be >= 1");
10650
10670
  this.threshold = threshold;
10671
+ this.spawnLoopThreshold = spawnLoopThreshold;
10672
+ }
10673
+ /**
10674
+ * Advance the spawn-loop streak for one tick.
10675
+ *
10676
+ * Counts only when a spawn was attempted AND the session is still unhealthy.
10677
+ * Health alone resets it - an agent that came up is not looping, however it
10678
+ * got there. A tick with no spawn attempt neither counts nor resets: that is
10679
+ * the OTHER failure, already owned by `counts`, and letting it clear this
10680
+ * streak would let the two shapes alternate and hide each other.
10681
+ */
10682
+ recordSpawnLoop(codeName, sessionHealthy, spawnAttempted) {
10683
+ if (sessionHealthy) {
10684
+ this.spawnLoopCounts.delete(codeName);
10685
+ this.spawnLoopWarned.delete(codeName);
10686
+ return { ticks: 0, shouldWarn: false };
10687
+ }
10688
+ if (!spawnAttempted) {
10689
+ return { ticks: this.spawnLoopCounts.get(codeName) ?? 0, shouldWarn: false };
10690
+ }
10691
+ const next = (this.spawnLoopCounts.get(codeName) ?? 0) + 1;
10692
+ this.spawnLoopCounts.set(codeName, next);
10693
+ const crossed = next >= this.spawnLoopThreshold && !this.spawnLoopWarned.has(codeName);
10694
+ if (crossed) this.spawnLoopWarned.add(codeName);
10695
+ return { ticks: next, shouldWarn: crossed };
10651
10696
  }
10652
10697
  /**
10653
10698
  * Record one tick for one agent. Returns whether the caller should log
@@ -10658,6 +10703,7 @@ var PersistentSessionStuckTracker = class {
10658
10703
  */
10659
10704
  record(input) {
10660
10705
  const { codeName, sessionHealthy, spawnAttempted } = input;
10706
+ const spawnLoop = this.recordSpawnLoop(codeName, sessionHealthy, spawnAttempted);
10661
10707
  const wasStuck = (this.counts.get(codeName) ?? 0) >= this.threshold;
10662
10708
  if (sessionHealthy || spawnAttempted) {
10663
10709
  this.counts.delete(codeName);
@@ -10665,7 +10711,9 @@ var PersistentSessionStuckTracker = class {
10665
10711
  return {
10666
10712
  consecutiveTicks: 0,
10667
10713
  shouldWarn: false,
10668
- recovered: wasStuck && wasWarned
10714
+ recovered: wasStuck && wasWarned,
10715
+ spawnLoopTicks: spawnLoop.ticks,
10716
+ shouldWarnSpawnLoop: spawnLoop.shouldWarn
10669
10717
  };
10670
10718
  }
10671
10719
  const next = (this.counts.get(codeName) ?? 0) + 1;
@@ -10675,17 +10723,25 @@ var PersistentSessionStuckTracker = class {
10675
10723
  return {
10676
10724
  consecutiveTicks: next,
10677
10725
  shouldWarn: crossed,
10678
- recovered: false
10726
+ recovered: false,
10727
+ spawnLoopTicks: spawnLoop.ticks,
10728
+ shouldWarnSpawnLoop: spawnLoop.shouldWarn
10679
10729
  };
10680
10730
  }
10681
10731
  /** Test/debug helper: peek at an agent's current streak. */
10682
10732
  peek(codeName) {
10683
10733
  return this.counts.get(codeName) ?? 0;
10684
10734
  }
10735
+ /** Test/debug helper: peek at an agent's current spawn-loop streak. */
10736
+ peekSpawnLoop(codeName) {
10737
+ return this.spawnLoopCounts.get(codeName) ?? 0;
10738
+ }
10685
10739
  /** Test helper: clear all state. */
10686
10740
  reset() {
10687
10741
  this.counts.clear();
10688
10742
  this.warned.clear();
10743
+ this.spawnLoopCounts.clear();
10744
+ this.spawnLoopWarned.clear();
10689
10745
  }
10690
10746
  };
10691
10747
 
@@ -12001,7 +12057,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
12001
12057
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
12002
12058
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
12003
12059
  async function channelInboundActivityAgeSecondsFor(codeName) {
12004
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-TDZDQXBU.js");
12060
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-JQS4WA2L.js");
12005
12061
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
12006
12062
  if (newest === null) return null;
12007
12063
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -12649,7 +12705,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12649
12705
  var lastVersionCheckAt = 0;
12650
12706
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12651
12707
  var lastResponsivenessProbeAt = 0;
12652
- var agtCliVersion = true ? "0.28.717" : "dev";
12708
+ var agtCliVersion = true ? "0.28.718" : "dev";
12653
12709
  function resolveBrewPath(execFileSync3) {
12654
12710
  try {
12655
12711
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -14176,7 +14232,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
14176
14232
  if (codeNames.length === 0) return;
14177
14233
  void (async () => {
14178
14234
  try {
14179
- const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
14235
+ const { collectDiagnostics } = await import("../persistent-session-2AWYIUCX.js");
14180
14236
  await api.post("/host/heartbeat", {
14181
14237
  host_id: hostId,
14182
14238
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -14294,7 +14350,7 @@ async function pollCycleInner() {
14294
14350
  }
14295
14351
  try {
14296
14352
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
14297
- const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
14353
+ const { collectDiagnostics } = await import("../persistent-session-2AWYIUCX.js");
14298
14354
  const diagCodeNames = [...agentState.persistentSessionAgents];
14299
14355
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
14300
14356
  let tailscaleHostname;
@@ -14463,7 +14519,7 @@ async function pollCycleInner() {
14463
14519
  collectPanelessActivityProbes,
14464
14520
  getResponsivenessIntervalMs,
14465
14521
  occupancyQualificationClassifications
14466
- } = await import("../responsiveness-probe-TDZDQXBU.js");
14522
+ } = await import("../responsiveness-probe-JQS4WA2L.js");
14467
14523
  const probeIntervalMs = getResponsivenessIntervalMs();
14468
14524
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
14469
14525
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -14573,7 +14629,7 @@ async function pollCycleInner() {
14573
14629
  collectResponsivenessProbes,
14574
14630
  livePendingInboundOldestAgeSeconds,
14575
14631
  parkPendingInbound
14576
- } = await import("../responsiveness-probe-TDZDQXBU.js");
14632
+ } = await import("../responsiveness-probe-JQS4WA2L.js");
14577
14633
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
14578
14634
  const wedgeNow = /* @__PURE__ */ new Date();
14579
14635
  const liveAgents = agentState.persistentSessionAgents;
@@ -14729,7 +14785,7 @@ async function pollCycleInner() {
14729
14785
  }
14730
14786
  try {
14731
14787
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
14732
- const { probeSessionAuth } = await import("../session-auth-dead-CPY4UZI7.js");
14788
+ const { probeSessionAuth } = await import("../session-auth-dead-VBMZW4GG.js");
14733
14789
  const observations = [];
14734
14790
  const pendingCacheCommits = [];
14735
14791
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -17150,6 +17206,12 @@ async function processAgent(agent, agentStates, managedToolkits) {
17150
17206
  } else if (stuck.recovered) {
17151
17207
  log(`[persistent-session-stuck] agent=${agent.code_name} recovered from stuck state`);
17152
17208
  }
17209
+ if (stuck.shouldWarnSpawnLoop) {
17210
+ const failure = getLastFailureContext(agent.code_name);
17211
+ log(
17212
+ `[persistent-session-spawn-loop] WARN: agent=${agent.code_name} respawned ${stuck.spawnLoopTicks} consecutive ticks and is still unhealthy (last_decision=${psResult.decision} signature=${failure.signature} restart_count=${failure.restartCount}) \u2014 the spawn is failing in a way a retry cannot fix; see the pane log tail for the cause (ENG-9614)`
17213
+ );
17214
+ }
17153
17215
  if (agentFw === "claude-code") {
17154
17216
  try {
17155
17217
  checkMcpConfigDriftAndScheduleRestart(agent.code_name, getProjectDir(agent.code_name));
@@ -18554,7 +18616,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
18554
18616
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
18555
18617
  void (async () => {
18556
18618
  try {
18557
- const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
18619
+ const { collectDiagnostics } = await import("../persistent-session-2AWYIUCX.js");
18558
18620
  await api.post("/host/heartbeat", {
18559
18621
  host_id: hostId,
18560
18622
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -18605,7 +18667,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
18605
18667
  }
18606
18668
  try {
18607
18669
  const hostId = await getHostId();
18608
- const { collectDiagnostics } = await import("../persistent-session-GB3D5OIA.js");
18670
+ const { collectDiagnostics } = await import("../persistent-session-2AWYIUCX.js");
18609
18671
  await api.post("/host/heartbeat", {
18610
18672
  host_id: hostId,
18611
18673
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
@@ -19237,7 +19299,7 @@ async function processClaudePairSessions(agents) {
19237
19299
  killPairSession,
19238
19300
  pairTmuxSession,
19239
19301
  finalizeClaudePairOnboarding
19240
- } = await import("../claude-pair-runtime-KWBCSCZO.js");
19302
+ } = await import("../claude-pair-runtime-PDG74SAT.js");
19241
19303
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
19242
19304
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
19243
19305
  const killed = await killPairSession(pairTmuxSession(pairId));