@integrity-labs/agt-cli 0.28.1010 → 0.28.1012
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 +5 -5
- package/dist/{chunk-HSYBLAWA.js → chunk-K73BIWKA.js} +57 -14
- package/dist/chunk-K73BIWKA.js.map +1 -0
- package/dist/{chunk-OPDT2OE5.js → chunk-LV72A4BE.js} +1 -1
- package/dist/chunk-LV72A4BE.js.map +1 -0
- package/dist/{chunk-V6HO4MUI.js → chunk-O3DODZVZ.js} +4 -4
- package/dist/{claude-pair-runtime-EQDC53WO.js → claude-pair-runtime-NPXBXUSE.js} +2 -2
- package/dist/lib/manager-worker.js +180 -76
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-NLQ6AASM.js → persistent-session-KPASTJIV.js} +3 -3
- package/dist/{responsiveness-probe-ETSEM5K6.js → responsiveness-probe-RSVGRS63.js} +3 -3
- package/dist/{session-auth-dead-J3MNBHCZ.js → session-auth-dead-YV2X4AGF.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-HSYBLAWA.js.map +0 -1
- package/dist/chunk-OPDT2OE5.js.map +0 -1
- /package/dist/{chunk-V6HO4MUI.js.map → chunk-O3DODZVZ.js.map} +0 -0
- /package/dist/{claude-pair-runtime-EQDC53WO.js.map → claude-pair-runtime-NPXBXUSE.js.map} +0 -0
- /package/dist/{persistent-session-NLQ6AASM.js.map → persistent-session-KPASTJIV.js.map} +0 -0
- /package/dist/{responsiveness-probe-ETSEM5K6.js.map → responsiveness-probe-RSVGRS63.js.map} +0 -0
- /package/dist/{session-auth-dead-J3MNBHCZ.js.map → session-auth-dead-YV2X4AGF.js.map} +0 -0
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
safeWriteJsonAtomic,
|
|
65
65
|
setConfigHash,
|
|
66
66
|
tripClass
|
|
67
|
-
} from "../chunk-
|
|
67
|
+
} from "../chunk-O3DODZVZ.js";
|
|
68
68
|
import {
|
|
69
69
|
getProjectDir as getProjectDir2,
|
|
70
70
|
getReadyTasks,
|
|
@@ -77,8 +77,10 @@ import {
|
|
|
77
77
|
CHANNEL_SECRET_ENV_KEYS,
|
|
78
78
|
CLAUDE_MANAGED_SETTINGS_DIR,
|
|
79
79
|
ChildProcessError,
|
|
80
|
+
DEFAULT_KILL_AFTER_MS,
|
|
80
81
|
agentRuntimeKey,
|
|
81
82
|
applyBlockedPromptVerdict,
|
|
83
|
+
boundedArgv,
|
|
82
84
|
buildEgressAllowlist,
|
|
83
85
|
checkChannelInputs,
|
|
84
86
|
collectChannelSpawnSecrets,
|
|
@@ -95,6 +97,7 @@ import {
|
|
|
95
97
|
getProjectDir,
|
|
96
98
|
getSessionState,
|
|
97
99
|
hardBoundedCapture,
|
|
100
|
+
hasTimeoutBinary,
|
|
98
101
|
hashFile,
|
|
99
102
|
injectMessage,
|
|
100
103
|
injectMessageWithStatus,
|
|
@@ -142,7 +145,7 @@ import {
|
|
|
142
145
|
takeZombieDetection,
|
|
143
146
|
toOpencodeModel,
|
|
144
147
|
writeEgressAllowlist
|
|
145
|
-
} from "../chunk-
|
|
148
|
+
} from "../chunk-K73BIWKA.js";
|
|
146
149
|
import {
|
|
147
150
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
148
151
|
AnchorSessionClient,
|
|
@@ -241,7 +244,7 @@ import {
|
|
|
241
244
|
subagentActivityAgeSeconds,
|
|
242
245
|
sumTranscriptUsageInWindow,
|
|
243
246
|
transcriptActivityAgeSeconds
|
|
244
|
-
} from "../chunk-
|
|
247
|
+
} from "../chunk-LV72A4BE.js";
|
|
245
248
|
import "../chunk-DHWNVVX4.js";
|
|
246
249
|
import {
|
|
247
250
|
reapOrphanChannelMcps
|
|
@@ -7652,8 +7655,8 @@ function shouldNudgeUnchangedBoard(signature, state9, now, fullCadenceMs, maxCad
|
|
|
7652
7655
|
if (state9.signature !== signature) return true;
|
|
7653
7656
|
return now - state9.nudgedAt >= nudgeIntervalForCount(state9.nudgeCount ?? 1, fullCadenceMs, maxCadenceMs);
|
|
7654
7657
|
}
|
|
7655
|
-
function failureRetryIntervalForCount(
|
|
7656
|
-
const exponent = Math.max(0, Math.min(
|
|
7658
|
+
function failureRetryIntervalForCount(failureCount2, baseMs, maxMs) {
|
|
7659
|
+
const exponent = Math.max(0, Math.min(failureCount2 - 1, 8));
|
|
7657
7660
|
return Math.min(baseMs * 3 ** exponent, Math.max(maxMs, baseMs));
|
|
7658
7661
|
}
|
|
7659
7662
|
var KANBAN_NOTICE_BREAKER_THRESHOLD = 5;
|
|
@@ -7911,7 +7914,7 @@ function loadKanbanNudgeState(target, configDir) {
|
|
|
7911
7914
|
if (!value || typeof value !== "object") continue;
|
|
7912
7915
|
const v = value;
|
|
7913
7916
|
if (typeof v.signature !== "string" || typeof v.nudgedAt !== "number" || !Number.isFinite(v.nudgedAt)) continue;
|
|
7914
|
-
const
|
|
7917
|
+
const failureCount2 = typeof v.failureCount === "number" && Number.isFinite(v.failureCount) && v.failureCount >= 1 ? Math.floor(v.failureCount) : void 0;
|
|
7915
7918
|
const failedAt = typeof v.failedAt === "number" && Number.isFinite(v.failedAt) ? v.failedAt : void 0;
|
|
7916
7919
|
target.set(codeName, {
|
|
7917
7920
|
signature: v.signature,
|
|
@@ -7920,8 +7923,8 @@ function loadKanbanNudgeState(target, configDir) {
|
|
|
7920
7923
|
// Only carry the pair when the count is real: a failedAt with no count
|
|
7921
7924
|
// cannot gate anything, and a count with no timestamp is handled as
|
|
7922
7925
|
// "due now" by shouldAttemptNoticeEnqueue rather than wedging the agent.
|
|
7923
|
-
...
|
|
7924
|
-
...
|
|
7926
|
+
...failureCount2 !== void 0 ? { failureCount: failureCount2 } : {},
|
|
7927
|
+
...failureCount2 !== void 0 && failedAt !== void 0 ? { failedAt } : {}
|
|
7925
7928
|
});
|
|
7926
7929
|
}
|
|
7927
7930
|
}
|
|
@@ -9764,6 +9767,105 @@ function stopPidPressureSampler() {
|
|
|
9764
9767
|
timer2 = null;
|
|
9765
9768
|
}
|
|
9766
9769
|
|
|
9770
|
+
// src/lib/runtime-version-sampler.ts
|
|
9771
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
9772
|
+
import { execFile as execFileCb } from "child_process";
|
|
9773
|
+
import { promisify as promisify2 } from "util";
|
|
9774
|
+
var execFileAsync2 = promisify2(execFileCb);
|
|
9775
|
+
var SAMPLE_INTERVAL_MS3 = 5 * 6e4;
|
|
9776
|
+
var lastSample2 = /* @__PURE__ */ new Map();
|
|
9777
|
+
var failureCount = /* @__PURE__ */ new Map();
|
|
9778
|
+
async function readVersionReal(codeName) {
|
|
9779
|
+
const timeoutMs = 1e4;
|
|
9780
|
+
timeoutBinaryAvailable ??= hasTimeoutBinary(execFileSync2);
|
|
9781
|
+
const { execFile: file, execArgs } = boundedArgv(
|
|
9782
|
+
"docker",
|
|
9783
|
+
["exec", `agt-${codeName}`, "claude", "--version"],
|
|
9784
|
+
timeoutMs,
|
|
9785
|
+
DEFAULT_KILL_AFTER_MS,
|
|
9786
|
+
timeoutBinaryAvailable
|
|
9787
|
+
);
|
|
9788
|
+
try {
|
|
9789
|
+
const { stdout } = await execFileAsync2(file, execArgs, {
|
|
9790
|
+
encoding: "utf-8",
|
|
9791
|
+
timeout: timeoutBinaryAvailable ? timeoutMs + DEFAULT_KILL_AFTER_MS + 5e3 : timeoutMs
|
|
9792
|
+
});
|
|
9793
|
+
return String(stdout ?? "");
|
|
9794
|
+
} catch {
|
|
9795
|
+
return null;
|
|
9796
|
+
}
|
|
9797
|
+
}
|
|
9798
|
+
var timeoutBinaryAvailable;
|
|
9799
|
+
function parseClaudeVersion(raw) {
|
|
9800
|
+
if (raw == null) return null;
|
|
9801
|
+
const m = raw.trim().match(/\b(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)\b/);
|
|
9802
|
+
return m ? m[1] : null;
|
|
9803
|
+
}
|
|
9804
|
+
async function sampleRuntimeVersionFor(codeName, io = {}) {
|
|
9805
|
+
const isolated = io.isolatedFor?.(codeName) ?? effectiveIsolationMode(codeName) === "docker";
|
|
9806
|
+
if (!isolated) {
|
|
9807
|
+
lastSample2.delete(codeName);
|
|
9808
|
+
failureCount.delete(codeName);
|
|
9809
|
+
return { state: "not-isolated", version: null, sampledAt: null, failures: 0 };
|
|
9810
|
+
}
|
|
9811
|
+
const resolveDir = io.resolveCgroupDir ?? resolveCgroupDirReal;
|
|
9812
|
+
const readVersion = io.readVersion ?? readVersionReal;
|
|
9813
|
+
const now = io.now ?? Date.now;
|
|
9814
|
+
const dir = resolveDir(codeName);
|
|
9815
|
+
if (dir == null) {
|
|
9816
|
+
const failures = (failureCount.get(codeName) ?? 0) + 1;
|
|
9817
|
+
failureCount.set(codeName, failures);
|
|
9818
|
+
lastSample2.delete(codeName);
|
|
9819
|
+
return { state: "error", version: null, sampledAt: null, failures };
|
|
9820
|
+
}
|
|
9821
|
+
const cached = lastSample2.get(codeName);
|
|
9822
|
+
if (cached && cached.dir === dir) return cached.sample;
|
|
9823
|
+
const version = parseClaudeVersion(await readVersion(codeName));
|
|
9824
|
+
if (version == null) {
|
|
9825
|
+
const failures = (failureCount.get(codeName) ?? 0) + 1;
|
|
9826
|
+
failureCount.set(codeName, failures);
|
|
9827
|
+
lastSample2.delete(codeName);
|
|
9828
|
+
return { state: "error", version: null, sampledAt: null, failures };
|
|
9829
|
+
}
|
|
9830
|
+
failureCount.delete(codeName);
|
|
9831
|
+
const sample = {
|
|
9832
|
+
state: "ok",
|
|
9833
|
+
version,
|
|
9834
|
+
sampledAt: new Date(now()).toISOString(),
|
|
9835
|
+
failures: 0
|
|
9836
|
+
};
|
|
9837
|
+
lastSample2.set(codeName, { dir, sample });
|
|
9838
|
+
return sample;
|
|
9839
|
+
}
|
|
9840
|
+
async function sampleRuntimeVersionOnce(codeNames, io = {}) {
|
|
9841
|
+
for (const codeName of codeNames) await sampleRuntimeVersionFor(codeName, io);
|
|
9842
|
+
}
|
|
9843
|
+
function runtimeVersionFor(codeName) {
|
|
9844
|
+
const cached = lastSample2.get(codeName);
|
|
9845
|
+
if (cached) return cached.sample;
|
|
9846
|
+
const failures = failureCount.get(codeName) ?? 0;
|
|
9847
|
+
if (failures > 0) return { state: "error", version: null, sampledAt: null, failures };
|
|
9848
|
+
return { state: "unsampled", version: null, sampledAt: null, failures: 0 };
|
|
9849
|
+
}
|
|
9850
|
+
var timer3 = null;
|
|
9851
|
+
var sampling = false;
|
|
9852
|
+
function startRuntimeVersionSampler(liveAgents, io = {}) {
|
|
9853
|
+
if (timer3) return;
|
|
9854
|
+
timer3 = setInterval(() => {
|
|
9855
|
+
if (sampling) return;
|
|
9856
|
+
sampling = true;
|
|
9857
|
+
void sampleRuntimeVersionOnce(liveAgents(), io).catch(() => {
|
|
9858
|
+
}).finally(() => {
|
|
9859
|
+
sampling = false;
|
|
9860
|
+
});
|
|
9861
|
+
}, SAMPLE_INTERVAL_MS3);
|
|
9862
|
+
timer3.unref?.();
|
|
9863
|
+
}
|
|
9864
|
+
function stopRuntimeVersionSampler() {
|
|
9865
|
+
if (timer3) clearInterval(timer3);
|
|
9866
|
+
timer3 = null;
|
|
9867
|
+
}
|
|
9868
|
+
|
|
9767
9869
|
// src/lib/opencode-slack-ingest.ts
|
|
9768
9870
|
import { createHash as createHash17 } from "crypto";
|
|
9769
9871
|
|
|
@@ -13247,7 +13349,7 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
|
|
|
13247
13349
|
clearTimeout(existing.timer);
|
|
13248
13350
|
log(`[hot-reload] Coalesced restart for '${codeName}': replacing pending timer with ${reason}`);
|
|
13249
13351
|
}
|
|
13250
|
-
const
|
|
13352
|
+
const timer4 = setTimeout(() => {
|
|
13251
13353
|
pendingSessionRestarts.delete(codeName);
|
|
13252
13354
|
const gate = restartGateFor(codeName, breakerReason);
|
|
13253
13355
|
if (gate !== "bypass" && gate !== "proceed") {
|
|
@@ -13335,8 +13437,8 @@ function scheduleSessionRestart(codeName, delayMs, reason, breakerReason = "hot-
|
|
|
13335
13437
|
void respawnAgentAfterMcpStop(codeName, reason);
|
|
13336
13438
|
}
|
|
13337
13439
|
}, delayMs);
|
|
13338
|
-
|
|
13339
|
-
pendingSessionRestarts.set(codeName, { timer:
|
|
13440
|
+
timer4.unref?.();
|
|
13441
|
+
pendingSessionRestarts.set(codeName, { timer: timer4, reason, breakerReason, beforeStop, auditDetail });
|
|
13340
13442
|
}
|
|
13341
13443
|
function cancelPendingSessionRestart(codeName) {
|
|
13342
13444
|
pendingRestartVerifications.delete(codeName);
|
|
@@ -13465,7 +13567,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13465
13567
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13466
13568
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13467
13569
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13468
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13570
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-RSVGRS63.js");
|
|
13469
13571
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13470
13572
|
if (newest === null) return null;
|
|
13471
13573
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -14208,10 +14310,10 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
14208
14310
|
var lastVersionCheckAt = 0;
|
|
14209
14311
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
14210
14312
|
var lastResponsivenessProbeAt = 0;
|
|
14211
|
-
var agtCliVersion = true ? "0.28.
|
|
14212
|
-
function resolveBrewPath(
|
|
14313
|
+
var agtCliVersion = true ? "0.28.1012" : "dev";
|
|
14314
|
+
function resolveBrewPath(execFileSync3) {
|
|
14213
14315
|
try {
|
|
14214
|
-
const out =
|
|
14316
|
+
const out = execFileSync3("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
14215
14317
|
if (out) return out;
|
|
14216
14318
|
} catch {
|
|
14217
14319
|
}
|
|
@@ -14225,7 +14327,7 @@ function resolveBrewPath(execFileSync2) {
|
|
|
14225
14327
|
}
|
|
14226
14328
|
return null;
|
|
14227
14329
|
}
|
|
14228
|
-
function claudeBinaryInstalled(
|
|
14330
|
+
function claudeBinaryInstalled(execFileSync3) {
|
|
14229
14331
|
const canonical = [
|
|
14230
14332
|
"/home/linuxbrew/.linuxbrew/bin/claude",
|
|
14231
14333
|
"/opt/homebrew/bin/claude",
|
|
@@ -14233,7 +14335,7 @@ function claudeBinaryInstalled(execFileSync2) {
|
|
|
14233
14335
|
];
|
|
14234
14336
|
if (canonical.some((path) => existsSync19(path))) return true;
|
|
14235
14337
|
try {
|
|
14236
|
-
|
|
14338
|
+
execFileSync3("which", ["claude"], { timeout: 5e3 });
|
|
14237
14339
|
return true;
|
|
14238
14340
|
} catch {
|
|
14239
14341
|
return false;
|
|
@@ -14267,9 +14369,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
14267
14369
|
}
|
|
14268
14370
|
const { binary, installer, package: pkg, script } = integration.cli_tool;
|
|
14269
14371
|
const resolvedInstaller = installer ?? "manual";
|
|
14270
|
-
const { execFileSync:
|
|
14372
|
+
const { execFileSync: execFileSync3, execSync } = await import("child_process");
|
|
14271
14373
|
try {
|
|
14272
|
-
|
|
14374
|
+
execFileSync3("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
14273
14375
|
toolkitCliEnsured.add(toolkitSlug);
|
|
14274
14376
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
14275
14377
|
toolkitCliFailureCount.delete(toolkitSlug);
|
|
@@ -14290,14 +14392,14 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
14290
14392
|
return;
|
|
14291
14393
|
}
|
|
14292
14394
|
log(`[toolkit-install] ${toolkitSlug}: installing via npm (${pkg})\u2026`);
|
|
14293
|
-
|
|
14395
|
+
execFileSync3("npm", ["install", "-g", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
14294
14396
|
} else if (resolvedInstaller === "brew") {
|
|
14295
14397
|
if (!pkg) {
|
|
14296
14398
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but no package declared`);
|
|
14297
14399
|
toolkitCliEnsured.add(toolkitSlug);
|
|
14298
14400
|
return;
|
|
14299
14401
|
}
|
|
14300
|
-
const brewPath = resolveBrewPath(
|
|
14402
|
+
const brewPath = resolveBrewPath(execFileSync3);
|
|
14301
14403
|
if (!brewPath) {
|
|
14302
14404
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but Homebrew not available \u2014 install manually: brew install ${pkg}`);
|
|
14303
14405
|
toolkitCliEnsured.add(toolkitSlug);
|
|
@@ -14307,9 +14409,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
14307
14409
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
14308
14410
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
14309
14411
|
if (isRoot) {
|
|
14310
|
-
|
|
14412
|
+
execFileSync3("sudo", ["-u", "ec2-user", "-H", brewPath, "install", pkg], { timeout: 18e4, stdio: "pipe", cwd: "/tmp" });
|
|
14311
14413
|
} else {
|
|
14312
|
-
|
|
14414
|
+
execFileSync3(brewPath, ["install", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
14313
14415
|
}
|
|
14314
14416
|
} else if (resolvedInstaller === "script") {
|
|
14315
14417
|
if (!script) {
|
|
@@ -14331,7 +14433,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
14331
14433
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
14332
14434
|
}
|
|
14333
14435
|
try {
|
|
14334
|
-
|
|
14436
|
+
execFileSync3("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
14335
14437
|
log(`[toolkit-install] ${toolkitSlug}: installed \u2014 ${binary} now on PATH`);
|
|
14336
14438
|
toolkitCliEnsured.add(toolkitSlug);
|
|
14337
14439
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
@@ -14379,16 +14481,16 @@ async function ensureIsolationImage(imageUri) {
|
|
|
14379
14481
|
}
|
|
14380
14482
|
isolationImageInFlight.add(imageUri);
|
|
14381
14483
|
try {
|
|
14382
|
-
const { execFileSync:
|
|
14484
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
14383
14485
|
try {
|
|
14384
|
-
|
|
14486
|
+
execFileSync3("which", ["docker"], { timeout: 5e3, stdio: "pipe" });
|
|
14385
14487
|
} catch {
|
|
14386
14488
|
recordIsolationImageFailure(imageUri, `'docker' not found on host - required to pull the isolation image (install it, then the manager retries)`);
|
|
14387
14489
|
return;
|
|
14388
14490
|
}
|
|
14389
14491
|
const hasAws = (() => {
|
|
14390
14492
|
try {
|
|
14391
|
-
|
|
14493
|
+
execFileSync3("which", ["aws"], { timeout: 5e3, stdio: "pipe" });
|
|
14392
14494
|
return true;
|
|
14393
14495
|
} catch {
|
|
14394
14496
|
return false;
|
|
@@ -14397,11 +14499,11 @@ async function ensureIsolationImage(imageUri) {
|
|
|
14397
14499
|
if (isPublic) {
|
|
14398
14500
|
if (hasAws) {
|
|
14399
14501
|
try {
|
|
14400
|
-
const password =
|
|
14502
|
+
const password = execFileSync3("aws", ["ecr-public", "get-login-password", "--region", "us-east-1"], {
|
|
14401
14503
|
timeout: 3e4,
|
|
14402
14504
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14403
14505
|
}).toString().trim();
|
|
14404
|
-
|
|
14506
|
+
execFileSync3("docker", ["login", "--username", "AWS", "--password-stdin", "public.ecr.aws"], {
|
|
14405
14507
|
input: password,
|
|
14406
14508
|
timeout: 3e4,
|
|
14407
14509
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -14416,11 +14518,11 @@ async function ensureIsolationImage(imageUri) {
|
|
|
14416
14518
|
return;
|
|
14417
14519
|
}
|
|
14418
14520
|
try {
|
|
14419
|
-
const password =
|
|
14521
|
+
const password = execFileSync3("aws", ["ecr", "get-login-password", "--region", privRegion], {
|
|
14420
14522
|
timeout: 3e4,
|
|
14421
14523
|
stdio: ["ignore", "pipe", "pipe"]
|
|
14422
14524
|
}).toString().trim();
|
|
14423
|
-
|
|
14525
|
+
execFileSync3("docker", ["login", "--username", "AWS", "--password-stdin", registry], {
|
|
14424
14526
|
input: password,
|
|
14425
14527
|
timeout: 3e4,
|
|
14426
14528
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -14501,7 +14603,7 @@ function runAsync(cmd, args, opts) {
|
|
|
14501
14603
|
let stdout = "";
|
|
14502
14604
|
let stderr = "";
|
|
14503
14605
|
let settled = false;
|
|
14504
|
-
const
|
|
14606
|
+
const timer4 = setTimeout(() => {
|
|
14505
14607
|
child.kill("SIGTERM");
|
|
14506
14608
|
if (settled) return;
|
|
14507
14609
|
settled = true;
|
|
@@ -14522,13 +14624,13 @@ function runAsync(cmd, args, opts) {
|
|
|
14522
14624
|
child.on("error", (err) => {
|
|
14523
14625
|
if (settled) return;
|
|
14524
14626
|
settled = true;
|
|
14525
|
-
clearTimeout(
|
|
14627
|
+
clearTimeout(timer4);
|
|
14526
14628
|
reject(err);
|
|
14527
14629
|
});
|
|
14528
14630
|
child.on("close", (code) => {
|
|
14529
14631
|
if (settled) return;
|
|
14530
14632
|
settled = true;
|
|
14531
|
-
clearTimeout(
|
|
14633
|
+
clearTimeout(timer4);
|
|
14532
14634
|
resolve2({ code: code ?? -1, stdout, stderr });
|
|
14533
14635
|
});
|
|
14534
14636
|
}).catch(reject);
|
|
@@ -14583,11 +14685,11 @@ function ensureClaudeManagedSettings(path = claudeManagedSettingsPath()) {
|
|
|
14583
14685
|
}
|
|
14584
14686
|
var OPENCODE_NPM_VERSION = "1.18.3";
|
|
14585
14687
|
async function ensureOpencodeBinary() {
|
|
14586
|
-
const { execFileSync:
|
|
14688
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
14587
14689
|
const bin = process.env["AGT_OPENCODE_BIN"]?.trim() || "opencode";
|
|
14588
14690
|
const probe = () => {
|
|
14589
14691
|
try {
|
|
14590
|
-
|
|
14692
|
+
execFileSync3(bin, ["--version"], { stdio: "ignore", timeout: 1e4 });
|
|
14591
14693
|
return true;
|
|
14592
14694
|
} catch {
|
|
14593
14695
|
return false;
|
|
@@ -14608,7 +14710,7 @@ async function ensureOpencodeBinary() {
|
|
|
14608
14710
|
return false;
|
|
14609
14711
|
}
|
|
14610
14712
|
try {
|
|
14611
|
-
const prefix =
|
|
14713
|
+
const prefix = execFileSync3("npm", ["prefix", "-g"], { encoding: "utf-8", timeout: 1e4 }).trim();
|
|
14612
14714
|
if (prefix) {
|
|
14613
14715
|
const npmBin = join42(prefix, "bin");
|
|
14614
14716
|
const current = (process.env.PATH ?? "").split(pathDelimiter);
|
|
@@ -14640,8 +14742,8 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
14640
14742
|
}
|
|
14641
14743
|
frameworkBinaryChecked.add(frameworkId);
|
|
14642
14744
|
lastManagedSettingsStatus = ensureClaudeManagedSettings();
|
|
14643
|
-
const { execFileSync:
|
|
14644
|
-
const brewPath = resolveBrewPath(
|
|
14745
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
14746
|
+
const brewPath = resolveBrewPath(execFileSync3);
|
|
14645
14747
|
if (!brewPath) {
|
|
14646
14748
|
log("Homebrew not found (no `brew` on PATH, no /home/linuxbrew/.linuxbrew/bin/brew). Cannot auto-install Claude Code. Install manually: https://claude.ai/download");
|
|
14647
14749
|
return;
|
|
@@ -14654,7 +14756,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
14654
14756
|
}
|
|
14655
14757
|
return runAsync(brewPath, args, opts);
|
|
14656
14758
|
};
|
|
14657
|
-
const claudeExists = claudeBinaryInstalled(
|
|
14759
|
+
const claudeExists = claudeBinaryInstalled(execFileSync3);
|
|
14658
14760
|
if (!claudeExists) {
|
|
14659
14761
|
log(`Claude Code binary not found \u2014 installing via Homebrew${isRoot ? " (as ec2-user via sudo)" : ""}...`);
|
|
14660
14762
|
try {
|
|
@@ -14689,13 +14791,13 @@ async function maybeUpgradeClaudeCode() {
|
|
|
14689
14791
|
}
|
|
14690
14792
|
claudeCodeUpgradeInFlight = true;
|
|
14691
14793
|
stampClaudeCodeUpgradeMarker();
|
|
14692
|
-
const { execFileSync:
|
|
14693
|
-
const brewPath = resolveBrewPath(
|
|
14794
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
14795
|
+
const brewPath = resolveBrewPath(execFileSync3);
|
|
14694
14796
|
if (!brewPath) {
|
|
14695
14797
|
claudeCodeUpgradeInFlight = false;
|
|
14696
14798
|
return;
|
|
14697
14799
|
}
|
|
14698
|
-
if (!claudeBinaryInstalled(
|
|
14800
|
+
if (!claudeBinaryInstalled(execFileSync3)) {
|
|
14699
14801
|
claudeCodeUpgradeInFlight = false;
|
|
14700
14802
|
return;
|
|
14701
14803
|
}
|
|
@@ -14825,8 +14927,8 @@ async function checkAndUpdateCli(opts) {
|
|
|
14825
14927
|
}
|
|
14826
14928
|
}
|
|
14827
14929
|
async function checkAndUpdateCliViaBrew(force = false) {
|
|
14828
|
-
const { execFileSync:
|
|
14829
|
-
const brewPath = resolveBrewPath(
|
|
14930
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
14931
|
+
const brewPath = resolveBrewPath(execFileSync3);
|
|
14830
14932
|
if (!brewPath) return "noop";
|
|
14831
14933
|
{
|
|
14832
14934
|
const brewPinRaw = resolveAgtCliPinRaw();
|
|
@@ -14853,13 +14955,13 @@ async function checkAndUpdateCliViaBrew(force = false) {
|
|
|
14853
14955
|
}
|
|
14854
14956
|
let metadataFresh = true;
|
|
14855
14957
|
try {
|
|
14856
|
-
|
|
14958
|
+
execFileSync3(brewPath, ["update", "--quiet"], { timeout: 6e4, stdio: "pipe" });
|
|
14857
14959
|
} catch (err) {
|
|
14858
14960
|
metadataFresh = false;
|
|
14859
14961
|
log(`[self-update] brew update failed (continuing with stale cache): ${err.message}`);
|
|
14860
14962
|
}
|
|
14861
14963
|
try {
|
|
14862
|
-
const outdated =
|
|
14964
|
+
const outdated = execFileSync3(brewPath, ["outdated", "--json=v2"], {
|
|
14863
14965
|
timeout: 3e4,
|
|
14864
14966
|
encoding: "utf-8"
|
|
14865
14967
|
});
|
|
@@ -14894,7 +14996,7 @@ async function checkAndUpdateCliViaBrew(force = false) {
|
|
|
14894
14996
|
const brewInstallHold = await selfUpdateDeviceStateHold(force);
|
|
14895
14997
|
if (brewInstallHold) return brewInstallHold;
|
|
14896
14998
|
try {
|
|
14897
|
-
|
|
14999
|
+
execFileSync3(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
|
|
14898
15000
|
timeout: 12e4,
|
|
14899
15001
|
stdio: "pipe"
|
|
14900
15002
|
});
|
|
@@ -15071,7 +15173,7 @@ async function fetchUrgentDistTagVersion() {
|
|
|
15071
15173
|
}
|
|
15072
15174
|
}
|
|
15073
15175
|
async function installAgtCliViaNpm(version, reasonLabel, force = false) {
|
|
15074
|
-
const { execFileSync:
|
|
15176
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
15075
15177
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
15076
15178
|
const cmd = isRoot ? "npm" : "sudo";
|
|
15077
15179
|
const installArgs = [
|
|
@@ -15084,14 +15186,14 @@ async function installAgtCliViaNpm(version, reasonLabel, force = false) {
|
|
|
15084
15186
|
const npmInstallHold = await selfUpdateDeviceStateHold(force);
|
|
15085
15187
|
if (npmInstallHold) return npmInstallHold;
|
|
15086
15188
|
try {
|
|
15087
|
-
|
|
15189
|
+
execFileSync3(cmd, args, { timeout: 18e4, stdio: "pipe" });
|
|
15088
15190
|
} catch (err) {
|
|
15089
15191
|
log(`[self-update] npm upgrade failed: ${err.message}`);
|
|
15090
15192
|
return "failed";
|
|
15091
15193
|
}
|
|
15092
15194
|
let smokeOk = false;
|
|
15093
15195
|
try {
|
|
15094
|
-
const out =
|
|
15196
|
+
const out = execFileSync3("agt", ["--version"], { timeout: 15e3, stdio: "pipe" }).toString();
|
|
15095
15197
|
smokeOk = isAgtVersionSmokeOk(out, version);
|
|
15096
15198
|
if (!smokeOk) {
|
|
15097
15199
|
log(
|
|
@@ -15156,8 +15258,8 @@ function effectiveRuntimeAuthenticated() {
|
|
|
15156
15258
|
async function maybeProbeClaudeRuntimeAuth() {
|
|
15157
15259
|
if (runtimeAuthProbeInFlight) return;
|
|
15158
15260
|
if (Date.now() - lastRuntimeAuthProbeAt < RUNTIME_AUTH_PROBE_INTERVAL_MS) return;
|
|
15159
|
-
const { execFileSync:
|
|
15160
|
-
if (!claudeBinaryInstalled(
|
|
15261
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
15262
|
+
if (!claudeBinaryInstalled(execFileSync3)) return;
|
|
15161
15263
|
runtimeAuthProbeInFlight = true;
|
|
15162
15264
|
lastRuntimeAuthProbeAt = Date.now();
|
|
15163
15265
|
try {
|
|
@@ -15266,8 +15368,8 @@ async function runHostUsageCommand() {
|
|
|
15266
15368
|
}
|
|
15267
15369
|
}
|
|
15268
15370
|
async function maybePollHostUsageFromCycle() {
|
|
15269
|
-
const { execFileSync:
|
|
15270
|
-
if (!claudeBinaryInstalled(
|
|
15371
|
+
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
15372
|
+
if (!claudeBinaryInstalled(execFileSync3)) return;
|
|
15271
15373
|
await maybePollHostUsage({
|
|
15272
15374
|
api,
|
|
15273
15375
|
runUsageCommand: runHostUsageCommand,
|
|
@@ -15842,10 +15944,10 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15842
15944
|
if (codeNames.length === 0) return;
|
|
15843
15945
|
void (async () => {
|
|
15844
15946
|
try {
|
|
15845
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15947
|
+
const { collectDiagnostics } = await import("../persistent-session-KPASTJIV.js");
|
|
15846
15948
|
await api.post("/host/heartbeat", {
|
|
15847
15949
|
host_id: hostId,
|
|
15848
|
-
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
15950
|
+
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
15849
15951
|
});
|
|
15850
15952
|
} catch (err) {
|
|
15851
15953
|
log(`[restart] post-respawn diagnostics flush failed: ${err.message}`);
|
|
@@ -15908,7 +16010,7 @@ async function pollCycleInner() {
|
|
|
15908
16010
|
getSlackToken: (codeName) => agentChannelTokens.get(codeName)?.slack ?? null,
|
|
15909
16011
|
sendSlack: async (botToken, body) => {
|
|
15910
16012
|
const controller = new AbortController();
|
|
15911
|
-
const
|
|
16013
|
+
const timer4 = setTimeout(() => controller.abort(), 5e3);
|
|
15912
16014
|
try {
|
|
15913
16015
|
const res = await fetch("https://slack.com/api/chat.postMessage", {
|
|
15914
16016
|
method: "POST",
|
|
@@ -15925,7 +16027,7 @@ async function pollCycleInner() {
|
|
|
15925
16027
|
const isAbort = err.name === "AbortError";
|
|
15926
16028
|
return { ok: false, error: isAbort ? "timeout" : err.message };
|
|
15927
16029
|
} finally {
|
|
15928
|
-
clearTimeout(
|
|
16030
|
+
clearTimeout(timer4);
|
|
15929
16031
|
}
|
|
15930
16032
|
},
|
|
15931
16033
|
// ENG-6399: report the restart to audit_log via POST /host/restart-event.
|
|
@@ -15984,9 +16086,9 @@ async function pollCycleInner() {
|
|
|
15984
16086
|
}
|
|
15985
16087
|
try {
|
|
15986
16088
|
const { detectHostSecurity } = await import("../host-security-KQYYZZVW.js");
|
|
15987
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
16089
|
+
const { collectDiagnostics } = await import("../persistent-session-KPASTJIV.js");
|
|
15988
16090
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15989
|
-
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
16091
|
+
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor) : void 0;
|
|
15990
16092
|
let tailscaleHostname;
|
|
15991
16093
|
try {
|
|
15992
16094
|
const { execSync: es } = await import("child_process");
|
|
@@ -16160,7 +16262,7 @@ async function pollCycleInner() {
|
|
|
16160
16262
|
collectPanelessActivityProbes,
|
|
16161
16263
|
getResponsivenessIntervalMs,
|
|
16162
16264
|
occupancyQualificationClassifications
|
|
16163
|
-
} = await import("../responsiveness-probe-
|
|
16265
|
+
} = await import("../responsiveness-probe-RSVGRS63.js");
|
|
16164
16266
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
16165
16267
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
16166
16268
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -16277,7 +16379,7 @@ async function pollCycleInner() {
|
|
|
16277
16379
|
collectResponsivenessProbes,
|
|
16278
16380
|
livePendingInboundOldestAgeSeconds,
|
|
16279
16381
|
parkPendingInbound
|
|
16280
|
-
} = await import("../responsiveness-probe-
|
|
16382
|
+
} = await import("../responsiveness-probe-RSVGRS63.js");
|
|
16281
16383
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-M6AFZWNU.js");
|
|
16282
16384
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
16283
16385
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -16433,7 +16535,7 @@ async function pollCycleInner() {
|
|
|
16433
16535
|
}
|
|
16434
16536
|
try {
|
|
16435
16537
|
const { scrapeMcpFailedBannerCount } = await import("../pane-mcp-banner-scraper-VR5QGP3J.js");
|
|
16436
|
-
const { probeSessionAuth } = await import("../session-auth-dead-
|
|
16538
|
+
const { probeSessionAuth } = await import("../session-auth-dead-YV2X4AGF.js");
|
|
16437
16539
|
const observations = [];
|
|
16438
16540
|
const pendingCacheCommits = [];
|
|
16439
16541
|
const modelApiErrorReportingOn = hostFlagStore().getBoolean("model-api-error-reporting");
|
|
@@ -20813,7 +20915,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20813
20915
|
try {
|
|
20814
20916
|
const freshId = rotateSessionForWedge(codeName);
|
|
20815
20917
|
consecutiveWedgeCycles.delete(codeName);
|
|
20816
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
20918
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-RSVGRS63.js");
|
|
20817
20919
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
20818
20920
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
20819
20921
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -20856,10 +20958,10 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20856
20958
|
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}`));
|
|
20857
20959
|
void (async () => {
|
|
20858
20960
|
try {
|
|
20859
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20961
|
+
const { collectDiagnostics } = await import("../persistent-session-KPASTJIV.js");
|
|
20860
20962
|
await api.post("/host/heartbeat", {
|
|
20861
20963
|
host_id: hostId,
|
|
20862
|
-
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
20964
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
20863
20965
|
});
|
|
20864
20966
|
} catch (err) {
|
|
20865
20967
|
log(`[restart-lane] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -20907,10 +21009,10 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
20907
21009
|
}
|
|
20908
21010
|
try {
|
|
20909
21011
|
const hostId = await getHostId();
|
|
20910
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
21012
|
+
const { collectDiagnostics } = await import("../persistent-session-KPASTJIV.js");
|
|
20911
21013
|
await api.post("/host/heartbeat", {
|
|
20912
21014
|
host_id: hostId,
|
|
20913
|
-
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
21015
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor, runtimeVersionFor)
|
|
20914
21016
|
});
|
|
20915
21017
|
} catch (err) {
|
|
20916
21018
|
log(`[fast-mcp-respawn] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -21508,17 +21610,17 @@ async function maybeInjectKanbanCheck(codeName, agentId, actionableCount, signat
|
|
|
21508
21610
|
});
|
|
21509
21611
|
return;
|
|
21510
21612
|
}
|
|
21511
|
-
const
|
|
21613
|
+
const failureCount2 = (priorState?.failureCount ?? 0) + 1;
|
|
21512
21614
|
setKanbanNudgeState(codeName, {
|
|
21513
21615
|
signature: priorState?.signature ?? signature,
|
|
21514
21616
|
nudgedAt: priorState?.nudgedAt ?? 0,
|
|
21515
21617
|
...priorState?.nudgeCount !== void 0 ? { nudgeCount: priorState.nudgeCount } : {},
|
|
21516
|
-
failureCount,
|
|
21618
|
+
failureCount: failureCount2,
|
|
21517
21619
|
failedAt: Date.now()
|
|
21518
21620
|
});
|
|
21519
|
-
if (
|
|
21621
|
+
if (failureCount2 === KANBAN_NOTICE_BREAKER_THRESHOLD) {
|
|
21520
21622
|
log(
|
|
21521
|
-
`[manager-worker] kanban notice rail BREAKER OPEN for '${codeName}' \u2014 ${
|
|
21623
|
+
`[manager-worker] kanban notice rail BREAKER OPEN for '${codeName}' \u2014 ${failureCount2} consecutive enqueue failures; retries continue at the capped interval`
|
|
21522
21624
|
);
|
|
21523
21625
|
getHostId().then((hostId) => {
|
|
21524
21626
|
if (!hostId) return;
|
|
@@ -21529,7 +21631,7 @@ async function maybeInjectKanbanCheck(codeName, agentId, actionableCount, signat
|
|
|
21529
21631
|
payload: {
|
|
21530
21632
|
agent_code_name: codeName,
|
|
21531
21633
|
agent_id: agentId,
|
|
21532
|
-
consecutive_failures:
|
|
21634
|
+
consecutive_failures: failureCount2,
|
|
21533
21635
|
retry_interval_ms: KANBAN_HYBRID_MAX_CADENCE_MS
|
|
21534
21636
|
},
|
|
21535
21637
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -21542,7 +21644,7 @@ async function maybeInjectKanbanCheck(codeName, agentId, actionableCount, signat
|
|
|
21542
21644
|
return;
|
|
21543
21645
|
}
|
|
21544
21646
|
log(
|
|
21545
|
-
`[manager-worker] kanban direct-chat enqueue failed for '${codeName}' (${
|
|
21647
|
+
`[manager-worker] kanban direct-chat enqueue failed for '${codeName}' (${failureCount2} consecutive) - backing off before the next attempt`
|
|
21546
21648
|
);
|
|
21547
21649
|
}
|
|
21548
21650
|
var lastHarvestAt = /* @__PURE__ */ new Map();
|
|
@@ -21578,7 +21680,7 @@ async function processClaudePairSessions(agents) {
|
|
|
21578
21680
|
// cannot take it for itself — by the time it runs, the write it is looking
|
|
21579
21681
|
// for may already have happened.
|
|
21580
21682
|
snapshotPairConfig
|
|
21581
|
-
} = await import("../claude-pair-runtime-
|
|
21683
|
+
} = await import("../claude-pair-runtime-NPXBXUSE.js");
|
|
21582
21684
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
21583
21685
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
21584
21686
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -22399,6 +22501,7 @@ function startPolling() {
|
|
|
22399
22501
|
livenessTimer.unref();
|
|
22400
22502
|
startPaneOccupancySampler(() => agentState.persistentSessionAgents);
|
|
22401
22503
|
startPidPressureSampler(() => agentState.persistentSessionAgents);
|
|
22504
|
+
startRuntimeVersionSampler(() => agentState.persistentSessionAgents);
|
|
22402
22505
|
{
|
|
22403
22506
|
const seedOutcome = seedClaudeConfigFromLegacy({ log });
|
|
22404
22507
|
const configDirUsable = claudeConfigDirIsReady();
|
|
@@ -22564,6 +22667,7 @@ async function stopPolling(opts = {}) {
|
|
|
22564
22667
|
}
|
|
22565
22668
|
stopPaneOccupancySampler();
|
|
22566
22669
|
stopPidPressureSampler();
|
|
22670
|
+
stopRuntimeVersionSampler();
|
|
22567
22671
|
const shutdownTimer = setTimeout(() => {
|
|
22568
22672
|
log("Shutdown timeout exceeded (15s), forcing exit");
|
|
22569
22673
|
process.exit(opts.forcedExitCode ?? 1);
|