@integrity-labs/agt-cli 0.28.329 → 0.28.331

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.
@@ -13865,19 +13865,19 @@ var StdioServerTransport = class {
13865
13865
 
13866
13866
  // src/teams-channel.ts
13867
13867
  import {
13868
- existsSync as existsSync4,
13868
+ existsSync as existsSync5,
13869
13869
  mkdirSync as mkdirSync4,
13870
13870
  readdirSync as readdirSync2,
13871
13871
  readFileSync as readFileSync4,
13872
13872
  renameSync,
13873
13873
  rmSync,
13874
13874
  statSync,
13875
- unlinkSync,
13875
+ unlinkSync as unlinkSync2,
13876
13876
  watch,
13877
13877
  writeFileSync as writeFileSync5
13878
13878
  } from "fs";
13879
13879
  import { homedir as homedir3 } from "os";
13880
- import { join as join5, resolve as resolvePath2 } from "path";
13880
+ import { join as join6, resolve as resolvePath2 } from "path";
13881
13881
  import { basename } from "path";
13882
13882
 
13883
13883
  // src/slack-loop-throttle.ts
@@ -15133,6 +15133,20 @@ function isThreadEntry(value) {
15133
15133
  return (v.involvement === "started" || v.involvement === "mentioned") && typeof v.last_seen_at === "string";
15134
15134
  }
15135
15135
 
15136
+ // src/recovery-ledger.ts
15137
+ import { existsSync as existsSync4, unlinkSync } from "fs";
15138
+ import { join as join5 } from "path";
15139
+ function removeRecoveryLedgerEntry(ledgerDir, markerName, unlink = (p) => {
15140
+ if (existsSync4(p)) unlinkSync(p);
15141
+ }) {
15142
+ if (!ledgerDir || !markerName) return;
15143
+ if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return;
15144
+ try {
15145
+ unlink(join5(ledgerDir, markerName));
15146
+ } catch {
15147
+ }
15148
+ }
15149
+
15136
15150
  // src/teams-channel.ts
15137
15151
  var APP_ID = process.env.MSTEAMS_APP_ID ?? null;
15138
15152
  var CLIENT_SECRET = process.env.MSTEAMS_CLIENT_SECRET ?? null;
@@ -15216,7 +15230,7 @@ var ADAPTIVE_CARDS_ENABLED = process.env.MSTEAMS_ADAPTIVE_CARDS_ENABLED === "tru
15216
15230
  var ADAPTIVE_CARDS_ASK_USER_ENABLED = process.env.MSTEAMS_ADAPTIVE_CARDS_ASK_USER_ENABLED === "true";
15217
15231
  var ASK_USER_DEFAULT_TIMEOUT_SECONDS = 300;
15218
15232
  var ASK_USER_POLL_INTERVAL_MS = 1e3;
15219
- var PROJECT_DIR = AGENT_CODE_NAME ? resolvePath2(join5(homedir3(), ".augmented", AGENT_CODE_NAME, "project")) : null;
15233
+ var PROJECT_DIR = AGENT_CODE_NAME ? resolvePath2(join6(homedir3(), ".augmented", AGENT_CODE_NAME, "project")) : null;
15220
15234
  var MAX_UPLOAD_BYTES = 4 * 1024 * 1024;
15221
15235
  var AAD_TOKEN_URL = (tenantId) => `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
15222
15236
  var BOT_FRAMEWORK_SCOPE = "https://api.botframework.com/.default";
@@ -15336,7 +15350,7 @@ var trackedThreads = /* @__PURE__ */ new Map();
15336
15350
  var threadPersister = null;
15337
15351
  function threadStorePath() {
15338
15352
  if (!AGENT_CODE_NAME) return null;
15339
- return join5(homedir3(), ".augmented", AGENT_CODE_NAME, "msteams-tracked-threads.json");
15353
+ return join6(homedir3(), ".augmented", AGENT_CODE_NAME, "msteams-tracked-threads.json");
15340
15354
  }
15341
15355
  function loadTrackedThreads() {
15342
15356
  const path = threadStorePath();
@@ -15381,9 +15395,9 @@ function rememberThread(conversationId, serviceUrl, mode, activityId) {
15381
15395
  });
15382
15396
  threadPersister?.schedule(trackedThreads);
15383
15397
  }
15384
- var AGENT_DIR = AGENT_CODE_NAME ? join5(homedir3(), ".augmented", AGENT_CODE_NAME) : null;
15385
- var PENDING_INBOUND_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-pending-inbound") : null;
15386
- var PROCESSED_DIR = PENDING_INBOUND_DIR ? join5(PENDING_INBOUND_DIR, ".processed") : null;
15398
+ var AGENT_DIR = AGENT_CODE_NAME ? join6(homedir3(), ".augmented", AGENT_CODE_NAME) : null;
15399
+ var PENDING_INBOUND_DIR = AGENT_DIR ? join6(AGENT_DIR, "msteams-pending-inbound") : null;
15400
+ var PROCESSED_DIR = PENDING_INBOUND_DIR ? join6(PENDING_INBOUND_DIR, ".processed") : null;
15387
15401
  function ensurePendingDirs() {
15388
15402
  if (!PENDING_INBOUND_DIR || !PROCESSED_DIR) return;
15389
15403
  try {
@@ -15399,7 +15413,7 @@ function ensurePendingDirs() {
15399
15413
  async function processPendingFile(filename) {
15400
15414
  if (!PENDING_INBOUND_DIR || !PROCESSED_DIR) return;
15401
15415
  if (!filename.endsWith(".json")) return;
15402
- const fullPath = join5(PENDING_INBOUND_DIR, filename);
15416
+ const fullPath = join6(PENDING_INBOUND_DIR, filename);
15403
15417
  let activity;
15404
15418
  try {
15405
15419
  const raw = readFileSync4(fullPath, "utf8");
@@ -15411,7 +15425,7 @@ async function processPendingFile(filename) {
15411
15425
  );
15412
15426
  if (PROCESSED_DIR) {
15413
15427
  try {
15414
- renameSync(fullPath, join5(PROCESSED_DIR, `${filename}.invalid`));
15428
+ renameSync(fullPath, join6(PROCESSED_DIR, `${filename}.invalid`));
15415
15429
  } catch {
15416
15430
  }
15417
15431
  }
@@ -15425,7 +15439,7 @@ async function processPendingFile(filename) {
15425
15439
  peerAgentMode: PEER_AGENT_MODE
15426
15440
  });
15427
15441
  try {
15428
- renameSync(fullPath, join5(PROCESSED_DIR, filename));
15442
+ renameSync(fullPath, join6(PROCESSED_DIR, filename));
15429
15443
  } catch {
15430
15444
  return;
15431
15445
  }
@@ -15581,7 +15595,7 @@ function startPendingInboundWatcher() {
15581
15595
  }
15582
15596
  ensurePendingDirs();
15583
15597
  try {
15584
- const entries = readdirSync2(PENDING_INBOUND_DIR).filter((f) => f.endsWith(".json")).map((f) => ({ f, m: safeMtimeMs(join5(PENDING_INBOUND_DIR, f)) })).sort((a, b) => a.m - b.m).map((e) => e.f);
15598
+ const entries = readdirSync2(PENDING_INBOUND_DIR).filter((f) => f.endsWith(".json")).map((f) => ({ f, m: safeMtimeMs(join6(PENDING_INBOUND_DIR, f)) })).sort((a, b) => a.m - b.m).map((e) => e.f);
15585
15599
  for (const f of entries) {
15586
15600
  void processPendingFile(f).catch((err) => {
15587
15601
  process.stderr.write(
@@ -15606,7 +15620,7 @@ function startPendingInboundWatcher() {
15606
15620
  if (!name || typeof name !== "string") return;
15607
15621
  if (!name.endsWith(".json")) return;
15608
15622
  if (name.startsWith(".")) return;
15609
- const fullPath = join5(PENDING_INBOUND_DIR, name);
15623
+ const fullPath = join6(PENDING_INBOUND_DIR, name);
15610
15624
  try {
15611
15625
  statSync(fullPath);
15612
15626
  } catch {
@@ -16025,7 +16039,7 @@ function optionalStringArg(args, key2) {
16025
16039
  function errResult(text) {
16026
16040
  return { content: [{ type: "text", text }], isError: true };
16027
16041
  }
16028
- var PENDING_INTERACTIONS_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-pending-interactions") : null;
16042
+ var PENDING_INTERACTIONS_DIR = AGENT_DIR ? join6(AGENT_DIR, "msteams-pending-interactions") : null;
16029
16043
  function ensurePendingInteractionsDir() {
16030
16044
  if (!PENDING_INTERACTIONS_DIR) return;
16031
16045
  try {
@@ -16041,13 +16055,13 @@ function writePendingInteraction(entry) {
16041
16055
  if (!PENDING_INTERACTIONS_DIR) return;
16042
16056
  ensurePendingInteractionsDir();
16043
16057
  writeFileSync5(
16044
- join5(PENDING_INTERACTIONS_DIR, `${entry.interaction_id}.json`),
16058
+ join6(PENDING_INTERACTIONS_DIR, `${entry.interaction_id}.json`),
16045
16059
  JSON.stringify(entry, null, 2)
16046
16060
  );
16047
16061
  }
16048
16062
  function readInteractionAnswer(interactionId) {
16049
16063
  if (!PENDING_INTERACTIONS_DIR) return null;
16050
- const path = join5(PENDING_INTERACTIONS_DIR, `${interactionId}.answer.json`);
16064
+ const path = join6(PENDING_INTERACTIONS_DIR, `${interactionId}.answer.json`);
16051
16065
  try {
16052
16066
  const raw = readFileSync4(path, "utf8");
16053
16067
  const parsed = JSON.parse(raw);
@@ -16071,9 +16085,9 @@ function readInteractionAnswer(interactionId) {
16071
16085
  function clearPendingInteraction(interactionId) {
16072
16086
  if (!PENDING_INTERACTIONS_DIR) return;
16073
16087
  for (const suffix of [".json", ".answer.json"]) {
16074
- const path = join5(PENDING_INTERACTIONS_DIR, `${interactionId}${suffix}`);
16088
+ const path = join6(PENDING_INTERACTIONS_DIR, `${interactionId}${suffix}`);
16075
16089
  try {
16076
- unlinkSync(path);
16090
+ unlinkSync2(path);
16077
16091
  } catch (err) {
16078
16092
  const code = err.code;
16079
16093
  if (code !== "ENOENT") {
@@ -16278,8 +16292,9 @@ async function handleUploadFile(args) {
16278
16292
  return errResult(`Failed: ${err.message}`);
16279
16293
  }
16280
16294
  }
16281
- var PENDING_MARKER_DIR = PENDING_INBOUND_DIR ? join5(PENDING_INBOUND_DIR, ".markers") : null;
16282
- var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-recovery-outbox") : null;
16295
+ var PENDING_MARKER_DIR = PENDING_INBOUND_DIR ? join6(PENDING_INBOUND_DIR, ".markers") : null;
16296
+ var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join6(AGENT_DIR, "msteams-recovery-outbox") : null;
16297
+ var RECOVERY_LEDGER_DIR = AGENT_DIR ? join6(AGENT_DIR, ".agt-msteams-recovery-ledger") : null;
16283
16298
  var STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
16284
16299
  var RECOVERY_RETRY_SCAN_INTERVAL_MS = 6e4;
16285
16300
  var RECOVERY_RETRY_BACKOFFS_MS = [6e4, 12e4, 24e4];
@@ -16307,7 +16322,7 @@ function writePendingMarker(activity) {
16307
16322
  const name = safeMarkerName(activity.conversation.id, activity.id);
16308
16323
  try {
16309
16324
  writeFileSync5(
16310
- join5(PENDING_MARKER_DIR, name),
16325
+ join6(PENDING_MARKER_DIR, name),
16311
16326
  JSON.stringify(
16312
16327
  {
16313
16328
  conversation_id: activity.conversation.id,
@@ -16340,7 +16355,7 @@ function clearPendingMarkersForConversation(conversationId) {
16340
16355
  for (const f of entries) {
16341
16356
  if (f.startsWith(`${safe}--`)) {
16342
16357
  try {
16343
- unlinkSync(join5(PENDING_MARKER_DIR, f));
16358
+ unlinkSync2(join6(PENDING_MARKER_DIR, f));
16344
16359
  } catch {
16345
16360
  }
16346
16361
  }
@@ -16357,11 +16372,11 @@ function sweepStaleMarkersOnBoot() {
16357
16372
  let pruned = 0;
16358
16373
  const now = Date.now();
16359
16374
  for (const f of entries) {
16360
- const path = join5(PENDING_MARKER_DIR, f);
16375
+ const path = join6(PENDING_MARKER_DIR, f);
16361
16376
  try {
16362
16377
  const stats = statSync(path);
16363
16378
  if (now - stats.mtimeMs > STALE_MARKER_MS) {
16364
- unlinkSync(path);
16379
+ unlinkSync2(path);
16365
16380
  pruned++;
16366
16381
  }
16367
16382
  } catch {
@@ -16389,7 +16404,7 @@ function recoveryNextAttempt(filename) {
16389
16404
  }
16390
16405
  async function processRecoveryFile(filename) {
16391
16406
  if (!RECOVERY_OUTBOX_DIR) return;
16392
- const fullPath = join5(RECOVERY_OUTBOX_DIR, filename);
16407
+ const fullPath = join6(RECOVERY_OUTBOX_DIR, filename);
16393
16408
  let payload;
16394
16409
  try {
16395
16410
  payload = JSON.parse(readFileSync4(fullPath, "utf8"));
@@ -16399,7 +16414,7 @@ async function processRecoveryFile(filename) {
16399
16414
  `
16400
16415
  );
