@integrity-labs/agt-cli 0.19.25 → 0.20.0

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.
@@ -14,7 +14,7 @@ import {
14
14
  stopAllSessionsAndWait,
15
15
  stopPersistentSession,
16
16
  writePersistentClaudeWrapper
17
- } from "./chunk-ZQNOWGHB.js";
17
+ } from "./chunk-55SJYI7V.js";
18
18
  export {
19
19
  _internals,
20
20
  collectDiagnostics,
@@ -32,4 +32,4 @@ export {
32
32
  stopPersistentSession,
33
33
  writePersistentClaudeWrapper
34
34
  };
35
- //# sourceMappingURL=persistent-session-J2K3JFJQ.js.map
35
+ //# sourceMappingURL=persistent-session-BVR3HES5.js.map
package/mcp/index.js CHANGED
@@ -21076,7 +21076,7 @@ var AGT_HOST = process.env.AGT_HOST;
21076
21076
  var AGT_API_KEY = process.env.AGT_API_KEY;
21077
21077
  var AGT_AGENT_ID = process.env.AGT_AGENT_ID;
21078
21078
  var AGT_AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME;
21079
- var AGT_APP_URL = (process.env.AGT_APP_URL ?? "").replace(/\/+$/, "");
21079
+ var AGT_APP_URL = (process.env.AGT_APP_URL?.trim() || "https://app.augmented.team").replace(/\/+$/, "");
21080
21080
  function readRunId() {
21081
21081
  const raw = process.env.AGT_RUN_ID ?? "";
21082
21082
  if (!raw || raw === "${AGT_RUN_ID}") return null;
@@ -14323,6 +14323,27 @@ async function isThreadKilled(opts) {
14323
14323
  }
14324
14324
  }
14325
14325
 
14326
+ // src/pending-timeout-rearm.ts
14327
+ var DEFAULT_STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
14328
+ var DEFAULT_RESPONSE_TIMEOUT_MS = 5 * 60 * 1e3;
14329
+ function decideRearmAction(opts) {
14330
+ const { receivedAtMs, nowMs } = opts;
14331
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_RESPONSE_TIMEOUT_MS;
14332
+ const staleMs = opts.staleMs ?? DEFAULT_STALE_MARKER_MS;
14333
+ if (!Number.isFinite(receivedAtMs)) {
14334
+ return { kind: "stale" };
14335
+ }
14336
+ const elapsedMs = Math.max(0, nowMs - receivedAtMs);
14337
+ if (elapsedMs > staleMs) {
14338
+ return { kind: "stale" };
14339
+ }
14340
+ const remainingMs = timeoutMs - elapsedMs;
14341
+ if (remainingMs <= 0) {
14342
+ return { kind: "fire" };
14343
+ }
14344
+ return { kind: "arm", remainingMs };
14345
+ }
14346
+
14326
14347
  // ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.27.1_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
14327
14348
  import process2 from "process";
14328
14349
 
@@ -15195,7 +15216,7 @@ async function processSlackRecoveryOutboxFile(filename) {
15195
15216
  `
15196
15217
  );
15197
15218
  if (payload.thread_ts) {
15198
- clearAllSlackPendingMarkersForThread(payload.channel, payload.thread_ts);
15219
+ clearPendingMessage(payload.channel, payload.thread_ts);
15199
15220
  }
15200
15221
  } else {
15201
15222
  process.stderr.write(
@@ -15306,37 +15327,126 @@ function startSlackRecoveryOutboxWatcher() {
15306
15327
  retryTimer.unref?.();
15307
15328
  }
15308
15329
  startSlackRecoveryOutboxWatcher();
15309
- function trackPendingMessage(channel, threadTs, messageTs) {
15330
+ async function fireSlackResponseTimeout(channel, threadTs, messageTs) {
15331
+ try {
15332
+ await fetch("https://slack.com/api/chat.postMessage", {
15333
+ method: "POST",
15334
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${BOT_TOKEN}` },
15335
+ body: JSON.stringify({
15336
+ channel,
15337
+ thread_ts: threadTs,
15338
+ text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant."
15339
+ })
15340
+ });
15341
+ } catch {
15342
+ }
15343
+ try {
15344
+ await fetch("https://slack.com/api/reactions.remove", {
15345
+ method: "POST",
15346
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${BOT_TOKEN}` },
15347
+ body: JSON.stringify({ channel, timestamp: messageTs, name: "eyes" })
15348
+ });
15349
+ } catch {
15350
+ }
15351
+ process.stderr.write(
15352
+ `slack-channel: Response timeout for message ${redactSlackId(messageTs)} in ${redactSlackId(channel)}
15353
+ `
15354
+ );
15355
+ clearSlackPendingInboundMarker(channel, threadTs, messageTs);
15356
+ }
15357
+ function armSlackPendingTimer(channel, threadTs, messageTs, durationMs) {
15310
15358
  const key2 = `${channel}:${threadTs}:${messageTs}`;
15311
- const timer = setTimeout(async () => {
15359
+ const existing = pendingMessages.get(key2);
15360
+ if (existing) clearTimeout(existing);
15361
+ const timer = setTimeout(() => {
15312
15362
  pendingMessages.delete(key2);
15363
+ void fireSlackResponseTimeout(channel, threadTs, messageTs);
15364
+ }, Math.max(0, durationMs));
15365
+ timer.unref?.();
15366
+ pendingMessages.set(key2, timer);
15367
+ }
15368
+ function trackPendingMessage(channel, threadTs, messageTs) {
15369
+ writeSlackPendingInboundMarker(channel, threadTs, messageTs);
15370
+ armSlackPendingTimer(channel, threadTs, messageTs, RESPONSE_TIMEOUT_MS);
15371
+ }
15372
+ var STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
15373
+ function rearmSlackPendingTimersFromDisk() {
15374
+ if (!SLACK_PENDING_INBOUND_DIR) return;
15375
+ if (!existsSync(SLACK_PENDING_INBOUND_DIR)) return;
15376
+ let filenames;
15377
+ try {
15378
+ filenames = readdirSync(SLACK_PENDING_INBOUND_DIR);
15379
+ } catch (err) {
15380
+ process.stderr.write(
15381
+ `slack-channel(${AGENT_CODE_NAME}): rearm readdir failed: ${err.message}
15382
+ `
15383
+ );
15384
+ return;
15385
+ }
15386
+ const now = Date.now();
15387
+ let armed = 0;
15388
+ let firedNow = 0;
15389
+ let cleared = 0;
15390
+ for (const filename of filenames) {
15391
+ if (!filename.endsWith(".json")) continue;
15392
+ const fullPath = join2(SLACK_PENDING_INBOUND_DIR, filename);
15393
+ let marker;
15313
15394
  try {
15314
- await fetch("https://slack.com/api/chat.postMessage", {
15315
- method: "POST",
15316
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${BOT_TOKEN}` },
15317
- body: JSON.stringify({
15318
- channel,
15319
- thread_ts: threadTs,
15320
- text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant."
15321
- })
15322
- });
15323
- } catch {
15395
+ marker = JSON.parse(readFileSync2(fullPath, "utf-8"));
15396
+ } catch (err) {
15397
+ process.stderr.write(
15398
+ `slack-channel(${AGENT_CODE_NAME}): rearm parse failed for ${filename}: ${err.message}
15399
+ `
15400
+ );
15401
+ try {
15402
+ unlinkSync(fullPath);
15403
+ } catch {
15404
+ }
15405
+ continue;
15324
15406
  }
