switchroom 0.13.52 → 0.13.54

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 (39) hide show
  1. package/dist/agent-scheduler/index.js +399 -213
  2. package/dist/auth-broker/index.js +576 -237
  3. package/dist/cli/drive-write-pretool.mjs +28 -13
  4. package/dist/cli/ms-365-write-pretool.mjs +259 -0
  5. package/dist/cli/skill-validate-pretool.mjs +72 -72
  6. package/dist/cli/switchroom.js +3241 -1382
  7. package/dist/host-control/main.js +396 -276
  8. package/dist/vault/approvals/kernel-server.js +8266 -8142
  9. package/dist/vault/broker/server.js +2894 -2770
  10. package/package.json +1 -1
  11. package/profiles/_base/start.sh.hbs +17 -0
  12. package/profiles/_shared/telegram-style.md.hbs +2 -0
  13. package/skills/switchroom-status/SKILL.md +8 -6
  14. package/telegram-plugin/chat-lock.ts +87 -19
  15. package/telegram-plugin/dist/bridge/bridge.js +112 -112
  16. package/telegram-plugin/dist/gateway/gateway.js +1283 -343
  17. package/telegram-plugin/dist/server.js +160 -160
  18. package/telegram-plugin/gateway/disconnect-flush.ts +32 -0
  19. package/telegram-plugin/gateway/gateway.ts +485 -72
  20. package/telegram-plugin/gateway/inbound-coalesce.ts +19 -6
  21. package/telegram-plugin/gateway/ipc-protocol.ts +37 -0
  22. package/telegram-plugin/gateway/ipc-server.ts +59 -0
  23. package/telegram-plugin/gateway/ms365-write-approval.test.ts +314 -0
  24. package/telegram-plugin/gateway/ms365-write-approval.ts +335 -0
  25. package/telegram-plugin/stream-reply-handler.ts +10 -8
  26. package/telegram-plugin/tests/gateway-disconnect-flush.test.ts +116 -0
  27. package/telegram-plugin/tests/inbound-coalesce.test.ts +20 -4
  28. package/telegram-plugin/tests/ipc-validator.test.ts +61 -0
  29. package/telegram-plugin/tests/outbound-ordering.test.ts +228 -0
  30. package/telegram-plugin/tests/parallel-turns-deadlock-fix.test.ts +217 -0
  31. package/telegram-plugin/tests/slash-command-smart-split.test.ts +115 -0
  32. package/telegram-plugin/tests/typing-wrap.test.ts +65 -8
  33. package/telegram-plugin/typing-wrap.ts +43 -21
  34. package/vendor/hindsight-memory/scripts/lib/gateway_ipc.py +35 -0
  35. package/vendor/hindsight-memory/scripts/recall.py +164 -4
  36. package/vendor/hindsight-memory/scripts/retain.py +52 -0
  37. package/vendor/hindsight-memory/scripts/tests/test_gateway_ipc.py +42 -0
  38. package/vendor/hindsight-memory/scripts/tests/test_recall_topic_filter.py +139 -0
  39. package/profiles/default/CLAUDE.md +0 -122
@@ -16,7 +16,7 @@ var __export = (target, all) => {
16
16
  };
17
17
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
18
18
 
