@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
|
@@ -14518,26 +14518,26 @@ var StdioServerTransport = class {
|
|
|
14518
14518
|
|
|
14519
14519
|
// src/telegram-channel.ts
|
|
14520
14520
|
import https from "https";
|
|
14521
|
-
import { createHash, randomUUID as randomUUID3 } from "crypto";
|
|
14521
|
+
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
14522
14522
|
import {
|
|
14523
14523
|
closeSync,
|
|
14524
14524
|
createWriteStream,
|
|
14525
|
-
existsSync as
|
|
14525
|
+
existsSync as existsSync9,
|
|
14526
14526
|
ftruncateSync,
|
|
14527
|
-
mkdirSync as
|
|
14527
|
+
mkdirSync as mkdirSync9,
|
|
14528
14528
|
openSync,
|
|
14529
|
-
readFileSync as
|
|
14530
|
-
readdirSync as
|
|
14529
|
+
readFileSync as readFileSync12,
|
|
14530
|
+
readdirSync as readdirSync4,
|
|
14531
14531
|
realpathSync,
|
|
14532
|
-
renameSync as
|
|
14532
|
+
renameSync as renameSync7,
|
|
14533
14533
|
statSync as statSync2,
|
|
14534
|
-
unlinkSync as
|
|
14534
|
+
unlinkSync as unlinkSync7,
|
|
14535
14535
|
watch,
|
|
14536
|
-
writeFileSync as
|
|
14536
|
+
writeFileSync as writeFileSync11,
|
|
14537
14537
|
writeSync
|
|
14538
14538
|
} from "fs";
|
|
14539
14539
|
import { homedir as homedir4 } from "os";
|
|
14540
|
-
import { basename, extname, join as
|
|
14540
|
+
import { basename, extname, join as join12, resolve as resolve2 } from "path";
|
|
14541
14541
|
|
|
14542
14542
|
// src/channel-attachments.ts
|
|
14543
14543
|
import { homedir } from "os";
|
|
@@ -17024,6 +17024,68 @@ function applyToChatMarkers(pendingDir, chatId, op, cutoffMs) {
|
|
|
17024
17024
|
return applied;
|
|
17025
17025
|
}
|
|
17026
17026
|
|
|
17027
|
+
// src/recovery-ledger.ts
|
|
17028
|
+
import { existsSync as existsSync6, unlinkSync as unlinkSync5 } from "fs";
|
|
17029
|
+
import { join as join8 } from "path";
|
|
17030
|
+
function recoveryLedgerEntryExists(ledgerDir, markerName, exists = (p) => existsSync6(p)) {
|
|
17031
|
+
if (!ledgerDir || !markerName) return false;
|
|
17032
|
+
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return false;
|
|
17033
|
+
try {
|
|
17034
|
+
return exists(join8(ledgerDir, markerName));
|
|
17035
|
+
} catch {
|
|
17036
|
+
return false;
|
|
17037
|
+
}
|
|
17038
|
+
}
|
|
17039
|
+
function removeRecoveryLedgerEntry(ledgerDir, markerName, unlink = (p) => {
|
|
17040
|
+
if (existsSync6(p)) unlinkSync5(p);
|
|
17041
|
+
}) {
|
|
17042
|
+
if (!ledgerDir || !markerName) return;
|
|
17043
|
+
if (markerName.includes("/") || markerName.includes("\\") || markerName.includes("..")) return;
|
|
17044
|
+
try {
|
|
17045
|
+
unlink(join8(ledgerDir, markerName));
|
|
17046
|
+
} catch {
|
|
17047
|
+
}
|
|
17048
|
+
}
|
|
17049
|
+
|
|
17050
|
+
// src/inbound-delivery-ledger.ts
|
|
17051
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync7, readdirSync as readdirSync2, readFileSync as readFileSync9, renameSync as renameSync5, writeFileSync as writeFileSync8 } from "fs";
|
|
17052
|
+
import { join as join9 } from "path";
|
|
17053
|
+
function safeInboundId(inboundId) {
|
|
17054
|
+
return inboundId.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
17055
|
+
}
|
|
17056
|
+
var defaultDeps = {
|
|
17057
|
+
mkdir: (dir) => mkdirSync7(dir, { recursive: true }),
|
|
17058
|
+
writeFile: (path, data) => writeFileSync8(path, data, "utf8"),
|
|
17059
|
+
rename: (from, to) => renameSync5(from, to),
|
|
17060
|
+
readdir: (dir) => readdirSync2(dir),
|
|
17061
|
+
readFile: (path) => readFileSync9(path, "utf8"),
|
|
17062
|
+
exists: (path) => existsSync7(path)
|
|
17063
|
+
};
|
|
17064
|
+
function writeInboundDeliveryLedgerEntry(dir, record2, deps = defaultDeps) {
|
|
17065
|
+
if (!dir || !record2.inbound_id || !record2.conv_key) return;
|
|
17066
|
+
const safe = safeInboundId(record2.inbound_id);
|
|
17067
|
+
if (!safe || safe.includes("/") || safe.includes("\\") || safe.includes("..")) return;
|
|
17068
|
+
try {
|
|
17069
|
+
deps.mkdir(dir);
|
|
17070
|
+
const final = join9(dir, `${safe}.json`);
|
|
17071
|
+
const tmp = `${final}.tmp`;
|
|
17072
|
+
deps.writeFile(tmp, JSON.stringify(record2));
|
|
17073
|
+
deps.rename(tmp, final);
|
|
17074
|
+
} catch {
|
|
17075
|
+
}
|
|
17076
|
+
}
|
|
17077
|
+
|
|
17078
|
+
// src/channel-inbound-id.ts
|
|
17079
|
+
import { createHash } from "crypto";
|
|
17080
|
+
var INBOUND_ID_HEX_LEN = 12;
|
|
17081
|
+
function hashInboundId(payload) {
|
|
17082
|
+
const digest = createHash("sha256").update(payload).digest("hex").slice(0, INBOUND_ID_HEX_LEN);
|
|
17083
|
+
return `ib_${digest}`;
|
|
17084
|
+
}
|
|
17085
|
+
function telegramInboundId(chatId, messageId) {
|
|
17086
|
+
return hashInboundId(`${chatId}|${messageId}`);
|
|
17087
|
+
}
|
|
17088
|
+
|
|
17027
17089
|
// src/channel-progress.ts
|
|
17028
17090
|
function channelLiveProgressEnabled() {
|
|
17029
17091
|
return resolveHostBooleanFlag({
|
|
@@ -17208,14 +17270,14 @@ function createKanbanCardActiveClient(args) {
|
|
|
17208
17270
|
|
|
17209
17271
|
// src/mcp-spawn-lock.ts
|
|
17210
17272
|
import {
|
|
17211
|
-
existsSync as
|
|
17212
|
-
mkdirSync as
|
|
17213
|
-
readFileSync as
|
|
17214
|
-
renameSync as
|
|
17215
|
-
unlinkSync as
|
|
17216
|
-
writeFileSync as
|
|
17273
|
+
existsSync as existsSync8,
|
|
17274
|
+
mkdirSync as mkdirSync8,
|
|
17275
|
+
readFileSync as readFileSync10,
|
|
17276
|
+
renameSync as renameSync6,
|
|
17277
|
+
unlinkSync as unlinkSync6,
|
|
17278
|
+
writeFileSync as writeFileSync9
|
|
17217
17279
|
} from "fs";
|
|
17218
|
-
import { join as
|
|
17280
|
+
import { join as join10 } from "path";
|
|
17219
17281
|
function defaultIsPidAlive(pid) {
|
|
17220
17282
|
if (!Number.isFinite(pid) || pid <= 0) return false;
|
|
17221
17283
|
try {
|
|
@@ -17233,7 +17295,7 @@ function acquireMcpSpawnLock(args) {
|
|
|
17233
17295
|
const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
|
|
17234
17296
|
const selfPid = options.selfPid ?? process.pid;
|
|
17235
17297
|
const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
|
|
17236
|
-
const path =
|
|
17298
|
+
const path = join10(agentDir, basename2);
|
|
17237
17299
|
const existing = readLockHolder(path);
|
|
17238
17300
|
if (existing) {
|
|
17239
17301
|
if (existing.pid === selfPid) {
|
|
@@ -17243,11 +17305,11 @@ function acquireMcpSpawnLock(args) {
|
|
|
17243
17305
|
return { kind: "blocked", path, holder: existing };
|
|
17244
17306
|
}
|
|
17245
17307
|
}
|
|
17246
|
-
|
|
17308
|
+
mkdirSync8(agentDir, { recursive: true, mode: 448 });
|
|
17247
17309
|
const tmpPath = `${path}.${selfPid}.tmp`;
|
|
17248
17310
|
const payload = { pid: selfPid, started_at: now() };
|
|
17249
|
-
|
|
17250
|
-
|
|
17311
|
+
writeFileSync9(tmpPath, JSON.stringify(payload), { mode: 384 });
|
|
17312
|
+
renameSync6(tmpPath, path);
|
|
17251
17313
|
return { kind: "acquired", path };
|
|
17252
17314
|
}
|
|
17253
17315
|
function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
@@ -17257,14 +17319,14 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
|
|
|
17257
17319
|
if (!existing) return;
|
|
17258
17320
|
if (existing.pid !== selfPid) return;
|
|
17259
17321
|
try {
|
|
17260
|
-
|
|
17322
|
+
unlinkSync6(lockPath);
|
|
17261
17323
|
} catch {
|
|
17262
17324
|
}
|
|
17263
17325
|
}
|
|
17264
17326
|
function readLockHolder(path) {
|
|
17265
|
-
if (!
|
|
17327
|
+
if (!existsSync8(path)) return null;
|
|
17266
17328
|
try {
|
|
17267
|
-
const raw =
|
|
17329
|
+
const raw = readFileSync10(path, "utf8");
|
|
17268
17330
|
const parsed = JSON.parse(raw);
|
|
17269
17331
|
const pid = typeof parsed.pid === "number" ? parsed.pid : Number(parsed.pid);
|
|
17270
17332
|
if (!Number.isFinite(pid) || pid <= 0) return null;
|
|
@@ -17276,8 +17338,8 @@ function readLockHolder(path) {
|
|
|
17276
17338
|
}
|
|
17277
17339
|
|
|
17278
17340
|
// src/ack-reaction.ts
|
|
17279
|
-
import { readdirSync as
|
|
17280
|
-
import { join as
|
|
17341
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
17342
|
+
import { join as join11 } from "path";
|
|
17281
17343
|
var REPLY_WEDGED_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
17282
17344
|
var ACK_STARTUP_GRACE_MS = 6e4;
|
|
17283
17345
|
var ACK_PANE_FRESH_THRESHOLD_MS = 6e4;
|
|
@@ -17350,7 +17412,7 @@ var GIVE_UP_SIGNAL_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
|
17350
17412
|
function readGiveUpSignal(path, now = Date.now()) {
|
|
17351
17413
|
if (!path) return null;
|
|
17352
17414
|
try {
|
|
17353
|
-
const raw = JSON.parse(
|
|
17415
|
+
const raw = JSON.parse(readFileSync11(path, "utf8"));
|
|
17354
17416
|
if (typeof raw.gave_up_at !== "string") return null;
|
|
17355
17417
|
const t = Date.parse(raw.gave_up_at);
|
|
17356
17418
|
if (!Number.isFinite(t) || t > now) return null;
|
|
@@ -17376,7 +17438,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
17376
17438
|
if (!dir) return null;
|
|
17377
17439
|
let names;
|
|
17378
17440
|
try {
|
|
17379
|
-
names =
|
|
17441
|
+
names = readdirSync3(dir);
|
|
17380
17442
|
} catch {
|
|
17381
17443
|
return null;
|
|
17382
17444
|
}
|
|
@@ -17385,7 +17447,7 @@ function oldestPendingMarkerAgeMs(dir, now = Date.now(), opts) {
|
|
|
17385
17447
|
if (!name.endsWith(".json")) continue;
|
|
17386
17448
|
let receivedAt;
|
|
17387
17449
|
try {
|
|
17388
|
-
const raw = JSON.parse(
|
|
17450
|
+
const raw = JSON.parse(readFileSync11(join11(dir, name), "utf-8"));
|
|
17389
17451
|
if (raw.discretionary === true) continue;
|
|
17390
17452
|
if (!opts?.includeSeen && typeof raw.seen_at === "string" && raw.seen_at) continue;
|
|
17391
17453
|
receivedAt = raw.received_at;
|
|
@@ -17453,20 +17515,20 @@ function isMarkerGenuinelyAged(receivedAt, nowMs, thresholdMs) {
|
|
|
17453
17515
|
}
|
|
17454
17516
|
var DEFLECTION_COUNTER_SUFFIX = "-deflections.json";
|
|
17455
17517
|
function deflectionCounterPath(agentDir, channel) {
|
|
17456
|
-
return
|
|
17518
|
+
return join11(agentDir, `${channel}${DEFLECTION_COUNTER_SUFFIX}`);
|
|
17457
17519
|
}
|
|
17458
17520
|
function recordChannelDeflection(agentDir, channel, cause) {
|
|
17459
17521
|
if (!agentDir) return;
|
|
17460
17522
|
const path = deflectionCounterPath(agentDir, channel);
|
|
17461
17523
|
let counts = {};
|
|
17462
17524
|
try {
|
|
17463
|
-
const parsed = JSON.parse(
|
|
17525
|
+
const parsed = JSON.parse(readFileSync11(path, "utf-8"));
|
|
17464
17526
|
if (parsed && typeof parsed === "object") counts = parsed;
|
|
17465
17527
|
} catch {
|
|
17466
17528
|
}
|
|
17467
17529
|
counts[cause] = (counts[cause] ?? 0) + 1;
|
|
17468
17530
|
try {
|
|
17469
|
-
|
|
17531
|
+
writeFileSync10(path, JSON.stringify(counts), { mode: 384 });
|
|
17470
17532
|
} catch {
|
|
17471
17533
|
}
|
|
17472
17534
|
}
|
|
@@ -17537,11 +17599,11 @@ async function actuateHostRestart(opts) {
|
|
|
17537
17599
|
|
|
17538
17600
|
// src/telegram-channel.ts
|
|
17539
17601
|
function redactId(id) {
|
|
17540
|
-
return
|
|
17602
|
+
return createHash2("sha256").update(String(id)).digest("hex").slice(0, 8);
|
|
17541
17603
|
}
|
|
17542
17604
|
var BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
17543
17605
|
var AGENT_CODE_NAME = process.env.AGT_AGENT_CODE_NAME ?? "unknown";
|
|
17544
|
-
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
17606
|
+
var TELEGRAM_AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join12(homedir4(), ".augmented", AGENT_CODE_NAME) : null;
|
|
17545
17607
|
var AGT_HOST = process.env.AGT_HOST ?? null;
|
|
17546
17608
|
var AGT_API_KEY = process.env.AGT_API_KEY ?? null;
|
|
17547
17609
|
var AGT_AGENT_ID = process.env.AGT_AGENT_ID ?? null;
|
|
@@ -17645,9 +17707,9 @@ if (!BOT_TOKEN) {
|
|
|
17645
17707
|
var stderrLogStream = null;
|
|
17646
17708
|
if (AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown") {
|
|
17647
17709
|
try {
|
|
17648
|
-
const logDir =
|
|
17649
|
-
|
|
17650
|
-
stderrLogStream = createWriteStream(
|
|
17710
|
+
const logDir = join12(homedir4(), ".augmented", AGENT_CODE_NAME);
|
|
17711
|
+
mkdirSync9(logDir, { recursive: true });
|
|
17712
|
+
stderrLogStream = createWriteStream(join12(logDir, "telegram-channel-stderr.log"), {
|
|
17651
17713
|
flags: "a",
|
|
17652
17714
|
mode: 384
|
|
17653
17715
|
});
|
|
@@ -17926,7 +17988,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
17926
17988
|
let paneLogFreshAgeMs = null;
|
|
17927
17989
|
if (AGENT_DIR) {
|
|
17928
17990
|
try {
|
|
17929
|
-
const paneMtimeMs = statSync2(
|
|
17991
|
+
const paneMtimeMs = statSync2(join12(AGENT_DIR, "pane.log")).mtimeMs;
|
|
17930
17992
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
17931
17993
|
} catch {
|
|
17932
17994
|
}
|
|
@@ -17956,7 +18018,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
|
|
|
17956
18018
|
function __resetBusyAckNoticeThrottle() {
|
|
17957
18019
|
lastBusyAckNoticeAt.clear();
|
|
17958
18020
|
}
|
|
17959
|
-
var RESTART_FLAGS_DIR =
|
|
18021
|
+
var RESTART_FLAGS_DIR = join12(homedir4(), ".augmented", "restart-flags");
|
|
17960
18022
|
function actuateHostRestartTelegram() {
|
|
17961
18023
|
return actuateHostRestart({
|
|
17962
18024
|
agtHost: AGT_HOST,
|
|
@@ -18338,10 +18400,10 @@ async function handleRestartCommand(opts) {
|
|
|
18338
18400
|
writeTelegramRestartConfirm({ chat_id: opts.chatId, message_id: opts.messageId }, opts.requesterName);
|
|
18339
18401
|
} else {
|
|
18340
18402
|
writeTelegramRestartConfirm({ chat_id: opts.chatId, message_id: opts.messageId }, opts.requesterName);
|
|
18341
|
-
if (!
|
|
18342
|
-
|
|
18403
|
+
if (!existsSync9(RESTART_FLAGS_DIR)) {
|
|
18404
|
+
mkdirSync9(RESTART_FLAGS_DIR, { recursive: true });
|
|
18343
18405
|
}
|
|
18344
|
-
const flagPath =
|
|
18406
|
+
const flagPath = join12(RESTART_FLAGS_DIR, `${AGENT_CODE_NAME}.flag`);
|
|
18345
18407
|
const flag = {
|
|
18346
18408
|
codeName: AGENT_CODE_NAME,
|
|
18347
18409
|
source: "telegram",
|
|
@@ -18349,8 +18411,8 @@ async function handleRestartCommand(opts) {
|
|
|
18349
18411
|
reply: { chat_id: opts.chatId, message_id: opts.messageId }
|
|
18350
18412
|
};
|
|
18351
18413
|
const tmpPath = `${flagPath}.${process.pid}.${randomUUID3()}.tmp`;
|
|
18352
|
-
|
|
18353
|
-
|
|
18414
|
+
writeFileSync11(tmpPath, JSON.stringify(flag) + "\n", "utf8");
|
|
18415
|
+
renameSync7(tmpPath, flagPath);
|
|
18354
18416
|
}
|
|
18355
18417
|
process.stderr.write(
|
|
18356
18418
|
`telegram-channel(${AGENT_CODE_NAME}): /restart queued from chat ${redactId(opts.chatId)}
|
|
@@ -18747,14 +18809,16 @@ async function classifyRestartCommand(text) {
|
|
|
18747
18809
|
if (!ours) return "verification_failed";
|
|
18748
18810
|
return target === ours ? "act" : "ignore";
|
|
18749
18811
|
}
|
|
18750
|
-
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ?
|
|
18751
|
-
var PENDING_INBOUND_DIR = AGENT_DIR ?
|
|
18752
|
-
var RECOVERY_OUTBOX_DIR = AGENT_DIR ?
|
|
18753
|
-
var
|
|
18812
|
+
var AGENT_DIR = AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? join12(homedir4(), ".augmented", AGENT_CODE_NAME) : null;
|
|
18813
|
+
var PENDING_INBOUND_DIR = AGENT_DIR ? join12(AGENT_DIR, "telegram-pending-inbound") : null;
|
|
18814
|
+
var RECOVERY_OUTBOX_DIR = AGENT_DIR ? join12(AGENT_DIR, "telegram-recovery-outbox") : null;
|
|
18815
|
+
var RECOVERY_LEDGER_DIR = AGENT_DIR ? join12(AGENT_DIR, ".agt-telegram-recovery-ledger") : null;
|
|
18816
|
+
var DELIVERY_LEDGER_DIR = AGENT_DIR ? join12(AGENT_DIR, ".agt-inbound-delivery-ledger") : null;
|
|
18817
|
+
var RESTART_CONFIRM_FILE = AGENT_DIR ? join12(AGENT_DIR, "telegram-restart-confirm.json") : null;
|
|
18754
18818
|
var TELEGRAM_PROCESS_BOOT_MS = Date.now();
|
|
18755
|
-
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ?
|
|
18756
|
-
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ?
|
|
18757
|
-
var TELEGRAM_OFFSET_FILE = AGENT_DIR ?
|
|
18819
|
+
var TELEGRAM_RECENT_DMS_FILE = AGENT_DIR ? join12(AGENT_DIR, "telegram-recent-dms.json") : null;
|
|
18820
|
+
var TELEGRAM_CHANNEL_ADD_RESTART_FILE = AGENT_DIR ? join12(AGENT_DIR, "telegram-channel-add-restart.json") : null;
|
|
18821
|
+
var TELEGRAM_OFFSET_FILE = AGENT_DIR ? join12(AGENT_DIR, "telegram-getupdates-offset.json") : null;
|
|
18758
18822
|
var recentDms = /* @__PURE__ */ new Map();
|
|
18759
18823
|
var recentDmPersister = TELEGRAM_RECENT_DMS_FILE ? createRecentDmPersister({
|
|
18760
18824
|
filePath: TELEGRAM_RECENT_DMS_FILE,
|
|
@@ -18809,7 +18873,7 @@ function safeMarkerName(chatId, messageId) {
|
|
|
18809
18873
|
}
|
|
18810
18874
|
function pendingInboundPath(chatId, messageId) {
|
|
18811
18875
|
if (!PENDING_INBOUND_DIR) return null;
|
|
18812
|
-
return
|
|
18876
|
+
return join12(PENDING_INBOUND_DIR, safeMarkerName(chatId, messageId));
|
|
18813
18877
|
}
|
|
18814
18878
|
function writePendingInboundMarker(chatId, messageId, chatType, undeliverable = false, payload) {
|
|
18815
18879
|
const path = pendingInboundPath(chatId, messageId);
|
|
@@ -18819,6 +18883,8 @@ function writePendingInboundMarker(chatId, messageId, chatType, undeliverable =
|
|
|
18819
18883
|
message_id: messageId,
|
|
18820
18884
|
chat_type: chatType,
|
|
18821
18885
|
received_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
18886
|
+
// ENG-7806 (fm1): stamp the deterministic inbound id (marker-semantics-neutral).
|
|
18887
|
+
inbound_id: telegramInboundId(chatId, messageId),
|
|
18822
18888
|
// Only persist the flag when set — keeps healthy-path markers byte-identical.
|
|
18823
18889
|
...undeliverable ? { undeliverable: true } : {},
|
|
18824
18890
|
// ENG-5969: carry the replay payload only when provided (the durable-replay
|
|
@@ -18826,8 +18892,8 @@ function writePendingInboundMarker(chatId, messageId, chatType, undeliverable =
|
|
|
18826
18892
|
...payload ? { payload } : {}
|
|
18827
18893
|
};
|
|
18828
18894
|
try {
|
|
18829
|
-
|
|
18830
|
-
|
|
18895
|
+
mkdirSync9(PENDING_INBOUND_DIR, { recursive: true, mode: 448 });
|
|
18896
|
+
writeFileSync11(path, JSON.stringify(marker), { mode: 384 });
|
|
18831
18897
|
} catch (err) {
|
|
18832
18898
|
process.stderr.write(
|
|
18833
18899
|
`telegram-channel(${AGENT_CODE_NAME}): pending-inbound marker write failed: ${err.message}
|
|
@@ -18855,7 +18921,7 @@ function rewriteTelegramMarkerInPlace(path, marker) {
|
|
|
18855
18921
|
function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
18856
18922
|
let marker = null;
|
|
18857
18923
|
try {
|
|
18858
|
-
marker = JSON.parse(
|
|
18924
|
+
marker = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
18859
18925
|
} catch {
|
|
18860
18926
|
}
|
|
18861
18927
|
if (marker && decideRecoveryHeal({
|
|
@@ -18865,14 +18931,14 @@ function clearTelegramMarkerFileWithHeal(fullPath) {
|
|
|
18865
18931
|
notifyBackOnline(marker.chat_id);
|
|
18866
18932
|
}
|
|
18867
18933
|
try {
|
|
18868
|
-
if (
|
|
18934
|
+
if (existsSync9(fullPath)) unlinkSync7(fullPath);
|
|
18869
18935
|
} catch {
|
|
18870
18936
|
}
|
|
18871
18937
|
}
|
|
18872
18938
|
function markTelegramMarkerSeenInPlace(fullPath) {
|
|
18873
18939
|
let marker;
|
|
18874
18940
|
try {
|
|
18875
|
-
marker = JSON.parse(
|
|
18941
|
+
marker = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
18876
18942
|
} catch {
|
|
18877
18943
|
return;
|
|
18878
18944
|
}
|
|
@@ -18884,7 +18950,7 @@ function markTelegramMarkerSeenInPlace(fullPath) {
|
|
|
18884
18950
|
function markTelegramMarkerSeenWithHeal(fullPath) {
|
|
18885
18951
|
let marker = null;
|
|
18886
18952
|
try {
|
|
18887
|
-
marker = JSON.parse(
|
|
18953
|
+
marker = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
18888
18954
|
} catch {
|
|
18889
18955
|
return;
|
|
18890
18956
|
}
|
|
@@ -18898,9 +18964,9 @@ function markTelegramMarkerSeenWithHeal(fullPath) {
|
|
|
18898
18964
|
}
|
|
18899
18965
|
function readPendingInboundMarker(chatId, messageId) {
|
|
18900
18966
|
const path = pendingInboundPath(chatId, messageId);
|
|
18901
|
-
if (!path || !
|
|
18967
|
+
if (!path || !existsSync9(path)) return null;
|
|
18902
18968
|
try {
|
|
18903
|
-
return JSON.parse(
|
|
18969
|
+
return JSON.parse(readFileSync12(path, "utf-8"));
|
|
18904
18970
|
} catch {
|
|
18905
18971
|
return null;
|
|
18906
18972
|
}
|
|
@@ -18920,10 +18986,10 @@ function nextRetryName(filename) {
|
|
|
18920
18986
|
async function processRecoveryOutboxFile(filename) {
|
|
18921
18987
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
18922
18988
|
if (filename.endsWith(".poison.json") || filename.endsWith(".tmp")) return;
|
|
18923
|
-
const fullPath =
|
|
18989
|
+
const fullPath = join12(RECOVERY_OUTBOX_DIR, filename);
|
|
18924
18990
|
let payload;
|
|
18925
18991
|
try {
|
|
18926
|
-
const raw =
|
|
18992
|
+
const raw = readFileSync12(fullPath, "utf-8");
|
|
18927
18993
|
payload = JSON.parse(raw);
|
|
18928
18994
|
} catch (err) {
|
|
18929
18995
|
process.stderr.write(
|
|
@@ -18931,7 +18997,7 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
18931
18997
|
`
|
|
18932
18998
|
);
|
|
18933
18999
|
try {
|
|
18934
|
-
|
|
19000
|
+
renameSync7(fullPath, `${fullPath}.parse-error.poison`);
|
|
18935
19001
|
} catch {
|
|
18936
19002
|
}
|
|
18937
19003
|
return;
|
|
@@ -18941,8 +19007,9 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
18941
19007
|
`telegram-channel(${AGENT_CODE_NAME}): recovery outbox malformed (${filename}): missing chat_id or text
|
|
18942
19008
|
`
|
|
18943
19009
|
);
|
|
19010
|
+
removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
|
|
18944
19011
|
try {
|
|
18945
|
-
|
|
19012
|
+
renameSync7(fullPath, `${fullPath}.malformed.poison`);
|
|
18946
19013
|
} catch {
|
|
18947
19014
|
}
|
|
18948
19015
|
return;
|
|
@@ -18969,8 +19036,9 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
18969
19036
|
);
|
|
18970
19037
|
if (decision.action === "suppress") {
|
|
18971
19038
|
clearPendingMessage(payload.chat_id, recoveryDrainCutoffMs);
|
|
19039
|
+
removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
|
|
18972
19040
|
try {
|
|
18973
|
-
|
|
19041
|
+
unlinkSync7(fullPath);
|
|
18974
19042
|
} catch {
|
|
18975
19043
|
}
|
|
18976
19044
|
return;
|
|
@@ -19005,8 +19073,9 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
19005
19073
|
);
|
|
19006
19074
|
}
|
|
19007
19075
|
if (sendSucceeded) {
|
|
19076
|
+
removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
|
|
19008
19077
|
try {
|
|
19009
|
-
|
|
19078
|
+
unlinkSync7(fullPath);
|
|
19010
19079
|
} catch {
|
|
19011
19080
|
}
|
|
19012
19081
|
return;
|
|
@@ -19014,12 +19083,13 @@ async function processRecoveryOutboxFile(filename) {
|
|
|
19014
19083
|
const next = nextRetryName(filename);
|
|
19015
19084
|
if (next) {
|
|
19016
19085
|
try {
|
|
19017
|
-
|
|
19086
|
+
renameSync7(fullPath, join12(RECOVERY_OUTBOX_DIR, next.next));
|
|
19018
19087
|
if (next.attempt >= MAX_RECOVERY_ATTEMPTS) {
|
|
19019
19088
|
process.stderr.write(
|
|
19020
19089
|
`telegram-channel(${AGENT_CODE_NAME}): ghost-reply recovery exhausted retries \u2014 moved to ${next.next}
|
|
19021
19090
|
`
|
|
19022
19091
|
);
|
|
19092
|
+
removeRecoveryLedgerEntry(RECOVERY_LEDGER_DIR, payload.marker_name);
|
|
19023
19093
|
}
|
|
19024
19094
|
} catch {
|
|
19025
19095
|
}
|
|
@@ -19045,7 +19115,7 @@ function scanRecoveryRetries() {
|
|
|
19045
19115
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
19046
19116
|
let entries;
|
|
19047
19117
|
try {
|
|
19048
|
-
entries =
|
|
19118
|
+
entries = readdirSync4(RECOVERY_OUTBOX_DIR);
|
|
19049
19119
|
} catch {
|
|
19050
19120
|
return;
|
|
19051
19121
|
}
|
|
@@ -19054,7 +19124,7 @@ function scanRecoveryRetries() {
|
|
|
19054
19124
|
if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
|
|
19055
19125
|
let mtimeMs;
|
|
19056
19126
|
try {
|
|
19057
|
-
mtimeMs = statSync2(
|
|
19127
|
+
mtimeMs = statSync2(join12(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
|
|
19058
19128
|
} catch {
|
|
19059
19129
|
continue;
|
|
19060
19130
|
}
|
|
@@ -19066,7 +19136,7 @@ function scanRecoveryRetries() {
|
|
|
19066
19136
|
function startRecoveryOutboxWatcher() {
|
|
19067
19137
|
if (!RECOVERY_OUTBOX_DIR) return;
|
|
19068
19138
|
try {
|
|
19069
|
-
|
|
19139
|
+
mkdirSync9(RECOVERY_OUTBOX_DIR, { recursive: true, mode: 448 });
|
|
19070
19140
|
} catch (err) {
|
|
19071
19141
|
process.stderr.write(
|
|
19072
19142
|
`telegram-channel(${AGENT_CODE_NAME}): recovery outbox mkdir failed: ${err.message}
|
|
@@ -19075,7 +19145,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
19075
19145
|
return;
|
|
19076
19146
|
}
|
|
19077
19147
|
try {
|
|
19078
|
-
for (const f of
|
|
19148
|
+
for (const f of readdirSync4(RECOVERY_OUTBOX_DIR)) {
|
|
19079
19149
|
if (isFirstAttemptOutboxFile(f)) void processRecoveryOutboxFile(f);
|
|
19080
19150
|
}
|
|
19081
19151
|
} catch {
|
|
@@ -19084,7 +19154,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
19084
19154
|
const watcher = watch(RECOVERY_OUTBOX_DIR, (event, filename) => {
|
|
19085
19155
|
if (event !== "rename" || !filename) return;
|
|
19086
19156
|
if (!isFirstAttemptOutboxFile(filename)) return;
|
|
19087
|
-
if (
|
|
19157
|
+
if (existsSync9(join12(RECOVERY_OUTBOX_DIR, filename))) {
|
|
19088
19158
|
void processRecoveryOutboxFile(filename);
|
|
19089
19159
|
}
|
|
19090
19160
|
});
|
|
@@ -19099,7 +19169,7 @@ function startRecoveryOutboxWatcher() {
|
|
|
19099
19169
|
retryTimer.unref?.();
|
|
19100
19170
|
}
|
|
19101
19171
|
startRecoveryOutboxWatcher();
|
|
19102
|
-
var NOTICE_OUTBOX_DIR = AGENT_DIR ?
|
|
19172
|
+
var NOTICE_OUTBOX_DIR = AGENT_DIR ? join12(AGENT_DIR, "telegram-notice-outbox") : null;
|
|
19103
19173
|
var NOTICE_MAX_AGE_MS = 9e4;
|
|
19104
19174
|
var NOTICE_INFLIGHT = /* @__PURE__ */ new Set();
|
|
19105
19175
|
async function processNoticeOutboxFile(filename) {
|
|
@@ -19107,7 +19177,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
19107
19177
|
if (filename.startsWith(".") || filename.endsWith(".tmp") || !filename.endsWith(".json")) return;
|
|
19108
19178
|
if (NOTICE_INFLIGHT.has(filename)) return;
|
|
19109
19179
|
NOTICE_INFLIGHT.add(filename);
|
|
19110
|
-
const fullPath =
|
|
19180
|
+
const fullPath = join12(NOTICE_OUTBOX_DIR, filename);
|
|
19111
19181
|
try {
|
|
19112
19182
|
let mtimeMs;
|
|
19113
19183
|
try {
|
|
@@ -19117,26 +19187,26 @@ async function processNoticeOutboxFile(filename) {
|
|
|
19117
19187
|
}
|
|
19118
19188
|
if (Date.now() - mtimeMs > NOTICE_MAX_AGE_MS) {
|
|
19119
19189
|
try {
|
|
19120
|
-
|
|
19190
|
+
unlinkSync7(fullPath);
|
|
19121
19191
|
} catch {
|
|
19122
19192
|
}
|
|
19123
19193
|
return;
|
|
19124
19194
|
}
|
|
19125
19195
|
let payload;
|
|
19126
19196
|
try {
|
|
19127
|
-
const parsed = JSON.parse(
|
|
19197
|
+
const parsed = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
19128
19198
|
if (!parsed || typeof parsed !== "object") throw new Error("not an object");
|
|
19129
19199
|
payload = parsed;
|
|
19130
19200
|
} catch {
|
|
19131
19201
|
try {
|
|
19132
|
-
|
|
19202
|
+
unlinkSync7(fullPath);
|
|
19133
19203
|
} catch {
|
|
19134
19204
|
}
|
|
19135
19205
|
return;
|
|
19136
19206
|
}
|
|
19137
19207
|
if (!payload.chat_id || !payload.text) {
|
|
19138
19208
|
try {
|
|
19139
|
-
|
|
19209
|
+
unlinkSync7(fullPath);
|
|
19140
19210
|
} catch {
|
|
19141
19211
|
}
|
|
19142
19212
|
return;
|
|
@@ -19147,7 +19217,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
19147
19217
|
defaultValue: false
|
|
19148
19218
|
})) {
|
|
19149
19219
|
try {
|
|
19150
|
-
|
|
19220
|
+
unlinkSync7(fullPath);
|
|
19151
19221
|
} catch {
|
|
19152
19222
|
}
|
|
19153
19223
|
return;
|
|
@@ -19176,7 +19246,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
19176
19246
|
);
|
|
19177
19247
|
}
|
|
19178
19248
|
try {
|
|
19179
|
-
|
|
19249
|
+
unlinkSync7(fullPath);
|
|
19180
19250
|
} catch {
|
|
19181
19251
|
}
|
|
19182
19252
|
} finally {
|
|
@@ -19186,7 +19256,7 @@ async function processNoticeOutboxFile(filename) {
|
|
|
19186
19256
|
function startNoticeOutboxWatcher() {
|
|
19187
19257
|
if (!NOTICE_OUTBOX_DIR) return;
|
|
19188
19258
|
try {
|
|
19189
|
-
|
|
19259
|
+
mkdirSync9(NOTICE_OUTBOX_DIR, { recursive: true, mode: 448 });
|
|
19190
19260
|
} catch (err) {
|
|
19191
19261
|
process.stderr.write(
|
|
19192
19262
|
`telegram-channel(${AGENT_CODE_NAME}): notice outbox mkdir failed: ${err.message}
|
|
@@ -19195,13 +19265,13 @@ function startNoticeOutboxWatcher() {
|
|
|
19195
19265
|
return;
|
|
19196
19266
|
}
|
|
19197
19267
|
try {
|
|
19198
|
-
for (const f of
|
|
19268
|
+
for (const f of readdirSync4(NOTICE_OUTBOX_DIR)) void processNoticeOutboxFile(f);
|
|
19199
19269
|
} catch {
|
|
19200
19270
|
}
|
|
19201
19271
|
try {
|
|
19202
19272
|
const watcher = watch(NOTICE_OUTBOX_DIR, (event, filename) => {
|
|
19203
19273
|
if (event !== "rename" || !filename) return;
|
|
19204
|
-
if (
|
|
19274
|
+
if (existsSync9(join12(NOTICE_OUTBOX_DIR, filename))) void processNoticeOutboxFile(filename);
|
|
19205
19275
|
});
|
|
19206
19276
|
watcher.unref?.();
|
|
19207
19277
|
} catch (err) {
|
|
@@ -19218,10 +19288,10 @@ function trackPendingMessage(chatId, messageId, chatType, undeliverable = false,
|
|
|
19218
19288
|
}
|
|
19219
19289
|
function sweepTelegramStaleMarkers(thresholdMs) {
|
|
19220
19290
|
if (!PENDING_INBOUND_DIR) return;
|
|
19221
|
-
if (!
|
|
19291
|
+
if (!existsSync9(PENDING_INBOUND_DIR)) return;
|
|
19222
19292
|
let filenames;
|
|
19223
19293
|
try {
|
|
19224
|
-
filenames =
|
|
19294
|
+
filenames = readdirSync4(PENDING_INBOUND_DIR);
|
|
19225
19295
|
} catch (err) {
|
|
19226
19296
|
process.stderr.write(
|
|
19227
19297
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker readdir failed: ${err.message}
|
|
@@ -19234,17 +19304,17 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
19234
19304
|
for (const filename of filenames) {
|
|
19235
19305
|
if (!filename.endsWith(".json")) continue;
|
|
19236
19306
|
if (filename.endsWith(".tmp")) continue;
|
|
19237
|
-
const fullPath =
|
|
19307
|
+
const fullPath = join12(PENDING_INBOUND_DIR, filename);
|
|
19238
19308
|
let marker;
|
|
19239
19309
|
try {
|
|
19240
|
-
marker = JSON.parse(
|
|
19310
|
+
marker = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
19241
19311
|
} catch (err) {
|
|
19242
19312
|
process.stderr.write(
|
|
19243
19313
|
`telegram-channel(${AGENT_CODE_NAME}): stale-marker parse failed for ${redactId(filename)}: ${err.message}
|
|
19244
19314
|
`
|
|
19245
19315
|
);
|
|
19246
19316
|
try {
|
|
19247
|
-
|
|
19317
|
+
unlinkSync7(fullPath);
|
|
19248
19318
|
} catch {
|
|
19249
19319
|
}
|
|
19250
19320
|
cleared++;
|
|
@@ -19262,7 +19332,7 @@ function sweepTelegramStaleMarkers(thresholdMs) {
|
|
|
19262
19332
|
);
|
|
19263
19333
|
}
|
|
19264
19334
|
try {
|
|
19265
|
-
|
|
19335
|
+
unlinkSync7(fullPath);
|
|
19266
19336
|
} catch {
|
|
19267
19337
|
}
|
|
19268
19338
|
cleared++;
|
|
@@ -19283,13 +19353,13 @@ var orphanSweepTimer = setInterval(() => {
|
|
|
19283
19353
|
checkWatchdogGiveUpNotice();
|
|
19284
19354
|
}, orphanSweepIntervalMs());
|
|
19285
19355
|
orphanSweepTimer.unref?.();
|
|
19286
|
-
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ?
|
|
19356
|
+
var TELEGRAM_PROGRESS_HEARTBEAT_PATH = AGENT_DIR ? join12(AGENT_DIR, "channel-progress-heartbeat.json") : null;
|
|
19287
19357
|
var telegramTrackedProgress = null;
|
|
19288
19358
|
var telegramProgressTickRunning = false;
|
|
19289
19359
|
function readTelegramProgressHeartbeat() {
|
|
19290
|
-
if (!TELEGRAM_PROGRESS_HEARTBEAT_PATH || !
|
|
19360
|
+
if (!TELEGRAM_PROGRESS_HEARTBEAT_PATH || !existsSync9(TELEGRAM_PROGRESS_HEARTBEAT_PATH)) return null;
|
|
19291
19361
|
try {
|
|
19292
|
-
return parseProgressHeartbeat(
|
|
19362
|
+
return parseProgressHeartbeat(readFileSync12(TELEGRAM_PROGRESS_HEARTBEAT_PATH, "utf-8"));
|
|
19293
19363
|
} catch {
|
|
19294
19364
|
return null;
|
|
19295
19365
|
}
|
|
@@ -19298,25 +19368,25 @@ function seedTelegramProgressHeartbeat() {
|
|
|
19298
19368
|
if (!TELEGRAM_PROGRESS_HEARTBEAT_PATH) return;
|
|
19299
19369
|
const tmp = `${TELEGRAM_PROGRESS_HEARTBEAT_PATH}.${process.pid}.tmp`;
|
|
19300
19370
|
try {
|
|
19301
|
-
|
|
19302
|
-
|
|
19371
|
+
writeFileSync11(tmp, serializeProgressHeartbeat(SEED_PROGRESS_STEP, Date.now()), { mode: 384 });
|
|
19372
|
+
renameSync7(tmp, TELEGRAM_PROGRESS_HEARTBEAT_PATH);
|
|
19303
19373
|
} catch {
|
|
19304
19374
|
try {
|
|
19305
|
-
|
|
19375
|
+
unlinkSync7(tmp);
|
|
19306
19376
|
} catch {
|
|
19307
19377
|
}
|
|
19308
19378
|
}
|
|
19309
19379
|
}
|
|
19310
19380
|
function findTelegramProgressTarget() {
|
|
19311
|
-
if (!PENDING_INBOUND_DIR || !
|
|
19381
|
+
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return null;
|
|
19312
19382
|
let best = null;
|
|
19313
19383
|
let bestMs = Infinity;
|
|
19314
19384
|
try {
|
|
19315
|
-
for (const name of
|
|
19385
|
+
for (const name of readdirSync4(PENDING_INBOUND_DIR)) {
|
|
19316
19386
|
if (!name.endsWith(".json")) continue;
|
|
19317
19387
|
let m;
|
|
19318
19388
|
try {
|
|
19319
|
-
m = JSON.parse(
|
|
19389
|
+
m = JSON.parse(readFileSync12(join12(PENDING_INBOUND_DIR, name), "utf-8"));
|
|
19320
19390
|
} catch {
|
|
19321
19391
|
continue;
|
|
19322
19392
|
}
|
|
@@ -19440,14 +19510,14 @@ if (BOT_TOKEN && PENDING_INBOUND_DIR) {
|
|
|
19440
19510
|
}
|
|
19441
19511
|
var lastGiveUpHandledAtMs = null;
|
|
19442
19512
|
function listPendingInboundChatIds() {
|
|
19443
|
-
if (!PENDING_INBOUND_DIR || !
|
|
19513
|
+
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return [];
|
|
19444
19514
|
const chats = /* @__PURE__ */ new Set();
|
|
19445
19515
|
try {
|
|
19446
|
-
for (const name of
|
|
19516
|
+
for (const name of readdirSync4(PENDING_INBOUND_DIR)) {
|
|
19447
19517
|
if (!name.endsWith(".json")) continue;
|
|
19448
19518
|
try {
|
|
19449
19519
|
const marker = JSON.parse(
|
|
19450
|
-
|
|
19520
|
+
readFileSync12(join12(PENDING_INBOUND_DIR, name), "utf8")
|
|
19451
19521
|
);
|
|
19452
19522
|
if (typeof marker.seen_at === "string" && marker.seen_at) continue;
|
|
19453
19523
|
if (typeof marker.chat_id === "string" && marker.chat_id) chats.add(marker.chat_id);
|
|
@@ -19489,7 +19559,7 @@ async function notifyWatchdogGiveUp(chatId, reason) {
|
|
|
19489
19559
|
}
|
|
19490
19560
|
function checkWatchdogGiveUpNotice() {
|
|
19491
19561
|
if (!AGENT_DIR) return;
|
|
19492
|
-
const signal = readGiveUpSignal(
|
|
19562
|
+
const signal = readGiveUpSignal(join12(AGENT_DIR, GIVE_UP_SIGNAL_FILENAME));
|
|
19493
19563
|
const signalAtMs = signal?.atMs ?? null;
|
|
19494
19564
|
const act = decideGiveUpNotice({
|
|
19495
19565
|
signalAtMs,
|
|
@@ -19551,7 +19621,7 @@ async function deliverQueuedReply(p) {
|
|
|
19551
19621
|
}
|
|
19552
19622
|
}
|
|
19553
19623
|
function clearPendingMessage(chatId, cutoffMs = Number.POSITIVE_INFINITY) {
|
|
19554
|
-
if (!PENDING_INBOUND_DIR || !
|
|
19624
|
+
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return;
|
|
19555
19625
|
clearAllTelegramPendingMarkersForChat(
|
|
19556
19626
|
PENDING_INBOUND_DIR,
|
|
19557
19627
|
chatId,
|
|
@@ -19560,7 +19630,7 @@ function clearPendingMessage(chatId, cutoffMs = Number.POSITIVE_INFINITY) {
|
|
|
19560
19630
|
);
|
|
19561
19631
|
}
|
|
19562
19632
|
function markSeenPendingMessage(chatId, cutoffMs = Number.POSITIVE_INFINITY) {
|
|
19563
|
-
if (!PENDING_INBOUND_DIR || !
|
|
19633
|
+
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return;
|
|
19564
19634
|
markSeenAllTelegramPendingMarkersForChat(
|
|
19565
19635
|
PENDING_INBOUND_DIR,
|
|
19566
19636
|
chatId,
|
|
@@ -19845,7 +19915,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
19845
19915
|
isError: true
|
|
19846
19916
|
};
|
|
19847
19917
|
}
|
|
19848
|
-
bytes =
|
|
19918
|
+
bytes = readFileSync12(realPath);
|
|
19849
19919
|
} catch (err) {
|
|
19850
19920
|
return { content: [{ type: "text", text: `Failed to read file: ${err.message}` }], isError: true };
|
|
19851
19921
|
}
|
|
@@ -19986,6 +20056,12 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
19986
20056
|
if (name === "telegram.reply") {
|
|
19987
20057
|
if (interim) markSeenPendingMessage(chat_id, drainCutoffMs);
|
|
19988
20058
|
else clearPendingMessage(chat_id, drainCutoffMs);
|
|
20059
|
+
writeInboundDeliveryLedgerEntry(DELIVERY_LEDGER_DIR, {
|
|
20060
|
+
inbound_id: telegramInboundId(chat_id, reply_to_message_id ? String(reply_to_message_id) : ""),
|
|
20061
|
+
source: "telegram",
|
|
20062
|
+
conv_key: chat_id,
|
|
20063
|
+
delivered_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
20064
|
+
});
|
|
19989
20065
|
}
|
|
19990
20066
|
return { content: [{ type: "text", text: "sent" }] };
|
|
19991
20067
|
} catch (err) {
|
|
@@ -20386,13 +20462,13 @@ await mcp.connect(new StdioServerTransport());
|
|
|
20386
20462
|
var REPLAY_SCAN_INTERVAL_MS = 6e4;
|
|
20387
20463
|
async function replayPendingTelegramMarkers() {
|
|
20388
20464
|
if (!channelReplayEnabled()) return;
|
|
20389
|
-
if (!PENDING_INBOUND_DIR || !
|
|
20465
|
+
if (!PENDING_INBOUND_DIR || !existsSync9(PENDING_INBOUND_DIR)) return;
|
|
20390
20466
|
const probe = process.env.TMUX && AGENT_CODE_NAME && AGENT_CODE_NAME !== "unknown" ? probeAgentSessionCached(AGENT_CODE_NAME) : { tmux: "unknown", claude: "unknown" };
|
|
20391
20467
|
const sessionAlive = probe.tmux === "alive" && probe.claude === "alive";
|
|
20392
20468
|
if (!sessionAlive) return;
|
|
20393
20469
|
let filenames;
|
|
20394
20470
|
try {
|
|
20395
|
-
filenames =
|
|
20471
|
+
filenames = readdirSync4(PENDING_INBOUND_DIR);
|
|
20396
20472
|
} catch {
|
|
20397
20473
|
return;
|
|
20398
20474
|
}
|
|
@@ -20400,7 +20476,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
20400
20476
|
let paneFreshAgeMs = null;
|
|
20401
20477
|
if (AGENT_DIR) {
|
|
20402
20478
|
try {
|
|
20403
|
-
paneFreshAgeMs = Math.max(0, now - statSync2(
|
|
20479
|
+
paneFreshAgeMs = Math.max(0, now - statSync2(join12(AGENT_DIR, "pane.log")).mtimeMs);
|
|
20404
20480
|
} catch {
|
|
20405
20481
|
}
|
|
20406
20482
|
}
|
|
@@ -20408,10 +20484,10 @@ async function replayPendingTelegramMarkers() {
|
|
|
20408
20484
|
const entries = [];
|
|
20409
20485
|
for (const name of filenames) {
|
|
20410
20486
|
if (!name.endsWith(".json") || name.endsWith(".tmp")) continue;
|
|
20411
|
-
const fullPath =
|
|
20487
|
+
const fullPath = join12(PENDING_INBOUND_DIR, name);
|
|
20412
20488
|
let marker;
|
|
20413
20489
|
try {
|
|
20414
|
-
marker = JSON.parse(
|
|
20490
|
+
marker = JSON.parse(readFileSync12(fullPath, "utf-8"));
|
|
20415
20491
|
} catch {
|
|
20416
20492
|
continue;
|
|
20417
20493
|
}
|
|
@@ -20421,6 +20497,7 @@ async function replayPendingTelegramMarkers() {
|
|
|
20421
20497
|
}
|
|
20422
20498
|
entries.sort((a, b) => b.ageMs - a.ageMs);
|
|
20423
20499
|
for (const { path, marker, ageMs } of entries) {
|
|
20500
|
+
if (recoveryLedgerEntryExists(RECOVERY_LEDGER_DIR, basename(path))) continue;
|
|
20424
20501
|
if (!shouldReplayMarker({
|
|
20425
20502
|
enabled: true,
|
|
20426
20503
|
hasPayload: Boolean(marker.payload),
|
|
@@ -20930,7 +21007,7 @@ async function pollLoop() {
|
|
|
20930
21007
|
let paneLogFreshAgeMs = null;
|
|
20931
21008
|
if (AGENT_DIR) {
|
|
20932
21009
|
try {
|
|
20933
|
-
const paneMtimeMs = statSync2(
|
|
21010
|
+
const paneMtimeMs = statSync2(join12(AGENT_DIR, "pane.log")).mtimeMs;
|
|
20934
21011
|
paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
|
|
20935
21012
|
} catch {
|
|
20936
21013
|
}
|