15325
- try {
15326
- await fetch("https://slack.com/api/reactions.remove", {
15327
- method: "POST",
15328
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${BOT_TOKEN}` },
15329
- body: JSON.stringify({ channel, timestamp: messageTs, name: "eyes" })
15330
- });
15331
- } catch {
15407
+ const { channel, thread_ts, message_ts, received_at } = marker;
15408
+ if (!channel || !thread_ts || !message_ts || !received_at) {
15409
+ try {
15410
+ unlinkSync(fullPath);
15411
+ } catch {
15412
+ }
15413
+ continue;
15332
15414
  }
15333
- process.stderr.write(`slack-channel: Response timeout for message ${redactSlackId(messageTs)} in ${redactSlackId(channel)}
15334
- `);
15335
- clearSlackPendingInboundMarker(channel, threadTs, messageTs);
15336
- }, RESPONSE_TIMEOUT_MS);
15337
- pendingMessages.set(key2, timer);
15338
- writeSlackPendingInboundMarker(channel, threadTs, messageTs);
15415
+ const action = decideRearmAction({
15416
+ receivedAtMs: Date.parse(received_at),
15417
+ nowMs: now,
15418
+ timeoutMs: RESPONSE_TIMEOUT_MS,
15419
+ staleMs: STALE_MARKER_MS
15420
+ });
15421
+ if (action.kind === "stale") {
15422
+ process.stderr.write(
15423
+ `slack-channel(${AGENT_CODE_NAME}): rearm skipping stale/invalid marker channel=${redactSlackId(channel)} message=${redactSlackId(message_ts)}
15424
+ `
15425
+ );
15426
+ try {
15427
+ unlinkSync(fullPath);
15428
+ } catch {
15429
+ }
15430
+ cleared++;
15431
+ continue;
15432
+ }
15433
+ if (action.kind === "fire") {
15434
+ pendingMessages.delete(`${channel}:${thread_ts}:${message_ts}`);
15435
+ void fireSlackResponseTimeout(channel, thread_ts, message_ts);
15436
+ firedNow++;
15437
+ } else {
15438
+ armSlackPendingTimer(channel, thread_ts, message_ts, action.remainingMs);
15439
+ armed++;
15440
+ }
15441
+ }
15442
+ if (armed > 0 || firedNow > 0 || cleared > 0) {
15443
+ process.stderr.write(
15444
+ `slack-channel(${AGENT_CODE_NAME}): rearm summary armed=${armed} fired_now=${firedNow} stale_cleared=${cleared}
15445
+ `
15446
+ );
15447
+ }
15339
15448
  }
15449
+ rearmSlackPendingTimersFromDisk();
15340
15450
  function clearPendingMessage(channel, threadTs) {
15341
15451
  for (const [key2, timer] of pendingMessages) {
15342
15452
  if (key2.startsWith(`${channel}:${threadTs}:`)) {
@@ -14000,6 +14000,27 @@ function redactAugmentedPaths(msg) {
14000
14000
  );
14001
14001
  }
14002
14002
 
14003
+ // src/pending-timeout-rearm.ts
14004
+ var DEFAULT_STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
14005
+ var DEFAULT_RESPONSE_TIMEOUT_MS = 5 * 60 * 1e3;
14006
+ function decideRearmAction(opts) {
14007
+ const { receivedAtMs, nowMs } = opts;
14008
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_RESPONSE_TIMEOUT_MS;
14009
+ const staleMs = opts.staleMs ?? DEFAULT_STALE_MARKER_MS;
14010
+ if (!Number.isFinite(receivedAtMs)) {
14011
+ return { kind: "stale" };
14012
+ }
14013
+ const elapsedMs = Math.max(0, nowMs - receivedAtMs);
14014
+ if (elapsedMs > staleMs) {
14015
+ return { kind: "stale" };
14016
+ }
14017
+ const remainingMs = timeoutMs - elapsedMs;
14018
+ if (remainingMs <= 0) {
14019
+ return { kind: "fire" };
14020
+ }
14021
+ return { kind: "arm", remainingMs };
14022
+ }
14023
+
14003
14024
  // src/telegram-attachments.ts
14004
14025
  import { mkdirSync, writeFileSync, chmodSync, renameSync, unlinkSync } from "fs";
14005
14026
  function resolveTelegramInboundDir(codeName) {
@@ -15226,7 +15247,7 @@ async function processRecoveryOutboxFile(filename) {
15226
15247
  `telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery sent (chat=${redactId(payload.chat_id)} msg=${redactId(payload.message_id ?? "")})
15227
15248
  `
15228
15249
  );
15229
- if (payload.message_id) clearPendingInboundMarker(payload.chat_id, payload.message_id);
15250
+ if (payload.message_id) clearPendingMessage(payload.chat_id, payload.message_id);
15230
15251
  } else {
15231
15252
  process.stderr.write(
15232
15253
  `telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery failed (chat=${redactId(payload.chat_id)}): ${resp.description ?? "unknown"}
@@ -15334,45 +15355,129 @@ function startRecoveryOutboxWatcher() {
15334
15355
  retryTimer.unref?.();
15335
15356
  }
15336
15357
  startRecoveryOutboxWatcher();
15337
- function trackPendingMessage(chatId, messageId, chatType) {
15358
+ function fireTelegramResponseTimeout(chatId, messageId) {
15359
+ clearPendingInboundMarker(chatId, messageId);
15360
+ void setMessageReaction(chatId, messageId, null);
15361
+ void telegramApiCall(
15362
+ "sendMessage",
15363
+ {
15364
+ chat_id: chatId,
15365
+ text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant.",
15366
+ reply_to_message_id: Number(messageId),
15367
+ allow_sending_without_reply: true
15368
+ },
15369
+ 1e4
15370
+ ).then((resp) => {
15371
+ if (!resp.ok) {
15372
+ process.stderr.write(
15373
+ `telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage failed for chat ${redactId(chatId)} message ${redactId(messageId)}: ${resp.description ?? "unknown"}
15374
+ `
15375
+ );
15376
+ }
15377
+ }).catch((err) => {
15378
+ process.stderr.write(
15379
+ `telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage error for chat ${redactId(chatId)} message ${redactId(messageId)}: ${err.message}
15380
+ `
15381
+ );
15382
+ });
15383
+ process.stderr.write(
15384
+ `telegram-channel(${AGENT_CODE_NAME}): response timeout for message ${redactId(messageId)} in chat ${redactId(chatId)}
15385
+ `
15386
+ );
15387
+ }
15388
+ function armTelegramPendingTimer(chatId, messageId, chatType, durationMs) {
15338
15389
  const key2 = `${chatId}:${messageId}`;
15339
15390
  const existing = pendingMessages.get(key2);
15340
15391
  if (existing) clearTimeout(existing.timer);
15341
15392
  const timer = setTimeout(() => {
15342
15393
  pendingMessages.delete(key2);
15343
- clearPendingInboundMarker(chatId, messageId);
15344
- void setMessageReaction(chatId, messageId, null);
15345
- void telegramApiCall(
15346
- "sendMessage",
15347
- {
15348
- chat_id: chatId,
15349
- text: "Sorry \u2014 I didn't get a response back to you within 5 minutes, so this one fell on the floor. Please re-send if it's still relevant.",
15350
- reply_to_message_id: Number(messageId),
15351
- allow_sending_without_reply: true
15352
- },
15353
- 1e4
15354
- ).then((resp) => {
15355
- if (!resp.ok) {
15356
- process.stderr.write(
15357
- `telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage failed for chat ${redactId(chatId)} message ${redactId(messageId)}: ${resp.description ?? "unknown"}
15394
+ fireTelegramResponseTimeout(chatId, messageId);
15395
+ }, Math.max(0, durationMs));
15396
+ timer.unref?.();
15397
+ pendingMessages.set(key2, { timer, chatType });
15398
+ }
15399
+ function trackPendingMessage(chatId, messageId, chatType) {
15400
+ writePendingInboundMarker(chatId, messageId, chatType);
15401
+ armTelegramPendingTimer(chatId, messageId, chatType, RESPONSE_TIMEOUT_MS);
15402
+ }
15403
+ var STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
15404
+ function rearmPendingTimersFromDisk() {
15405
+ if (!PENDING_INBOUND_DIR) return;
15406
+ if (!existsSync(PENDING_INBOUND_DIR)) return;
15407
+ let filenames;
15408
+ try {
15409
+ filenames = readdirSync(PENDING_INBOUND_DIR);
15410
+ } catch (err) {
15411
+ process.stderr.write(
15412
+ `telegram-channel(${AGENT_CODE_NAME}): rearm readdir failed: ${err.message}
15358
15413
  `
15359
- );
15360
- }
15361
- }).catch((err) => {
15414
+ );
15415
+ return;
15416
+ }
15417
+ const now = Date.now();
15418
+ let armed = 0;
15419
+ let firedNow = 0;
15420
+ let cleared = 0;
15421
+ for (const filename of filenames) {
15422
+ if (!filename.endsWith(".json")) continue;
15423
+ const fullPath = join2(PENDING_INBOUND_DIR, filename);
15424
+ let marker;
15425
+ try {
15426
+ marker = JSON.parse(readFileSync(fullPath, "utf-8"));
15427
+ } catch (err) {
15362
15428
  process.stderr.write(
15363
- `telegram-channel(${AGENT_CODE_NAME}): timeout sendMessage error for chat ${redactId(chatId)} message ${redactId(messageId)}: ${err.message}
15429
+ `telegram-channel(${AGENT_CODE_NAME}): rearm parse failed for ${filename}: ${err.message}
15364
15430
  `
15365
15431
  );
15432
+ try {
15433
+ unlinkSync2(fullPath);
15434
+ } catch {
15435
+ }
15436
+ continue;
15437
+ }
15438
+ const { chat_id, message_id, chat_type, received_at } = marker;
15439
+ if (!chat_id || !message_id || !received_at) {
15440
+ try {
15441
+ unlinkSync2(fullPath);
15442
+ } catch {
15443
+ }
15444
+ continue;
15445
+ }
15446
+ const action = decideRearmAction({
15447
+ receivedAtMs: Date.parse(received_at),
15448
+ nowMs: now,
15449
+ timeoutMs: RESPONSE_TIMEOUT_MS,
15450
+ staleMs: STALE_MARKER_MS
15366
15451
  });
15452
+ if (action.kind === "stale") {
15453
+ process.stderr.write(
15454
+ `telegram-channel(${AGENT_CODE_NAME}): rearm skipping stale/invalid marker chat=${redactId(chat_id)} message=${redactId(message_id)}
15455
+ `
15456
+ );
15457
+ try {
15458
+ unlinkSync2(fullPath);
15459
+ } catch {
15460
+ }
15461
+ cleared++;
15462
+ continue;
15463
+ }
15464
+ if (action.kind === "fire") {
15465
+ pendingMessages.delete(`${chat_id}:${message_id}`);
15466
+ fireTelegramResponseTimeout(chat_id, message_id);
15467
+ firedNow++;
15468
+ } else {
15469
+ armTelegramPendingTimer(chat_id, message_id, chat_type ?? "private", action.remainingMs);
15470
+ armed++;
15471
+ }
15472
+ }
15473
+ if (armed > 0 || firedNow > 0 || cleared > 0) {
15367
15474
  process.stderr.write(
15368
- `telegram-channel(${AGENT_CODE_NAME}): response timeout for message ${redactId(messageId)} in chat ${redactId(chatId)}
15475
+ `telegram-channel(${AGENT_CODE_NAME}): rearm summary armed=${armed} fired_now=${firedNow} stale_cleared=${cleared}
15369
15476
  `
15370
15477
  );
15371
- }, RESPONSE_TIMEOUT_MS);
15372
- timer.unref?.();
15373
- pendingMessages.set(key2, { timer, chatType });
15374
- writePendingInboundMarker(chatId, messageId, chatType);
15478
+ }
15375
15479
  }
15480
+ rearmPendingTimersFromDisk();
15376
15481
  function clearPendingMessage(chatId, messageId) {
15377
15482
  if (messageId) {
15378
15483
  const key2 = `${chatId}:${messageId}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.19.25",
3
+ "version": "0.20.0",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {