@integrity-labs/agt-cli 0.28.384 → 0.28.386
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-MQHDPJZD.js → chunk-LAO2CUZU.js} +20 -4
- package/dist/chunk-LAO2CUZU.js.map +1 -0
- package/dist/{chunk-IXN2AFOX.js → chunk-O37EMHVE.js} +15 -7
- package/dist/{chunk-IXN2AFOX.js.map → chunk-O37EMHVE.js.map} +1 -1
- package/dist/{claude-pair-runtime-OIK6HKPS.js → claude-pair-runtime-NVMVUAGS.js} +2 -2
- package/dist/lib/manager-worker.js +53 -14
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +13 -0
- package/dist/mcp/origami.js +13 -0
- package/dist/mcp/slack-channel.js +13 -0
- package/dist/mcp/telegram-channel.js +13 -0
- package/dist/{persistent-session-MDQVHXKX.js → persistent-session-KQHWYEQF.js} +2 -2
- package/dist/{responsiveness-probe-CG7XM7GL.js → responsiveness-probe-5X6WVKUZ.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-MQHDPJZD.js.map +0 -1
- /package/dist/{claude-pair-runtime-OIK6HKPS.js.map → claude-pair-runtime-NVMVUAGS.js.map} +0 -0
- /package/dist/{persistent-session-MDQVHXKX.js.map → persistent-session-KQHWYEQF.js.map} +0 -0
- /package/dist/{responsiveness-probe-CG7XM7GL.js.map → responsiveness-probe-5X6WVKUZ.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-KQHWYEQF.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-NVMVUAGS.js.map
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
resolveEffectivePinRaw,
|
|
44
44
|
safeWriteJsonAtomic,
|
|
45
45
|
setConfigHash
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-O37EMHVE.js";
|
|
47
47
|
import {
|
|
48
48
|
getProjectDir as getProjectDir2,
|
|
49
49
|
getReadyTasks,
|
|
@@ -145,7 +145,7 @@ import {
|
|
|
145
145
|
toOpencodeModel,
|
|
146
146
|
transcriptActivityAgeSeconds,
|
|
147
147
|
writeEgressAllowlist
|
|
148
|
-
} from "../chunk-
|
|
148
|
+
} from "../chunk-LAO2CUZU.js";
|
|
149
149
|
import {
|
|
150
150
|
reapOrphanChannelMcps
|
|
151
151
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -725,6 +725,24 @@ var ChannelQuarantineStore = class {
|
|
|
725
725
|
const forAgent = this.load()[codeName];
|
|
726
726
|
return new Set(forAgent ? Object.keys(forAgent) : []);
|
|
727
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* ENG-8018: the full quarantine entries for `codeName` (serverKey → {reason,
|
|
730
|
+
* quarantinedAt}), empty array if none. Unlike {@link getQuarantinedKeys} this
|
|
731
|
+
* carries the reason + timestamp needed to surface the quarantine to the
|
|
732
|
+
* control plane (the manager folds it into the agent heartbeat's diagnostics)
|
|
733
|
+
* and to the agent itself, so an operator sees WHY/WHEN on the webapp badge
|
|
734
|
+
* and the agent reports the real cause instead of confabulating one (ENG-8003).
|
|
735
|
+
* Returns a defensive copy so callers can't mutate the cached store.
|
|
736
|
+
*/
|
|
737
|
+
getQuarantineEntries(codeName) {
|
|
738
|
+
const forAgent = this.load()[codeName];
|
|
739
|
+
if (!forAgent) return [];
|
|
740
|
+
return Object.entries(forAgent).map(([serverKey, entry]) => ({
|
|
741
|
+
serverKey,
|
|
742
|
+
reason: entry.reason,
|
|
743
|
+
quarantinedAt: entry.quarantinedAt
|
|
744
|
+
}));
|
|
745
|
+
}
|
|
728
746
|
/**
|
|
729
747
|
* Mark `serverKey` quarantined for `codeName`. Idempotent — re-quarantining
|
|
730
748
|
* an already-quarantined key preserves the original `quarantinedAt` (so the
|
|
@@ -8207,6 +8225,7 @@ function hasRevokedResiduals(state7) {
|
|
|
8207
8225
|
return state7.gatewayRunning || state7.portAllocated || state7.provisionDirExists;
|
|
8208
8226
|
}
|
|
8209
8227
|
var pendingSessionRestarts = /* @__PURE__ */ new Map();
|
|
8228
|
+
var lastRestartWasExternal = /* @__PURE__ */ new Map();
|
|
8210
8229
|
var pendingRestartVerifications = /* @__PURE__ */ new Map();
|
|
8211
8230
|
var restartBreaker = new RestartBreaker();
|
|
8212
8231
|
var reportedTrips = /* @__PURE__ */ new Map();
|
|
@@ -8907,6 +8926,7 @@ function stopPersistentSessionAndForgetMcpBaseline(codeName, breakerReason, gate
|
|
|
8907
8926
|
}
|
|
8908
8927
|
cancelPendingSessionRestart(codeName);
|
|
8909
8928
|
stopPersistentSession(codeName, log);
|
|
8929
|
+
lastRestartWasExternal.set(codeName, gateReason !== "mcp-presence-reaper");
|
|
8910
8930
|
runningMcpHashes.delete(codeName);
|
|
8911
8931
|
runningMcpServerKeys.delete(codeName);
|
|
8912
8932
|
runningChannelSecretHashes.delete(codeName);
|
|
@@ -9093,7 +9113,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9093
9113
|
var lastVersionCheckAt = 0;
|
|
9094
9114
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9095
9115
|
var lastResponsivenessProbeAt = 0;
|
|
9096
|
-
var agtCliVersion = true ? "0.28.
|
|
9116
|
+
var agtCliVersion = true ? "0.28.386" : "dev";
|
|
9097
9117
|
function resolveBrewPath(execFileSync2) {
|
|
9098
9118
|
try {
|
|
9099
9119
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -10083,6 +10103,9 @@ function channelQuarantineStore() {
|
|
|
10083
10103
|
}
|
|
10084
10104
|
return _channelQuarantineStore;
|
|
10085
10105
|
}
|
|
10106
|
+
function quarantineEntriesFor(codeName) {
|
|
10107
|
+
return channelQuarantineStore().getQuarantineEntries(codeName);
|
|
10108
|
+
}
|
|
10086
10109
|
var _hostFlagStore = null;
|
|
10087
10110
|
function hostFlagStore() {
|
|
10088
10111
|
if (!_hostFlagStore) {
|
|
@@ -10222,10 +10245,10 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
10222
10245
|
if (codeNames.length === 0) return;
|
|
10223
10246
|
void (async () => {
|
|
10224
10247
|
try {
|
|
10225
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10248
|
+
const { collectDiagnostics } = await import("../persistent-session-KQHWYEQF.js");
|
|
10226
10249
|
await api.post("/host/heartbeat", {
|
|
10227
10250
|
host_id: hostId,
|
|
10228
|
-
agent_diagnostics: collectDiagnostics(codeNames)
|
|
10251
|
+
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor)
|
|
10229
10252
|
});
|
|
10230
10253
|
} catch (err) {
|
|
10231
10254
|
log(`[restart] post-respawn diagnostics flush failed: ${err.message}`);
|
|
@@ -10321,9 +10344,9 @@ async function pollCycle() {
|
|
|
10321
10344
|
}
|
|
10322
10345
|
try {
|
|
10323
10346
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
10324
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10347
|
+
const { collectDiagnostics } = await import("../persistent-session-KQHWYEQF.js");
|
|
10325
10348
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
10326
|
-
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
10349
|
+
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor) : void 0;
|
|
10327
10350
|
let tailscaleHostname;
|
|
10328
10351
|
try {
|
|
10329
10352
|
const { execSync: es } = await import("child_process");
|
|
@@ -10476,7 +10499,7 @@ async function pollCycle() {
|
|
|
10476
10499
|
const {
|
|
10477
10500
|
collectResponsivenessProbes,
|
|
10478
10501
|
getResponsivenessIntervalMs
|
|
10479
|
-
} = await import("../responsiveness-probe-
|
|
10502
|
+
} = await import("../responsiveness-probe-5X6WVKUZ.js");
|
|
10480
10503
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
10481
10504
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
10482
10505
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -10508,7 +10531,7 @@ async function pollCycle() {
|
|
|
10508
10531
|
collectResponsivenessProbes,
|
|
10509
10532
|
livePendingInboundOldestAgeSeconds,
|
|
10510
10533
|
parkPendingInbound
|
|
10511
|
-
} = await import("../responsiveness-probe-
|
|
10534
|
+
} = await import("../responsiveness-probe-5X6WVKUZ.js");
|
|
10512
10535
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-HYOOQV4A.js");
|
|
10513
10536
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
10514
10537
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -12723,6 +12746,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12723
12746
|
// but-not-yet-live MCP, so don't let the reaper re-fire + inflate the
|
|
12724
12747
|
// McpReaperRestartsHourly metric into a false flapping alarm.
|
|
12725
12748
|
restartPending: pendingSessionRestarts.has(agent.code_name),
|
|
12749
|
+
// ENG-8013 (storm-awareness): tell the reaper whether THIS session
|
|
12750
|
+
// generation was born from an external respawn (integration-change /
|
|
12751
|
+
// channel-set-change / day-rollover / wedge / operator restart, or a
|
|
12752
|
+
// storm) vs the reaper's own recovery restart. When external, a missing
|
|
12753
|
+
// channel MCP is churn collateral and must not accrue quarantine budget,
|
|
12754
|
+
// the durable fix for the ENG-8003 storm-quarantine incident. Absent map
|
|
12755
|
+
// entry (first boot) → false → count normally.
|
|
12756
|
+
currentGenerationExternallyStarted: lastRestartWasExternal.get(agent.code_name) ?? false,
|
|
12726
12757
|
// ENG-5441 / ENG-5547: a mcp-presence-reaper restart counts against
|
|
12727
12758
|
// the agent-wide breaker ONLY when several distinct MCP servers are
|
|
12728
12759
|
// missing at once — a thrashing collection that rotates restarts of
|
|
@@ -12844,6 +12875,14 @@ async function processAgent(agent, agentStates) {
|
|
|
12844
12875
|
"quarantine",
|
|
12845
12876
|
`optional channel '${serverKey}' dead past restart budget + dwell \u2014 quarantined`
|
|
12846
12877
|
);
|
|
12878
|
+
void injectMessage(
|
|
12879
|
+
codeName,
|
|
12880
|
+
"system",
|
|
12881
|
+
`Your "${serverKey}" channel has been quarantined by the host runtime: it repeatedly failed to start (no live MCP process) past the recovery budget, so it has been pulled from your active channel set. You cannot send or receive on ${serverKey} until an operator re-enables it. This is an infrastructure fault, not a policy or allowlist decision. If anyone asks why you are quiet on ${serverKey}, tell them the channel is quarantined and ask them to have an operator re-enable it. Do not guess at other causes.`,
|
|
12882
|
+
{ task_name: "channel-quarantine" },
|
|
12883
|
+
log
|
|
12884
|
+
).catch(() => {
|
|
12885
|
+
});
|
|
12847
12886
|
}
|
|
12848
12887
|
}
|
|
12849
12888
|
});
|
|
@@ -13703,10 +13742,10 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
13703
13742
|
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}`));
|
|
13704
13743
|
void (async () => {
|
|
13705
13744
|
try {
|
|
13706
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13745
|
+
const { collectDiagnostics } = await import("../persistent-session-KQHWYEQF.js");
|
|
13707
13746
|
await api.post("/host/heartbeat", {
|
|
13708
13747
|
host_id: hostId,
|
|
13709
|
-
agent_diagnostics: collectDiagnostics([codeName])
|
|
13748
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
|
|
13710
13749
|
});
|
|
13711
13750
|
} catch (err) {
|
|
13712
13751
|
log(`[restart-lane] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -13753,10 +13792,10 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
13753
13792
|
}
|
|
13754
13793
|
try {
|
|
13755
13794
|
const hostId = await getHostId();
|
|
13756
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
13795
|
+
const { collectDiagnostics } = await import("../persistent-session-KQHWYEQF.js");
|
|
13757
13796
|
await api.post("/host/heartbeat", {
|
|
13758
13797
|
host_id: hostId,
|
|
13759
|
-
agent_diagnostics: collectDiagnostics([codeName])
|
|
13798
|
+
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
|
|
13760
13799
|
});
|
|
13761
13800
|
} catch (err) {
|
|
13762
13801
|
log(`[fast-mcp-respawn] post-respawn diagnostics flush failed for '${codeName}': ${err.message}`);
|
|
@@ -14206,7 +14245,7 @@ async function processClaudePairSessions(agents) {
|
|
|
14206
14245
|
killPairSession,
|
|
14207
14246
|
pairTmuxSession,
|
|
14208
14247
|
finalizeClaudePairOnboarding
|
|
14209
|
-
} = await import("../claude-pair-runtime-
|
|
14248
|
+
} = await import("../claude-pair-runtime-NVMVUAGS.js");
|
|
14210
14249
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
14211
14250
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
14212
14251
|
const killed = await killPairSession(pairTmuxSession(pairId));
|