@integrity-labs/agt-cli 0.28.330 → 0.28.332

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,
13869
- mkdirSync as mkdirSync4,
13870
- readdirSync as readdirSync2,
13871
- readFileSync as readFileSync4,
13872
- renameSync,
13868
+ existsSync as existsSync6,
13869
+ mkdirSync as mkdirSync5,
13870
+ readdirSync as readdirSync3,
13871
+ readFileSync as readFileSync5,
13872
+ renameSync as renameSync2,
13873
13873
  rmSync,
13874
13874
  statSync,
13875
- unlinkSync,
13875
+ unlinkSync as unlinkSync2,
13876
13876
  watch,
13877
- writeFileSync as writeFileSync5
13877
+ writeFileSync as writeFileSync6
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 join7, resolve as resolvePath2 } from "path";
13881
13881
  import { basename } from "path";
13882
13882
 
13883
13883
  // src/slack-loop-throttle.ts
@@ -15133,6 +15133,59 @@ 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
+
15150
+ // src/inbound-delivery-ledger.ts
15151
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync4, renameSync, writeFileSync as writeFileSync5 } from "fs";
15152
+ import { join as join6 } from "path";
15153
+ function safeInboundId(inboundId) {
15154
+ return inboundId.replace(/[^A-Za-z0-9_-]/g, "_");
15155
+ }
15156
+ var defaultDeps = {
15157
+ mkdir: (dir) => mkdirSync4(dir, { recursive: true }),
15158
+ writeFile: (path, data) => writeFileSync5(path, data, "utf8"),
15159
+ rename: (from, to) => renameSync(from, to),
15160
+ readdir: (dir) => readdirSync2(dir),
15161
+ readFile: (path) => readFileSync4(path, "utf8"),
15162
+ exists: (path) => existsSync5(path)
15163
+ };
15164
+ function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
15165
+ if (!dir || !record2.inbound_id || !record2.conv_key) return;
15166
+ const safe = safeInboundId(record2.inbound_id);
15167
+ if (!safe || safe.includes("/") || safe.includes("\\") || safe.includes("..")) return;
15168
+ try {
15169
+ deps.mkdir(dir);
15170
+ const final = join6(dir, `${safe}.json`);
15171
+ const tmp = `${final}.tmp`;
15172
+ deps.writeFile(tmp, JSON.stringify(record2));
15173
+ deps.rename(tmp, final);
15174
+ } catch {
15175
+ }
15176
+ }
15177
+
15178
+ // src/channel-inbound-id.ts
15179
+ import { createHash } from "crypto";
15180
+ var INBOUND_ID_HEX_LEN = 12;
15181
+ function hashInboundId(payload) {
15182
+ const digest = createHash("sha256").update(payload).digest("hex").slice(0, INBOUND_ID_HEX_LEN);
15183
+ return `ib_${digest}`;
15184
+ }
15185
+ function teamsInboundId(conversationId, activityId) {
15186
+ return hashInboundId(`${conversationId}|${activityId}`);
15187
+ }
15188
+
15136
15189
  // src/teams-channel.ts
15137
15190
  var APP_ID = process.env.MSTEAMS_APP_ID ?? null;
15138
15191
  var CLIENT_SECRET = process.env.MSTEAMS_CLIENT_SECRET ?? null;
@@ -15216,7 +15269,7 @@ var ADAPTIVE_CARDS_ENABLED = process.env.MSTEAMS_ADAPTIVE_CARDS_ENABLED === "tru
15216
15269
  var ADAPTIVE_CARDS_ASK_USER_ENABLED = process.env.MSTEAMS_ADAPTIVE_CARDS_ASK_USER_ENABLED === "true";
15217
15270
  var ASK_USER_DEFAULT_TIMEOUT_SECONDS = 300;
15218
15271
  var ASK_USER_POLL_INTERVAL_MS = 1e3;
