@integrity-labs/agt-cli 0.28.663 → 0.28.665

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-Z2CPEN6A.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-SQWO4TKG.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-36KWLDV6.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-XSUQMCIQ.js.map
@@ -55,7 +55,7 @@ import {
55
55
  safeWriteJsonAtomic,
56
56
  setConfigHash,
57
57
  tripClass
58
- } from "../chunk-I7R5DFBQ.js";
58
+ } from "../chunk-FQUJWSWQ.js";
59
59
  import {
60
60
  getProjectDir as getProjectDir2,
61
61
  getReadyTasks,
@@ -111,7 +111,7 @@ import {
111
111
  takeZombieDetection,
112
112
  toOpencodeModel,
113
113
  writeEgressAllowlist
114
- } from "../chunk-ZHLGAOYL.js";
114
+ } from "../chunk-EX5XJEGF.js";
115
115
  import {
116
116
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
117
117
  AnchorSessionClient,
@@ -192,7 +192,7 @@ import {
192
192
  subagentActivityAgeSeconds,
193
193
  sumTranscriptUsageInWindow,
194
194
  transcriptActivityAgeSeconds
195
- } from "../chunk-MRHKXV7D.js";
195
+ } from "../chunk-FYZOD3SS.js";
196
196
  import {
197
197
  reapOrphanChannelMcps
198
198
  } from "../chunk-XWVM4KPK.js";
@@ -10651,7 +10651,7 @@ function stopRealtimeIntegrationContext() {
10651
10651
  integrationContextChannel = null;
10652
10652
  }
10653
10653
  function startRealtimeTokenRotation(config2) {
10654
- const { agentIds, onTokenRotated, onSubscriptionLost, log: log2 } = config2;
10654
+ const { agentIds, onTokenRotated, onSubscriptionLost, onSubscribed, log: log2 } = config2;
10655
10655
  if (agentIds.length === 0) return;
10656
10656
  stopRealtimeTokenRotation();
10657
10657
  const epoch = ++tokenRotationEpoch;
@@ -10677,7 +10677,9 @@ function startRealtimeTokenRotation(config2) {
10677
10677
  if (status === "CLOSED" || status === "CHANNEL_ERROR" || status === "TIMED_OUT") {
10678
10678
  log2(`[realtime] Token rotation channel for agent ${agentId}: ${status}`);
10679
10679
  onSubscriptionLost?.(agentId, status);
10680
+ return;
10680
10681
  }
10682
+ if (status === "SUBSCRIBED") onSubscribed?.(agentId);
10681
10683
  });
10682
10684
  tokenRotationChannels.push(channel);
10683
10685
  }
