@integrity-labs/agt-cli 0.28.1068 → 0.28.1069

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.
@@ -266,7 +266,7 @@ async function spawnPairSession(session) {
266
266
  return { ok: true };
267
267
  } catch {
268
268
  }
269
- const { resolveClaudeBinary } = await import("./persistent-session-VRAVB743.js");
269
+ const { resolveClaudeBinary } = await import("./persistent-session-52A2G7D7.js");
270
270
  const claudeBin = resolveClaudeBinary();
271
271
  const pairEnv = {
272
272
  ...process.env,
@@ -734,4 +734,4 @@ export {
734
734
  startClaudePair,
735
735
  submitClaudePairCode
736
736
  };
737
- //# sourceMappingURL=claude-pair-runtime-4BISLPPZ.js.map
737
+ //# sourceMappingURL=claude-pair-runtime-Z7SMBMUG.js.map
@@ -67,7 +67,7 @@ import {
67
67
  safeWriteJsonAtomic,
68
68
  setConfigHash,
69
69
  tripClass
70
- } from "../chunk-WLB2E3PO.js";
70
+ } from "../chunk-CO2ODT4I.js";
71
71
  import {
72
72
  getProjectDir as getProjectDir2,
73
73
  getReadyTasks,
@@ -154,7 +154,7 @@ import {
154
154
  webFetchBaselineValue,
155
155
  webFetchRestartNeeded,
156
156
  writeEgressAllowlist
157
- } from "../chunk-65F44JJJ.js";
157
+ } from "../chunk-FHUYRSCF.js";
158
158
  import {
159
159
  ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
160
160
  AnchorSessionClient,
@@ -309,7 +309,7 @@ function defaultUnique() {
309
309
  // src/lib/manager-worker.ts
310
310
  import { execFileSync as syncExecFile } from "child_process";
311
311
  import { join as join43, dirname as dirname11, delimiter as pathDelimiter } from "path";
312
- import { homedir as homedir17 } from "os";
312
+ import { homedir as homedir17, platform as platform3 } from "os";
313
313
  import { fileURLToPath as fileURLToPath2 } from "url";
314
314
 
315
315
  // ../../packages/core/dist/provisioning/channel-policy-env.js
@@ -3292,6 +3292,24 @@ async function maybePollHostUsage(deps) {
3292
3292
  }
3293
3293
  }
3294
3294
 
3295
+ // src/lib/claude-host-args.ts
3296
+ var HOST_CLAUDE_RETENTION_SETTINGS = JSON.stringify({ cleanupPeriodDays: 3650 });
3297
+ function hostClaudeOneShotArgs(emptyMcpConfigPath) {
3298
+ return [
3299
+ // No project config, no MCP, no tools: these exercise the model or auth only.
3300
+ "--mcp-config",
3301
+ emptyMcpConfigPath,
3302
+ "--strict-mcp-config",
3303
+ "--permission-mode",
3304
+ "auto",
3305
+ "--allowedTools",
3306
+ "",
3307
+ // ENG-11277: never age anything out of the shared ~/.claude from here.
3308
+ "--settings",
3309
+ HOST_CLAUDE_RETENTION_SETTINGS
3310
+ ];
3311
+ }
3312
+
3295
3313
  // src/lib/claude-account-fingerprint.ts
3296
3314
  import { createHash as createHash6 } from "crypto";
3297
3315
  import { readFile as readFile3, readdir as readdir3 } from "fs/promises";
@@ -14123,7 +14141,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
14123
14141
  var dayRolloverInboundHold = /* @__PURE__ */ new Map();
14124
14142
  var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
14125
14143
  async function channelInboundActivityAgeSecondsFor(codeName) {
14126
- const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-QTYKXBH7.js");
14144
+ const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-SJCP4V4X.js");
14127
14145
  const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
14128
14146
  if (newest === null) return null;
14129
14147
  return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
@@ -14144,6 +14162,11 @@ function inboundHeldMinutesFor(codeName) {
14144
14162
  }
14145
14163
  var consecutiveWedgeCycles = /* @__PURE__ */ new Map();
14146
14164
  var wedgeExemptionLogged = /* @__PURE__ */ new Set();
14165
+ var transcriptMountStreak = /* @__PURE__ */ new Map();
14166
+ var transcriptMountRestarts = /* @__PURE__ */ new Map();
14167
+ var transcriptMountReported = /* @__PURE__ */ new Set();
14168
+ var containerPidCache = /* @__PURE__ */ new Map();
14169
+ var transcriptMountEscalatedAt = /* @__PURE__ */ new Map();
14147
14170
  var paneFatalStreak = /* @__PURE__ */ new Map();
14148
14171
  var paneFatalRestarts = /* @__PURE__ */ new Map();
14149
14172
  var paneFatalReported = /* @__PURE__ */ new Set();
@@ -14875,7 +14898,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
14875
14898
  var lastVersionCheckAt = 0;
14876
14899
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
14877
14900
  var lastResponsivenessProbeAt = 0;
14878
- var agtCliVersion = true ? "0.28.1068" : "dev";
14901
+ var agtCliVersion = true ? "0.28.1069" : "dev";
14879
14902
  function resolveBrewPath(execFileSync3) {
14880
14903
  try {
14881
14904
  const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -15869,13 +15892,7 @@ async function runClaudeRuntimeAuthProbe() {
15869
15892
  "text",
15870
15893
  // Same isolation as conversation-eval: no project config, no MCP, no tools.
15871
15894
  // The probe must exercise AUTH and nothing else.
15872
- "--mcp-config",
15873
- emptyMcp,
15874
- "--strict-mcp-config",
15875
- "--permission-mode",
15876
- "auto",
15877
- "--allowedTools",
15878
- ""
15895
+ ...hostClaudeOneShotArgs(emptyMcp)
15879
15896
  ];
15880
15897
  try {
15881
15898
  const { stdout, stderr } = await execFilePromiseLong(resolveClaudeBinary(), args, {
@@ -15910,13 +15927,7 @@ async function runHostUsageCommand() {
15910
15927
  const emptyMcp = ensureEvalEmptyMcpConfig();
15911
15928
  const args = [
15912
15929
  ...USAGE_COMMAND_ARGS,
15913
- "--mcp-config",
15914
- emptyMcp,
15915
- "--strict-mcp-config",
15916
- "--permission-mode",
15917
- "auto",
15918
- "--allowedTools",
15919
- ""
15930
+ ...hostClaudeOneShotArgs(emptyMcp)
15920
15931
  ];
15921
15932
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
15922
15933
  cwd: homedir17(),
@@ -15988,13 +15999,7 @@ async function runEvalClaude(prompt, model) {
15988
15999
  "--output-format",
15989
16000
  "text",
15990
16001
  // Isolation: only the empty MCP config, ignore project/user config + no tools.
15991
- "--mcp-config",
15992
- emptyMcp,
15993
- "--strict-mcp-config",
15994
- "--permission-mode",
15995
- "auto",
15996
- "--allowedTools",
15997
- ""
16002
+ ...hostClaudeOneShotArgs(emptyMcp)
15998
16003
  ];
15999
16004
  const { stdout } = await execFilePromiseLong(resolveClaudeBinary(), args, {
16000
16005
  cwd: homedir17(),
@@ -16510,7 +16515,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
16510
16515
  if (codeNames.length === 0) return;
16511
16516
  void (async () => {
16512
16517
  try {
16513
- const { collectDiagnostics } = await import("../persistent-session-VRAVB743.js");
16518
+ const { collectDiagnostics } = await import("../persistent-session-52A2G7D7.js");
16514
16519
  await api.post("/host/heartbeat", {
16515
16520
  host_id: hostId,
16516
16521
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -16652,7 +16657,7 @@ async function pollCycleInner() {
16652
16657
  }
16653
16658
  try {
16654
16659
  const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
16655
- const { collectDiagnostics } = await import("../persistent-session-VRAVB743.js");
16660
+ const { collectDiagnostics } = await import("../persistent-session-52A2G7D7.js");
16656
16661
  const diagCodeNames = [...agentState.persistentSessionAgents];
16657
16662
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
16658
16663
  let tailscaleHostname;
@@ -16860,7 +16865,7 @@ async function pollCycleInner() {
16860
16865
  collectPanelessActivityProbes,
16861
16866
  getResponsivenessIntervalMs,
16862
16867
  occupancyQualificationClassifications
16863
- } = await import("../responsiveness-probe-QTYKXBH7.js");
16868
+ } = await import("../responsiveness-probe-SJCP4V4X.js");
16864
16869
  const probeIntervalMs = getResponsivenessIntervalMs();
16865
16870
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
16866
16871
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -16977,7 +16982,7 @@ async function pollCycleInner() {
16977
16982
  collectResponsivenessProbes,
16978
16983
  livePendingInboundOldestAgeSeconds,
16979
16984
  parkPendingInbound
16980
- } = await import("../responsiveness-probe-QTYKXBH7.js");
16985
+ } = await import("../responsiveness-probe-SJCP4V4X.js");
16981
16986
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
16982
16987
  const wedgeNow = /* @__PURE__ */ new Date();
16983
16988
  const liveAgents = agentState.persistentSessionAgents;
@@ -17253,7 +17258,7 @@ async function pollCycleInner() {
17253
17258
  }
17254
17259
  }
17255
17260
  );
17256
- const { parkPendingInbound } = await import("../responsiveness-probe-QTYKXBH7.js");
17261
+ const { parkPendingInbound } = await import("../responsiveness-probe-SJCP4V4X.js");
17257
17262
  const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
17258
17263
  paneFatalStreak.delete(codeName);
17259
17264
  paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
@@ -17276,6 +17281,177 @@ async function pollCycleInner() {
17276
17281
  } catch (err) {
17277
17282
  log(`[pane-fatal] detection failed: ${err.message}`);
17278
17283
  }
17284
+ try {
17285
+ const {
17286
+ probeContainerTranscriptMounts,
17287
+ decideTranscriptMountAction,
17288
+ resolveTranscriptMountConfig,
17289
+ TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
17290
+ bindSourceEscalations
17291
+ } = await import("../transcript-mount-health-OHE6IVJV.js");
17292
+ const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-52A2G7D7.js");
17293
+ const mountConfig = resolveTranscriptMountConfig();
17294
+ const liveAgents = agentState.persistentSessionAgents;
17295
+ for (const tracked of [
17296
+ ...transcriptMountStreak.keys(),
17297
+ ...transcriptMountRestarts.keys(),
17298
+ ...transcriptMountReported,
17299
+ ...containerPidCache.keys()
17300
+ ]) {
17301
+ if (!liveAgents.has(tracked)) {
17302
+ transcriptMountStreak.delete(tracked);
17303
+ transcriptMountRestarts.delete(tracked);
17304
+ transcriptMountReported.delete(tracked);
17305
+ containerPidCache.delete(tracked);
17306
+ transcriptMountEscalatedAt.delete(`${tracked}:give-up`);
17307
+ transcriptMountEscalatedAt.delete(`${tracked}:layout`);
17308
+ transcriptMountEscalatedAt.delete(`${tracked}:io`);
17309
+ }
17310
+ }
17311
+ const escalateTranscriptMount = (codeName, agentId, cause, action, reason, nowMs) => {
17312
+ const key = `${codeName}:${cause}`;
17313
+ const last = transcriptMountEscalatedAt.get(key);
17314
+ if (last !== void 0 && nowMs - last < TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS) return false;
17315
+ transcriptMountEscalatedAt.set(key, nowMs);
17316
+ if (mountConfig.mode === "enforce") {
17317
+ void reportReaperEvent(agentId, "transcript-mount-reaper", action, reason);
17318
+ }
17319
+ return last === void 0;
17320
+ };
17321
+ if (mountConfig.mode !== "off" && platform3() === "linux") {
17322
+ const mountNowMs = Date.now();
17323
+ const homeDirForBinds = process.env.HOME?.trim() || homedir17();
17324
+ for (const codeName of liveAgents) {
17325
+ if (effectiveIsolationMode(codeName) !== "docker") continue;
17326
+ if (!isSessionHealthy(codeName)) {
17327
+ transcriptMountStreak.delete(codeName);
17328
+ containerPidCache.delete(codeName);
17329
+ continue;
17330
+ }
17331
+ const agentId = agentState.codeNameToAgentId.get(codeName);
17332
+ if (!agentId) continue;
17333
+ let pid = containerPidCache.get(codeName) ?? null;
17334
+ if (pid !== null && !existsSync19(`/proc/${pid}`)) pid = null;
17335
+ if (pid === null) {
17336
+ try {
17337
+ const out = syncExecFile("docker", ["inspect", "-f", "{{.State.Pid}}", `agt-${codeName}`], {
17338
+ stdio: ["ignore", "pipe", "ignore"],
17339
+ timeout: 5e3
17340
+ }).toString().trim();
17341
+ const parsed = Number.parseInt(out, 10);
17342
+ pid = Number.isInteger(parsed) && parsed > 0 ? parsed : null;
17343
+ } catch {
17344
+ pid = null;
17345
+ }
17346
+ if (pid !== null) containerPidCache.set(codeName, pid);
17347
+ }
17348
+ const src = transcriptBindSourcesFor({
17349
+ homeDir: homeDirForBinds,
17350
+ agentId,
17351
+ projectDir: getProjectDir(codeName)
17352
+ });
17353
+ const verdict = probeContainerTranscriptMounts({
17354
+ pid,
17355
+ // Mask (parent) first: an unlinked mask root is the cause even when
17356
+ // the nested slug bind still resolves.
17357
+ binds: [
17358
+ { containerPath: src.projects, hostPath: src.mask },
17359
+ { containerPath: src.own, hostPath: src.own }
17360
+ ],
17361
+ stat: (path) => statSync14(path)
17362
+ });
17363
+ if (verdict.state !== "orphaned") {
17364
+ transcriptMountStreak.delete(codeName);
17365
+ if (verdict.state === "ok") {
17366
+ transcriptMountReported.delete(codeName);
17367
+ transcriptMountEscalatedAt.delete(`${codeName}:give-up`);
17368
+ const { refused } = ensureTranscriptBindSources({
17369
+ homeDir: homeDirForBinds,
17370
+ agentId,
17371
+ projectDir: getProjectDir(codeName)
17372
+ });
17373
+ const escalations = bindSourceEscalations(refused);
17374
+ for (const cause of ["layout", "io"]) {
17375
+ if (!escalations.some((e) => e.cause === cause)) transcriptMountEscalatedAt.delete(`${codeName}:${cause}`);
17376
+ }
17377
+ for (const e of escalations) {
17378
+ if (escalateTranscriptMount(codeName, agentId, e.cause, e.action, e.message, mountNowMs)) {
17379
+ log(`[transcript-mount] bind source ${e.cause} problem for agent=${codeName}: ${e.message}`);
17380
+ }
17381
+ }
17382
+ }
17383
+ continue;
17384
+ }
17385
+ const cycles = (transcriptMountStreak.get(codeName) ?? 0) + 1;
17386
+ transcriptMountStreak.set(codeName, cycles);
17387
+ const history = (transcriptMountRestarts.get(codeName) ?? []).filter(
17388
+ (t) => mountNowMs - t < mountConfig.restartWindowMs
17389
+ );
17390
+ transcriptMountRestarts.set(codeName, history);
17391
+ const action = decideTranscriptMountAction(
17392
+ { verdict, consecutiveCycles: cycles, recentRestartsMs: history, nowMs: mountNowMs },
17393
+ mountConfig
17394
+ );
17395
+ if (action === "none") continue;
17396
+ const detail = `agent=${codeName} path=${verdict.path} reason=${verdict.reason} cycles=${cycles} restartsInWindow=${history.length}`;
17397
+ if (action === "would-restart") {
17398
+ if (!transcriptMountReported.has(codeName)) {
17399
+ transcriptMountReported.add(codeName);
17400
+ log(`[transcript-mount] SHADOW would respawn (container transcript dir orphaned) ${detail}`);
17401
+ }
17402
+ continue;
17403
+ }
17404
+ if (action === "give-up") {
17405
+ if (!transcriptMountReported.has(codeName)) {
17406
+ transcriptMountReported.add(codeName);
17407
+ log(
17408
+ `[transcript-mount] restart budget spent and the transcript dir is orphaned again \u2014 NOT respawning; something on the host keeps removing it ${detail}`
17409
+ );
17410
+ }
17411
+ escalateTranscriptMount(
17412
+ codeName,
17413
+ agentId,
17414
+ "give-up",
17415
+ "blocked",
17416
+ `Container transcript directory ${verdict.path} is orphaned (${verdict.reason}) again after ${history.length} respawn(s) in the window; transcript writes and compaction are failing ENOENT. Stopped auto-restarting: something on the host keeps removing the bind source.`,
17417
+ mountNowMs
17418
+ );
17419
+ continue;
17420
+ }
17421
+ try {
17422
+ stopPersistentSessionAndForgetMcpBaseline(
17423
+ codeName,
17424
+ "transcript-mount-orphaned",
17425
+ void 0,
17426
+ { outcome: "failed", message: `transcript mount orphaned (${verdict.reason})` },
17427
+ {
17428
+ reason: `transcript bind ${verdict.path} orphaned (${verdict.reason}); respawn to re-bind (ENG-11277)`,
17429
+ detail: {
17430
+ mount_path: verdict.path,
17431
+ mount_state: verdict.reason,
17432
+ consecutive_cycles: cycles,
17433
+ restarts_in_window: history.length
17434
+ }
17435
+ }
17436
+ );
17437
+ containerPidCache.delete(codeName);
17438
+ transcriptMountStreak.delete(codeName);
17439
+ transcriptMountRestarts.set(codeName, [...history, mountNowMs]);
17440
+ log(`[transcript-mount] respawning to re-bind orphaned transcript mount ${detail}`);
17441
+ void reportReaperEvent(
17442
+ agentId,
17443
+ "transcript-mount-reaper",
17444
+ "restart",
17445
+ `Container transcript directory ${verdict.path} was ${verdict.reason}; transcript writes and compaction were failing ENOENT. Respawned to re-bind.`
17446
+ );
17447
+ } catch (err) {
17448
+ log(`[transcript-mount] respawn failed for ${codeName}: ${err.message}`);
17449
+ }
17450
+ }
17451
+ }
17452
+ } catch (err) {
17453
+ log(`[transcript-mount] probe failed: ${err.message}`);
17454
+ }
17279
17455
  try {
17280
17456
  const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
17281
17457
  const { probeSessionAuth } = await import("../session-auth-dead-JJPNV3YQ.js");
@@ -21843,7 +22019,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
21843
22019
  try {
21844
22020
  const freshId = rotateSessionForWedge(codeName);
21845
22021
  consecutiveWedgeCycles.delete(codeName);
21846
- const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-QTYKXBH7.js");
22022
+ const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-SJCP4V4X.js");
21847
22023
  const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
21848
22024
  const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
21849
22025
  const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
@@ -21886,7 +22062,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
21886
22062
  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}`));
21887
22063
  void (async () => {
21888
22064
  try {
21889
- const { collectDiagnostics } = await import("../persistent-session-VRAVB743.js");
22065
+ const { collectDiagnostics } = await import("../persistent-session-52A2G7D7.js");
21890
22066
  await api.post("/host/heartbeat", {
21891
22067
  host_id: hostId,
21892
22068
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -21937,7 +22113,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
21937
22113
  }
21938
22114
  try {
21939
22115
  const hostId = await getHostId();
21940
- const { collectDiagnostics } = await import("../persistent-session-VRAVB743.js");
22116
+ const { collectDiagnostics } = await import("../persistent-session-52A2G7D7.js");
21941
22117
  await api.post("/host/heartbeat", {
21942
22118
  host_id: hostId,
21943
22119
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
@@ -22609,7 +22785,7 @@ async function processClaudePairSessions(agents) {
22609
22785
  // cannot take it for itself — by the time it runs, the write it is looking
22610
22786
  // for may already have happened.
22611
22787
  snapshotPairConfig
22612
- } = await import("../claude-pair-runtime-4BISLPPZ.js");
22788
+ } = await import("../claude-pair-runtime-Z7SMBMUG.js");
22613
22789
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
22614
22790
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
22615
22791
  const killed = await killPairSession(pairTmuxSession(pairId));