switchroom 0.21.8 → 0.21.10

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.
Files changed (40) hide show
  1. package/dist/cli/switchroom.js +100 -39
  2. package/dist/host-control/main.js +1 -1
  3. package/package.json +2 -2
  4. package/skills/switchroom-architecture/telegram.md +12 -10
  5. package/skills/switchroom-cli/SKILL.md +1 -1
  6. package/telegram-plugin/README.md +3 -1
  7. package/telegram-plugin/dist/gateway/gateway.js +919 -348
  8. package/telegram-plugin/format.ts +30 -5
  9. package/telegram-plugin/gateway/outbound-send-path.ts +7 -0
  10. package/telegram-plugin/gateway/speech-capture.ts +158 -0
  11. package/telegram-plugin/package.json +1 -1
  12. package/telegram-plugin/render/code-segments.ts +38 -4
  13. package/telegram-plugin/render/dollar-math-guard.ts +16 -1
  14. package/telegram-plugin/render/html-fold.ts +354 -0
  15. package/telegram-plugin/render/ir.ts +53 -3
  16. package/telegram-plugin/render/parse.ts +642 -42
  17. package/telegram-plugin/render/render.ts +53 -15
  18. package/telegram-plugin/render/unsupported-token-guard.ts +45 -80
  19. package/telegram-plugin/rich-send.ts +22 -7
  20. package/telegram-plugin/shared/bot-runtime.ts +3 -2
  21. package/telegram-plugin/telegraph.ts +6 -4
  22. package/telegram-plugin/tests/grammy-rich-message-types.test.ts +199 -0
  23. package/telegram-plugin/tests/render/dollar-math-guard.test.ts +43 -0
  24. package/telegram-plugin/tests/render/guard-composition.test.ts +102 -0
  25. package/telegram-plugin/tests/render/html-dialect-content-loss.test.ts +253 -0
  26. package/telegram-plugin/tests/render/html-dialect.test.ts +283 -0
  27. package/telegram-plugin/tests/render/parse.test.ts +39 -10
  28. package/telegram-plugin/tests/render/render.test.ts +9 -4
  29. package/telegram-plugin/tests/render/rich-render.test.ts +46 -5
  30. package/telegram-plugin/tests/render/tg-entity.test.ts +242 -0
  31. package/telegram-plugin/tests/render/unsupported-token-guard.test.ts +66 -66
  32. package/telegram-plugin/tests/send-reply-golden.test.ts +99 -1
  33. package/telegram-plugin/tests/sent-text-capture.test.ts +3 -3
  34. package/telegram-plugin/tests/speech-capture.test.ts +296 -0
  35. package/telegram-plugin/tests/telegraph.test.ts +1 -1
  36. package/telegram-plugin/tests/tts-normalize.test.ts +114 -0
  37. package/telegram-plugin/tests/voice-normalize-text.test.ts +89 -0
  38. package/telegram-plugin/tts-normalize.ts +47 -9
  39. package/telegram-plugin/uat/scenarios/jtbd-rich-formatting-render-dm.test.ts +17 -8
  40. package/telegram-plugin/voice-normalize-text.ts +48 -9