@@ -11609,7 +11611,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
11609
11611
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
11610
11612
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
11611
11613
  async function channelInboundActivityAgeSecondsFor(codeName) {
11612
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-I3MCPV3Z.js");
11614
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-RWMERSER.js");
11613
11615
  const newest = newestPendingInboundActivityMtimeMs(dirname10(paneLogPath(codeName)));
11614
11616
  if (newest === null) return null;
11615
11617
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -12219,6 +12221,7 @@ function resolveAgentFramework(codeName) {
12219
12221
  function clearAgentCaches(agentId, codeName) {
12220
12222
  const channelCacheMutated = clearAgentState(agentId, codeName);
12221
12223
  agentChannelTokens.delete(codeName);
12224
+ forgetRealtimeRebindState(agentId);
12222
12225
  forgetChannelSyncState(agentId);
12223
12226
  sharedBusyBuckets.reset(codeName);
12224
12227
  stopOpencodeSlackIngest(codeName, log);
@@ -12253,7 +12256,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
12253
12256
  var lastVersionCheckAt = 0;
12254
12257
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
12255
12258
  var lastResponsivenessProbeAt = 0;
12256
- var agtCliVersion = true ? "0.28.663" : "dev";
12259
+ var agtCliVersion = true ? "0.28.665" : "dev";
12257
12260
  function resolveBrewPath(execFileSync3) {
12258
12261
  try {
12259
12262
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -13617,7 +13620,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
13617
13620
  if (codeNames.length === 0) return;
13618
13621
  void (async () => {
13619
13622
  try {
13620
- const { collectDiagnostics } = await import("../persistent-session-Z2CPEN6A.js");
13623
+ const { collectDiagnostics } = await import("../persistent-session-SQWO4TKG.js");
13621
13624
  await api.post("/host/heartbeat", {
13622
13625
  host_id: hostId,
13623
13626
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -13733,7 +13736,7 @@ async function pollCycleInner() {
13733
13736
  }
13734
13737
  try {
13735
13738
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
13736
- const { collectDiagnostics } = await import("../persistent-session-Z2CPEN6A.js");
13739
+ const { collectDiagnostics } = await import("../persistent-session-SQWO4TKG.js");
13737
13740
  const diagCodeNames = [...agentState.persistentSessionAgents];
13738
13741
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor) : void 0;
13739
13742
  let tailscaleHostname;
@@ -13820,6 +13823,19 @@ async function pollCycleInner() {
13820
13823
  // close a resolved alert on the edge. Omitting it when empty would make
13821
13824
  // "recovered" and "this CLI is too old to report" the same wire value.
13822
13825
  channel_sync_stuck: stuckChannelSyncs(channelSyncFailures, Date.now()),
13826
+ // ENG-9265: agents whose realtime token-rotation subscription has been
13827
+ // failing to bind for longer than the stuck threshold. Same contract as
13828
+ // the field above — ALWAYS sent, including as an empty array, because
13829
+ // that is what lets the API close a resolved alert on the edge. An
13830
+ // absent field means an older CLI that cannot report; an empty one is
13831
+ // the affirmative all-clear.
13832
+ //
13833
+ // This is the ask that matters most on the ticket. A manager churning
13834
+ // subscriptions every tick for half an hour produced NO signal of its
13835
+ // own; the only alert was the host going silent, by which point four
13836
+ // customer agents had been dark for three minutes. Bounding the retry
13837
+ // without this would fix the CPU and leave the blindness.
13838
+ realtime_rebind_stuck: stuckRealtimeRebinds(realtimeRebindFailures, Date.now()),
13823
13839
  // ENG-6251: capability advertisement — the flags schema version this
13824
13840
  // CLI compiled with, so the admin UI can show flip reach across a
13825
13841
  // mixed-CLI fleet (an older CLI sends an older fingerprint).
@@ -13872,7 +13888,7 @@ async function pollCycleInner() {
13872
13888
  collectPanelessActivityProbes,
13873
13889
  getResponsivenessIntervalMs,
13874
13890
  occupancyQualificationClassifications
13875
- } = await import("../responsiveness-probe-I3MCPV3Z.js");
13891
+ } = await import("../responsiveness-probe-RWMERSER.js");
13876
13892
  const probeIntervalMs = getResponsivenessIntervalMs();
13877
13893
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
13878
13894
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -13982,7 +13998,7 @@ async function pollCycleInner() {
13982
13998
  collectResponsivenessProbes,
13983
13999
  livePendingInboundOldestAgeSeconds,
13984
14000
  parkPendingInbound
13985
- } = await import("../responsiveness-probe-I3MCPV3Z.js");
14001
+ } = await import("../responsiveness-probe-RWMERSER.js");
13986
14002
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
13987
14003
  const wedgeNow = /* @__PURE__ */ new Date();
13988
14004
  const liveAgents = agentState.persistentSessionAgents;
@@ -14138,7 +14154,7 @@ async function pollCycleInner() {
14138
14154
  }
14139
14155
  try {
14140
14156
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-JA437JIB.js");
14141
- const { probeSessionAuth } = await import("../session-auth-dead-XHOOI7MT.js");
14157
+ const { probeSessionAuth } = await import("../session-auth-dead-OOWR5BPI.js");
14142
14158
  const observations = [];
14143
14159
  const pendingCacheCommits = [];
14144
14160
  const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
@@ -17643,6 +17659,69 @@ var realtimeStarted = false;
17643
17659
  var realtimeDriftStarted = false;
17644
17660
  var realtimeKanbanStarted = false;
17645
17661
  var subscribedIntegrationContextAgentIds = /* @__PURE__ */ new Set();
17662
+ var realtimeRebindFailures = /* @__PURE__ */ new Map();
17663
+ var REALTIME_REBIND_FREE_ATTEMPTS = 2;
17664
+ var REALTIME_REBIND_MAX_BACKOFF_MS = 5 * 6e4;
17665
+ var REALTIME_REBIND_STUCK_AFTER_MS = 5 * 6e4;
17666
+ var REALTIME_REBIND_IN_FLIGHT_GRACE_MS = 15e3;
17667
+ function realtimeRebindBackoffMs(attempts) {
17668
+ if (attempts <= REALTIME_REBIND_FREE_ATTEMPTS) return 0;
17669
+ const step = attempts - REALTIME_REBIND_FREE_ATTEMPTS;
17670
+ return Math.min(1e4 * 2 ** (step - 1), REALTIME_REBIND_MAX_BACKOFF_MS);
17671
+ }
17672
+ function recordRealtimeRebindFailure(failures, agentId, status, now) {
17673
+ const prior = failures.get(agentId);
17674
+ const attempts = (prior?.attempts ?? 0) + 1;
17675
+ const next = {
17676
+ attempts,
17677
+ since: prior?.since ?? now,
17678
+ lastStatus: status,
17679
+ loggedAtAttempt: prior?.loggedAtAttempt ?? 0,
17680
+ nextAttemptAt: now + realtimeRebindBackoffMs(attempts)
17681
+ };
17682
+ failures.set(agentId, next);
17683
+ return next;
17684
+ }
17685
+ function realtimeRebindDue(failures, now) {
17686
+ for (const state8 of failures.values()) if (now >= state8.nextAttemptAt) return true;
17687
+ return false;
17688
+ }
17689
+ function stuckRealtimeRebinds(failures, now, thresholdMs = REALTIME_REBIND_STUCK_AFTER_MS) {
17690
+ const out = [];
17691
+ for (const [agentId, state8] of failures) {
17692
+ const stuckForMs = now - state8.since;
17693
+ if (stuckForMs < thresholdMs) continue;
17694
+ out.push({
17695
+ agent_id: agentId,
17696
+ attempts: state8.attempts,
17697
+ stuck_for_seconds: Math.floor(stuckForMs / 1e3),
17698
+ status: state8.lastStatus
17699
+ });
17700
+ }
17701
+ out.sort((a, b) => b.stuck_for_seconds - a.stuck_for_seconds);
17702
+ return out;
17703
+ }
17704
+ function forgetRealtimeRebindState(agentId) {
17705
+ realtimeRebindFailures.delete(agentId);
17706
+ }
17707
+ function pruneRealtimeRebindState(failures, liveAgentIds) {
17708
+ const live = liveAgentIds instanceof Set ? liveAgentIds : new Set(liveAgentIds);
17709
+ let dropped = 0;
17710
+ for (const agentId of [...failures.keys()]) {
17711
+ if (!live.has(agentId)) {
17712
+ failures.delete(agentId);
17713
+ dropped++;
17714
+ }
17715
+ }
17716
+ return dropped;
17717
+ }
17718
+ function holdRealtimeRebindInFlight(failures, agentIds, now, graceMs = REALTIME_REBIND_IN_FLIGHT_GRACE_MS) {
17719
+ const until = now + graceMs;
17720
+ for (const agentId of agentIds) {
17721
+ const state8 = failures.get(agentId);
17722
+ if (state8) state8.nextAttemptAt = Math.max(state8.nextAttemptAt, until);
17723
+ }
17724
+ }
17646
17725
  var realtimeAssignStarted = false;
17647
17726
  var realtimeConfigStarted = false;
17648
17727
  var realtimeSubscribedAgentIds = /* @__PURE__ */ new Set();
@@ -17812,7 +17891,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
17812
17891
  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}`));
17813
17892
  void (async () => {
17814
17893
  try {
17815
- const { collectDiagnostics } = await import("../persistent-session-Z2CPEN6A.js");
17894
+ const { collectDiagnostics } = await import("../persistent-session-SQWO4TKG.js");
17816
17895
  await api.post("/host/heartbeat", {
17817
17896
  host_id: hostId,
17818
17897
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -17863,7 +17942,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
17863
17942
  }
17864
17943
  try {
17865
17944
  const hostId = await getHostId();
17866
- const { collectDiagnostics } = await import("../persistent-session-Z2CPEN6A.js");
17945
+ const { collectDiagnostics } = await import("../persistent-session-SQWO4TKG.js");
17867
17946
  await api.post("/host/heartbeat", {
17868
17947
  host_id: hostId,
17869
17948
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor)
@@ -18008,6 +18087,12 @@ function activeAgentIdSetsEqual(current, previous) {
18008
18087
  }
18009
18088
  function ensureRealtimeIntegrationContextStarted(agentStates) {
18010
18089
  const activeAgentIds = agentStates.filter((a) => a.status === "active").map((a) => a.agentId);
18090
+ if (realtimeRebindFailures.size > 0) {
18091
+ const dropped = pruneRealtimeRebindState(realtimeRebindFailures, activeAgentIds);
18092
+ if (dropped > 0) {
18093
+ log(`[realtime] Dropped ${dropped} token-rotation rebind streak(s) for no-longer-active agent(s) (ENG-9265)`);
18094
+ }
18095
+ }
18011
18096
  if (activeAgentIds.length === 0) {
18012
18097
  if (subscribedIntegrationContextAgentIds.size > 0) {
18013
18098
  stopRealtimeIntegrationContext();
@@ -18017,6 +18102,9 @@ function ensureRealtimeIntegrationContextStarted(agentStates) {
18017
18102
  }
18018
18103
  return;
18019
18104
  }
18105
+ if (realtimeRebindFailures.size > 0 && realtimeRebindDue(realtimeRebindFailures, Date.now()) && subscribedIntegrationContextAgentIds.size > 0) {
18106
+ subscribedIntegrationContextAgentIds = /* @__PURE__ */ new Set();
18107
+ }
18020
18108
  if (activeAgentIdSetsEqual(activeAgentIds, subscribedIntegrationContextAgentIds)) return;
18021
18109
  const apiKey = process.env["AGT_API_KEY"];
18022
18110
  if (!apiKey) return;
@@ -18027,6 +18115,9 @@ function ensureRealtimeIntegrationContextStarted(agentStates) {
18027
18115
  }
18028
18116
  const targetSet = new Set(activeAgentIds);
18029
18117
  subscribedIntegrationContextAgentIds = targetSet;
18118
+ if (realtimeRebindFailures.size > 0) {
18119
+ holdRealtimeRebindInFlight(realtimeRebindFailures, targetSet, Date.now());
18120
+ }
18030
18121
  void exchangeApiKey(apiKey).then((exchange) => {
18031
18122
  if (subscribedIntegrationContextAgentIds !== targetSet) return;
18032
18123
  if (!exchange.supabaseUrl || !exchange.supabaseAnonKey) {
@@ -18061,9 +18152,31 @@ function ensureRealtimeIntegrationContextStarted(agentStates) {
18061
18152
  `integration token rotated for agent ${agentId} (integration ${event.integration_id}, ${event.definition_id})`
18062
18153
  );
18063
18154
  },
18155
+ onSubscribed: (agentId) => {
18156
+ const ended = realtimeRebindFailures.get(agentId);
18157
+ if (!ended) return;
18158
+ realtimeRebindFailures.delete(agentId);
18159
+ const stuckForSeconds = Math.floor((Date.now() - ended.since) / 1e3);
18160
+ log(
18161
+ `[realtime] Token rotation subscription for agent ${agentId} recovered after ${ended.attempts} failed attempt(s) over ${stuckForSeconds}s (ENG-9265)`
18162
+ );
18163
+ },
18064
18164
  onSubscriptionLost: (agentId, status) => {
18065
- log(`[realtime] Token rotation subscription lost for agent ${agentId} (${status}) \u2014 will rebind next tick`);
18066
- subscribedIntegrationContextAgentIds = /* @__PURE__ */ new Set();
18165
+ const state8 = recordRealtimeRebindFailure(
18166
+ realtimeRebindFailures,
18167
+ agentId,
18168
+ status,
18169
+ Date.now()
18170
+ );
18171
+ const waitMs = realtimeRebindBackoffMs(state8.attempts);
18172
+ if (state8.attempts === 1 || state8.attempts > state8.loggedAtAttempt) {
18173
+ state8.loggedAtAttempt = state8.attempts;
18174
+ const stuckForSeconds = Math.floor((Date.now() - state8.since) / 1e3);
18175
+ log(
18176
+ `[realtime] Token rotation subscription lost for agent ${agentId} (${status}) \u2014 attempt ${state8.attempts}, stuck ${stuckForSeconds}s, next rebind in ${Math.round(waitMs / 1e3)}s (ENG-9265)`
18177
+ );
18178
+ }
18179
+ if (waitMs === 0) subscribedIntegrationContextAgentIds = /* @__PURE__ */ new Set();
18067
18180
  },
18068
18181
  log
18069
18182
  });
@@ -18460,7 +18573,7 @@ async function processClaudePairSessions(agents) {
18460
18573
  killPairSession,
18461
18574
  pairTmuxSession,
18462
18575
  finalizeClaudePairOnboarding
18463
- } = await import("../claude-pair-runtime-36KWLDV6.js");
18576
+ } = await import("../claude-pair-runtime-XSUQMCIQ.js");
18464
18577
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
18465
18578
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
18466
18579
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -19432,6 +19545,10 @@ export {
19432
19545
  DAY_ROLLOVER_FORCE_GRACE_MIN,
19433
19546
  DAY_ROLLOVER_INBOUND_DEFER_MAX_MIN,
19434
19547
  DAY_ROLLOVER_INBOUND_GRACE_SEC,
19548
+ REALTIME_REBIND_FREE_ATTEMPTS,
19549
+ REALTIME_REBIND_IN_FLIGHT_GRACE_MS,
19550
+ REALTIME_REBIND_MAX_BACKOFF_MS,
19551
+ REALTIME_REBIND_STUCK_AFTER_MS,
19435
19552
  UntrustworthyToolkitResponseError,
19436
19553
  applyRestartAcks,
19437
19554
  cancelKanbanNoticeOnDrain,
@@ -19451,7 +19568,9 @@ export {
19451
19568
  extractCharterTelegramPeers,
19452
19569
  fetchManagedToolkits,
19453
19570
  forgetChannelSyncState,
19571
+ forgetRealtimeRebindState,
19454
19572
  hasRevokedResiduals,
19573
+ holdRealtimeRebindInFlight,
19455
19574
  inboundHoldMinutes,
19456
19575
  isOlderSemverTuple,
19457
19576
  isPrereleaseVersion,
@@ -19459,7 +19578,11 @@ export {
19459
19578
  maybeInjectKanbanCheck,
19460
19579
  maybeProbeClaudeRuntimeAuth,
19461
19580
  maybeUpgradeClaudeCode,
19581
+ pruneRealtimeRebindState,
19582
+ realtimeRebindBackoffMs,
19583
+ realtimeRebindDue,
19462
19584
  recordChannelSyncFailure,
19585
+ recordRealtimeRebindFailure,
19463
19586
  refreshSkillsIndexInClaudeMd,
19464
19587
  reorderRestartedFirst,
19465
19588
  resolveManagedMcpServerId,
@@ -19474,6 +19597,7 @@ export {
19474
19597
  startManager,
19475
19598
  stopManager,
19476
19599
  stuckChannelSyncs,
19600
+ stuckRealtimeRebinds,
19477
19601
  supersededRuntimeImageIds
19478
19602
  };
19479
19603
  //# sourceMappingURL=manager-worker.js.map