@integrity-labs/agt-cli 0.28.291 → 0.28.292

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.
@@ -9,6 +9,7 @@ import {
9
9
  atomicWriteFileSync,
10
10
  buildConnectivityProbeDeps,
11
11
  buildProbeEnv,
12
+ classifyEnvIntegrationsDiff,
12
13
  clearPresenceReaperState,
13
14
  clearPresenceReaperStateForKeys,
14
15
  defaultFlagsCachePath,
@@ -38,7 +39,7 @@ import {
38
39
  requireHost,
39
40
  safeWriteJsonAtomic,
40
41
  setConfigHash
41
- } from "../chunk-R3VRYIZJ.js";
42
+ } from "../chunk-PTJHDSJU.js";
42
43
  import {
43
44
  getProjectDir as getProjectDir2,
44
45
  getReadyTasks,
@@ -657,14 +658,27 @@ var PROVISIONING_RELOAD_REASONS = /* @__PURE__ */ new Set([
657
658
  function isProvisioningReloadReason(reason) {
658
659
  return PROVISIONING_RELOAD_REASONS.has(reason);
659
660
  }
661
+ var CREDENTIAL_ROTATION_REASONS = /* @__PURE__ */ new Set([
662
+ "credential-rotation"
663
+ ]);
664
+ function isCredentialRotationReason(reason) {
665
+ return CREDENTIAL_ROTATION_REASONS.has(reason);
666
+ }
667
+ function restartReasonClass(reason) {
668
+ if (isCredentialRotationReason(reason)) return "credential-rotation";
669
+ return isProvisioningReloadReason(reason) ? "provisioning" : "crash";
670
+ }
660
671
  function countByClass(events) {
661
672
  let crash = 0;
662
673
  let provisioning = 0;
674
+ let credentialRotation = 0;
663
675
  for (const e of events) {
664
- if (isProvisioningReloadReason(e.reason)) provisioning += 1;
676
+ const klass = restartReasonClass(e.reason);
677
+ if (klass === "provisioning") provisioning += 1;
678
+ else if (klass === "credential-rotation") credentialRotation += 1;
665
679
  else crash += 1;
666
680
  }
667
- return { crash, provisioning };
681
+ return { crash, provisioning, "credential-rotation": credentialRotation };
668
682
  }
669
683
  var DEFAULT_MAX = 2;
670
684
  var DEFAULT_WINDOW_MS = 6e5;
@@ -738,15 +752,19 @@ var RestartBreaker = class {
738
752
  prior.push({ reason, at });
739
753
  this.events.set(codeName, prior);
740
754
  const crashCount = prior.filter(
741
- (e) => e.at >= at - this.windowMs && !isProvisioningReloadReason(e.reason)
755
+ (e) => e.at >= at - this.windowMs && restartReasonClass(e.reason) === "crash"
742
756
  ).length;
743
757
  const provEvents = prior.filter(
744
758
  (e) => e.at >= at - this.provisioningWindowMs && isProvisioningReloadReason(e.reason)
745
759
  );
760
+ const credRotCount = prior.filter(
761
+ (e) => e.at >= at - this.provisioningWindowMs && isCredentialRotationReason(e.reason)
762
+ ).length;
746
763
  const windowCount = prior.filter((e) => e.at >= at - this.windowMs).length;
747
764
  const classCounts = {
748
765
  crash: crashCount,
749
- provisioning: provEvents.length
766
+ provisioning: provEvents.length,
767
+ "credential-rotation": credRotCount
750
768
  };
751
769
  let trippedClass;
752
770
  let tripEvents;
@@ -754,7 +772,7 @@ var RestartBreaker = class {
754
772
  if (crashCount > this.max) {
755
773
  trippedClass = "crash";
756
774
  tripEvents = prior.filter(
757
- (e) => e.at >= at - this.windowMs && !isProvisioningReloadReason(e.reason)
775
+ (e) => e.at >= at - this.windowMs && restartReasonClass(e.reason) === "crash"
758
776
  );
759
777
  tripWindowMs = this.windowMs;
760
778
  } else if (provEvents.length > this.provisioningMax) {
@@ -6326,7 +6344,14 @@ function restartReasonBindsNewMcp(breakerReason) {
6326
6344
  // above always described it, but the path passed no breakerReason so it never
6327
6345
  // hit this predicate. Including it arms the ENG-6174 respawn verification for
6328
6346
  // the ONE real respawn of an integration add.
6329
- breakerReason === "integration-change";
6347
+ breakerReason === "integration-change" || // ENG-7541: a 'credential-rotation' respawn IS the env-only re-mint path
6348
+ // (ENG-7510), just tagged with a non-tripping breaker class. It must behave
6349
+ // IDENTICALLY to 'hot-reload-mcp' for respawn timing + verification — come
6350
+ // back immediately so the agent picks up the fresh credential, and arm the
6351
+ // ENG-6174 respawn verification (the unchanged MCP set re-binds normally, so
6352
+ // verification passes). The ONLY thing that differs from 'hot-reload-mcp' is
6353
+ // the breaker tally it lands on.
6354
+ breakerReason === "credential-rotation";
6330
6355
  }
6331
6356
  function dashboardRestartBreakerReason(restartReason) {
6332
6357
  return restartReason === "integration-change" ? "integration-change" : void 0;
@@ -6897,7 +6922,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
6897
6922
  var lastVersionCheckAt = 0;
6898
6923
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
6899
6924
  var lastResponsivenessProbeAt = 0;
6900
- var agtCliVersion = true ? "0.28.291" : "dev";
6925
+ var agtCliVersion = true ? "0.28.292" : "dev";
6901
6926
  function resolveBrewPath(execFileSync2) {
6902
6927
  try {
6903
6928
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -9574,6 +9599,9 @@ async function processAgent(agent, agentStates) {
9574
9599
  });
9575
9600
  }
9576
9601
  const respawnVars = envOnlyRespawnVars(changedVars, mcpJsonForReap, CHANNEL_SECRET_ENV_KEYS);
9602
+ const envDiff = classifyEnvIntegrationsDiff(preWriteEnv, postWriteEnv);
9603
+ const rotatedOnlyVars = new Set(envDiff.rotated);
9604
+ const envRespawnReason = respawnVars.length > 0 && respawnVars.every((v) => rotatedOnlyVars.has(v)) ? "credential-rotation" : "hot-reload-mcp";
9577
9605
  const needsRespawn = respawnVars.length > 0 && !intFlap.flapping;
9578
9606
  const names = integrations.map((i) => i.display_name || i.definition_id).join(", ");
9579
9607
  const reconnectNote = affectedServerKeys.length > 0 ? ` The MCP servers that depend on rotating credentials (${affectedServerKeys.join(", ")}) have been signalled to reconnect.` : "";
@@ -9592,10 +9620,11 @@ async function processAgent(agent, agentStates) {
9592
9620
  scheduleSessionRestart(
9593
9621
  agent.code_name,
9594
9622
  0,
9595
- `env-only integration change (${respawnVars.join(", ")})`
9623
+ `env-only integration change (${respawnVars.join(", ")})`,
9624
+ envRespawnReason
9596
9625
  );
9597
9626
  log(
9598
- `[hot-reload] Scheduled respawn for '${agent.code_name}' to apply env-only integration change (no MCP child to reap): ${respawnVars.join(", ")} (ENG-7510)`
9627
+ `[hot-reload] Scheduled respawn for '${agent.code_name}' to apply env-only integration change (no MCP child to reap): ${respawnVars.join(", ")} [reason=${envRespawnReason}] (ENG-7510/ENG-7541)`
9599
9628
  );
9600
9629
  }
9601
9630
  } catch (err) {