@integrity-labs/agt-cli 0.27.122 → 0.27.124
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 +3 -3
- package/dist/{chunk-EGFIMYNT.js → chunk-MQHZBG7J.js} +1 -1
- package/dist/lib/manager-worker.js +2 -2
- package/dist/lib/manager-worker.js.map +1 -1
- package/dist/mcp/slack-channel.js +97 -0
- package/dist/mcp/telegram-channel.js +100 -0
- package/package.json +1 -1
- /package/dist/{chunk-EGFIMYNT.js.map → chunk-MQHZBG7J.js.map} +0 -0
|
@@ -14335,6 +14335,29 @@ function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDEL
|
|
|
14335
14335
|
function undeliverableNoticeText() {
|
|
14336
14336
|
return "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
|
|
14337
14337
|
}
|
|
14338
|
+
var BUSY_ACK_THRESHOLD_MS = 9e4;
|
|
14339
|
+
var BUSY_ACK_NOTICE_THROTTLE_MS = 10 * 60 * 1e3;
|
|
14340
|
+
function channelBusyAckEnabled() {
|
|
14341
|
+
const v = process.env.AGT_CHANNEL_BUSY_ACK_ENABLED;
|
|
14342
|
+
return v === "1" || v === "true";
|
|
14343
|
+
}
|
|
14344
|
+
function channelBusyAckThresholdMs() {
|
|
14345
|
+
const raw = parseInt(process.env.AGT_CHANNEL_BUSY_ACK_THRESHOLD_MS ?? "", 10);
|
|
14346
|
+
return Number.isFinite(raw) && raw > 0 ? raw : BUSY_ACK_THRESHOLD_MS;
|
|
14347
|
+
}
|
|
14348
|
+
function decideBusyAck(i) {
|
|
14349
|
+
if (!i.hasTarget) return false;
|
|
14350
|
+
if (!i.stillPending) return false;
|
|
14351
|
+
if (!Number.isFinite(i.pendingAgeMs)) return false;
|
|
14352
|
+
const threshold = i.thresholdMs ?? channelBusyAckThresholdMs();
|
|
14353
|
+
if (i.pendingAgeMs < threshold) return false;
|
|
14354
|
+
if (!i.sessionAlive) return false;
|
|
14355
|
+
const paneFreshThreshold = i.paneFreshThresholdMs ?? ACK_PANE_FRESH_THRESHOLD_MS;
|
|
14356
|
+
return i.paneLogFreshAgeMs != null && i.paneLogFreshAgeMs <= paneFreshThreshold;
|
|
14357
|
+
}
|
|
14358
|
+
function busyAckNoticeText() {
|
|
14359
|
+
return "\u{1F6E0}\uFE0F I'm in the middle of something right now \u2014 I'll follow up on this as soon as I'm free.";
|
|
14360
|
+
}
|
|
14338
14361
|
var GIVE_UP_SIGNAL_FILENAME = "watchdog-give-up.json";
|
|
14339
14362
|
var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
14340
14363
|
function readGiveUpSignalAtMs(path, now = Date.now()) {
|
|
@@ -16249,6 +16272,15 @@ function writeSlackPendingInboundMarker(channel, threadTs, messageTs, undelivera
|
|
|
16249
16272
|
);
|
|
16250
16273
|
}
|
|
16251
16274
|
}
|
|
16275
|
+
function readSlackPendingInboundMarker(channel, threadTs, messageTs) {
|
|
16276
|
+
const path = slackPendingInboundPath(channel, threadTs, messageTs);
|
|
16277
|
+
if (!path || !existsSync4(path)) return null;
|
|
16278
|
+
try {
|
|
16279
|
+
return JSON.parse(readFileSync5(path, "utf-8"));
|
|
16280
|
+
} catch {
|
|
16281
|
+
return null;
|
|
16282
|
+
}
|
|
16283
|
+
}
|
|
16252
16284
|
function healSlackUndeliverable(channel, messageTs) {
|
|
16253
16285
|
if (!BOT_TOKEN || !channel || !messageTs) return;
|
|
16254
16286
|
const headers = {
|
|
@@ -16299,6 +16331,67 @@ function postUndeliverableNotice(channel, threadTs, isThreadReply) {
|
|
|
16299
16331
|
function __resetSlackUndeliverableNoticeThrottle() {
|
|
16300
16332
|
lastSlackUndeliverableNoticeAt.clear();
|
|
16301
16333
|
}
|
|
16334
|
+
var lastSlackBusyAckNoticeAt = /* @__PURE__ */ new Map();
|
|
16335
|
+
function postBusyAckNotice(channel, threadTs, isThreadReply) {
|
|
16336
|
+
if (!BOT_TOKEN || !channel) return;
|
|
16337
|
+
const now = Date.now();
|
|
16338
|
+
const conversationKey = isThreadReply && threadTs ? `${channel}:${threadTs}` : channel;
|
|
16339
|
+
if (!shouldPostUndeliverableNotice(
|
|
16340
|
+
lastSlackBusyAckNoticeAt.get(conversationKey),
|
|
16341
|
+
now,
|
|
16342
|
+
BUSY_ACK_NOTICE_THROTTLE_MS
|
|
16343
|
+
)) {
|
|
16344
|
+
return;
|
|
16345
|
+
}
|
|
16346
|
+
lastSlackBusyAckNoticeAt.set(conversationKey, now);
|
|
16347
|
+
fetch("https://slack.com/api/chat.postMessage", {
|
|
16348
|
+
method: "POST",
|
|
16349
|
+
headers: {
|
|
16350
|
+
"Content-Type": "application/json",
|
|
16351
|
+
Authorization: `Bearer ${BOT_TOKEN}`
|
|
16352
|
+
},
|
|
16353
|
+
body: JSON.stringify({
|
|
16354
|
+
channel,
|
|
16355
|
+
text: busyAckNoticeText(),
|
|
16356
|
+
...threadTs ? { thread_ts: threadTs } : {}
|
|
16357
|
+
}),
|
|
16358
|
+
// Bound the request so a hung Slack call can't dangle to the platform
|
|
16359
|
+
// timeout (matches the other bounded REST calls in this file). 10s mirrors
|
|
16360
|
+
// Telegram's busy-ack send; fire-and-forget, an abort is swallowed below.
|
|
16361
|
+
signal: AbortSignal.timeout(1e4)
|
|
16362
|
+
}).catch(() => {
|
|
16363
|
+
});
|
|
16364
|
+
}
|
|
16365
|
+
function scheduleBusyAck(channel, threadTs, messageTs, isThreadReply) {
|
|
16366
|
+
if (!channelBusyAckEnabled()) return;
|
|
16367
|
+
const thresholdMs = channelBusyAckThresholdMs();
|
|
16368
|
+
const timer = setTimeout(() => {
|
|
16369
|
+
const probe = process.env.TMUX && AGENT_CODE_NAME ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
|
|
16370
|
+
let paneLogFreshAgeMs = null;
|
|
16371
|
+
if (SLACK_AGENT_DIR) {
|
|
16372
|
+
try {
|
|
16373
|
+
const paneMtimeMs = statSync2(join5(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
|
|
16374
|
+
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
16375
|
+
} catch {
|
|
16376
|
+
}
|
|
16377
|
+
}
|
|
16378
|
+
const marker = readSlackPendingInboundMarker(channel, threadTs, messageTs);
|
|
16379
|
+
if (!marker) return;
|
|
16380
|
+
const post = decideBusyAck({
|
|
16381
|
+
hasTarget: Boolean(channel && messageTs),
|
|
16382
|
+
stillPending: true,
|
|
16383
|
+
pendingAgeMs: Math.max(0, Date.now() - Date.parse(marker.received_at)),
|
|
16384
|
+
sessionAlive: probe.tmux === "alive" && probe.claude === "alive",
|
|
16385
|
+
paneLogFreshAgeMs,
|
|
16386
|
+
thresholdMs
|
|
16387
|
+
});
|
|
16388
|
+
if (post) postBusyAckNotice(channel, threadTs, isThreadReply);
|
|
16389
|
+
}, thresholdMs);
|
|
16390
|
+
timer.unref();
|
|
16391
|
+
}
|
|
16392
|
+
function __resetSlackBusyAckNoticeThrottle() {
|
|
16393
|
+
lastSlackBusyAckNoticeAt.clear();
|
|
16394
|
+
}
|
|
16302
16395
|
function clearSlackMarkerFileWithHeal(fullPath) {
|
|
16303
16396
|
let marker = null;
|
|
16304
16397
|
try {
|
|
@@ -18917,6 +19010,9 @@ async function connectSocketMode() {
|
|
|
18917
19010
|
}
|
|
18918
19011
|
if (channel && ts && shouldEngage) {
|
|
18919
19012
|
trackPendingMessage(channel, threadTs, ts, ackDecision === "undeliverable");
|
|
19013
|
+
if (ackDecision === "ack") {
|
|
19014
|
+
scheduleBusyAck(channel, threadTs, ts, isThreadReply);
|
|
19015
|
+
}
|
|
18920
19016
|
}
|
|
18921
19017
|
const userName = await resolveUserName(user);
|
|
18922
19018
|
const fileMeta = await buildInboundFileMeta(evt.files, AGENT_CODE_NAME, channel);
|
|
@@ -19091,6 +19187,7 @@ if (THREAD_STORE_PATH) {
|
|
|
19091
19187
|
}
|
|
19092
19188
|
connectSocketModeSafely();
|
|
19093
19189
|
export {
|
|
19190
|
+
__resetSlackBusyAckNoticeThrottle,
|
|
19094
19191
|
__resetSlackGiveUpNoticeStateForTests,
|
|
19095
19192
|
__resetSlackUndeliverableNoticeThrottle
|
|
19096
19193
|
};
|
|
@@ -15832,6 +15832,29 @@ function shouldPostUndeliverableNotice(lastNoticeAtMs, nowMs, throttleMs = UNDEL
|
|
|
15832
15832
|
function undeliverableNoticeText() {
|
|
15833
15833
|
return "\u23F3 I can't get to this right now. Please resend in a few minutes \u2014 I may not see this one.";
|
|
15834
15834
|
}
|
|
15835
|
+
var BUSY_ACK_THRESHOLD_MS = 9e4;
|
|
15836
|
+
var BUSY_ACK_NOTICE_THROTTLE_MS = 10 * 60 * 1e3;
|
|
15837
|
+
function channelBusyAckEnabled() {
|
|
15838
|
+
const v = process.env.AGT_CHANNEL_BUSY_ACK_ENABLED;
|
|
15839
|
+
return v === "1" || v === "true";
|
|
15840
|
+
}
|
|
15841
|
+
function channelBusyAckThresholdMs() {
|
|
15842
|
+
const raw = parseInt(process.env.AGT_CHANNEL_BUSY_ACK_THRESHOLD_MS ?? "", 10);
|
|
15843
|
+
return Number.isFinite(raw) && raw > 0 ? raw : BUSY_ACK_THRESHOLD_MS;
|
|
15844
|
+
}
|
|
15845
|
+
function decideBusyAck(i) {
|
|
15846
|
+
if (!i.hasTarget) return false;
|
|
15847
|
+
if (!i.stillPending) return false;
|
|
15848
|
+
if (!Number.isFinite(i.pendingAgeMs)) return false;
|
|
15849
|
+
const threshold = i.thresholdMs ?? channelBusyAckThresholdMs();
|
|
15850
|
+
if (i.pendingAgeMs < threshold) return false;
|
|
15851
|
+
if (!i.sessionAlive) return false;
|
|
15852
|
+
const paneFreshThreshold = i.paneFreshThresholdMs ?? ACK_PANE_FRESH_THRESHOLD_MS;
|
|
15853
|
+
return i.paneLogFreshAgeMs != null && i.paneLogFreshAgeMs <= paneFreshThreshold;
|
|
15854
|
+
}
|
|
15855
|
+
function busyAckNoticeText() {
|
|
15856
|
+
return "\u{1F6E0}\uFE0F I'm in the middle of something right now \u2014 I'll follow up on this as soon as I'm free.";
|
|
15857
|
+
}
|
|
15835
15858
|
var GIVE_UP_SIGNAL_FILENAME = "watchdog-give-up.json";
|
|
15836
15859
|
var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
15837
15860
|
function readGiveUpSignalAtMs(path, now = Date.now()) {
|
|
@@ -16161,6 +16184,70 @@ function notifyBackOnline(chatId) {
|
|
|
16161
16184
|
function __resetBackOnlineNoticeThrottle() {
|
|
16162
16185
|
lastBackOnlineNoticeAt.clear();
|
|
16163
16186
|
}
|
|
16187
|
+
var lastBusyAckNoticeAt = /* @__PURE__ */ new Map();
|
|
16188
|
+
function postBusyAckNotice(chatId, messageId) {
|
|
16189
|
+
const key2 = String(chatId);
|
|
16190
|
+
const now = Date.now();
|
|
16191
|
+
if (!shouldPostUndeliverableNotice(lastBusyAckNoticeAt.get(key2), now, BUSY_ACK_NOTICE_THROTTLE_MS)) {
|
|
16192
|
+
return;
|
|
16193
|
+
}
|
|
16194
|
+
lastBusyAckNoticeAt.set(key2, now);
|
|
16195
|
+
void (async () => {
|
|
16196
|
+
try {
|
|
16197
|
+
const resp = await telegramApiCall(
|
|
16198
|
+
"sendMessage",
|
|
16199
|
+
{
|
|
16200
|
+
chat_id: chatId,
|
|
16201
|
+
text: busyAckNoticeText(),
|
|
16202
|
+
reply_to_message_id: Number(messageId),
|
|
16203
|
+
allow_sending_without_reply: true
|
|
16204
|
+
},
|
|
16205
|
+
1e4
|
|
16206
|
+
);
|
|
16207
|
+
if (!resp.ok) {
|
|
16208
|
+
process.stderr.write(
|
|
16209
|
+
`telegram-channel(${AGENT_CODE_NAME}): busy-ack notice failed (chat=${redactId(chatId)}): ${resp.description ?? "unknown"}
|
|
16210
|
+
`
|
|
16211
|
+
);
|
|
16212
|
+
}
|
|
16213
|
+
} catch (err) {
|
|
16214
|
+
process.stderr.write(
|
|
16215
|
+
`telegram-channel(${AGENT_CODE_NAME}): busy-ack notice error: ${err.message}
|
|
16216
|
+
`
|
|
16217
|
+
);
|
|
16218
|
+
}
|
|
16219
|
+
})();
|
|
16220
|
+
}
|
|
16221
|
+
function scheduleBusyAck(chatId, messageId) {
|
|
16222
|
+
if (!channelBusyAckEnabled()) return;
|
|
16223
|
+
const thresholdMs = channelBusyAckThresholdMs();
|
|
16224
|
+
const timer = setTimeout(() => {
|
|
16225
|
+
const probe = process.env.TMUX && AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
|
|
16226
|
+
let paneLogFreshAgeMs = null;
|
|
16227
|
+
if (AGENT_DIR) {
|
|
16228
|
+
try {
|
|
16229
|
+
const paneMtimeMs = statSync(join4(AGENT_DIR, "pane.log")).mtimeMs;
|
|
16230
|
+
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
16231
|
+
} catch {
|
|
16232
|
+
}
|
|
16233
|
+
}
|
|
16234
|
+
const marker = readPendingInboundMarker(chatId, messageId);
|
|
16235
|
+
if (!marker) return;
|
|
16236
|
+
const post = decideBusyAck({
|
|
16237
|
+
hasTarget: Boolean(chatId && messageId),
|
|
16238
|
+
stillPending: true,
|
|
16239
|
+
pendingAgeMs: Math.max(0, Date.now() - Date.parse(marker.received_at)),
|
|
16240
|
+
sessionAlive: probe.tmux === "alive" && probe.claude === "alive",
|
|
16241
|
+
paneLogFreshAgeMs,
|
|
16242
|
+
thresholdMs
|
|
16243
|
+
});
|
|
16244
|
+
if (post) postBusyAckNotice(chatId, messageId);
|
|
16245
|
+
}, thresholdMs);
|
|
16246
|
+
timer.unref();
|
|
16247
|
+
}
|
|
16248
|
+
function __resetBusyAckNoticeThrottle() {
|
|
16249
|
+
lastBusyAckNoticeAt.clear();
|
|
16250
|
+
}
|
|
16164
16251
|
var RESTART_FLAGS_DIR = join4(homedir2(), ".augmented", "restart-flags");
|
|
16165
16252
|
function buildTelegramHelpMessage(codeName) {
|
|
16166
16253
|
return [
|
|
@@ -16630,6 +16717,15 @@ function clearPendingInboundMarker(chatId, messageId) {
|
|
|
16630
16717
|
if (!path) return;
|
|
16631
16718
|
clearTelegramMarkerFileWithHeal(path);
|
|
16632
16719
|
}
|
|
16720
|
+
function readPendingInboundMarker(chatId, messageId) {
|
|
16721
|
+
const path = pendingInboundPath(chatId, messageId);
|
|
16722
|
+
if (!path || !existsSync2(path)) return null;
|
|
16723
|
+
try {
|
|
16724
|
+
return JSON.parse(readFileSync3(path, "utf-8"));
|
|
16725
|
+
} catch {
|
|
16726
|
+
return null;
|
|
16727
|
+
}
|
|
16728
|
+
}
|
|
16633
16729
|
var MAX_RECOVERY_ATTEMPTS = 3;
|
|
16634
16730
|
function nextRetryName(filename) {
|
|
16635
16731
|
const match = filename.match(/^(.*?)(?:\.retry-(\d+))?\.json$/);
|
|
@@ -18042,6 +18138,9 @@ async function pollLoop() {
|
|
|
18042
18138
|
ackDecision === "undeliverable",
|
|
18043
18139
|
channelPayload
|
|
18044
18140
|
);
|
|
18141
|
+
if (ackDecision === "ack") {
|
|
18142
|
+
scheduleBusyAck(chatId, messageId);
|
|
18143
|
+
}
|
|
18045
18144
|
await mcp.notification({
|
|
18046
18145
|
method: "notifications/claude/channel",
|
|
18047
18146
|
params: channelPayload
|
|
@@ -18139,6 +18238,7 @@ pollLoop().catch((err) => {
|
|
|
18139
18238
|
});
|
|
18140
18239
|
export {
|
|
18141
18240
|
__resetBackOnlineNoticeThrottle,
|
|
18241
|
+
__resetBusyAckNoticeThrottle,
|
|
18142
18242
|
__resetGiveUpNoticeStateForTests,
|
|
18143
18243
|
__resetUndeliverableNoticeThrottle,
|
|
18144
18244
|
_resetQueuedReplyCountsForTests
|
package/package.json
CHANGED
|
File without changes
|