switchroom 0.21.7 → 0.21.9
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/bin/tmp-reaper.sh +234 -0
- package/dist/agent-scheduler/index.js +1 -1
- package/dist/auth-broker/index.js +2 -2
- package/dist/cli/notion-write-pretool.mjs +1 -1
- package/dist/cli/switchroom.js +3520 -2782
- package/dist/host-control/main.js +177 -13
- package/dist/vault/approvals/kernel-server.js +2 -2
- package/dist/vault/broker/server.js +2 -2
- package/package.json +6 -5
- package/profiles/_base/start.sh.hbs +115 -0
- package/profiles/_shared/local-time.md.hbs +6 -0
- package/profiles/default/CLAUDE.md.hbs +0 -12
- package/skills/switchroom-architecture/telegram.md +12 -10
- package/skills/switchroom-cli/SKILL.md +1 -1
- package/telegram-plugin/README.md +3 -1
- package/telegram-plugin/dist/gateway/gateway.js +1164 -547
- package/telegram-plugin/format.ts +12 -4
- package/telegram-plugin/gateway/agent-process-liveness.ts +558 -0
- package/telegram-plugin/gateway/approval-hold.ts +32 -1
- package/telegram-plugin/gateway/approval-outcome-sources.ts +274 -0
- package/telegram-plugin/gateway/bridge-dead-watchdog.ts +21 -9
- package/telegram-plugin/gateway/callback-query-handlers.ts +87 -15
- package/telegram-plugin/gateway/eval-case-proposal-inbound-builders.ts +197 -0
- package/telegram-plugin/gateway/gateway.ts +12 -10
- package/telegram-plugin/gateway/pending-inbound-buffer.ts +167 -11
- package/telegram-plugin/gateway/self-improve-proposal-wiring.test.ts +333 -0
- package/telegram-plugin/gateway/self-improve-proposal-wiring.ts +152 -3
- package/telegram-plugin/gateway/subagent-handback-marker.ts +19 -0
- package/telegram-plugin/package.json +1 -1
- package/telegram-plugin/render/code-segments.ts +38 -4
- package/telegram-plugin/render/dollar-math-guard.ts +16 -1
- package/telegram-plugin/render/ir.ts +53 -3
- package/telegram-plugin/render/parse.ts +73 -14
- package/telegram-plugin/render/render.ts +53 -15
- package/telegram-plugin/render/unsupported-token-guard.ts +45 -80
- package/telegram-plugin/rich-send.ts +22 -7
- package/telegram-plugin/shared/bot-runtime.ts +3 -2
- package/telegram-plugin/telegraph.ts +6 -4
- package/telegram-plugin/tests/agent-process-liveness.test.ts +406 -0
- package/telegram-plugin/tests/approval-hold-record.test.ts +21 -8
- package/telegram-plugin/tests/boot-resume-gateway-only-respawn.test.ts +752 -0
- package/telegram-plugin/tests/boot-resume-guard-wiring.test.ts +203 -0
- package/telegram-plugin/tests/callback-query-handlers.test.ts +143 -1
- package/telegram-plugin/tests/eval-case-proposal-inbound-builders.test.ts +144 -0
- package/telegram-plugin/tests/grammy-rich-message-types.test.ts +199 -0
- package/telegram-plugin/tests/hermes-messages-paging.test.ts +149 -0
- package/telegram-plugin/tests/hermes-session-search.test.ts +146 -0
- package/telegram-plugin/tests/pending-inbound-buffer.test.ts +443 -2
- package/telegram-plugin/tests/render/dollar-math-guard.test.ts +43 -0
- package/telegram-plugin/tests/render/guard-composition.test.ts +102 -0
- package/telegram-plugin/tests/render/parse.test.ts +30 -5
- package/telegram-plugin/tests/render/render.test.ts +9 -4
- package/telegram-plugin/tests/render/rich-render.test.ts +46 -5
- package/telegram-plugin/tests/render/tg-entity.test.ts +242 -0
- package/telegram-plugin/tests/render/unsupported-token-guard.test.ts +66 -66
- package/telegram-plugin/tests/sent-text-capture.test.ts +3 -3
- package/telegram-plugin/tests/subagent-handback-marker.test.ts +14 -0
- package/telegram-plugin/tests/telegraph.test.ts +1 -1
- package/telegram-plugin/uat/scenarios/jtbd-rich-formatting-render-dm.test.ts +17 -8
|
@@ -66,7 +66,7 @@ var __export = (target, all) => {
|
|
|
66
66
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
67
67
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
68
68
|
|
|
69
|
-
// ../node_modules/.bun/grammy@1.
|
|
69
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/filter.js
|
|
70
70
|
var require_filter = __commonJS((exports) => {
|
|
71
71
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
72
72
|
exports.matchFilter = matchFilter;
|
|
@@ -357,6 +357,8 @@ var require_filter = __commonJS((exports) => {
|
|
|
357
357
|
checklist: { others_can_add_tasks: {}, others_can_mark_tasks_as_done: {} },
|
|
358
358
|
checklist_tasks_done: {},
|
|
359
359
|
checklist_tasks_added: {},
|
|
360
|
+
community_chat_added: {},
|
|
361
|
+
community_chat_removed: {},
|
|
360
362
|
poll_option_added: {},
|
|
361
363
|
poll_option_deleted: {},
|
|
362
364
|
suggested_post_info: {},
|
|
@@ -411,7 +413,8 @@ var require_filter = __commonJS((exports) => {
|
|
|
411
413
|
message_reaction_count: MESSAGE_REACTION_COUNT_UPDATED_KEYS,
|
|
412
414
|
chat_boost: {},
|
|
413
415
|
removed_chat_boost: {},
|
|
414
|
-
purchased_paid_media: {}
|
|
416
|
+
purchased_paid_media: {},
|
|
417
|
+
subscription: { state: { canceled: {}, active: {}, failed: {} } }
|
|
415
418
|
};
|
|
416
419
|
var L1_SHORTCUTS = {
|
|
417
420
|
"": ["message", "channel_post"],
|
|
@@ -435,7 +438,7 @@ var require_filter = __commonJS((exports) => {
|
|
|
435
438
|
};
|
|
436
439
|
});
|
|
437
440
|
|
|
438
|
-
// ../node_modules/.bun/grammy@1.
|
|
441
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/context.js
|
|
439
442
|
var require_context = __commonJS((exports) => {
|
|
440
443
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
441
444
|
exports.Context = undefined;
|
|
@@ -676,6 +679,9 @@ var require_context = __commonJS((exports) => {
|
|
|
676
679
|
get purchasedPaidMedia() {
|
|
677
680
|
return this.update.purchased_paid_media;
|
|
678
681
|
}
|
|
682
|
+
get subscription() {
|
|
683
|
+
return this.update.subscription;
|
|
684
|
+
}
|
|
679
685
|
get msg() {
|
|
680
686
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
681
687
|
return (_g = (_f = (_e = (_d = (_c = (_b = (_a = this.message) !== null && _a !== undefined ? _a : this.editedMessage) !== null && _b !== undefined ? _b : this.channelPost) !== null && _c !== undefined ? _c : this.editedChannelPost) !== null && _d !== undefined ? _d : this.businessMessage) !== null && _e !== undefined ? _e : this.editedBusinessMessage) !== null && _f !== undefined ? _f : this.guestMessage) !== null && _g !== undefined ? _g : (_h = this.callbackQuery) === null || _h === undefined ? undefined : _h.message;
|
|
@@ -689,8 +695,8 @@ var require_context = __commonJS((exports) => {
|
|
|
689
695
|
return (_a = this.msg) === null || _a === undefined ? undefined : _a.sender_chat;
|
|
690
696
|
}
|
|
691
697
|
get from() {
|
|
692
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
693
|
-
return (_h = (_g = (_c = (_b = (_a = this.businessConnection) !== null && _a !== undefined ? _a : this.messageReaction) !== null && _b !== undefined ? _b : this.managedBot) !== null && _c !== undefined ? _c : (_f = (_e = (_d = this.chatBoost) === null || _d === undefined ? undefined : _d.boost) !== null && _e !== undefined ? _e : this.removedChatBoost) === null || _f === undefined ? undefined : _f.source) === null ||
|
|
698
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
699
|
+
return (_j = (_h = (_g = (_c = (_b = (_a = this.businessConnection) !== null && _a !== undefined ? _a : this.messageReaction) !== null && _b !== undefined ? _b : this.managedBot) !== null && _c !== undefined ? _c : (_f = (_e = (_d = this.chatBoost) === null || _d === undefined ? undefined : _d.boost) !== null && _e !== undefined ? _e : this.removedChatBoost) === null || _f === undefined ? undefined : _f.source) !== null && _g !== undefined ? _g : this.subscription) === null || _h === undefined ? undefined : _h.user) !== null && _j !== undefined ? _j : (_u = (_t = (_s = (_r = (_q = (_p = (_o = (_m = (_l = (_k = this.callbackQuery) !== null && _k !== undefined ? _k : this.msg) !== null && _l !== undefined ? _l : this.inlineQuery) !== null && _m !== undefined ? _m : this.chosenInlineResult) !== null && _o !== undefined ? _o : this.shippingQuery) !== null && _p !== undefined ? _p : this.preCheckoutQuery) !== null && _q !== undefined ? _q : this.myChatMember) !== null && _r !== undefined ? _r : this.chatMember) !== null && _s !== undefined ? _s : this.chatJoinRequest) !== null && _t !== undefined ? _t : this.purchasedPaidMedia) === null || _u === undefined ? undefined : _u.from;
|
|
694
700
|
}
|
|
695
701
|
get msgId() {
|
|
696
702
|
var _a, _b, _c, _d, _e;
|
|
@@ -1349,6 +1355,22 @@ var require_context = __commonJS((exports) => {
|
|
|
1349
1355
|
var _a, _b, _c, _d, _e;
|
|
1350
1356
|
return this.api.stopPoll(orThrow(this.chatId, "stopPoll"), orThrow((_d = (_b = (_a = this.msg) === null || _a === undefined ? undefined : _a.message_id) !== null && _b !== undefined ? _b : (_c = this.messageReaction) === null || _c === undefined ? undefined : _c.message_id) !== null && _d !== undefined ? _d : (_e = this.messageReactionCount) === null || _e === undefined ? undefined : _e.message_id, "stopPoll"), { business_connection_id: this.businessConnectionId, ...other }, signal);
|
|
1351
1357
|
}
|
|
1358
|
+
editEphemeralMessageText(text, other, signal) {
|
|
1359
|
+
const msg = orThrow(this.msg, "editEphemeralMessageText");
|
|
1360
|
+
return this.api.editEphemeralMessageText(msg.chat.id, orThrow(msg.receiver_user, "editEphemeralMessageText").id, orThrow(msg.ephemeral_message_id, "editEphemeralMessageText"), text, other, signal);
|
|
1361
|
+
}
|
|
1362
|
+
editEphemeralMessageMedia(media, other, signal) {
|
|
1363
|
+
const msg = orThrow(this.msg, "editEphemeralMessageMedia");
|
|
1364
|
+
return this.api.editEphemeralMessageMedia(msg.chat.id, orThrow(msg.receiver_user, "editEphemeralMessageMedia").id, orThrow(msg.ephemeral_message_id, "editEphemeralMessageMedia"), media, other, signal);
|
|
1365
|
+
}
|
|
1366
|
+
editEphemeralMessageCaption(caption, other, signal) {
|
|
1367
|
+
const msg = orThrow(this.msg, "editEphemeralMessageCaption");
|
|
1368
|
+
return this.api.editEphemeralMessageCaption(msg.chat.id, orThrow(msg.receiver_user, "editEphemeralMessageCaption").id, orThrow(msg.ephemeral_message_id, "editEphemeralMessageCaption"), caption, other, signal);
|
|
1369
|
+
}
|
|
1370
|
+
editEphemeralMessageReplyMarkup(other, signal) {
|
|
1371
|
+
const msg = orThrow(this.msg, "editEphemeralMessageReplyMarkup");
|
|
1372
|
+
return this.api.editEphemeralMessageReplyMarkup(msg.chat.id, orThrow(msg.receiver_user, "editEphemeralMessageReplyMarkup").id, orThrow(msg.ephemeral_message_id, "editEphemeralMessageReplyMarkup"), other, signal);
|
|
1373
|
+
}
|
|
1352
1374
|
deleteMessage(signal) {
|
|
1353
1375
|
var _a, _b, _c, _d, _e;
|
|
1354
1376
|
return this.api.deleteMessage(orThrow(this.chatId, "deleteMessage"), orThrow((_d = (_b = (_a = this.msg) === null || _a === undefined ? undefined : _a.message_id) !== null && _b !== undefined ? _b : (_c = this.messageReaction) === null || _c === undefined ? undefined : _c.message_id) !== null && _d !== undefined ? _d : (_e = this.messageReactionCount) === null || _e === undefined ? undefined : _e.message_id, "deleteMessage"), signal);
|
|
@@ -1356,6 +1378,10 @@ var require_context = __commonJS((exports) => {
|
|
|
1356
1378
|
deleteMessages(message_ids, signal) {
|
|
1357
1379
|
return this.api.deleteMessages(orThrow(this.chatId, "deleteMessages"), message_ids, signal);
|
|
1358
1380
|
}
|
|
1381
|
+
deleteEphemeralMessage(signal) {
|
|
1382
|
+
const msg = orThrow(this.msg, "deleteEphemeralMessage");
|
|
1383
|
+
return this.api.deleteEphemeralMessage(msg.chat.id, orThrow(msg.receiver_user, "deleteEphemeralMessage").id, orThrow(msg.ephemeral_message_id, "deleteEphemeralMessage"), signal);
|
|
1384
|
+
}
|
|
1359
1385
|
deleteMessageReaction(other, signal) {
|
|
1360
1386
|
const reaction = orThrow(this.messageReaction, "deleteMessageReaction");
|
|
1361
1387
|
if (reaction.user !== undefined) {
|
|
@@ -1548,7 +1574,7 @@ var require_context = __commonJS((exports) => {
|
|
|
1548
1574
|
}
|
|
1549
1575
|
});
|
|
1550
1576
|
|
|
1551
|
-
// ../node_modules/.bun/grammy@1.
|
|
1577
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/composer.js
|
|
1552
1578
|
var require_composer = __commonJS((exports) => {
|
|
1553
1579
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1554
1580
|
exports.Composer = exports.BotError = undefined;
|
|
@@ -2444,7 +2470,7 @@ var require_src = __commonJS((exports, module) => {
|
|
|
2444
2470
|
}
|
|
2445
2471
|
});
|
|
2446
2472
|
|
|
2447
|
-
// ../node_modules/.bun/grammy@1.
|
|
2473
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/platform.node.js
|
|
2448
2474
|
var require_platform_node = __commonJS((exports) => {
|
|
2449
2475
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2450
2476
|
exports.defaultAdapter = exports.itrToStream = exports.debug = undefined;
|
|
@@ -2472,19 +2498,21 @@ var require_platform_node = __commonJS((exports) => {
|
|
|
2472
2498
|
if (apiRoot.startsWith("https:")) {
|
|
2473
2499
|
return {
|
|
2474
2500
|
compress: true,
|
|
2475
|
-
agent: getCached(httpsAgents, apiRoot, () => new https_1.Agent({ keepAlive: true }))
|
|
2501
|
+
agent: getCached(httpsAgents, apiRoot, () => new https_1.Agent({ keepAlive: true })),
|
|
2502
|
+
duplex: "half"
|
|
2476
2503
|
};
|
|
2477
2504
|
} else if (apiRoot.startsWith("http:")) {
|
|
2478
2505
|
return {
|
|
2479
|
-
agent: getCached(httpAgents, apiRoot, () => new http_1.Agent({ keepAlive: true }))
|
|
2506
|
+
agent: getCached(httpAgents, apiRoot, () => new http_1.Agent({ keepAlive: true })),
|
|
2507
|
+
duplex: "half"
|
|
2480
2508
|
};
|
|
2481
2509
|
} else
|
|
2482
|
-
return {};
|
|
2510
|
+
return { duplex: "half" };
|
|
2483
2511
|
}
|
|
2484
2512
|
exports.defaultAdapter = "express";
|
|
2485
2513
|
});
|
|
2486
2514
|
|
|
2487
|
-
// ../node_modules/.bun/grammy@1.
|
|
2515
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/core/error.js
|
|
2488
2516
|
var require_error = __commonJS((exports) => {
|
|
2489
2517
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2490
2518
|
exports.HttpError = exports.GrammyError = undefined;
|
|
@@ -2540,10 +2568,10 @@ var require_error = __commonJS((exports) => {
|
|
|
2540
2568
|
}
|
|
2541
2569
|
});
|
|
2542
2570
|
|
|
2543
|
-
// ../node_modules/.bun/@grammyjs+types@
|
|
2571
|
+
// ../node_modules/.bun/@grammyjs+types@4.0.0/node_modules/@grammyjs/types/mod.js
|
|
2544
2572
|
var exports_mod = {};
|
|
2545
2573
|
|
|
2546
|
-
// ../node_modules/.bun/grammy@1.
|
|
2574
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/types.node.js
|
|
2547
2575
|
var require_types_node = __commonJS((exports) => {
|
|
2548
2576
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2549
2577
|
if (k2 === undefined)
|
|
@@ -2634,7 +2662,7 @@ var require_types_node = __commonJS((exports) => {
|
|
|
2634
2662
|
}
|
|
2635
2663
|
});
|
|
2636
2664
|
|
|
2637
|
-
// ../node_modules/.bun/grammy@1.
|
|
2665
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/types.js
|
|
2638
2666
|
var require_types = __commonJS((exports) => {
|
|
2639
2667
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
2640
2668
|
if (k2 === undefined)
|
|
@@ -2660,7 +2688,7 @@ var require_types = __commonJS((exports) => {
|
|
|
2660
2688
|
__exportStar(require_types_node(), exports);
|
|
2661
2689
|
});
|
|
2662
2690
|
|
|
2663
|
-
// ../node_modules/.bun/grammy@1.
|
|
2691
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/core/payload.js
|
|
2664
2692
|
var require_payload = __commonJS((exports) => {
|
|
2665
2693
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2666
2694
|
exports.requiresFormDataUpload = requiresFormDataUpload;
|
|
@@ -3320,7 +3348,7 @@ var require_abort_controller = __commonJS((exports, module) => {
|
|
|
3320
3348
|
module.exports.AbortSignal = AbortSignal2;
|
|
3321
3349
|
});
|
|
3322
3350
|
|
|
3323
|
-
// ../node_modules/.bun/grammy@1.
|
|
3351
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/shim.node.js
|
|
3324
3352
|
var require_shim_node = __commonJS((exports) => {
|
|
3325
3353
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3326
3354
|
exports.fetch = exports.AbortController = undefined;
|
|
@@ -3334,7 +3362,7 @@ var require_shim_node = __commonJS((exports) => {
|
|
|
3334
3362
|
} });
|
|
3335
3363
|
});
|
|
3336
3364
|
|
|
3337
|
-
// ../node_modules/.bun/grammy@1.
|
|
3365
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/core/client.js
|
|
3338
3366
|
var require_client = __commonJS((exports) => {
|
|
3339
3367
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3340
3368
|
exports.createRawApi = createRawApi;
|
|
@@ -3514,7 +3542,7 @@ If you want to prevent such mistakes in the future, consider using TypeScript. h
|
|
|
3514
3542
|
var shim_node_js_1 = require_shim_node();
|
|
3515
3543
|
});
|
|
3516
3544
|
|
|
3517
|
-
// ../node_modules/.bun/grammy@1.
|
|
3545
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/core/api.js
|
|
3518
3546
|
var require_api = __commonJS((exports) => {
|
|
3519
3547
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3520
3548
|
exports.Api = undefined;
|
|
@@ -3955,12 +3983,39 @@ var require_api = __commonJS((exports) => {
|
|
|
3955
3983
|
stopPoll(chat_id, message_id, other, signal) {
|
|
3956
3984
|
return this.raw.stopPoll({ chat_id, message_id, ...other }, signal);
|
|
3957
3985
|
}
|
|
3986
|
+
editEphemeralMessageText(chat_id, receiver_user_id, ephemeral_message_id, text, other, signal) {
|
|
3987
|
+
return this.raw.editEphemeralMessageText({ chat_id, receiver_user_id, ephemeral_message_id, text, ...other }, signal);
|
|
3988
|
+
}
|
|
3989
|
+
editEphemeralMessageMedia(chat_id, receiver_user_id, ephemeral_message_id, media, other, signal) {
|
|
3990
|
+
return this.raw.editEphemeralMessageMedia({
|
|
3991
|
+
chat_id,
|
|
3992
|
+
receiver_user_id,
|
|
3993
|
+
ephemeral_message_id,
|
|
3994
|
+
media,
|
|
3995
|
+
...other
|
|
3996
|
+
}, signal);
|
|
3997
|
+
}
|
|
3998
|
+
editEphemeralMessageCaption(chat_id, receiver_user_id, ephemeral_message_id, caption, other, signal) {
|
|
3999
|
+
return this.raw.editEphemeralMessageCaption({
|
|
4000
|
+
chat_id,
|
|
4001
|
+
receiver_user_id,
|
|
4002
|
+
ephemeral_message_id,
|
|
4003
|
+
caption,
|
|
4004
|
+
...other
|
|
4005
|
+
}, signal);
|
|
4006
|
+
}
|
|
4007
|
+
editEphemeralMessageReplyMarkup(chat_id, receiver_user_id, ephemeral_message_id, other, signal) {
|
|
4008
|
+
return this.raw.editEphemeralMessageReplyMarkup({ chat_id, receiver_user_id, ephemeral_message_id, ...other }, signal);
|
|
4009
|
+
}
|
|
3958
4010
|
deleteMessage(chat_id, message_id, signal) {
|
|
3959
4011
|
return this.raw.deleteMessage({ chat_id, message_id }, signal);
|
|
3960
4012
|
}
|
|
3961
4013
|
deleteMessages(chat_id, message_ids, signal) {
|
|
3962
4014
|
return this.raw.deleteMessages({ chat_id, message_ids }, signal);
|
|
3963
4015
|
}
|
|
4016
|
+
deleteEphemeralMessage(chat_id, receiver_user_id, ephemeral_message_id, signal) {
|
|
4017
|
+
return this.raw.deleteEphemeralMessage({ chat_id, receiver_user_id, ephemeral_message_id }, signal);
|
|
4018
|
+
}
|
|
3964
4019
|
deleteMessageReactionUser(chat_id, message_id, user_id, other, signal) {
|
|
3965
4020
|
return this.raw.deleteMessageReaction({
|
|
3966
4021
|
chat_id,
|
|
@@ -4202,7 +4257,7 @@ var require_api = __commonJS((exports) => {
|
|
|
4202
4257
|
exports.Api = Api;
|
|
4203
4258
|
});
|
|
4204
4259
|
|
|
4205
|
-
// ../node_modules/.bun/grammy@1.
|
|
4260
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/bot.js
|
|
4206
4261
|
var require_bot = __commonJS((exports) => {
|
|
4207
4262
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4208
4263
|
exports.Bot = exports.BotError = exports.DEFAULT_UPDATE_TYPES = undefined;
|
|
@@ -4240,7 +4295,8 @@ var require_bot = __commonJS((exports) => {
|
|
|
4240
4295
|
"managed_bot",
|
|
4241
4296
|
"chat_join_request",
|
|
4242
4297
|
"chat_boost",
|
|
4243
|
-
"removed_chat_boost"
|
|
4298
|
+
"removed_chat_boost",
|
|
4299
|
+
"subscription"
|
|
4244
4300
|
];
|
|
4245
4301
|
|
|
4246
4302
|
class Bot extends composer_js_1.Composer {
|
|
@@ -4532,7 +4588,7 @@ On the other hand, if you actually know what you're doing and you do need to ins
|
|
|
4532
4588
|
var shim_node_js_1 = require_shim_node();
|
|
4533
4589
|
});
|
|
4534
4590
|
|
|
4535
|
-
// ../node_modules/.bun/grammy@1.
|
|
4591
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/constants.js
|
|
4536
4592
|
var require_constants = __commonJS((exports) => {
|
|
4537
4593
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4538
4594
|
exports.API_CONSTANTS = undefined;
|
|
@@ -4569,7 +4625,7 @@ var require_constants = __commonJS((exports) => {
|
|
|
4569
4625
|
Object.freeze(exports.API_CONSTANTS);
|
|
4570
4626
|
});
|
|
4571
4627
|
|
|
4572
|
-
// ../node_modules/.bun/grammy@1.
|
|
4628
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/inline_query.js
|
|
4573
4629
|
var require_inline_query = __commonJS((exports) => {
|
|
4574
4630
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4575
4631
|
exports.InlineQueryResultBuilder = undefined;
|
|
@@ -4774,7 +4830,7 @@ var require_inline_query = __commonJS((exports) => {
|
|
|
4774
4830
|
};
|
|
4775
4831
|
});
|
|
4776
4832
|
|
|
4777
|
-
// ../node_modules/.bun/grammy@1.
|
|
4833
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/input_media.js
|
|
4778
4834
|
var require_input_media = __commonJS((exports) => {
|
|
4779
4835
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4780
4836
|
exports.InputMediaBuilder = undefined;
|
|
@@ -4797,7 +4853,7 @@ var require_input_media = __commonJS((exports) => {
|
|
|
4797
4853
|
};
|
|
4798
4854
|
});
|
|
4799
4855
|
|
|
4800
|
-
// ../node_modules/.bun/grammy@1.
|
|
4856
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/keyboard.js
|
|
4801
4857
|
var require_keyboard = __commonJS((exports) => {
|
|
4802
4858
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4803
4859
|
exports.InlineKeyboard = exports.Keyboard = undefined;
|
|
@@ -5155,7 +5211,7 @@ var require_keyboard = __commonJS((exports) => {
|
|
|
5155
5211
|
}
|
|
5156
5212
|
});
|
|
5157
5213
|
|
|
5158
|
-
// ../node_modules/.bun/grammy@1.
|
|
5214
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/session.js
|
|
5159
5215
|
var require_session = __commonJS((exports) => {
|
|
5160
5216
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5161
5217
|
exports.MemorySessionStorage = undefined;
|
|
@@ -5455,7 +5511,7 @@ var require_session = __commonJS((exports) => {
|
|
|
5455
5511
|
}
|
|
5456
5512
|
});
|
|
5457
5513
|
|
|
5458
|
-
// ../node_modules/.bun/grammy@1.
|
|
5514
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/frameworks.js
|
|
5459
5515
|
var require_frameworks = __commonJS((exports) => {
|
|
5460
5516
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5461
5517
|
exports.adapters = undefined;
|
|
@@ -5827,7 +5883,7 @@ var require_frameworks = __commonJS((exports) => {
|
|
|
5827
5883
|
};
|
|
5828
5884
|
});
|
|
5829
5885
|
|
|
5830
|
-
// ../node_modules/.bun/grammy@1.
|
|
5886
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/convenience/webhook.js
|
|
5831
5887
|
var require_webhook = __commonJS((exports) => {
|
|
5832
5888
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5833
5889
|
exports.webhookCallback = webhookCallback;
|
|
@@ -5921,7 +5977,7 @@ var require_webhook = __commonJS((exports) => {
|
|
|
5921
5977
|
}
|
|
5922
5978
|
});
|
|
5923
5979
|
|
|
5924
|
-
// ../node_modules/.bun/grammy@1.
|
|
5980
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/mod.js
|
|
5925
5981
|
var require_mod = __commonJS((exports) => {
|
|
5926
5982
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
5927
5983
|
if (k2 === undefined)
|
|
@@ -5987,7 +6043,7 @@ var require_mod = __commonJS((exports) => {
|
|
|
5987
6043
|
} });
|
|
5988
6044
|
});
|
|
5989
6045
|
|
|
5990
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6046
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/platform.node.js
|
|
5991
6047
|
var require_platform_node2 = __commonJS((exports) => {
|
|
5992
6048
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5993
6049
|
exports.parentThread = exports.createThread = undefined;
|
|
@@ -6018,7 +6074,7 @@ var require_platform_node2 = __commonJS((exports) => {
|
|
|
6018
6074
|
exports.parentThread = parentThread;
|
|
6019
6075
|
});
|
|
6020
6076
|
|
|
6021
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6077
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/distribute.js
|
|
6022
6078
|
var require_distribute = __commonJS((exports) => {
|
|
6023
6079
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6024
6080
|
exports.distribute = undefined;
|
|
@@ -6063,7 +6119,7 @@ var require_distribute = __commonJS((exports) => {
|
|
|
6063
6119
|
exports.distribute = distribute;
|
|
6064
6120
|
});
|
|
6065
6121
|
|
|
6066
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6122
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/queue.js
|
|
6067
6123
|
var require_queue = __commonJS((exports) => {
|
|
6068
6124
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6069
6125
|
exports.DecayingDeque = undefined;
|
|
@@ -6207,7 +6263,7 @@ var require_queue = __commonJS((exports) => {
|
|
|
6207
6263
|
exports.DecayingDeque = DecayingDeque;
|
|
6208
6264
|
});
|
|
6209
6265
|
|
|
6210
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6266
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/sink.js
|
|
6211
6267
|
var require_sink = __commonJS((exports) => {
|
|
6212
6268
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6213
6269
|
exports.createConcurrentSink = exports.createBatchSink = exports.createSequentialSink = undefined;
|
|
@@ -6252,7 +6308,7 @@ var require_sink = __commonJS((exports) => {
|
|
|
6252
6308
|
exports.createConcurrentSink = createConcurrentSink;
|
|
6253
6309
|
});
|
|
6254
6310
|
|
|
6255
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6311
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/node-shim.js
|
|
6256
6312
|
var require_node_shim = __commonJS((exports) => {
|
|
6257
6313
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
6258
6314
|
if (k2 === undefined)
|
|
@@ -6278,7 +6334,7 @@ var require_node_shim = __commonJS((exports) => {
|
|
|
6278
6334
|
__exportStar(require_abort_controller(), exports);
|
|
6279
6335
|
});
|
|
6280
6336
|
|
|
6281
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6337
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/source.js
|
|
6282
6338
|
var require_source = __commonJS((exports) => {
|
|
6283
6339
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6284
6340
|
exports.createSource = undefined;
|
|
@@ -6358,7 +6414,7 @@ var require_source = __commonJS((exports) => {
|
|
|
6358
6414
|
var node_shim_js_1 = require_node_shim();
|
|
6359
6415
|
});
|
|
6360
6416
|
|
|
6361
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6417
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/runner.js
|
|
6362
6418
|
var require_runner = __commonJS((exports) => {
|
|
6363
6419
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6364
6420
|
exports.createRunner = exports.createUpdateFetcher = exports.run = undefined;
|
|
@@ -6510,7 +6566,7 @@ var require_runner = __commonJS((exports) => {
|
|
|
6510
6566
|
}
|
|
6511
6567
|
});
|
|
6512
6568
|
|
|
6513
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6569
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/sequentialize.js
|
|
6514
6570
|
var require_sequentialize = __commonJS((exports) => {
|
|
6515
6571
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6516
6572
|
exports.sequentialize = undefined;
|
|
@@ -6553,7 +6609,7 @@ var require_sequentialize = __commonJS((exports) => {
|
|
|
6553
6609
|
exports.sequentialize = sequentialize;
|
|
6554
6610
|
});
|
|
6555
6611
|
|
|
6556
|
-
// ../node_modules/.bun/grammy@1.
|
|
6612
|
+
// ../node_modules/.bun/grammy@1.45.1/node_modules/grammy/out/mod.js
|
|
6557
6613
|
var require_mod2 = __commonJS((exports) => {
|
|
6558
6614
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
6559
6615
|
if (k2 === undefined)
|
|
@@ -6619,7 +6675,7 @@ var require_mod2 = __commonJS((exports) => {
|
|
|
6619
6675
|
} });
|
|
6620
6676
|
});
|
|
6621
6677
|
|
|
6622
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6678
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/deps.node.js
|
|
6623
6679
|
var require_deps_node = __commonJS((exports) => {
|
|
6624
6680
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6625
6681
|
exports.BotError = exports.Bot = undefined;
|
|
@@ -6632,7 +6688,7 @@ var require_deps_node = __commonJS((exports) => {
|
|
|
6632
6688
|
} });
|
|
6633
6689
|
});
|
|
6634
6690
|
|
|
6635
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6691
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/worker.js
|
|
6636
6692
|
var require_worker = __commonJS((exports) => {
|
|
6637
6693
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6638
6694
|
exports.BotWorker = undefined;
|
|
@@ -6674,7 +6730,7 @@ var require_worker = __commonJS((exports) => {
|
|
|
6674
6730
|
exports.BotWorker = BotWorker;
|
|
6675
6731
|
});
|
|
6676
6732
|
|
|
6677
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
6733
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/mod.js
|
|
6678
6734
|
var require_mod3 = __commonJS((exports) => {
|
|
6679
6735
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
6680
6736
|
if (k2 === undefined)
|
|
@@ -7283,7 +7339,7 @@ var init_format = __esm(() => {
|
|
|
7283
7339
|
/\*\*[^*\n]+\*\*/g,
|
|
7284
7340
|
/__[^_\n]+__/g,
|
|
7285
7341
|
/(?<![\w*])_[^_\n]+_(?![\w*])/g,
|
|
7286
|
-
|
|
7342
|
+
/!?\[[^\]\n]*\]\([^)\n]*\)/g,
|
|
7287
7343
|
/~~[^~\n]+~~/g,
|
|
7288
7344
|
/\|\|[^|\n]+\|\|/g
|
|
7289
7345
|
];
|
|
@@ -13444,6 +13500,15 @@ function splitProseProtected(text) {
|
|
|
13444
13500
|
continue;
|
|
13445
13501
|
}
|
|
13446
13502
|
}
|
|
13503
|
+
if (ch === "$") {
|
|
13504
|
+
const m = COMPACT_MATH_PAIR.exec(text.slice(i));
|
|
13505
|
+
if (m && !CURRENCY_SHAPED_INNER.test(m[1])) {
|
|
13506
|
+
const end = i + m[0].length;
|
|
13507
|
+
pushProtected(i, end);
|
|
13508
|
+
i = end;
|
|
13509
|
+
continue;
|
|
13510
|
+
}
|
|
13511
|
+
}
|
|
13447
13512
|
i++;
|
|
13448
13513
|
}
|
|
13449
13514
|
if (plainStart < text.length)
|
|
@@ -13462,6 +13527,11 @@ function splitProtectedSegments(text) {
|
|
|
13462
13527
|
}
|
|
13463
13528
|
return out;
|
|
13464
13529
|
}
|
|
13530
|
+
var COMPACT_MATH_PAIR, CURRENCY_SHAPED_INNER;
|
|
13531
|
+
var init_code_segments = __esm(() => {
|
|
13532
|
+
COMPACT_MATH_PAIR = /^\$([^\s$]+)\$/;
|
|
13533
|
+
CURRENCY_SHAPED_INNER = /^[0-9.,+\-kKmMbB]+$/;
|
|
13534
|
+
});
|
|
13465
13535
|
|
|
13466
13536
|
// render/dollar-math-guard.ts
|
|
13467
13537
|
function guardDollarMath(text) {
|
|
@@ -13483,6 +13553,7 @@ function guardDollarMath(text) {
|
|
|
13483
13553
|
}
|
|
13484
13554
|
var ANY_DOLLAR, CURRENCY_SIGNAL, UNESCAPED_DOLLAR;
|
|
13485
13555
|
var init_dollar_math_guard = __esm(() => {
|
|
13556
|
+
init_code_segments();
|
|
13486
13557
|
ANY_DOLLAR = /\$/g;
|
|
13487
13558
|
CURRENCY_SIGNAL = /\$\.?\d|\d\s?\$/;
|
|
13488
13559
|
UNESCAPED_DOLLAR = /(?<!\\)\$/g;
|
|
@@ -13554,6 +13625,7 @@ function guardAccidentalEmphasis(text) {
|
|
|
13554
13625
|
}
|
|
13555
13626
|
var INTRA_WORD_UNDERSCORE, INTRA_WORD_ASTERISK, BOUNDARY_FLANKED_ASTERISK, ANY_UNDERSCORE, ANY_ASTERISK;
|
|
13556
13627
|
var init_emphasis_guard = __esm(() => {
|
|
13628
|
+
init_code_segments();
|
|
13557
13629
|
INTRA_WORD_UNDERSCORE = /(?<=[A-Za-z0-9])_(?=[A-Za-z0-9])/g;
|
|
13558
13630
|
INTRA_WORD_ASTERISK = /(?<=[A-Za-z0-9])\*(?=[A-Za-z0-9])/g;
|
|
13559
13631
|
BOUNDARY_FLANKED_ASTERISK = /(?<=^|\s)\*(?=\s|$)/g;
|
|
@@ -13639,6 +13711,7 @@ function guardAccidentalHeading(text) {
|
|
|
13639
13711
|
}
|
|
13640
13712
|
var ACCIDENTAL_BLOCKQUOTE, ACCIDENTAL_ORDERED_LIST, ACCIDENTAL_HEADING, ACCIDENTAL_HEADING_AFTER_MARKER;
|
|
13641
13713
|
var init_line_start_guard = __esm(() => {
|
|
13714
|
+
init_code_segments();
|
|
13642
13715
|
ACCIDENTAL_BLOCKQUOTE = /^>[0-9=]/;
|
|
13643
13716
|
ACCIDENTAL_ORDERED_LIST = /^(\d{4,})([.)])(\s|$)/;
|
|
13644
13717
|
ACCIDENTAL_HEADING = /^([ \t]{0,3})(#{1,6})(?=[^\s#])/;
|
|
@@ -13683,50 +13756,25 @@ function guardAccidentalInlinePairs(text) {
|
|
|
13683
13756
|
}
|
|
13684
13757
|
var TILDE_APPROX, MARK_OP, SPOILER_OP;
|
|
13685
13758
|
var init_inline_pairs_guard = __esm(() => {
|
|
13759
|
+
init_code_segments();
|
|
13686
13760
|
TILDE_APPROX = /(?<!\\)~(?=\$?\.?\d)/g;
|
|
13687
13761
|
MARK_OP = /(?<=\w)==(?=\w)/g;
|
|
13688
13762
|
SPOILER_OP = /(?<=\w)\|\|(?=\w)/g;
|
|
13689
13763
|
});
|
|
13690
13764
|
|
|
13691
13765
|
// render/unsupported-token-guard.ts
|
|
13692
|
-
function toExpandableBlockquote(title, body) {
|
|
13693
|
-
const lines = [];
|
|
13694
|
-
const t = title.trim();
|
|
13695
|
-
if (t)
|
|
13696
|
-
lines.push(t);
|
|
13697
|
-
for (const raw of body.split(`
|
|
13698
|
-
`)) {
|
|
13699
|
-
const line = raw.trimEnd();
|
|
13700
|
-
if (line.trim() === "" && lines.length === 0)
|
|
13701
|
-
continue;
|
|
13702
|
-
lines.push(line);
|
|
13703
|
-
}
|
|
13704
|
-
while (lines.length > 0 && lines[lines.length - 1].trim() === "")
|
|
13705
|
-
lines.pop();
|
|
13706
|
-
if (lines.length === 0)
|
|
13707
|
-
return "";
|
|
13708
|
-
return lines.map((line, i) => i === 0 ? `**> ${line}` : `> ${line}`).join(`
|
|
13709
|
-
`);
|
|
13710
|
-
}
|
|
13711
13766
|
function repairProse(text) {
|
|
13712
|
-
|
|
13713
|
-
out = out.replace(DETAILS_BLOCK, (_m, summary, body) => toExpandableBlockquote(summary ?? "", body ?? ""));
|
|
13714
|
-
out = out.replace(ORPHAN_TAGS, "");
|
|
13715
|
-
out = out.replace(CARET_PAIR, (_m, inner) => inner);
|
|
13716
|
-
out = out.replace(FOOTNOTE_MARKER, "");
|
|
13717
|
-
return out;
|
|
13767
|
+
return text.replace(CARET_PAIR, (_m, inner) => inner);
|
|
13718
13768
|
}
|
|
13719
13769
|
function guardUnsupportedTokens(text) {
|
|
13720
|
-
if (
|
|
13770
|
+
if (!text.includes("^"))
|
|
13721
13771
|
return text;
|
|
13722
13772
|
return splitProtectedSegments(text).map((seg) => seg.code ? seg.text : repairProse(seg.text)).join("");
|
|
13723
13773
|
}
|
|
13724
|
-
var CARET_PAIR
|
|
13774
|
+
var CARET_PAIR;
|
|
13725
13775
|
var init_unsupported_token_guard = __esm(() => {
|
|
13776
|
+
init_code_segments();
|
|
13726
13777
|
CARET_PAIR = /\^([A-Za-z0-9]+)\^/g;
|
|
13727
|
-
FOOTNOTE_MARKER = /\[\^[A-Za-z0-9]{1,10}\](?!:)/g;
|
|
13728
|
-
DETAILS_BLOCK = /<details[^>]*>\s*(?:<summary[^>]*>([\s\S]*?)<\/summary>)?([\s\S]*?)<\/details>/gi;
|
|
13729
|
-
ORPHAN_TAGS = /<\/?(?:details|summary)[^>]*>/gi;
|
|
13730
13778
|
});
|
|
13731
13779
|
|
|
13732
13780
|
// rich-send.ts
|
|
@@ -13767,7 +13815,7 @@ var init_rich_send = __esm(() => {
|
|
|
13767
13815
|
import_grammy = __toESM(require_mod2(), 1);
|
|
13768
13816
|
});
|
|
13769
13817
|
|
|
13770
|
-
// ../node_modules/.bun/@grammyjs+runner@2.0.3+
|
|
13818
|
+
// ../node_modules/.bun/@grammyjs+runner@2.0.3+a732625cbf2c154c/node_modules/@grammyjs/runner/out/mod.js
|
|
13771
13819
|
var require_mod4 = __commonJS((exports) => {
|
|
13772
13820
|
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
13773
13821
|
if (k2 === undefined)
|
|
@@ -22355,7 +22403,7 @@ var init_schema = __esm(() => {
|
|
|
22355
22403
|
repos: exports_external.record(exports_external.string().regex(/^[a-z0-9][a-z0-9-]*$/, "Repo slug must be kebab-case ASCII: start with a lowercase letter or digit, contain only lowercase letters, digits, and hyphens"), exports_external.object({
|
|
22356
22404
|
url: exports_external.string().min(1).describe("Git remote URL for the repo (e.g. 'git@github.com:org/repo.git' or " + "'https://github.com/org/repo.git'). Used verbatim for git clone."),
|
|
22357
22405
|
branch_default: exports_external.string().optional().describe("Default branch to track (defaults to the remote's HEAD, typically 'main'). " + "The per-agent branch 'agent/<agentName>/main' fast-forwards to this branch " + "when the worktree is clean on session start.")
|
|
22358
|
-
})).optional().describe("Repos this agent operates on. Switchroom provisions a dedicated
|
|
22406
|
+
})).optional().describe("Repos this agent operates on. Switchroom provisions a dedicated standing tree for " + "each repo at <agentDir>/work/<slug>/ on branch agent/<agentName>/main \u2014 an " + "independent clone (own refs/stash, hardlinked objects) seeded from a shared bare " + "clone at ~/.switchroom/repos/<slug>.git. The tree's path is injected " + "into the agent's environment as SWITCHROOM_REPO_<SLUG_UPPER>. " + "Agents without this field continue to work unchanged."),
|
|
22359
22407
|
experimental: exports_external.object({
|
|
22360
22408
|
legacy_pty: exports_external.boolean().optional().describe("Opt out of the default tmux supervisor (#725) and run the agent " + "under the legacy PTY supervisor instead. Default: false."),
|
|
22361
22409
|
legacy_autoaccept_expect: exports_external.boolean().optional().describe("Opt the autoaccept gateway back into the legacy expect-script " + "behaviour instead of the tmux send-keys path. Default: false.")
|
|
@@ -24113,7 +24161,7 @@ var init_approval_card = __esm(() => {
|
|
|
24113
24161
|
});
|
|
24114
24162
|
|
|
24115
24163
|
// flood-429-ledger.ts
|
|
24116
|
-
import { readFileSync as readFileSync15, writeFileSync as
|
|
24164
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync14, mkdirSync as mkdirSync17, chmodSync as chmodSync4, unlinkSync as unlinkSync10 } from "node:fs";
|
|
24117
24165
|
import { dirname as dirname9, join as join20 } from "node:path";
|
|
24118
24166
|
function flood429LedgerPathFromFloodState(floodStatePath) {
|
|
24119
24167
|
return join20(dirname9(floodStatePath), FLOOD_429_LEDGER_FILE);
|
|
@@ -24217,7 +24265,7 @@ function writeFlood429Ledger(path2, episodes, log = (l) => process.stderr.write(
|
|
|
24217
24265
|
mkdirSync17(dirname9(path2), { recursive: true });
|
|
24218
24266
|
} catch {}
|
|
24219
24267
|
try {
|
|
24220
|
-
|
|
24268
|
+
writeFileSync14(path2, payload, { mode: FLOOD_429_LEDGER_MODE });
|
|
24221
24269
|
try {
|
|
24222
24270
|
chmodSync4(path2, FLOOD_429_LEDGER_MODE);
|
|
24223
24271
|
} catch {}
|
|
@@ -24230,8 +24278,8 @@ function writeFlood429Ledger(path2, episodes, log = (l) => process.stderr.write(
|
|
|
24230
24278
|
return;
|
|
24231
24279
|
}
|
|
24232
24280
|
try {
|
|
24233
|
-
|
|
24234
|
-
|
|
24281
|
+
unlinkSync10(path2);
|
|
24282
|
+
writeFileSync14(path2, payload, { mode: FLOOD_429_LEDGER_MODE });
|
|
24235
24283
|
} catch (err2) {
|
|
24236
24284
|
log(`telegram gateway: 429-ledger: cannot persist the 429 pressure ledger to ${path2} ` + `(${code2}, recreate failed: ${err2?.message ?? String(err2)}). ` + `Flood-pressure history will be missing from \`switchroom doctor\`
|
|
24237
24285
|
`);
|
|
@@ -24253,11 +24301,11 @@ var init_flood_429_ledger = __esm(() => {
|
|
|
24253
24301
|
import {
|
|
24254
24302
|
existsSync as existsSync14,
|
|
24255
24303
|
readFileSync as readFileSync16,
|
|
24256
|
-
writeFileSync as
|
|
24304
|
+
writeFileSync as writeFileSync15,
|
|
24257
24305
|
mkdirSync as mkdirSync18,
|
|
24258
24306
|
chmodSync as chmodSync5,
|
|
24259
|
-
unlinkSync as
|
|
24260
|
-
renameSync as
|
|
24307
|
+
unlinkSync as unlinkSync11,
|
|
24308
|
+
renameSync as renameSync11
|
|
24261
24309
|
} from "node:fs";
|
|
24262
24310
|
import { dirname as dirname10, join as join21 } from "node:path";
|
|
24263
24311
|
function floodStatePath(stateDir) {
|
|
@@ -24313,7 +24361,7 @@ function writeFloodState(path2, state, log = (l) => process.stderr.write(l)) {
|
|
|
24313
24361
|
mkdirSync18(dirname10(path2), { recursive: true });
|
|
24314
24362
|
} catch {}
|
|
24315
24363
|
try {
|
|
24316
|
-
|
|
24364
|
+
writeFileSync15(path2, payload, { mode: FLOOD_STATE_MODE });
|
|
24317
24365
|
try {
|
|
24318
24366
|
chmodSync5(path2, FLOOD_STATE_MODE);
|
|
24319
24367
|
} catch {}
|
|
@@ -24326,8 +24374,8 @@ function writeFloodState(path2, state, log = (l) => process.stderr.write(l)) {
|
|
|
24326
24374
|
return;
|
|
24327
24375
|
}
|
|
24328
24376
|
try {
|
|
24329
|
-
|
|
24330
|
-
|
|
24377
|
+
unlinkSync11(path2);
|
|
24378
|
+
writeFileSync15(path2, payload, { mode: FLOOD_STATE_MODE });
|
|
24331
24379
|
log(`telegram gateway: flood-breaker: recreated ${path2} \u2014 it was owned by another uid ` + `and could not be updated (${code2}); the breaker was blind (issue #3106)
|
|
24332
24380
|
`);
|
|
24333
24381
|
} catch (err2) {
|
|
@@ -30636,7 +30684,7 @@ var init_turn_flush_suppression = () => {};
|
|
|
30636
30684
|
|
|
30637
30685
|
// ../src/agents/generation-stamp.ts
|
|
30638
30686
|
import { createHash as createHash6 } from "node:crypto";
|
|
30639
|
-
import { existsSync as existsSync36, readFileSync as readFileSync35, writeFileSync as
|
|
30687
|
+
import { existsSync as existsSync36, readFileSync as readFileSync35, writeFileSync as writeFileSync31 } from "node:fs";
|
|
30640
30688
|
import { join as join44 } from "node:path";
|
|
30641
30689
|
function sha256Text(s) {
|
|
30642
30690
|
return createHash6("sha256").update(s, "utf-8").digest("hex");
|
|
@@ -36473,7 +36521,7 @@ function renderAuthLine(state7, agentName3, now = Date.now()) {
|
|
|
36473
36521
|
}
|
|
36474
36522
|
|
|
36475
36523
|
// gateway/quota-cache.ts
|
|
36476
|
-
import { existsSync as existsSync49, readFileSync as readFileSync49, writeFileSync as
|
|
36524
|
+
import { existsSync as existsSync49, readFileSync as readFileSync49, writeFileSync as writeFileSync41, mkdirSync as mkdirSync42 } from "fs";
|
|
36477
36525
|
import { join as join59, dirname as dirname25 } from "path";
|
|
36478
36526
|
function defaultCachePath() {
|
|
36479
36527
|
return process.env.SWITCHROOM_QUOTA_CACHE_PATH ?? join59(process.env.HOME ?? "/tmp", ".switchroom", "quota-cache.json");
|
|
@@ -36512,7 +36560,7 @@ function writeQuotaCache(result, opts = {}) {
|
|
|
36512
36560
|
};
|
|
36513
36561
|
try {
|
|
36514
36562
|
mkdirSync42(dirname25(path3), { recursive: true });
|
|
36515
|
-
|
|
36563
|
+
writeFileSync41(path3, JSON.stringify(entry, null, 2), { mode: 384 });
|
|
36516
36564
|
} catch {}
|
|
36517
36565
|
}
|
|
36518
36566
|
var DEFAULT_TTL_MS4, RATE_LIMIT_TTL_MS;
|
|
@@ -37383,7 +37431,7 @@ var init_boot_probes = __esm(() => {
|
|
|
37383
37431
|
});
|
|
37384
37432
|
|
|
37385
37433
|
// gateway/boot-issue-cache.ts
|
|
37386
|
-
import { existsSync as existsSync51, readFileSync as readFileSync51, writeFileSync as
|
|
37434
|
+
import { existsSync as existsSync51, readFileSync as readFileSync51, writeFileSync as writeFileSync42, mkdirSync as mkdirSync43, renameSync as renameSync25 } from "fs";
|
|
37387
37435
|
import { dirname as dirname26 } from "path";
|
|
37388
37436
|
function fingerprintProbe(key, r) {
|
|
37389
37437
|
if (r.status === "ok")
|
|
@@ -37476,7 +37524,7 @@ function loadCache(path3, now = Date.now) {
|
|
|
37476
37524
|
parsed = JSON.parse(raw);
|
|
37477
37525
|
} catch {
|
|
37478
37526
|
try {
|
|
37479
|
-
|
|
37527
|
+
renameSync25(path3, `${path3}.corrupt-${now()}`);
|
|
37480
37528
|
} catch {}
|
|
37481
37529
|
return { ...EMPTY_CACHE, probes: {} };
|
|
37482
37530
|
}
|
|
@@ -37512,8 +37560,8 @@ function applyAndSave(path3, cache, diff) {
|
|
|
37512
37560
|
try {
|
|
37513
37561
|
mkdirSync43(dirname26(path3), { recursive: true });
|
|
37514
37562
|
const tmp = `${path3}.tmp`;
|
|
37515
|
-
|
|
37516
|
-
|
|
37563
|
+
writeFileSync42(tmp, JSON.stringify(next), { mode: 384 });
|
|
37564
|
+
renameSync25(tmp, path3);
|
|
37517
37565
|
} catch {}
|
|
37518
37566
|
return next;
|
|
37519
37567
|
}
|
|
@@ -37526,7 +37574,7 @@ var init_boot_issue_cache = __esm(() => {
|
|
|
37526
37574
|
|
|
37527
37575
|
// gateway/config-snapshot.ts
|
|
37528
37576
|
import { createHash as createHash7 } from "crypto";
|
|
37529
|
-
import { existsSync as existsSync52, readFileSync as readFileSync52, writeFileSync as
|
|
37577
|
+
import { existsSync as existsSync52, readFileSync as readFileSync52, writeFileSync as writeFileSync43, mkdirSync as mkdirSync44, renameSync as renameSync26 } from "fs";
|
|
37530
37578
|
import { dirname as dirname27 } from "path";
|
|
37531
37579
|
function hashStringArray(items) {
|
|
37532
37580
|
if (!items || items.length === 0)
|
|
@@ -37604,7 +37652,7 @@ function loadSnapshot(path3, now = Date.now) {
|
|
|
37604
37652
|
parsed = JSON.parse(raw);
|
|
37605
37653
|
} catch {
|
|
37606
37654
|
try {
|
|
37607
|
-
|
|
37655
|
+
renameSync26(path3, `${path3}.corrupt-${now()}`);
|
|
37608
37656
|
} catch {}
|
|
37609
37657
|
return null;
|
|
37610
37658
|
}
|
|
@@ -37627,8 +37675,8 @@ function persistSnapshot(path3, snapshot) {
|
|
|
37627
37675
|
try {
|
|
37628
37676
|
mkdirSync44(dirname27(path3), { recursive: true });
|
|
37629
37677
|
const tmp = `${path3}.tmp`;
|
|
37630
|
-
|
|
37631
|
-
|
|
37678
|
+
writeFileSync43(tmp, JSON.stringify(snapshot), { mode: 384 });
|
|
37679
|
+
renameSync26(tmp, path3);
|
|
37632
37680
|
} catch {}
|
|
37633
37681
|
}
|
|
37634
37682
|
var init_config_snapshot = __esm(() => {
|
|
@@ -37636,7 +37684,7 @@ var init_config_snapshot = __esm(() => {
|
|
|
37636
37684
|
});
|
|
37637
37685
|
|
|
37638
37686
|
// gateway/boot-card-msgid.ts
|
|
37639
|
-
import { readFileSync as readFileSync53, writeFileSync as
|
|
37687
|
+
import { readFileSync as readFileSync53, writeFileSync as writeFileSync44 } from "node:fs";
|
|
37640
37688
|
function bootCardChatKey(chatId, threadId) {
|
|
37641
37689
|
return `${chatId}:${threadId ?? ""}`;
|
|
37642
37690
|
}
|
|
@@ -37661,7 +37709,7 @@ function saveBootCardMsgId(path3, chatKey3, messageId) {
|
|
|
37661
37709
|
if (store3[chatKey3] === messageId)
|
|
37662
37710
|
return;
|
|
37663
37711
|
store3[chatKey3] = messageId;
|
|
37664
|
-
|
|
37712
|
+
writeFileSync44(path3, JSON.stringify(store3), "utf8");
|
|
37665
37713
|
} catch {}
|
|
37666
37714
|
}
|
|
37667
37715
|
var init_boot_card_msgid = () => {};
|
|
@@ -38695,7 +38743,7 @@ __export(exports_tmux2, {
|
|
|
38695
38743
|
captureAgentPane: () => captureAgentPane2
|
|
38696
38744
|
});
|
|
38697
38745
|
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
38698
|
-
import { chmodSync as chmodSync13, mkdirSync as mkdirSync49, readdirSync as
|
|
38746
|
+
import { chmodSync as chmodSync13, mkdirSync as mkdirSync49, readdirSync as readdirSync18, statSync as statSync24, unlinkSync as unlinkSync32, writeFileSync as writeFileSync54 } from "node:fs";
|
|
38699
38747
|
import { resolve as resolve12 } from "node:path";
|
|
38700
38748
|
function captureAgentPane2(opts) {
|
|
38701
38749
|
const { agentName: agentName3, agentDir, reason } = opts;
|
|
@@ -38746,7 +38794,7 @@ function captureAgentPane2(opts) {
|
|
|
38746
38794
|
` + `
|
|
38747
38795
|
`;
|
|
38748
38796
|
try {
|
|
38749
|
-
|
|
38797
|
+
writeFileSync54(outPath, Buffer.concat([Buffer.from(header, "utf8"), body]), {
|
|
38750
38798
|
mode: 384
|
|
38751
38799
|
});
|
|
38752
38800
|
} catch (err) {
|
|
@@ -38816,7 +38864,7 @@ function sleepSync3(ms) {
|
|
|
38816
38864
|
function pruneOldReports2(dir, retain) {
|
|
38817
38865
|
let entries;
|
|
38818
38866
|
try {
|
|
38819
|
-
entries =
|
|
38867
|
+
entries = readdirSync18(dir);
|
|
38820
38868
|
} catch {
|
|
38821
38869
|
return;
|
|
38822
38870
|
}
|
|
@@ -38830,7 +38878,7 @@ function pruneOldReports2(dir, retain) {
|
|
|
38830
38878
|
}).sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
38831
38879
|
for (const stale of files.slice(retain)) {
|
|
38832
38880
|
try {
|
|
38833
|
-
|
|
38881
|
+
unlinkSync32(stale.full);
|
|
38834
38882
|
} catch {}
|
|
38835
38883
|
}
|
|
38836
38884
|
}
|
|
@@ -39640,7 +39688,7 @@ __export(exports_materialize_bot_token, {
|
|
|
39640
39688
|
materializeBotToken: () => materializeBotToken,
|
|
39641
39689
|
BotTokenMaterializeError: () => BotTokenMaterializeError
|
|
39642
39690
|
});
|
|
39643
|
-
import { existsSync as
|
|
39691
|
+
import { existsSync as existsSync64 } from "node:fs";
|
|
39644
39692
|
function pickConfiguredToken(config, agentName3) {
|
|
39645
39693
|
if (agentName3) {
|
|
39646
39694
|
const agent = config.agents?.[agentName3];
|
|
@@ -39654,7 +39702,7 @@ function tryDirectVaultRead4(ref, config, passphrase) {
|
|
|
39654
39702
|
if (!passphrase)
|
|
39655
39703
|
return null;
|
|
39656
39704
|
const vaultPath = resolvePath(config.vault?.path ?? "~/.switchroom/vault.enc");
|
|
39657
|
-
if (!
|
|
39705
|
+
if (!existsSync64(vaultPath))
|
|
39658
39706
|
return null;
|
|
39659
39707
|
try {
|
|
39660
39708
|
const secrets = openVault(passphrase, vaultPath);
|
|
@@ -39809,19 +39857,19 @@ var import_runner3 = __toESM(require_mod3(), 1);
|
|
|
39809
39857
|
import { randomBytes as randomBytes12, createHash as createHash8 } from "crypto";
|
|
39810
39858
|
import { execFileSync as execFileSync9, execSync as execSync2, spawn as spawn2 } from "child_process";
|
|
39811
39859
|
import {
|
|
39812
|
-
readFileSync as
|
|
39813
|
-
writeFileSync as
|
|
39860
|
+
readFileSync as readFileSync67,
|
|
39861
|
+
writeFileSync as writeFileSync55,
|
|
39814
39862
|
mkdirSync as mkdirSync50,
|
|
39815
|
-
readdirSync as
|
|
39863
|
+
readdirSync as readdirSync19,
|
|
39816
39864
|
rmSync as rmSync9,
|
|
39817
39865
|
statSync as statSync25,
|
|
39818
|
-
renameSync as
|
|
39866
|
+
renameSync as renameSync32,
|
|
39819
39867
|
realpathSync as realpathSync6,
|
|
39820
39868
|
chmodSync as chmodSync14,
|
|
39821
39869
|
openSync as openSync18,
|
|
39822
39870
|
closeSync as closeSync18,
|
|
39823
|
-
existsSync as
|
|
39824
|
-
unlinkSync as
|
|
39871
|
+
existsSync as existsSync65,
|
|
39872
|
+
unlinkSync as unlinkSync33,
|
|
39825
39873
|
appendFileSync as appendFileSync11
|
|
39826
39874
|
} from "fs";
|
|
39827
39875
|
|
|
@@ -39839,7 +39887,7 @@ function fsyncPathSync(path) {
|
|
|
39839
39887
|
|
|
39840
39888
|
// gateway/gateway.ts
|
|
39841
39889
|
import { homedir as homedir22 } from "os";
|
|
39842
|
-
import { join as
|
|
39890
|
+
import { join as join77, sep as sep6, basename as basename19 } from "path";
|
|
39843
39891
|
|
|
39844
39892
|
// plugin-logger.ts
|
|
39845
39893
|
import { appendFileSync, mkdirSync, renameSync as renameSync2, statSync, existsSync } from "fs";
|
|
@@ -50974,7 +51022,7 @@ function createSweepableCardStore(deps) {
|
|
|
50974
51022
|
init_rich_send();
|
|
50975
51023
|
var import_grammy4 = __toESM(require_mod2(), 1);
|
|
50976
51024
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
50977
|
-
import { mkdirSync as mkdirSync15, writeFileSync as
|
|
51025
|
+
import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync11 } from "fs";
|
|
50978
51026
|
import { dirname as dirname7 } from "path";
|
|
50979
51027
|
init_client2();
|
|
50980
51028
|
|
|
@@ -51754,11 +51802,15 @@ import {
|
|
|
51754
51802
|
mkdirSync as mkdirSync14,
|
|
51755
51803
|
openSync as openSync8,
|
|
51756
51804
|
readFileSync as readFileSync13,
|
|
51805
|
+
renameSync as renameSync10,
|
|
51806
|
+
unlinkSync as unlinkSync6,
|
|
51807
|
+
writeFileSync as writeFileSync10,
|
|
51757
51808
|
writeSync as writeSync7
|
|
51758
51809
|
} from "node:fs";
|
|
51759
51810
|
import { join as join15 } from "node:path";
|
|
51760
51811
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
51761
51812
|
var EVAL_CASE_PROPOSALS_FILE = "eval-case-proposals.jsonl";
|
|
51813
|
+
var MAX_EVAL_CASE_PROPOSALS = 200;
|
|
51762
51814
|
function proposalsPath2(stateDir) {
|
|
51763
51815
|
return join15(stateDir, EVAL_CASE_PROPOSALS_FILE);
|
|
51764
51816
|
}
|
|
@@ -51801,6 +51853,49 @@ function readEvalCaseProposals(stateDir) {
|
|
|
51801
51853
|
}
|
|
51802
51854
|
return [...byId.values()];
|
|
51803
51855
|
}
|
|
51856
|
+
function withinBound(all, now) {
|
|
51857
|
+
const isLiveRejection = (r) => {
|
|
51858
|
+
if (r.status !== "rejected")
|
|
51859
|
+
return false;
|
|
51860
|
+
const age = now - new Date(r.created_at).getTime();
|
|
51861
|
+
return !Number.isFinite(age) || age <= REJECTION_TTL_MS;
|
|
51862
|
+
};
|
|
51863
|
+
const keepTail = (rows) => rows.length > MAX_EVAL_CASE_PROPOSALS ? rows.slice(rows.length - MAX_EVAL_CASE_PROPOSALS) : rows;
|
|
51864
|
+
const keep = new Set([
|
|
51865
|
+
...keepTail(all.filter(isLiveRejection)).map((r) => r.id),
|
|
51866
|
+
...keepTail(all.filter((r) => !isLiveRejection(r))).map((r) => r.id)
|
|
51867
|
+
]);
|
|
51868
|
+
return all.filter((r) => keep.has(r.id));
|
|
51869
|
+
}
|
|
51870
|
+
function compactIfOversized(stateDir, now) {
|
|
51871
|
+
const path = proposalsPath2(stateDir);
|
|
51872
|
+
let raw;
|
|
51873
|
+
try {
|
|
51874
|
+
raw = readFileSync13(path, "utf-8");
|
|
51875
|
+
} catch {
|
|
51876
|
+
return;
|
|
51877
|
+
}
|
|
51878
|
+
const lines = raw.split(`
|
|
51879
|
+
`).filter((l) => l.trim().length > 0);
|
|
51880
|
+
if (lines.length <= MAX_EVAL_CASE_PROPOSALS * 2)
|
|
51881
|
+
return;
|
|
51882
|
+
const kept = withinBound(readEvalCaseProposals(stateDir), now);
|
|
51883
|
+
if (kept.length >= lines.length)
|
|
51884
|
+
return;
|
|
51885
|
+
const tmp = `${path}.tmp.${process.pid}`;
|
|
51886
|
+
try {
|
|
51887
|
+
writeFileSync10(tmp, kept.map((r) => JSON.stringify(r) + `
|
|
51888
|
+
`).join(""), {
|
|
51889
|
+
encoding: "utf-8",
|
|
51890
|
+
mode: 420
|
|
51891
|
+
});
|
|
51892
|
+
renameSync10(tmp, path);
|
|
51893
|
+
} catch {
|
|
51894
|
+
try {
|
|
51895
|
+
unlinkSync6(tmp);
|
|
51896
|
+
} catch {}
|
|
51897
|
+
}
|
|
51898
|
+
}
|
|
51804
51899
|
function getEvalCaseProposal(stateDir, id) {
|
|
51805
51900
|
return readEvalCaseProposals(stateDir).find((p) => p.id === id);
|
|
51806
51901
|
}
|
|
@@ -51814,6 +51909,7 @@ function enqueueEvalCaseProposal(stateDir, input, opts = {}) {
|
|
|
51814
51909
|
...input
|
|
51815
51910
|
};
|
|
51816
51911
|
appendLine2(proposalsPath2(stateDir), proposal);
|
|
51912
|
+
compactIfOversized(stateDir, now());
|
|
51817
51913
|
return proposal;
|
|
51818
51914
|
}
|
|
51819
51915
|
function setEvalCaseProposalStatus(stateDir, id, status) {
|
|
@@ -51822,8 +51918,94 @@ function setEvalCaseProposalStatus(stateDir, id, status) {
|
|
|
51822
51918
|
return;
|
|
51823
51919
|
const next = { ...cur, status };
|
|
51824
51920
|
appendLine2(proposalsPath2(stateDir), next);
|
|
51921
|
+
compactIfOversized(stateDir, Date.now());
|
|
51825
51922
|
return next;
|
|
51826
51923
|
}
|
|
51924
|
+
|
|
51925
|
+
// gateway/eval-case-proposal-inbound-builders.ts
|
|
51926
|
+
function commonMeta(opts) {
|
|
51927
|
+
return {
|
|
51928
|
+
agent: opts.ctx.agent,
|
|
51929
|
+
...opts.ctx.threadId != null ? { message_thread_id: String(opts.ctx.threadId) } : {},
|
|
51930
|
+
proposal_id: opts.proposalId,
|
|
51931
|
+
skill_slug: opts.skillSlug,
|
|
51932
|
+
held_out: String(opts.heldOut),
|
|
51933
|
+
operator_id: opts.operatorId
|
|
51934
|
+
};
|
|
51935
|
+
}
|
|
51936
|
+
function buildEvalCaseAppliedInbound(opts) {
|
|
51937
|
+
const ts = opts.nowMs ?? Date.now();
|
|
51938
|
+
const sink2 = opts.heldOut ? "the held-out sink" : `\`${opts.skillSlug}\`'s \`evals.json\``;
|
|
51939
|
+
return {
|
|
51940
|
+
type: "inbound",
|
|
51941
|
+
chatId: opts.ctx.chat_id,
|
|
51942
|
+
...opts.ctx.threadId != null ? { threadId: opts.ctx.threadId } : {},
|
|
51943
|
+
messageId: ts,
|
|
51944
|
+
user: "self-improve",
|
|
51945
|
+
userId: 0,
|
|
51946
|
+
ts,
|
|
51947
|
+
text: `\u2705 Operator approved your proposed eval case for \`${opts.skillSlug}\` ` + `(proposal ${opts.proposalId}). The case was applied DETERMINISTICALLY by ` + `the gateway and is already written to ${sink2} \u2014 do NOT write it yourself ` + `and do NOT re-propose it. Resume whatever you were doing.`,
|
|
51948
|
+
meta: {
|
|
51949
|
+
source: "eval_case_applied",
|
|
51950
|
+
...commonMeta({
|
|
51951
|
+
ctx: opts.ctx,
|
|
51952
|
+
proposalId: opts.proposalId,
|
|
51953
|
+
skillSlug: opts.skillSlug,
|
|
51954
|
+
heldOut: opts.heldOut,
|
|
51955
|
+
operatorId: opts.operatorId
|
|
51956
|
+
})
|
|
51957
|
+
}
|
|
51958
|
+
};
|
|
51959
|
+
}
|
|
51960
|
+
function buildEvalCaseRejectedInbound(opts) {
|
|
51961
|
+
const ts = opts.nowMs ?? Date.now();
|
|
51962
|
+
return {
|
|
51963
|
+
type: "inbound",
|
|
51964
|
+
chatId: opts.ctx.chat_id,
|
|
51965
|
+
...opts.ctx.threadId != null ? { threadId: opts.ctx.threadId } : {},
|
|
51966
|
+
messageId: ts,
|
|
51967
|
+
user: "self-improve",
|
|
51968
|
+
userId: 0,
|
|
51969
|
+
ts,
|
|
51970
|
+
text: `\uD83D\uDEAB Operator dismissed your proposed eval case for \`${opts.skillSlug}\` ` + `(proposal ${opts.proposalId}). NOTHING was written \u2014 no eval case was ` + `added. Carry on with the original task without it. Do NOT re-propose the ` + `same case without first asking the user.`,
|
|
51971
|
+
meta: {
|
|
51972
|
+
source: "eval_case_rejected",
|
|
51973
|
+
...commonMeta({
|
|
51974
|
+
ctx: opts.ctx,
|
|
51975
|
+
proposalId: opts.proposalId,
|
|
51976
|
+
skillSlug: opts.skillSlug,
|
|
51977
|
+
heldOut: opts.heldOut,
|
|
51978
|
+
operatorId: opts.operatorId
|
|
51979
|
+
})
|
|
51980
|
+
}
|
|
51981
|
+
};
|
|
51982
|
+
}
|
|
51983
|
+
function buildEvalCaseApplyFailedInbound(opts) {
|
|
51984
|
+
const ts = opts.nowMs ?? Date.now();
|
|
51985
|
+
const tail = opts.applyOut.trim().slice(0, 500);
|
|
51986
|
+
return {
|
|
51987
|
+
type: "inbound",
|
|
51988
|
+
chatId: opts.ctx.chat_id,
|
|
51989
|
+
...opts.ctx.threadId != null ? { threadId: opts.ctx.threadId } : {},
|
|
51990
|
+
messageId: ts,
|
|
51991
|
+
user: "self-improve",
|
|
51992
|
+
userId: 0,
|
|
51993
|
+
ts,
|
|
51994
|
+
text: `\u26a0\ufe0f The operator approved your proposed eval case for \`${opts.skillSlug}\` ` + `(proposal ${opts.proposalId}) but the applier FAILED. The case was NOT ` + `written \u2014 do NOT assume the regression test exists. Applier output:
|
|
51995
|
+
` + `${tail.length > 0 ? tail : "(no output)"}
|
|
51996
|
+
` + `Carry on with the original task; report the failure to the operator if it ` + `still matters.`,
|
|
51997
|
+
meta: {
|
|
51998
|
+
source: "eval_case_apply_failed",
|
|
51999
|
+
...commonMeta({
|
|
52000
|
+
ctx: opts.ctx,
|
|
52001
|
+
proposalId: opts.proposalId,
|
|
52002
|
+
skillSlug: opts.skillSlug,
|
|
52003
|
+
heldOut: opts.heldOut,
|
|
52004
|
+
operatorId: opts.operatorId
|
|
52005
|
+
})
|
|
52006
|
+
}
|
|
52007
|
+
};
|
|
52008
|
+
}
|
|
51827
52009
|
// gateway/callback-query-handlers.ts
|
|
51828
52010
|
init_auth_snapshot_format();
|
|
51829
52011
|
|
|
@@ -52003,13 +52185,14 @@ var AgentSmokeRequestSchema = exports_external.object({
|
|
|
52003
52185
|
deep: exports_external.boolean().optional()
|
|
52004
52186
|
})
|
|
52005
52187
|
});
|
|
52188
|
+
var CANONICAL_CONFIG_PATH = "/state/config/switchroom.yaml";
|
|
52006
52189
|
var ConfigProposeEditRequestSchema = exports_external.object({
|
|
52007
52190
|
...RequestEnvelope,
|
|
52008
52191
|
op: exports_external.literal("config_propose_edit"),
|
|
52009
52192
|
args: exports_external.object({
|
|
52010
52193
|
unified_diff: exports_external.string().min(1).max(MAX_FRAME_BYTES3 - 1024),
|
|
52011
52194
|
reason: exports_external.string().min(1).max(500),
|
|
52012
|
-
target_path: exports_external.literal(
|
|
52195
|
+
target_path: exports_external.literal(CANONICAL_CONFIG_PATH)
|
|
52013
52196
|
})
|
|
52014
52197
|
});
|
|
52015
52198
|
var RequestSchema3 = exports_external.discriminatedUnion("op", [
|
|
@@ -52335,6 +52518,20 @@ function createCallbackQueryHandlers(deps) {
|
|
|
52335
52518
|
const listViaBroker2 = deps.brokerList ?? listViaBroker;
|
|
52336
52519
|
const listGrantsViaBroker2 = deps.brokerListGrants ?? listGrantsViaBroker;
|
|
52337
52520
|
const vaultTokenFilePath2 = deps.brokerVaultTokenFilePath ?? vaultTokenFilePath;
|
|
52521
|
+
const runEvalCaseApply = deps.runEvalCaseApply ?? ((id) => {
|
|
52522
|
+
const cli = process.env.SWITCHROOM_CLI_PATH ?? "switchroom";
|
|
52523
|
+
try {
|
|
52524
|
+
const out = execFileSync3(cli, ["self-improve", "apply-eval-case", "--id", id], { encoding: "utf8", timeout: 15000, env: process.env }).trim();
|
|
52525
|
+
return { ok: true, out };
|
|
52526
|
+
} catch (err) {
|
|
52527
|
+
const e = err;
|
|
52528
|
+
return {
|
|
52529
|
+
ok: false,
|
|
52530
|
+
out: [e.stdout, e.stderr, e.message].filter(Boolean).join(`
|
|
52531
|
+
`).trim()
|
|
52532
|
+
};
|
|
52533
|
+
}
|
|
52534
|
+
});
|
|
52338
52535
|
async function handleVaultRecentDenialCallback(ctx, data) {
|
|
52339
52536
|
const senderId = String(ctx.from?.id ?? "");
|
|
52340
52537
|
const access = loadAccess();
|
|
@@ -52375,7 +52572,7 @@ function createCallbackQueryHandlers(deps) {
|
|
|
52375
52572
|
const tokenPath = vaultTokenFilePath2(agentName);
|
|
52376
52573
|
try {
|
|
52377
52574
|
mkdirSync15(dirname7(tokenPath), { recursive: true });
|
|
52378
|
-
|
|
52575
|
+
writeFileSync11(tokenPath, token, { mode: 384 });
|
|
52379
52576
|
} catch (err) {
|
|
52380
52577
|
await switchroomReply(ctx, `**Grant created (${escapeHtmlForTg2(id)}) but token write failed:** ` + `${escapeHtmlForTg2(String(err))}
|
|
52381
52578
|
` + `_Recover with: \`switchroom vault grant ${escapeHtmlForTg2(agentName)} ` + `--keys ${escapeHtmlForTg2(keyName)} --duration 30d\` on the host._`, { html: true });
|
|
@@ -52527,7 +52724,7 @@ function createCallbackQueryHandlers(deps) {
|
|
|
52527
52724
|
const tokenPath = vaultTokenFilePath2(pending.agent);
|
|
52528
52725
|
try {
|
|
52529
52726
|
mkdirSync15(dirname7(tokenPath), { recursive: true });
|
|
52530
|
-
|
|
52727
|
+
writeFileSync11(tokenPath, token, { mode: 384 });
|
|
52531
52728
|
} catch (err) {
|
|
52532
52729
|
await switchroomReply(ctx, `**Grant created (${escapeHtmlForTg2(id)}) but token write failed:** ` + `${escapeHtmlForTg2(String(err))}
|
|
52533
52730
|
` + `_Recover with: \`switchroom vault grant ${escapeHtmlForTg2(pending.agent)} ` + `--keys ${escapeHtmlForTg2(pending.key)} --duration ${Math.round(pending.ttl_seconds / 86400)}d\` on the host._`, { html: true });
|
|
@@ -52668,36 +52865,57 @@ _Approver verified by Telegram identity \u2014 broker auto-unlocked at startup._
|
|
|
52668
52865
|
}
|
|
52669
52866
|
return;
|
|
52670
52867
|
}
|
|
52868
|
+
const cbChatId = String(ctx.chat?.id ?? ctx.from?.id ?? "");
|
|
52869
|
+
const cbThreadId = resolveThreadId(cbChatId, ctx.callbackQuery?.message?.message_thread_id);
|
|
52870
|
+
const inboundCtx = {
|
|
52871
|
+
agent,
|
|
52872
|
+
chat_id: cbChatId,
|
|
52873
|
+
...cbThreadId != null ? { threadId: cbThreadId } : {}
|
|
52874
|
+
};
|
|
52671
52875
|
if (parsed.action === "deny") {
|
|
52672
52876
|
setEvalCaseProposalStatus(stateDir, parsed.id, "rejected");
|
|
52877
|
+
const denied = deliverResumeSyntheticOrBuffer(agent, buildEvalCaseRejectedInbound({
|
|
52878
|
+
ctx: inboundCtx,
|
|
52879
|
+
proposalId: proposal.id,
|
|
52880
|
+
skillSlug: proposal.skill_slug,
|
|
52881
|
+
heldOut: proposal.held_out,
|
|
52882
|
+
operatorId: senderId
|
|
52883
|
+
}));
|
|
52673
52884
|
await ctx.answerCallbackQuery({ text: "\uD83D\uDEAB Dismissed." }).catch(() => {});
|
|
52674
52885
|
if (ctx.callbackQuery?.message && "text" in ctx.callbackQuery.message) {
|
|
52675
52886
|
await ctx.editMessageText(`${escapeHtmlForTg2(ctx.callbackQuery.message.text ?? "")}
|
|
52676
52887
|
|
|
52677
52888
|
\uD83D\uDEAB <i>Dismissed.</i>`, { parse_mode: "HTML", reply_markup: { inline_keyboard: [] } }).catch(() => {});
|
|
52678
52889
|
}
|
|
52890
|
+
process.stderr.write(`telegram gateway: eval_case_rejected agent=${agent} proposal=${proposal.id} ` + `slug=${proposal.skill_slug} delivered=${denied}
|
|
52891
|
+
`);
|
|
52679
52892
|
return;
|
|
52680
52893
|
}
|
|
52681
52894
|
setEvalCaseProposalStatus(stateDir, parsed.id, "approved");
|
|
52682
52895
|
await ctx.answerCallbackQuery({ text: "\u2705 Adding the eval case\u2026" }).catch(() => {});
|
|
52683
|
-
const
|
|
52684
|
-
let applyOk = true;
|
|
52685
|
-
let applyOut = "";
|
|
52686
|
-
try {
|
|
52687
|
-
applyOut = execFileSync3(cli, ["self-improve", "apply-eval-case", "--id", parsed.id], { encoding: "utf8", timeout: 15000, env: process.env }).trim();
|
|
52688
|
-
} catch (err) {
|
|
52689
|
-
applyOk = false;
|
|
52690
|
-
const e = err;
|
|
52691
|
-
applyOut = [e.stdout, e.stderr, e.message].filter(Boolean).join(`
|
|
52692
|
-
`).trim();
|
|
52693
|
-
}
|
|
52896
|
+
const { ok: applyOk, out: applyOut } = runEvalCaseApply(parsed.id);
|
|
52694
52897
|
const footer = applyOk ? "\u2705 <i>Added as a regression test.</i>" : `\u26a0\ufe0f <i>Apply failed:</i> ${escapeHtmlForTg2(applyOut.slice(0, 200))}`;
|
|
52695
52898
|
if (ctx.callbackQuery?.message && "text" in ctx.callbackQuery.message) {
|
|
52696
52899
|
await ctx.editMessageText(`${escapeHtmlForTg2(ctx.callbackQuery.message.text ?? "")}
|
|
52697
52900
|
|
|
52698
52901
|
${footer}`, { parse_mode: "HTML", reply_markup: { inline_keyboard: [] } }).catch(() => {});
|
|
52699
52902
|
}
|
|
52700
|
-
|
|
52903
|
+
const outcomeInbound = applyOk ? buildEvalCaseAppliedInbound({
|
|
52904
|
+
ctx: inboundCtx,
|
|
52905
|
+
proposalId: proposal.id,
|
|
52906
|
+
skillSlug: proposal.skill_slug,
|
|
52907
|
+
heldOut: proposal.held_out,
|
|
52908
|
+
operatorId: senderId
|
|
52909
|
+
}) : buildEvalCaseApplyFailedInbound({
|
|
52910
|
+
ctx: inboundCtx,
|
|
52911
|
+
proposalId: proposal.id,
|
|
52912
|
+
skillSlug: proposal.skill_slug,
|
|
52913
|
+
heldOut: proposal.held_out,
|
|
52914
|
+
operatorId: senderId,
|
|
52915
|
+
applyOut
|
|
52916
|
+
});
|
|
52917
|
+
const delivered = deliverResumeSyntheticOrBuffer(agent, outcomeInbound);
|
|
52918
|
+
process.stderr.write(`telegram gateway: eval_case_apply agent=${agent} proposal=${proposal.id} ` + `slug=${proposal.skill_slug} ok=${applyOk} delivered=${delivered}
|
|
52701
52919
|
`);
|
|
52702
52920
|
}
|
|
52703
52921
|
async function handleMentalModelProposeCallback(ctx, data) {
|
|
@@ -53421,7 +53639,7 @@ ${keyList}`,
|
|
|
53421
53639
|
const tokenPath = vaultTokenFilePath2(state.agent);
|
|
53422
53640
|
try {
|
|
53423
53641
|
mkdirSync15(dirname7(tokenPath), { recursive: true });
|
|
53424
|
-
|
|
53642
|
+
writeFileSync11(tokenPath, token, { mode: 384 });
|
|
53425
53643
|
} catch (err) {
|
|
53426
53644
|
await switchroomReply(ctx, `**Grant created but token write failed:** ${escapeHtmlForTg2(String(err))}`, { html: true });
|
|
53427
53645
|
return;
|
|
@@ -54480,7 +54698,7 @@ function hangStalenessMs(env = process.env) {
|
|
|
54480
54698
|
|
|
54481
54699
|
// gateway/missed-approvals-store.ts
|
|
54482
54700
|
init_state_owner();
|
|
54483
|
-
import { unlinkSync as
|
|
54701
|
+
import { unlinkSync as unlinkSync7 } from "node:fs";
|
|
54484
54702
|
import { join as join17 } from "node:path";
|
|
54485
54703
|
var MAX_PENDING = 50;
|
|
54486
54704
|
var MAX_DELIVERED = 20;
|
|
@@ -54565,7 +54783,7 @@ function createMissedApprovalsStore(stateDir, log = (l) => process.stderr.write(
|
|
|
54565
54783
|
},
|
|
54566
54784
|
clear() {
|
|
54567
54785
|
try {
|
|
54568
|
-
|
|
54786
|
+
unlinkSync7(filePath);
|
|
54569
54787
|
} catch {}
|
|
54570
54788
|
}
|
|
54571
54789
|
};
|
|
@@ -54573,7 +54791,7 @@ function createMissedApprovalsStore(stateDir, log = (l) => process.stderr.write(
|
|
|
54573
54791
|
|
|
54574
54792
|
// gateway/always-allow-persist-queue.ts
|
|
54575
54793
|
init_state_owner();
|
|
54576
|
-
import { unlinkSync as
|
|
54794
|
+
import { unlinkSync as unlinkSync8 } from "node:fs";
|
|
54577
54795
|
import { join as join18 } from "node:path";
|
|
54578
54796
|
var MAX_ATTEMPTS = 5;
|
|
54579
54797
|
var MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
@@ -54710,7 +54928,7 @@ function createAlwaysAllowPersistQueue(stateDir, writeFileSyncFn = atomicWriteSe
|
|
|
54710
54928
|
},
|
|
54711
54929
|
clear() {
|
|
54712
54930
|
try {
|
|
54713
|
-
|
|
54931
|
+
unlinkSync8(filePath);
|
|
54714
54932
|
} catch {}
|
|
54715
54933
|
}
|
|
54716
54934
|
};
|
|
@@ -54873,7 +55091,7 @@ function pickRecoveredPermissionOrigin(recentTurns, now, maxAgeMs) {
|
|
|
54873
55091
|
}
|
|
54874
55092
|
|
|
54875
55093
|
// gateway/approval-hold.ts
|
|
54876
|
-
import { mkdirSync as mkdirSync16, writeFileSync as
|
|
55094
|
+
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync13, readFileSync as readFileSync14, unlinkSync as unlinkSync9, chmodSync as chmodSync3, lstatSync as lstatSync2 } from "node:fs";
|
|
54877
55095
|
import { join as join19, dirname as dirname8 } from "node:path";
|
|
54878
55096
|
var BLOCKED_APPROVAL_FILE_MODE = 420;
|
|
54879
55097
|
var BLOCKED_APPROVAL_DIR_MODE = 1023;
|
|
@@ -54902,7 +55120,8 @@ var ACTION_SAFE_WITH_INPUT2 = new Set([
|
|
|
54902
55120
|
function safeActionForRecord(naturalAction2, toolName, inputPreview) {
|
|
54903
55121
|
return ACTION_SAFE_WITH_INPUT2.has(toolName) ? naturalAction2(toolName, inputPreview) : naturalAction2(toolName, undefined);
|
|
54904
55122
|
}
|
|
54905
|
-
function createBlockedApprovalStore(dir, agent, fallbackDir) {
|
|
55123
|
+
function createBlockedApprovalStore(dir, agent, fallbackDir, deps = {}) {
|
|
55124
|
+
const write_ = deps.writeFileSync ?? writeFileSync13;
|
|
54906
55125
|
const primary = join19(dir, `${agent}.json`);
|
|
54907
55126
|
const fallback = fallbackDir != null ? join19(fallbackDir, "blocked-approval.json") : null;
|
|
54908
55127
|
let active = primary;
|
|
@@ -54919,7 +55138,7 @@ function createBlockedApprovalStore(dir, agent, fallbackDir) {
|
|
|
54919
55138
|
chmodSync3(parent, dirMode);
|
|
54920
55139
|
} catch {}
|
|
54921
55140
|
}
|
|
54922
|
-
|
|
55141
|
+
write_(target, body, { encoding: "utf-8", mode: BLOCKED_APPROVAL_FILE_MODE });
|
|
54923
55142
|
chmodSync3(target, BLOCKED_APPROVAL_FILE_MODE);
|
|
54924
55143
|
return true;
|
|
54925
55144
|
} catch {
|
|
@@ -54937,7 +55156,7 @@ function createBlockedApprovalStore(dir, agent, fallbackDir) {
|
|
|
54937
55156
|
active = primary;
|
|
54938
55157
|
if (fallback != null) {
|
|
54939
55158
|
try {
|
|
54940
|
-
|
|
55159
|
+
unlinkSync9(fallback);
|
|
54941
55160
|
} catch {}
|
|
54942
55161
|
}
|
|
54943
55162
|
return;
|
|
@@ -54956,7 +55175,7 @@ function createBlockedApprovalStore(dir, agent, fallbackDir) {
|
|
|
54956
55175
|
if (p == null)
|
|
54957
55176
|
continue;
|
|
54958
55177
|
try {
|
|
54959
|
-
|
|
55178
|
+
unlinkSync9(p);
|
|
54960
55179
|
} catch {}
|
|
54961
55180
|
}
|
|
54962
55181
|
active = primary;
|
|
@@ -64799,6 +65018,11 @@ function slice(source, node2) {
|
|
|
64799
65018
|
return source.slice(start, end);
|
|
64800
65019
|
}
|
|
64801
65020
|
var EXPANDABLE_MARKER_RE = /^\*\*>/;
|
|
65021
|
+
var TG_INLINE_ENTITY_HREFS = ["tg://emoji", "tg://time"];
|
|
65022
|
+
function isTgInlineEntityHref(href) {
|
|
65023
|
+
const h = href.toLowerCase();
|
|
65024
|
+
return TG_INLINE_ENTITY_HREFS.some((base) => h === base || h.startsWith(`${base}?`));
|
|
65025
|
+
}
|
|
64802
65026
|
function markExpandableQuotes(markdown) {
|
|
64803
65027
|
const expandableLineStarts = new Set;
|
|
64804
65028
|
let out = "";
|
|
@@ -64850,6 +65074,14 @@ function foldInline(node2, source) {
|
|
|
64850
65074
|
children: foldInlineChildren(node2, source),
|
|
64851
65075
|
...pos(node2)
|
|
64852
65076
|
};
|
|
65077
|
+
case "image": {
|
|
65078
|
+
if (isTgInlineEntityHref(node2.url)) {
|
|
65079
|
+
return { type: "tg-entity", label: node2.alt ?? "", href: node2.url, ...pos(node2) };
|
|
65080
|
+
}
|
|
65081
|
+
return { type: "plain", text: slice(source, node2), ...pos(node2) };
|
|
65082
|
+
}
|
|
65083
|
+
case "footnoteReference":
|
|
65084
|
+
return { type: "raw", text: slice(source, node2), ...pos(node2) };
|
|
64853
65085
|
default:
|
|
64854
65086
|
return { type: "plain", text: slice(source, node2), ...pos(node2) };
|
|
64855
65087
|
}
|
|
@@ -64965,6 +65197,12 @@ function foldBlock(node2, source, expandableLineStarts) {
|
|
|
64965
65197
|
...pos(node2)
|
|
64966
65198
|
};
|
|
64967
65199
|
}
|
|
65200
|
+
case "footnoteDefinition":
|
|
65201
|
+
return {
|
|
65202
|
+
type: "paragraph",
|
|
65203
|
+
children: [{ type: "raw", text: slice(source, node2), ...pos(node2) }],
|
|
65204
|
+
...pos(node2)
|
|
65205
|
+
};
|
|
64968
65206
|
default:
|
|
64969
65207
|
return {
|
|
64970
65208
|
type: "paragraph",
|
|
@@ -64986,6 +65224,9 @@ function parse2(markdown) {
|
|
|
64986
65224
|
|
|
64987
65225
|
// render/render.ts
|
|
64988
65226
|
init_format();
|
|
65227
|
+
function collapseLabelBreaks(label) {
|
|
65228
|
+
return label.replace(/[ \t]*\r?\n[ \t\r\n]*/g, " ");
|
|
65229
|
+
}
|
|
64989
65230
|
function renderInline(node2, ctx = {}) {
|
|
64990
65231
|
switch (node2.type) {
|
|
64991
65232
|
case "plain":
|
|
@@ -65008,6 +65249,10 @@ function renderInline(node2, ctx = {}) {
|
|
|
65008
65249
|
}
|
|
65009
65250
|
case "link":
|
|
65010
65251
|
return `[${renderInlineChildren(node2.children, ctx)}](${escapeLinkHref(node2.href)})`;
|
|
65252
|
+
case "tg-entity":
|
|
65253
|
+
return `})`;
|
|
65254
|
+
case "raw":
|
|
65255
|
+
return node2.text;
|
|
65011
65256
|
default: {
|
|
65012
65257
|
const _exhaustive = node2;
|
|
65013
65258
|
return escapeMarkdown(_exhaustive.text ?? "");
|
|
@@ -65024,15 +65269,6 @@ function prefixLines(text4, prefix) {
|
|
|
65024
65269
|
}
|
|
65025
65270
|
function renderBlockquote(node2) {
|
|
65026
65271
|
const inner = renderBlocks3(node2.children);
|
|
65027
|
-
if (node2.expandable) {
|
|
65028
|
-
const lines = inner.split(`
|
|
65029
|
-
`);
|
|
65030
|
-
return lines.map((line, i) => {
|
|
65031
|
-
const marker = i === 0 ? "**> " : "> ";
|
|
65032
|
-
return line.length > 0 ? `${marker}${line}` : marker.trimEnd();
|
|
65033
|
-
}).join(`
|
|
65034
|
-
`);
|
|
65035
|
-
}
|
|
65036
65272
|
return prefixLines(inner, "> ");
|
|
65037
65273
|
}
|
|
65038
65274
|
function renderCodeBlock(node2) {
|
|
@@ -67336,11 +67572,11 @@ init_flood_429_ledger();
|
|
|
67336
67572
|
import {
|
|
67337
67573
|
existsSync as existsSync15,
|
|
67338
67574
|
readFileSync as readFileSync17,
|
|
67339
|
-
writeFileSync as
|
|
67575
|
+
writeFileSync as writeFileSync16,
|
|
67340
67576
|
mkdirSync as mkdirSync19,
|
|
67341
67577
|
chmodSync as chmodSync6,
|
|
67342
|
-
unlinkSync as
|
|
67343
|
-
renameSync as
|
|
67578
|
+
unlinkSync as unlinkSync12,
|
|
67579
|
+
renameSync as renameSync12
|
|
67344
67580
|
} from "node:fs";
|
|
67345
67581
|
import { dirname as dirname11, join as join22 } from "node:path";
|
|
67346
67582
|
var FLOOD_STATE_FILE2 = "flood-wait.json";
|
|
@@ -67398,7 +67634,7 @@ function writeFloodState2(path2, state, log = (l) => process.stderr.write(l)) {
|
|
|
67398
67634
|
mkdirSync19(dirname11(path2), { recursive: true });
|
|
67399
67635
|
} catch {}
|
|
67400
67636
|
try {
|
|
67401
|
-
|
|
67637
|
+
writeFileSync16(path2, payload, { mode: FLOOD_STATE_MODE2 });
|
|
67402
67638
|
try {
|
|
67403
67639
|
chmodSync6(path2, FLOOD_STATE_MODE2);
|
|
67404
67640
|
} catch {}
|
|
@@ -67411,8 +67647,8 @@ function writeFloodState2(path2, state, log = (l) => process.stderr.write(l)) {
|
|
|
67411
67647
|
return;
|
|
67412
67648
|
}
|
|
67413
67649
|
try {
|
|
67414
|
-
|
|
67415
|
-
|
|
67650
|
+
unlinkSync12(path2);
|
|
67651
|
+
writeFileSync16(path2, payload, { mode: FLOOD_STATE_MODE2 });
|
|
67416
67652
|
log(`telegram gateway: flood-breaker: recreated ${path2} \u2014 it was owned by another uid ` + `and could not be updated (${code2}); the breaker was blind (issue #3106)
|
|
67417
67653
|
`);
|
|
67418
67654
|
} catch (err2) {
|
|
@@ -67546,8 +67782,8 @@ function writeFloodWindow(path2, record, now) {
|
|
|
67546
67782
|
}
|
|
67547
67783
|
const arr = [...byScope.values()];
|
|
67548
67784
|
const tmp = `${path2}.tmp-${process.pid}`;
|
|
67549
|
-
|
|
67550
|
-
|
|
67785
|
+
writeFileSync16(tmp, JSON.stringify(arr), { mode: FLOOD_STATE_MODE2 });
|
|
67786
|
+
renameSync12(tmp, path2);
|
|
67551
67787
|
try {
|
|
67552
67788
|
chmodSync6(path2, FLOOD_STATE_MODE2);
|
|
67553
67789
|
} catch {}
|
|
@@ -72144,7 +72380,7 @@ class PostHog extends PostHogBackendClient {
|
|
|
72144
72380
|
}
|
|
72145
72381
|
|
|
72146
72382
|
// analytics-posthog.ts
|
|
72147
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync20, readFileSync as readFileSync18, writeFileSync as
|
|
72383
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync20, readFileSync as readFileSync18, writeFileSync as writeFileSync17 } from "node:fs";
|
|
72148
72384
|
import { dirname as dirname13, join as join24 } from "node:path";
|
|
72149
72385
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
72150
72386
|
var DEFAULT_KEY = "phc_qKY87cKWZm6ZyCtk7LcRd2cU8Sg42u7Ywhui5stYCegd";
|
|
@@ -72185,7 +72421,7 @@ function getDistinctId() {
|
|
|
72185
72421
|
cachedDistinctId = id;
|
|
72186
72422
|
try {
|
|
72187
72423
|
mkdirSync20(dirname13(fallbackPath), { recursive: true });
|
|
72188
|
-
|
|
72424
|
+
writeFileSync17(fallbackPath, id, "utf-8");
|
|
72189
72425
|
} catch {}
|
|
72190
72426
|
return id;
|
|
72191
72427
|
}
|
|
@@ -72260,7 +72496,7 @@ import { mkdirSync as mkdirSync22, appendFileSync as appendFileSync4 } from "nod
|
|
|
72260
72496
|
import { dirname as dirname15, join as join26 } from "node:path";
|
|
72261
72497
|
|
|
72262
72498
|
// analytics-posthog.ts
|
|
72263
|
-
import { existsSync as existsSync17, mkdirSync as mkdirSync21, readFileSync as readFileSync19, writeFileSync as
|
|
72499
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync21, readFileSync as readFileSync19, writeFileSync as writeFileSync18 } from "node:fs";
|
|
72264
72500
|
import { dirname as dirname14, join as join25 } from "node:path";
|
|
72265
72501
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
72266
72502
|
var DEFAULT_KEY2 = "phc_qKY87cKWZm6ZyCtk7LcRd2cU8Sg42u7Ywhui5stYCegd";
|
|
@@ -72300,7 +72536,7 @@ function getDistinctId2() {
|
|
|
72300
72536
|
cachedDistinctId2 = id;
|
|
72301
72537
|
try {
|
|
72302
72538
|
mkdirSync21(dirname14(fallbackPath), { recursive: true });
|
|
72303
|
-
|
|
72539
|
+
writeFileSync18(fallbackPath, id, "utf-8");
|
|
72304
72540
|
} catch {}
|
|
72305
72541
|
return id;
|
|
72306
72542
|
}
|
|
@@ -73036,7 +73272,7 @@ function __resetAllForTests3() {
|
|
|
73036
73272
|
}
|
|
73037
73273
|
|
|
73038
73274
|
// silent-end.ts
|
|
73039
|
-
import { existsSync as existsSync19, readFileSync as readFileSync20, writeFileSync as
|
|
73275
|
+
import { existsSync as existsSync19, readFileSync as readFileSync20, writeFileSync as writeFileSync19, unlinkSync as unlinkSync13, mkdirSync as mkdirSync23 } from "node:fs";
|
|
73040
73276
|
import { dirname as dirname16, join as join27 } from "node:path";
|
|
73041
73277
|
import { homedir as homedir5 } from "node:os";
|
|
73042
73278
|
var SILENT_END_MAX_RETRIES = 2;
|
|
@@ -73081,7 +73317,7 @@ function writeSilentEndState(args, deps) {
|
|
|
73081
73317
|
};
|
|
73082
73318
|
try {
|
|
73083
73319
|
mkdirSync23(dirname16(statePath), { recursive: true });
|
|
73084
|
-
|
|
73320
|
+
writeFileSync19(statePath, JSON.stringify(state3), "utf8");
|
|
73085
73321
|
emitLog(deps, `silent-end: wrote state file turnKey=${args.turnKey} retryCount=${retryCount}
|
|
73086
73322
|
`);
|
|
73087
73323
|
} catch (err) {
|
|
@@ -73097,7 +73333,7 @@ function clearSilentEndState(turnKey3, deps) {
|
|
|
73097
73333
|
const prev = JSON.parse(readFileSync20(statePath, "utf8"));
|
|
73098
73334
|
if (prev.turnKey != null && prev.turnKey !== turnKey3)
|
|
73099
73335
|
return;
|
|
73100
|
-
|
|
73336
|
+
unlinkSync13(statePath);
|
|
73101
73337
|
emitLog(deps, `silent-end: cleared state file turnKey=${turnKey3}
|
|
73102
73338
|
`);
|
|
73103
73339
|
} catch {}
|
|
@@ -74028,7 +74264,7 @@ async function gatewayStartupRetry(fn, opts = {}) {
|
|
|
74028
74264
|
}
|
|
74029
74265
|
|
|
74030
74266
|
// gateway/quarantine.ts
|
|
74031
|
-
import { mkdirSync as mkdirSync24, writeFileSync as
|
|
74267
|
+
import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync20 } from "node:fs";
|
|
74032
74268
|
import { join as join30 } from "node:path";
|
|
74033
74269
|
var QUARANTINE_FILENAME = "quarantine.json";
|
|
74034
74270
|
function writeQuarantineMarker(telegramStateDir, reason, detail, nowFn = Date.now) {
|
|
@@ -74039,7 +74275,7 @@ function writeQuarantineMarker(telegramStateDir, reason, detail, nowFn = Date.no
|
|
|
74039
74275
|
ts: nowFn(),
|
|
74040
74276
|
detail
|
|
74041
74277
|
};
|
|
74042
|
-
|
|
74278
|
+
writeFileSync20(join30(telegramStateDir, QUARANTINE_FILENAME), JSON.stringify(marker) + `
|
|
74043
74279
|
`, "utf-8");
|
|
74044
74280
|
}
|
|
74045
74281
|
|
|
@@ -75512,7 +75748,7 @@ async function materializeSidecarToken2(opts = {}, logger2 = (line) => process.s
|
|
|
75512
75748
|
}
|
|
75513
75749
|
|
|
75514
75750
|
// ../src/setup/host-capabilities.ts
|
|
75515
|
-
import { mkdirSync as mkdirSync25, readFileSync as readFileSync22, writeFileSync as
|
|
75751
|
+
import { mkdirSync as mkdirSync25, readFileSync as readFileSync22, writeFileSync as writeFileSync21 } from "node:fs";
|
|
75516
75752
|
init_paths();
|
|
75517
75753
|
function hostCapabilitiesPath() {
|
|
75518
75754
|
return resolveStatePath("host-capabilities.json");
|
|
@@ -75676,7 +75912,7 @@ function resolveExhaustUntil(resetAtMs, now = Date.now()) {
|
|
|
75676
75912
|
|
|
75677
75913
|
// gateway/auth-add-flow.ts
|
|
75678
75914
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
75679
|
-
import { existsSync as existsSync24, mkdirSync as mkdirSync27, readFileSync as readFileSync24, readdirSync as readdirSync7, rmSync as rmSync6, statSync as statSync10, writeFileSync as
|
|
75915
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync27, readFileSync as readFileSync24, readdirSync as readdirSync7, rmSync as rmSync6, statSync as statSync10, writeFileSync as writeFileSync23 } from "node:fs";
|
|
75680
75916
|
import { homedir as homedir8 } from "node:os";
|
|
75681
75917
|
import { join as join32 } from "node:path";
|
|
75682
75918
|
import { randomBytes as randomBytes8 } from "node:crypto";
|
|
@@ -75686,7 +75922,7 @@ import {
|
|
|
75686
75922
|
readFileSync as readFileSync23,
|
|
75687
75923
|
readdirSync as readdirSync6,
|
|
75688
75924
|
existsSync as existsSync23,
|
|
75689
|
-
writeFileSync as
|
|
75925
|
+
writeFileSync as writeFileSync22,
|
|
75690
75926
|
mkdirSync as mkdirSync26,
|
|
75691
75927
|
mkdtempSync as mkdtempSync2,
|
|
75692
75928
|
rmSync as rmSync5,
|
|
@@ -75847,7 +76083,7 @@ async function startAccountAuthSession(label, opts = {}) {
|
|
|
75847
76083
|
const tmuxSocket = `switchroom-${agentName3}`;
|
|
75848
76084
|
const tmuxSession = `auth-add-${label}-${hexSuffix}`.slice(0, 64);
|
|
75849
76085
|
try {
|
|
75850
|
-
|
|
76086
|
+
writeFileSync23(join32(scratchDir, AUTH_TMUX_SESSION_FILE), `${tmuxSocket}
|
|
75851
76087
|
${tmuxSession}`, "utf8");
|
|
75852
76088
|
} catch {}
|
|
75853
76089
|
const sessionEnv = {
|
|
@@ -78836,7 +79072,7 @@ function startRestartWatchdog(config) {
|
|
|
78836
79072
|
}
|
|
78837
79073
|
|
|
78838
79074
|
// gateway/access-store.ts
|
|
78839
|
-
import { mkdirSync as mkdirSync28, readFileSync as readFileSync25, renameSync as
|
|
79075
|
+
import { mkdirSync as mkdirSync28, readFileSync as readFileSync25, renameSync as renameSync13, writeFileSync as writeFileSync24 } from "node:fs";
|
|
78840
79076
|
|
|
78841
79077
|
// gateway/access-validator.ts
|
|
78842
79078
|
function validateStringArray(field, value, tag = "gateway") {
|
|
@@ -78900,7 +79136,7 @@ function createAccessStore(deps) {
|
|
|
78900
79136
|
if (err.code === "ENOENT")
|
|
78901
79137
|
return defaultAccess();
|
|
78902
79138
|
try {
|
|
78903
|
-
|
|
79139
|
+
renameSync13(accessFile, `${accessFile}.corrupt-${Date.now()}`);
|
|
78904
79140
|
} catch {}
|
|
78905
79141
|
process.stderr.write(`telegram gateway: access.json is corrupt, moved aside. Starting fresh.
|
|
78906
79142
|
`);
|
|
@@ -78945,9 +79181,9 @@ function createAccessStore(deps) {
|
|
|
78945
79181
|
return;
|
|
78946
79182
|
mkdirSync28(stateDir, { recursive: true, mode: 448 });
|
|
78947
79183
|
const tmp = accessFile + ".tmp";
|
|
78948
|
-
|
|
79184
|
+
writeFileSync24(tmp, JSON.stringify(a, null, 2) + `
|
|
78949
79185
|
`, { mode: 384 });
|
|
78950
|
-
|
|
79186
|
+
renameSync13(tmp, accessFile);
|
|
78951
79187
|
}
|
|
78952
79188
|
function pruneExpired(a) {
|
|
78953
79189
|
const now = Date.now();
|
|
@@ -79212,7 +79448,7 @@ var INLINE_SPAN_PATTERNS2 = [
|
|
|
79212
79448
|
/\*\*[^*\n]+\*\*/g,
|
|
79213
79449
|
/__[^_\n]+__/g,
|
|
79214
79450
|
/(?<![\w*])_[^_\n]+_(?![\w*])/g,
|
|
79215
|
-
|
|
79451
|
+
/!?\[[^\]\n]*\]\([^)\n]*\)/g,
|
|
79216
79452
|
/~~[^~\n]+~~/g,
|
|
79217
79453
|
/\|\|[^|\n]+\|\|/g
|
|
79218
79454
|
];
|
|
@@ -79784,10 +80020,10 @@ import {
|
|
|
79784
80020
|
mkdirSync as mkdirSync29,
|
|
79785
80021
|
readFileSync as readFileSync26,
|
|
79786
80022
|
readdirSync as readdirSync8,
|
|
79787
|
-
renameSync as
|
|
80023
|
+
renameSync as renameSync14,
|
|
79788
80024
|
statSync as statSync11,
|
|
79789
|
-
unlinkSync as
|
|
79790
|
-
writeFileSync as
|
|
80025
|
+
unlinkSync as unlinkSync14,
|
|
80026
|
+
writeFileSync as writeFileSync25,
|
|
79791
80027
|
appendFileSync as appendFileSync5
|
|
79792
80028
|
} from "node:fs";
|
|
79793
80029
|
import { join as join34 } from "node:path";
|
|
@@ -79891,8 +80127,8 @@ function writeOutboxRecordAtomic(record, stateDir) {
|
|
|
79891
80127
|
if (existsSync26(finalPath))
|
|
79892
80128
|
return true;
|
|
79893
80129
|
const tmpPath = join34(dir, `.${record.turnNonce}.${process.pid}.tmp`);
|
|
79894
|
-
|
|
79895
|
-
|
|
80130
|
+
writeFileSync25(tmpPath, JSON.stringify(record), { mode: 384 });
|
|
80131
|
+
renameSync14(tmpPath, finalPath);
|
|
79896
80132
|
return true;
|
|
79897
80133
|
} catch {
|
|
79898
80134
|
return false;
|
|
@@ -79919,7 +80155,7 @@ function claimRecord(nonce, stateDir) {
|
|
|
79919
80155
|
const from = join34(dir, `${nonce}.json`);
|
|
79920
80156
|
const to = join34(dir, `${nonce}.sending`);
|
|
79921
80157
|
try {
|
|
79922
|
-
|
|
80158
|
+
renameSync14(from, to);
|
|
79923
80159
|
return to;
|
|
79924
80160
|
} catch {
|
|
79925
80161
|
return null;
|
|
@@ -79928,12 +80164,12 @@ function claimRecord(nonce, stateDir) {
|
|
|
79928
80164
|
function releaseClaim(nonce, stateDir) {
|
|
79929
80165
|
const dir = resolveOutboxDir(stateDir);
|
|
79930
80166
|
try {
|
|
79931
|
-
|
|
80167
|
+
renameSync14(join34(dir, `${nonce}.sending`), join34(dir, `${nonce}.json`));
|
|
79932
80168
|
} catch {}
|
|
79933
80169
|
}
|
|
79934
80170
|
function removeClaimed(nonce, stateDir) {
|
|
79935
80171
|
try {
|
|
79936
|
-
|
|
80172
|
+
unlinkSync14(join34(resolveOutboxDir(stateDir), `${nonce}.sending`));
|
|
79937
80173
|
} catch {}
|
|
79938
80174
|
}
|
|
79939
80175
|
function reclaimStaleSending(stateDir, now = Date.now()) {
|
|
@@ -79948,7 +80184,7 @@ function reclaimStaleSending(stateDir, now = Date.now()) {
|
|
|
79948
80184
|
try {
|
|
79949
80185
|
const st = statSync11(join34(dir, f));
|
|
79950
80186
|
if (now - st.mtimeMs > OUTBOX_SENDING_TIMEOUT_MS) {
|
|
79951
|
-
|
|
80187
|
+
renameSync14(join34(dir, f), join34(dir, f.replace(/\.sending$/, ".json")));
|
|
79952
80188
|
}
|
|
79953
80189
|
} catch {}
|
|
79954
80190
|
}
|
|
@@ -80019,17 +80255,17 @@ function compactJournalIfLarge(path2) {
|
|
|
80019
80255
|
return;
|
|
80020
80256
|
const kept = lines.slice(lines.length - JOURNAL_KEEP);
|
|
80021
80257
|
const tmp = `${path2}.${process.pid}.compact`;
|
|
80022
|
-
|
|
80258
|
+
writeFileSync25(tmp, kept.join(`
|
|
80023
80259
|
`) + `
|
|
80024
80260
|
`, { mode: 384 });
|
|
80025
|
-
|
|
80261
|
+
renameSync14(tmp, path2);
|
|
80026
80262
|
} catch {}
|
|
80027
80263
|
}
|
|
80028
80264
|
function clearOutboxRecord(nonce, stateDir) {
|
|
80029
80265
|
const dir = resolveOutboxDir(stateDir);
|
|
80030
80266
|
for (const suffix of [".json", ".sending"]) {
|
|
80031
80267
|
try {
|
|
80032
|
-
|
|
80268
|
+
unlinkSync14(join34(dir, `${nonce}${suffix}`));
|
|
80033
80269
|
} catch {}
|
|
80034
80270
|
}
|
|
80035
80271
|
}
|
|
@@ -80097,8 +80333,8 @@ import {
|
|
|
80097
80333
|
existsSync as existsSync27,
|
|
80098
80334
|
mkdirSync as mkdirSync30,
|
|
80099
80335
|
readFileSync as readFileSync27,
|
|
80100
|
-
renameSync as
|
|
80101
|
-
writeFileSync as
|
|
80336
|
+
renameSync as renameSync15,
|
|
80337
|
+
writeFileSync as writeFileSync26,
|
|
80102
80338
|
appendFileSync as appendFileSync6
|
|
80103
80339
|
} from "node:fs";
|
|
80104
80340
|
import { join as join35 } from "node:path";
|
|
@@ -80227,10 +80463,10 @@ function compactIfLarge(path2) {
|
|
|
80227
80463
|
return;
|
|
80228
80464
|
const kept = lines.slice(lines.length - SHOWN_LEDGER_KEEP);
|
|
80229
80465
|
const tmp = `${path2}.${process.pid}.compact`;
|
|
80230
|
-
|
|
80466
|
+
writeFileSync26(tmp, kept.join(`
|
|
80231
80467
|
`) + `
|
|
80232
80468
|
`, { mode: 384 });
|
|
80233
|
-
|
|
80469
|
+
renameSync15(tmp, path2);
|
|
80234
80470
|
} catch {}
|
|
80235
80471
|
}
|
|
80236
80472
|
|
|
@@ -80750,6 +80986,10 @@ var INBOUND_SOURCE_CLASSIFICATION = {
|
|
|
80750
80986
|
mental_model_proposal_failed: { decoupledCompletion: false },
|
|
80751
80987
|
webhook: { decoupledCompletion: false },
|
|
80752
80988
|
linear: { decoupledCompletion: false },
|
|
80989
|
+
eval_case_applied: { decoupledCompletion: false },
|
|
80990
|
+
eval_case_rejected: { decoupledCompletion: false },
|
|
80991
|
+
eval_case_apply_failed: { decoupledCompletion: false },
|
|
80992
|
+
eval_case_suppressed: { decoupledCompletion: false },
|
|
80753
80993
|
buzz: { decoupledCompletion: false },
|
|
80754
80994
|
boot_briefing: { decoupledCompletion: false }
|
|
80755
80995
|
};
|
|
@@ -80988,7 +81228,7 @@ function monotonicNowMs2() {
|
|
|
80988
81228
|
}
|
|
80989
81229
|
|
|
80990
81230
|
// silent-end.ts
|
|
80991
|
-
import { existsSync as existsSync28, readFileSync as readFileSync28, writeFileSync as
|
|
81231
|
+
import { existsSync as existsSync28, readFileSync as readFileSync28, writeFileSync as writeFileSync27, unlinkSync as unlinkSync15, mkdirSync as mkdirSync31 } from "node:fs";
|
|
80992
81232
|
import { dirname as dirname17, join as join36 } from "node:path";
|
|
80993
81233
|
import { homedir as homedir10 } from "node:os";
|
|
80994
81234
|
var SILENT_END_MAX_RETRIES2 = 2;
|
|
@@ -81037,7 +81277,7 @@ function writeSilentEndState2(args, deps) {
|
|
|
81037
81277
|
};
|
|
81038
81278
|
try {
|
|
81039
81279
|
mkdirSync31(dirname17(statePath), { recursive: true });
|
|
81040
|
-
|
|
81280
|
+
writeFileSync27(statePath, JSON.stringify(state3), "utf8");
|
|
81041
81281
|
emitLog2(deps, `silent-end: wrote state file turnKey=${args.turnKey} retryCount=${retryCount}
|
|
81042
81282
|
`);
|
|
81043
81283
|
} catch (err) {
|
|
@@ -81053,7 +81293,7 @@ function clearSilentEndState2(turnKey3, deps) {
|
|
|
81053
81293
|
const prev = JSON.parse(readFileSync28(statePath, "utf8"));
|
|
81054
81294
|
if (prev.turnKey != null && prev.turnKey !== turnKey3)
|
|
81055
81295
|
return;
|
|
81056
|
-
|
|
81296
|
+
unlinkSync15(statePath);
|
|
81057
81297
|
emitLog2(deps, `silent-end: cleared state file turnKey=${turnKey3}
|
|
81058
81298
|
`);
|
|
81059
81299
|
} catch {}
|
|
@@ -83416,7 +83656,7 @@ import {
|
|
|
83416
83656
|
openSync as openSync10,
|
|
83417
83657
|
readFileSync as readFileSync29,
|
|
83418
83658
|
statSync as statSync13,
|
|
83419
|
-
unlinkSync as
|
|
83659
|
+
unlinkSync as unlinkSync16,
|
|
83420
83660
|
utimesSync
|
|
83421
83661
|
} from "node:fs";
|
|
83422
83662
|
import { join as join39 } from "node:path";
|
|
@@ -83445,7 +83685,7 @@ function touchTurnActiveMarker(stateDir) {
|
|
|
83445
83685
|
}
|
|
83446
83686
|
function removeTurnActiveMarker(stateDir) {
|
|
83447
83687
|
try {
|
|
83448
|
-
|
|
83688
|
+
unlinkSync16(join39(stateDir, TURN_ACTIVE_MARKER_FILE));
|
|
83449
83689
|
} catch {}
|
|
83450
83690
|
}
|
|
83451
83691
|
function readTurnActiveMarkerAgeMs(stateDir, now) {
|
|
@@ -85770,7 +86010,7 @@ function resolveAgentDirFromEnv() {
|
|
|
85770
86010
|
}
|
|
85771
86011
|
|
|
85772
86012
|
// active-reactions.ts
|
|
85773
|
-
import { readFileSync as readFileSync30, writeFileSync as
|
|
86013
|
+
import { readFileSync as readFileSync30, writeFileSync as writeFileSync28, renameSync as renameSync16, existsSync as existsSync32, unlinkSync as unlinkSync17 } from "node:fs";
|
|
85774
86014
|
import { join as join40 } from "node:path";
|
|
85775
86015
|
var ACTIVE_REACTIONS_FILENAME = ".active-reactions.json";
|
|
85776
86016
|
function reactionsPath(agentDir) {
|
|
@@ -85808,15 +86048,15 @@ function writeActiveReactions(agentDir, reactions) {
|
|
|
85808
86048
|
const p = reactionsPath(agentDir);
|
|
85809
86049
|
if (reactions.length === 0) {
|
|
85810
86050
|
try {
|
|
85811
|
-
|
|
86051
|
+
unlinkSync17(p);
|
|
85812
86052
|
} catch {}
|
|
85813
86053
|
return;
|
|
85814
86054
|
}
|
|
85815
86055
|
const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
|
|
85816
86056
|
try {
|
|
85817
|
-
|
|
86057
|
+
writeFileSync28(tmp, JSON.stringify(reactions) + `
|
|
85818
86058
|
`, "utf-8");
|
|
85819
|
-
|
|
86059
|
+
renameSync16(tmp, p);
|
|
85820
86060
|
} catch {}
|
|
85821
86061
|
}
|
|
85822
86062
|
function addActiveReaction(agentDir, reaction) {
|
|
@@ -85833,12 +86073,12 @@ function removeActiveReaction(agentDir, chatId, messageId) {
|
|
|
85833
86073
|
}
|
|
85834
86074
|
function clearActiveReactions(agentDir) {
|
|
85835
86075
|
try {
|
|
85836
|
-
|
|
86076
|
+
unlinkSync17(reactionsPath(agentDir));
|
|
85837
86077
|
} catch {}
|
|
85838
86078
|
}
|
|
85839
86079
|
|
|
85840
86080
|
// active-reactions.ts
|
|
85841
|
-
import { readFileSync as readFileSync31, writeFileSync as
|
|
86081
|
+
import { readFileSync as readFileSync31, writeFileSync as writeFileSync29, renameSync as renameSync17, existsSync as existsSync33, unlinkSync as unlinkSync18 } from "node:fs";
|
|
85842
86082
|
import { join as join41 } from "node:path";
|
|
85843
86083
|
var ACTIVE_REACTIONS_FILENAME2 = ".active-reactions.json";
|
|
85844
86084
|
function reactionsPath2(agentDir) {
|
|
@@ -85874,7 +86114,7 @@ function readActiveReactions2(agentDir) {
|
|
|
85874
86114
|
}
|
|
85875
86115
|
function clearActiveReactions2(agentDir) {
|
|
85876
86116
|
try {
|
|
85877
|
-
|
|
86117
|
+
unlinkSync18(reactionsPath2(agentDir));
|
|
85878
86118
|
} catch {}
|
|
85879
86119
|
}
|
|
85880
86120
|
|
|
@@ -88116,15 +88356,15 @@ async function menuWithBannerStatic(deps, banner) {
|
|
|
88116
88356
|
}
|
|
88117
88357
|
|
|
88118
88358
|
// gateway/session-model-file.ts
|
|
88119
|
-
import { readFileSync as readFileSync33, writeFileSync as
|
|
88359
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync30, renameSync as renameSync18, rmSync as rmSync7 } from "node:fs";
|
|
88120
88360
|
import { join as join43 } from "node:path";
|
|
88121
88361
|
var SESSION_MODEL_FILE = ".session-model";
|
|
88122
88362
|
var CONFIGURED_DEFAULT_MODEL_FILE = ".configured-default-model";
|
|
88123
88363
|
var SESSION_MODEL_BOOT_ATTEMPTS_FILE = ".session-model-boot-attempts";
|
|
88124
88364
|
function atomicWrite(path2, content3) {
|
|
88125
88365
|
const tmp = `${path2}.tmp-${process.pid}-${Date.now()}`;
|
|
88126
|
-
|
|
88127
|
-
|
|
88366
|
+
writeFileSync30(tmp, content3, "utf8");
|
|
88367
|
+
renameSync18(tmp, path2);
|
|
88128
88368
|
}
|
|
88129
88369
|
function serializeSessionModel(rec) {
|
|
88130
88370
|
return `${JSON.stringify({
|
|
@@ -88652,7 +88892,7 @@ var AUDIT_ROOT = join45(homedir11(), ".switchroom", "audit");
|
|
|
88652
88892
|
|
|
88653
88893
|
// ../src/agents/profiles.ts
|
|
88654
88894
|
var import_handlebars = __toESM(require_lib(), 1);
|
|
88655
|
-
import { readFileSync as readFileSync36, writeFileSync as
|
|
88895
|
+
import { readFileSync as readFileSync36, writeFileSync as writeFileSync32, existsSync as existsSync37, readdirSync as readdirSync9, statSync as statSync14, copyFileSync, mkdirSync as mkdirSync33, realpathSync as realpathSync4 } from "node:fs";
|
|
88656
88896
|
import { resolve as resolve8, join as join46, sep as pathSep } from "node:path";
|
|
88657
88897
|
function resolveProfilesRootDetailed() {
|
|
88658
88898
|
return resolveShippedAsset(PROFILES_ASSET, {
|
|
@@ -88670,7 +88910,7 @@ import_handlebars.default.registerHelper("isNumber", (value) => {
|
|
|
88670
88910
|
return typeof value === "number" && Number.isFinite(value);
|
|
88671
88911
|
});
|
|
88672
88912
|
var SHARED_FRAGMENTS_DIR = resolve8(PROFILES_ROOT, "_shared");
|
|
88673
|
-
var SHARED_FRAGMENTS = ["vault-protocol", "agent-self-service", "execution-discipline", "reply-discipline", "dev-protocol"];
|
|
88913
|
+
var SHARED_FRAGMENTS = ["vault-protocol", "agent-self-service", "execution-discipline", "reply-discipline", "dev-protocol", "local-time"];
|
|
88674
88914
|
for (const name of SHARED_FRAGMENTS) {
|
|
88675
88915
|
const fragPath = join46(SHARED_FRAGMENTS_DIR, `${name}.md.hbs`);
|
|
88676
88916
|
if (existsSync37(fragPath)) {
|
|
@@ -90623,7 +90863,7 @@ function numField(obj, key) {
|
|
|
90623
90863
|
}
|
|
90624
90864
|
|
|
90625
90865
|
// gateway/context-occupancy.ts
|
|
90626
|
-
import { mkdirSync as mkdirSync34, writeFileSync as
|
|
90866
|
+
import { mkdirSync as mkdirSync34, writeFileSync as writeFileSync33 } from "node:fs";
|
|
90627
90867
|
import { join as join47 } from "node:path";
|
|
90628
90868
|
var CONTEXT_OCCUPANCY_FILENAME = "context-occupancy.json";
|
|
90629
90869
|
var TIGHT_FRACTION = 0.8;
|
|
@@ -90649,7 +90889,7 @@ function writeContextOccupancySnapshot(stateDir, snapshot, deps) {
|
|
|
90649
90889
|
try {
|
|
90650
90890
|
const path2 = join47(stateDir, CONTEXT_OCCUPANCY_FILENAME);
|
|
90651
90891
|
(deps?.mkdir ?? ((p, o) => mkdirSync34(p, o)))(stateDir, { recursive: true });
|
|
90652
|
-
(deps?.writeFile ?? ((p, d) =>
|
|
90892
|
+
(deps?.writeFile ?? ((p, d) => writeFileSync33(p, d)))(path2, JSON.stringify(snapshot, null, 2) + `
|
|
90653
90893
|
`);
|
|
90654
90894
|
} catch {}
|
|
90655
90895
|
}
|
|
@@ -92031,7 +92271,7 @@ import {
|
|
|
92031
92271
|
openSync as openSync11,
|
|
92032
92272
|
readdirSync as readdirSync10,
|
|
92033
92273
|
statSync as statSync15,
|
|
92034
|
-
writeFileSync as
|
|
92274
|
+
writeFileSync as writeFileSync34
|
|
92035
92275
|
} from "node:fs";
|
|
92036
92276
|
import { dirname as dirname21, join as join51, relative as relative2, sep as sep5 } from "node:path";
|
|
92037
92277
|
var NOFOLLOW2 = constants5.O_NOFOLLOW ?? 0;
|
|
@@ -92114,7 +92354,7 @@ function mkdirStateSync2(path2, options = { recursive: true }, log = defaultLog3
|
|
|
92114
92354
|
function writeStateFileSync2(path2, data, options, log = defaultLog3) {
|
|
92115
92355
|
const owner = resolveStateOwner2(dirname21(path2));
|
|
92116
92356
|
if (!owner) {
|
|
92117
|
-
|
|
92357
|
+
writeFileSync34(path2, data, options);
|
|
92118
92358
|
return;
|
|
92119
92359
|
}
|
|
92120
92360
|
const mode = options?.mode ?? 438;
|
|
@@ -92122,7 +92362,7 @@ function writeStateFileSync2(path2, data, options, log = defaultLog3) {
|
|
|
92122
92362
|
let fd = null;
|
|
92123
92363
|
try {
|
|
92124
92364
|
fd = openSync11(path2, constants5.O_WRONLY | constants5.O_CREAT | constants5.O_TRUNC | NOFOLLOW2, mode);
|
|
92125
|
-
|
|
92365
|
+
writeFileSync34(fd, buf);
|
|
92126
92366
|
try {
|
|
92127
92367
|
fchownSync4(fd, owner.uid, owner.gid);
|
|
92128
92368
|
} catch (err) {
|
|
@@ -92136,7 +92376,7 @@ function writeStateFileSync2(path2, data, options, log = defaultLog3) {
|
|
|
92136
92376
|
fd = null;
|
|
92137
92377
|
}
|
|
92138
92378
|
noteFailure2("write", path2, err, log);
|
|
92139
|
-
|
|
92379
|
+
writeFileSync34(path2, data, options);
|
|
92140
92380
|
return;
|
|
92141
92381
|
} finally {
|
|
92142
92382
|
if (fd !== null) {
|
|
@@ -92261,7 +92501,7 @@ function adoptAndReport(path2, owner, log) {
|
|
|
92261
92501
|
|
|
92262
92502
|
// gateway/webhook-ingest-server.ts
|
|
92263
92503
|
import net4 from "node:net";
|
|
92264
|
-
import { chmodSync as chmodSync10, existsSync as existsSync43, unlinkSync as
|
|
92504
|
+
import { chmodSync as chmodSync10, existsSync as existsSync43, unlinkSync as unlinkSync19 } from "node:fs";
|
|
92265
92505
|
var MAX_REQUEST_BYTES = 1024 * 1024;
|
|
92266
92506
|
function fdOf(conn) {
|
|
92267
92507
|
const handle = conn._handle;
|
|
@@ -92274,7 +92514,7 @@ function startWebhookIngestServer(opts) {
|
|
|
92274
92514
|
const allowed = new Set(opts.allowedUids);
|
|
92275
92515
|
try {
|
|
92276
92516
|
if (existsSync43(opts.socketPath))
|
|
92277
|
-
|
|
92517
|
+
unlinkSync19(opts.socketPath);
|
|
92278
92518
|
} catch (err) {
|
|
92279
92519
|
log(`webhook-ingest-server: could not unlink stale socket: ${err.message}
|
|
92280
92520
|
`);
|
|
@@ -92367,7 +92607,7 @@ function startWebhookIngestServer(opts) {
|
|
|
92367
92607
|
} catch {}
|
|
92368
92608
|
try {
|
|
92369
92609
|
if (existsSync43(opts.socketPath))
|
|
92370
|
-
|
|
92610
|
+
unlinkSync19(opts.socketPath);
|
|
92371
92611
|
} catch {}
|
|
92372
92612
|
}
|
|
92373
92613
|
};
|
|
@@ -92379,7 +92619,7 @@ import { join as join55 } from "path";
|
|
|
92379
92619
|
import { homedir as homedir16 } from "os";
|
|
92380
92620
|
|
|
92381
92621
|
// ../src/web/webhook-handler.ts
|
|
92382
|
-
import { appendFileSync as appendFileSync9, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as
|
|
92622
|
+
import { appendFileSync as appendFileSync9, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
|
|
92383
92623
|
import { join as join53 } from "path";
|
|
92384
92624
|
|
|
92385
92625
|
// ../src/util/log-rotation.ts
|
|
@@ -92734,7 +92974,7 @@ function saveDedupFile(path3, deliveries, now) {
|
|
|
92734
92974
|
}
|
|
92735
92975
|
const sorted = Object.entries(pruned).sort((a, b) => b[1] - a[1]).slice(0, DEDUP_MAX);
|
|
92736
92976
|
const final = Object.fromEntries(sorted);
|
|
92737
|
-
|
|
92977
|
+
writeFileSync35(path3, JSON.stringify({ deliveries: final }), {
|
|
92738
92978
|
mode: 384
|
|
92739
92979
|
});
|
|
92740
92980
|
}
|
|
@@ -92764,7 +93004,7 @@ var tokenBuckets = new Map;
|
|
|
92764
93004
|
var throttleIssueWindow = new Map;
|
|
92765
93005
|
|
|
92766
93006
|
// ../src/web/webhook-dispatch.ts
|
|
92767
|
-
import { existsSync as existsSync46, mkdirSync as mkdirSync39, readFileSync as readFileSync42, writeFileSync as
|
|
93007
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync39, readFileSync as readFileSync42, writeFileSync as writeFileSync36 } from "fs";
|
|
92768
93008
|
import { join as join54 } from "path";
|
|
92769
93009
|
import { homedir as homedir15 } from "os";
|
|
92770
93010
|
|
|
@@ -93074,7 +93314,7 @@ function loadCooldownFile(path3) {
|
|
|
93074
93314
|
}
|
|
93075
93315
|
function saveCooldownFile(path3, dispatches) {
|
|
93076
93316
|
try {
|
|
93077
|
-
|
|
93317
|
+
writeFileSync36(path3, JSON.stringify({ dispatches }), {
|
|
93078
93318
|
mode: 384
|
|
93079
93319
|
});
|
|
93080
93320
|
} catch {}
|
|
@@ -93420,7 +93660,7 @@ function recordWebhookEvent(rec, deps = {}) {
|
|
|
93420
93660
|
|
|
93421
93661
|
// gateway/ipc-server.ts
|
|
93422
93662
|
init_format();
|
|
93423
|
-
import { renameSync as
|
|
93663
|
+
import { renameSync as renameSync20, unlinkSync as unlinkSync21, chmodSync as chmodSync11 } from "fs";
|
|
93424
93664
|
var MAX_BUFFER_SIZE = 1024 * 1024;
|
|
93425
93665
|
var VALID_OPERATOR_KINDS = new Set(OPERATOR_EVENT_KINDS);
|
|
93426
93666
|
var AGENT_NAME_RE3 = /^[a-z0-9][a-z0-9_-]{0,50}$/;
|
|
@@ -93674,10 +93914,10 @@ function createIpcServer(options) {
|
|
|
93674
93914
|
return false;
|
|
93675
93915
|
};
|
|
93676
93916
|
try {
|
|
93677
|
-
|
|
93917
|
+
renameSync20(socketPath, socketPath + ".bak");
|
|
93678
93918
|
} catch {}
|
|
93679
93919
|
try {
|
|
93680
|
-
|
|
93920
|
+
unlinkSync21(socketPath + ".bak");
|
|
93681
93921
|
} catch {}
|
|
93682
93922
|
const clients = new Set;
|
|
93683
93923
|
const agentIndex = new Map;
|
|
@@ -94131,7 +94371,7 @@ function createIpcServer(options) {
|
|
|
94131
94371
|
clientBySocketId.clear();
|
|
94132
94372
|
server.stop(true);
|
|
94133
94373
|
try {
|
|
94134
|
-
|
|
94374
|
+
renameSync20(socketPath, socketPath + ".bak");
|
|
94135
94375
|
} catch {}
|
|
94136
94376
|
}
|
|
94137
94377
|
};
|
|
@@ -94705,8 +94945,132 @@ function buildDiffPreviewCard(input) {
|
|
|
94705
94945
|
return { text: text4, reply_markup: kb };
|
|
94706
94946
|
}
|
|
94707
94947
|
|
|
94948
|
+
// gateway/approval-outcome-sources.ts
|
|
94949
|
+
var APPROVAL_OUTCOME_SOURCES = Object.freeze(new Set([
|
|
94950
|
+
"vault_grant_approved",
|
|
94951
|
+
"vault_grant_denied",
|
|
94952
|
+
"vault_grant_timeout",
|
|
94953
|
+
"vault_save_completed",
|
|
94954
|
+
"vault_save_discarded",
|
|
94955
|
+
"vault_save_failed",
|
|
94956
|
+
"vault_save_timeout",
|
|
94957
|
+
"secret_provided",
|
|
94958
|
+
"secret_declined",
|
|
94959
|
+
"secret_provide_failed",
|
|
94960
|
+
"secret_request_timeout",
|
|
94961
|
+
"mental_model_proposal_applied",
|
|
94962
|
+
"mental_model_proposal_denied",
|
|
94963
|
+
"mental_model_proposal_failed",
|
|
94964
|
+
"mental_model_propose_timeout",
|
|
94965
|
+
"skill_proposal_apply",
|
|
94966
|
+
"eval_case_applied",
|
|
94967
|
+
"eval_case_rejected",
|
|
94968
|
+
"eval_case_apply_failed",
|
|
94969
|
+
"eval_case_suppressed"
|
|
94970
|
+
]));
|
|
94971
|
+
var APPROVAL_OUTCOME_DROPPED_SOURCE = "approval_outcome_dropped";
|
|
94972
|
+
function isApprovalOutcome(msg) {
|
|
94973
|
+
const meta = msg.meta;
|
|
94974
|
+
if (meta == null)
|
|
94975
|
+
return false;
|
|
94976
|
+
if (meta.source != null && APPROVAL_OUTCOME_SOURCES.has(meta.source))
|
|
94977
|
+
return true;
|
|
94978
|
+
return meta.button_callback === "true";
|
|
94979
|
+
}
|
|
94980
|
+
function approvalOutcomeLabel(msg) {
|
|
94981
|
+
const src = msg.meta?.source;
|
|
94982
|
+
if (src != null && src !== "")
|
|
94983
|
+
return src;
|
|
94984
|
+
if (msg.meta?.button_callback === "true")
|
|
94985
|
+
return "button_callback";
|
|
94986
|
+
return "-";
|
|
94987
|
+
}
|
|
94988
|
+
function buildApprovalOutcomeDroppedInbound(opts) {
|
|
94989
|
+
const ts = opts.nowMs ?? Date.now();
|
|
94990
|
+
const list2 = opts.sources.length > 0 ? opts.sources.join(", ") : "unknown";
|
|
94991
|
+
const plural = opts.sources.length === 1 ? "an approval outcome" : "approval outcomes";
|
|
94992
|
+
const msg = {
|
|
94993
|
+
type: "inbound",
|
|
94994
|
+
chatId: opts.chatId,
|
|
94995
|
+
...opts.threadId != null ? { threadId: opts.threadId } : {},
|
|
94996
|
+
messageId: ts,
|
|
94997
|
+
user: "gateway",
|
|
94998
|
+
userId: 0,
|
|
94999
|
+
ts,
|
|
95000
|
+
text: `\u26a0\ufe0f Your inbound buffer overflowed while every queued message was ${plural}, ` + `so the oldest had to be dropped: ${list2}. Do NOT keep waiting on it \u2014 ` + `re-check the underlying state directly (e.g. retry the vault read to see ` + `whether the grant exists) and tell the operator plainly what was lost.`,
|
|
95001
|
+
meta: {
|
|
95002
|
+
source: APPROVAL_OUTCOME_DROPPED_SOURCE,
|
|
95003
|
+
agent: opts.agent,
|
|
95004
|
+
...opts.threadId != null ? { message_thread_id: String(opts.threadId) } : {},
|
|
95005
|
+
dropped_sources: list2,
|
|
95006
|
+
dropped_count: String(opts.sources.length)
|
|
95007
|
+
}
|
|
95008
|
+
};
|
|
95009
|
+
return msg;
|
|
95010
|
+
}
|
|
95011
|
+
var APPROVAL_OUTCOME_NOTICE_HOPS = 2;
|
|
95012
|
+
function createApprovalOutcomeDropNotifier(opts) {
|
|
95013
|
+
const log = opts.log ?? ((line) => process.stderr.write(line));
|
|
95014
|
+
const defer = opts.defer ?? ((fn) => queueMicrotask(fn));
|
|
95015
|
+
const hops = opts.hops ?? APPROVAL_OUTCOME_NOTICE_HOPS;
|
|
95016
|
+
const pending = new Map;
|
|
95017
|
+
const scheduled = new Set;
|
|
95018
|
+
return (agent, evicted) => {
|
|
95019
|
+
const label = approvalOutcomeLabel(evicted);
|
|
95020
|
+
log(`telegram gateway: APPROVAL-OUTCOME-DROPPED agent=${agent} source=${label} ` + `chat=${evicted.chatId} ts=${evicted.ts}
|
|
95021
|
+
`);
|
|
95022
|
+
const list2 = pending.get(agent) ?? [];
|
|
95023
|
+
list2.push(label);
|
|
95024
|
+
pending.set(agent, list2);
|
|
95025
|
+
if (scheduled.has(agent))
|
|
95026
|
+
return;
|
|
95027
|
+
scheduled.add(agent);
|
|
95028
|
+
const chatId = evicted.chatId;
|
|
95029
|
+
const threadId = evicted.threadId;
|
|
95030
|
+
const flush = (budget) => {
|
|
95031
|
+
const sources = [...pending.get(agent) ?? []];
|
|
95032
|
+
const before = sources.length;
|
|
95033
|
+
try {
|
|
95034
|
+
opts.push(agent, buildApprovalOutcomeDroppedInbound({
|
|
95035
|
+
agent,
|
|
95036
|
+
chatId,
|
|
95037
|
+
...threadId != null ? { threadId } : {},
|
|
95038
|
+
sources,
|
|
95039
|
+
...opts.nowMs != null ? { nowMs: opts.nowMs() } : {}
|
|
95040
|
+
}));
|
|
95041
|
+
} catch (e) {
|
|
95042
|
+
log(`telegram gateway: APPROVAL-OUTCOME-DROPPED notice push failed: ${String(e)}
|
|
95043
|
+
`);
|
|
95044
|
+
} finally {
|
|
95045
|
+
scheduled.delete(agent);
|
|
95046
|
+
}
|
|
95047
|
+
if (budget > 0 && (pending.get(agent)?.length ?? 0) > before) {
|
|
95048
|
+
scheduled.add(agent);
|
|
95049
|
+
defer(() => flush(budget - 1));
|
|
95050
|
+
} else {
|
|
95051
|
+
pending.delete(agent);
|
|
95052
|
+
}
|
|
95053
|
+
};
|
|
95054
|
+
defer(() => flush(hops));
|
|
95055
|
+
};
|
|
95056
|
+
}
|
|
95057
|
+
|
|
94708
95058
|
// gateway/pending-inbound-buffer.ts
|
|
94709
95059
|
var DEFAULT_PENDING_INBOUND_CAP = 32;
|
|
95060
|
+
var APPROVAL_OUTCOME_PROTECTION_MS = 15 * 60 * 1000;
|
|
95061
|
+
function selectEvictionVictim(q, nowMs3, protectMaxAgeMs = APPROVAL_OUTCOME_PROTECTION_MS) {
|
|
95062
|
+
for (let i = 0;i < q.length; i++) {
|
|
95063
|
+
if (!isApprovalOutcome(q[i]))
|
|
95064
|
+
return { index: i, reason: "non-outcome" };
|
|
95065
|
+
}
|
|
95066
|
+
for (let i = 0;i < q.length; i++) {
|
|
95067
|
+
const ts = q[i].ts;
|
|
95068
|
+
if (typeof ts === "number" && Number.isFinite(ts) && nowMs3 - ts >= protectMaxAgeMs) {
|
|
95069
|
+
return { index: i, reason: "stale-outcome" };
|
|
95070
|
+
}
|
|
95071
|
+
}
|
|
95072
|
+
return { index: 0, reason: "all-outcomes" };
|
|
95073
|
+
}
|
|
94710
95074
|
function redeliverBufferedInbound(buffer, agent, send, spool, onDelivered) {
|
|
94711
95075
|
const pending = buffer.drain(agent);
|
|
94712
95076
|
let redelivered = 0;
|
|
@@ -94815,8 +95179,10 @@ function createPendingInboundBuffer(opts = {}) {
|
|
|
94815
95179
|
const cap = opts.capPerAgent ?? DEFAULT_PENDING_INBOUND_CAP;
|
|
94816
95180
|
const log = opts.log ?? ((line) => process.stderr.write(line));
|
|
94817
95181
|
const spool = opts.spool;
|
|
95182
|
+
const now = opts.now ?? (() => Date.now());
|
|
95183
|
+
const protectionMs = opts.approvalOutcomeProtectionMs ?? APPROVAL_OUTCOME_PROTECTION_MS;
|
|
94818
95184
|
const queues = new Map;
|
|
94819
|
-
|
|
95185
|
+
const buffer = {
|
|
94820
95186
|
push(agent, msg) {
|
|
94821
95187
|
let q = queues.get(agent);
|
|
94822
95188
|
if (q == null) {
|
|
@@ -94825,14 +95191,19 @@ function createPendingInboundBuffer(opts = {}) {
|
|
|
94825
95191
|
}
|
|
94826
95192
|
let evicted = false;
|
|
94827
95193
|
if (q.length >= cap) {
|
|
94828
|
-
const
|
|
95194
|
+
const { index: index2, reason } = selectEvictionVictim(q, now(), protectionMs);
|
|
95195
|
+
const dropped = q.splice(index2, 1)[0];
|
|
94829
95196
|
evicted = true;
|
|
94830
|
-
log(`pending-inbound-buffer: agent=${agent} cap=${cap} reached \u2014 ` + `dropped
|
|
95197
|
+
log(`pending-inbound-buffer: agent=${agent} cap=${cap} reached \u2014 ` + `dropped entry idx=${index2} reason=${reason} ` + `source=${dropped?.meta?.source ?? "-"} ts=${dropped?.ts ?? "-"}
|
|
94831
95198
|
`);
|
|
94832
|
-
if (dropped != null
|
|
94833
|
-
|
|
94834
|
-
|
|
94835
|
-
|
|
95199
|
+
if (dropped != null) {
|
|
95200
|
+
const critical = reason !== "non-outcome";
|
|
95201
|
+
const cb = critical ? onEvictCritical : opts.onEvict;
|
|
95202
|
+
if (cb != null) {
|
|
95203
|
+
try {
|
|
95204
|
+
cb(agent, dropped);
|
|
95205
|
+
} catch {}
|
|
95206
|
+
}
|
|
94836
95207
|
}
|
|
94837
95208
|
}
|
|
94838
95209
|
q.push(msg);
|
|
@@ -94866,6 +95237,13 @@ function createPendingInboundBuffer(opts = {}) {
|
|
|
94866
95237
|
},
|
|
94867
95238
|
beforeRedeliver: opts.beforeRedeliver
|
|
94868
95239
|
};
|
|
95240
|
+
const onEvictCritical = opts.onEvictCritical ?? createApprovalOutcomeDropNotifier({
|
|
95241
|
+
push: (a, m) => {
|
|
95242
|
+
buffer.push(a, m);
|
|
95243
|
+
},
|
|
95244
|
+
log
|
|
95245
|
+
});
|
|
95246
|
+
return buffer;
|
|
94869
95247
|
}
|
|
94870
95248
|
|
|
94871
95249
|
// gateway/represent-guard.ts
|
|
@@ -94928,6 +95306,7 @@ function makeSessionBusyDrainDeferral(boundMs, staleGapMs = DEFAULT_DRAIN_DEFER_
|
|
|
94928
95306
|
}
|
|
94929
95307
|
|
|
94930
95308
|
// gateway/pending-inbound-buffer.ts
|
|
95309
|
+
var APPROVAL_OUTCOME_PROTECTION_MS2 = 15 * 60 * 1000;
|
|
94931
95310
|
function redeliverBufferedInbound2(buffer, agent, send, spool, onDelivered) {
|
|
94932
95311
|
const pending = buffer.drain(agent);
|
|
94933
95312
|
let redelivered = 0;
|
|
@@ -97832,7 +98211,7 @@ function purgeStaleTurnsForChat(chatId, keys, purger, isStale = () => true) {
|
|
|
97832
98211
|
}
|
|
97833
98212
|
|
|
97834
98213
|
// gateway/compaction-marker.ts
|
|
97835
|
-
import { statSync as statSync17, unlinkSync as
|
|
98214
|
+
import { statSync as statSync17, unlinkSync as unlinkSync22 } from "node:fs";
|
|
97836
98215
|
import { homedir as homedir17 } from "node:os";
|
|
97837
98216
|
import { join as join56 } from "node:path";
|
|
97838
98217
|
var COMPACTION_MARKER_FILE = "compaction-in-flight.json";
|
|
@@ -97849,7 +98228,7 @@ function readCompactionMarkerAgeMs(stateDir, now) {
|
|
|
97849
98228
|
}
|
|
97850
98229
|
function removeCompactionMarker(stateDir) {
|
|
97851
98230
|
try {
|
|
97852
|
-
|
|
98231
|
+
unlinkSync22(join56(stateDir, COMPACTION_MARKER_FILE));
|
|
97853
98232
|
} catch {}
|
|
97854
98233
|
}
|
|
97855
98234
|
|
|
@@ -98609,6 +98988,26 @@ function maybeFireWarmup(ctx) {
|
|
|
98609
98988
|
}
|
|
98610
98989
|
|
|
98611
98990
|
// gateway/self-improve-proposal-wiring.ts
|
|
98991
|
+
function buildEvalCaseSuppressedInbound(opts) {
|
|
98992
|
+
const ts = opts.nowMs ?? Date.now();
|
|
98993
|
+
return {
|
|
98994
|
+
type: "inbound",
|
|
98995
|
+
chatId: opts.chatId,
|
|
98996
|
+
...opts.threadId != null ? { threadId: opts.threadId } : {},
|
|
98997
|
+
messageId: ts,
|
|
98998
|
+
user: "self-improve",
|
|
98999
|
+
userId: 0,
|
|
99000
|
+
ts,
|
|
99001
|
+
text: `\u2139\ufe0f Your proposed eval case for \`${opts.skillSlug}\` was NOT posted as a ` + `card: the operator already dismissed this exact case, and the dismissal ` + `is still in effect. This is EXPECTED and is not an error or a failure on ` + `your part \u2014 nothing was written and no card is pending, so do NOT wait ` + `for an approval tap. Do NOT re-propose this case. Carry on with the ` + `original task without it.`,
|
|
99002
|
+
meta: {
|
|
99003
|
+
source: "eval_case_suppressed",
|
|
99004
|
+
agent: opts.agent,
|
|
99005
|
+
...opts.threadId != null ? { message_thread_id: String(opts.threadId) } : {},
|
|
99006
|
+
skill_slug: opts.skillSlug,
|
|
99007
|
+
fingerprint: opts.fingerprint
|
|
99008
|
+
}
|
|
99009
|
+
};
|
|
99010
|
+
}
|
|
98612
99011
|
function handlePostSkillProposal(msg, deps) {
|
|
98613
99012
|
const { bot, assertAllowedChat, swallowingApiCall } = deps;
|
|
98614
99013
|
const self = process.env.SWITCHROOM_AGENT_NAME;
|
|
@@ -98665,8 +99064,28 @@ function handlePostSkillProposal(msg, deps) {
|
|
|
98665
99064
|
process.stderr.write(`telegram gateway: post_skill_proposal agent=${msg.agentName} chat=${msg.chatId} ` + `proposal=${proposal.id} slug=${proposal.skill_slug} new=${proposal.is_new}
|
|
98666
99065
|
`);
|
|
98667
99066
|
}
|
|
99067
|
+
function isEvalCaseProposalSuppressed(stateDir, candidate, opts = {}) {
|
|
99068
|
+
if (typeof candidate.fingerprint !== "string" || candidate.fingerprint.length === 0) {
|
|
99069
|
+
return false;
|
|
99070
|
+
}
|
|
99071
|
+
const now = (opts.now ?? Date.now)();
|
|
99072
|
+
const ttl = opts.ttlMs ?? REJECTION_TTL_MS;
|
|
99073
|
+
for (const p of readEvalCaseProposals(stateDir)) {
|
|
99074
|
+
if (p.status !== "rejected")
|
|
99075
|
+
continue;
|
|
99076
|
+
if (p.skill_slug !== candidate.skillSlug)
|
|
99077
|
+
continue;
|
|
99078
|
+
if (p.fingerprint !== candidate.fingerprint)
|
|
99079
|
+
continue;
|
|
99080
|
+
const age = now - new Date(p.created_at).getTime();
|
|
99081
|
+
if (!Number.isFinite(age) || age > ttl)
|
|
99082
|
+
continue;
|
|
99083
|
+
return true;
|
|
99084
|
+
}
|
|
99085
|
+
return false;
|
|
99086
|
+
}
|
|
98668
99087
|
function handlePostEvalCaseProposal(msg, deps) {
|
|
98669
|
-
const { bot, assertAllowedChat, swallowingApiCall } = deps;
|
|
99088
|
+
const { bot, assertAllowedChat, swallowingApiCall, deliverResumeSyntheticOrBuffer } = deps;
|
|
98670
99089
|
const self = process.env.SWITCHROOM_AGENT_NAME;
|
|
98671
99090
|
if (self && msg.agentName !== self) {
|
|
98672
99091
|
process.stderr.write(`telegram gateway: post_eval_case_proposal rejected \u2014 agent mismatch (${msg.agentName} != ${self})
|
|
@@ -98683,6 +99102,21 @@ function handlePostEvalCaseProposal(msg, deps) {
|
|
|
98683
99102
|
const stateDir = process.env.TELEGRAM_STATE_DIR;
|
|
98684
99103
|
if (stateDir == null || stateDir.length === 0) {
|
|
98685
99104
|
process.stderr.write(`telegram gateway: post_eval_case_proposal: TELEGRAM_STATE_DIR unset, skipping
|
|
99105
|
+
`);
|
|
99106
|
+
return;
|
|
99107
|
+
}
|
|
99108
|
+
if (isEvalCaseProposalSuppressed(stateDir, {
|
|
99109
|
+
skillSlug: msg.skillSlug,
|
|
99110
|
+
fingerprint: msg.fingerprint
|
|
99111
|
+
})) {
|
|
99112
|
+
const delivered = deliverResumeSyntheticOrBuffer(msg.agentName, buildEvalCaseSuppressedInbound({
|
|
99113
|
+
agent: msg.agentName,
|
|
99114
|
+
chatId: msg.chatId,
|
|
99115
|
+
...msg.threadId != null ? { threadId: msg.threadId } : {},
|
|
99116
|
+
skillSlug: msg.skillSlug,
|
|
99117
|
+
fingerprint: msg.fingerprint
|
|
99118
|
+
}));
|
|
99119
|
+
process.stderr.write(`telegram gateway: post_eval_case_proposal suppressed (dismissed before) ` + `slug=${msg.skillSlug} fp=${msg.fingerprint} delivered=${delivered}
|
|
98686
99120
|
`);
|
|
98687
99121
|
return;
|
|
98688
99122
|
}
|
|
@@ -99214,15 +99648,15 @@ function escapeBody2(s) {
|
|
|
99214
99648
|
}
|
|
99215
99649
|
|
|
99216
99650
|
// gateway/pid-file.ts
|
|
99217
|
-
import { writeFileSync as
|
|
99651
|
+
import { writeFileSync as writeFileSync37, readFileSync as readFileSync43, unlinkSync as unlinkSync23, renameSync as renameSync21 } from "node:fs";
|
|
99218
99652
|
function writePidFile(path3, record) {
|
|
99219
99653
|
const tmp = `${path3}.tmp-${process.pid}-${Date.now()}`;
|
|
99220
|
-
|
|
99221
|
-
|
|
99654
|
+
writeFileSync37(tmp, JSON.stringify(record), "utf-8");
|
|
99655
|
+
renameSync21(tmp, path3);
|
|
99222
99656
|
}
|
|
99223
99657
|
function clearPidFile(path3) {
|
|
99224
99658
|
try {
|
|
99225
|
-
|
|
99659
|
+
unlinkSync23(path3);
|
|
99226
99660
|
} catch {}
|
|
99227
99661
|
}
|
|
99228
99662
|
|
|
@@ -99439,11 +99873,11 @@ function safeCount(fn) {
|
|
|
99439
99873
|
}
|
|
99440
99874
|
|
|
99441
99875
|
// gateway/session-marker.ts
|
|
99442
|
-
import { writeFileSync as
|
|
99876
|
+
import { writeFileSync as writeFileSync38, readFileSync as readFileSync45, renameSync as renameSync22, unlinkSync as unlinkSync24 } from "node:fs";
|
|
99443
99877
|
function writeSessionMarker(path3, marker) {
|
|
99444
99878
|
const tmp = `${path3}.tmp-${process.pid}-${Date.now()}`;
|
|
99445
|
-
|
|
99446
|
-
|
|
99879
|
+
writeFileSync38(tmp, JSON.stringify(marker), "utf-8");
|
|
99880
|
+
renameSync22(tmp, path3);
|
|
99447
99881
|
}
|
|
99448
99882
|
function readSessionMarker(path3) {
|
|
99449
99883
|
try {
|
|
@@ -99469,12 +99903,12 @@ function shouldFireRestartBanner(input) {
|
|
|
99469
99903
|
}
|
|
99470
99904
|
|
|
99471
99905
|
// gateway/clean-shutdown-marker.ts
|
|
99472
|
-
import { writeFileSync as
|
|
99906
|
+
import { writeFileSync as writeFileSync39, readFileSync as readFileSync46, renameSync as renameSync23, unlinkSync as unlinkSync25 } from "node:fs";
|
|
99473
99907
|
var DEFAULT_MAX_AGE_MS = 60000;
|
|
99474
99908
|
function writeCleanShutdownMarker(path3, marker) {
|
|
99475
99909
|
const tmp = `${path3}.tmp-${process.pid}-${Date.now()}`;
|
|
99476
|
-
|
|
99477
|
-
|
|
99910
|
+
writeFileSync39(tmp, JSON.stringify(marker), "utf-8");
|
|
99911
|
+
renameSync23(tmp, path3);
|
|
99478
99912
|
}
|
|
99479
99913
|
function readCleanShutdownMarker(path3) {
|
|
99480
99914
|
try {
|
|
@@ -99493,7 +99927,7 @@ function readCleanShutdownMarker(path3) {
|
|
|
99493
99927
|
}
|
|
99494
99928
|
function clearCleanShutdownMarker(path3) {
|
|
99495
99929
|
try {
|
|
99496
|
-
|
|
99930
|
+
unlinkSync25(path3);
|
|
99497
99931
|
} catch {}
|
|
99498
99932
|
}
|
|
99499
99933
|
function shouldSuppressRecoveryBanner(marker, now, maxAgeMs = DEFAULT_MAX_AGE_MS) {
|
|
@@ -101409,31 +101843,31 @@ function startSubagentWatcher(config) {
|
|
|
101409
101843
|
// ../src/worktree/registry.ts
|
|
101410
101844
|
import {
|
|
101411
101845
|
mkdirSync as mkdirSync41,
|
|
101412
|
-
writeFileSync as
|
|
101846
|
+
writeFileSync as writeFileSync40,
|
|
101413
101847
|
readFileSync as readFileSync48,
|
|
101414
101848
|
readdirSync as readdirSync13,
|
|
101415
|
-
unlinkSync as
|
|
101849
|
+
unlinkSync as unlinkSync26,
|
|
101416
101850
|
existsSync as existsSync48,
|
|
101417
|
-
renameSync as
|
|
101851
|
+
renameSync as renameSync24
|
|
101418
101852
|
} from "node:fs";
|
|
101419
101853
|
import { join as join58, resolve as resolve10 } from "node:path";
|
|
101420
101854
|
import { homedir as homedir18 } from "node:os";
|
|
101421
|
-
function
|
|
101855
|
+
function registryDir2() {
|
|
101422
101856
|
return resolve10(process.env.SWITCHROOM_WORKTREE_DIR ?? join58(homedir18(), ".switchroom", "worktrees"));
|
|
101423
101857
|
}
|
|
101424
101858
|
function recordPath(id) {
|
|
101425
|
-
return join58(
|
|
101859
|
+
return join58(registryDir2(), `${id}.json`);
|
|
101426
101860
|
}
|
|
101427
101861
|
function ensureDir4() {
|
|
101428
|
-
mkdirSync41(
|
|
101862
|
+
mkdirSync41(registryDir2(), { recursive: true });
|
|
101429
101863
|
}
|
|
101430
|
-
function
|
|
101864
|
+
function writeRecord2(record) {
|
|
101431
101865
|
ensureDir4();
|
|
101432
101866
|
const target = recordPath(record.id);
|
|
101433
101867
|
const tmp = `${target}.tmp${process.pid}`;
|
|
101434
|
-
|
|
101868
|
+
writeFileSync40(tmp, JSON.stringify(record, null, 2) + `
|
|
101435
101869
|
`, { mode: 384 });
|
|
101436
|
-
|
|
101870
|
+
renameSync24(tmp, target);
|
|
101437
101871
|
}
|
|
101438
101872
|
function readRecord(id) {
|
|
101439
101873
|
const path3 = recordPath(id);
|
|
@@ -101446,7 +101880,7 @@ function readRecord(id) {
|
|
|
101446
101880
|
}
|
|
101447
101881
|
function listRecords() {
|
|
101448
101882
|
ensureDir4();
|
|
101449
|
-
const dir =
|
|
101883
|
+
const dir = registryDir2();
|
|
101450
101884
|
const records = [];
|
|
101451
101885
|
for (const entry of readdirSync13(dir)) {
|
|
101452
101886
|
if (!entry.endsWith(".json"))
|
|
@@ -101465,7 +101899,7 @@ function touchHeartbeat(id, onAfterRead) {
|
|
|
101465
101899
|
onAfterRead?.();
|
|
101466
101900
|
if (!recordExists(id))
|
|
101467
101901
|
return;
|
|
101468
|
-
|
|
101902
|
+
writeRecord2({ ...rec, heartbeatAt: new Date().toISOString() });
|
|
101469
101903
|
}
|
|
101470
101904
|
function recordExists(id) {
|
|
101471
101905
|
return existsSync48(recordPath(id));
|
|
@@ -101845,7 +102279,7 @@ function maybeRenderUpdateAnnouncement(opts = {}) {
|
|
|
101845
102279
|
|
|
101846
102280
|
// issues-card.ts
|
|
101847
102281
|
init_card_format();
|
|
101848
|
-
import { readFileSync as readFileSync56, writeFileSync as
|
|
102282
|
+
import { readFileSync as readFileSync56, writeFileSync as writeFileSync45 } from "node:fs";
|
|
101849
102283
|
var SEVERITY_EMOJI = {
|
|
101850
102284
|
info: "\u2139\ufe0f",
|
|
101851
102285
|
warn: "\u26a0\ufe0f",
|
|
@@ -101953,7 +102387,7 @@ function readPersistedMessageId(path3, log) {
|
|
|
101953
102387
|
}
|
|
101954
102388
|
function writePersistedMessageId(path3, messageId, log) {
|
|
101955
102389
|
try {
|
|
101956
|
-
|
|
102390
|
+
writeFileSync45(path3, JSON.stringify({ messageId }) + `
|
|
101957
102391
|
`, { mode: 384 });
|
|
101958
102392
|
} catch (err) {
|
|
101959
102393
|
log(`issues-card: persist write failed (${err.message})`);
|
|
@@ -102057,10 +102491,10 @@ import {
|
|
|
102057
102491
|
openSync as openSync15,
|
|
102058
102492
|
readdirSync as readdirSync15,
|
|
102059
102493
|
readFileSync as readFileSync57,
|
|
102060
|
-
renameSync as
|
|
102494
|
+
renameSync as renameSync27,
|
|
102061
102495
|
statSync as statSync20,
|
|
102062
|
-
unlinkSync as
|
|
102063
|
-
writeFileSync as
|
|
102496
|
+
unlinkSync as unlinkSync27,
|
|
102497
|
+
writeFileSync as writeFileSync46,
|
|
102064
102498
|
writeSync as writeSync8
|
|
102065
102499
|
} from "node:fs";
|
|
102066
102500
|
import { join as join64 } from "node:path";
|
|
@@ -102143,8 +102577,8 @@ function writeAll(stateDir, events) {
|
|
|
102143
102577
|
const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
|
|
102144
102578
|
`) + `
|
|
102145
102579
|
`;
|
|
102146
|
-
|
|
102147
|
-
|
|
102580
|
+
writeFileSync46(tmp, body, "utf-8");
|
|
102581
|
+
renameSync27(tmp, path3);
|
|
102148
102582
|
}
|
|
102149
102583
|
var ORPHAN_TMP_TTL_MS = 60000;
|
|
102150
102584
|
var TMP_PREFIX = `${ISSUES_FILE}.tmp-`;
|
|
@@ -102163,7 +102597,7 @@ function sweepOrphanTmpFiles(stateDir) {
|
|
|
102163
102597
|
try {
|
|
102164
102598
|
const stat = statSync20(tmpPath2);
|
|
102165
102599
|
if (stat.mtimeMs < cutoff) {
|
|
102166
|
-
|
|
102600
|
+
unlinkSync27(tmpPath2);
|
|
102167
102601
|
}
|
|
102168
102602
|
} catch {}
|
|
102169
102603
|
}
|
|
@@ -102199,7 +102633,7 @@ function withLock(stateDir, fn) {
|
|
|
102199
102633
|
closeSync15(fd);
|
|
102200
102634
|
} catch {}
|
|
102201
102635
|
try {
|
|
102202
|
-
|
|
102636
|
+
unlinkSync27(lockPath);
|
|
102203
102637
|
} catch {}
|
|
102204
102638
|
}
|
|
102205
102639
|
}
|
|
@@ -102213,13 +102647,13 @@ function tryStealStaleLock(lockPath) {
|
|
|
102213
102647
|
const pid = Number(pidStr);
|
|
102214
102648
|
if (!Number.isFinite(pid) || pid <= 0) {
|
|
102215
102649
|
try {
|
|
102216
|
-
|
|
102650
|
+
unlinkSync27(lockPath);
|
|
102217
102651
|
} catch {}
|
|
102218
102652
|
return true;
|
|
102219
102653
|
}
|
|
102220
102654
|
if (pid === process.pid) {
|
|
102221
102655
|
try {
|
|
102222
|
-
|
|
102656
|
+
unlinkSync27(lockPath);
|
|
102223
102657
|
} catch {}
|
|
102224
102658
|
return true;
|
|
102225
102659
|
}
|
|
@@ -102234,7 +102668,7 @@ function tryStealStaleLock(lockPath) {
|
|
|
102234
102668
|
return false;
|
|
102235
102669
|
}
|
|
102236
102670
|
try {
|
|
102237
|
-
|
|
102671
|
+
unlinkSync27(lockPath);
|
|
102238
102672
|
} catch {}
|
|
102239
102673
|
return true;
|
|
102240
102674
|
}
|
|
@@ -103436,7 +103870,7 @@ function isDiffPreApproved(agentName3, unifiedDiff, deps) {
|
|
|
103436
103870
|
|
|
103437
103871
|
// credits-watch.ts
|
|
103438
103872
|
init_card_format();
|
|
103439
|
-
import { readFileSync as readFileSync58, writeFileSync as
|
|
103873
|
+
import { readFileSync as readFileSync58, writeFileSync as writeFileSync47, existsSync as existsSync56, mkdirSync as mkdirSync47 } from "fs";
|
|
103440
103874
|
import { join as join67 } from "path";
|
|
103441
103875
|
var STATE_FILE = "credits-watch.json";
|
|
103442
103876
|
var DEFAULT_CREDIT_FATAL_REASONS = new Set;
|
|
@@ -103560,14 +103994,14 @@ function loadCreditState(stateDir) {
|
|
|
103560
103994
|
function saveCreditState(stateDir, state7) {
|
|
103561
103995
|
mkdirSync47(stateDir, { recursive: true });
|
|
103562
103996
|
const path3 = join67(stateDir, STATE_FILE);
|
|
103563
|
-
|
|
103997
|
+
writeFileSync47(path3, JSON.stringify(state7, null, 2) + `
|
|
103564
103998
|
`, { mode: 384 });
|
|
103565
103999
|
}
|
|
103566
104000
|
|
|
103567
104001
|
// quota-watch.ts
|
|
103568
104002
|
init_auth_snapshot_format();
|
|
103569
104003
|
init_card_format();
|
|
103570
|
-
import { readFileSync as readFileSync59, writeFileSync as
|
|
104004
|
+
import { readFileSync as readFileSync59, writeFileSync as writeFileSync48, existsSync as existsSync57, mkdirSync as mkdirSync48 } from "fs";
|
|
103571
104005
|
import { join as join68 } from "path";
|
|
103572
104006
|
var STATE_FILE2 = "quota-watch.json";
|
|
103573
104007
|
function emptyQuotaWatchState() {
|
|
@@ -103829,7 +104263,7 @@ function loadQuotaWatchState(stateDir) {
|
|
|
103829
104263
|
function saveQuotaWatchState(stateDir, state7) {
|
|
103830
104264
|
mkdirSync48(stateDir, { recursive: true });
|
|
103831
104265
|
const path3 = join68(stateDir, STATE_FILE2);
|
|
103832
|
-
|
|
104266
|
+
writeFileSync48(path3, JSON.stringify(state7, null, 2) + `
|
|
103833
104267
|
`, { mode: 384 });
|
|
103834
104268
|
}
|
|
103835
104269
|
function patchQuotaWatchState(current, accountLabel, accountState) {
|
|
@@ -103882,7 +104316,7 @@ import {
|
|
|
103882
104316
|
openSync as openSync16,
|
|
103883
104317
|
readFileSync as readFileSync60,
|
|
103884
104318
|
statSync as statSync22,
|
|
103885
|
-
unlinkSync as
|
|
104319
|
+
unlinkSync as unlinkSync28,
|
|
103886
104320
|
utimesSync as utimesSync2
|
|
103887
104321
|
} from "node:fs";
|
|
103888
104322
|
import { join as join69 } from "node:path";
|
|
@@ -103891,7 +104325,7 @@ var TURN_ACTIVE_HARD_TTL_MS2 = 10 * 60000;
|
|
|
103891
104325
|
var TURN_ACTIVE_IDLE_SWEEP_MS = 60000;
|
|
103892
104326
|
function removeTurnActiveMarker2(stateDir) {
|
|
103893
104327
|
try {
|
|
103894
|
-
|
|
104328
|
+
unlinkSync28(join69(stateDir, TURN_ACTIVE_MARKER_FILE2));
|
|
103895
104329
|
} catch {}
|
|
103896
104330
|
}
|
|
103897
104331
|
function sweepStaleTurnActiveMarker(stateDir, opts) {
|
|
@@ -103910,7 +104344,7 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
|
|
|
103910
104344
|
try {
|
|
103911
104345
|
payload = readFileSync60(path3, "utf8");
|
|
103912
104346
|
} catch {}
|
|
103913
|
-
|
|
104347
|
+
unlinkSync28(path3);
|
|
103914
104348
|
if (opts.onRemove) {
|
|
103915
104349
|
try {
|
|
103916
104350
|
opts.onRemove({
|
|
@@ -103972,9 +104406,9 @@ import {
|
|
|
103972
104406
|
fsyncSync as fsyncSync6,
|
|
103973
104407
|
openSync as openSync17,
|
|
103974
104408
|
readFileSync as readFileSync61,
|
|
103975
|
-
renameSync as
|
|
103976
|
-
unlinkSync as
|
|
103977
|
-
writeFileSync as
|
|
104409
|
+
renameSync as renameSync28,
|
|
104410
|
+
unlinkSync as unlinkSync29,
|
|
104411
|
+
writeFileSync as writeFileSync49
|
|
103978
104412
|
} from "node:fs";
|
|
103979
104413
|
import { join as join71 } from "node:path";
|
|
103980
104414
|
var BOOT_BEACON_FILE = "gateway-beacon.json";
|
|
@@ -104081,12 +104515,12 @@ function writeBootBeaconFile(stateDir, beacon) {
|
|
|
104081
104515
|
try {
|
|
104082
104516
|
mkdirStateSync(stateDir, { recursive: true, mode: 448 });
|
|
104083
104517
|
fd = openSync17(tmp, "w", 384);
|
|
104084
|
-
|
|
104518
|
+
writeFileSync49(fd, serializeBootBeacon(beacon));
|
|
104085
104519
|
adoptStateOwnershipFd(fd, stateDir);
|
|
104086
104520
|
fsyncSync6(fd);
|
|
104087
104521
|
closeSync17(fd);
|
|
104088
104522
|
fd = undefined;
|
|
104089
|
-
|
|
104523
|
+
renameSync28(tmp, path3);
|
|
104090
104524
|
return true;
|
|
104091
104525
|
} catch {
|
|
104092
104526
|
if (fd !== undefined) {
|
|
@@ -104095,7 +104529,7 @@ function writeBootBeaconFile(stateDir, beacon) {
|
|
|
104095
104529
|
} catch {}
|
|
104096
104530
|
}
|
|
104097
104531
|
try {
|
|
104098
|
-
|
|
104532
|
+
unlinkSync29(tmp);
|
|
104099
104533
|
} catch {}
|
|
104100
104534
|
return false;
|
|
104101
104535
|
}
|
|
@@ -104467,10 +104901,10 @@ function startOutboxSweep(deps) {
|
|
|
104467
104901
|
}
|
|
104468
104902
|
|
|
104469
104903
|
// ../src/build-info.ts
|
|
104470
|
-
var VERSION2 = "0.21.
|
|
104471
|
-
var COMMIT_SHA = "
|
|
104472
|
-
var COMMIT_DATE = "2026-08-
|
|
104473
|
-
var LATEST_PR =
|
|
104904
|
+
var VERSION2 = "0.21.9";
|
|
104905
|
+
var COMMIT_SHA = "08262924";
|
|
104906
|
+
var COMMIT_DATE = "2026-08-13T12:13:46Z";
|
|
104907
|
+
var LATEST_PR = 4686;
|
|
104474
104908
|
var COMMITS_AHEAD_OF_TAG = 0;
|
|
104475
104909
|
|
|
104476
104910
|
// gateway/boot-version.ts
|
|
@@ -105852,7 +106286,7 @@ function selectResumeBuilder(endedVia, opts) {
|
|
|
105852
106286
|
}
|
|
105853
106287
|
|
|
105854
106288
|
// gateway/boot-briefing-wiring.ts
|
|
105855
|
-
import { existsSync as existsSync60, readFileSync as readFileSync63, writeFileSync as
|
|
106289
|
+
import { existsSync as existsSync60, readFileSync as readFileSync63, writeFileSync as writeFileSync50 } from "node:fs";
|
|
105856
106290
|
import { join as join74 } from "node:path";
|
|
105857
106291
|
init_history();
|
|
105858
106292
|
|
|
@@ -106208,7 +106642,7 @@ async function maybeQueueBootBriefing(opts) {
|
|
|
106208
106642
|
if (!bootId)
|
|
106209
106643
|
return;
|
|
106210
106644
|
try {
|
|
106211
|
-
|
|
106645
|
+
writeFileSync50(genMarkerPath, `${bootId}
|
|
106212
106646
|
`);
|
|
106213
106647
|
} catch {}
|
|
106214
106648
|
};
|
|
@@ -106282,7 +106716,7 @@ async function maybeQueueBootBriefing(opts) {
|
|
|
106282
106716
|
}
|
|
106283
106717
|
|
|
106284
106718
|
// gateway/pending-turn-env.ts
|
|
106285
|
-
import { existsSync as existsSync61, renameSync as
|
|
106719
|
+
import { existsSync as existsSync61, renameSync as renameSync29, rmSync as rmSync8, writeFileSync as writeFileSync51 } from "node:fs";
|
|
106286
106720
|
import { join as join75 } from "node:path";
|
|
106287
106721
|
function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.write(l)) {
|
|
106288
106722
|
const pendingEnvPath = join75(agentDir, ".pending-turn.env");
|
|
@@ -106299,10 +106733,10 @@ function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.writ
|
|
|
106299
106733
|
pending.interrupt_reason != null ? `SWITCHROOM_PENDING_INTERRUPT_REASON=${pending.interrupt_reason}` : `SWITCHROOM_PENDING_INTERRUPT_REASON=`
|
|
106300
106734
|
];
|
|
106301
106735
|
const pendingEnvTmp = `${pendingEnvPath}.tmp-${process.pid}`;
|
|
106302
|
-
|
|
106736
|
+
writeFileSync51(pendingEnvTmp, lines.join(`
|
|
106303
106737
|
`) + `
|
|
106304
106738
|
`, { mode: 384 });
|
|
106305
|
-
|
|
106739
|
+
renameSync29(pendingEnvTmp, pendingEnvPath);
|
|
106306
106740
|
log(`telegram gateway: pending-turn env written to ${pendingEnvPath} ` + `turnKey=${pending.turn_key} endedVia=${pending.ended_via ?? "open"}
|
|
106307
106741
|
`);
|
|
106308
106742
|
} else if (existsSync61(pendingEnvPath)) {
|
|
@@ -106316,8 +106750,184 @@ function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.writ
|
|
|
106316
106750
|
}
|
|
106317
106751
|
}
|
|
106318
106752
|
|
|
106753
|
+
// gateway/agent-process-liveness.ts
|
|
106754
|
+
import { existsSync as existsSync62, readFileSync as readFileSync64, writeFileSync as writeFileSync52, renameSync as renameSync30, unlinkSync as unlinkSync30, readdirSync as readdirSync16 } from "node:fs";
|
|
106755
|
+
import { join as join76, dirname as dirname28, basename as basename18 } from "node:path";
|
|
106756
|
+
var AGENT_PROCESS_RECORD_FILE = "agent-process.json";
|
|
106757
|
+
var BOOT_RESUME_DONE_FILE = ".boot-resume-done";
|
|
106758
|
+
function parseProcStat(raw) {
|
|
106759
|
+
const close = raw.lastIndexOf(") ");
|
|
106760
|
+
const open = raw.indexOf(" (");
|
|
106761
|
+
if (close < 0 || open < 0 || close < open)
|
|
106762
|
+
return null;
|
|
106763
|
+
const comm = raw.slice(open + 2, close);
|
|
106764
|
+
const rest = raw.slice(close + 2).trim().split(/\s+/);
|
|
106765
|
+
const state7 = rest[0];
|
|
106766
|
+
const starttime = rest[19];
|
|
106767
|
+
if (state7 == null || state7.length === 0)
|
|
106768
|
+
return null;
|
|
106769
|
+
if (starttime == null || !/^\d+$/.test(starttime))
|
|
106770
|
+
return null;
|
|
106771
|
+
return { comm, state: state7, starttime };
|
|
106772
|
+
}
|
|
106773
|
+
function readProcIdentity(pid, procRoot = "/proc") {
|
|
106774
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
106775
|
+
return null;
|
|
106776
|
+
let identity;
|
|
106777
|
+
try {
|
|
106778
|
+
identity = parseProcStat(readFileSync64(join76(procRoot, String(pid), "stat"), "utf8"));
|
|
106779
|
+
} catch {
|
|
106780
|
+
return null;
|
|
106781
|
+
}
|
|
106782
|
+
if (identity != null && identity.state === "Z")
|
|
106783
|
+
return null;
|
|
106784
|
+
return identity;
|
|
106785
|
+
}
|
|
106786
|
+
function readAgentProcessRecord(path3) {
|
|
106787
|
+
let parsed;
|
|
106788
|
+
try {
|
|
106789
|
+
parsed = JSON.parse(readFileSync64(path3, "utf8"));
|
|
106790
|
+
} catch {
|
|
106791
|
+
return null;
|
|
106792
|
+
}
|
|
106793
|
+
if (parsed == null || typeof parsed !== "object")
|
|
106794
|
+
return null;
|
|
106795
|
+
const o = parsed;
|
|
106796
|
+
const pid = typeof o.pid === "number" ? o.pid : Number(o.pid);
|
|
106797
|
+
const starttime = typeof o.starttime === "string" ? o.starttime : String(o.starttime ?? "");
|
|
106798
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
106799
|
+
return null;
|
|
106800
|
+
if (!/^\d+$/.test(starttime))
|
|
106801
|
+
return null;
|
|
106802
|
+
const rec = { pid, starttime };
|
|
106803
|
+
if (typeof o.comm === "string" && o.comm.length > 0)
|
|
106804
|
+
rec.comm = o.comm;
|
|
106805
|
+
if (typeof o.boot_at === "number" && Number.isFinite(o.boot_at))
|
|
106806
|
+
rec.boot_at = o.boot_at;
|
|
106807
|
+
return rec;
|
|
106808
|
+
}
|
|
106809
|
+
function bootResumeDonePath(stateDir) {
|
|
106810
|
+
return join76(stateDir, BOOT_RESUME_DONE_FILE);
|
|
106811
|
+
}
|
|
106812
|
+
function containerBootIdentity(procRoot = "/proc") {
|
|
106813
|
+
return readProcIdentity(1, procRoot)?.starttime ?? null;
|
|
106814
|
+
}
|
|
106815
|
+
function readBootResumeSentinel(path3, opts = {}) {
|
|
106816
|
+
let raw;
|
|
106817
|
+
try {
|
|
106818
|
+
if (!existsSync62(path3))
|
|
106819
|
+
return { present: false, stale: false };
|
|
106820
|
+
raw = readFileSync64(path3, "utf8");
|
|
106821
|
+
} catch {
|
|
106822
|
+
return { present: false, stale: false };
|
|
106823
|
+
}
|
|
106824
|
+
let stamped = null;
|
|
106825
|
+
try {
|
|
106826
|
+
const parsed = JSON.parse(raw);
|
|
106827
|
+
if (parsed != null && typeof parsed === "object" && typeof parsed.boot === "string" && parsed.boot.length > 0) {
|
|
106828
|
+
stamped = parsed.boot;
|
|
106829
|
+
}
|
|
106830
|
+
} catch {}
|
|
106831
|
+
const live = containerBootIdentity(opts.procRoot);
|
|
106832
|
+
if (stamped != null && live != null && stamped !== live)
|
|
106833
|
+
return { present: true, stale: true };
|
|
106834
|
+
return { present: true, stale: false };
|
|
106835
|
+
}
|
|
106836
|
+
function sweepStrayTmps(path3) {
|
|
106837
|
+
const prefix = `${basename18(path3)}.tmp.`;
|
|
106838
|
+
try {
|
|
106839
|
+
for (const name of readdirSync16(dirname28(path3))) {
|
|
106840
|
+
if (!name.startsWith(prefix))
|
|
106841
|
+
continue;
|
|
106842
|
+
try {
|
|
106843
|
+
unlinkSync30(join76(dirname28(path3), name));
|
|
106844
|
+
} catch {}
|
|
106845
|
+
}
|
|
106846
|
+
} catch {}
|
|
106847
|
+
}
|
|
106848
|
+
function markBootResumeComplete(stateDir, opts = {}) {
|
|
106849
|
+
const path3 = opts.path ?? bootResumeDonePath(stateDir);
|
|
106850
|
+
const tmp = `${path3}.tmp.${process.pid}`;
|
|
106851
|
+
const boot = containerBootIdentity(opts.procRoot);
|
|
106852
|
+
try {
|
|
106853
|
+
const token = { pid: process.pid, at: opts.now ?? Date.now() };
|
|
106854
|
+
if (boot != null)
|
|
106855
|
+
token.boot = boot;
|
|
106856
|
+
writeFileSync52(tmp, JSON.stringify(token) + `
|
|
106857
|
+
`);
|
|
106858
|
+
renameSync30(tmp, path3);
|
|
106859
|
+
sweepStrayTmps(path3);
|
|
106860
|
+
} catch (err) {
|
|
106861
|
+
try {
|
|
106862
|
+
unlinkSync30(tmp);
|
|
106863
|
+
} catch {}
|
|
106864
|
+
const log = opts.log ?? ((s) => process.stderr.write(s));
|
|
106865
|
+
log(`telegram gateway: boot: could not stamp ${BOOT_RESUME_DONE_FILE} ` + `(${err.message}) \u2014 a gateway respawn may repeat the boot resume (#4641)
|
|
106866
|
+
`);
|
|
106867
|
+
}
|
|
106868
|
+
}
|
|
106869
|
+
function decideGatewayOnlyRespawn(input) {
|
|
106870
|
+
const { sentinelPresent, sentinelStale, record: record2, live } = input;
|
|
106871
|
+
if (!sentinelPresent) {
|
|
106872
|
+
return { gatewayOnly: false, reason: "no-boot-resume-sentinel", pid: record2?.pid ?? null };
|
|
106873
|
+
}
|
|
106874
|
+
if (sentinelStale === true) {
|
|
106875
|
+
return { gatewayOnly: false, reason: "stale-boot-token", pid: record2?.pid ?? null };
|
|
106876
|
+
}
|
|
106877
|
+
if (record2 == null) {
|
|
106878
|
+
return { gatewayOnly: true, reason: "gateway-only-respawn-no-record", pid: null };
|
|
106879
|
+
}
|
|
106880
|
+
if (live == null)
|
|
106881
|
+
return { gatewayOnly: false, reason: "agent-process-dead", pid: record2.pid };
|
|
106882
|
+
if (live.starttime !== record2.starttime) {
|
|
106883
|
+
return { gatewayOnly: false, reason: "starttime-mismatch", pid: record2.pid };
|
|
106884
|
+
}
|
|
106885
|
+
if (record2.comm != null && record2.comm !== live.comm) {
|
|
106886
|
+
return { gatewayOnly: false, reason: "comm-mismatch", pid: record2.pid };
|
|
106887
|
+
}
|
|
106888
|
+
return { gatewayOnly: true, reason: "gateway-only-respawn", pid: record2.pid };
|
|
106889
|
+
}
|
|
106890
|
+
function detectGatewayOnlyRespawn(opts) {
|
|
106891
|
+
if (opts.enabled === false)
|
|
106892
|
+
return { gatewayOnly: false, reason: "guard-disabled", pid: null };
|
|
106893
|
+
const procRoot = opts.procRoot ?? "/proc";
|
|
106894
|
+
const sentinel = readBootResumeSentinel(opts.sentinelPath ?? bootResumeDonePath(opts.stateDir), { procRoot });
|
|
106895
|
+
const recordPath2 = opts.recordPath ?? join76(opts.stateDir, AGENT_PROCESS_RECORD_FILE);
|
|
106896
|
+
const record2 = readAgentProcessRecord(recordPath2);
|
|
106897
|
+
const live = record2 == null ? null : readProcIdentity(record2.pid, procRoot);
|
|
106898
|
+
return decideGatewayOnlyRespawn({
|
|
106899
|
+
sentinelPresent: sentinel.present,
|
|
106900
|
+
sentinelStale: sentinel.stale,
|
|
106901
|
+
record: record2,
|
|
106902
|
+
live
|
|
106903
|
+
});
|
|
106904
|
+
}
|
|
106905
|
+
function shouldSkipBootResumeForGatewayOnlyRespawn(stateDir, opts = {}) {
|
|
106906
|
+
const log = opts.log ?? ((s) => process.stderr.write(s));
|
|
106907
|
+
let decision;
|
|
106908
|
+
try {
|
|
106909
|
+
decision = detectGatewayOnlyRespawn({
|
|
106910
|
+
...opts,
|
|
106911
|
+
stateDir,
|
|
106912
|
+
enabled: opts.enabled ?? process.env.SWITCHROOM_GATEWAY_RESPAWN_GUARD !== "0"
|
|
106913
|
+
});
|
|
106914
|
+
} catch (err) {
|
|
106915
|
+
log(`telegram gateway: boot: agent-liveness probe failed (${err.message}) \u2014 assuming agent restart
|
|
106916
|
+
`);
|
|
106917
|
+
return false;
|
|
106918
|
+
}
|
|
106919
|
+
if (decision.gatewayOnly) {
|
|
106920
|
+
log(`telegram gateway: boot: GATEWAY-ONLY respawn \u2014 this container generation's boot resume is already ` + `done (${BOOT_RESUME_DONE_FILE} present, reason=${decision.reason}, agent pid=${decision.pid ?? "unrecorded"}). ` + `Skipping the orphan-turn reaper, the bridge-dead marker, the resume synthetic, crash-redelivery capture ` + `and .pending-turn.env (#4641): the claude session, its in-flight turn and its sub-agents were never interrupted.
|
|
106921
|
+
`);
|
|
106922
|
+
return true;
|
|
106923
|
+
}
|
|
106924
|
+
log(`telegram gateway: boot: agent-liveness probe \u2192 treating as agent restart (reason=${decision.reason})
|
|
106925
|
+
`);
|
|
106926
|
+
return false;
|
|
106927
|
+
}
|
|
106928
|
+
|
|
106319
106929
|
// gateway/bridge-dead-watchdog.ts
|
|
106320
|
-
import { readFileSync as
|
|
106930
|
+
import { readFileSync as readFileSync65, writeFileSync as writeFileSync53, renameSync as renameSync31, unlinkSync as unlinkSync31 } from "node:fs";
|
|
106321
106931
|
|
|
106322
106932
|
// gateway/cron-session.ts
|
|
106323
106933
|
var CRON_IDENTITY_SUFFIX2 = "-cron";
|
|
@@ -106350,7 +106960,7 @@ function readFreshCrashLogTail(path3, opts = {}) {
|
|
|
106350
106960
|
const nowMs3 = opts.nowMs ?? Date.now();
|
|
106351
106961
|
const freshWindowMs = opts.freshWindowMs ?? CRASH_LOG_FRESH_WINDOW_MS;
|
|
106352
106962
|
const maxLines = opts.maxLines ?? CRASH_LOG_TAIL_LINES;
|
|
106353
|
-
const readFile = opts.readFile ?? ((p) =>
|
|
106963
|
+
const readFile = opts.readFile ?? ((p) => readFileSync65(p, "utf8"));
|
|
106354
106964
|
let raw;
|
|
106355
106965
|
try {
|
|
106356
106966
|
raw = readFile(path3);
|
|
@@ -106371,13 +106981,13 @@ function readFreshCrashLogTail(path3, opts = {}) {
|
|
|
106371
106981
|
}
|
|
106372
106982
|
function writeBridgeDeadEscalationMarker(path3, marker) {
|
|
106373
106983
|
const tmp = `${path3}.tmp-${process.pid}-${Date.now()}`;
|
|
106374
|
-
|
|
106375
|
-
|
|
106984
|
+
writeFileSync53(tmp, JSON.stringify(marker), "utf8");
|
|
106985
|
+
renameSync31(tmp, path3);
|
|
106376
106986
|
}
|
|
106377
106987
|
function consumeBridgeDeadEscalationMarker(path3, nowMs3 = Date.now(), maxAgeMs = ESCALATION_MARKER_MAX_AGE_MS) {
|
|
106378
106988
|
let marker = null;
|
|
106379
106989
|
try {
|
|
106380
|
-
const parsed = JSON.parse(
|
|
106990
|
+
const parsed = JSON.parse(readFileSync65(path3, "utf8"));
|
|
106381
106991
|
if (typeof parsed.ts === "number" && Number.isFinite(parsed.ts) && typeof parsed.reason === "string") {
|
|
106382
106992
|
const age = nowMs3 - parsed.ts;
|
|
106383
106993
|
if (age >= 0 && age < maxAgeMs) {
|
|
@@ -106389,7 +106999,7 @@ function consumeBridgeDeadEscalationMarker(path3, nowMs3 = Date.now(), maxAgeMs
|
|
|
106389
106999
|
}
|
|
106390
107000
|
} catch {}
|
|
106391
107001
|
try {
|
|
106392
|
-
|
|
107002
|
+
unlinkSync31(path3);
|
|
106393
107003
|
} catch {}
|
|
106394
107004
|
return marker;
|
|
106395
107005
|
}
|
|
@@ -106530,7 +107140,7 @@ function createBridgeDeadWatchdog(opts) {
|
|
|
106530
107140
|
}
|
|
106531
107141
|
|
|
106532
107142
|
// gateway/boot-probes.ts
|
|
106533
|
-
import { readFileSync as
|
|
107143
|
+
import { readFileSync as readFileSync66, readdirSync as readdirSync17, existsSync as existsSync63 } from "fs";
|
|
106534
107144
|
init_quota_cache();
|
|
106535
107145
|
init_generation_stamp();
|
|
106536
107146
|
init_quota_check();
|
|
@@ -106538,8 +107148,8 @@ import { execFile as execFileCb2 } from "child_process";
|
|
|
106538
107148
|
import { promisify as promisify2 } from "util";
|
|
106539
107149
|
var execFile2 = promisify2(execFileCb2);
|
|
106540
107150
|
var realProcFs2 = {
|
|
106541
|
-
readdir: (p) =>
|
|
106542
|
-
readFile: (p) =>
|
|
107151
|
+
readdir: (p) => readdirSync17(p),
|
|
107152
|
+
readFile: (p) => readFileSync66(p, "utf-8")
|
|
106543
107153
|
};
|
|
106544
107154
|
function findAgentProcessInContainer2(fs4 = realProcFs2) {
|
|
106545
107155
|
let entries;
|
|
@@ -106840,7 +107450,7 @@ if (isGatewayMain) {
|
|
|
106840
107450
|
shutdownAnalytics();
|
|
106841
107451
|
});
|
|
106842
107452
|
}
|
|
106843
|
-
var STATE_DIR = process.env.TELEGRAM_STATE_DIR ??
|
|
107453
|
+
var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join77(homedir22(), ".claude", "channels", "telegram");
|
|
106844
107454
|
var permCardStore = createPermissionCardStore(STATE_DIR);
|
|
106845
107455
|
var BLOCKED_APPROVALS_DIR = process.env.SWITCHROOM_BLOCKED_APPROVALS_DIR ?? "/state/blocked-approvals";
|
|
106846
107456
|
var AGENT_NAME = process.env.SWITCHROOM_AGENT_NAME ?? "agent";
|
|
@@ -106879,7 +107489,7 @@ function alwaysAllowDrainDeps() {
|
|
|
106879
107489
|
return {
|
|
106880
107490
|
readConfigText: () => {
|
|
106881
107491
|
const cfgPath = process.env.SWITCHROOM_CONFIG ?? SWITCHROOM_CONFIG ?? findConfigFile2();
|
|
106882
|
-
return
|
|
107492
|
+
return readFileSync67(cfgPath, "utf8");
|
|
106883
107493
|
},
|
|
106884
107494
|
resolveAllowList: (_configText, agentName3) => {
|
|
106885
107495
|
const cfg = loadConfig2();
|
|
@@ -106940,11 +107550,11 @@ function scheduleAlwaysAllowPersistDrain() {
|
|
|
106940
107550
|
}, ALWAYS_ALLOW_DRAIN_INTERVAL_MS);
|
|
106941
107551
|
timer3.unref?.();
|
|
106942
107552
|
}
|
|
106943
|
-
var ACCESS_FILE =
|
|
106944
|
-
var APPROVED_DIR =
|
|
106945
|
-
var ENV_FILE =
|
|
106946
|
-
var INBOX_DIR =
|
|
106947
|
-
var PEOPLE_FILE =
|
|
107553
|
+
var ACCESS_FILE = join77(STATE_DIR, "access.json");
|
|
107554
|
+
var APPROVED_DIR = join77(STATE_DIR, "approved");
|
|
107555
|
+
var ENV_FILE = join77(STATE_DIR, ".env");
|
|
107556
|
+
var INBOX_DIR = join77(STATE_DIR, "inbox");
|
|
107557
|
+
var PEOPLE_FILE = join77(STATE_DIR, "people.json");
|
|
106948
107558
|
function triggerSelfRestart(targetAgent, reason, delayMs = 300) {
|
|
106949
107559
|
const isDocker = process.env.SWITCHROOM_RUNTIME === "docker";
|
|
106950
107560
|
const selfAgent = process.env.SWITCHROOM_AGENT_NAME;
|
|
@@ -107009,7 +107619,7 @@ function formatBootVersion() {
|
|
|
107009
107619
|
}
|
|
107010
107620
|
try {
|
|
107011
107621
|
chmodSync14(ENV_FILE, 384);
|
|
107012
|
-
for (const line of
|
|
107622
|
+
for (const line of readFileSync67(ENV_FILE, "utf8").split(`
|
|
107013
107623
|
`)) {
|
|
107014
107624
|
const m = line.match(/^(\w+)=(.*)$/);
|
|
107015
107625
|
if (m && process.env[m[1]] === undefined)
|
|
@@ -107030,7 +107640,7 @@ var bot;
|
|
|
107030
107640
|
var lastGetUpdatesHeartbeatMs = Date.now();
|
|
107031
107641
|
var GRAMMY_VERSION = (() => {
|
|
107032
107642
|
try {
|
|
107033
|
-
const raw =
|
|
107643
|
+
const raw = readFileSync67(new URL("../../node_modules/grammy/package.json", import.meta.url), "utf8");
|
|
107034
107644
|
return JSON.parse(raw).version ?? "unknown";
|
|
107035
107645
|
} catch {
|
|
107036
107646
|
return "unknown";
|
|
@@ -107071,7 +107681,7 @@ function assertSendable(f) {
|
|
|
107071
107681
|
} catch {
|
|
107072
107682
|
throw new Error(`refusing to send file \u2014 cannot resolve real path: ${f}`);
|
|
107073
107683
|
}
|
|
107074
|
-
const inbox =
|
|
107684
|
+
const inbox = join77(stateReal, "inbox");
|
|
107075
107685
|
if (real.startsWith(stateReal + sep6) && !real.startsWith(inbox + sep6)) {
|
|
107076
107686
|
throw new Error(`refusing to send channel state: ${f}`);
|
|
107077
107687
|
}
|
|
@@ -107100,7 +107710,7 @@ var HISTORY_ENABLED = HISTORY_ACCESS.historyEnabled !== false;
|
|
|
107100
107710
|
if (isGatewayMain && HISTORY_ENABLED) {
|
|
107101
107711
|
try {
|
|
107102
107712
|
initHistory(STATE_DIR, HISTORY_ACCESS.historyRetentionDays ?? 30);
|
|
107103
|
-
process.stderr.write(`telegram gateway: history capture enabled at ${
|
|
107713
|
+
process.stderr.write(`telegram gateway: history capture enabled at ${join77(STATE_DIR, "history.db")}
|
|
107104
107714
|
`);
|
|
107105
107715
|
} catch (err) {
|
|
107106
107716
|
process.stderr.write(`telegram gateway: history init failed (${err.message}) \u2014 capture disabled
|
|
@@ -107111,174 +107721,179 @@ var turnsDb = null;
|
|
|
107111
107721
|
var bootResumeInbound = null;
|
|
107112
107722
|
var pendingRedelivery = null;
|
|
107113
107723
|
var bridgeDeadPriorStreak = 0;
|
|
107114
|
-
|
|
107115
|
-
|
|
107116
|
-
|
|
107117
|
-
turnsDb = openTurnsDb(agentDir);
|
|
107118
|
-
applySubagentsSchema(turnsDb);
|
|
107119
|
-
let markerTurnKey = null;
|
|
107120
|
-
let markerAgeMs = null;
|
|
107724
|
+
var bootResumeThrew = false;
|
|
107725
|
+
bootResumeInit:
|
|
107726
|
+
if (isGatewayMain)
|
|
107121
107727
|
try {
|
|
107122
|
-
const
|
|
107123
|
-
|
|
107124
|
-
|
|
107125
|
-
|
|
107126
|
-
|
|
107127
|
-
|
|
107128
|
-
|
|
107129
|
-
|
|
107130
|
-
|
|
107131
|
-
|
|
107132
|
-
|
|
107133
|
-
|
|
107134
|
-
|
|
107135
|
-
|
|
107136
|
-
|
|
107137
|
-
|
|
107138
|
-
|
|
107139
|
-
|
|
107140
|
-
|
|
107141
|
-
|
|
107142
|
-
|
|
107143
|
-
|
|
107144
|
-
|
|
107145
|
-
|
|
107146
|
-
|
|
107147
|
-
|
|
107148
|
-
|
|
107149
|
-
|
|
107150
|
-
const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join76(STATE_DIR, "bridge-dead-escalation.json"));
|
|
107151
|
-
if (bridgeDeadMarker != null) {
|
|
107152
|
-
bridgeDeadPriorStreak = bridgeDeadMarker.count ?? 1;
|
|
107153
|
-
process.stderr.write(`telegram gateway: boot: prior restart was a bridge-dead escalation (reason=${bridgeDeadMarker.reason}` + `, consecutive=${bridgeDeadPriorStreak}` + `${bridgeDeadMarker.crashTail ? `, crashTail=${bridgeDeadMarker.crashTail}` : ""})
|
|
107154
|
-
`);
|
|
107155
|
-
}
|
|
107156
|
-
const bridgeDeadRestartCause = bridgeDeadMarker != null ? {
|
|
107157
|
-
reason: bridgeDeadMarker.reason,
|
|
107158
|
-
note: "The framework itself triggered this restart: your Telegram MCP bridge process had died " + "(chat tools were unavailable \u2014 you could not send replies), so the container was bounced " + "to restore the chat surface. This was NOT an operator-initiated restart and NOT a hang-watchdog kill."
|
|
107159
|
-
} : undefined;
|
|
107160
|
-
const pending2 = findLatestTurnIfInterrupted(turnsDb);
|
|
107161
|
-
const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
|
|
107162
|
-
if (pending2 != null && selfAgent) {
|
|
107163
|
-
const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join76(STATE_DIR, "clean-shutdown.json");
|
|
107164
|
-
const bootResumeCleanMarker = readCleanShutdownMarker(bootResumeMarkerPath);
|
|
107165
|
-
const bootResumeForceAlways = process.env.SWITCHROOM_BOOT_RESUME_ALWAYS === "1";
|
|
107166
|
-
const bootResumeMode = parseBootResumeMode(process.env.SWITCHROOM_BOOT_RESUME);
|
|
107167
|
-
const bootResumeSuppressed = shouldSuppressBootResume(bootResumeCleanMarker, Date.now(), {
|
|
107168
|
-
forceAlways: bootResumeForceAlways,
|
|
107169
|
-
mode: bootResumeMode
|
|
107170
|
-
});
|
|
107171
|
-
const RESUME_MAX_AGE_MS = (() => {
|
|
107172
|
-
const v = Number(process.env.SWITCHROOM_RESUME_MAX_AGE_MS);
|
|
107173
|
-
return Number.isFinite(v) && v > 0 ? v : 10800000;
|
|
107174
|
-
})();
|
|
107175
|
-
const bootResumeKind = decideBootResumeKind({
|
|
107176
|
-
pending: pending2,
|
|
107177
|
-
suppressed: bootResumeSuppressed,
|
|
107178
|
-
ageMs: Math.max(0, Date.now() - pending2.started_at),
|
|
107179
|
-
maxAgeMs: RESUME_MAX_AGE_MS
|
|
107180
|
-
});
|
|
107181
|
-
const redeliverCapture = decideRedeliverCapture({
|
|
107182
|
-
willBeResumed: bootResumeKind === "resume",
|
|
107183
|
-
hasSessionId: Boolean(pending2.session_id)
|
|
107728
|
+
const agentDir = STATE_DIR.endsWith("/telegram") ? STATE_DIR.slice(0, -"/telegram".length) : STATE_DIR;
|
|
107729
|
+
turnsDb = openTurnsDb(agentDir);
|
|
107730
|
+
applySubagentsSchema(turnsDb);
|
|
107731
|
+
if (shouldSkipBootResumeForGatewayOnlyRespawn(STATE_DIR))
|
|
107732
|
+
break bootResumeInit;
|
|
107733
|
+
let markerTurnKey = null;
|
|
107734
|
+
let markerAgeMs = null;
|
|
107735
|
+
try {
|
|
107736
|
+
const markerPath = join77(STATE_DIR, TURN_ACTIVE_MARKER_FILE2);
|
|
107737
|
+
if (existsSync65(markerPath)) {
|
|
107738
|
+
const st = statSync25(markerPath);
|
|
107739
|
+
markerAgeMs = Date.now() - st.mtimeMs;
|
|
107740
|
+
try {
|
|
107741
|
+
const payload = JSON.parse(readFileSync67(markerPath, "utf8"));
|
|
107742
|
+
if (typeof payload.turnKey === "string" && payload.turnKey.length > 0) {
|
|
107743
|
+
markerTurnKey = payload.turnKey;
|
|
107744
|
+
}
|
|
107745
|
+
} catch {}
|
|
107746
|
+
}
|
|
107747
|
+
} catch {}
|
|
107748
|
+
const hangSecs = Number(process.env.TURN_HANG_SECS);
|
|
107749
|
+
const hangThresholdMs = (Number.isFinite(hangSecs) && hangSecs > 0 ? hangSecs : 300) * 1000;
|
|
107750
|
+
const reasonSnapshot = markerAgeMs != null ? JSON.stringify({ idleMs: Math.round(markerAgeMs) }) : null;
|
|
107751
|
+
const { reaped, timeoutTurnKey } = markOrphanedWithTimeoutClassification(turnsDb, {
|
|
107752
|
+
markerTurnKey,
|
|
107753
|
+
markerAgeMs,
|
|
107754
|
+
hangThresholdMs,
|
|
107755
|
+
reasonSnapshot
|
|
107184
107756
|
});
|
|
107185
|
-
if (
|
|
107186
|
-
|
|
107187
|
-
} else if (redeliverCapture.skipReason === "will-be-resumed") {
|
|
107188
|
-
process.stderr.write(`telegram gateway: crash-redelivery suppressed \u2014 interrupted turnKey=${pending2.turn_key} will be ` + `RESUMED (bootResumeKind=resume); the fresh re-answer supersedes the recovered draft (no double-send)
|
|
107757
|
+
if (reaped > 0) {
|
|
107758
|
+
process.stderr.write(`telegram gateway: turn-registry boot-reaper stamped ${reaped} orphaned turn(s)` + `${timeoutTurnKey ? ` (turnKey=${timeoutTurnKey} as 'timeout', markerAgeMs=${markerAgeMs})` : " as 'restart'"}
|
|
107189
107759
|
`);
|
|
107190
107760
|
} else {
|
|
107191
|
-
process.stderr.write(`telegram gateway:
|
|
107761
|
+
process.stderr.write(`telegram gateway: turn-registry initialized at ${join77(agentDir, "telegram", "registry.db")}
|
|
107192
107762
|
`);
|
|
107193
107763
|
}
|
|
107194
|
-
|
|
107195
|
-
|
|
107196
|
-
|
|
107197
|
-
|
|
107198
|
-
process.stderr.write(`telegram gateway: boot-resume subagent lookup failed (${err.message}) \u2014 continuing without worker list
|
|
107764
|
+
const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join77(STATE_DIR, "bridge-dead-escalation.json"));
|
|
107765
|
+
if (bridgeDeadMarker != null) {
|
|
107766
|
+
bridgeDeadPriorStreak = bridgeDeadMarker.count ?? 1;
|
|
107767
|
+
process.stderr.write(`telegram gateway: boot: prior restart was a bridge-dead escalation (reason=${bridgeDeadMarker.reason}` + `, consecutive=${bridgeDeadPriorStreak}` + `${bridgeDeadMarker.crashTail ? `, crashTail=${bridgeDeadMarker.crashTail}` : ""})
|
|
107199
107768
|
`);
|
|
107200
107769
|
}
|
|
107201
|
-
|
|
107202
|
-
|
|
107203
|
-
|
|
107204
|
-
|
|
107205
|
-
|
|
107206
|
-
|
|
107207
|
-
|
|
107208
|
-
|
|
107209
|
-
|
|
107210
|
-
|
|
107211
|
-
|
|
107212
|
-
|
|
107213
|
-
|
|
107214
|
-
|
|
107215
|
-
|
|
107216
|
-
|
|
107217
|
-
|
|
107770
|
+
const bridgeDeadRestartCause = bridgeDeadMarker != null ? {
|
|
107771
|
+
reason: bridgeDeadMarker.reason,
|
|
107772
|
+
note: "The framework itself triggered this restart: your Telegram MCP bridge process had died " + "(chat tools were unavailable \u2014 you could not send replies), so the container was bounced " + "to restore the chat surface. This was NOT an operator-initiated restart and NOT a hang-watchdog kill."
|
|
107773
|
+
} : undefined;
|
|
107774
|
+
const pending2 = findLatestTurnIfInterrupted(turnsDb);
|
|
107775
|
+
const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
|
|
107776
|
+
if (pending2 != null && selfAgent) {
|
|
107777
|
+
const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
|
|
107778
|
+
const bootResumeCleanMarker = readCleanShutdownMarker(bootResumeMarkerPath);
|
|
107779
|
+
const bootResumeForceAlways = process.env.SWITCHROOM_BOOT_RESUME_ALWAYS === "1";
|
|
107780
|
+
const bootResumeMode = parseBootResumeMode(process.env.SWITCHROOM_BOOT_RESUME);
|
|
107781
|
+
const bootResumeSuppressed = shouldSuppressBootResume(bootResumeCleanMarker, Date.now(), {
|
|
107782
|
+
forceAlways: bootResumeForceAlways,
|
|
107783
|
+
mode: bootResumeMode
|
|
107784
|
+
});
|
|
107785
|
+
const RESUME_MAX_AGE_MS = (() => {
|
|
107786
|
+
const v = Number(process.env.SWITCHROOM_RESUME_MAX_AGE_MS);
|
|
107787
|
+
return Number.isFinite(v) && v > 0 ? v : 10800000;
|
|
107788
|
+
})();
|
|
107789
|
+
const bootResumeKind = decideBootResumeKind({
|
|
107790
|
+
pending: pending2,
|
|
107791
|
+
suppressed: bootResumeSuppressed,
|
|
107792
|
+
ageMs: Math.max(0, Date.now() - pending2.started_at),
|
|
107793
|
+
maxAgeMs: RESUME_MAX_AGE_MS
|
|
107794
|
+
});
|
|
107795
|
+
const redeliverCapture = decideRedeliverCapture({
|
|
107796
|
+
willBeResumed: bootResumeKind === "resume",
|
|
107797
|
+
hasSessionId: Boolean(pending2.session_id)
|
|
107798
|
+
});
|
|
107799
|
+
if (redeliverCapture.capture) {
|
|
107800
|
+
pendingRedelivery = { turn: pending2, maxAgeMs: RESUME_MAX_AGE_MS };
|
|
107801
|
+
} else if (redeliverCapture.skipReason === "will-be-resumed") {
|
|
107802
|
+
process.stderr.write(`telegram gateway: crash-redelivery suppressed \u2014 interrupted turnKey=${pending2.turn_key} will be ` + `RESUMED (bootResumeKind=resume); the fresh re-answer supersedes the recovered draft (no double-send)
|
|
107803
|
+
`);
|
|
107804
|
+
} else {
|
|
107805
|
+
process.stderr.write(`telegram gateway: crash-redelivery skipped \u2014 interrupted turnKey=${pending2.turn_key} has no ` + `pinned session_id (pre-feature turn or no session event seen); cannot resolve exact transcript
|
|
107806
|
+
`);
|
|
107218
107807
|
}
|
|
107219
|
-
|
|
107220
|
-
|
|
107221
|
-
|
|
107222
|
-
|
|
107223
|
-
|
|
107224
|
-
turn: pending2,
|
|
107225
|
-
idleMs,
|
|
107226
|
-
subagents: interruptedSubagents,
|
|
107227
|
-
restartCause: bridgeDeadRestartCause
|
|
107228
|
-
})
|
|
107229
|
-
};
|
|
107230
|
-
} else if (bootResumeKind === "defer-loop" || bootResumeKind === "defer-suppressed") {
|
|
107231
|
-
bootResumeInbound = {
|
|
107232
|
-
agent: selfAgent,
|
|
107233
|
-
msg: buildResumeDeferredReportInbound({
|
|
107234
|
-
turn: pending2,
|
|
107235
|
-
reason: bootResumeKind === "defer-loop" ? "loop-guard" : "clean-restart-suppressed",
|
|
107236
|
-
subagents: interruptedSubagents,
|
|
107237
|
-
restartCause: bridgeDeadRestartCause
|
|
107238
|
-
})
|
|
107239
|
-
};
|
|
107240
|
-
}
|
|
107241
|
-
if (bootResumeKind === "defer-suppressed") {
|
|
107242
|
-
process.stderr.write(`telegram gateway: boot-resume suppressed (clean shutdown` + `${bootResumeCleanMarker?.reason ? ` reason=${JSON.stringify(bootResumeCleanMarker.reason)}` : ""}` + `, mode=${bootResumeMode}) \u2014 passive report delivered for turnKey=${pending2.turn_key}
|
|
107808
|
+
let interruptedSubagents = [];
|
|
107809
|
+
try {
|
|
107810
|
+
interruptedSubagents = listNonTerminalSubagentsForTurn(turnsDb, pending2.turn_key).map((s) => ({ agentType: s.agent_type, description: s.description, status: s.status }));
|
|
107811
|
+
} catch (err) {
|
|
107812
|
+
process.stderr.write(`telegram gateway: boot-resume subagent lookup failed (${err.message}) \u2014 continuing without worker list
|
|
107243
107813
|
`);
|
|
107244
|
-
|
|
107245
|
-
|
|
107814
|
+
}
|
|
107815
|
+
if (bootResumeKind === "resume") {
|
|
107816
|
+
bootResumeInbound = {
|
|
107817
|
+
agent: selfAgent,
|
|
107818
|
+
msg: buildResumeInterruptedInbound({
|
|
107819
|
+
turn: pending2,
|
|
107820
|
+
subagents: interruptedSubagents,
|
|
107821
|
+
restartCause: bridgeDeadRestartCause
|
|
107822
|
+
})
|
|
107823
|
+
};
|
|
107824
|
+
} else if (bootResumeKind === "report") {
|
|
107825
|
+
let idleMs = pending2.turn_key === timeoutTurnKey && markerAgeMs != null ? markerAgeMs : null;
|
|
107826
|
+
if (idleMs == null && pending2.interrupt_reason) {
|
|
107827
|
+
try {
|
|
107828
|
+
const parsed = JSON.parse(pending2.interrupt_reason);
|
|
107829
|
+
if (typeof parsed.idleMs === "number" && Number.isFinite(parsed.idleMs))
|
|
107830
|
+
idleMs = parsed.idleMs;
|
|
107831
|
+
} catch {}
|
|
107832
|
+
}
|
|
107833
|
+
if (idleMs == null)
|
|
107834
|
+
idleMs = Math.max(0, Date.now() - pending2.started_at);
|
|
107835
|
+
bootResumeInbound = {
|
|
107836
|
+
agent: selfAgent,
|
|
107837
|
+
msg: buildResumeWatchdogReportInbound({
|
|
107838
|
+
turn: pending2,
|
|
107839
|
+
idleMs,
|
|
107840
|
+
subagents: interruptedSubagents,
|
|
107841
|
+
restartCause: bridgeDeadRestartCause
|
|
107842
|
+
})
|
|
107843
|
+
};
|
|
107844
|
+
} else if (bootResumeKind === "defer-loop" || bootResumeKind === "defer-suppressed") {
|
|
107845
|
+
bootResumeInbound = {
|
|
107846
|
+
agent: selfAgent,
|
|
107847
|
+
msg: buildResumeDeferredReportInbound({
|
|
107848
|
+
turn: pending2,
|
|
107849
|
+
reason: bootResumeKind === "defer-loop" ? "loop-guard" : "clean-restart-suppressed",
|
|
107850
|
+
subagents: interruptedSubagents,
|
|
107851
|
+
restartCause: bridgeDeadRestartCause
|
|
107852
|
+
})
|
|
107853
|
+
};
|
|
107854
|
+
}
|
|
107855
|
+
if (bootResumeKind === "defer-suppressed") {
|
|
107856
|
+
process.stderr.write(`telegram gateway: boot-resume suppressed (clean shutdown` + `${bootResumeCleanMarker?.reason ? ` reason=${JSON.stringify(bootResumeCleanMarker.reason)}` : ""}` + `, mode=${bootResumeMode}) \u2014 passive report delivered for turnKey=${pending2.turn_key}
|
|
107246
107857
|
`);
|
|
107247
|
-
|
|
107248
|
-
|
|
107249
|
-
process.stderr.write(`telegram gateway: boot-resume queued kind=${bootResumeKind} mode=${bootResumeMode} ` + `turnKey=${pending2.turn_key} endedVia=${pending2.ended_via ?? "open"} chat=${pending2.chat_id}
|
|
107858
|
+
} else if (bootResumeKind === "defer-loop") {
|
|
107859
|
+
process.stderr.write(`telegram gateway: boot-resume loop-guard tripped (interrupted turn was itself a resume) ` + `\u2014 passive report delivered instead of re-resuming turnKey=${pending2.turn_key}
|
|
107250
107860
|
`);
|
|
107251
|
-
}
|
|
107252
|
-
}
|
|
107253
|
-
if (bridgeDeadMarker != null && bootResumeInbound == null && selfAgent) {
|
|
107254
|
-
const idleNoticeChat = (() => {
|
|
107255
|
-
try {
|
|
107256
|
-
return loadAccess().allowFrom[0] ?? null;
|
|
107257
|
-
} catch {
|
|
107258
|
-
return null;
|
|
107259
107861
|
}
|
|
107260
|
-
|
|
107261
|
-
|
|
107262
|
-
bootResumeInbound = {
|
|
107263
|
-
agent: selfAgent,
|
|
107264
|
-
msg: buildBridgeDeadIdleNoticeInbound({
|
|
107265
|
-
chatId: String(idleNoticeChat),
|
|
107266
|
-
marker: bridgeDeadMarker
|
|
107267
|
-
})
|
|
107268
|
-
};
|
|
107269
|
-
process.stderr.write(`telegram gateway: boot: bridge-dead idle notice queued chat=${idleNoticeChat} (no turn was in flight)
|
|
107862
|
+
if (bootResumeInbound != null) {
|
|
107863
|
+
process.stderr.write(`telegram gateway: boot-resume queued kind=${bootResumeKind} mode=${bootResumeMode} ` + `turnKey=${pending2.turn_key} endedVia=${pending2.ended_via ?? "open"} chat=${pending2.chat_id}
|
|
107270
107864
|
`);
|
|
107271
|
-
|
|
107272
|
-
|
|
107865
|
+
}
|
|
107866
|
+
}
|
|
107867
|
+
if (bridgeDeadMarker != null && bootResumeInbound == null && selfAgent) {
|
|
107868
|
+
const idleNoticeChat = (() => {
|
|
107869
|
+
try {
|
|
107870
|
+
return loadAccess().allowFrom[0] ?? null;
|
|
107871
|
+
} catch {
|
|
107872
|
+
return null;
|
|
107873
|
+
}
|
|
107874
|
+
})();
|
|
107875
|
+
if (idleNoticeChat != null) {
|
|
107876
|
+
bootResumeInbound = {
|
|
107877
|
+
agent: selfAgent,
|
|
107878
|
+
msg: buildBridgeDeadIdleNoticeInbound({
|
|
107879
|
+
chatId: String(idleNoticeChat),
|
|
107880
|
+
marker: bridgeDeadMarker
|
|
107881
|
+
})
|
|
107882
|
+
};
|
|
107883
|
+
process.stderr.write(`telegram gateway: boot: bridge-dead idle notice queued chat=${idleNoticeChat} (no turn was in flight)
|
|
107884
|
+
`);
|
|
107885
|
+
} else {
|
|
107886
|
+
process.stderr.write(`telegram gateway: boot: bridge-dead idle notice skipped \u2014 no allowFrom chat to surface it in
|
|
107273
107887
|
`);
|
|
107888
|
+
}
|
|
107274
107889
|
}
|
|
107275
|
-
|
|
107276
|
-
|
|
107277
|
-
|
|
107278
|
-
process.stderr.write(`telegram gateway: turn-registry init failed (${err.message}) \u2014 turn tracking disabled
|
|
107890
|
+
writePendingTurnEnv(agentDir, pending2);
|
|
107891
|
+
} catch (err) {
|
|
107892
|
+
process.stderr.write(`telegram gateway: turn-registry init failed (${err.message}) \u2014 turn tracking disabled
|
|
107279
107893
|
`);
|
|
107280
|
-
|
|
107281
|
-
|
|
107894
|
+
turnsDb = null;
|
|
107895
|
+
bootResumeThrew = true;
|
|
107896
|
+
}
|
|
107282
107897
|
function resolveSubagentOriginChat(agentId) {
|
|
107283
107898
|
if (turnsDb == null)
|
|
107284
107899
|
return null;
|
|
@@ -107361,12 +107976,12 @@ if (isGatewayMain && !STATIC)
|
|
|
107361
107976
|
function checkApprovals() {
|
|
107362
107977
|
let files;
|
|
107363
107978
|
try {
|
|
107364
|
-
files =
|
|
107979
|
+
files = readdirSync19(APPROVED_DIR);
|
|
107365
107980
|
} catch {
|
|
107366
107981
|
return;
|
|
107367
107982
|
}
|
|
107368
107983
|
for (const senderId of files) {
|
|
107369
|
-
const file =
|
|
107984
|
+
const file = join77(APPROVED_DIR, senderId);
|
|
107370
107985
|
bot.api.sendMessage(senderId, "Paired! Say hi to Claude.").then(() => rmSync9(file, { force: true }), (err) => {
|
|
107371
107986
|
process.stderr.write(`telegram gateway: failed to send approval confirm: ${err}
|
|
107372
107987
|
`);
|
|
@@ -107544,15 +108159,15 @@ function noteAgentOutputAt(key, ts) {
|
|
|
107544
108159
|
lastAgentOutputAt.delete(oldest);
|
|
107545
108160
|
}
|
|
107546
108161
|
}
|
|
107547
|
-
var OBLIGATION_STORE_PATH =
|
|
108162
|
+
var OBLIGATION_STORE_PATH = join77(STATE_DIR, "obligations.json");
|
|
107548
108163
|
var obligationStoreFs = {
|
|
107549
|
-
readFileSync: (p) =>
|
|
108164
|
+
readFileSync: (p) => readFileSync67(p, "utf8"),
|
|
107550
108165
|
writeFileSync: (p, d) => writeStateFileSync2(p, d),
|
|
107551
|
-
renameSync: (a, b) =>
|
|
107552
|
-
existsSync: (p) =>
|
|
108166
|
+
renameSync: (a, b) => renameSync32(a, b),
|
|
108167
|
+
existsSync: (p) => existsSync65(p),
|
|
107553
108168
|
fsyncFileSync: fsyncPathSync,
|
|
107554
108169
|
fsyncDirSync: fsyncPathSync,
|
|
107555
|
-
unlinkSync:
|
|
108170
|
+
unlinkSync: unlinkSync33
|
|
107556
108171
|
};
|
|
107557
108172
|
var obligationLedger = new ObligationLedger(OBLIGATION_REPRESENT_MAX, {
|
|
107558
108173
|
onChange: STATIC || !OBLIGATION_LEDGER_ENABLED ? undefined : (snapshot) => persistObligations(OBLIGATION_STORE_PATH, obligationStoreFs, snapshot)
|
|
@@ -108311,7 +108926,7 @@ function emitTurnRecord(turn, endedAt) {
|
|
|
108311
108926
|
return;
|
|
108312
108927
|
}
|
|
108313
108928
|
},
|
|
108314
|
-
rename: (from, to) =>
|
|
108929
|
+
rename: (from, to) => renameSync32(from, to)
|
|
108315
108930
|
});
|
|
108316
108931
|
appendFileSync11(turnsPath, rec);
|
|
108317
108932
|
} catch {}
|
|
@@ -109882,28 +110497,28 @@ var PIN_STATUS_WHILE_WORKING = (() => {
|
|
|
109882
110497
|
})();
|
|
109883
110498
|
var statusPinClaims = new Map;
|
|
109884
110499
|
var statusPinRightsCache = new PinRightsCache2;
|
|
109885
|
-
var STATUS_PIN_STORE_PATH =
|
|
110500
|
+
var STATUS_PIN_STORE_PATH = join77(STATE_DIR, "status-pins.json");
|
|
109886
110501
|
var statusPinStoreFs = {
|
|
109887
|
-
readFileSync: (p) =>
|
|
110502
|
+
readFileSync: (p) => readFileSync67(p, "utf8"),
|
|
109888
110503
|
writeFileSync: (p, d) => writeStateFileSync2(p, d),
|
|
109889
|
-
renameSync: (a, b) =>
|
|
109890
|
-
existsSync: (p) =>
|
|
110504
|
+
renameSync: (a, b) => renameSync32(a, b),
|
|
110505
|
+
existsSync: (p) => existsSync65(p)
|
|
109891
110506
|
};
|
|
109892
110507
|
var statusPinPersistEnabled = !STATIC && PIN_STATUS_WHILE_WORKING;
|
|
109893
|
-
var ACTIVITY_CARD_STORE_PATH =
|
|
110508
|
+
var ACTIVITY_CARD_STORE_PATH = join77(STATE_DIR, "activity-cards-pending.json");
|
|
109894
110509
|
var activityCardStoreFs = {
|
|
109895
|
-
readFileSync: (p) =>
|
|
110510
|
+
readFileSync: (p) => readFileSync67(p, "utf8"),
|
|
109896
110511
|
writeFileSync: (p, d) => writeStateFileSync2(p, d),
|
|
109897
|
-
renameSync: (a, b) =>
|
|
109898
|
-
existsSync: (p) =>
|
|
110512
|
+
renameSync: (a, b) => renameSync32(a, b),
|
|
110513
|
+
existsSync: (p) => existsSync65(p)
|
|
109899
110514
|
};
|
|
109900
110515
|
var activityCardPersistEnabled = !STATIC;
|
|
109901
|
-
var QUEUED_CARD_STORE_PATH =
|
|
110516
|
+
var QUEUED_CARD_STORE_PATH = join77(STATE_DIR, "queued-cards-pending.json");
|
|
109902
110517
|
var queuedCardStoreFs = {
|
|
109903
|
-
readFileSync: (p) =>
|
|
110518
|
+
readFileSync: (p) => readFileSync67(p, "utf8"),
|
|
109904
110519
|
writeFileSync: (p, d) => writeStateFileSync2(p, d),
|
|
109905
|
-
renameSync: (a, b) =>
|
|
109906
|
-
existsSync: (p) =>
|
|
110520
|
+
renameSync: (a, b) => renameSync32(a, b),
|
|
110521
|
+
existsSync: (p) => existsSync65(p)
|
|
109907
110522
|
};
|
|
109908
110523
|
var queuedCardPersistEnabled = !STATIC;
|
|
109909
110524
|
function persistQueuedCard(key, chatId, threadId, messageId) {
|
|
@@ -110186,11 +110801,11 @@ async function unpinAllStatusPins() {
|
|
|
110186
110801
|
}
|
|
110187
110802
|
}
|
|
110188
110803
|
var stalePinSweepEligible = false;
|
|
110189
|
-
var STALE_PIN_SWEEP_STORE_PATH =
|
|
110804
|
+
var STALE_PIN_SWEEP_STORE_PATH = join77(STATE_DIR, "stale-pin-sweep.json");
|
|
110190
110805
|
var sweepStoreFs = {
|
|
110191
|
-
readFileSync: (p) =>
|
|
110806
|
+
readFileSync: (p) => readFileSync67(p, "utf-8"),
|
|
110192
110807
|
writeFileSync: (p, data) => atomicWriteStateFileSync2(p, data, 384),
|
|
110193
|
-
existsSync: (p) =>
|
|
110808
|
+
existsSync: (p) => existsSync65(p)
|
|
110194
110809
|
};
|
|
110195
110810
|
var stalePinSweeper = createGatewayStalePinSweeper({
|
|
110196
110811
|
telegram: { handle: () => lockedBot, call: robustApiCall },
|
|
@@ -110227,12 +110842,12 @@ var getPinnedProgressCardMessageId = null;
|
|
|
110227
110842
|
var completeProgressCardTurn = null;
|
|
110228
110843
|
var subagentWatcher = null;
|
|
110229
110844
|
var workerActivityFeed = null;
|
|
110230
|
-
var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ??
|
|
110845
|
+
var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join77(STATE_DIR, "gateway.sock");
|
|
110231
110846
|
if (isGatewayMain)
|
|
110232
110847
|
mkdirStateSync2(STATE_DIR, { recursive: true, mode: 448 });
|
|
110233
|
-
var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ??
|
|
110234
|
-
var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ??
|
|
110235
|
-
var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ??
|
|
110848
|
+
var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join77(STATE_DIR, "gateway.pid.json");
|
|
110849
|
+
var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join77(STATE_DIR, "gateway-session.json");
|
|
110850
|
+
var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
|
|
110236
110851
|
var GATEWAY_STARTED_AT_MS = Date.now();
|
|
110237
110852
|
var BOOT_CARD_ENABLED = process.env.SWITCHROOM_BOOT_CARD !== "false";
|
|
110238
110853
|
var activeBootCard = null;
|
|
@@ -110262,7 +110877,7 @@ function ensureIssuesCard(chatId, threadId) {
|
|
|
110262
110877
|
bot: botApi,
|
|
110263
110878
|
log: (msg) => process.stderr.write(`telegram gateway: ${msg}
|
|
110264
110879
|
`),
|
|
110265
|
-
persistPath:
|
|
110880
|
+
persistPath: join77(stateDir, "issues-card.json")
|
|
110266
110881
|
});
|
|
110267
110882
|
activeIssuesWatcher = startIssuesWatcher({
|
|
110268
110883
|
stateDir,
|
|
@@ -110467,13 +111082,13 @@ if (isGatewayMain)
|
|
|
110467
111082
|
var inboundSpool;
|
|
110468
111083
|
if (isGatewayMain)
|
|
110469
111084
|
inboundSpool = STATIC ? undefined : createInboundSpool({
|
|
110470
|
-
path:
|
|
111085
|
+
path: join77(STATE_DIR, "inbound-spool.jsonl"),
|
|
110471
111086
|
fs: {
|
|
110472
111087
|
appendFileSync: (p, d) => appendStateFileSync(p, d),
|
|
110473
|
-
readFileSync: (p) =>
|
|
111088
|
+
readFileSync: (p) => readFileSync67(p, "utf8"),
|
|
110474
111089
|
writeFileSync: (p, d) => writeStateFileSync2(p, d),
|
|
110475
|
-
renameSync: (a, b) =>
|
|
110476
|
-
existsSync: (p) =>
|
|
111090
|
+
renameSync: (a, b) => renameSync32(a, b),
|
|
111091
|
+
existsSync: (p) => existsSync65(p),
|
|
110477
111092
|
statSizeSync: (p) => statSync25(p).size,
|
|
110478
111093
|
fsyncFileSync: fsyncPathSync,
|
|
110479
111094
|
fsyncDirSync: fsyncPathSync
|
|
@@ -110538,13 +111153,13 @@ async function maybeRedeliverUndeliveredAnswer() {
|
|
|
110538
111153
|
let transcriptText;
|
|
110539
111154
|
try {
|
|
110540
111155
|
const projectsDir = getProjectsDirForCwd();
|
|
110541
|
-
const path3 =
|
|
110542
|
-
if (!
|
|
111156
|
+
const path3 = join77(projectsDir, `${sessionId}.jsonl`);
|
|
111157
|
+
if (!existsSync65(path3)) {
|
|
110543
111158
|
process.stderr.write(`telegram gateway: crash-redelivery \u2014 transcript not found for turnKey=${turn.turn_key} session=${sessionId} (${path3}); skipping
|
|
110544
111159
|
`);
|
|
110545
111160
|
return;
|
|
110546
111161
|
}
|
|
110547
|
-
transcriptText =
|
|
111162
|
+
transcriptText = readFileSync67(path3, "utf8");
|
|
110548
111163
|
} catch (err) {
|
|
110549
111164
|
process.stderr.write(`telegram gateway: crash-redelivery \u2014 transcript read failed turnKey=${turn.turn_key}: ${err.message}
|
|
110550
111165
|
`);
|
|
@@ -110638,6 +111253,8 @@ if (isGatewayMain && bootResumeInbound != null) {
|
|
|
110638
111253
|
}
|
|
110639
111254
|
}
|
|
110640
111255
|
}
|
|
111256
|
+
if (isGatewayMain && !bootResumeThrew)
|
|
111257
|
+
markBootResumeComplete(STATE_DIR);
|
|
110641
111258
|
if (isGatewayMain && inboundSpool != null) {
|
|
110642
111259
|
const replay = inboundSpool.liveEntries();
|
|
110643
111260
|
for (const e of replay)
|
|
@@ -110711,8 +111328,8 @@ var bridgeDeadWatchdog = createBridgeDeadWatchdog({
|
|
|
110711
111328
|
isSessionAlive: () => findAgentProcessInContainer2()?.comm === "claude",
|
|
110712
111329
|
isShuttingDown: () => shuttingDown,
|
|
110713
111330
|
escalate: (reason) => triggerSelfRestart(process.env.SWITCHROOM_AGENT_NAME ?? "", reason, 1500),
|
|
110714
|
-
crashLogPath:
|
|
110715
|
-
markerPath:
|
|
111331
|
+
crashLogPath: join77(STATE_DIR, "bridge-crash.log"),
|
|
111332
|
+
markerPath: join77(STATE_DIR, "bridge-dead-escalation.json"),
|
|
110716
111333
|
log: (line) => process.stderr.write(`${line}
|
|
110717
111334
|
`),
|
|
110718
111335
|
priorStreak: bridgeDeadPriorStreak,
|
|
@@ -110819,8 +111436,8 @@ if (isGatewayMain)
|
|
|
110819
111436
|
probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
|
|
110820
111437
|
tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
|
|
110821
111438
|
dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
|
|
110822
|
-
configSnapshotPath:
|
|
110823
|
-
bootCardStatePath:
|
|
111439
|
+
configSnapshotPath: join77(resolvedAgentDirForCard, ".config-snapshot.json"),
|
|
111440
|
+
bootCardStatePath: join77(resolvedAgentDirForCard, ".boot-card-msgid.json"),
|
|
110824
111441
|
floodStatePath: FLOOD_STATE_PATH,
|
|
110825
111442
|
...updateOutcomeLine ? { updateOutcomeLine } : {}
|
|
110826
111443
|
}, ackMsgId).then((handle) => {
|
|
@@ -110920,7 +111537,7 @@ if (isGatewayMain)
|
|
|
110920
111537
|
if (turnsDb != null && msg.activeFile != null) {
|
|
110921
111538
|
const stampKey = currentTurn?.registryKey ?? null;
|
|
110922
111539
|
if (stampKey != null && stampKey !== lastSessionStampedTurnKey) {
|
|
110923
|
-
const sessionId =
|
|
111540
|
+
const sessionId = basename19(msg.activeFile).replace(/\.jsonl$/, "");
|
|
110924
111541
|
if (sessionId) {
|
|
110925
111542
|
try {
|
|
110926
111543
|
stampTurnSessionId(turnsDb, stampKey, sessionId);
|
|
@@ -111418,10 +112035,10 @@ if (isGatewayMain)
|
|
|
111418
112035
|
}
|
|
111419
112036
|
},
|
|
111420
112037
|
onPostSkillProposal(_client, msg) {
|
|
111421
|
-
handlePostSkillProposal(msg, { bot, assertAllowedChat, swallowingApiCall });
|
|
112038
|
+
handlePostSkillProposal(msg, { bot, assertAllowedChat, swallowingApiCall, deliverResumeSyntheticOrBuffer });
|
|
111422
112039
|
},
|
|
111423
112040
|
onPostEvalCaseProposal(_client, msg) {
|
|
111424
|
-
handlePostEvalCaseProposal(msg, { bot, assertAllowedChat, swallowingApiCall });
|
|
112041
|
+
handlePostEvalCaseProposal(msg, { bot, assertAllowedChat, swallowingApiCall, deliverResumeSyntheticOrBuffer });
|
|
111425
112042
|
},
|
|
111426
112043
|
onBuzzPublishResult: (_c, m) => getBuzzMirror()?.onPublishResult(m),
|
|
111427
112044
|
log: (msg) => process.stderr.write(`telegram gateway: ipc \u2014 ${msg}
|
|
@@ -111454,7 +112071,7 @@ if (isGatewayMain)
|
|
|
111454
112071
|
const receiverUid = receiverUidRaw ? Number(receiverUidRaw) : NaN;
|
|
111455
112072
|
if (Number.isInteger(receiverUid))
|
|
111456
112073
|
allowedUids.push(receiverUid);
|
|
111457
|
-
const socketPath =
|
|
112074
|
+
const socketPath = join77(STATE_DIR, "webhook.sock");
|
|
111458
112075
|
const webhookInject = (agentName3, inbound) => {
|
|
111459
112076
|
const msg = inbound;
|
|
111460
112077
|
const delivered = ipcServer.sendToAgent(agentName3, msg);
|
|
@@ -111706,9 +112323,9 @@ function redactOutboundText(text5, site) {
|
|
|
111706
112323
|
var VOICE_OUT_DEFAULT_CHUNK_CHARS = 600;
|
|
111707
112324
|
var VOICE_OUT_HARD_CHUNK_CAP = 4096;
|
|
111708
112325
|
var voiceOnDemandCache = new VoiceOnDemandCache({
|
|
111709
|
-
persistPath:
|
|
112326
|
+
persistPath: join77(STATE_DIR, "voice-ondemand.json")
|
|
111710
112327
|
});
|
|
111711
|
-
var VOICE_CACHE_DIR =
|
|
112328
|
+
var VOICE_CACHE_DIR = join77(STATE_DIR, "voice-cache");
|
|
111712
112329
|
var voicePreSynthQueue = new PreSynthQueue({
|
|
111713
112330
|
runJob: async (job) => {
|
|
111714
112331
|
const sidecarToken = await materializeSidecarToken2();
|
|
@@ -112116,11 +112733,11 @@ async function executeSendGif(rawArgs) {
|
|
|
112116
112733
|
};
|
|
112117
112734
|
}
|
|
112118
112735
|
async function publishToTelegraph(text5, shortName, authorName) {
|
|
112119
|
-
const accountPath =
|
|
112736
|
+
const accountPath = join77(STATE_DIR, "telegraph-account.json");
|
|
112120
112737
|
let account = null;
|
|
112121
112738
|
try {
|
|
112122
|
-
if (
|
|
112123
|
-
const raw =
|
|
112739
|
+
if (existsSync65(accountPath)) {
|
|
112740
|
+
const raw = readFileSync67(accountPath, "utf-8");
|
|
112124
112741
|
const parsed = JSON.parse(raw);
|
|
112125
112742
|
if (parsed.shortName && parsed.accessToken) {
|
|
112126
112743
|
account = parsed;
|
|
@@ -112140,7 +112757,7 @@ async function publishToTelegraph(text5, shortName, authorName) {
|
|
|
112140
112757
|
account = created.value;
|
|
112141
112758
|
try {
|
|
112142
112759
|
mkdirStateSync2(STATE_DIR, { recursive: true, mode: 448 });
|
|
112143
|
-
|
|
112760
|
+
writeFileSync55(accountPath, JSON.stringify(account, null, 2), { mode: 384 });
|
|
112144
112761
|
} catch (err) {
|
|
112145
112762
|
process.stderr.write(`telegram gateway: telegraph cache write failed: ${err.message}
|
|
112146
112763
|
`);
|
|
@@ -112256,7 +112873,7 @@ _The secret was NOT saved. The agent can re-request with \`request_secret\`._`,
|
|
|
112256
112873
|
}
|
|
112257
112874
|
function readLiveSwitchroomConfigText() {
|
|
112258
112875
|
const cfgPath = process.env.SWITCHROOM_CONFIG ?? findConfigFile2();
|
|
112259
|
-
return
|
|
112876
|
+
return readFileSync67(cfgPath, "utf8");
|
|
112260
112877
|
}
|
|
112261
112878
|
async function executeReact(args) {
|
|
112262
112879
|
if (!args.chat_id)
|
|
@@ -112297,7 +112914,7 @@ async function executeDownloadAttachment(args) {
|
|
|
112297
112914
|
});
|
|
112298
112915
|
mkdirSync50(INBOX_DIR, { recursive: true, mode: 448 });
|
|
112299
112916
|
assertInsideInbox2(INBOX_DIR, dlPath);
|
|
112300
|
-
|
|
112917
|
+
writeFileSync55(dlPath, buf, { mode: 384 });
|
|
112301
112918
|
return { content: [{ type: "text", text: dlPath }] };
|
|
112302
112919
|
}
|
|
112303
112920
|
async function executeEditMessage(args) {
|
|
@@ -113653,7 +114270,7 @@ function getMyAgentName() {
|
|
|
113653
114270
|
const fromEnv = process.env.SWITCHROOM_AGENT_NAME;
|
|
113654
114271
|
if (fromEnv && fromEnv.trim().length > 0)
|
|
113655
114272
|
return fromEnv.trim();
|
|
113656
|
-
return
|
|
114273
|
+
return basename19(process.cwd());
|
|
113657
114274
|
}
|
|
113658
114275
|
function isSelfTargetingCommand(name) {
|
|
113659
114276
|
if (name === "all")
|
|
@@ -113666,14 +114283,14 @@ function restartMarkerPath() {
|
|
|
113666
114283
|
const agentDir = resolveAgentDirFromEnv();
|
|
113667
114284
|
if (!agentDir)
|
|
113668
114285
|
return null;
|
|
113669
|
-
return
|
|
114286
|
+
return join77(agentDir, "restart-pending.json");
|
|
113670
114287
|
}
|
|
113671
114288
|
function writeRestartMarker(marker) {
|
|
113672
114289
|
const p = restartMarkerPath();
|
|
113673
114290
|
if (!p)
|
|
113674
114291
|
return;
|
|
113675
114292
|
try {
|
|
113676
|
-
|
|
114293
|
+
writeFileSync55(p, JSON.stringify(marker));
|
|
113677
114294
|
lastPlannedRestartAt = Date.now();
|
|
113678
114295
|
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}
|
|
113679
114296
|
`);
|
|
@@ -113692,7 +114309,7 @@ function readRestartMarker() {
|
|
|
113692
114309
|
if (!p)
|
|
113693
114310
|
return null;
|
|
113694
114311
|
try {
|
|
113695
|
-
return JSON.parse(
|
|
114312
|
+
return JSON.parse(readFileSync67(p, "utf8"));
|
|
113696
114313
|
} catch {
|
|
113697
114314
|
return null;
|
|
113698
114315
|
}
|
|
@@ -113841,7 +114458,7 @@ var _dockerReachable;
|
|
|
113841
114458
|
function isDockerReachable() {
|
|
113842
114459
|
if (_dockerReachable !== undefined)
|
|
113843
114460
|
return _dockerReachable;
|
|
113844
|
-
if (!
|
|
114461
|
+
if (!existsSync65("/var/run/docker.sock")) {
|
|
113845
114462
|
_dockerReachable = false;
|
|
113846
114463
|
return _dockerReachable;
|
|
113847
114464
|
}
|
|
@@ -113858,12 +114475,12 @@ function _resetDockerReachableCache() {
|
|
|
113858
114475
|
}
|
|
113859
114476
|
function spawnSwitchroomDetached(args, onFailure) {
|
|
113860
114477
|
const fullArgs = SWITCHROOM_CONFIG ? ["--config", SWITCHROOM_CONFIG, ...args] : args;
|
|
113861
|
-
const logPath =
|
|
114478
|
+
const logPath = join77(STATE_DIR, "detached-spawn.log");
|
|
113862
114479
|
let outFd = null;
|
|
113863
114480
|
try {
|
|
113864
114481
|
mkdirStateSync2(STATE_DIR, { recursive: true });
|
|
113865
114482
|
outFd = openSync18(logPath, "a");
|
|
113866
|
-
|
|
114483
|
+
writeFileSync55(logPath, `
|
|
113867
114484
|
[${new Date().toISOString()}] spawn ${SWITCHROOM_CLI} ${fullArgs.join(" ")}
|
|
113868
114485
|
`, { flag: "a" });
|
|
113869
114486
|
} catch {}
|
|
@@ -113889,7 +114506,7 @@ function spawnSwitchroomDetached(args, onFailure) {
|
|
|
113889
114506
|
return;
|
|
113890
114507
|
let tail = "";
|
|
113891
114508
|
try {
|
|
113892
|
-
const full =
|
|
114509
|
+
const full = readFileSync67(logPath, "utf8");
|
|
113893
114510
|
tail = full.split(`
|
|
113894
114511
|
`).slice(-30).join(`
|
|
113895
114512
|
`).trim();
|
|
@@ -114151,10 +114768,10 @@ ${preBlock(formatSwitchroomOutput(detail))}`, { html: true });
|
|
|
114151
114768
|
}
|
|
114152
114769
|
function readRecentDenialsForAgent(agentName3, windowMs, limit) {
|
|
114153
114770
|
try {
|
|
114154
|
-
const auditPath =
|
|
114155
|
-
if (!
|
|
114771
|
+
const auditPath = join77(homedir22(), ".switchroom", "vault-audit.log");
|
|
114772
|
+
if (!existsSync65(auditPath))
|
|
114156
114773
|
return [];
|
|
114157
|
-
const raw =
|
|
114774
|
+
const raw = readFileSync67(auditPath, "utf8");
|
|
114158
114775
|
return recentDenialsFromAuditLog(raw, { agentName: agentName3, windowMs, limit });
|
|
114159
114776
|
} catch {
|
|
114160
114777
|
return [];
|
|
@@ -114205,7 +114822,7 @@ async function buildAgentMetadata(agentName3) {
|
|
|
114205
114822
|
try {
|
|
114206
114823
|
const agentDir = resolveAgentDirFromEnv();
|
|
114207
114824
|
if (agentDir) {
|
|
114208
|
-
const raw =
|
|
114825
|
+
const raw = readFileSync67(join77(agentDir, ".claude", ".claude.json"), "utf8");
|
|
114209
114826
|
claudeJson = JSON.parse(raw);
|
|
114210
114827
|
}
|
|
114211
114828
|
} catch {}
|
|
@@ -114334,7 +114951,7 @@ function buildModelDeps(restartCtx) {
|
|
|
114334
114951
|
try {
|
|
114335
114952
|
const agentDir = resolveAgentDirFromEnv();
|
|
114336
114953
|
if (agentDir) {
|
|
114337
|
-
const local = await fetchQuota2({ claudeConfigDir:
|
|
114954
|
+
const local = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
|
|
114338
114955
|
if (local.ok)
|
|
114339
114956
|
return formatQuotaLine2(local.data);
|
|
114340
114957
|
}
|
|
@@ -114581,10 +115198,10 @@ function effortMenuReplyMarkup(reply) {
|
|
|
114581
115198
|
function flushAgentHandoff(agentDir) {
|
|
114582
115199
|
let removed = 0;
|
|
114583
115200
|
for (const fname of [".handoff.md", ".handoff-topic"]) {
|
|
114584
|
-
const p =
|
|
115201
|
+
const p = join77(agentDir, fname);
|
|
114585
115202
|
try {
|
|
114586
|
-
if (
|
|
114587
|
-
|
|
115203
|
+
if (existsSync65(p)) {
|
|
115204
|
+
unlinkSync33(p);
|
|
114588
115205
|
removed++;
|
|
114589
115206
|
}
|
|
114590
115207
|
} catch (err) {
|
|
@@ -114639,7 +115256,7 @@ async function handleNewCommand(ctx) {
|
|
|
114639
115256
|
writeRestartMarker({ chat_id: chatId, thread_id: threadId ?? null, ack_message_id: ackId, ts: Date.now() });
|
|
114640
115257
|
if (agentDir != null) {
|
|
114641
115258
|
try {
|
|
114642
|
-
|
|
115259
|
+
writeFileSync55(join77(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
|
|
114643
115260
|
`, "utf8");
|
|
114644
115261
|
} catch (err) {
|
|
114645
115262
|
process.stderr.write(`telegram gateway: failed to write force-fresh marker: ${err}
|
|
@@ -114752,16 +115369,16 @@ function buildFolderPickerDeps() {
|
|
|
114752
115369
|
};
|
|
114753
115370
|
}
|
|
114754
115371
|
var lockoutOps = {
|
|
114755
|
-
readFileSync: (p, enc) =>
|
|
115372
|
+
readFileSync: (p, enc) => readFileSync67(p, enc),
|
|
114756
115373
|
writeFileSync: (p, data, opts) => writeStateFileSync2(p, data, opts),
|
|
114757
|
-
existsSync: (p) =>
|
|
115374
|
+
existsSync: (p) => existsSync65(p),
|
|
114758
115375
|
mkdirSync: (p, opts) => mkdirStateSync2(p, opts),
|
|
114759
|
-
joinPath: (...parts) =>
|
|
115376
|
+
joinPath: (...parts) => join77(...parts)
|
|
114760
115377
|
};
|
|
114761
115378
|
var FLEET_FALLBACK_DEDUP_MS = 30000;
|
|
114762
115379
|
function isAuthBrokerSocketReachable() {
|
|
114763
115380
|
try {
|
|
114764
|
-
return
|
|
115381
|
+
return existsSync65(resolveAuthBrokerSocketPath2());
|
|
114765
115382
|
} catch {
|
|
114766
115383
|
return false;
|
|
114767
115384
|
}
|
|
@@ -115017,7 +115634,7 @@ async function runCreditWatch() {
|
|
|
115017
115634
|
if (!agentDir)
|
|
115018
115635
|
return;
|
|
115019
115636
|
const agentName3 = getMyAgentName();
|
|
115020
|
-
const claudeConfigDir =
|
|
115637
|
+
const claudeConfigDir = join77(agentDir, ".claude");
|
|
115021
115638
|
const stateDir = STATE_DIR;
|
|
115022
115639
|
const reason = readClaudeJsonOverage(claudeConfigDir);
|
|
115023
115640
|
const prev = loadCreditState(stateDir);
|
|
@@ -116787,7 +117404,7 @@ Send \`/auth ${parsed.provider} cancel\` to abort.`, { html: true });
|
|
|
116787
117404
|
await switchroomReply(ctx, "**/usage:** cannot resolve agent dir.", { html: true });
|
|
116788
117405
|
return;
|
|
116789
117406
|
}
|
|
116790
|
-
const result = await fetchQuota2({ claudeConfigDir:
|
|
117407
|
+
const result = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
|
|
116791
117408
|
if (!result.ok) {
|
|
116792
117409
|
await switchroomReply(ctx, `**/usage:** ${escapeHtmlForTg2(result.reason)}`, { html: true });
|
|
116793
117410
|
return;
|
|
@@ -117178,7 +117795,7 @@ ${interimLabel}` : interimLabel
|
|
|
117178
117795
|
const unifiedDiff = (() => {
|
|
117179
117796
|
try {
|
|
117180
117797
|
const cfgPath = process.env.SWITCHROOM_CONFIG ?? SWITCHROOM_CONFIG ?? findConfigFile2();
|
|
117181
|
-
const raw =
|
|
117798
|
+
const raw = readFileSync67(cfgPath, "utf8");
|
|
117182
117799
|
return synthesizeAllowRuleDiff({ agentName: agentName3, rule: chosen.rule, configText: raw });
|
|
117183
117800
|
} catch (err) {
|
|
117184
117801
|
process.stderr.write(`telegram gateway: always-allow diff synth failed: ${err.message}
|
|
@@ -118053,7 +118670,7 @@ async function startGateway() {
|
|
|
118053
118670
|
return;
|
|
118054
118671
|
}
|
|
118055
118672
|
})();
|
|
118056
|
-
const resolvedAgentDirForBootCard = agentDir ??
|
|
118673
|
+
const resolvedAgentDirForBootCard = agentDir ?? join77(homedir22(), ".switchroom", "agents", agentSlug);
|
|
118057
118674
|
const handle = await startBootCard(chatId, threadId, botApiForCard, {
|
|
118058
118675
|
agentName: agentDisplayName,
|
|
118059
118676
|
agentSlug,
|
|
@@ -118067,8 +118684,8 @@ async function startGateway() {
|
|
|
118067
118684
|
probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
|
|
118068
118685
|
tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
|
|
118069
118686
|
dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
|
|
118070
|
-
configSnapshotPath:
|
|
118071
|
-
bootCardStatePath:
|
|
118687
|
+
configSnapshotPath: join77(resolvedAgentDirForBootCard, ".config-snapshot.json"),
|
|
118688
|
+
bootCardStatePath: join77(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
|
|
118072
118689
|
floodStatePath: FLOOD_STATE_PATH,
|
|
118073
118690
|
...updateOutcomeLine ? { updateOutcomeLine } : {}
|
|
118074
118691
|
}, ackMsgId);
|
|
@@ -118101,7 +118718,7 @@ async function startGateway() {
|
|
|
118101
118718
|
if (smAgentDir) {
|
|
118102
118719
|
const resolutionTimeoutMs = resolveSessionModelResolutionTimeoutMs(process.env.SWITCHROOM_SESSION_MODEL_RESOLUTION_TIMEOUT_MS);
|
|
118103
118720
|
const resolved = await waitForSessionModelResolution({
|
|
118104
|
-
barrierExists: () =>
|
|
118721
|
+
barrierExists: () => existsSync65(join77(smAgentDir, ".session-model-resolved")),
|
|
118105
118722
|
timeoutMs: resolutionTimeoutMs
|
|
118106
118723
|
});
|
|
118107
118724
|
if (!resolved) {
|
|
@@ -118109,10 +118726,10 @@ async function startGateway() {
|
|
|
118109
118726
|
process.stderr.write(`telegram gateway: gw /model relaunch UNRESOLVED agent=${getMyAgentName()} target=${target} (barrier timeout after ${resolutionTimeoutMs}ms)
|
|
118110
118727
|
`);
|
|
118111
118728
|
} else {
|
|
118112
|
-
const activePath =
|
|
118113
|
-
if (
|
|
118729
|
+
const activePath = join77(smAgentDir, ".active-session-model");
|
|
118730
|
+
if (existsSync65(activePath)) {
|
|
118114
118731
|
try {
|
|
118115
|
-
const launched =
|
|
118732
|
+
const launched = readFileSync67(activePath, "utf8").trim();
|
|
118116
118733
|
const configured = (() => {
|
|
118117
118734
|
const d = switchroomExecJson(["agent", "list"]);
|
|
118118
118735
|
const raw = d?.agents?.find((a) => a.name === getMyAgentName())?.model ?? null;
|
|
@@ -118145,29 +118762,29 @@ async function startGateway() {
|
|
|
118145
118762
|
deliverModelSwitchBootNotice({
|
|
118146
118763
|
...modelBootCardDeps,
|
|
118147
118764
|
confirmation,
|
|
118148
|
-
hasSessionModelAlert:
|
|
118765
|
+
hasSessionModelAlert: existsSync65(join77(smAgentDir, ".session-model-alert"))
|
|
118149
118766
|
});
|
|
118150
118767
|
}
|
|
118151
118768
|
} catch {}
|
|
118152
118769
|
}
|
|
118153
|
-
const activeEffortPath =
|
|
118154
|
-
if (
|
|
118770
|
+
const activeEffortPath = join77(smAgentDir, ".active-session-effort");
|
|
118771
|
+
if (existsSync65(activeEffortPath)) {
|
|
118155
118772
|
try {
|
|
118156
|
-
const launchedEffort =
|
|
118773
|
+
const launchedEffort = readFileSync67(activeEffortPath, "utf8").trim();
|
|
118157
118774
|
const configuredEffort = getConfiguredEffortForPersist();
|
|
118158
118775
|
sessionEffortOverride = launchedEffort.length > 0 && launchedEffort !== configuredEffort ? launchedEffort : null;
|
|
118159
118776
|
} catch {}
|
|
118160
118777
|
}
|
|
118161
|
-
const alertPath =
|
|
118162
|
-
if (
|
|
118778
|
+
const alertPath = join77(smAgentDir, ".session-model-alert");
|
|
118779
|
+
if (existsSync65(alertPath)) {
|
|
118163
118780
|
let alertText = null;
|
|
118164
118781
|
try {
|
|
118165
|
-
alertText =
|
|
118782
|
+
alertText = readFileSync67(alertPath, "utf8").trim();
|
|
118166
118783
|
} catch {
|
|
118167
118784
|
alertText = null;
|
|
118168
118785
|
}
|
|
118169
118786
|
try {
|
|
118170
|
-
|
|
118787
|
+
unlinkSync33(alertPath);
|
|
118171
118788
|
} catch {}
|
|
118172
118789
|
if (alertText && alertText.length > 0) {
|
|
118173
118790
|
const operators = loadAccess().allowFrom;
|