15219
- var PROJECT_DIR = AGENT_CODE_NAME ? resolvePath2(join5(homedir3(), ".augmented", AGENT_CODE_NAME, "project")) : null;
15272
+ var PROJECT_DIR = AGENT_CODE_NAME ? resolvePath2(join7(homedir3(), ".augmented", AGENT_CODE_NAME, "project")) : null;
15220
15273
  var MAX_UPLOAD_BYTES = 4 * 1024 * 1024;
15221
15274
  var AAD_TOKEN_URL = (tenantId) => `https://login.microsoftonline.com/${encodeURIComponent(tenantId)}/oauth2/v2.0/token`;
15222
15275
  var BOT_FRAMEWORK_SCOPE = "https://api.botframework.com/.default";
@@ -15336,7 +15389,7 @@ var trackedThreads = /* @__PURE__ */ new Map();
15336
15389
  var threadPersister = null;
15337
15390
  function threadStorePath() {
15338
15391
  if (!AGENT_CODE_NAME) return null;
15339
- return join5(homedir3(), ".augmented", AGENT_CODE_NAME, "msteams-tracked-threads.json");
15392
+ return join7(homedir3(), ".augmented", AGENT_CODE_NAME, "msteams-tracked-threads.json");
15340
15393
  }
15341
15394
  function loadTrackedThreads() {
15342
15395
  const path = threadStorePath();
@@ -15381,14 +15434,14 @@ function rememberThread(conversationId, serviceUrl, mode, activityId) {
15381
15434
  });
15382
15435
  threadPersister?.schedule(trackedThreads);