19
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
19
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
20
20
  var require_identity = __commonJS((exports) => {
21
21
  var ALIAS = Symbol.for("yaml.alias");
22
22
  var DOC = Symbol.for("yaml.document");
@@ -70,7 +70,7 @@ var require_identity = __commonJS((exports) => {
70
70
  exports.isSeq = isSeq;
71
71
  });
72
72
 
73
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
73
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
74
74
  var require_visit = __commonJS((exports) => {
75
75
  var identity = require_identity();
76
76
  var BREAK = Symbol("break visit");
@@ -225,7 +225,7 @@ var require_visit = __commonJS((exports) => {
225
225
  exports.visitAsync = visitAsync;
226
226
  });
227
227
 
228
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
228
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
229
229
  var require_directives = __commonJS((exports) => {
230
230
  var identity = require_identity();
231
231
  var visit = require_visit();
@@ -377,7 +377,7 @@ var require_directives = __commonJS((exports) => {
377
377
  exports.Directives = Directives;
378
378
  });
379
379
 
380
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
380
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
381
381
  var require_anchors = __commonJS((exports) => {
382
382
  var identity = require_identity();
383
383
  var visit = require_visit();
@@ -439,7 +439,7 @@ var require_anchors = __commonJS((exports) => {
439
439
  exports.findNewAnchor = findNewAnchor;
440
440
  });
441
441
 
442
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
442
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
443
443
  var require_applyReviver = __commonJS((exports) => {
444
444
  function applyReviver(reviver, obj, key, val) {
445
445
  if (val && typeof val === "object") {
@@ -486,7 +486,7 @@ var require_applyReviver = __commonJS((exports) => {
486
486
  exports.applyReviver = applyReviver;
487
487
  });
488
488
 
489
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
489
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
490
490
  var require_toJS = __commonJS((exports) => {
491
491
  var identity = require_identity();
492
492
  function toJS(value, arg, ctx) {
@@ -513,7 +513,7 @@ var require_toJS = __commonJS((exports) => {
513
513
  exports.toJS = toJS;
514
514
  });
515
515
 
516
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
516
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
517
517
  var require_Node = __commonJS((exports) => {
518
518
  var applyReviver = require_applyReviver();
519
519
  var identity = require_identity();
@@ -550,7 +550,7 @@ var require_Node = __commonJS((exports) => {
550
550
  exports.NodeBase = NodeBase;
551
551
  });
552
552
 
553
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
553
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
554
554
  var require_Alias = __commonJS((exports) => {
555
555
  var anchors = require_anchors();
556
556
  var visit = require_visit();
@@ -658,7 +658,7 @@ var require_Alias = __commonJS((exports) => {
658
658
  exports.Alias = Alias;
659
659
  });
660
660
 
661
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
661
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
662
662
  var require_Scalar = __commonJS((exports) => {
663
663
  var identity = require_identity();
664
664
  var Node = require_Node();
@@ -686,7 +686,7 @@ var require_Scalar = __commonJS((exports) => {
686
686
  exports.isScalarValue = isScalarValue;
687
687
  });
688
688
 
689
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
689
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
690
690
  var require_createNode = __commonJS((exports) => {
691
691
  var Alias = require_Alias();
692
692
  var identity = require_identity();
@@ -758,7 +758,7 @@ var require_createNode = __commonJS((exports) => {
758
758
  exports.createNode = createNode;
759
759
  });
760
760
 
761
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
761
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
762
762
  var require_Collection = __commonJS((exports) => {
763
763
  var createNode = require_createNode();
764
764
  var identity = require_identity();
@@ -873,7 +873,7 @@ var require_Collection = __commonJS((exports) => {
873
873
  exports.isEmptyPath = isEmptyPath;
874
874
  });
875
875
 
876
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
876
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
877
877
  var require_stringifyComment = __commonJS((exports) => {
878
878
  var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
879
879
  function indentComment(comment, indent) {
@@ -890,7 +890,7 @@ var require_stringifyComment = __commonJS((exports) => {
890
890
  exports.stringifyComment = stringifyComment;
891
891
  });
892
892
 
893
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
893
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
894
894
  var require_foldFlowLines = __commonJS((exports) => {
895
895
  var FOLD_FLOW = "flow";
896
896
  var FOLD_BLOCK = "block";
@@ -1027,7 +1027,7 @@ ${indent}${text.slice(fold + 1, end2)}`;
1027
1027
  exports.foldFlowLines = foldFlowLines;
1028
1028
  });
1029
1029
 
1030
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
1030
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
1031
1031
  var require_stringifyString = __commonJS((exports) => {
1032
1032
  var Scalar = require_Scalar();
1033
1033
  var foldFlowLines = require_foldFlowLines();
@@ -1325,7 +1325,7 @@ ${indent}`);
1325
1325
  exports.stringifyString = stringifyString;
1326
1326
  });
1327
1327
 
1328
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
1328
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
1329
1329
  var require_stringify = __commonJS((exports) => {
1330
1330
  var anchors = require_anchors();
1331
1331
  var identity = require_identity();
@@ -1446,7 +1446,7 @@ ${ctx.indent}${str}`;
1446
1446
  exports.stringify = stringify;
1447
1447
  });
1448
1448
 
1449
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
1449
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
1450
1450
  var require_stringifyPair = __commonJS((exports) => {
1451
1451
  var identity = require_identity();
1452
1452
  var Scalar = require_Scalar();
@@ -1582,7 +1582,7 @@ ${ctx.indent}`;
1582
1582
  exports.stringifyPair = stringifyPair;
1583
1583
  });
1584
1584
 
1585
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
1585
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
1586
1586
  var require_log = __commonJS((exports) => {
1587
1587
  var node_process = __require("process");
1588
1588
  function debug(logLevel, ...messages) {
@@ -1601,7 +1601,7 @@ var require_log = __commonJS((exports) => {
1601
1601
  exports.warn = warn;
1602
1602
  });
1603
1603
 
1604
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
1604
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
1605
1605
  var require_merge = __commonJS((exports) => {
1606
1606
  var identity = require_identity();
1607
1607
  var Scalar = require_Scalar();
@@ -1655,7 +1655,7 @@ var require_merge = __commonJS((exports) => {
1655
1655
  exports.merge = merge;
1656
1656
  });
1657
1657
 
1658
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
1658
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
1659
1659
  var require_addPairToJSMap = __commonJS((exports) => {
1660
1660
  var log = require_log();
1661
1661
  var merge = require_merge();
@@ -1716,7 +1716,7 @@ var require_addPairToJSMap = __commonJS((exports) => {
1716
1716
  exports.addPairToJSMap = addPairToJSMap;
1717
1717
  });
1718
1718
 
1719
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
1719
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
1720
1720
  var require_Pair = __commonJS((exports) => {
1721
1721
  var createNode = require_createNode();
1722
1722
  var stringifyPair = require_stringifyPair();
@@ -1754,7 +1754,7 @@ var require_Pair = __commonJS((exports) => {
1754
1754
  exports.createPair = createPair;
1755
1755
  });
1756
1756
 
1757
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
1757
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
1758
1758
  var require_stringifyCollection = __commonJS((exports) => {
1759
1759
  var identity = require_identity();
1760
1760
  var stringify = require_stringify();
@@ -1906,7 +1906,7 @@ ${indent}${end}`;
1906
1906
  exports.stringifyCollection = stringifyCollection;
1907
1907
  });
1908
1908
 
1909
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
1909
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
1910
1910
  var require_YAMLMap = __commonJS((exports) => {
1911
1911
  var stringifyCollection = require_stringifyCollection();
1912
1912
  var addPairToJSMap = require_addPairToJSMap();
@@ -2033,7 +2033,7 @@ var require_YAMLMap = __commonJS((exports) => {
2033
2033
  exports.findPair = findPair;
2034
2034
  });
2035
2035
 
2036
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
2036
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
2037
2037
  var require_map = __commonJS((exports) => {
2038
2038
  var identity = require_identity();
2039
2039
  var YAMLMap = require_YAMLMap();
@@ -2052,7 +2052,7 @@ var require_map = __commonJS((exports) => {
2052
2052
  exports.map = map;
2053
2053
  });
2054
2054
 
2055
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
2055
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
2056
2056
  var require_YAMLSeq = __commonJS((exports) => {
2057
2057
  var createNode = require_createNode();
2058
2058
  var stringifyCollection = require_stringifyCollection();
@@ -2145,7 +2145,7 @@ var require_YAMLSeq = __commonJS((exports) => {
2145
2145
  exports.YAMLSeq = YAMLSeq;
2146
2146
  });
2147
2147
 
2148
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
2148
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
2149
2149
  var require_seq = __commonJS((exports) => {
2150
2150
  var identity = require_identity();
2151
2151
  var YAMLSeq = require_YAMLSeq();
@@ -2164,7 +2164,7 @@ var require_seq = __commonJS((exports) => {
2164
2164
  exports.seq = seq;
2165
2165
  });
2166
2166
 
2167
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
2167
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
2168
2168
  var require_string = __commonJS((exports) => {
2169
2169
  var stringifyString = require_stringifyString();
2170
2170
  var string = {
@@ -2180,7 +2180,7 @@ var require_string = __commonJS((exports) => {
2180
2180
  exports.string = string;
2181
2181
  });
2182
2182
 
2183
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
2183
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
2184
2184
  var require_null = __commonJS((exports) => {
2185
2185
  var Scalar = require_Scalar();
2186
2186
  var nullTag = {
@@ -2195,7 +2195,7 @@ var require_null = __commonJS((exports) => {
2195
2195
  exports.nullTag = nullTag;
2196
2196
  });
2197
2197
 
2198
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
2198
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
2199
2199
  var require_bool = __commonJS((exports) => {
2200
2200
  var Scalar = require_Scalar();
2201
2201
  var boolTag = {
@@ -2216,7 +2216,7 @@ var require_bool = __commonJS((exports) => {
2216
2216
  exports.boolTag = boolTag;
2217
2217
  });
2218
2218
 
2219
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
2219
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
2220
2220
  var require_stringifyNumber = __commonJS((exports) => {
2221
2221
  function stringifyNumber({ format, minFractionDigits, tag, value }) {
2222
2222
  if (typeof value === "bigint")
@@ -2240,7 +2240,7 @@ var require_stringifyNumber = __commonJS((exports) => {
2240
2240
  exports.stringifyNumber = stringifyNumber;
2241
2241
  });
2242
2242
 
2243
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
2243
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
2244
2244
  var require_float = __commonJS((exports) => {
2245
2245
  var Scalar = require_Scalar();
2246
2246
  var stringifyNumber = require_stringifyNumber();
@@ -2283,7 +2283,7 @@ var require_float = __commonJS((exports) => {
2283
2283
  exports.floatNaN = floatNaN;
2284
2284
  });
2285
2285
 
2286
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
2286
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
2287
2287
  var require_int = __commonJS((exports) => {
2288
2288
  var stringifyNumber = require_stringifyNumber();
2289
2289
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -2325,7 +2325,7 @@ var require_int = __commonJS((exports) => {
2325
2325
  exports.intOct = intOct;
2326
2326
  });
2327
2327
 
2328
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
2328
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
2329
2329
  var require_schema = __commonJS((exports) => {
2330
2330
  var map = require_map();
2331
2331
  var _null = require_null();
@@ -2350,7 +2350,7 @@ var require_schema = __commonJS((exports) => {
2350
2350
  exports.schema = schema;
2351
2351
  });
2352
2352
 
2353
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
2353
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
2354
2354
  var require_schema2 = __commonJS((exports) => {
2355
2355
  var Scalar = require_Scalar();
2356
2356
  var map = require_map();
@@ -2414,7 +2414,7 @@ var require_schema2 = __commonJS((exports) => {
2414
2414
  exports.schema = schema;
2415
2415
  });
2416
2416
 
2417
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
2417
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
2418
2418
  var require_binary = __commonJS((exports) => {
2419
2419
  var node_buffer = __require("buffer");
2420
2420
  var Scalar = require_Scalar();
@@ -2469,7 +2469,7 @@ var require_binary = __commonJS((exports) => {
2469
2469
  exports.binary = binary;
2470
2470
  });
2471
2471
 
2472
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
2472
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
2473
2473
  var require_pairs = __commonJS((exports) => {
2474
2474
  var identity = require_identity();
2475
2475
  var Pair = require_Pair();
@@ -2544,7 +2544,7 @@ ${cn.comment}` : item.comment;
2544
2544
  exports.resolvePairs = resolvePairs;
2545
2545
  });
2546
2546
 
2547
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
2547
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
2548
2548
  var require_omap = __commonJS((exports) => {
2549
2549
  var identity = require_identity();
2550
2550
  var toJS = require_toJS();
@@ -2616,7 +2616,7 @@ var require_omap = __commonJS((exports) => {
2616
2616
  exports.omap = omap;
2617
2617
  });
2618
2618
 
2619
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
2619
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
2620
2620
  var require_bool2 = __commonJS((exports) => {
2621
2621
  var Scalar = require_Scalar();
2622
2622
  function boolStringify({ value, source }, ctx) {
@@ -2645,7 +2645,7 @@ var require_bool2 = __commonJS((exports) => {
2645
2645
  exports.trueTag = trueTag;
2646
2646
  });
2647
2647
 
2648
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
2648
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
2649
2649
  var require_float2 = __commonJS((exports) => {
2650
2650
  var Scalar = require_Scalar();
2651
2651
  var stringifyNumber = require_stringifyNumber();
@@ -2691,7 +2691,7 @@ var require_float2 = __commonJS((exports) => {
2691
2691
  exports.floatNaN = floatNaN;
2692
2692
  });
2693
2693
 
2694
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
2694
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
2695
2695
  var require_int2 = __commonJS((exports) => {
2696
2696
  var stringifyNumber = require_stringifyNumber();
2697
2697
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -2767,7 +2767,7 @@ var require_int2 = __commonJS((exports) => {
2767
2767
  exports.intOct = intOct;
2768
2768
  });
2769
2769
 
2770
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
2770
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
2771
2771
  var require_set = __commonJS((exports) => {
2772
2772
  var identity = require_identity();
2773
2773
  var Pair = require_Pair();
@@ -2850,7 +2850,7 @@ var require_set = __commonJS((exports) => {
2850
2850
  exports.set = set;
2851
2851
  });
2852
2852
 
2853
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
2853
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
2854
2854
  var require_timestamp = __commonJS((exports) => {
2855
2855
  var stringifyNumber = require_stringifyNumber();
2856
2856
  function parseSexagesimal(str, asBigInt) {
@@ -2932,7 +2932,7 @@ var require_timestamp = __commonJS((exports) => {
2932
2932
  exports.timestamp = timestamp;
2933
2933
  });
2934
2934
 
2935
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
2935
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
2936
2936
  var require_schema3 = __commonJS((exports) => {
2937
2937
  var map = require_map();
2938
2938
  var _null = require_null();
@@ -2973,7 +2973,7 @@ var require_schema3 = __commonJS((exports) => {
2973
2973
  exports.schema = schema;
2974
2974
  });
2975
2975
 
2976
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
2976
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
2977
2977
  var require_tags = __commonJS((exports) => {
2978
2978
  var map = require_map();
2979
2979
  var _null = require_null();
@@ -3064,7 +3064,7 @@ var require_tags = __commonJS((exports) => {
3064
3064
  exports.getTags = getTags;
3065
3065
  });
3066
3066
 
3067
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
3067
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
3068
3068
  var require_Schema = __commonJS((exports) => {
3069
3069
  var identity = require_identity();
3070
3070
  var map = require_map();
@@ -3094,7 +3094,7 @@ var require_Schema = __commonJS((exports) => {
3094
3094
  exports.Schema = Schema;
3095
3095
  });
3096
3096
 
3097
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
3097
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
3098
3098
  var require_stringifyDocument = __commonJS((exports) => {
3099
3099
  var identity = require_identity();
3100
3100
  var stringify = require_stringify();
@@ -3174,7 +3174,7 @@ var require_stringifyDocument = __commonJS((exports) => {
3174
3174
  exports.stringifyDocument = stringifyDocument;
3175
3175
  });
3176
3176
 
3177
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
3177
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
3178
3178
  var require_Document = __commonJS((exports) => {
3179
3179
  var Alias = require_Alias();
3180
3180
  var Collection = require_Collection();
@@ -3409,7 +3409,7 @@ var require_Document = __commonJS((exports) => {
3409
3409
  exports.Document = Document;
3410
3410
  });
3411
3411
 
3412
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
3412
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
3413
3413
  var require_errors = __commonJS((exports) => {
3414
3414
  class YAMLError extends Error {
3415
3415
  constructor(name, pos, code, message) {
@@ -3474,7 +3474,7 @@ ${pointer}
3474
3474
  exports.prettifyError = prettifyError;
3475
3475
  });
3476
3476
 
3477
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
3477
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
3478
3478
  var require_resolve_props = __commonJS((exports) => {
3479
3479
  function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
3480
3480
  let spaceBefore = false;
@@ -3604,7 +3604,7 @@ var require_resolve_props = __commonJS((exports) => {
3604
3604
  exports.resolveProps = resolveProps;
3605
3605
  });
3606
3606
 
3607
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
3607
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
3608
3608
  var require_util_contains_newline = __commonJS((exports) => {
3609
3609
  function containsNewline(key) {
3610
3610
  if (!key)
@@ -3644,7 +3644,7 @@ var require_util_contains_newline = __commonJS((exports) => {
3644
3644
  exports.containsNewline = containsNewline;
3645
3645
  });
3646
3646
 
3647
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
3647
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
3648
3648
  var require_util_flow_indent_check = __commonJS((exports) => {
3649
3649
  var utilContainsNewline = require_util_contains_newline();
3650
3650
  function flowIndentCheck(indent, fc, onError) {
@@ -3659,7 +3659,7 @@ var require_util_flow_indent_check = __commonJS((exports) => {
3659
3659
  exports.flowIndentCheck = flowIndentCheck;
3660
3660
  });
3661
3661
 
3662
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
3662
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
3663
3663
  var require_util_map_includes = __commonJS((exports) => {
3664
3664
  var identity = require_identity();
3665
3665
  function mapIncludes(ctx, items, search) {
@@ -3672,7 +3672,7 @@ var require_util_map_includes = __commonJS((exports) => {
3672
3672
  exports.mapIncludes = mapIncludes;
3673
3673
  });
3674
3674
 
3675
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
3675
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
3676
3676
  var require_resolve_block_map = __commonJS((exports) => {
3677
3677
  var Pair = require_Pair();
3678
3678
  var YAMLMap = require_YAMLMap();
@@ -3779,7 +3779,7 @@ var require_resolve_block_map = __commonJS((exports) => {
3779
3779
  exports.resolveBlockMap = resolveBlockMap;
3780
3780
  });
3781
3781
 
3782
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
3782
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
3783
3783
  var require_resolve_block_seq = __commonJS((exports) => {
3784
3784
  var YAMLSeq = require_YAMLSeq();
3785
3785
  var resolveProps = require_resolve_props();
@@ -3827,7 +3827,7 @@ var require_resolve_block_seq = __commonJS((exports) => {
3827
3827
  exports.resolveBlockSeq = resolveBlockSeq;
3828
3828
  });
3829
3829
 
3830
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
3830
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
3831
3831
  var require_resolve_end = __commonJS((exports) => {
3832
3832
  function resolveEnd(end, offset, reqSpace, onError) {
3833
3833
  let comment = "";
@@ -3867,7 +3867,7 @@ var require_resolve_end = __commonJS((exports) => {
3867
3867
  exports.resolveEnd = resolveEnd;
3868
3868
  });
3869
3869
 
3870
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
3870
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
3871
3871
  var require_resolve_flow_collection = __commonJS((exports) => {
3872
3872
  var identity = require_identity();
3873
3873
  var Pair = require_Pair();
@@ -4058,7 +4058,7 @@ var require_resolve_flow_collection = __commonJS((exports) => {
4058
4058
  exports.resolveFlowCollection = resolveFlowCollection;
4059
4059
  });
4060
4060
 
4061
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
4061
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
4062
4062
  var require_compose_collection = __commonJS((exports) => {
4063
4063
  var identity = require_identity();
4064
4064
  var Scalar = require_Scalar();
@@ -4120,7 +4120,7 @@ var require_compose_collection = __commonJS((exports) => {
4120
4120
  exports.composeCollection = composeCollection;
4121
4121
  });
4122
4122
 
4123
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
4123
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
4124
4124
  var require_resolve_block_scalar = __commonJS((exports) => {
4125
4125
  var Scalar = require_Scalar();
4126
4126
  function resolveBlockScalar(ctx, scalar, onError) {
@@ -4313,7 +4313,7 @@ var require_resolve_block_scalar = __commonJS((exports) => {
4313
4313
  exports.resolveBlockScalar = resolveBlockScalar;
4314
4314
  });
4315
4315
 
4316
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
4316
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
4317
4317
  var require_resolve_flow_scalar = __commonJS((exports) => {
4318
4318
  var Scalar = require_Scalar();
4319
4319
  var resolveEnd = require_resolve_end();
@@ -4529,7 +4529,7 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
4529
4529
  exports.resolveFlowScalar = resolveFlowScalar;
4530
4530
  });
4531
4531
 
4532
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
4532
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
4533
4533
  var require_compose_scalar = __commonJS((exports) => {
4534
4534
  var identity = require_identity();
4535
4535
  var Scalar = require_Scalar();
@@ -4607,7 +4607,7 @@ var require_compose_scalar = __commonJS((exports) => {
4607
4607
  exports.composeScalar = composeScalar;
4608
4608
  });
4609
4609
 
4610
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
4610
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
4611
4611
  var require_util_empty_scalar_position = __commonJS((exports) => {
4612
4612
  function emptyScalarPosition(offset, before, pos) {
4613
4613
  if (before) {
@@ -4634,7 +4634,7 @@ var require_util_empty_scalar_position = __commonJS((exports) => {
4634
4634
  exports.emptyScalarPosition = emptyScalarPosition;
4635
4635
  });
4636
4636
 
4637
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
4637
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
4638
4638
  var require_compose_node = __commonJS((exports) => {
4639
4639
  var Alias = require_Alias();
4640
4640
  var identity = require_identity();
@@ -4737,7 +4737,7 @@ var require_compose_node = __commonJS((exports) => {
4737
4737
  exports.composeNode = composeNode;
4738
4738
  });
4739
4739
 
4740
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
4740
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
4741
4741
  var require_compose_doc = __commonJS((exports) => {
4742
4742
  var Document = require_Document();
4743
4743
  var composeNode = require_compose_node();
@@ -4777,7 +4777,7 @@ var require_compose_doc = __commonJS((exports) => {
4777
4777
  exports.composeDoc = composeDoc;
4778
4778
  });
4779
4779
 
4780
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
4780
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
4781
4781
  var require_composer = __commonJS((exports) => {
4782
4782
  var node_process = __require("process");
4783
4783
  var directives = require_directives();
@@ -4966,7 +4966,7 @@ ${end.comment}` : end.comment;
4966
4966
  exports.Composer = Composer;
4967
4967
  });
4968
4968
 
4969
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
4969
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
4970
4970
  var require_cst_scalar = __commonJS((exports) => {
4971
4971
  var resolveBlockScalar = require_resolve_block_scalar();
4972
4972
  var resolveFlowScalar = require_resolve_flow_scalar();
@@ -5156,7 +5156,7 @@ var require_cst_scalar = __commonJS((exports) => {
5156
5156
  exports.setScalarValue = setScalarValue;
5157
5157
  });
5158
5158
 
5159
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
5159
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
5160
5160
  var require_cst_stringify = __commonJS((exports) => {
5161
5161
  var stringify = (cst) => ("type" in cst) ? stringifyToken(cst) : stringifyItem(cst);
5162
5162
  function stringifyToken(token) {
@@ -5214,7 +5214,7 @@ var require_cst_stringify = __commonJS((exports) => {
5214
5214
  exports.stringify = stringify;
5215
5215
  });
5216
5216
 
5217
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
5217
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
5218
5218
  var require_cst_visit = __commonJS((exports) => {
5219
5219
  var BREAK = Symbol("break visit");
5220
5220
  var SKIP = Symbol("skip children");
@@ -5273,7 +5273,7 @@ var require_cst_visit = __commonJS((exports) => {
5273
5273
  exports.visit = visit;
5274
5274
  });
5275
5275
 
5276
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
5276
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
5277
5277
  var require_cst = __commonJS((exports) => {
5278
5278
  var cstScalar = require_cst_scalar();
5279
5279
  var cstStringify = require_cst_stringify();
@@ -5374,7 +5374,7 @@ var require_cst = __commonJS((exports) => {
5374
5374
  exports.tokenType = tokenType;
5375
5375
  });
5376
5376
 
5377
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
5377
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
5378
5378
  var require_lexer = __commonJS((exports) => {
5379
5379
  var cst = require_cst();
5380
5380
  function isEmpty(ch) {
@@ -5960,7 +5960,7 @@ var require_lexer = __commonJS((exports) => {
5960
5960
  exports.Lexer = Lexer;
5961
5961
  });
5962
5962
 
5963
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
5963
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
5964
5964
  var require_line_counter = __commonJS((exports) => {
5965
5965
  class LineCounter {
5966
5966
  constructor() {
@@ -5988,7 +5988,7 @@ var require_line_counter = __commonJS((exports) => {
5988
5988
  exports.LineCounter = LineCounter;
5989
5989
  });
5990
5990
 
5991
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
5991
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
5992
5992
  var require_parser = __commonJS((exports) => {
5993
5993
  var node_process = __require("process");
5994
5994
  var cst = require_cst();
@@ -6837,7 +6837,7 @@ var require_parser = __commonJS((exports) => {
6837
6837
  exports.Parser = Parser;
6838
6838
  });
6839
6839
 
6840
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
6840
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
6841
6841
  var require_public_api = __commonJS((exports) => {
6842
6842
  var composer = require_composer();
6843
6843
  var Document = require_Document();
@@ -6939,7 +6939,7 @@ import { readFileSync as readFileSync2, existsSync as existsSync3 } from "node:f
6939
6939
  import { homedir } from "node:os";
6940
6940
  import { resolve as resolve3 } from "node:path";
6941
6941
 
6942
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
6942
+ // ../switchroom-sec-1417/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
6943
6943
  var composer = require_composer();
6944
6944
  var Document = require_Document();
6945
6945
  var Schema = require_Schema();
@@ -6985,7 +6985,7 @@ var $stringify = publicApi.stringify;
6985
6985
  var $visit = visit.visit;
6986
6986
  var $visitAsync = visit.visitAsync;
6987
6987
 
6988
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
6988
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
6989
6989
  var exports_external = {};
6990
6990
  __export(exports_external, {
6991
6991
  void: () => voidType,
@@ -7097,7 +7097,7 @@ __export(exports_external, {
7097
7097
  BRAND: () => BRAND
7098
7098
  });
7099
7099
 
7100
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
7100
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
7101
7101
  var util;
7102
7102
  (function(util2) {
7103
7103
  util2.assertEqual = (_) => {};
@@ -7228,7 +7228,7 @@ var getParsedType = (data) => {
7228
7228
  }
7229
7229
  };
7230
7230
 
7231
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
7231
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
7232
7232
  var ZodIssueCode = util.arrayToEnum([
7233
7233
  "invalid_type",
7234
7234
  "invalid_literal",
@@ -7347,7 +7347,7 @@ ZodError.create = (issues) => {
7347
7347
  return error;
7348
7348
  };
7349
7349
 
7350
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
7350
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
7351
7351
  var errorMap = (issue, _ctx) => {
7352
7352
  let message;
7353
7353
  switch (issue.code) {
@@ -7450,7 +7450,7 @@ var errorMap = (issue, _ctx) => {
7450
7450
  };
7451
7451
  var en_default = errorMap;
7452
7452
 
7453
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
7453
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
7454
7454
  var overrideErrorMap = en_default;
7455
7455
  function setErrorMap(map) {
7456
7456
  overrideErrorMap = map;
@@ -7458,7 +7458,7 @@ function setErrorMap(map) {
7458
7458
  function getErrorMap() {
7459
7459
  return overrideErrorMap;
7460
7460
  }
7461
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
7461
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
7462
7462
  var makeIssue = (params) => {
7463
7463
  const { data, path, errorMaps, issueData } = params;
7464
7464
  const fullPath = [...path, ...issueData.path || []];
@@ -7564,14 +7564,14 @@ var isAborted = (x) => x.status === "aborted";
7564
7564
  var isDirty = (x) => x.status === "dirty";
7565
7565
  var isValid = (x) => x.status === "valid";
7566
7566
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
7567
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
7567
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
7568
7568
  var errorUtil;
7569
7569
  (function(errorUtil2) {
7570
7570
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
7571
7571
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
7572
7572
  })(errorUtil || (errorUtil = {}));
7573
7573
 
7574
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
7574
+ // ../switchroom-sec-1417/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
7575
7575
  class ParseInputLazyPath {
7576
7576
  constructor(parent, value, path, key) {
7577
7577
  this._cachedPath = [];
@@ -10973,7 +10973,11 @@ var ScheduleEntrySchema = exports_external.object({
10973
10973
  cron: exports_external.string().describe("Cron expression (e.g., '0 8 * * *')"),
10974
10974
  prompt: exports_external.string().describe("Prompt to send at the scheduled time"),
10975
10975
  model: exports_external.string().optional().describe("DEPRECATED / IGNORED. Pre-v0.8 the singleton scheduler ran each " + "task as an isolated headless invocation 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 " + "— 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."),
10976
- 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 — 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 — " + "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.")
10976
+ 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 — 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 — " + "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."),
10977
+ topic: exports_external.union([
10978
+ exports_external.string().min(1, "topic alias must be non-empty"),
10979
+ exports_external.number().int().positive("topic ID must be a positive integer")
10980
+ ]).optional().describe("Forum topic this cron fires into when the owning agent is in " + "supergroup-owned mode (channels.telegram.chat_id set). Either a " + 'string alias resolved against `topic_aliases` (e.g. "planning") ' + "or a numeric topic ID. Falls back to the agent's `default_topic_id` " + "when unset. Ignored for agents in fleet-shared or dm_only mode. " + "Alias-resolution happens at config-load — typos surface immediately. " + "See docs/rfcs/supergroup-mode.md.")
10977
10981
  });
10978
10982
  var AgentSoulSchema = exports_external.object({
10979
10983
  name: exports_external.string().describe("Agent persona name (e.g., 'Coach', 'Sage')"),
@@ -10993,7 +10997,8 @@ var AgentMemorySchema = exports_external.object({
10993
10997
  recall: exports_external.object({
10994
10998
  max_memories: exports_external.number().int().min(0).optional().describe("Cap on the number of memories injected into the prompt by " + "auto-recall, regardless of token budget. Plugin default is 12. " + "0 disables the cap (all memories Hindsight returns are injected)."),
10995
10999
  cache_ttl_secs: exports_external.number().int().min(0).optional().describe("Per-session recall cache TTL in seconds. When > 0, identical " + "(prompt, bank) within the same session reuse the cached recall " + "result instead of round-tripping to Hindsight. 0 disables. " + "Default is 600 (10 min) for switchroom-managed agents."),
10996
- min_overlap: exports_external.number().min(0).max(1).optional().describe("Minimum Jaccard token overlap [0.0–1.0] between the user " + "prompt and a memory's text for the memory to be injected. " + "Drops low-relevance matches before the count cap so weak hits " + "don't fill the slot on real queries. 0.0 disables (default — " + "current behaviour). Try 0.10–0.20 to start; observe the " + "`overlap_dropped` field via `switchroom memory recall-log`.")
11000
+ min_overlap: exports_external.number().min(0).max(1).optional().describe("Minimum Jaccard token overlap [0.0–1.0] between the user " + "prompt and a memory's text for the memory to be injected. " + "Drops low-relevance matches before the count cap so weak hits " + "don't fill the slot on real queries. 0.0 disables (default — " + "current behaviour). Try 0.10–0.20 to start; observe the " + "`overlap_dropped` field via `switchroom memory recall-log`."),
11001
+ topic_filter_mode: exports_external.enum(["soft-preamble", "hard-filter"]).optional().describe("Supergroup-mode cross-topic memory behaviour. Default " + "(unset) → soft-preamble: recall returns memories from all " + "topics, and a 'Current topic: …' preamble tells the model " + "to self-scope. hard-filter: drop any recalled memory whose " + "metadata.thread_id differs from the active inbound's topic. " + "Flip to hard-filter when the recall_log shows binding " + "failures (model surfacing the right memory but applying " + "it to the wrong topic).")
10997
11002
  }).optional().describe("Auto-recall tuning knobs")
10998
11003
  }).optional();
10999
11004
  var HookEntrySchema = exports_external.object({
@@ -11085,8 +11090,35 @@ var TelegramChannelSchema = exports_external.object({
11085
11090
  }).optional().describe("Auto-dispatch rules: when a verified webhook event matches a rule, " + "inject the rendered prompt into the agent's live session (#1625). " + "Supports cooldowns, quiet hours, and label/action matchers. " + "Off by default — opt in per agent. See src/web/webhook-dispatch.ts."),
11086
11091
  webhook_rate_limit: exports_external.object({
11087
11092
  rpm: exports_external.number().int().positive()
11088
- }).optional().describe("Per-source rate limit for the webhook ingest path (#714). " + "Off by default — when this key is absent the handler skips " + "rate-limit checks entirely. Opt in by setting `rpm` to an " + "integer requests-per-minute (token bucket per (agent, source); " + "burst equal to rpm). When enabled, exceeding the limit returns " + "429 with Retry-After header; first throttle event per " + "(agent, source) per 60s window is written to " + "<agent>/telegram/issues.jsonl. " + "Cascades from defaults.channels.telegram.webhook_rate_limit.")
11089
- }).optional();
11093
+ }).optional().describe("Per-source rate limit for the webhook ingest path (#714). " + "Off by default — when this key is absent the handler skips " + "rate-limit checks entirely. Opt in by setting `rpm` to an " + "integer requests-per-minute (token bucket per (agent, source); " + "burst equal to rpm). When enabled, exceeding the limit returns " + "429 with Retry-After header; first throttle event per " + "(agent, source) per 60s window is written to " + "<agent>/telegram/issues.jsonl. " + "Cascades from defaults.channels.telegram.webhook_rate_limit."),
11094
+ chat_id: exports_external.string().regex(/^-\d+$/, 'supergroup chat_id must be a negative integer as a string (e.g. "-1001234567890")').optional().describe("Per-agent supergroup ID — overrides fleet `telegram.forum_chat_id`. " + "When set, requires `default_topic_id`. Negative integer as string. " + "Forbidden when `dm_only: true`. See docs/rfcs/supergroup-mode.md."),
11095
+ default_topic_id: exports_external.number().int().positive().optional().describe("Forum topic ID this agent's automated outbounds default to when " + "no more-specific alias resolves. Required when `chat_id` is set. " + "Telegram's General topic is `id=1` at MTProto but sends omit the " + "field — the outbound wrapper strips `message_thread_id === 1` " + "on send. Forbidden when `dm_only: true`."),
11096
+ topic_aliases: exports_external.record(exports_external.string(), exports_external.number().int().positive()).optional().describe("Operator-friendly names for forum topic IDs (e.g. " + "`{ general: 1, planning: 17, cron: 23, admin: 31, alerts: 41 }`). " + "Referenced from per-cron `topic:` fields and the outbound router " + "for autonomous events (boot → alerts, hostd → admin, etc.). " + "Cascades per-key through defaults → profile → agent.")
11097
+ }).optional().superRefine((tg, ctx) => {
11098
+ if (!tg)
11099
+ return;
11100
+ if (tg.chat_id != null && tg.default_topic_id == null) {
11101
+ ctx.addIssue({
11102
+ code: exports_external.ZodIssueCode.custom,
11103
+ message: "`channels.telegram.chat_id` requires `default_topic_id` — supergroup-mode agents need a fallback topic for unclassified outbounds.",
11104
+ path: ["default_topic_id"]
11105
+ });
11106
+ }
11107
+ if (tg.default_topic_id != null && tg.chat_id == null) {
11108
+ ctx.addIssue({
11109
+ code: exports_external.ZodIssueCode.custom,
11110
+ message: "`channels.telegram.default_topic_id` requires `chat_id` — default_topic_id is only meaningful when the agent owns its own supergroup.",
11111
+ path: ["chat_id"]
11112
+ });
11113
+ }
11114
+ if (tg.topic_aliases != null && tg.chat_id == null) {
11115
+ ctx.addIssue({
11116
+ code: exports_external.ZodIssueCode.custom,
11117
+ message: "`channels.telegram.topic_aliases` requires `chat_id` — aliases only resolve in supergroup-owned mode.",
11118
+ path: ["topic_aliases"]
11119
+ });
11120
+ }
11121
+ });
11090
11122
  var ChannelsSchema = exports_external.object({
11091
11123
  telegram: TelegramChannelSchema
11092
11124
  }).optional();
@@ -11103,6 +11135,12 @@ var GoogleWorkspaceConfigSchema = exports_external.object({
11103
11135
  approvers: exports_external.array(ApproverIdSchema).min(1).describe("Array of numeric Telegram user IDs authorized to approve drive onboarding. " + "At least one must be specified."),
11104
11136
  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 — see RFC G §5).")
11105
11137
  }).optional();
11138
+ var MicrosoftWorkspaceConfigSchema = exports_external.object({
11139
+ microsoft_client_id: exports_external.string().min(1).describe("Microsoft OAuth application (client) ID from Entra portal " + "(literal string or vault reference e.g. " + "'vault:microsoft-oauth-client-id')."),
11140
+ microsoft_client_secret: exports_external.string().min(1).optional().describe("Microsoft OAuth client secret. Optional — public-client apps " + "(Mobile + Desktop platform with 'Allow public client flows' " + "enabled) work without a secret; confidential clients pass " + "one. Either literal or vault reference e.g. " + "'vault:microsoft-oauth-client-secret'."),
11141
+ authority: exports_external.string().url().optional().describe("Microsoft authority endpoint. Defaults to " + "'https://login.microsoftonline.com/common' which accepts both " + "personal MSA and work/school tenants. Override only for " + "single-tenant deployments."),
11142
+ org_mode: exports_external.boolean().optional().describe("Opt-in to Teams + SharePoint surfaces (RFC §6.4). When true, " + "the v1 scope set adds Sites.ReadWrite.All AND the launcher " + "spawns softeria with --org-mode. Defaults to false — personal " + "MSA + standard work surfaces only. Flipping for an existing " + "consented account requires re-running 'auth microsoft account " + "add --replace' to consent the additional scope.")
11143
+ }).optional();
11106
11144
  var AgentGoogleWorkspaceConfigSchema = exports_external.object({
11107
11145
  account: exports_external.string().regex(/^[^@\s:]+@[^@\s:]+\.[^@\s:]+$/, {
11108
11146
  message: "google_workspace.account must be a Google account email like " + "'alice@example.com' (colons not allowed)"
@@ -11110,6 +11148,12 @@ var AgentGoogleWorkspaceConfigSchema = exports_external.object({
11110
11148
  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."),
11111
11149
  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.")
11112
11150
  }).optional();
11151
+ var AgentMicrosoftWorkspaceConfigSchema = exports_external.object({
11152
+ account: exports_external.string().regex(/^[^@\s:]+@[^@\s:]+\.[^@\s:]+$/, {
11153
+ message: "microsoft_workspace.account must be a Microsoft account email like " + "'alice@outlook.com' or 'alice@contoso.com' (colons not allowed)"
11154
+ }).transform((v) => v.trim().toLowerCase()).optional().describe("RFC #1873: the Microsoft account this agent uses for the M365 MCP. " + "Must be a key in top-level `microsoft_accounts:` with this agent " + "listed in its `enabled_for[]`. Read by the auth-broker " + "(get-credentials, provider=microsoft) and by the scaffold to " + "decide whether to emit the `ms-365` MCP entry. Normalized to " + "lowercase so it matches the microsoft_accounts key (which is " + "also normalized)."),
11155
+ org_mode: exports_external.boolean().optional().describe("Per-agent org_mode override (RFC #1873 §6.4). When set, replaces " + "the top-level microsoft_workspace.org_mode for this agent. " + "Defaults to top-level value (which defaults to false).")
11156
+ }).optional();
11113
11157
  var ReactionsSchema = exports_external.object({
11114
11158
  enabled: exports_external.boolean().optional().describe("Master switch for the reaction-trigger path. When false, " + "reactions are still persisted via recordReaction but never " + "dispatched to the agent as synthetic inbound turns. Default true."),
11115
11159
  trigger_emojis: exports_external.array(exports_external.string()).optional().describe("Emoji allowlist that triggers a synthetic inbound when reacted " + "to a bot message. Default ['\uD83D\uDC4E', '❌', '\uD83D\uDC4D', '✅']. Cascade " + "mode: REPLACE (not union) — setting this at a layer replaces " + "lower layers entirely, so an operator can narrow to [] to " + "disable triggering without flipping `enabled`."),
@@ -11245,6 +11289,7 @@ var AgentSchema = exports_external.object({
11245
11289
  code_repos: exports_external.array(CodeRepoEntrySchema).optional().describe("Git repositories this agent is allowed to claim worktrees from. " + "Each entry provides a short name alias, a source path, and an " + "optional concurrency cap (default 5). When code_repos is set, " + "claim_worktree accepts the alias as the repo argument. " + "Absolute paths may always be passed regardless of this list."),
11246
11290
  drive: AgentGoogleWorkspaceConfigSchema.describe("RFC D legacy key — use `google_workspace:` instead. Per-agent " + "google_workspace overrides (currently approvers + tier). When set, " + "replaces the top-level approvers list for this agent. " + "google_client_id/secret are not per-agent — they live at the top level."),
11247
11291
  google_workspace: AgentGoogleWorkspaceConfigSchema.describe("RFC G canonical key. Per-agent Google Workspace overrides — currently " + "approvers (replaces, does not extend the top-level list) and tier " + "(`core` | `extended` | `complete`, replaces top-level default). " + "google_client_id/secret are not per-agent — they live at the top level. " + "Mutually exclusive with `drive:` on the same agent (loader fails fast " + "if both are set)."),
11292
+ microsoft_workspace: AgentMicrosoftWorkspaceConfigSchema.describe("RFC #1873 (Microsoft 365 integration). Per-agent Microsoft Workspace " + "override — pins the Microsoft account this agent reads via the " + "auth-broker (must be a key in top-level `microsoft_accounts:` with " + "this agent in its `enabled_for[]`) and optionally overrides org_mode. " + "microsoft_client_id/secret are not per-agent."),
11248
11293
  repos: exports_external.record(exports_external.string().regex(/^[a-z0-9][a-z0-9-]*$/, "Repo slug must be kebab-case ASCII: start with a lowercase letter or digit, contain only lowercase letters, digits, and hyphens"), exports_external.object({
11249
11294
  url: exports_external.string().min(1).describe("Git remote URL for the repo (e.g. 'git@github.com:org/repo.git' or " + "'https://github.com/org/repo.git'). Used verbatim for git clone."),
11250
11295
  branch_default: exports_external.string().optional().describe("Default branch to track (defaults to the remote's HEAD, typically 'main'). " + "The per-agent branch 'agent/<agentName>/main' fast-forwards to this branch " + "when the worktree is clean on session start.")
@@ -11259,6 +11304,33 @@ var AgentSchema = exports_external.object({
11259
11304
  pids_limit: exports_external.number().int().positive().optional(),
11260
11305
  cpus: exports_external.number().positive().optional()
11261
11306
  }).optional()
11307
+ }).superRefine((agent, ctx) => {
11308
+ if (agent.dm_only !== true)
11309
+ return;
11310
+ const tg = agent.channels?.telegram;
11311
+ if (tg == null)
11312
+ return;
11313
+ if (tg.chat_id != null) {
11314
+ ctx.addIssue({
11315
+ code: exports_external.ZodIssueCode.custom,
11316
+ message: "`dm_only: true` forbids `channels.telegram.chat_id` — DM-only agents have their own private chat, not a supergroup.",
11317
+ path: ["channels", "telegram", "chat_id"]
11318
+ });
11319
+ }
11320
+ if (tg.default_topic_id != null) {
11321
+ ctx.addIssue({
11322
+ code: exports_external.ZodIssueCode.custom,
11323
+ message: "`dm_only: true` forbids `channels.telegram.default_topic_id` — DMs don't have forum topics.",
11324
+ path: ["channels", "telegram", "default_topic_id"]
11325
+ });
11326
+ }
11327
+ if (tg.topic_aliases != null) {
11328
+ ctx.addIssue({
11329
+ code: exports_external.ZodIssueCode.custom,
11330
+ message: "`dm_only: true` forbids `channels.telegram.topic_aliases` — DMs don't have forum topics.",
11331
+ path: ["channels", "telegram", "topic_aliases"]
11332
+ });
11333
+ }
11262
11334
  });
11263
11335
  var TelegramConfigSchema = exports_external.object({
11264
11336
  bot_token: exports_external.string().describe("Telegram bot token or vault reference (e.g., 'vault:telegram-bot-token')"),
@@ -11340,6 +11412,7 @@ var SwitchroomConfigSchema = exports_external.object({
11340
11412
  }).optional().describe("Switchroom-auth-broker configuration (RFC H). Fleet-wide active account, " + "fallback order, admin-agent ACL, and ephemeral-consumer surface. " + "Required from the v0.8+ schema onwards; pre-v0.8 fleets are migrated " + "in-place by `switchroom apply` (see src/auth/migrate-schema.ts)."),
11341
11413
  drive: GoogleWorkspaceConfigSchema.describe("RFC D legacy key — 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."),
11342
11414
  google_workspace: GoogleWorkspaceConfigSchema.describe("RFC G canonical key. Top-level Google Workspace configuration — " + "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)."),
11415
+ microsoft_workspace: MicrosoftWorkspaceConfigSchema.describe("RFC #1873 (Microsoft 365 integration). Top-level Microsoft Workspace " + "configuration — OAuth client credentials (Entra app), authority " + "endpoint (defaults to /common for personal MSA + work), and the " + "org_mode opt-in for Teams/SharePoint surfaces. Block is optional; " + "when omitted the broker does not register the Microsoft provider."),
11343
11416
  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."),
11344
11417
  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)."),
11345
11418
  hostd: HostdConfigSchema.default({}).describe("hostd verb-level knobs (RFC admin-agent-config-edit). Distinct " + "from `host_control:` which governs whether the daemon runs at " + "all. Currently scopes the opt-in flag and rate cap for the new " + "`config_propose_edit` verb (PR 1a — disabled by default)."),
@@ -11350,6 +11423,13 @@ var SwitchroomConfigSchema = exports_external.object({
11350
11423
  message: "Agent name must match the standard agent-name pattern"
11351
11424
  })).describe("Agent slugs that may read this account's vault slots " + "(`google:<account>:refresh_token` etc). Per-agent ACL is " + "enforced at the broker, not at the agent identity layer — " + "the agent still authenticates via socket-path-as-identity " + "per RFC D §4.1, broker just gates the cross-agent token share.")
11352
11425
  })).optional().describe("RFC G Phase 2: per-Google-account ACL for vault slots holding " + "OAuth refresh tokens. Maps account email → list of agents " + "permitted to read that account's slots. Written by `switchroom " + "auth google enable|disable` (Phase 3); read by the broker on " + "every Google slot access. Replaces RFC D's per-agent vault slot " + "scope (which can't express 'two agents share one Google account')."),
11426
+ microsoft_accounts: exports_external.record(exports_external.string().regex(/^[^@\s:]+@[^@\s:]+\.[^@\s:]+$/, {
11427
+ message: "Account key must be a Microsoft account email like 'alice@outlook.com' or 'alice@contoso.com' (colons not allowed)"
11428
+ }).transform((v) => v.trim().toLowerCase()), exports_external.object({
11429
+ enabled_for: exports_external.array(exports_external.string().regex(/^[a-z0-9][a-z0-9_-]{0,50}$/, {
11430
+ message: "Agent name must match the standard agent-name pattern"
11431
+ })).describe("Agent slugs that may read this Microsoft account's broker " + "credentials. Per-agent ACL enforced at the broker; agents " + "still authenticate via socket-path-as-identity, broker just " + "gates the cross-agent token share. Mirrors google_accounts.")
11432
+ })).optional().describe("RFC #1873: per-Microsoft-account ACL. Maps account email → list of " + "agents permitted to use that account's broker credentials. Written " + "by `switchroom auth microsoft enable|disable`; read by the broker " + "on get-credentials with provider=microsoft."),
11353
11433
  defaults: AgentDefaultsSchema.describe("Implicit bottom-of-cascade profile applied to every agent before " + "per-agent config and `extends:` resolution. Tools, mcp_servers, and " + "schedule are unioned/concatenated; scalars and nested objects are " + "shallow-merged with per-agent values winning."),
11354
11434
  profiles: exports_external.record(exports_external.string(), ProfileSchema).optional().describe("Named profile definitions. Agents reference via `extends: <name>`. " + "Inline profiles declared here take priority over filesystem " + "profiles/<name>/ directories when both exist."),
11355
11435
  agents: exports_external.record(exports_external.string().regex(/^[a-z0-9][a-z0-9_-]{0,50}$/, {
@@ -11519,157 +11599,6 @@ function applyAgentOverlays(config) {
11519
11599
  return { config, warnings };
11520
11600
  }
11521
11601
 
11522
- // src/config/loader.ts
11523
- class ConfigError extends Error {
11524
- details;
11525
- constructor(message, details) {
11526
- super(message);
11527
- this.details = details;
11528
- this.name = "ConfigError";
11529
- }
11530
- }
11531
- function formatZodErrors(error) {
11532
- return error.errors.map((e) => {
11533
- const path = e.path.join(".");
11534
- return ` ${path}: ${e.message}`;
11535
- });
11536
- }
11537
- function coerceLegacyGoogleWorkspaceKeys(parsed, filePath) {
11538
- const stableStringify = (v) => {
11539
- if (v === null || typeof v !== "object")
11540
- return JSON.stringify(v);
11541
- if (Array.isArray(v))
11542
- return `[${v.map(stableStringify).join(",")}]`;
11543
- const obj = v;
11544
- const keys = Object.keys(obj).sort();
11545
- return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(",")}}`;
11546
- };
11547
- const aliasInPlace = (obj, where) => {
11548
- const a = obj.drive;
11549
- const b = obj.google_workspace;
11550
- if (a !== undefined && b !== undefined) {
11551
- if (stableStringify(a) !== stableStringify(b)) {
11552
- throw new ConfigError(`Both \`drive:\` and \`google_workspace:\` are set on ${where} in ${filePath} with different values.`, [
11553
- " These are aliases — pick one and remove the other.",
11554
- " `google_workspace:` is the RFC G canonical key; `drive:` is the legacy alias.",
11555
- " Allowed during transition: setting both with identical values."
11556
- ]);
11557
- }
11558
- return;
11559
- }
11560
- if (a !== undefined && b === undefined)
11561
- obj.google_workspace = a;
11562
- if (b !== undefined && a === undefined)
11563
- obj.drive = b;
11564
- };
11565
- aliasInPlace(parsed, "the top level");
11566
- const agents = parsed.agents;
11567
- if (agents && typeof agents === "object" && !Array.isArray(agents)) {
11568
- for (const [name, agent] of Object.entries(agents)) {
11569
- if (agent && typeof agent === "object" && !Array.isArray(agent)) {
11570
- aliasInPlace(agent, `agent \`${name}\``);
11571
- }
11572
- }
11573
- }
11574
- }
11575
- function findConfigFile(startDir) {
11576
- const envPath = process.env.SWITCHROOM_CONFIG;
11577
- const home2 = homedir();
11578
- const userDir = resolve3(home2, ".switchroom");
11579
- const searchPaths = [
11580
- envPath ? resolve3(envPath) : null,
11581
- startDir ? resolve3(startDir, "switchroom.yaml") : null,
11582
- startDir ? resolve3(startDir, "switchroom.yml") : null,
11583
- startDir ? resolve3(startDir, "clerk.yaml") : null,
11584
- startDir ? resolve3(startDir, "clerk.yml") : null,
11585
- resolve3(process.cwd(), "switchroom.yaml"),
11586
- resolve3(process.cwd(), "switchroom.yml"),
11587
- resolve3(process.cwd(), "clerk.yaml"),
11588
- resolve3(process.cwd(), "clerk.yml"),
11589
- resolve3(userDir, "switchroom.yaml"),
11590
- resolve3(userDir, "switchroom.yml"),
11591
- resolve3(userDir, "clerk.yaml"),
11592
- resolve3(userDir, "clerk.yml")
11593
- ].filter(Boolean);
11594
- for (const path of searchPaths) {
11595
- if (existsSync3(path)) {
11596
- return path;
11597
- }
11598
- }
11599
- throw new ConfigError("No switchroom.yaml found", searchPaths.map((p) => ` Searched: ${p}`));
11600
- }
11601
- function loadConfig(configPath) {
11602
- const filePath = configPath ?? findConfigFile();
11603
- if (!existsSync3(filePath)) {
11604
- throw new ConfigError(`Config file not found: ${filePath}`);
11605
- }
11606
- let raw;
11607
- try {
11608
- raw = readFileSync2(filePath, "utf-8");
11609
- } catch (err) {
11610
- throw new ConfigError(`Failed to read config file: ${filePath}`, [
11611
- ` ${err.message}`
11612
- ]);
11613
- }
11614
- let parsed;
11615
- try {
11616
- parsed = $parse(raw);
11617
- } catch (err) {
11618
- throw new ConfigError(`Invalid YAML in ${filePath}`, [
11619
- ` ${err.message}`
11620
- ]);
11621
- }
11622
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && parsed.clerk !== undefined && parsed.switchroom === undefined) {
11623
- const obj = parsed;
11624
- obj.switchroom = obj.clerk;
11625
- delete obj.clerk;
11626
- }
11627
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
11628
- coerceLegacyGoogleWorkspaceKeys(parsed, filePath);
11629
- }
11630
- let config;
11631
- try {
11632
- config = SwitchroomConfigSchema.parse(parsed);
11633
- } catch (err) {
11634
- if (err instanceof ZodError) {
11635
- throw new ConfigError("Invalid switchroom.yaml configuration", formatZodErrors(err));
11636
- }
11637
- throw err;
11638
- }
11639
- applyAgentOverlays(config);
11640
- return config;
11641
- }
11642
- function resolveAgentsDir(config) {
11643
- const override = process.env.SWITCHROOM_AGENTS_DIR;
11644
- if (override && override.length > 0 && override.startsWith("/")) {
11645
- return override;
11646
- }
11647
- return resolveDualPath(config.switchroom.agents_dir);
11648
- }
11649
-
11650
- // src/auth/broker/server.ts
11651
- import * as net from "node:net";
11652
- import {
11653
- chmodSync,
11654
- chownSync as chownSync2,
11655
- existsSync as existsSync6,
11656
- lstatSync,
11657
- mkdirSync as mkdirSync3,
11658
- readFileSync as readFileSync5,
11659
- renameSync as renameSync3,
11660
- rmSync as rmSync4,
11661
- statSync as statSync4,
11662
- unlinkSync,
11663
- writeFileSync as writeFileSync2
11664
- } from "node:fs";
11665
- import { closeSync as closeSync2, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
11666
- import * as constants2 from "node:constants";
11667
- import { createHash as createHash2 } from "node:crypto";
11668
- import { dirname as dirname2, join as join3, resolve as resolve6 } from "node:path";
11669
-
11670
- // src/agents/compose.ts
11671
- import { createHash } from "node:crypto";
11672
-
11673
11602
  // src/config/merge.ts
11674
11603
  function dedupe(items) {
11675
11604
  const seen = new Set;
@@ -11698,6 +11627,20 @@ function deepMergeJson(base, override) {
11698
11627
  }
11699
11628
  return out;
11700
11629
  }
11630
+ function resolveAgentConfig(defaults, profiles, agent) {
11631
+ if (!mergeAgentConfig.suppressDeprecationLogs && !mergeAgentConfig.notifiedWorkerIsolationMove && defaults?.subagents?.worker?.isolation === "worktree") {
11632
+ mergeAgentConfig.notifiedWorkerIsolationMove = true;
11633
+ console.warn("[switchroom] NOTICE: defaults.subagents.worker.isolation moved to the " + "`coding` profile in switchroom 0.6.6 (#682). Agents extending coding " + "still get worktree-isolated workers; other agents would have hard-failed " + "the first time they delegated. See CHANGELOG.");
11634
+ }
11635
+ const name = agent.extends;
11636
+ const profile = name && profiles ? profiles[name] : undefined;
11637
+ if (!profile) {
11638
+ return mergeAgentConfig(defaults, agent);
11639
+ }
11640
+ const { extends: _unused, ...profileWithoutExtends } = profile;
11641
+ const layered = mergeAgentConfig(defaults, profileWithoutExtends);
11642
+ return mergeAgentConfig(layered, agent);
11643
+ }
11701
11644
  function foldDeprecatedTelegramFields(config) {
11702
11645
  const c = config;
11703
11646
  const root = c;
@@ -11965,6 +11908,183 @@ function mergeAgentConfig(defaultsIn, agentIn) {
11965
11908
  mergeAgentConfig.notifiedWorkerIsolationMove = false;
11966
11909
  })(mergeAgentConfig ||= {});
11967
11910
 
11911
+ // src/config/loader.ts
11912
+ class ConfigError extends Error {
11913
+ details;
11914
+ constructor(message, details) {
11915
+ super(message);
11916
+ this.details = details;
11917
+ this.name = "ConfigError";
11918
+ }
11919
+ }
11920
+ function formatZodErrors(error) {
11921
+ return error.errors.map((e) => {
11922
+ const path = e.path.join(".");
11923
+ return ` ${path}: ${e.message}`;
11924
+ });
11925
+ }
11926
+ function coerceLegacyGoogleWorkspaceKeys(parsed, filePath) {
11927
+ const stableStringify = (v) => {
11928
+ if (v === null || typeof v !== "object")
11929
+ return JSON.stringify(v);
11930
+ if (Array.isArray(v))
11931
+ return `[${v.map(stableStringify).join(",")}]`;
11932
+ const obj = v;
11933
+ const keys = Object.keys(obj).sort();
11934
+ return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(",")}}`;
11935
+ };
11936
+ const aliasInPlace = (obj, where) => {
11937
+ const a = obj.drive;
11938
+ const b = obj.google_workspace;
11939
+ if (a !== undefined && b !== undefined) {
11940
+ if (stableStringify(a) !== stableStringify(b)) {
11941
+ throw new ConfigError(`Both \`drive:\` and \`google_workspace:\` are set on ${where} in ${filePath} with different values.`, [
11942
+ " These are aliases — pick one and remove the other.",
11943
+ " `google_workspace:` is the RFC G canonical key; `drive:` is the legacy alias.",
11944
+ " Allowed during transition: setting both with identical values."
11945
+ ]);
11946
+ }
11947
+ return;
11948
+ }
11949
+ if (a !== undefined && b === undefined)
11950
+ obj.google_workspace = a;
11951
+ if (b !== undefined && a === undefined)
11952
+ obj.drive = b;
11953
+ };
11954
+ aliasInPlace(parsed, "the top level");
11955
+ const agents = parsed.agents;
11956
+ if (agents && typeof agents === "object" && !Array.isArray(agents)) {
11957
+ for (const [name, agent] of Object.entries(agents)) {
11958
+ if (agent && typeof agent === "object" && !Array.isArray(agent)) {
11959
+ aliasInPlace(agent, `agent \`${name}\``);
11960
+ }
11961
+ }
11962
+ }
11963
+ }
11964
+ function findConfigFile(startDir) {
11965
+ const envPath = process.env.SWITCHROOM_CONFIG;
11966
+ const home2 = homedir();
11967
+ const userDir = resolve3(home2, ".switchroom");
11968
+ const searchPaths = [
11969
+ envPath ? resolve3(envPath) : null,
11970
+ startDir ? resolve3(startDir, "switchroom.yaml") : null,
11971
+ startDir ? resolve3(startDir, "switchroom.yml") : null,
11972
+ startDir ? resolve3(startDir, "clerk.yaml") : null,
11973
+ startDir ? resolve3(startDir, "clerk.yml") : null,
11974
+ resolve3(process.cwd(), "switchroom.yaml"),
11975
+ resolve3(process.cwd(), "switchroom.yml"),
11976
+ resolve3(process.cwd(), "clerk.yaml"),
11977
+ resolve3(process.cwd(), "clerk.yml"),
11978
+ resolve3(userDir, "switchroom.yaml"),
11979
+ resolve3(userDir, "switchroom.yml"),
11980
+ resolve3(userDir, "clerk.yaml"),
11981
+ resolve3(userDir, "clerk.yml")
11982
+ ].filter(Boolean);
11983
+ for (const path of searchPaths) {
11984
+ if (existsSync3(path)) {
11985
+ return path;
11986
+ }
11987
+ }
11988
+ throw new ConfigError("No switchroom.yaml found", searchPaths.map((p) => ` Searched: ${p}`));
11989
+ }
11990
+ function loadConfig(configPath) {
11991
+ const filePath = configPath ?? findConfigFile();
11992
+ if (!existsSync3(filePath)) {
11993
+ throw new ConfigError(`Config file not found: ${filePath}`);
11994
+ }
11995
+ let raw;
11996
+ try {
11997
+ raw = readFileSync2(filePath, "utf-8");
11998
+ } catch (err) {
11999
+ throw new ConfigError(`Failed to read config file: ${filePath}`, [
12000
+ ` ${err.message}`
12001
+ ]);
12002
+ }
12003
+ let parsed;
12004
+ try {
12005
+ parsed = $parse(raw);
12006
+ } catch (err) {
12007
+ throw new ConfigError(`Invalid YAML in ${filePath}`, [
12008
+ ` ${err.message}`
12009
+ ]);
12010
+ }
12011
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && parsed.clerk !== undefined && parsed.switchroom === undefined) {
12012
+ const obj = parsed;
12013
+ obj.switchroom = obj.clerk;
12014
+ delete obj.clerk;
12015
+ }
12016
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
12017
+ coerceLegacyGoogleWorkspaceKeys(parsed, filePath);
12018
+ }
12019
+ let config;
12020
+ try {
12021
+ config = SwitchroomConfigSchema.parse(parsed);
12022
+ } catch (err) {
12023
+ if (err instanceof ZodError) {
12024
+ throw new ConfigError("Invalid switchroom.yaml configuration", formatZodErrors(err));
12025
+ }
12026
+ throw err;
12027
+ }
12028
+ applyAgentOverlays(config);
12029
+ validateAllCronTopicAliases(config, filePath);
12030
+ return config;
12031
+ }
12032
+ function validateAllCronTopicAliases(config, filePath) {
12033
+ const issues = [];
12034
+ for (const [agentName, agentRaw] of Object.entries(config.agents)) {
12035
+ if (!agentRaw)
12036
+ continue;
12037
+ const resolved = resolveAgentConfig(config.defaults, config.profiles, agentRaw);
12038
+ const schedule = resolved.schedule ?? [];
12039
+ if (schedule.length === 0)
12040
+ continue;
12041
+ const tg = resolved.channels?.telegram;
12042
+ const aliases = new Set(Object.keys(tg?.topic_aliases ?? {}));
12043
+ for (const entry of schedule) {
12044
+ if (entry.topic == null)
12045
+ continue;
12046
+ if (typeof entry.topic === "number")
12047
+ continue;
12048
+ if (!aliases.has(entry.topic)) {
12049
+ issues.push(` agents.${agentName}.schedule cron \`${entry.cron}\`: ` + `topic alias "${entry.topic}" is not defined in ` + `channels.telegram.topic_aliases.`);
12050
+ }
12051
+ }
12052
+ }
12053
+ if (issues.length > 0) {
12054
+ throw new ConfigError(`Cron \`topic:\` alias references unknown topic_aliases in ${filePath}`, issues);
12055
+ }
12056
+ }
12057
+ function resolveAgentsDir(config) {
12058
+ const override = process.env.SWITCHROOM_AGENTS_DIR;
12059
+ if (override && override.length > 0 && override.startsWith("/")) {
12060
+ return override;
12061
+ }
12062
+ return resolveDualPath(config.switchroom.agents_dir);
12063
+ }
12064
+
12065
+ // src/auth/broker/server.ts
12066
+ import * as net from "node:net";
12067
+ import {
12068
+ chmodSync,
12069
+ chownSync as chownSync2,
12070
+ existsSync as existsSync6,
12071
+ lstatSync,
12072
+ mkdirSync as mkdirSync3,
12073
+ readFileSync as readFileSync5,
12074
+ renameSync as renameSync3,
12075
+ rmSync as rmSync4,
12076
+ statSync as statSync4,
12077
+ unlinkSync,
12078
+ writeFileSync as writeFileSync2
12079
+ } from "node:fs";
12080
+ import { closeSync as closeSync2, openSync as openSync2, writeSync as writeSync2 } from "node:fs";
12081
+ import * as constants2 from "node:constants";
12082
+ import { createHash as createHash2 } from "node:crypto";
12083
+ import { dirname as dirname2, join as join3, resolve as resolve6 } from "node:path";
12084
+
12085
+ // src/agents/compose.ts
12086
+ import { createHash } from "node:crypto";
12087
+
11968
12088
  // src/vault/broker/peercred.ts
11969
12089
  var RESERVED_AGENT_NAMES = new Set(["operator", "hostd"]);
11970
12090
  function isReservedAgentName(name) {
@@ -12552,6 +12672,202 @@ function classifyAsyncError(err) {
12552
12672
  return { ok: false, kind: "provider_error", detail: msg };
12553
12673
  }
12554
12674
 
12675
+ // src/microsoft/oauth.ts
12676
+ var MICROSOFT_OAUTH_BASE = "https://login.microsoftonline.com/common/oauth2/v2.0";
12677
+ var PERSONAL_MSA_TENANT_ID = "9188040d-6c67-4c5b-b112-36a304b66dad";
12678
+
12679
+ class MicrosoftInvalidGrantError extends Error {
12680
+ detail;
12681
+ constructor(detail) {
12682
+ super(`invalid_grant: ${detail}`);
12683
+ this.detail = detail;
12684
+ this.name = "MicrosoftInvalidGrantError";
12685
+ }
12686
+ }
12687
+ async function refreshMicrosoftAccessToken(cfg, refreshToken, fetchImpl = fetch) {
12688
+ const body = new URLSearchParams({
12689
+ client_id: cfg.client_id,
12690
+ refresh_token: refreshToken,
12691
+ grant_type: "refresh_token"
12692
+ });
12693
+ if (cfg.client_secret !== undefined && cfg.client_secret.length > 0) {
12694
+ body.set("client_secret", cfg.client_secret);
12695
+ }
12696
+ if (cfg.scopes && cfg.scopes.length > 0) {
12697
+ body.set("scope", cfg.scopes.join(" "));
12698
+ }
12699
+ const res = await fetchImpl(`${MICROSOFT_OAUTH_BASE}/token`, {
12700
+ method: "POST",
12701
+ headers: { "content-type": "application/x-www-form-urlencoded" },
12702
+ body: body.toString()
12703
+ });
12704
+ const json = await res.json();
12705
+ if (!res.ok) {
12706
+ if (typeof json.error === "string" && json.error === "invalid_grant") {
12707
+ throw new MicrosoftInvalidGrantError(typeof json.error_description === "string" ? json.error_description : "refresh token rejected by Microsoft");
12708
+ }
12709
+ throw new Error(`refresh failed (${res.status}): ${JSON.stringify(json)}`);
12710
+ }
12711
+ return json;
12712
+ }
12713
+ function decodeJwtPayloadUnsafe(token) {
12714
+ const parts = token.split(".");
12715
+ if (parts.length !== 3)
12716
+ return null;
12717
+ try {
12718
+ const padded = parts[1] + "===".slice((parts[1].length + 3) % 4);
12719
+ const base64 = padded.replace(/-/g, "+").replace(/_/g, "/");
12720
+ const buf = Buffer.from(base64, "base64");
12721
+ const json = JSON.parse(buf.toString("utf-8"));
12722
+ if (json && typeof json === "object") {
12723
+ return json;
12724
+ }
12725
+ return null;
12726
+ } catch {
12727
+ return null;
12728
+ }
12729
+ }
12730
+ function classifyAccountType(tenantId) {
12731
+ return tenantId === PERSONAL_MSA_TENANT_ID ? "personal" : "work";
12732
+ }
12733
+
12734
+ // src/auth/broker/microsoft-provider.ts
12735
+ class MicrosoftProvider {
12736
+ opts;
12737
+ name = "microsoft";
12738
+ constructor(opts) {
12739
+ this.opts = opts;
12740
+ }
12741
+ async refresh(req) {
12742
+ if (!req.refreshToken) {
12743
+ return {
12744
+ ok: false,
12745
+ kind: "provider_error",
12746
+ detail: "MicrosoftProvider.refresh: refreshToken is required"
12747
+ };
12748
+ }
12749
+ const cfg = {
12750
+ client_id: this.opts.clientId,
12751
+ client_secret: this.opts.clientSecret,
12752
+ scopes: []
12753
+ };
12754
+ let token;
12755
+ try {
12756
+ token = await refreshMicrosoftAccessToken(cfg, req.refreshToken, this.opts.fetcher ?? fetch);
12757
+ } catch (err) {
12758
+ if (err instanceof MicrosoftInvalidGrantError) {
12759
+ return {
12760
+ ok: false,
12761
+ kind: "invalid_grant",
12762
+ detail: err.message
12763
+ };
12764
+ }
12765
+ return classifyAsyncError2(err);
12766
+ }
12767
+ const expiresAt = Date.now() + token.expires_in * 1000;
12768
+ const prior = req.priorCredentials?.microsoftOauth;
12769
+ let tenantId = prior?.tenantId ?? "";
12770
+ let accountType = prior?.accountType ?? "work";
12771
+ let homeAccountId = prior?.homeAccountId ?? "";
12772
+ let accountEmail = req.accountEmail ?? prior?.accountEmail ?? "";
12773
+ if (token.id_token) {
12774
+ const claims = decodeJwtPayloadUnsafe(token.id_token);
12775
+ if (claims) {
12776
+ if (typeof claims.tid === "string")
12777
+ tenantId = claims.tid;
12778
+ if (tenantId)
12779
+ accountType = classifyAccountType(tenantId);
12780
+ if (typeof claims.oid === "string" && typeof claims.tid === "string") {
12781
+ homeAccountId = `${claims.oid}.${claims.tid}`;
12782
+ }
12783
+ if (typeof claims.preferred_username === "string") {
12784
+ accountEmail = claims.preferred_username;
12785
+ } else if (typeof claims.email === "string") {
12786
+ accountEmail = claims.email;
12787
+ }
12788
+ }
12789
+ }
12790
+ const rawCredentials = {
12791
+ microsoftOauth: {
12792
+ accessToken: token.access_token,
12793
+ refreshToken: token.refresh_token ?? req.refreshToken,
12794
+ expiresAt,
12795
+ scope: token.scope ?? "",
12796
+ clientId: this.opts.clientId,
12797
+ accountEmail,
12798
+ tokenType: "Bearer",
12799
+ tenantId,
12800
+ accountType,
12801
+ homeAccountId
12802
+ }
12803
+ };
12804
+ return {
12805
+ ok: true,
12806
+ accessToken: token.access_token,
12807
+ expiresAt,
12808
+ newRefreshToken: token.refresh_token,
12809
+ rawCredentials
12810
+ };
12811
+ }
12812
+ extractExpiresAt(credentials) {
12813
+ const c = credentials;
12814
+ return c?.microsoftOauth?.expiresAt;
12815
+ }
12816
+ validateCredentialShape(credentials) {
12817
+ if (!credentials || typeof credentials !== "object") {
12818
+ return "Microsoft credentials must be an object";
12819
+ }
12820
+ const c = credentials;
12821
+ if (!c.microsoftOauth || typeof c.microsoftOauth !== "object") {
12822
+ return "Microsoft credentials must have a microsoftOauth object";
12823
+ }
12824
+ const oauth = c.microsoftOauth;
12825
+ const required = [
12826
+ "accessToken",
12827
+ "refreshToken",
12828
+ "expiresAt",
12829
+ "scope",
12830
+ "clientId",
12831
+ "accountEmail",
12832
+ "tenantId",
12833
+ "accountType",
12834
+ "homeAccountId"
12835
+ ];
12836
+ for (const field of required) {
12837
+ if (oauth[field] === undefined || oauth[field] === null) {
12838
+ return `Microsoft microsoftOauth.${field} is required`;
12839
+ }
12840
+ }
12841
+ if (typeof oauth.accessToken !== "string" || oauth.accessToken.length === 0) {
12842
+ return "Microsoft microsoftOauth.accessToken must be a non-empty string";
12843
+ }
12844
+ if (typeof oauth.refreshToken !== "string" || oauth.refreshToken.length === 0) {
12845
+ return "Microsoft microsoftOauth.refreshToken must be a non-empty string";
12846
+ }
12847
+ if (typeof oauth.expiresAt !== "number" || oauth.expiresAt <= 0) {
12848
+ return "Microsoft microsoftOauth.expiresAt must be a positive unix-ms timestamp";
12849
+ }
12850
+ if (oauth.tokenType !== "Bearer") {
12851
+ return "Microsoft microsoftOauth.tokenType must be 'Bearer'";
12852
+ }
12853
+ if (oauth.accountType !== "personal" && oauth.accountType !== "work") {
12854
+ return "Microsoft microsoftOauth.accountType must be 'personal' or 'work'";
12855
+ }
12856
+ return null;
12857
+ }
12858
+ }
12859
+ function classifyAsyncError2(err) {
12860
+ const msg = err instanceof Error ? err.message : String(err);
12861
+ const lower = msg.toLowerCase();
12862
+ if (lower.includes("etimedout") || lower.includes("econnreset") || lower.includes("network") || lower.includes("fetch failed") || lower.includes("getaddrinfo")) {
12863
+ return { ok: false, kind: "network", detail: msg };
12864
+ }
12865
+ if (lower.includes("429") || lower.includes("rate") || lower.includes("quota") || lower.includes("too many requests") || lower.includes("aadsts50196")) {
12866
+ return { ok: false, kind: "quota_exceeded", detail: msg };
12867
+ }
12868
+ return { ok: false, kind: "provider_error", detail: msg };
12869
+ }
12870
+
12555
12871
  // src/auth/broker/google-storage.ts
12556
12872
  import { existsSync as existsSync5, mkdirSync as mkdirSync2, readdirSync as readdirSync3, readFileSync as readFileSync4, rmSync as rmSync3, statSync as statSync3 } from "node:fs";
12557
12873
  import { dirname, join as join2, resolve as resolve5 } from "node:path";
@@ -12694,7 +13010,7 @@ function validateConsumerNames(config) {
12694
13010
  // src/auth/broker/protocol.ts
12695
13011
  var MAX_FRAME_BYTES = 64 * 1024;
12696
13012
  var PROTOCOL_VERSION = 1;
12697
- var ProviderNameSchema = exports_external.enum(["anthropic", "google"]);
13013
+ var ProviderNameSchema = exports_external.enum(["anthropic", "google", "microsoft"]);
12698
13014
  var GetCredentialsRequestSchema = exports_external.object({
12699
13015
  v: exports_external.literal(PROTOCOL_VERSION),
12700
13016
  op: exports_external.literal("get-credentials"),
@@ -12747,9 +13063,24 @@ var GoogleCredentialsSchema = exports_external.object({
12747
13063
  tokenType: exports_external.literal("Bearer")
12748
13064
  })
12749
13065
  });
13066
+ var MicrosoftCredentialsSchema = exports_external.object({
13067
+ microsoftOauth: exports_external.object({
13068
+ accessToken: exports_external.string(),
13069
+ refreshToken: exports_external.string(),
13070
+ expiresAt: exports_external.number(),
13071
+ scope: exports_external.string(),
13072
+ clientId: exports_external.string(),
13073
+ accountEmail: exports_external.string(),
13074
+ tokenType: exports_external.literal("Bearer"),
13075
+ tenantId: exports_external.string(),
13076
+ accountType: exports_external.enum(["personal", "work"]),
13077
+ homeAccountId: exports_external.string()
13078
+ })
13079
+ });
12750
13080
  var ProviderCredentialsSchema = exports_external.union([
12751
13081
  AnthropicCredentialsSchema,
12752
- GoogleCredentialsSchema
13082
+ GoogleCredentialsSchema,
13083
+ MicrosoftCredentialsSchema
12753
13084
  ]);
12754
13085
  var AddAccountRequestSchema = exports_external.object({
12755
13086
  v: exports_external.literal(PROTOCOL_VERSION),
@@ -13001,6 +13332,14 @@ class AuthBroker {
13001
13332
  fetcher: opts.fetcher
13002
13333
  }));
13003
13334
  }
13335
+ const microsoftClientId = config.microsoft_workspace?.microsoft_client_id;
13336
+ if (microsoftClientId !== undefined) {
13337
+ this.providers.register(new MicrosoftProvider({
13338
+ clientId: microsoftClientId,
13339
+ clientSecret: config.microsoft_workspace?.microsoft_client_secret,
13340
+ fetcher: opts.fetcher
13341
+ }));
13342
+ }
13004
13343
  this.assertConfigConsistent(config);
13005
13344
  }
13006
13345
  homeRoot() {