switchroom 0.11.0 → 0.12.0

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 (62) hide show
  1. package/README.md +7 -6
  2. package/dist/agent-scheduler/index.js +218 -99
  3. package/dist/auth-broker/index.js +300 -99
  4. package/dist/cli/drive-write-pretool.mjs +45 -12
  5. package/dist/cli/switchroom.js +44972 -42457
  6. package/dist/cli/ui/index.html +1281 -0
  7. package/dist/host-control/main.js +3630 -311
  8. package/dist/vault/approvals/kernel-server.js +209 -100
  9. package/dist/vault/broker/server.js +220 -99
  10. package/examples/personal-google-workspace-mcp/README.md +8 -3
  11. package/examples/switchroom.yaml +91 -42
  12. package/package.json +2 -2
  13. package/profiles/_base/start.sh.hbs +76 -36
  14. package/profiles/default/CLAUDE.md.hbs +4 -2
  15. package/skills/file-bug/SKILL.md +6 -4
  16. package/skills/switchroom-cli/SKILL.md +20 -4
  17. package/skills/switchroom-install/SKILL.md +3 -3
  18. package/telegram-plugin/auth-snapshot-format.ts +4 -4
  19. package/telegram-plugin/auto-fallback-fleet.ts +4 -4
  20. package/telegram-plugin/card-format.ts +3 -3
  21. package/telegram-plugin/dist/bridge/bridge.js +112 -112
  22. package/telegram-plugin/dist/gateway/gateway.js +1029 -628
  23. package/telegram-plugin/dist/server.js +162 -161
  24. package/telegram-plugin/format.ts +71 -0
  25. package/telegram-plugin/gateway/approval-card.test.ts +18 -18
  26. package/telegram-plugin/gateway/approval-card.ts +1 -1
  27. package/telegram-plugin/gateway/auth-broker-client.ts +2 -0
  28. package/telegram-plugin/gateway/auth-command.ts +12 -2
  29. package/telegram-plugin/gateway/boot-card.ts +40 -3
  30. package/telegram-plugin/gateway/boot-probes.ts +71 -27
  31. package/telegram-plugin/gateway/diff-preview-card.test.ts +15 -15
  32. package/telegram-plugin/gateway/diff-preview-card.ts +1 -1
  33. package/telegram-plugin/gateway/drive-write-approval.test.ts +2 -2
  34. package/telegram-plugin/gateway/gateway.ts +244 -46
  35. package/telegram-plugin/gateway/hostd-dispatch.ts +10 -2
  36. package/telegram-plugin/gateway/update-announce.ts +167 -0
  37. package/telegram-plugin/quota-check.ts +0 -195
  38. package/telegram-plugin/retry-api-call.ts +24 -0
  39. package/telegram-plugin/server.ts +8 -5
  40. package/telegram-plugin/tests/auth-add-flow.test.ts +31 -2
  41. package/telegram-plugin/tests/boot-probes.test.ts +53 -0
  42. package/telegram-plugin/tests/bot-runtime.test.ts +23 -1
  43. package/telegram-plugin/tests/quota-check.test.ts +0 -409
  44. package/telegram-plugin/tests/retry-api-call.test.ts +76 -0
  45. package/telegram-plugin/tests/telegram-format.test.ts +84 -1
  46. package/telegram-plugin/tests/update-announce.test.ts +154 -0
  47. package/telegram-plugin/welcome-text.ts +1 -8
  48. package/profiles/default/CLAUDE.md +0 -192
  49. package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-313.pyc +0 -0
  50. package/skills/docx/scripts/office/validators/__pycache__/base.cpython-313.pyc +0 -0
  51. package/skills/skill-creator/scripts/__pycache__/__init__.cpython-313.pyc +0 -0
  52. package/skills/skill-creator/scripts/__pycache__/generate_report.cpython-313.pyc +0 -0
  53. package/skills/skill-creator/scripts/__pycache__/improve_description.cpython-313.pyc +0 -0
  54. package/skills/skill-creator/scripts/__pycache__/run_eval.cpython-313.pyc +0 -0
  55. package/skills/skill-creator/scripts/__pycache__/run_loop.cpython-313.pyc +0 -0
  56. package/skills/skill-creator/scripts/__pycache__/utils.cpython-313.pyc +0 -0
  57. package/telegram-plugin/first-paint.ts +0 -225
  58. package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  59. package/telegram-plugin/server.js +0 -41795
  60. package/telegram-plugin/tests/html-balanced.ts +0 -63
  61. package/telegram-plugin/tests/snapshot-serializer.ts +0 -79
  62. package/telegram-plugin/tool-error-filter.ts +0 -89
@@ -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.42.0/node_modules/grammy/out/filter.js
69
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/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;
@@ -430,7 +430,7 @@ var require_filter = __commonJS((exports) => {
430
430
  };
431
431
  });
432
432
 
