@integrity-labs/agt-cli 0.28.886 → 0.28.888
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-FP5M5OVX.js → chunk-OMRYKBFE.js} +99 -3
- package/dist/chunk-OMRYKBFE.js.map +1 -0
- package/dist/{chunk-2E7GOSID.js → chunk-P2EMIE25.js} +3 -3
- package/dist/{claude-pair-runtime-BQGZXRPV.js → claude-pair-runtime-5UINWQ52.js} +2 -2
- package/dist/lib/manager-worker.js +60 -19
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/index.js +116 -3
- package/dist/{persistent-session-SG4HA35I.js → persistent-session-RFQKA2H5.js} +2 -2
- package/dist/{responsiveness-probe-3OEZ6D3O.js → responsiveness-probe-65AHLKWV.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-FP5M5OVX.js.map +0 -1
- /package/dist/{chunk-2E7GOSID.js.map → chunk-P2EMIE25.js.map} +0 -0
- /package/dist/{claude-pair-runtime-BQGZXRPV.js.map → claude-pair-runtime-5UINWQ52.js.map} +0 -0
- /package/dist/{persistent-session-SG4HA35I.js.map → persistent-session-RFQKA2H5.js.map} +0 -0
- /package/dist/{responsiveness-probe-3OEZ6D3O.js.map → responsiveness-probe-65AHLKWV.js.map} +0 -0
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
parseEnvIntegrations,
|
|
17
17
|
shellQuote,
|
|
18
18
|
summarizeUnanswerablePane
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-OMRYKBFE.js";
|
|
20
20
|
import {
|
|
21
21
|
BIND_FAILURE_QUARANTINE_THRESHOLD,
|
|
22
22
|
INTEGRATIONS_SECTION_END,
|
|
@@ -6841,7 +6841,7 @@ function exchangeFailureKind(err) {
|
|
|
6841
6841
|
}
|
|
6842
6842
|
|
|
6843
6843
|
// src/lib/api-client.ts
|
|
6844
|
-
var agtCliVersion = true ? "0.28.
|
|
6844
|
+
var agtCliVersion = true ? "0.28.888" : "dev";
|
|
6845
6845
|
var lastConfigHash = null;
|
|
6846
6846
|
function setConfigHash(hash) {
|
|
6847
6847
|
lastConfigHash = hash && hash.length > 0 ? hash : null;
|
|
@@ -11451,4 +11451,4 @@ export {
|
|
|
11451
11451
|
managerInstallSystemUnitCommand,
|
|
11452
11452
|
managerUninstallSystemUnitCommand
|
|
11453
11453
|
};
|
|
11454
|
-
//# sourceMappingURL=chunk-
|
|
11454
|
+
//# sourceMappingURL=chunk-P2EMIE25.js.map
|
|
@@ -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-RFQKA2H5.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-5UINWQ52.js.map
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
safeWriteJsonAtomic,
|
|
64
64
|
setConfigHash,
|
|
65
65
|
tripClass
|
|
66
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-P2EMIE25.js";
|
|
67
67
|
import {
|
|
68
68
|
getProjectDir as getProjectDir2,
|
|
69
69
|
getReadyTasks,
|
|
@@ -72,9 +72,11 @@ import {
|
|
|
72
72
|
syncTasksToScheduler
|
|
73
73
|
} from "../chunk-3HLECXMI.js";
|
|
74
74
|
import {
|
|
75
|
+
BLOCKED_ON_PROMPT_DECISION,
|
|
75
76
|
CHANNEL_SECRET_ENV_KEYS,
|
|
76
77
|
ChildProcessError,
|
|
77
78
|
agentRuntimeKey,
|
|
79
|
+
applyBlockedPromptVerdict,
|
|
78
80
|
buildEgressAllowlist,
|
|
79
81
|
checkChannelInputs,
|
|
80
82
|
collectChannelSpawnSecrets,
|
|
@@ -94,6 +96,7 @@ import {
|
|
|
94
96
|
injectMessage,
|
|
95
97
|
injectMessageWithStatus,
|
|
96
98
|
injectOpencodeMessage,
|
|
99
|
+
isConfirmedRespawn,
|
|
97
100
|
isOpencodeSessionHealthy,
|
|
98
101
|
isSessionHealthy,
|
|
99
102
|
isolationMode,
|
|
@@ -101,6 +104,7 @@ import {
|
|
|
101
104
|
mergeOpencodeConfigArtifact,
|
|
102
105
|
modelPolicyAuthComponent,
|
|
103
106
|
modelPolicyEgressDomains,
|
|
107
|
+
noteSessionBlockedOnPrompt,
|
|
104
108
|
paneLogPath,
|
|
105
109
|
parseEnvIntegrations,
|
|
106
110
|
parseModelPolicy,
|
|
@@ -117,8 +121,11 @@ import {
|
|
|
117
121
|
restartEgressSidecar,
|
|
118
122
|
rotatePaneLogForDayRollover,
|
|
119
123
|
rotateSessionForWedge,
|
|
124
|
+
sessionBlockedOnPrompt,
|
|
125
|
+
sessionHealthyAndUnblocked,
|
|
120
126
|
sha256,
|
|
121
127
|
sharedBusyBuckets,
|
|
128
|
+
shouldLogBlockedPrompt,
|
|
122
129
|
startOpencodeSession,
|
|
123
130
|
startPersistentSession,
|
|
124
131
|
stopAllSessionsAndWait,
|
|
@@ -129,7 +136,7 @@ import {
|
|
|
129
136
|
takeZombieDetection,
|
|
130
137
|
toOpencodeModel,
|
|
131
138
|
writeEgressAllowlist
|
|
132
|
-
} from "../chunk-
|
|
139
|
+
} from "../chunk-OMRYKBFE.js";
|
|
133
140
|
import {
|
|
134
141
|
ACCOUNT_ENFORCEMENT_MARKER_FILENAME,
|
|
135
142
|
AnchorSessionClient,
|
|
@@ -12935,7 +12942,7 @@ var firstConnectUnsettledByAgent = /* @__PURE__ */ new Map();
|
|
|
12935
12942
|
function verifyPendingRestarts(now) {
|
|
12936
12943
|
if (pendingRestartVerifications.size === 0) return;
|
|
12937
12944
|
for (const [codeName, pending2] of pendingRestartVerifications) {
|
|
12938
|
-
const healthy =
|
|
12945
|
+
const healthy = sessionHealthyAndUnblocked(codeName, isSessionHealthy);
|
|
12939
12946
|
const session = getSessionState(codeName);
|
|
12940
12947
|
const startedAt = session?.startedAt ?? null;
|
|
12941
12948
|
const respawnId = session?.currentSessionId ?? null;
|
|
@@ -12979,7 +12986,7 @@ function verifyPendingRestarts(now) {
|
|
|
12979
12986
|
finishRestartTiming(codeName, "failed", `${outcome.attempt} verify attempts`, log, now);
|
|
12980
12987
|
if (bindRemediationEnabled() && spawnWasRefusedWithNoSession(codeName)) {
|
|
12981
12988
|
log(
|
|
12982
|
-
`[bind-remediation] '${codeName}' NOT remediating \u2014 the last spawn was refused and no session is running (e.g. the host cannot authenticate to Claude). A re-respawn cannot bind tools when nothing can start, so this would loop without the breaker ever seeing it (ENG-8581). Fix the host, not the session.`
|
|
12989
|
+
`[bind-remediation] '${codeName}' NOT remediating \u2014 the last spawn was refused and no session is running, or the session is blocked on a prompt it cannot answer (e.g. the host cannot authenticate to Claude, ENG-10335). A re-respawn cannot bind tools when nothing can start, so this would loop without the breaker ever seeing it (ENG-8581). Fix the host, not the session.`
|
|
12983
12990
|
);
|
|
12984
12991
|
}
|
|
12985
12992
|
if (shouldRemediateUnverifiedRestart(outcome, {
|
|
@@ -13016,7 +13023,7 @@ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
|
|
|
13016
13023
|
var dayRolloverInboundHold = /* @__PURE__ */ new Map();
|
|
13017
13024
|
var INBOUND_HOLD_EPISODE_GAP_MS = 12e4;
|
|
13018
13025
|
async function channelInboundActivityAgeSecondsFor(codeName) {
|
|
13019
|
-
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-
|
|
13026
|
+
const { newestPendingInboundActivityMtimeMs } = await import("../responsiveness-probe-65AHLKWV.js");
|
|
13020
13027
|
const newest = newestPendingInboundActivityMtimeMs(dirname11(paneLogPath(codeName)));
|
|
13021
13028
|
if (newest === null) return null;
|
|
13022
13029
|
return Math.max(0, Math.floor((Date.now() - newest) / 1e3));
|
|
@@ -13684,7 +13691,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
|
|
|
13684
13691
|
var lastVersionCheckAt = 0;
|
|
13685
13692
|
var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
|
|
13686
13693
|
var lastResponsivenessProbeAt = 0;
|
|
13687
|
-
var agtCliVersion = true ? "0.28.
|
|
13694
|
+
var agtCliVersion = true ? "0.28.888" : "dev";
|
|
13688
13695
|
function resolveBrewPath(execFileSync2) {
|
|
13689
13696
|
try {
|
|
13690
13697
|
const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
|
|
@@ -15274,7 +15281,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
|
|
|
15274
15281
|
if (codeNames.length === 0) return;
|
|
15275
15282
|
void (async () => {
|
|
15276
15283
|
try {
|
|
15277
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15284
|
+
const { collectDiagnostics } = await import("../persistent-session-RFQKA2H5.js");
|
|
15278
15285
|
await api.post("/host/heartbeat", {
|
|
15279
15286
|
host_id: hostId,
|
|
15280
15287
|
agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -15416,7 +15423,7 @@ async function pollCycleInner() {
|
|
|
15416
15423
|
}
|
|
15417
15424
|
try {
|
|
15418
15425
|
const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
|
|
15419
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
15426
|
+
const { collectDiagnostics } = await import("../persistent-session-RFQKA2H5.js");
|
|
15420
15427
|
const diagCodeNames = [...agentState.persistentSessionAgents];
|
|
15421
15428
|
const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor) : void 0;
|
|
15422
15429
|
let tailscaleHostname;
|
|
@@ -15585,7 +15592,7 @@ async function pollCycleInner() {
|
|
|
15585
15592
|
collectPanelessActivityProbes,
|
|
15586
15593
|
getResponsivenessIntervalMs,
|
|
15587
15594
|
occupancyQualificationClassifications
|
|
15588
|
-
} = await import("../responsiveness-probe-
|
|
15595
|
+
} = await import("../responsiveness-probe-65AHLKWV.js");
|
|
15589
15596
|
const probeIntervalMs = getResponsivenessIntervalMs();
|
|
15590
15597
|
if (now - lastResponsivenessProbeAt > probeIntervalMs) {
|
|
15591
15598
|
const probeCodeNames = [...agentState.persistentSessionAgents];
|
|
@@ -15702,7 +15709,7 @@ async function pollCycleInner() {
|
|
|
15702
15709
|
collectResponsivenessProbes,
|
|
15703
15710
|
livePendingInboundOldestAgeSeconds,
|
|
15704
15711
|
parkPendingInbound
|
|
15705
|
-
} = await import("../responsiveness-probe-
|
|
15712
|
+
} = await import("../responsiveness-probe-65AHLKWV.js");
|
|
15706
15713
|
const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
|
|
15707
15714
|
const wedgeNow = /* @__PURE__ */ new Date();
|
|
15708
15715
|
const liveAgents = agentState.persistentSessionAgents;
|
|
@@ -18687,6 +18694,7 @@ async function processAgent(agent, agentStates, managedToolkits) {
|
|
|
18687
18694
|
// reaper is the only component that knows a restart is futile, so it is
|
|
18688
18695
|
// the only one that can say so.
|
|
18689
18696
|
onPaneBlocked: (codeName, ctx) => {
|
|
18697
|
+
noteSessionBlockedOnPrompt(codeName, ctx.kind, "mcp-presence-reaper");
|
|
18690
18698
|
void reportReaperEvent(
|
|
18691
18699
|
agent.agent_id,
|
|
18692
18700
|
"mcp-presence-reaper",
|
|
@@ -19253,7 +19261,12 @@ async function ensureOpencodeRuntime(agent, refreshData, agentTimezone) {
|
|
|
19253
19261
|
detail: `opencode serve on 127.0.0.1:${session.port ?? "?"}`
|
|
19254
19262
|
};
|
|
19255
19263
|
}
|
|
19256
|
-
async function ensurePersistentSession(
|
|
19264
|
+
async function ensurePersistentSession(...args) {
|
|
19265
|
+
const result = await ensurePersistentSessionUnchecked(...args);
|
|
19266
|
+
const blocked = result.sessionHealthyAfter ? sessionBlockedOnPrompt(args[0].code_name) : null;
|
|
19267
|
+
return applyBlockedPromptVerdict(result, blocked);
|
|
19268
|
+
}
|
|
19269
|
+
async function ensurePersistentSessionUnchecked(agent, tasks, boardItems, refreshData) {
|
|
19257
19270
|
const codeName = agent.code_name;
|
|
19258
19271
|
if ((agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK) === "claude-code" && !isSessionHealthy(codeName)) {
|
|
19259
19272
|
maybeMigrateAgentToIdKeyedLayout(agent, {
|
|
@@ -19841,7 +19854,19 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash20("sha256")
|
|
|
19841
19854
|
`[persistent-session] Deferring ${ready.length} ready task(s) for '${codeName}' \u2014 minting a fresh session after an idle day-rollover; schedule NOT advanced, task fires on the fresh session next tick [ENG-8461]`
|
|
19842
19855
|
);
|
|
19843
19856
|
}
|
|
19844
|
-
|
|
19857
|
+
let deferReadyForBlockedPrompt = false;
|
|
19858
|
+
if (!deferReadyForUsageCap && !deferReadyForRollover && ready.length > 0) {
|
|
19859
|
+
const blockedKind = sessionBlockedOnPrompt(codeName);
|
|
19860
|
+
if (blockedKind) {
|
|
19861
|
+
deferReadyForBlockedPrompt = true;
|
|
19862
|
+
if (shouldLogBlockedPrompt(codeName, "scheduled-firing")) {
|
|
19863
|
+
log(
|
|
19864
|
+
`[persistent-session] Deferring ${ready.length} ready task(s) for '${codeName}' \u2014 session is blocked on an interactive prompt (${blockedKind}) and cannot run a tool call; schedule NOT advanced, will fire once the prompt is answered (further deferrals this episode are not logged) [ENG-10335]`
|
|
19865
|
+
);
|
|
19866
|
+
}
|
|
19867
|
+
}
|
|
19868
|
+
}
|
|
19869
|
+
for (const task of deferReadyForUsageCap || deferReadyForRollover || deferReadyForBlockedPrompt ? [] : ready) {
|
|
19845
19870
|
if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
|
|
19846
19871
|
const updated = markTaskFired(codeName, task.taskId, "ok");
|
|
19847
19872
|
claudeSchedulerStates.set(codeName, updated);
|
|
@@ -20103,7 +20128,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20103
20128
|
try {
|
|
20104
20129
|
const freshId = rotateSessionForWedge(codeName);
|
|
20105
20130
|
consecutiveWedgeCycles.delete(codeName);
|
|
20106
|
-
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-
|
|
20131
|
+
const { parkPendingInbound: parkForRestart } = await import("../responsiveness-probe-65AHLKWV.js");
|
|
20107
20132
|
const { parked, deadLettered } = parkForRestart(codeName, /* @__PURE__ */ new Date());
|
|
20108
20133
|
const parkNote = parked > 0 ? `, ${parked} inbound parked` : "";
|
|
20109
20134
|
const deadNote = deadLettered > 0 ? `, ${deadLettered} undeliverable dead-lettered` : "";
|
|
@@ -20134,14 +20159,19 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
|
|
|
20134
20159
|
refreshData
|
|
20135
20160
|
);
|
|
20136
20161
|
recordSpawnOutcome(codeName, result);
|
|
20137
|
-
if (
|
|
20162
|
+
if (!isConfirmedRespawn(result)) {
|
|
20138
20163
|
log(`[restart-lane] respawn not confirmed for '${codeName}' (decision=${result.decision}) - leaving for slow poll`);
|
|
20139
20164
|
return;
|
|
20140
20165
|
}
|
|
20166
|
+
if (result.decision === BLOCKED_ON_PROMPT_DECISION) {
|
|
20167
|
+
log(
|
|
20168
|
+
`[restart-lane] '${codeName}' respawned but is blocked on an interactive prompt - acking, not retrying: a respawn re-presents the same prompt; published unhealthy [ENG-10335]`
|
|
20169
|
+
);
|
|
20170
|
+
}
|
|
20141
20171
|
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}`));
|
|
20142
20172
|
void (async () => {
|
|
20143
20173
|
try {
|
|
20144
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20174
|
+
const { collectDiagnostics } = await import("../persistent-session-RFQKA2H5.js");
|
|
20145
20175
|
await api.post("/host/heartbeat", {
|
|
20146
20176
|
host_id: hostId,
|
|
20147
20177
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20179,15 +20209,20 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
|
|
|
20179
20209
|
refreshData
|
|
20180
20210
|
);
|
|
20181
20211
|
recordSpawnOutcome(codeName, result);
|
|
20182
|
-
if (
|
|
20212
|
+
if (!isConfirmedRespawn(result)) {
|
|
20183
20213
|
log(
|
|
20184
20214
|
`[fast-mcp-respawn] respawn not confirmed for '${codeName}' (decision=${result.decision}) - leaving for slow poll`
|
|
20185
20215
|
);
|
|
20186
20216
|
return;
|
|
20187
20217
|
}
|
|
20218
|
+
if (result.decision === BLOCKED_ON_PROMPT_DECISION) {
|
|
20219
|
+
log(
|
|
20220
|
+
`[fast-mcp-respawn] '${codeName}' respawned but is blocked on an interactive prompt - not retrying, a respawn re-presents the same prompt; published unhealthy [ENG-10335]`
|
|
20221
|
+
);
|
|
20222
|
+
}
|
|
20188
20223
|
try {
|
|
20189
20224
|
const hostId = await getHostId();
|
|
20190
|
-
const { collectDiagnostics } = await import("../persistent-session-
|
|
20225
|
+
const { collectDiagnostics } = await import("../persistent-session-RFQKA2H5.js");
|
|
20191
20226
|
await api.post("/host/heartbeat", {
|
|
20192
20227
|
host_id: hostId,
|
|
20193
20228
|
agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor, spawnOutcomeForDiagnostics, pidPressureFor, forwardedToolsFor)
|
|
@@ -20583,7 +20618,13 @@ async function processDirectChatMessage(agent, msg) {
|
|
|
20583
20618
|
);
|
|
20584
20619
|
return;
|
|
20585
20620
|
}
|
|
20586
|
-
|
|
20621
|
+
const blockedOnPrompt = sessionBlockedOnPrompt(agent.codeName);
|
|
20622
|
+
if (blockedOnPrompt && shouldLogBlockedPrompt(agent.codeName, "direct-chat")) {
|
|
20623
|
+
log(
|
|
20624
|
+
`[direct-chat] Not delivering to '${agent.codeName}' (msg=${msg.id}) \u2014 session is blocked on an interactive prompt (${blockedOnPrompt}), so nothing in-session can pull it; leaving pending for durable replay once the prompt is answered (further messages this episode are not logged) [ENG-10335]`
|
|
20625
|
+
);
|
|
20626
|
+
}
|
|
20627
|
+
if (!blockedOnPrompt && isSessionHealthy(agent.codeName)) {
|
|
20587
20628
|
const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
|
|
20588
20629
|
if (useDoorbell) {
|
|
20589
20630
|
try {
|
|
@@ -20823,7 +20864,7 @@ async function processClaudePairSessions(agents) {
|
|
|
20823
20864
|
killPairSession,
|
|
20824
20865
|
pairTmuxSession,
|
|
20825
20866
|
finalizeClaudePairOnboarding
|
|
20826
|
-
} = await import("../claude-pair-runtime-
|
|
20867
|
+
} = await import("../claude-pair-runtime-5UINWQ52.js");
|
|
20827
20868
|
for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
|
|
20828
20869
|
log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
|
|
20829
20870
|
const killed = await killPairSession(pairTmuxSession(pairId));
|