switchroom 0.14.47 → 0.14.49
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/cli/switchroom.js +2 -2
- package/package.json +1 -1
- package/telegram-plugin/dist/gateway/gateway.js +190 -90
- package/telegram-plugin/gateway/boot-card-msgid.ts +70 -0
- package/telegram-plugin/gateway/boot-card.ts +81 -14
- package/telegram-plugin/gateway/gateway.ts +88 -2
- package/telegram-plugin/gateway/inbound-delivery-machine-dispatch.ts +12 -0
- package/telegram-plugin/gateway/pending-inbound-buffer.ts +17 -1
- package/telegram-plugin/gateway/resume-inbound-builder.ts +20 -4
- package/telegram-plugin/tests/boot-card-edit-in-place.test.ts +139 -0
- package/telegram-plugin/tests/boot-card-msgid.test.ts +88 -0
- package/telegram-plugin/tests/pending-inbound-buffer.test.ts +27 -0
- package/telegram-plugin/tests/resume-inbound-builder.test.ts +19 -0
|
@@ -29493,6 +29493,37 @@ function persistSnapshot(path, snapshot) {
|
|
|
29493
29493
|
}
|
|
29494
29494
|
var init_config_snapshot = () => {};
|
|
29495
29495
|
|
|
29496
|
+
// gateway/boot-card-msgid.ts
|
|
29497
|
+
import { readFileSync as readFileSync27, writeFileSync as writeFileSync17 } from "node:fs";
|
|
29498
|
+
function bootCardChatKey(chatId, threadId) {
|
|
29499
|
+
return `${chatId}:${threadId ?? ""}`;
|
|
29500
|
+
}
|
|
29501
|
+
function readStore(path) {
|
|
29502
|
+
try {
|
|
29503
|
+
const parsed = JSON.parse(readFileSync27(path, "utf8"));
|
|
29504
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
29505
|
+
return parsed;
|
|
29506
|
+
}
|
|
29507
|
+
} catch {}
|
|
29508
|
+
return {};
|
|
29509
|
+
}
|
|
29510
|
+
function loadBootCardMsgId(path, chatKey3) {
|
|
29511
|
+
const id = readStore(path)[chatKey3];
|
|
29512
|
+
return typeof id === "number" && Number.isFinite(id) && id > 0 ? id : null;
|
|
29513
|
+
}
|
|
29514
|
+
function saveBootCardMsgId(path, chatKey3, messageId) {
|
|
29515
|
+
if (!(Number.isFinite(messageId) && messageId > 0))
|
|
29516
|
+
return;
|
|
29517
|
+
try {
|
|
29518
|
+
const store2 = readStore(path);
|
|
29519
|
+
if (store2[chatKey3] === messageId)
|
|
29520
|
+
return;
|
|
29521
|
+
store2[chatKey3] = messageId;
|
|
29522
|
+
writeFileSync17(path, JSON.stringify(store2), "utf8");
|
|
29523
|
+
} catch {}
|
|
29524
|
+
}
|
|
29525
|
+
var init_boot_card_msgid = () => {};
|
|
29526
|
+
|
|
29496
29527
|
// gateway/boot-card.ts
|
|
29497
29528
|
var exports_boot_card = {};
|
|
29498
29529
|
__export(exports_boot_card, {
|
|
@@ -29640,22 +29671,46 @@ async function startBootCard(chatId, threadId, bot, opts, ackMessageId, log) {
|
|
|
29640
29671
|
...opts.updateOutcomeLine ? { updateOutcomeLine: opts.updateOutcomeLine } : {}
|
|
29641
29672
|
});
|
|
29642
29673
|
const silentBootCard = true;
|
|
29643
|
-
|
|
29644
|
-
|
|
29645
|
-
|
|
29646
|
-
|
|
29647
|
-
|
|
29648
|
-
|
|
29649
|
-
|
|
29650
|
-
|
|
29651
|
-
|
|
29652
|
-
|
|
29653
|
-
|
|
29674
|
+
const chatKey3 = bootCardChatKey(chatId, threadId);
|
|
29675
|
+
const reuseId = ackMessageId == null && opts.bootCardStatePath != null && bot.editMessageTextStrict != null ? loadBootCardMsgId(opts.bootCardStatePath, chatKey3) : null;
|
|
29676
|
+
let messageId = -1;
|
|
29677
|
+
if (reuseId != null && bot.editMessageTextStrict != null) {
|
|
29678
|
+
try {
|
|
29679
|
+
const outcome = await bot.editMessageTextStrict(chatId, reuseId, ackText, {
|
|
29680
|
+
parse_mode: "HTML",
|
|
29681
|
+
link_preview_options: { is_disabled: true },
|
|
29682
|
+
...threadId != null ? { message_thread_id: threadId } : {}
|
|
29683
|
+
});
|
|
29684
|
+
if (outcome === "edited") {
|
|
29685
|
+
messageId = reuseId;
|
|
29686
|
+
logger2(`telegram gateway: boot-card: reused msgId=${messageId} chatId=${chatId} reason=${opts.restartReason ?? "-"} reason_detail=${opts.restartReasonDetail ?? "-"} edit_in_place=true notify=none
|
|
29654
29687
|
`);
|
|
29655
|
-
|
|
29656
|
-
|
|
29688
|
+
}
|
|
29689
|
+
} catch (err) {
|
|
29690
|
+
logger2(`telegram gateway: boot-card: edit-in-place probe failed (${err?.message ?? String(err)}) \u2014 sending fresh
|
|
29657
29691
|
`);
|
|
29658
|
-
|
|
29692
|
+
}
|
|
29693
|
+
}
|
|
29694
|
+
if (messageId < 0) {
|
|
29695
|
+
try {
|
|
29696
|
+
const sent = await bot.sendMessage(chatId, ackText, {
|
|
29697
|
+
parse_mode: "HTML",
|
|
29698
|
+
link_preview_options: { is_disabled: true },
|
|
29699
|
+
...threadId != null ? { message_thread_id: threadId } : {},
|
|
29700
|
+
...ackMessageId != null ? { reply_parameters: { message_id: ackMessageId } } : {},
|
|
29701
|
+
...silentBootCard ? { disable_notification: true } : {}
|
|
29702
|
+
});
|
|
29703
|
+
messageId = sent.message_id;
|
|
29704
|
+
logger2(`telegram gateway: boot-card: posted msgId=${messageId} chatId=${chatId} reason=${opts.restartReason ?? "-"} reason_detail=${opts.restartReasonDetail ?? "-"} silent=${silentBootCard}
|
|
29705
|
+
`);
|
|
29706
|
+
} catch (err) {
|
|
29707
|
+
logger2(`telegram gateway: boot-card: failed to post ack: ${err?.message ?? String(err)}
|
|
29708
|
+
`);
|
|
29709
|
+
return { messageId: -1, complete: () => {} };
|
|
29710
|
+
}
|
|
29711
|
+
}
|
|
29712
|
+
if (opts.bootCardStatePath != null && messageId > 0) {
|
|
29713
|
+
saveBootCardMsgId(opts.bootCardStatePath, chatKey3, messageId);
|
|
29659
29714
|
}
|
|
29660
29715
|
const liveWindowMs = opts.agentLiveWindowMs ?? AGENT_LIVE_WINDOW_MS;
|
|
29661
29716
|
setTimeoutFn(() => {
|
|
@@ -29822,6 +29877,7 @@ var init_boot_card = __esm(() => {
|
|
|
29822
29877
|
init_boot_probes();
|
|
29823
29878
|
init_boot_issue_cache();
|
|
29824
29879
|
init_config_snapshot();
|
|
29880
|
+
init_boot_card_msgid();
|
|
29825
29881
|
init_loader();
|
|
29826
29882
|
init_merge();
|
|
29827
29883
|
DOT = {
|
|
@@ -30211,8 +30267,8 @@ var init_flock = () => {};
|
|
|
30211
30267
|
// ../src/vault/vault.ts
|
|
30212
30268
|
import { randomBytes as randomBytes5, scryptSync, createCipheriv, createDecipheriv } from "node:crypto";
|
|
30213
30269
|
import {
|
|
30214
|
-
readFileSync as
|
|
30215
|
-
writeFileSync as
|
|
30270
|
+
readFileSync as readFileSync35,
|
|
30271
|
+
writeFileSync as writeFileSync23,
|
|
30216
30272
|
existsSync as existsSync36,
|
|
30217
30273
|
renameSync as renameSync11,
|
|
30218
30274
|
mkdirSync as mkdirSync23,
|
|
@@ -30256,7 +30312,7 @@ function openVault(passphrase, vaultPath) {
|
|
|
30256
30312
|
}
|
|
30257
30313
|
let vaultFile;
|
|
30258
30314
|
try {
|
|
30259
|
-
vaultFile = JSON.parse(
|
|
30315
|
+
vaultFile = JSON.parse(readFileSync35(vaultPath, "utf8"));
|
|
30260
30316
|
} catch {
|
|
30261
30317
|
throw new VaultError(`Failed to read vault file: ${vaultPath}`);
|
|
30262
30318
|
}
|
|
@@ -30637,7 +30693,7 @@ __export(exports_tmux, {
|
|
|
30637
30693
|
captureAgentPane: () => captureAgentPane
|
|
30638
30694
|
});
|
|
30639
30695
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
30640
|
-
import { mkdirSync as mkdirSync25, readdirSync as readdirSync6, statSync as statSync12, unlinkSync as unlinkSync13, writeFileSync as
|
|
30696
|
+
import { mkdirSync as mkdirSync25, readdirSync as readdirSync6, statSync as statSync12, unlinkSync as unlinkSync13, writeFileSync as writeFileSync24 } from "node:fs";
|
|
30641
30697
|
import { resolve as resolve7 } from "node:path";
|
|
30642
30698
|
function captureAgentPane(opts) {
|
|
30643
30699
|
const { agentName: agentName3, agentDir, reason } = opts;
|
|
@@ -30683,7 +30739,7 @@ function captureAgentPane(opts) {
|
|
|
30683
30739
|
` + `
|
|
30684
30740
|
`;
|
|
30685
30741
|
try {
|
|
30686
|
-
|
|
30742
|
+
writeFileSync24(outPath, Buffer.concat([Buffer.from(header, "utf8"), body]), {
|
|
30687
30743
|
mode: 420
|
|
30688
30744
|
});
|
|
30689
30745
|
} catch (err) {
|
|
@@ -31259,8 +31315,8 @@ var import_runner2 = __toESM(require_mod3(), 1);
|
|
|
31259
31315
|
import { randomBytes as randomBytes6 } from "crypto";
|
|
31260
31316
|
import { execFileSync as execFileSync5, execSync as execSync2, spawn as spawn2 } from "child_process";
|
|
31261
31317
|
import {
|
|
31262
|
-
readFileSync as
|
|
31263
|
-
writeFileSync as
|
|
31318
|
+
readFileSync as readFileSync36,
|
|
31319
|
+
writeFileSync as writeFileSync25,
|
|
31264
31320
|
mkdirSync as mkdirSync26,
|
|
31265
31321
|
readdirSync as readdirSync7,
|
|
31266
31322
|
rmSync as rmSync4,
|
|
@@ -46927,7 +46983,7 @@ function escapeHtml7(s) {
|
|
|
46927
46983
|
|
|
46928
46984
|
// gateway/pending-inbound-buffer.ts
|
|
46929
46985
|
var DEFAULT_PENDING_INBOUND_CAP = 32;
|
|
46930
|
-
function redeliverBufferedInbound(buffer, agent, send, spool) {
|
|
46986
|
+
function redeliverBufferedInbound(buffer, agent, send, spool, onDelivered) {
|
|
46931
46987
|
const pending = buffer.drain(agent);
|
|
46932
46988
|
let redelivered = 0;
|
|
46933
46989
|
let rebuffered = 0;
|
|
@@ -46942,6 +46998,7 @@ function redeliverBufferedInbound(buffer, agent, send, spool) {
|
|
|
46942
46998
|
for (const o of originals)
|
|
46943
46999
|
spool?.ack(o);
|
|
46944
47000
|
redelivered += originals.length;
|
|
47001
|
+
onDelivered?.(merged, originals);
|
|
46945
47002
|
} else {
|
|
46946
47003
|
for (const o of originals)
|
|
46947
47004
|
buffer.push(agent, o);
|
|
@@ -47004,14 +47061,14 @@ function mergeRun(run2) {
|
|
|
47004
47061
|
merged.attachment = mediaEntry.attachment;
|
|
47005
47062
|
return merged;
|
|
47006
47063
|
}
|
|
47007
|
-
function idleDrainTick(buffer, agent, isBridgeAlive, send, spool) {
|
|
47064
|
+
function idleDrainTick(buffer, agent, isBridgeAlive, send, spool, onDelivered) {
|
|
47008
47065
|
if (!agent)
|
|
47009
47066
|
return null;
|
|
47010
47067
|
if (buffer.depth(agent) === 0)
|
|
47011
47068
|
return null;
|
|
47012
47069
|
if (!isBridgeAlive())
|
|
47013
47070
|
return null;
|
|
47014
|
-
return redeliverBufferedInbound(buffer, agent, send, spool);
|
|
47071
|
+
return redeliverBufferedInbound(buffer, agent, send, spool, onDelivered);
|
|
47015
47072
|
}
|
|
47016
47073
|
function createPendingInboundBuffer(opts = {}) {
|
|
47017
47074
|
const cap = opts.capPerAgent ?? DEFAULT_PENDING_INBOUND_CAP;
|
|
@@ -47618,7 +47675,7 @@ function formatEventDetail(event) {
|
|
|
47618
47675
|
}
|
|
47619
47676
|
|
|
47620
47677
|
// gateway/pending-inbound-buffer.ts
|
|
47621
|
-
function redeliverBufferedInbound2(buffer, agent, send, spool) {
|
|
47678
|
+
function redeliverBufferedInbound2(buffer, agent, send, spool, onDelivered) {
|
|
47622
47679
|
const pending = buffer.drain(agent);
|
|
47623
47680
|
let redelivered = 0;
|
|
47624
47681
|
let rebuffered = 0;
|
|
@@ -47633,6 +47690,7 @@ function redeliverBufferedInbound2(buffer, agent, send, spool) {
|
|
|
47633
47690
|
for (const o of originals)
|
|
47634
47691
|
spool?.ack(o);
|
|
47635
47692
|
redelivered += originals.length;
|
|
47693
|
+
onDelivered?.(merged, originals);
|
|
47636
47694
|
} else {
|
|
47637
47695
|
for (const o of originals)
|
|
47638
47696
|
buffer.push(agent, o);
|
|
@@ -47725,7 +47783,7 @@ function dispatchOne(effect, ctx) {
|
|
|
47725
47783
|
}
|
|
47726
47784
|
return ctx.ipcServer.sendToAgent(ctx.selfAgent, msg);
|
|
47727
47785
|
};
|
|
47728
|
-
const result = redeliverBufferedInbound2(ctx.pendingInboundBuffer, ctx.selfAgent, send, ctx.inboundSpool ?? undefined);
|
|
47786
|
+
const result = redeliverBufferedInbound2(ctx.pendingInboundBuffer, ctx.selfAgent, send, ctx.inboundSpool ?? undefined, ctx.onUserInboundDelivered ? (merged) => ctx.onUserInboundDelivered(merged) : undefined);
|
|
47729
47787
|
if (result.drained > 0) {
|
|
47730
47788
|
log(`telegram gateway: dispatch drainBuffer agent=${ctx.selfAgent} ` + `drained=${result.drained} redelivered=${result.redelivered} ` + `rebuffered=${result.rebuffered}
|
|
47731
47789
|
`);
|
|
@@ -50437,7 +50495,7 @@ function determineRestartReason(opts) {
|
|
|
50437
50495
|
init_boot_card();
|
|
50438
50496
|
|
|
50439
50497
|
// gateway/update-announce.ts
|
|
50440
|
-
import { existsSync as existsSync29, mkdirSync as mkdirSync17, openSync as openSync3, closeSync as closeSync3, readFileSync as
|
|
50498
|
+
import { existsSync as existsSync29, mkdirSync as mkdirSync17, openSync as openSync3, closeSync as closeSync3, readFileSync as readFileSync28 } from "node:fs";
|
|
50441
50499
|
import { join as join26 } from "node:path";
|
|
50442
50500
|
import { homedir as homedir12 } from "node:os";
|
|
50443
50501
|
|
|
@@ -50552,7 +50610,7 @@ var DEFAULT_LOOKBACK_MS = 10 * 60 * 1000;
|
|
|
50552
50610
|
function readLastTerminalUpdateAudit(opts = {}) {
|
|
50553
50611
|
const path = opts.auditLogPath ?? defaultAuditLogPath();
|
|
50554
50612
|
const exists = opts.exists ?? existsSync29;
|
|
50555
|
-
const readFile = opts.readFile ?? ((p) =>
|
|
50613
|
+
const readFile = opts.readFile ?? ((p) => readFileSync28(p, "utf-8"));
|
|
50556
50614
|
if (!exists(path))
|
|
50557
50615
|
return null;
|
|
50558
50616
|
let raw;
|
|
@@ -50640,7 +50698,7 @@ function maybeRenderUpdateAnnouncement(opts = {}) {
|
|
|
50640
50698
|
}
|
|
50641
50699
|
|
|
50642
50700
|
// issues-card.ts
|
|
50643
|
-
import { readFileSync as
|
|
50701
|
+
import { readFileSync as readFileSync29, writeFileSync as writeFileSync18 } from "node:fs";
|
|
50644
50702
|
var SEVERITY_EMOJI = {
|
|
50645
50703
|
info: "\u2139\ufe0f",
|
|
50646
50704
|
warn: "\u26a0\ufe0f",
|
|
@@ -50732,7 +50790,7 @@ function extractRetryAfterSecs2(err) {
|
|
|
50732
50790
|
var COOLDOWN_JITTER_MS2 = 500;
|
|
50733
50791
|
function readPersistedMessageId(path, log) {
|
|
50734
50792
|
try {
|
|
50735
|
-
const raw =
|
|
50793
|
+
const raw = readFileSync29(path, "utf8");
|
|
50736
50794
|
const parsed = JSON.parse(raw);
|
|
50737
50795
|
const v = parsed.messageId;
|
|
50738
50796
|
if (typeof v === "number" && Number.isInteger(v) && v > 0)
|
|
@@ -50748,7 +50806,7 @@ function readPersistedMessageId(path, log) {
|
|
|
50748
50806
|
}
|
|
50749
50807
|
function writePersistedMessageId(path, messageId, log) {
|
|
50750
50808
|
try {
|
|
50751
|
-
|
|
50809
|
+
writeFileSync18(path, JSON.stringify({ messageId }) + `
|
|
50752
50810
|
`, { mode: 384 });
|
|
50753
50811
|
} catch (err) {
|
|
50754
50812
|
log(`issues-card: persist write failed (${err.message})`);
|
|
@@ -50851,11 +50909,11 @@ import {
|
|
|
50851
50909
|
mkdirSync as mkdirSync18,
|
|
50852
50910
|
openSync as openSync4,
|
|
50853
50911
|
readdirSync as readdirSync5,
|
|
50854
|
-
readFileSync as
|
|
50912
|
+
readFileSync as readFileSync30,
|
|
50855
50913
|
renameSync as renameSync10,
|
|
50856
50914
|
statSync as statSync7,
|
|
50857
50915
|
unlinkSync as unlinkSync10,
|
|
50858
|
-
writeFileSync as
|
|
50916
|
+
writeFileSync as writeFileSync19,
|
|
50859
50917
|
writeSync
|
|
50860
50918
|
} from "node:fs";
|
|
50861
50919
|
import { join as join27 } from "node:path";
|
|
@@ -50882,7 +50940,7 @@ function readAll(stateDir) {
|
|
|
50882
50940
|
return [];
|
|
50883
50941
|
let raw;
|
|
50884
50942
|
try {
|
|
50885
|
-
raw =
|
|
50943
|
+
raw = readFileSync30(path, "utf-8");
|
|
50886
50944
|
} catch {
|
|
50887
50945
|
return [];
|
|
50888
50946
|
}
|
|
@@ -50938,7 +50996,7 @@ function writeAll(stateDir, events) {
|
|
|
50938
50996
|
const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
|
|
50939
50997
|
`) + `
|
|
50940
50998
|
`;
|
|
50941
|
-
|
|
50999
|
+
writeFileSync19(tmp, body, "utf-8");
|
|
50942
51000
|
renameSync10(tmp, path);
|
|
50943
51001
|
}
|
|
50944
51002
|
var ORPHAN_TMP_TTL_MS = 60000;
|
|
@@ -51001,7 +51059,7 @@ function withLock(stateDir, fn) {
|
|
|
51001
51059
|
function tryStealStaleLock(lockPath) {
|
|
51002
51060
|
let pidStr;
|
|
51003
51061
|
try {
|
|
51004
|
-
pidStr =
|
|
51062
|
+
pidStr = readFileSync30(lockPath, "utf-8").trim();
|
|
51005
51063
|
} catch {
|
|
51006
51064
|
return true;
|
|
51007
51065
|
}
|
|
@@ -51779,7 +51837,7 @@ function extractFlowItems(line) {
|
|
|
51779
51837
|
}
|
|
51780
51838
|
|
|
51781
51839
|
// credits-watch.ts
|
|
51782
|
-
import { readFileSync as
|
|
51840
|
+
import { readFileSync as readFileSync31, writeFileSync as writeFileSync20, existsSync as existsSync32, mkdirSync as mkdirSync19 } from "fs";
|
|
51783
51841
|
import { join as join29 } from "path";
|
|
51784
51842
|
var STATE_FILE = "credits-watch.json";
|
|
51785
51843
|
var FATAL_REASONS = new Set([
|
|
@@ -51797,7 +51855,7 @@ function readClaudeJsonOverage(claudeConfigDir) {
|
|
|
51797
51855
|
return null;
|
|
51798
51856
|
let raw;
|
|
51799
51857
|
try {
|
|
51800
|
-
raw =
|
|
51858
|
+
raw = readFileSync31(path, "utf-8");
|
|
51801
51859
|
} catch {
|
|
51802
51860
|
return null;
|
|
51803
51861
|
}
|
|
@@ -51881,7 +51939,7 @@ function loadCreditState(stateDir) {
|
|
|
51881
51939
|
if (!existsSync32(path))
|
|
51882
51940
|
return emptyCreditState();
|
|
51883
51941
|
try {
|
|
51884
|
-
const raw =
|
|
51942
|
+
const raw = readFileSync31(path, "utf-8");
|
|
51885
51943
|
const parsed = JSON.parse(raw);
|
|
51886
51944
|
if (parsed && typeof parsed === "object" && (parsed.lastNotifiedReason === null || typeof parsed.lastNotifiedReason === "string") && typeof parsed.lastNotifiedAt === "number" && Number.isFinite(parsed.lastNotifiedAt)) {
|
|
51887
51945
|
return {
|
|
@@ -51895,12 +51953,12 @@ function loadCreditState(stateDir) {
|
|
|
51895
51953
|
function saveCreditState(stateDir, state4) {
|
|
51896
51954
|
mkdirSync19(stateDir, { recursive: true });
|
|
51897
51955
|
const path = join29(stateDir, STATE_FILE);
|
|
51898
|
-
|
|
51956
|
+
writeFileSync20(path, JSON.stringify(state4, null, 2) + `
|
|
51899
51957
|
`, { mode: 384 });
|
|
51900
51958
|
}
|
|
51901
51959
|
|
|
51902
51960
|
// quota-watch.ts
|
|
51903
|
-
import { readFileSync as
|
|
51961
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync21, existsSync as existsSync33, mkdirSync as mkdirSync20 } from "fs";
|
|
51904
51962
|
import { join as join30 } from "path";
|
|
51905
51963
|
var STATE_FILE2 = "quota-watch.json";
|
|
51906
51964
|
function emptyQuotaWatchState() {
|
|
@@ -51995,7 +52053,7 @@ function loadQuotaWatchState(stateDir) {
|
|
|
51995
52053
|
if (!existsSync33(path))
|
|
51996
52054
|
return emptyQuotaWatchState();
|
|
51997
52055
|
try {
|
|
51998
|
-
const raw =
|
|
52056
|
+
const raw = readFileSync32(path, "utf-8");
|
|
51999
52057
|
const parsed = JSON.parse(raw);
|
|
52000
52058
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
52001
52059
|
return emptyQuotaWatchState();
|
|
@@ -52014,7 +52072,7 @@ function loadQuotaWatchState(stateDir) {
|
|
|
52014
52072
|
function saveQuotaWatchState(stateDir, state4) {
|
|
52015
52073
|
mkdirSync20(stateDir, { recursive: true });
|
|
52016
52074
|
const path = join30(stateDir, STATE_FILE2);
|
|
52017
|
-
|
|
52075
|
+
writeFileSync21(path, JSON.stringify(state4, null, 2) + `
|
|
52018
52076
|
`, { mode: 384 });
|
|
52019
52077
|
}
|
|
52020
52078
|
function patchQuotaWatchState(current, accountLabel, accountState) {
|
|
@@ -52030,18 +52088,18 @@ import {
|
|
|
52030
52088
|
existsSync as existsSync34,
|
|
52031
52089
|
mkdirSync as mkdirSync21,
|
|
52032
52090
|
openSync as openSync5,
|
|
52033
|
-
readFileSync as
|
|
52091
|
+
readFileSync as readFileSync33,
|
|
52034
52092
|
statSync as statSync9,
|
|
52035
52093
|
unlinkSync as unlinkSync11,
|
|
52036
52094
|
utimesSync as utimesSync2,
|
|
52037
|
-
writeFileSync as
|
|
52095
|
+
writeFileSync as writeFileSync22
|
|
52038
52096
|
} from "node:fs";
|
|
52039
52097
|
import { join as join31 } from "node:path";
|
|
52040
52098
|
var TURN_ACTIVE_MARKER_FILE2 = "turn-active.json";
|
|
52041
52099
|
function writeTurnActiveMarker(stateDir, marker) {
|
|
52042
52100
|
try {
|
|
52043
52101
|
mkdirSync21(stateDir, { recursive: true });
|
|
52044
|
-
|
|
52102
|
+
writeFileSync22(join31(stateDir, TURN_ACTIVE_MARKER_FILE2), JSON.stringify(marker, null, 2) + `
|
|
52045
52103
|
`, { mode: 384 });
|
|
52046
52104
|
} catch {}
|
|
52047
52105
|
}
|
|
@@ -52078,7 +52136,7 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
|
|
|
52078
52136
|
return false;
|
|
52079
52137
|
let payload = null;
|
|
52080
52138
|
try {
|
|
52081
|
-
payload =
|
|
52139
|
+
payload = readFileSync33(path, "utf8");
|
|
52082
52140
|
} catch {}
|
|
52083
52141
|
unlinkSync11(path);
|
|
52084
52142
|
if (opts.onRemove) {
|
|
@@ -52097,10 +52155,10 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
|
|
|
52097
52155
|
}
|
|
52098
52156
|
|
|
52099
52157
|
// ../src/build-info.ts
|
|
52100
|
-
var VERSION = "0.14.
|
|
52101
|
-
var COMMIT_SHA = "
|
|
52102
|
-
var COMMIT_DATE = "2026-06-
|
|
52103
|
-
var LATEST_PR =
|
|
52158
|
+
var VERSION = "0.14.49";
|
|
52159
|
+
var COMMIT_SHA = "df84be56";
|
|
52160
|
+
var COMMIT_DATE = "2026-06-03T09:45:46Z";
|
|
52161
|
+
var LATEST_PR = 2123;
|
|
52104
52162
|
var COMMITS_AHEAD_OF_TAG = 0;
|
|
52105
52163
|
|
|
52106
52164
|
// gateway/boot-version.ts
|
|
@@ -52665,14 +52723,20 @@ function buildResumeWatchdogReportInbound(ctx) {
|
|
|
52665
52723
|
meta
|
|
52666
52724
|
};
|
|
52667
52725
|
}
|
|
52668
|
-
function selectResumeBuilder(endedVia) {
|
|
52726
|
+
function selectResumeBuilder(endedVia, opts) {
|
|
52727
|
+
let kind;
|
|
52669
52728
|
if (endedVia === "timeout")
|
|
52729
|
+
kind = "report";
|
|
52730
|
+
else if (endedVia === "restart" || endedVia === "sigterm" || endedVia === "unknown")
|
|
52731
|
+
kind = "resume";
|
|
52732
|
+
else if (endedVia == null)
|
|
52733
|
+
kind = "resume";
|
|
52734
|
+
else
|
|
52735
|
+
kind = null;
|
|
52736
|
+
if (kind === "resume" && opts?.ageMs != null && opts?.maxAgeMs != null && opts.ageMs > opts.maxAgeMs) {
|
|
52670
52737
|
return "report";
|
|
52671
|
-
|
|
52672
|
-
|
|
52673
|
-
if (endedVia == null)
|
|
52674
|
-
return "resume";
|
|
52675
|
-
return null;
|
|
52738
|
+
}
|
|
52739
|
+
return kind;
|
|
52676
52740
|
}
|
|
52677
52741
|
|
|
52678
52742
|
// registry/subagents-schema.ts
|
|
@@ -52841,7 +52905,7 @@ function formatBootVersion() {
|
|
|
52841
52905
|
}
|
|
52842
52906
|
try {
|
|
52843
52907
|
chmodSync6(ENV_FILE, 384);
|
|
52844
|
-
for (const line of
|
|
52908
|
+
for (const line of readFileSync36(ENV_FILE, "utf8").split(`
|
|
52845
52909
|
`)) {
|
|
52846
52910
|
const m = line.match(/^(\w+)=(.*)$/);
|
|
52847
52911
|
if (m && process.env[m[1]] === undefined)
|
|
@@ -52894,7 +52958,7 @@ installTgPostLogger(bot);
|
|
|
52894
52958
|
var _rawSendMessageDraft = bot.api.raw.sendMessageDraft;
|
|
52895
52959
|
var GRAMMY_VERSION = (() => {
|
|
52896
52960
|
try {
|
|
52897
|
-
const raw =
|
|
52961
|
+
const raw = readFileSync36(new URL("../../node_modules/grammy/package.json", import.meta.url), "utf8");
|
|
52898
52962
|
return JSON.parse(raw).version ?? "unknown";
|
|
52899
52963
|
} catch {
|
|
52900
52964
|
return "unknown";
|
|
@@ -52986,7 +53050,7 @@ function assertSendable(f) {
|
|
|
52986
53050
|
}
|
|
52987
53051
|
function readAccessFile() {
|
|
52988
53052
|
try {
|
|
52989
|
-
const raw =
|
|
53053
|
+
const raw = readFileSync36(ACCESS_FILE, "utf8");
|
|
52990
53054
|
const parsed = JSON.parse(raw);
|
|
52991
53055
|
const allowFrom = validateStringArray("allowFrom", parsed.allowFrom ?? []);
|
|
52992
53056
|
const groups = {};
|
|
@@ -53056,7 +53120,7 @@ function saveAccess(a) {
|
|
|
53056
53120
|
return;
|
|
53057
53121
|
mkdirSync26(STATE_DIR, { recursive: true, mode: 448 });
|
|
53058
53122
|
const tmp = ACCESS_FILE + ".tmp";
|
|
53059
|
-
|
|
53123
|
+
writeFileSync25(tmp, JSON.stringify(a, null, 2) + `
|
|
53060
53124
|
`, { mode: 384 });
|
|
53061
53125
|
renameSync12(tmp, ACCESS_FILE);
|
|
53062
53126
|
}
|
|
@@ -53097,7 +53161,7 @@ try {
|
|
|
53097
53161
|
const st = statSync13(markerPath);
|
|
53098
53162
|
markerAgeMs = Date.now() - st.mtimeMs;
|
|
53099
53163
|
try {
|
|
53100
|
-
const payload = JSON.parse(
|
|
53164
|
+
const payload = JSON.parse(readFileSync36(markerPath, "utf8"));
|
|
53101
53165
|
if (typeof payload.turnKey === "string" && payload.turnKey.length > 0) {
|
|
53102
53166
|
markerTurnKey = payload.turnKey;
|
|
53103
53167
|
}
|
|
@@ -53123,7 +53187,14 @@ try {
|
|
|
53123
53187
|
const pending2 = findLatestTurnIfInterrupted(turnsDb);
|
|
53124
53188
|
const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
|
|
53125
53189
|
if (pending2 != null && selfAgent) {
|
|
53126
|
-
const
|
|
53190
|
+
const RESUME_MAX_AGE_MS = (() => {
|
|
53191
|
+
const v = Number(process.env.SWITCHROOM_RESUME_MAX_AGE_MS);
|
|
53192
|
+
return Number.isFinite(v) && v > 0 ? v : 10800000;
|
|
53193
|
+
})();
|
|
53194
|
+
const kind = selectResumeBuilder(pending2.ended_via, {
|
|
53195
|
+
ageMs: Math.max(0, Date.now() - pending2.started_at),
|
|
53196
|
+
maxAgeMs: RESUME_MAX_AGE_MS
|
|
53197
|
+
});
|
|
53127
53198
|
if (kind === "resume") {
|
|
53128
53199
|
bootResumeInbound = { agent: selfAgent, msg: buildResumeInterruptedInbound({ turn: pending2 }) };
|
|
53129
53200
|
} else if (kind === "report") {
|
|
@@ -53161,7 +53232,7 @@ try {
|
|
|
53161
53232
|
pending2.interrupt_reason != null ? `SWITCHROOM_PENDING_INTERRUPT_REASON=${pending2.interrupt_reason}` : `SWITCHROOM_PENDING_INTERRUPT_REASON=`
|
|
53162
53233
|
];
|
|
53163
53234
|
const pendingEnvTmp = `${pendingEnvPath}.tmp-${process.pid}`;
|
|
53164
|
-
|
|
53235
|
+
writeFileSync25(pendingEnvTmp, lines.join(`
|
|
53165
53236
|
`) + `
|
|
53166
53237
|
`, { mode: 384 });
|
|
53167
53238
|
renameSync12(pendingEnvTmp, pendingEnvPath);
|
|
@@ -53390,7 +53461,7 @@ function purgeReactionTracking(key, endingTurn) {
|
|
|
53390
53461
|
if (d)
|
|
53391
53462
|
markClaudeBusyForInbound(m);
|
|
53392
53463
|
return d;
|
|
53393
|
-
}, inboundSpool);
|
|
53464
|
+
}, inboundSpool, trackRedeliveredInbound);
|
|
53394
53465
|
if (fr.redelivered > 0) {
|
|
53395
53466
|
process.stderr.write(`telegram gateway: turn-complete flushed ${fr.redelivered}/${fr.drained} held inbound for ${selfAgentForFlush}${fr.rebuffered > 0 ? ` (${fr.rebuffered} re-buffered)` : ""}
|
|
53396
53467
|
`);
|
|
@@ -53420,7 +53491,7 @@ function releaseTurnBufferGate(key) {
|
|
|
53420
53491
|
if (d)
|
|
53421
53492
|
markClaudeBusyForInbound(m);
|
|
53422
53493
|
return d;
|
|
53423
|
-
}, inboundSpool);
|
|
53494
|
+
}, inboundSpool, trackRedeliveredInbound);
|
|
53424
53495
|
if (fr.redelivered > 0) {
|
|
53425
53496
|
process.stderr.write(`telegram gateway: reply-released-gate flushed ${fr.redelivered}/${fr.drained} held inbound for ${selfAgentForFlush}${fr.rebuffered > 0 ? ` (${fr.rebuffered} re-buffered)` : ""}
|
|
53426
53497
|
`);
|
|
@@ -53783,7 +53854,18 @@ function wrapBootCardApi(threadId) {
|
|
|
53783
53854
|
const sent = await robustApiCall(() => lockedBot.api.sendMessage(cid, text, sendOpts), opts(cid));
|
|
53784
53855
|
return sent;
|
|
53785
53856
|
},
|
|
53786
|
-
editMessageText: (cid, mid, text, editOpts) => robustApiCall(() => lockedBot.api.editMessageText(cid, mid, text, editOpts), opts(cid))
|
|
53857
|
+
editMessageText: (cid, mid, text, editOpts) => robustApiCall(() => lockedBot.api.editMessageText(cid, mid, text, editOpts), opts(cid)),
|
|
53858
|
+
editMessageTextStrict: async (cid, mid, text, editOpts) => {
|
|
53859
|
+
try {
|
|
53860
|
+
await lockedBot.api.editMessageText(cid, mid, text, editOpts);
|
|
53861
|
+
return "edited";
|
|
53862
|
+
} catch (err) {
|
|
53863
|
+
const desc = err instanceof import_grammy9.GrammyError ? err.description : err instanceof Error ? err.message : String(err);
|
|
53864
|
+
if (typeof desc === "string" && desc.toLowerCase().includes("not modified"))
|
|
53865
|
+
return "edited";
|
|
53866
|
+
return "gone";
|
|
53867
|
+
}
|
|
53868
|
+
}
|
|
53787
53869
|
};
|
|
53788
53870
|
}
|
|
53789
53871
|
function wrapIssuesCardApi(threadId) {
|
|
@@ -54406,7 +54488,7 @@ startTimer({
|
|
|
54406
54488
|
if (d)
|
|
54407
54489
|
markClaudeBusyForInbound(m);
|
|
54408
54490
|
return d;
|
|
54409
|
-
}, inboundSpool);
|
|
54491
|
+
}, inboundSpool, trackRedeliveredInbound);
|
|
54410
54492
|
process.stderr.write(`telegram gateway: silence-poke framework-fallback ended wedged turn chat=${fbChatId} thread=${ctx.threadId ?? "-"} silence_ms=${ctx.silenceMs} currentTurn_nulled=${turnMatchesFallback} drained_buffered=${fbRedeliver.redelivered}/${fbRedeliver.drained}${fbRedeliver.rebuffered > 0 ? ` rebuffered=${fbRedeliver.rebuffered}` : ""}${fbExtraPurge.purged.length > 0 ? ` extra_keys_purged=${fbExtraPurge.purged.length}` : ""}
|
|
54411
54493
|
`);
|
|
54412
54494
|
}
|
|
@@ -54416,6 +54498,20 @@ var _deliveryMachineTick = setInterval(() => {
|
|
|
54416
54498
|
shadowEmit({ kind: "tick", now: Date.now() });
|
|
54417
54499
|
}, DELIVERY_MACHINE_TICK_MS);
|
|
54418
54500
|
_deliveryMachineTick.unref?.();
|
|
54501
|
+
function trackRedeliveredInbound(merged) {
|
|
54502
|
+
if (!DELIVERY_CONFIRM_ENABLED)
|
|
54503
|
+
return;
|
|
54504
|
+
if (!shouldTrackDelivery({
|
|
54505
|
+
isSteering: false,
|
|
54506
|
+
isInterrupt: false,
|
|
54507
|
+
hasSource: merged.meta?.source != null,
|
|
54508
|
+
effectiveText: merged.text
|
|
54509
|
+
})) {
|
|
54510
|
+
return;
|
|
54511
|
+
}
|
|
54512
|
+
const key = chatKey2(merged.chatId, merged.threadId != null ? Number(merged.threadId) : null);
|
|
54513
|
+
trackDelivery(deliveryQueue, key, merged, Date.now(), merged.messageId != null ? String(merged.messageId) : null);
|
|
54514
|
+
}
|
|
54419
54515
|
async function redeliverStrandedInbound(p) {
|
|
54420
54516
|
const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
|
|
54421
54517
|
process.stderr.write(`telegram gateway: inbound strand (no enqueue ack) key=${p.key} \u2014 re-clearing composer + re-delivering
|
|
@@ -54467,8 +54563,8 @@ var inboundSpool = STATIC ? undefined : createInboundSpool({
|
|
|
54467
54563
|
path: join35(STATE_DIR, "inbound-spool.jsonl"),
|
|
54468
54564
|
fs: {
|
|
54469
54565
|
appendFileSync: (p, d) => appendFileSync5(p, d),
|
|
54470
|
-
readFileSync: (p) =>
|
|
54471
|
-
writeFileSync: (p, d) =>
|
|
54566
|
+
readFileSync: (p) => readFileSync36(p, "utf8"),
|
|
54567
|
+
writeFileSync: (p, d) => writeFileSync25(p, d),
|
|
54472
54568
|
renameSync: (a, b) => renameSync12(a, b),
|
|
54473
54569
|
existsSync: (p) => existsSync38(p),
|
|
54474
54570
|
statSizeSync: (p) => statSync13(p).size
|
|
@@ -54522,7 +54618,8 @@ var ipcServer = createIpcServer({
|
|
|
54522
54618
|
pendingInboundBuffer,
|
|
54523
54619
|
inboundSpool: inboundSpool ?? null,
|
|
54524
54620
|
pendingPermissionBuffer,
|
|
54525
|
-
client: client3
|
|
54621
|
+
client: client3,
|
|
54622
|
+
onUserInboundDelivered: trackRedeliveredInbound
|
|
54526
54623
|
});
|
|
54527
54624
|
} else {
|
|
54528
54625
|
const pending2 = pendingInboundBuffer.drain(client3.agentName);
|
|
@@ -54530,6 +54627,7 @@ var ipcServer = createIpcServer({
|
|
|
54530
54627
|
try {
|
|
54531
54628
|
client3.send(msg);
|
|
54532
54629
|
inboundSpool?.ack(msg);
|
|
54630
|
+
trackRedeliveredInbound(msg);
|
|
54533
54631
|
} catch (err) {
|
|
54534
54632
|
process.stderr.write(`telegram gateway: pending-inbound drain failed agent=${client3.agentName} source=${msg.meta?.source ?? "-"}: ${err.message}
|
|
54535
54633
|
`);
|
|
@@ -54611,6 +54709,7 @@ var ipcServer = createIpcServer({
|
|
|
54611
54709
|
tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
|
|
54612
54710
|
dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
|
|
54613
54711
|
configSnapshotPath: join35(resolvedAgentDirForCard, ".config-snapshot.json"),
|
|
54712
|
+
bootCardStatePath: join35(resolvedAgentDirForCard, ".boot-card-msgid.json"),
|
|
54614
54713
|
...updateOutcomeLine ? { updateOutcomeLine } : {}
|
|
54615
54714
|
}, ackMsgId).then((handle) => {
|
|
54616
54715
|
activeBootCard = handle;
|
|
@@ -55085,7 +55184,7 @@ if (!STATIC) {
|
|
|
55085
55184
|
if (d)
|
|
55086
55185
|
markClaudeBusyForInbound(m);
|
|
55087
55186
|
return d;
|
|
55088
|
-
}, inboundSpool);
|
|
55187
|
+
}, inboundSpool, trackRedeliveredInbound);
|
|
55089
55188
|
if (r != null && r.redelivered > 0) {
|
|
55090
55189
|
process.stderr.write(`telegram gateway: idle-drain flushed ${r.redelivered}/${r.drained} buffered inbound for ${selfAgent}${r.rebuffered > 0 ? ` (${r.rebuffered} re-buffered)` : ""}
|
|
55091
55190
|
`);
|
|
@@ -56050,7 +56149,7 @@ async function publishToTelegraph(text, shortName, authorName) {
|
|
|
56050
56149
|
let account = null;
|
|
56051
56150
|
try {
|
|
56052
56151
|
if (existsSync38(accountPath)) {
|
|
56053
|
-
const raw =
|
|
56152
|
+
const raw = readFileSync36(accountPath, "utf-8");
|
|
56054
56153
|
const parsed = JSON.parse(raw);
|
|
56055
56154
|
if (parsed.shortName && parsed.accessToken) {
|
|
56056
56155
|
account = parsed;
|
|
@@ -56070,7 +56169,7 @@ async function publishToTelegraph(text, shortName, authorName) {
|
|
|
56070
56169
|
account = created.value;
|
|
56071
56170
|
try {
|
|
56072
56171
|
mkdirSync26(STATE_DIR, { recursive: true, mode: 448 });
|
|
56073
|
-
|
|
56172
|
+
writeFileSync25(accountPath, JSON.stringify(account, null, 2), { mode: 384 });
|
|
56074
56173
|
} catch (err) {
|
|
56075
56174
|
process.stderr.write(`telegram gateway: telegraph cache write failed: ${err.message}
|
|
56076
56175
|
`);
|
|
@@ -56544,7 +56643,7 @@ async function executeDownloadAttachment(args) {
|
|
|
56544
56643
|
});
|
|
56545
56644
|
mkdirSync26(INBOX_DIR, { recursive: true, mode: 448 });
|
|
56546
56645
|
assertInsideInbox(INBOX_DIR, dlPath);
|
|
56547
|
-
|
|
56646
|
+
writeFileSync25(dlPath, buf, { mode: 384 });
|
|
56548
56647
|
return { content: [{ type: "text", text: dlPath }] };
|
|
56549
56648
|
}
|
|
56550
56649
|
async function executeEditMessage(args) {
|
|
@@ -58433,7 +58532,7 @@ function writeRestartMarker(marker) {
|
|
|
58433
58532
|
if (!p)
|
|
58434
58533
|
return;
|
|
58435
58534
|
try {
|
|
58436
|
-
|
|
58535
|
+
writeFileSync25(p, JSON.stringify(marker));
|
|
58437
58536
|
lastPlannedRestartAt = Date.now();
|
|
58438
58537
|
process.stderr.write(`telegram gateway: restart-marker: write chat_id=${marker.chat_id} thread_id=${marker.thread_id ?? "-"} ack=${marker.ack_message_id ?? "-"} path=${p}
|
|
58439
58538
|
`);
|
|
@@ -58452,7 +58551,7 @@ function readRestartMarker() {
|
|
|
58452
58551
|
if (!p)
|
|
58453
58552
|
return null;
|
|
58454
58553
|
try {
|
|
58455
|
-
return JSON.parse(
|
|
58554
|
+
return JSON.parse(readFileSync36(p, "utf8"));
|
|
58456
58555
|
} catch {
|
|
58457
58556
|
return null;
|
|
58458
58557
|
}
|
|
@@ -58589,7 +58688,7 @@ function spawnSwitchroomDetached(args, onFailure) {
|
|
|
58589
58688
|
try {
|
|
58590
58689
|
mkdirSync26(STATE_DIR, { recursive: true });
|
|
58591
58690
|
outFd = openSync8(logPath, "a");
|
|
58592
|
-
|
|
58691
|
+
writeFileSync25(logPath, `
|
|
58593
58692
|
[${new Date().toISOString()}] spawn ${SWITCHROOM_CLI} ${fullArgs.join(" ")}
|
|
58594
58693
|
`, { flag: "a" });
|
|
58595
58694
|
} catch {}
|
|
@@ -58615,7 +58714,7 @@ function spawnSwitchroomDetached(args, onFailure) {
|
|
|
58615
58714
|
return;
|
|
58616
58715
|
let tail = "";
|
|
58617
58716
|
try {
|
|
58618
|
-
const full =
|
|
58717
|
+
const full = readFileSync36(logPath, "utf8");
|
|
58619
58718
|
tail = full.split(`
|
|
58620
58719
|
`).slice(-30).join(`
|
|
58621
58720
|
`).trim();
|
|
@@ -58960,7 +59059,7 @@ function readRecentDenialsForAgent(agentName3, windowMs, limit) {
|
|
|
58960
59059
|
const auditPath = join35(homedir14(), ".switchroom", "vault-audit.log");
|
|
58961
59060
|
if (!existsSync38(auditPath))
|
|
58962
59061
|
return [];
|
|
58963
|
-
const raw =
|
|
59062
|
+
const raw = readFileSync36(auditPath, "utf8");
|
|
58964
59063
|
return recentDenialsFromAuditLog(raw, { agentName: agentName3, windowMs, limit });
|
|
58965
59064
|
} catch {
|
|
58966
59065
|
return [];
|
|
@@ -59011,7 +59110,7 @@ async function buildAgentMetadata(agentName3) {
|
|
|
59011
59110
|
try {
|
|
59012
59111
|
const agentDir = resolveAgentDirFromEnv();
|
|
59013
59112
|
if (agentDir) {
|
|
59014
|
-
const raw =
|
|
59113
|
+
const raw = readFileSync36(join35(agentDir, ".claude", ".claude.json"), "utf8");
|
|
59015
59114
|
claudeJson = JSON.parse(raw);
|
|
59016
59115
|
}
|
|
59017
59116
|
} catch {}
|
|
@@ -59283,7 +59382,7 @@ async function handleNewOrResetCommand(ctx, kind) {
|
|
|
59283
59382
|
writeRestartMarker({ chat_id: chatId, thread_id: threadId ?? null, ack_message_id: ackId, ts: Date.now() });
|
|
59284
59383
|
if (agentDir != null) {
|
|
59285
59384
|
try {
|
|
59286
|
-
|
|
59385
|
+
writeFileSync25(join35(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
|
|
59287
59386
|
`, "utf8");
|
|
59288
59387
|
} catch (err) {
|
|
59289
59388
|
process.stderr.write(`telegram gateway: failed to write force-fresh marker: ${err}
|
|
@@ -59647,8 +59746,8 @@ bot.command("interrupt", async (ctx) => {
|
|
|
59647
59746
|
await runSwitchroomCommand(ctx, ["agent", "interrupt", name], `interrupt ${name}`);
|
|
59648
59747
|
});
|
|
59649
59748
|
var lockoutOps = {
|
|
59650
|
-
readFileSync: (p, enc) =>
|
|
59651
|
-
writeFileSync: (p, data, opts) =>
|
|
59749
|
+
readFileSync: (p, enc) => readFileSync36(p, enc),
|
|
59750
|
+
writeFileSync: (p, data, opts) => writeFileSync25(p, data, opts),
|
|
59652
59751
|
existsSync: (p) => existsSync38(p),
|
|
59653
59752
|
mkdirSync: (p, opts) => mkdirSync26(p, opts),
|
|
59654
59753
|
joinPath: (...parts) => join35(...parts)
|
|
@@ -60023,7 +60122,7 @@ async function handleVaultRecentDenialCallback(ctx, data) {
|
|
|
60023
60122
|
const tokenPath = join35(homedir14(), ".switchroom", "agents", agentName3, ".vault-token");
|
|
60024
60123
|
try {
|
|
60025
60124
|
mkdirSync26(join35(homedir14(), ".switchroom", "agents", agentName3), { recursive: true });
|
|
60026
|
-
|
|
60125
|
+
writeFileSync25(tokenPath, token, { mode: 384 });
|
|
60027
60126
|
} catch (err) {
|
|
60028
60127
|
await switchroomReply(ctx, `<b>Grant created (${escapeHtmlForTg(id)}) but token write failed:</b> ${escapeHtmlForTg(String(err))}
|
|
60029
60128
|
<i>Recover with: <code>switchroom vault grant ${escapeHtmlForTg(agentName3)} --keys ${escapeHtmlForTg(keyName)} --duration 30d</code> on the host.</i>`, { html: true });
|
|
@@ -60102,7 +60201,7 @@ async function performVaultAccessApproval(ctx, pending2, stageId, senderId, atte
|
|
|
60102
60201
|
const tokenPath = join35(homedir14(), ".switchroom", "agents", pending2.agent, ".vault-token");
|
|
60103
60202
|
try {
|
|
60104
60203
|
mkdirSync26(join35(homedir14(), ".switchroom", "agents", pending2.agent), { recursive: true });
|
|
60105
|
-
|
|
60204
|
+
writeFileSync25(tokenPath, token, { mode: 384 });
|
|
60106
60205
|
} catch (err) {
|
|
60107
60206
|
await switchroomReply(ctx, `<b>Grant created (${escapeHtmlForTg(id)}) but token write failed:</b> ${escapeHtmlForTg(String(err))}
|
|
60108
60207
|
<i>Recover with: <code>switchroom vault grant ${escapeHtmlForTg(pending2.agent)} --keys ${escapeHtmlForTg(pending2.key)} --duration ${Math.round(pending2.ttl_seconds / 86400)}d</code> on the host.</i>`, { html: true });
|
|
@@ -60606,7 +60705,7 @@ async function executeGrantWizard(ctx, chatId, state4) {
|
|
|
60606
60705
|
const tokenPath = join35(homedir14(), ".switchroom", "agents", state4.agent, ".vault-token");
|
|
60607
60706
|
try {
|
|
60608
60707
|
mkdirSync26(join35(homedir14(), ".switchroom", "agents", state4.agent), { recursive: true });
|
|
60609
|
-
|
|
60708
|
+
writeFileSync25(tokenPath, token, { mode: 384 });
|
|
60610
60709
|
} catch (err) {
|
|
60611
60710
|
await switchroomReply(ctx, `<b>Grant created but token write failed:</b> ${escapeHtmlForTg(String(err))}`, { html: true });
|
|
60612
60711
|
return;
|
|
@@ -61902,7 +62001,7 @@ ${preBlock(formatSwitchroomOutput(err.message ?? "unknown error"))}`, { html: tr
|
|
|
61902
62001
|
const unifiedDiff = (() => {
|
|
61903
62002
|
try {
|
|
61904
62003
|
const cfgPath = process.env.SWITCHROOM_CONFIG ?? SWITCHROOM_CONFIG ?? findConfigFile2();
|
|
61905
|
-
const raw =
|
|
62004
|
+
const raw = readFileSync36(cfgPath, "utf8");
|
|
61906
62005
|
return synthesizeAllowRuleDiff({ agentName: agentName3, rule: chosen.rule, configText: raw });
|
|
61907
62006
|
} catch (err) {
|
|
61908
62007
|
process.stderr.write(`telegram gateway: always-allow diff synth failed: ${err.message}
|
|
@@ -62050,7 +62149,7 @@ bot.on("message:photo", async (ctx) => {
|
|
|
62050
62149
|
});
|
|
62051
62150
|
mkdirSync26(INBOX_DIR, { recursive: true, mode: 448 });
|
|
62052
62151
|
assertInsideInbox(INBOX_DIR, dlPath);
|
|
62053
|
-
|
|
62152
|
+
writeFileSync25(dlPath, buf, { mode: 384 });
|
|
62054
62153
|
return dlPath;
|
|
62055
62154
|
} catch (err) {
|
|
62056
62155
|
const msg = err instanceof Error ? err.message : "unknown error";
|
|
@@ -62091,7 +62190,7 @@ async function maybeTranscribeVoice(fileId, mimeType, language) {
|
|
|
62091
62190
|
try {
|
|
62092
62191
|
const path = __require("path").join(__require("os").homedir(), ".switchroom", "openai-api-key");
|
|
62093
62192
|
if (existsSync38(path)) {
|
|
62094
|
-
apiKey =
|
|
62193
|
+
apiKey = readFileSync36(path, "utf-8").trim();
|
|
62095
62194
|
}
|
|
62096
62195
|
} catch (err) {
|
|
62097
62196
|
process.stderr.write(`telegram gateway: voice-in: failed to read api key: ${err.message}
|
|
@@ -62961,6 +63060,7 @@ var didOneTimeSetup = false;
|
|
|
62961
63060
|
tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
|
|
62962
63061
|
dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
|
|
62963
63062
|
configSnapshotPath: join35(resolvedAgentDirForBootCard, ".config-snapshot.json"),
|
|
63063
|
+
bootCardStatePath: join35(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
|
|
62964
63064
|
...updateOutcomeLine ? { updateOutcomeLine } : {}
|
|
62965
63065
|
}, ackMsgId);
|
|
62966
63066
|
activeBootCard = handle;
|