@integrity-labs/agt-cli 0.19.23 → 0.19.26
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 +3 -3
- package/dist/{chunk-3K3RO5NS.js → chunk-55SJYI7V.js} +8 -1
- package/dist/chunk-55SJYI7V.js.map +1 -0
- package/dist/{chunk-EPYGSR3M.js → chunk-V7PNYKIT.js} +8240 -8239
- package/dist/chunk-V7PNYKIT.js.map +1 -0
- package/dist/{claude-pair-runtime-UF4OMFCA.js → claude-pair-runtime-WA4BYPN5.js} +23 -14
- package/dist/{claude-pair-runtime-UF4OMFCA.js.map → claude-pair-runtime-WA4BYPN5.js.map} +1 -1
- package/dist/lib/manager-worker.js +149 -36
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-M2GVL6Z6.js → persistent-session-BVR3HES5.js} +2 -2
- package/mcp/index.js +1 -1
- package/mcp/slack-channel.js +135 -25
- package/mcp/telegram-channel.js +130 -25
- package/package.json +24 -24
- package/dist/chunk-3K3RO5NS.js.map +0 -1
- package/dist/chunk-EPYGSR3M.js.map +0 -1
- /package/dist/{persistent-session-M2GVL6Z6.js.map → persistent-session-BVR3HES5.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveChannels,
|
|
23
23
|
resolveDmTarget,
|
|
24
24
|
wrapScheduledTaskPrompt
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-V7PNYKIT.js";
|
|
26
26
|
import {
|
|
27
27
|
findTaskByTemplate,
|
|
28
28
|
getProjectDir,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
buildAllowedTools,
|
|
36
36
|
getLastFailureContext,
|
|
37
37
|
getProjectDir as getProjectDir2,
|
|
38
|
+
getSessionState,
|
|
38
39
|
injectMessage,
|
|
39
40
|
isAgentIdle,
|
|
40
41
|
isSessionHealthy,
|
|
@@ -49,7 +50,7 @@ import {
|
|
|
49
50
|
startPersistentSession,
|
|
50
51
|
stopAllSessionsAndWait,
|
|
51
52
|
stopPersistentSession
|
|
52
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-55SJYI7V.js";
|
|
53
54
|
|
|
54
55
|
// src/lib/manager-worker.ts
|
|
55
56
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -295,6 +296,68 @@ function reapStaleMcpChildren(args) {
|
|
|
295
296
|
return targets;
|
|
296
297
|
}
|
|
297
298
|
|
|
299
|
+
// src/lib/mcp-presence-reaper.ts
|
|
300
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
301
|
+
var DEFAULT_COLD_START_GRACE_MS = 9e4;
|
|
302
|
+
function findMissingMcpServers(args) {
|
|
303
|
+
const { rows, codeName, mcpJson } = args;
|
|
304
|
+
const declared = Object.keys(mcpJson?.mcpServers ?? {});
|
|
305
|
+
if (declared.length === 0) return [];
|
|
306
|
+
const missing = [];
|
|
307
|
+
for (const key of declared) {
|
|
308
|
+
const live = findMcpChildrenForAgent({
|
|
309
|
+
rows,
|
|
310
|
+
codeName,
|
|
311
|
+
serverKeys: [key],
|
|
312
|
+
mcpJson
|
|
313
|
+
});
|
|
314
|
+
if (live.length === 0) missing.push(key);
|
|
315
|
+
}
|
|
316
|
+
return missing;
|
|
317
|
+
}
|
|
318
|
+
function reapMissingMcpSessions(args) {
|
|
319
|
+
const {
|
|
320
|
+
log: log2,
|
|
321
|
+
codeName,
|
|
322
|
+
mcpJson,
|
|
323
|
+
sessionStartedAt,
|
|
324
|
+
stopSession,
|
|
325
|
+
graceMs = DEFAULT_COLD_START_GRACE_MS
|
|
326
|
+
} = args;
|
|
327
|
+
const now = args.now ?? Date.now;
|
|
328
|
+
const runPs = args.runPs ?? (() => execFileSync2("ps", ["-eo", "pid,ppid,args"], { encoding: "utf-8", timeout: 5e3 }));
|
|
329
|
+
if (!mcpJson?.mcpServers) {
|
|
330
|
+
return { missing: [], restarted: false, reason: "no-mcp-json" };
|
|
331
|
+
}
|
|
332
|
+
const declaredCount = Object.keys(mcpJson.mcpServers).length;
|
|
333
|
+
if (declaredCount === 0) {
|
|
334
|
+
return { missing: [], restarted: false, reason: "no-declared-servers" };
|
|
335
|
+
}
|
|
336
|
+
if (sessionStartedAt === null) {
|
|
337
|
+
return { missing: [], restarted: false, reason: "session-start-unknown" };
|
|
338
|
+
}
|
|
339
|
+
if (now() - sessionStartedAt < graceMs) {
|
|
340
|
+
return { missing: [], restarted: false, reason: "cold-start" };
|
|
341
|
+
}
|
|
342
|
+
let psOutput;
|
|
343
|
+
try {
|
|
344
|
+
psOutput = runPs();
|
|
345
|
+
} catch (err) {
|
|
346
|
+
log2(`[mcp-presence-reaper] ps invocation failed for '${codeName}': ${err.message} \u2014 skipping`);
|
|
347
|
+
return { missing: [], restarted: false, reason: "healthy" };
|
|
348
|
+
}
|
|
349
|
+
const rows = parsePsRows(psOutput);
|
|
350
|
+
const missing = findMissingMcpServers({ rows, codeName, mcpJson });
|
|
351
|
+
if (missing.length === 0) {
|
|
352
|
+
return { missing, restarted: false, reason: "healthy" };
|
|
353
|
+
}
|
|
354
|
+
log2(
|
|
355
|
+
`[mcp-presence-reaper] '${codeName}': declared MCP(s) [${missing.join(", ")}] have no live children \u2014 restarting session`
|
|
356
|
+
);
|
|
357
|
+
stopSession(codeName);
|
|
358
|
+
return { missing, restarted: true };
|
|
359
|
+
}
|
|
360
|
+
|
|
298
361
|
// src/lib/channel-restart-decision.ts
|
|
299
362
|
function launchableChannelIds(channelConfigs) {
|
|
300
363
|
if (!channelConfigs) return /* @__PURE__ */ new Set();
|
|
@@ -323,6 +386,22 @@ function decideChannelRestart(input) {
|
|
|
323
386
|
return { restart: true, added, removed };
|
|
324
387
|
}
|
|
325
388
|
|
|
389
|
+
// src/lib/poll-backoff.ts
|
|
390
|
+
var POLL_BACKOFF_BASE_MS = 1e3;
|
|
391
|
+
var POLL_BACKOFF_MAX_MS = 6e4;
|
|
392
|
+
function currentPollBackoffMs(consecutivePollFailures2) {
|
|
393
|
+
if (consecutivePollFailures2 <= 0) return 0;
|
|
394
|
+
const expDelay = POLL_BACKOFF_BASE_MS * Math.pow(2, consecutivePollFailures2 - 1);
|
|
395
|
+
return Math.min(POLL_BACKOFF_MAX_MS, expDelay);
|
|
396
|
+
}
|
|
397
|
+
function classifyPollError(message) {
|
|
398
|
+
const msg = message.toLowerCase();
|
|
399
|
+
if (msg.includes("api unreachable") || /\b5\d\d\b/.test(msg) || msg.includes("internal server error") || msg.includes("bad gateway")) return "5xx";
|
|
400
|
+
if (msg.includes("exchange failed") || /\b401\b/.test(msg) || msg.includes("invalid token")) return "auth";
|
|
401
|
+
if (msg.includes("econn") || msg.includes("etimedout") || msg.includes("fetch failed")) return "network";
|
|
402
|
+
return "other";
|
|
403
|
+
}
|
|
404
|
+
|
|
326
405
|
// src/lib/integration-context-render.ts
|
|
327
406
|
var PLUGIN_CONTEXT_PLACEHOLDER_RE = /\{\{\s*context\.([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g;
|
|
328
407
|
var TEAM_OVERRIDES_HEADER = "## Team Overrides\n\n> **The following overrides anything you've read above.** If any rule here conflicts with earlier instructions in this skill, follow what is written here. These are user-supplied directives that take precedence over the plugin's default guidance.\n";
|
|
@@ -885,7 +964,7 @@ function saveChannelHashCache(source, configDir) {
|
|
|
885
964
|
}
|
|
886
965
|
|
|
887
966
|
// src/lib/channel-sweep.ts
|
|
888
|
-
import { execFileSync as
|
|
967
|
+
import { execFileSync as execFileSync3 } from "child_process";
|
|
889
968
|
var CHANNEL_BASENAMES = [
|
|
890
969
|
"slack-channel",
|
|
891
970
|
"direct-chat-channel",
|
|
@@ -1048,7 +1127,7 @@ function resolveLiveAnchorPids(agentCodeNames) {
|
|
|
1048
1127
|
for (const codeName of agentCodeNames) {
|
|
1049
1128
|
const pids = /* @__PURE__ */ new Set();
|
|
1050
1129
|
try {
|
|
1051
|
-
const out =
|
|
1130
|
+
const out = execFileSync3("tmux", ["list-panes", "-t", `agt-${codeName}`, "-F", "#{pane_pid}"], {
|
|
1052
1131
|
encoding: "utf-8",
|
|
1053
1132
|
timeout: 2e3,
|
|
1054
1133
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -1068,7 +1147,7 @@ async function sweepChannelProcesses(opts) {
|
|
|
1068
1147
|
const kill = opts.killFn ?? defaultKill;
|
|
1069
1148
|
let psOutput = "";
|
|
1070
1149
|
try {
|
|
1071
|
-
psOutput =
|
|
1150
|
+
psOutput = execFileSync3("ps", ["eww", "-o", "pid=,ppid=,etime=,command="], {
|
|
1072
1151
|
encoding: "utf-8",
|
|
1073
1152
|
timeout: 5e3,
|
|
1074
1153
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -1105,7 +1184,7 @@ function defaultKillSignal(pid, signal) {
|
|
|
1105
1184
|
}
|
|
1106
1185
|
}
|
|
1107
1186
|
function defaultPs() {
|
|
1108
|
-
return
|
|
1187
|
+
return execFileSync3("ps", ["eww", "-o", "pid=,ppid=,etime=,command="], {
|
|
1109
1188
|
encoding: "utf-8",
|
|
1110
1189
|
timeout: 5e3,
|
|
1111
1190
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -1955,9 +2034,10 @@ function cancelPendingSessionRestart(codeName) {
|
|
|
1955
2034
|
var writtenHashes = /* @__PURE__ */ new Map();
|
|
1956
2035
|
var knownSecretsHashes = /* @__PURE__ */ new Map();
|
|
1957
2036
|
var runningMcpHashes = /* @__PURE__ */ new Map();
|
|
1958
|
-
function projectMcpHash(
|
|
2037
|
+
function projectMcpHash(_codeName, projectDir) {
|
|
1959
2038
|
try {
|
|
1960
|
-
|
|
2039
|
+
const raw = readFileSync3(join4(projectDir, ".mcp.json"), "utf-8");
|
|
2040
|
+
return createHash2("sha256").update(canonicalJson(JSON.parse(raw))).digest("hex");
|
|
1961
2041
|
} catch {
|
|
1962
2042
|
return null;
|
|
1963
2043
|
}
|
|
@@ -2060,10 +2140,10 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
2060
2140
|
var cachedFrameworkVersion = null;
|
|
2061
2141
|
var lastVersionCheckAt = 0;
|
|
2062
2142
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2063
|
-
var agtCliVersion = true ? "0.19.
|
|
2064
|
-
function resolveBrewPath(
|
|
2143
|
+
var agtCliVersion = true ? "0.19.26" : "dev";
|
|
2144
|
+
function resolveBrewPath(execFileSync4) {
|
|
2065
2145
|
try {
|
|
2066
|
-
const out =
|
|
2146
|
+
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
2067
2147
|
if (out) return out;
|
|
2068
2148
|
} catch {
|
|
2069
2149
|
}
|
|
@@ -2105,9 +2185,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2105
2185
|
}
|
|
2106
2186
|
const { binary, installer, package: pkg, script } = integration.cli_tool;
|
|
2107
2187
|
const resolvedInstaller = installer ?? "manual";
|
|
2108
|
-
const { execFileSync:
|
|
2188
|
+
const { execFileSync: execFileSync4, execSync } = await import("child_process");
|
|
2109
2189
|
try {
|
|
2110
|
-
|
|
2190
|
+
execFileSync4("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
2111
2191
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2112
2192
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
2113
2193
|
toolkitCliFailureCount.delete(toolkitSlug);
|
|
@@ -2128,14 +2208,14 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2128
2208
|
return;
|
|
2129
2209
|
}
|
|
2130
2210
|
log(`[toolkit-install] ${toolkitSlug}: installing via npm (${pkg})\u2026`);
|
|
2131
|
-
|
|
2211
|
+
execFileSync4("npm", ["install", "-g", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
2132
2212
|
} else if (resolvedInstaller === "brew") {
|
|
2133
2213
|
if (!pkg) {
|
|
2134
2214
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but no package declared`);
|
|
2135
2215
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2136
2216
|
return;
|
|
2137
2217
|
}
|
|
2138
|
-
const brewPath = resolveBrewPath(
|
|
2218
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2139
2219
|
if (!brewPath) {
|
|
2140
2220
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but Homebrew not available \u2014 install manually: brew install ${pkg}`);
|
|
2141
2221
|
toolkitCliEnsured.add(toolkitSlug);
|
|
@@ -2145,9 +2225,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2145
2225
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
2146
2226
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
2147
2227
|
if (isRoot) {
|
|
2148
|
-
|
|
2228
|
+
execFileSync4("sudo", ["-u", "ec2-user", "-H", brewPath, "install", pkg], { timeout: 18e4, stdio: "pipe", cwd: "/tmp" });
|
|
2149
2229
|
} else {
|
|
2150
|
-
|
|
2230
|
+
execFileSync4(brewPath, ["install", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
2151
2231
|
}
|
|
2152
2232
|
} else if (resolvedInstaller === "script") {
|
|
2153
2233
|
if (!script) {
|
|
@@ -2167,7 +2247,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2167
2247
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
2168
2248
|
}
|
|
2169
2249
|
try {
|
|
2170
|
-
|
|
2250
|
+
execFileSync4("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
2171
2251
|
log(`[toolkit-install] ${toolkitSlug}: installed \u2014 ${binary} now on PATH`);
|
|
2172
2252
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2173
2253
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
@@ -2220,8 +2300,8 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
2220
2300
|
if (frameworkId !== "claude-code") return;
|
|
2221
2301
|
if (frameworkBinaryChecked.has(frameworkId)) return;
|
|
2222
2302
|
frameworkBinaryChecked.add(frameworkId);
|
|
2223
|
-
const { execFileSync:
|
|
2224
|
-
const brewPath = resolveBrewPath(
|
|
2303
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2304
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2225
2305
|
if (!brewPath) {
|
|
2226
2306
|
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");
|
|
2227
2307
|
return;
|
|
@@ -2237,7 +2317,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
2237
2317
|
let claudeExists = existsSync3("/home/linuxbrew/.linuxbrew/bin/claude");
|
|
2238
2318
|
if (!claudeExists) {
|
|
2239
2319
|
try {
|
|
2240
|
-
|
|
2320
|
+
execFileSync4("which", ["claude"], { timeout: 5e3 });
|
|
2241
2321
|
claudeExists = true;
|
|
2242
2322
|
} catch {
|
|
2243
2323
|
}
|
|
@@ -2329,16 +2409,16 @@ async function checkAndUpdateCli() {
|
|
|
2329
2409
|
}
|
|
2330
2410
|
}
|
|
2331
2411
|
async function checkAndUpdateCliViaBrew() {
|
|
2332
|
-
const { execFileSync:
|
|
2333
|
-
const brewPath = resolveBrewPath(
|
|
2412
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2413
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2334
2414
|
if (!brewPath) return;
|
|
2335
2415
|
try {
|
|
2336
|
-
|
|
2416
|
+
execFileSync4(brewPath, ["update", "--quiet"], { timeout: 6e4, stdio: "pipe" });
|
|
2337
2417
|
} catch (err) {
|
|
2338
2418
|
log(`[self-update] brew update failed (continuing with stale cache): ${err.message}`);
|
|
2339
2419
|
}
|
|
2340
2420
|
try {
|
|
2341
|
-
const outdated =
|
|
2421
|
+
const outdated = execFileSync4(brewPath, ["outdated", "--json=v2"], {
|
|
2342
2422
|
timeout: 3e4,
|
|
2343
2423
|
encoding: "utf-8"
|
|
2344
2424
|
});
|
|
@@ -2349,7 +2429,7 @@ async function checkAndUpdateCliViaBrew() {
|
|
|
2349
2429
|
const latest = agtOutdated.current_version ?? "unknown";
|
|
2350
2430
|
log(`[self-update] agt CLI update available: ${installed} \u2192 ${latest}. Upgrading via brew...`);
|
|
2351
2431
|
try {
|
|
2352
|
-
|
|
2432
|
+
execFileSync4(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
|
|
2353
2433
|
timeout: 12e4,
|
|
2354
2434
|
stdio: "pipe"
|
|
2355
2435
|
});
|
|
@@ -2368,7 +2448,7 @@ async function checkAndUpdateCliViaBrew() {
|
|
|
2368
2448
|
}
|
|
2369
2449
|
}
|
|
2370
2450
|
async function checkAndUpdateCliViaNpm() {
|
|
2371
|
-
const { execFileSync:
|
|
2451
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2372
2452
|
if (agtCliVersion === "dev") return;
|
|
2373
2453
|
let latest;
|
|
2374
2454
|
try {
|
|
@@ -2417,7 +2497,7 @@ async function checkAndUpdateCliViaNpm() {
|
|
|
2417
2497
|
"--registry=https://registry.npmjs.org"
|
|
2418
2498
|
];
|
|
2419
2499
|
try {
|
|
2420
|
-
|
|
2500
|
+
execFileSync4(cmd, args, { timeout: 18e4, stdio: "pipe" });
|
|
2421
2501
|
log(`[self-update] agt CLI upgraded to ${latest}. Scheduling manager restart so the new binary takes effect.`);
|
|
2422
2502
|
restartAfterUpgrade = true;
|
|
2423
2503
|
pendingUpgradeVersion = latest;
|
|
@@ -2895,6 +2975,7 @@ Automatic restart failed: ${err.message}`
|
|
|
2895
2975
|
}
|
|
2896
2976
|
}
|
|
2897
2977
|
}
|
|
2978
|
+
var consecutivePollFailures = 0;
|
|
2898
2979
|
async function pollCycle() {
|
|
2899
2980
|
if (!config) return;
|
|
2900
2981
|
if (restartAfterUpgrade) return;
|
|
@@ -2963,7 +3044,7 @@ async function pollCycle() {
|
|
|
2963
3044
|
}
|
|
2964
3045
|
try {
|
|
2965
3046
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
2966
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
3047
|
+
const { collectDiagnostics } = await import("../persistent-session-BVR3HES5.js");
|
|
2967
3048
|
const diagCodeNames = [...persistentSessionAgents];
|
|
2968
3049
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
2969
3050
|
let tailscaleHostname;
|
|
@@ -3193,17 +3274,23 @@ async function pollCycle() {
|
|
|
3193
3274
|
pollCount: state.pollCount + 1,
|
|
3194
3275
|
agents: agentStates
|
|
3195
3276
|
};
|
|
3277
|
+
if (consecutivePollFailures > 0) {
|
|
3278
|
+
log(`[poll-backoff] recovered after ${consecutivePollFailures} failure(s), resuming normal interval`);
|
|
3279
|
+
consecutivePollFailures = 0;
|
|
3280
|
+
}
|
|
3196
3281
|
send({ type: "state-update", state });
|
|
3197
3282
|
} catch (err) {
|
|
3198
3283
|
state.errorCount++;
|
|
3199
3284
|
const message = err.message;
|
|
3200
3285
|
log(`Poll error: ${message}`);
|
|
3201
3286
|
send({ type: "error", message });
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3287
|
+
consecutivePollFailures += 1;
|
|
3288
|
+
const scheduledDelayMs = Math.max(
|
|
3289
|
+
config?.intervalMs ?? 0,
|
|
3290
|
+
currentPollBackoffMs(consecutivePollFailures)
|
|
3291
|
+
);
|
|
3292
|
+
const errorClass = classifyPollError(message);
|
|
3293
|
+
log(`[poll-backoff] attempt=${consecutivePollFailures} class=${errorClass} next_retry_ms=${scheduledDelayMs}`);
|
|
3207
3294
|
}
|
|
3208
3295
|
}
|
|
3209
3296
|
async function getOrCacheRegisteredAgents(adapter, profile) {
|
|
@@ -4136,6 +4223,24 @@ async function processAgent(agent, agentStates) {
|
|
|
4136
4223
|
} catch (err) {
|
|
4137
4224
|
log(`[hot-reload] .mcp.json drift check failed for '${agent.code_name}': ${err.message}`);
|
|
4138
4225
|
}
|
|
4226
|
+
try {
|
|
4227
|
+
const sess = getSessionState(agent.code_name);
|
|
4228
|
+
let mcpJsonParsed = null;
|
|
4229
|
+
try {
|
|
4230
|
+
const mcpPath = join4(getProjectDir2(agent.code_name), ".mcp.json");
|
|
4231
|
+
mcpJsonParsed = JSON.parse(readFileSync3(mcpPath, "utf-8"));
|
|
4232
|
+
} catch {
|
|
4233
|
+
}
|
|
4234
|
+
reapMissingMcpSessions({
|
|
4235
|
+
log,
|
|
4236
|
+
codeName: agent.code_name,
|
|
4237
|
+
mcpJson: mcpJsonParsed,
|
|
4238
|
+
sessionStartedAt: sess?.startedAt ?? null,
|
|
4239
|
+
stopSession: (codeName) => stopPersistentSessionAndForgetMcpBaseline(codeName)
|
|
4240
|
+
});
|
|
4241
|
+
} catch (err) {
|
|
4242
|
+
log(`[mcp-presence-reaper] presence check failed for '${agent.code_name}': ${err.message}`);
|
|
4243
|
+
}
|
|
4139
4244
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
4140
4245
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
4141
4246
|
} else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
|
|
@@ -4951,6 +5056,11 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
4951
5056
|
} catch (err) {
|
|
4952
5057
|
log(`[persistent-session] Failed to provision isolation hook for '${codeName}': ${err.message}`);
|
|
4953
5058
|
}
|
|
5059
|
+
const sessionRunResult = await startRun({
|
|
5060
|
+
agent_id: agent.agent_id,
|
|
5061
|
+
source_type: "system",
|
|
5062
|
+
metadata: { type: "persistent_session_boot" }
|
|
5063
|
+
});
|
|
4954
5064
|
startPersistentSession({
|
|
4955
5065
|
codeName,
|
|
4956
5066
|
agentId: agent.agent_id,
|
|
@@ -4962,6 +5072,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
4962
5072
|
apiHost: requireHost(),
|
|
4963
5073
|
claudeAuthMode,
|
|
4964
5074
|
anthropicApiKey,
|
|
5075
|
+
runId: sessionRunResult.run_id,
|
|
4965
5076
|
log
|
|
4966
5077
|
});
|
|
4967
5078
|
persistentSessionAgents.add(codeName);
|
|
@@ -6299,7 +6410,7 @@ async function processClaudePairSessions(agents) {
|
|
|
6299
6410
|
killPairSession,
|
|
6300
6411
|
pairTmuxSession,
|
|
6301
6412
|
finalizeClaudePairOnboarding
|
|
6302
|
-
} = await import("../claude-pair-runtime-
|
|
6413
|
+
} = await import("../claude-pair-runtime-WA4BYPN5.js");
|
|
6303
6414
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
6304
6415
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
6305
6416
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -6810,13 +6921,15 @@ function scheduleNext() {
|
|
|
6810
6921
|
restartNow();
|
|
6811
6922
|
return;
|
|
6812
6923
|
}
|
|
6924
|
+
const backoffMs = currentPollBackoffMs(consecutivePollFailures);
|
|
6925
|
+
const delayMs = Math.max(config.intervalMs, backoffMs);
|
|
6813
6926
|
pollTimer = setTimeout(() => {
|
|
6814
6927
|
if (restartAfterUpgrade) {
|
|
6815
6928
|
restartNow();
|
|
6816
6929
|
return;
|
|
6817
6930
|
}
|
|
6818
6931
|
void pollCycle().then(scheduleNext);
|
|
6819
|
-
},
|
|
6932
|
+
}, delayMs);
|
|
6820
6933
|
}
|
|
6821
6934
|
async function killAllAgtTmuxSessions() {
|
|
6822
6935
|
try {
|