433
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/context.js
433
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/context.js
434
434
  var require_context = __commonJS((exports) => {
435
435
  Object.defineProperty(exports, "__esModule", { value: true });
436
436
  exports.Context = undefined;
@@ -1457,7 +1457,7 @@ var require_context = __commonJS((exports) => {
1457
1457
  }
1458
1458
  });
1459
1459
 
1460
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/composer.js
1460
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/composer.js
1461
1461
  var require_composer = __commonJS((exports) => {
1462
1462
  Object.defineProperty(exports, "__esModule", { value: true });
1463
1463
  exports.Composer = exports.BotError = undefined;
@@ -1619,7 +1619,7 @@ var require_composer = __commonJS((exports) => {
1619
1619
  exports.Composer = Composer;
1620
1620
  });
1621
1621
 
1622
- // ../node_modules/.bun/ms@2.1.3/node_modules/ms/index.js
1622
+ // ../../switchroom/node_modules/.bun/ms@2.1.3/node_modules/ms/index.js
1623
1623
  var require_ms = __commonJS((exports, module) => {
1624
1624
  var s = 1000;
1625
1625
  var m = s * 60;
@@ -1729,7 +1729,7 @@ var require_ms = __commonJS((exports, module) => {
1729
1729
  }
1730
1730
  });
1731
1731
 
1732
- // ../node_modules/.bun/debug@4.4.3/node_modules/debug/src/common.js
1732
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/common.js
1733
1733
  var require_common = __commonJS((exports, module) => {
1734
1734
  function setup(env) {
1735
1735
  createDebug.debug = createDebug;
@@ -1904,7 +1904,7 @@ var require_common = __commonJS((exports, module) => {
1904
1904
  module.exports = setup;
1905
1905
  });
1906
1906
 
1907
- // ../node_modules/.bun/debug@4.4.3/node_modules/debug/src/browser.js
1907
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/browser.js
1908
1908
  var require_browser = __commonJS((exports, module) => {
1909
1909
  exports.formatArgs = formatArgs;
1910
1910
  exports.save = save;
@@ -2064,7 +2064,7 @@ var require_browser = __commonJS((exports, module) => {
2064
2064
  };
2065
2065
  });
2066
2066
 
2067
- // ../node_modules/.bun/has-flag@4.0.0/node_modules/has-flag/index.js
2067
+ // ../../switchroom/node_modules/.bun/has-flag@4.0.0/node_modules/has-flag/index.js
2068
2068
  var require_has_flag = __commonJS((exports, module) => {
2069
2069
  module.exports = (flag, argv = process.argv) => {
2070
2070
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -2074,7 +2074,7 @@ var require_has_flag = __commonJS((exports, module) => {
2074
2074
  };
2075
2075
  });
2076
2076
 
2077
- // ../node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
2077
+ // ../../switchroom/node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
2078
2078
  var require_supports_color = __commonJS((exports, module) => {
2079
2079
  var os = __require("os");
2080
2080
  var tty = __require("tty");
@@ -2173,7 +2173,7 @@ var require_supports_color = __commonJS((exports, module) => {
2173
2173
  };
2174
2174
  });
2175
2175
 
2176
- // ../node_modules/.bun/debug@4.4.3/node_modules/debug/src/node.js
2176
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/node.js
2177
2177
  var require_node = __commonJS((exports, module) => {
2178
2178
  var tty = __require("tty");
2179
2179
  var util = __require("util");
@@ -2344,7 +2344,7 @@ var require_node = __commonJS((exports, module) => {
2344
2344
  };
2345
2345
  });
2346
2346
 
2347
- // ../node_modules/.bun/debug@4.4.3/node_modules/debug/src/index.js
2347
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/index.js
2348
2348
  var require_src = __commonJS((exports, module) => {
2349
2349
  if (typeof process === "undefined" || process.type === "renderer" || false || process.__nwjs) {
2350
2350
  module.exports = require_browser();
@@ -2353,7 +2353,7 @@ var require_src = __commonJS((exports, module) => {
2353
2353
  }
2354
2354
  });
2355
2355
 
2356
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/platform.node.js
2356
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/platform.node.js
2357
2357
  var require_platform_node = __commonJS((exports) => {
2358
2358
  Object.defineProperty(exports, "__esModule", { value: true });
2359
2359
  exports.defaultAdapter = exports.itrToStream = exports.debug = undefined;
@@ -2393,7 +2393,7 @@ var require_platform_node = __commonJS((exports) => {
2393
2393
  exports.defaultAdapter = "express";
2394
2394
  });
2395
2395
 
2396
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/error.js
2396
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/error.js
2397
2397
  var require_error = __commonJS((exports) => {
2398
2398
  Object.defineProperty(exports, "__esModule", { value: true });
2399
2399
  exports.HttpError = exports.GrammyError = undefined;
@@ -2449,10 +2449,10 @@ var require_error = __commonJS((exports) => {
2449
2449
  }
2450
2450
  });
2451
2451
 
2452
- // ../node_modules/.bun/@grammyjs+types@3.26.0/node_modules/@grammyjs/types/mod.js
2452
+ // ../../switchroom/node_modules/.bun/@grammyjs+types@3.26.0/node_modules/@grammyjs/types/mod.js
2453
2453
  var exports_mod = {};
2454
2454
 
2455
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/types.node.js
2455
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/types.node.js
2456
2456
  var require_types_node = __commonJS((exports) => {
2457
2457
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
2458
2458
  if (k2 === undefined)
@@ -2543,7 +2543,7 @@ var require_types_node = __commonJS((exports) => {
2543
2543
  }
2544
2544
  });
2545
2545
 
2546
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/types.js
2546
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/types.js
2547
2547
  var require_types = __commonJS((exports) => {
2548
2548
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
2549
2549
  if (k2 === undefined)
@@ -2569,7 +2569,7 @@ var require_types = __commonJS((exports) => {
2569
2569
  __exportStar(require_types_node(), exports);
2570
2570
  });
2571
2571
 
2572
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/payload.js
2572
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/payload.js
2573
2573
  var require_payload = __commonJS((exports) => {
2574
2574
  Object.defineProperty(exports, "__esModule", { value: true });
2575
2575
  exports.requiresFormDataUpload = requiresFormDataUpload;
@@ -2709,7 +2709,7 @@ content-type:application/octet-stream\r
2709
2709
  }
2710
2710
  });
2711
2711
 
2712
- // ../node_modules/.bun/event-target-shim@5.0.1/node_modules/event-target-shim/dist/event-target-shim.js
2712
+ // ../../switchroom/node_modules/.bun/event-target-shim@5.0.1/node_modules/event-target-shim/dist/event-target-shim.js
2713
2713
  var require_event_target_shim = __commonJS((exports, module) => {
2714
2714
  Object.defineProperty(exports, "__esModule", { value: true });
2715
2715
  var privateData = new WeakMap;
@@ -3149,7 +3149,7 @@ var require_event_target_shim = __commonJS((exports, module) => {
3149
3149
  module.exports.defineEventAttribute = defineEventAttribute;
3150
3150
  });
3151
3151
 
3152
- // ../node_modules/.bun/abort-controller@3.0.0/node_modules/abort-controller/dist/abort-controller.js
3152
+ // ../../switchroom/node_modules/.bun/abort-controller@3.0.0/node_modules/abort-controller/dist/abort-controller.js
3153
3153
  var require_abort_controller = __commonJS((exports, module) => {
3154
3154
  Object.defineProperty(exports, "__esModule", { value: true });
3155
3155
  var eventTargetShim = require_event_target_shim();
@@ -3229,7 +3229,7 @@ var require_abort_controller = __commonJS((exports, module) => {
3229
3229
  module.exports.AbortSignal = AbortSignal2;
3230
3230
  });
3231
3231
 
3232
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/shim.node.js
3232
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/shim.node.js
3233
3233
  var require_shim_node = __commonJS((exports) => {
3234
3234
  Object.defineProperty(exports, "__esModule", { value: true });
3235
3235
  exports.fetch = exports.AbortController = undefined;
@@ -3243,7 +3243,7 @@ var require_shim_node = __commonJS((exports) => {
3243
3243
  } });
3244
3244
  });
3245
3245
 
3246
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/client.js
3246
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/client.js
3247
3247
  var require_client = __commonJS((exports) => {
3248
3248
  Object.defineProperty(exports, "__esModule", { value: true });
3249
3249
  exports.createRawApi = createRawApi;
@@ -3423,7 +3423,7 @@ If you want to prevent such mistakes in the future, consider using TypeScript. h
3423
3423
  var shim_node_js_1 = require_shim_node();
3424
3424
  });
3425
3425
 
3426
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/api.js
3426
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/core/api.js
3427
3427
  var require_api = __commonJS((exports) => {
3428
3428
  Object.defineProperty(exports, "__esModule", { value: true });
3429
3429
  exports.Api = undefined;
@@ -4041,7 +4041,7 @@ var require_api = __commonJS((exports) => {
4041
4041
  exports.Api = Api;
4042
4042
  });
4043
4043
 
4044
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/bot.js
4044
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/bot.js
4045
4045
  var require_bot = __commonJS((exports) => {
4046
4046
  Object.defineProperty(exports, "__esModule", { value: true });
4047
4047
  exports.Bot = exports.BotError = exports.DEFAULT_UPDATE_TYPES = undefined;
@@ -4370,7 +4370,7 @@ On the other hand, if you actually know what you're doing and you do need to ins
4370
4370
  var shim_node_js_1 = require_shim_node();
4371
4371
  });
4372
4372
 
4373
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/constants.js
4373
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/constants.js
4374
4374
  var require_constants = __commonJS((exports) => {
4375
4375
  Object.defineProperty(exports, "__esModule", { value: true });
4376
4376
  exports.API_CONSTANTS = undefined;
@@ -4406,7 +4406,7 @@ var require_constants = __commonJS((exports) => {
4406
4406
  Object.freeze(exports.API_CONSTANTS);
4407
4407
  });
4408
4408
 
4409
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/inline_query.js
4409
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/inline_query.js
4410
4410
  var require_inline_query = __commonJS((exports) => {
4411
4411
  Object.defineProperty(exports, "__esModule", { value: true });
4412
4412
  exports.InlineQueryResultBuilder = undefined;
@@ -4604,7 +4604,7 @@ var require_inline_query = __commonJS((exports) => {
4604
4604
  };
4605
4605
  });
4606
4606
 
4607
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/input_media.js
4607
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/input_media.js
4608
4608
  var require_input_media = __commonJS((exports) => {
4609
4609
  Object.defineProperty(exports, "__esModule", { value: true });
4610
4610
  exports.InputMediaBuilder = undefined;
@@ -4627,7 +4627,7 @@ var require_input_media = __commonJS((exports) => {
4627
4627
  };
4628
4628
  });
4629
4629
 
4630
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/keyboard.js
4630
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/keyboard.js
4631
4631
  var require_keyboard = __commonJS((exports) => {
4632
4632
  Object.defineProperty(exports, "__esModule", { value: true });
4633
4633
  exports.InlineKeyboard = exports.Keyboard = undefined;
@@ -4985,7 +4985,7 @@ var require_keyboard = __commonJS((exports) => {
4985
4985
  }
4986
4986
  });
4987
4987
 
4988
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/session.js
4988
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/session.js
4989
4989
  var require_session = __commonJS((exports) => {
4990
4990
  Object.defineProperty(exports, "__esModule", { value: true });
4991
4991
  exports.MemorySessionStorage = undefined;
@@ -5285,7 +5285,7 @@ var require_session = __commonJS((exports) => {
5285
5285
  }
5286
5286
  });
5287
5287
 
5288
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/frameworks.js
5288
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/frameworks.js
5289
5289
  var require_frameworks = __commonJS((exports) => {
5290
5290
  Object.defineProperty(exports, "__esModule", { value: true });
5291
5291
  exports.adapters = undefined;
@@ -5653,7 +5653,7 @@ var require_frameworks = __commonJS((exports) => {
5653
5653
  };
5654
5654
  });
5655
5655
 
5656
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/webhook.js
5656
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/convenience/webhook.js
5657
5657
  var require_webhook = __commonJS((exports) => {
5658
5658
  Object.defineProperty(exports, "__esModule", { value: true });
5659
5659
  exports.webhookCallback = webhookCallback;
@@ -5747,7 +5747,7 @@ var require_webhook = __commonJS((exports) => {
5747
5747
  }
5748
5748
  });
5749
5749
 
5750
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/mod.js
5750
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/mod.js
5751
5751
  var require_mod = __commonJS((exports) => {
5752
5752
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
5753
5753
  if (k2 === undefined)
@@ -5813,7 +5813,7 @@ var require_mod = __commonJS((exports) => {
5813
5813
  } });
5814
5814
  });
5815
5815
 
5816
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/platform.node.js
5816
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/platform.node.js
5817
5817
  var require_platform_node2 = __commonJS((exports) => {
5818
5818
  Object.defineProperty(exports, "__esModule", { value: true });
5819
5819
  exports.parentThread = exports.createThread = undefined;
@@ -5844,7 +5844,7 @@ var require_platform_node2 = __commonJS((exports) => {
5844
5844
  exports.parentThread = parentThread;
5845
5845
  });
5846
5846
 
5847
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/distribute.js
5847
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/distribute.js
5848
5848
  var require_distribute = __commonJS((exports) => {
5849
5849
  Object.defineProperty(exports, "__esModule", { value: true });
5850
5850
  exports.distribute = undefined;
@@ -5889,7 +5889,7 @@ var require_distribute = __commonJS((exports) => {
5889
5889
  exports.distribute = distribute;
5890
5890
  });
5891
5891
 
5892
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/queue.js
5892
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/queue.js
5893
5893
  var require_queue = __commonJS((exports) => {
5894
5894
  Object.defineProperty(exports, "__esModule", { value: true });
5895
5895
  exports.DecayingDeque = undefined;
@@ -6033,7 +6033,7 @@ var require_queue = __commonJS((exports) => {
6033
6033
  exports.DecayingDeque = DecayingDeque;
6034
6034
  });
6035
6035
 
6036
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/sink.js
6036
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/sink.js
6037
6037
  var require_sink = __commonJS((exports) => {
6038
6038
  Object.defineProperty(exports, "__esModule", { value: true });
6039
6039
  exports.createConcurrentSink = exports.createBatchSink = exports.createSequentialSink = undefined;
@@ -6078,7 +6078,7 @@ var require_sink = __commonJS((exports) => {
6078
6078
  exports.createConcurrentSink = createConcurrentSink;
6079
6079
  });
6080
6080
 
6081
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/node-shim.js
6081
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/node-shim.js
6082
6082
  var require_node_shim = __commonJS((exports) => {
6083
6083
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
6084
6084
  if (k2 === undefined)
@@ -6104,7 +6104,7 @@ var require_node_shim = __commonJS((exports) => {
6104
6104
  __exportStar(require_abort_controller(), exports);
6105
6105
  });
6106
6106
 
6107
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/source.js
6107
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/source.js
6108
6108
  var require_source = __commonJS((exports) => {
6109
6109
  Object.defineProperty(exports, "__esModule", { value: true });
6110
6110
  exports.createSource = undefined;
@@ -6184,7 +6184,7 @@ var require_source = __commonJS((exports) => {
6184
6184
  var node_shim_js_1 = require_node_shim();
6185
6185
  });
6186
6186
 
6187
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/runner.js
6187
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/runner.js
6188
6188
  var require_runner = __commonJS((exports) => {
6189
6189
  Object.defineProperty(exports, "__esModule", { value: true });
6190
6190
  exports.createRunner = exports.createUpdateFetcher = exports.run = undefined;
@@ -6336,7 +6336,7 @@ var require_runner = __commonJS((exports) => {
6336
6336
  }
6337
6337
  });
6338
6338
 
6339
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/sequentialize.js
6339
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/sequentialize.js
6340
6340
  var require_sequentialize = __commonJS((exports) => {
6341
6341
  Object.defineProperty(exports, "__esModule", { value: true });
6342
6342
  exports.sequentialize = undefined;
@@ -6379,7 +6379,7 @@ var require_sequentialize = __commonJS((exports) => {
6379
6379
  exports.sequentialize = sequentialize;
6380
6380
  });
6381
6381
 
6382
- // ../node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/mod.js
6382
+ // ../../switchroom/node_modules/.bun/grammy@1.42.0/node_modules/grammy/out/mod.js
6383
6383
  var require_mod2 = __commonJS((exports) => {
6384
6384
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
6385
6385
  if (k2 === undefined)
@@ -6445,7 +6445,7 @@ var require_mod2 = __commonJS((exports) => {
6445
6445
  } });
6446
6446
  });
6447
6447
 
6448
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/deps.node.js
6448
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/deps.node.js
6449
6449
  var require_deps_node = __commonJS((exports) => {
6450
6450
  Object.defineProperty(exports, "__esModule", { value: true });
6451
6451
  exports.BotError = exports.Bot = undefined;
@@ -6458,7 +6458,7 @@ var require_deps_node = __commonJS((exports) => {
6458
6458
  } });
6459
6459
  });
6460
6460
 
6461
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/worker.js
6461
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/worker.js
6462
6462
  var require_worker = __commonJS((exports) => {
6463
6463
  Object.defineProperty(exports, "__esModule", { value: true });
6464
6464
  exports.BotWorker = undefined;
@@ -6500,7 +6500,7 @@ var require_worker = __commonJS((exports) => {
6500
6500
  exports.BotWorker = BotWorker;
6501
6501
  });
6502
6502
 
6503
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/mod.js
6503
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/mod.js
6504
6504
  var require_mod3 = __commonJS((exports) => {
6505
6505
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
6506
6506
  if (k2 === undefined)
@@ -6532,7 +6532,7 @@ var require_mod3 = __commonJS((exports) => {
6532
6532
  __exportStar(require_worker(), exports);
6533
6533
  });
6534
6534
 
6535
- // ../node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/mod.js
6535
+ // ../../switchroom/node_modules/.bun/@grammyjs+runner@2.0.3+c6be0243b1bbec89/node_modules/@grammyjs/runner/out/mod.js
6536
6536
  var require_mod4 = __commonJS((exports) => {
6537
6537
  var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
6538
6538
  if (k2 === undefined)
@@ -6564,7 +6564,7 @@ var require_mod4 = __commonJS((exports) => {
6564
6564
  __exportStar(require_worker(), exports);
6565
6565
  });
6566
6566
 
6567
- // ../node_modules/.bun/@xterm+headless@6.0.0/node_modules/@xterm/headless/lib-headless/xterm-headless.js
6567
+ // ../../switchroom/node_modules/.bun/@xterm+headless@6.0.0/node_modules/@xterm/headless/lib-headless/xterm-headless.js
6568
6568
  var require_xterm_headless = __commonJS((exports2) => {
6569
6569
  (() => {
6570
6570
  var e = { 5639: (e2, t2, s2) => {
@@ -12119,7 +12119,7 @@ ${i3.join(`
12119
12119
  })();
12120
12120
  });
12121
12121
 
12122
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
12122
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
12123
12123
  var util, objectUtil, ZodParsedType, getParsedType = (data) => {
12124
12124
  const t = typeof data;
12125
12125
  switch (t) {
@@ -12250,7 +12250,7 @@ var init_util = __esm(() => {
12250
12250
  ]);
12251
12251
  });
12252
12252
 
12253
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
12253
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
12254
12254
  var ZodIssueCode, quotelessJson = (obj) => {
12255
12255
  const json = JSON.stringify(obj, null, 2);
12256
12256
  return json.replace(/"([^"]+)":/g, "$1:");
@@ -12371,7 +12371,7 @@ var init_ZodError = __esm(() => {
12371
12371
  };
12372
12372
  });
12373
12373
 
12374
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
12374
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
12375
12375
  var errorMap = (issue, _ctx) => {
12376
12376
  let message;
12377
12377
  switch (issue.code) {
@@ -12478,7 +12478,7 @@ var init_en = __esm(() => {
12478
12478
  en_default = errorMap;
12479
12479
  });
12480
12480
 
12481
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
12481
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
12482
12482
  function setErrorMap(map) {
12483
12483
  overrideErrorMap = map;
12484
12484
  }
@@ -12491,7 +12491,7 @@ var init_errors = __esm(() => {
12491
12491
  overrideErrorMap = en_default;
12492
12492
  });
12493
12493
 
12494
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
12494
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
12495
12495
  function addIssueToContext(ctx, issueData) {
12496
12496
  const overrideMap = getErrorMap();
12497
12497
  const issue = makeIssue({
@@ -12596,10 +12596,10 @@ var init_parseUtil = __esm(() => {
12596
12596
  });
12597
12597
  });
12598
12598
 
12599
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/typeAliases.js
12599
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/typeAliases.js
12600
12600
  var init_typeAliases = () => {};
12601
12601
 
12602
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
12602
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
12603
12603
  var errorUtil;
12604
12604
  var init_errorUtil = __esm(() => {
12605
12605
  (function(errorUtil2) {
@@ -12608,7 +12608,7 @@ var init_errorUtil = __esm(() => {
12608
12608
  })(errorUtil || (errorUtil = {}));
12609
12609
  });
12610
12610
 
12611
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
12611
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
12612
12612
  class ParseInputLazyPath {
12613
12613
  constructor(parent, value, path, key) {
12614
12614
  this._cachedPath = [];
@@ -15959,7 +15959,7 @@ var init_types = __esm(() => {
15959
15959
  NEVER = INVALID;
15960
15960
  });
15961
15961
 
15962
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
15962
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
15963
15963
  var exports_external = {};
15964
15964
  __export(exports_external, {
15965
15965
  void: () => voidType,
@@ -16079,7 +16079,7 @@ var init_external = __esm(() => {
16079
16079
  init_ZodError();
16080
16080
  });
16081
16081
 
16082
- // ../node_modules/.bun/zod@3.25.76/node_modules/zod/index.js
16082
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/index.js
16083
16083
  var init_zod = __esm(() => {
16084
16084
  init_external();
16085
16085
  init_external();
@@ -16105,7 +16105,7 @@ function decodeResponse(line) {
16105
16105
  }
16106
16106
  return ResponseSchema.parse(parsed);
16107
16107
  }
16108
- var MAX_FRAME_BYTES, PROTOCOL_VERSION = 1, ProviderNameSchema, GetCredentialsRequestSchema, ListStateRequestSchema, SetActiveRequestSchema, MarkExhaustedRequestSchema, RefreshAccountRequestSchema, AnthropicCredentialsSchema, GoogleCredentialsSchema, ProviderCredentialsSchema, AddAccountRequestSchema, RmAccountRequestSchema, SetOverrideRequestSchema, ListGoogleAccountsRequestSchema, RequestSchema, GetCredentialsDataSchema, AccountStateSchema, AgentStateSchema, ConsumerStateSchema, ListStateDataSchema, SetActiveDataSchema, MarkExhaustedDataSchema, RefreshAccountDataSchema, AddAccountDataSchema, RmAccountDataSchema, SetOverrideDataSchema, GoogleAccountStateSchema, ListGoogleAccountsDataSchema, ErrorBodySchema, SuccessResponseSchema, ErrorResponseSchema, ResponseSchema;
16108
+ var MAX_FRAME_BYTES, PROTOCOL_VERSION = 1, ProviderNameSchema, GetCredentialsRequestSchema, ListStateRequestSchema, SetActiveRequestSchema, MarkExhaustedRequestSchema, RefreshAccountRequestSchema, AnthropicCredentialsSchema, GoogleCredentialsSchema, ProviderCredentialsSchema, AddAccountRequestSchema, RmAccountRequestSchema, SetOverrideRequestSchema, ListGoogleAccountsRequestSchema, ProbeQuotaRequestSchema, RequestSchema, GetCredentialsDataSchema, AccountStateSchema, AgentStateSchema, ConsumerStateSchema, ListStateDataSchema, SetActiveDataSchema, MarkExhaustedDataSchema, RefreshAccountDataSchema, AddAccountDataSchema, RmAccountDataSchema, SetOverrideDataSchema, GoogleAccountStateSchema, ListGoogleAccountsDataSchema, ErrorBodySchema, SuccessResponseSchema, ErrorResponseSchema, ResponseSchema;
16109
16109
  var init_protocol = __esm(() => {
16110
16110
  init_zod();
16111
16111
  MAX_FRAME_BYTES = 64 * 1024;
@@ -16194,6 +16194,13 @@ var init_protocol = __esm(() => {
16194
16194
  op: exports_external.literal("list-google-accounts"),
16195
16195
  id: exports_external.string().min(1)
16196
16196
  });
16197
+ ProbeQuotaRequestSchema = exports_external.object({
16198
+ v: exports_external.literal(PROTOCOL_VERSION),
16199
+ op: exports_external.literal("probe-quota"),
16200
+ id: exports_external.string().min(1),
16201
+ accounts: exports_external.array(exports_external.string().min(1)).min(1).max(32),
16202
+ timeoutMs: exports_external.number().int().positive().max(60000).optional()
16203
+ });
16197
16204
  RequestSchema = exports_external.discriminatedUnion("op", [
16198
16205
  GetCredentialsRequestSchema,
16199
16206
  ListStateRequestSchema,
@@ -16203,7 +16210,8 @@ var init_protocol = __esm(() => {
16203
16210
  AddAccountRequestSchema,
16204
16211
  RmAccountRequestSchema,
16205
16212
  SetOverrideRequestSchema,
16206
- ListGoogleAccountsRequestSchema
16213
+ ListGoogleAccountsRequestSchema,
16214
+ ProbeQuotaRequestSchema
16207
16215
  ]);
16208
16216
  GetCredentialsDataSchema = exports_external.object({
16209
16217
  account: exports_external.string(),
@@ -16315,6 +16323,14 @@ import { existsSync as existsSync6 } from "node:fs";
16315
16323
  import { homedir as homedir3 } from "node:os";
16316
16324
  import { randomUUID as randomUUID3 } from "node:crypto";
16317
16325
  import { join as join8 } from "node:path";
16326
+ function reviveDate(v) {
16327
+ if (v == null)
16328
+ return null;
16329
+ if (v instanceof Date)
16330
+ return Number.isNaN(v.getTime()) ? null : v;
16331
+ const d = new Date(v);
16332
+ return Number.isNaN(d.getTime()) ? null : d;
16333
+ }
16318
16334
  function operatorSocketPath(home = homedir3()) {
16319
16335
  return join8(home, ".switchroom", "state", "auth-broker-operator", "sock");
16320
16336
  }
@@ -16382,6 +16398,23 @@ class AuthBrokerClient {
16382
16398
  });
16383
16399
  return data;
16384
16400
  }
16401
+ async probeQuota(accounts, timeoutMs) {
16402
+ const data = await this.send({
16403
+ v: PROTOCOL_VERSION,
16404
+ id: randomUUID3(),
16405
+ op: "probe-quota",
16406
+ accounts: [...accounts],
16407
+ ...timeoutMs !== undefined ? { timeoutMs } : {}
16408
+ });
16409
+ const parsed = data;
16410
+ for (const entry of parsed.results) {
16411
+ if (entry.result.ok) {
16412
+ entry.result.data.fiveHourResetAt = reviveDate(entry.result.data.fiveHourResetAt);
16413
+ entry.result.data.sevenDayResetAt = reviveDate(entry.result.data.sevenDayResetAt);
16414
+ }
16415
+ }
16416
+ return parsed;
16417
+ }
16385
16418
  async setActive(account) {
16386
16419
  const data = await this.send({
16387
16420
  v: PROTOCOL_VERSION,
@@ -16594,7 +16627,7 @@ var init_client = __esm(() => {
16594
16627
  };
16595
16628
  });
16596
16629
 
16597
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
16630
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
16598
16631
  var require_identity = __commonJS((exports2) => {
16599
16632
  var ALIAS = Symbol.for("yaml.alias");
16600
16633
  var DOC = Symbol.for("yaml.document");
@@ -16648,7 +16681,7 @@ var require_identity = __commonJS((exports2) => {
16648
16681
  exports2.isSeq = isSeq;
16649
16682
  });
16650
16683
 
16651
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
16684
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
16652
16685
  var require_visit = __commonJS((exports2) => {
16653
16686
  var identity = require_identity();
16654
16687
  var BREAK = Symbol("break visit");
@@ -16803,7 +16836,7 @@ var require_visit = __commonJS((exports2) => {
16803
16836
  exports2.visitAsync = visitAsync;
16804
16837
  });
16805
16838
 
16806
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
16839
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
16807
16840
  var require_directives = __commonJS((exports2) => {
16808
16841
  var identity = require_identity();
16809
16842
  var visit = require_visit();
@@ -16955,7 +16988,7 @@ var require_directives = __commonJS((exports2) => {
16955
16988
  exports2.Directives = Directives;
16956
16989
  });
16957
16990
 
16958
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
16991
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
16959
16992
  var require_anchors = __commonJS((exports2) => {
16960
16993
  var identity = require_identity();
16961
16994
  var visit = require_visit();
@@ -17017,7 +17050,7 @@ var require_anchors = __commonJS((exports2) => {
17017
17050
  exports2.findNewAnchor = findNewAnchor;
17018
17051
  });
17019
17052
 
17020
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
17053
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
17021
17054
  var require_applyReviver = __commonJS((exports2) => {
17022
17055
  function applyReviver(reviver, obj, key, val) {
17023
17056
  if (val && typeof val === "object") {
@@ -17064,7 +17097,7 @@ var require_applyReviver = __commonJS((exports2) => {
17064
17097
  exports2.applyReviver = applyReviver;
17065
17098
  });
17066
17099
 
17067
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
17100
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
17068
17101
  var require_toJS = __commonJS((exports2) => {
17069
17102
  var identity = require_identity();
17070
17103
  function toJS(value, arg, ctx) {
@@ -17091,7 +17124,7 @@ var require_toJS = __commonJS((exports2) => {
17091
17124
  exports2.toJS = toJS;
17092
17125
  });
17093
17126
 
17094
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
17127
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
17095
17128
  var require_Node = __commonJS((exports2) => {
17096
17129
  var applyReviver = require_applyReviver();
17097
17130
  var identity = require_identity();
@@ -17128,7 +17161,7 @@ var require_Node = __commonJS((exports2) => {
17128
17161
  exports2.NodeBase = NodeBase;
17129
17162
  });
17130
17163
 
17131
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
17164
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
17132
17165
  var require_Alias = __commonJS((exports2) => {
17133
17166
  var anchors = require_anchors();
17134
17167
  var visit = require_visit();
@@ -17236,7 +17269,7 @@ var require_Alias = __commonJS((exports2) => {
17236
17269
  exports2.Alias = Alias;
17237
17270
  });
17238
17271
 
17239
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
17272
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
17240
17273
  var require_Scalar = __commonJS((exports2) => {
17241
17274
  var identity = require_identity();
17242
17275
  var Node = require_Node();
@@ -17264,7 +17297,7 @@ var require_Scalar = __commonJS((exports2) => {
17264
17297
  exports2.isScalarValue = isScalarValue;
17265
17298
  });
17266
17299
 
17267
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
17300
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
17268
17301
  var require_createNode = __commonJS((exports2) => {
17269
17302
  var Alias = require_Alias();
17270
17303
  var identity = require_identity();
@@ -17336,7 +17369,7 @@ var require_createNode = __commonJS((exports2) => {
17336
17369
  exports2.createNode = createNode;
17337
17370
  });
17338
17371
 
17339
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
17372
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
17340
17373
  var require_Collection = __commonJS((exports2) => {
17341
17374
  var createNode = require_createNode();
17342
17375
  var identity = require_identity();
@@ -17451,7 +17484,7 @@ var require_Collection = __commonJS((exports2) => {
17451
17484
  exports2.isEmptyPath = isEmptyPath;
17452
17485
  });
17453
17486
 
17454
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
17487
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
17455
17488
  var require_stringifyComment = __commonJS((exports2) => {
17456
17489
  var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
17457
17490
  function indentComment(comment, indent) {
@@ -17468,7 +17501,7 @@ var require_stringifyComment = __commonJS((exports2) => {
17468
17501
  exports2.stringifyComment = stringifyComment;
17469
17502
  });
17470
17503
 
17471
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
17504
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
17472
17505
  var require_foldFlowLines = __commonJS((exports2) => {
17473
17506
  var FOLD_FLOW = "flow";
17474
17507
  var FOLD_BLOCK = "block";
@@ -17605,7 +17638,7 @@ ${indent}${text.slice(fold + 1, end2)}`;
17605
17638
  exports2.foldFlowLines = foldFlowLines;
17606
17639
  });
17607
17640
 
17608
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
17641
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
17609
17642
  var require_stringifyString = __commonJS((exports2) => {
17610
17643
  var Scalar = require_Scalar();
17611
17644
  var foldFlowLines = require_foldFlowLines();
@@ -17903,7 +17936,7 @@ ${indent}`);
17903
17936
  exports2.stringifyString = stringifyString;
17904
17937
  });
17905
17938
 
17906
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
17939
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
17907
17940
  var require_stringify = __commonJS((exports2) => {
17908
17941
  var anchors = require_anchors();
17909
17942
  var identity = require_identity();
@@ -18024,7 +18057,7 @@ ${ctx.indent}${str}`;
18024
18057
  exports2.stringify = stringify;
18025
18058
  });
18026
18059
 
18027
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
18060
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
18028
18061
  var require_stringifyPair = __commonJS((exports2) => {
18029
18062
  var identity = require_identity();
18030
18063
  var Scalar = require_Scalar();
@@ -18160,7 +18193,7 @@ ${ctx.indent}`;
18160
18193
  exports2.stringifyPair = stringifyPair;
18161
18194
  });
18162
18195
 
18163
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
18196
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
18164
18197
  var require_log = __commonJS((exports2) => {
18165
18198
  var node_process = __require("process");
18166
18199
  function debug(logLevel, ...messages) {
@@ -18179,7 +18212,7 @@ var require_log = __commonJS((exports2) => {
18179
18212
  exports2.warn = warn;
18180
18213
  });
18181
18214
 
18182
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
18215
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
18183
18216
  var require_merge = __commonJS((exports2) => {
18184
18217
  var identity = require_identity();
18185
18218
  var Scalar = require_Scalar();
@@ -18233,7 +18266,7 @@ var require_merge = __commonJS((exports2) => {
18233
18266
  exports2.merge = merge;
18234
18267
  });
18235
18268
 
18236
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
18269
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
18237
18270
  var require_addPairToJSMap = __commonJS((exports2) => {
18238
18271
  var log = require_log();
18239
18272
  var merge = require_merge();
@@ -18294,7 +18327,7 @@ var require_addPairToJSMap = __commonJS((exports2) => {
18294
18327
  exports2.addPairToJSMap = addPairToJSMap;
18295
18328
  });
18296
18329
 
18297
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
18330
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
18298
18331
  var require_Pair = __commonJS((exports2) => {
18299
18332
  var createNode = require_createNode();
18300
18333
  var stringifyPair = require_stringifyPair();
@@ -18332,7 +18365,7 @@ var require_Pair = __commonJS((exports2) => {
18332
18365
  exports2.createPair = createPair;
18333
18366
  });
18334
18367
 
18335
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
18368
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
18336
18369
  var require_stringifyCollection = __commonJS((exports2) => {
18337
18370
  var identity = require_identity();
18338
18371
  var stringify = require_stringify();
@@ -18484,7 +18517,7 @@ ${indent}${end}`;
18484
18517
  exports2.stringifyCollection = stringifyCollection;
18485
18518
  });
18486
18519
 
18487
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
18520
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
18488
18521
  var require_YAMLMap = __commonJS((exports2) => {
18489
18522
  var stringifyCollection = require_stringifyCollection();
18490
18523
  var addPairToJSMap = require_addPairToJSMap();
@@ -18611,7 +18644,7 @@ var require_YAMLMap = __commonJS((exports2) => {
18611
18644
  exports2.findPair = findPair;
18612
18645
  });
18613
18646
 
18614
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
18647
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
18615
18648
  var require_map = __commonJS((exports2) => {
18616
18649
  var identity = require_identity();
18617
18650
  var YAMLMap = require_YAMLMap();
@@ -18630,7 +18663,7 @@ var require_map = __commonJS((exports2) => {
18630
18663
  exports2.map = map;
18631
18664
  });
18632
18665
 
18633
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
18666
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
18634
18667
  var require_YAMLSeq = __commonJS((exports2) => {
18635
18668
  var createNode = require_createNode();
18636
18669
  var stringifyCollection = require_stringifyCollection();
@@ -18723,7 +18756,7 @@ var require_YAMLSeq = __commonJS((exports2) => {
18723
18756
  exports2.YAMLSeq = YAMLSeq;
18724
18757
  });
18725
18758
 
18726
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
18759
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
18727
18760
  var require_seq = __commonJS((exports2) => {
18728
18761
  var identity = require_identity();
18729
18762
  var YAMLSeq = require_YAMLSeq();
@@ -18742,7 +18775,7 @@ var require_seq = __commonJS((exports2) => {
18742
18775
  exports2.seq = seq;
18743
18776
  });
18744
18777
 
18745
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
18778
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
18746
18779
  var require_string = __commonJS((exports2) => {
18747
18780
  var stringifyString = require_stringifyString();
18748
18781
  var string = {
@@ -18758,7 +18791,7 @@ var require_string = __commonJS((exports2) => {
18758
18791
  exports2.string = string;
18759
18792
  });
18760
18793
 
18761
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
18794
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
18762
18795
  var require_null = __commonJS((exports2) => {
18763
18796
  var Scalar = require_Scalar();
18764
18797
  var nullTag = {
@@ -18773,7 +18806,7 @@ var require_null = __commonJS((exports2) => {
18773
18806
  exports2.nullTag = nullTag;
18774
18807
  });
18775
18808
 
18776
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
18809
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
18777
18810
  var require_bool = __commonJS((exports2) => {
18778
18811
  var Scalar = require_Scalar();
18779
18812
  var boolTag = {
@@ -18794,7 +18827,7 @@ var require_bool = __commonJS((exports2) => {
18794
18827
  exports2.boolTag = boolTag;
18795
18828
  });
18796
18829
 
18797
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
18830
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
18798
18831
  var require_stringifyNumber = __commonJS((exports2) => {
18799
18832
  function stringifyNumber({ format, minFractionDigits, tag, value }) {
18800
18833
  if (typeof value === "bigint")
@@ -18818,7 +18851,7 @@ var require_stringifyNumber = __commonJS((exports2) => {
18818
18851
  exports2.stringifyNumber = stringifyNumber;
18819
18852
  });
18820
18853
 
18821
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
18854
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
18822
18855
  var require_float = __commonJS((exports2) => {
18823
18856
  var Scalar = require_Scalar();
18824
18857
  var stringifyNumber = require_stringifyNumber();
@@ -18861,7 +18894,7 @@ var require_float = __commonJS((exports2) => {
18861
18894
  exports2.floatNaN = floatNaN;
18862
18895
  });
18863
18896
 
18864
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
18897
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
18865
18898
  var require_int = __commonJS((exports2) => {
18866
18899
  var stringifyNumber = require_stringifyNumber();
18867
18900
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -18903,7 +18936,7 @@ var require_int = __commonJS((exports2) => {
18903
18936
  exports2.intOct = intOct;
18904
18937
  });
18905
18938
 
18906
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
18939
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
18907
18940
  var require_schema = __commonJS((exports2) => {
18908
18941
  var map = require_map();
18909
18942
  var _null = require_null();
@@ -18928,7 +18961,7 @@ var require_schema = __commonJS((exports2) => {
18928
18961
  exports2.schema = schema;
18929
18962
  });
18930
18963
 
18931
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
18964
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
18932
18965
  var require_schema2 = __commonJS((exports2) => {
18933
18966
  var Scalar = require_Scalar();
18934
18967
  var map = require_map();
@@ -18992,7 +19025,7 @@ var require_schema2 = __commonJS((exports2) => {
18992
19025
  exports2.schema = schema;
18993
19026
  });
18994
19027
 
18995
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
19028
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
18996
19029
  var require_binary = __commonJS((exports2) => {
18997
19030
  var node_buffer = __require("buffer");
18998
19031
  var Scalar = require_Scalar();
@@ -19047,7 +19080,7 @@ var require_binary = __commonJS((exports2) => {
19047
19080
  exports2.binary = binary;
19048
19081
  });
19049
19082
 
19050
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
19083
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
19051
19084
  var require_pairs = __commonJS((exports2) => {
19052
19085
  var identity = require_identity();
19053
19086
  var Pair = require_Pair();
@@ -19122,7 +19155,7 @@ ${cn.comment}` : item.comment;
19122
19155
  exports2.resolvePairs = resolvePairs;
19123
19156
  });
19124
19157
 
19125
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
19158
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
19126
19159
  var require_omap = __commonJS((exports2) => {
19127
19160
  var identity = require_identity();
19128
19161
  var toJS = require_toJS();
@@ -19194,7 +19227,7 @@ var require_omap = __commonJS((exports2) => {
19194
19227
  exports2.omap = omap;
19195
19228
  });
19196
19229
 
19197
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
19230
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
19198
19231
  var require_bool2 = __commonJS((exports2) => {
19199
19232
  var Scalar = require_Scalar();
19200
19233
  function boolStringify({ value, source }, ctx) {
@@ -19223,7 +19256,7 @@ var require_bool2 = __commonJS((exports2) => {
19223
19256
  exports2.trueTag = trueTag;
19224
19257
  });
19225
19258
 
19226
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
19259
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
19227
19260
  var require_float2 = __commonJS((exports2) => {
19228
19261
  var Scalar = require_Scalar();
19229
19262
  var stringifyNumber = require_stringifyNumber();
@@ -19269,7 +19302,7 @@ var require_float2 = __commonJS((exports2) => {
19269
19302
  exports2.floatNaN = floatNaN;
19270
19303
  });
19271
19304
 
19272
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
19305
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
19273
19306
  var require_int2 = __commonJS((exports2) => {
19274
19307
  var stringifyNumber = require_stringifyNumber();
19275
19308
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -19345,7 +19378,7 @@ var require_int2 = __commonJS((exports2) => {
19345
19378
  exports2.intOct = intOct;
19346
19379
  });
19347
19380
 
19348
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
19381
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
19349
19382
  var require_set = __commonJS((exports2) => {
19350
19383
  var identity = require_identity();
19351
19384
  var Pair = require_Pair();
@@ -19428,7 +19461,7 @@ var require_set = __commonJS((exports2) => {
19428
19461
  exports2.set = set;
19429
19462
  });
19430
19463
 
19431
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
19464
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
19432
19465
  var require_timestamp = __commonJS((exports2) => {
19433
19466
  var stringifyNumber = require_stringifyNumber();
19434
19467
  function parseSexagesimal(str, asBigInt) {
@@ -19510,7 +19543,7 @@ var require_timestamp = __commonJS((exports2) => {
19510
19543
  exports2.timestamp = timestamp;
19511
19544
  });
19512
19545
 
19513
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
19546
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
19514
19547
  var require_schema3 = __commonJS((exports2) => {
19515
19548
  var map = require_map();
19516
19549
  var _null = require_null();
@@ -19551,7 +19584,7 @@ var require_schema3 = __commonJS((exports2) => {
19551
19584
  exports2.schema = schema;
19552
19585
  });
19553
19586
 
19554
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
19587
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
19555
19588
  var require_tags = __commonJS((exports2) => {
19556
19589
  var map = require_map();
19557
19590
  var _null = require_null();
@@ -19642,7 +19675,7 @@ var require_tags = __commonJS((exports2) => {
19642
19675
  exports2.getTags = getTags;
19643
19676
  });
19644
19677
 
19645
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
19678
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
19646
19679
  var require_Schema = __commonJS((exports2) => {
19647
19680
  var identity = require_identity();
19648
19681
  var map = require_map();
@@ -19672,7 +19705,7 @@ var require_Schema = __commonJS((exports2) => {
19672
19705
  exports2.Schema = Schema;
19673
19706
  });
19674
19707
 
19675
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
19708
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
19676
19709
  var require_stringifyDocument = __commonJS((exports2) => {
19677
19710
  var identity = require_identity();
19678
19711
  var stringify = require_stringify();
@@ -19752,7 +19785,7 @@ var require_stringifyDocument = __commonJS((exports2) => {
19752
19785
  exports2.stringifyDocument = stringifyDocument;
19753
19786
  });
19754
19787
 
19755
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
19788
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
19756
19789
  var require_Document = __commonJS((exports2) => {
19757
19790
  var Alias = require_Alias();
19758
19791
  var Collection = require_Collection();
@@ -19987,7 +20020,7 @@ var require_Document = __commonJS((exports2) => {
19987
20020
  exports2.Document = Document;
19988
20021
  });
19989
20022
 
19990
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
20023
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
19991
20024
  var require_errors = __commonJS((exports2) => {
19992
20025
  class YAMLError extends Error {
19993
20026
  constructor(name, pos, code, message) {
@@ -20052,7 +20085,7 @@ ${pointer}
20052
20085
  exports2.prettifyError = prettifyError;
20053
20086
  });
20054
20087
 
20055
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
20088
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
20056
20089
  var require_resolve_props = __commonJS((exports2) => {
20057
20090
  function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
20058
20091
  let spaceBefore = false;
@@ -20182,7 +20215,7 @@ var require_resolve_props = __commonJS((exports2) => {
20182
20215
  exports2.resolveProps = resolveProps;
20183
20216
  });
20184
20217
 
20185
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
20218
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
20186
20219
  var require_util_contains_newline = __commonJS((exports2) => {
20187
20220
  function containsNewline(key) {
20188
20221
  if (!key)
@@ -20222,7 +20255,7 @@ var require_util_contains_newline = __commonJS((exports2) => {
20222
20255
  exports2.containsNewline = containsNewline;
20223
20256
  });
20224
20257
 
20225
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
20258
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
20226
20259
  var require_util_flow_indent_check = __commonJS((exports2) => {
20227
20260
  var utilContainsNewline = require_util_contains_newline();
20228
20261
  function flowIndentCheck(indent, fc, onError) {
@@ -20237,7 +20270,7 @@ var require_util_flow_indent_check = __commonJS((exports2) => {
20237
20270
  exports2.flowIndentCheck = flowIndentCheck;
20238
20271
  });
20239
20272
 
20240
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
20273
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
20241
20274
  var require_util_map_includes = __commonJS((exports2) => {
20242
20275
  var identity = require_identity();
20243
20276
  function mapIncludes(ctx, items, search) {
@@ -20250,7 +20283,7 @@ var require_util_map_includes = __commonJS((exports2) => {
20250
20283
  exports2.mapIncludes = mapIncludes;
20251
20284
  });
20252
20285
 
20253
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
20286
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
20254
20287
  var require_resolve_block_map = __commonJS((exports2) => {
20255
20288
  var Pair = require_Pair();
20256
20289
  var YAMLMap = require_YAMLMap();
@@ -20357,7 +20390,7 @@ var require_resolve_block_map = __commonJS((exports2) => {
20357
20390
  exports2.resolveBlockMap = resolveBlockMap;
20358
20391
  });
20359
20392
 
20360
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
20393
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
20361
20394
  var require_resolve_block_seq = __commonJS((exports2) => {
20362
20395
  var YAMLSeq = require_YAMLSeq();
20363
20396
  var resolveProps = require_resolve_props();
@@ -20405,7 +20438,7 @@ var require_resolve_block_seq = __commonJS((exports2) => {
20405
20438
  exports2.resolveBlockSeq = resolveBlockSeq;
20406
20439
  });
20407
20440
 
20408
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
20441
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
20409
20442
  var require_resolve_end = __commonJS((exports2) => {
20410
20443
  function resolveEnd(end, offset, reqSpace, onError) {
20411
20444
  let comment = "";
@@ -20445,7 +20478,7 @@ var require_resolve_end = __commonJS((exports2) => {
20445
20478
  exports2.resolveEnd = resolveEnd;
20446
20479
  });
20447
20480
 
20448
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
20481
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
20449
20482
  var require_resolve_flow_collection = __commonJS((exports2) => {
20450
20483
  var identity = require_identity();
20451
20484
  var Pair = require_Pair();
@@ -20636,7 +20669,7 @@ var require_resolve_flow_collection = __commonJS((exports2) => {
20636
20669
  exports2.resolveFlowCollection = resolveFlowCollection;
20637
20670
  });
20638
20671
 
20639
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
20672
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
20640
20673
  var require_compose_collection = __commonJS((exports2) => {
20641
20674
  var identity = require_identity();
20642
20675
  var Scalar = require_Scalar();
@@ -20698,7 +20731,7 @@ var require_compose_collection = __commonJS((exports2) => {
20698
20731
  exports2.composeCollection = composeCollection;
20699
20732
  });
20700
20733
 
20701
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
20734
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
20702
20735
  var require_resolve_block_scalar = __commonJS((exports2) => {
20703
20736
  var Scalar = require_Scalar();
20704
20737
  function resolveBlockScalar(ctx, scalar, onError) {
@@ -20891,7 +20924,7 @@ var require_resolve_block_scalar = __commonJS((exports2) => {
20891
20924
  exports2.resolveBlockScalar = resolveBlockScalar;
20892
20925
  });
20893
20926
 
20894
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
20927
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
20895
20928
  var require_resolve_flow_scalar = __commonJS((exports2) => {
20896
20929
  var Scalar = require_Scalar();
20897
20930
  var resolveEnd = require_resolve_end();
@@ -21107,7 +21140,7 @@ var require_resolve_flow_scalar = __commonJS((exports2) => {
21107
21140
  exports2.resolveFlowScalar = resolveFlowScalar;
21108
21141
  });
21109
21142
 
21110
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
21143
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
21111
21144
  var require_compose_scalar = __commonJS((exports2) => {
21112
21145
  var identity = require_identity();
21113
21146
  var Scalar = require_Scalar();
@@ -21185,7 +21218,7 @@ var require_compose_scalar = __commonJS((exports2) => {
21185
21218
  exports2.composeScalar = composeScalar;
21186
21219
  });
21187
21220
 
21188
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
21221
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
21189
21222
  var require_util_empty_scalar_position = __commonJS((exports2) => {
21190
21223
  function emptyScalarPosition(offset, before, pos) {
21191
21224
  if (before) {
@@ -21212,7 +21245,7 @@ var require_util_empty_scalar_position = __commonJS((exports2) => {
21212
21245
  exports2.emptyScalarPosition = emptyScalarPosition;
21213
21246
  });
21214
21247
 
21215
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
21248
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
21216
21249
  var require_compose_node = __commonJS((exports2) => {
21217
21250
  var Alias = require_Alias();
21218
21251
  var identity = require_identity();
@@ -21315,7 +21348,7 @@ var require_compose_node = __commonJS((exports2) => {
21315
21348
  exports2.composeNode = composeNode;
21316
21349
  });
21317
21350
 
21318
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
21351
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
21319
21352
  var require_compose_doc = __commonJS((exports2) => {
21320
21353
  var Document = require_Document();
21321
21354
  var composeNode = require_compose_node();
@@ -21355,7 +21388,7 @@ var require_compose_doc = __commonJS((exports2) => {
21355
21388
  exports2.composeDoc = composeDoc;
21356
21389
  });
21357
21390
 
21358
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
21391
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
21359
21392
  var require_composer2 = __commonJS((exports2) => {
21360
21393
  var node_process = __require("process");
21361
21394
  var directives = require_directives();
@@ -21544,7 +21577,7 @@ ${end.comment}` : end.comment;
21544
21577
  exports2.Composer = Composer;
21545
21578
  });
21546
21579
 
21547
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
21580
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
21548
21581
  var require_cst_scalar = __commonJS((exports2) => {
21549
21582
  var resolveBlockScalar = require_resolve_block_scalar();
21550
21583
  var resolveFlowScalar = require_resolve_flow_scalar();
@@ -21734,7 +21767,7 @@ var require_cst_scalar = __commonJS((exports2) => {
21734
21767
  exports2.setScalarValue = setScalarValue;
21735
21768
  });
21736
21769
 
21737
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
21770
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
21738
21771
  var require_cst_stringify = __commonJS((exports2) => {
21739
21772
  var stringify = (cst) => ("type" in cst) ? stringifyToken(cst) : stringifyItem(cst);
21740
21773
  function stringifyToken(token) {
@@ -21792,7 +21825,7 @@ var require_cst_stringify = __commonJS((exports2) => {
21792
21825
  exports2.stringify = stringify;
21793
21826
  });
21794
21827
 
21795
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
21828
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
21796
21829
  var require_cst_visit = __commonJS((exports2) => {
21797
21830
  var BREAK = Symbol("break visit");
21798
21831
  var SKIP = Symbol("skip children");
@@ -21851,7 +21884,7 @@ var require_cst_visit = __commonJS((exports2) => {
21851
21884
  exports2.visit = visit;
21852
21885
  });
21853
21886
 
21854
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
21887
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
21855
21888
  var require_cst = __commonJS((exports2) => {
21856
21889
  var cstScalar = require_cst_scalar();
21857
21890
  var cstStringify = require_cst_stringify();
@@ -21952,7 +21985,7 @@ var require_cst = __commonJS((exports2) => {
21952
21985
  exports2.tokenType = tokenType;
21953
21986
  });
21954
21987
 
21955
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
21988
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
21956
21989
  var require_lexer = __commonJS((exports2) => {
21957
21990
  var cst = require_cst();
21958
21991
  function isEmpty2(ch) {
@@ -22538,7 +22571,7 @@ var require_lexer = __commonJS((exports2) => {
22538
22571
  exports2.Lexer = Lexer;
22539
22572
  });
22540
22573
 
22541
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
22574
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
22542
22575
  var require_line_counter = __commonJS((exports2) => {
22543
22576
  class LineCounter {
22544
22577
  constructor() {
@@ -22566,7 +22599,7 @@ var require_line_counter = __commonJS((exports2) => {
22566
22599
  exports2.LineCounter = LineCounter;
22567
22600
  });
22568
22601
 
22569
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
22602
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
22570
22603
  var require_parser = __commonJS((exports2) => {
22571
22604
  var node_process = __require("process");
22572
22605
  var cst = require_cst();
@@ -23415,7 +23448,7 @@ var require_parser = __commonJS((exports2) => {
23415
23448
  exports2.Parser = Parser;
23416
23449
  });
23417
23450
 
23418
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
23451
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
23419
23452
  var require_public_api = __commonJS((exports2) => {
23420
23453
  var composer = require_composer2();
23421
23454
  var Document = require_Document();
@@ -23509,7 +23542,7 @@ var require_public_api = __commonJS((exports2) => {
23509
23542
  exports2.stringify = stringify;
23510
23543
  });
23511
23544
 
23512
- // ../node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
23545
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
23513
23546
  var composer, Document, Schema, errors2, Alias, identity, Pair, Scalar, YAMLMap, YAMLSeq, cst, lexer, lineCounter, parser, publicApi, visit, $Composer, $Document, $Schema, $YAMLError, $YAMLParseError, $YAMLWarning, $Alias, $isAlias, $isCollection, $isDocument, $isMap, $isNode, $isPair, $isScalar, $isSeq, $Pair, $Scalar, $YAMLMap, $YAMLSeq, $Lexer, $LineCounter, $Parser, $parse, $parseAllDocuments, $parseDocument, $stringify, $visit, $visitAsync;
23514
23547
  var init_dist = __esm(() => {
23515
23548
  composer = require_composer2();
@@ -23559,7 +23592,7 @@ var init_dist = __esm(() => {
23559
23592
  });
23560
23593
 
23561
23594
  // ../src/config/schema.ts
23562
- var CodeRepoEntrySchema, AgentBindMountSchema, ScheduleEntrySchema, AgentSoulSchema, AgentToolsSchema, AgentMemorySchema, HookEntrySchema, AgentHooksSchema, SubagentSchema, SessionSchema, SessionContinuitySchema, TelegramChannelSchema, ChannelsSchema, TIMEZONE_REGEX, ApproverIdSchema, GoogleWorkspaceTierSchema, GoogleWorkspaceConfigSchema, AgentGoogleWorkspaceConfigSchema, ReactionsSchema, profileFields, ProfileSchema, _omitExtends, defaultsFields, AgentDefaultsSchema, AgentSchema, TelegramConfigSchema, MemoryBackendConfigSchema, VaultConfigSchema, QuotaConfigSchema, HostControlConfigSchema, SwitchroomConfigSchema;
23595
+ var CodeRepoEntrySchema, AgentBindMountSchema, ScheduleEntrySchema, AgentSoulSchema, AgentToolsSchema, AgentMemorySchema, HookEntrySchema, AgentHooksSchema, SubagentSchema, SessionSchema, SessionContinuitySchema, TelegramChannelSchema, ChannelsSchema, TIMEZONE_REGEX, ApproverIdSchema, GoogleWorkspaceTierSchema, GoogleWorkspaceConfigSchema, AgentGoogleWorkspaceConfigSchema, ReactionsSchema, ReleaseBlock, NetworkIsolationSchema, profileFields, ProfileSchema, _omitExtends, defaultsFields, AgentDefaultsSchema, AgentSchema, TelegramConfigSchema, MemoryBackendConfigSchema, VaultConfigSchema, QuotaConfigSchema, HostControlConfigSchema, SwitchroomConfigSchema;
23563
23596
  var init_schema = __esm(() => {
23564
23597
  init_zod();
23565
23598
  CodeRepoEntrySchema = exports_external.object({
@@ -23575,7 +23608,7 @@ var init_schema = __esm(() => {
23575
23608
  ScheduleEntrySchema = exports_external.object({
23576
23609
  cron: exports_external.string().describe("Cron expression (e.g., '0 8 * * *')"),
23577
23610
  prompt: exports_external.string().describe("Prompt to send at the scheduled time"),
23578
- model: exports_external.string().optional().describe("Model for this task. Defaults to claude-sonnet-4-6 (cheap, fast). " + "Use claude-opus-4-7 for tasks needing complex reasoning."),
23611
+ model: exports_external.string().optional().describe("DEPRECATED / IGNORED. Pre-v0.8 the singleton scheduler ran each " + "task as an isolated `claude -p` and could set --model per task. " + "Post cron-fold-in (v0.8) the fire is injected into the agent's " + "running session, so it always uses the agent's configured model " + "\u2014 this field has no effect. Accepted (optional) only so existing " + "configs keep validating; set the model at the agent level instead. " + "See docs/scheduling.md."),
23579
23612
  secrets: exports_external.array(exports_external.string().regex(/^[a-zA-Z0-9_\-/]+$/, "Secret key names must contain only alphanumeric characters, underscores, hyphens, and forward slashes")).default([]).describe("Vault key names this cron task may read via the vault-broker daemon. " + "Empty by default \u2014 broker requests for unlisted keys are denied. " + "Note: this is misconfiguration protection (a typo in cron-A doesn't " + "accidentally read cron-B's keys) rather than a security boundary \u2014 " + "anyone who can edit cron scripts can also edit switchroom.yaml, and " + "anyone with the vault passphrase can read the vault file directly. " + "See docs/configuration.md for the full framing.")
23580
23613
  });
23581
23614
  AgentSoulSchema = exports_external.object({
@@ -23642,6 +23675,7 @@ var init_schema = __esm(() => {
23642
23675
  resume_max_bytes: exports_external.number().int().positive().optional().describe("Byte threshold above which 'auto' mode falls back to handoff " + "instead of --continue. Default 2_000_000 (~2MB). Large transcripts " + "can blow out the context window even with prefix caching, and " + "--continue replay is known-fragile at scale.")
23643
23676
  }).optional();
23644
23677
  TelegramChannelSchema = exports_external.object({
23678
+ enabled: exports_external.boolean().default(true).describe("Master switch for the per-agent Telegram gateway sidecar. " + "When false, start.sh skips the gateway supervise loop and the " + "agent boots without bot-token requirements (smoke-test + " + "offline-dev use case)."),
23645
23679
  plugin: exports_external.enum(["switchroom", "official"]).optional().describe("Which Telegram MCP plugin to load. Default is 'switchroom' \u2014 the " + "enhanced fork with streaming edits, reactions, history, and " + "access control. Set to 'official' for the upstream marketplace " + "plugin (basic send/receive only)."),
23646
23680
  format: exports_external.enum(["html", "markdownv2", "text"]).optional().describe("Default reply format passed to the plugin"),
23647
23681
  rate_limit_ms: exports_external.number().optional().describe("Minimum delay between outgoing messages in ms"),
@@ -23706,6 +23740,9 @@ var init_schema = __esm(() => {
23706
23740
  tier: GoogleWorkspaceTierSchema.optional().describe("RFC G Phase 1: which upstream MCP tier to expose. " + "core (default) = ~16 tools (Drive+Docs+Sheets+Calendar). " + "extended = ~40 tools (+Slides, Forms, Tasks, Chat). " + "complete = ~60+ tools (+Gmail; not recommended yet \u2014 see RFC G \u00a75).")
23707
23741
  }).optional();
23708
23742
  AgentGoogleWorkspaceConfigSchema = exports_external.object({
23743
+ account: exports_external.string().regex(/^[^@\s:]+@[^@\s:]+\.[^@\s:]+$/, {
23744
+ message: "google_workspace.account must be a Google account email like " + "'alice@example.com' (colons not allowed)"
23745
+ }).transform((v) => v.trim().toLowerCase()).optional().describe("RFC G: the Google account this agent uses for the Workspace MCP. " + "Must be a key in top-level `google_accounts:` with this agent " + "listed in its `enabled_for[]`. Read by the auth-broker " + "(get-credentials, provider=google) and by the scaffold to decide " + "whether to emit the `gdrive` MCP entry. Normalized to lowercase " + "so it matches the google_accounts key (which is also normalized)."),
23709
23746
  approvers: exports_external.array(ApproverIdSchema).min(1).optional().describe("Per-agent approver override. When set, replaces (does not extend) " + "the top-level drive.approvers list for this agent's onboarding card."),
23710
23747
  tier: GoogleWorkspaceTierSchema.optional().describe("Per-agent tier override (RFC G Phase 1). When set, replaces the " + "top-level google_workspace.tier for this agent. Common case: most " + "agents on `core`, one specialist on `extended` for Slides access.")
23711
23748
  }).optional();
@@ -23716,9 +23753,17 @@ var init_schema = __esm(() => {
23716
23753
  per_hour_cap: exports_external.number().int().nonnegative().optional().describe("Max reaction-triggered synthetic turns per chat per rolling hour. " + "Refusals are stderr-logged but not surfaced to the agent. " + "Default 10. Set to 0 to disable triggering via the cap path."),
23717
23754
  group_admin_only: exports_external.boolean().optional().describe("In groups/supergroups (negative chat_id), only trigger a synthetic " + "turn when the reacter is a chat admin (creator or administrator). " + "Failing the lookup is treated as non-admin (fail-closed). " + "DMs are never affected by this flag \u2014 the reacter IS the user. " + "Default true.")
23718
23755
  }).optional();
23756
+ ReleaseBlock = exports_external.object({
23757
+ channel: exports_external.enum(["dev", "rc", "latest"]).optional(),
23758
+ pin: exports_external.string().regex(/^(sha-[0-9a-f]{7,40}|v\d+\.\d+\.\d+)$/).optional()
23759
+ }).strict().refine((r) => !(r.channel && r.pin), {
23760
+ message: "release.channel and release.pin are mutually exclusive"
23761
+ });
23762
+ NetworkIsolationSchema = exports_external.enum(["host", "strict"]).optional().describe("Container network mode (sec WS6-F1 #1390 / feature #1413). " + "'host' (DEFAULT when unset): `network_mode: host` \u2014 the agent " + "shares the host network stack; hindsight 127.0.0.1:18888 and " + "operator-LAN devices are reachable, but there is NO network " + "isolation from sibling agents or host services (the documented, " + "deliberate shared-host tradeoff). 'strict': the agent joins its " + "OWN dedicated docker bridge network instead \u2014 it cannot reach " + "sibling agents; host services are reached via " + "`host.docker.internal`. OPT-IN: validate hindsight / operator-" + "LAN / cron / boot-self-test paths for your deployment before " + "adopting fleet-wide (default-flip is deferred to that validation " + "cycle, #1413). Cascades override (agent \u2192 profile \u2192 defaults).");
23719
23763
  profileFields = {
23720
23764
  extends: exports_external.string().optional(),
23721
23765
  bot_token: exports_external.string().optional(),
23766
+ release: ReleaseBlock.optional().describe("Release-channel pin / pointer. Either `channel` (dev|rc|latest) or " + "`pin` (sha-<hex>|v<semver>) \u2014 mutually exclusive. Per-agent value " + "REPLACES the root entirely (no field merge)."),
23722
23767
  timezone: exports_external.string().regex(TIMEZONE_REGEX, "timezone must be an IANA zone name like 'Australia/Melbourne' or 'UTC' " + "(three-letter aliases like EST/PST and bare offsets like UTC+10 are not accepted)").optional().describe("IANA timezone name (e.g. 'Australia/Melbourne', 'America/New_York', " + "'UTC'). Used to generate the per-turn local-time hint the agent's " + "UserPromptSubmit timezone hook emits, and baked into the systemd " + "unit as TZ= so subprocess `date`/`Date.now()` are correct. If unset " + "at every cascade layer, switchroom auto-detects from /etc/timezone " + "and warns on `reconcile` when the detected zone is UTC."),
23723
23768
  soul: exports_external.object({
23724
23769
  name: exports_external.string().optional(),
@@ -23755,8 +23800,8 @@ var init_schema = __esm(() => {
23755
23800
  session: SessionSchema,
23756
23801
  session_continuity: SessionContinuitySchema,
23757
23802
  channels: ChannelsSchema,
23803
+ network_isolation: NetworkIsolationSchema,
23758
23804
  dangerous_mode: exports_external.boolean().optional(),
23759
- skip_permission_prompt: exports_external.boolean().optional(),
23760
23805
  settings_raw: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
23761
23806
  claude_md_raw: exports_external.string().optional(),
23762
23807
  cli_args: exports_external.array(exports_external.string()).optional(),
@@ -23778,6 +23823,7 @@ var init_schema = __esm(() => {
23778
23823
  AgentSchema = exports_external.object({
23779
23824
  extends: exports_external.string().optional().describe("Name of a profile to inherit from (e.g., 'coding', 'health-coach'). " + "Profiles may be defined inline under switchroom.yaml `profiles:` or as a " + "filesystem directory `profiles/<name>/`. Defaults to DEFAULT_PROFILE " + "('default') when unset."),
23780
23825
  bot_token: exports_external.string().optional().describe("Per-agent Telegram bot token or vault reference (overrides global telegram.bot_token)"),
23826
+ release: ReleaseBlock.optional().describe("Per-agent release-channel pin / pointer. REPLACES the root " + "`release` block entirely (no field merge) \u2014 a pinned agent does " + "not inherit the fleet channel, and vice versa."),
23781
23827
  bot_username: exports_external.string().optional().describe("Per-agent Telegram bot username (without leading @) when it doesn't " + "contain the agent slug. Replaces the default 'username includes slug' " + "preflight check with an exact (case-insensitive) match. Use when an " + "agent and its bot have intentionally divergent names (e.g. agent " + "'lawgpt' paired with bot '@meken_law_bot')."),
23782
23828
  timezone: exports_external.string().regex(TIMEZONE_REGEX, "timezone must be an IANA zone name like 'Australia/Melbourne' or 'UTC' " + "(three-letter aliases like EST/PST and bare offsets like UTC+10 are not accepted)").optional().describe("Per-agent IANA timezone override. Wins over any profile/defaults " + "value and over the top-level switchroom.timezone global. Controls " + "the UserPromptSubmit timezone hook's emitted local time and the " + "systemd unit's TZ= env."),
23783
23829
  auth: exports_external.object({
@@ -23822,7 +23868,7 @@ var init_schema = __esm(() => {
23822
23868
  session_continuity: SessionContinuitySchema.describe("Handoff-briefing settings. When enabled (default), a Stop hook " + "summarizes each session at shutdown and start.sh injects that " + "briefing into the next session via --append-system-prompt."),
23823
23869
  channels: ChannelsSchema.describe("Per-channel configuration. Today only `telegram` is defined; the " + "shape is designed to expand to other channels (Slack, Discord, " + "Matrix, Email) as they're added."),
23824
23870
  dangerous_mode: exports_external.boolean().optional().describe("If true, include --dangerously-skip-permissions in start.sh"),
23825
- skip_permission_prompt: exports_external.boolean().optional().describe("DEPRECATED no-op (accepted for backwards compatibility). Claude Code " + "ignores skipDangerousModePermissionPrompt at project scope; autoaccept " + "(src/agents/autoaccept.ts) handles the bypass-mode prompt instead. " + "Safe to remove from switchroom.yaml."),
23871
+ network_isolation: NetworkIsolationSchema,
23826
23872
  admin: exports_external.boolean().optional().describe("If true, the agent's Telegram gateway intercepts admin slash commands " + "(/agents, /logs, /restart, /delete, /update, /auth, /reconcile, etc.) " + "locally before forwarding to Claude. Commands are handled silently \u2014 " + "Claude never sees them. Requires the agent to use the switchroom-telegram " + "plugin. When false or absent, all messages pass through to Claude unchanged."),
23827
23873
  settings_raw: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Escape hatch: raw object deep-merged into the generated " + "settings.json as the final step. Use for Claude Code settings " + "keys switchroom doesn't wrap directly (e.g. effort, apiKeyHelper). " + "Power-user-only \u2014 prefer the typed fields when they exist."),
23828
23874
  claude_md_raw: exports_external.string().optional().describe("Escape hatch: markdown text appended verbatim to CLAUDE.md on " + "initial scaffold. Not re-applied on reconcile (CLAUDE.md is " + "user-protected). Use for one-off persona tuning that isn't " + "worth a template."),
@@ -23889,7 +23935,7 @@ var init_schema = __esm(() => {
23889
23935
  monthly_budget_usd: exports_external.number().positive().optional().describe("Monthly USD spend budget. If unset, the greeting shows raw usage only.")
23890
23936
  });
23891
23937
  HostControlConfigSchema = exports_external.object({
23892
- enabled: exports_external.boolean().optional().describe("Opt-in to the host-control daemon. Default: false. " + "When true, the compose generator emits per-agent bind mounts " + "at `~/.switchroom/hostd/<name>/sock` for every admin-flagged " + "agent. Install the daemon with `switchroom hostd install` \u2014 " + "it runs as a docker container in its own compose project " + "(`switchroom-hostd`), separate from the agent fleet's compose " + "project so `up -d --remove-orphans` cycles of the fleet " + "can't recreate the daemon mid-RPC. See RFC C \u00a75.1. " + "Since Phase 2 (#1175 PR \u03b3) the gateway's /restart, /new, /reset, " + "and /update apply slash-commands automatically dispatch through " + "hostd when enabled \u2014 replacing the in-container " + "`spawnSwitchroomDetached` shellout that requires docker access. " + "Set enabled: true on docker-mode installs to make those verbs work " + "(they otherwise fail because the agent container has no docker " + "binary/socket).")
23938
+ enabled: exports_external.boolean().default(true).describe("Whether the host-control daemon is in use. Default: true (since " + "RFC C Phase 2 default-flip \u2014 the gateway's /restart, /new, /reset, " + "and /update apply slash-commands all dispatch through hostd, and " + "without it those verbs fail on docker-mode installs because the " + "agent container has no docker binary/socket). " + "When true, the compose generator emits per-agent bind mounts " + "at `~/.switchroom/hostd/<name>/sock` for every admin-flagged " + "agent. Install the daemon with `switchroom hostd install` \u2014 " + "it runs as a docker container in its own compose project " + "(`switchroom-hostd`), separate from the agent fleet's compose " + "project so `up -d --remove-orphans` cycles of the fleet " + "can't recreate the daemon mid-RPC. See RFC C \u00a75.1. " + "Set enabled: false only on legacy systemd-mode installs that " + "still rely on the in-container `spawnSwitchroomDetached` " + "shellout (removal is tracked as RFC C Phase 3).")
23893
23939
  });
23894
23940
  SwitchroomConfigSchema = exports_external.object({
23895
23941
  switchroom: exports_external.object({
@@ -23899,6 +23945,7 @@ var init_schema = __esm(() => {
23899
23945
  timezone: exports_external.string().regex(TIMEZONE_REGEX, "timezone must be an IANA zone name like 'Australia/Melbourne' or 'UTC'").optional().describe("Global default IANA timezone applied to every agent unless the " + "agent (or its profile) declares its own. See the per-agent " + "timezone field for the full cascade and auto-detection fallback.")
23900
23946
  }),
23901
23947
  telegram: TelegramConfigSchema,
23948
+ release: ReleaseBlock.optional().describe("Fleet-wide default release-channel pin / pointer for the update " + "flow. Either `channel` (dev|rc|latest) or `pin` (sha-<hex>|v<semver>) " + "\u2014 mutually exclusive. Per-agent `release` REPLACES this entirely."),
23902
23949
  memory: MemoryBackendConfigSchema.optional(),
23903
23950
  vault: VaultConfigSchema.optional(),
23904
23951
  auth: exports_external.object({
@@ -23915,7 +23962,7 @@ var init_schema = __esm(() => {
23915
23962
  drive: GoogleWorkspaceConfigSchema.describe("RFC D legacy key \u2014 use `google_workspace:` instead. Optional Google " + "Workspace onboarding configuration. When set, supplies Google OAuth " + "client credentials, the approver allowlist for `switchroom drive " + "connect`, and the optional tier knob. Env vars " + "(SWITCHROOM_GOOGLE_CLIENT_ID, SWITCHROOM_GOOGLE_CLIENT_SECRET, " + "SWITCHROOM_APPROVER_USER_ID) take precedence over this block when " + "set, preserving back-compat with the env-only flow shipped in #766."),
23916
23963
  google_workspace: GoogleWorkspaceConfigSchema.describe("RFC G canonical key. Top-level Google Workspace configuration \u2014 " + "OAuth client credentials, approver allowlist, and tier knob (`core` " + "| `extended` | `complete`, default `core`). Mutually exclusive with " + "`drive:` at the top level (loader fails fast if both are set)."),
23917
23964
  quota: QuotaConfigSchema.optional().describe("Optional weekly/monthly USD spend budgets rendered in the session " + "greeting. Usage is read from ccusage at runtime; no network calls."),
23918
- host_control: HostControlConfigSchema.optional().describe("Optional host-control daemon configuration. See RFC C " + "(docs/rfcs/host-control-daemon.md) and the field-level help on " + "`enabled` for the Phase 1 scope."),
23965
+ host_control: HostControlConfigSchema.default({}).describe("Host-control daemon configuration. Defaults to enabled=true since " + "RFC C Phase 2 (docs/rfcs/host-control-daemon.md). Omit the block " + "to accept defaults; set `enabled: false` only on legacy systemd-" + "mode installs (removal tracked as RFC C Phase 3)."),
23919
23966
  google_accounts: exports_external.record(exports_external.string().regex(/^[^@\s:]+@[^@\s:]+\.[^@\s:]+$/, {
23920
23967
  message: "Account key must be a Google account email like 'alice@example.com' (colons not allowed)"
23921
23968
  }).transform((v) => v.trim().toLowerCase()), exports_external.object({
@@ -23937,6 +23984,13 @@ import { resolve as resolve2 } from "node:path";
23937
23984
  function home() {
23938
23985
  return process.env.HOME ?? "/root";
23939
23986
  }
23987
+ function warnLegacyStateOnce(legacy) {
23988
+ if (_legacyStateWarned)
23989
+ return;
23990
+ _legacyStateWarned = true;
23991
+ process.stderr.write(`[switchroom] DEPRECATED: reading legacy state from ${legacy}. ` + "Run `mv ~/.clerk ~/.switchroom` (and rename any top-level `clerk:` " + "key in switchroom.yaml to `switchroom:`). This back-compat shim is " + `REMOVED in v0.13.0 \u2014 no automatic migration exists.
23992
+ `);
23993
+ }
23940
23994
  function resolveDualPath(pathStr) {
23941
23995
  const h = home();
23942
23996
  if (pathStr.startsWith("~/")) {
@@ -23946,15 +24000,17 @@ function resolveDualPath(pathStr) {
23946
24000
  const frag = rest.slice(DEFAULT_STATE_DIR.length + 1);
23947
24001
  if (!existsSync7(absolute)) {
23948
24002
  const legacy = resolve2(h, LEGACY_STATE_DIR, frag);
23949
- if (existsSync7(legacy))
24003
+ if (existsSync7(legacy)) {
24004
+ warnLegacyStateOnce(legacy);
23950
24005
  return legacy;
24006
+ }
23951
24007
  }
23952
24008
  }
23953
24009
  return absolute;
23954
24010
  }
23955
24011
  return resolve2(pathStr);
23956
24012
  }
23957
- var DEFAULT_STATE_DIR = ".switchroom", LEGACY_STATE_DIR = ".clerk";
24013
+ var DEFAULT_STATE_DIR = ".switchroom", LEGACY_STATE_DIR = ".clerk", _legacyStateWarned = false;
23958
24014
  var init_paths = () => {};
23959
24015
 
23960
24016
  // ../src/config/overlay-schema.ts
@@ -24589,11 +24645,8 @@ function formatResetRelative(target, now = new Date) {
24589
24645
  const remH = hours % 24;
24590
24646
  return remH > 0 ? `resets in ${days}d ${remH}h` : `resets in ${days}d`;
24591
24647
  }
24592
- var OAUTH_BETA = "oauth-2025-04-20", DEFAULT_USER_AGENT = "claude-cli/1.0.0 (external, cli)", DEFAULT_PROBE_MODEL = "claude-haiku-4-5-20251001", ACCOUNT_QUOTA_CACHE_TTL_MS, accountQuotaCache;
24593
- var init_quota_check = __esm(() => {
24594
- ACCOUNT_QUOTA_CACHE_TTL_MS = 5 * 60000;
24595
- accountQuotaCache = new Map;
24596
- });
24648
+ var OAUTH_BETA = "oauth-2025-04-20", DEFAULT_USER_AGENT = "claude-cli/1.0.0 (external, cli)", DEFAULT_PROBE_MODEL = "claude-haiku-4-5-20251001";
24649
+ var init_quota_check = () => {};
24597
24650
 
24598
24651
  // ../src/vault/broker/protocol.ts
24599
24652
  function encodeRequest2(req) {
@@ -24691,7 +24744,7 @@ var init_protocol2 = __esm(() => {
24691
24744
  ApprovalConsumeRequestSchema = exports_external.object({
24692
24745
  v: exports_external.literal(1),
24693
24746
  op: exports_external.literal("approval_consume"),
24694
- request_id: exports_external.string().regex(/^[0-9a-f]{8}$/)
24747
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/)
24695
24748
  });
24696
24749
  ApprovalRevokeRequestSchema = exports_external.object({
24697
24750
  v: exports_external.literal(1),
@@ -24715,7 +24768,7 @@ var init_protocol2 = __esm(() => {
24715
24768
  ApprovalRecordRequestSchema = exports_external.object({
24716
24769
  v: exports_external.literal(1),
24717
24770
  op: exports_external.literal("approval_record"),
24718
- request_id: exports_external.string().regex(/^[0-9a-f]{8}$/),
24771
+ request_id: exports_external.string().regex(/^[0-9a-f]{32}$/),
24719
24772
  decision: ApprovalDecisionModeSchema,
24720
24773
  approver_set: exports_external.array(exports_external.string()),
24721
24774
  granted_by_user_id: exports_external.number().int(),
@@ -24901,17 +24954,16 @@ function isDockerRuntime() {
24901
24954
  import * as net3 from "node:net";
24902
24955
  import * as fs from "node:fs";
24903
24956
  import { homedir as homedir7 } from "node:os";
24904
- import { join as join17 } from "node:path";
24957
+ import { join as join16 } from "node:path";
24905
24958
  function defaultBrokerSocketPath() {
24906
- if (isDockerRuntime()) {
24907
- if (fs.existsSync(OPERATOR_SOCKET_PATH))
24908
- return OPERATOR_SOCKET_PATH;
24959
+ if (fs.existsSync(OPERATOR_SOCKET_PATH))
24960
+ return OPERATOR_SOCKET_PATH;
24961
+ if (isDockerRuntime())
24909
24962
  return OPERATOR_SOCKET_PATH;
24910
- }
24911
24963
  return LEGACY_SOCKET_PATH;
24912
24964
  }
24913
24965
  function vaultTokenFilePath(agentSlug) {
24914
- return join17(homedir7(), ".switchroom", "agents", agentSlug, ".vault-token");
24966
+ return join16(homedir7(), ".switchroom", "agents", agentSlug, ".vault-token");
24915
24967
  }
24916
24968
  function readVaultTokenFile(agentSlug) {
24917
24969
  const filePath = vaultTokenFilePath(agentSlug);
@@ -25038,8 +25090,8 @@ var DEFAULT_TIMEOUT_MS3 = 2000, LEGACY_SOCKET_PATH, OPERATOR_SOCKET_PATH;
25038
25090
  var init_client2 = __esm(() => {
25039
25091
  init_protocol2();
25040
25092
  init_peercred();
25041
- LEGACY_SOCKET_PATH = join17(homedir7(), ".switchroom", "vault-broker.sock");
25042
- OPERATOR_SOCKET_PATH = join17(homedir7(), ".switchroom", "broker-operator", "sock");
25093
+ LEGACY_SOCKET_PATH = join16(homedir7(), ".switchroom", "vault-broker.sock");
25094
+ OPERATOR_SOCKET_PATH = join16(homedir7(), ".switchroom", "broker-operator", "sock");
25043
25095
  });
25044
25096
 
25045
25097
  // ../src/drive/deep-links.ts
@@ -25189,7 +25241,7 @@ function deriveSlug(inputs, existing) {
25189
25241
  return `${base}_${n}`;
25190
25242
  }
25191
25243
 
25192
- // ../node_modules/.bun/boundary@2.0.0/node_modules/boundary/lib/index.js
25244
+ // ../../switchroom/node_modules/.bun/boundary@2.0.0/node_modules/boundary/lib/index.js
25193
25245
  var require_lib = __commonJS((exports2) => {
25194
25246
  Object.defineProperty(exports2, "__esModule", { value: true });
25195
25247
  exports2.binarySearch = exports2.upperBound = exports2.lowerBound = exports2.compare = undefined;
@@ -25236,7 +25288,7 @@ var require_lib = __commonJS((exports2) => {
25236
25288
  exports2.binarySearch = binarySearch;
25237
25289
  });
25238
25290
 
25239
- // ../node_modules/.bun/structured-source@4.0.0/node_modules/structured-source/lib/structured-source.js
25291
+ // ../../switchroom/node_modules/.bun/structured-source@4.0.0/node_modules/structured-source/lib/structured-source.js
25240
25292
  var require_structured_source = __commonJS((exports2) => {
25241
25293
  Object.defineProperty(exports2, "__esModule", { value: true });
25242
25294
  exports2.StructuredSource = undefined;
@@ -25291,13 +25343,13 @@ var require_structured_source = __commonJS((exports2) => {
25291
25343
  }
25292
25344
  exports2.StructuredSource = StructuredSource;
25293
25345
  });
25294
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/SecretLintSourceCodeImpl.js
25346
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/SecretLintSourceCodeImpl.js
25295
25347
  var import_structured_source;
25296
25348
  var init_SecretLintSourceCodeImpl = __esm(() => {
25297
25349
  import_structured_source = __toESM(require_structured_source(), 1);
25298
25350
  });
25299
25351
 
25300
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/helper/promise-event-emitter.js
25352
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/helper/promise-event-emitter.js
25301
25353
  class EventEmitter {
25302
25354
  #listeners = new Map;
25303
25355
  on(type, listener) {
@@ -25336,9 +25388,9 @@ class EventEmitter {
25336
25388
  return Array.from(this.#listeners.get(type) ?? []);
25337
25389
  }
25338
25390
  }
25339
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RuleContext.js
25391
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RuleContext.js
25340
25392
  var init_RuleContext = () => {};
25341
- // ../node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/index.js
25393
+ // ../../switchroom/node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/index.js
25342
25394
  class SecretLintProfiler {
25343
25395
  perf;
25344
25396
  entries = [];
@@ -25395,7 +25447,7 @@ class SecretLintProfiler {
25395
25447
  }
25396
25448
  }
25397
25449
 
25398
- // ../node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/node.js
25450
+ // ../../switchroom/node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/node.js
25399
25451
  import perf_hooks from "node:perf_hooks";
25400
25452
 
25401
25453
  class NullPerformanceObserver {
@@ -25410,19 +25462,19 @@ var init_node = __esm(() => {
25410
25462
  });
25411
25463
  });
25412
25464
 
25413
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RunningEvents.js
25465
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RunningEvents.js
25414
25466
  var init_RunningEvents = __esm(() => {
25415
25467
  init_node();
25416
25468
  });
25417
25469
 
25418
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RulePresetContext.js
25470
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RulePresetContext.js
25419
25471
  var init_RulePresetContext = __esm(() => {
25420
25472
  init_RuleContext();
25421
25473
  });
25422
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/messages/index.js
25474
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/messages/index.js
25423
25475
  var init_messages = () => {};
25424
25476
 
25425
- // ../node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/index.js
25477
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/index.js
25426
25478
  var import_debug, debug;
25427
25479
  var init_module = __esm(() => {
25428
25480
  init_SecretLintSourceCodeImpl();
@@ -25435,7 +25487,7 @@ var init_module = __esm(() => {
25435
25487
  debug = import_debug.default("@secretlint/core");
25436
25488
  });
25437
25489
 
25438
- // ../node_modules/.bun/@secretlint+secretlint-rule-preset-recommend@12.2.0/node_modules/@secretlint/secretlint-rule-preset-recommend/module/index.js
25490
+ // ../../switchroom/node_modules/.bun/@secretlint+secretlint-rule-preset-recommend@12.2.0/node_modules/@secretlint/secretlint-rule-preset-recommend/module/index.js
25439
25491
  function requireLodash_uniq() {
25440
25492
  if (hasRequiredLodash_uniq)
25441
25493
  return lodash_uniq;
@@ -27677,35 +27729,45 @@ async function probeGateway(info) {
27677
27729
  return { status: "ok", label: "Gateway", detail: parts.join(" \u00b7 ") };
27678
27730
  })());
27679
27731
  }
27680
- async function probeQuota(claudeConfigDir, _agentDir, fetchImpl = fetch) {
27732
+ async function probeQuota(claudeConfigDir, _agentDir, fetchImpl = fetch, opts = {}) {
27681
27733
  return withTimeout("Quota", (async () => {
27682
27734
  const cached = readQuotaCache();
27683
27735
  if (cached) {
27684
27736
  return cached;
27685
27737
  }
27686
- let claudeDirForProbe = null;
27687
- for (const candidate of [
27688
- claudeConfigDir,
27689
- join21(claudeConfigDir, "accounts", "default")
27690
- ]) {
27691
- if (existsSync23(join21(candidate, ".oauth-token"))) {
27692
- claudeDirForProbe = candidate;
27693
- break;
27738
+ let probe = null;
27739
+ if (opts.brokerProbe) {
27740
+ try {
27741
+ probe = await opts.brokerProbe(QUOTA_BROKER_TIMEOUT_MS);
27742
+ } catch {
27743
+ probe = null;
27694
27744
  }
27695
27745
  }
27696
- if (!claudeDirForProbe) {
27697
- return {
27698
- status: "degraded",
27699
- label: "Quota",
27700
- detail: "no OAuth token",
27701
- nextStep: "No OAuth token on disk \u2014 register a fleet account: `switchroom auth add <label> --from-oauth` then `switchroom auth use <label>` (RFC H)"
27702
- };
27746
+ if (!probe) {
27747
+ let claudeDirForProbe = null;
27748
+ for (const candidate of [
27749
+ claudeConfigDir,
27750
+ join21(claudeConfigDir, "accounts", "default")
27751
+ ]) {
27752
+ if (existsSync23(join21(candidate, ".oauth-token"))) {
27753
+ claudeDirForProbe = candidate;
27754
+ break;
27755
+ }
27756
+ }
27757
+ if (!claudeDirForProbe) {
27758
+ return {
27759
+ status: "degraded",
27760
+ label: "Quota",
27761
+ detail: "no OAuth token",
27762
+ nextStep: "No OAuth token on disk \u2014 register a fleet account: `switchroom auth add <label> --from-oauth` then `switchroom auth use <label>` (RFC H)"
27763
+ };
27764
+ }
27765
+ probe = await fetchQuota({
27766
+ claudeConfigDir: claudeDirForProbe,
27767
+ fetchImpl,
27768
+ timeoutMs: QUOTA_DIRECT_FALLBACK_TIMEOUT_MS
27769
+ });
27703
27770
  }
27704
- const probe = await fetchQuota({
27705
- claudeConfigDir: claudeDirForProbe,
27706
- fetchImpl,
27707
- timeoutMs: 1800
27708
- });
27709
27771
  if (!probe.ok) {
27710
27772
  const isAuth = /auth rejected|HTTP 401|HTTP 403/i.test(probe.reason);
27711
27773
  return {
@@ -27722,7 +27784,7 @@ async function probeQuota(claudeConfigDir, _agentDir, fetchImpl = fetch) {
27722
27784
  };
27723
27785
  writeQuotaCache(result);
27724
27786
  return result;
27725
- })());
27787
+ })(), QUOTA_PROBE_OUTER_TIMEOUT_MS);
27726
27788
  }
27727
27789
  async function probeHindsight(bankName, fetchImpl = fetch) {
27728
27790
  return withTimeout("Hindsight", (async () => {
@@ -27743,7 +27805,7 @@ async function probeHindsight(bankName, fetchImpl = fetch) {
27743
27805
  status: "fail",
27744
27806
  label: "Hindsight",
27745
27807
  detail: "unreachable",
27746
- nextStep: "Hindsight server not responding on 127.0.0.1:18888 \u2014 start it with `hindsight serve` or check `systemctl --user status hindsight`"
27808
+ nextStep: process.env.SWITCHROOM_RUNTIME === "docker" ? "Hindsight server not responding on 127.0.0.1:18888 \u2014 check the hindsight container (`docker ps` / `docker logs`); it must be reachable on the host network." : "Hindsight server not responding on 127.0.0.1:18888 \u2014 start it with `hindsight serve` (or check `systemctl --user status hindsight`)."
27747
27809
  };
27748
27810
  }
27749
27811
  const bankSuffix = bankName ? ` \u00b7 bank=${bankName}` : "";
@@ -27961,7 +28023,7 @@ async function probeSkills(agentDir, opts = {}) {
27961
28023
  };
27962
28024
  })());
27963
28025
  }
27964
- var execFile3, PROBE_TIMEOUT_MS = 2000, TOKEN_EXPIRING_SOON_DAYS = 7, AGENT_RETRY_INTERVAL_MS = 1500, AGENT_RETRY_MAX_MS = 12000, AGENT_LIVE_WINDOW_MS = 45000, AGENT_LIVE_POLL_INTERVAL_MS = 2000, AGENT_LIVE_FOLLOWUP_REPOLL_MS = 30000, realProcFs, SCHEDULER_LOCK_PATH_DEFAULT = "/state/agent/scheduler.lock", SCHEDULER_JSONL_PATH_DEFAULT = "/state/agent/scheduler.jsonl", SCHEDULER_FRESH_BOOT_MS = 30000, realSchedulerFs, realSkillsFs;
28026
+ var execFile3, PROBE_TIMEOUT_MS = 2000, QUOTA_BROKER_TIMEOUT_MS = 7000, QUOTA_DIRECT_FALLBACK_TIMEOUT_MS = 5000, QUOTA_PROBE_OUTER_TIMEOUT_MS = 9000, TOKEN_EXPIRING_SOON_DAYS = 7, AGENT_RETRY_INTERVAL_MS = 1500, AGENT_RETRY_MAX_MS = 12000, AGENT_LIVE_WINDOW_MS = 45000, AGENT_LIVE_POLL_INTERVAL_MS = 2000, AGENT_LIVE_FOLLOWUP_REPOLL_MS = 30000, realProcFs, SCHEDULER_LOCK_PATH_DEFAULT = "/state/agent/scheduler.lock", SCHEDULER_JSONL_PATH_DEFAULT = "/state/agent/scheduler.jsonl", SCHEDULER_FRESH_BOOT_MS = 30000, realSchedulerFs, realSkillsFs;
27965
28027
  var init_boot_probes = __esm(() => {
27966
28028
  init_quota_cache();
27967
28029
  init_quota_check();
@@ -28182,7 +28244,8 @@ function renderBootCard(opts) {
28182
28244
  if (restartReason === "crash") {
28183
28245
  const ageStr = restartAgeMs != null && restartAgeMs > 0 ? ` \u00b7 ${(restartAgeMs / 1000).toFixed(1)}s ago` : "";
28184
28246
  degradedRows.push(`\u26a0\ufe0f <b>Restart</b> ${escapeHtml8(REASON_LABEL.crash)}${ageStr}`);
28185
- degradedRows.push(` \u21b3 Tail logs: <code>journalctl --user -u switchroom-${escapeHtml8(agentSlug)} -n 100</code>`);
28247
+ const tailCmd = process.env.SWITCHROOM_RUNTIME === "docker" ? `docker logs --tail 100 switchroom-${escapeHtml8(agentSlug)}` : `journalctl --user -u switchroom-${escapeHtml8(agentSlug)} -n 100`;
28248
+ degradedRows.push(` \u21b3 Tail logs: <code>${tailCmd}</code>`);
28186
28249
  }
28187
28250
  if (probes) {
28188
28251
  for (const key of PROBE_KEYS) {
@@ -28206,6 +28269,10 @@ function renderBootCard(opts) {
28206
28269
  sections.push("", ...degradedRows);
28207
28270
  if (accountRows.length > 0)
28208
28271
  sections.push("", ...accountRows);
28272
+ if (opts.updateOutcomeLine) {
28273
+ sections.push("", ...opts.updateOutcomeLine.split(`
28274
+ `));
28275
+ }
28209
28276
  if (sections.length === 1)
28210
28277
  return ack;
28211
28278
  return sections.join(`
@@ -28225,7 +28292,7 @@ async function runAllProbes(opts) {
28225
28292
  probeGateway(opts.gatewayInfo).then((r) => {
28226
28293
  probes.gateway = r;
28227
28294
  }),
28228
- probeQuota(claudeDir, opts.agentDir, opts.fetchImpl).then((r) => {
28295
+ probeQuota(claudeDir, opts.agentDir, opts.fetchImpl, { brokerProbe: opts.probeQuotaViaBroker }).then((r) => {
28229
28296
  probes.quota = r;
28230
28297
  }),
28231
28298
  probeHindsight(opts.bankName, opts.fetchImpl).then((r) => {
@@ -28255,7 +28322,8 @@ async function startBootCard(chatId, threadId, bot, opts, ackMessageId, log) {
28255
28322
  agentSlug: opts.agentSlug,
28256
28323
  version: opts.version,
28257
28324
  restartReason: opts.restartReason,
28258
- restartAgeMs: opts.restartAgeMs
28325
+ restartAgeMs: opts.restartAgeMs,
28326
+ ...opts.updateOutcomeLine ? { updateOutcomeLine: opts.updateOutcomeLine } : {}
28259
28327
  });
28260
28328
  const silentBootCard = opts.restartReasonDetail?.startsWith("operator:") === true;
28261
28329
  let messageId;
@@ -28320,7 +28388,8 @@ async function startBootCard(chatId, threadId, bot, opts, ackMessageId, log) {
28320
28388
  restartAgeMs: opts.restartAgeMs,
28321
28389
  ...accountRows ? { accounts: accountRows } : {},
28322
28390
  ...resolvedRows.length > 0 ? { resolvedRows } : {},
28323
- ...snoozeRows.length > 0 ? { snoozeRows } : {}
28391
+ ...snoozeRows.length > 0 ? { snoozeRows } : {},
28392
+ ...opts.updateOutcomeLine ? { updateOutcomeLine: opts.updateOutcomeLine } : {}
28324
28393
  });
28325
28394
  if (currentText !== ackText) {
28326
28395
  try {
@@ -28361,7 +28430,8 @@ async function startBootCard(chatId, threadId, bot, opts, ackMessageId, log) {
28361
28430
  restartAgeMs: opts.restartAgeMs,
28362
28431
  ...accountRows ? { accounts: accountRows } : {},
28363
28432
  ...resolvedRows.length > 0 ? { resolvedRows } : {},
28364
- ...snoozeRows.length > 0 ? { snoozeRows } : {}
28433
+ ...snoozeRows.length > 0 ? { snoozeRows } : {},
28434
+ ...opts.updateOutcomeLine ? { updateOutcomeLine: opts.updateOutcomeLine } : {}
28365
28435
  });
28366
28436
  if (updatedText === currentText)
28367
28437
  continue;
@@ -28451,11 +28521,11 @@ var init_flock = () => {};
28451
28521
  // ../src/vault/vault.ts
28452
28522
  import { randomBytes as randomBytes5, scryptSync, createCipheriv, createDecipheriv } from "node:crypto";
28453
28523
  import {
28454
- readFileSync as readFileSync29,
28524
+ readFileSync as readFileSync30,
28455
28525
  writeFileSync as writeFileSync19,
28456
- existsSync as existsSync30,
28526
+ existsSync as existsSync31,
28457
28527
  renameSync as renameSync11,
28458
- mkdirSync as mkdirSync17,
28528
+ mkdirSync as mkdirSync18,
28459
28529
  unlinkSync as unlinkSync12,
28460
28530
  lstatSync,
28461
28531
  realpathSync
@@ -28491,12 +28561,12 @@ function normalizeSecrets(raw) {
28491
28561
  return out;
28492
28562
  }
28493
28563
  function openVault(passphrase, vaultPath) {
28494
- if (!existsSync30(vaultPath)) {
28564
+ if (!existsSync31(vaultPath)) {
28495
28565
  throw new VaultError(`Vault file not found: ${vaultPath}`);
28496
28566
  }
28497
28567
  let vaultFile;
28498
28568
  try {
28499
- vaultFile = JSON.parse(readFileSync29(vaultPath, "utf8"));
28569
+ vaultFile = JSON.parse(readFileSync30(vaultPath, "utf8"));
28500
28570
  } catch {
28501
28571
  throw new VaultError(`Failed to read vault file: ${vaultPath}`);
28502
28572
  }
@@ -28542,15 +28612,15 @@ var init_vault = __esm(() => {
28542
28612
  // ../src/vault/resolver.ts
28543
28613
  import {
28544
28614
  chmodSync as chmodSync4,
28545
- closeSync as closeSync6,
28546
- mkdirSync as mkdirSync18,
28615
+ closeSync as closeSync7,
28616
+ mkdirSync as mkdirSync19,
28547
28617
  mkdtempSync as mkdtempSync2,
28548
- openSync as openSync6,
28618
+ openSync as openSync7,
28549
28619
  rmSync as rmSync3,
28550
28620
  statSync as statSync11,
28551
28621
  writeSync as writeSync2
28552
28622
  } from "node:fs";
28553
- import { join as join29 } from "node:path";
28623
+ import { join as join31 } from "node:path";
28554
28624
  import { tmpdir } from "node:os";
28555
28625
  import { constants as fsConstants } from "node:fs";
28556
28626
  function isVaultReference(value) {
@@ -28602,32 +28672,32 @@ function materializationRoot() {
28602
28672
  return cachedRoot;
28603
28673
  const xdg = process.env.XDG_RUNTIME_DIR;
28604
28674
  if (xdg) {
28605
- const base = join29(xdg, "switchroom", "vault");
28606
- mkdirSync18(base, { recursive: true, mode: 448 });
28607
- cachedRoot = mkdtempSync2(join29(base, "run-"));
28675
+ const base = join31(xdg, "switchroom", "vault");
28676
+ mkdirSync19(base, { recursive: true, mode: 448 });
28677
+ cachedRoot = mkdtempSync2(join31(base, "run-"));
28608
28678
  } else {
28609
- cachedRoot = mkdtempSync2(join29(tmpdir(), "switchroom-vault-"));
28679
+ cachedRoot = mkdtempSync2(join31(tmpdir(), "switchroom-vault-"));
28610
28680
  }
28611
28681
  chmodSync4(cachedRoot, 448);
28612
28682
  return cachedRoot;
28613
28683
  }
28614
28684
  function writeFileExclusive(filePath, content) {
28615
28685
  const buf = typeof content === "string" ? Buffer.from(content, "utf8") : content;
28616
- const fd = openSync6(filePath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL, 384);
28686
+ const fd = openSync7(filePath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL, 384);
28617
28687
  try {
28618
28688
  writeSync2(fd, buf);
28619
28689
  } finally {
28620
- closeSync6(fd);
28690
+ closeSync7(fd);
28621
28691
  }
28622
28692
  }
28623
28693
  function materializeFilesEntry(key, files) {
28624
- const dir = join29(materializationRoot(), key);
28694
+ const dir = join31(materializationRoot(), key);
28625
28695
  if (materializedDirs.has(dir)) {
28626
28696
  try {
28627
28697
  rmSync3(dir, { recursive: true, force: true });
28628
28698
  } catch {}
28629
28699
  }
28630
- mkdirSync18(dir, { recursive: true, mode: 448 });
28700
+ mkdirSync19(dir, { recursive: true, mode: 448 });
28631
28701
  chmodSync4(dir, 448);
28632
28702
  const st = statSync11(dir);
28633
28703
  if (typeof process.getuid === "function" && st.uid !== process.getuid()) {
@@ -28637,7 +28707,7 @@ function materializeFilesEntry(key, files) {
28637
28707
  if (filename.includes("/") || filename.includes("\\") || filename === ".." || filename === "." || filename.includes("\x00")) {
28638
28708
  throw new Error(`Refusing to materialize vault file with unsafe name: ${filename}`);
28639
28709
  }
28640
- const filePath = join29(dir, filename);
28710
+ const filePath = join31(dir, filename);
28641
28711
  const content = encoding === "base64" ? Buffer.from(value, "base64") : value;
28642
28712
  writeFileExclusive(filePath, content);
28643
28713
  }
@@ -28770,7 +28840,7 @@ __export(exports_materialize_bot_token, {
28770
28840
  materializeBotToken: () => materializeBotToken,
28771
28841
  BotTokenMaterializeError: () => BotTokenMaterializeError
28772
28842
  });
28773
- import { existsSync as existsSync31 } from "node:fs";
28843
+ import { existsSync as existsSync32 } from "node:fs";
28774
28844
  function pickConfiguredToken(config, agentName3) {
28775
28845
  if (agentName3) {
28776
28846
  const agent = config.agents?.[agentName3];
@@ -28784,7 +28854,7 @@ function tryDirectVaultRead(ref, config, passphrase) {
28784
28854
  if (!passphrase)
28785
28855
  return null;
28786
28856
  const vaultPath = resolvePath(config.vault?.path ?? "~/.switchroom/vault.enc");
28787
- if (!existsSync31(vaultPath))
28857
+ if (!existsSync32(vaultPath))
28788
28858
  return null;
28789
28859
  try {
28790
28860
  const secrets = openVault(passphrase, vaultPath);
@@ -28836,7 +28906,7 @@ async function materializeBotToken(opts = {}) {
28836
28906
  }
28837
28907
  }
28838
28908
  if (!brokerResult.ok && brokerResult.reason === "locked") {
28839
- throw new BotTokenMaterializeError("Bot token is a vault reference but vault is locked. Run: switchroom vault unlock", "locked");
28909
+ throw new BotTokenMaterializeError("Bot token is a vault reference but the vault is locked. Run `switchroom vault broker unlock` (or set SWITCHROOM_VAULT_PASSPHRASE / enable auto-unlock).", "locked");
28840
28910
  }
28841
28911
  if (!brokerResult.ok && brokerResult.reason === "denied") {
28842
28912
  throw new BotTokenMaterializeError(`Bot token resolution denied by vault broker (ACL). Check that this unit is authorised for the bot_token key in switchroom.yaml.`, "denied");
@@ -28851,7 +28921,7 @@ async function materializeBotToken(opts = {}) {
28851
28921
  }
28852
28922
  return direct;
28853
28923
  }
28854
- const unlockHint = isDockerRuntime() ? "Bring up the project (docker compose -p switchroom up -d), then `switchroom vault broker unlock` (or `docker exec -it switchroom-vault-broker switchroom vault broker unlock`), or set SWITCHROOM_VAULT_PASSPHRASE." : "Start the broker (switchroom vault unlock) or set SWITCHROOM_VAULT_PASSPHRASE.";
28924
+ const unlockHint = isDockerRuntime() ? "Bring up the project (docker compose -p switchroom up -d), then `switchroom vault broker unlock` (or `docker exec -it switchroom-vault-broker switchroom vault broker unlock`), or set SWITCHROOM_VAULT_PASSPHRASE." : "Start + unlock the broker (`switchroom vault broker unlock`) or set SWITCHROOM_VAULT_PASSPHRASE.";
28855
28925
  throw new BotTokenMaterializeError(`Bot token is a vault reference (${configured}) but vault broker is unreachable and no SWITCHROOM_VAULT_PASSPHRASE is available for direct decrypt. ` + unlockHint, brokerResult.ok ? "unknown" : brokerResult.reason);
28856
28926
  }
28857
28927
  var BotTokenMaterializeError;
@@ -28876,7 +28946,7 @@ __export(exports_tmux, {
28876
28946
  captureAgentPane: () => captureAgentPane
28877
28947
  });
28878
28948
  import { execFileSync as execFileSync4 } from "node:child_process";
28879
- import { mkdirSync as mkdirSync19, readdirSync as readdirSync6, statSync as statSync12, unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
28949
+ import { mkdirSync as mkdirSync20, readdirSync as readdirSync6, statSync as statSync12, unlinkSync as unlinkSync13, writeFileSync as writeFileSync20 } from "node:fs";
28880
28950
  import { resolve as resolve7 } from "node:path";
28881
28951
  function captureAgentPane(opts) {
28882
28952
  const { agentName: agentName3, agentDir, reason } = opts;
@@ -28888,7 +28958,7 @@ function captureAgentPane(opts) {
28888
28958
  const reasonSlug = sanitizeReason(reason);
28889
28959
  const outPath = resolve7(outDir, `${ts}-${reasonSlug}.txt`);
28890
28960
  try {
28891
- mkdirSync19(outDir, { recursive: true, mode: 493 });
28961
+ mkdirSync20(outDir, { recursive: true, mode: 493 });
28892
28962
  } catch (err) {
28893
28963
  const msg = `mkdir crash-reports failed: ${err.message}`;
28894
28964
  console.error(`[tmux-capture] ${agentName3}: ${msg}`);
@@ -29458,7 +29528,7 @@ function parseApprovalCallback(data) {
29458
29528
  return null;
29459
29529
  const request_id = parts[1];
29460
29530
  const choiceStr = parts[2];
29461
- if (!/^[0-9a-f]{8}$/.test(request_id ?? ""))
29531
+ if (!/^[0-9a-f]{32}$/.test(request_id ?? ""))
29462
29532
  return null;
29463
29533
  switch (choiceStr) {
29464
29534
  case "once":
@@ -29593,22 +29663,22 @@ var import_runner2 = __toESM(require_mod3(), 1);
29593
29663
  import { randomBytes as randomBytes6 } from "crypto";
29594
29664
  import { execFileSync as execFileSync5, execSync as execSync2, spawn as spawn2 } from "child_process";
29595
29665
  import {
29596
- readFileSync as readFileSync30,
29666
+ readFileSync as readFileSync31,
29597
29667
  writeFileSync as writeFileSync21,
29598
- mkdirSync as mkdirSync20,
29668
+ mkdirSync as mkdirSync21,
29599
29669
  readdirSync as readdirSync7,
29600
29670
  rmSync as rmSync4,
29601
29671
  statSync as statSync13,
29602
29672
  renameSync as renameSync12,
29603
29673
  realpathSync as realpathSync2,
29604
29674
  chmodSync as chmodSync5,
29605
- openSync as openSync7,
29606
- closeSync as closeSync7,
29607
- existsSync as existsSync32,
29675
+ openSync as openSync8,
29676
+ closeSync as closeSync8,
29677
+ existsSync as existsSync33,
29608
29678
  unlinkSync as unlinkSync14
29609
29679
  } from "fs";
29610
- import { homedir as homedir10 } from "os";
29611
- import { join as join30, extname, sep as sep3, basename as basename7 } from "path";
29680
+ import { homedir as homedir12 } from "os";
29681
+ import { join as join32, extname, sep as sep3, basename as basename7 } from "path";
29612
29682
 
29613
29683
  // plugin-logger.ts
29614
29684
  import { appendFileSync, mkdirSync, renameSync, statSync, existsSync } from "fs";
@@ -31742,6 +31812,12 @@ async function retryWithThreadFallback(retry, send, opts) {
31742
31812
  throw err;
31743
31813
  }
31744
31814
  }
31815
+ function isHtmlParseRejectError(err) {
31816
+ if (!(err instanceof import_grammy.GrammyError) || err.error_code !== 400)
31817
+ return false;
31818
+ const d = (err.description || "").toLowerCase();
31819
+ return d.includes("can't parse entities") || d.includes("can\u2019t parse entities") || d.includes("unsupported start tag") || d.includes("unclosed start tag") || d.includes("can't find end of the entity") || d.includes("expected end tag");
31820
+ }
31745
31821
 
31746
31822
  // shared/bot-runtime.ts
31747
31823
  var import_grammy3 = __toESM(require_mod2(), 1);
@@ -31906,7 +31982,7 @@ function clear(key) {
31906
31982
  state.delete(key);
31907
31983
  }
31908
31984
 
31909
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
31985
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
31910
31986
  import { dirname as dirname2, posix, sep as sep2 } from "path";
31911
31987
  function createModulerModifier() {
31912
31988
  const getModuleFromFileName = createGetModuleFromFilename();
@@ -31942,7 +32018,7 @@ function normalizeWindowsPath(path) {
31942
32018
  return path.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
31943
32019
  }
31944
32020
 
31945
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/featureFlagUtils.mjs
32021
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/featureFlagUtils.mjs
31946
32022
  var normalizeFlagsResponse = (flagsResponse) => {
31947
32023
  if ("flags" in flagsResponse) {
31948
32024
  const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
@@ -32013,7 +32089,7 @@ var parsePayload = (response) => {
32013
32089
  }
32014
32090
  };
32015
32091
 
32016
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/gzip.mjs
32092
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/gzip.mjs
32017
32093
  function isGzipSupported() {
32018
32094
  return "CompressionStream" in globalThis;
32019
32095
  }
@@ -32033,7 +32109,7 @@ async function gzipCompress(input, isDebug = true) {
32033
32109
  }
32034
32110
  }
32035
32111
 
32036
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
32112
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
32037
32113
  /*! For license information please see uuidv7.mjs.LICENSE.txt */
32038
32114
  var DIGITS = "0123456789abcdef";
32039
32115
 
@@ -32211,7 +32287,7 @@ var defaultGenerator;
32211
32287
  var uuidv7 = () => uuidv7obj().toString();
32212
32288
  var uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator)).generate();
32213
32289
 
32214
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/types.mjs
32290
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/types.mjs
32215
32291
  var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedProperty) {
32216
32292
  PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
32217
32293
  PostHogPersistedProperty["DistinctId"] = "distinct_id";
@@ -32244,7 +32320,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
32244
32320
  return PostHogPersistedProperty;
32245
32321
  }({});
32246
32322
 
32247
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bot-detection.mjs
32323
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bot-detection.mjs
32248
32324
  var DEFAULT_BLOCKED_UA_STRS = [
32249
32325
  "amazonbot",
32250
32326
  "amazonproductbot",
@@ -32333,7 +32409,7 @@ var isBlockedUA = function(ua, customBlockedUserAgents = []) {
32333
32409
  return uaLower.indexOf(blockedUaLower) !== -1;
32334
32410
  });
32335
32411
  };
32336
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/type-utils.mjs
32412
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/type-utils.mjs
32337
32413
  var nativeIsArray = Array.isArray;
32338
32414
  var ObjProto = Object.prototype;
32339
32415
  var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
@@ -32370,7 +32446,7 @@ function isInstanceOf(candidate, base) {
32370
32446
  }
32371
32447
  }
32372
32448
 
32373
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/number-utils.mjs
32449
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/number-utils.mjs
32374
32450
  function clampToRange(value, min, max, logger, fallbackValue) {
32375
32451
  if (min > max) {
32376
32452
  logger.warn("min cannot be greater than max.");
@@ -32390,7 +32466,7 @@ function clampToRange(value, min, max, logger, fallbackValue) {
32390
32466
  return clampToRange(fallbackValue || max, min, max, logger);
32391
32467
  }
32392
32468
 
32393
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
32469
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
32394
32470
  var ONE_DAY_IN_MS = 86400000;
32395
32471
 
32396
32472
  class BucketedRateLimiter {
@@ -32434,7 +32510,7 @@ class BucketedRateLimiter {
32434
32510
  this._buckets = {};
32435
32511
  }
32436
32512
  }
32437
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/promise-queue.mjs
32513
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/promise-queue.mjs
32438
32514
  class PromiseQueue {
32439
32515
  add(promise) {
32440
32516
  const promiseUUID = uuidv7();
@@ -32460,7 +32536,7 @@ class PromiseQueue {
32460
32536
  this.promiseByIds = {};
32461
32537
  }
32462
32538
  }
32463
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/logger.mjs
32539
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/logger.mjs
32464
32540
  function createConsole(consoleLike = console) {
32465
32541
  const lockedMethods = {
32466
32542
  log: consoleLike.log.bind(consoleLike),
@@ -32498,7 +32574,7 @@ var passThrough = (fn) => fn();
32498
32574
  function createLogger(prefix, maybeCall = passThrough) {
32499
32575
  return _createLogger(prefix, maybeCall, createConsole());
32500
32576
  }
32501
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
32577
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
32502
32578
  var MOBILE = "Mobile";
32503
32579
  var IOS = "iOS";
32504
32580
  var ANDROID = "Android";
@@ -32755,7 +32831,7 @@ var osMatchers = [
32755
32831
  ]
32756
32832
  ];
32757
32833
 
32758
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/index.mjs
32834
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/index.mjs
32759
32835
  var STRING_FORMAT = "utf8";
32760
32836
  function assert(truthyValue, message) {
32761
32837
  if (!truthyValue || typeof truthyValue != "string" || isEmpty(truthyValue))
@@ -32803,7 +32879,7 @@ function allSettled(promises) {
32803
32879
  reason
32804
32880
  }))));
32805
32881
  }
32806
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/eventemitter.mjs
32882
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/eventemitter.mjs
32807
32883
  class SimpleEventEmitter {
32808
32884
  constructor() {
32809
32885
  this.events = {};
@@ -32825,7 +32901,7 @@ class SimpleEventEmitter {
32825
32901
  }
32826
32902
  }
32827
32903
 
32828
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
32904
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
32829
32905
  class PostHogFetchHttpError extends Error {
32830
32906
  constructor(response, reqByteLength) {
32831
32907
  super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
@@ -33540,7 +33616,7 @@ class PostHogCoreStateless {
33540
33616
  return this.shutdownPromise;
33541
33617
  }
33542
33618
  }
33543
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/index.mjs
33619
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/index.mjs
33544
33620
  var exports_error_tracking = {};
33545
33621
  __export(exports_error_tracking, {
33546
33622
  winjsStackLineParser: () => winjsStackLineParser,
@@ -33564,7 +33640,7 @@ __export(exports_error_tracking, {
33564
33640
  DOMExceptionCoercer: () => DOMExceptionCoercer
33565
33641
  });
33566
33642
 
33567
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
33643
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
33568
33644
  var parsedStackResults;
33569
33645
  var lastKeysCount;
33570
33646
  var cachedFilenameChunkIds;
@@ -33603,7 +33679,7 @@ function getFilenameToChunkIdMap(stackParser) {
33603
33679
  return cachedFilenameChunkIds;
33604
33680
  }
33605
33681
 
33606
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
33682
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
33607
33683
  var MAX_CAUSE_RECURSION = 4;
33608
33684
 
33609
33685
  class ErrorPropertiesBuilder {
@@ -33725,7 +33801,7 @@ class ErrorPropertiesBuilder {
33725
33801
  return context;
33726
33802
  }
33727
33803
  }
33728
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
33804
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
33729
33805
  var UNKNOWN_FUNCTION = "?";
33730
33806
  function createFrame(platform, filename, func, lineno, colno) {
33731
33807
  const frame = {
@@ -33741,7 +33817,7 @@ function createFrame(platform, filename, func, lineno, colno) {
33741
33817
  return frame;
33742
33818
  }
33743
33819
 
33744
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
33820
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
33745
33821
  var extractSafariExtensionDetails = (func, filename) => {
33746
33822
  const isSafariExtension = func.indexOf("safari-extension") !== -1;
33747
33823
  const isSafariWebExtension = func.indexOf("safari-web-extension") !== -1;
@@ -33754,7 +33830,7 @@ var extractSafariExtensionDetails = (func, filename) => {
33754
33830
  ];
33755
33831
  };
33756
33832
 
33757
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
33833
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
33758
33834
  var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
33759
33835
  var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
33760
33836
  var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
@@ -33780,7 +33856,7 @@ var chromeStackLineParser = (line, platform) => {
33780
33856
  }
33781
33857
  };
33782
33858
 
33783
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
33859
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
33784
33860
  var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
33785
33861
  var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
33786
33862
  var geckoStackLineParser = (line, platform) => {
@@ -33803,14 +33879,14 @@ var geckoStackLineParser = (line, platform) => {
33803
33879
  }
33804
33880
  };
33805
33881
 
33806
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
33882
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
33807
33883
  var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
33808
33884
  var winjsStackLineParser = (line, platform) => {
33809
33885
  const parts = winjsRegex.exec(line);
33810
33886
  return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined) : undefined;
33811
33887
  };
33812
33888
 
33813
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
33889
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
33814
33890
  var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
33815
33891
  var opera10StackLineParser = (line, platform) => {
33816
33892
  const parts = opera10Regex.exec(line);
@@ -33822,7 +33898,7 @@ var opera11StackLineParser = (line, platform) => {
33822
33898
  return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
33823
33899
  };
33824
33900
 
33825
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
33901
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
33826
33902
  var FILENAME_MATCH = /^\s*[-]{4,}$/;
33827
33903
  var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
33828
33904
  var nodeStackLineParser = (line, platform) => {
@@ -33891,7 +33967,7 @@ function _parseIntOrUndefined(input) {
33891
33967
  return parseInt(input || "", 10) || undefined;
33892
33968
  }
33893
33969
 
33894
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
33970
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
33895
33971
  var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
33896
33972
  var STACKTRACE_FRAME_LIMIT = 50;
33897
33973
  function reverseAndStripFrames(stack) {
@@ -33936,7 +34012,7 @@ function createStackParser(platform, ...parsers) {
33936
34012
  return reverseAndStripFrames(frames);
33937
34013
  };
33938
34014
  }
33939
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
34015
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
33940
34016
  class DOMExceptionCoercer {
33941
34017
  match(err) {
33942
34018
  return this.isDOMException(err) || this.isDOMError(err);
@@ -33966,7 +34042,7 @@ class DOMExceptionCoercer {
33966
34042
  return isBuiltin(err, "DOMError");
33967
34043
  }
33968
34044
  }
33969
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
34045
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
33970
34046
  class ErrorCoercer {
33971
34047
  match(err) {
33972
34048
  return isPlainError(err);
@@ -33993,7 +34069,7 @@ class ErrorCoercer {
33993
34069
  return err.stacktrace || err.stack || undefined;
33994
34070
  }
33995
34071
  }
33996
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
34072
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
33997
34073
  class ErrorEventCoercer {
33998
34074
  constructor() {}
33999
34075
  match(err) {
@@ -34011,7 +34087,7 @@ class ErrorEventCoercer {
34011
34087
  return exceptionLike;
34012
34088
  }
34013
34089
  }
34014
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
34090
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
34015
34091
  var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
34016
34092
 
34017
34093
  class StringCoercer {
@@ -34041,7 +34117,7 @@ class StringCoercer {
34041
34117
  ];
34042
34118
  }
34043
34119
  }
34044
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/types.mjs
34120
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/types.mjs
34045
34121
  var severityLevels = [
34046
34122
  "fatal",
34047
34123
  "error",
@@ -34051,7 +34127,7 @@ var severityLevels = [
34051
34127
  "debug"
34052
34128
  ];
34053
34129
 
34054
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
34130
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
34055
34131
  function extractExceptionKeysForMessage(err, maxLength = 40) {
34056
34132
  const keys = Object.keys(err);
34057
34133
  keys.sort();
@@ -34068,7 +34144,7 @@ function extractExceptionKeysForMessage(err, maxLength = 40) {
34068
34144
  return "";
34069
34145
  }
34070
34146
 
34071
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
34147
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
34072
34148
  class ObjectCoercer {
34073
34149
  match(candidate) {
34074
34150
  return typeof candidate == "object" && candidate !== null;
@@ -34121,7 +34197,7 @@ class ObjectCoercer {
34121
34197
  }
34122
34198
  }
34123
34199
  }
34124
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
34200
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
34125
34201
  class EventCoercer {
34126
34202
  match(err) {
34127
34203
  return isEvent(err);
@@ -34136,7 +34212,7 @@ class EventCoercer {
34136
34212
  };
34137
34213
  }
34138
34214
  }
34139
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
34215
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
34140
34216
  class PrimitiveCoercer {
34141
34217
  match(candidate) {
34142
34218
  return isPrimitive(candidate);
@@ -34150,7 +34226,7 @@ class PrimitiveCoercer {
34150
34226
  };
34151
34227
  }
34152
34228
  }
34153
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
34229
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
34154
34230
  class PromiseRejectionEventCoercer {
34155
34231
  match(err) {
34156
34232
  return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
@@ -34186,7 +34262,7 @@ class PromiseRejectionEventCoercer {
34186
34262
  return error;
34187
34263
  }
34188
34264
  }
34189
- // ../node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/utils.mjs
34265
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/utils.mjs
34190
34266
  class ReduceableCache {
34191
34267
  constructor(_maxSize) {
34192
34268
  this._maxSize = _maxSize;
@@ -34211,7 +34287,7 @@ class ReduceableCache {
34211
34287
  }
34212
34288
  }
34213
34289
  }
34214
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
34290
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
34215
34291
  import { createReadStream } from "node:fs";
34216
34292
  import { createInterface } from "node:readline";
34217
34293
  var LRU_FILE_CONTENTS_CACHE = new exports_error_tracking.ReduceableCache(25);
@@ -34429,7 +34505,7 @@ function snipLine(line, colno) {
34429
34505
  return newLine;
34430
34506
  }
34431
34507
 
34432
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
34508
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
34433
34509
  function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
34434
34510
  let calledFatalError = false;
34435
34511
  return Object.assign((error) => {
@@ -34461,7 +34537,7 @@ function addUnhandledRejectionListener(captureFn) {
34461
34537
  }));
34462
34538
  }
34463
34539
 
34464
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
34540
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
34465
34541
  var SHUTDOWN_TIMEOUT = 2000;
34466
34542
 
34467
34543
  class ErrorTracking {
@@ -34530,10 +34606,10 @@ class ErrorTracking {
34530
34606
  }
34531
34607
  }
34532
34608
 
34533
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/version.mjs
34609
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/version.mjs
34534
34610
  var version = "5.29.2";
34535
34611
 
34536
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/types.mjs
34612
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/types.mjs
34537
34613
  var FeatureFlagError2 = {
34538
34614
  ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
34539
34615
  FLAG_MISSING: "flag_missing",
@@ -34541,7 +34617,7 @@ var FeatureFlagError2 = {
34541
34617
  UNKNOWN_ERROR: "unknown_error"
34542
34618
  };
34543
34619
 
34544
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
34620
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
34545
34621
  async function hashSHA1(text) {
34546
34622
  const subtle = globalThis.crypto?.subtle;
34547
34623
  if (!subtle)
@@ -34551,7 +34627,7 @@ async function hashSHA1(text) {
34551
34627
  return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
34552
34628
  }
34553
34629
 
34554
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
34630
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
34555
34631
  var SIXTY_SECONDS = 60000;
34556
34632
  var LONG_SCALE = 1152921504606847000;
34557
34633
  var NULL_VALUES_ALLOWED_OPERATORS = [
@@ -35425,7 +35501,7 @@ function relativeDateParseForFeatureFlagMatching(value) {
35425
35501
  }
35426
35502
  }
35427
35503
 
35428
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/storage-memory.mjs
35504
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/storage-memory.mjs
35429
35505
  class PostHogMemoryStorage {
35430
35506
  getProperty(key) {
35431
35507
  return this._memoryStorage[key];
@@ -35438,7 +35514,7 @@ class PostHogMemoryStorage {
35438
35514
  }
35439
35515
  }
35440
35516
 
35441
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/client.mjs
35517
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/client.mjs
35442
35518
  var MINIMUM_POLLING_INTERVAL = 100;
35443
35519
  var THIRTY_SECONDS = 30000;
35444
35520
  var MAX_CACHE_SIZE = 50000;
@@ -36226,7 +36302,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
36226
36302
  }
36227
36303
  }
36228
36304
 
36229
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/context/context.mjs
36305
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/context/context.mjs
36230
36306
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
36231
36307
 
36232
36308
  class PostHogContext {
@@ -36257,7 +36333,7 @@ class PostHogContext {
36257
36333
  }
36258
36334
  }
36259
36335
 
36260
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
36336
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
36261
36337
  var NAME = "posthog-node";
36262
36338
  function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
36263
36339
  "error"
@@ -36325,7 +36401,7 @@ class PostHogSentryIntegration {
36325
36401
  };
36326
36402
  }
36327
36403
  }
36328
- // ../node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/entrypoints/index.node.mjs
36404
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/entrypoints/index.node.mjs
36329
36405
  ErrorTracking.errorPropertiesBuilder = new exports_error_tracking.ErrorPropertiesBuilder([
36330
36406
  new exports_error_tracking.EventCoercer,
36331
36407
  new exports_error_tracking.ErrorCoercer,
@@ -38161,7 +38237,8 @@ function createAuthBrokerClient() {
38161
38237
  setActive: (label) => broker.setActive(label),
38162
38238
  rmAccount: (label) => broker.rmAccount(label),
38163
38239
  refreshAccount: (label) => broker.refreshAccount(label),
38164
- setOverride: (agent, account) => broker.setOverride(agent, account)
38240
+ setOverride: (agent, account) => broker.setOverride(agent, account),
38241
+ probeQuota: (accounts, timeoutMs) => broker.probeQuota(accounts, timeoutMs)
38165
38242
  };
38166
38243
  return { client: client3, close: () => broker.close() };
38167
38244
  }
@@ -38185,6 +38262,14 @@ import { homedir as homedir4 } from "node:os";
38185
38262
  import { randomUUID as randomUUID4 } from "node:crypto";
38186
38263
  import { join as join9 } from "node:path";
38187
38264
  var DEFAULT_TIMEOUT_MS2 = 5000;
38265
+ function reviveDate2(v) {
38266
+ if (v == null)
38267
+ return null;
38268
+ if (v instanceof Date)
38269
+ return Number.isNaN(v.getTime()) ? null : v;
38270
+ const d = new Date(v);
38271
+ return Number.isNaN(d.getTime()) ? null : d;
38272
+ }
38188
38273
  function operatorSocketPath2(home = homedir4()) {
38189
38274
  return join9(home, ".switchroom", "state", "auth-broker-operator", "sock");
38190
38275
  }
@@ -38272,6 +38357,23 @@ class AuthBrokerClient2 {
38272
38357
  });
38273
38358
  return data;
38274
38359
  }
38360
+ async probeQuota(accounts, timeoutMs) {
38361
+ const data = await this.send({
38362
+ v: PROTOCOL_VERSION,
38363
+ id: randomUUID4(),
38364
+ op: "probe-quota",
38365
+ accounts: [...accounts],
38366
+ ...timeoutMs !== undefined ? { timeoutMs } : {}
38367
+ });
38368
+ const parsed = data;
38369
+ for (const entry of parsed.results) {
38370
+ if (entry.result.ok) {
38371
+ entry.result.data.fiveHourResetAt = reviveDate2(entry.result.data.fiveHourResetAt);
38372
+ entry.result.data.sevenDayResetAt = reviveDate2(entry.result.data.sevenDayResetAt);
38373
+ }
38374
+ }
38375
+ return parsed;
38376
+ }
38275
38377
  async setActive(account) {
38276
38378
  const data = await this.send({
38277
38379
  v: PROTOCOL_VERSION,
@@ -39195,194 +39297,6 @@ function pctSummary(q) {
39195
39297
  return `${Math.round(q.fiveHourUtilizationPct)}% / ${Math.round(q.sevenDayUtilizationPct)}%`;
39196
39298
  }
39197
39299
 
39198
- // quota-check.ts
39199
- import { readFileSync as readFileSync9, existsSync as existsSync13 } from "fs";
39200
- import { join as join13 } from "path";
39201
- var OAUTH_BETA2 = "oauth-2025-04-20";
39202
- var DEFAULT_USER_AGENT2 = "claude-cli/1.0.0 (external, cli)";
39203
- var DEFAULT_PROBE_MODEL2 = "claude-haiku-4-5-20251001";
39204
- function readOauthToken2(claudeConfigDir) {
39205
- const tokenFile = join13(claudeConfigDir, ".oauth-token");
39206
- if (!existsSync13(tokenFile))
39207
- return null;
39208
- try {
39209
- const raw = readFileSync9(tokenFile, "utf-8").trim();
39210
- return raw.length > 0 ? raw : null;
39211
- } catch {
39212
- return null;
39213
- }
39214
- }
39215
- function parseFloatHeader2(headers, name) {
39216
- const v = headers.get(name);
39217
- if (v == null || v.trim().length === 0)
39218
- return null;
39219
- const n = Number(v);
39220
- return Number.isFinite(n) ? n : null;
39221
- }
39222
- function parseEpochHeader2(headers, name) {
39223
- const v = headers.get(name);
39224
- if (v == null)
39225
- return null;
39226
- const n = Number(v);
39227
- if (!Number.isFinite(n) || n <= 0)
39228
- return null;
39229
- return new Date(n * 1000);
39230
- }
39231
- function parseQuotaHeaders2(headers) {
39232
- const fiveHour = parseFloatHeader2(headers, "anthropic-ratelimit-unified-5h-utilization");
39233
- const sevenDay = parseFloatHeader2(headers, "anthropic-ratelimit-unified-7d-utilization");
39234
- if (fiveHour == null && sevenDay == null) {
39235
- return {
39236
- ok: false,
39237
- reason: "no unified rate-limit headers in response (API token, not OAuth?)"
39238
- };
39239
- }
39240
- return {
39241
- ok: true,
39242
- data: {
39243
- fiveHourUtilizationPct: (fiveHour ?? 0) * 100,
39244
- sevenDayUtilizationPct: (sevenDay ?? 0) * 100,
39245
- fiveHourResetAt: parseEpochHeader2(headers, "anthropic-ratelimit-unified-5h-reset"),
39246
- sevenDayResetAt: parseEpochHeader2(headers, "anthropic-ratelimit-unified-7d-reset"),
39247
- representativeClaim: headers.get("anthropic-ratelimit-unified-representative-claim"),
39248
- overageStatus: headers.get("anthropic-ratelimit-unified-overage-status"),
39249
- overageDisabledReason: headers.get("anthropic-ratelimit-unified-overage-disabled-reason")
39250
- }
39251
- };
39252
- }
39253
- async function fetchQuota2(opts) {
39254
- let token;
39255
- if (opts.accessToken && opts.claudeConfigDir) {
39256
- return {
39257
- ok: false,
39258
- reason: "pass only one of `accessToken` or `claudeConfigDir`, not both"
39259
- };
39260
- }
39261
- if (opts.accessToken) {
39262
- token = opts.accessToken.trim().length > 0 ? opts.accessToken : null;
39263
- } else if (opts.claudeConfigDir) {
39264
- token = readOauthToken2(opts.claudeConfigDir);
39265
- } else {
39266
- return {
39267
- ok: false,
39268
- reason: "fetchQuota requires `accessToken` or `claudeConfigDir`"
39269
- };
39270
- }
39271
- if (!token) {
39272
- return { ok: false, reason: "no OAuth token at .oauth-token" };
39273
- }
39274
- const controller = new AbortController;
39275
- const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? 1e4);
39276
- const fetchFn = opts.fetchImpl ?? fetch;
39277
- let resp;
39278
- try {
39279
- resp = await fetchFn("https://api.anthropic.com/v1/messages", {
39280
- method: "POST",
39281
- headers: {
39282
- "anthropic-version": "2023-06-01",
39283
- "anthropic-beta": OAUTH_BETA2,
39284
- authorization: `Bearer ${token}`,
39285
- "x-app": "cli",
39286
- "user-agent": DEFAULT_USER_AGENT2,
39287
- "content-type": "application/json"
39288
- },
39289
- body: JSON.stringify({
39290
- model: opts.model ?? DEFAULT_PROBE_MODEL2,
39291
- max_tokens: 1,
39292
- messages: [{ role: "user", content: "hi" }]
39293
- }),
39294
- signal: controller.signal
39295
- });
39296
- } catch (err) {
39297
- const msg = err?.message ?? String(err);
39298
- return { ok: false, reason: `request failed: ${msg}` };
39299
- } finally {
39300
- clearTimeout(timeout);
39301
- }
39302
- if (resp.status === 401 || resp.status === 403) {
39303
- return { ok: false, reason: `auth rejected (HTTP ${resp.status})` };
39304
- }
39305
- const parsed = parseQuotaHeaders2(resp.headers);
39306
- if (!parsed.ok && resp.status >= 400) {
39307
- return { ok: false, reason: `HTTP ${resp.status}, ${parsed.reason}` };
39308
- }
39309
- return parsed;
39310
- }
39311
- function formatResetRelative2(target, now = new Date) {
39312
- if (!target)
39313
- return "\u2014";
39314
- const deltaMs = target.getTime() - now.getTime();
39315
- if (deltaMs <= 0)
39316
- return "resets now";
39317
- const totalMin = Math.round(deltaMs / 60000);
39318
- if (totalMin < 60)
39319
- return `resets in ${totalMin}m`;
39320
- const hours = Math.floor(totalMin / 60);
39321
- const mins = totalMin % 60;
39322
- if (hours < 24)
39323
- return mins > 0 ? `resets in ${hours}h ${mins}m` : `resets in ${hours}h`;
39324
- const days = Math.floor(hours / 24);
39325
- const remH = hours % 24;
39326
- return remH > 0 ? `resets in ${days}d ${remH}h` : `resets in ${days}d`;
39327
- }
39328
- function formatQuotaBlock(q, now = new Date) {
39329
- const lines = [];
39330
- lines.push("<b>Claude plan quota</b>");
39331
- lines.push("");
39332
- lines.push(`<b>5h window</b> ${Math.round(q.fiveHourUtilizationPct)}% \u00b7 ${formatResetRelative2(q.fiveHourResetAt, now)}`);
39333
- lines.push(`<b>7d window</b> ${Math.round(q.sevenDayUtilizationPct)}% \u00b7 ${formatResetRelative2(q.sevenDayResetAt, now)}`);
39334
- if (q.representativeClaim) {
39335
- lines.push("");
39336
- lines.push(`<i>Binding window: ${q.representativeClaim.replace(/_/g, " ")}</i>`);
39337
- }
39338
- if (q.overageStatus && q.overageStatus !== "allowed") {
39339
- const reason = q.overageDisabledReason ? ` (${q.overageDisabledReason})` : "";
39340
- lines.push(`<i>Overage: ${q.overageStatus}${reason}</i>`);
39341
- }
39342
- return lines.join(`
39343
- `);
39344
- }
39345
- function readAccountAccessToken(label, home2 = process.env.HOME ?? "/root") {
39346
- const credPath = join13(home2, ".switchroom", "accounts", label, "credentials.json");
39347
- if (!existsSync13(credPath))
39348
- return null;
39349
- try {
39350
- const raw = readFileSync9(credPath, "utf-8");
39351
- const parsed = JSON.parse(raw);
39352
- const token = parsed.claudeAiOauth?.accessToken?.trim();
39353
- return token && token.length > 0 ? token : null;
39354
- } catch {
39355
- return null;
39356
- }
39357
- }
39358
- var ACCOUNT_QUOTA_CACHE_TTL_MS2 = 5 * 60000;
39359
- var accountQuotaCache2 = new Map;
39360
- async function fetchAccountQuota(label, opts = {}) {
39361
- const now = opts.now?.() ?? Date.now();
39362
- if (!opts.force) {
39363
- const cached = accountQuotaCache2.get(label);
39364
- if (cached && now - cached.fetchedAt < ACCOUNT_QUOTA_CACHE_TTL_MS2) {
39365
- return cached.result;
39366
- }
39367
- }
39368
- const token = readAccountAccessToken(label, opts.home);
39369
- if (!token) {
39370
- const result2 = {
39371
- ok: false,
39372
- reason: "no credentials.json or accessToken for account"
39373
- };
39374
- accountQuotaCache2.set(label, { fetchedAt: now, result: result2 });
39375
- return result2;
39376
- }
39377
- const result = await fetchQuota2({
39378
- accessToken: token,
39379
- fetchImpl: opts.fetchImpl,
39380
- timeoutMs: opts.timeoutMs
39381
- });
39382
- accountQuotaCache2.set(label, { fetchedAt: now, result });
39383
- return result;
39384
- }
39385
-
39386
39300
  // gateway/restart-watchdog.ts
39387
39301
  function parseSystemdShowOutput(raw) {
39388
39302
  const lines = raw.split(/\r?\n/);
@@ -39681,6 +39595,28 @@ function markdownToHtml(text) {
39681
39595
  function escapeHtml4(text) {
39682
39596
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
39683
39597
  }
39598
+ function telegramHtmlToPlainText(html) {
39599
+ const decodeEntities = (s) => s.replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#0*39;|&#x0*27;|&apos;/gi, "'").replace(/&nbsp;/g, " ").replace(/&#(\d+);/g, (_m, d) => {
39600
+ const cp = Number(d);
39601
+ return Number.isFinite(cp) && cp > 0 && cp <= 1114111 ? String.fromCodePoint(cp) : _m;
39602
+ }).replace(/&#x([0-9a-fA-F]+);/g, (_m, h) => {
39603
+ const cp = parseInt(h, 16);
39604
+ return Number.isFinite(cp) && cp > 0 && cp <= 1114111 ? String.fromCodePoint(cp) : _m;
39605
+ });
39606
+ const stripTags = (s) => decodeEntities(s.replace(/<\s*br\s*\/?\s*>/gi, `
39607
+ `).replace(/<\/\s*(?:p|div|li|blockquote|pre|h[1-6])\s*>/gi, `
39608
+ `).replace(/<[^>]*>/g, ""));
39609
+ const withPlainLinks = html.replace(/<a\b[^>]*\bhref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))[^>]*>([\s\S]*?)<\/a>/gi, (_m, dq, sq, uq, label) => {
39610
+ const href = decodeEntities((dq ?? sq ?? uq ?? "").trim());
39611
+ const text = stripTags(label).trim();
39612
+ if (!href)
39613
+ return text;
39614
+ return !text || text === href ? href : `${text} (${href})`;
39615
+ });
39616
+ return stripTags(withPlainLinks).replace(/[ \t]+$/gm, "").replace(/\n{3,}/g, `
39617
+
39618
+ `).trim();
39619
+ }
39684
39620
  function repairEscapedWhitespace(text) {
39685
39621
  if (text.includes(`
39686
39622
  `) || text.includes("\r"))
@@ -40278,8 +40214,8 @@ function isTurnFlushSafetyEnabled(env = process.env) {
40278
40214
  }
40279
40215
 
40280
40216
  // handoff-continuity.ts
40281
- import { readFileSync as readFileSync10, unlinkSync as unlinkSync2, existsSync as existsSync14, writeFileSync as writeFileSync6, renameSync as renameSync2 } from "node:fs";
40282
- import { dirname as dirname7, join as join14 } from "node:path";
40217
+ import { readFileSync as readFileSync9, unlinkSync as unlinkSync2, existsSync as existsSync13, writeFileSync as writeFileSync6, renameSync as renameSync2 } from "node:fs";
40218
+ import { dirname as dirname7, join as join13 } from "node:path";
40283
40219
  var TOPIC_DISPLAY_MAX = 117;
40284
40220
  var HANDOFF_TOPIC_FILENAME = ".handoff-topic";
40285
40221
  var LAST_TURN_SUMMARY_FILENAME = ".last-turn-summary";
@@ -40290,12 +40226,12 @@ function resolveAgentDirFromEnv() {
40290
40226
  return dirname7(state3);
40291
40227
  }
40292
40228
  function readHandoffTopic(agentDir) {
40293
- const p = join14(agentDir, HANDOFF_TOPIC_FILENAME);
40294
- if (!existsSync14(p))
40229
+ const p = join13(agentDir, HANDOFF_TOPIC_FILENAME);
40230
+ if (!existsSync13(p))
40295
40231
  return null;
40296
40232
  let raw;
40297
40233
  try {
40298
- raw = readFileSync10(p, "utf-8");
40234
+ raw = readFileSync9(p, "utf-8");
40299
40235
  } catch {
40300
40236
  return null;
40301
40237
  }
@@ -40309,12 +40245,12 @@ function readHandoffTopic(agentDir) {
40309
40245
  return topic;
40310
40246
  }
40311
40247
  function readLastTurnSummary(agentDir) {
40312
- const p = join14(agentDir, LAST_TURN_SUMMARY_FILENAME);
40313
- if (!existsSync14(p))
40248
+ const p = join13(agentDir, LAST_TURN_SUMMARY_FILENAME);
40249
+ if (!existsSync13(p))
40314
40250
  return null;
40315
40251
  let raw;
40316
40252
  try {
40317
- raw = readFileSync10(p, "utf-8");
40253
+ raw = readFileSync9(p, "utf-8");
40318
40254
  } catch {
40319
40255
  return null;
40320
40256
  }
@@ -40329,8 +40265,8 @@ function readLastTurnSummary(agentDir) {
40329
40265
  }
40330
40266
  function consumeHandoffTopic(agentDir) {
40331
40267
  const primary = readHandoffTopic(agentDir);
40332
- const primaryPath = join14(agentDir, HANDOFF_TOPIC_FILENAME);
40333
- const fallbackPath = join14(agentDir, LAST_TURN_SUMMARY_FILENAME);
40268
+ const primaryPath = join13(agentDir, HANDOFF_TOPIC_FILENAME);
40269
+ const fallbackPath = join13(agentDir, LAST_TURN_SUMMARY_FILENAME);
40334
40270
  const removeFallback = () => {
40335
40271
  try {
40336
40272
  unlinkSync2(fallbackPath);
@@ -40383,19 +40319,19 @@ function escapeMarkdownV2(s) {
40383
40319
  }
40384
40320
 
40385
40321
  // active-reactions.ts
40386
- import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, renameSync as renameSync3, existsSync as existsSync15, unlinkSync as unlinkSync3 } from "node:fs";
40387
- import { join as join15 } from "node:path";
40322
+ import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, renameSync as renameSync3, existsSync as existsSync14, unlinkSync as unlinkSync3 } from "node:fs";
40323
+ import { join as join14 } from "node:path";
40388
40324
  var ACTIVE_REACTIONS_FILENAME = ".active-reactions.json";
40389
40325
  function reactionsPath(agentDir) {
40390
- return join15(agentDir, ACTIVE_REACTIONS_FILENAME);
40326
+ return join14(agentDir, ACTIVE_REACTIONS_FILENAME);
40391
40327
  }
40392
40328
  function readActiveReactions(agentDir) {
40393
40329
  const p = reactionsPath(agentDir);
40394
- if (!existsSync15(p))
40330
+ if (!existsSync14(p))
40395
40331
  return [];
40396
40332
  let raw;
40397
40333
  try {
40398
- raw = readFileSync11(p, "utf-8");
40334
+ raw = readFileSync10(p, "utf-8");
40399
40335
  } catch {
40400
40336
  return [];
40401
40337
  }
@@ -40451,19 +40387,19 @@ function clearActiveReactions(agentDir) {
40451
40387
  }
40452
40388
 
40453
40389
  // active-reactions.ts
40454
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync8, renameSync as renameSync4, existsSync as existsSync16, unlinkSync as unlinkSync4 } from "node:fs";
40455
- import { join as join16 } from "node:path";
40390
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync8, renameSync as renameSync4, existsSync as existsSync15, unlinkSync as unlinkSync4 } from "node:fs";
40391
+ import { join as join15 } from "node:path";
40456
40392
  var ACTIVE_REACTIONS_FILENAME2 = ".active-reactions.json";
40457
40393
  function reactionsPath2(agentDir) {
40458
- return join16(agentDir, ACTIVE_REACTIONS_FILENAME2);
40394
+ return join15(agentDir, ACTIVE_REACTIONS_FILENAME2);
40459
40395
  }
40460
40396
  function readActiveReactions2(agentDir) {
40461
40397
  const p = reactionsPath2(agentDir);
40462
- if (!existsSync16(p))
40398
+ if (!existsSync15(p))
40463
40399
  return [];
40464
40400
  let raw;
40465
40401
  try {
40466
- raw = readFileSync12(p, "utf-8");
40402
+ raw = readFileSync11(p, "utf-8");
40467
40403
  } catch {
40468
40404
  return [];
40469
40405
  }
@@ -41321,6 +41257,154 @@ async function approvalRecord(args, opts) {
41321
41257
  return r.resp.decision_id;
41322
41258
  }
41323
41259
 
41260
+ // quota-check.ts
41261
+ import { readFileSync as readFileSync13, existsSync as existsSync17 } from "fs";
41262
+ import { join as join17 } from "path";
41263
+ var OAUTH_BETA2 = "oauth-2025-04-20";
41264
+ var DEFAULT_USER_AGENT2 = "claude-cli/1.0.0 (external, cli)";
41265
+ var DEFAULT_PROBE_MODEL2 = "claude-haiku-4-5-20251001";
41266
+ function readOauthToken2(claudeConfigDir) {
41267
+ const tokenFile = join17(claudeConfigDir, ".oauth-token");
41268
+ if (!existsSync17(tokenFile))
41269
+ return null;
41270
+ try {
41271
+ const raw = readFileSync13(tokenFile, "utf-8").trim();
41272
+ return raw.length > 0 ? raw : null;
41273
+ } catch {
41274
+ return null;
41275
+ }
41276
+ }
41277
+ function parseFloatHeader2(headers, name) {
41278
+ const v = headers.get(name);
41279
+ if (v == null || v.trim().length === 0)
41280
+ return null;
41281
+ const n = Number(v);
41282
+ return Number.isFinite(n) ? n : null;
41283
+ }
41284
+ function parseEpochHeader2(headers, name) {
41285
+ const v = headers.get(name);
41286
+ if (v == null)
41287
+ return null;
41288
+ const n = Number(v);
41289
+ if (!Number.isFinite(n) || n <= 0)
41290
+ return null;
41291
+ return new Date(n * 1000);
41292
+ }
41293
+ function parseQuotaHeaders2(headers) {
41294
+ const fiveHour = parseFloatHeader2(headers, "anthropic-ratelimit-unified-5h-utilization");
41295
+ const sevenDay = parseFloatHeader2(headers, "anthropic-ratelimit-unified-7d-utilization");
41296
+ if (fiveHour == null && sevenDay == null) {
41297
+ return {
41298
+ ok: false,
41299
+ reason: "no unified rate-limit headers in response (API token, not OAuth?)"
41300
+ };
41301
+ }
41302
+ return {
41303
+ ok: true,
41304
+ data: {
41305
+ fiveHourUtilizationPct: (fiveHour ?? 0) * 100,
41306
+ sevenDayUtilizationPct: (sevenDay ?? 0) * 100,
41307
+ fiveHourResetAt: parseEpochHeader2(headers, "anthropic-ratelimit-unified-5h-reset"),
41308
+ sevenDayResetAt: parseEpochHeader2(headers, "anthropic-ratelimit-unified-7d-reset"),
41309
+ representativeClaim: headers.get("anthropic-ratelimit-unified-representative-claim"),
41310
+ overageStatus: headers.get("anthropic-ratelimit-unified-overage-status"),
41311
+ overageDisabledReason: headers.get("anthropic-ratelimit-unified-overage-disabled-reason")
41312
+ }
41313
+ };
41314
+ }
41315
+ async function fetchQuota2(opts) {
41316
+ let token;
41317
+ if (opts.accessToken && opts.claudeConfigDir) {
41318
+ return {
41319
+ ok: false,
41320
+ reason: "pass only one of `accessToken` or `claudeConfigDir`, not both"
41321
+ };
41322
+ }
41323
+ if (opts.accessToken) {
41324
+ token = opts.accessToken.trim().length > 0 ? opts.accessToken : null;
41325
+ } else if (opts.claudeConfigDir) {
41326
+ token = readOauthToken2(opts.claudeConfigDir);
41327
+ } else {
41328
+ return {
41329
+ ok: false,
41330
+ reason: "fetchQuota requires `accessToken` or `claudeConfigDir`"
41331
+ };
41332
+ }
41333
+ if (!token) {
41334
+ return { ok: false, reason: "no OAuth token at .oauth-token" };
41335
+ }
41336
+ const controller = new AbortController;
41337
+ const timeout = setTimeout(() => controller.abort(), opts.timeoutMs ?? 1e4);
41338
+ const fetchFn = opts.fetchImpl ?? fetch;
41339
+ let resp;
41340
+ try {
41341
+ resp = await fetchFn("https://api.anthropic.com/v1/messages", {
41342
+ method: "POST",
41343
+ headers: {
41344
+ "anthropic-version": "2023-06-01",
41345
+ "anthropic-beta": OAUTH_BETA2,
41346
+ authorization: `Bearer ${token}`,
41347
+ "x-app": "cli",
41348
+ "user-agent": DEFAULT_USER_AGENT2,
41349
+ "content-type": "application/json"
41350
+ },
41351
+ body: JSON.stringify({
41352
+ model: opts.model ?? DEFAULT_PROBE_MODEL2,
41353
+ max_tokens: 1,
41354
+ messages: [{ role: "user", content: "hi" }]
41355
+ }),
41356
+ signal: controller.signal
41357
+ });
41358
+ } catch (err) {
41359
+ const msg = err?.message ?? String(err);
41360
+ return { ok: false, reason: `request failed: ${msg}` };
41361
+ } finally {
41362
+ clearTimeout(timeout);
41363
+ }
41364
+ if (resp.status === 401 || resp.status === 403) {
41365
+ return { ok: false, reason: `auth rejected (HTTP ${resp.status})` };
41366
+ }
41367
+ const parsed = parseQuotaHeaders2(resp.headers);
41368
+ if (!parsed.ok && resp.status >= 400) {
41369
+ return { ok: false, reason: `HTTP ${resp.status}, ${parsed.reason}` };
41370
+ }
41371
+ return parsed;
41372
+ }
41373
+ function formatResetRelative2(target, now = new Date) {
41374
+ if (!target)
41375
+ return "\u2014";
41376
+ const deltaMs = target.getTime() - now.getTime();
41377
+ if (deltaMs <= 0)
41378
+ return "resets now";
41379
+ const totalMin = Math.round(deltaMs / 60000);
41380
+ if (totalMin < 60)
41381
+ return `resets in ${totalMin}m`;
41382
+ const hours = Math.floor(totalMin / 60);
41383
+ const mins = totalMin % 60;
41384
+ if (hours < 24)
41385
+ return mins > 0 ? `resets in ${hours}h ${mins}m` : `resets in ${hours}h`;
41386
+ const days = Math.floor(hours / 24);
41387
+ const remH = hours % 24;
41388
+ return remH > 0 ? `resets in ${days}d ${remH}h` : `resets in ${days}d`;
41389
+ }
41390
+ function formatQuotaBlock(q, now = new Date) {
41391
+ const lines = [];
41392
+ lines.push("<b>Claude plan quota</b>");
41393
+ lines.push("");
41394
+ lines.push(`<b>5h window</b> ${Math.round(q.fiveHourUtilizationPct)}% \u00b7 ${formatResetRelative2(q.fiveHourResetAt, now)}`);
41395
+ lines.push(`<b>7d window</b> ${Math.round(q.sevenDayUtilizationPct)}% \u00b7 ${formatResetRelative2(q.sevenDayResetAt, now)}`);
41396
+ if (q.representativeClaim) {
41397
+ lines.push("");
41398
+ lines.push(`<i>Binding window: ${q.representativeClaim.replace(/_/g, " ")}</i>`);
41399
+ }
41400
+ if (q.overageStatus && q.overageStatus !== "allowed") {
41401
+ const reason = q.overageDisabledReason ? ` (${q.overageDisabledReason})` : "";
41402
+ lines.push(`<i>Overage: ${q.overageStatus}${reason}</i>`);
41403
+ }
41404
+ return lines.join(`
41405
+ `);
41406
+ }
41407
+
41324
41408
  // auto-fallback.ts
41325
41409
  var DEFAULT_FALLBACK_COOLDOWN_MS = 2 * 60000;
41326
41410
  var LOCKOUT_FILE = "auto-fallback-lockout.json";
@@ -42004,8 +42088,8 @@ function mergeAgentConfig(defaultsIn, agentIn) {
42004
42088
  if (defaults.dangerous_mode !== undefined && merged.dangerous_mode === undefined) {
42005
42089
  merged.dangerous_mode = defaults.dangerous_mode;
42006
42090
  }
42007
- if (defaults.skip_permission_prompt !== undefined && merged.skip_permission_prompt === undefined) {
42008
- merged.skip_permission_prompt = defaults.skip_permission_prompt;
42091
+ if (defaults.network_isolation !== undefined && merged.network_isolation === undefined) {
42092
+ merged.network_isolation = defaults.network_isolation;
42009
42093
  }
42010
42094
  if (defaults.thinking_effort !== undefined && merged.thinking_effort === undefined) {
42011
42095
  merged.thinking_effort = defaults.thinking_effort;
@@ -42125,6 +42209,9 @@ function mergeAgentConfig(defaultsIn, agentIn) {
42125
42209
  }
42126
42210
  merged.session_continuity = combined;
42127
42211
  }
42212
+ if (merged.release === undefined && defaults.release !== undefined) {
42213
+ merged.release = defaults.release;
42214
+ }
42128
42215
  if (defaults.channels || merged.channels) {
42129
42216
  const dChan = defaults.channels ?? {};
42130
42217
  const aChan = merged.channels ?? {};
@@ -42256,7 +42343,9 @@ var UpdateApplyRequestSchema = exports_external.object({
42256
42343
  op: exports_external.literal("update_apply"),
42257
42344
  args: exports_external.object({
42258
42345
  skip_images: exports_external.boolean().optional(),
42259
- rebuild: exports_external.boolean().optional()
42346
+ rebuild: exports_external.boolean().optional(),
42347
+ channel: exports_external.enum(["dev", "rc", "latest"]).nullable().optional(),
42348
+ pin: exports_external.string().regex(/^(sha-[0-9a-f]{7,40}|v\d+\.\d+\.\d+)$/).nullable().optional()
42260
42349
  }).optional()
42261
42350
  });
42262
42351
  var ApplyRequestSchema = exports_external.object({
@@ -42419,7 +42508,7 @@ function isHostdEnabled() {
42419
42508
  return _hostdEnabled;
42420
42509
  try {
42421
42510
  const cfg = loadConfig();
42422
- _hostdEnabled = cfg.host_control?.enabled === true;
42511
+ _hostdEnabled = cfg.host_control?.enabled !== false;
42423
42512
  } catch {
42424
42513
  _hostdEnabled = false;
42425
42514
  }
@@ -43073,7 +43162,7 @@ function clampTtl(requested, fallback, min, max) {
43073
43162
 
43074
43163
  // gateway/diff-preview-card.ts
43075
43164
  var import_grammy5 = __toESM(require_mod2(), 1);
43076
- var REQUEST_ID_RE = /^[0-9a-f]{8}$/;
43165
+ var REQUEST_ID_RE = /^[0-9a-f]{32}$/;
43077
43166
  var PENDING_FILE_ID_SENTINEL = "pending-create";
43078
43167
  function buildDiffPreviewCard(input) {
43079
43168
  if (!REQUEST_ID_RE.test(input.suggestRequestId)) {
@@ -45402,8 +45491,211 @@ function determineRestartReason(opts) {
45402
45491
  // gateway/gateway.ts
45403
45492
  init_boot_card();
45404
45493
 
45494
+ // gateway/update-announce.ts
45495
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, openSync as openSync3, closeSync as closeSync3, readFileSync as readFileSync24 } from "node:fs";
45496
+ import { join as join24 } from "node:path";
45497
+ import { homedir as homedir10 } from "node:os";
45498
+
45499
+ // ../src/host-control/audit-reader.ts
45500
+ import { homedir as homedir9 } from "node:os";
45501
+ import { join as join23 } from "node:path";
45502
+ function defaultAuditLogPath(home2 = homedir9()) {
45503
+ return join23(home2, ".switchroom", "host-control-audit.log");
45504
+ }
45505
+ function parseAuditLine(line) {
45506
+ const trimmed = line.trim();
45507
+ if (trimmed.length === 0)
45508
+ return null;
45509
+ let obj;
45510
+ try {
45511
+ obj = JSON.parse(trimmed);
45512
+ } catch {
45513
+ return null;
45514
+ }
45515
+ if (typeof obj !== "object" || obj === null)
45516
+ return null;
45517
+ const o = obj;
45518
+ if (typeof o.ts !== "string" || typeof o.op !== "string")
45519
+ return null;
45520
+ if (typeof o.request_id !== "string" || typeof o.result !== "string")
45521
+ return null;
45522
+ if (typeof o.duration_ms !== "number")
45523
+ return null;
45524
+ const callerRaw = o.caller;
45525
+ let caller;
45526
+ if (callerRaw && callerRaw.kind === "agent" && typeof callerRaw.name === "string") {
45527
+ caller = { kind: "agent", name: callerRaw.name };
45528
+ } else if (callerRaw && callerRaw.kind === "operator") {
45529
+ caller = { kind: "operator" };
45530
+ } else {
45531
+ return null;
45532
+ }
45533
+ const exit_code = o.exit_code === null || typeof o.exit_code === "number" ? o.exit_code : null;
45534
+ const entry = {
45535
+ ts: o.ts,
45536
+ op: o.op,
45537
+ caller,
45538
+ request_id: o.request_id,
45539
+ result: o.result,
45540
+ exit_code,
45541
+ duration_ms: o.duration_ms
45542
+ };
45543
+ if (typeof o.error === "string")
45544
+ entry.error = o.error;
45545
+ if (typeof o.phase === "string")
45546
+ entry.phase = o.phase;
45547
+ if (typeof o.stdout_tail === "string")
45548
+ entry.stdout_tail = o.stdout_tail;
45549
+ if (typeof o.stderr_tail === "string")
45550
+ entry.stderr_tail = o.stderr_tail;
45551
+ if (typeof o.channel === "string")
45552
+ entry.channel = o.channel;
45553
+ if (typeof o.pin === "string")
45554
+ entry.pin = o.pin;
45555
+ if (o.resolved_sha && typeof o.resolved_sha === "object" && !Array.isArray(o.resolved_sha)) {
45556
+ const rs = {};
45557
+ for (const [k, v] of Object.entries(o.resolved_sha)) {
45558
+ if (typeof v === "string")
45559
+ rs[k] = v;
45560
+ }
45561
+ if (Object.keys(rs).length > 0)
45562
+ entry.resolved_sha = rs;
45563
+ }
45564
+ if (o.install_context && typeof o.install_context === "object" && !Array.isArray(o.install_context)) {
45565
+ const ic = o.install_context;
45566
+ if (typeof ic.install_type === "string" && typeof ic.detected_at === "string") {
45567
+ entry.install_context = {
45568
+ install_type: ic.install_type,
45569
+ detected_at: ic.detected_at
45570
+ };
45571
+ }
45572
+ }
45573
+ return entry;
45574
+ }
45575
+ function filterEntries(entries, filters) {
45576
+ return entries.filter((e) => {
45577
+ if (filters.agent != null) {
45578
+ if (e.caller.kind !== "agent")
45579
+ return false;
45580
+ if (e.caller.name !== filters.agent)
45581
+ return false;
45582
+ }
45583
+ if (filters.op != null && e.op !== filters.op)
45584
+ return false;
45585
+ if (filters.errorOnly) {
45586
+ if (e.result !== "error" && e.result !== "denied")
45587
+ return false;
45588
+ }
45589
+ return true;
45590
+ });
45591
+ }
45592
+ function readAndFilter(raw, filters, limit) {
45593
+ const lines = raw.split(`
45594
+ `);
45595
+ const parsed = [];
45596
+ for (const line of lines) {
45597
+ const e = parseAuditLine(line);
45598
+ if (e != null)
45599
+ parsed.push(e);
45600
+ }
45601
+ const filtered = filterEntries(parsed, filters);
45602
+ return filtered.slice(-Math.max(1, limit));
45603
+ }
45604
+
45605
+ // gateway/update-announce.ts
45606
+ var DEFAULT_LOOKBACK_MS = 10 * 60 * 1000;
45607
+ function readLastTerminalUpdateAudit(opts = {}) {
45608
+ const path = opts.auditLogPath ?? defaultAuditLogPath();
45609
+ const exists = opts.exists ?? existsSync25;
45610
+ const readFile = opts.readFile ?? ((p) => readFileSync24(p, "utf-8"));
45611
+ if (!exists(path))
45612
+ return null;
45613
+ let raw;
45614
+ try {
45615
+ raw = readFile(path);
45616
+ } catch {
45617
+ return null;
45618
+ }
45619
+ const recent = readAndFilter(raw, { op: "update_apply" }, 200);
45620
+ const now = opts.now ?? Date.now();
45621
+ const since = now - (opts.lookbackMs ?? DEFAULT_LOOKBACK_MS);
45622
+ let best = null;
45623
+ for (const e of recent) {
45624
+ if (e.phase !== "terminal")
45625
+ continue;
45626
+ const ts = Date.parse(e.ts);
45627
+ if (Number.isNaN(ts))
45628
+ continue;
45629
+ if (ts < since)
45630
+ continue;
45631
+ if (best == null || Date.parse(best.ts) < ts)
45632
+ best = e;
45633
+ }
45634
+ return best;
45635
+ }
45636
+ var RECOVERY_HINTS = {
45637
+ binary: "curl https://switchroom.ai/install.sh | sh && switchroom update",
45638
+ source: "cd ~/code/switchroom && git pull && bun install && bun run build && switchroom update",
45639
+ "source-unlinked": "cd ~/code/switchroom && bun link && switchroom update # ensures binary is in PATH first",
45640
+ docker: "docker compose -p switchroom pull && docker compose -p switchroom up -d",
45641
+ unknown: "Cannot auto-detect install type. Run `switchroom apply` to refresh ~/.switchroom/install-type.json, then retry."
45642
+ };
45643
+ function recoveryHint(installType) {
45644
+ if (!installType)
45645
+ return RECOVERY_HINTS.unknown;
45646
+ return RECOVERY_HINTS[installType] ?? RECOVERY_HINTS.unknown;
45647
+ }
45648
+ function shortSha(s) {
45649
+ return s.replace(/^sha256:/, "").slice(0, 12);
45650
+ }
45651
+ function renderUpdateOutcomeLine(entry) {
45652
+ const success = entry.exit_code === 0 && entry.result !== "error" && entry.result !== "denied";
45653
+ if (success) {
45654
+ const channel = entry.channel ? `channel:${entry.channel}` : entry.pin ? `pin:${entry.pin}` : "channel:?";
45655
+ let shaStr = "";
45656
+ if (entry.resolved_sha) {
45657
+ const firstSha = Object.values(entry.resolved_sha)[0];
45658
+ if (firstSha)
45659
+ shaStr = `, sha:${shortSha(firstSha)}`;
45660
+ }
45661
+ return `\u2705 update completed (${channel}${shaStr})`;
45662
+ }
45663
+ const stderrTail = (entry.stderr_tail ?? entry.error ?? "").slice(-400);
45664
+ const opStep = entry.op;
45665
+ const hint = recoveryHint(entry.install_context?.install_type);
45666
+ const lines = [`\u274c update failed at ${opStep}: ${stderrTail || "(no stderr captured)"}`, ` \u21b3 Recovery: ${hint}`];
45667
+ return lines.join(`
45668
+ `);
45669
+ }
45670
+ function claimUpdateAnnouncement(requestId, opts = {}) {
45671
+ const stateDir = opts.stateDir ?? process.env.TELEGRAM_STATE_DIR ?? join24(homedir10(), ".switchroom");
45672
+ const dir = join24(stateDir, "update-announced");
45673
+ try {
45674
+ mkdirSync13(dir, { recursive: true });
45675
+ } catch {
45676
+ return false;
45677
+ }
45678
+ const safeId = requestId.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 200);
45679
+ const path = join24(dir, safeId);
45680
+ try {
45681
+ const fd = openSync3(path, "wx");
45682
+ closeSync3(fd);
45683
+ return true;
45684
+ } catch {
45685
+ return false;
45686
+ }
45687
+ }
45688
+ function maybeRenderUpdateAnnouncement(opts = {}) {
45689
+ const entry = readLastTerminalUpdateAudit(opts);
45690
+ if (!entry)
45691
+ return null;
45692
+ if (!claimUpdateAnnouncement(entry.request_id, opts))
45693
+ return null;
45694
+ return renderUpdateOutcomeLine(entry);
45695
+ }
45696
+
45405
45697
  // issues-card.ts
45406
- import { readFileSync as readFileSync24, writeFileSync as writeFileSync15 } from "node:fs";
45698
+ import { readFileSync as readFileSync25, writeFileSync as writeFileSync15 } from "node:fs";
45407
45699
  var SEVERITY_EMOJI = {
45408
45700
  info: "\u2139\ufe0f",
45409
45701
  warn: "\u26a0\ufe0f",
@@ -45495,7 +45787,7 @@ function extractRetryAfterSecs(err) {
45495
45787
  var COOLDOWN_JITTER_MS = 500;
45496
45788
  function readPersistedMessageId(path, log) {
45497
45789
  try {
45498
- const raw = readFileSync24(path, "utf8");
45790
+ const raw = readFileSync25(path, "utf8");
45499
45791
  const parsed = JSON.parse(raw);
45500
45792
  const v = parsed.messageId;
45501
45793
  if (typeof v === "number" && Number.isInteger(v) && v > 0)
@@ -45604,24 +45896,24 @@ function createIssuesCardHandle(opts) {
45604
45896
  }
45605
45897
 
45606
45898
  // issues-watcher.ts
45607
- import { existsSync as existsSync26, statSync as statSync8 } from "node:fs";
45608
- import { join as join24 } from "node:path";
45899
+ import { existsSync as existsSync27, statSync as statSync8 } from "node:fs";
45900
+ import { join as join26 } from "node:path";
45609
45901
 
45610
45902
  // ../src/issues/store.ts
45611
45903
  import {
45612
- closeSync as closeSync3,
45613
- existsSync as existsSync25,
45614
- mkdirSync as mkdirSync13,
45615
- openSync as openSync3,
45904
+ closeSync as closeSync4,
45905
+ existsSync as existsSync26,
45906
+ mkdirSync as mkdirSync14,
45907
+ openSync as openSync4,
45616
45908
  readdirSync as readdirSync5,
45617
- readFileSync as readFileSync25,
45909
+ readFileSync as readFileSync26,
45618
45910
  renameSync as renameSync10,
45619
45911
  statSync as statSync7,
45620
45912
  unlinkSync as unlinkSync10,
45621
45913
  writeFileSync as writeFileSync16,
45622
45914
  writeSync
45623
45915
  } from "node:fs";
45624
- import { join as join23 } from "node:path";
45916
+ import { join as join25 } from "node:path";
45625
45917
  import { randomBytes as randomBytes4 } from "node:crypto";
45626
45918
  import { execSync } from "node:child_process";
45627
45919
 
@@ -45637,12 +45929,12 @@ var SEVERITY_RANK2 = {
45637
45929
  var ISSUES_FILE = "issues.jsonl";
45638
45930
  var ISSUES_LOCK = "issues.lock";
45639
45931
  function readAll(stateDir) {
45640
- const path = join23(stateDir, ISSUES_FILE);
45641
- if (!existsSync25(path))
45932
+ const path = join25(stateDir, ISSUES_FILE);
45933
+ if (!existsSync26(path))
45642
45934
  return [];
45643
45935
  let raw;
45644
45936
  try {
45645
- raw = readFileSync25(path, "utf-8");
45937
+ raw = readFileSync26(path, "utf-8");
45646
45938
  } catch {
45647
45939
  return [];
45648
45940
  }
@@ -45674,7 +45966,7 @@ function list(stateDir, opts = {}) {
45674
45966
  });
45675
45967
  }
45676
45968
  function resolve6(stateDir, fingerprint, nowFn = Date.now) {
45677
- if (!existsSync25(join23(stateDir, ISSUES_FILE)))
45969
+ if (!existsSync26(join25(stateDir, ISSUES_FILE)))
45678
45970
  return 0;
45679
45971
  return withLock(stateDir, () => {
45680
45972
  const all = readAll(stateDir);
@@ -45692,7 +45984,7 @@ function resolve6(stateDir, fingerprint, nowFn = Date.now) {
45692
45984
  });
45693
45985
  }
45694
45986
  function writeAll(stateDir, events) {
45695
- const path = join23(stateDir, ISSUES_FILE);
45987
+ const path = join25(stateDir, ISSUES_FILE);
45696
45988
  sweepOrphanTmpFiles(stateDir);
45697
45989
  const tmp = `${path}.tmp-${process.pid}-${randomBytes4(4).toString("hex")}`;
45698
45990
  const body = events.length === 0 ? "" : events.map((e) => JSON.stringify(e)).join(`
@@ -45714,7 +46006,7 @@ function sweepOrphanTmpFiles(stateDir) {
45714
46006
  for (const entry of entries) {
45715
46007
  if (!entry.startsWith(TMP_PREFIX))
45716
46008
  continue;
45717
- const tmpPath2 = join23(stateDir, entry);
46009
+ const tmpPath2 = join25(stateDir, entry);
45718
46010
  try {
45719
46011
  const stat = statSync7(tmpPath2);
45720
46012
  if (stat.mtimeMs < cutoff) {
@@ -45726,12 +46018,12 @@ function sweepOrphanTmpFiles(stateDir) {
45726
46018
  var LOCK_RETRY_MS = 25;
45727
46019
  var LOCK_TIMEOUT_MS = 1e4;
45728
46020
  function withLock(stateDir, fn) {
45729
- const lockPath = join23(stateDir, ISSUES_LOCK);
46021
+ const lockPath = join25(stateDir, ISSUES_LOCK);
45730
46022
  const startedAt = Date.now();
45731
46023
  let fd = null;
45732
46024
  while (fd === null) {
45733
46025
  try {
45734
- fd = openSync3(lockPath, "wx");
46026
+ fd = openSync4(lockPath, "wx");
45735
46027
  try {
45736
46028
  writeSync(fd, String(process.pid));
45737
46029
  } catch {}
@@ -45751,7 +46043,7 @@ function withLock(stateDir, fn) {
45751
46043
  return fn();
45752
46044
  } finally {
45753
46045
  try {
45754
- closeSync3(fd);
46046
+ closeSync4(fd);
45755
46047
  } catch {}
45756
46048
  try {
45757
46049
  unlinkSync10(lockPath);
@@ -45761,7 +46053,7 @@ function withLock(stateDir, fn) {
45761
46053
  function tryStealStaleLock(lockPath) {
45762
46054
  let pidStr;
45763
46055
  try {
45764
- pidStr = readFileSync25(lockPath, "utf-8").trim();
46056
+ pidStr = readFileSync26(lockPath, "utf-8").trim();
45765
46057
  } catch {
45766
46058
  return true;
45767
46059
  }
@@ -45811,7 +46103,7 @@ function isIssueEvent(v) {
45811
46103
  // issues-watcher.ts
45812
46104
  var DEFAULT_POLL_INTERVAL_MS2 = 2000;
45813
46105
  function startIssuesWatcher(opts) {
45814
- const path = join24(opts.stateDir, ISSUES_FILE);
46106
+ const path = join26(opts.stateDir, ISSUES_FILE);
45815
46107
  const log = opts.log ?? (() => {});
45816
46108
  const intervalMs = opts.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS2;
45817
46109
  const setIntervalFn = opts.setInterval ?? setInterval;
@@ -45859,7 +46151,7 @@ function startIssuesWatcher(opts) {
45859
46151
  };
45860
46152
  }
45861
46153
  function defaultSignatureProvider(path) {
45862
- if (!existsSync26(path))
46154
+ if (!existsSync27(path))
45863
46155
  return null;
45864
46156
  try {
45865
46157
  const stat = statSync8(path);
@@ -46048,8 +46340,8 @@ function skillBasenameFromPath2(input) {
46048
46340
  }
46049
46341
 
46050
46342
  // credits-watch.ts
46051
- import { readFileSync as readFileSync26, writeFileSync as writeFileSync17, existsSync as existsSync27, mkdirSync as mkdirSync14 } from "fs";
46052
- import { join as join25 } from "path";
46343
+ import { readFileSync as readFileSync27, writeFileSync as writeFileSync17, existsSync as existsSync28, mkdirSync as mkdirSync15 } from "fs";
46344
+ import { join as join27 } from "path";
46053
46345
  var STATE_FILE = "credits-watch.json";
46054
46346
  var FATAL_REASONS = new Set([
46055
46347
  "out_of_credits",
@@ -46061,12 +46353,12 @@ function emptyCreditState() {
46061
46353
  return { lastNotifiedReason: null, lastNotifiedAt: 0 };
46062
46354
  }
46063
46355
  function readClaudeJsonOverage(claudeConfigDir) {
46064
- const path = join25(claudeConfigDir, ".claude.json");
46065
- if (!existsSync27(path))
46356
+ const path = join27(claudeConfigDir, ".claude.json");
46357
+ if (!existsSync28(path))
46066
46358
  return null;
46067
46359
  let raw;
46068
46360
  try {
46069
- raw = readFileSync26(path, "utf-8");
46361
+ raw = readFileSync27(path, "utf-8");
46070
46362
  } catch {
46071
46363
  return null;
46072
46364
  }
@@ -46146,11 +46438,11 @@ function escapeHtml10(s) {
46146
46438
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
46147
46439
  }
46148
46440
  function loadCreditState(stateDir) {
46149
- const path = join25(stateDir, STATE_FILE);
46150
- if (!existsSync27(path))
46441
+ const path = join27(stateDir, STATE_FILE);
46442
+ if (!existsSync28(path))
46151
46443
  return emptyCreditState();
46152
46444
  try {
46153
- const raw = readFileSync26(path, "utf-8");
46445
+ const raw = readFileSync27(path, "utf-8");
46154
46446
  const parsed = JSON.parse(raw);
46155
46447
  if (parsed && typeof parsed === "object" && (parsed.lastNotifiedReason === null || typeof parsed.lastNotifiedReason === "string") && typeof parsed.lastNotifiedAt === "number" && Number.isFinite(parsed.lastNotifiedAt)) {
46156
46448
  return {
@@ -46162,55 +46454,55 @@ function loadCreditState(stateDir) {
46162
46454
  return emptyCreditState();
46163
46455
  }
46164
46456
  function saveCreditState(stateDir, state3) {
46165
- mkdirSync14(stateDir, { recursive: true });
46166
- const path = join25(stateDir, STATE_FILE);
46457
+ mkdirSync15(stateDir, { recursive: true });
46458
+ const path = join27(stateDir, STATE_FILE);
46167
46459
  writeFileSync17(path, JSON.stringify(state3, null, 2) + `
46168
46460
  `, { mode: 384 });
46169
46461
  }
46170
46462
 
46171
46463
  // gateway/turn-active-marker.ts
46172
46464
  import {
46173
- closeSync as closeSync4,
46174
- existsSync as existsSync28,
46175
- mkdirSync as mkdirSync15,
46176
- openSync as openSync4,
46177
- readFileSync as readFileSync27,
46465
+ closeSync as closeSync5,
46466
+ existsSync as existsSync29,
46467
+ mkdirSync as mkdirSync16,
46468
+ openSync as openSync5,
46469
+ readFileSync as readFileSync28,
46178
46470
  statSync as statSync9,
46179
46471
  unlinkSync as unlinkSync11,
46180
46472
  utimesSync as utimesSync2,
46181
46473
  writeFileSync as writeFileSync18
46182
46474
  } from "node:fs";
46183
- import { join as join26 } from "node:path";
46475
+ import { join as join28 } from "node:path";
46184
46476
  var TURN_ACTIVE_MARKER_FILE2 = "turn-active.json";
46185
46477
  function writeTurnActiveMarker(stateDir, marker) {
46186
46478
  try {
46187
- mkdirSync15(stateDir, { recursive: true });
46188
- writeFileSync18(join26(stateDir, TURN_ACTIVE_MARKER_FILE2), JSON.stringify(marker, null, 2) + `
46479
+ mkdirSync16(stateDir, { recursive: true });
46480
+ writeFileSync18(join28(stateDir, TURN_ACTIVE_MARKER_FILE2), JSON.stringify(marker, null, 2) + `
46189
46481
  `, { mode: 384 });
46190
46482
  } catch {}
46191
46483
  }
46192
46484
  function touchTurnActiveMarker2(stateDir) {
46193
- const path = join26(stateDir, TURN_ACTIVE_MARKER_FILE2);
46194
- if (!existsSync28(path))
46485
+ const path = join28(stateDir, TURN_ACTIVE_MARKER_FILE2);
46486
+ if (!existsSync29(path))
46195
46487
  return;
46196
46488
  const now = new Date;
46197
46489
  try {
46198
46490
  utimesSync2(path, now, now);
46199
46491
  } catch {
46200
46492
  try {
46201
- const fd = openSync4(path, "r+");
46202
- closeSync4(fd);
46493
+ const fd = openSync5(path, "r+");
46494
+ closeSync5(fd);
46203
46495
  } catch {}
46204
46496
  }
46205
46497
  }
46206
46498
  function removeTurnActiveMarker(stateDir) {
46207
46499
  try {
46208
- unlinkSync11(join26(stateDir, TURN_ACTIVE_MARKER_FILE2));
46500
+ unlinkSync11(join28(stateDir, TURN_ACTIVE_MARKER_FILE2));
46209
46501
  } catch {}
46210
46502
  }
46211
46503
  function sweepStaleTurnActiveMarker(stateDir, opts) {
46212
- const path = join26(stateDir, TURN_ACTIVE_MARKER_FILE2);
46213
- if (!existsSync28(path))
46504
+ const path = join28(stateDir, TURN_ACTIVE_MARKER_FILE2);
46505
+ if (!existsSync29(path))
46214
46506
  return false;
46215
46507
  const now = opts.now ?? Date.now();
46216
46508
  try {
@@ -46222,7 +46514,7 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
46222
46514
  return false;
46223
46515
  let payload = null;
46224
46516
  try {
46225
- payload = readFileSync27(path, "utf8");
46517
+ payload = readFileSync28(path, "utf8");
46226
46518
  } catch {}
46227
46519
  unlinkSync11(path);
46228
46520
  if (opts.onRemove) {
@@ -46241,10 +46533,10 @@ function sweepStaleTurnActiveMarker(stateDir, opts) {
46241
46533
  }
46242
46534
 
46243
46535
  // ../src/build-info.ts
46244
- var VERSION = "0.11.0";
46245
- var COMMIT_SHA = "abff20c7";
46246
- var COMMIT_DATE = "2026-05-15T16:50:03+10:00";
46247
- var LATEST_PR = 1335;
46536
+ var VERSION = "0.12.0";
46537
+ var COMMIT_SHA = "2870fb03";
46538
+ var COMMIT_DATE = "2026-05-17T08:03:22Z";
46539
+ var LATEST_PR = 1462;
46248
46540
  var COMMITS_AHEAD_OF_TAG = 0;
46249
46541
 
46250
46542
  // gateway/boot-version.ts
@@ -46309,17 +46601,16 @@ init_protocol2();
46309
46601
  init_peercred();
46310
46602
  import * as net4 from "node:net";
46311
46603
  import * as fs2 from "node:fs";
46312
- import { homedir as homedir9 } from "node:os";
46313
- import { join as join27 } from "node:path";
46604
+ import { homedir as homedir11 } from "node:os";
46605
+ import { join as join29 } from "node:path";
46314
46606
  var DEFAULT_TIMEOUT_MS4 = 2000;
46315
- var LEGACY_SOCKET_PATH2 = join27(homedir9(), ".switchroom", "vault-broker.sock");
46316
- var OPERATOR_SOCKET_PATH2 = join27(homedir9(), ".switchroom", "broker-operator", "sock");
46607
+ var LEGACY_SOCKET_PATH2 = join29(homedir11(), ".switchroom", "vault-broker.sock");
46608
+ var OPERATOR_SOCKET_PATH2 = join29(homedir11(), ".switchroom", "broker-operator", "sock");
46317
46609
  function defaultBrokerSocketPath2() {
46318
- if (isDockerRuntime()) {
46319
- if (fs2.existsSync(OPERATOR_SOCKET_PATH2))
46320
- return OPERATOR_SOCKET_PATH2;
46610
+ if (fs2.existsSync(OPERATOR_SOCKET_PATH2))
46611
+ return OPERATOR_SOCKET_PATH2;
46612
+ if (isDockerRuntime())
46321
46613
  return OPERATOR_SOCKET_PATH2;
46322
- }
46323
46614
  return LEGACY_SOCKET_PATH2;
46324
46615
  }
46325
46616
  function resolveBrokerSocketPath2(opts) {
@@ -46536,8 +46827,8 @@ function resolveVaultApprovalPosture(broker) {
46536
46827
  }
46537
46828
 
46538
46829
  // registry/turns-schema.ts
46539
- import { chmodSync as chmodSync3, mkdirSync as mkdirSync16 } from "fs";
46540
- import { join as join28 } from "path";
46830
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync17 } from "fs";
46831
+ import { join as join30 } from "path";
46541
46832
  var DatabaseClass2 = null;
46542
46833
  function loadDatabaseClass2() {
46543
46834
  if (DatabaseClass2 != null)
@@ -46596,9 +46887,9 @@ function applySchema(db2) {
46596
46887
  }
46597
46888
  function openTurnsDb(agentDir) {
46598
46889
  const Database = loadDatabaseClass2();
46599
- const dir = join28(agentDir, "telegram");
46600
- mkdirSync16(dir, { recursive: true, mode: 448 });
46601
- const path = join28(dir, "registry.db");
46890
+ const dir = join30(agentDir, "telegram");
46891
+ mkdirSync17(dir, { recursive: true, mode: 448 });
46892
+ const path = join30(dir, "registry.db");
46602
46893
  const db2 = new Database(path, { create: true });
46603
46894
  applySchema(db2);
46604
46895
  try {
@@ -46737,11 +47028,11 @@ installGlobalErrorHandlers();
46737
47028
  process.on("beforeExit", () => {
46738
47029
  shutdownAnalytics();
46739
47030
  });
46740
- var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join30(homedir10(), ".claude", "channels", "telegram");
46741
- var ACCESS_FILE = join30(STATE_DIR, "access.json");
46742
- var APPROVED_DIR = join30(STATE_DIR, "approved");
46743
- var ENV_FILE = join30(STATE_DIR, ".env");
46744
- var INBOX_DIR = join30(STATE_DIR, "inbox");
47031
+ var STATE_DIR = process.env.TELEGRAM_STATE_DIR ?? join32(homedir12(), ".claude", "channels", "telegram");
47032
+ var ACCESS_FILE = join32(STATE_DIR, "access.json");
47033
+ var APPROVED_DIR = join32(STATE_DIR, "approved");
47034
+ var ENV_FILE = join32(STATE_DIR, ".env");
47035
+ var INBOX_DIR = join32(STATE_DIR, "inbox");
46745
47036
  function triggerSelfRestart(targetAgent, reason, delayMs = 300) {
46746
47037
  const isDocker = process.env.SWITCHROOM_RUNTIME === "docker";
46747
47038
  const selfAgent = process.env.SWITCHROOM_AGENT_NAME;
@@ -46806,7 +47097,7 @@ function formatBootVersion() {
46806
47097
  }
46807
47098
  try {
46808
47099
  chmodSync5(ENV_FILE, 384);
46809
- for (const line of readFileSync30(ENV_FILE, "utf8").split(`
47100
+ for (const line of readFileSync31(ENV_FILE, "utf8").split(`
46810
47101
  `)) {
46811
47102
  const m = line.match(/^(\w+)=(.*)$/);
46812
47103
  if (m && process.env[m[1]] === undefined)
@@ -46859,7 +47150,7 @@ installTgPostLogger(bot);
46859
47150
  var _rawSendMessageDraft = bot.api.raw.sendMessageDraft;
46860
47151
  var GRAMMY_VERSION = (() => {
46861
47152
  try {
46862
- const raw = readFileSync30(new URL("../../node_modules/grammy/package.json", import.meta.url), "utf8");
47153
+ const raw = readFileSync31(new URL("../../node_modules/grammy/package.json", import.meta.url), "utf8");
46863
47154
  return JSON.parse(raw).version ?? "unknown";
46864
47155
  } catch {
46865
47156
  return "unknown";
@@ -46932,7 +47223,7 @@ function assertSendable(f) {
46932
47223
  } catch {
46933
47224
  throw new Error(`refusing to send file \u2014 cannot resolve real path: ${f}`);
46934
47225
  }
46935
- const inbox = join30(stateReal, "inbox");
47226
+ const inbox = join32(stateReal, "inbox");
46936
47227
  if (real.startsWith(stateReal + sep3) && !real.startsWith(inbox + sep3)) {
46937
47228
  throw new Error(`refusing to send channel state: ${f}`);
46938
47229
  }
@@ -46951,7 +47242,7 @@ function assertSendable(f) {
46951
47242
  }
46952
47243
  function readAccessFile() {
46953
47244
  try {
46954
- const raw = readFileSync30(ACCESS_FILE, "utf8");
47245
+ const raw = readFileSync31(ACCESS_FILE, "utf8");
46955
47246
  const parsed = JSON.parse(raw);
46956
47247
  const allowFrom = validateStringArray("allowFrom", parsed.allowFrom ?? []);
46957
47248
  const groups = {};
@@ -47016,7 +47307,7 @@ function assertAllowedChat(chat_id) {
47016
47307
  function saveAccess(a) {
47017
47308
  if (STATIC)
47018
47309
  return;
47019
- mkdirSync20(STATE_DIR, { recursive: true, mode: 448 });
47310
+ mkdirSync21(STATE_DIR, { recursive: true, mode: 448 });
47020
47311
  const tmp = ACCESS_FILE + ".tmp";
47021
47312
  writeFileSync21(tmp, JSON.stringify(a, null, 2) + `
47022
47313
  `, { mode: 384 });
@@ -47038,7 +47329,7 @@ var HISTORY_ENABLED = HISTORY_ACCESS.historyEnabled !== false;
47038
47329
  if (HISTORY_ENABLED) {
47039
47330
  try {
47040
47331
  initHistory(STATE_DIR, HISTORY_ACCESS.historyRetentionDays ?? 30);
47041
- process.stderr.write(`telegram gateway: history capture enabled at ${join30(STATE_DIR, "history.db")}
47332
+ process.stderr.write(`telegram gateway: history capture enabled at ${join32(STATE_DIR, "history.db")}
47042
47333
  `);
47043
47334
  } catch (err) {
47044
47335
  process.stderr.write(`telegram gateway: history init failed (${err.message}) \u2014 capture disabled
@@ -47055,10 +47346,10 @@ try {
47055
47346
  process.stderr.write(`telegram gateway: turn-registry boot-reaper stamped ${reaped} orphaned turn(s) as ended_via='restart'
47056
47347
  `);
47057
47348
  } else {
47058
- process.stderr.write(`telegram gateway: turn-registry initialized at ${join30(agentDir, "telegram", "registry.db")}
47349
+ process.stderr.write(`telegram gateway: turn-registry initialized at ${join32(agentDir, "telegram", "registry.db")}
47059
47350
  `);
47060
47351
  }
47061
- const pendingEnvPath = join30(agentDir, ".pending-turn.env");
47352
+ const pendingEnvPath = join32(agentDir, ".pending-turn.env");
47062
47353
  try {
47063
47354
  const pending = findMostRecentInterruptedTurn(turnsDb);
47064
47355
  if (pending != null) {
@@ -47078,7 +47369,7 @@ try {
47078
47369
  renameSync12(pendingEnvTmp, pendingEnvPath);
47079
47370
  process.stderr.write(`telegram gateway: pending-turn env written to ${pendingEnvPath} turnKey=${pending.turn_key} endedVia=${pending.ended_via ?? "open"}
47080
47371
  `);
47081
- } else if (existsSync32(pendingEnvPath)) {
47372
+ } else if (existsSync33(pendingEnvPath)) {
47082
47373
  rmSync4(pendingEnvPath, { force: true });
47083
47374
  process.stderr.write(`telegram gateway: pending-turn env cleared (clean previous shutdown)
47084
47375
  `);
@@ -47132,7 +47423,7 @@ function checkApprovals() {
47132
47423
  return;
47133
47424
  }
47134
47425
  for (const senderId of files) {
47135
- const file = join30(APPROVED_DIR, senderId);
47426
+ const file = join32(APPROVED_DIR, senderId);
47136
47427
  bot.api.sendMessage(senderId, "Paired! Say hi to Claude.").then(() => rmSync4(file, { force: true }), (err) => {
47137
47428
  process.stderr.write(`telegram gateway: failed to send approval confirm: ${err}
47138
47429
  `);
@@ -47778,11 +48069,11 @@ var unpinProgressCardForChat = null;
47778
48069
  var getPinnedProgressCardMessageId = null;
47779
48070
  var completeProgressCardTurn = null;
47780
48071
  var subagentWatcher = null;
47781
- var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join30(STATE_DIR, "gateway.sock");
47782
- mkdirSync20(STATE_DIR, { recursive: true, mode: 448 });
47783
- var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join30(STATE_DIR, "gateway.pid.json");
47784
- var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join30(STATE_DIR, "gateway-session.json");
47785
- var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join30(STATE_DIR, "clean-shutdown.json");
48072
+ var SOCKET_PATH = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join32(STATE_DIR, "gateway.sock");
48073
+ mkdirSync21(STATE_DIR, { recursive: true, mode: 448 });
48074
+ var GATEWAY_PID_PATH = process.env.SWITCHROOM_GATEWAY_PID_FILE ?? join32(STATE_DIR, "gateway.pid.json");
48075
+ var GATEWAY_SESSION_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_SESSION_MARKER ?? join32(STATE_DIR, "gateway-session.json");
48076
+ var GATEWAY_CLEAN_SHUTDOWN_MARKER_PATH = process.env.SWITCHROOM_GATEWAY_CLEAN_SHUTDOWN_MARKER ?? join32(STATE_DIR, "clean-shutdown.json");
47786
48077
  var GATEWAY_STARTED_AT_MS = Date.now();
47787
48078
  var BOOT_CARD_ENABLED = process.env.SWITCHROOM_BOOT_CARD !== "false";
47788
48079
  var activeBootCard = null;
@@ -47811,7 +48102,7 @@ function ensureIssuesCard(chatId, threadId) {
47811
48102
  bot: botApi,
47812
48103
  log: (msg) => process.stderr.write(`telegram gateway: ${msg}
47813
48104
  `),
47814
- persistPath: join30(stateDir, "issues-card.json")
48105
+ persistPath: join32(stateDir, "issues-card.json")
47815
48106
  });
47816
48107
  activeIssuesWatcher = startIssuesWatcher({
47817
48108
  stateDir,
@@ -47969,6 +48260,13 @@ var ipcServer = createIpcServer({
47969
48260
  const agentDisplayName = resolvePersonaName(agentSlug);
47970
48261
  const botApiForCard = wrapBootCardApi(threadId);
47971
48262
  bootCardPending = true;
48263
+ const updateOutcomeLine = (() => {
48264
+ try {
48265
+ return maybeRenderUpdateAnnouncement() ?? undefined;
48266
+ } catch {
48267
+ return;
48268
+ }
48269
+ })();
47972
48270
  startBootCard(chatId, threadId, botApiForCard, {
47973
48271
  agentName: agentDisplayName,
47974
48272
  agentSlug,
@@ -47979,8 +48277,10 @@ var ipcServer = createIpcServer({
47979
48277
  restartAgeMs: markerAgeMs,
47980
48278
  restartReasonDetail: cleanMarker?.reason,
47981
48279
  loadAccounts: () => loadAccountsForBootCard(agentSlug),
48280
+ probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
47982
48281
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
47983
- dockerMode: process.env.SWITCHROOM_RUNTIME === "docker"
48282
+ dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
48283
+ ...updateOutcomeLine ? { updateOutcomeLine } : {}
47984
48284
  }, ackMsgId).then((handle) => {
47985
48285
  activeBootCard = handle;
47986
48286
  }).catch((err) => {
@@ -48475,6 +48775,17 @@ ${url}`;
48475
48775
  previewMessageId = null;
48476
48776
  }
48477
48777
  }
48778
+ const sendChunkPlainText = async (opts) => {
48779
+ const plainOpts = { ...opts };
48780
+ delete plainOpts.parse_mode;
48781
+ const stripped = telegramHtmlToPlainText(chunks[i]);
48782
+ const plain = stripped.length > 0 ? stripped : "\u26A0\uFE0F (a formatted fragment could not be rendered for Telegram)";
48783
+ const sent = await lockedBot.api.sendMessage(chat_id, plain, plainOpts);
48784
+ sentIds.push(sent.message_id);
48785
+ logOutbound("reply", chat_id, sent.message_id, plain.length, `chunk=${i + 1}/${chunks.length} plaintext-fallback`);
48786
+ process.stderr.write(`telegram gateway: HTML parse-reject \u2014 resent chunk ${i + 1}/${chunks.length} as plain text
48787
+ `);
48788
+ };
48478
48789
  try {
48479
48790
  const sent = await robustApiCall(() => lockedBot.api.sendMessage(chat_id, chunks[i], sendOpts), { threadId, chat_id });
48480
48791
  sentIds.push(sent.message_id);
@@ -48484,8 +48795,17 @@ ${url}`;
48484
48795
  threadId = undefined;
48485
48796
  const retryOpts = { ...sendOpts };
48486
48797
  delete retryOpts.message_thread_id;
48487
- const sent = await lockedBot.api.sendMessage(chat_id, chunks[i], retryOpts);
48488
- sentIds.push(sent.message_id);
48798
+ try {
48799
+ const sent = await lockedBot.api.sendMessage(chat_id, chunks[i], retryOpts);
48800
+ sentIds.push(sent.message_id);
48801
+ } catch (retryErr) {
48802
+ if (isHtmlParseRejectError(retryErr))
48803
+ await sendChunkPlainText(retryOpts);
48804
+ else
48805
+ throw retryErr;
48806
+ }
48807
+ } else if (isHtmlParseRejectError(err)) {
48808
+ await sendChunkPlainText(sendOpts);
48489
48809
  } else {
48490
48810
  throw err;
48491
48811
  }
@@ -48945,11 +49265,11 @@ async function executeSendGif(rawArgs) {
48945
49265
  };
48946
49266
  }
48947
49267
  async function publishToTelegraph(text, shortName, authorName) {
48948
- const accountPath = join30(STATE_DIR, "telegraph-account.json");
49268
+ const accountPath = join32(STATE_DIR, "telegraph-account.json");
48949
49269
  let account = null;
48950
49270
  try {
48951
- if (existsSync32(accountPath)) {
48952
- const raw = readFileSync30(accountPath, "utf-8");
49271
+ if (existsSync33(accountPath)) {
49272
+ const raw = readFileSync31(accountPath, "utf-8");
48953
49273
  const parsed = JSON.parse(raw);
48954
49274
  if (parsed.shortName && parsed.accessToken) {
48955
49275
  account = parsed;
@@ -48968,7 +49288,7 @@ async function publishToTelegraph(text, shortName, authorName) {
48968
49288
  }
48969
49289
  account = created.value;
48970
49290
  try {
48971
- mkdirSync20(STATE_DIR, { recursive: true, mode: 448 });
49291
+ mkdirSync21(STATE_DIR, { recursive: true, mode: 448 });
48972
49292
  writeFileSync21(accountPath, JSON.stringify(account, null, 2), { mode: 384 });
48973
49293
  } catch (err) {
48974
49294
  process.stderr.write(`telegram gateway: telegraph cache write failed: ${err.message}
@@ -49194,7 +49514,7 @@ async function executeDownloadAttachment(args) {
49194
49514
  fileUniqueId: file.file_unique_id,
49195
49515
  now: Date.now()
49196
49516
  });
49197
- mkdirSync20(INBOX_DIR, { recursive: true, mode: 448 });
49517
+ mkdirSync21(INBOX_DIR, { recursive: true, mode: 448 });
49198
49518
  assertInsideInbox(INBOX_DIR, dlPath);
49199
49519
  writeFileSync21(dlPath, buf, { mode: 384 });
49200
49520
  return { content: [{ type: "text", text: dlPath }] };
@@ -50786,7 +51106,7 @@ function restartMarkerPath() {
50786
51106
  const agentDir = resolveAgentDirFromEnv();
50787
51107
  if (!agentDir)
50788
51108
  return null;
50789
- return join30(agentDir, "restart-pending.json");
51109
+ return join32(agentDir, "restart-pending.json");
50790
51110
  }
50791
51111
  function writeRestartMarker(marker) {
50792
51112
  const p = restartMarkerPath();
@@ -50812,7 +51132,7 @@ function readRestartMarker() {
50812
51132
  if (!p)
50813
51133
  return null;
50814
51134
  try {
50815
- return JSON.parse(readFileSync30(p, "utf8"));
51135
+ return JSON.parse(readFileSync31(p, "utf8"));
50816
51136
  } catch {
50817
51137
  return null;
50818
51138
  }
@@ -50881,7 +51201,7 @@ var _dockerReachable;
50881
51201
  function isDockerReachable() {
50882
51202
  if (_dockerReachable !== undefined)
50883
51203
  return _dockerReachable;
50884
- if (!existsSync32("/var/run/docker.sock")) {
51204
+ if (!existsSync33("/var/run/docker.sock")) {
50885
51205
  _dockerReachable = false;
50886
51206
  return _dockerReachable;
50887
51207
  }
@@ -50898,11 +51218,11 @@ function _resetDockerReachableCache() {
50898
51218
  }
50899
51219
  function spawnSwitchroomDetached(args, onFailure) {
50900
51220
  const fullArgs = SWITCHROOM_CONFIG ? ["--config", SWITCHROOM_CONFIG, ...args] : args;
50901
- const logPath = join30(STATE_DIR, "detached-spawn.log");
51221
+ const logPath = join32(STATE_DIR, "detached-spawn.log");
50902
51222
  let outFd = null;
50903
51223
  try {
50904
- mkdirSync20(STATE_DIR, { recursive: true });
50905
- outFd = openSync7(logPath, "a");
51224
+ mkdirSync21(STATE_DIR, { recursive: true });
51225
+ outFd = openSync8(logPath, "a");
50906
51226
  writeFileSync21(logPath, `
50907
51227
  [${new Date().toISOString()}] spawn ${SWITCHROOM_CLI} ${fullArgs.join(" ")}
50908
51228
  `, { flag: "a" });
@@ -50917,7 +51237,7 @@ function spawnSwitchroomDetached(args, onFailure) {
50917
51237
  });
50918
51238
  if (outFd != null) {
50919
51239
  try {
50920
- closeSync7(outFd);
51240
+ closeSync8(outFd);
50921
51241
  } catch {}
50922
51242
  }
50923
51243
  if (onFailure) {
@@ -50929,7 +51249,7 @@ function spawnSwitchroomDetached(args, onFailure) {
50929
51249
  return;
50930
51250
  let tail = "";
50931
51251
  try {
50932
- const full = readFileSync30(logPath, "utf8");
51252
+ const full = readFileSync31(logPath, "utf8");
50933
51253
  tail = full.split(`
50934
51254
  `).slice(-30).join(`
50935
51255
  `).trim();
@@ -51244,27 +51564,37 @@ ${preBlock(formatSwitchroomOutput(detail))}`, { html: true });
51244
51564
  }
51245
51565
  }
51246
51566
  bot.use(async (ctx, next) => {
51247
- if (!AGENT_ADMIN && ctx.message?.text) {
51567
+ if (ctx.message?.text) {
51248
51568
  const myName = getMyAgentName();
51249
51569
  const decision = classifyAdminGate(ctx.message.text, myName);
51250
51570
  if (decision.action === "block") {
51251
- process.stderr.write(`telegram gateway: admin-gate blocked cmd=/${decision.cmd} agent=${process.env.SWITCHROOM_AGENT_NAME ?? "-"} reason=${decision.reason} (AGENT_ADMIN=false)
51252
- `);
51253
51571
  const cmdHtml = escapeHtmlForTg(`/${decision.cmd}`);
51254
51572
  const nameHtml = escapeHtmlForTg(myName);
51255
- const text = decision.reason === "other-agent" ? `\u26A0\uFE0F <code>${cmdHtml}</code> targeting another agent is an admin operation \u2014 this agent (<code>${nameHtml}</code>) isn't admin-flagged. Run it from an admin agent, or set <code>admin: true</code> for this agent in switchroom.yaml. (Self-restart is allowed: send <code>/restart</code> with no arg.)` : `\u26A0\uFE0F <code>${cmdHtml}</code> is an admin command \u2014 this agent (<code>${nameHtml}</code>) isn't admin-flagged. Run it from an admin agent, or set <code>admin: true</code> for this agent in switchroom.yaml.`;
51256
- await switchroomReply(ctx, text, { html: true });
51257
- return;
51573
+ const notFlagged = decision.reason === "other-agent" ? `\u26A0\uFE0F <code>${cmdHtml}</code> targeting another agent is an admin operation \u2014 this agent (<code>${nameHtml}</code>) isn't admin-flagged. Run it from an admin agent, or set <code>admin: true</code> for this agent in switchroom.yaml. (Self-restart is allowed: send <code>/restart</code> with no arg.)` : `\u26A0\uFE0F <code>${cmdHtml}</code> is an admin command \u2014 this agent (<code>${nameHtml}</code>) isn't admin-flagged. Run it from an admin agent, or set <code>admin: true</code> for this agent in switchroom.yaml.`;
51574
+ if (!AGENT_ADMIN) {
51575
+ process.stderr.write(`telegram gateway: admin-gate blocked cmd=/${decision.cmd} agent=${process.env.SWITCHROOM_AGENT_NAME ?? "-"} reason=${decision.reason} (AGENT_ADMIN=false)
51576
+ `);
51577
+ await switchroomReply(ctx, notFlagged, { html: true });
51578
+ return;
51579
+ }
51580
+ const senderId = String(ctx.from?.id ?? "");
51581
+ const operatorPrivate = ctx.chat?.type === "private" && loadAccess().allowFrom.includes(senderId);
51582
+ if (!operatorPrivate) {
51583
+ process.stderr.write(`telegram gateway: admin-gate refused (not operator-private) cmd=/${decision.cmd} agent=${process.env.SWITCHROOM_AGENT_NAME ?? "-"} chat=${ctx.chat?.type ?? "?"} sender=${senderId}
51584
+ `);
51585
+ await switchroomReply(ctx, `\u26A0\uFE0F <code>${cmdHtml}</code> is a fleet-admin command \u2014 it is <b>operator-private</b>. Send it as a direct message to me from your operator account (a private chat where your Telegram ID is on the access allowlist), not in a group or forum.`, { html: true });
51586
+ return;
51587
+ }
51258
51588
  }
51259
51589
  }
51260
51590
  await next();
51261
51591
  });
51262
51592
  function readRecentDenialsForAgent(agentName3, windowMs, limit) {
51263
51593
  try {
51264
- const auditPath = join30(homedir10(), ".switchroom", "vault-audit.log");
51265
- if (!existsSync32(auditPath))
51594
+ const auditPath = join32(homedir12(), ".switchroom", "vault-audit.log");
51595
+ if (!existsSync33(auditPath))
51266
51596
  return [];
51267
- const raw = readFileSync30(auditPath, "utf8");
51597
+ const raw = readFileSync31(auditPath, "utf8");
51268
51598
  return recentDenialsFromAuditLog(raw, { agentName: agentName3, windowMs, limit });
51269
51599
  } catch {
51270
51600
  return [];
@@ -51315,7 +51645,7 @@ async function buildAgentMetadata(agentName3) {
51315
51645
  try {
51316
51646
  const agentDir = resolveAgentDirFromEnv();
51317
51647
  if (agentDir) {
51318
- const raw = readFileSync30(join30(agentDir, ".claude", ".claude.json"), "utf8");
51648
+ const raw = readFileSync31(join32(agentDir, ".claude", ".claude.json"), "utf8");
51319
51649
  claudeJson = JSON.parse(raw);
51320
51650
  }
51321
51651
  } catch {}
@@ -51344,7 +51674,8 @@ async function buildLiveProbeRows(agentName3) {
51344
51674
  agentDir,
51345
51675
  gatewayInfo: { pid: process.pid, startedAtMs: GATEWAY_STARTED_AT_MS },
51346
51676
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
51347
- dockerMode: process.env.SWITCHROOM_RUNTIME === "docker"
51677
+ dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
51678
+ probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentName3, t)
51348
51679
  });
51349
51680
  const rows = [];
51350
51681
  const order = [
@@ -51528,9 +51859,9 @@ bot.command("restart", async (ctx) => {
51528
51859
  function flushAgentHandoff(agentDir) {
51529
51860
  let removed = 0;
51530
51861
  for (const fname of [".handoff.md", ".handoff-topic"]) {
51531
- const p = join30(agentDir, fname);
51862
+ const p = join32(agentDir, fname);
51532
51863
  try {
51533
- if (existsSync32(p)) {
51864
+ if (existsSync33(p)) {
51534
51865
  unlinkSync14(p);
51535
51866
  removed++;
51536
51867
  }
@@ -51586,7 +51917,7 @@ async function handleNewOrResetCommand(ctx, kind) {
51586
51917
  writeRestartMarker({ chat_id: chatId, thread_id: threadId ?? null, ack_message_id: ackId, ts: Date.now() });
51587
51918
  if (agentDir != null) {
51588
51919
  try {
51589
- writeFileSync21(join30(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
51920
+ writeFileSync21(join32(agentDir, ".force-fresh-session"), `${kind} at ${new Date().toISOString()}
51590
51921
  `, "utf8");
51591
51922
  } catch (err) {
51592
51923
  process.stderr.write(`telegram gateway: failed to write force-fresh marker: ${err}
@@ -51755,7 +52086,7 @@ bot.command("audit", async (ctx) => {
51755
52086
  return;
51756
52087
  const arg = (ctx.match ?? "").trim();
51757
52088
  if (arg === "" || arg === "help" || arg === "--help") {
51758
- await switchroomReply(ctx, "Usage: <code>/audit hostd [--tail N] [--agent &lt;name&gt;] [--op &lt;verb&gt;] [--error]</code>", { html: true });
52089
+ await switchroomReply(ctx, "Usage: <code>/audit hostd [--tail N] [--agent &lt;name&gt;] [--op &lt;verb&gt;] [--error] [--verbose]</code>", { html: true });
51759
52090
  return;
51760
52091
  }
51761
52092
  const tokens = arg.split(/\s+/);
@@ -51784,6 +52115,10 @@ bot.command("audit", async (ctx) => {
51784
52115
  argv.push("--error");
51785
52116
  continue;
51786
52117
  }
52118
+ if (t === "--verbose") {
52119
+ argv.push("--verbose");
52120
+ continue;
52121
+ }
51787
52122
  if (t === "--tail" || t === "--agent" || t === "--op") {
51788
52123
  const v = tokens[++i];
51789
52124
  if (v == null) {
@@ -51805,7 +52140,7 @@ bot.command("audit", async (ctx) => {
51805
52140
  argv.push(t, v);
51806
52141
  continue;
51807
52142
  }
51808
- await switchroomReply(ctx, `Unknown flag <code>${escapeHtmlForTg(t)}</code>. Allowed: <code>--tail</code>, <code>--agent</code>, <code>--op</code>, <code>--error</code>.`, { html: true });
52143
+ await switchroomReply(ctx, `Unknown flag <code>${escapeHtmlForTg(t)}</code>. Allowed: <code>--tail</code>, <code>--agent</code>, <code>--op</code>, <code>--error</code>, <code>--verbose</code>.`, { html: true });
51809
52144
  return;
51810
52145
  }
51811
52146
  await runSwitchroomCommand(ctx, argv, `hostd audit${argv.length > 2 ? " \u2026" : ""}`);
@@ -51926,16 +52261,16 @@ bot.command("interrupt", async (ctx) => {
51926
52261
  await runSwitchroomCommand(ctx, ["agent", "interrupt", name], `interrupt ${name}`);
51927
52262
  });
51928
52263
  var lockoutOps = {
51929
- readFileSync: (p, enc) => readFileSync30(p, enc),
52264
+ readFileSync: (p, enc) => readFileSync31(p, enc),
51930
52265
  writeFileSync: (p, data, opts) => writeFileSync21(p, data, opts),
51931
- existsSync: (p) => existsSync32(p),
51932
- mkdirSync: (p, opts) => mkdirSync20(p, opts),
51933
- joinPath: (...parts) => join30(...parts)
52266
+ existsSync: (p) => existsSync33(p),
52267
+ mkdirSync: (p, opts) => mkdirSync21(p, opts),
52268
+ joinPath: (...parts) => join32(...parts)
51934
52269
  };
51935
52270
  var FLEET_FALLBACK_DEDUP_MS = 30000;
51936
52271
  function isAuthBrokerSocketReachable() {
51937
52272
  try {
51938
- return existsSync32(resolveAuthBrokerSocketPath2());
52273
+ return existsSync33(resolveAuthBrokerSocketPath2());
51939
52274
  } catch {
51940
52275
  return false;
51941
52276
  }
@@ -51962,7 +52297,11 @@ async function doFireFleetAutoFallback(triggerAgent) {
51962
52297
  return false;
51963
52298
  }
51964
52299
  const state3 = await client3.listState();
51965
- const quotas = await Promise.all(state3.accounts.map((a) => fetchAccountQuota(a.label, { force: true })));
52300
+ const probeResp = state3.accounts.length > 0 ? await client3.probeQuota(state3.accounts.map((a) => a.label)).catch(() => ({ results: [] })) : { results: [] };
52301
+ const quotas = state3.accounts.map((a) => {
52302
+ const hit = probeResp.results.find((r) => r.label === a.label);
52303
+ return hit?.result ?? { ok: false, reason: "broker returned no result for account" };
52304
+ });
51966
52305
  const tz = process.env.SWITCHROOM_TIMEZONE ?? process.env.TZ ?? "UTC";
51967
52306
  const outcome = await runFleetAutoFallback({
51968
52307
  state: state3,
@@ -51992,7 +52331,7 @@ async function runCreditWatch() {
51992
52331
  if (!agentDir)
51993
52332
  return;
51994
52333
  const agentName3 = getMyAgentName();
51995
- const claudeConfigDir = join30(agentDir, ".claude");
52334
+ const claudeConfigDir = join32(agentDir, ".claude");
51996
52335
  const stateDir = STATE_DIR;
51997
52336
  const reason = readClaudeJsonOverage(claudeConfigDir);
51998
52337
  const prev = loadCreditState(stateDir);
@@ -52020,8 +52359,16 @@ async function runCreditWatch() {
52020
52359
  }
52021
52360
  }
52022
52361
  bot.command("auth", async (ctx) => {
52023
- if (!isAuthorizedSender(ctx))
52362
+ const authSenderId = String(ctx.from?.id ?? "");
52363
+ const authOperatorPrivate = ctx.chat?.type === "private" && loadAccess().allowFrom.includes(authSenderId);
52364
+ if (!authOperatorPrivate) {
52365
+ if (ctx.chat?.type !== "private") {
52366
+ process.stderr.write(`telegram gateway: /auth refused (not operator-private) agent=${process.env.SWITCHROOM_AGENT_NAME ?? "-"} chat=${ctx.chat?.type ?? "?"} sender=${authSenderId}
52367
+ `);
52368
+ await switchroomReply(ctx, `\u26A0\uFE0F <code>/auth</code> manages account credentials \u2014 it is <b>operator-private</b>. Send it as a direct message to me from your operator account (a private chat where your Telegram ID is on the access allowlist), not in a group or forum.`, { html: true }).catch(() => {});
52369
+ }
52024
52370
  return;
52371
+ }
52025
52372
  const text = ctx.message?.text ?? "";
52026
52373
  const parsed = parseAuthCommand(text);
52027
52374
  if (!parsed)
@@ -52087,7 +52434,20 @@ Send <code>/auth cancel</code> to abort.`, { html: true });
52087
52434
  isAdmin: isAdmin2,
52088
52435
  client: client3,
52089
52436
  chatId,
52090
- liveQuotas: async (accounts) => Promise.all(accounts.map((a) => fetchAccountQuota(a.label, { force: true }))),
52437
+ liveQuotas: async (accounts) => {
52438
+ try {
52439
+ const { results } = await client3.probeQuota(accounts.map((a) => a.label));
52440
+ return accounts.map((a) => {
52441
+ const hit = results.find((r) => r.label === a.label);
52442
+ if (!hit)
52443
+ return { ok: false, reason: "broker returned no result for account" };
52444
+ return hit.result;
52445
+ });
52446
+ } catch (err) {
52447
+ const reason = `broker probe-quota failed: ${err?.message ?? String(err)}`;
52448
+ return accounts.map(() => ({ ok: false, reason }));
52449
+ }
52450
+ },
52091
52451
  tz: process.env.SWITCHROOM_TIMEZONE ?? process.env.TZ
52092
52452
  });
52093
52453
  if (reply.keyboard && reply.keyboard.length > 0) {
@@ -52125,6 +52485,24 @@ async function loadAccountsForBootCard(agent) {
52125
52485
  return null;
52126
52486
  }
52127
52487
  }
52488
+ async function probeQuotaForBootCard(agent, timeoutMs) {
52489
+ try {
52490
+ const client3 = await getAuthBrokerClient(agent);
52491
+ if (!client3)
52492
+ return null;
52493
+ const state3 = await client3.listState();
52494
+ const entry = state3.agents.find((a) => a.name === agent);
52495
+ const label = entry?.override ?? entry?.account ?? state3.active;
52496
+ if (!label)
52497
+ return null;
52498
+ const { results } = await client3.probeQuota([label], timeoutMs);
52499
+ return results.find((r) => r.label === label)?.result ?? null;
52500
+ } catch (err) {
52501
+ process.stderr.write(`telegram gateway: boot-card quota probe failed: ${err?.message ?? String(err)}
52502
+ `);
52503
+ return null;
52504
+ }
52505
+ }
52128
52506
  async function handleVaultRecentDenialCallback(ctx, data) {
52129
52507
  const senderId = String(ctx.from?.id ?? "");
52130
52508
  const access = loadAccess();
@@ -52162,9 +52540,9 @@ async function handleVaultRecentDenialCallback(ctx, data) {
52162
52540
  return;
52163
52541
  }
52164
52542
  const { token, id } = result;
52165
- const tokenPath = join30(homedir10(), ".switchroom", "agents", agentName3, ".vault-token");
52543
+ const tokenPath = join32(homedir12(), ".switchroom", "agents", agentName3, ".vault-token");
52166
52544
  try {
52167
- mkdirSync20(join30(homedir10(), ".switchroom", "agents", agentName3), { recursive: true });
52545
+ mkdirSync21(join32(homedir12(), ".switchroom", "agents", agentName3), { recursive: true });
52168
52546
  writeFileSync21(tokenPath, token, { mode: 384 });
52169
52547
  } catch (err) {
52170
52548
  await switchroomReply(ctx, `<b>Grant created (${escapeHtmlForTg(id)}) but token write failed:</b> ${escapeHtmlForTg(String(err))}
@@ -52229,9 +52607,9 @@ async function performVaultAccessApproval(ctx, pending, stageId, senderId, attes
52229
52607
  return;
52230
52608
  }
52231
52609
  const { token, id } = result;
52232
- const tokenPath = join30(homedir10(), ".switchroom", "agents", pending.agent, ".vault-token");
52610
+ const tokenPath = join32(homedir12(), ".switchroom", "agents", pending.agent, ".vault-token");
52233
52611
  try {
52234
- mkdirSync20(join30(homedir10(), ".switchroom", "agents", pending.agent), { recursive: true });
52612
+ mkdirSync21(join32(homedir12(), ".switchroom", "agents", pending.agent), { recursive: true });
52235
52613
  writeFileSync21(tokenPath, token, { mode: 384 });
52236
52614
  } catch (err) {
52237
52615
  await switchroomReply(ctx, `<b>Grant created (${escapeHtmlForTg(id)}) but token write failed:</b> ${escapeHtmlForTg(String(err))}
@@ -52659,9 +53037,9 @@ async function executeGrantWizard(ctx, chatId, state3) {
52659
53037
  return;
52660
53038
  }
52661
53039
  const { token, id } = result;
52662
- const tokenPath = join30(homedir10(), ".switchroom", "agents", state3.agent, ".vault-token");
53040
+ const tokenPath = join32(homedir12(), ".switchroom", "agents", state3.agent, ".vault-token");
52663
53041
  try {
52664
- mkdirSync20(join30(homedir10(), ".switchroom", "agents", state3.agent), { recursive: true });
53042
+ mkdirSync21(join32(homedir12(), ".switchroom", "agents", state3.agent), { recursive: true });
52665
53043
  writeFileSync21(tokenPath, token, { mode: 384 });
52666
53044
  } catch (err) {
52667
53045
  await switchroomReply(ctx, `<b>Grant created but token write failed:</b> ${escapeHtmlForTg(String(err))}`, { html: true });
@@ -53095,7 +53473,11 @@ async function handleAuthDashboardCallback(ctx) {
53095
53473
  return;
53096
53474
  }
53097
53475
  const state3 = await client3.listState();
53098
- const quotas = await Promise.all(state3.accounts.map((a) => fetchAccountQuota(a.label, { force: true })));
53476
+ const probeResp = state3.accounts.length > 0 ? await client3.probeQuota(state3.accounts.map((a) => a.label)).catch(() => ({ results: [] })) : { results: [] };
53477
+ const quotas = state3.accounts.map((a) => {
53478
+ const hit = probeResp.results.find((r) => r.label === a.label);
53479
+ return hit?.result ?? { ok: false, reason: "broker returned no result for account" };
53480
+ });
53099
53481
  const tz = process.env.SWITCHROOM_TIMEZONE ?? process.env.TZ ?? "UTC";
53100
53482
  const { renderAuthSnapshotFormat2: renderAuthSnapshotFormat23, buildSnapshotsFromState: buildSnapshotsFromState3, buildSnapshotKeyboard: buildSnapshotKeyboard3 } = await Promise.resolve().then(() => (init_auth_snapshot_format(), exports_auth_snapshot_format));
53101
53483
  const snapshots = buildSnapshotsFromState3(state3, quotas);
@@ -53488,7 +53870,11 @@ bot.command("usage", async (ctx) => {
53488
53870
  if (client3) {
53489
53871
  const state3 = await client3.listState();
53490
53872
  if (state3.accounts.length > 0) {
53491
- const quotas = await Promise.all(state3.accounts.map((a) => fetchAccountQuota(a.label, { force: true })));
53873
+ const probeResp = await client3.probeQuota(state3.accounts.map((a) => a.label)).catch(() => ({ results: [] }));
53874
+ const quotas = state3.accounts.map((a) => {
53875
+ const hit = probeResp.results.find((r) => r.label === a.label);
53876
+ return hit?.result ?? { ok: false, reason: "broker returned no result for account" };
53877
+ });
53492
53878
  const { renderAuthSnapshotFormat2: renderAuthSnapshotFormat23, buildSnapshotsFromState: buildSnapshotsFromState3 } = await Promise.resolve().then(() => (init_auth_snapshot_format(), exports_auth_snapshot_format));
53493
53879
  const tz = process.env.SWITCHROOM_TIMEZONE ?? process.env.TZ ?? "UTC";
53494
53880
  const snapshots = buildSnapshotsFromState3(state3, quotas);
@@ -53510,7 +53896,7 @@ bot.command("usage", async (ctx) => {
53510
53896
  await switchroomReply(ctx, "<b>/usage:</b> cannot resolve agent dir.", { html: true });
53511
53897
  return;
53512
53898
  }
53513
- const result = await fetchQuota2({ claudeConfigDir: join30(agentDir, ".claude") });
53899
+ const result = await fetchQuota2({ claudeConfigDir: join32(agentDir, ".claude") });
53514
53900
  if (!result.ok) {
53515
53901
  await switchroomReply(ctx, `<b>/usage:</b> ${escapeHtmlForTg(result.reason)}`, { html: true });
53516
53902
  return;
@@ -53640,6 +54026,12 @@ bot.on("callback_query:data", async (ctx) => {
53640
54026
  return;
53641
54027
  }
53642
54028
  if (data.startsWith("apv:")) {
54029
+ const access2 = loadAccess();
54030
+ const senderId2 = String(ctx.from?.id ?? "");
54031
+ if (!access2.allowFrom.includes(senderId2)) {
54032
+ await ctx.answerCallbackQuery({ text: "Not authorized." });
54033
+ return;
54034
+ }
53643
54035
  const { handleApprovalCallback: handleApprovalCallback2 } = await Promise.resolve().then(() => (init_approval_callback(), exports_approval_callback));
53644
54036
  await handleApprovalCallback2(ctx, data);
53645
54037
  return;
@@ -53921,7 +54313,7 @@ bot.on("message:photo", async (ctx) => {
53921
54313
  fileUniqueId: best.file_unique_id,
53922
54314
  now: Date.now()
53923
54315
  });
53924
- mkdirSync20(INBOX_DIR, { recursive: true, mode: 448 });
54316
+ mkdirSync21(INBOX_DIR, { recursive: true, mode: 448 });
53925
54317
  assertInsideInbox(INBOX_DIR, dlPath);
53926
54318
  writeFileSync21(dlPath, buf, { mode: 384 });
53927
54319
  return dlPath;
@@ -53963,8 +54355,8 @@ async function maybeTranscribeVoice(fileId, mimeType, language) {
53963
54355
  let apiKey = null;
53964
54356
  try {
53965
54357
  const path = __require("path").join(__require("os").homedir(), ".switchroom", "openai-api-key");
53966
- if (existsSync32(path)) {
53967
- apiKey = readFileSync30(path, "utf-8").trim();
54358
+ if (existsSync33(path)) {
54359
+ apiKey = readFileSync31(path, "utf-8").trim();
53968
54360
  }
53969
54361
  } catch (err) {
53970
54362
  process.stderr.write(`telegram gateway: voice-in: failed to read api key: ${err.message}
@@ -54807,18 +55199,27 @@ var didOneTimeSetup = false;
54807
55199
  const botApiForCard = wrapBootCardApi(threadId);
54808
55200
  bootCardPending = true;
54809
55201
  try {
55202
+ const updateOutcomeLine = (() => {
55203
+ try {
55204
+ return maybeRenderUpdateAnnouncement() ?? undefined;
55205
+ } catch {
55206
+ return;
55207
+ }
55208
+ })();
54810
55209
  const handle = await startBootCard(chatId, threadId, botApiForCard, {
54811
55210
  agentName: agentDisplayName,
54812
55211
  agentSlug,
54813
55212
  version: formatBootVersion(),
54814
- agentDir: agentDir ?? join30(homedir10(), ".switchroom", "agents", agentSlug),
55213
+ agentDir: agentDir ?? join32(homedir12(), ".switchroom", "agents", agentSlug),
54815
55214
  gatewayInfo: { pid: process.pid, startedAtMs: GATEWAY_STARTED_AT_MS },
54816
55215
  restartReason: reason,
54817
55216
  restartAgeMs: markerAgeMs,
54818
55217
  restartReasonDetail: cleanMarker?.reason,
54819
55218
  loadAccounts: () => loadAccountsForBootCard(agentSlug),
55219
+ probeQuotaViaBroker: (t) => probeQuotaForBootCard(agentSlug, t),
54820
55220
  tmuxSupervisor: process.env.SWITCHROOM_TMUX_SUPERVISOR === "1",
54821
- dockerMode: process.env.SWITCHROOM_RUNTIME === "docker"
55221
+ dockerMode: process.env.SWITCHROOM_RUNTIME === "docker",
55222
+ ...updateOutcomeLine ? { updateOutcomeLine } : {}
54822
55223
  }, ackMsgId);
54823
55224
  activeBootCard = handle;
54824
55225
  } catch (err) {