@@ -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.44.0/node_modules/grammy/out/filter.js
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.44.0/node_modules/grammy/out/context.js
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 || _g === undefined ? undefined : _g.user) !== null && _h !== undefined ? _h : (_t = (_s = (_r = (_q = (_p = (_o = (_m = (_l = (_k = (_j = this.callbackQuery) !== null && _j !== undefined ? _j : this.msg) !== null && _k !== undefined ? _k : this.inlineQuery) !== null && _l !== undefined ? _l : this.chosenInlineResult) !== null && _m !== undefined ? _m : this.shippingQuery) !== null && _o !== undefined ? _o : this.preCheckoutQuery) !== null && _p !== undefined ? _p : this.myChatMember) !== null && _q !== undefined ? _q : this.chatMember) !== null && _r !== undefined ? _r : this.chatJoinRequest) !== null && _s !== undefined ? _s : this.purchasedPaidMedia) === null || _t === undefined ? undefined : _t.from;
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.44.0/node_modules/grammy/out/composer.js
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.44.0/node_modules/grammy/out/platform.node.js
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.44.0/node_modules/grammy/out/core/error.js
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@3.28.0/node_modules/@grammyjs/types/mod.js
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.44.0/node_modules/grammy/out/types.node.js
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.44.0/node_modules/grammy/out/types.js
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.44.0/node_modules/grammy/out/core/payload.js
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.44.0/node_modules/grammy/out/shim.node.js
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.44.0/node_modules/grammy/out/core/client.js
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.44.0/node_modules/grammy/out/core/api.js
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.44.0/node_modules/grammy/out/bot.js
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.44.0/node_modules/grammy/out/convenience/constants.js
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.44.0/node_modules/grammy/out/convenience/inline_query.js
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.44.0/node_modules/grammy/out/convenience/input_media.js
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.44.0/node_modules/grammy/out/convenience/keyboard.js
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.44.0/node_modules/grammy/out/convenience/session.js
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.44.0/node_modules/grammy/out/convenience/frameworks.js
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.44.0/node_modules/grammy/out/convenience/webhook.js
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.44.0/node_modules/grammy/out/mod.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/platform.node.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/distribute.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/queue.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/sink.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/node-shim.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/source.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/runner.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/sequentialize.js
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.44.0/node_modules/grammy/out/mod.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/deps.node.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/worker.js
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/mod.js
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)
@@ -6714,7 +6770,7 @@ function codeSpanSafe(s) {
6714
6770
  return s.replace(/`/g, "`\u200b");
6715
6771
  }
6716
6772
  function escapeLinkHref(href) {
6717
- return href.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)");
6773
+ return href.replace(/\\/g, "\\\\").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(/[\x00-\x20\x7f]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
6718
6774
  }
6719
6775
  function repairEscapedWhitespace(text) {
6720
6776
  if (!/\\[nrt"\\]/.test(text))
@@ -7283,7 +7339,7 @@ var init_format = __esm(() => {
7283
7339
  /\*\*[^*\n]+\*\*/g,
7284
7340
  /__[^_\n]+__/g,
7285
7341
  /(?<![\w*])_[^_\n]+_(?![\w*])/g,
7286
- /\[[^\]\n]*\]\([^)\n]*\)/g,
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
- let out = text;
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 (!/[\^]|<details|<\/details|<summary/i.test(text))
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, FOOTNOTE_MARKER, DETAILS_BLOCK, ORPHAN_TAGS;
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+061f65c8e99495c7/node_modules/@grammyjs/runner/out/mod.js
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)
@@ -30125,7 +30173,7 @@ __export(exports_history, {
30125
30173
  MIN_PREFIX_MATCH_CHARS: () => MIN_PREFIX_MATCH_CHARS2
30126
30174
  });
30127
30175
  import { chmodSync as chmodSync9, existsSync as existsSync29 } from "fs";
30128
- import { join as join37 } from "path";
30176
+ import { join as join38 } from "path";
30129
30177
  function loadDatabaseClass2() {
30130
30178
  if (DatabaseClass2 != null)
30131
30179
  return DatabaseClass2;
@@ -30183,7 +30231,7 @@ function initHistory2(stateDir, retentionDays = 30) {
30183
30231
  return;
30184
30232
  const Database = loadDatabaseClass2();
30185
30233
  mkdirStateSync(stateDir, { recursive: true, mode: 448 });
30186
- const path2 = join37(stateDir, "history.db");
30234
+ const path2 = join38(stateDir, "history.db");
30187
30235
  dbPath2 = path2;
30188
30236
  db2 = new Database(path2, { create: true });
30189
30237
  db2.exec("PRAGMA journal_mode = WAL");
@@ -30637,7 +30685,7 @@ var init_turn_flush_suppression = () => {};
30637
30685
  // ../src/agents/generation-stamp.ts
30638
30686
  import { createHash as createHash6 } from "node:crypto";
30639
30687
  import { existsSync as existsSync36, readFileSync as readFileSync35, writeFileSync as writeFileSync31 } from "node:fs";
30640
- import { join as join44 } from "node:path";
30688
+ import { join as join45 } from "node:path";
30641
30689
  function sha256Text(s) {
30642
30690
  return createHash6("sha256").update(s, "utf-8").digest("hex");
30643
30691
  }
@@ -30647,7 +30695,7 @@ function hashManagedClaudeMd(content3) {
30647
30695
  return sha256Text(managed);
30648
30696
  }
30649
30697
  function hashStampedFileOnDisk(agentDir, rel) {
30650
- const p = join44(agentDir, rel);
30698
+ const p = join45(agentDir, rel);
30651
30699
  if (!existsSync36(p))
30652
30700
  return null;
30653
30701
  let content3;
@@ -30659,7 +30707,7 @@ function hashStampedFileOnDisk(agentDir, rel) {
30659
30707
  return rel === "CLAUDE.md" ? hashManagedClaudeMd(content3) : sha256Text(content3);
30660
30708
  }
30661
30709
  function readGenerationStamp(agentDir) {
30662
- const p = join44(agentDir, GENERATION_STAMP_FILE);
30710
+ const p = join45(agentDir, GENERATION_STAMP_FILE);
30663
30711
  if (!existsSync36(p))
30664
30712
  return null;
30665
30713
  try {
@@ -33663,7 +33711,7 @@ var require_util = __commonJS((exports2) => {
33663
33711
  return path2;
33664
33712
  }
33665
33713
  exports2.normalize = normalize;
33666
- function join46(aRoot, aPath) {
33714
+ function join47(aRoot, aPath) {
33667
33715
  if (aRoot === "") {
33668
33716
  aRoot = ".";
33669
33717
  }
@@ -33695,7 +33743,7 @@ var require_util = __commonJS((exports2) => {
33695
33743
  }
33696
33744
  return joined;
33697
33745
  }
33698
- exports2.join = join46;
33746
+ exports2.join = join47;
33699
33747
  exports2.isAbsolute = function(aPath) {
33700
33748
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
33701
33749
  };
@@ -33868,7 +33916,7 @@ var require_util = __commonJS((exports2) => {
33868
33916
  parsed.path = parsed.path.substring(0, index2 + 1);
33869
33917
  }
33870
33918
  }
33871
- sourceURL = join46(urlGenerate(parsed), sourceURL);
33919
+ sourceURL = join47(urlGenerate(parsed), sourceURL);
33872
33920
  }
33873
33921
  return normalize(sourceURL);
33874
33922
  }
@@ -36474,9 +36522,9 @@ function renderAuthLine(state7, agentName3, now = Date.now()) {
36474
36522
 
36475
36523
  // gateway/quota-cache.ts
36476
36524
  import { existsSync as existsSync49, readFileSync as readFileSync49, writeFileSync as writeFileSync41, mkdirSync as mkdirSync42 } from "fs";
36477
- import { join as join59, dirname as dirname25 } from "path";
36525
+ import { join as join60, dirname as dirname25 } from "path";
36478
36526
  function defaultCachePath() {
36479
- return process.env.SWITCHROOM_QUOTA_CACHE_PATH ?? join59(process.env.HOME ?? "/tmp", ".switchroom", "quota-cache.json");
36527
+ return process.env.SWITCHROOM_QUOTA_CACHE_PATH ?? join60(process.env.HOME ?? "/tmp", ".switchroom", "quota-cache.json");
36480
36528
  }
36481
36529
  function readQuotaCache(opts = {}) {
36482
36530
  const path3 = opts.path ?? defaultCachePath();
@@ -36523,7 +36571,7 @@ var init_quota_cache = __esm(() => {
36523
36571
 
36524
36572
  // gateway/boot-probes.ts
36525
36573
  import { readFileSync as readFileSync50, readdirSync as readdirSync14, existsSync as existsSync50 } from "fs";
36526
- import { join as join60 } from "path";
36574
+ import { join as join61 } from "path";
36527
36575
  import { execFile as execFileCb } from "child_process";
36528
36576
  import { promisify } from "util";
36529
36577
  async function withTimeout(label, p, timeoutMs = PROBE_TIMEOUT_MS) {
@@ -36565,8 +36613,8 @@ function mapPlan(billingType, hasExtra) {
36565
36613
  }
36566
36614
  async function probeAccount(agentDir) {
36567
36615
  return withTimeout("Account", (async () => {
36568
- const claudeDir = join60(agentDir, ".claude");
36569
- const claudeJsonPath = join60(claudeDir, ".claude.json");
36616
+ const claudeDir = join61(agentDir, ".claude");
36617
+ const claudeJsonPath = join61(claudeDir, ".claude.json");
36570
36618
  let cfg = {};
36571
36619
  try {
36572
36620
  const raw = readFileSync50(claudeJsonPath, "utf8");
@@ -36587,8 +36635,8 @@ async function probeAccount(agentDir) {
36587
36635
  let tokenStr = "";
36588
36636
  let status = "ok";
36589
36637
  for (const candidate of [
36590
- join60(claudeDir, ".oauth-token.meta.json"),
36591
- join60(claudeDir, "accounts", "default", ".oauth-token.meta.json")
36638
+ join61(claudeDir, ".oauth-token.meta.json"),
36639
+ join61(claudeDir, "accounts", "default", ".oauth-token.meta.json")
36592
36640
  ]) {
36593
36641
  if (existsSync50(candidate)) {
36594
36642
  try {
@@ -36974,9 +37022,9 @@ async function probeQuota(claudeConfigDir, _agentDir, fetchImpl = fetch, opts =
36974
37022
  let claudeDirForProbe = null;
36975
37023
  for (const candidate of [
36976
37024
  claudeConfigDir,
36977
- join60(claudeConfigDir, "accounts", "default")
37025
+ join61(claudeConfigDir, "accounts", "default")
36978
37026
  ]) {
36979
- if (existsSync50(join60(candidate, ".oauth-token"))) {
37027
+ if (existsSync50(join61(candidate, ".oauth-token"))) {
36980
37028
  claudeDirForProbe = candidate;
36981
37029
  break;
36982
37030
  }
@@ -37211,7 +37259,7 @@ async function probeSkills(agentDir, opts = {}) {
37211
37259
  return withTimeout("Skills", (async () => {
37212
37260
  const fs3 = opts.fs ?? realSkillsFs;
37213
37261
  const max = opts.maxNamesShown ?? 3;
37214
- const skillsDir = join60(agentDir, ".claude", "skills");
37262
+ const skillsDir = join61(agentDir, ".claude", "skills");
37215
37263
  if (!fs3.exists(skillsDir)) {
37216
37264
  return { status: "ok", label: "Skills", detail: "no skills dir" };
37217
37265
  }
@@ -37226,17 +37274,17 @@ async function probeSkills(agentDir, opts = {}) {
37226
37274
  }
37227
37275
  const dangling = [];
37228
37276
  for (const name of entries) {
37229
- const skillPath = join60(skillsDir, name);
37277
+ const skillPath = join61(skillsDir, name);
37230
37278
  if (!fs3.exists(skillPath)) {
37231
37279
  dangling.push(name);
37232
37280
  continue;
37233
37281
  }
37234
- const skillMd = join60(skillPath, "SKILL.md");
37282
+ const skillMd = join61(skillPath, "SKILL.md");
37235
37283
  if (!fs3.exists(skillMd) && !fs3.exists(skillPath + ".md")) {
37236
37284
  continue;
37237
37285
  }
37238
37286
  }
37239
- const overlayDir = opts.overlaySkillsDir ?? join60(agentDir, "skills.d");
37287
+ const overlayDir = opts.overlaySkillsDir ?? join61(agentDir, "skills.d");
37240
37288
  const overlaySlugs = new Set;
37241
37289
  if (fs3.exists(overlayDir)) {
37242
37290
  let overlayEntries = [];
@@ -37278,7 +37326,7 @@ function renderBucketedSkills(switchroom, agent) {
37278
37326
  }
37279
37327
  async function probeConnections(agentDir, opts = {}) {
37280
37328
  return withTimeout("Connections", (async () => {
37281
- const path3 = join60(agentDir, ".claude", "connection-health.json");
37329
+ const path3 = join61(agentDir, ".claude", "connection-health.json");
37282
37330
  const read = opts.readFileImpl ?? ((p) => readFileSync50(p, "utf8"));
37283
37331
  let issues = [];
37284
37332
  try {
@@ -37319,7 +37367,7 @@ async function probeDrift(agentDir, opts = {}) {
37319
37367
  }
37320
37368
  } catch {}
37321
37369
  try {
37322
- const raw = readFileSync50(join60(agentDir, ".switchroom-drift.json"), "utf8");
37370
+ const raw = readFileSync50(join61(agentDir, ".switchroom-drift.json"), "utf8");
37323
37371
  const report = JSON.parse(raw);
37324
37372
  if (report?.version === 1 && Array.isArray(report.findings)) {
37325
37373
  const gen = report.generatedAt ? Date.parse(report.generatedAt) : NaN;
@@ -37679,7 +37727,7 @@ __export(exports_boot_card, {
37679
37727
  readRoutingMode: () => readRoutingMode,
37680
37728
  containerBootStartMs: () => containerBootStartMs
37681
37729
  });
37682
- import { join as join61 } from "path";
37730
+ import { join as join62 } from "path";
37683
37731
  import { readFileSync as readFileSync54, statSync as statSync19 } from "fs";
37684
37732
  function resolvePersonaName(slug, loadConfig3) {
37685
37733
  try {
@@ -37724,7 +37772,7 @@ function containerBootStartMs(fsImpl = { readFileSync: readFileSync54 }) {
37724
37772
  }
37725
37773
  }
37726
37774
  function readRoutingMode(agentDir, bootStartMs, fsImpl = { readFileSync: readFileSync54, statSync: statSync19 }) {
37727
- const path3 = join61(agentDir, ".routing-mode");
37775
+ const path3 = join62(agentDir, ".routing-mode");
37728
37776
  try {
37729
37777
  const raw = fsImpl.readFileSync(path3, "utf-8");
37730
37778
  const line = raw.split(`
@@ -37831,7 +37879,7 @@ function renderBootCard(opts) {
37831
37879
  return stackCardLines(flatLines);
37832
37880
  }
37833
37881
  async function runAllProbes(opts) {
37834
- const claudeDir = join61(opts.agentDir, ".claude");
37882
+ const claudeDir = join62(opts.agentDir, ".claude");
37835
37883
  const probes = {};
37836
37884
  const slug = opts.agentSlug ?? opts.agentName;
37837
37885
  await Promise.allSettled([
@@ -39822,7 +39870,7 @@ import {
39822
39870
  closeSync as closeSync18,
39823
39871
  existsSync as existsSync65,
39824
39872
  unlinkSync as unlinkSync33,
39825
- appendFileSync as appendFileSync11
39873
+ appendFileSync as appendFileSync12
39826
39874
  } from "fs";
39827
39875
 
39828
39876
  // ../src/util/atomic.ts
@@ -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 join77, sep as sep6, basename as basename19 } from "path";
39890
+ import { join as join78, 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";
@@ -41584,7 +41632,7 @@ function normalizeForSpeech(input) {
41584
41632
  const w = numberToWords(Number(n) * 1000);
41585
41633
  return w ? w : m;
41586
41634
  });
41587
- s = s.replace(/\b(\d{1,9})(ms|sec|min|kb|mb|gb|tb|hr|s|m|h|d)(?![a-z])/gi, (m, num, unitRaw) => {
41635
+ const unitReplacer = (m, num, unitRaw) => {
41588
41636
  const unit = UNIT_MAP[unitRaw.toLowerCase()];
41589
41637
  if (!unit)
41590
41638
  return m;
@@ -41593,7 +41641,9 @@ function normalizeForSpeech(input) {
41593
41641
  if (!w)
41594
41642
  return m;
41595
41643
  return `${w} ${n === 1 ? unit.s : unit.p}`;
41596
- });
41644
+ };
41645
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})(ms|sec|min|kb|mb|gb|tb|hr)(?![a-zA-Z])/gi, unitReplacer);
41646
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})(s|m|h|d)(?![a-zA-Z])/g, unitReplacer);
41597
41647
  s = s.replace(/(\S)\s*\+\s*(\S)/g, "$1 plus $2");
41598
41648
  s = s.replace(/\s=\s/g, " equals ");
41599
41649
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
@@ -41955,7 +42005,7 @@ table omitted.`);
41955
42005
  const w = ordinalToWords(num);
41956
42006
  return w ?? m;
41957
42007
  });
41958
- s = s.replace(/\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi|s|m|h|d|g)(?![a-z])/gi, (m, num, unitRaw) => {
42008
+ const unitReplacer = (m, num, unitRaw) => {
41959
42009
  const unit = UNIT_MAP2[unitRaw.toLowerCase()];
41960
42010
  if (!unit)
41961
42011
  return m;
@@ -41964,7 +42014,9 @@ table omitted.`);
41964
42014
  if (!w)
41965
42015
  return m;
41966
42016
  return `${w} ${n === 1 ? unit.s : unit.p}`;
41967
- });
42017
+ };
42018
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi)(?![a-zA-Z])/gi, unitReplacer);
42019
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(s|m|h|d|g)(?![a-zA-Z])/g, unitReplacer);
41968
42020
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
41969
42021
  s = s.replace(/(\w)&(\w)/g, "$1 and $2");
41970
42022
  s = s.replace(/(^|\s)@(\w)/g, "$1at $2");
@@ -48063,7 +48115,7 @@ table omitted.`);
48063
48115
  const w = ordinalToWords2(num);
48064
48116
  return w ?? m;
48065
48117
  });
48066
- s = s.replace(/\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi|s|m|h|d|g)(?![a-z])/gi, (m, num, unitRaw) => {
48118
+ const unitReplacer = (m, num, unitRaw) => {
48067
48119
  const unit = UNIT_MAP3[unitRaw.toLowerCase()];
48068
48120
  if (!unit)
48069
48121
  return m;
@@ -48072,7 +48124,9 @@ table omitted.`);
48072
48124
  if (!w)
48073
48125
  return m;
48074
48126
  return `${w} ${n === 1 ? unit.s : unit.p}`;
48075
- });
48127
+ };
48128
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(ms|sec|min|km|cm|mm|kg|kb|mb|gb|tb|ghz|mhz|hr|mi)(?![a-zA-Z])/gi, unitReplacer);
48129
+ s = s.replace(/(?<![\d.,])\b(\d{1,9})\s?(s|m|h|d|g)(?![a-zA-Z])/g, unitReplacer);
48076
48130
  s = s.replace(/(\s)&(\s)/g, "$1and$2");
48077
48131
  s = s.replace(/(\w)&(\w)/g, "$1 and $2");
48078
48132
  s = s.replace(/(^|\s)@(\w)/g, "$1at $2");
@@ -64957,6 +65011,176 @@ function gfmFromMarkdown() {
64957
65011
  gfmTaskListItemFromMarkdown()
64958
65012
  ];
64959
65013
  }
65014
+ // render/html-fold.ts
65015
+ var HTML_FOLD_TAGS = {
65016
+ b: "bold",
65017
+ strong: "bold",
65018
+ i: "italic",
65019
+ em: "italic",
65020
+ s: "strike",
65021
+ del: "strike",
65022
+ strike: "strike",
65023
+ code: "code",
65024
+ a: "link",
65025
+ br: "break",
65026
+ pre: "pre"
65027
+ };
65028
+ var HTML_VOID_TAGS = new Set([
65029
+ "area",
65030
+ "base",
65031
+ "col",
65032
+ "embed",
65033
+ "hr",
65034
+ "img",
65035
+ "input",
65036
+ "link",
65037
+ "meta",
65038
+ "param",
65039
+ "source",
65040
+ "track",
65041
+ "wbr"
65042
+ ]);
65043
+ var HTML_BLOCK_LEVEL_TAGS = new Set([
65044
+ "address",
65045
+ "article",
65046
+ "blockquote",
65047
+ "center",
65048
+ "dd",
65049
+ "div",
65050
+ "dl",
65051
+ "dt",
65052
+ "fieldset",
65053
+ "figcaption",
65054
+ "figure",
65055
+ "footer",
65056
+ "form",
65057
+ "h1",
65058
+ "h2",
65059
+ "h3",
65060
+ "h4",
65061
+ "h5",
65062
+ "h6",
65063
+ "header",
65064
+ "hr",
65065
+ "li",
65066
+ "main",
65067
+ "nav",
65068
+ "ol",
65069
+ "p",
65070
+ "section",
65071
+ "table",
65072
+ "tbody",
65073
+ "td",
65074
+ "tfoot",
65075
+ "th",
65076
+ "thead",
65077
+ "tr",
65078
+ "ul"
65079
+ ]);
65080
+ function isBlockLevelTag(name) {
65081
+ return HTML_BLOCK_LEVEL_TAGS.has(name);
65082
+ }
65083
+ function isVoidTag(name) {
65084
+ return HTML_VOID_TAGS.has(name);
65085
+ }
65086
+ function escapeHtmlLiteral(text4) {
65087
+ return text4.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
65088
+ }
65089
+ var LANGUAGE_CLASS_RE = /(?:^|\s)class\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))/i;
65090
+ function languageOf(tag) {
65091
+ const m = LANGUAGE_CLASS_RE.exec(tag.attrs);
65092
+ if (m == null)
65093
+ return null;
65094
+ const cls = m[1] ?? m[2] ?? m[3] ?? "";
65095
+ const lang = cls.split(/\s+/).map((c) => /^language-(.+)$/.exec(c)?.[1]).find((c) => c != null && c.length > 0);
65096
+ return lang != null && !lang.includes("`") ? lang : null;
65097
+ }
65098
+ var HTML_PASSTHROUGH_TAGS = new Set([
65099
+ "u",
65100
+ "sub",
65101
+ "sup",
65102
+ "details",
65103
+ "summary",
65104
+ "aside",
65105
+ "cite"
65106
+ ]);
65107
+ var HTML_TOKEN_RE = /<!--[\s\S]*?-->|<\/?[A-Za-z][A-Za-z0-9-]*(?:\s[^<>]*?)?\/?>/g;
65108
+ var TAG_RE = /^<(\/?)([A-Za-z][A-Za-z0-9-]*)((?:\s[^<>]*?)?)(\/?)>$/;
65109
+ var HREF_RE = /(?:^|\s)href\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+))/i;
65110
+ function classifyHtmlTag(raw) {
65111
+ if (raw.startsWith("<!--"))
65112
+ return { kind: "comment", name: "", raw, attrs: "" };
65113
+ const m = TAG_RE.exec(raw);
65114
+ if (m == null)
65115
+ return { kind: "other", name: "", raw, attrs: "" };
65116
+ const [, slash, name, attrs, selfClose] = m;
65117
+ const kind = slash === "/" ? "close" : selfClose === "/" ? "selfclose" : "open";
65118
+ return { kind, name: name.toLowerCase(), raw, attrs: attrs ?? "" };
65119
+ }
65120
+ function hrefOf(tag) {
65121
+ const m = HREF_RE.exec(tag.attrs);
65122
+ if (m == null)
65123
+ return null;
65124
+ const value = m[1] ?? m[2] ?? m[3] ?? "";
65125
+ return value.length > 0 ? value : null;
65126
+ }
65127
+ function isPassthroughTag(tag) {
65128
+ return tag.name.length > 0 && HTML_PASSTHROUGH_TAGS.has(tag.name);
65129
+ }
65130
+ function matchedTagOffsets(tokens) {
65131
+ const matched = new Set;
65132
+ const stack = [];
65133
+ for (const { tag, start } of tokens) {
65134
+ if (tag.kind === "open" && !isVoidTag(tag.name)) {
65135
+ stack.push({ name: tag.name, start });
65136
+ continue;
65137
+ }
65138
+ if (tag.kind !== "close")
65139
+ continue;
65140
+ for (let i = stack.length - 1;i >= 0; i--) {
65141
+ if (stack[i].name !== tag.name)
65142
+ continue;
65143
+ matched.add(stack[i].start);
65144
+ matched.add(start);
65145
+ stack.length = i;
65146
+ break;
65147
+ }
65148
+ }
65149
+ return matched;
65150
+ }
65151
+ function tokenizeHtml(raw, base) {
65152
+ const pieces = [];
65153
+ const re = new RegExp(HTML_TOKEN_RE.source, "g");
65154
+ let last = 0;
65155
+ let m;
65156
+ while ((m = re.exec(raw)) != null) {
65157
+ if (m.index > last) {
65158
+ pieces.push({
65159
+ kind: "text",
65160
+ text: raw.slice(last, m.index),
65161
+ start: base + last,
65162
+ end: base + m.index
65163
+ });
65164
+ }
65165
+ pieces.push({
65166
+ kind: "tag",
65167
+ tag: classifyHtmlTag(m[0]),
65168
+ start: base + m.index,
65169
+ end: base + m.index + m[0].length
65170
+ });
65171
+ last = m.index + m[0].length;
65172
+ }
65173
+ if (last < raw.length) {
65174
+ pieces.push({
65175
+ kind: "text",
65176
+ text: raw.slice(last),
65177
+ start: base + last,
65178
+ end: base + raw.length
65179
+ });
65180
+ }
65181
+ return pieces;
65182
+ }
65183
+
64960
65184
  // render/parse.ts
64961
65185
  function pos(node2) {
64962
65186
  const p = node2.position;
@@ -64970,11 +65194,37 @@ function slice(source, node2) {
64970
65194
  return source.slice(start, end);
64971
65195
  }
64972
65196
  var EXPANDABLE_MARKER_RE = /^\*\*>/;
65197
+ var TG_INLINE_ENTITY_HREFS = ["tg://emoji", "tg://time"];
65198
+ function isTgInlineEntityHref(href) {
65199
+ const h = href.toLowerCase();
65200
+ return TG_INLINE_ENTITY_HREFS.some((base) => h === base || h.startsWith(`${base}?`));
65201
+ }
65202
+ var FENCE_DELIM_RE = /^ {0,3}(`{3,}|~{3,})/;
64973
65203
  function markExpandableQuotes(markdown) {
64974
65204
  const expandableLineStarts = new Set;
64975
65205
  let out = "";
64976
65206
  let offset = 0;
65207
+ let openFence = null;
64977
65208
  for (const line of markdown.split(/(?<=\n)/)) {
65209
+ const body = line.replace(/\r?\n$/, "");
65210
+ const fence = FENCE_DELIM_RE.exec(body)?.[1] ?? null;
65211
+ if (openFence !== null) {
65212
+ out += line;
65213
+ if (fence !== null && fence[0] === openFence[0] && fence.length >= openFence.length && body.slice(body.indexOf(fence) + fence.length).trim() === "") {
65214
+ openFence = null;
65215
+ }
65216
+ offset += line.length;
65217
+ continue;
65218
+ }
65219
+ if (fence !== null) {
65220
+ const rest = body.slice(body.indexOf(fence) + fence.length);
65221
+ if (!(fence[0] === "`" && rest.includes("`"))) {
65222
+ openFence = fence;
65223
+ out += line;
65224
+ offset += line.length;
65225
+ continue;
65226
+ }
65227
+ }
64978
65228
  if (EXPANDABLE_MARKER_RE.test(line)) {
64979
65229
  expandableLineStarts.add(offset);
64980
65230
  out += " " + line.slice(2);
@@ -64995,7 +65245,7 @@ function lineStart(source, offset) {
64995
65245
  function foldAlign(a) {
64996
65246
  return a ?? null;
64997
65247
  }
64998
- function foldInline(node2, source) {
65248
+ function foldInline(node2, source, ctx) {
64999
65249
  switch (node2.type) {
65000
65250
  case "text":
65001
65251
  return { type: "plain", text: node2.value, ...pos(node2) };
@@ -65004,23 +65254,31 @@ function foldInline(node2, source) {
65004
65254
  const underline = source.slice(p.start, p.start + 2) === "__";
65005
65255
  return {
65006
65256
  type: underline ? "underline" : "bold",
65007
- children: foldInlineChildren(node2, source),
65257
+ children: foldInlineChildren(node2, source, ctx),
65008
65258
  ...p
65009
65259
  };
65010
65260
  }
65011
65261
  case "emphasis":
65012
- return { type: "italic", children: foldInlineChildren(node2, source), ...pos(node2) };
65262
+ return { type: "italic", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65013
65263
  case "delete":
65014
- return { type: "strike", children: foldInlineChildren(node2, source), ...pos(node2) };
65264
+ return { type: "strike", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65015
65265
  case "inlineCode":
65016
65266
  return { type: "code", text: node2.value, ...pos(node2) };
65017
65267
  case "link":
65018
65268
  return {
65019
65269
  type: "link",
65020
65270
  href: node2.url,
65021
- children: foldInlineChildren(node2, source),
65271
+ children: foldInlineChildren(node2, source, ctx),
65022
65272
  ...pos(node2)
65023
65273
  };
65274
+ case "image": {
65275
+ if (isTgInlineEntityHref(node2.url)) {
65276
+ return { type: "tg-entity", label: node2.alt ?? "", href: node2.url, ...pos(node2) };
65277
+ }
65278
+ return { type: "plain", text: slice(source, node2), ...pos(node2) };
65279
+ }
65280
+ case "footnoteReference":
65281
+ return { type: "raw", text: slice(source, node2), ...pos(node2) };
65024
65282
  default:
65025
65283
  return { type: "plain", text: slice(source, node2), ...pos(node2) };
65026
65284
  }
@@ -65066,28 +65324,250 @@ function expandPlainNode(node2, source) {
65066
65324
  }
65067
65325
  return out;
65068
65326
  }
65069
- function buildInlines(children, source) {
65070
- return children.map((c) => foldInline(c, source)).flatMap((n) => n.type === "plain" ? expandPlainNode(n, source) : [n]);
65327
+ function findClosingTag(items, from, name) {
65328
+ let depth = 0;
65329
+ for (let i = from;i < items.length; i++) {
65330
+ const it = items[i];
65331
+ if (it.kind !== "tag" || it.tag.name !== name)
65332
+ continue;
65333
+ if (it.tag.kind === "open")
65334
+ depth++;
65335
+ else if (it.tag.kind === "close") {
65336
+ if (depth === 0)
65337
+ return i;
65338
+ depth--;
65339
+ }
65340
+ }
65341
+ return -1;
65342
+ }
65343
+ function inlineLiteralText(nodes) {
65344
+ let out = "";
65345
+ for (const n of nodes) {
65346
+ if (n.type !== "plain")
65347
+ return null;
65348
+ out += n.text;
65349
+ }
65350
+ return out;
65351
+ }
65352
+ var structuralSeparators = new WeakSet;
65353
+ function mkSeparator(ctx, start, end) {
65354
+ const node2 = {
65355
+ type: "raw",
65356
+ text: ctx.noBreaks === true ? " " : `
65357
+ `,
65358
+ start,
65359
+ end
65360
+ };
65361
+ structuralSeparators.add(node2);
65362
+ return node2;
65363
+ }
65364
+ function normalizeSeparators(nodes) {
65365
+ const out = [];
65366
+ for (const node2 of nodes) {
65367
+ if (!structuralSeparators.has(node2)) {
65368
+ out.push(node2);
65369
+ continue;
65370
+ }
65371
+ if (out.length === 0)
65372
+ continue;
65373
+ if (structuralSeparators.has(out[out.length - 1]))
65374
+ continue;
65375
+ out.push(node2);
65376
+ }
65377
+ while (out.length > 0 && structuralSeparators.has(out[out.length - 1]))
65378
+ out.pop();
65379
+ return out;
65380
+ }
65381
+ function literalTag(tag, start, end) {
65382
+ return { type: "plain", text: escapeHtmlLiteral(tag.raw), start, end };
65383
+ }
65384
+ function foldHtmlItems(items, active, ctx) {
65385
+ const out = [];
65386
+ let i = 0;
65387
+ while (i < items.length) {
65388
+ const it = items[i];
65389
+ if (it.kind === "inline") {
65390
+ out.push(it.node);
65391
+ i++;
65392
+ continue;
65393
+ }
65394
+ const tag = it.tag;
65395
+ if (tag.kind === "comment") {
65396
+ i++;
65397
+ continue;
65398
+ }
65399
+ if (HTML_FOLD_TAGS[tag.name] === "break" && tag.kind !== "close") {
65400
+ out.push(ctx.noBreaks === true ? { type: "raw", text: " ", start: it.start, end: it.end } : { type: "raw", text: `
65401
+ `, start: it.start, end: it.end });
65402
+ i++;
65403
+ continue;
65404
+ }
65405
+ if (tag.kind === "selfclose" || tag.kind === "open" && isVoidTag(tag.name)) {
65406
+ if (isPassthroughTag(tag)) {
65407
+ out.push({ type: "raw", text: tag.raw, start: it.start, end: it.end });
65408
+ } else if (isBlockLevelTag(tag.name)) {
65409
+ out.push(mkSeparator(ctx, it.start, it.end));
65410
+ }
65411
+ i++;
65412
+ continue;
65413
+ }
65414
+ if (isPassthroughTag(tag) && (tag.kind === "open" || tag.kind === "close")) {
65415
+ out.push(ctx.matched.has(it.start) ? { type: "raw", text: tag.raw, start: it.start, end: it.end } : literalTag(tag, it.start, it.end));
65416
+ i++;
65417
+ continue;
65418
+ }
65419
+ if (tag.kind === "open") {
65420
+ const close = findClosingTag(items, i + 1, tag.name);
65421
+ const closeItem = close >= 0 ? items[close] : undefined;
65422
+ if (closeItem !== undefined && closeItem.kind === "tag") {
65423
+ out.push(...foldMatchedTag(tag, closeItem, items.slice(i + 1, close), active, ctx, {
65424
+ start: it.start,
65425
+ end: closeItem.end
65426
+ }));
65427
+ i = close + 1;
65428
+ continue;
65429
+ }
65430
+ }
65431
+ if (ctx.matched.has(it.start) && tag.kind !== "other") {
65432
+ if (isBlockLevelTag(tag.name))
65433
+ out.push(mkSeparator(ctx, it.start, it.end));
65434
+ i++;
65435
+ continue;
65436
+ }
65437
+ out.push(literalTag(tag, it.start, it.end));
65438
+ i++;
65439
+ }
65440
+ return normalizeSeparators(out);
65441
+ }
65442
+ function foldMatchedTag(tag, closeTag, innerItems, active, ctx, span) {
65443
+ const target = HTML_FOLD_TAGS[tag.name];
65444
+ if (target === "pre") {
65445
+ const folded = buildPreBlock(innerItems, ctx, span);
65446
+ if (folded !== null)
65447
+ return folded;
65448
+ }
65449
+ if (target !== undefined && target !== "break" && target !== "pre") {
65450
+ const nested = new Set(active);
65451
+ nested.add(target);
65452
+ const inner2 = foldHtmlItems(innerItems, nested, ctx);
65453
+ if (active.has(target)) {
65454
+ return target === "link" ? [
65455
+ literalTag(tag, span.start, span.start + tag.raw.length),
65456
+ ...inner2,
65457
+ literalTag(closeTag.tag, closeTag.start, closeTag.end)
65458
+ ] : inner2;
65459
+ }
65460
+ const folded = buildFoldedTag(target, tag, inner2, span.start, span.end);
65461
+ return folded !== null ? [folded] : inner2;
65462
+ }
65463
+ const inner = foldHtmlItems(innerItems, active, ctx);
65464
+ if (!isBlockLevelTag(tag.name))
65465
+ return inner;
65466
+ return [
65467
+ mkSeparator(ctx, span.start, span.start + tag.raw.length),
65468
+ ...inner,
65469
+ mkSeparator(ctx, closeTag.start, closeTag.end)
65470
+ ];
65471
+ }
65472
+ function buildPreBlock(innerItems, ctx, span) {
65473
+ let body = innerItems;
65474
+ let language = null;
65475
+ const first = body[0];
65476
+ const last = body[body.length - 1];
65477
+ if (body.length >= 2 && first?.kind === "tag" && first.tag.kind === "open" && first.tag.name === "code" && last?.kind === "tag" && last.tag.kind === "close" && last.tag.name === "code") {
65478
+ language = languageOf(first.tag);
65479
+ body = body.slice(1, -1);
65480
+ }
65481
+ let text4 = "";
65482
+ for (const item of body) {
65483
+ if (item.kind !== "inline" || item.node.type !== "plain")
65484
+ return null;
65485
+ text4 += item.node.text;
65486
+ }
65487
+ text4 = text4.replace(/^\r?\n/, "").replace(/[ \t]*\r?\n[ \t]*$/, "");
65488
+ if (ctx.noBreaks === true) {
65489
+ return [{ type: "code", text: text4.replace(/\s*\r?\n\s*/g, " "), ...span }];
65490
+ }
65491
+ const fence = "```";
65492
+ return [
65493
+ mkSeparator(ctx, span.start, span.start),
65494
+ {
65495
+ type: "raw",
65496
+ text: `${fence}${language ?? ""}
65497
+ ${text4}
65498
+ ${fence}`,
65499
+ ...span
65500
+ },
65501
+ mkSeparator(ctx, span.end, span.end)
65502
+ ];
65503
+ }
65504
+ function buildFoldedTag(target, tag, children, start, end) {
65505
+ switch (target) {
65506
+ case "bold":
65507
+ case "italic":
65508
+ case "strike":
65509
+ if (children.length === 1 && children[0].type === target)
65510
+ return children[0];
65511
+ return { type: target, children, start, end };
65512
+ case "code": {
65513
+ const text4 = inlineLiteralText(children);
65514
+ return text4 === null ? null : { type: "code", text: text4, start, end };
65515
+ }
65516
+ case "link": {
65517
+ const href = hrefOf(tag);
65518
+ return href === null ? null : { type: "link", href, children, start, end };
65519
+ }
65520
+ default:
65521
+ return null;
65522
+ }
65523
+ }
65524
+ function htmlStringToItems(raw, base, source) {
65525
+ return tokenizeHtml(raw, base).flatMap((piece) => piece.kind === "tag" ? [{ kind: "tag", tag: piece.tag, start: piece.start, end: piece.end }] : expandPlainNode(mkPlain(piece.text, piece.start, piece.end), source).map((node2) => ({ kind: "inline", node: node2 })));
65071
65526
  }
65072
- function foldInlineChildren(node2, source) {
65073
- return buildInlines(node2.children, source);
65527
+ function buildInlines(children, source, ctx) {
65528
+ const items = [];
65529
+ let sawHtml = false;
65530
+ for (const child of children) {
65531
+ if (child.type === "html") {
65532
+ sawHtml = true;
65533
+ const p = pos(child);
65534
+ items.push(...htmlStringToItems(slice(source, child), p.start, source));
65535
+ continue;
65536
+ }
65537
+ const folded = foldInline(child, source, ctx);
65538
+ const expanded = folded.type === "plain" ? expandPlainNode(folded, source) : [folded];
65539
+ for (const node2 of expanded)
65540
+ items.push({ kind: "inline", node: node2 });
65541
+ }
65542
+ if (!sawHtml)
65543
+ return items.map((it) => it.node);
65544
+ return foldHtmlItems(items, new Set, ctx);
65074
65545
  }
65075
- function foldTableRow(row, source) {
65546
+ function foldInlineChildren(node2, source, ctx) {
65547
+ return buildInlines(node2.children, source, ctx);
65548
+ }
65549
+ function foldTableRow(row, source, ctx) {
65076
65550
  const cells = row.children.map((cell) => ({
65077
- children: buildInlines(cell.children, source),
65551
+ children: buildInlines(cell.children, source, { ...ctx, noBreaks: true }),
65078
65552
  ...pos(cell)
65079
65553
  }));
65080
65554
  return { cells, ...pos(row) };
65081
65555
  }
65082
- function foldBlock(node2, source, expandableLineStarts) {
65556
+ function isEmptyBlock(block) {
65557
+ return block.type === "paragraph" && block.children.length === 0;
65558
+ }
65559
+ function foldBlocks(nodes, source, expandableLineStarts, ctx) {
65560
+ return nodes.map((n) => foldBlock(n, source, expandableLineStarts, ctx)).filter((b) => !isEmptyBlock(b));
65561
+ }
65562
+ function foldBlock(node2, source, expandableLineStarts, ctx) {
65083
65563
  switch (node2.type) {
65084
65564
  case "paragraph":
65085
- return { type: "paragraph", children: foldInlineChildren(node2, source), ...pos(node2) };
65565
+ return { type: "paragraph", children: foldInlineChildren(node2, source, ctx), ...pos(node2) };
65086
65566
  case "heading":
65087
65567
  return {
65088
65568
  type: "heading",
65089
65569
  level: node2.depth,
65090
- children: foldInlineChildren(node2, source),
65570
+ children: foldInlineChildren(node2, source, { ...ctx, noBreaks: true }),
65091
65571
  ...pos(node2)
65092
65572
  };
65093
65573
  case "blockquote": {
@@ -65095,7 +65575,7 @@ function foldBlock(node2, source, expandableLineStarts) {
65095
65575
  const expandable = expandableLineStarts.has(lineStart(source, p.start));
65096
65576
  return {
65097
65577
  type: "blockquote",
65098
- children: node2.children.map((c) => foldBlock(c, source, expandableLineStarts)),
65578
+ children: foldBlocks(node2.children, source, expandableLineStarts, ctx),
65099
65579
  expandable,
65100
65580
  ...p
65101
65581
  };
@@ -65109,7 +65589,7 @@ function foldBlock(node2, source, expandableLineStarts) {
65109
65589
  };
65110
65590
  case "list": {
65111
65591
  const items = node2.children.map((li) => ({
65112
- children: li.children.map((c) => foldBlock(c, source, expandableLineStarts)),
65592
+ children: foldBlocks(li.children, source, expandableLineStarts, ctx),
65113
65593
  checked: li.checked ?? null,
65114
65594
  spread: li.spread ?? false,
65115
65595
  ...pos(li)
@@ -65130,12 +65610,26 @@ function foldBlock(node2, source, expandableLineStarts) {
65130
65610
  const [headerRow2, ...bodyRows] = rows;
65131
65611
  return {
65132
65612
  type: "table",
65133
- header: foldTableRow(headerRow2, source),
65134
- rows: bodyRows.map((r) => foldTableRow(r, source)),
65613
+ header: foldTableRow(headerRow2, source, ctx),
65614
+ rows: bodyRows.map((r) => foldTableRow(r, source, ctx)),
65135
65615
  align: (node2.align ?? []).map(foldAlign),
65136
65616
  ...pos(node2)
65137
65617
  };
65138
65618
  }
65619
+ case "footnoteDefinition":
65620
+ return {
65621
+ type: "paragraph",
65622
+ children: [{ type: "raw", text: slice(source, node2), ...pos(node2) }],
65623
+ ...pos(node2)
65624
+ };
65625
+ case "html": {
65626
+ const p = pos(node2);
65627
+ return {
65628
+ type: "paragraph",
65629
+ children: foldHtmlItems(htmlStringToItems(slice(source, node2), p.start, source), new Set, ctx),
65630
+ ...p
65631
+ };
65632
+ }
65139
65633
  default:
65140
65634
  return {
65141
65635
  type: "paragraph",
@@ -65151,12 +65645,37 @@ function parse2(markdown) {
65151
65645
  mdastExtensions: [gfmFromMarkdown()]
65152
65646
  });
65153
65647
  return {
65154
- blocks: tree.children.map((child) => foldBlock(child, markdown, expandableLineStarts))
65648
+ blocks: foldBlocks(tree.children, markdown, expandableLineStarts, {
65649
+ matched: matchedTagOffsets(collectHtmlTokens(tree.children, markdown))
65650
+ })
65155
65651
  };
65156
65652
  }
65653
+ function collectHtmlTokens(nodes, source) {
65654
+ const out = [];
65655
+ const walk = (list2) => {
65656
+ for (const node2 of list2) {
65657
+ if (node2.type === "html") {
65658
+ const p = pos(node2);
65659
+ for (const piece of tokenizeHtml(slice(source, node2), p.start)) {
65660
+ if (piece.kind === "tag")
65661
+ out.push({ tag: piece.tag, start: piece.start });
65662
+ }
65663
+ continue;
65664
+ }
65665
+ const children = node2.children;
65666
+ if (Array.isArray(children))
65667
+ walk(children);
65668
+ }
65669
+ };
65670
+ walk(nodes);
65671
+ return out;
65672
+ }
65157
65673
 
65158
65674
  // render/render.ts
65159
65675
  init_format();
65676
+ function collapseLabelBreaks(label) {
65677
+ return label.replace(/[ \t]*\r?\n[ \t\r\n]*/g, " ");
65678
+ }
65160
65679
  function renderInline(node2, ctx = {}) {
65161
65680
  switch (node2.type) {
65162
65681
  case "plain":
@@ -65179,6 +65698,10 @@ function renderInline(node2, ctx = {}) {
65179
65698
  }
65180
65699
  case "link":
65181
65700
  return `[${renderInlineChildren(node2.children, ctx)}](${escapeLinkHref(node2.href)})`;
65701
+ case "tg-entity":
65702
+ return `![${escapeMarkdown(collapseLabelBreaks(node2.label))}](${escapeLinkHref(node2.href)})`;
65703
+ case "raw":
65704
+ return node2.text;
65182
65705
  default: {
65183
65706
  const _exhaustive = node2;
65184
65707
  return escapeMarkdown(_exhaustive.text ?? "");
@@ -65195,15 +65718,6 @@ function prefixLines(text4, prefix) {
65195
65718
  }
65196
65719
  function renderBlockquote(node2) {
65197
65720
  const inner = renderBlocks3(node2.children);
65198
- if (node2.expandable) {
65199
- const lines = inner.split(`
65200
- `);
65201
- return lines.map((line, i) => {
65202
- const marker = i === 0 ? "**> " : "> ";
65203
- return line.length > 0 ? `${marker}${line}` : marker.trimEnd();
65204
- }).join(`
65205
- `);
65206
- }
65207
65721
  return prefixLines(inner, "> ");
65208
65722
  }
65209
65723
  function renderCodeBlock(node2) {
@@ -79383,7 +79897,7 @@ var INLINE_SPAN_PATTERNS2 = [
79383
79897
  /\*\*[^*\n]+\*\*/g,
79384
79898
  /__[^_\n]+__/g,
79385
79899
  /(?<![\w*])_[^_\n]+_(?![\w*])/g,
79386
- /\[[^\]\n]*\]\([^)\n]*\)/g,
79900
+ /!?\[[^\]\n]*\]\([^)\n]*\)/g,
79387
79901
  /~~[^~\n]+~~/g,
79388
79902
  /\|\|[^|\n]+\|\|/g
79389
79903
  ];
@@ -79815,6 +80329,62 @@ function normalizeTemporal(text4, tz, nowMs2) {
79815
80329
  return normalizeRelativeDays(normalizeUtcDatetimes(text4, tz, nowMs2), tz, nowMs2);
79816
80330
  }
79817
80331
 
80332
+ // gateway/speech-capture.ts
80333
+ import { appendFileSync as appendFileSync5 } from "node:fs";
80334
+ import { join as join34 } from "node:path";
80335
+ var SPEECH_CAPTURE_FILE_NAME = "speech-capture.jsonl";
80336
+ var SPEECH_CAPTURE_FILE_MODE = 384;
80337
+ function envFlagEnabled() {
80338
+ const v = process.env.SWITCHROOM_SPEECH_CAPTURE;
80339
+ return v === "1" || v === "true";
80340
+ }
80341
+ function isCaptureEnabled(override) {
80342
+ if (override !== undefined)
80343
+ return override;
80344
+ return envFlagEnabled();
80345
+ }
80346
+ var loggedEnabledOnce = false;
80347
+ var lastWriteErrorLoggedAt = null;
80348
+ var WRITE_ERROR_LOG_INTERVAL_MS = 5 * 60000;
80349
+ function logEnabledOnce() {
80350
+ if (loggedEnabledOnce)
80351
+ return;
80352
+ loggedEnabledOnce = true;
80353
+ try {
80354
+ process.stderr.write(`telegram gateway: speech-capture: enabled \u2014 writing $TELEGRAM_STATE_DIR/${SPEECH_CAPTURE_FILE_NAME}
80355
+ `);
80356
+ } catch {}
80357
+ }
80358
+ function logWriteErrorRateLimited(err, nowMs2) {
80359
+ if (lastWriteErrorLoggedAt !== null && nowMs2 - lastWriteErrorLoggedAt < WRITE_ERROR_LOG_INTERVAL_MS)
80360
+ return;
80361
+ lastWriteErrorLoggedAt = nowMs2;
80362
+ try {
80363
+ const msg = err instanceof Error ? err.message : String(err);
80364
+ process.stderr.write(`telegram gateway: speech-capture: write failed (further failures rate-limited ` + `${Math.round(WRITE_ERROR_LOG_INTERVAL_MS / 60000)}m) err=${msg}
80365
+ `);
80366
+ } catch {}
80367
+ }
80368
+ function captureSpeechText(text4, opts = {}) {
80369
+ if (!isCaptureEnabled(opts.enabled))
80370
+ return;
80371
+ logEnabledOnce();
80372
+ try {
80373
+ const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR;
80374
+ if (stateDir == null || stateDir.length === 0)
80375
+ return;
80376
+ const now = opts.now ?? Date.now;
80377
+ const line = `${JSON.stringify({ ts: now(), text: text4 })}
80378
+ `;
80379
+ appendFileSync5(join34(stateDir, SPEECH_CAPTURE_FILE_NAME), line, {
80380
+ encoding: "utf8",
80381
+ mode: SPEECH_CAPTURE_FILE_MODE
80382
+ });
80383
+ } catch (err) {
80384
+ logWriteErrorRateLimited(err, Date.now());
80385
+ }
80386
+ }
80387
+
79818
80388
  // gateway/outbound-send-path.ts
79819
80389
  var import_grammy11 = __toESM(require_mod2(), 1);
79820
80390
  import { statSync as statSync12 } from "fs";
@@ -79959,9 +80529,9 @@ import {
79959
80529
  statSync as statSync11,
79960
80530
  unlinkSync as unlinkSync14,
79961
80531
  writeFileSync as writeFileSync25,
79962
- appendFileSync as appendFileSync5
80532
+ appendFileSync as appendFileSync6
79963
80533
  } from "node:fs";
79964
- import { join as join34 } from "node:path";
80534
+ import { join as join35 } from "node:path";
79965
80535
  import { homedir as homedir9 } from "node:os";
79966
80536
 
79967
80537
  // hooks/audience-classify.mjs
@@ -80045,10 +80615,10 @@ function resolveStateDir2(explicit) {
80045
80615
  if (env != null && env !== "")
80046
80616
  return env;
80047
80617
  const home2 = process.env.HOME ?? homedir9();
80048
- return join34(home2, ".claude", "channels", "telegram");
80618
+ return join35(home2, ".claude", "channels", "telegram");
80049
80619
  }
80050
80620
  function resolveOutboxDir(stateDir) {
80051
- return join34(resolveStateDir2(stateDir), "outbox");
80621
+ return join35(resolveStateDir2(stateDir), "outbox");
80052
80622
  }
80053
80623
  var JOURNAL_FILE = "delivered.jsonl";
80054
80624
  var OUTBOX_MAX_AGE_MS = 30 * 60000;
@@ -80058,10 +80628,10 @@ function writeOutboxRecordAtomic(record, stateDir) {
80058
80628
  const dir = resolveOutboxDir(stateDir);
80059
80629
  try {
80060
80630
  mkdirSync29(dir, { recursive: true });
80061
- const finalPath = join34(dir, `${record.turnNonce}.json`);
80631
+ const finalPath = join35(dir, `${record.turnNonce}.json`);
80062
80632
  if (existsSync26(finalPath))
80063
80633
  return true;
80064
- const tmpPath = join34(dir, `.${record.turnNonce}.${process.pid}.tmp`);
80634
+ const tmpPath = join35(dir, `.${record.turnNonce}.${process.pid}.tmp`);
80065
80635
  writeFileSync25(tmpPath, JSON.stringify(record), { mode: 384 });
80066
80636
  renameSync14(tmpPath, finalPath);
80067
80637
  return true;
@@ -80079,7 +80649,7 @@ function listPendingRecords(stateDir) {
80079
80649
  }
80080
80650
  function readOutboxRecord(fileName, stateDir) {
80081
80651
  try {
80082
- const raw = readFileSync26(join34(resolveOutboxDir(stateDir), fileName), "utf8");
80652
+ const raw = readFileSync26(join35(resolveOutboxDir(stateDir), fileName), "utf8");
80083
80653
  return JSON.parse(raw);
80084
80654
  } catch {
80085
80655
  return null;
@@ -80087,8 +80657,8 @@ function readOutboxRecord(fileName, stateDir) {
80087
80657
  }
80088
80658
  function claimRecord(nonce, stateDir) {
80089
80659
  const dir = resolveOutboxDir(stateDir);
80090
- const from = join34(dir, `${nonce}.json`);
80091
- const to = join34(dir, `${nonce}.sending`);
80660
+ const from = join35(dir, `${nonce}.json`);
80661
+ const to = join35(dir, `${nonce}.sending`);
80092
80662
  try {
80093
80663
  renameSync14(from, to);
80094
80664
  return to;
@@ -80099,12 +80669,12 @@ function claimRecord(nonce, stateDir) {
80099
80669
  function releaseClaim(nonce, stateDir) {
80100
80670
  const dir = resolveOutboxDir(stateDir);
80101
80671
  try {
80102
- renameSync14(join34(dir, `${nonce}.sending`), join34(dir, `${nonce}.json`));
80672
+ renameSync14(join35(dir, `${nonce}.sending`), join35(dir, `${nonce}.json`));
80103
80673
  } catch {}
80104
80674
  }
80105
80675
  function removeClaimed(nonce, stateDir) {
80106
80676
  try {
80107
- unlinkSync14(join34(resolveOutboxDir(stateDir), `${nonce}.sending`));
80677
+ unlinkSync14(join35(resolveOutboxDir(stateDir), `${nonce}.sending`));
80108
80678
  } catch {}
80109
80679
  }
80110
80680
  function reclaimStaleSending(stateDir, now = Date.now()) {
@@ -80117,16 +80687,16 @@ function reclaimStaleSending(stateDir, now = Date.now()) {
80117
80687
  }
80118
80688
  for (const f of files) {
80119
80689
  try {
80120
- const st = statSync11(join34(dir, f));
80690
+ const st = statSync11(join35(dir, f));
80121
80691
  if (now - st.mtimeMs > OUTBOX_SENDING_TIMEOUT_MS) {
80122
- renameSync14(join34(dir, f), join34(dir, f.replace(/\.sending$/, ".json")));
80692
+ renameSync14(join35(dir, f), join35(dir, f.replace(/\.sending$/, ".json")));
80123
80693
  }
80124
80694
  } catch {}
80125
80695
  }
80126
80696
  }
80127
80697
  function readDeliveredNonces(stateDir) {
80128
80698
  const set = new Set;
80129
- const path2 = join34(resolveOutboxDir(stateDir), JOURNAL_FILE);
80699
+ const path2 = join35(resolveOutboxDir(stateDir), JOURNAL_FILE);
80130
80700
  if (!existsSync26(path2))
80131
80701
  return set;
80132
80702
  try {
@@ -80153,7 +80723,7 @@ function isBackstopDeliveredEntry(e) {
80153
80723
  function backstopAlreadyDelivered(nonce, stateDir) {
80154
80724
  if (nonce == null || nonce === "")
80155
80725
  return false;
80156
- const path2 = join34(resolveOutboxDir(stateDir), JOURNAL_FILE);
80726
+ const path2 = join35(resolveOutboxDir(stateDir), JOURNAL_FILE);
80157
80727
  if (!existsSync26(path2))
80158
80728
  return false;
80159
80729
  try {
@@ -80174,10 +80744,10 @@ var JOURNAL_KEEP = 2000;
80174
80744
  var JOURNAL_ROTATE_AT = 4000;
80175
80745
  function appendDelivered(entry, stateDir) {
80176
80746
  const dir = resolveOutboxDir(stateDir);
80177
- const path2 = join34(dir, JOURNAL_FILE);
80747
+ const path2 = join35(dir, JOURNAL_FILE);
80178
80748
  try {
80179
80749
  mkdirSync29(dir, { recursive: true });
80180
- appendFileSync5(path2, JSON.stringify(entry) + `
80750
+ appendFileSync6(path2, JSON.stringify(entry) + `
80181
80751
  `, { mode: 384 });
80182
80752
  compactJournalIfLarge(path2);
80183
80753
  } catch {}
@@ -80200,7 +80770,7 @@ function clearOutboxRecord(nonce, stateDir) {
80200
80770
  const dir = resolveOutboxDir(stateDir);
80201
80771
  for (const suffix of [".json", ".sending"]) {
80202
80772
  try {
80203
- unlinkSync14(join34(dir, `${nonce}${suffix}`));
80773
+ unlinkSync14(join35(dir, `${nonce}${suffix}`));
80204
80774
  } catch {}
80205
80775
  }
80206
80776
  }
@@ -80270,9 +80840,9 @@ import {
80270
80840
  readFileSync as readFileSync27,
80271
80841
  renameSync as renameSync15,
80272
80842
  writeFileSync as writeFileSync26,
80273
- appendFileSync as appendFileSync6
80843
+ appendFileSync as appendFileSync7
80274
80844
  } from "node:fs";
80275
- import { join as join35 } from "node:path";
80845
+ import { join as join36 } from "node:path";
80276
80846
 
80277
80847
  // hooks/narration-classify.mjs
80278
80848
  import { createHash as createHash5 } from "node:crypto";
@@ -80343,7 +80913,7 @@ var SHOWN_LEDGER_FILE = "shown-ledger.jsonl";
80343
80913
  var SHOWN_LEDGER_KEEP = 2000;
80344
80914
  var SHOWN_LEDGER_ROTATE_AT = 4000;
80345
80915
  function shownLedgerPath(stateDir) {
80346
- return join35(resolveOutboxDir(stateDir), SHOWN_LEDGER_FILE);
80916
+ return join36(resolveOutboxDir(stateDir), SHOWN_LEDGER_FILE);
80347
80917
  }
80348
80918
  function appendShownBlock(turnNonce, text4, stateDir, now = Date.now()) {
80349
80919
  if (turnNonce == null || turnNonce === "")
@@ -80356,7 +80926,7 @@ function appendShownBlock(turnNonce, text4, stateDir, now = Date.now()) {
80356
80926
  try {
80357
80927
  mkdirSync30(dir, { recursive: true });
80358
80928
  const entry = { turnNonce, hash: ledgerHashHex(trimmed), ts: now };
80359
- appendFileSync6(path2, JSON.stringify(entry) + `
80929
+ appendFileSync7(path2, JSON.stringify(entry) + `
80360
80930
  `, { mode: 384 });
80361
80931
  compactIfLarge(path2);
80362
80932
  } catch {}
@@ -81164,7 +81734,7 @@ function monotonicNowMs2() {
81164
81734
 
81165
81735
  // silent-end.ts
81166
81736
  import { existsSync as existsSync28, readFileSync as readFileSync28, writeFileSync as writeFileSync27, unlinkSync as unlinkSync15, mkdirSync as mkdirSync31 } from "node:fs";
81167
- import { dirname as dirname17, join as join36 } from "node:path";
81737
+ import { dirname as dirname17, join as join37 } from "node:path";
81168
81738
  import { homedir as homedir10 } from "node:os";
81169
81739
  var SILENT_END_MAX_RETRIES2 = 2;
81170
81740
  var SILENT_END_STALE_RECORD_MAX_AGE_MS2 = 30 * 60000;
@@ -81179,10 +81749,10 @@ function resolveStateDir3(deps) {
81179
81749
  if (env != null && env !== "")
81180
81750
  return env;
81181
81751
  const home2 = process.env.HOME ?? homedir10();
81182
- return join36(home2, ".claude", "channels", "telegram");
81752
+ return join37(home2, ".claude", "channels", "telegram");
81183
81753
  }
81184
81754
  function resolveStatePath3(deps) {
81185
- return join36(resolveStateDir3(deps), "silent-end-pending.json");
81755
+ return join37(resolveStateDir3(deps), "silent-end-pending.json");
81186
81756
  }
81187
81757
  function emitLog2(deps, line) {
81188
81758
  if (deps?.log != null)
@@ -81710,6 +82280,7 @@ async function sendReply(deps, req) {
81710
82280
  const protectContent = args.protect_content === true;
81711
82281
  const quoteText = args.quote_text;
81712
82282
  const access = loadAccess();
82283
+ captureSpeechText(text4);
81713
82284
  const voiceOutPlan = resolveVoiceOutPlan(access.voice_out, text4);
81714
82285
  const configParseMode = access.parseMode ?? "html";
81715
82286
  const format = args.format ?? configParseMode;
@@ -83037,20 +83608,20 @@ var INTERRUPTED_VIA = new Set([
83037
83608
  init_rich_send();
83038
83609
 
83039
83610
  // runtime-metrics.ts
83040
- import { mkdirSync as mkdirSync32, appendFileSync as appendFileSync7 } from "node:fs";
83041
- import { dirname as dirname18, join as join38 } from "node:path";
83611
+ import { mkdirSync as mkdirSync32, appendFileSync as appendFileSync8 } from "node:fs";
83612
+ import { dirname as dirname18, join as join39 } from "node:path";
83042
83613
  function resolveJsonlPath2() {
83043
83614
  const override = process.env.SWITCHROOM_RUNTIME_METRICS_PATH;
83044
83615
  if (override && override.trim() !== "")
83045
83616
  return override.trim();
83046
83617
  const base = process.env.SWITCHROOM_RUNTIME_STATE_DIR ?? "/state/agent";
83047
- return join38(base, "runtime-metrics.jsonl");
83618
+ return join39(base, "runtime-metrics.jsonl");
83048
83619
  }
83049
83620
  function appendJsonl2(line) {
83050
83621
  const path2 = resolveJsonlPath2();
83051
83622
  try {
83052
83623
  mkdirSync32(dirname18(path2), { recursive: true });
83053
- appendFileSync7(path2, line + `
83624
+ appendFileSync8(path2, line + `
83054
83625
  `, "utf-8");
83055
83626
  } catch (err) {
83056
83627
  process.stderr.write(`runtime-metrics: jsonl write failed: ${err.message}
@@ -83594,18 +84165,18 @@ import {
83594
84165
  unlinkSync as unlinkSync16,
83595
84166
  utimesSync
83596
84167
  } from "node:fs";
83597
- import { join as join39 } from "node:path";
84168
+ import { join as join40 } from "node:path";
83598
84169
  var TURN_ACTIVE_MARKER_FILE = "turn-active.json";
83599
84170
  var TURN_ACTIVE_HARD_TTL_MS = 10 * 60000;
83600
84171
  function writeTurnActiveMarker(stateDir, marker) {
83601
84172
  try {
83602
84173
  mkdirStateSync(stateDir, { recursive: true });
83603
- writeStateFileSync(join39(stateDir, TURN_ACTIVE_MARKER_FILE), JSON.stringify(marker, null, 2) + `
84174
+ writeStateFileSync(join40(stateDir, TURN_ACTIVE_MARKER_FILE), JSON.stringify(marker, null, 2) + `
83604
84175
  `, { mode: 384 });
83605
84176
  } catch {}
83606
84177
  }
83607
84178
  function touchTurnActiveMarker(stateDir) {
83608
- const path2 = join39(stateDir, TURN_ACTIVE_MARKER_FILE);
84179
+ const path2 = join40(stateDir, TURN_ACTIVE_MARKER_FILE);
83609
84180
  if (!existsSync31(path2))
83610
84181
  return;
83611
84182
  const now = new Date;
@@ -83620,11 +84191,11 @@ function touchTurnActiveMarker(stateDir) {
83620
84191
  }
83621
84192
  function removeTurnActiveMarker(stateDir) {
83622
84193
  try {
83623
- unlinkSync16(join39(stateDir, TURN_ACTIVE_MARKER_FILE));
84194
+ unlinkSync16(join40(stateDir, TURN_ACTIVE_MARKER_FILE));
83624
84195
  } catch {}
83625
84196
  }
83626
84197
  function readTurnActiveMarkerAgeMs(stateDir, now) {
83627
- const path2 = join39(stateDir, TURN_ACTIVE_MARKER_FILE);
84198
+ const path2 = join40(stateDir, TURN_ACTIVE_MARKER_FILE);
83628
84199
  try {
83629
84200
  const st = statSync13(path2);
83630
84201
  return (now ?? Date.now()) - st.mtimeMs;
@@ -85946,10 +86517,10 @@ function resolveAgentDirFromEnv() {
85946
86517
 
85947
86518
  // active-reactions.ts
85948
86519
  import { readFileSync as readFileSync30, writeFileSync as writeFileSync28, renameSync as renameSync16, existsSync as existsSync32, unlinkSync as unlinkSync17 } from "node:fs";
85949
- import { join as join40 } from "node:path";
86520
+ import { join as join41 } from "node:path";
85950
86521
  var ACTIVE_REACTIONS_FILENAME = ".active-reactions.json";
85951
86522
  function reactionsPath(agentDir) {
85952
- return join40(agentDir, ACTIVE_REACTIONS_FILENAME);
86523
+ return join41(agentDir, ACTIVE_REACTIONS_FILENAME);
85953
86524
  }
85954
86525
  function readActiveReactions(agentDir) {
85955
86526
  const p = reactionsPath(agentDir);
@@ -86014,10 +86585,10 @@ function clearActiveReactions(agentDir) {
86014
86585
 
86015
86586
  // active-reactions.ts
86016
86587
  import { readFileSync as readFileSync31, writeFileSync as writeFileSync29, renameSync as renameSync17, existsSync as existsSync33, unlinkSync as unlinkSync18 } from "node:fs";
86017
- import { join as join41 } from "node:path";
86588
+ import { join as join42 } from "node:path";
86018
86589
  var ACTIVE_REACTIONS_FILENAME2 = ".active-reactions.json";
86019
86590
  function reactionsPath2(agentDir) {
86020
- return join41(agentDir, ACTIVE_REACTIONS_FILENAME2);
86591
+ return join42(agentDir, ACTIVE_REACTIONS_FILENAME2);
86021
86592
  }
86022
86593
  function readActiveReactions2(agentDir) {
86023
86594
  const p = reactionsPath2(agentDir);
@@ -86897,12 +87468,12 @@ async function approvalRecord(args, opts) {
86897
87468
 
86898
87469
  // quota-check.ts
86899
87470
  import { readFileSync as readFileSync32, existsSync as existsSync34 } from "fs";
86900
- import { join as join42 } from "path";
87471
+ import { join as join43 } from "path";
86901
87472
  var OAUTH_BETA2 = "oauth-2025-04-20";
86902
87473
  var DEFAULT_USER_AGENT2 = "claude-cli/1.0.0 (external, cli)";
86903
87474
  var DEFAULT_PROBE_MODEL2 = "claude-haiku-4-5-20251001";
86904
87475
  function readOauthToken2(claudeConfigDir) {
86905
- const tokenFile = join42(claudeConfigDir, ".oauth-token");
87476
+ const tokenFile = join43(claudeConfigDir, ".oauth-token");
86906
87477
  if (!existsSync34(tokenFile))
86907
87478
  return null;
86908
87479
  try {
@@ -88292,7 +88863,7 @@ async function menuWithBannerStatic(deps, banner) {
88292
88863
 
88293
88864
  // gateway/session-model-file.ts
88294
88865
  import { readFileSync as readFileSync33, writeFileSync as writeFileSync30, renameSync as renameSync18, rmSync as rmSync7 } from "node:fs";
88295
- import { join as join43 } from "node:path";
88866
+ import { join as join44 } from "node:path";
88296
88867
  var SESSION_MODEL_FILE = ".session-model";
88297
88868
  var CONFIGURED_DEFAULT_MODEL_FILE = ".configured-default-model";
88298
88869
  var SESSION_MODEL_BOOT_ATTEMPTS_FILE = ".session-model-boot-attempts";
@@ -88314,28 +88885,28 @@ function writeSessionModelFile(agentDir, model, configuredDefaultAtWrite) {
88314
88885
  throw new Error(`refusing to persist non-canonical session model token: ${JSON.stringify(model)}`);
88315
88886
  }
88316
88887
  try {
88317
- rmSync7(join43(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88888
+ rmSync7(join44(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88318
88889
  } catch {}
88319
- atomicWrite(join43(agentDir, SESSION_MODEL_FILE), serializeSessionModel({ model, configuredDefaultAtWrite, ts: Date.now() }));
88890
+ atomicWrite(join44(agentDir, SESSION_MODEL_FILE), serializeSessionModel({ model, configuredDefaultAtWrite, ts: Date.now() }));
88320
88891
  }
88321
88892
  function readSessionModelFileRaw(agentDir) {
88322
88893
  try {
88323
- return readFileSync33(join43(agentDir, SESSION_MODEL_FILE), "utf8");
88894
+ return readFileSync33(join44(agentDir, SESSION_MODEL_FILE), "utf8");
88324
88895
  } catch {
88325
88896
  return null;
88326
88897
  }
88327
88898
  }
88328
88899
  function clearSessionModelFile(agentDir) {
88329
88900
  try {
88330
- rmSync7(join43(agentDir, SESSION_MODEL_FILE), { force: true });
88901
+ rmSync7(join44(agentDir, SESSION_MODEL_FILE), { force: true });
88331
88902
  } catch {}
88332
88903
  }
88333
88904
  function consumeSessionModelCarrierOnHealthyBoot(agentDir) {
88334
88905
  try {
88335
- rmSync7(join43(agentDir, SESSION_MODEL_FILE), { force: true });
88906
+ rmSync7(join44(agentDir, SESSION_MODEL_FILE), { force: true });
88336
88907
  } catch {}
88337
88908
  try {
88338
- rmSync7(join43(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88909
+ rmSync7(join44(agentDir, SESSION_MODEL_BOOT_ATTEMPTS_FILE), { force: true });
88339
88910
  } catch {}
88340
88911
  }
88341
88912
  function restoreSessionModelFileRaw(agentDir, raw) {
@@ -88344,12 +88915,12 @@ function restoreSessionModelFileRaw(agentDir, raw) {
88344
88915
  return;
88345
88916
  }
88346
88917
  try {
88347
- atomicWrite(join43(agentDir, SESSION_MODEL_FILE), raw);
88918
+ atomicWrite(join44(agentDir, SESSION_MODEL_FILE), raw);
88348
88919
  } catch {}
88349
88920
  }
88350
88921
  function readConfiguredDefaultModel(agentDir) {
88351
88922
  try {
88352
- const v = readFileSync33(join43(agentDir, CONFIGURED_DEFAULT_MODEL_FILE), "utf8").trim();
88923
+ const v = readFileSync33(join44(agentDir, CONFIGURED_DEFAULT_MODEL_FILE), "utf8").trim();
88353
88924
  return v.length > 0 ? v : null;
88354
88925
  } catch {
88355
88926
  return null;
@@ -88361,12 +88932,12 @@ function writeSessionEffortFile(agentDir, level, configuredDefaultAtWrite) {
88361
88932
  if (!EFFORT_LEVEL_RE.test(level)) {
88362
88933
  throw new Error(`refusing to persist non-allowlisted effort level: ${JSON.stringify(level)}`);
88363
88934
  }
88364
- atomicWrite(join43(agentDir, SESSION_EFFORT_FILE), `${JSON.stringify({ level, configuredDefaultAtWrite: configuredDefaultAtWrite ?? "", ts: Date.now() })}
88935
+ atomicWrite(join44(agentDir, SESSION_EFFORT_FILE), `${JSON.stringify({ level, configuredDefaultAtWrite: configuredDefaultAtWrite ?? "", ts: Date.now() })}
88365
88936
  `);
88366
88937
  }
88367
88938
  function clearSessionEffortFile(agentDir) {
88368
88939
  try {
88369
- rmSync7(join43(agentDir, SESSION_EFFORT_FILE), { force: true });
88940
+ rmSync7(join44(agentDir, SESSION_EFFORT_FILE), { force: true });
88370
88941
  } catch {}
88371
88942
  }
88372
88943
  var PREMIUM_RECOVERY_FILE = ".premium-recovery";
@@ -88389,13 +88960,13 @@ function writePremiumRecoveryFile(agentDir, premiumModel, chats) {
88389
88960
  if (clean.length === 0) {
88390
88961
  throw new Error("refusing to persist premium-recovery marker with no chats to notify");
88391
88962
  }
88392
- atomicWrite(join43(agentDir, PREMIUM_RECOVERY_FILE), `${JSON.stringify({ premiumModel, chats: clean, ts: Date.now() })}
88963
+ atomicWrite(join44(agentDir, PREMIUM_RECOVERY_FILE), `${JSON.stringify({ premiumModel, chats: clean, ts: Date.now() })}
88393
88964
  `);
88394
88965
  }
88395
88966
  function readPremiumRecoveryFile(agentDir) {
88396
88967
  let raw;
88397
88968
  try {
88398
- raw = readFileSync33(join43(agentDir, PREMIUM_RECOVERY_FILE), "utf8");
88969
+ raw = readFileSync33(join44(agentDir, PREMIUM_RECOVERY_FILE), "utf8");
88399
88970
  } catch {
88400
88971
  return null;
88401
88972
  }
@@ -88408,7 +88979,7 @@ function readPremiumRecoveryFile(agentDir) {
88408
88979
  }
88409
88980
  function clearPremiumRecoveryFile(agentDir) {
88410
88981
  try {
88411
- rmSync7(join43(agentDir, PREMIUM_RECOVERY_FILE), { force: true });
88982
+ rmSync7(join44(agentDir, PREMIUM_RECOVERY_FILE), { force: true });
88412
88983
  } catch {}
88413
88984
  }
88414
88985
 
@@ -88802,7 +89373,7 @@ init_merge();
88802
89373
  init_timezone();
88803
89374
 
88804
89375
  // ../src/cli/agent-config.ts
88805
- import { join as join45 } from "node:path";
89376
+ import { join as join46 } from "node:path";
88806
89377
  import { homedir as homedir11 } from "node:os";
88807
89378
 
88808
89379
  // ../src/cli/helpers.ts
@@ -88823,12 +89394,12 @@ var WEBKITE_VAULT_KEYS = new Set([
88823
89394
  init_overlay_loader();
88824
89395
 
88825
89396
  // ../src/cli/agent-config.ts
88826
- var AUDIT_ROOT = join45(homedir11(), ".switchroom", "audit");
89397
+ var AUDIT_ROOT = join46(homedir11(), ".switchroom", "audit");
88827
89398
 
88828
89399
  // ../src/agents/profiles.ts
88829
89400
  var import_handlebars = __toESM(require_lib(), 1);
88830
89401
  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";
88831
- import { resolve as resolve8, join as join46, sep as pathSep } from "node:path";
89402
+ import { resolve as resolve8, join as join47, sep as pathSep } from "node:path";
88832
89403
  function resolveProfilesRootDetailed() {
88833
89404
  return resolveShippedAsset(PROFILES_ASSET, {
88834
89405
  bundleDir: import.meta.dirname,
@@ -88847,7 +89418,7 @@ import_handlebars.default.registerHelper("isNumber", (value) => {
88847
89418
  var SHARED_FRAGMENTS_DIR = resolve8(PROFILES_ROOT, "_shared");
88848
89419
  var SHARED_FRAGMENTS = ["vault-protocol", "agent-self-service", "execution-discipline", "reply-discipline", "dev-protocol", "local-time"];
88849
89420
  for (const name of SHARED_FRAGMENTS) {
88850
- const fragPath = join46(SHARED_FRAGMENTS_DIR, `${name}.md.hbs`);
89421
+ const fragPath = join47(SHARED_FRAGMENTS_DIR, `${name}.md.hbs`);
88851
89422
  if (existsSync37(fragPath)) {
88852
89423
  import_handlebars.default.registerPartial(name, readFileSync36(fragPath, "utf-8"));
88853
89424
  }
@@ -90799,7 +91370,7 @@ function numField(obj, key) {
90799
91370
 
90800
91371
  // gateway/context-occupancy.ts
90801
91372
  import { mkdirSync as mkdirSync34, writeFileSync as writeFileSync33 } from "node:fs";
90802
- import { join as join47 } from "node:path";
91373
+ import { join as join48 } from "node:path";
90803
91374
  var CONTEXT_OCCUPANCY_FILENAME = "context-occupancy.json";
90804
91375
  var TIGHT_FRACTION = 0.8;
90805
91376
  function buildContextOccupancy(occupancy, cap, now) {
@@ -90822,7 +91393,7 @@ function buildContextOccupancy(occupancy, cap, now) {
90822
91393
  }
90823
91394
  function writeContextOccupancySnapshot(stateDir, snapshot, deps) {
90824
91395
  try {
90825
- const path2 = join47(stateDir, CONTEXT_OCCUPANCY_FILENAME);
91396
+ const path2 = join48(stateDir, CONTEXT_OCCUPANCY_FILENAME);
90826
91397
  (deps?.mkdir ?? ((p, o) => mkdirSync34(p, o)))(stateDir, { recursive: true });
90827
91398
  (deps?.writeFile ?? ((p, d) => writeFileSync33(p, d)))(path2, JSON.stringify(snapshot, null, 2) + `
90828
91399
  `);
@@ -90960,17 +91531,17 @@ function idleDurationToMs(raw) {
90960
91531
  init_state_owner();
90961
91532
  import { readFileSync as readFileSync39, mkdirSync as mkdirSync35 } from "node:fs";
90962
91533
  import { homedir as homedir13 } from "node:os";
90963
- import { join as join48 } from "node:path";
91534
+ import { join as join49 } from "node:path";
90964
91535
  function emptyPrivacyState() {
90965
91536
  return { version: 1, intervals: [] };
90966
91537
  }
90967
91538
  var PRIVATE_ON_REPLY = "\uD83D\uDD12 Private mode ON \u2014 memory writing paused. Nothing said until /public is stored.";
90968
91539
  var PUBLIC_REPLY = "\uD83D\uDD13 Public mode \u2014 memory writing resumed. The private stretch was excluded from memory.";
90969
91540
  function resolvePrivacyStateDir() {
90970
- return process.env.TELEGRAM_STATE_DIR ?? join48(homedir13(), ".claude", "channels", "telegram");
91541
+ return process.env.TELEGRAM_STATE_DIR ?? join49(homedir13(), ".claude", "channels", "telegram");
90971
91542
  }
90972
91543
  function privacyStatePath(stateDir = resolvePrivacyStateDir()) {
90973
- return join48(stateDir, "privacy-state.json");
91544
+ return join49(stateDir, "privacy-state.json");
90974
91545
  }
90975
91546
  function isInterval(v) {
90976
91547
  if (v === null || typeof v !== "object")
@@ -91026,22 +91597,22 @@ function closePrivateInterval(now = new Date, stateDir = resolvePrivacyStateDir(
91026
91597
 
91027
91598
  // gateway/privacy-reset.ts
91028
91599
  import { existsSync as existsSync40 } from "node:fs";
91029
- import { join as join50 } from "node:path";
91600
+ import { join as join51 } from "node:path";
91030
91601
 
91031
91602
  // gateway/privacy-state.ts
91032
91603
  init_state_owner();
91033
91604
  import { readFileSync as readFileSync40, mkdirSync as mkdirSync36 } from "node:fs";
91034
91605
  import { homedir as homedir14 } from "node:os";
91035
- import { join as join49 } from "node:path";
91606
+ import { join as join50 } from "node:path";
91036
91607
  function emptyPrivacyState2() {
91037
91608
  return { version: 1, intervals: [] };
91038
91609
  }
91039
91610
  var SESSION_RESET_ALERT = "\uD83D\uDD13 New session \u2014 memory writing is ON by default. Private mode from the previous session was reset.";
91040
91611
  function resolvePrivacyStateDir2() {
91041
- return process.env.TELEGRAM_STATE_DIR ?? join49(homedir14(), ".claude", "channels", "telegram");
91612
+ return process.env.TELEGRAM_STATE_DIR ?? join50(homedir14(), ".claude", "channels", "telegram");
91042
91613
  }
91043
91614
  function privacyStatePath2(stateDir = resolvePrivacyStateDir2()) {
91044
- return join49(stateDir, "privacy-state.json");
91615
+ return join50(stateDir, "privacy-state.json");
91045
91616
  }
91046
91617
  function isInterval2(v) {
91047
91618
  if (v === null || typeof v !== "object")
@@ -91105,7 +91676,7 @@ function bootRestoresTranscript(opts) {
91105
91676
  return opts.resumeMode === "continue" || opts.resumeMode === "auto";
91106
91677
  }
91107
91678
  function isContinueRestoreBoot(agentDir) {
91108
- const forceFresh = process.env.SWITCHROOM_FORCE_FRESH === "1" || agentDir != null && existsSync40(join50(agentDir, ".force-fresh-session"));
91679
+ const forceFresh = process.env.SWITCHROOM_FORCE_FRESH === "1" || agentDir != null && existsSync40(join51(agentDir, ".force-fresh-session"));
91109
91680
  return bootRestoresTranscript({
91110
91681
  resumeMode: process.env.SWITCHROOM_RESUME_MODE,
91111
91682
  forceFresh
@@ -92196,7 +92767,7 @@ function reseedSweepLedger(path2, fs2, log = (l) => process.stderr.write(l)) {
92196
92767
  // ../src/util/state-owner.ts
92197
92768
  init_atomic();
92198
92769
  import {
92199
- appendFileSync as appendFileSync8,
92770
+ appendFileSync as appendFileSync9,
92200
92771
  closeSync as closeSync11,
92201
92772
  constants as constants5,
92202
92773
  existsSync as existsSync42,
@@ -92208,7 +92779,7 @@ import {
92208
92779
  statSync as statSync15,
92209
92780
  writeFileSync as writeFileSync34
92210
92781
  } from "node:fs";
92211
- import { dirname as dirname21, join as join51, relative as relative2, sep as sep5 } from "node:path";
92782
+ import { dirname as dirname21, join as join52, relative as relative2, sep as sep5 } from "node:path";
92212
92783
  var NOFOLLOW2 = constants5.O_NOFOLLOW ?? 0;
92213
92784
  var ownerCache2 = new Map;
92214
92785
  var loggedFailure2 = false;
@@ -92282,7 +92853,7 @@ function mkdirStateSync2(path2, options = { recursive: true }, log = defaultLog3
92282
92853
  for (const part of tail.split(sep5)) {
92283
92854
  if (part === "")
92284
92855
  continue;
92285
- current = join51(current, part);
92856
+ current = join52(current, part);
92286
92857
  adoptStateOwnership2(current, owner, log);
92287
92858
  }
92288
92859
  }
@@ -92324,11 +92895,11 @@ function writeStateFileSync2(path2, data, options, log = defaultLog3) {
92324
92895
  function appendStateFileSync(path2, data, options, log = defaultLog3) {
92325
92896
  const owner = resolveStateOwner2(dirname21(path2));
92326
92897
  if (!owner) {
92327
- appendFileSync8(path2, data, options);
92898
+ appendFileSync9(path2, data, options);
92328
92899
  return;
92329
92900
  }
92330
92901
  const existed = existsSync42(path2);
92331
- appendFileSync8(path2, data, options);
92902
+ appendFileSync9(path2, data, options);
92332
92903
  if (!existed)
92333
92904
  adoptStateOwnership2(path2, owner, log);
92334
92905
  }
@@ -92384,7 +92955,7 @@ function reconcileStateDirOwnership(dir, opts = {}) {
92384
92955
  result.symlinksSkipped++;
92385
92956
  continue;
92386
92957
  }
92387
- const child = join51(current, entry.name);
92958
+ const child = join52(current, entry.name);
92388
92959
  result.scanned++;
92389
92960
  if (adoptAndReport(child, owner, log))
92390
92961
  result.adopted++;
@@ -92549,13 +93120,13 @@ function startWebhookIngestServer(opts) {
92549
93120
  }
92550
93121
 
92551
93122
  // ../src/web/webhook-gateway-record.ts
92552
- import { appendFileSync as appendFileSync10, mkdirSync as mkdirSync40 } from "fs";
92553
- import { join as join55 } from "path";
93123
+ import { appendFileSync as appendFileSync11, mkdirSync as mkdirSync40 } from "fs";
93124
+ import { join as join56 } from "path";
92554
93125
  import { homedir as homedir16 } from "os";
92555
93126
 
92556
93127
  // ../src/web/webhook-handler.ts
92557
- import { appendFileSync as appendFileSync9, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
92558
- import { join as join53 } from "path";
93128
+ import { appendFileSync as appendFileSync10, existsSync as existsSync45, mkdirSync as mkdirSync38, readFileSync as readFileSync41, writeFileSync as writeFileSync35 } from "fs";
93129
+ import { join as join54 } from "path";
92559
93130
 
92560
93131
  // ../src/util/log-rotation.ts
92561
93132
  import * as fs2 from "node:fs";
@@ -92917,8 +93488,8 @@ var agentDedupCache = new Map;
92917
93488
  function createFileDedupStore(resolveAgentDir) {
92918
93489
  return {
92919
93490
  check(agent, deliveryId, now) {
92920
- const telegramDir = join53(resolveAgentDir(agent), "telegram");
92921
- const filePath = join53(telegramDir, "webhook-dedup.json");
93491
+ const telegramDir = join54(resolveAgentDir(agent), "telegram");
93492
+ const filePath = join54(telegramDir, "webhook-dedup.json");
92922
93493
  if (!agentDedupCache.has(agent)) {
92923
93494
  agentDedupCache.set(agent, loadDedupFile(filePath));
92924
93495
  }
@@ -92940,7 +93511,7 @@ var throttleIssueWindow = new Map;
92940
93511
 
92941
93512
  // ../src/web/webhook-dispatch.ts
92942
93513
  import { existsSync as existsSync46, mkdirSync as mkdirSync39, readFileSync as readFileSync42, writeFileSync as writeFileSync36 } from "fs";
92943
- import { join as join54 } from "path";
93514
+ import { join as join55 } from "path";
92944
93515
  import { homedir as homedir15 } from "os";
92945
93516
 
92946
93517
  // ../src/agent-scheduler/ipc-client.ts
@@ -93260,8 +93831,8 @@ function createFileCooldownStore(resolveAgentDir) {
93260
93831
  isCoolingDown(agent, key, cooldownMs, now) {
93261
93832
  if (cooldownMs <= 0)
93262
93833
  return false;
93263
- const telegramDir = join54(resolveAgentDir(agent), "telegram");
93264
- const filePath = join54(telegramDir, "webhook-cooldown.json");
93834
+ const telegramDir = join55(resolveAgentDir(agent), "telegram");
93835
+ const filePath = join55(telegramDir, "webhook-cooldown.json");
93265
93836
  if (!cache.has(agent)) {
93266
93837
  cache.set(agent, loadCooldownFile(filePath));
93267
93838
  }
@@ -93318,9 +93889,9 @@ async function defaultInject(socketPath, agentName3, inbound) {
93318
93889
  }
93319
93890
  function injectWebhookInbound(agent, prompt, ctx, deps = {}) {
93320
93891
  const log = deps.log ?? ((s) => process.stderr.write(s));
93321
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join54(homedir15(), ".switchroom", "agents", a));
93892
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir15(), ".switchroom", "agents", a));
93322
93893
  const now = (deps.now ?? Date.now)();
93323
- const socketPath = join54(resolveAgentDir(agent), "telegram", "gateway.sock");
93894
+ const socketPath = join55(resolveAgentDir(agent), "telegram", "gateway.sock");
93324
93895
  const inbound = {
93325
93896
  type: "inbound",
93326
93897
  chatId: ctx.chatId,
@@ -93392,7 +93963,7 @@ function evaluateDispatch(args, deps = {}) {
93392
93963
  const log = deps.log ?? ((s) => process.stderr.write(s));
93393
93964
  const now = (deps.now ?? Date.now)();
93394
93965
  const nowDate = deps.nowDate ?? (() => new Date(now));
93395
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join54(homedir15(), ".switchroom", "agents", a));
93966
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir15(), ".switchroom", "agents", a));
93396
93967
  const cooldownStore = deps.cooldownStore ?? createFileCooldownStore(resolveAgentDir);
93397
93968
  if (!DISPATCH_SOURCES.includes(args.source))
93398
93969
  return 0;
@@ -93470,10 +94041,10 @@ var CONSOLIDATION_COMPLETED_EVENT = "consolidation.completed";
93470
94041
  function recordWebhookEvent(rec, deps = {}) {
93471
94042
  const log = deps.log ?? ((s) => process.stderr.write(s));
93472
94043
  const now = rec.ts || (deps.now ?? Date.now)();
93473
- const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join55(homedir16(), ".switchroom", "agents", a));
94044
+ const resolveAgentDir = deps.resolveAgentDir ?? ((a) => join56(homedir16(), ".switchroom", "agents", a));
93474
94045
  const dedupStore = deps.dedupStore ?? createFileDedupStore(resolveAgentDir);
93475
94046
  const agent = rec.agent;
93476
- const telegramDir = join55(resolveAgentDir(agent), "telegram");
94047
+ const telegramDir = join56(resolveAgentDir(agent), "telegram");
93477
94048
  if (rec.source === "github" && rec.delivery_id) {
93478
94049
  const originalTs = dedupStore.check(agent, rec.delivery_id, now);
93479
94050
  if (originalTs !== undefined) {
@@ -93482,7 +94053,7 @@ function recordWebhookEvent(rec, deps = {}) {
93482
94053
  return { status: "deduped", ts: originalTs };
93483
94054
  }
93484
94055
  }
93485
- const logPath = join55(telegramDir, "webhook-events.jsonl");
94056
+ const logPath = join56(telegramDir, "webhook-events.jsonl");
93486
94057
  try {
93487
94058
  mkdirSync40(telegramDir, { recursive: true });
93488
94059
  rotateWebhookLogIfNeeded(logPath);
@@ -93493,7 +94064,7 @@ function recordWebhookEvent(rec, deps = {}) {
93493
94064
  rendered_text: rec.rendered_text,
93494
94065
  payload: rec.payload
93495
94066
  };
93496
- appendFileSync10(logPath, JSON.stringify(record) + `
94067
+ appendFileSync11(logPath, JSON.stringify(record) + `
93497
94068
  `, { mode: 384 });
93498
94069
  } catch (err) {
93499
94070
  log(`webhook-gateway: agent='${agent}' source='${rec.source}' write failed: ${err.message}
@@ -98148,14 +98719,14 @@ function purgeStaleTurnsForChat(chatId, keys, purger, isStale = () => true) {
98148
98719
  // gateway/compaction-marker.ts
98149
98720
  import { statSync as statSync17, unlinkSync as unlinkSync22 } from "node:fs";
98150
98721
  import { homedir as homedir17 } from "node:os";
98151
- import { join as join56 } from "node:path";
98722
+ import { join as join57 } from "node:path";
98152
98723
  var COMPACTION_MARKER_FILE = "compaction-in-flight.json";
98153
98724
  function resolveTelegramStateDir() {
98154
- return process.env.TELEGRAM_STATE_DIR ?? join56(homedir17(), ".claude", "channels", "telegram");
98725
+ return process.env.TELEGRAM_STATE_DIR ?? join57(homedir17(), ".claude", "channels", "telegram");
98155
98726
  }
98156
98727
  function readCompactionMarkerAgeMs(stateDir, now) {
98157
98728
  try {
98158
- const st = statSync17(join56(stateDir, COMPACTION_MARKER_FILE));
98729
+ const st = statSync17(join57(stateDir, COMPACTION_MARKER_FILE));
98159
98730
  return (now ?? Date.now()) - st.mtimeMs;
98160
98731
  } catch {
98161
98732
  return null;
@@ -98163,7 +98734,7 @@ function readCompactionMarkerAgeMs(stateDir, now) {
98163
98734
  }
98164
98735
  function removeCompactionMarker(stateDir) {
98165
98736
  try {
98166
- unlinkSync22(join56(stateDir, COMPACTION_MARKER_FILE));
98737
+ unlinkSync22(join57(stateDir, COMPACTION_MARKER_FILE));
98167
98738
  } catch {}
98168
98739
  }
98169
98740
 
@@ -100228,7 +100799,7 @@ import {
100228
100799
  readdirSync as readdirSync12,
100229
100800
  readFileSync as readFileSync47
100230
100801
  } from "fs";
100231
- import { join as join57 } from "path";
100802
+ import { join as join58 } from "path";
100232
100803
 
100233
100804
  // session-tail.ts
100234
100805
  function sanitizeCwdToProjectName2(cwd) {
@@ -101551,8 +102122,8 @@ function startSubagentWatcher(config) {
101551
102122
  if (stopped)
101552
102123
  return;
101553
102124
  pruneVanishedDirWatchers();
101554
- const claudeHome = join57(agentDir, ".claude");
101555
- const projectsRoot = join57(claudeHome, "projects");
102125
+ const claudeHome = join58(agentDir, ".claude");
102126
+ const projectsRoot = join58(claudeHome, "projects");
101556
102127
  if (!fs3.existsSync(projectsRoot))
101557
102128
  return;
101558
102129
  let projectDirs;
@@ -101586,7 +102157,7 @@ function startSubagentWatcher(config) {
101586
102157
  continue;
101587
102158
  }
101588
102159
  warnedForeignSlugs.delete(pDir);
101589
- const projectPath = join57(projectsRoot, pDir);
102160
+ const projectPath = join58(projectsRoot, pDir);
101590
102161
  let sessionDirs;
101591
102162
  try {
101592
102163
  sessionDirs = fs3.readdirSync(projectPath);
@@ -101596,7 +102167,7 @@ function startSubagentWatcher(config) {
101596
102167
  for (const sDir of sessionDirs) {
101597
102168
  if (sDir.endsWith(".jsonl"))
101598
102169
  continue;
101599
- const subagentsPath = join57(projectPath, sDir, "subagents");
102170
+ const subagentsPath = join58(projectPath, sDir, "subagents");
101600
102171
  if (!fs3.existsSync(subagentsPath))
101601
102172
  continue;
101602
102173
  const watchAndScan = (dirPath) => {
@@ -101605,7 +102176,7 @@ function startSubagentWatcher(config) {
101605
102176
  const w = fs3.watch(dirPath, (_event, filename) => {
101606
102177
  if (!filename || !filename.toString().startsWith("agent-") || !filename.toString().endsWith(".jsonl"))
101607
102178
  return;
101608
- const filePath = join57(dirPath, filename.toString());
102179
+ const filePath = join58(dirPath, filename.toString());
101609
102180
  if (!knownFiles.has(filePath)) {
101610
102181
  scanSubagentsDir(dirPath);
101611
102182
  }
@@ -101619,7 +102190,7 @@ function startSubagentWatcher(config) {
101619
102190
  scanSubagentsDir(dirPath);
101620
102191
  };
101621
102192
  watchAndScan(subagentsPath);
101622
- const workflowsPath = join57(subagentsPath, "workflows");
102193
+ const workflowsPath = join58(subagentsPath, "workflows");
101623
102194
  if (fs3.existsSync(workflowsPath)) {
101624
102195
  let wfDirs;
101625
102196
  try {
@@ -101629,7 +102200,7 @@ function startSubagentWatcher(config) {
101629
102200
  }
101630
102201
  for (const wfDir of wfDirs) {
101631
102202
  try {
101632
- const wfPath = join57(workflowsPath, wfDir);
102203
+ const wfPath = join58(workflowsPath, wfDir);
101633
102204
  if (!fs3.statSync(wfPath).isDirectory())
101634
102205
  continue;
101635
102206
  watchAndScan(wfPath);
@@ -101649,7 +102220,7 @@ function startSubagentWatcher(config) {
101649
102220
  for (const e of entries) {
101650
102221
  if (!e.startsWith("agent-") || !e.endsWith(".jsonl"))
101651
102222
  continue;
101652
- const filePath = join57(subagentsPath, e);
102223
+ const filePath = join58(subagentsPath, e);
101653
102224
  if (knownFiles.has(filePath))
101654
102225
  continue;
101655
102226
  const agentId = e.slice("agent-".length, -".jsonl".length);
@@ -101785,13 +102356,13 @@ import {
101785
102356
  existsSync as existsSync48,
101786
102357
  renameSync as renameSync24
101787
102358
  } from "node:fs";
101788
- import { join as join58, resolve as resolve10 } from "node:path";
102359
+ import { join as join59, resolve as resolve10 } from "node:path";
101789
102360
  import { homedir as homedir18 } from "node:os";
101790
102361
  function registryDir2() {
101791
- return resolve10(process.env.SWITCHROOM_WORKTREE_DIR ?? join58(homedir18(), ".switchroom", "worktrees"));
102362
+ return resolve10(process.env.SWITCHROOM_WORKTREE_DIR ?? join59(homedir18(), ".switchroom", "worktrees"));
101792
102363
  }
101793
102364
  function recordPath(id) {
101794
- return join58(registryDir2(), `${id}.json`);
102365
+ return join59(registryDir2(), `${id}.json`);
101795
102366
  }
101796
102367
  function ensureDir4() {
101797
102368
  mkdirSync41(registryDir2(), { recursive: true });
@@ -101975,19 +102546,19 @@ function determineBridgeReconnectReason(opts) {
101975
102546
 
101976
102547
  // gateway/update-announce.ts
101977
102548
  import { existsSync as existsSync53, mkdirSync as mkdirSync45, openSync as openSync14, closeSync as closeSync14, readFileSync as readFileSync55 } from "node:fs";
101978
- import { join as join63 } from "node:path";
102549
+ import { join as join64 } from "node:path";
101979
102550
  import { homedir as homedir20 } from "node:os";
101980
102551
 
101981
102552
  // ../src/host-control/audit-reader.ts
101982
102553
  import { homedir as homedir19 } from "node:os";
101983
- import { join as join62 } from "node:path";
102554
+ import { join as join63 } from "node:path";
101984
102555
 
101985
102556
  // ../src/host-control/audit-rotation-config.ts
101986
102557
  var DEFAULT_HOSTD_AUDIT_MAX_BYTES = 32 * 1024 * 1024;
101987
102558
 
101988
102559
  // ../src/host-control/audit-reader.ts
101989
102560
  function defaultAuditLogPath(home2 = homedir19()) {
101990
- return join62(home2, ".switchroom", "host-control-audit.log");
102561
+ return join63(home2, ".switchroom", "host-control-audit.log");
101991
102562
  }
101992
102563
  var AUDIT_READ_WINDOW_BYTES = 4 * 1024 * 1024;
101993
102564
  function parseAuditLine(line) {
@@ -102186,15 +102757,15 @@ function renderUpdateOutcomeLine(entry) {
102186
102757
  `);
102187
102758
  }
102188
102759
  function claimUpdateAnnouncement(requestId, opts = {}) {
102189
- const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR ?? join63(homedir20(), ".switchroom");
102190
- const dir = join63(stateDir, "update-announced");
102760
+ const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR ?? join64(homedir20(), ".switchroom");
102761
+ const dir = join64(stateDir, "update-announced");
102191
102762
  try {
102192
102763
  mkdirSync45(dir, { recursive: true });
102193
102764
  } catch {
102194
102765
  return false;
102195
102766
  }
102196
102767
  const safeId = requestId.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 200);
102197
- const path3 = join63(dir, safeId);
102768
+ const path3 = join64(dir, safeId);
102198
102769
  try {
102199
102770
  const fd = openSync14(path3, "wx");
102200
102771
  closeSync14(fd);
@@ -102416,7 +102987,7 @@ function createIssuesCardHandle(opts) {
102416
102987
 
102417
102988
  // issues-watcher.ts
102418
102989
  import { existsSync as existsSync55, statSync as statSync21 } from "node:fs";
102419
- import { join as join65 } from "node:path";
102990
+ import { join as join66 } from "node:path";
102420
102991
 
102421
102992
  // ../src/issues/store.ts
102422
102993
  import {
@@ -102432,7 +103003,7 @@ import {
102432
103003
  writeFileSync as writeFileSync46,
102433
103004
  writeSync as writeSync8
102434
103005
  } from "node:fs";
102435
- import { join as join64 } from "node:path";
103006
+ import { join as join65 } from "node:path";
102436
103007
  import { randomBytes as randomBytes10 } from "node:crypto";
102437
103008
  import { execSync } from "node:child_process";
102438
103009
 
@@ -102451,7 +103022,7 @@ init_redact();
102451
103022
  var ISSUES_FILE = "issues.jsonl";
102452
103023
  var ISSUES_LOCK = "issues.lock";
102453
103024
  function readAll(stateDir) {
102454
- const path3 = join64(stateDir, ISSUES_FILE);
103025
+ const path3 = join65(stateDir, ISSUES_FILE);
102455
103026
  if (!existsSync54(path3))
102456
103027
  return [];
102457
103028
  let raw;
@@ -102488,7 +103059,7 @@ function list2(stateDir, opts = {}) {
102488
103059
  });
102489
103060
  }
102490
103061
  function resolve11(stateDir, fingerprint, nowFn = Date.now) {
102491
- if (!existsSync54(join64(stateDir, ISSUES_FILE)))
103062
+ if (!existsSync54(join65(stateDir, ISSUES_FILE)))
102492
103063
  return 0;
102493
103064
  return withLock(stateDir, () => {
102494
103065
  const all2 = readAll(stateDir);
@@ -102506,7 +103077,7 @@ function resolve11(stateDir, fingerprint, nowFn = Date.now) {
102506
103077
  });
102507
103078
  }
102508
103079
  function writeAll(stateDir, events) {
102509
- const path3 = join64(stateDir, ISSUES_FILE);
103080
+ const path3 = join65(stateDir, ISSUES_FILE);
102510
103081
  sweepOrphanTmpFiles(stateDir);
102511
103082
  const tmp = `${path3}.tmp-${process.pid}-${randomBytes10(4).toString("hex")}`;
102512
103083
  const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
@@ -102528,7 +103099,7 @@ function sweepOrphanTmpFiles(stateDir) {
102528
103099
  for (const entry of entries) {
102529
103100
  if (!entry.startsWith(TMP_PREFIX))
102530
103101
  continue;
102531
- const tmpPath2 = join64(stateDir, entry);
103102
+ const tmpPath2 = join65(stateDir, entry);
102532
103103
  try {
102533
103104
  const stat = statSync20(tmpPath2);
102534
103105
  if (stat.mtimeMs < cutoff) {
@@ -102540,7 +103111,7 @@ function sweepOrphanTmpFiles(stateDir) {
102540
103111
  var LOCK_RETRY_MS = 25;
102541
103112
  var LOCK_TIMEOUT_MS = 1e4;
102542
103113
  function withLock(stateDir, fn) {
102543
- const lockPath = join64(stateDir, ISSUES_LOCK);
103114
+ const lockPath = join65(stateDir, ISSUES_LOCK);
102544
103115
  const startedAt = Date.now();
102545
103116
  let fd = null;
102546
103117
  while (fd === null) {
@@ -102625,7 +103196,7 @@ function isIssueEvent(v) {
102625
103196
  // issues-watcher.ts
102626
103197
  var DEFAULT_POLL_INTERVAL_MS2 = 2000;
102627
103198
  function startIssuesWatcher(opts) {
102628
- const path3 = join65(opts.stateDir, ISSUES_FILE);
103199
+ const path3 = join66(opts.stateDir, ISSUES_FILE);
102629
103200
  const log = opts.log ?? (() => {});
102630
103201
  const intervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
102631
103202
  const setIntervalFn = opts.setInterval ?? setInterval;
@@ -103385,7 +103956,7 @@ function readBashCommand(inputPreview) {
103385
103956
 
103386
103957
  // gateway/scoped-grant-store.ts
103387
103958
  init_state_owner();
103388
- import { join as join66 } from "node:path";
103959
+ import { join as join67 } from "node:path";
103389
103960
 
103390
103961
  // scoped-approval.ts
103391
103962
  var SCOPED_APPROVAL_DEFAULT_TTL_MS2 = 30 * 60 * 1000;
@@ -103427,7 +103998,7 @@ function scopedGrantPersistEnabled(env = process.env) {
103427
103998
  return env.SWITCHROOM_SCOPED_GRANT_PERSIST !== "0";
103428
103999
  }
103429
104000
  function createScopedGrantStore(stateDir, env = process.env, log = (l) => process.stderr.write(l)) {
103430
- const filePath = join66(stateDir, "scoped-grants.json");
104001
+ const filePath = join67(stateDir, "scoped-grants.json");
103431
104002
  const enabled7 = scopedGrantPersistEnabled(env);
103432
104003
  let unreadable = false;
103433
104004
  function read() {
@@ -103806,7 +104377,7 @@ function isDiffPreApproved(agentName3, unifiedDiff, deps) {
103806
104377
  // credits-watch.ts
103807
104378
  init_card_format();
103808
104379
  import { readFileSync as readFileSync58, writeFileSync as writeFileSync47, existsSync as existsSync56, mkdirSync as mkdirSync47 } from "fs";
103809
- import { join as join67 } from "path";
104380
+ import { join as join68 } from "path";
103810
104381
  var STATE_FILE = "credits-watch.json";
103811
104382
  var DEFAULT_CREDIT_FATAL_REASONS = new Set;
103812
104383
  var KNOWN_CREDIT_REASONS = [
@@ -103828,7 +104399,7 @@ function emptyCreditState() {
103828
104399
  return { lastNotifiedReason: null, lastNotifiedAt: 0 };
103829
104400
  }
103830
104401
  function readClaudeJsonOverage(claudeConfigDir) {
103831
- const path3 = join67(claudeConfigDir, ".claude.json");
104402
+ const path3 = join68(claudeConfigDir, ".claude.json");
103832
104403
  if (!existsSync56(path3))
103833
104404
  return null;
103834
104405
  let raw;
@@ -103911,7 +104482,7 @@ function humanizeReason(reason) {
103911
104482
  }
103912
104483
  }
103913
104484
  function loadCreditState(stateDir) {
103914
- const path3 = join67(stateDir, STATE_FILE);
104485
+ const path3 = join68(stateDir, STATE_FILE);
103915
104486
  if (!existsSync56(path3))
103916
104487
  return emptyCreditState();
103917
104488
  try {
@@ -103928,7 +104499,7 @@ function loadCreditState(stateDir) {
103928
104499
  }
103929
104500
  function saveCreditState(stateDir, state7) {
103930
104501
  mkdirSync47(stateDir, { recursive: true });
103931
- const path3 = join67(stateDir, STATE_FILE);
104502
+ const path3 = join68(stateDir, STATE_FILE);
103932
104503
  writeFileSync47(path3, JSON.stringify(state7, null, 2) + `
103933
104504
  `, { mode: 384 });
103934
104505
  }
@@ -103937,7 +104508,7 @@ function saveCreditState(stateDir, state7) {
103937
104508
  init_auth_snapshot_format();
103938
104509
  init_card_format();
103939
104510
  import { readFileSync as readFileSync59, writeFileSync as writeFileSync48, existsSync as existsSync57, mkdirSync as mkdirSync48 } from "fs";
103940
- import { join as join68 } from "path";
104511
+ import { join as join69 } from "path";
103941
104512
  var STATE_FILE2 = "quota-watch.json";
103942
104513
  function emptyQuotaWatchState() {
103943
104514
  return {};
@@ -104175,7 +104746,7 @@ function buildRecoveryMessage(agentName3, snap) {
104175
104746
  `);
104176
104747
  }
104177
104748
  function loadQuotaWatchState(stateDir) {
104178
- const path3 = join68(stateDir, STATE_FILE2);
104749
+ const path3 = join69(stateDir, STATE_FILE2);
104179
104750
  if (!existsSync57(path3))
104180
104751
  return emptyQuotaWatchState();
104181
104752
  try {
@@ -104197,7 +104768,7 @@ function loadQuotaWatchState(stateDir) {
104197
104768
  }
104198
104769
  function saveQuotaWatchState(stateDir, state7) {
104199
104770
  mkdirSync48(stateDir, { recursive: true });
104200
- const path3 = join68(stateDir, STATE_FILE2);
104771
+ const path3 = join69(stateDir, STATE_FILE2);
104201
104772
  writeFileSync48(path3, JSON.stringify(state7, null, 2) + `
104202
104773
  `, { mode: 384 });
104203
104774
  }
@@ -104254,17 +104825,17 @@ import {
104254
104825
  unlinkSync as unlinkSync28,
104255
104826
  utimesSync as utimesSync2
104256
104827
  } from "node:fs";
104257
- import { join as join69 } from "node:path";
104828
+ import { join as join70 } from "node:path";
104258
104829
  var TURN_ACTIVE_MARKER_FILE2 = "turn-active.json";
104259
104830
  var TURN_ACTIVE_HARD_TTL_MS2 = 10 * 60000;
104260
104831
  var TURN_ACTIVE_IDLE_SWEEP_MS = 60000;
104261
104832
  function removeTurnActiveMarker2(stateDir) {
104262
104833
  try {
104263
- unlinkSync28(join69(stateDir, TURN_ACTIVE_MARKER_FILE2));
104834
+ unlinkSync28(join70(stateDir, TURN_ACTIVE_MARKER_FILE2));
104264
104835
  } catch {}
104265
104836
  }
104266
104837
  function sweepStaleTurnActiveMarker(stateDir, opts) {
104267
- const path3 = join69(stateDir, TURN_ACTIVE_MARKER_FILE2);
104838
+ const path3 = join70(stateDir, TURN_ACTIVE_MARKER_FILE2);
104268
104839
  if (!existsSync58(path3))
104269
104840
  return false;
104270
104841
  const now = opts.now ?? Date.now();
@@ -104295,7 +104866,7 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
104295
104866
  }
104296
104867
  }
104297
104868
  function readTurnActiveMarkerAgeMs2(stateDir, now) {
104298
- const path3 = join69(stateDir, TURN_ACTIVE_MARKER_FILE2);
104869
+ const path3 = join70(stateDir, TURN_ACTIVE_MARKER_FILE2);
104299
104870
  try {
104300
104871
  const st = statSync22(path3);
104301
104872
  return (now ?? Date.now()) - st.mtimeMs;
@@ -104310,11 +104881,11 @@ function effectiveTurnAgeMs(markerAgeMs, turnStartedAt, now) {
104310
104881
  // gateway/gateway-heartbeat.ts
104311
104882
  init_state_owner();
104312
104883
  import { utimesSync as utimesSync3 } from "node:fs";
104313
- import { join as join70 } from "node:path";
104884
+ import { join as join71 } from "node:path";
104314
104885
  var GATEWAY_HEARTBEAT_FILE = "gateway-heartbeat";
104315
104886
  var GATEWAY_HEARTBEAT_INTERVAL_MS = 15000;
104316
104887
  function touchGatewayHeartbeat(stateDir) {
104317
- const path3 = join70(stateDir, GATEWAY_HEARTBEAT_FILE);
104888
+ const path3 = join71(stateDir, GATEWAY_HEARTBEAT_FILE);
104318
104889
  const now = new Date;
104319
104890
  try {
104320
104891
  utimesSync3(path3, now, now);
@@ -104345,7 +104916,7 @@ import {
104345
104916
  unlinkSync as unlinkSync29,
104346
104917
  writeFileSync as writeFileSync49
104347
104918
  } from "node:fs";
104348
- import { join as join71 } from "node:path";
104919
+ import { join as join72 } from "node:path";
104349
104920
  var BOOT_BEACON_FILE = "gateway-beacon.json";
104350
104921
  var HOST_BOOT_ID_PATH = "/proc/sys/kernel/random/boot_id";
104351
104922
  var CGROUP_MEMORY_EVENTS_PATH = "/sys/fs/cgroup/memory.events";
@@ -104444,7 +105015,7 @@ function sampleBeaconHost(paths = {}) {
104444
105015
  return sample3;
104445
105016
  }
104446
105017
  function writeBootBeaconFile(stateDir, beacon) {
104447
- const path3 = join71(stateDir, BOOT_BEACON_FILE);
105018
+ const path3 = join72(stateDir, BOOT_BEACON_FILE);
104448
105019
  const tmp = `${path3}.tmp-${process.pid}`;
104449
105020
  let fd;
104450
105021
  try {
@@ -104836,10 +105407,10 @@ function startOutboxSweep(deps) {
104836
105407
  }
104837
105408
 
104838
105409
  // ../src/build-info.ts
104839
- var VERSION2 = "0.21.8";
104840
- var COMMIT_SHA = "d778afb6";
104841
- var COMMIT_DATE = "2026-08-13T03:44:10Z";
104842
- var LATEST_PR = 4677;
105410
+ var VERSION2 = "0.21.10";
105411
+ var COMMIT_SHA = "fd1650e7";
105412
+ var COMMIT_DATE = "2026-08-14T03:50:00Z";
105413
+ var LATEST_PR = 4698;
104843
105414
  var COMMITS_AHEAD_OF_TAG = 0;
104844
105415
 
104845
105416
  // gateway/boot-version.ts
@@ -104917,11 +105488,11 @@ init_peercred();
104917
105488
  import * as net5 from "node:net";
104918
105489
  import * as fs3 from "node:fs";
104919
105490
  import { homedir as homedir21 } from "node:os";
104920
- import { join as join72 } from "node:path";
105491
+ import { join as join73 } from "node:path";
104921
105492
  var DEFAULT_TIMEOUT_MS4 = 2000;
104922
105493
  var UNLOCK_TIMEOUT_MS = 30000;
104923
- var LEGACY_SOCKET_PATH2 = join72(homedir21(), ".switchroom", "vault-broker.sock");
104924
- var OPERATOR_SOCKET_PATH2 = join72(homedir21(), ".switchroom", "broker-operator", "sock");
105494
+ var LEGACY_SOCKET_PATH2 = join73(homedir21(), ".switchroom", "vault-broker.sock");
105495
+ var OPERATOR_SOCKET_PATH2 = join73(homedir21(), ".switchroom", "broker-operator", "sock");
104925
105496
  function defaultBrokerSocketPath2() {
104926
105497
  if (fs3.existsSync(OPERATOR_SOCKET_PATH2))
104927
105498
  return OPERATOR_SOCKET_PATH2;
@@ -105805,7 +106376,7 @@ function resolveVaultApprovalPosture(broker) {
105805
106376
  // registry/turns-schema.ts
105806
106377
  init_state_owner();
105807
106378
  import { chmodSync as chmodSync12 } from "fs";
105808
- import { join as join73 } from "path";
106379
+ import { join as join74 } from "path";
105809
106380
  var DatabaseClass3 = null;
105810
106381
  function loadDatabaseClass3() {
105811
106382
  if (DatabaseClass3 != null)
@@ -105877,9 +106448,9 @@ function applySchema(db3) {
105877
106448
  }
105878
106449
  function openTurnsDb(agentDir) {
105879
106450
  const Database = loadDatabaseClass3();
105880
- const dir = join73(agentDir, "telegram");
106451
+ const dir = join74(agentDir, "telegram");
105881
106452
  mkdirStateSync(dir, { recursive: true, mode: 448 });
105882
- const path3 = join73(dir, "registry.db");
106453
+ const path3 = join74(dir, "registry.db");
105883
106454
  const db3 = new Database(path3, { create: true });
105884
106455
  applySchema(db3);
105885
106456
  try {
@@ -106222,7 +106793,7 @@ function selectResumeBuilder(endedVia, opts) {
106222
106793
 
106223
106794
  // gateway/boot-briefing-wiring.ts
106224
106795
  import { existsSync as existsSync60, readFileSync as readFileSync63, writeFileSync as writeFileSync50 } from "node:fs";
106225
- import { join as join74 } from "node:path";
106796
+ import { join as join75 } from "node:path";
106226
106797
  init_history();
106227
106798
 
106228
106799
  // gateway/resume-inbound-builder.ts
@@ -106529,8 +107100,8 @@ function readDailyMemory(agentDir, env, nowMs3, readFile = (p) => readFileSync63
106529
107100
  const date = agentLocalDate(nowMs3, env.SWITCHROOM_TIMEZONE || env.TZ || undefined);
106530
107101
  if (!date)
106531
107102
  return null;
106532
- const workspaceDir = env.WORKSPACE_DIR && env.WORKSPACE_DIR.trim() ? env.WORKSPACE_DIR : join74(agentDir, "workspace");
106533
- const file = join74(workspaceDir, "memory", `${date}.md`);
107103
+ const workspaceDir = env.WORKSPACE_DIR && env.WORKSPACE_DIR.trim() ? env.WORKSPACE_DIR : join75(agentDir, "workspace");
107104
+ const file = join75(workspaceDir, "memory", `${date}.md`);
106534
107105
  try {
106535
107106
  const content3 = readFile(file);
106536
107107
  if (!content3 || !content3.trim())
@@ -106559,7 +107130,7 @@ async function maybeQueueBootBriefing(opts) {
106559
107130
  try {
106560
107131
  const agentDir = opts.stateDir.endsWith("/telegram") ? opts.stateDir.slice(0, -"/telegram".length) : opts.stateDir;
106561
107132
  const bootId = opts.env.SWITCHROOM_GATEWAY_BOOT_ID;
106562
- const genMarkerPath = join74(agentDir, ".boot-briefing-generation");
107133
+ const genMarkerPath = join75(agentDir, ".boot-briefing-generation");
106563
107134
  if (bootId) {
106564
107135
  let prevGen = null;
106565
107136
  try {
@@ -106581,7 +107152,7 @@ async function maybeQueueBootBriefing(opts) {
106581
107152
  `);
106582
107153
  } catch {}
106583
107154
  };
106584
- const forceFresh = opts.env.SWITCHROOM_FORCE_FRESH === "1" || existsSync60(join74(agentDir, ".force-fresh-session"));
107155
+ const forceFresh = opts.env.SWITCHROOM_FORCE_FRESH === "1" || existsSync60(join75(agentDir, ".force-fresh-session"));
106585
107156
  const decision = decideBootBriefing({
106586
107157
  briefingMode: opts.env.SWITCHROOM_SESSION_BRIEFING,
106587
107158
  resumeMode: opts.env.SWITCHROOM_RESUME_MODE,
@@ -106615,7 +107186,7 @@ async function maybeQueueBootBriefing(opts) {
106615
107186
  return null;
106616
107187
  }
106617
107188
  const restartReason = readRestartBreadcrumb({
106618
- restartReasonPath: join74(agentDir, ".restart-reason"),
107189
+ restartReasonPath: join75(agentDir, ".restart-reason"),
106619
107190
  env: opts.env,
106620
107191
  readFile: (p) => readFileSync63(p, "utf8")
106621
107192
  });
@@ -106652,9 +107223,9 @@ async function maybeQueueBootBriefing(opts) {
106652
107223
 
106653
107224
  // gateway/pending-turn-env.ts
106654
107225
  import { existsSync as existsSync61, renameSync as renameSync29, rmSync as rmSync8, writeFileSync as writeFileSync51 } from "node:fs";
106655
- import { join as join75 } from "node:path";
107226
+ import { join as join76 } from "node:path";
106656
107227
  function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.write(l)) {
106657
- const pendingEnvPath = join75(agentDir, ".pending-turn.env");
107228
+ const pendingEnvPath = join76(agentDir, ".pending-turn.env");
106658
107229
  try {
106659
107230
  if (pending != null) {
106660
107231
  const lines = [
@@ -106687,7 +107258,7 @@ function writePendingTurnEnv(agentDir, pending, log = (l) => process.stderr.writ
106687
107258
 
106688
107259
  // gateway/agent-process-liveness.ts
106689
107260
  import { existsSync as existsSync62, readFileSync as readFileSync64, writeFileSync as writeFileSync52, renameSync as renameSync30, unlinkSync as unlinkSync30, readdirSync as readdirSync16 } from "node:fs";
106690
- import { join as join76, dirname as dirname28, basename as basename18 } from "node:path";
107261
+ import { join as join77, dirname as dirname28, basename as basename18 } from "node:path";
106691
107262
  var AGENT_PROCESS_RECORD_FILE = "agent-process.json";
106692
107263
  var BOOT_RESUME_DONE_FILE = ".boot-resume-done";
106693
107264
  function parseProcStat(raw) {
@@ -106710,7 +107281,7 @@ function readProcIdentity(pid, procRoot = "/proc") {
106710
107281
  return null;
106711
107282
  let identity;
106712
107283
  try {
106713
- identity = parseProcStat(readFileSync64(join76(procRoot, String(pid), "stat"), "utf8"));
107284
+ identity = parseProcStat(readFileSync64(join77(procRoot, String(pid), "stat"), "utf8"));
106714
107285
  } catch {
106715
107286
  return null;
106716
107287
  }
@@ -106742,7 +107313,7 @@ function readAgentProcessRecord(path3) {
106742
107313
  return rec;
106743
107314
  }
106744
107315
  function bootResumeDonePath(stateDir) {
106745
- return join76(stateDir, BOOT_RESUME_DONE_FILE);
107316
+ return join77(stateDir, BOOT_RESUME_DONE_FILE);
106746
107317
  }
106747
107318
  function containerBootIdentity(procRoot = "/proc") {
106748
107319
  return readProcIdentity(1, procRoot)?.starttime ?? null;
@@ -106775,7 +107346,7 @@ function sweepStrayTmps(path3) {
106775
107346
  if (!name.startsWith(prefix))
106776
107347
  continue;
106777
107348
  try {
106778
- unlinkSync30(join76(dirname28(path3), name));
107349
+ unlinkSync30(join77(dirname28(path3), name));
106779
107350
  } catch {}
106780
107351
  }
106781
107352
  } catch {}
@@ -106827,7 +107398,7 @@ function detectGatewayOnlyRespawn(opts) {
106827
107398
  return { gatewayOnly: false, reason: "guard-disabled", pid: null };
106828
107399
  const procRoot = opts.procRoot ?? "/proc";
106829
107400
  const sentinel = readBootResumeSentinel(opts.sentinelPath ?? bootResumeDonePath(opts.stateDir), { procRoot });
106830
- const recordPath2 = opts.recordPath ?? join76(opts.stateDir, AGENT_PROCESS_RECORD_FILE);
107401
+ const recordPath2 = opts.recordPath ?? join77(opts.stateDir, AGENT_PROCESS_RECORD_FILE);
106831
107402
  const record2 = readAgentProcessRecord(recordPath2);
106832
107403
  const live = record2 == null ? null : readProcIdentity(record2.pid, procRoot);
106833
107404
  return decideGatewayOnlyRespawn({
@@ -107385,7 +107956,7 @@ if (isGatewayMain) {
107385
107956
  shutdownAnalytics();
107386
107957
  });
107387
107958
  }
107388
- var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join77(homedir22(), ".claude", "channels", "telegram");
107959
+ var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join78(homedir22(), ".claude", "channels", "telegram");
107389
107960
  var permCardStore = createPermissionCardStore(STATE_DIR);
107390
107961
  var BLOCKED_APPROVALS_DIR = process.env.SWITCHROOM_BLOCKED_APPROVALS_DIR ?? "/state/blocked-approvals";
107391
107962
  var AGENT_NAME = process.env.SWITCHROOM_AGENT_NAME ?? "agent";
@@ -107485,11 +108056,11 @@ function scheduleAlwaysAllowPersistDrain() {
107485
108056
  }, ALWAYS_ALLOW_DRAIN_INTERVAL_MS);
107486
108057
  timer3.unref?.();
107487
108058
  }
107488
- var ACCESS_FILE = join77(STATE_DIR, "access.json");
107489
- var APPROVED_DIR = join77(STATE_DIR, "approved");
107490
- var ENV_FILE = join77(STATE_DIR, ".env");
107491
- var INBOX_DIR = join77(STATE_DIR, "inbox");
107492
- var PEOPLE_FILE = join77(STATE_DIR, "people.json");
108059
+ var ACCESS_FILE = join78(STATE_DIR, "access.json");
108060
+ var APPROVED_DIR = join78(STATE_DIR, "approved");
108061
+ var ENV_FILE = join78(STATE_DIR, ".env");
108062
+ var INBOX_DIR = join78(STATE_DIR, "inbox");
108063
+ var PEOPLE_FILE = join78(STATE_DIR, "people.json");
107493
108064
  function triggerSelfRestart(targetAgent, reason, delayMs = 300) {
107494
108065
  const isDocker = process.env.SWITCHROOM_RUNTIME === "docker";
107495
108066
  const selfAgent = process.env.SWITCHROOM_AGENT_NAME;
@@ -107616,7 +108187,7 @@ function assertSendable(f) {
107616
108187
  } catch {
107617
108188
  throw new Error(`refusing to send file \u2014 cannot resolve real path: ${f}`);
107618
108189
  }
107619
- const inbox = join77(stateReal, "inbox");
108190
+ const inbox = join78(stateReal, "inbox");
107620
108191
  if (real.startsWith(stateReal + sep6) && !real.startsWith(inbox + sep6)) {
107621
108192
  throw new Error(`refusing to send channel state: ${f}`);
107622
108193
  }
@@ -107645,7 +108216,7 @@ var HISTORY_ENABLED = HISTORY_ACCESS.historyEnabled !== false;
107645
108216
  if (isGatewayMain && HISTORY_ENABLED) {
107646
108217
  try {
107647
108218
  initHistory(STATE_DIR, HISTORY_ACCESS.historyRetentionDays ?? 30);
107648
- process.stderr.write(`telegram gateway: history capture enabled at ${join77(STATE_DIR, "history.db")}
108219
+ process.stderr.write(`telegram gateway: history capture enabled at ${join78(STATE_DIR, "history.db")}
107649
108220
  `);
107650
108221
  } catch (err) {
107651
108222
  process.stderr.write(`telegram gateway: history init failed (${err.message}) \u2014 capture disabled
@@ -107668,7 +108239,7 @@ bootResumeInit:
107668
108239
  let markerTurnKey = null;
107669
108240
  let markerAgeMs = null;
107670
108241
  try {
107671
- const markerPath = join77(STATE_DIR, TURN_ACTIVE_MARKER_FILE2);
108242
+ const markerPath = join78(STATE_DIR, TURN_ACTIVE_MARKER_FILE2);
107672
108243
  if (existsSync65(markerPath)) {
107673
108244
  const st = statSync25(markerPath);
107674
108245
  markerAgeMs = Date.now() - st.mtimeMs;
@@ -107693,10 +108264,10 @@ bootResumeInit:
107693
108264
  process.stderr.write(`telegram gateway: turn-registry boot-reaper stamped ${reaped} orphaned turn(s)` + `${timeoutTurnKey ? ` (turnKey=${timeoutTurnKey} as 'timeout', markerAgeMs=${markerAgeMs})` : " as 'restart'"}
107694
108265
  `);
107695
108266
  } else {
107696
- process.stderr.write(`telegram gateway: turn-registry initialized at ${join77(agentDir, "telegram", "registry.db")}
108267
+ process.stderr.write(`telegram gateway: turn-registry initialized at ${join78(agentDir, "telegram", "registry.db")}
107697
108268
  `);
107698
108269
  }
107699
- const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join77(STATE_DIR, "bridge-dead-escalation.json"));
108270
+ const bridgeDeadMarker = consumeBridgeDeadEscalationMarker(join78(STATE_DIR, "bridge-dead-escalation.json"));
107700
108271
  if (bridgeDeadMarker != null) {
107701
108272
  bridgeDeadPriorStreak = bridgeDeadMarker.count ?? 1;
107702
108273
  process.stderr.write(`telegram gateway: boot: prior restart was a bridge-dead escalation (reason=${bridgeDeadMarker.reason}` + `, consecutive=${bridgeDeadPriorStreak}` + `${bridgeDeadMarker.crashTail ? `, crashTail=${bridgeDeadMarker.crashTail}` : ""})
@@ -107709,7 +108280,7 @@ bootResumeInit:
107709
108280
  const pending2 = findLatestTurnIfInterrupted(turnsDb);
107710
108281
  const selfAgent = process.env.SWITCHROOM_AGENT_NAME ?? "";
107711
108282
  if (pending2 != null && selfAgent) {
107712
- const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
108283
+ const bootResumeMarkerPath = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join78(STATE_DIR, "clean-shutdown.json");
107713
108284
  const bootResumeCleanMarker = readCleanShutdownMarker(bootResumeMarkerPath);
107714
108285
  const bootResumeForceAlways = process.env.SWITCHROOM_BOOT_RESUME_ALWAYS === "1";
107715
108286
  const bootResumeMode = parseBootResumeMode(process.env.SWITCHROOM_BOOT_RESUME);
@@ -107916,7 +108487,7 @@ function checkApprovals() {
107916
108487
  return;
107917
108488
  }
107918
108489
  for (const senderId of files) {
107919
- const file = join77(APPROVED_DIR, senderId);
108490
+ const file = join78(APPROVED_DIR, senderId);
107920
108491
  bot.api.sendMessage(senderId, "Paired! Say hi to Claude.").then(() => rmSync9(file, { force: true }), (err) => {
107921
108492
  process.stderr.write(`telegram gateway: failed to send approval confirm: ${err}
107922
108493
  `);
@@ -108094,7 +108665,7 @@ function noteAgentOutputAt(key, ts) {
108094
108665
  lastAgentOutputAt.delete(oldest);
108095
108666
  }
108096
108667
  }
108097
- var OBLIGATION_STORE_PATH = join77(STATE_DIR, "obligations.json");
108668
+ var OBLIGATION_STORE_PATH = join78(STATE_DIR, "obligations.json");
108098
108669
  var obligationStoreFs = {
108099
108670
  readFileSync: (p) => readFileSync67(p, "utf8"),
108100
108671
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -108863,7 +109434,7 @@ function emitTurnRecord(turn, endedAt) {
108863
109434
  },
108864
109435
  rename: (from, to) => renameSync32(from, to)
108865
109436
  });
108866
- appendFileSync11(turnsPath, rec);
109437
+ appendFileSync12(turnsPath, rec);
108867
109438
  } catch {}
108868
109439
  }
108869
109440
  function maybeProactiveCompact() {
@@ -110432,7 +111003,7 @@ var PIN_STATUS_WHILE_WORKING = (() => {
110432
111003
  })();
110433
111004
  var statusPinClaims = new Map;
110434
111005
  var statusPinRightsCache = new PinRightsCache2;
110435
- var STATUS_PIN_STORE_PATH = join77(STATE_DIR, "status-pins.json");
111006
+ var STATUS_PIN_STORE_PATH = join78(STATE_DIR, "status-pins.json");
110436
111007
  var statusPinStoreFs = {
110437
111008
  readFileSync: (p) => readFileSync67(p, "utf8"),
110438
111009
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110440,7 +111011,7 @@ var statusPinStoreFs = {
110440
111011
  existsSync: (p) => existsSync65(p)
110441
111012
  };
110442
111013
  var statusPinPersistEnabled = !STATIC && PIN_STATUS_WHILE_WORKING;
110443
- var ACTIVITY_CARD_STORE_PATH = join77(STATE_DIR, "activity-cards-pending.json");
111014
+ var ACTIVITY_CARD_STORE_PATH = join78(STATE_DIR, "activity-cards-pending.json");
110444
111015
  var activityCardStoreFs = {
110445
111016
  readFileSync: (p) => readFileSync67(p, "utf8"),
110446
111017
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110448,7 +111019,7 @@ var activityCardStoreFs = {
110448
111019
  existsSync: (p) => existsSync65(p)
110449
111020
  };
110450
111021
  var activityCardPersistEnabled = !STATIC;
110451
- var QUEUED_CARD_STORE_PATH = join77(STATE_DIR, "queued-cards-pending.json");
111022
+ var QUEUED_CARD_STORE_PATH = join78(STATE_DIR, "queued-cards-pending.json");
110452
111023
  var queuedCardStoreFs = {
110453
111024
  readFileSync: (p) => readFileSync67(p, "utf8"),
110454
111025
  writeFileSync: (p, d) => writeStateFileSync2(p, d),
@@ -110736,7 +111307,7 @@ async function unpinAllStatusPins() {
110736
111307
  }
110737
111308
  }
110738
111309
  var stalePinSweepEligible = false;
110739
- var STALE_PIN_SWEEP_STORE_PATH = join77(STATE_DIR, "stale-pin-sweep.json");
111310
+ var STALE_PIN_SWEEP_STORE_PATH = join78(STATE_DIR, "stale-pin-sweep.json");
110740
111311
  var sweepStoreFs = {
110741
111312
  readFileSync: (p) => readFileSync67(p, "utf-8"),
110742
111313
  writeFileSync: (p, data) => atomicWriteStateFileSync2(p, data, 384),
@@ -110777,12 +111348,12 @@ var getPinnedProgressCardMessageId = null;
110777
111348
  var completeProgressCardTurn = null;
110778
111349
  var subagentWatcher = null;
110779
111350
  var workerActivityFeed = null;
110780
- var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join77(STATE_DIR, "gateway.sock");
111351
+ var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join78(STATE_DIR, "gateway.sock");
110781
111352
  if (isGatewayMain)
110782
111353
  mkdirStateSync2(STATE_DIR, { recursive: true, mode: 448 });
110783
- var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join77(STATE_DIR, "gateway.pid.json");
110784
- var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join77(STATE_DIR, "gateway-session.json");
110785
- var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join77(STATE_DIR, "clean-shutdown.json");
111354
+ var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join78(STATE_DIR, "gateway.pid.json");
111355
+ var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join78(STATE_DIR, "gateway-session.json");
111356
+ var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join78(STATE_DIR, "clean-shutdown.json");
110786
111357
  var GATEWAY_STARTED_AT_MS = Date.now();
110787
111358
  var BOOT_CARD_ENABLED = process.env.SWITCHROOM_BOOT_CARD !== "false";
110788
111359
  var activeBootCard = null;
@@ -110812,7 +111383,7 @@ function ensureIssuesCard(chatId, threadId) {
110812
111383
  bot: botApi,
110813
111384
  log: (msg) => process.stderr.write(`telegram gateway: ${msg}
110814
111385
  `),
110815
- persistPath: join77(stateDir, "issues-card.json")
111386
+ persistPath: join78(stateDir, "issues-card.json")
110816
111387
  });
110817
111388
  activeIssuesWatcher = startIssuesWatcher({
110818
111389
  stateDir,
@@ -111017,7 +111588,7 @@ if (isGatewayMain)
111017
111588
  var inboundSpool;
111018
111589
  if (isGatewayMain)
111019
111590
  inboundSpool = STATIC ? undefined : createInboundSpool({
111020
- path: join77(STATE_DIR, "inbound-spool.jsonl"),
111591
+ path: join78(STATE_DIR, "inbound-spool.jsonl"),
111021
111592
  fs: {
111022
111593
  appendFileSync: (p, d) => appendStateFileSync(p, d),
111023
111594
  readFileSync: (p) => readFileSync67(p, "utf8"),
@@ -111088,7 +111659,7 @@ async function maybeRedeliverUndeliveredAnswer() {
111088
111659
  let transcriptText;
111089
111660
  try {
111090
111661
  const projectsDir = getProjectsDirForCwd();
111091
- const path3 = join77(projectsDir, `${sessionId}.jsonl`);
111662
+ const path3 = join78(projectsDir, `${sessionId}.jsonl`);
111092
111663
  if (!existsSync65(path3)) {
111093
111664
  process.stderr.write(`telegram gateway: crash-redelivery \u2014 transcript not found for turnKey=${turn.turn_key} session=${sessionId} (${path3}); skipping
111094
111665
  `);
@@ -111263,8 +111834,8 @@ var bridgeDeadWatchdog = createBridgeDeadWatchdog({
111263
111834
  isSessionAlive: () => findAgentProcessInContainer2()?.comm === "claude",
111264
111835
  isShuttingDown: () => shuttingDown,
111265
111836
  escalate: (reason) => triggerSelfRestart(process.env.SWITCHROOM_AGENT_NAME ?? "", reason, 1500),
111266
- crashLogPath: join77(STATE_DIR, "bridge-crash.log"),
111267
- markerPath: join77(STATE_DIR, "bridge-dead-escalation.json"),
111837
+ crashLogPath: join78(STATE_DIR, "bridge-crash.log"),
111838
+ markerPath: join78(STATE_DIR, "bridge-dead-escalation.json"),
111268
111839
  log: (line) => process.stderr.write(`${line}
111269
111840
  `),
111270
111841
  priorStreak: bridgeDeadPriorStreak,
@@ -111371,8 +111942,8 @@ if (isGatewayMain)
111371
111942
  probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
111372
111943
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
111373
111944
  dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
111374
- configSnapshotPath: join77(resolvedAgentDirForCard, ".config-snapshot.json"),
111375
- bootCardStatePath: join77(resolvedAgentDirForCard, ".boot-card-msgid.json"),
111945
+ configSnapshotPath: join78(resolvedAgentDirForCard, ".config-snapshot.json"),
111946
+ bootCardStatePath: join78(resolvedAgentDirForCard, ".boot-card-msgid.json"),
111376
111947
  floodStatePath: FLOOD_STATE_PATH,
111377
111948
  ...updateOutcomeLine ? { updateOutcomeLine } : {}
111378
111949
  }, ackMsgId).then((handle) => {
@@ -112006,7 +112577,7 @@ if (isGatewayMain)
112006
112577
  const receiverUid = receiverUidRaw ? Number(receiverUidRaw) : NaN;
112007
112578
  if (Number.isInteger(receiverUid))
112008
112579
  allowedUids.push(receiverUid);
112009
- const socketPath = join77(STATE_DIR, "webhook.sock");
112580
+ const socketPath = join78(STATE_DIR, "webhook.sock");
112010
112581
  const webhookInject = (agentName3, inbound) => {
112011
112582
  const msg = inbound;
112012
112583
  const delivered = ipcServer.sendToAgent(agentName3, msg);
@@ -112258,9 +112829,9 @@ function redactOutboundText(text5, site) {
112258
112829
  var VOICE_OUT_DEFAULT_CHUNK_CHARS = 600;
112259
112830
  var VOICE_OUT_HARD_CHUNK_CAP = 4096;
112260
112831
  var voiceOnDemandCache = new VoiceOnDemandCache({
112261
- persistPath: join77(STATE_DIR, "voice-ondemand.json")
112832
+ persistPath: join78(STATE_DIR, "voice-ondemand.json")
112262
112833
  });
112263
- var VOICE_CACHE_DIR = join77(STATE_DIR, "voice-cache");
112834
+ var VOICE_CACHE_DIR = join78(STATE_DIR, "voice-cache");
112264
112835
  var voicePreSynthQueue = new PreSynthQueue({
112265
112836
  runJob: async (job) => {
112266
112837
  const sidecarToken = await materializeSidecarToken2();
@@ -112668,7 +113239,7 @@ async function executeSendGif(rawArgs) {
112668
113239
  };
112669
113240
  }
112670
113241
  async function publishToTelegraph(text5, shortName, authorName) {
112671
- const accountPath = join77(STATE_DIR, "telegraph-account.json");
113242
+ const accountPath = join78(STATE_DIR, "telegraph-account.json");
112672
113243
  let account = null;
112673
113244
  try {
112674
113245
  if (existsSync65(accountPath)) {
@@ -114218,7 +114789,7 @@ function restartMarkerPath() {
114218
114789
  const agentDir = resolveAgentDirFromEnv();
114219
114790
  if (!agentDir)
114220
114791
  return null;
114221
- return join77(agentDir, "restart-pending.json");
114792
+ return join78(agentDir, "restart-pending.json");
114222
114793
  }
114223
114794
  function writeRestartMarker(marker) {
114224
114795
  const p = restartMarkerPath();
@@ -114410,7 +114981,7 @@ function _resetDockerReachableCache() {
114410
114981
  }
114411
114982
  function spawnSwitchroomDetached(args, onFailure) {
114412
114983
  const fullArgs = SWITCHROOM_CONFIG ? ["--config", SWITCHROOM_CONFIG, ...args] : args;
114413
- const logPath = join77(STATE_DIR, "detached-spawn.log");
114984
+ const logPath = join78(STATE_DIR, "detached-spawn.log");
114414
114985
  let outFd = null;
114415
114986
  try {
114416
114987
  mkdirStateSync2(STATE_DIR, { recursive: true });
@@ -114703,7 +115274,7 @@ ${preBlock(formatSwitchroomOutput(detail))}`, { html: true });
114703
115274
  }
114704
115275
  function readRecentDenialsForAgent(agentName3, windowMs, limit) {
114705
115276
  try {
114706
- const auditPath = join77(homedir22(), ".switchroom", "vault-audit.log");
115277
+ const auditPath = join78(homedir22(), ".switchroom", "vault-audit.log");
114707
115278
  if (!existsSync65(auditPath))
114708
115279
  return [];
114709
115280
  const raw = readFileSync67(auditPath, "utf8");
@@ -114757,7 +115328,7 @@ async function buildAgentMetadata(agentName3) {
114757
115328
  try {
114758
115329
  const agentDir = resolveAgentDirFromEnv();
114759
115330
  if (agentDir) {
114760
- const raw = readFileSync67(join77(agentDir, ".claude", ".claude.json"), "utf8");
115331
+ const raw = readFileSync67(join78(agentDir, ".claude", ".claude.json"), "utf8");
114761
115332
  claudeJson = JSON.parse(raw);
114762
115333
  }
114763
115334
  } catch {}
@@ -114886,7 +115457,7 @@ function buildModelDeps(restartCtx) {
114886
115457
  try {
114887
115458
  const agentDir = resolveAgentDirFromEnv();
114888
115459
  if (agentDir) {
114889
- const local = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
115460
+ const local = await fetchQuota2({ claudeConfigDir: join78(agentDir, ".claude") });
114890
115461
  if (local.ok)
114891
115462
  return formatQuotaLine2(local.data);
114892
115463
  }
@@ -115133,7 +115704,7 @@ function effortMenuReplyMarkup(reply) {
115133
115704
  function flushAgentHandoff(agentDir) {
115134
115705
  let removed = 0;
115135
115706
  for (const fname of [".handoff.md", ".handoff-topic"]) {
115136
- const p = join77(agentDir, fname);
115707
+ const p = join78(agentDir, fname);
115137
115708
  try {
115138
115709
  if (existsSync65(p)) {
115139
115710
  unlinkSync33(p);
@@ -115191,7 +115762,7 @@ async function handleNewCommand(ctx) {
115191
115762
  writeRestartMarker({ chat_id: chatId, thread_id: threadId ?? null, ack_message_id: ackId, ts: Date.now() });
115192
115763
  if (agentDir != null) {
115193
115764
  try {
115194
- writeFileSync55(join77(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
115765
+ writeFileSync55(join78(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
115195
115766
  `, "utf8");
115196
115767
  } catch (err) {
115197
115768
  process.stderr.write(`telegram gateway: failed to write force-fresh marker: ${err}
@@ -115308,7 +115879,7 @@ var lockoutOps = {
115308
115879
  writeFileSync: (p, data, opts) => writeStateFileSync2(p, data, opts),
115309
115880
  existsSync: (p) => existsSync65(p),
115310
115881
  mkdirSync: (p, opts) => mkdirStateSync2(p, opts),
115311
- joinPath: (...parts) => join77(...parts)
115882
+ joinPath: (...parts) => join78(...parts)
115312
115883
  };
115313
115884
  var FLEET_FALLBACK_DEDUP_MS = 30000;
115314
115885
  function isAuthBrokerSocketReachable() {
@@ -115569,7 +116140,7 @@ async function runCreditWatch() {
115569
116140
  if (!agentDir)
115570
116141
  return;
115571
116142
  const agentName3 = getMyAgentName();
115572
- const claudeConfigDir = join77(agentDir, ".claude");
116143
+ const claudeConfigDir = join78(agentDir, ".claude");
115573
116144
  const stateDir = STATE_DIR;
115574
116145
  const reason = readClaudeJsonOverage(claudeConfigDir);
115575
116146
  const prev = loadCreditState(stateDir);
@@ -117339,7 +117910,7 @@ Send \`/auth ${parsed.provider} cancel\` to abort.`, { html: true });
117339
117910
  await switchroomReply(ctx, "**/usage:** cannot resolve agent dir.", { html: true });
117340
117911
  return;
117341
117912
  }
117342
- const result = await fetchQuota2({ claudeConfigDir: join77(agentDir, ".claude") });
117913
+ const result = await fetchQuota2({ claudeConfigDir: join78(agentDir, ".claude") });
117343
117914
  if (!result.ok) {
117344
117915
  await switchroomReply(ctx, `**/usage:** ${escapeHtmlForTg2(result.reason)}`, { html: true });
117345
117916
  return;
@@ -118605,7 +119176,7 @@ async function startGateway() {
118605
119176
  return;
118606
119177
  }
118607
119178
  })();
118608
- const resolvedAgentDirForBootCard = agentDir ?? join77(homedir22(), ".switchroom", "agents", agentSlug);
119179
+ const resolvedAgentDirForBootCard = agentDir ?? join78(homedir22(), ".switchroom", "agents", agentSlug);
118609
119180
  const handle = await startBootCard(chatId, threadId, botApiForCard, {
118610
119181
  agentName: agentDisplayName,
118611
119182
  agentSlug,
@@ -118619,8 +119190,8 @@ async function startGateway() {
118619
119190
  probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
118620
119191
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
118621
119192
  dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
118622
- configSnapshotPath: join77(resolvedAgentDirForBootCard, ".config-snapshot.json"),
118623
- bootCardStatePath: join77(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
119193
+ configSnapshotPath: join78(resolvedAgentDirForBootCard, ".config-snapshot.json"),
119194
+ bootCardStatePath: join78(resolvedAgentDirForBootCard, ".boot-card-msgid.json"),
118624
119195
  floodStatePath: FLOOD_STATE_PATH,
118625
119196
  ...updateOutcomeLine ? { updateOutcomeLine } : {}
118626
119197
  }, ackMsgId);
@@ -118653,7 +119224,7 @@ async function startGateway() {
118653
119224
  if (smAgentDir) {
118654
119225
  const resolutionTimeoutMs = resolveSessionModelResolutionTimeoutMs(process.env.SWITCHROOM_SESSION_MODEL_RESOLUTION_TIMEOUT_MS);
118655
119226
  const resolved = await waitForSessionModelResolution({
118656
- barrierExists: () => existsSync65(join77(smAgentDir, ".session-model-resolved")),
119227
+ barrierExists: () => existsSync65(join78(smAgentDir, ".session-model-resolved")),
118657
119228
  timeoutMs: resolutionTimeoutMs
118658
119229
  });
118659
119230
  if (!resolved) {
@@ -118661,7 +119232,7 @@ async function startGateway() {
118661
119232
  process.stderr.write(`telegram gateway: gw /model relaunch UNRESOLVED agent=${getMyAgentName()} target=${target} (barrier timeout after ${resolutionTimeoutMs}ms)
118662
119233
  `);
118663
119234
  } else {
118664
- const activePath = join77(smAgentDir, ".active-session-model");
119235
+ const activePath = join78(smAgentDir, ".active-session-model");
118665
119236
  if (existsSync65(activePath)) {
118666
119237
  try {
118667
119238
  const launched = readFileSync67(activePath, "utf8").trim();
@@ -118697,12 +119268,12 @@ async function startGateway() {
118697
119268
  deliverModelSwitchBootNotice({
118698
119269
  ...modelBootCardDeps,
118699
119270
  confirmation,
118700
- hasSessionModelAlert: existsSync65(join77(smAgentDir, ".session-model-alert"))
119271
+ hasSessionModelAlert: existsSync65(join78(smAgentDir, ".session-model-alert"))
118701
119272
  });
118702
119273
  }
118703
119274
  } catch {}
118704
119275
  }
118705
- const activeEffortPath = join77(smAgentDir, ".active-session-effort");
119276
+ const activeEffortPath = join78(smAgentDir, ".active-session-effort");
118706
119277
  if (existsSync65(activeEffortPath)) {
118707
119278
  try {
118708
119279
  const launchedEffort = readFileSync67(activeEffortPath, "utf8").trim();
@@ -118710,7 +119281,7 @@ async function startGateway() {
118710
119281
  sessionEffortOverride = launchedEffort.length > 0 && launchedEffort !== configuredEffort ? launchedEffort : null;
118711
119282
  } catch {}
118712
119283
  }
118713
- const alertPath = join77(smAgentDir, ".session-model-alert");
119284
+ const alertPath = join78(smAgentDir, ".session-model-alert");
118714
119285
  if (existsSync65(alertPath)) {
118715
119286
  let alertText = null;
118716
119287
  try {