@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.
- package/dist/bin/agt.js +3 -3
- package/dist/{chunk-CDRVXSQ3.js → chunk-YNHMQ4CW.js} +200 -41
- package/dist/chunk-YNHMQ4CW.js.map +1 -0
- package/dist/lib/manager-worker.js +4 -4
- package/dist/mcp/direct-chat-channel.js +92 -51
- package/dist/mcp/slack-channel.js +212 -146
- package/dist/mcp/teams-channel.js +133 -63
- package/dist/mcp/telegram-channel.js +187 -110
- package/dist/{responsiveness-probe-OJJESVVX.js → responsiveness-probe-46XFHCPY.js} +12 -2
- package/dist/responsiveness-probe-46XFHCPY.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-CDRVXSQ3.js.map +0 -1
- package/dist/responsiveness-probe-OJJESVVX.js.map +0 -1
|
@@ -13865,19 +13865,19 @@ var StdioServerTransport = class {
|
|
|
13865
13865
|
|
|
13866
13866
|
// src/teams-channel.ts
|
|
13867
13867
|
import {
|
|
13868
|
-
existsSync as
|
|
13869
|
-
mkdirSync as
|
|
13870
|
-
readdirSync as
|
|
13871
|
-
readFileSync as
|
|
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
|
|
13877
|
+
writeFileSync as writeFileSync6
|
|
13878
13878
|
} from "fs";
|
|
13879
13879
|
import { homedir as homedir3 } from "os";
|
|
13880
|
-
import { join as
|
|
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(
|
|
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
|
|
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 ?
|
|
15385
|
-
var PENDING_INBOUND_DIR = AGENT_DIR ?
|
|
15386
|
-
var PROCESSED_DIR = PENDING_INBOUND_DIR ?
|
|
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
|
-
|
|
15391
|
-
|
|
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 =
|
|
15455
|
+
const fullPath = join7(PENDING_INBOUND_DIR, filename);
|
|
15403
15456
|
let activity;
|
|
15404
15457
|
try {
|
|
15405
|
-
const raw =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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
|
-
|
|
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
|
-
|
|
16044
|
-
|
|
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 =
|
|
16109
|
+
const path = join7(PENDING_INTERACTIONS_DIR, `${interactionId}.answer.json`);
|
|
16051
16110
|
try {
|
|
16052
|
-
const raw =
|
|
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 =
|
|
16133
|
+
const path = join7(PENDING_INTERACTIONS_DIR, `${interactionId}${suffix}`);
|
|
16075
16134
|
try {
|
|
16076
|
-
|
|
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 =
|
|
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 ?
|
|
16282
|
-
var RECOVERY_OUTBOX_DIR = AGENT_DIR ?
|
|
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
|
-
|
|
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
|
-
|
|
16310
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
16456
|
+
const fullPath = join7(RECOVERY_OUTBOX_DIR, filename);
|
|
16393
16457
|
let payload;
|
|
16394
16458
|
try {
|
|
16395
|
-
payload = JSON.parse(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16533
|
+
unlinkSync2(fullPath);
|
|
16464
16534
|
} catch {
|
|
16465
16535
|
}
|
|
16466
16536
|
return;
|
|
16467
16537
|
}
|
|
16468
16538
|
try {
|
|
16469
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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
|
-
|
|
16680
|
+
unlinkSync2(fullPath);
|
|
16611
16681
|
} catch {
|
|
16612
16682
|
}
|
|
16613
16683
|
return;
|
|
16614
16684
|
}
|
|
16615
16685
|
let payload;
|
|
16616
16686
|
try {
|
|
16617
|
-
payload = JSON.parse(
|
|
16687
|
+
payload = JSON.parse(readFileSync5(fullPath, "utf8"));
|
|
16618
16688
|
} catch {
|
|
16619
16689
|
try {
|
|
16620
|
-
|
|
16690
|
+
unlinkSync2(fullPath);
|
|
16621
16691
|
} catch {
|
|
16622
16692
|
}
|
|
16623
16693
|
return;
|
|
16624
16694
|
}
|
|
16625
16695
|
if (!isNoticePayload(payload)) {
|
|
16626
16696
|
try {
|
|
16627
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
16751
|
+
if (existsSync6(join7(NOTICE_OUTBOX_DIR, name))) void processNoticeFile(name);
|
|
16682
16752
|
});
|
|
16683
16753
|
w.unref?.();
|
|
16684
16754
|
} catch (err) {
|