@integrity-labs/agt-cli 0.28.503 → 0.28.504

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-4PVEGHA5.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-AB4SAH5B.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-JEMJAZPB.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-E3KMHKQQ.js.map
@@ -52,7 +52,7 @@ import {
52
52
  safeWriteJsonAtomic,
53
53
  setConfigHash,
54
54
  tripClass
55
- } from "../chunk-GR375XXG.js";
55
+ } from "../chunk-GXEXHVNW.js";
56
56
  import {
57
57
  getProjectDir as getProjectDir2,
58
58
  getReadyTasks,
@@ -172,7 +172,7 @@ import {
172
172
  toOpencodeModel,
173
173
  transcriptActivityAgeSeconds,
174
174
  writeEgressAllowlist
175
- } from "../chunk-GBSMIV4P.js";
175
+ } from "../chunk-HEUDF73X.js";
176
176
  import {
177
177
  reapOrphanChannelMcps
178
178
  } from "../chunk-XWVM4KPK.js";
@@ -3665,13 +3665,34 @@ function bundleFingerprint(files) {
3665
3665
 
3666
3666
  // src/lib/channel-config-hash.ts
3667
3667
  import { createHash as createHash7 } from "crypto";
3668
+ var DERIVED_PRINCIPAL_ID_LIST_KEYS = [
3669
+ "allowed_users",
3670
+ "diagnostic_chat_ids",
3671
+ "ping_allowed_users",
3672
+ "ping_allowed_chat_ids"
3673
+ ];
3674
+ function normalizeChannelConfigForHash(config2) {
3675
+ if (config2 === null || typeof config2 !== "object" || Array.isArray(config2)) return config2;
3676
+ const src = config2;
3677
+ let normalized = null;
3678
+ for (const key of DERIVED_PRINCIPAL_ID_LIST_KEYS) {
3679
+ const list = src[key];
3680
+ if (!Array.isArray(list)) continue;
3681
+ normalized ??= { ...src };
3682
+ normalized[key] = [...list].sort();
3683
+ }
3684
+ return normalized ?? config2;
3685
+ }
3668
3686
  var CHANNEL_WRITE_VERSION = 9;
3669
3687
  function computeChannelConfigHash(input) {
3670
3688
  return createHash7("sha256").update(
3671
3689
  canonicalJson({
3672
3690
  writeVersion: CHANNEL_WRITE_VERSION,
3673
3691
  cliVersion: input.cliVersion,
3674
- config: input.config,
3692
+ // ENG-8399: value-blind on the server-derived principal id SETS so a
3693
+ // reorder of the same principals can't oscillate this hash into a
3694
+ // false rewrite (and, downstream, a session respawn).
3695
+ config: normalizeChannelConfigForHash(input.config),
3675
3696
  team: input.team,
3676
3697
  peers: input.peers,
3677
3698
  sessionMode: input.sessionMode ?? null,
@@ -8902,7 +8923,7 @@ function hasRevokedResiduals(state7) {
8902
8923
  var pendingSessionRestarts = /* @__PURE__ */ new Map();
8903
8924
  var lastRestartWasExternal = /* @__PURE__ */ new Map();
8904
8925
  var pendingRestartVerifications = /* @__PURE__ */ new Map();
8905
- var restartBreaker = new RestartBreaker();
8926
+ var restartBreaker = new RestartBreaker({ runtimeKey: (codeName) => agentRuntimeKey(codeName) });
8906
8927
  {
8907
8928
  const clamp = restartBreaker.getQuarantineOrderingClamp();
8908
8929
  if (clamp) {
@@ -9015,9 +9036,9 @@ function maybeClearStaleTrip(agent) {
9015
9036
  log(
9016
9037
  `[circuit-breaker] agent=${codeName} cleared STALE trip \u2014 authoritative status=active while a trip was held (age=${Math.round(decision.ageMs / 6e4)}min, trippedAt=${new Date(trip.trippedAt).toISOString()}); the pause this trip caused is no longer in force (ENG-7577)`
9017
9038
  );
9018
- const marker = autoResumeMarkers.get(codeName);
9039
+ const marker = getAutoResumeMarker(codeName);
9019
9040
  const isSelfResume = marker !== void 0 && Date.now() - marker.autoResumedAt < AUTO_RESUME_SELF_WINDOW_MS;
9020
- if (!isSelfResume) autoResumeMarkers.delete(codeName);
9041
+ if (!isSelfResume) deleteAutoResumeMarker(codeName);
9021
9042
  state6 = {
9022
9043
  ...state6,
9023
9044
  circuitBreakerTrips: restartBreaker.serialize(),
@@ -9026,6 +9047,30 @@ function maybeClearStaleTrip(agent) {
9026
9047
  send({ type: "state-update", state: state6 });
9027
9048
  }
9028
9049
  var autoResumeMarkers = /* @__PURE__ */ new Map();
9050
+ function autoResumeMarkerKey(codeName) {
9051
+ return agentRuntimeKey(codeName);
9052
+ }
9053
+ function getAutoResumeMarker(codeName) {
9054
+ const key = autoResumeMarkerKey(codeName);
9055
+ const hit = autoResumeMarkers.get(key);
9056
+ if (hit || key === codeName) return hit;
9057
+ const legacy = autoResumeMarkers.get(codeName);
9058
+ if (!legacy) return void 0;
9059
+ autoResumeMarkers.delete(codeName);
9060
+ autoResumeMarkers.set(key, legacy);
9061
+ return legacy;
9062
+ }
9063
+ function setAutoResumeMarker(codeName, rec) {
9064
+ const key = autoResumeMarkerKey(codeName);
9065
+ if (key !== codeName) autoResumeMarkers.delete(codeName);
9066
+ autoResumeMarkers.set(key, rec);
9067
+ }
9068
+ function deleteAutoResumeMarker(codeName) {
9069
+ const key = autoResumeMarkerKey(codeName);
9070
+ let removed = autoResumeMarkers.delete(key);
9071
+ if (key !== codeName && autoResumeMarkers.delete(codeName)) removed = true;
9072
+ return removed;
9073
+ }
9029
9074
  var autoResumeInFlight = /* @__PURE__ */ new Set();
9030
9075
  var AUTO_RESUME_SELF_WINDOW_MS = 12e4;
9031
9076
  var autoResumeLoggedSkips = /* @__PURE__ */ new Map();
@@ -9046,7 +9091,7 @@ function maybeAutoResume(agent) {
9046
9091
  if (trip && autoResumeStandDowns.has(`${codeName}:${trip.trippedAt}`)) return;
9047
9092
  const decision = decideAutoResume({
9048
9093
  trip,
9049
- marker: autoResumeMarkers.get(codeName),
9094
+ marker: getAutoResumeMarker(codeName),
9050
9095
  config: readAutoResumeConfig(),
9051
9096
  now: Date.now()
9052
9097
  });
@@ -9073,7 +9118,7 @@ function maybeAutoResume(agent) {
9073
9118
  }).then((res) => {
9074
9119
  autoResumeInFlight.delete(codeName);
9075
9120
  if (res.resumed) {
9076
- autoResumeMarkers.set(codeName, { trippedAt, autoResumedAt: Date.now() });
9121
+ setAutoResumeMarker(codeName, { trippedAt, autoResumedAt: Date.now() });
9077
9122
  restartBreaker.clear(codeName);
9078
9123
  reportedTrips.delete(codeName);
9079
9124
  dependencyRecoveryLedger.clear(codeName);
@@ -9150,7 +9195,7 @@ async function maybeResumeReconcile(agent) {
9150
9195
  const mcpPresent = deriveMcpPresent(declaredKeys, givenUpMcpServerKeys(codeName));
9151
9196
  const decision = decideResumeReconcile({
9152
9197
  trip,
9153
- marker: autoResumeMarkers.get(codeName),
9198
+ marker: getAutoResumeMarker(codeName),
9154
9199
  health: { ...serverHealth, mcpPresent },
9155
9200
  config: config2,
9156
9201
  now: Date.now()
@@ -9187,7 +9232,7 @@ async function maybeResumeReconcile(agent) {
9187
9232
  }
9188
9233
  );
9189
9234
  if (res.resumed) {
9190
- autoResumeMarkers.set(codeName, { trippedAt, autoResumedAt: Date.now() });
9235
+ setAutoResumeMarker(codeName, { trippedAt, autoResumedAt: Date.now() });
9191
9236
  restartBreaker.clear(codeName);
9192
9237
  reportedTrips.delete(codeName);
9193
9238
  dependencyRecoveryLedger.clear(codeName);
@@ -9956,7 +10001,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
9956
10001
  var lastVersionCheckAt = 0;
9957
10002
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9958
10003
  var lastResponsivenessProbeAt = 0;
9959
- var agtCliVersion = true ? "0.28.503" : "dev";
10004
+ var agtCliVersion = true ? "0.28.504" : "dev";
9960
10005
  function resolveBrewPath(execFileSync2) {
9961
10006
  try {
9962
10007
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10191,6 +10236,9 @@ async function ensureIsolationImage(imageUri) {
10191
10236
  return;
10192
10237
  }
10193
10238
  log(`[isolation-image] ${localTag} now points at ${imageUri}`);
10239
+ if (shouldReapOnRetag(hostFlagStore().getString("docker-hygiene"))) {
10240
+ await reapSupersededRuntimeImages(imageUri, localTag);
10241
+ }
10194
10242
  isolationImageEnsured.add(imageUri);
10195
10243
  isolationImageRetryAfter.delete(imageUri);
10196
10244
  isolationImageFailureCount.delete(imageUri);
@@ -10198,6 +10246,47 @@ async function ensureIsolationImage(imageUri) {
10198
10246
  isolationImageInFlight.delete(imageUri);
10199
10247
  }
10200
10248
  }
10249
+ function supersededRuntimeImageIds(currentId, repoImageIds) {
10250
+ const cur = currentId.trim();
10251
+ const out = [];
10252
+ const seen = /* @__PURE__ */ new Set();
10253
+ for (const raw of repoImageIds) {
10254
+ const id = raw.trim();
10255
+ if (!id || id === cur || seen.has(id)) continue;
10256
+ seen.add(id);
10257
+ out.push(id);
10258
+ }
10259
+ return out;
10260
+ }
10261
+ function shouldReapOnRetag(mode) {
10262
+ return mode === "reap-superseded" || mode === "full";
10263
+ }
10264
+ async function reapSupersededRuntimeImages(imageUri, localTag) {
10265
+ try {
10266
+ const repo = imageUri.replace(/@sha256:[a-f0-9]+$/i, "").replace(/:[^/:]+$/, "");
10267
+ const idRes = await runAsync("docker", ["image", "inspect", "--format", "{{.Id}}", localTag], { timeout: 15e3 });
10268
+ if (idRes.code !== 0) {
10269
+ log(`[docker-gc] could not resolve ${localTag} id, skipping reap: ${idRes.stderr.trim().slice(0, 160)}`);
10270
+ return;
10271
+ }
10272
+ const currentId = idRes.stdout.trim();
10273
+ const lsRes = await runAsync("docker", ["images", "--no-trunc", "--format", "{{.ID}}", repo], { timeout: 15e3 });
10274
+ if (lsRes.code !== 0) {
10275
+ log(`[docker-gc] could not list ${repo} images, skipping reap: ${lsRes.stderr.trim().slice(0, 160)}`);
10276
+ return;
10277
+ }
10278
+ const targets = supersededRuntimeImageIds(currentId, lsRes.stdout.split("\n"));
10279
+ let reaped = 0;
10280
+ for (const id of targets) {
10281
+ const rm = await runAsync("docker", ["rmi", id], { timeout: 3e4 });
10282
+ if (rm.code === 0) reaped++;
10283
+ else log(`[docker-gc] skip ${id.slice(0, 19)}: ${(rm.stderr || rm.stdout).trim().slice(0, 120)}`);
10284
+ }
10285
+ if (reaped > 0) log(`[docker-gc] reaped ${reaped} superseded ${repo} image(s)`);
10286
+ } catch (err) {
10287
+ log(`[docker-gc] reap failed: ${isolationImageErrDetail(err)}`);
10288
+ }
10289
+ }
10201
10290
  function runAsync(cmd, args, opts) {
10202
10291
  return new Promise((resolve, reject) => {
10203
10292
  import("child_process").then(({ spawn }) => {
@@ -11119,7 +11208,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11119
11208
  if (codeNames.length === 0) return;
11120
11209
  void (async () => {
11121
11210
  try {
11122
- const { collectDiagnostics } = await import("../persistent-session-4PVEGHA5.js");
11211
+ const { collectDiagnostics } = await import("../persistent-session-AB4SAH5B.js");
11123
11212
  await api.post("/host/heartbeat", {
11124
11213
  host_id: hostId,
11125
11214
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11226,7 +11315,7 @@ async function pollCycle() {
11226
11315
  }
11227
11316
  try {
11228
11317
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11229
- const { collectDiagnostics } = await import("../persistent-session-4PVEGHA5.js");
11318
+ const { collectDiagnostics } = await import("../persistent-session-AB4SAH5B.js");
11230
11319
  const diagCodeNames = [...agentState.persistentSessionAgents];
11231
11320
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11232
11321
  let tailscaleHostname;
@@ -11341,7 +11430,7 @@ async function pollCycle() {
11341
11430
  collectResponsivenessProbes,
11342
11431
  collectPanelessActivityProbes,
11343
11432
  getResponsivenessIntervalMs
11344
- } = await import("../responsiveness-probe-PNKFXRVF.js");
11433
+ } = await import("../responsiveness-probe-O4SCSCKC.js");
11345
11434
  const probeIntervalMs = getResponsivenessIntervalMs();
11346
11435
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11347
11436
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11405,7 +11494,7 @@ async function pollCycle() {
11405
11494
  collectResponsivenessProbes,
11406
11495
  livePendingInboundOldestAgeSeconds,
11407
11496
  parkPendingInbound
11408
- } = await import("../responsiveness-probe-PNKFXRVF.js");
11497
+ } = await import("../responsiveness-probe-O4SCSCKC.js");
11409
11498
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11410
11499
  const wedgeNow = /* @__PURE__ */ new Date();
11411
11500
  const liveAgents = agentState.persistentSessionAgents;
@@ -12097,9 +12186,9 @@ async function processAgent(agent, agentStates) {
12097
12186
  log(`[circuit-breaker] Cleared trip for '${agent.code_name}' on operator resume (paused \u2192 active)`);
12098
12187
  }
12099
12188
  if (previousStatus === "paused" && agent.status === "active") {
12100
- const marker = autoResumeMarkers.get(agent.code_name);
12189
+ const marker = getAutoResumeMarker(agent.code_name);
12101
12190
  const isSelfResume = marker !== void 0 && Date.now() - marker.autoResumedAt < AUTO_RESUME_SELF_WINDOW_MS;
12102
- if (!isSelfResume && autoResumeMarkers.delete(agent.code_name)) {
12191
+ if (!isSelfResume && deleteAutoResumeMarker(agent.code_name)) {
12103
12192
  state6 = {
12104
12193
  ...state6,
12105
12194
  circuitBreakerAutoResumes: Object.fromEntries(autoResumeMarkers.entries())
@@ -14897,7 +14986,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
14897
14986
  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}`));
14898
14987
  void (async () => {
14899
14988
  try {
14900
- const { collectDiagnostics } = await import("../persistent-session-4PVEGHA5.js");
14989
+ const { collectDiagnostics } = await import("../persistent-session-AB4SAH5B.js");
14901
14990
  await api.post("/host/heartbeat", {
14902
14991
  host_id: hostId,
14903
14992
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -14947,7 +15036,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
14947
15036
  }
14948
15037
  try {
14949
15038
  const hostId = await getHostId();
14950
- const { collectDiagnostics } = await import("../persistent-session-4PVEGHA5.js");
15039
+ const { collectDiagnostics } = await import("../persistent-session-AB4SAH5B.js");
14951
15040
  await api.post("/host/heartbeat", {
14952
15041
  host_id: hostId,
14953
15042
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15465,7 +15554,7 @@ async function processClaudePairSessions(agents) {
15465
15554
  killPairSession,
15466
15555
  pairTmuxSession,
15467
15556
  finalizeClaudePairOnboarding
15468
- } = await import("../claude-pair-runtime-JEMJAZPB.js");
15557
+ } = await import("../claude-pair-runtime-E3KMHKQQ.js");
15469
15558
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15470
15559
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15471
15560
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -16405,11 +16494,13 @@ export {
16405
16494
  reorderRestartedFirst,
16406
16495
  resolveManagedMcpServerId,
16407
16496
  restartReasonBindsNewMcp,
16497
+ shouldReapOnRetag,
16408
16498
  shouldReportRestartToAudit,
16409
16499
  shouldSkipRevokedCleanup,
16410
16500
  shouldUpdateOnLatest,
16411
16501
  stampClaudeCodeUpgradeMarker,
16412
16502
  startManager,
16413
- stopManager
16503
+ stopManager,
16504
+ supersededRuntimeImageIds
16414
16505
  };
16415
16506
  //# sourceMappingURL=manager-worker.js.map