@integrity-labs/agt-cli 0.19.22 → 0.19.25
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-TD4ZSQ74.js → chunk-EJKRQX3I.js} +1 -1
- package/dist/{chunk-3K3RO5NS.js → chunk-ZQNOWGHB.js} +4 -1
- package/dist/chunk-ZQNOWGHB.js.map +1 -0
- package/dist/{claude-pair-runtime-UF4OMFCA.js → claude-pair-runtime-LI2ISCVI.js} +2 -2
- package/dist/lib/manager-worker.js +146 -34
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/{persistent-session-M2GVL6Z6.js → persistent-session-J2K3JFJQ.js} +2 -2
- package/mcp/slack-channel.js +5 -2
- package/package.json +24 -24
- package/dist/chunk-3K3RO5NS.js.map +0 -1
- /package/dist/{chunk-TD4ZSQ74.js.map → chunk-EJKRQX3I.js.map} +0 -0
- /package/dist/{claude-pair-runtime-UF4OMFCA.js.map → claude-pair-runtime-LI2ISCVI.js.map} +0 -0
- /package/dist/{persistent-session-M2GVL6Z6.js.map → persistent-session-J2K3JFJQ.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveChannels,
|
|
23
23
|
resolveDmTarget,
|
|
24
24
|
wrapScheduledTaskPrompt
|
|
25
|
-
} from "../chunk-
|
|
25
|
+
} from "../chunk-EJKRQX3I.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-ZQNOWGHB.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
|
|
@@ -2060,10 +2139,10 @@ function clearAgentCaches(agentId, codeName) {
|
|
|
2060
2139
|
var cachedFrameworkVersion = null;
|
|
2061
2140
|
var lastVersionCheckAt = 0;
|
|
2062
2141
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2063
|
-
var agtCliVersion = true ? "0.19.
|
|
2064
|
-
function resolveBrewPath(
|
|
2142
|
+
var agtCliVersion = true ? "0.19.25" : "dev";
|
|
2143
|
+
function resolveBrewPath(execFileSync4) {
|
|
2065
2144
|
try {
|
|
2066
|
-
const out =
|
|
2145
|
+
const out = execFileSync4("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
2067
2146
|
if (out) return out;
|
|
2068
2147
|
} catch {
|
|
2069
2148
|
}
|
|
@@ -2105,9 +2184,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2105
2184
|
}
|
|
2106
2185
|
const { binary, installer, package: pkg, script } = integration.cli_tool;
|
|
2107
2186
|
const resolvedInstaller = installer ?? "manual";
|
|
2108
|
-
const { execFileSync:
|
|
2187
|
+
const { execFileSync: execFileSync4, execSync } = await import("child_process");
|
|
2109
2188
|
try {
|
|
2110
|
-
|
|
2189
|
+
execFileSync4("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
2111
2190
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2112
2191
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
2113
2192
|
toolkitCliFailureCount.delete(toolkitSlug);
|
|
@@ -2128,14 +2207,14 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2128
2207
|
return;
|
|
2129
2208
|
}
|
|
2130
2209
|
log(`[toolkit-install] ${toolkitSlug}: installing via npm (${pkg})\u2026`);
|
|
2131
|
-
|
|
2210
|
+
execFileSync4("npm", ["install", "-g", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
2132
2211
|
} else if (resolvedInstaller === "brew") {
|
|
2133
2212
|
if (!pkg) {
|
|
2134
2213
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but no package declared`);
|
|
2135
2214
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2136
2215
|
return;
|
|
2137
2216
|
}
|
|
2138
|
-
const brewPath = resolveBrewPath(
|
|
2217
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2139
2218
|
if (!brewPath) {
|
|
2140
2219
|
log(`[toolkit-install] ${toolkitSlug}: installer=brew but Homebrew not available \u2014 install manually: brew install ${pkg}`);
|
|
2141
2220
|
toolkitCliEnsured.add(toolkitSlug);
|
|
@@ -2145,9 +2224,9 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2145
2224
|
const isRoot = typeof process.getuid === "function" && process.getuid() === 0;
|
|
2146
2225
|
log(`[toolkit-install] ${toolkitSlug}: installing via brew (${pkg})\u2026`);
|
|
2147
2226
|
if (isRoot) {
|
|
2148
|
-
|
|
2227
|
+
execFileSync4("sudo", ["-u", "ec2-user", "-H", brewPath, "install", pkg], { timeout: 18e4, stdio: "pipe", cwd: "/tmp" });
|
|
2149
2228
|
} else {
|
|
2150
|
-
|
|
2229
|
+
execFileSync4(brewPath, ["install", pkg], { timeout: 18e4, stdio: "pipe" });
|
|
2151
2230
|
}
|
|
2152
2231
|
} else if (resolvedInstaller === "script") {
|
|
2153
2232
|
if (!script) {
|
|
@@ -2167,7 +2246,7 @@ async function ensureToolkitCli(toolkitSlug) {
|
|
|
2167
2246
|
process.env.PATH = `${brewBinDir}:${process.env.PATH ?? ""}`;
|
|
2168
2247
|
}
|
|
2169
2248
|
try {
|
|
2170
|
-
|
|
2249
|
+
execFileSync4("which", [binary], { timeout: 5e3, stdio: "pipe" });
|
|
2171
2250
|
log(`[toolkit-install] ${toolkitSlug}: installed \u2014 ${binary} now on PATH`);
|
|
2172
2251
|
toolkitCliEnsured.add(toolkitSlug);
|
|
2173
2252
|
toolkitCliRetryAfter.delete(toolkitSlug);
|
|
@@ -2220,8 +2299,8 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
2220
2299
|
if (frameworkId !== "claude-code") return;
|
|
2221
2300
|
if (frameworkBinaryChecked.has(frameworkId)) return;
|
|
2222
2301
|
frameworkBinaryChecked.add(frameworkId);
|
|
2223
|
-
const { execFileSync:
|
|
2224
|
-
const brewPath = resolveBrewPath(
|
|
2302
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2303
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2225
2304
|
if (!brewPath) {
|
|
2226
2305
|
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
2306
|
return;
|
|
@@ -2237,7 +2316,7 @@ async function ensureFrameworkBinary(frameworkId) {
|
|
|
2237
2316
|
let claudeExists = existsSync3("/home/linuxbrew/.linuxbrew/bin/claude");
|
|
2238
2317
|
if (!claudeExists) {
|
|
2239
2318
|
try {
|
|
2240
|
-
|
|
2319
|
+
execFileSync4("which", ["claude"], { timeout: 5e3 });
|
|
2241
2320
|
claudeExists = true;
|
|
2242
2321
|
} catch {
|
|
2243
2322
|
}
|
|
@@ -2329,16 +2408,16 @@ async function checkAndUpdateCli() {
|
|
|
2329
2408
|
}
|
|
2330
2409
|
}
|
|
2331
2410
|
async function checkAndUpdateCliViaBrew() {
|
|
2332
|
-
const { execFileSync:
|
|
2333
|
-
const brewPath = resolveBrewPath(
|
|
2411
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2412
|
+
const brewPath = resolveBrewPath(execFileSync4);
|
|
2334
2413
|
if (!brewPath) return;
|
|
2335
2414
|
try {
|
|
2336
|
-
|
|
2415
|
+
execFileSync4(brewPath, ["update", "--quiet"], { timeout: 6e4, stdio: "pipe" });
|
|
2337
2416
|
} catch (err) {
|
|
2338
2417
|
log(`[self-update] brew update failed (continuing with stale cache): ${err.message}`);
|
|
2339
2418
|
}
|
|
2340
2419
|
try {
|
|
2341
|
-
const outdated =
|
|
2420
|
+
const outdated = execFileSync4(brewPath, ["outdated", "--json=v2"], {
|
|
2342
2421
|
timeout: 3e4,
|
|
2343
2422
|
encoding: "utf-8"
|
|
2344
2423
|
});
|
|
@@ -2349,7 +2428,7 @@ async function checkAndUpdateCliViaBrew() {
|
|
|
2349
2428
|
const latest = agtOutdated.current_version ?? "unknown";
|
|
2350
2429
|
log(`[self-update] agt CLI update available: ${installed} \u2192 ${latest}. Upgrading via brew...`);
|
|
2351
2430
|
try {
|
|
2352
|
-
|
|
2431
|
+
execFileSync4(brewPath, ["upgrade", "integrity-labs/tap/agt"], {
|
|
2353
2432
|
timeout: 12e4,
|
|
2354
2433
|
stdio: "pipe"
|
|
2355
2434
|
});
|
|
@@ -2368,7 +2447,7 @@ async function checkAndUpdateCliViaBrew() {
|
|
|
2368
2447
|
}
|
|
2369
2448
|
}
|
|
2370
2449
|
async function checkAndUpdateCliViaNpm() {
|
|
2371
|
-
const { execFileSync:
|
|
2450
|
+
const { execFileSync: execFileSync4 } = await import("child_process");
|
|
2372
2451
|
if (agtCliVersion === "dev") return;
|
|
2373
2452
|
let latest;
|
|
2374
2453
|
try {
|
|
@@ -2417,7 +2496,7 @@ async function checkAndUpdateCliViaNpm() {
|
|
|
2417
2496
|
"--registry=https://registry.npmjs.org"
|
|
2418
2497
|
];
|
|
2419
2498
|
try {
|
|
2420
|
-
|
|
2499
|
+
execFileSync4(cmd, args, { timeout: 18e4, stdio: "pipe" });
|
|
2421
2500
|
log(`[self-update] agt CLI upgraded to ${latest}. Scheduling manager restart so the new binary takes effect.`);
|
|
2422
2501
|
restartAfterUpgrade = true;
|
|
2423
2502
|
pendingUpgradeVersion = latest;
|
|
@@ -2895,6 +2974,7 @@ Automatic restart failed: ${err.message}`
|
|
|
2895
2974
|
}
|
|
2896
2975
|
}
|
|
2897
2976
|
}
|
|
2977
|
+
var consecutivePollFailures = 0;
|
|
2898
2978
|
async function pollCycle() {
|
|
2899
2979
|
if (!config) return;
|
|
2900
2980
|
if (restartAfterUpgrade) return;
|
|
@@ -2963,7 +3043,7 @@ async function pollCycle() {
|
|
|
2963
3043
|
}
|
|
2964
3044
|
try {
|
|
2965
3045
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
2966
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
3046
|
+
const { collectDiagnostics } = await import("../persistent-session-J2K3JFJQ.js");
|
|
2967
3047
|
const diagCodeNames = [...persistentSessionAgents];
|
|
2968
3048
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
2969
3049
|
let tailscaleHostname;
|
|
@@ -3193,17 +3273,23 @@ async function pollCycle() {
|
|
|
3193
3273
|
pollCount: state.pollCount + 1,
|
|
3194
3274
|
agents: agentStates
|
|
3195
3275
|
};
|
|
3276
|
+
if (consecutivePollFailures > 0) {
|
|
3277
|
+
log(`[poll-backoff] recovered after ${consecutivePollFailures} failure(s), resuming normal interval`);
|
|
3278
|
+
consecutivePollFailures = 0;
|
|
3279
|
+
}
|
|
3196
3280
|
send({ type: "state-update", state });
|
|
3197
3281
|
} catch (err) {
|
|
3198
3282
|
state.errorCount++;
|
|
3199
3283
|
const message = err.message;
|
|
3200
3284
|
log(`Poll error: ${message}`);
|
|
3201
3285
|
send({ type: "error", message });
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3286
|
+
consecutivePollFailures += 1;
|
|
3287
|
+
const scheduledDelayMs = Math.max(
|
|
3288
|
+
config?.intervalMs ?? 0,
|
|
3289
|
+
currentPollBackoffMs(consecutivePollFailures)
|
|
3290
|
+
);
|
|
3291
|
+
const errorClass = classifyPollError(message);
|
|
3292
|
+
log(`[poll-backoff] attempt=${consecutivePollFailures} class=${errorClass} next_retry_ms=${scheduledDelayMs}`);
|
|
3207
3293
|
}
|
|
3208
3294
|
}
|
|
3209
3295
|
async function getOrCacheRegisteredAgents(adapter, profile) {
|
|
@@ -4136,6 +4222,24 @@ async function processAgent(agent, agentStates) {
|
|
|
4136
4222
|
} catch (err) {
|
|
4137
4223
|
log(`[hot-reload] .mcp.json drift check failed for '${agent.code_name}': ${err.message}`);
|
|
4138
4224
|
}
|
|
4225
|
+
try {
|
|
4226
|
+
const sess = getSessionState(agent.code_name);
|
|
4227
|
+
let mcpJsonParsed = null;
|
|
4228
|
+
try {
|
|
4229
|
+
const mcpPath = join4(getProjectDir2(agent.code_name), ".mcp.json");
|
|
4230
|
+
mcpJsonParsed = JSON.parse(readFileSync3(mcpPath, "utf-8"));
|
|
4231
|
+
} catch {
|
|
4232
|
+
}
|
|
4233
|
+
reapMissingMcpSessions({
|
|
4234
|
+
log,
|
|
4235
|
+
codeName: agent.code_name,
|
|
4236
|
+
mcpJson: mcpJsonParsed,
|
|
4237
|
+
sessionStartedAt: sess?.startedAt ?? null,
|
|
4238
|
+
stopSession: (codeName) => stopPersistentSessionAndForgetMcpBaseline(codeName)
|
|
4239
|
+
});
|
|
4240
|
+
} catch (err) {
|
|
4241
|
+
log(`[mcp-presence-reaper] presence check failed for '${agent.code_name}': ${err.message}`);
|
|
4242
|
+
}
|
|
4139
4243
|
} else if (agentFw === "claude-code" && tasks.length > 0) {
|
|
4140
4244
|
await syncAndCheckClaudeScheduler(agent, tasks, boardItems, refreshData);
|
|
4141
4245
|
} else if (frameworkAdapter.syncScheduledTasks && gatewayRunning && gatewayPort) {
|
|
@@ -4951,6 +5055,11 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
4951
5055
|
} catch (err) {
|
|
4952
5056
|
log(`[persistent-session] Failed to provision isolation hook for '${codeName}': ${err.message}`);
|
|
4953
5057
|
}
|
|
5058
|
+
const sessionRunResult = await startRun({
|
|
5059
|
+
agent_id: agent.agent_id,
|
|
5060
|
+
source_type: "system",
|
|
5061
|
+
metadata: { type: "persistent_session_boot" }
|
|
5062
|
+
});
|
|
4954
5063
|
startPersistentSession({
|
|
4955
5064
|
codeName,
|
|
4956
5065
|
agentId: agent.agent_id,
|
|
@@ -4962,6 +5071,7 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash2("sha256").
|
|
|
4962
5071
|
apiHost: requireHost(),
|
|
4963
5072
|
claudeAuthMode,
|
|
4964
5073
|
anthropicApiKey,
|
|
5074
|
+
runId: sessionRunResult.run_id,
|
|
4965
5075
|
log
|
|
4966
5076
|
});
|
|
4967
5077
|
persistentSessionAgents.add(codeName);
|
|
@@ -6299,7 +6409,7 @@ async function processClaudePairSessions(agents) {
|
|
|
6299
6409
|
killPairSession,
|
|
6300
6410
|
pairTmuxSession,
|
|
6301
6411
|
finalizeClaudePairOnboarding
|
|
6302
|
-
} = await import("../claude-pair-runtime-
|
|
6412
|
+
} = await import("../claude-pair-runtime-LI2ISCVI.js");
|
|
6303
6413
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
6304
6414
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
6305
6415
|
const killed = await killPairSession(pairTmuxSession(pairId));
|
|
@@ -6810,13 +6920,15 @@ function scheduleNext() {
|
|
|
6810
6920
|
restartNow();
|
|
6811
6921
|
return;
|
|
6812
6922
|
}
|
|
6923
|
+
const backoffMs = currentPollBackoffMs(consecutivePollFailures);
|
|
6924
|
+
const delayMs = Math.max(config.intervalMs, backoffMs);
|
|
6813
6925
|
pollTimer = setTimeout(() => {
|
|
6814
6926
|
if (restartAfterUpgrade) {
|
|
6815
6927
|
restartNow();
|
|
6816
6928
|
return;
|
|
6817
6929
|
}
|
|
6818
6930
|
void pollCycle().then(scheduleNext);
|
|
6819
|
-
},
|
|
6931
|
+
}, delayMs);
|
|
6820
6932
|
}
|
|
6821
6933
|
async function killAllAgtTmuxSessions() {
|
|
6822
6934
|
try {
|