@integrity-labs/agt-cli 0.28.273 → 0.28.274
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-NKNOIJMC.js → chunk-73NA6BKT.js} +3 -3
- package/dist/{chunk-PNETKYLF.js → chunk-THMHJITM.js} +16 -13
- package/dist/{chunk-PNETKYLF.js.map → chunk-THMHJITM.js.map} +1 -1
- package/dist/{claude-pair-runtime-WVZRDAFK.js → claude-pair-runtime-Z726QSAR.js} +2 -2
- package/dist/lib/manager-worker.js +92 -21
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/origami.js +15 -12
- package/dist/{persistent-session-UQNLB3UF.js → persistent-session-SDDSZN5E.js} +2 -2
- package/dist/{responsiveness-probe-GVLCH2IM.js → responsiveness-probe-ODKT4WUR.js} +2 -2
- package/package.json +1 -1
- /package/dist/{chunk-NKNOIJMC.js.map → chunk-73NA6BKT.js.map} +0 -0
- /package/dist/{claude-pair-runtime-WVZRDAFK.js.map → claude-pair-runtime-Z726QSAR.js.map} +0 -0
- /package/dist/{persistent-session-UQNLB3UF.js.map → persistent-session-SDDSZN5E.js.map} +0 -0
- /package/dist/{responsiveness-probe-GVLCH2IM.js.map → responsiveness-probe-ODKT4WUR.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-SDDSZN5E.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-Z726QSAR.js.map
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
requireHost,
|
|
39
39
|
safeWriteJsonAtomic,
|
|
40
40
|
setConfigHash
|
|
41
|
-
} from "../chunk-
|
|
41
|
+
} from "../chunk-73NA6BKT.js";
|
|
42
42
|
import {
|
|
43
43
|
getProjectDir as getProjectDir2,
|
|
44
44
|
getReadyTasks,
|
|
@@ -125,7 +125,7 @@ import {
|
|
|
125
125
|
takeZombieDetection,
|
|
126
126
|
transcriptActivityAgeSeconds,
|
|
127
127
|
writeEgressAllowlist
|
|
128
|
-
} from "../chunk-
|
|
128
|
+
} from "../chunk-THMHJITM.js";
|
|
129
129
|
import {
|
|
130
130
|
reapOrphanChannelMcps
|
|
131
131
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -611,8 +611,27 @@ function isQuarantineFile(value) {
|
|
|
611
611
|
function reaperRestartBreakerReason(activeKeys) {
|
|
612
612
|
return activeKeys.length >= 2 ? "mcp-presence-reaper" : void 0;
|
|
613
613
|
}
|
|
614
|
+
var PROVISIONING_RELOAD_REASONS = /* @__PURE__ */ new Set([
|
|
615
|
+
"hot-reload-mcp",
|
|
616
|
+
"managed-mcp-churn",
|
|
617
|
+
"bind-remediation"
|
|
618
|
+
]);
|
|
619
|
+
function isProvisioningReloadReason(reason) {
|
|
620
|
+
return PROVISIONING_RELOAD_REASONS.has(reason);
|
|
621
|
+
}
|
|
622
|
+
function countByClass(events) {
|
|
623
|
+
let crash = 0;
|
|
624
|
+
let provisioning = 0;
|
|
625
|
+
for (const e of events) {
|
|
626
|
+
if (isProvisioningReloadReason(e.reason)) provisioning += 1;
|
|
627
|
+
else crash += 1;
|
|
628
|
+
}
|
|
629
|
+
return { crash, provisioning };
|
|
630
|
+
}
|
|
614
631
|
var DEFAULT_MAX = 2;
|
|
615
632
|
var DEFAULT_WINDOW_MS = 6e5;
|
|
633
|
+
var DEFAULT_PROVISIONING_MAX = 5;
|
|
634
|
+
var DEFAULT_PROVISIONING_WINDOW_MS = 18e5;
|
|
616
635
|
function readEnvNumber(name, fallback) {
|
|
617
636
|
const raw = process.env[name];
|
|
618
637
|
if (!raw) return fallback;
|
|
@@ -622,12 +641,18 @@ function readEnvNumber(name, fallback) {
|
|
|
622
641
|
var RestartBreaker = class {
|
|
623
642
|
max;
|
|
624
643
|
windowMs;
|
|
644
|
+
provisioningMax;
|
|
645
|
+
provisioningWindowMs;
|
|
646
|
+
/** Longest window either tally needs — how long the events log must retain. */
|
|
647
|
+
retentionMs;
|
|
625
648
|
now;
|
|
626
649
|
events = /* @__PURE__ */ new Map();
|
|
627
650
|
trips = /* @__PURE__ */ new Map();
|
|
628
651
|
constructor(opts = {}) {
|
|
629
652
|
this.max = opts.max ?? readEnvNumber("AGT_RESTART_BREAKER_MAX", DEFAULT_MAX);
|
|
630
653
|
this.windowMs = opts.windowMs ?? readEnvNumber("AGT_RESTART_BREAKER_WINDOW_MS", DEFAULT_WINDOW_MS);
|
|
654
|
+
this.provisioningMax = opts.provisioningMax ?? readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", DEFAULT_PROVISIONING_MAX);
|
|
655
|
+
this.provisioningWindowMs = opts.provisioningWindowMs ?? readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_WINDOW_MS", DEFAULT_PROVISIONING_WINDOW_MS);
|
|
631
656
|
this.now = opts.now ?? Date.now;
|
|
632
657
|
if (!Number.isFinite(this.max) || this.max < 1) {
|
|
633
658
|
throw new Error("restart-breaker max must be a finite number >= 1");
|
|
@@ -635,6 +660,13 @@ var RestartBreaker = class {
|
|
|
635
660
|
if (!Number.isFinite(this.windowMs) || this.windowMs < 1e3) {
|
|
636
661
|
throw new Error("restart-breaker windowMs must be a finite number >= 1000");
|
|
637
662
|
}
|
|
663
|
+
if (!Number.isFinite(this.provisioningMax) || this.provisioningMax < 1) {
|
|
664
|
+
throw new Error("restart-breaker provisioningMax must be a finite number >= 1");
|
|
665
|
+
}
|
|
666
|
+
if (!Number.isFinite(this.provisioningWindowMs) || this.provisioningWindowMs < 1e3) {
|
|
667
|
+
throw new Error("restart-breaker provisioningWindowMs must be a finite number >= 1000");
|
|
668
|
+
}
|
|
669
|
+
this.retentionMs = Math.max(this.windowMs, this.provisioningWindowMs);
|
|
638
670
|
}
|
|
639
671
|
/** True if this agent's breaker is currently tripped (manager must skip spawn). */
|
|
640
672
|
isTripped(codeName) {
|
|
@@ -655,24 +687,54 @@ var RestartBreaker = class {
|
|
|
655
687
|
record(codeName, reason) {
|
|
656
688
|
const existing = this.trips.get(codeName);
|
|
657
689
|
if (existing) {
|
|
658
|
-
return {
|
|
690
|
+
return {
|
|
691
|
+
tripped: false,
|
|
692
|
+
trip: existing,
|
|
693
|
+
windowCount: existing.eventsAtTrip.length,
|
|
694
|
+
classCounts: countByClass(existing.eventsAtTrip)
|
|
695
|
+
};
|
|
659
696
|
}
|
|
660
697
|
const at = this.now();
|
|
661
|
-
const
|
|
662
|
-
const prior = (this.events.get(codeName) ?? []).filter((e) => e.at >=
|
|
698
|
+
const retentionCutoff = at - this.retentionMs;
|
|
699
|
+
const prior = (this.events.get(codeName) ?? []).filter((e) => e.at >= retentionCutoff);
|
|
663
700
|
prior.push({ reason, at });
|
|
664
701
|
this.events.set(codeName, prior);
|
|
665
|
-
|
|
702
|
+
const crashCount = prior.filter(
|
|
703
|
+
(e) => e.at >= at - this.windowMs && !isProvisioningReloadReason(e.reason)
|
|
704
|
+
).length;
|
|
705
|
+
const provEvents = prior.filter(
|
|
706
|
+
(e) => e.at >= at - this.provisioningWindowMs && isProvisioningReloadReason(e.reason)
|
|
707
|
+
);
|
|
708
|
+
const windowCount = prior.filter((e) => e.at >= at - this.windowMs).length;
|
|
709
|
+
const classCounts = {
|
|
710
|
+
crash: crashCount,
|
|
711
|
+
provisioning: provEvents.length
|
|
712
|
+
};
|
|
713
|
+
let trippedClass;
|
|
714
|
+
let tripEvents;
|
|
715
|
+
let tripWindowMs = this.windowMs;
|
|
716
|
+
if (crashCount > this.max) {
|
|
717
|
+
trippedClass = "crash";
|
|
718
|
+
tripEvents = prior.filter(
|
|
719
|
+
(e) => e.at >= at - this.windowMs && !isProvisioningReloadReason(e.reason)
|
|
720
|
+
);
|
|
721
|
+
tripWindowMs = this.windowMs;
|
|
722
|
+
} else if (provEvents.length > this.provisioningMax) {
|
|
723
|
+
trippedClass = "provisioning";
|
|
724
|
+
tripEvents = provEvents;
|
|
725
|
+
tripWindowMs = this.provisioningWindowMs;
|
|
726
|
+
}
|
|
727
|
+
if (trippedClass && tripEvents) {
|
|
666
728
|
const trip = {
|
|
667
729
|
trippedAt: at,
|
|
668
|
-
eventsAtTrip: [...
|
|
669
|
-
statusMessage: formatStatusMessage(
|
|
730
|
+
eventsAtTrip: [...tripEvents],
|
|
731
|
+
statusMessage: formatStatusMessage(tripEvents, tripWindowMs, trippedClass)
|
|
670
732
|
};
|
|
671
733
|
this.trips.set(codeName, trip);
|
|
672
734
|
this.events.delete(codeName);
|
|
673
|
-
return { tripped: true, trip, windowCount
|
|
735
|
+
return { tripped: true, trip, windowCount, classCounts, trippedClass };
|
|
674
736
|
}
|
|
675
|
-
return { tripped: false, windowCount
|
|
737
|
+
return { tripped: false, windowCount, classCounts };
|
|
676
738
|
}
|
|
677
739
|
/** Operator-initiated reset: drops the trip + the events log for this agent. */
|
|
678
740
|
clear(codeName) {
|
|
@@ -703,13 +765,14 @@ var RestartBreaker = class {
|
|
|
703
765
|
return (this.events.get(codeName) ?? []).filter((e) => e.at >= cutoff).length;
|
|
704
766
|
}
|
|
705
767
|
};
|
|
706
|
-
function formatStatusMessage(events, windowMs) {
|
|
768
|
+
function formatStatusMessage(events, windowMs, klass = "crash") {
|
|
707
769
|
const last = events[events.length - 1];
|
|
708
770
|
const windowLabel = windowMs < 6e4 ? `${Math.round(windowMs / 1e3)}s` : `${(windowMs / 6e4).toFixed(1).replace(/\.0$/, "")}min`;
|
|
709
771
|
const reasonCounts = /* @__PURE__ */ new Map();
|
|
710
772
|
for (const e of events) reasonCounts.set(e.reason, (reasonCounts.get(e.reason) ?? 0) + 1);
|
|
711
773
|
const breakdown = Array.from(reasonCounts.entries()).map(([r, n]) => `${r}=${n}`).join(", ");
|
|
712
|
-
|
|
774
|
+
const classLabel = klass === "provisioning" ? "provisioning-reload " : "";
|
|
775
|
+
return `Circuit breaker tripped: ${events.length} ${classLabel}restarts in ${windowLabel} (${breakdown}); most recent=${last.reason} at ${new Date(last.at).toISOString()}`;
|
|
713
776
|
}
|
|
714
777
|
|
|
715
778
|
// src/lib/mcp-flap-dampener.ts
|
|
@@ -5953,6 +6016,7 @@ var pendingSessionRestarts = /* @__PURE__ */ new Map();
|
|
|
5953
6016
|
var pendingRestartVerifications = /* @__PURE__ */ new Map();
|
|
5954
6017
|
var restartBreaker = new RestartBreaker();
|
|
5955
6018
|
var reportedTrips = /* @__PURE__ */ new Map();
|
|
6019
|
+
var RESTART_BREAKER_PROVISIONING_MAX = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
|
|
5956
6020
|
var mcpFlapDampener = new McpFlapDampener();
|
|
5957
6021
|
var FLAP_BREAKER_COOLDOWN_MS = readEnvNumber2(
|
|
5958
6022
|
"AGT_MCP_FLAP_BREAKER_COOLDOWN_MS",
|
|
@@ -5992,7 +6056,14 @@ function recordRestartForBreaker(codeName, reason) {
|
|
|
5992
6056
|
return;
|
|
5993
6057
|
}
|
|
5994
6058
|
const result = restartBreaker.record(codeName, reason);
|
|
5995
|
-
if (!result.tripped || !result.trip)
|
|
6059
|
+
if (!result.tripped || !result.trip) {
|
|
6060
|
+
if (isProvisioningReloadReason(reason) && result.classCounts.provisioning >= RESTART_BREAKER_PROVISIONING_MAX) {
|
|
6061
|
+
log(
|
|
6062
|
+
`[restart-breaker] agent=${codeName} provisioning-reload churn at the trip bar: ${result.classCounts.provisioning} provisioning restarts in window (reason=${reason}); one more will auto-pause the agent \u2014 a freshly-added integration is likely churning (ENG-7560)`
|
|
6063
|
+
);
|
|
6064
|
+
}
|
|
6065
|
+
return;
|
|
6066
|
+
}
|
|
5996
6067
|
const trip = result.trip;
|
|
5997
6068
|
log(
|
|
5998
6069
|
`[persistent-session-decision] agent=${codeName} decision=circuit-tripped detail=${JSON.stringify(trip.statusMessage)} (ENG-5441)`
|
|
@@ -6717,7 +6788,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
6717
6788
|
var lastVersionCheckAt = 0;
|
|
6718
6789
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
6719
6790
|
var lastResponsivenessProbeAt = 0;
|
|
6720
|
-
var agtCliVersion = true ? "0.28.
|
|
6791
|
+
var agtCliVersion = true ? "0.28.274" : "dev";
|
|
6721
6792
|
function resolveBrewPath(execFileSync2) {
|
|
6722
6793
|
try {
|
|
6723
6794
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -7567,7 +7638,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
7567
7638
|
if (codeNames.length === 0) return;
|
|
7568
7639
|
void (async () => {
|
|
7569
7640
|
try {
|
|
7570
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
7641
|
+
const { collectDiagnostics } = await import("../persistent-session-SDDSZN5E.js");
|
|
7571
7642
|
await api.post("/host/heartbeat", {
|
|
7572
7643
|
host_id: hostId,
|
|
7573
7644
|
agent_diagnostics: collectDiagnostics(codeNames)
|
|
@@ -7665,7 +7736,7 @@ async function pollCycle() {
|
|
|
7665
7736
|
}
|
|
7666
7737
|
try {
|
|
7667
7738
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
7668
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
7739
|
+
const { collectDiagnostics } = await import("../persistent-session-SDDSZN5E.js");
|
|
7669
7740
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
7670
7741
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames) : void 0;
|
|
7671
7742
|
let tailscaleHostname;
|
|
@@ -7813,7 +7884,7 @@ async function pollCycle() {
|
|
|
7813
7884
|
const {
|
|
7814
7885
|
collectResponsivenessProbes,
|
|
7815
7886
|
getResponsivenessIntervalMs
|
|
7816
|
-
} = await import("../responsiveness-probe-
|
|
7887
|
+
} = await import("../responsiveness-probe-ODKT4WUR.js");
|
|
7817
7888
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
7818
7889
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
7819
7890
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -7845,7 +7916,7 @@ async function pollCycle() {
|
|
|
7845
7916
|
collectResponsivenessProbes,
|
|
7846
7917
|
livePendingInboundOldestAgeSeconds,
|
|
7847
7918
|
parkPendingInbound
|
|
7848
|
-
} = await import("../responsiveness-probe-
|
|
7919
|
+
} = await import("../responsiveness-probe-ODKT4WUR.js");
|
|
7849
7920
|
const { getProjectDir: wedgeProjectDir } = await import("../claude-scheduler-FATCLHDM.js");
|
|
7850
7921
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
7851
7922
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -10731,7 +10802,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
10731
10802
|
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}`));
|
|
10732
10803
|
void (async () => {
|
|
10733
10804
|
try {
|
|
10734
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10805
|
+
const { collectDiagnostics } = await import("../persistent-session-SDDSZN5E.js");
|
|
10735
10806
|
await api.post("/host/heartbeat", {
|
|
10736
10807
|
host_id: hostId,
|
|
10737
10808
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -10781,7 +10852,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
10781
10852
|
}
|
|
10782
10853
|
try {
|
|
10783
10854
|
const hostId = await getHostId();
|
|
10784
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
10855
|
+
const { collectDiagnostics } = await import("../persistent-session-SDDSZN5E.js");
|
|
10785
10856
|
await api.post("/host/heartbeat", {
|
|
10786
10857
|
host_id: hostId,
|
|
10787
10858
|
agent_diagnostics: collectDiagnostics([codeName])
|
|
@@ -11185,7 +11256,7 @@ async function processClaudePairSessions(agents) {
|
|
|
11185
11256
|
killPairSession,
|
|
11186
11257
|
pairTmuxSession,
|
|
11187
11258
|
finalizeClaudePairOnboarding
|
|
11188
|
-
} = await import("../claude-pair-runtime-
|
|
11259
|
+
} = await import("../claude-pair-runtime-Z726QSAR.js");
|
|
11189
11260
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
11190
11261
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
11191
11262
|
const killed = await killPairSession(pairTmuxSession(pairId));
|