@integrity-labs/agt-cli 0.28.408 → 0.28.410
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 +4 -4
- package/dist/{chunk-DRWBCTED.js → chunk-QZEA7FWB.js} +23 -3
- package/dist/{chunk-DRWBCTED.js.map → chunk-QZEA7FWB.js.map} +1 -1
- package/dist/{chunk-G7M7OFCG.js → chunk-YLLK4G3B.js} +31 -2
- package/dist/{chunk-G7M7OFCG.js.map → chunk-YLLK4G3B.js.map} +1 -1
- package/dist/{claude-pair-runtime-WWTKA7QC.js → claude-pair-runtime-XGPENQB7.js} +2 -2
- package/dist/lib/manager-worker.js +146 -104
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +9 -0
- package/dist/mcp/origami.js +9 -0
- package/dist/mcp/slack-channel.js +9 -0
- package/dist/mcp/telegram-channel.js +9 -0
- package/dist/{persistent-session-WYGZTU4O.js → persistent-session-W5QSIM7F.js} +2 -2
- package/dist/{responsiveness-probe-Z6XRHNMB.js → responsiveness-probe-B7XCQQN4.js} +2 -2
- package/package.json +1 -1
- /package/dist/{claude-pair-runtime-WWTKA7QC.js.map → claude-pair-runtime-XGPENQB7.js.map} +0 -0
- /package/dist/{persistent-session-WYGZTU4O.js.map → persistent-session-W5QSIM7F.js.map} +0 -0
- /package/dist/{responsiveness-probe-Z6XRHNMB.js.map → responsiveness-probe-B7XCQQN4.js.map} +0 -0
|
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
|
|
|
100
100
|
return { ok: true };
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
const { resolveClaudeBinary } = await import("./persistent-session-
|
|
103
|
+
const { resolveClaudeBinary } = await import("./persistent-session-W5QSIM7F.js");
|
|
104
104
|
const claudeBin = resolveClaudeBinary();
|
|
105
105
|
const pairEnv = {
|
|
106
106
|
...process.env,
|
|
@@ -373,4 +373,4 @@ export {
|
|
|
373
373
|
startClaudePair,
|
|
374
374
|
submitClaudePairCode
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=claude-pair-runtime-
|
|
376
|
+
//# sourceMappingURL=claude-pair-runtime-XGPENQB7.js.map
|
|
@@ -45,7 +45,7 @@ import {
|
|
|
45
45
|
resolveEffectivePinRaw,
|
|
46
46
|
safeWriteJsonAtomic,
|
|
47
47
|
setConfigHash
|
|
48
|
-
} from "../chunk-
|
|
48
|
+
} from "../chunk-QZEA7FWB.js";
|
|
49
49
|
import {
|
|
50
50
|
getProjectDir as getProjectDir2,
|
|
51
51
|
getReadyTasks,
|
|
@@ -147,7 +147,7 @@ import {
|
|
|
147
147
|
toOpencodeModel,
|
|
148
148
|
transcriptActivityAgeSeconds,
|
|
149
149
|
writeEgressAllowlist
|
|
150
|
-
} from "../chunk-
|
|
150
|
+
} from "../chunk-YLLK4G3B.js";
|
|
151
151
|
import {
|
|
152
152
|
reapOrphanChannelMcps
|
|
153
153
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -1207,7 +1207,7 @@ function isManagedMcpServerKey(key) {
|
|
|
1207
1207
|
function isRemoteMcpEntry(value) {
|
|
1208
1208
|
if (!value || typeof value !== "object") return false;
|
|
1209
1209
|
const e = value;
|
|
1210
|
-
return e.type === "http" || e.type === "sse" || typeof e.url === "string" && e.command === void 0;
|
|
1210
|
+
return e.type === "http" || e.type === "sse" || e.type === "remote" || typeof e.url === "string" && e.command === void 0;
|
|
1211
1211
|
}
|
|
1212
1212
|
function orphanedRemoteMcpKeys(mcpServers, expectedIntegrationKeys) {
|
|
1213
1213
|
const orphans = [];
|
|
@@ -1588,6 +1588,10 @@ function decideMaintenanceWindowGate(opts) {
|
|
|
1588
1588
|
function shouldConsumeForcedUpdate(outcome) {
|
|
1589
1589
|
return outcome !== "failed";
|
|
1590
1590
|
}
|
|
1591
|
+
var FORCED_UPDATE_DEFER_ESCALATE_AFTER = 20;
|
|
1592
|
+
function shouldRelaxForcedUpdateIdleGate(deferStreak) {
|
|
1593
|
+
return deferStreak >= FORCED_UPDATE_DEFER_ESCALATE_AFTER;
|
|
1594
|
+
}
|
|
1591
1595
|
function decideForcedUpdate(opts) {
|
|
1592
1596
|
const { requestedAt, lastProcessedAt, hostBusy } = opts;
|
|
1593
1597
|
if (!requestedAt) return "none";
|
|
@@ -8931,14 +8935,20 @@ function restartGateFor(codeName, reason) {
|
|
|
8931
8935
|
now: /* @__PURE__ */ new Date()
|
|
8932
8936
|
});
|
|
8933
8937
|
}
|
|
8934
|
-
function isHostBusyForForcedUpdate() {
|
|
8938
|
+
function isHostBusyForForcedUpdate(opts) {
|
|
8935
8939
|
const now = /* @__PURE__ */ new Date();
|
|
8936
8940
|
for (const agent of state6.agents) {
|
|
8937
8941
|
const decision = decideRestartGate({
|
|
8938
8942
|
window: null,
|
|
8939
8943
|
paneLogAgeSeconds: paneLogAgeSecondsFor(agent.codeName),
|
|
8940
8944
|
transcriptAgeSeconds: transcriptAgeSecondsFor(agent.codeName),
|
|
8941
|
-
|
|
8945
|
+
// ENG-8079: past the defer-streak threshold, drop the inbound-quiet axis
|
|
8946
|
+
// and gate on progress alone. Passing null means "no signal" for that axis
|
|
8947
|
+
// (see decideRestartGate), so only transcript/pane progress governs — an
|
|
8948
|
+
// agent mid-turn still defers, an agent that merely received a message in
|
|
8949
|
+
// the last 5 minutes no longer does. On a 14-agent host the inbound axis
|
|
8950
|
+
// is what made the gate un-satisfiable in practice.
|
|
8951
|
+
inboundAgeSeconds: opts?.relaxed ? null : inboundAgeSecondsFor(agent.codeName),
|
|
8942
8952
|
now,
|
|
8943
8953
|
env: {}
|
|
8944
8954
|
});
|
|
@@ -8946,6 +8956,66 @@ function isHostBusyForForcedUpdate() {
|
|
|
8946
8956
|
}
|
|
8947
8957
|
return false;
|
|
8948
8958
|
}
|
|
8959
|
+
function runPendingForcedUpdate() {
|
|
8960
|
+
const requestedUpdateAt = cachedUpdateRequestedAt;
|
|
8961
|
+
const relaxed = shouldRelaxForcedUpdateIdleGate(forcedUpdateDeferStreak);
|
|
8962
|
+
const forcedUpdate = decideForcedUpdate({
|
|
8963
|
+
requestedAt: requestedUpdateAt,
|
|
8964
|
+
lastProcessedAt: state6.lastUpdateRequestProcessedAt ?? null,
|
|
8965
|
+
hostBusy: isHostBusyForForcedUpdate({ relaxed })
|
|
8966
|
+
});
|
|
8967
|
+
if (forcedUpdate !== "defer-idle") forcedUpdateDeferStreak = 0;
|
|
8968
|
+
if (forcedUpdate === "none" || forcedUpdate === "already-handled") return false;
|
|
8969
|
+
if (forcedUpdate === "defer-idle") {
|
|
8970
|
+
forcedUpdateDeferStreak += 1;
|
|
8971
|
+
if (forcedUpdateDeferStreak === 1 || forcedUpdateDeferStreak % 10 === 0) {
|
|
8972
|
+
log(
|
|
8973
|
+
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: an agent is mid-turn / recently active (consecutive defers: ${forcedUpdateDeferStreak}). Retrying next poll.`
|
|
8974
|
+
);
|
|
8975
|
+
}
|
|
8976
|
+
if (forcedUpdateDeferStreak === FORCED_UPDATE_DEFER_ESCALATE_AFTER) {
|
|
8977
|
+
log(
|
|
8978
|
+
`[self-update] WARN "Update CLI now" has deferred ${forcedUpdateDeferStreak} consecutive polls waiting for an idle host. Relaxing the idle gate to the progress axis only (an agent actively producing tokens still defers; "received a message in the last 5 minutes" no longer does).`
|
|
8979
|
+
);
|
|
8980
|
+
}
|
|
8981
|
+
return false;
|
|
8982
|
+
}
|
|
8983
|
+
if (selfUpdateInFlight) {
|
|
8984
|
+
log(
|
|
8985
|
+
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: a self-update is already in flight. Retrying next poll.`
|
|
8986
|
+
);
|
|
8987
|
+
return false;
|
|
8988
|
+
}
|
|
8989
|
+
log(
|
|
8990
|
+
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 running window-bypassing self-update now (host idle${relaxed ? ", relaxed gate" : ""}).`
|
|
8991
|
+
);
|
|
8992
|
+
const prevProcessedAt = state6.lastUpdateRequestProcessedAt ?? null;
|
|
8993
|
+
void checkAndUpdateCli({ force: true }).then((outcome) => {
|
|
8994
|
+
if (!shouldConsumeForcedUpdate(outcome)) {
|
|
8995
|
+
log(
|
|
8996
|
+
`[self-update] "Update CLI now" did not complete (no install ran) \u2014 leaving the request pending; the next idle poll retries.`
|
|
8997
|
+
);
|
|
8998
|
+
return;
|
|
8999
|
+
}
|
|
9000
|
+
log(
|
|
9001
|
+
outcome === "updated" ? `[self-update] "Update CLI now" completed \u2014 upgrade installed; manager restart scheduled.` : `[self-update] "Update CLI now" completed \u2014 host was already on the latest in-channel build; nothing to install.`
|
|
9002
|
+
);
|
|
9003
|
+
state6.lastUpdateRequestProcessedAt = requestedUpdateAt;
|
|
9004
|
+
try {
|
|
9005
|
+
atomicWriteFileSync(getStateFile(), JSON.stringify(state6, null, 2));
|
|
9006
|
+
} catch (err) {
|
|
9007
|
+
state6.lastUpdateRequestProcessedAt = prevProcessedAt;
|
|
9008
|
+
log(
|
|
9009
|
+
`[self-update] failed to persist update-request ack; retrying next poll: ${err.message}`
|
|
9010
|
+
);
|
|
9011
|
+
}
|
|
9012
|
+
}).catch((err) => {
|
|
9013
|
+
log(
|
|
9014
|
+
`[self-update] forced check failed: ${err.message} \u2014 leaving the request pending for retry.`
|
|
9015
|
+
);
|
|
9016
|
+
});
|
|
9017
|
+
return true;
|
|
9018
|
+
}
|
|
8949
9019
|
var runningMcpHashes = /* @__PURE__ */ new Map();
|
|
8950
9020
|
var anchorSessionLifecycle = new AnchorSessionLifecycle();
|
|
8951
9021
|
var runningMcpServerKeys = /* @__PURE__ */ new Map();
|
|
@@ -9307,7 +9377,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9307
9377
|
var lastVersionCheckAt = 0;
|
|
9308
9378
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9309
9379
|
var lastResponsivenessProbeAt = 0;
|
|
9310
|
-
var agtCliVersion = true ? "0.28.
|
|
9380
|
+
var agtCliVersion = true ? "0.28.410" : "dev";
|
|
9311
9381
|
function resolveBrewPath(execFileSync2) {
|
|
9312
9382
|
try {
|
|
9313
9383
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -9776,6 +9846,8 @@ var selfUpdatePinInvalidLogged = false;
|
|
|
9776
9846
|
var restartAfterUpgrade = false;
|
|
9777
9847
|
var pendingUpgradeVersion = null;
|
|
9778
9848
|
var selfUpdateInFlight = false;
|
|
9849
|
+
var cachedUpdateRequestedAt = null;
|
|
9850
|
+
var forcedUpdateDeferStreak = 0;
|
|
9779
9851
|
async function checkAndUpdateCli(opts) {
|
|
9780
9852
|
const force = opts?.force ?? false;
|
|
9781
9853
|
if (selfUpdateInFlight) return "failed";
|
|
@@ -9954,27 +10026,41 @@ async function checkAndUpdateCliViaNpm(force = false) {
|
|
|
9954
10026
|
);
|
|
9955
10027
|
return await installAgtCliViaNpm(pinDecision.version, `pin=${pinDecision.version}`);
|
|
9956
10028
|
}
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
10029
|
+
const REGISTRY_TIMEOUT_MS = 1e4;
|
|
10030
|
+
const registryAttempts = force ? 2 : 1;
|
|
10031
|
+
let latest = null;
|
|
10032
|
+
let lastFetchErr = "";
|
|
10033
|
+
for (let attempt = 1; attempt <= registryAttempts; attempt++) {
|
|
10034
|
+
try {
|
|
10035
|
+
const res = await fetch(
|
|
10036
|
+
`https://registry.npmjs.org/@integrity-labs/agt-cli/${encodeURIComponent(channel)}`,
|
|
10037
|
+
{
|
|
10038
|
+
signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),
|
|
10039
|
+
headers: { Accept: "application/json" }
|
|
10040
|
+
}
|
|
10041
|
+
);
|
|
10042
|
+
if (!res.ok) {
|
|
10043
|
+
log(`[self-update] npm registry returned ${res.status} (channel=${channel})`);
|
|
10044
|
+
return "failed";
|
|
10045
|
+
}
|
|
10046
|
+
const body = await res.json();
|
|
10047
|
+
if (!body.version) {
|
|
10048
|
+
log(`[self-update] npm registry response missing version field`);
|
|
10049
|
+
return "failed";
|
|
10050
|
+
}
|
|
10051
|
+
latest = body.version;
|
|
10052
|
+
break;
|
|
10053
|
+
} catch (err) {
|
|
10054
|
+
lastFetchErr = err.message;
|
|
10055
|
+
if (attempt < registryAttempts) {
|
|
10056
|
+
log(
|
|
10057
|
+
`[self-update] npm registry fetch failed (attempt ${attempt}/${registryAttempts}): ${lastFetchErr} \u2014 retrying.`
|
|
10058
|
+
);
|
|
9964
10059
|
}
|
|
9965
|
-
);
|
|
9966
|
-
if (!res.ok) {
|
|
9967
|
-
log(`[self-update] npm registry returned ${res.status} (channel=${channel})`);
|
|
9968
|
-
return "failed";
|
|
9969
|
-
}
|
|
9970
|
-
const body = await res.json();
|
|
9971
|
-
if (!body.version) {
|
|
9972
|
-
log(`[self-update] npm registry response missing version field`);
|
|
9973
|
-
return "failed";
|
|
9974
10060
|
}
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
log(`[self-update] npm registry fetch failed: ${
|
|
10061
|
+
}
|
|
10062
|
+
if (latest === null) {
|
|
10063
|
+
log(`[self-update] npm registry fetch failed: ${lastFetchErr}`);
|
|
9978
10064
|
return "failed";
|
|
9979
10065
|
}
|
|
9980
10066
|
const urgentTarget = await fetchUrgentDistTagVersion();
|
|
@@ -10439,7 +10525,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10439
10525
|
if (codeNames.length === 0) return;
|
|
10440
10526
|
void (async () => {
|
|
10441
10527
|
try {
|
|
10442
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10528
|
+
const { collectDiagnostics } = await import("../persistent-session-W5QSIM7F.js");
|
|
10443
10529
|
await api.post("/host/heartbeat", {
|
|
10444
10530
|
host_id: hostId,
|
|
10445
10531
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor)
|
|
@@ -10515,7 +10601,15 @@ async function pollCycle() {
|
|
|
10515
10601
|
} catch (err) {
|
|
10516
10602
|
log(`[restart-handler] processRestartFlags threw: ${err.message}`);
|
|
10517
10603
|
}
|
|
10518
|
-
|
|
10604
|
+
let forcedUpdateKicked = false;
|
|
10605
|
+
try {
|
|
10606
|
+
forcedUpdateKicked = runPendingForcedUpdate();
|
|
10607
|
+
} catch (err) {
|
|
10608
|
+
log(`[self-update] runPendingForcedUpdate threw: ${err.message}`);
|
|
10609
|
+
}
|
|
10610
|
+
if (!forcedUpdateKicked) {
|
|
10611
|
+
checkAndUpdateCli().catch((err) => log(`[self-update] Check failed: ${err.message}`));
|
|
10612
|
+
}
|
|
10519
10613
|
maybeUpgradeClaudeCode().catch((err) => log(`[claude-code-upgrade] Check failed: ${err.message}`));
|
|
10520
10614
|
try {
|
|
10521
10615
|
registeredAgentsCache.clear();
|
|
@@ -10538,7 +10632,7 @@ async function pollCycle() {
|
|
|
10538
10632
|
}
|
|
10539
10633
|
try {
|
|
10540
10634
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
10541
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10635
|
+
const { collectDiagnostics } = await import("../persistent-session-W5QSIM7F.js");
|
|
10542
10636
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
10543
10637
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor) : void 0;
|
|
10544
10638
|
let tailscaleHostname;
|
|
@@ -10625,49 +10719,7 @@ async function pollCycle() {
|
|
|
10625
10719
|
cachedDesiredAgtCliVersion = hbResp.desired_agt_cli_version ?? null;
|
|
10626
10720
|
}
|
|
10627
10721
|
}
|
|
10628
|
-
|
|
10629
|
-
const forcedUpdate = decideForcedUpdate({
|
|
10630
|
-
requestedAt: requestedUpdateAt,
|
|
10631
|
-
lastProcessedAt: state6.lastUpdateRequestProcessedAt ?? null,
|
|
10632
|
-
hostBusy: isHostBusyForForcedUpdate()
|
|
10633
|
-
});
|
|
10634
|
-
if (forcedUpdate === "defer-idle") {
|
|
10635
|
-
log(
|
|
10636
|
-
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: an agent is mid-turn / recently active. Retrying next poll.`
|
|
10637
|
-
);
|
|
10638
|
-
} else if (forcedUpdate === "consume") {
|
|
10639
|
-
if (selfUpdateInFlight) {
|
|
10640
|
-
log(
|
|
10641
|
-
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: a self-update is already in flight. Retrying next poll.`
|
|
10642
|
-
);
|
|
10643
|
-
} else {
|
|
10644
|
-
log(
|
|
10645
|
-
`[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 running window-bypassing self-update now (host idle).`
|
|
10646
|
-
);
|
|
10647
|
-
const prevProcessedAt = state6.lastUpdateRequestProcessedAt ?? null;
|
|
10648
|
-
void checkAndUpdateCli({ force: true }).then((outcome) => {
|
|
10649
|
-
if (!shouldConsumeForcedUpdate(outcome)) {
|
|
10650
|
-
log(
|
|
10651
|
-
`[self-update] "Update CLI now" did not complete (no install ran) \u2014 leaving the request pending; the next idle heartbeat retries.`
|
|
10652
|
-
);
|
|
10653
|
-
return;
|
|
10654
|
-
}
|
|
10655
|
-
state6.lastUpdateRequestProcessedAt = requestedUpdateAt;
|
|
10656
|
-
try {
|
|
10657
|
-
atomicWriteFileSync(getStateFile(), JSON.stringify(state6, null, 2));
|
|
10658
|
-
} catch (err) {
|
|
10659
|
-
state6.lastUpdateRequestProcessedAt = prevProcessedAt;
|
|
10660
|
-
log(
|
|
10661
|
-
`[self-update] failed to persist update-request ack; retrying next heartbeat: ${err.message}`
|
|
10662
|
-
);
|
|
10663
|
-
}
|
|
10664
|
-
}).catch((err) => {
|
|
10665
|
-
log(
|
|
10666
|
-
`[self-update] forced check failed: ${err.message} \u2014 leaving the request pending for retry.`
|
|
10667
|
-
);
|
|
10668
|
-
});
|
|
10669
|
-
}
|
|
10670
|
-
}
|
|
10722
|
+
cachedUpdateRequestedAt = hbResp?.update_requested_at ?? null;
|
|
10671
10723
|
if (hbResp?.feature_flags) {
|
|
10672
10724
|
hostFlagStore().applyHeartbeat(hbResp.feature_flags, hbResp.flags_schema_version);
|
|
10673
10725
|
}
|
|
@@ -10693,7 +10745,7 @@ async function pollCycle() {
|
|
|
10693
10745
|
const {
|
|
10694
10746
|
collectResponsivenessProbes,
|
|
10695
10747
|
getResponsivenessIntervalMs
|
|
10696
|
-
} = await import("../responsiveness-probe-
|
|
10748
|
+
} = await import("../responsiveness-probe-B7XCQQN4.js");
|
|
10697
10749
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
10698
10750
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
10699
10751
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -10725,7 +10777,7 @@ async function pollCycle() {
|
|
|
10725
10777
|
collectResponsivenessProbes,
|
|
10726
10778
|
livePendingInboundOldestAgeSeconds,
|
|
10727
10779
|
parkPendingInbound
|
|
10728
|
-
} = await import("../responsiveness-probe-
|
|
10780
|
+
} = await import("../responsiveness-probe-B7XCQQN4.js");
|
|
10729
10781
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-HYOOQV4A.js");
|
|
10730
10782
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
10731
10783
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -12364,21 +12416,18 @@ async function processAgent(agent, agentStates) {
|
|
|
12364
12416
|
else promptBindProbeAttempts.delete(agent.code_name);
|
|
12365
12417
|
}
|
|
12366
12418
|
}
|
|
12367
|
-
if (frameworkAdapter.removeMcpServer && frameworkAdapter.
|
|
12368
|
-
|
|
12369
|
-
|
|
12370
|
-
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
);
|
|
12375
|
-
|
|
12376
|
-
frameworkAdapter.removeMcpServer(agent.code_name, key);
|
|
12377
|
-
log(`[hot-reload] Removed orphaned remote MCP server '${key}' for '${agent.code_name}' (integration removed)`);
|
|
12378
|
-
}
|
|
12379
|
-
} catch (err) {
|
|
12380
|
-
log(`[hot-reload] Failed to prune orphaned remote MCP servers for '${agent.code_name}': ${err.message}`);
|
|
12419
|
+
if (frameworkAdapter.removeMcpServer && frameworkAdapter.readMcpServers) {
|
|
12420
|
+
try {
|
|
12421
|
+
const declaredServers = frameworkAdapter.readMcpServers(agent.code_name);
|
|
12422
|
+
const expectedRemoteKeys = new Set(
|
|
12423
|
+
integrations.map((i) => i.definition_id)
|
|
12424
|
+
);
|
|
12425
|
+
for (const key of orphanedRemoteMcpKeys(declaredServers, expectedRemoteKeys)) {
|
|
12426
|
+
frameworkAdapter.removeMcpServer(agent.code_name, key);
|
|
12427
|
+
log(`[hot-reload] Removed orphaned remote MCP server '${key}' for '${agent.code_name}' (integration removed)`);
|
|
12381
12428
|
}
|
|
12429
|
+
} catch (err) {
|
|
12430
|
+
log(`[hot-reload] Failed to prune orphaned remote MCP servers for '${agent.code_name}': ${err.message}`);
|
|
12382
12431
|
}
|
|
12383
12432
|
}
|
|
12384
12433
|
const currentIntIds = integrations.map((i) => i.definition_id);
|
|
@@ -12560,22 +12609,15 @@ async function processAgent(agent, agentStates) {
|
|
|
12560
12609
|
const urlHash = createHash14("sha256").update(e.url).digest("hex").slice(0, 12);
|
|
12561
12610
|
log(`[managed-toolkit] ${agent.code_name}: wrote '${e.name}' (serverId=${e.serverId}, url_hash=${urlHash})`);
|
|
12562
12611
|
}
|
|
12563
|
-
if (frameworkAdapter.removeMcpServer && frameworkAdapter.
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
if (mcpConfig.mcpServers) {
|
|
12570
|
-
for (const key of Object.keys(mcpConfig.mcpServers)) {
|
|
12571
|
-
if (isManagedMcpServerKey(key) && !expectedServerIds.has(key)) {
|
|
12572
|
-
frameworkAdapter.removeMcpServer(agent.code_name, key);
|
|
12573
|
-
log(`[managed-toolkit] Removed stale MCP server '${key}' for '${agent.code_name}'`);
|
|
12574
|
-
}
|
|
12575
|
-
}
|
|
12612
|
+
if (frameworkAdapter.removeMcpServer && frameworkAdapter.readMcpServers) {
|
|
12613
|
+
try {
|
|
12614
|
+
for (const key of Object.keys(frameworkAdapter.readMcpServers(agent.code_name))) {
|
|
12615
|
+
if (isManagedMcpServerKey(key) && !expectedServerIds.has(key)) {
|
|
12616
|
+
frameworkAdapter.removeMcpServer(agent.code_name, key);
|
|
12617
|
+
log(`[managed-toolkit] Removed stale MCP server '${key}' for '${agent.code_name}'`);
|
|
12576
12618
|
}
|
|
12577
|
-
} catch {
|
|
12578
12619
|
}
|
|
12620
|
+
} catch {
|
|
12579
12621
|
}
|
|
12580
12622
|
}
|
|
12581
12623
|
agentState.knownManagedMcpHashes.set(agent.agent_id, mcpHash);
|
|
@@ -14037,7 +14079,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
14037
14079
|
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}`));
|
|
14038
14080
|
void (async () => {
|
|
14039
14081
|
try {
|
|
14040
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14082
|
+
const { collectDiagnostics } = await import("../persistent-session-W5QSIM7F.js");
|
|
14041
14083
|
await api.post("/host/heartbeat", {
|
|
14042
14084
|
host_id: hostId,
|
|
14043
14085
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
|
|
@@ -14087,7 +14129,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
14087
14129
|
}
|
|
14088
14130
|
try {
|
|
14089
14131
|
const hostId = await getHostId();
|
|
14090
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14132
|
+
const { collectDiagnostics } = await import("../persistent-session-W5QSIM7F.js");
|
|
14091
14133
|
await api.post("/host/heartbeat", {
|
|
14092
14134
|
host_id: hostId,
|
|
14093
14135
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
|
|
@@ -14540,7 +14582,7 @@ async function processClaudePairSessions(agents) {
|
|
|
14540
14582
|
killPairSession,
|
|
14541
14583
|
pairTmuxSession,
|
|
14542
14584
|
finalizeClaudePairOnboarding
|
|
14543
|
-
} = await import("../claude-pair-runtime-
|
|
14585
|
+
} = await import("../claude-pair-runtime-XGPENQB7.js");
|
|
14544
14586
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
14545
14587
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
14546
14588
|
const killed = await killPairSession(pairTmuxSession(pairId));
|