@integrity-labs/agt-cli 0.28.452 → 0.28.454
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-WOZINHUT.js → chunk-23E2T5UT.js} +3 -3
- package/dist/{chunk-ESZRW7A3.js → chunk-3NJHNIO3.js} +31 -9
- package/dist/chunk-3NJHNIO3.js.map +1 -0
- package/dist/{claude-pair-runtime-RCH4LKDE.js → claude-pair-runtime-NRKOKQYR.js} +2 -2
- package/dist/lib/manager-worker.js +87 -20
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/direct-chat-channel.js +25 -8
- package/dist/mcp/origami.js +25 -8
- package/dist/mcp/slack-channel.js +75 -19
- package/dist/mcp/telegram-channel.js +75 -19
- package/dist/{persistent-session-7HZXY56P.js → persistent-session-X5N7UFEF.js} +2 -2
- package/dist/{responsiveness-probe-AIA7ZEBW.js → responsiveness-probe-OAZ55KPC.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-ESZRW7A3.js.map +0 -1
- /package/dist/{chunk-WOZINHUT.js.map → chunk-23E2T5UT.js.map} +0 -0
- /package/dist/{claude-pair-runtime-RCH4LKDE.js.map → claude-pair-runtime-NRKOKQYR.js.map} +0 -0
- /package/dist/{persistent-session-7HZXY56P.js.map → persistent-session-X5N7UFEF.js.map} +0 -0
- /package/dist/{responsiveness-probe-AIA7ZEBW.js.map → responsiveness-probe-OAZ55KPC.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-X5N7UFEF.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-NRKOKQYR.js.map
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
resolveEffectivePinRaw,
|
|
43
43
|
safeWriteJsonAtomic,
|
|
44
44
|
setConfigHash
|
|
45
|
-
} from "../chunk-
|
|
45
|
+
} from "../chunk-23E2T5UT.js";
|
|
46
46
|
import {
|
|
47
47
|
getProjectDir as getProjectDir2,
|
|
48
48
|
getReadyTasks,
|
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
import {
|
|
54
54
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
55
55
|
AnchorSessionClient,
|
|
56
|
+
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
56
57
|
CLAUDE_MD_MAX_CHARS,
|
|
57
58
|
CONVERSATION_FAILURE_CATEGORIES,
|
|
58
59
|
DEFAULT_FRAMEWORK,
|
|
@@ -63,6 +64,9 @@ import {
|
|
|
63
64
|
KANBAN_CHECK_COMMAND,
|
|
64
65
|
KANBAN_NUDGE_ACTIONABLE_STATUSES,
|
|
65
66
|
MAX_AVATAR_ENV_URL_BYTES,
|
|
67
|
+
MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
|
|
68
|
+
RESTART_BREAKER_PROVISIONING_MAX,
|
|
69
|
+
RESTART_BREAKER_PROVISIONING_WINDOW_MS,
|
|
66
70
|
SCHEDULED_TURN_MARKER_FILENAME,
|
|
67
71
|
SUPPRESS_SENTINEL,
|
|
68
72
|
StreamEncoder,
|
|
@@ -160,7 +164,7 @@ import {
|
|
|
160
164
|
toOpencodeModel,
|
|
161
165
|
transcriptActivityAgeSeconds,
|
|
162
166
|
writeEgressAllowlist
|
|
163
|
-
} from "../chunk-
|
|
167
|
+
} from "../chunk-3NJHNIO3.js";
|
|
164
168
|
import {
|
|
165
169
|
reapOrphanChannelMcps
|
|
166
170
|
} from "../chunk-XWVM4KPK.js";
|
|
@@ -844,7 +848,13 @@ function reaperRestartBreakerReason(activeKeys) {
|
|
|
844
848
|
var KNOWN_REASON_CLASS_MAP = {
|
|
845
849
|
crash: true,
|
|
846
850
|
provisioning: true,
|
|
847
|
-
"credential-rotation": true
|
|
851
|
+
"credential-rotation": true,
|
|
852
|
+
// ENG-8215: the self-healing class (bind-remediation - the manager's OWN
|
|
853
|
+
// repair attempts, which must never count toward a trip). Adding it here is
|
|
854
|
+
// forced by the Record type, which is exactly why that shape was chosen over
|
|
855
|
+
// a Set literal (ENG-7577, CodeRabbit on #3861) - a new union member cannot
|
|
856
|
+
// be silently omitted from the rehydration allowlist.
|
|
857
|
+
"self-healing": true
|
|
848
858
|
};
|
|
849
859
|
var KNOWN_REASON_CLASSES = new Set(
|
|
850
860
|
Object.keys(KNOWN_REASON_CLASS_MAP)
|
|
@@ -852,7 +862,10 @@ var KNOWN_REASON_CLASSES = new Set(
|
|
|
852
862
|
var PROVISIONING_RELOAD_REASONS = /* @__PURE__ */ new Set([
|
|
853
863
|
"hot-reload-mcp",
|
|
854
864
|
"managed-mcp-churn",
|
|
855
|
-
|
|
865
|
+
// ENG-8215: 'bind-remediation' MOVED OUT of this set into SELF_HEALING_REASONS.
|
|
866
|
+
// It is the manager repairing itself, not a config reload, and counting it
|
|
867
|
+
// meant the harder the platform tried to fix an agent the more certain it
|
|
868
|
+
// became that it should give up. Deliberately NOT re-added here.
|
|
856
869
|
// ENG-7576: the dashboard integration-add stop itself - the first restart of
|
|
857
870
|
// the very burst this class exists for, previously uncounted entirely.
|
|
858
871
|
"integration-change",
|
|
@@ -876,21 +889,35 @@ var CREDENTIAL_ROTATION_REASONS = /* @__PURE__ */ new Set([
|
|
|
876
889
|
function isCredentialRotationReason(reason) {
|
|
877
890
|
return CREDENTIAL_ROTATION_REASONS.has(reason);
|
|
878
891
|
}
|
|
892
|
+
var SELF_HEALING_REASONS = /* @__PURE__ */ new Set([
|
|
893
|
+
"bind-remediation"
|
|
894
|
+
]);
|
|
895
|
+
function isSelfHealingReason(reason) {
|
|
896
|
+
return SELF_HEALING_REASONS.has(reason);
|
|
897
|
+
}
|
|
879
898
|
function restartReasonClass(reason) {
|
|
880
899
|
if (isCredentialRotationReason(reason)) return "credential-rotation";
|
|
900
|
+
if (isSelfHealingReason(reason)) return "self-healing";
|
|
881
901
|
return isProvisioningReloadReason(reason) ? "provisioning" : "crash";
|
|
882
902
|
}
|
|
883
903
|
function countByClass(events) {
|
|
884
904
|
let crash = 0;
|
|
885
905
|
let provisioning = 0;
|
|
886
906
|
let credentialRotation = 0;
|
|
907
|
+
let selfHealing = 0;
|
|
887
908
|
for (const e of events) {
|
|
888
909
|
const klass = restartReasonClass(e.reason);
|
|
889
910
|
if (klass === "provisioning") provisioning += 1;
|
|
890
911
|
else if (klass === "credential-rotation") credentialRotation += 1;
|
|
912
|
+
else if (klass === "self-healing") selfHealing += 1;
|
|
891
913
|
else crash += 1;
|
|
892
914
|
}
|
|
893
|
-
return {
|
|
915
|
+
return {
|
|
916
|
+
crash,
|
|
917
|
+
provisioning,
|
|
918
|
+
"credential-rotation": credentialRotation,
|
|
919
|
+
"self-healing": selfHealing
|
|
920
|
+
};
|
|
894
921
|
}
|
|
895
922
|
function maxProvisioningBucket(events) {
|
|
896
923
|
const buckets = /* @__PURE__ */ new Map();
|
|
@@ -912,8 +939,8 @@ function tripClass(trip) {
|
|
|
912
939
|
}
|
|
913
940
|
var DEFAULT_MAX = 2;
|
|
914
941
|
var DEFAULT_WINDOW_MS = 6e5;
|
|
915
|
-
var DEFAULT_PROVISIONING_MAX =
|
|
916
|
-
var DEFAULT_PROVISIONING_WINDOW_MS =
|
|
942
|
+
var DEFAULT_PROVISIONING_MAX = RESTART_BREAKER_PROVISIONING_MAX;
|
|
943
|
+
var DEFAULT_PROVISIONING_WINDOW_MS = RESTART_BREAKER_PROVISIONING_WINDOW_MS;
|
|
917
944
|
function readEnvNumber(name, fallback) {
|
|
918
945
|
const raw = process.env[name];
|
|
919
946
|
if (!raw) return fallback;
|
|
@@ -923,6 +950,11 @@ function readEnvNumber(name, fallback) {
|
|
|
923
950
|
var RestartBreaker = class {
|
|
924
951
|
max;
|
|
925
952
|
windowMs;
|
|
953
|
+
/**
|
|
954
|
+
* ENG-8215: NOT readonly - the constructor may clamp it upward to preserve the
|
|
955
|
+
* quarantine-fires-first ordering against a runtime override. Never mutated
|
|
956
|
+
* after construction.
|
|
957
|
+
*/
|
|
926
958
|
provisioningMax;
|
|
927
959
|
provisioningWindowMs;
|
|
928
960
|
/** Longest window either tally needs — how long the events log must retain. */
|
|
@@ -930,6 +962,13 @@ var RestartBreaker = class {
|
|
|
930
962
|
now;
|
|
931
963
|
events = /* @__PURE__ */ new Map();
|
|
932
964
|
trips = /* @__PURE__ */ new Map();
|
|
965
|
+
/**
|
|
966
|
+
* ENG-8215: set when a supplied `provisioningMax` was raised to keep MCP
|
|
967
|
+
* quarantine ahead of the breaker. Read once by the manager at construction so
|
|
968
|
+
* an overridden-and-clamped value is visible in manager.log rather than
|
|
969
|
+
* silently discarded.
|
|
970
|
+
*/
|
|
971
|
+
quarantineOrderingClamped;
|
|
933
972
|
constructor(opts = {}) {
|
|
934
973
|
this.max = opts.max ?? readEnvNumber("AGT_RESTART_BREAKER_MAX", DEFAULT_MAX);
|
|
935
974
|
this.windowMs = opts.windowMs ?? readEnvNumber("AGT_RESTART_BREAKER_WINDOW_MS", DEFAULT_WINDOW_MS);
|
|
@@ -945,11 +984,27 @@ var RestartBreaker = class {
|
|
|
945
984
|
if (!Number.isFinite(this.provisioningMax) || this.provisioningMax < 1) {
|
|
946
985
|
throw new Error("restart-breaker provisioningMax must be a finite number >= 1");
|
|
947
986
|
}
|
|
987
|
+
if (this.provisioningMax < MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING) {
|
|
988
|
+
this.quarantineOrderingClamped = {
|
|
989
|
+
requested: this.provisioningMax,
|
|
990
|
+
applied: MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING,
|
|
991
|
+
quarantineThreshold: BIND_FAILURE_QUARANTINE_THRESHOLD
|
|
992
|
+
};
|
|
993
|
+
this.provisioningMax = MIN_PROVISIONING_MAX_FOR_QUARANTINE_ORDERING;
|
|
994
|
+
}
|
|
948
995
|
if (!Number.isFinite(this.provisioningWindowMs) || this.provisioningWindowMs < 1e3) {
|
|
949
996
|
throw new Error("restart-breaker provisioningWindowMs must be a finite number >= 1000");
|
|
950
997
|
}
|
|
951
998
|
this.retentionMs = Math.max(this.windowMs, this.provisioningWindowMs);
|
|
952
999
|
}
|
|
1000
|
+
/**
|
|
1001
|
+
* ENG-8215: the clamp record, if the configured provisioning max had to be
|
|
1002
|
+
* raised to keep MCP quarantine ahead of the breaker. `undefined` when the
|
|
1003
|
+
* configured value already satisfied the ordering.
|
|
1004
|
+
*/
|
|
1005
|
+
getQuarantineOrderingClamp() {
|
|
1006
|
+
return this.quarantineOrderingClamped;
|
|
1007
|
+
}
|
|
953
1008
|
/** True if this agent's breaker is currently tripped (manager must skip spawn). */
|
|
954
1009
|
isTripped(codeName) {
|
|
955
1010
|
return this.trips.has(codeName);
|
|
@@ -995,11 +1050,15 @@ var RestartBreaker = class {
|
|
|
995
1050
|
const credRotCount = prior.filter(
|
|
996
1051
|
(e) => e.at >= at - this.provisioningWindowMs && isCredentialRotationReason(e.reason)
|
|
997
1052
|
).length;
|
|
1053
|
+
const selfHealCount = prior.filter(
|
|
1054
|
+
(e) => e.at >= at - this.provisioningWindowMs && isSelfHealingReason(e.reason)
|
|
1055
|
+
).length;
|
|
998
1056
|
const windowCount = prior.filter((e) => e.at >= at - this.windowMs).length;
|
|
999
1057
|
const classCounts = {
|
|
1000
1058
|
crash: crashCount,
|
|
1001
1059
|
provisioning: provEvents.length,
|
|
1002
|
-
"credential-rotation": credRotCount
|
|
1060
|
+
"credential-rotation": credRotCount,
|
|
1061
|
+
"self-healing": selfHealCount
|
|
1003
1062
|
};
|
|
1004
1063
|
const provBucket = maxProvisioningBucket(provEvents);
|
|
1005
1064
|
let trippedClass;
|
|
@@ -8863,9 +8922,17 @@ var pendingSessionRestarts = /* @__PURE__ */ new Map();
|
|
|
8863
8922
|
var lastRestartWasExternal = /* @__PURE__ */ new Map();
|
|
8864
8923
|
var pendingRestartVerifications = /* @__PURE__ */ new Map();
|
|
8865
8924
|
var restartBreaker = new RestartBreaker();
|
|
8925
|
+
{
|
|
8926
|
+
const clamp = restartBreaker.getQuarantineOrderingClamp();
|
|
8927
|
+
if (clamp) {
|
|
8928
|
+
log(
|
|
8929
|
+
`[circuit-breaker] provisioningMax=${clamp.requested} would trip before MCP quarantine (threshold=${clamp.quarantineThreshold}); raised to ${clamp.applied} so a failing integration is isolated before the whole agent is paused (ENG-8215)`
|
|
8930
|
+
);
|
|
8931
|
+
}
|
|
8932
|
+
}
|
|
8866
8933
|
var reportedTrips = /* @__PURE__ */ new Map();
|
|
8867
|
-
var
|
|
8868
|
-
var
|
|
8934
|
+
var RESTART_BREAKER_PROVISIONING_MAX2 = readEnvNumber("AGT_RESTART_BREAKER_PROVISIONING_MAX", 5);
|
|
8935
|
+
var RESTART_BREAKER_PROVISIONING_WINDOW_MS2 = readEnvNumber(
|
|
8869
8936
|
"AGT_RESTART_BREAKER_PROVISIONING_WINDOW_MS",
|
|
8870
8937
|
18e5
|
|
8871
8938
|
);
|
|
@@ -8910,13 +8977,13 @@ function recordRestartForBreaker(codeName, reason) {
|
|
|
8910
8977
|
let integrationKey;
|
|
8911
8978
|
if (isProvisioningReloadReason(reason)) {
|
|
8912
8979
|
const attribution = agentState.provisioningAttribution.get(codeName);
|
|
8913
|
-
if (attribution && Date.now() - attribution.at <=
|
|
8980
|
+
if (attribution && Date.now() - attribution.at <= RESTART_BREAKER_PROVISIONING_WINDOW_MS2) {
|
|
8914
8981
|
integrationKey = attribution.key;
|
|
8915
8982
|
}
|
|
8916
8983
|
}
|
|
8917
8984
|
const result = restartBreaker.record(codeName, reason, integrationKey);
|
|
8918
8985
|
if (!result.tripped || !result.trip) {
|
|
8919
|
-
if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >=
|
|
8986
|
+
if (isProvisioningReloadReason(reason) && result.maxProvisioningBucket >= RESTART_BREAKER_PROVISIONING_MAX2) {
|
|
8920
8987
|
const culprit = result.maxProvisioningBucketKey ? ` [${result.maxProvisioningBucketKey}]` : "";
|
|
8921
8988
|
log(
|
|
8922
8989
|
`[restart-breaker] agent=${codeName} provisioning-reload churn at the trip bar: ${result.maxProvisioningBucket} restarts for one integration${culprit} in window (reason=${reason}); one more will auto-pause the agent; that integration is likely churning (ENG-7560, ENG-7812)`
|
|
@@ -9882,7 +9949,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
9882
9949
|
var lastVersionCheckAt = 0;
|
|
9883
9950
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
9884
9951
|
var lastResponsivenessProbeAt = 0;
|
|
9885
|
-
var agtCliVersion = true ? "0.28.
|
|
9952
|
+
var agtCliVersion = true ? "0.28.454" : "dev";
|
|
9886
9953
|
function resolveBrewPath(execFileSync2) {
|
|
9887
9954
|
try {
|
|
9888
9955
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -11043,7 +11110,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
11043
11110
|
if (codeNames.length === 0) return;
|
|
11044
11111
|
void (async () => {
|
|
11045
11112
|
try {
|
|
11046
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11113
|
+
const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
|
|
11047
11114
|
await api.post("/host/heartbeat", {
|
|
11048
11115
|
host_id: hostId,
|
|
11049
11116
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -11150,7 +11217,7 @@ async function pollCycle() {
|
|
|
11150
11217
|
}
|
|
11151
11218
|
try {
|
|
11152
11219
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
11153
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
11220
|
+
const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
|
|
11154
11221
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
11155
11222
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
|
|
11156
11223
|
let tailscaleHostname;
|
|
@@ -11264,7 +11331,7 @@ async function pollCycle() {
|
|
|
11264
11331
|
collectResponsivenessProbes,
|
|
11265
11332
|
collectPanelessActivityProbes,
|
|
11266
11333
|
getResponsivenessIntervalMs
|
|
11267
|
-
} = await import("../responsiveness-probe-
|
|
11334
|
+
} = await import("../responsiveness-probe-OAZ55KPC.js");
|
|
11268
11335
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
11269
11336
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
11270
11337
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -11328,7 +11395,7 @@ async function pollCycle() {
|
|
|
11328
11395
|
collectResponsivenessProbes,
|
|
11329
11396
|
livePendingInboundOldestAgeSeconds,
|
|
11330
11397
|
parkPendingInbound
|
|
11331
|
-
} = await import("../responsiveness-probe-
|
|
11398
|
+
} = await import("../responsiveness-probe-OAZ55KPC.js");
|
|
11332
11399
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
11333
11400
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
11334
11401
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -14700,7 +14767,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
14700
14767
|
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}`));
|
|
14701
14768
|
void (async () => {
|
|
14702
14769
|
try {
|
|
14703
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14770
|
+
const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
|
|
14704
14771
|
await api.post("/host/heartbeat", {
|
|
14705
14772
|
host_id: hostId,
|
|
14706
14773
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -14750,7 +14817,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
14750
14817
|
}
|
|
14751
14818
|
try {
|
|
14752
14819
|
const hostId = await getHostId();
|
|
14753
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
14820
|
+
const { collectDiagnostics } = await import("../persistent-session-X5N7UFEF.js");
|
|
14754
14821
|
await api.post("/host/heartbeat", {
|
|
14755
14822
|
host_id: hostId,
|
|
14756
14823
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
|
|
@@ -15203,7 +15270,7 @@ async function processClaudePairSessions(agents) {
|
|
|
15203
15270
|
killPairSession,
|
|
15204
15271
|
pairTmuxSession,
|
|
15205
15272
|
finalizeClaudePairOnboarding
|
|
15206
|
-
} = await import("../claude-pair-runtime-
|
|
15273
|
+
} = await import("../claude-pair-runtime-NRKOKQYR.js");
|
|
15207
15274
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
15208
15275
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
15209
15276
|
const killed = await killPairSession(pairTmuxSession(pairId));
|