16401
16416
  try {
16402
- unlinkSync(fullPath);
16417
+ unlinkSync2(fullPath);
16403
16418
  } catch {
16404
16419
  }
16405
16420
  return;
@@ -16407,8 +16422,10 @@ async function processRecoveryFile(filename) {
16407
16422
  if (!isRecoveryPayload(payload)) {
16408
16423
  process.stderr.write(`teams-channel: recovery file ${filename} malformed \u2014 dropping
16409
16424
  `);
16425
+ const malformedMarker = typeof payload === "object" && payload && "marker_name" in payload ? payload.marker_name : void 0;
16426
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, malformedMarker);
16410
16427
  try {
16411
- unlinkSync(fullPath);
16428
+ unlinkSync2(fullPath);
16412
16429
  } catch {
16413
16430
  }
16414
16431
  return;
@@ -16433,8 +16450,9 @@ async function processRecoveryFile(filename) {
16433
16450
  );
16434
16451
  if (decision.action === "suppress") {
16435
16452
  clearPendingMarkersForConversation(payload.conversation_id);
16453
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16436
16454
  try {
16437
- unlinkSync(fullPath);
16455
+ unlinkSync2(fullPath);
16438
16456
  } catch {
16439
16457
  }
16440
16458
  return;
@@ -16446,8 +16464,10 @@ async function processRecoveryFile(filename) {
16446
16464
  text: apiErr.text,
16447
16465
  ...payload.reply_to_id ? { replyToId: payload.reply_to_id } : {}
16448
16466
  });
16467
+ clearPendingMarkersForConversation(payload.conversation_id);
16468
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16449
16469
  try {
16450
- unlinkSync(fullPath);
16470
+ unlinkSync2(fullPath);
16451
16471
  } catch {
16452
16472
  }
16453
16473
  process.stderr.write(`teams-channel: recovery delivered ${filename}
@@ -16459,14 +16479,15 @@ async function processRecoveryFile(filename) {
16459
16479
  `teams-channel: recovery ${filename} exhausted retries (${err.message}) \u2014 dropping
16460
16480
  `
16461
16481
  );
16482
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16462
16483
  try {
16463
- unlinkSync(fullPath);
16484
+ unlinkSync2(fullPath);
16464
16485
  } catch {
16465
16486
  }
16466
16487
  return;
16467
16488
  }
16468
16489
  try {
16469
- renameSync(fullPath, join5(RECOVERY_OUTBOX_DIR, next.next));
16490
+ renameSync(fullPath, join6(RECOVERY_OUTBOX_DIR, next.next));
16470
16491
  process.stderr.write(
16471
16492
  `teams-channel: recovery ${filename} \u2192 attempt ${next.attempt} (${err.message})
16472
16493
  `
@@ -16492,7 +16513,7 @@ function startRecoveryOutboxWatcher() {
16492
16513
  for (const f of entries) {
16493
16514
  if (!f.endsWith(".json")) continue;
16494
16515
  if (f.startsWith(".")) continue;
16495
- const path = join5(RECOVERY_OUTBOX_DIR, f);
16516
+ const path = join6(RECOVERY_OUTBOX_DIR, f);
16496
16517
  let mtimeMs;
16497
16518
  try {
16498
16519
  mtimeMs = statSync(path).mtimeMs;
@@ -16517,7 +16538,7 @@ function startRecoveryOutboxWatcher() {
16517
16538
  if (!name || typeof name !== "string") return;
16518
16539
  if (!name.endsWith(".json")) return;
16519
16540
  if (name.startsWith(".")) return;
16520
- const path = join5(RECOVERY_OUTBOX_DIR, name);
16541
+ const path = join6(RECOVERY_OUTBOX_DIR, name);
16521
16542
  let mtimeMs;
16522
16543
  try {
16523
16544
  mtimeMs = statSync(path).mtimeMs;
@@ -16583,7 +16604,7 @@ ensureGhostReplyDirs();
16583
16604
  sweepStaleMarkersOnBoot();
16584
16605
  startPendingInboundWatcher();
16585
16606
  startRecoveryOutboxWatcher();
16586
- var NOTICE_OUTBOX_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-notice-outbox") : null;
16607
+ var NOTICE_OUTBOX_DIR = AGENT_DIR ? join6(AGENT_DIR, "msteams-notice-outbox") : null;
16587
16608
  var NOTICE_MAX_AGE_MS = 9e4;
16588
16609
  function isNoticePayload(value) {
16589
16610
  if (!value || typeof value !== "object") return false;
@@ -16597,7 +16618,7 @@ async function processNoticeFile(filename) {
16597
16618
  if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
16598
16619
  if (NOTICE_INFLIGHT.has(filename)) return;
16599
16620
  NOTICE_INFLIGHT.add(filename);
16600
- const fullPath = join5(NOTICE_OUTBOX_DIR, filename);
16621
+ const fullPath = join6(NOTICE_OUTBOX_DIR, filename);
16601
16622
  try {
16602
16623
  let mtimeMs;
16603
16624
  try {
@@ -16607,7 +16628,7 @@ async function processNoticeFile(filename) {
16607
16628
  }
16608
16629
  if (Date.now() - mtimeMs > NOTICE_MAX_AGE_MS) {
16609
16630
  try {
16610
- unlinkSync(fullPath);
16631
+ unlinkSync2(fullPath);
16611
16632
  } catch {
16612
16633
  }
16613
16634
  return;
@@ -16617,14 +16638,14 @@ async function processNoticeFile(filename) {
16617
16638
  payload = JSON.parse(readFileSync4(fullPath, "utf8"));
16618
16639
  } catch {
16619
16640
  try {
16620
- unlinkSync(fullPath);
16641
+ unlinkSync2(fullPath);
16621
16642
  } catch {
16622
16643
  }
16623
16644
  return;
16624
16645
  }
16625
16646
  if (!isNoticePayload(payload)) {
16626
16647
  try {
16627
- unlinkSync(fullPath);
16648
+ unlinkSync2(fullPath);
16628
16649
  } catch {
16629
16650
  }
16630
16651
  return;
@@ -16635,7 +16656,7 @@ async function processNoticeFile(filename) {
16635
16656
  defaultValue: false
16636
16657
  })) {
16637
16658
  try {
16638
- unlinkSync(fullPath);
16659
+ unlinkSync2(fullPath);
16639
16660
  } catch {
16640
16661
  }
16641
16662
  return;
@@ -16655,7 +16676,7 @@ async function processNoticeFile(filename) {
16655
16676
  );
16656
16677
  }
16657
16678
  try {
16658
- unlinkSync(fullPath);
16679
+ unlinkSync2(fullPath);
16659
16680
  } catch {
16660
16681
  }
16661
16682
  } finally {
@@ -16678,7 +16699,7 @@ function startNoticeOutboxWatcher() {
16678
16699
  try {
16679
16700
  const w = watch(NOTICE_OUTBOX_DIR, (_event, name) => {
16680
16701
  if (!name) return;
16681
- if (existsSync4(join5(NOTICE_OUTBOX_DIR, name))) void processNoticeFile(name);
16702
+ if (existsSync5(join6(NOTICE_OUTBOX_DIR, name))) void processNoticeFile(name);
16682
16703
  });
16683
16704
  w.unref?.();
16684
16705
  } catch (err) {