@integrity-labs/agt-cli 0.28.1145 → 0.28.1147
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.
- package/dist/bin/agt.js +6 -6
- package/dist/{chunk-XAZ4C444.js → chunk-FISAZWZ3.js} +2 -2
- package/dist/{chunk-EZYLIFK2.js → chunk-NBKNLVIB.js} +3 -3
- package/dist/{chunk-IEZQK73G.js → chunk-SF7ZOIKU.js} +10 -6
- package/dist/{chunk-IEZQK73G.js.map → chunk-SF7ZOIKU.js.map} +1 -1
- package/dist/{claude-code-updater-HTDCRIMM.js → chunk-WDC6ZLG5.js} +10 -10
- package/dist/{claude-code-updater-HTDCRIMM.js.map → chunk-WDC6ZLG5.js.map} +1 -1
- package/dist/{chunk-FQD4EIUF.js → chunk-XZ6THC7Q.js} +1 -1
- package/dist/{chunk-FQD4EIUF.js.map → chunk-XZ6THC7Q.js.map} +1 -1
- package/dist/claude-code-updater-SWTQNL3W.js +35 -0
- package/dist/{claude-pair-runtime-VEDZCIJR.js → claude-pair-runtime-4GZOYK4O.js} +2 -2
- package/dist/lib/manager-worker.js +278 -20
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-JKD36BCM.js → persistent-session-JKX5IIHF.js} +4 -4
- package/dist/persistent-session-JKX5IIHF.js.map +1 -0
- package/dist/{responsiveness-probe-GGBDYMEW.js → responsiveness-probe-IWC6K5NQ.js} +4 -4
- package/dist/{session-auth-dead-7AG56OKQ.js → session-auth-dead-U5JSZD5Z.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-XAZ4C444.js.map → chunk-FISAZWZ3.js.map} +0 -0
- /package/dist/{chunk-EZYLIFK2.js.map → chunk-NBKNLVIB.js.map} +0 -0
- /package/dist/{persistent-session-JKD36BCM.js.map → claude-code-updater-SWTQNL3W.js.map} +0 -0
- /package/dist/{claude-pair-runtime-VEDZCIJR.js.map → claude-pair-runtime-4GZOYK4O.js.map} +0 -0
- /package/dist/{responsiveness-probe-GGBDYMEW.js.map → responsiveness-probe-IWC6K5NQ.js.map} +0 -0
- /package/dist/{session-auth-dead-7AG56OKQ.js.map → session-auth-dead-U5JSZD5Z.js.map} +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLAUDE_CODE_SECURITY_FLOOR,
|
|
3
|
+
WELL_KNOWN_CLAUDE_PATHS,
|
|
4
|
+
_resetClaudeCodeUpdaterState,
|
|
5
|
+
compareVersions,
|
|
6
|
+
hostHasLiveAgent,
|
|
7
|
+
isBelowSecurityFloor,
|
|
8
|
+
isConcreteVersion,
|
|
9
|
+
isNativeInstallPath,
|
|
10
|
+
maybeUpdateClaudeCode,
|
|
11
|
+
parseVersion,
|
|
12
|
+
probeClaudeInstalls,
|
|
13
|
+
readsAsNativeInstall,
|
|
14
|
+
shouldRunClaudeCodeUpdater
|
|
15
|
+
} from "./chunk-WDC6ZLG5.js";
|
|
16
|
+
import "./chunk-XWVM4KPK.js";
|
|
17
|
+
import "./chunk-XZ6THC7Q.js";
|
|
18
|
+
import "./chunk-EL5MWGGH.js";
|
|
19
|
+
import "./chunk-DGUM43GV.js";
|
|
20
|
+
export {
|
|
21
|
+
CLAUDE_CODE_SECURITY_FLOOR,
|
|
22
|
+
WELL_KNOWN_CLAUDE_PATHS,
|
|
23
|
+
_resetClaudeCodeUpdaterState,
|
|
24
|
+
compareVersions,
|
|
25
|
+
hostHasLiveAgent,
|
|
26
|
+
isBelowSecurityFloor,
|
|
27
|
+
isConcreteVersion,
|
|
28
|
+
isNativeInstallPath,
|
|
29
|
+
maybeUpdateClaudeCode,
|
|
30
|
+
parseVersion,
|
|
31
|
+
probeClaudeInstalls,
|
|
32
|
+
readsAsNativeInstall,
|
|
33
|
+
shouldRunClaudeCodeUpdater
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=claude-code-updater-SWTQNL3W.js.map
|
|
@@ -269,7 +269,7 @@ async function spawnPairSession(session) {
|
|
|
269
269
|
return { ok: true };
|
|
270
270
|
} catch {
|
|
271
271
|
}
|
|
272
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
272
|
+
const { resolveClaudeBinary } = await import("./persistent-session-JKX5IIHF.js");
|
|
273
273
|
const claudeBin = resolveClaudeBinary();
|
|
274
274
|
const pairEnv = {
|
|
275
275
|
...process.env,
|
|
@@ -739,4 +739,4 @@ export {
|
|
|
739
739
|
startClaudePair,
|
|
740
740
|
submitClaudePairCode
|
|
741
741
|
};
|
|
742
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
742
|
+
//# sourceMappingURL=claude-pair-runtime-4GZOYK4O.js.map
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
TunnelWatcher,
|
|
14
14
|
api,
|
|
15
15
|
atomicWriteFileSync,
|
|
16
|
+
buildClaudeAgentMatcher,
|
|
16
17
|
buildConnectivityProbeDeps,
|
|
17
18
|
buildProbeEnv,
|
|
18
19
|
classifyEnvIntegrationsDiff,
|
|
@@ -76,7 +77,11 @@ import {
|
|
|
76
77
|
setConfigHash,
|
|
77
78
|
shellGuard,
|
|
78
79
|
tripClass
|
|
79
|
-
} from "../chunk-
|
|
80
|
+
} from "../chunk-SF7ZOIKU.js";
|
|
81
|
+
import {
|
|
82
|
+
CLAUDE_CODE_SECURITY_FLOOR,
|
|
83
|
+
compareVersions
|
|
84
|
+
} from "../chunk-WDC6ZLG5.js";
|
|
80
85
|
import {
|
|
81
86
|
getProjectDir as getProjectDir2,
|
|
82
87
|
getReadyTasks,
|
|
@@ -163,7 +168,7 @@ import {
|
|
|
163
168
|
webFetchBaselineValue,
|
|
164
169
|
webFetchRestartNeeded,
|
|
165
170
|
writeEgressAllowlist
|
|
166
|
-
} from "../chunk-
|
|
171
|
+
} from "../chunk-NBKNLVIB.js";
|
|
167
172
|
import {
|
|
168
173
|
isAgentIdle,
|
|
169
174
|
isStaleForToday,
|
|
@@ -172,7 +177,7 @@ import {
|
|
|
172
177
|
sessionTranscriptDir,
|
|
173
178
|
subagentActivityAgeSeconds,
|
|
174
179
|
transcriptActivityAgeSeconds
|
|
175
|
-
} from "../chunk-
|
|
180
|
+
} from "../chunk-FISAZWZ3.js";
|
|
176
181
|
import {
|
|
177
182
|
classifyUnanswerablePane,
|
|
178
183
|
focusedConfirmDialogBlock,
|
|
@@ -182,6 +187,7 @@ import {
|
|
|
182
187
|
simpleTextHash
|
|
183
188
|
} from "../chunk-B6UYVEMD.js";
|
|
184
189
|
import {
|
|
190
|
+
parsePsRows,
|
|
185
191
|
reapOrphanChannelMcps
|
|
186
192
|
} from "../chunk-XWVM4KPK.js";
|
|
187
193
|
import {
|
|
@@ -287,7 +293,7 @@ import {
|
|
|
287
293
|
serializeAccountEnforcementMarker,
|
|
288
294
|
stabiliseResetInstant,
|
|
289
295
|
sumTranscriptUsageInWindow
|
|
290
|
-
} from "../chunk-
|
|
296
|
+
} from "../chunk-XZ6THC7Q.js";
|
|
291
297
|
import {
|
|
292
298
|
CLAUDE_CONFIG_DIR_ENV,
|
|
293
299
|
claudeConfigDirFor,
|
|
@@ -299,7 +305,7 @@ import "../chunk-DGUM43GV.js";
|
|
|
299
305
|
|
|
300
306
|
// src/lib/manager-worker.ts
|
|
301
307
|
import { createHash as createHash20 } from "crypto";
|
|
302
|
-
import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync16, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync13, statSync as statSync14, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4 } from "fs";
|
|
308
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync18, mkdirSync as mkdirSync16, existsSync as existsSync19, rmSync as rmSync8, readdirSync as readdirSync13, statSync as statSync14, unlinkSync as unlinkSync6, renameSync as renameSync11, utimesSync as utimesSync4, readlinkSync as readlinkSync2 } from "fs";
|
|
303
309
|
|
|
304
310
|
// src/lib/atomic-file-replace.ts
|
|
305
311
|
import { copyFileSync, renameSync, unlinkSync } from "fs";
|
|
@@ -562,6 +568,161 @@ function heartbeatHostNodeFields(observation, pin, pinState) {
|
|
|
562
568
|
|
|
563
569
|
// src/lib/manager-worker.ts
|
|
564
570
|
import { execFileSync as syncExecFile } from "child_process";
|
|
571
|
+
|
|
572
|
+
// src/lib/runtime-image-recycle.ts
|
|
573
|
+
var RUNTIME_CLAUDE_CODE_SECURITY_FLOOR = CLAUDE_CODE_SECURITY_FLOOR;
|
|
574
|
+
var RECYCLE_STAGGER_MS = 2 * 6e4;
|
|
575
|
+
var CONTAINER_IMAGE_CACHE_MS = 5 * 6e4;
|
|
576
|
+
var LOCAL_TAG_CACHE_MS = 6e4;
|
|
577
|
+
function isBelowRuntimeFloor(version, floor = RUNTIME_CLAUDE_CODE_SECURITY_FLOOR) {
|
|
578
|
+
if (!version) return false;
|
|
579
|
+
const cmp = compareVersions(version, floor);
|
|
580
|
+
return cmp !== null && cmp < 0;
|
|
581
|
+
}
|
|
582
|
+
function isReplacedExeLink(link) {
|
|
583
|
+
return typeof link === "string" && link.endsWith(" (deleted)");
|
|
584
|
+
}
|
|
585
|
+
function isContainerImageStale(containerImageId, localTagImageId) {
|
|
586
|
+
if (!containerImageId || !localTagImageId) return false;
|
|
587
|
+
return containerImageId.trim() !== localTagImageId.trim();
|
|
588
|
+
}
|
|
589
|
+
function decideImageRecycleAction(i) {
|
|
590
|
+
if (!i.stale || !i.sessionHealthy) return "none";
|
|
591
|
+
if (!i.inWindow && !i.belowFloor) return "defer-window";
|
|
592
|
+
let verdict;
|
|
593
|
+
if (i.idle) {
|
|
594
|
+
verdict = "recycle";
|
|
595
|
+
} else if (i.belowFloor && i.belowFloorBusyForMs >= i.deadlineMs) {
|
|
596
|
+
const inboundFresh = i.recentInboundAgeSec !== null && i.recentInboundAgeSec < i.inboundGraceSec;
|
|
597
|
+
if (inboundFresh && i.inboundHeldMin < i.inboundHoldMaxMin) return "defer-inbound";
|
|
598
|
+
verdict = "recycle-deadline";
|
|
599
|
+
} else {
|
|
600
|
+
return "defer-busy";
|
|
601
|
+
}
|
|
602
|
+
if (i.sinceLastHostRecycleMs !== null && i.sinceLastHostRecycleMs < i.staggerMs) return "defer-stagger";
|
|
603
|
+
if (!i.deviceStateReady) return "defer-device-state";
|
|
604
|
+
return verdict;
|
|
605
|
+
}
|
|
606
|
+
var belowFloorBusySince = /* @__PURE__ */ new Map();
|
|
607
|
+
var inboundHeldSince = /* @__PURE__ */ new Map();
|
|
608
|
+
var containerImageCache = /* @__PURE__ */ new Map();
|
|
609
|
+
var localTagCache = null;
|
|
610
|
+
var hostSessionCache = /* @__PURE__ */ new Map();
|
|
611
|
+
var lastHostRecycleAt = null;
|
|
612
|
+
var lastLoggedDecision = /* @__PURE__ */ new Map();
|
|
613
|
+
function containerImageIdFor(codeName, io) {
|
|
614
|
+
const now = io.now();
|
|
615
|
+
const hit = containerImageCache.get(codeName);
|
|
616
|
+
if (hit && now - hit.at < CONTAINER_IMAGE_CACHE_MS) return hit.imageId;
|
|
617
|
+
const imageId = io.inspectContainerImage(codeName);
|
|
618
|
+
containerImageCache.set(codeName, { at: now, imageId });
|
|
619
|
+
return imageId;
|
|
620
|
+
}
|
|
621
|
+
function hostSessionStateFor(codeName, io) {
|
|
622
|
+
const now = io.now();
|
|
623
|
+
const hit = hostSessionCache.get(codeName);
|
|
624
|
+
if (hit && now - hit.at < CONTAINER_IMAGE_CACHE_MS) return hit;
|
|
625
|
+
const probe = io.hostSessionBinary ? io.hostSessionBinary(codeName) : null;
|
|
626
|
+
const replaced = probe ? isReplacedExeLink(probe.exeLink) : false;
|
|
627
|
+
let version = null;
|
|
628
|
+
if (probe && replaced && io.runningBinaryVersion) {
|
|
629
|
+
const raw = io.runningBinaryVersion(probe.pid);
|
|
630
|
+
version = raw ? raw.match(/\d+\.\d+\.\d+[A-Za-z0-9.+-]*/)?.[0] ?? null : null;
|
|
631
|
+
}
|
|
632
|
+
const state10 = { at: now, pid: probe?.pid ?? null, replaced, version };
|
|
633
|
+
hostSessionCache.set(codeName, state10);
|
|
634
|
+
return state10;
|
|
635
|
+
}
|
|
636
|
+
function localTagImageIdFor(tag, io) {
|
|
637
|
+
const now = io.now();
|
|
638
|
+
if (localTagCache && localTagCache.tag === tag && now - localTagCache.at < LOCAL_TAG_CACHE_MS) {
|
|
639
|
+
return localTagCache.imageId;
|
|
640
|
+
}
|
|
641
|
+
const imageId = io.inspectTagImage(tag);
|
|
642
|
+
localTagCache = { at: now, tag, imageId };
|
|
643
|
+
return imageId;
|
|
644
|
+
}
|
|
645
|
+
function evaluateImageRecycle(args, io) {
|
|
646
|
+
const { codeName } = args;
|
|
647
|
+
const now = io.now();
|
|
648
|
+
if (!args.sessionHealthy) {
|
|
649
|
+
clearEpisode(codeName);
|
|
650
|
+
return "none";
|
|
651
|
+
}
|
|
652
|
+
const mode = args.mode ?? "container";
|
|
653
|
+
let stale;
|
|
654
|
+
let runningVersion;
|
|
655
|
+
let describe;
|
|
656
|
+
if (mode === "host") {
|
|
657
|
+
const host = hostSessionStateFor(codeName, io);
|
|
658
|
+
stale = host.replaced;
|
|
659
|
+
runningVersion = host.version;
|
|
660
|
+
describe = `host session pid ${host.pid ?? "unknown"} runs a replaced claude binary (running ${host.version ?? "unknown"})`;
|
|
661
|
+
} else {
|
|
662
|
+
const containerImage = containerImageIdFor(codeName, io);
|
|
663
|
+
const localImage = localTagImageIdFor(args.imageTag, io);
|
|
664
|
+
stale = isContainerImageStale(containerImage, localImage);
|
|
665
|
+
runningVersion = args.runtimeClaudeVersion;
|
|
666
|
+
const short = (id) => id ? id.replace(/^sha256:/, "").slice(0, 12) : "unknown";
|
|
667
|
+
describe = `runs image ${short(containerImage)}, ${args.imageTag} is ${short(localImage)}`;
|
|
668
|
+
}
|
|
669
|
+
if (!stale) {
|
|
670
|
+
clearEpisode(codeName);
|
|
671
|
+
return "none";
|
|
672
|
+
}
|
|
673
|
+
const belowFloor = isBelowRuntimeFloor(runningVersion, args.floor);
|
|
674
|
+
if (belowFloor && !args.idle) {
|
|
675
|
+
if (!belowFloorBusySince.has(codeName)) belowFloorBusySince.set(codeName, now);
|
|
676
|
+
} else {
|
|
677
|
+
belowFloorBusySince.delete(codeName);
|
|
678
|
+
}
|
|
679
|
+
const busySince = belowFloorBusySince.get(codeName);
|
|
680
|
+
const heldSince = inboundHeldSince.get(codeName);
|
|
681
|
+
const base = {
|
|
682
|
+
stale,
|
|
683
|
+
sessionHealthy: args.sessionHealthy,
|
|
684
|
+
inWindow: args.inWindow,
|
|
685
|
+
belowFloor,
|
|
686
|
+
idle: args.idle,
|
|
687
|
+
belowFloorBusyForMs: busySince === void 0 ? 0 : now - busySince,
|
|
688
|
+
deadlineMs: args.deadlineMs,
|
|
689
|
+
recentInboundAgeSec: args.recentInboundAgeSec,
|
|
690
|
+
inboundGraceSec: args.inboundGraceSec,
|
|
691
|
+
inboundHeldMin: heldSince === void 0 ? 0 : (now - heldSince) / 6e4,
|
|
692
|
+
inboundHoldMaxMin: args.inboundHoldMaxMin,
|
|
693
|
+
sinceLastHostRecycleMs: lastHostRecycleAt === null ? null : now - lastHostRecycleAt,
|
|
694
|
+
staggerMs: RECYCLE_STAGGER_MS,
|
|
695
|
+
deviceStateReady: true
|
|
696
|
+
};
|
|
697
|
+
let decision = decideImageRecycleAction(base);
|
|
698
|
+
if ((decision === "recycle" || decision === "recycle-deadline") && !args.deviceStateReady()) {
|
|
699
|
+
decision = decideImageRecycleAction({ ...base, deviceStateReady: false });
|
|
700
|
+
}
|
|
701
|
+
if (decision === "defer-inbound") {
|
|
702
|
+
if (!inboundHeldSince.has(codeName)) inboundHeldSince.set(codeName, now);
|
|
703
|
+
} else {
|
|
704
|
+
inboundHeldSince.delete(codeName);
|
|
705
|
+
}
|
|
706
|
+
if (lastLoggedDecision.get(codeName) !== decision) {
|
|
707
|
+
lastLoggedDecision.set(codeName, decision);
|
|
708
|
+
const floorNote = belowFloor ? ` running Claude Code ${runningVersion} is below the security floor ${args.floor ?? RUNTIME_CLAUDE_CODE_SECURITY_FLOOR};` : "";
|
|
709
|
+
io.log(`[runtime-image-recycle] '${codeName}' ${describe};${floorNote} decision=${decision}`);
|
|
710
|
+
}
|
|
711
|
+
return decision;
|
|
712
|
+
}
|
|
713
|
+
function noteRecycled(codeName, io) {
|
|
714
|
+
lastHostRecycleAt = io.now();
|
|
715
|
+
clearEpisode(codeName);
|
|
716
|
+
containerImageCache.delete(codeName);
|
|
717
|
+
hostSessionCache.delete(codeName);
|
|
718
|
+
}
|
|
719
|
+
function clearEpisode(codeName) {
|
|
720
|
+
belowFloorBusySince.delete(codeName);
|
|
721
|
+
inboundHeldSince.delete(codeName);
|
|
722
|
+
lastLoggedDecision.delete(codeName);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// src/lib/manager-worker.ts
|
|
565
726
|
import { join as join43, dirname as dirname11, delimiter as pathDelimiter } from "path";
|
|
566
727
|
import { homedir as homedir17, hostname, platform as platform3 } from "os";
|
|
567
728
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
@@ -14730,7 +14891,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
14730
14891
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
14731
14892
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
14732
14893
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
14733
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
14894
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-IWC6K5NQ.js");
|
|
14734
14895
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
14735
14896
|
if (newest === null) return null;
|
|
14736
14897
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -15488,7 +15649,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
15488
15649
|
var lastVersionCheckAt = 0;
|
|
15489
15650
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
15490
15651
|
var lastResponsivenessProbeAt = 0;
|
|
15491
|
-
var agtCliVersion = true ? "0.28.
|
|
15652
|
+
var agtCliVersion = true ? "0.28.1147" : "dev";
|
|
15492
15653
|
function resolveBrewPath(execFileSync3) {
|
|
15493
15654
|
try {
|
|
15494
15655
|
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -15630,6 +15791,61 @@ async function ensureToolkitCliInner(toolkitSlug) {
|
|
|
15630
15791
|
}
|
|
15631
15792
|
}
|
|
15632
15793
|
var isolationImageEnsured = /* @__PURE__ */ new Set();
|
|
15794
|
+
var runtimeImageRecycleIo = {
|
|
15795
|
+
now: () => Date.now(),
|
|
15796
|
+
inspectContainerImage: (codeName) => {
|
|
15797
|
+
try {
|
|
15798
|
+
return syncExecFile("docker", ["inspect", "--format", "{{.Image}}", `agt-${codeName}`], {
|
|
15799
|
+
timeout: 5e3,
|
|
15800
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15801
|
+
}).toString().trim() || null;
|
|
15802
|
+
} catch {
|
|
15803
|
+
return null;
|
|
15804
|
+
}
|
|
15805
|
+
},
|
|
15806
|
+
inspectTagImage: (tag) => {
|
|
15807
|
+
try {
|
|
15808
|
+
return syncExecFile("docker", ["image", "inspect", "--format", "{{.Id}}", tag], {
|
|
15809
|
+
timeout: 5e3,
|
|
15810
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15811
|
+
}).toString().trim() || null;
|
|
15812
|
+
} catch {
|
|
15813
|
+
return null;
|
|
15814
|
+
}
|
|
15815
|
+
},
|
|
15816
|
+
// Non-isolated sessions: find `claude --name agt-<code>` (not the docker
|
|
15817
|
+
// wrapper) and read its /proc exe link. Linux-only by nature; anywhere /proc
|
|
15818
|
+
// is absent the link read fails, the session reads as current, and nothing
|
|
15819
|
+
// recycles.
|
|
15820
|
+
hostSessionBinary: (codeName) => {
|
|
15821
|
+
try {
|
|
15822
|
+
const matcher = buildClaudeAgentMatcher(codeName);
|
|
15823
|
+
const ps = syncExecFile("ps", ["-eo", "pid,ppid,args"], { timeout: 5e3, maxBuffer: 16 * 1024 * 1024 }).toString();
|
|
15824
|
+
const row = parsePsRows(ps).find((r) => matcher.test(r.args) && !/\bdocker\b/.test(r.args));
|
|
15825
|
+
if (!row) return null;
|
|
15826
|
+
let exeLink = null;
|
|
15827
|
+
try {
|
|
15828
|
+
exeLink = readlinkSync2(`/proc/${row.pid}/exe`);
|
|
15829
|
+
} catch {
|
|
15830
|
+
exeLink = null;
|
|
15831
|
+
}
|
|
15832
|
+
return { pid: row.pid, exeLink };
|
|
15833
|
+
} catch {
|
|
15834
|
+
return null;
|
|
15835
|
+
}
|
|
15836
|
+
},
|
|
15837
|
+
runningBinaryVersion: (pid) => {
|
|
15838
|
+
try {
|
|
15839
|
+
return syncExecFile(`/proc/${pid}/exe`, ["--version"], {
|
|
15840
|
+
timeout: 1e4,
|
|
15841
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15842
|
+
}).toString().trim() || null;
|
|
15843
|
+
} catch {
|
|
15844
|
+
return null;
|
|
15845
|
+
}
|
|
15846
|
+
},
|
|
15847
|
+
log: (msg) => log(msg)
|
|
15848
|
+
};
|
|
15633
15849
|
var isolationImageRetryAfter = /* @__PURE__ */ new Map();
|
|
15634
15850
|
var isolationImageFailureCount = /* @__PURE__ */ new Map();
|
|
15635
15851
|
var isolationImageInFlight = /* @__PURE__ */ new Set();
|
|
@@ -17208,7 +17424,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
17208
17424
|
if (codeNames.length === 0) return;
|
|
17209
17425
|
void (async () => {
|
|
17210
17426
|
try {
|
|
17211
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
17427
|
+
const { collectDiagnostics } = await import("../persistent-session-JKX5IIHF.js");
|
|
17212
17428
|
await api.post("/host/heartbeat", {
|
|
17213
17429
|
host_id: hostId,
|
|
17214
17430
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -17350,7 +17566,7 @@ async function pollCycleInner() {
|
|
|
17350
17566
|
}
|
|
17351
17567
|
try {
|
|
17352
17568
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
17353
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
17569
|
+
const { collectDiagnostics } = await import("../persistent-session-JKX5IIHF.js");
|
|
17354
17570
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
17355
17571
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
|
|
17356
17572
|
let tailscaleHostname;
|
|
@@ -17550,7 +17766,7 @@ async function pollCycleInner() {
|
|
|
17550
17766
|
setConfigHash(hbResp?.config_hash ?? null);
|
|
17551
17767
|
try {
|
|
17552
17768
|
const desiredClaudeCodeVersion = hbResp?.desired_claude_code_version?.trim();
|
|
17553
|
-
const { maybeUpdateClaudeCode, shouldRunClaudeCodeUpdater } = await import("../claude-code-updater-
|
|
17769
|
+
const { maybeUpdateClaudeCode, shouldRunClaudeCodeUpdater } = await import("../claude-code-updater-SWTQNL3W.js");
|
|
17554
17770
|
if (desiredClaudeCodeVersion && shouldRunClaudeCodeUpdater({
|
|
17555
17771
|
desiredVersion: desiredClaudeCodeVersion,
|
|
17556
17772
|
installedVersion: cachedFrameworkVersion,
|
|
@@ -17575,7 +17791,7 @@ async function pollCycleInner() {
|
|
|
17575
17791
|
collectPanelessActivityProbes,
|
|
17576
17792
|
getResponsivenessIntervalMs,
|
|
17577
17793
|
occupancyQualificationClassifications
|
|
17578
|
-
} = await import("../responsiveness-probe-
|
|
17794
|
+
} = await import("../responsiveness-probe-IWC6K5NQ.js");
|
|
17579
17795
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
17580
17796
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
17581
17797
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -17692,7 +17908,7 @@ async function pollCycleInner() {
|
|
|
17692
17908
|
collectResponsivenessProbes,
|
|
17693
17909
|
livePendingInboundOldestAgeSeconds,
|
|
17694
17910
|
parkPendingInbound
|
|
17695
|
-
} = await import("../responsiveness-probe-
|
|
17911
|
+
} = await import("../responsiveness-probe-IWC6K5NQ.js");
|
|
17696
17912
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
17697
17913
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
17698
17914
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -17978,7 +18194,7 @@ async function pollCycleInner() {
|
|
|
17978
18194
|
}
|
|
17979
18195
|
}
|
|
17980
18196
|
);
|
|
17981
|
-
const { parkPendingInbound } = await import("../responsiveness-probe-
|
|
18197
|
+
const { parkPendingInbound } = await import("../responsiveness-probe-IWC6K5NQ.js");
|
|
17982
18198
|
const { parked, deadLettered } = parkPendingInbound(codeName, new Date(fatalNowMs));
|
|
17983
18199
|
paneFatalStreak.delete(codeName);
|
|
17984
18200
|
paneFatalRestarts.set(codeName, [...history, fatalNowMs]);
|
|
@@ -18009,7 +18225,7 @@ async function pollCycleInner() {
|
|
|
18009
18225
|
TRANSCRIPT_MOUNT_ESCALATION_REFRESH_MS,
|
|
18010
18226
|
bindSourceEscalations
|
|
18011
18227
|
} = await import("../transcript-mount-health-OHE6IVJV.js");
|
|
18012
|
-
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-
|
|
18228
|
+
const { transcriptBindSourcesFor, ensureTranscriptBindSources } = await import("../persistent-session-JKX5IIHF.js");
|
|
18013
18229
|
const mountConfig = resolveTranscriptMountConfig();
|
|
18014
18230
|
const liveAgents = agentState.persistentSessionAgents;
|
|
18015
18231
|
for (const tracked of [
|
|
@@ -18174,7 +18390,7 @@ async function pollCycleInner() {
|
|
|
18174
18390
|
}
|
|
18175
18391
|
try {
|
|
18176
18392
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
18177
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
18393
|
+
const { probeSessionAuth } = await import("../session-auth-dead-U5JSZD5Z.js");
|
|
18178
18394
|
const observations = [];
|
|
18179
18395
|
const pendingCacheCommits = [];
|
|
18180
18396
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -22157,6 +22373,48 @@ async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refres
|
|
|
22157
22373
|
if (rolloverDecision !== "inbound-wait") {
|
|
22158
22374
|
dayRolloverInboundHold.delete(codeName);
|
|
22159
22375
|
}
|
|
22376
|
+
if (restartTrigger === null) {
|
|
22377
|
+
try {
|
|
22378
|
+
const recycleMode = isolationMode(codeName) === "docker" ? "container" : "host";
|
|
22379
|
+
const recycleSessionHealthy = isSessionHealthy(codeName);
|
|
22380
|
+
const recycleCurrent = recycleSessionHealthy ? peekCurrentSession(codeName) : null;
|
|
22381
|
+
const recycleIdle = recycleCurrent ? isAgentIdle(projectDir, recycleCurrent.sessionId) : false;
|
|
22382
|
+
const runtimeSample = runtimeVersionFor(codeName);
|
|
22383
|
+
const runtimeClaudeVersion = recycleMode === "container" ? runtimeSample.state === "ok" ? runtimeSample.version : null : hostSessionStateFor(codeName, runtimeImageRecycleIo).version;
|
|
22384
|
+
const recycleBelowFloor = isBelowRuntimeFloor(runtimeClaudeVersion);
|
|
22385
|
+
const recycleDecision = evaluateImageRecycle(
|
|
22386
|
+
{
|
|
22387
|
+
codeName,
|
|
22388
|
+
mode: recycleMode,
|
|
22389
|
+
imageTag: process.env.AGT_ISOLATION_IMAGE || "agt-runtime:latest",
|
|
22390
|
+
sessionHealthy: recycleSessionHealthy && recycleCurrent !== null,
|
|
22391
|
+
inWindow: decideMaintenanceWindowGate({ window: cachedMaintenanceWindow, now: /* @__PURE__ */ new Date() }) === "proceed",
|
|
22392
|
+
runtimeClaudeVersion,
|
|
22393
|
+
idle: recycleIdle,
|
|
22394
|
+
// Only stat the channel dirs when a forced recycle is on the table.
|
|
22395
|
+
recentInboundAgeSec: recycleBelowFloor && !recycleIdle ? await channelInboundActivityAgeSecondsFor(codeName) : null,
|
|
22396
|
+
inboundGraceSec: DAY_ROLLOVER_INBOUND_GRACE_SEC,
|
|
22397
|
+
inboundHoldMaxMin: DAY_ROLLOVER_INBOUND_DEFER_MAX_MIN,
|
|
22398
|
+
deadlineMs: FORCED_UPDATE_HARD_DEADLINE_MS,
|
|
22399
|
+
deviceStateReady: () => deviceStateAllowsRollover(codeName, "force-reset")
|
|
22400
|
+
},
|
|
22401
|
+
runtimeImageRecycleIo
|
|
22402
|
+
);
|
|
22403
|
+
if (recycleDecision === "recycle" || recycleDecision === "recycle-deadline") {
|
|
22404
|
+
const tornDown = stopPersistentSessionAndForgetMcpBaseline(codeName, "runtime-image-update", void 0, void 0, {
|
|
22405
|
+
reason: recycleDecision === "recycle-deadline" ? `${recycleMode === "container" ? "container" : "host session"} below Claude Code security floor ${RUNTIME_CLAUDE_CODE_SECURITY_FLOOR}; busy past the deadline, recycled onto the current ${recycleMode === "container" ? "agt-runtime image" : "claude binary"}` : recycleMode === "container" ? "container running a superseded agt-runtime image; recycled between turns" : "host session running a replaced claude binary; recycled between turns",
|
|
22406
|
+
detail: { runtime_claude_version: runtimeClaudeVersion, decision: recycleDecision, mode: recycleMode }
|
|
22407
|
+
});
|
|
22408
|
+
if (tornDown) {
|
|
22409
|
+
agentState.persistentSessionAgents.delete(codeName);
|
|
22410
|
+
noteRecycled(codeName, runtimeImageRecycleIo);
|
|
22411
|
+
restartTrigger = "runtime-image";
|
|
22412
|
+
}
|
|
22413
|
+
}
|
|
22414
|
+
} catch (err) {
|
|
22415
|
+
log(`[runtime-image-recycle] check failed for '${codeName}' (leaving the session alone): ${err.message}`);
|
|
22416
|
+
}
|
|
22417
|
+
}
|
|
22160
22418
|
if (restartTrigger === "day-rollover") {
|
|
22161
22419
|
rotatePaneLogForDayRollover(codeName, log, agentTimezone);
|
|
22162
22420
|
}
|
|
@@ -22532,7 +22790,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash20("sha256")
|
|
|
22532
22790
|
break;
|
|
22533
22791
|
}
|
|
22534
22792
|
}
|
|
22535
|
-
const finalDecision = restartTrigger === "auth-tuple" ? "restart-pending" : restartTrigger === "day-rollover" ? dayRolloverForced ? "day-rollover-forced" : "day-rollover-restart" : dayRolloverDeferred ? "day-rollover-deferred" : "healthy";
|
|
22793
|
+
const finalDecision = restartTrigger === "auth-tuple" || restartTrigger === "runtime-image" ? "restart-pending" : restartTrigger === "day-rollover" ? dayRolloverForced ? "day-rollover-forced" : "day-rollover-restart" : dayRolloverDeferred ? "day-rollover-deferred" : "healthy";
|
|
22536
22794
|
return {
|
|
22537
22795
|
decision: finalDecision,
|
|
22538
22796
|
spawnAttempted: false,
|
|
@@ -22772,7 +23030,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
22772
23030
|
try {
|
|
22773
23031
|
const freshId = rotateSessionForWedge(codeName);
|
|
22774
23032
|
consecutiveWedgeCycles.delete(codeName);
|
|
22775
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
23033
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-IWC6K5NQ.js");
|
|
22776
23034
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
22777
23035
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
22778
23036
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -22815,7 +23073,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
22815
23073
|
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}`));
|
|
22816
23074
|
void (async () => {
|
|
22817
23075
|
try {
|
|
22818
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
23076
|
+
const { collectDiagnostics } = await import("../persistent-session-JKX5IIHF.js");
|
|
22819
23077
|
await api.post("/host/heartbeat", {
|
|
22820
23078
|
host_id: hostId,
|
|
22821
23079
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -22866,7 +23124,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
22866
23124
|
}
|
|
22867
23125
|
try {
|
|
22868
23126
|
const hostId = await getHostId();
|
|
22869
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
23127
|
+
const { collectDiagnostics } = await import("../persistent-session-JKX5IIHF.js");
|
|
22870
23128
|
await api.post("/host/heartbeat", {
|
|
22871
23129
|
host_id: hostId,
|
|
22872
23130
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
@@ -23539,7 +23797,7 @@ async function processClaudePairSessions(agents) {
|
|
|
23539
23797
|
// cannot take it for itself — by the time it runs, the write it is looking
|
|
23540
23798
|
// for may already have happened.
|
|
23541
23799
|
snapshotPairConfig
|
|
23542
|
-
} = await import("../claude-pair-runtime-
|
|
23800
|
+
} = await import("../claude-pair-runtime-4GZOYK4O.js");
|
|
23543
23801
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
23544
23802
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
23545
23803
|
const killed = await killPairSession(pairTmuxSession(pairId));
|