15383
15436
  }
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;
15437
+ var AGENT_DIR = AGENT_CODE_NAME ? join7(homedir3(), ".augmented", AGENT_CODE_NAME) : null;
15438
+ var PENDING_INBOUND_DIR = AGENT_DIR ? join7(AGENT_DIR, "msteams-pending-inbound") : null;
15439
+ var PROCESSED_DIR = PENDING_INBOUND_DIR ? join7(PENDING_INBOUND_DIR, ".processed") : null;
15387
15440
  function ensurePendingDirs() {
15388
15441
  if (!PENDING_INBOUND_DIR || !PROCESSED_DIR) return;
15389
15442
  try {
15390
- mkdirSync4(PENDING_INBOUND_DIR, { recursive: true });
15391
- mkdirSync4(PROCESSED_DIR, { recursive: true });
15443
+ mkdirSync5(PENDING_INBOUND_DIR, { recursive: true });
15444
+ mkdirSync5(PROCESSED_DIR, { recursive: true });
15392
15445
  } catch (err) {
15393
15446
  process.stderr.write(
15394
15447
  `teams-channel: failed to ensure pending-inbound dir (${err.message})
@@ -15399,10 +15452,10 @@ function ensurePendingDirs() {
15399
15452
  async function processPendingFile(filename) {
15400
15453
  if (!PENDING_INBOUND_DIR || !PROCESSED_DIR) return;
15401
15454
  if (!filename.endsWith(".json")) return;
15402
- const fullPath = join5(PENDING_INBOUND_DIR, filename);
15455
+ const fullPath = join7(PENDING_INBOUND_DIR, filename);
15403
15456
  let activity;
15404
15457
  try {
15405
- const raw = readFileSync4(fullPath, "utf8");
15458
+ const raw = readFileSync5(fullPath, "utf8");
15406
15459
  activity = JSON.parse(raw);
15407
15460
  } catch (err) {
15408
15461
  process.stderr.write(
@@ -15411,7 +15464,7 @@ async function processPendingFile(filename) {
15411
15464
  );
15412
15465
  if (PROCESSED_DIR) {
15413
15466
  try {
15414
- renameSync(fullPath, join5(PROCESSED_DIR, `${filename}.invalid`));
15467
+ renameSync2(fullPath, join7(PROCESSED_DIR, `${filename}.invalid`));
15415
15468
  } catch {
15416
15469
  }
15417
15470
  }
@@ -15425,7 +15478,7 @@ async function processPendingFile(filename) {
15425
15478
  peerAgentMode: PEER_AGENT_MODE
15426
15479
  });
15427
15480
  try {
15428
- renameSync(fullPath, join5(PROCESSED_DIR, filename));
15481
+ renameSync2(fullPath, join7(PROCESSED_DIR, filename));
15429
15482
  } catch {
15430
15483
  return;
15431
15484
  }
@@ -15581,7 +15634,7 @@ function startPendingInboundWatcher() {
15581
15634
  }
15582
15635
  ensurePendingDirs();
15583
15636
  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);
15637
+ const entries = readdirSync3(PENDING_INBOUND_DIR).filter((f) => f.endsWith(".json")).map((f) => ({ f, m: safeMtimeMs(join7(PENDING_INBOUND_DIR, f)) })).sort((a, b) => a.m - b.m).map((e) => e.f);
15585
15638
  for (const f of entries) {
15586
15639
  void processPendingFile(f).catch((err) => {
15587
15640
  process.stderr.write(
@@ -15606,7 +15659,7 @@ function startPendingInboundWatcher() {
15606
15659
  if (!name || typeof name !== "string") return;
15607
15660
  if (!name.endsWith(".json")) return;
15608
15661
  if (name.startsWith(".")) return;
15609
- const fullPath = join5(PENDING_INBOUND_DIR, name);
15662
+ const fullPath = join7(PENDING_INBOUND_DIR, name);
15610
15663
  try {
15611
15664
  statSync(fullPath);
15612
15665
  } catch {
@@ -15863,6 +15916,12 @@ async function handleReply(args) {
15863
15916
  });
15864
15917
  recordReply(conversationId, throttleKey, now, throttleCfg);
15865
15918
  clearPendingMarkersForConversation(conversationId);
15919
+ writeInboundDeliveryLedgerEntry(DELIVERY_LEDGER_DIR, {
15920
+ inbound_id: teamsInboundId(conversationId, replyToId ?? ""),
15921
+ source: "msteams",
15922
+ conv_key: conversationId,
15923
+ delivered_at: (/* @__PURE__ */ new Date()).toISOString()
15924
+ });
15866
15925
  if (THREAD_AUTO_FOLLOW !== "off") {
15867
15926
  rememberThread(conversationId, serviceUrl, replyToId ? "mentioned" : "started", result.id);
15868
15927
  }
@@ -16025,11 +16084,11 @@ function optionalStringArg(args, key2) {
16025
16084
  function errResult(text) {
16026
16085
  return { content: [{ type: "text", text }], isError: true };
16027
16086
  }
16028
- var PENDING_INTERACTIONS_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-pending-interactions") : null;
16087
+ var PENDING_INTERACTIONS_DIR = AGENT_DIR ? join7(AGENT_DIR, "msteams-pending-interactions") : null;
16029
16088
  function ensurePendingInteractionsDir() {
16030
16089
  if (!PENDING_INTERACTIONS_DIR) return;
16031
16090
  try {
16032
- mkdirSync4(PENDING_INTERACTIONS_DIR, { recursive: true });
16091
+ mkdirSync5(PENDING_INTERACTIONS_DIR, { recursive: true });
16033
16092
  } catch (err) {
16034
16093
  process.stderr.write(
16035
16094
  `teams-channel: failed to ensure pending-interactions dir (${err.message})
@@ -16040,16 +16099,16 @@ function ensurePendingInteractionsDir() {
16040
16099
  function writePendingInteraction(entry) {
16041
16100
  if (!PENDING_INTERACTIONS_DIR) return;
16042
16101
  ensurePendingInteractionsDir();
16043
- writeFileSync5(
16044
- join5(PENDING_INTERACTIONS_DIR, `${entry.interaction_id}.json`),
16102
+ writeFileSync6(
16103
+ join7(PENDING_INTERACTIONS_DIR, `${entry.interaction_id}.json`),
16045
16104
  JSON.stringify(entry, null, 2)
16046
16105
  );
16047
16106
  }
16048
16107
  function readInteractionAnswer(interactionId) {
16049
16108
  if (!PENDING_INTERACTIONS_DIR) return null;
16050
- const path = join5(PENDING_INTERACTIONS_DIR, `${interactionId}.answer.json`);
16109
+ const path = join7(PENDING_INTERACTIONS_DIR, `${interactionId}.answer.json`);
16051
16110
  try {
16052
- const raw = readFileSync4(path, "utf8");
16111
+ const raw = readFileSync5(path, "utf8");
16053
16112
  const parsed = JSON.parse(raw);
16054
16113
  if (typeof parsed.value !== "string") return null;
16055
16114
  return {
@@ -16071,9 +16130,9 @@ function readInteractionAnswer(interactionId) {
16071
16130
  function clearPendingInteraction(interactionId) {
16072
16131
  if (!PENDING_INTERACTIONS_DIR) return;
16073
16132
  for (const suffix of [".json", ".answer.json"]) {
16074
- const path = join5(PENDING_INTERACTIONS_DIR, `${interactionId}${suffix}`);
16133
+ const path = join7(PENDING_INTERACTIONS_DIR, `${interactionId}${suffix}`);
16075
16134
  try {
16076
- unlinkSync(path);
16135
+ unlinkSync2(path);
16077
16136
  } catch (err) {
16078
16137
  const code = err.code;
16079
16138
  if (code !== "ENOENT") {
@@ -16235,7 +16294,7 @@ async function handleUploadFile(args) {
16235
16294
  );
16236
16295
  }
16237
16296
  try {
16238
- buffer = readFileSync4(sandboxed.resolved);
16297
+ buffer = readFileSync5(sandboxed.resolved);
16239
16298
  } catch (err) {
16240
16299
  return errResult(`Failed to read file: ${err.message}`);
16241
16300
  }
@@ -16278,8 +16337,10 @@ async function handleUploadFile(args) {
16278
16337
  return errResult(`Failed: ${err.message}`);
16279
16338
  }
16280
16339
  }
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;
16340
+ var PENDING_MARKER_DIR = PENDING_INBOUND_DIR ? join7(PENDING_INBOUND_DIR, ".markers") : null;
16341
+ var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join7(AGENT_DIR, "msteams-recovery-outbox") : null;
16342
+ var RECOVERY_LEDGER_DIR = AGENT_DIR ? join7(AGENT_DIR, ".agt-msteams-recovery-ledger") : null;
16343
+ var DELIVERY_LEDGER_DIR = AGENT_DIR ? join7(AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
16283
16344
  var STALE_MARKER_MS = 24 * 60 * 60 * 1e3;
16284
16345
  var RECOVERY_RETRY_SCAN_INTERVAL_MS = 6e4;
16285
16346
  var RECOVERY_RETRY_BACKOFFS_MS = [6e4, 12e4, 24e4];
@@ -16288,7 +16349,7 @@ function ensureGhostReplyDirs() {
16288
16349
  for (const dir of [PENDING_MARKER_DIR, RECOVERY_OUTBOX_DIR]) {
16289
16350
  if (!dir) continue;
16290
16351
  try {
16291
- mkdirSync4(dir, { recursive: true });
16352
+ mkdirSync5(dir, { recursive: true });
16292
16353
  } catch (err) {
16293
16354
  process.stderr.write(
16294
16355
  `teams-channel: failed to ensure ${dir} (${err.message})
@@ -16306,8 +16367,8 @@ function writePendingMarker(activity) {
16306
16367
  ensureGhostReplyDirs();
16307
16368
  const name = safeMarkerName(activity.conversation.id, activity.id);
16308
16369
  try {
16309
- writeFileSync5(
16310
- join5(PENDING_MARKER_DIR, name),
16370
+ writeFileSync6(
16371
+ join7(PENDING_MARKER_DIR, name),
16311
16372
  JSON.stringify(
16312
16373
  {
16313
16374
  conversation_id: activity.conversation.id,
@@ -16315,7 +16376,10 @@ function writePendingMarker(activity) {
16315
16376
  activity_id: activity.id,
16316
16377
  from: activity.from,
16317
16378
  text: activity.text,
16318
- received_at: (/* @__PURE__ */ new Date()).toISOString()
16379
+ received_at: (/* @__PURE__ */ new Date()).toISOString(),
16380
+ // ENG-7806 (fm1): deterministic inbound id (marker-semantics-neutral);
16381
+ // the Stop hook reads it to look up the inbound-delivery ledger.
16382
+ inbound_id: teamsInboundId(activity.conversation.id, activity.id ?? "")
16319
16383
  },
16320
16384
  null,
16321
16385
  2
@@ -16333,14 +16397,14 @@ function clearPendingMarkersForConversation(conversationId) {
16333
16397
  const safe = Buffer.from(conversationId, "utf8").toString("hex").slice(0, 64);
16334
16398
  let entries;
16335
16399
  try {
16336
- entries = readdirSync2(PENDING_MARKER_DIR);
16400
+ entries = readdirSync3(PENDING_MARKER_DIR);
16337
16401
  } catch {
16338
16402
  return;
16339
16403
  }
16340
16404
  for (const f of entries) {
16341
16405
  if (f.startsWith(`${safe}--`)) {
16342
16406
  try {
16343
- unlinkSync(join5(PENDING_MARKER_DIR, f));
16407
+ unlinkSync2(join7(PENDING_MARKER_DIR, f));
16344
16408
  } catch {
16345
16409
  }
16346
16410
  }
@@ -16350,18 +16414,18 @@ function sweepStaleMarkersOnBoot() {
16350
16414
  if (!PENDING_MARKER_DIR) return;
16351
16415
  let entries;
16352
16416
  try {
16353
- entries = readdirSync2(PENDING_MARKER_DIR);
16417
+ entries = readdirSync3(PENDING_MARKER_DIR);
16354
16418
  } catch {
16355
16419
  return;
16356
16420
  }
16357
16421
  let pruned = 0;
16358
16422
  const now = Date.now();
16359
16423
  for (const f of entries) {
16360
- const path = join5(PENDING_MARKER_DIR, f);
16424
+ const path = join7(PENDING_MARKER_DIR, f);
16361
16425
  try {
16362
16426
  const stats = statSync(path);
16363
16427
  if (now - stats.mtimeMs > STALE_MARKER_MS) {
16364
- unlinkSync(path);
16428
+ unlinkSync2(path);
16365
16429
  pruned++;
16366
16430
  }
16367
16431
  } catch {
@@ -16389,17 +16453,17 @@ function recoveryNextAttempt(filename) {
16389
16453
  }
16390
16454
  async function processRecoveryFile(filename) {
16391
16455
  if (!RECOVERY_OUTBOX_DIR) return;
16392
- const fullPath = join5(RECOVERY_OUTBOX_DIR, filename);
16456
+ const fullPath = join7(RECOVERY_OUTBOX_DIR, filename);
16393
16457
  let payload;
16394
16458
  try {
16395
- payload = JSON.parse(readFileSync4(fullPath, "utf8"));
16459
+ payload = JSON.parse(readFileSync5(fullPath, "utf8"));
16396
16460
  } catch (err) {
16397
16461
  process.stderr.write(
16398
16462
  `teams-channel: recovery file ${filename} unreadable (${err.message}) \u2014 dropping
16399
16463
  `
16400
16464
  );
16401
16465
  try {
16402
- unlinkSync(fullPath);
16466
+ unlinkSync2(fullPath);
16403
16467
  } catch {
16404
16468
  }
16405
16469
  return;
@@ -16407,8 +16471,10 @@ async function processRecoveryFile(filename) {
16407
16471
  if (!isRecoveryPayload(payload)) {
16408
16472
  process.stderr.write(`teams-channel: recovery file ${filename} malformed \u2014 dropping
16409
16473
  `);
16474
+ const malformedMarker = typeof payload === "object" && payload && "marker_name" in payload ? payload.marker_name : void 0;
16475
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, malformedMarker);
16410
16476
  try {
16411
- unlinkSync(fullPath);
16477
+ unlinkSync2(fullPath);
16412
16478
  } catch {
16413
16479
  }
16414
16480
  return;
@@ -16433,8 +16499,9 @@ async function processRecoveryFile(filename) {
16433
16499
  );
16434
16500
  if (decision.action === "suppress") {
16435
16501
  clearPendingMarkersForConversation(payload.conversation_id);
16502
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16436
16503
  try {
16437
- unlinkSync(fullPath);
16504
+ unlinkSync2(fullPath);
16438
16505
  } catch {
16439
16506
  }
16440
16507
  return;
@@ -16446,8 +16513,10 @@ async function processRecoveryFile(filename) {
16446
16513
  text: apiErr.text,
16447
16514
  ...payload.reply_to_id ? { replyToId: payload.reply_to_id } : {}
16448
16515
  });
16516
+ clearPendingMarkersForConversation(payload.conversation_id);
16517
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16449
16518
  try {
16450
- unlinkSync(fullPath);
16519
+ unlinkSync2(fullPath);
16451
16520
  } catch {
16452
16521
  }
16453
16522
  process.stderr.write(`teams-channel: recovery delivered ${filename}
@@ -16459,14 +16528,15 @@ async function processRecoveryFile(filename) {
16459
16528
  `teams-channel: recovery ${filename} exhausted retries (${err.message}) \u2014 dropping
16460
16529
  `
16461
16530
  );
16531
+ removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
16462
16532
  try {
16463
- unlinkSync(fullPath);
16533
+ unlinkSync2(fullPath);
16464
16534
  } catch {
16465
16535
  }
16466
16536
  return;
16467
16537
  }
16468
16538
  try {
16469
- renameSync(fullPath, join5(RECOVERY_OUTBOX_DIR, next.next));
16539
+ renameSync2(fullPath, join7(RECOVERY_OUTBOX_DIR, next.next));
16470
16540
  process.stderr.write(
16471
16541
  `teams-channel: recovery ${filename} \u2192 attempt ${next.attempt} (${err.message})
16472
16542
  `
@@ -16488,11 +16558,11 @@ function startRecoveryOutboxWatcher() {
16488
16558
  ensureGhostReplyDirs();
16489
16559
  const scan = () => {
16490
16560
  try {
16491
- const entries = readdirSync2(RECOVERY_OUTBOX_DIR);
16561
+ const entries = readdirSync3(RECOVERY_OUTBOX_DIR);
16492
16562
  for (const f of entries) {
16493
16563
  if (!f.endsWith(".json")) continue;
16494
16564
  if (f.startsWith(".")) continue;
16495
- const path = join5(RECOVERY_OUTBOX_DIR, f);
16565
+ const path = join7(RECOVERY_OUTBOX_DIR, f);
16496
16566
  let mtimeMs;
16497
16567
  try {
16498
16568
  mtimeMs = statSync(path).mtimeMs;
@@ -16517,7 +16587,7 @@ function startRecoveryOutboxWatcher() {
16517
16587
  if (!name || typeof name !== "string") return;
16518
16588
  if (!name.endsWith(".json")) return;
16519
16589
  if (name.startsWith(".")) return;
16520
- const path = join5(RECOVERY_OUTBOX_DIR, name);
16590
+ const path = join7(RECOVERY_OUTBOX_DIR, name);
16521
16591
  let mtimeMs;
16522
16592
  try {
16523
16593
  mtimeMs = statSync(path).mtimeMs;
@@ -16583,7 +16653,7 @@ ensureGhostReplyDirs();
16583
16653
  sweepStaleMarkersOnBoot();
16584
16654
  startPendingInboundWatcher();
16585
16655
  startRecoveryOutboxWatcher();
16586
- var NOTICE_OUTBOX_DIR = AGENT_DIR ? join5(AGENT_DIR, "msteams-notice-outbox") : null;
16656
+ var NOTICE_OUTBOX_DIR = AGENT_DIR ? join7(AGENT_DIR, "msteams-notice-outbox") : null;
16587
16657
  var NOTICE_MAX_AGE_MS = 9e4;
16588
16658
  function isNoticePayload(value) {
16589
16659
  if (!value || typeof value !== "object") return false;
@@ -16597,7 +16667,7 @@ async function processNoticeFile(filename) {
16597
16667
  if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
16598
16668
  if (NOTICE_INFLIGHT.has(filename)) return;
16599
16669
  NOTICE_INFLIGHT.add(filename);
16600
- const fullPath = join5(NOTICE_OUTBOX_DIR, filename);
16670
+ const fullPath = join7(NOTICE_OUTBOX_DIR, filename);
16601
16671
  try {
16602
16672
  let mtimeMs;
16603
16673
  try {
@@ -16607,24 +16677,24 @@ async function processNoticeFile(filename) {
16607
16677
  }
16608
16678
  if (Date.now() - mtimeMs > NOTICE_MAX_AGE_MS) {
16609
16679
  try {
16610
- unlinkSync(fullPath);
16680
+ unlinkSync2(fullPath);
16611
16681
  } catch {
16612
16682
  }
16613
16683
  return;
16614
16684
  }
16615
16685
  let payload;
16616
16686
  try {
16617
- payload = JSON.parse(readFileSync4(fullPath, "utf8"));
16687
+ payload = JSON.parse(readFileSync5(fullPath, "utf8"));
16618
16688
  } catch {
16619
16689
  try {
16620
- unlinkSync(fullPath);
16690
+ unlinkSync2(fullPath);
16621
16691
  } catch {
16622
16692
  }
16623
16693
  return;
16624
16694
  }
16625
16695
  if (!isNoticePayload(payload)) {
16626
16696
  try {
16627
- unlinkSync(fullPath);
16697
+ unlinkSync2(fullPath);
16628
16698
  } catch {
16629
16699
  }
16630
16700
  return;
@@ -16635,7 +16705,7 @@ async function processNoticeFile(filename) {
16635
16705
  defaultValue: false
16636
16706
  })) {
16637
16707
  try {
16638
- unlinkSync(fullPath);
16708
+ unlinkSync2(fullPath);
16639
16709
  } catch {
16640
16710
  }
16641
16711
  return;
@@ -16655,7 +16725,7 @@ async function processNoticeFile(filename) {
16655
16725
  );
16656
16726
  }
16657
16727
  try {
16658
- unlinkSync(fullPath);
16728
+ unlinkSync2(fullPath);
16659
16729
  } catch {
16660
16730
  }
16661
16731
  } finally {
@@ -16665,20 +16735,20 @@ async function processNoticeFile(filename) {
16665
16735
  function startNoticeOutboxWatcher() {
16666
16736
  if (!NOTICE_OUTBOX_DIR) return;
16667
16737
  try {
16668
- mkdirSync4(NOTICE_OUTBOX_DIR, { recursive: true, mode: 448 });
16738
+ mkdirSync5(NOTICE_OUTBOX_DIR, { recursive: true, mode: 448 });
16669
16739
  } catch (err) {
16670
16740
  process.stderr.write(`teams-channel: notice outbox mkdir failed (${err.message})
16671
16741
  `);
16672
16742
  return;
16673
16743
  }
16674
16744
  try {
16675
- for (const f of readdirSync2(NOTICE_OUTBOX_DIR)) void processNoticeFile(f);
16745
+ for (const f of readdirSync3(NOTICE_OUTBOX_DIR)) void processNoticeFile(f);
16676
16746
  } catch {
16677
16747
  }
16678
16748
  try {
16679
16749
  const w = watch(NOTICE_OUTBOX_DIR, (_event, name) => {
16680
16750
  if (!name) return;
16681
- if (existsSync4(join5(NOTICE_OUTBOX_DIR, name))) void processNoticeFile(name);
16751
+ if (existsSync6(join7(NOTICE_OUTBOX_DIR, name))) void processNoticeFile(name);
16682
16752
  });
16683
16753
  w.unref?.();
16684
16754
  } catch (err) {