switchroom 0.15.44 → 0.16.4

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 (150) hide show
  1. package/dist/agent-scheduler/index.js +122 -88
  2. package/dist/auth-broker/index.js +463 -177
  3. package/dist/cli/autoaccept-poll.js +4842 -35
  4. package/dist/cli/drive-write-pretool.mjs +17 -14
  5. package/dist/cli/notion-write-pretool.mjs +117 -86
  6. package/dist/cli/self-improve-apply-guard-pretool.mjs +626 -0
  7. package/dist/cli/self-improve-stop.mjs +428 -0
  8. package/dist/cli/skill-validate-pretool.mjs +72 -72
  9. package/dist/cli/switchroom.js +3249 -1241
  10. package/dist/cli/ui/index.html +1 -1
  11. package/dist/host-control/main.js +2833 -355
  12. package/dist/vault/approvals/kernel-server.js +7482 -7439
  13. package/dist/vault/broker/server.js +11315 -11272
  14. package/examples/minimal.yaml +1 -0
  15. package/examples/switchroom.yaml +1 -0
  16. package/package.json +3 -3
  17. package/profiles/_base/start.sh.hbs +88 -1
  18. package/profiles/_shared/execution-discipline.md.hbs +18 -0
  19. package/profiles/default/CLAUDE.md.hbs +3 -22
  20. package/telegram-plugin/.claude-plugin/plugin.json +2 -2
  21. package/telegram-plugin/answer-stream-flag.ts +12 -49
  22. package/telegram-plugin/answer-stream.ts +5 -150
  23. package/telegram-plugin/auth-snapshot-format.ts +280 -48
  24. package/telegram-plugin/auto-fallback-fleet.ts +44 -1
  25. package/telegram-plugin/context-exhaustion.ts +12 -0
  26. package/telegram-plugin/demo-mask.ts +154 -0
  27. package/telegram-plugin/dist/bridge/bridge.js +167 -124
  28. package/telegram-plugin/dist/gateway/gateway.js +3039 -1159
  29. package/telegram-plugin/dist/server.js +215 -172
  30. package/telegram-plugin/docs/waiting-ux-spec.md +2 -2
  31. package/telegram-plugin/draft-stream.ts +47 -410
  32. package/telegram-plugin/final-answer-detect.ts +17 -12
  33. package/telegram-plugin/fleet-fallback-resume.ts +131 -0
  34. package/telegram-plugin/format.ts +56 -19
  35. package/telegram-plugin/gateway/auth-add-flow.ts +332 -127
  36. package/telegram-plugin/gateway/auth-broker-client.ts +2 -2
  37. package/telegram-plugin/gateway/auth-command.ts +70 -14
  38. package/telegram-plugin/gateway/clean-shutdown-marker.ts +44 -0
  39. package/telegram-plugin/gateway/config-approval-handler.test.ts +91 -4
  40. package/telegram-plugin/gateway/config-approval-handler.ts +94 -13
  41. package/telegram-plugin/gateway/current-turn-map.ts +188 -0
  42. package/telegram-plugin/gateway/disconnect-flush.ts +3 -1
  43. package/telegram-plugin/gateway/effort-command.ts +8 -3
  44. package/telegram-plugin/gateway/emission-authority.ts +369 -0
  45. package/telegram-plugin/gateway/feed-open-gate.ts +292 -0
  46. package/telegram-plugin/gateway/gateway.ts +1837 -291
  47. package/telegram-plugin/gateway/inject-handler.test.ts +2 -1
  48. package/telegram-plugin/gateway/ms365-write-approval.test.ts +4 -4
  49. package/telegram-plugin/gateway/represent-guard.ts +72 -0
  50. package/telegram-plugin/gateway/status-surface-log.test.ts +5 -4
  51. package/telegram-plugin/gateway/status-surface-log.ts +14 -3
  52. package/telegram-plugin/history.ts +33 -11
  53. package/telegram-plugin/hooks/repo-context-pretool.mjs +26 -0
  54. package/telegram-plugin/hooks/subagent-tracker-posttool.mjs +5 -0
  55. package/telegram-plugin/hooks/subagent-tracker-pretool.mjs +8 -0
  56. package/telegram-plugin/hooks/tool-label-pretool.mjs +39 -15
  57. package/telegram-plugin/issues-card.ts +4 -0
  58. package/telegram-plugin/model-unavailable.ts +124 -0
  59. package/telegram-plugin/narrative-dedup.ts +69 -0
  60. package/telegram-plugin/over-ping-safety-net.ts +70 -4
  61. package/telegram-plugin/package.json +3 -3
  62. package/telegram-plugin/pending-work-progress.ts +12 -0
  63. package/telegram-plugin/permission-rule.ts +32 -5
  64. package/telegram-plugin/permission-title.ts +152 -9
  65. package/telegram-plugin/quota-check.ts +13 -0
  66. package/telegram-plugin/quota-watch.ts +135 -7
  67. package/telegram-plugin/registry/turns-schema.test.ts +24 -0
  68. package/telegram-plugin/registry/turns-schema.ts +9 -0
  69. package/telegram-plugin/runtime-metrics.ts +13 -0
  70. package/telegram-plugin/session-tail.ts +96 -11
  71. package/telegram-plugin/silence-poke.ts +170 -24
  72. package/telegram-plugin/slot-banner-driver.ts +3 -0
  73. package/telegram-plugin/status-no-truncate.ts +44 -0
  74. package/telegram-plugin/status-reactions.ts +20 -3
  75. package/telegram-plugin/stream-controller.ts +4 -23
  76. package/telegram-plugin/stream-reply-handler.ts +6 -24
  77. package/telegram-plugin/streaming-metrics.ts +91 -0
  78. package/telegram-plugin/subagent-watcher.ts +212 -66
  79. package/telegram-plugin/tests/activity-ever-opened-sticky.test.ts +47 -0
  80. package/telegram-plugin/tests/answer-stream-dedup.test.ts +9 -26
  81. package/telegram-plugin/tests/answer-stream-flag.test.ts +25 -58
  82. package/telegram-plugin/tests/answer-stream-silent-markers.test.ts +41 -51
  83. package/telegram-plugin/tests/answer-stream.test.ts +2 -411
  84. package/telegram-plugin/tests/auth-add-flow.test.ts +488 -253
  85. package/telegram-plugin/tests/auth-command-format2.test.ts +71 -1
  86. package/telegram-plugin/tests/auth-snapshot-format.test.ts +376 -6
  87. package/telegram-plugin/tests/auto-fallback-fleet.test.ts +120 -0
  88. package/telegram-plugin/tests/cross-turn-card-gate.test.ts +424 -0
  89. package/telegram-plugin/tests/demo-mask.test.ts +127 -0
  90. package/telegram-plugin/tests/draft-stream.test.ts +0 -827
  91. package/telegram-plugin/tests/emission-authority-card-drain-gate.test.ts +236 -0
  92. package/telegram-plugin/tests/emission-authority-facade.test.ts +488 -0
  93. package/telegram-plugin/tests/emission-authority-open-gate.test.ts +179 -0
  94. package/telegram-plugin/tests/emission-authority-ping-gate.test.ts +395 -0
  95. package/telegram-plugin/tests/emission-determinism-wiring.test.ts +177 -0
  96. package/telegram-plugin/tests/feed-heartbeat-liveness-open.test.ts +146 -0
  97. package/telegram-plugin/tests/feed-open-gate.test.ts +259 -0
  98. package/telegram-plugin/tests/feed-survival.test.ts +526 -0
  99. package/telegram-plugin/tests/fleet-fallback-resume.test.ts +197 -0
  100. package/telegram-plugin/tests/gateway-clean-shutdown-marker.test.ts +117 -0
  101. package/telegram-plugin/tests/gateway-no-reply-single-emit.test.ts +4 -11
  102. package/telegram-plugin/tests/history.test.ts +60 -0
  103. package/telegram-plugin/tests/model-unavailable.test.ts +118 -0
  104. package/telegram-plugin/tests/narrative-dedup.test.ts +118 -0
  105. package/telegram-plugin/tests/orphaned-reply-rearm.test.ts +285 -0
  106. package/telegram-plugin/tests/over-ping-final-answer-decoupling.test.ts +194 -0
  107. package/telegram-plugin/tests/over-ping-safety-net.test.ts +2 -2
  108. package/telegram-plugin/tests/per-topic-current-turn.test.ts +373 -0
  109. package/telegram-plugin/tests/permission-card-origin-kill-switch.test.ts +42 -0
  110. package/telegram-plugin/tests/permission-rule.test.ts +17 -0
  111. package/telegram-plugin/tests/permission-title.test.ts +206 -17
  112. package/telegram-plugin/tests/quota-watch.test.ts +252 -9
  113. package/telegram-plugin/tests/reply-terminal-reaction.test.ts +6 -1
  114. package/telegram-plugin/tests/repo-context-pretool.test.ts +62 -0
  115. package/telegram-plugin/tests/represent-guard.test.ts +162 -0
  116. package/telegram-plugin/tests/session-tail.test.ts +147 -3
  117. package/telegram-plugin/tests/silence-liveness-wiring.test.ts +18 -0
  118. package/telegram-plugin/tests/status-card-budget-parity.test.ts +72 -0
  119. package/telegram-plugin/tests/status-surface-log.test.ts +146 -0
  120. package/telegram-plugin/tests/subagent-watcher-clip-narrative.test.ts +58 -0
  121. package/telegram-plugin/tests/subagent-watcher-parent-turn-key.test.ts +102 -0
  122. package/telegram-plugin/tests/subagent-watcher-workflow-visibility.test.ts +225 -0
  123. package/telegram-plugin/tests/subagent-watcher.test.ts +147 -0
  124. package/telegram-plugin/tests/telegram-activity-visibility-integration.test.ts +597 -0
  125. package/telegram-plugin/tests/telegram-format.test.ts +101 -6
  126. package/telegram-plugin/tests/tool-activity-summary.test.ts +550 -15
  127. package/telegram-plugin/tests/tool-label-pretool.test.ts +73 -0
  128. package/telegram-plugin/tests/tool-label-sidecar.test.ts +44 -0
  129. package/telegram-plugin/tests/tool-labels.test.ts +67 -0
  130. package/telegram-plugin/tests/turn-liveness-floor.test.ts +196 -0
  131. package/telegram-plugin/tests/turn-liveness-invariant.test.ts +340 -0
  132. package/telegram-plugin/tests/welcome-text.test.ts +32 -3
  133. package/telegram-plugin/tests/worker-activity-feed.test.ts +470 -22
  134. package/telegram-plugin/tool-activity-summary.ts +375 -58
  135. package/telegram-plugin/turn-liveness-floor.ts +240 -0
  136. package/telegram-plugin/uat/assertions.ts +115 -0
  137. package/telegram-plugin/uat/driver.ts +68 -0
  138. package/telegram-plugin/uat/scenarios/bg-sub-agent-dispatch-dm.test.ts +119 -133
  139. package/telegram-plugin/uat/scenarios/jtbd-answer-pings.test.ts +94 -0
  140. package/telegram-plugin/uat/scenarios/jtbd-cross-turn-card-dm.test.ts +109 -0
  141. package/telegram-plugin/uat/scenarios/jtbd-foreground-feed-thinkgap-dm.test.ts +478 -0
  142. package/telegram-plugin/uat/scenarios/jtbd-foreground-feed-visibility-dm.test.ts +396 -0
  143. package/telegram-plugin/uat/scenarios/jtbd-liveness-feed-open-dm.test.ts +202 -0
  144. package/telegram-plugin/uat/scenarios/jtbd-reply-is-last-dm.test.ts +202 -0
  145. package/telegram-plugin/uat/scenarios/reactions-dm.test.ts +93 -87
  146. package/telegram-plugin/welcome-text.ts +13 -1
  147. package/telegram-plugin/worker-activity-feed.ts +157 -82
  148. package/telegram-plugin/draft-transport.ts +0 -122
  149. package/telegram-plugin/tests/draft-retirement-wiring.test.ts +0 -82
  150. package/telegram-plugin/tests/draft-transport.test.ts +0 -211
@@ -46,7 +46,7 @@ var __export = (target, all) => {
46
46
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
47
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
48
48
 
49
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
49
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/identity.js
50
50
  var require_identity = __commonJS((exports) => {
51
51
  var ALIAS = Symbol.for("yaml.alias");
52
52
  var DOC = Symbol.for("yaml.document");
@@ -100,7 +100,7 @@ var require_identity = __commonJS((exports) => {
100
100
  exports.isSeq = isSeq;
101
101
  });
102
102
 
103
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
103
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/visit.js
104
104
  var require_visit = __commonJS((exports) => {
105
105
  var identity = require_identity();
106
106
  var BREAK = Symbol("break visit");
@@ -255,7 +255,7 @@ var require_visit = __commonJS((exports) => {
255
255
  exports.visitAsync = visitAsync;
256
256
  });
257
257
 
258
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
258
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/directives.js
259
259
  var require_directives = __commonJS((exports) => {
260
260
  var identity = require_identity();
261
261
  var visit = require_visit();
@@ -407,7 +407,7 @@ var require_directives = __commonJS((exports) => {
407
407
  exports.Directives = Directives;
408
408
  });
409
409
 
410
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
410
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/anchors.js
411
411
  var require_anchors = __commonJS((exports) => {
412
412
  var identity = require_identity();
413
413
  var visit = require_visit();
@@ -469,7 +469,7 @@ var require_anchors = __commonJS((exports) => {
469
469
  exports.findNewAnchor = findNewAnchor;
470
470
  });
471
471
 
472
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
472
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/applyReviver.js
473
473
  var require_applyReviver = __commonJS((exports) => {
474
474
  function applyReviver(reviver, obj, key, val) {
475
475
  if (val && typeof val === "object") {
@@ -516,7 +516,7 @@ var require_applyReviver = __commonJS((exports) => {
516
516
  exports.applyReviver = applyReviver;
517
517
  });
518
518
 
519
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
519
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/toJS.js
520
520
  var require_toJS = __commonJS((exports) => {
521
521
  var identity = require_identity();
522
522
  function toJS(value, arg, ctx) {
@@ -543,7 +543,7 @@ var require_toJS = __commonJS((exports) => {
543
543
  exports.toJS = toJS;
544
544
  });
545
545
 
546
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
546
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Node.js
547
547
  var require_Node = __commonJS((exports) => {
548
548
  var applyReviver = require_applyReviver();
549
549
  var identity = require_identity();
@@ -580,7 +580,7 @@ var require_Node = __commonJS((exports) => {
580
580
  exports.NodeBase = NodeBase;
581
581
  });
582
582
 
583
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
583
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Alias.js
584
584
  var require_Alias = __commonJS((exports) => {
585
585
  var anchors = require_anchors();
586
586
  var visit = require_visit();
@@ -688,7 +688,7 @@ var require_Alias = __commonJS((exports) => {
688
688
  exports.Alias = Alias;
689
689
  });
690
690
 
691
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
691
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Scalar.js
692
692
  var require_Scalar = __commonJS((exports) => {
693
693
  var identity = require_identity();
694
694
  var Node = require_Node();
@@ -716,7 +716,7 @@ var require_Scalar = __commonJS((exports) => {
716
716
  exports.isScalarValue = isScalarValue;
717
717
  });
718
718
 
719
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
719
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/createNode.js
720
720
  var require_createNode = __commonJS((exports) => {
721
721
  var Alias = require_Alias();
722
722
  var identity = require_identity();
@@ -788,7 +788,7 @@ var require_createNode = __commonJS((exports) => {
788
788
  exports.createNode = createNode;
789
789
  });
790
790
 
791
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
791
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Collection.js
792
792
  var require_Collection = __commonJS((exports) => {
793
793
  var createNode = require_createNode();
794
794
  var identity = require_identity();
@@ -903,7 +903,7 @@ var require_Collection = __commonJS((exports) => {
903
903
  exports.isEmptyPath = isEmptyPath;
904
904
  });
905
905
 
906
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
906
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyComment.js
907
907
  var require_stringifyComment = __commonJS((exports) => {
908
908
  var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
909
909
  function indentComment(comment, indent) {
@@ -920,7 +920,7 @@ var require_stringifyComment = __commonJS((exports) => {
920
920
  exports.stringifyComment = stringifyComment;
921
921
  });
922
922
 
923
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
923
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/foldFlowLines.js
924
924
  var require_foldFlowLines = __commonJS((exports) => {
925
925
  var FOLD_FLOW = "flow";
926
926
  var FOLD_BLOCK = "block";
@@ -1057,7 +1057,7 @@ ${indent}${text.slice(fold + 1, end2)}`;
1057
1057
  exports.foldFlowLines = foldFlowLines;
1058
1058
  });
1059
1059
 
1060
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
1060
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyString.js
1061
1061
  var require_stringifyString = __commonJS((exports) => {
1062
1062
  var Scalar = require_Scalar();
1063
1063
  var foldFlowLines = require_foldFlowLines();
@@ -1355,7 +1355,7 @@ ${indent}`);
1355
1355
  exports.stringifyString = stringifyString;
1356
1356
  });
1357
1357
 
1358
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
1358
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringify.js
1359
1359
  var require_stringify = __commonJS((exports) => {
1360
1360
  var anchors = require_anchors();
1361
1361
  var identity = require_identity();
@@ -1476,7 +1476,7 @@ ${ctx.indent}${str}`;
1476
1476
  exports.stringify = stringify;
1477
1477
  });
1478
1478
 
1479
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
1479
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyPair.js
1480
1480
  var require_stringifyPair = __commonJS((exports) => {
1481
1481
  var identity = require_identity();
1482
1482
  var Scalar = require_Scalar();
@@ -1612,7 +1612,7 @@ ${ctx.indent}`;
1612
1612
  exports.stringifyPair = stringifyPair;
1613
1613
  });
1614
1614
 
1615
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
1615
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/log.js
1616
1616
  var require_log = __commonJS((exports) => {
1617
1617
  var node_process = __require("process");
1618
1618
  function debug(logLevel, ...messages) {
@@ -1631,7 +1631,7 @@ var require_log = __commonJS((exports) => {
1631
1631
  exports.warn = warn;
1632
1632
  });
1633
1633
 
1634
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
1634
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/merge.js
1635
1635
  var require_merge = __commonJS((exports) => {
1636
1636
  var identity = require_identity();
1637
1637
  var Scalar = require_Scalar();
@@ -1685,7 +1685,7 @@ var require_merge = __commonJS((exports) => {
1685
1685
  exports.merge = merge;
1686
1686
  });
1687
1687
 
1688
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
1688
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/addPairToJSMap.js
1689
1689
  var require_addPairToJSMap = __commonJS((exports) => {
1690
1690
  var log = require_log();
1691
1691
  var merge = require_merge();
@@ -1746,7 +1746,7 @@ var require_addPairToJSMap = __commonJS((exports) => {
1746
1746
  exports.addPairToJSMap = addPairToJSMap;
1747
1747
  });
1748
1748
 
1749
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
1749
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/Pair.js
1750
1750
  var require_Pair = __commonJS((exports) => {
1751
1751
  var createNode = require_createNode();
1752
1752
  var stringifyPair = require_stringifyPair();
@@ -1784,7 +1784,7 @@ var require_Pair = __commonJS((exports) => {
1784
1784
  exports.createPair = createPair;
1785
1785
  });
1786
1786
 
1787
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
1787
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyCollection.js
1788
1788
  var require_stringifyCollection = __commonJS((exports) => {
1789
1789
  var identity = require_identity();
1790
1790
  var stringify = require_stringify();
@@ -1936,7 +1936,7 @@ ${indent}${end}`;
1936
1936
  exports.stringifyCollection = stringifyCollection;
1937
1937
  });
1938
1938
 
1939
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
1939
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLMap.js
1940
1940
  var require_YAMLMap = __commonJS((exports) => {
1941
1941
  var stringifyCollection = require_stringifyCollection();
1942
1942
  var addPairToJSMap = require_addPairToJSMap();
@@ -2063,7 +2063,7 @@ var require_YAMLMap = __commonJS((exports) => {
2063
2063
  exports.findPair = findPair;
2064
2064
  });
2065
2065
 
2066
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
2066
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/map.js
2067
2067
  var require_map = __commonJS((exports) => {
2068
2068
  var identity = require_identity();
2069
2069
  var YAMLMap = require_YAMLMap();
@@ -2082,7 +2082,7 @@ var require_map = __commonJS((exports) => {
2082
2082
  exports.map = map;
2083
2083
  });
2084
2084
 
2085
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
2085
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/nodes/YAMLSeq.js
2086
2086
  var require_YAMLSeq = __commonJS((exports) => {
2087
2087
  var createNode = require_createNode();
2088
2088
  var stringifyCollection = require_stringifyCollection();
@@ -2175,7 +2175,7 @@ var require_YAMLSeq = __commonJS((exports) => {
2175
2175
  exports.YAMLSeq = YAMLSeq;
2176
2176
  });
2177
2177
 
2178
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
2178
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/seq.js
2179
2179
  var require_seq = __commonJS((exports) => {
2180
2180
  var identity = require_identity();
2181
2181
  var YAMLSeq = require_YAMLSeq();
@@ -2194,7 +2194,7 @@ var require_seq = __commonJS((exports) => {
2194
2194
  exports.seq = seq;
2195
2195
  });
2196
2196
 
2197
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
2197
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/string.js
2198
2198
  var require_string = __commonJS((exports) => {
2199
2199
  var stringifyString = require_stringifyString();
2200
2200
  var string = {
@@ -2210,7 +2210,7 @@ var require_string = __commonJS((exports) => {
2210
2210
  exports.string = string;
2211
2211
  });
2212
2212
 
2213
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
2213
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/common/null.js
2214
2214
  var require_null = __commonJS((exports) => {
2215
2215
  var Scalar = require_Scalar();
2216
2216
  var nullTag = {
@@ -2225,7 +2225,7 @@ var require_null = __commonJS((exports) => {
2225
2225
  exports.nullTag = nullTag;
2226
2226
  });
2227
2227
 
2228
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
2228
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/bool.js
2229
2229
  var require_bool = __commonJS((exports) => {
2230
2230
  var Scalar = require_Scalar();
2231
2231
  var boolTag = {
@@ -2246,7 +2246,7 @@ var require_bool = __commonJS((exports) => {
2246
2246
  exports.boolTag = boolTag;
2247
2247
  });
2248
2248
 
2249
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
2249
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyNumber.js
2250
2250
  var require_stringifyNumber = __commonJS((exports) => {
2251
2251
  function stringifyNumber({ format, minFractionDigits, tag, value }) {
2252
2252
  if (typeof value === "bigint")
@@ -2270,7 +2270,7 @@ var require_stringifyNumber = __commonJS((exports) => {
2270
2270
  exports.stringifyNumber = stringifyNumber;
2271
2271
  });
2272
2272
 
2273
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
2273
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/float.js
2274
2274
  var require_float = __commonJS((exports) => {
2275
2275
  var Scalar = require_Scalar();
2276
2276
  var stringifyNumber = require_stringifyNumber();
@@ -2313,7 +2313,7 @@ var require_float = __commonJS((exports) => {
2313
2313
  exports.floatNaN = floatNaN;
2314
2314
  });
2315
2315
 
2316
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
2316
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/int.js
2317
2317
  var require_int = __commonJS((exports) => {
2318
2318
  var stringifyNumber = require_stringifyNumber();
2319
2319
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -2355,7 +2355,7 @@ var require_int = __commonJS((exports) => {
2355
2355
  exports.intOct = intOct;
2356
2356
  });
2357
2357
 
2358
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
2358
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/core/schema.js
2359
2359
  var require_schema = __commonJS((exports) => {
2360
2360
  var map = require_map();
2361
2361
  var _null = require_null();
@@ -2380,7 +2380,7 @@ var require_schema = __commonJS((exports) => {
2380
2380
  exports.schema = schema;
2381
2381
  });
2382
2382
 
2383
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
2383
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/json/schema.js
2384
2384
  var require_schema2 = __commonJS((exports) => {
2385
2385
  var Scalar = require_Scalar();
2386
2386
  var map = require_map();
@@ -2444,7 +2444,7 @@ var require_schema2 = __commonJS((exports) => {
2444
2444
  exports.schema = schema;
2445
2445
  });
2446
2446
 
2447
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
2447
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/binary.js
2448
2448
  var require_binary = __commonJS((exports) => {
2449
2449
  var node_buffer = __require("buffer");
2450
2450
  var Scalar = require_Scalar();
@@ -2499,7 +2499,7 @@ var require_binary = __commonJS((exports) => {
2499
2499
  exports.binary = binary;
2500
2500
  });
2501
2501
 
2502
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
2502
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/pairs.js
2503
2503
  var require_pairs = __commonJS((exports) => {
2504
2504
  var identity = require_identity();
2505
2505
  var Pair = require_Pair();
@@ -2574,7 +2574,7 @@ ${cn.comment}` : item.comment;
2574
2574
  exports.resolvePairs = resolvePairs;
2575
2575
  });
2576
2576
 
2577
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
2577
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/omap.js
2578
2578
  var require_omap = __commonJS((exports) => {
2579
2579
  var identity = require_identity();
2580
2580
  var toJS = require_toJS();
@@ -2646,7 +2646,7 @@ var require_omap = __commonJS((exports) => {
2646
2646
  exports.omap = omap;
2647
2647
  });
2648
2648
 
2649
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
2649
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/bool.js
2650
2650
  var require_bool2 = __commonJS((exports) => {
2651
2651
  var Scalar = require_Scalar();
2652
2652
  function boolStringify({ value, source }, ctx) {
@@ -2675,7 +2675,7 @@ var require_bool2 = __commonJS((exports) => {
2675
2675
  exports.trueTag = trueTag;
2676
2676
  });
2677
2677
 
2678
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
2678
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/float.js
2679
2679
  var require_float2 = __commonJS((exports) => {
2680
2680
  var Scalar = require_Scalar();
2681
2681
  var stringifyNumber = require_stringifyNumber();
@@ -2721,7 +2721,7 @@ var require_float2 = __commonJS((exports) => {
2721
2721
  exports.floatNaN = floatNaN;
2722
2722
  });
2723
2723
 
2724
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
2724
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/int.js
2725
2725
  var require_int2 = __commonJS((exports) => {
2726
2726
  var stringifyNumber = require_stringifyNumber();
2727
2727
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
@@ -2797,7 +2797,7 @@ var require_int2 = __commonJS((exports) => {
2797
2797
  exports.intOct = intOct;
2798
2798
  });
2799
2799
 
2800
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
2800
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/set.js
2801
2801
  var require_set = __commonJS((exports) => {
2802
2802
  var identity = require_identity();
2803
2803
  var Pair = require_Pair();
@@ -2880,7 +2880,7 @@ var require_set = __commonJS((exports) => {
2880
2880
  exports.set = set;
2881
2881
  });
2882
2882
 
2883
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
2883
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
2884
2884
  var require_timestamp = __commonJS((exports) => {
2885
2885
  var stringifyNumber = require_stringifyNumber();
2886
2886
  function parseSexagesimal(str, asBigInt) {
@@ -2962,7 +2962,7 @@ var require_timestamp = __commonJS((exports) => {
2962
2962
  exports.timestamp = timestamp;
2963
2963
  });
2964
2964
 
2965
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
2965
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/yaml-1.1/schema.js
2966
2966
  var require_schema3 = __commonJS((exports) => {
2967
2967
  var map = require_map();
2968
2968
  var _null = require_null();
@@ -3003,7 +3003,7 @@ var require_schema3 = __commonJS((exports) => {
3003
3003
  exports.schema = schema;
3004
3004
  });
3005
3005
 
3006
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
3006
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/tags.js
3007
3007
  var require_tags = __commonJS((exports) => {
3008
3008
  var map = require_map();
3009
3009
  var _null = require_null();
@@ -3094,7 +3094,7 @@ var require_tags = __commonJS((exports) => {
3094
3094
  exports.getTags = getTags;
3095
3095
  });
3096
3096
 
3097
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
3097
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/schema/Schema.js
3098
3098
  var require_Schema = __commonJS((exports) => {
3099
3099
  var identity = require_identity();
3100
3100
  var map = require_map();
@@ -3124,7 +3124,7 @@ var require_Schema = __commonJS((exports) => {
3124
3124
  exports.Schema = Schema;
3125
3125
  });
3126
3126
 
3127
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
3127
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/stringify/stringifyDocument.js
3128
3128
  var require_stringifyDocument = __commonJS((exports) => {
3129
3129
  var identity = require_identity();
3130
3130
  var stringify = require_stringify();
@@ -3204,7 +3204,7 @@ var require_stringifyDocument = __commonJS((exports) => {
3204
3204
  exports.stringifyDocument = stringifyDocument;
3205
3205
  });
3206
3206
 
3207
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
3207
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/doc/Document.js
3208
3208
  var require_Document = __commonJS((exports) => {
3209
3209
  var Alias = require_Alias();
3210
3210
  var Collection = require_Collection();
@@ -3439,7 +3439,7 @@ var require_Document = __commonJS((exports) => {
3439
3439
  exports.Document = Document;
3440
3440
  });
3441
3441
 
3442
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
3442
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/errors.js
3443
3443
  var require_errors = __commonJS((exports) => {
3444
3444
  class YAMLError extends Error {
3445
3445
  constructor(name, pos, code, message) {
@@ -3504,7 +3504,7 @@ ${pointer}
3504
3504
  exports.prettifyError = prettifyError;
3505
3505
  });
3506
3506
 
3507
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
3507
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-props.js
3508
3508
  var require_resolve_props = __commonJS((exports) => {
3509
3509
  function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
3510
3510
  let spaceBefore = false;
@@ -3634,7 +3634,7 @@ var require_resolve_props = __commonJS((exports) => {
3634
3634
  exports.resolveProps = resolveProps;
3635
3635
  });
3636
3636
 
3637
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
3637
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-contains-newline.js
3638
3638
  var require_util_contains_newline = __commonJS((exports) => {
3639
3639
  function containsNewline(key) {
3640
3640
  if (!key)
@@ -3674,7 +3674,7 @@ var require_util_contains_newline = __commonJS((exports) => {
3674
3674
  exports.containsNewline = containsNewline;
3675
3675
  });
3676
3676
 
3677
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
3677
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-flow-indent-check.js
3678
3678
  var require_util_flow_indent_check = __commonJS((exports) => {
3679
3679
  var utilContainsNewline = require_util_contains_newline();
3680
3680
  function flowIndentCheck(indent, fc, onError) {
@@ -3689,7 +3689,7 @@ var require_util_flow_indent_check = __commonJS((exports) => {
3689
3689
  exports.flowIndentCheck = flowIndentCheck;
3690
3690
  });
3691
3691
 
3692
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
3692
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-map-includes.js
3693
3693
  var require_util_map_includes = __commonJS((exports) => {
3694
3694
  var identity = require_identity();
3695
3695
  function mapIncludes(ctx, items, search) {
@@ -3702,7 +3702,7 @@ var require_util_map_includes = __commonJS((exports) => {
3702
3702
  exports.mapIncludes = mapIncludes;
3703
3703
  });
3704
3704
 
3705
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
3705
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-map.js
3706
3706
  var require_resolve_block_map = __commonJS((exports) => {
3707
3707
  var Pair = require_Pair();
3708
3708
  var YAMLMap = require_YAMLMap();
@@ -3809,7 +3809,7 @@ var require_resolve_block_map = __commonJS((exports) => {
3809
3809
  exports.resolveBlockMap = resolveBlockMap;
3810
3810
  });
3811
3811
 
3812
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
3812
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-seq.js
3813
3813
  var require_resolve_block_seq = __commonJS((exports) => {
3814
3814
  var YAMLSeq = require_YAMLSeq();
3815
3815
  var resolveProps = require_resolve_props();
@@ -3857,7 +3857,7 @@ var require_resolve_block_seq = __commonJS((exports) => {
3857
3857
  exports.resolveBlockSeq = resolveBlockSeq;
3858
3858
  });
3859
3859
 
3860
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
3860
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-end.js
3861
3861
  var require_resolve_end = __commonJS((exports) => {
3862
3862
  function resolveEnd(end, offset, reqSpace, onError) {
3863
3863
  let comment = "";
@@ -3897,7 +3897,7 @@ var require_resolve_end = __commonJS((exports) => {
3897
3897
  exports.resolveEnd = resolveEnd;
3898
3898
  });
3899
3899
 
3900
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
3900
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-collection.js
3901
3901
  var require_resolve_flow_collection = __commonJS((exports) => {
3902
3902
  var identity = require_identity();
3903
3903
  var Pair = require_Pair();
@@ -4088,7 +4088,7 @@ var require_resolve_flow_collection = __commonJS((exports) => {
4088
4088
  exports.resolveFlowCollection = resolveFlowCollection;
4089
4089
  });
4090
4090
 
4091
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
4091
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-collection.js
4092
4092
  var require_compose_collection = __commonJS((exports) => {
4093
4093
  var identity = require_identity();
4094
4094
  var Scalar = require_Scalar();
@@ -4150,7 +4150,7 @@ var require_compose_collection = __commonJS((exports) => {
4150
4150
  exports.composeCollection = composeCollection;
4151
4151
  });
4152
4152
 
4153
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
4153
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-block-scalar.js
4154
4154
  var require_resolve_block_scalar = __commonJS((exports) => {
4155
4155
  var Scalar = require_Scalar();
4156
4156
  function resolveBlockScalar(ctx, scalar, onError) {
@@ -4343,7 +4343,7 @@ var require_resolve_block_scalar = __commonJS((exports) => {
4343
4343
  exports.resolveBlockScalar = resolveBlockScalar;
4344
4344
  });
4345
4345
 
4346
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
4346
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/resolve-flow-scalar.js
4347
4347
  var require_resolve_flow_scalar = __commonJS((exports) => {
4348
4348
  var Scalar = require_Scalar();
4349
4349
  var resolveEnd = require_resolve_end();
@@ -4559,7 +4559,7 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
4559
4559
  exports.resolveFlowScalar = resolveFlowScalar;
4560
4560
  });
4561
4561
 
4562
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
4562
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-scalar.js
4563
4563
  var require_compose_scalar = __commonJS((exports) => {
4564
4564
  var identity = require_identity();
4565
4565
  var Scalar = require_Scalar();
@@ -4637,7 +4637,7 @@ var require_compose_scalar = __commonJS((exports) => {
4637
4637
  exports.composeScalar = composeScalar;
4638
4638
  });
4639
4639
 
4640
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
4640
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/util-empty-scalar-position.js
4641
4641
  var require_util_empty_scalar_position = __commonJS((exports) => {
4642
4642
  function emptyScalarPosition(offset, before, pos) {
4643
4643
  if (before) {
@@ -4664,7 +4664,7 @@ var require_util_empty_scalar_position = __commonJS((exports) => {
4664
4664
  exports.emptyScalarPosition = emptyScalarPosition;
4665
4665
  });
4666
4666
 
4667
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
4667
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-node.js
4668
4668
  var require_compose_node = __commonJS((exports) => {
4669
4669
  var Alias = require_Alias();
4670
4670
  var identity = require_identity();
@@ -4767,7 +4767,7 @@ var require_compose_node = __commonJS((exports) => {
4767
4767
  exports.composeNode = composeNode;
4768
4768
  });
4769
4769
 
4770
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
4770
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/compose-doc.js
4771
4771
  var require_compose_doc = __commonJS((exports) => {
4772
4772
  var Document = require_Document();
4773
4773
  var composeNode = require_compose_node();
@@ -4807,7 +4807,7 @@ var require_compose_doc = __commonJS((exports) => {
4807
4807
  exports.composeDoc = composeDoc;
4808
4808
  });
4809
4809
 
4810
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
4810
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/compose/composer.js
4811
4811
  var require_composer = __commonJS((exports) => {
4812
4812
  var node_process = __require("process");
4813
4813
  var directives = require_directives();
@@ -4996,7 +4996,7 @@ ${end.comment}` : end.comment;
4996
4996
  exports.Composer = Composer;
4997
4997
  });
4998
4998
 
4999
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
4999
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-scalar.js
5000
5000
  var require_cst_scalar = __commonJS((exports) => {
5001
5001
  var resolveBlockScalar = require_resolve_block_scalar();
5002
5002
  var resolveFlowScalar = require_resolve_flow_scalar();
@@ -5186,7 +5186,7 @@ var require_cst_scalar = __commonJS((exports) => {
5186
5186
  exports.setScalarValue = setScalarValue;
5187
5187
  });
5188
5188
 
5189
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
5189
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-stringify.js
5190
5190
  var require_cst_stringify = __commonJS((exports) => {
5191
5191
  var stringify = (cst) => ("type" in cst) ? stringifyToken(cst) : stringifyItem(cst);
5192
5192
  function stringifyToken(token) {
@@ -5244,7 +5244,7 @@ var require_cst_stringify = __commonJS((exports) => {
5244
5244
  exports.stringify = stringify;
5245
5245
  });
5246
5246
 
5247
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
5247
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst-visit.js
5248
5248
  var require_cst_visit = __commonJS((exports) => {
5249
5249
  var BREAK = Symbol("break visit");
5250
5250
  var SKIP = Symbol("skip children");
@@ -5303,7 +5303,7 @@ var require_cst_visit = __commonJS((exports) => {
5303
5303
  exports.visit = visit;
5304
5304
  });
5305
5305
 
5306
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
5306
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/cst.js
5307
5307
  var require_cst = __commonJS((exports) => {
5308
5308
  var cstScalar = require_cst_scalar();
5309
5309
  var cstStringify = require_cst_stringify();
@@ -5404,7 +5404,7 @@ var require_cst = __commonJS((exports) => {
5404
5404
  exports.tokenType = tokenType;
5405
5405
  });
5406
5406
 
5407
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
5407
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/lexer.js
5408
5408
  var require_lexer = __commonJS((exports) => {
5409
5409
  var cst = require_cst();
5410
5410
  function isEmpty(ch) {
@@ -5990,7 +5990,7 @@ var require_lexer = __commonJS((exports) => {
5990
5990
  exports.Lexer = Lexer;
5991
5991
  });
5992
5992
 
5993
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
5993
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/line-counter.js
5994
5994
  var require_line_counter = __commonJS((exports) => {
5995
5995
  class LineCounter {
5996
5996
  constructor() {
@@ -6018,7 +6018,7 @@ var require_line_counter = __commonJS((exports) => {
6018
6018
  exports.LineCounter = LineCounter;
6019
6019
  });
6020
6020
 
6021
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
6021
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/parse/parser.js
6022
6022
  var require_parser = __commonJS((exports) => {
6023
6023
  var node_process = __require("process");
6024
6024
  var cst = require_cst();
@@ -6867,7 +6867,7 @@ var require_parser = __commonJS((exports) => {
6867
6867
  exports.Parser = Parser;
6868
6868
  });
6869
6869
 
6870
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
6870
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/public-api.js
6871
6871
  var require_public_api = __commonJS((exports) => {
6872
6872
  var composer = require_composer();
6873
6873
  var Document = require_Document();
@@ -7001,7 +7001,7 @@ function deriveSlug(inputs, existing) {
7001
7001
  return `${base}_${n}`;
7002
7002
  }
7003
7003
 
7004
- // node_modules/.bun/boundary@2.0.0/node_modules/boundary/lib/index.js
7004
+ // ../../switchroom/node_modules/.bun/boundary@2.0.0/node_modules/boundary/lib/index.js
7005
7005
  var require_lib = __commonJS((exports2) => {
7006
7006
  Object.defineProperty(exports2, "__esModule", { value: true });
7007
7007
  exports2.binarySearch = exports2.upperBound = exports2.lowerBound = exports2.compare = undefined;
@@ -7048,7 +7048,7 @@ var require_lib = __commonJS((exports2) => {
7048
7048
  exports2.binarySearch = binarySearch;
7049
7049
  });
7050
7050
 
7051
- // node_modules/.bun/structured-source@4.0.0/node_modules/structured-source/lib/structured-source.js
7051
+ // ../../switchroom/node_modules/.bun/structured-source@4.0.0/node_modules/structured-source/lib/structured-source.js
7052
7052
  var require_structured_source = __commonJS((exports2) => {
7053
7053
  Object.defineProperty(exports2, "__esModule", { value: true });
7054
7054
  exports2.StructuredSource = undefined;
@@ -7103,13 +7103,13 @@ var require_structured_source = __commonJS((exports2) => {
7103
7103
  }
7104
7104
  exports2.StructuredSource = StructuredSource;
7105
7105
  });
7106
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/SecretLintSourceCodeImpl.js
7106
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/SecretLintSourceCodeImpl.js
7107
7107
  var import_structured_source;
7108
7108
  var init_SecretLintSourceCodeImpl = __esm(() => {
7109
7109
  import_structured_source = __toESM(require_structured_source(), 1);
7110
7110
  });
7111
7111
 
7112
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/helper/promise-event-emitter.js
7112
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/helper/promise-event-emitter.js
7113
7113
  class EventEmitter {
7114
7114
  #listeners = new Map;
7115
7115
  on(type, listener) {
@@ -7148,9 +7148,9 @@ class EventEmitter {
7148
7148
  return Array.from(this.#listeners.get(type) ?? []);
7149
7149
  }
7150
7150
  }
7151
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RuleContext.js
7151
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RuleContext.js
7152
7152
  var init_RuleContext = () => {};
7153
- // node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/index.js
7153
+ // ../../switchroom/node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/index.js
7154
7154
  class SecretLintProfiler {
7155
7155
  perf;
7156
7156
  entries = [];
@@ -7207,7 +7207,7 @@ class SecretLintProfiler {
7207
7207
  }
7208
7208
  }
7209
7209
 
7210
- // node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/node.js
7210
+ // ../../switchroom/node_modules/.bun/@secretlint+profiler@12.2.0/node_modules/@secretlint/profiler/module/node.js
7211
7211
  import perf_hooks from "node:perf_hooks";
7212
7212
 
7213
7213
  class NullPerformanceObserver {
@@ -7222,19 +7222,19 @@ var init_node = __esm(() => {
7222
7222
  });
7223
7223
  });
7224
7224
 
7225
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RunningEvents.js
7225
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RunningEvents.js
7226
7226
  var init_RunningEvents = __esm(() => {
7227
7227
  init_node();
7228
7228
  });
7229
7229
 
7230
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RulePresetContext.js
7230
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/RulePresetContext.js
7231
7231
  var init_RulePresetContext = __esm(() => {
7232
7232
  init_RuleContext();
7233
7233
  });
7234
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/messages/index.js
7234
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/messages/index.js
7235
7235
  var init_messages = () => {};
7236
7236
 
7237
- // node_modules/.bun/ms@2.1.3/node_modules/ms/index.js
7237
+ // ../../switchroom/node_modules/.bun/ms@2.1.3/node_modules/ms/index.js
7238
7238
  var require_ms = __commonJS((exports2, module) => {
7239
7239
  var s = 1000;
7240
7240
  var m = s * 60;
@@ -7344,7 +7344,7 @@ var require_ms = __commonJS((exports2, module) => {
7344
7344
  }
7345
7345
  });
7346
7346
 
7347
- // node_modules/.bun/debug@4.4.3/node_modules/debug/src/common.js
7347
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/common.js
7348
7348
  var require_common = __commonJS((exports2, module) => {
7349
7349
  function setup(env) {
7350
7350
  createDebug.debug = createDebug;
@@ -7519,7 +7519,7 @@ var require_common = __commonJS((exports2, module) => {
7519
7519
  module.exports = setup;
7520
7520
  });
7521
7521
 
7522
- // node_modules/.bun/debug@4.4.3/node_modules/debug/src/browser.js
7522
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/browser.js
7523
7523
  var require_browser = __commonJS((exports2, module) => {
7524
7524
  exports2.formatArgs = formatArgs;
7525
7525
  exports2.save = save;
@@ -7679,7 +7679,7 @@ var require_browser = __commonJS((exports2, module) => {
7679
7679
  };
7680
7680
  });
7681
7681
 
7682
- // node_modules/.bun/has-flag@4.0.0/node_modules/has-flag/index.js
7682
+ // ../../switchroom/node_modules/.bun/has-flag@4.0.0/node_modules/has-flag/index.js
7683
7683
  var require_has_flag = __commonJS((exports2, module) => {
7684
7684
  module.exports = (flag, argv = process.argv) => {
7685
7685
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -7689,7 +7689,7 @@ var require_has_flag = __commonJS((exports2, module) => {
7689
7689
  };
7690
7690
  });
7691
7691
 
7692
- // node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
7692
+ // ../../switchroom/node_modules/.bun/supports-color@7.2.0/node_modules/supports-color/index.js
7693
7693
  var require_supports_color = __commonJS((exports2, module) => {
7694
7694
  var os = __require("os");
7695
7695
  var tty = __require("tty");
@@ -7788,7 +7788,7 @@ var require_supports_color = __commonJS((exports2, module) => {
7788
7788
  };
7789
7789
  });
7790
7790
 
7791
- // node_modules/.bun/debug@4.4.3/node_modules/debug/src/node.js
7791
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/node.js
7792
7792
  var require_node = __commonJS((exports2, module) => {
7793
7793
  var tty = __require("tty");
7794
7794
  var util3 = __require("util");
@@ -7959,7 +7959,7 @@ var require_node = __commonJS((exports2, module) => {
7959
7959
  };
7960
7960
  });
7961
7961
 
7962
- // node_modules/.bun/debug@4.4.3/node_modules/debug/src/index.js
7962
+ // ../../switchroom/node_modules/.bun/debug@4.4.3/node_modules/debug/src/index.js
7963
7963
  var require_src = __commonJS((exports2, module) => {
7964
7964
  if (typeof process === "undefined" || process.type === "renderer" || false || process.__nwjs) {
7965
7965
  module.exports = require_browser();
@@ -7968,7 +7968,7 @@ var require_src = __commonJS((exports2, module) => {
7968
7968
  }
7969
7969
  });
7970
7970
 
7971
- // node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/index.js
7971
+ // ../../switchroom/node_modules/.bun/@secretlint+core@12.2.0/node_modules/@secretlint/core/module/index.js
7972
7972
  var import_debug, debug;
7973
7973
  var init_module = __esm(() => {
7974
7974
  init_SecretLintSourceCodeImpl();
@@ -7981,7 +7981,7 @@ var init_module = __esm(() => {
7981
7981
  debug = import_debug.default("@secretlint/core");
7982
7982
  });
7983
7983
 
7984
- // node_modules/.bun/@secretlint+secretlint-rule-preset-recommend@12.2.0/node_modules/@secretlint/secretlint-rule-preset-recommend/module/index.js
7984
+ // ../../switchroom/node_modules/.bun/@secretlint+secretlint-rule-preset-recommend@12.2.0/node_modules/@secretlint/secretlint-rule-preset-recommend/module/index.js
7985
7985
  function requireLodash_uniq() {
7986
7986
  if (hasRequiredLodash_uniq)
7987
7987
  return lodash_uniq;
@@ -9664,17 +9664,2051 @@ var init_secretlint_source = __esm(() => {
9664
9664
  init_suppressor();
9665
9665
  });
9666
9666
 
9667
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/error.js
9668
+ var require_error = __commonJS((exports2) => {
9669
+ class CommanderError extends Error {
9670
+ constructor(exitCode, code, message) {
9671
+ super(message);
9672
+ Error.captureStackTrace(this, this.constructor);
9673
+ this.name = this.constructor.name;
9674
+ this.code = code;
9675
+ this.exitCode = exitCode;
9676
+ this.nestedError = undefined;
9677
+ }
9678
+ }
9679
+
9680
+ class InvalidArgumentError extends CommanderError {
9681
+ constructor(message) {
9682
+ super(1, "commander.invalidArgument", message);
9683
+ Error.captureStackTrace(this, this.constructor);
9684
+ this.name = this.constructor.name;
9685
+ }
9686
+ }
9687
+ exports2.CommanderError = CommanderError;
9688
+ exports2.InvalidArgumentError = InvalidArgumentError;
9689
+ });
9690
+
9691
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/argument.js
9692
+ var require_argument = __commonJS((exports2) => {
9693
+ var { InvalidArgumentError } = require_error();
9694
+
9695
+ class Argument {
9696
+ constructor(name, description) {
9697
+ this.description = description || "";
9698
+ this.variadic = false;
9699
+ this.parseArg = undefined;
9700
+ this.defaultValue = undefined;
9701
+ this.defaultValueDescription = undefined;
9702
+ this.argChoices = undefined;
9703
+ switch (name[0]) {
9704
+ case "<":
9705
+ this.required = true;
9706
+ this._name = name.slice(1, -1);
9707
+ break;
9708
+ case "[":
9709
+ this.required = false;
9710
+ this._name = name.slice(1, -1);
9711
+ break;
9712
+ default:
9713
+ this.required = true;
9714
+ this._name = name;
9715
+ break;
9716
+ }
9717
+ if (this._name.length > 3 && this._name.slice(-3) === "...") {
9718
+ this.variadic = true;
9719
+ this._name = this._name.slice(0, -3);
9720
+ }
9721
+ }
9722
+ name() {
9723
+ return this._name;
9724
+ }
9725
+ _concatValue(value, previous) {
9726
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
9727
+ return [value];
9728
+ }
9729
+ return previous.concat(value);
9730
+ }
9731
+ default(value, description) {
9732
+ this.defaultValue = value;
9733
+ this.defaultValueDescription = description;
9734
+ return this;
9735
+ }
9736
+ argParser(fn) {
9737
+ this.parseArg = fn;
9738
+ return this;
9739
+ }
9740
+ choices(values) {
9741
+ this.argChoices = values.slice();
9742
+ this.parseArg = (arg, previous) => {
9743
+ if (!this.argChoices.includes(arg)) {
9744
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
9745
+ }
9746
+ if (this.variadic) {
9747
+ return this._concatValue(arg, previous);
9748
+ }
9749
+ return arg;
9750
+ };
9751
+ return this;
9752
+ }
9753
+ argRequired() {
9754
+ this.required = true;
9755
+ return this;
9756
+ }
9757
+ argOptional() {
9758
+ this.required = false;
9759
+ return this;
9760
+ }
9761
+ }
9762
+ function humanReadableArgName(arg) {
9763
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
9764
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
9765
+ }
9766
+ exports2.Argument = Argument;
9767
+ exports2.humanReadableArgName = humanReadableArgName;
9768
+ });
9769
+
9770
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/help.js
9771
+ var require_help = __commonJS((exports2) => {
9772
+ var { humanReadableArgName } = require_argument();
9773
+
9774
+ class Help {
9775
+ constructor() {
9776
+ this.helpWidth = undefined;
9777
+ this.minWidthToWrap = 40;
9778
+ this.sortSubcommands = false;
9779
+ this.sortOptions = false;
9780
+ this.showGlobalOptions = false;
9781
+ }
9782
+ prepareContext(contextOptions) {
9783
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
9784
+ }
9785
+ visibleCommands(cmd) {
9786
+ const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
9787
+ const helpCommand = cmd._getHelpCommand();
9788
+ if (helpCommand && !helpCommand._hidden) {
9789
+ visibleCommands.push(helpCommand);
9790
+ }
9791
+ if (this.sortSubcommands) {
9792
+ visibleCommands.sort((a, b) => {
9793
+ return a.name().localeCompare(b.name());
9794
+ });
9795
+ }
9796
+ return visibleCommands;
9797
+ }
9798
+ compareOptions(a, b) {
9799
+ const getSortKey = (option) => {
9800
+ return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
9801
+ };
9802
+ return getSortKey(a).localeCompare(getSortKey(b));
9803
+ }
9804
+ visibleOptions(cmd) {
9805
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
9806
+ const helpOption = cmd._getHelpOption();
9807
+ if (helpOption && !helpOption.hidden) {
9808
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
9809
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
9810
+ if (!removeShort && !removeLong) {
9811
+ visibleOptions.push(helpOption);
9812
+ } else if (helpOption.long && !removeLong) {
9813
+ visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
9814
+ } else if (helpOption.short && !removeShort) {
9815
+ visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
9816
+ }
9817
+ }
9818
+ if (this.sortOptions) {
9819
+ visibleOptions.sort(this.compareOptions);
9820
+ }
9821
+ return visibleOptions;
9822
+ }
9823
+ visibleGlobalOptions(cmd) {
9824
+ if (!this.showGlobalOptions)
9825
+ return [];
9826
+ const globalOptions = [];
9827
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
9828
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
9829
+ globalOptions.push(...visibleOptions);
9830
+ }
9831
+ if (this.sortOptions) {
9832
+ globalOptions.sort(this.compareOptions);
9833
+ }
9834
+ return globalOptions;
9835
+ }
9836
+ visibleArguments(cmd) {
9837
+ if (cmd._argsDescription) {
9838
+ cmd.registeredArguments.forEach((argument) => {
9839
+ argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
9840
+ });
9841
+ }
9842
+ if (cmd.registeredArguments.find((argument) => argument.description)) {
9843
+ return cmd.registeredArguments;
9844
+ }
9845
+ return [];
9846
+ }
9847
+ subcommandTerm(cmd) {
9848
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
9849
+ return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
9850
+ }
9851
+ optionTerm(option) {
9852
+ return option.flags;
9853
+ }
9854
+ argumentTerm(argument) {
9855
+ return argument.name();
9856
+ }
9857
+ longestSubcommandTermLength(cmd, helper) {
9858
+ return helper.visibleCommands(cmd).reduce((max, command) => {
9859
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
9860
+ }, 0);
9861
+ }
9862
+ longestOptionTermLength(cmd, helper) {
9863
+ return helper.visibleOptions(cmd).reduce((max, option) => {
9864
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
9865
+ }, 0);
9866
+ }
9867
+ longestGlobalOptionTermLength(cmd, helper) {
9868
+ return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
9869
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
9870
+ }, 0);
9871
+ }
9872
+ longestArgumentTermLength(cmd, helper) {
9873
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
9874
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
9875
+ }, 0);
9876
+ }
9877
+ commandUsage(cmd) {
9878
+ let cmdName = cmd._name;
9879
+ if (cmd._aliases[0]) {
9880
+ cmdName = cmdName + "|" + cmd._aliases[0];
9881
+ }
9882
+ let ancestorCmdNames = "";
9883
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
9884
+ ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
9885
+ }
9886
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
9887
+ }
9888
+ commandDescription(cmd) {
9889
+ return cmd.description();
9890
+ }
9891
+ subcommandDescription(cmd) {
9892
+ return cmd.summary() || cmd.description();
9893
+ }
9894
+ optionDescription(option) {
9895
+ const extraInfo = [];
9896
+ if (option.argChoices) {
9897
+ extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
9898
+ }
9899
+ if (option.defaultValue !== undefined) {
9900
+ const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
9901
+ if (showDefault) {
9902
+ extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
9903
+ }
9904
+ }
9905
+ if (option.presetArg !== undefined && option.optional) {
9906
+ extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
9907
+ }
9908
+ if (option.envVar !== undefined) {
9909
+ extraInfo.push(`env: ${option.envVar}`);
9910
+ }
9911
+ if (extraInfo.length > 0) {
9912
+ return `${option.description} (${extraInfo.join(", ")})`;
9913
+ }
9914
+ return option.description;
9915
+ }
9916
+ argumentDescription(argument) {
9917
+ const extraInfo = [];
9918
+ if (argument.argChoices) {
9919
+ extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
9920
+ }
9921
+ if (argument.defaultValue !== undefined) {
9922
+ extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
9923
+ }
9924
+ if (extraInfo.length > 0) {
9925
+ const extraDescription = `(${extraInfo.join(", ")})`;
9926
+ if (argument.description) {
9927
+ return `${argument.description} ${extraDescription}`;
9928
+ }
9929
+ return extraDescription;
9930
+ }
9931
+ return argument.description;
9932
+ }
9933
+ formatHelp(cmd, helper) {
9934
+ const termWidth = helper.padWidth(cmd, helper);
9935
+ const helpWidth = helper.helpWidth ?? 80;
9936
+ function callFormatItem(term, description) {
9937
+ return helper.formatItem(term, termWidth, description, helper);
9938
+ }
9939
+ let output = [
9940
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
9941
+ ""
9942
+ ];
9943
+ const commandDescription = helper.commandDescription(cmd);
9944
+ if (commandDescription.length > 0) {
9945
+ output = output.concat([
9946
+ helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
9947
+ ""
9948
+ ]);
9949
+ }
9950
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
9951
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
9952
+ });
9953
+ if (argumentList.length > 0) {
9954
+ output = output.concat([
9955
+ helper.styleTitle("Arguments:"),
9956
+ ...argumentList,
9957
+ ""
9958
+ ]);
9959
+ }
9960
+ const optionList = helper.visibleOptions(cmd).map((option) => {
9961
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
9962
+ });
9963
+ if (optionList.length > 0) {
9964
+ output = output.concat([
9965
+ helper.styleTitle("Options:"),
9966
+ ...optionList,
9967
+ ""
9968
+ ]);
9969
+ }
9970
+ if (helper.showGlobalOptions) {
9971
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
9972
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
9973
+ });
9974
+ if (globalOptionList.length > 0) {
9975
+ output = output.concat([
9976
+ helper.styleTitle("Global Options:"),
9977
+ ...globalOptionList,
9978
+ ""
9979
+ ]);
9980
+ }
9981
+ }
9982
+ const commandList = helper.visibleCommands(cmd).map((cmd2) => {
9983
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(cmd2)), helper.styleSubcommandDescription(helper.subcommandDescription(cmd2)));
9984
+ });
9985
+ if (commandList.length > 0) {
9986
+ output = output.concat([
9987
+ helper.styleTitle("Commands:"),
9988
+ ...commandList,
9989
+ ""
9990
+ ]);
9991
+ }
9992
+ return output.join(`
9993
+ `);
9994
+ }
9995
+ displayWidth(str) {
9996
+ return stripColor(str).length;
9997
+ }
9998
+ styleTitle(str) {
9999
+ return str;
10000
+ }
10001
+ styleUsage(str) {
10002
+ return str.split(" ").map((word) => {
10003
+ if (word === "[options]")
10004
+ return this.styleOptionText(word);
10005
+ if (word === "[command]")
10006
+ return this.styleSubcommandText(word);
10007
+ if (word[0] === "[" || word[0] === "<")
10008
+ return this.styleArgumentText(word);
10009
+ return this.styleCommandText(word);
10010
+ }).join(" ");
10011
+ }
10012
+ styleCommandDescription(str) {
10013
+ return this.styleDescriptionText(str);
10014
+ }
10015
+ styleOptionDescription(str) {
10016
+ return this.styleDescriptionText(str);
10017
+ }
10018
+ styleSubcommandDescription(str) {
10019
+ return this.styleDescriptionText(str);
10020
+ }
10021
+ styleArgumentDescription(str) {
10022
+ return this.styleDescriptionText(str);
10023
+ }
10024
+ styleDescriptionText(str) {
10025
+ return str;
10026
+ }
10027
+ styleOptionTerm(str) {
10028
+ return this.styleOptionText(str);
10029
+ }
10030
+ styleSubcommandTerm(str) {
10031
+ return str.split(" ").map((word) => {
10032
+ if (word === "[options]")
10033
+ return this.styleOptionText(word);
10034
+ if (word[0] === "[" || word[0] === "<")
10035
+ return this.styleArgumentText(word);
10036
+ return this.styleSubcommandText(word);
10037
+ }).join(" ");
10038
+ }
10039
+ styleArgumentTerm(str) {
10040
+ return this.styleArgumentText(str);
10041
+ }
10042
+ styleOptionText(str) {
10043
+ return str;
10044
+ }
10045
+ styleArgumentText(str) {
10046
+ return str;
10047
+ }
10048
+ styleSubcommandText(str) {
10049
+ return str;
10050
+ }
10051
+ styleCommandText(str) {
10052
+ return str;
10053
+ }
10054
+ padWidth(cmd, helper) {
10055
+ return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
10056
+ }
10057
+ preformatted(str) {
10058
+ return /\n[^\S\r\n]/.test(str);
10059
+ }
10060
+ formatItem(term, termWidth, description, helper) {
10061
+ const itemIndent = 2;
10062
+ const itemIndentStr = " ".repeat(itemIndent);
10063
+ if (!description)
10064
+ return itemIndentStr + term;
10065
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
10066
+ const spacerWidth = 2;
10067
+ const helpWidth = this.helpWidth ?? 80;
10068
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
10069
+ let formattedDescription;
10070
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
10071
+ formattedDescription = description;
10072
+ } else {
10073
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
10074
+ formattedDescription = wrappedDescription.replace(/\n/g, `
10075
+ ` + " ".repeat(termWidth + spacerWidth));
10076
+ }
10077
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
10078
+ ${itemIndentStr}`);
10079
+ }
10080
+ boxWrap(str, width) {
10081
+ if (width < this.minWidthToWrap)
10082
+ return str;
10083
+ const rawLines = str.split(/\r\n|\n/);
10084
+ const chunkPattern = /[\s]*[^\s]+/g;
10085
+ const wrappedLines = [];
10086
+ rawLines.forEach((line) => {
10087
+ const chunks = line.match(chunkPattern);
10088
+ if (chunks === null) {
10089
+ wrappedLines.push("");
10090
+ return;
10091
+ }
10092
+ let sumChunks = [chunks.shift()];
10093
+ let sumWidth = this.displayWidth(sumChunks[0]);
10094
+ chunks.forEach((chunk2) => {
10095
+ const visibleWidth = this.displayWidth(chunk2);
10096
+ if (sumWidth + visibleWidth <= width) {
10097
+ sumChunks.push(chunk2);
10098
+ sumWidth += visibleWidth;
10099
+ return;
10100
+ }
10101
+ wrappedLines.push(sumChunks.join(""));
10102
+ const nextChunk = chunk2.trimStart();
10103
+ sumChunks = [nextChunk];
10104
+ sumWidth = this.displayWidth(nextChunk);
10105
+ });
10106
+ wrappedLines.push(sumChunks.join(""));
10107
+ });
10108
+ return wrappedLines.join(`
10109
+ `);
10110
+ }
10111
+ }
10112
+ function stripColor(str) {
10113
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
10114
+ return str.replace(sgrPattern, "");
10115
+ }
10116
+ exports2.Help = Help;
10117
+ exports2.stripColor = stripColor;
10118
+ });
10119
+
10120
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/option.js
10121
+ var require_option = __commonJS((exports2) => {
10122
+ var { InvalidArgumentError } = require_error();
10123
+
10124
+ class Option {
10125
+ constructor(flags, description) {
10126
+ this.flags = flags;
10127
+ this.description = description || "";
10128
+ this.required = flags.includes("<");
10129
+ this.optional = flags.includes("[");
10130
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags);
10131
+ this.mandatory = false;
10132
+ const optionFlags = splitOptionFlags(flags);
10133
+ this.short = optionFlags.shortFlag;
10134
+ this.long = optionFlags.longFlag;
10135
+ this.negate = false;
10136
+ if (this.long) {
10137
+ this.negate = this.long.startsWith("--no-");
10138
+ }
10139
+ this.defaultValue = undefined;
10140
+ this.defaultValueDescription = undefined;
10141
+ this.presetArg = undefined;
10142
+ this.envVar = undefined;
10143
+ this.parseArg = undefined;
10144
+ this.hidden = false;
10145
+ this.argChoices = undefined;
10146
+ this.conflictsWith = [];
10147
+ this.implied = undefined;
10148
+ }
10149
+ default(value, description) {
10150
+ this.defaultValue = value;
10151
+ this.defaultValueDescription = description;
10152
+ return this;
10153
+ }
10154
+ preset(arg) {
10155
+ this.presetArg = arg;
10156
+ return this;
10157
+ }
10158
+ conflicts(names) {
10159
+ this.conflictsWith = this.conflictsWith.concat(names);
10160
+ return this;
10161
+ }
10162
+ implies(impliedOptionValues) {
10163
+ let newImplied = impliedOptionValues;
10164
+ if (typeof impliedOptionValues === "string") {
10165
+ newImplied = { [impliedOptionValues]: true };
10166
+ }
10167
+ this.implied = Object.assign(this.implied || {}, newImplied);
10168
+ return this;
10169
+ }
10170
+ env(name) {
10171
+ this.envVar = name;
10172
+ return this;
10173
+ }
10174
+ argParser(fn) {
10175
+ this.parseArg = fn;
10176
+ return this;
10177
+ }
10178
+ makeOptionMandatory(mandatory = true) {
10179
+ this.mandatory = !!mandatory;
10180
+ return this;
10181
+ }
10182
+ hideHelp(hide = true) {
10183
+ this.hidden = !!hide;
10184
+ return this;
10185
+ }
10186
+ _concatValue(value, previous) {
10187
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
10188
+ return [value];
10189
+ }
10190
+ return previous.concat(value);
10191
+ }
10192
+ choices(values) {
10193
+ this.argChoices = values.slice();
10194
+ this.parseArg = (arg, previous) => {
10195
+ if (!this.argChoices.includes(arg)) {
10196
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
10197
+ }
10198
+ if (this.variadic) {
10199
+ return this._concatValue(arg, previous);
10200
+ }
10201
+ return arg;
10202
+ };
10203
+ return this;
10204
+ }
10205
+ name() {
10206
+ if (this.long) {
10207
+ return this.long.replace(/^--/, "");
10208
+ }
10209
+ return this.short.replace(/^-/, "");
10210
+ }
10211
+ attributeName() {
10212
+ if (this.negate) {
10213
+ return camelcase(this.name().replace(/^no-/, ""));
10214
+ }
10215
+ return camelcase(this.name());
10216
+ }
10217
+ is(arg) {
10218
+ return this.short === arg || this.long === arg;
10219
+ }
10220
+ isBoolean() {
10221
+ return !this.required && !this.optional && !this.negate;
10222
+ }
10223
+ }
10224
+
10225
+ class DualOptions {
10226
+ constructor(options) {
10227
+ this.positiveOptions = new Map;
10228
+ this.negativeOptions = new Map;
10229
+ this.dualOptions = new Set;
10230
+ options.forEach((option) => {
10231
+ if (option.negate) {
10232
+ this.negativeOptions.set(option.attributeName(), option);
10233
+ } else {
10234
+ this.positiveOptions.set(option.attributeName(), option);
10235
+ }
10236
+ });
10237
+ this.negativeOptions.forEach((value, key) => {
10238
+ if (this.positiveOptions.has(key)) {
10239
+ this.dualOptions.add(key);
10240
+ }
10241
+ });
10242
+ }
10243
+ valueFromOption(value, option) {
10244
+ const optionKey = option.attributeName();
10245
+ if (!this.dualOptions.has(optionKey))
10246
+ return true;
10247
+ const preset = this.negativeOptions.get(optionKey).presetArg;
10248
+ const negativeValue = preset !== undefined ? preset : false;
10249
+ return option.negate === (negativeValue === value);
10250
+ }
10251
+ }
10252
+ function camelcase(str) {
10253
+ return str.split("-").reduce((str2, word) => {
10254
+ return str2 + word[0].toUpperCase() + word.slice(1);
10255
+ });
10256
+ }
10257
+ function splitOptionFlags(flags) {
10258
+ let shortFlag;
10259
+ let longFlag;
10260
+ const shortFlagExp = /^-[^-]$/;
10261
+ const longFlagExp = /^--[^-]/;
10262
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
10263
+ if (shortFlagExp.test(flagParts[0]))
10264
+ shortFlag = flagParts.shift();
10265
+ if (longFlagExp.test(flagParts[0]))
10266
+ longFlag = flagParts.shift();
10267
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
10268
+ shortFlag = flagParts.shift();
10269
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
10270
+ shortFlag = longFlag;
10271
+ longFlag = flagParts.shift();
10272
+ }
10273
+ if (flagParts[0].startsWith("-")) {
10274
+ const unsupportedFlag = flagParts[0];
10275
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
10276
+ if (/^-[^-][^-]/.test(unsupportedFlag))
10277
+ throw new Error(`${baseError}
10278
+ - a short flag is a single dash and a single character
10279
+ - either use a single dash and a single character (for a short flag)
10280
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
10281
+ if (shortFlagExp.test(unsupportedFlag))
10282
+ throw new Error(`${baseError}
10283
+ - too many short flags`);
10284
+ if (longFlagExp.test(unsupportedFlag))
10285
+ throw new Error(`${baseError}
10286
+ - too many long flags`);
10287
+ throw new Error(`${baseError}
10288
+ - unrecognised flag format`);
10289
+ }
10290
+ if (shortFlag === undefined && longFlag === undefined)
10291
+ throw new Error(`option creation failed due to no flags found in '${flags}'.`);
10292
+ return { shortFlag, longFlag };
10293
+ }
10294
+ exports2.Option = Option;
10295
+ exports2.DualOptions = DualOptions;
10296
+ });
10297
+
10298
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/suggestSimilar.js
10299
+ var require_suggestSimilar = __commonJS((exports2) => {
10300
+ var maxDistance = 3;
10301
+ function editDistance(a, b) {
10302
+ if (Math.abs(a.length - b.length) > maxDistance)
10303
+ return Math.max(a.length, b.length);
10304
+ const d = [];
10305
+ for (let i = 0;i <= a.length; i++) {
10306
+ d[i] = [i];
10307
+ }
10308
+ for (let j = 0;j <= b.length; j++) {
10309
+ d[0][j] = j;
10310
+ }
10311
+ for (let j = 1;j <= b.length; j++) {
10312
+ for (let i = 1;i <= a.length; i++) {
10313
+ let cost = 1;
10314
+ if (a[i - 1] === b[j - 1]) {
10315
+ cost = 0;
10316
+ } else {
10317
+ cost = 1;
10318
+ }
10319
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
10320
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
10321
+ d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
10322
+ }
10323
+ }
10324
+ }
10325
+ return d[a.length][b.length];
10326
+ }
10327
+ function suggestSimilar(word, candidates) {
10328
+ if (!candidates || candidates.length === 0)
10329
+ return "";
10330
+ candidates = Array.from(new Set(candidates));
10331
+ const searchingOptions = word.startsWith("--");
10332
+ if (searchingOptions) {
10333
+ word = word.slice(2);
10334
+ candidates = candidates.map((candidate) => candidate.slice(2));
10335
+ }
10336
+ let similar = [];
10337
+ let bestDistance = maxDistance;
10338
+ const minSimilarity = 0.4;
10339
+ candidates.forEach((candidate) => {
10340
+ if (candidate.length <= 1)
10341
+ return;
10342
+ const distance = editDistance(word, candidate);
10343
+ const length = Math.max(word.length, candidate.length);
10344
+ const similarity = (length - distance) / length;
10345
+ if (similarity > minSimilarity) {
10346
+ if (distance < bestDistance) {
10347
+ bestDistance = distance;
10348
+ similar = [candidate];
10349
+ } else if (distance === bestDistance) {
10350
+ similar.push(candidate);
10351
+ }
10352
+ }
10353
+ });
10354
+ similar.sort((a, b) => a.localeCompare(b));
10355
+ if (searchingOptions) {
10356
+ similar = similar.map((candidate) => `--${candidate}`);
10357
+ }
10358
+ if (similar.length > 1) {
10359
+ return `
10360
+ (Did you mean one of ${similar.join(", ")}?)`;
10361
+ }
10362
+ if (similar.length === 1) {
10363
+ return `
10364
+ (Did you mean ${similar[0]}?)`;
10365
+ }
10366
+ return "";
10367
+ }
10368
+ exports2.suggestSimilar = suggestSimilar;
10369
+ });
10370
+
10371
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/lib/command.js
10372
+ var require_command = __commonJS((exports2) => {
10373
+ var EventEmitter2 = __require("node:events").EventEmitter;
10374
+ var childProcess = __require("node:child_process");
10375
+ var path2 = __require("node:path");
10376
+ var fs2 = __require("node:fs");
10377
+ var process2 = __require("node:process");
10378
+ var { Argument, humanReadableArgName } = require_argument();
10379
+ var { CommanderError } = require_error();
10380
+ var { Help, stripColor } = require_help();
10381
+ var { Option, DualOptions } = require_option();
10382
+ var { suggestSimilar } = require_suggestSimilar();
10383
+
10384
+ class Command extends EventEmitter2 {
10385
+ constructor(name) {
10386
+ super();
10387
+ this.commands = [];
10388
+ this.options = [];
10389
+ this.parent = null;
10390
+ this._allowUnknownOption = false;
10391
+ this._allowExcessArguments = false;
10392
+ this.registeredArguments = [];
10393
+ this._args = this.registeredArguments;
10394
+ this.args = [];
10395
+ this.rawArgs = [];
10396
+ this.processedArgs = [];
10397
+ this._scriptPath = null;
10398
+ this._name = name || "";
10399
+ this._optionValues = {};
10400
+ this._optionValueSources = {};
10401
+ this._storeOptionsAsProperties = false;
10402
+ this._actionHandler = null;
10403
+ this._executableHandler = false;
10404
+ this._executableFile = null;
10405
+ this._executableDir = null;
10406
+ this._defaultCommandName = null;
10407
+ this._exitCallback = null;
10408
+ this._aliases = [];
10409
+ this._combineFlagAndOptionalValue = true;
10410
+ this._description = "";
10411
+ this._summary = "";
10412
+ this._argsDescription = undefined;
10413
+ this._enablePositionalOptions = false;
10414
+ this._passThroughOptions = false;
10415
+ this._lifeCycleHooks = {};
10416
+ this._showHelpAfterError = false;
10417
+ this._showSuggestionAfterError = true;
10418
+ this._savedState = null;
10419
+ this._outputConfiguration = {
10420
+ writeOut: (str) => process2.stdout.write(str),
10421
+ writeErr: (str) => process2.stderr.write(str),
10422
+ outputError: (str, write) => write(str),
10423
+ getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
10424
+ getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
10425
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
10426
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
10427
+ stripColor: (str) => stripColor(str)
10428
+ };
10429
+ this._hidden = false;
10430
+ this._helpOption = undefined;
10431
+ this._addImplicitHelpCommand = undefined;
10432
+ this._helpCommand = undefined;
10433
+ this._helpConfiguration = {};
10434
+ }
10435
+ copyInheritedSettings(sourceCommand) {
10436
+ this._outputConfiguration = sourceCommand._outputConfiguration;
10437
+ this._helpOption = sourceCommand._helpOption;
10438
+ this._helpCommand = sourceCommand._helpCommand;
10439
+ this._helpConfiguration = sourceCommand._helpConfiguration;
10440
+ this._exitCallback = sourceCommand._exitCallback;
10441
+ this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
10442
+ this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
10443
+ this._allowExcessArguments = sourceCommand._allowExcessArguments;
10444
+ this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
10445
+ this._showHelpAfterError = sourceCommand._showHelpAfterError;
10446
+ this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
10447
+ return this;
10448
+ }
10449
+ _getCommandAndAncestors() {
10450
+ const result = [];
10451
+ for (let command = this;command; command = command.parent) {
10452
+ result.push(command);
10453
+ }
10454
+ return result;
10455
+ }
10456
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
10457
+ let desc = actionOptsOrExecDesc;
10458
+ let opts = execOpts;
10459
+ if (typeof desc === "object" && desc !== null) {
10460
+ opts = desc;
10461
+ desc = null;
10462
+ }
10463
+ opts = opts || {};
10464
+ const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
10465
+ const cmd = this.createCommand(name);
10466
+ if (desc) {
10467
+ cmd.description(desc);
10468
+ cmd._executableHandler = true;
10469
+ }
10470
+ if (opts.isDefault)
10471
+ this._defaultCommandName = cmd._name;
10472
+ cmd._hidden = !!(opts.noHelp || opts.hidden);
10473
+ cmd._executableFile = opts.executableFile || null;
10474
+ if (args)
10475
+ cmd.arguments(args);
10476
+ this._registerCommand(cmd);
10477
+ cmd.parent = this;
10478
+ cmd.copyInheritedSettings(this);
10479
+ if (desc)
10480
+ return this;
10481
+ return cmd;
10482
+ }
10483
+ createCommand(name) {
10484
+ return new Command(name);
10485
+ }
10486
+ createHelp() {
10487
+ return Object.assign(new Help, this.configureHelp());
10488
+ }
10489
+ configureHelp(configuration) {
10490
+ if (configuration === undefined)
10491
+ return this._helpConfiguration;
10492
+ this._helpConfiguration = configuration;
10493
+ return this;
10494
+ }
10495
+ configureOutput(configuration) {
10496
+ if (configuration === undefined)
10497
+ return this._outputConfiguration;
10498
+ Object.assign(this._outputConfiguration, configuration);
10499
+ return this;
10500
+ }
10501
+ showHelpAfterError(displayHelp = true) {
10502
+ if (typeof displayHelp !== "string")
10503
+ displayHelp = !!displayHelp;
10504
+ this._showHelpAfterError = displayHelp;
10505
+ return this;
10506
+ }
10507
+ showSuggestionAfterError(displaySuggestion = true) {
10508
+ this._showSuggestionAfterError = !!displaySuggestion;
10509
+ return this;
10510
+ }
10511
+ addCommand(cmd, opts) {
10512
+ if (!cmd._name) {
10513
+ throw new Error(`Command passed to .addCommand() must have a name
10514
+ - specify the name in Command constructor or using .name()`);
10515
+ }
10516
+ opts = opts || {};
10517
+ if (opts.isDefault)
10518
+ this._defaultCommandName = cmd._name;
10519
+ if (opts.noHelp || opts.hidden)
10520
+ cmd._hidden = true;
10521
+ this._registerCommand(cmd);
10522
+ cmd.parent = this;
10523
+ cmd._checkForBrokenPassThrough();
10524
+ return this;
10525
+ }
10526
+ createArgument(name, description) {
10527
+ return new Argument(name, description);
10528
+ }
10529
+ argument(name, description, fn, defaultValue) {
10530
+ const argument = this.createArgument(name, description);
10531
+ if (typeof fn === "function") {
10532
+ argument.default(defaultValue).argParser(fn);
10533
+ } else {
10534
+ argument.default(fn);
10535
+ }
10536
+ this.addArgument(argument);
10537
+ return this;
10538
+ }
10539
+ arguments(names) {
10540
+ names.trim().split(/ +/).forEach((detail) => {
10541
+ this.argument(detail);
10542
+ });
10543
+ return this;
10544
+ }
10545
+ addArgument(argument) {
10546
+ const previousArgument = this.registeredArguments.slice(-1)[0];
10547
+ if (previousArgument && previousArgument.variadic) {
10548
+ throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
10549
+ }
10550
+ if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
10551
+ throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
10552
+ }
10553
+ this.registeredArguments.push(argument);
10554
+ return this;
10555
+ }
10556
+ helpCommand(enableOrNameAndArgs, description) {
10557
+ if (typeof enableOrNameAndArgs === "boolean") {
10558
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
10559
+ return this;
10560
+ }
10561
+ enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
10562
+ const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
10563
+ const helpDescription = description ?? "display help for command";
10564
+ const helpCommand = this.createCommand(helpName);
10565
+ helpCommand.helpOption(false);
10566
+ if (helpArgs)
10567
+ helpCommand.arguments(helpArgs);
10568
+ if (helpDescription)
10569
+ helpCommand.description(helpDescription);
10570
+ this._addImplicitHelpCommand = true;
10571
+ this._helpCommand = helpCommand;
10572
+ return this;
10573
+ }
10574
+ addHelpCommand(helpCommand, deprecatedDescription) {
10575
+ if (typeof helpCommand !== "object") {
10576
+ this.helpCommand(helpCommand, deprecatedDescription);
10577
+ return this;
10578
+ }
10579
+ this._addImplicitHelpCommand = true;
10580
+ this._helpCommand = helpCommand;
10581
+ return this;
10582
+ }
10583
+ _getHelpCommand() {
10584
+ const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
10585
+ if (hasImplicitHelpCommand) {
10586
+ if (this._helpCommand === undefined) {
10587
+ this.helpCommand(undefined, undefined);
10588
+ }
10589
+ return this._helpCommand;
10590
+ }
10591
+ return null;
10592
+ }
10593
+ hook(event, listener) {
10594
+ const allowedValues = ["preSubcommand", "preAction", "postAction"];
10595
+ if (!allowedValues.includes(event)) {
10596
+ throw new Error(`Unexpected value for event passed to hook : '${event}'.
10597
+ Expecting one of '${allowedValues.join("', '")}'`);
10598
+ }
10599
+ if (this._lifeCycleHooks[event]) {
10600
+ this._lifeCycleHooks[event].push(listener);
10601
+ } else {
10602
+ this._lifeCycleHooks[event] = [listener];
10603
+ }
10604
+ return this;
10605
+ }
10606
+ exitOverride(fn) {
10607
+ if (fn) {
10608
+ this._exitCallback = fn;
10609
+ } else {
10610
+ this._exitCallback = (err2) => {
10611
+ if (err2.code !== "commander.executeSubCommandAsync") {
10612
+ throw err2;
10613
+ } else {}
10614
+ };
10615
+ }
10616
+ return this;
10617
+ }
10618
+ _exit(exitCode, code, message) {
10619
+ if (this._exitCallback) {
10620
+ this._exitCallback(new CommanderError(exitCode, code, message));
10621
+ }
10622
+ process2.exit(exitCode);
10623
+ }
10624
+ action(fn) {
10625
+ const listener = (args) => {
10626
+ const expectedArgsCount = this.registeredArguments.length;
10627
+ const actionArgs = args.slice(0, expectedArgsCount);
10628
+ if (this._storeOptionsAsProperties) {
10629
+ actionArgs[expectedArgsCount] = this;
10630
+ } else {
10631
+ actionArgs[expectedArgsCount] = this.opts();
10632
+ }
10633
+ actionArgs.push(this);
10634
+ return fn.apply(this, actionArgs);
10635
+ };
10636
+ this._actionHandler = listener;
10637
+ return this;
10638
+ }
10639
+ createOption(flags, description) {
10640
+ return new Option(flags, description);
10641
+ }
10642
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
10643
+ try {
10644
+ return target.parseArg(value, previous);
10645
+ } catch (err2) {
10646
+ if (err2.code === "commander.invalidArgument") {
10647
+ const message = `${invalidArgumentMessage} ${err2.message}`;
10648
+ this.error(message, { exitCode: err2.exitCode, code: err2.code });
10649
+ }
10650
+ throw err2;
10651
+ }
10652
+ }
10653
+ _registerOption(option) {
10654
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
10655
+ if (matchingOption) {
10656
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
10657
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
10658
+ - already used by option '${matchingOption.flags}'`);
10659
+ }
10660
+ this.options.push(option);
10661
+ }
10662
+ _registerCommand(command) {
10663
+ const knownBy = (cmd) => {
10664
+ return [cmd.name()].concat(cmd.aliases());
10665
+ };
10666
+ const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
10667
+ if (alreadyUsed) {
10668
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
10669
+ const newCmd = knownBy(command).join("|");
10670
+ throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
10671
+ }
10672
+ this.commands.push(command);
10673
+ }
10674
+ addOption(option) {
10675
+ this._registerOption(option);
10676
+ const oname = option.name();
10677
+ const name = option.attributeName();
10678
+ if (option.negate) {
10679
+ const positiveLongFlag = option.long.replace(/^--no-/, "--");
10680
+ if (!this._findOption(positiveLongFlag)) {
10681
+ this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, "default");
10682
+ }
10683
+ } else if (option.defaultValue !== undefined) {
10684
+ this.setOptionValueWithSource(name, option.defaultValue, "default");
10685
+ }
10686
+ const handleOptionValue = (val, invalidValueMessage, valueSource) => {
10687
+ if (val == null && option.presetArg !== undefined) {
10688
+ val = option.presetArg;
10689
+ }
10690
+ const oldValue = this.getOptionValue(name);
10691
+ if (val !== null && option.parseArg) {
10692
+ val = this._callParseArg(option, val, oldValue, invalidValueMessage);
10693
+ } else if (val !== null && option.variadic) {
10694
+ val = option._concatValue(val, oldValue);
10695
+ }
10696
+ if (val == null) {
10697
+ if (option.negate) {
10698
+ val = false;
10699
+ } else if (option.isBoolean() || option.optional) {
10700
+ val = true;
10701
+ } else {
10702
+ val = "";
10703
+ }
10704
+ }
10705
+ this.setOptionValueWithSource(name, val, valueSource);
10706
+ };
10707
+ this.on("option:" + oname, (val) => {
10708
+ const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
10709
+ handleOptionValue(val, invalidValueMessage, "cli");
10710
+ });
10711
+ if (option.envVar) {
10712
+ this.on("optionEnv:" + oname, (val) => {
10713
+ const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
10714
+ handleOptionValue(val, invalidValueMessage, "env");
10715
+ });
10716
+ }
10717
+ return this;
10718
+ }
10719
+ _optionEx(config, flags, description, fn, defaultValue) {
10720
+ if (typeof flags === "object" && flags instanceof Option) {
10721
+ throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
10722
+ }
10723
+ const option = this.createOption(flags, description);
10724
+ option.makeOptionMandatory(!!config.mandatory);
10725
+ if (typeof fn === "function") {
10726
+ option.default(defaultValue).argParser(fn);
10727
+ } else if (fn instanceof RegExp) {
10728
+ const regex = fn;
10729
+ fn = (val, def) => {
10730
+ const m = regex.exec(val);
10731
+ return m ? m[0] : def;
10732
+ };
10733
+ option.default(defaultValue).argParser(fn);
10734
+ } else {
10735
+ option.default(fn);
10736
+ }
10737
+ return this.addOption(option);
10738
+ }
10739
+ option(flags, description, parseArg, defaultValue) {
10740
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
10741
+ }
10742
+ requiredOption(flags, description, parseArg, defaultValue) {
10743
+ return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
10744
+ }
10745
+ combineFlagAndOptionalValue(combine = true) {
10746
+ this._combineFlagAndOptionalValue = !!combine;
10747
+ return this;
10748
+ }
10749
+ allowUnknownOption(allowUnknown = true) {
10750
+ this._allowUnknownOption = !!allowUnknown;
10751
+ return this;
10752
+ }
10753
+ allowExcessArguments(allowExcess = true) {
10754
+ this._allowExcessArguments = !!allowExcess;
10755
+ return this;
10756
+ }
10757
+ enablePositionalOptions(positional = true) {
10758
+ this._enablePositionalOptions = !!positional;
10759
+ return this;
10760
+ }
10761
+ passThroughOptions(passThrough2 = true) {
10762
+ this._passThroughOptions = !!passThrough2;
10763
+ this._checkForBrokenPassThrough();
10764
+ return this;
10765
+ }
10766
+ _checkForBrokenPassThrough() {
10767
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
10768
+ throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
10769
+ }
10770
+ }
10771
+ storeOptionsAsProperties(storeAsProperties = true) {
10772
+ if (this.options.length) {
10773
+ throw new Error("call .storeOptionsAsProperties() before adding options");
10774
+ }
10775
+ if (Object.keys(this._optionValues).length) {
10776
+ throw new Error("call .storeOptionsAsProperties() before setting option values");
10777
+ }
10778
+ this._storeOptionsAsProperties = !!storeAsProperties;
10779
+ return this;
10780
+ }
10781
+ getOptionValue(key) {
10782
+ if (this._storeOptionsAsProperties) {
10783
+ return this[key];
10784
+ }
10785
+ return this._optionValues[key];
10786
+ }
10787
+ setOptionValue(key, value) {
10788
+ return this.setOptionValueWithSource(key, value, undefined);
10789
+ }
10790
+ setOptionValueWithSource(key, value, source) {
10791
+ if (this._storeOptionsAsProperties) {
10792
+ this[key] = value;
10793
+ } else {
10794
+ this._optionValues[key] = value;
10795
+ }
10796
+ this._optionValueSources[key] = source;
10797
+ return this;
10798
+ }
10799
+ getOptionValueSource(key) {
10800
+ return this._optionValueSources[key];
10801
+ }
10802
+ getOptionValueSourceWithGlobals(key) {
10803
+ let source;
10804
+ this._getCommandAndAncestors().forEach((cmd) => {
10805
+ if (cmd.getOptionValueSource(key) !== undefined) {
10806
+ source = cmd.getOptionValueSource(key);
10807
+ }
10808
+ });
10809
+ return source;
10810
+ }
10811
+ _prepareUserArgs(argv, parseOptions) {
10812
+ if (argv !== undefined && !Array.isArray(argv)) {
10813
+ throw new Error("first parameter to parse must be array or undefined");
10814
+ }
10815
+ parseOptions = parseOptions || {};
10816
+ if (argv === undefined && parseOptions.from === undefined) {
10817
+ if (process2.versions?.electron) {
10818
+ parseOptions.from = "electron";
10819
+ }
10820
+ const execArgv = process2.execArgv ?? [];
10821
+ if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
10822
+ parseOptions.from = "eval";
10823
+ }
10824
+ }
10825
+ if (argv === undefined) {
10826
+ argv = process2.argv;
10827
+ }
10828
+ this.rawArgs = argv.slice();
10829
+ let userArgs;
10830
+ switch (parseOptions.from) {
10831
+ case undefined:
10832
+ case "node":
10833
+ this._scriptPath = argv[1];
10834
+ userArgs = argv.slice(2);
10835
+ break;
10836
+ case "electron":
10837
+ if (process2.defaultApp) {
10838
+ this._scriptPath = argv[1];
10839
+ userArgs = argv.slice(2);
10840
+ } else {
10841
+ userArgs = argv.slice(1);
10842
+ }
10843
+ break;
10844
+ case "user":
10845
+ userArgs = argv.slice(0);
10846
+ break;
10847
+ case "eval":
10848
+ userArgs = argv.slice(1);
10849
+ break;
10850
+ default:
10851
+ throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
10852
+ }
10853
+ if (!this._name && this._scriptPath)
10854
+ this.nameFromFilename(this._scriptPath);
10855
+ this._name = this._name || "program";
10856
+ return userArgs;
10857
+ }
10858
+ parse(argv, parseOptions) {
10859
+ this._prepareForParse();
10860
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
10861
+ this._parseCommand([], userArgs);
10862
+ return this;
10863
+ }
10864
+ async parseAsync(argv, parseOptions) {
10865
+ this._prepareForParse();
10866
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
10867
+ await this._parseCommand([], userArgs);
10868
+ return this;
10869
+ }
10870
+ _prepareForParse() {
10871
+ if (this._savedState === null) {
10872
+ this.saveStateBeforeParse();
10873
+ } else {
10874
+ this.restoreStateBeforeParse();
10875
+ }
10876
+ }
10877
+ saveStateBeforeParse() {
10878
+ this._savedState = {
10879
+ _name: this._name,
10880
+ _optionValues: { ...this._optionValues },
10881
+ _optionValueSources: { ...this._optionValueSources }
10882
+ };
10883
+ }
10884
+ restoreStateBeforeParse() {
10885
+ if (this._storeOptionsAsProperties)
10886
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
10887
+ - either make a new Command for each call to parse, or stop storing options as properties`);
10888
+ this._name = this._savedState._name;
10889
+ this._scriptPath = null;
10890
+ this.rawArgs = [];
10891
+ this._optionValues = { ...this._savedState._optionValues };
10892
+ this._optionValueSources = { ...this._savedState._optionValueSources };
10893
+ this.args = [];
10894
+ this.processedArgs = [];
10895
+ }
10896
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
10897
+ if (fs2.existsSync(executableFile))
10898
+ return;
10899
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
10900
+ const executableMissing = `'${executableFile}' does not exist
10901
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
10902
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
10903
+ - ${executableDirMessage}`;
10904
+ throw new Error(executableMissing);
10905
+ }
10906
+ _executeSubCommand(subcommand, args) {
10907
+ args = args.slice();
10908
+ let launchWithNode = false;
10909
+ const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
10910
+ function findFile(baseDir, baseName) {
10911
+ const localBin = path2.resolve(baseDir, baseName);
10912
+ if (fs2.existsSync(localBin))
10913
+ return localBin;
10914
+ if (sourceExt.includes(path2.extname(baseName)))
10915
+ return;
10916
+ const foundExt = sourceExt.find((ext) => fs2.existsSync(`${localBin}${ext}`));
10917
+ if (foundExt)
10918
+ return `${localBin}${foundExt}`;
10919
+ return;
10920
+ }
10921
+ this._checkForMissingMandatoryOptions();
10922
+ this._checkForConflictingOptions();
10923
+ let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
10924
+ let executableDir = this._executableDir || "";
10925
+ if (this._scriptPath) {
10926
+ let resolvedScriptPath;
10927
+ try {
10928
+ resolvedScriptPath = fs2.realpathSync(this._scriptPath);
10929
+ } catch {
10930
+ resolvedScriptPath = this._scriptPath;
10931
+ }
10932
+ executableDir = path2.resolve(path2.dirname(resolvedScriptPath), executableDir);
10933
+ }
10934
+ if (executableDir) {
10935
+ let localFile = findFile(executableDir, executableFile);
10936
+ if (!localFile && !subcommand._executableFile && this._scriptPath) {
10937
+ const legacyName = path2.basename(this._scriptPath, path2.extname(this._scriptPath));
10938
+ if (legacyName !== this._name) {
10939
+ localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
10940
+ }
10941
+ }
10942
+ executableFile = localFile || executableFile;
10943
+ }
10944
+ launchWithNode = sourceExt.includes(path2.extname(executableFile));
10945
+ let proc;
10946
+ if (process2.platform !== "win32") {
10947
+ if (launchWithNode) {
10948
+ args.unshift(executableFile);
10949
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
10950
+ proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
10951
+ } else {
10952
+ proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
10953
+ }
10954
+ } else {
10955
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
10956
+ args.unshift(executableFile);
10957
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
10958
+ proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
10959
+ }
10960
+ if (!proc.killed) {
10961
+ const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
10962
+ signals.forEach((signal) => {
10963
+ process2.on(signal, () => {
10964
+ if (proc.killed === false && proc.exitCode === null) {
10965
+ proc.kill(signal);
10966
+ }
10967
+ });
10968
+ });
10969
+ }
10970
+ const exitCallback = this._exitCallback;
10971
+ proc.on("close", (code) => {
10972
+ code = code ?? 1;
10973
+ if (!exitCallback) {
10974
+ process2.exit(code);
10975
+ } else {
10976
+ exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
10977
+ }
10978
+ });
10979
+ proc.on("error", (err2) => {
10980
+ if (err2.code === "ENOENT") {
10981
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
10982
+ } else if (err2.code === "EACCES") {
10983
+ throw new Error(`'${executableFile}' not executable`);
10984
+ }
10985
+ if (!exitCallback) {
10986
+ process2.exit(1);
10987
+ } else {
10988
+ const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
10989
+ wrappedError.nestedError = err2;
10990
+ exitCallback(wrappedError);
10991
+ }
10992
+ });
10993
+ this.runningCommand = proc;
10994
+ }
10995
+ _dispatchSubcommand(commandName, operands, unknown) {
10996
+ const subCommand = this._findCommand(commandName);
10997
+ if (!subCommand)
10998
+ this.help({ error: true });
10999
+ subCommand._prepareForParse();
11000
+ let promiseChain;
11001
+ promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
11002
+ promiseChain = this._chainOrCall(promiseChain, () => {
11003
+ if (subCommand._executableHandler) {
11004
+ this._executeSubCommand(subCommand, operands.concat(unknown));
11005
+ } else {
11006
+ return subCommand._parseCommand(operands, unknown);
11007
+ }
11008
+ });
11009
+ return promiseChain;
11010
+ }
11011
+ _dispatchHelpCommand(subcommandName) {
11012
+ if (!subcommandName) {
11013
+ this.help();
11014
+ }
11015
+ const subCommand = this._findCommand(subcommandName);
11016
+ if (subCommand && !subCommand._executableHandler) {
11017
+ subCommand.help();
11018
+ }
11019
+ return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
11020
+ }
11021
+ _checkNumberOfArguments() {
11022
+ this.registeredArguments.forEach((arg, i) => {
11023
+ if (arg.required && this.args[i] == null) {
11024
+ this.missingArgument(arg.name());
11025
+ }
11026
+ });
11027
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
11028
+ return;
11029
+ }
11030
+ if (this.args.length > this.registeredArguments.length) {
11031
+ this._excessArguments(this.args);
11032
+ }
11033
+ }
11034
+ _processArguments() {
11035
+ const myParseArg = (argument, value, previous) => {
11036
+ let parsedValue = value;
11037
+ if (value !== null && argument.parseArg) {
11038
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
11039
+ parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
11040
+ }
11041
+ return parsedValue;
11042
+ };
11043
+ this._checkNumberOfArguments();
11044
+ const processedArgs = [];
11045
+ this.registeredArguments.forEach((declaredArg, index) => {
11046
+ let value = declaredArg.defaultValue;
11047
+ if (declaredArg.variadic) {
11048
+ if (index < this.args.length) {
11049
+ value = this.args.slice(index);
11050
+ if (declaredArg.parseArg) {
11051
+ value = value.reduce((processed, v) => {
11052
+ return myParseArg(declaredArg, v, processed);
11053
+ }, declaredArg.defaultValue);
11054
+ }
11055
+ } else if (value === undefined) {
11056
+ value = [];
11057
+ }
11058
+ } else if (index < this.args.length) {
11059
+ value = this.args[index];
11060
+ if (declaredArg.parseArg) {
11061
+ value = myParseArg(declaredArg, value, declaredArg.defaultValue);
11062
+ }
11063
+ }
11064
+ processedArgs[index] = value;
11065
+ });
11066
+ this.processedArgs = processedArgs;
11067
+ }
11068
+ _chainOrCall(promise, fn) {
11069
+ if (promise && promise.then && typeof promise.then === "function") {
11070
+ return promise.then(() => fn());
11071
+ }
11072
+ return fn();
11073
+ }
11074
+ _chainOrCallHooks(promise, event) {
11075
+ let result = promise;
11076
+ const hooks = [];
11077
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== undefined).forEach((hookedCommand) => {
11078
+ hookedCommand._lifeCycleHooks[event].forEach((callback) => {
11079
+ hooks.push({ hookedCommand, callback });
11080
+ });
11081
+ });
11082
+ if (event === "postAction") {
11083
+ hooks.reverse();
11084
+ }
11085
+ hooks.forEach((hookDetail) => {
11086
+ result = this._chainOrCall(result, () => {
11087
+ return hookDetail.callback(hookDetail.hookedCommand, this);
11088
+ });
11089
+ });
11090
+ return result;
11091
+ }
11092
+ _chainOrCallSubCommandHook(promise, subCommand, event) {
11093
+ let result = promise;
11094
+ if (this._lifeCycleHooks[event] !== undefined) {
11095
+ this._lifeCycleHooks[event].forEach((hook) => {
11096
+ result = this._chainOrCall(result, () => {
11097
+ return hook(this, subCommand);
11098
+ });
11099
+ });
11100
+ }
11101
+ return result;
11102
+ }
11103
+ _parseCommand(operands, unknown) {
11104
+ const parsed = this.parseOptions(unknown);
11105
+ this._parseOptionsEnv();
11106
+ this._parseOptionsImplied();
11107
+ operands = operands.concat(parsed.operands);
11108
+ unknown = parsed.unknown;
11109
+ this.args = operands.concat(unknown);
11110
+ if (operands && this._findCommand(operands[0])) {
11111
+ return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
11112
+ }
11113
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
11114
+ return this._dispatchHelpCommand(operands[1]);
11115
+ }
11116
+ if (this._defaultCommandName) {
11117
+ this._outputHelpIfRequested(unknown);
11118
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
11119
+ }
11120
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
11121
+ this.help({ error: true });
11122
+ }
11123
+ this._outputHelpIfRequested(parsed.unknown);
11124
+ this._checkForMissingMandatoryOptions();
11125
+ this._checkForConflictingOptions();
11126
+ const checkForUnknownOptions = () => {
11127
+ if (parsed.unknown.length > 0) {
11128
+ this.unknownOption(parsed.unknown[0]);
11129
+ }
11130
+ };
11131
+ const commandEvent = `command:${this.name()}`;
11132
+ if (this._actionHandler) {
11133
+ checkForUnknownOptions();
11134
+ this._processArguments();
11135
+ let promiseChain;
11136
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
11137
+ promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
11138
+ if (this.parent) {
11139
+ promiseChain = this._chainOrCall(promiseChain, () => {
11140
+ this.parent.emit(commandEvent, operands, unknown);
11141
+ });
11142
+ }
11143
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
11144
+ return promiseChain;
11145
+ }
11146
+ if (this.parent && this.parent.listenerCount(commandEvent)) {
11147
+ checkForUnknownOptions();
11148
+ this._processArguments();
11149
+ this.parent.emit(commandEvent, operands, unknown);
11150
+ } else if (operands.length) {
11151
+ if (this._findCommand("*")) {
11152
+ return this._dispatchSubcommand("*", operands, unknown);
11153
+ }
11154
+ if (this.listenerCount("command:*")) {
11155
+ this.emit("command:*", operands, unknown);
11156
+ } else if (this.commands.length) {
11157
+ this.unknownCommand();
11158
+ } else {
11159
+ checkForUnknownOptions();
11160
+ this._processArguments();
11161
+ }
11162
+ } else if (this.commands.length) {
11163
+ checkForUnknownOptions();
11164
+ this.help({ error: true });
11165
+ } else {
11166
+ checkForUnknownOptions();
11167
+ this._processArguments();
11168
+ }
11169
+ }
11170
+ _findCommand(name) {
11171
+ if (!name)
11172
+ return;
11173
+ return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
11174
+ }
11175
+ _findOption(arg) {
11176
+ return this.options.find((option) => option.is(arg));
11177
+ }
11178
+ _checkForMissingMandatoryOptions() {
11179
+ this._getCommandAndAncestors().forEach((cmd) => {
11180
+ cmd.options.forEach((anOption) => {
11181
+ if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === undefined) {
11182
+ cmd.missingMandatoryOptionValue(anOption);
11183
+ }
11184
+ });
11185
+ });
11186
+ }
11187
+ _checkForConflictingLocalOptions() {
11188
+ const definedNonDefaultOptions = this.options.filter((option) => {
11189
+ const optionKey = option.attributeName();
11190
+ if (this.getOptionValue(optionKey) === undefined) {
11191
+ return false;
11192
+ }
11193
+ return this.getOptionValueSource(optionKey) !== "default";
11194
+ });
11195
+ const optionsWithConflicting = definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0);
11196
+ optionsWithConflicting.forEach((option) => {
11197
+ const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
11198
+ if (conflictingAndDefined) {
11199
+ this._conflictingOption(option, conflictingAndDefined);
11200
+ }
11201
+ });
11202
+ }
11203
+ _checkForConflictingOptions() {
11204
+ this._getCommandAndAncestors().forEach((cmd) => {
11205
+ cmd._checkForConflictingLocalOptions();
11206
+ });
11207
+ }
11208
+ parseOptions(argv) {
11209
+ const operands = [];
11210
+ const unknown = [];
11211
+ let dest = operands;
11212
+ const args = argv.slice();
11213
+ function maybeOption(arg) {
11214
+ return arg.length > 1 && arg[0] === "-";
11215
+ }
11216
+ let activeVariadicOption = null;
11217
+ while (args.length) {
11218
+ const arg = args.shift();
11219
+ if (arg === "--") {
11220
+ if (dest === unknown)
11221
+ dest.push(arg);
11222
+ dest.push(...args);
11223
+ break;
11224
+ }
11225
+ if (activeVariadicOption && !maybeOption(arg)) {
11226
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
11227
+ continue;
11228
+ }
11229
+ activeVariadicOption = null;
11230
+ if (maybeOption(arg)) {
11231
+ const option = this._findOption(arg);
11232
+ if (option) {
11233
+ if (option.required) {
11234
+ const value = args.shift();
11235
+ if (value === undefined)
11236
+ this.optionMissingArgument(option);
11237
+ this.emit(`option:${option.name()}`, value);
11238
+ } else if (option.optional) {
11239
+ let value = null;
11240
+ if (args.length > 0 && !maybeOption(args[0])) {
11241
+ value = args.shift();
11242
+ }
11243
+ this.emit(`option:${option.name()}`, value);
11244
+ } else {
11245
+ this.emit(`option:${option.name()}`);
11246
+ }
11247
+ activeVariadicOption = option.variadic ? option : null;
11248
+ continue;
11249
+ }
11250
+ }
11251
+ if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
11252
+ const option = this._findOption(`-${arg[1]}`);
11253
+ if (option) {
11254
+ if (option.required || option.optional && this._combineFlagAndOptionalValue) {
11255
+ this.emit(`option:${option.name()}`, arg.slice(2));
11256
+ } else {
11257
+ this.emit(`option:${option.name()}`);
11258
+ args.unshift(`-${arg.slice(2)}`);
11259
+ }
11260
+ continue;
11261
+ }
11262
+ }
11263
+ if (/^--[^=]+=/.test(arg)) {
11264
+ const index = arg.indexOf("=");
11265
+ const option = this._findOption(arg.slice(0, index));
11266
+ if (option && (option.required || option.optional)) {
11267
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
11268
+ continue;
11269
+ }
11270
+ }
11271
+ if (maybeOption(arg)) {
11272
+ dest = unknown;
11273
+ }
11274
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
11275
+ if (this._findCommand(arg)) {
11276
+ operands.push(arg);
11277
+ if (args.length > 0)
11278
+ unknown.push(...args);
11279
+ break;
11280
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
11281
+ operands.push(arg);
11282
+ if (args.length > 0)
11283
+ operands.push(...args);
11284
+ break;
11285
+ } else if (this._defaultCommandName) {
11286
+ unknown.push(arg);
11287
+ if (args.length > 0)
11288
+ unknown.push(...args);
11289
+ break;
11290
+ }
11291
+ }
11292
+ if (this._passThroughOptions) {
11293
+ dest.push(arg);
11294
+ if (args.length > 0)
11295
+ dest.push(...args);
11296
+ break;
11297
+ }
11298
+ dest.push(arg);
11299
+ }
11300
+ return { operands, unknown };
11301
+ }
11302
+ opts() {
11303
+ if (this._storeOptionsAsProperties) {
11304
+ const result = {};
11305
+ const len = this.options.length;
11306
+ for (let i = 0;i < len; i++) {
11307
+ const key = this.options[i].attributeName();
11308
+ result[key] = key === this._versionOptionName ? this._version : this[key];
11309
+ }
11310
+ return result;
11311
+ }
11312
+ return this._optionValues;
11313
+ }
11314
+ optsWithGlobals() {
11315
+ return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
11316
+ }
11317
+ error(message, errorOptions) {
11318
+ this._outputConfiguration.outputError(`${message}
11319
+ `, this._outputConfiguration.writeErr);
11320
+ if (typeof this._showHelpAfterError === "string") {
11321
+ this._outputConfiguration.writeErr(`${this._showHelpAfterError}
11322
+ `);
11323
+ } else if (this._showHelpAfterError) {
11324
+ this._outputConfiguration.writeErr(`
11325
+ `);
11326
+ this.outputHelp({ error: true });
11327
+ }
11328
+ const config = errorOptions || {};
11329
+ const exitCode = config.exitCode || 1;
11330
+ const code = config.code || "commander.error";
11331
+ this._exit(exitCode, code, message);
11332
+ }
11333
+ _parseOptionsEnv() {
11334
+ this.options.forEach((option) => {
11335
+ if (option.envVar && option.envVar in process2.env) {
11336
+ const optionKey = option.attributeName();
11337
+ if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
11338
+ if (option.required || option.optional) {
11339
+ this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
11340
+ } else {
11341
+ this.emit(`optionEnv:${option.name()}`);
11342
+ }
11343
+ }
11344
+ }
11345
+ });
11346
+ }
11347
+ _parseOptionsImplied() {
11348
+ const dualHelper = new DualOptions(this.options);
11349
+ const hasCustomOptionValue = (optionKey) => {
11350
+ return this.getOptionValue(optionKey) !== undefined && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
11351
+ };
11352
+ this.options.filter((option) => option.implied !== undefined && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
11353
+ Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
11354
+ this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
11355
+ });
11356
+ });
11357
+ }
11358
+ missingArgument(name) {
11359
+ const message = `error: missing required argument '${name}'`;
11360
+ this.error(message, { code: "commander.missingArgument" });
11361
+ }
11362
+ optionMissingArgument(option) {
11363
+ const message = `error: option '${option.flags}' argument missing`;
11364
+ this.error(message, { code: "commander.optionMissingArgument" });
11365
+ }
11366
+ missingMandatoryOptionValue(option) {
11367
+ const message = `error: required option '${option.flags}' not specified`;
11368
+ this.error(message, { code: "commander.missingMandatoryOptionValue" });
11369
+ }
11370
+ _conflictingOption(option, conflictingOption) {
11371
+ const findBestOptionFromValue = (option2) => {
11372
+ const optionKey = option2.attributeName();
11373
+ const optionValue = this.getOptionValue(optionKey);
11374
+ const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
11375
+ const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
11376
+ if (negativeOption && (negativeOption.presetArg === undefined && optionValue === false || negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)) {
11377
+ return negativeOption;
11378
+ }
11379
+ return positiveOption || option2;
11380
+ };
11381
+ const getErrorMessage = (option2) => {
11382
+ const bestOption = findBestOptionFromValue(option2);
11383
+ const optionKey = bestOption.attributeName();
11384
+ const source = this.getOptionValueSource(optionKey);
11385
+ if (source === "env") {
11386
+ return `environment variable '${bestOption.envVar}'`;
11387
+ }
11388
+ return `option '${bestOption.flags}'`;
11389
+ };
11390
+ const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
11391
+ this.error(message, { code: "commander.conflictingOption" });
11392
+ }
11393
+ unknownOption(flag) {
11394
+ if (this._allowUnknownOption)
11395
+ return;
11396
+ let suggestion = "";
11397
+ if (flag.startsWith("--") && this._showSuggestionAfterError) {
11398
+ let candidateFlags = [];
11399
+ let command = this;
11400
+ do {
11401
+ const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
11402
+ candidateFlags = candidateFlags.concat(moreFlags);
11403
+ command = command.parent;
11404
+ } while (command && !command._enablePositionalOptions);
11405
+ suggestion = suggestSimilar(flag, candidateFlags);
11406
+ }
11407
+ const message = `error: unknown option '${flag}'${suggestion}`;
11408
+ this.error(message, { code: "commander.unknownOption" });
11409
+ }
11410
+ _excessArguments(receivedArgs) {
11411
+ if (this._allowExcessArguments)
11412
+ return;
11413
+ const expected = this.registeredArguments.length;
11414
+ const s = expected === 1 ? "" : "s";
11415
+ const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
11416
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
11417
+ this.error(message, { code: "commander.excessArguments" });
11418
+ }
11419
+ unknownCommand() {
11420
+ const unknownName = this.args[0];
11421
+ let suggestion = "";
11422
+ if (this._showSuggestionAfterError) {
11423
+ const candidateNames = [];
11424
+ this.createHelp().visibleCommands(this).forEach((command) => {
11425
+ candidateNames.push(command.name());
11426
+ if (command.alias())
11427
+ candidateNames.push(command.alias());
11428
+ });
11429
+ suggestion = suggestSimilar(unknownName, candidateNames);
11430
+ }
11431
+ const message = `error: unknown command '${unknownName}'${suggestion}`;
11432
+ this.error(message, { code: "commander.unknownCommand" });
11433
+ }
11434
+ version(str, flags, description) {
11435
+ if (str === undefined)
11436
+ return this._version;
11437
+ this._version = str;
11438
+ flags = flags || "-V, --version";
11439
+ description = description || "output the version number";
11440
+ const versionOption = this.createOption(flags, description);
11441
+ this._versionOptionName = versionOption.attributeName();
11442
+ this._registerOption(versionOption);
11443
+ this.on("option:" + versionOption.name(), () => {
11444
+ this._outputConfiguration.writeOut(`${str}
11445
+ `);
11446
+ this._exit(0, "commander.version", str);
11447
+ });
11448
+ return this;
11449
+ }
11450
+ description(str, argsDescription) {
11451
+ if (str === undefined && argsDescription === undefined)
11452
+ return this._description;
11453
+ this._description = str;
11454
+ if (argsDescription) {
11455
+ this._argsDescription = argsDescription;
11456
+ }
11457
+ return this;
11458
+ }
11459
+ summary(str) {
11460
+ if (str === undefined)
11461
+ return this._summary;
11462
+ this._summary = str;
11463
+ return this;
11464
+ }
11465
+ alias(alias) {
11466
+ if (alias === undefined)
11467
+ return this._aliases[0];
11468
+ let command = this;
11469
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
11470
+ command = this.commands[this.commands.length - 1];
11471
+ }
11472
+ if (alias === command._name)
11473
+ throw new Error("Command alias can't be the same as its name");
11474
+ const matchingCommand = this.parent?._findCommand(alias);
11475
+ if (matchingCommand) {
11476
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
11477
+ throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
11478
+ }
11479
+ command._aliases.push(alias);
11480
+ return this;
11481
+ }
11482
+ aliases(aliases) {
11483
+ if (aliases === undefined)
11484
+ return this._aliases;
11485
+ aliases.forEach((alias) => this.alias(alias));
11486
+ return this;
11487
+ }
11488
+ usage(str) {
11489
+ if (str === undefined) {
11490
+ if (this._usage)
11491
+ return this._usage;
11492
+ const args = this.registeredArguments.map((arg) => {
11493
+ return humanReadableArgName(arg);
11494
+ });
11495
+ return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
11496
+ }
11497
+ this._usage = str;
11498
+ return this;
11499
+ }
11500
+ name(str) {
11501
+ if (str === undefined)
11502
+ return this._name;
11503
+ this._name = str;
11504
+ return this;
11505
+ }
11506
+ nameFromFilename(filename) {
11507
+ this._name = path2.basename(filename, path2.extname(filename));
11508
+ return this;
11509
+ }
11510
+ executableDir(path3) {
11511
+ if (path3 === undefined)
11512
+ return this._executableDir;
11513
+ this._executableDir = path3;
11514
+ return this;
11515
+ }
11516
+ helpInformation(contextOptions) {
11517
+ const helper = this.createHelp();
11518
+ const context = this._getOutputContext(contextOptions);
11519
+ helper.prepareContext({
11520
+ error: context.error,
11521
+ helpWidth: context.helpWidth,
11522
+ outputHasColors: context.hasColors
11523
+ });
11524
+ const text = helper.formatHelp(this, helper);
11525
+ if (context.hasColors)
11526
+ return text;
11527
+ return this._outputConfiguration.stripColor(text);
11528
+ }
11529
+ _getOutputContext(contextOptions) {
11530
+ contextOptions = contextOptions || {};
11531
+ const error = !!contextOptions.error;
11532
+ let baseWrite;
11533
+ let hasColors;
11534
+ let helpWidth;
11535
+ if (error) {
11536
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
11537
+ hasColors = this._outputConfiguration.getErrHasColors();
11538
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
11539
+ } else {
11540
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
11541
+ hasColors = this._outputConfiguration.getOutHasColors();
11542
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
11543
+ }
11544
+ const write = (str) => {
11545
+ if (!hasColors)
11546
+ str = this._outputConfiguration.stripColor(str);
11547
+ return baseWrite(str);
11548
+ };
11549
+ return { error, write, hasColors, helpWidth };
11550
+ }
11551
+ outputHelp(contextOptions) {
11552
+ let deprecatedCallback;
11553
+ if (typeof contextOptions === "function") {
11554
+ deprecatedCallback = contextOptions;
11555
+ contextOptions = undefined;
11556
+ }
11557
+ const outputContext = this._getOutputContext(contextOptions);
11558
+ const eventContext = {
11559
+ error: outputContext.error,
11560
+ write: outputContext.write,
11561
+ command: this
11562
+ };
11563
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
11564
+ this.emit("beforeHelp", eventContext);
11565
+ let helpInformation = this.helpInformation({ error: outputContext.error });
11566
+ if (deprecatedCallback) {
11567
+ helpInformation = deprecatedCallback(helpInformation);
11568
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
11569
+ throw new Error("outputHelp callback must return a string or a Buffer");
11570
+ }
11571
+ }
11572
+ outputContext.write(helpInformation);
11573
+ if (this._getHelpOption()?.long) {
11574
+ this.emit(this._getHelpOption().long);
11575
+ }
11576
+ this.emit("afterHelp", eventContext);
11577
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
11578
+ }
11579
+ helpOption(flags, description) {
11580
+ if (typeof flags === "boolean") {
11581
+ if (flags) {
11582
+ this._helpOption = this._helpOption ?? undefined;
11583
+ } else {
11584
+ this._helpOption = null;
11585
+ }
11586
+ return this;
11587
+ }
11588
+ flags = flags ?? "-h, --help";
11589
+ description = description ?? "display help for command";
11590
+ this._helpOption = this.createOption(flags, description);
11591
+ return this;
11592
+ }
11593
+ _getHelpOption() {
11594
+ if (this._helpOption === undefined) {
11595
+ this.helpOption(undefined, undefined);
11596
+ }
11597
+ return this._helpOption;
11598
+ }
11599
+ addHelpOption(option) {
11600
+ this._helpOption = option;
11601
+ return this;
11602
+ }
11603
+ help(contextOptions) {
11604
+ this.outputHelp(contextOptions);
11605
+ let exitCode = Number(process2.exitCode ?? 0);
11606
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
11607
+ exitCode = 1;
11608
+ }
11609
+ this._exit(exitCode, "commander.help", "(outputHelp)");
11610
+ }
11611
+ addHelpText(position, text) {
11612
+ const allowedValues = ["beforeAll", "before", "after", "afterAll"];
11613
+ if (!allowedValues.includes(position)) {
11614
+ throw new Error(`Unexpected value for position to addHelpText.
11615
+ Expecting one of '${allowedValues.join("', '")}'`);
11616
+ }
11617
+ const helpEvent = `${position}Help`;
11618
+ this.on(helpEvent, (context) => {
11619
+ let helpStr;
11620
+ if (typeof text === "function") {
11621
+ helpStr = text({ error: context.error, command: context.command });
11622
+ } else {
11623
+ helpStr = text;
11624
+ }
11625
+ if (helpStr) {
11626
+ context.write(`${helpStr}
11627
+ `);
11628
+ }
11629
+ });
11630
+ return this;
11631
+ }
11632
+ _outputHelpIfRequested(args) {
11633
+ const helpOption = this._getHelpOption();
11634
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
11635
+ if (helpRequested) {
11636
+ this.outputHelp();
11637
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
11638
+ }
11639
+ }
11640
+ }
11641
+ function incrementNodeInspectorPort(args) {
11642
+ return args.map((arg) => {
11643
+ if (!arg.startsWith("--inspect")) {
11644
+ return arg;
11645
+ }
11646
+ let debugOption;
11647
+ let debugHost = "127.0.0.1";
11648
+ let debugPort = "9229";
11649
+ let match;
11650
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
11651
+ debugOption = match[1];
11652
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
11653
+ debugOption = match[1];
11654
+ if (/^\d+$/.test(match[3])) {
11655
+ debugPort = match[3];
11656
+ } else {
11657
+ debugHost = match[3];
11658
+ }
11659
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
11660
+ debugOption = match[1];
11661
+ debugHost = match[3];
11662
+ debugPort = match[4];
11663
+ }
11664
+ if (debugOption && debugPort !== "0") {
11665
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
11666
+ }
11667
+ return arg;
11668
+ });
11669
+ }
11670
+ function useColor() {
11671
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
11672
+ return false;
11673
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
11674
+ return true;
11675
+ return;
11676
+ }
11677
+ exports2.Command = Command;
11678
+ exports2.useColor = useColor;
11679
+ });
11680
+
11681
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/index.js
11682
+ var require_commander = __commonJS((exports2) => {
11683
+ var { Argument } = require_argument();
11684
+ var { Command } = require_command();
11685
+ var { CommanderError, InvalidArgumentError } = require_error();
11686
+ var { Help } = require_help();
11687
+ var { Option } = require_option();
11688
+ exports2.program = new Command;
11689
+ exports2.createCommand = (name) => new Command(name);
11690
+ exports2.createOption = (flags, description) => new Option(flags, description);
11691
+ exports2.createArgument = (name, description) => new Argument(name, description);
11692
+ exports2.Command = Command;
11693
+ exports2.Option = Option;
11694
+ exports2.Argument = Argument;
11695
+ exports2.Help = Help;
11696
+ exports2.CommanderError = CommanderError;
11697
+ exports2.InvalidArgumentError = InvalidArgumentError;
11698
+ exports2.InvalidOptionArgumentError = InvalidArgumentError;
11699
+ });
11700
+
9667
11701
  // src/host-control/main.ts
9668
- import { homedir as homedir3 } from "node:os";
9669
- import { existsSync as existsSync8 } from "node:fs";
9670
- import { join as join4, resolve as resolve6 } from "node:path";
11702
+ import { homedir as homedir4 } from "node:os";
11703
+ import { existsSync as existsSync9 } from "node:fs";
11704
+ import { join as join6, resolve as resolve7 } from "node:path";
9671
11705
 
9672
11706
  // src/config/loader.ts
9673
11707
  import { readFileSync as readFileSync2, existsSync as existsSync3 } from "node:fs";
9674
11708
  import { homedir } from "node:os";
9675
11709
  import { resolve as resolve3 } from "node:path";
9676
11710
 
9677
- // node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
11711
+ // ../../switchroom/node_modules/.bun/yaml@2.8.3/node_modules/yaml/dist/index.js
9678
11712
  var composer = require_composer();
9679
11713
  var Document = require_Document();
9680
11714
  var Schema = require_Schema();
@@ -9720,7 +11754,7 @@ var $stringify = publicApi.stringify;
9720
11754
  var $visit = visit.visit;
9721
11755
  var $visitAsync = visit.visitAsync;
9722
11756
 
9723
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
11757
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
9724
11758
  var exports_external = {};
9725
11759
  __export(exports_external, {
9726
11760
  void: () => voidType,
@@ -9832,7 +11866,7 @@ __export(exports_external, {
9832
11866
  BRAND: () => BRAND
9833
11867
  });
9834
11868
 
9835
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
11869
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
9836
11870
  var util;
9837
11871
  (function(util2) {
9838
11872
  util2.assertEqual = (_) => {};
@@ -9963,7 +11997,7 @@ var getParsedType = (data) => {
9963
11997
  }
9964
11998
  };
9965
11999
 
9966
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
12000
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
9967
12001
  var ZodIssueCode = util.arrayToEnum([
9968
12002
  "invalid_type",
9969
12003
  "invalid_literal",
@@ -10082,7 +12116,7 @@ ZodError.create = (issues) => {
10082
12116
  return error;
10083
12117
  };
10084
12118
 
10085
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
12119
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
10086
12120
  var errorMap = (issue, _ctx) => {
10087
12121
  let message;
10088
12122
  switch (issue.code) {
@@ -10185,7 +12219,7 @@ var errorMap = (issue, _ctx) => {
10185
12219
  };
10186
12220
  var en_default = errorMap;
10187
12221
 
10188
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
12222
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
10189
12223
  var overrideErrorMap = en_default;
10190
12224
  function setErrorMap(map) {
10191
12225
  overrideErrorMap = map;
@@ -10193,7 +12227,7 @@ function setErrorMap(map) {
10193
12227
  function getErrorMap() {
10194
12228
  return overrideErrorMap;
10195
12229
  }
10196
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
12230
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
10197
12231
  var makeIssue = (params) => {
10198
12232
  const { data, path, errorMaps, issueData } = params;
10199
12233
  const fullPath = [...path, ...issueData.path || []];
@@ -10299,14 +12333,14 @@ var isAborted = (x) => x.status === "aborted";
10299
12333
  var isDirty = (x) => x.status === "dirty";
10300
12334
  var isValid = (x) => x.status === "valid";
10301
12335
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
10302
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
12336
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
10303
12337
  var errorUtil;
10304
12338
  (function(errorUtil2) {
10305
12339
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
10306
12340
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
10307
12341
  })(errorUtil || (errorUtil = {}));
10308
12342
 
10309
- // node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
12343
+ // ../../switchroom/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
10310
12344
  class ParseInputLazyPath {
10311
12345
  constructor(parent, value, path, key) {
10312
12346
  this._cachedPath = [];
@@ -13885,7 +15919,7 @@ var TelegramChannelSchema = exports_external.object({
13885
15919
  format: exports_external.enum(["html", "markdownv2", "text"]).optional().describe("Default reply format passed to the plugin"),
13886
15920
  rate_limit_ms: exports_external.number().optional().describe("Minimum delay between outgoing messages in ms"),
13887
15921
  stream_mode: exports_external.enum(["pty", "checklist"]).optional().describe("How live progress is streamed to Telegram during a turn. " + "'pty' (default) surfaces text snapshots of Claude Code's TUI — " + "compatible but can flicker as Ink re-renders. 'checklist' drives " + "a structured progress card from session-tail events — stable " + "order, per-tool status emojis, fires only on semantic transitions."),
13888
- stream_throttle_ms: exports_external.number().int().nonnegative().optional().describe("Throttle window in ms between successive stream edits (or " + "sendMessageDraft tics) during a turn. Lower = more responsive " + "stream, higher = fewer API calls. Floored at 250 by draft-stream " + "itself. Default 300 for draft transport (DMs) and 1000 for " + "message transport (groups/forums). Override per-agent if a " + "particular agent needs snappier or quieter streaming."),
15922
+ stream_throttle_ms: exports_external.number().int().nonnegative().optional().describe("Throttle window in ms between successive in-place stream edits " + "during a turn. Lower = more responsive stream, higher = fewer API " + "calls. Floored at 250 by draft-stream itself. Default 400 ms for DMs " + "and 1000 ms for groups/forums (respects Telegram's ~1 edit/sec/message " + "practical ceiling). Override per-agent if a particular agent needs " + "snappier or quieter streaming."),
13889
15923
  clear_status_on_completion: exports_external.boolean().optional().describe("When true, the live activity/status feed (the in-place 'what it's " + "doing' message — Reading X, Searching the web for Y, …) is DELETED " + "when the turn's final answer lands, so only the reply remains. " + "Default false: the status message is left in the chat as a record " + "(its last step marked done) — no post-then-delete. Per-agent " + "override; cascades defaults → profile → agent (per-key)."),
13890
15924
  hotReloadStable: exports_external.boolean().optional().describe("If true, the stable workspace prefix (AGENTS.md, SOUL.md, USER.md, " + "IDENTITY.md, TOOLS.md) is re-injected on every turn via " + "the UserPromptSubmit hook instead of baked into --append-system-prompt " + "at session start. Lets workspace edits propagate without a restart. " + "Costs ~5-10% per-turn latency/spend since the stable prefix is no " + "longer prompt-cached."),
13891
15925
  inject_on_change: exports_external.boolean().optional().describe("Context-efficiency gate for per-turn hook injection (default true). " + "When true (the default), the turn-pacing directive and dynamic " + "workspace content are only re-emitted when their content changes or " + "the session_id changes — suppressing redundant injection that " + "otherwise triples compaction frequency. Set to false to revert to " + "the legacy always-emit behaviour (every turn injects the full " + "content regardless of whether it changed)."),
@@ -13973,6 +16007,14 @@ var GoogleWorkspaceConfigSchema = exports_external.object({
13973
16007
  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."),
13974
16008
  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).")
13975
16009
  }).optional();
16010
+ var LiteLLMConfigSchema = exports_external.object({
16011
+ enabled: exports_external.boolean().optional().describe("Opt-in toggle. When true, `switchroom apply` provisions a per-agent " + "LiteLLM virtual key and injects routing env into the container. " + "Default OFF."),
16012
+ base_url: exports_external.string().optional().describe("LiteLLM proxy base URL the agent's claude CLI routes through, e.g. " + "'http://127.0.0.1:4010'. Agents use network_mode:host, so loopback " + "reaches a host-bound proxy. Exported as ANTHROPIC_BASE_URL."),
16013
+ admin_key: exports_external.string().optional().describe("LiteLLM master/admin key used at apply time to provision the team + " + "virtual key. Supports a vault reference (e.g. " + "'vault:litellm/master-key') — resolution happens at apply time via " + "the vault-broker. Never injected into the agent container."),
16014
+ team: exports_external.string().optional().describe("LiteLLM team alias the per-agent key is created under. Defaults to " + "'switchroom' (applied in code, not as a schema default)."),
16015
+ small_fast_model: exports_external.string().optional().describe("Model id exported as ANTHROPIC_SMALL_FAST_MODEL for the claude CLI's " + "background/fast lane, e.g. 'claude-haiku-4-5-20251001'."),
16016
+ tags: exports_external.record(exports_external.string(), exports_external.string()).optional().describe("Extra key/value metadata tags attached to the provisioned LiteLLM " + "virtual key. Merged per-key across cascade layers (agent wins).")
16017
+ }).optional().describe("LiteLLM routing config — opt-in per-agent virtual-key auto-provisioning " + "+ routing env. Default OFF. See LiteLLMConfigSchema doc for the full flow.");
13976
16018
  var MicrosoftWorkspaceConfigSchema = exports_external.object({
13977
16019
  microsoft_client_id: exports_external.string().min(1).optional().describe("Microsoft OAuth application (client) ID from Entra portal " + "(literal string or vault reference e.g. " + "'vault:microsoft-oauth-client-id'). OPTIONAL — omit it to use " + "switchroom's shipped default Microsoft app (zero-config). " + "Set it only to bring your own Entra app (BYO)."),
13978
16020
  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'."),
@@ -14069,6 +16111,7 @@ var profileFields = {
14069
16111
  mcp_servers: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
14070
16112
  hooks: AgentHooksSchema,
14071
16113
  env: exports_external.record(exports_external.string(), exports_external.string()).optional(),
16114
+ litellm: LiteLLMConfigSchema,
14072
16115
  system_prompt_append: exports_external.string().optional(),
14073
16116
  skills: exports_external.array(exports_external.string()).optional(),
14074
16117
  bundled_skills: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Opt-out map for switchroom's bundled-default skills " + "(e.g. skill-creator, mcp-builder, webapp-testing, pdf, docx, " + "xlsx, pptx, switchroom-cli, switchroom-status, switchroom-health). " + "Set a key to `false` to suppress that default for this agent. " + "Cascades from defaults.bundled_skills."),
@@ -14141,6 +16184,7 @@ var AgentSchema = exports_external.object({
14141
16184
  mcp_servers: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Additional MCP server configurations"),
14142
16185
  hooks: AgentHooksSchema.describe("Claude Code lifecycle hooks (SessionStart, UserPromptSubmit, Stop, etc). " + "Written to settings.json.hooks in Claude Code's native shape."),
14143
16186
  env: exports_external.record(exports_external.string(), exports_external.string()).optional().describe("Environment variables exported in start.sh before claude runs"),
16187
+ litellm: LiteLLMConfigSchema.describe("Per-agent LiteLLM routing override. Presence with `enabled: true` opts " + "this agent IN to per-agent virtual-key auto-provisioning + routing env " + "(falls back to the top-level `litellm:` block for base_url/admin_key/" + "team/small_fast_model). Deep-merges one level over defaults/profile; " + "`tags` merge per-key, agent wins. Default OFF."),
14144
16188
  system_prompt_append: exports_external.string().optional().describe("Text passed via claude's --append-system-prompt flag. " + "Appended to the default or CLAUDE.md-derived system prompt."),
14145
16189
  skills: exports_external.array(exports_external.string()).optional().describe("Names of skills from switchroom.skills_dir to symlink into this " + "agent's skills/ directory. Unioned with defaults.skills."),
14146
16190
  bundled_skills: exports_external.record(exports_external.string(), exports_external.boolean()).optional().describe("Per-agent override of switchroom's bundled-default skills " + "(skill-creator, mcp-builder, webapp-testing, pdf, docx, xlsx, " + "pptx, switchroom-cli/status/health). Set a key to `false` to " + "opt out for this agent. Per-agent value wins over defaults.bundled_skills."),
@@ -14266,7 +16310,7 @@ var WebServiceConfigSchema = exports_external.object({
14266
16310
  });
14267
16311
  var HostdConfigSchema = exports_external.object({
14268
16312
  config_edit_enabled: exports_external.boolean().default(false).describe("Opt-in toggle for the `config_propose_edit` hostd verb (RFC " + "admin-agent-config-edit §3). Default false — the verb returns " + "`E_CONFIG_EDIT_DISABLED` until the operator explicitly flips " + "this to true. When true, admin agents can propose unified-diff " + "patches against " + "`/state/config/switchroom.yaml`, gated by an operator approval " + "card in the primary chat. Same trust posture as `update_apply` " + "and `agent_restart`: the human-in-the-loop tap is the security " + "boundary, not the agent's judgement."),
14269
- config_edit_rate_per_hour: exports_external.number().int().min(1).max(20).default(3).describe("Per-requesting-agent rate cap for `config_propose_edit` cards " + "(RFC admin-agent-config-edit §5). Default 3 cards/hour; min 1, " + "max 20. Configurable now, but the rate limiter is not yet enforced " + "(no `E_RATE_LIMITED` is currently raised); the field is reserved so " + "operators can pin the cap ahead of the limiter going live.")
16313
+ config_edit_rate_per_hour: exports_external.number().int().min(1).max(20).default(3).describe("Per-requesting-agent rate cap for `config_propose_edit` cards " + "(RFC admin-agent-config-edit §5). Default 3 cards/hour; min 1, " + "max 20. ENFORCED server-side: a caller exceeding this in a sliding " + "1-hour window is rejected with `E_RATE_LIMITED` (carrying a " + "`retry_after` fix) instead of posting another operator approval " + "card so a looping agent is throttled rather than spamming the chat.")
14270
16314
  });
14271
16315
  var CronEgressSchema = exports_external.object({
14272
16316
  allowed_hosts: exports_external.array(exports_external.string().min(1)).default([]).describe("Hosts a poll may reach (exact, https-only). loopback/private/IP-literal are always rejected."),
@@ -14299,11 +16343,14 @@ var SwitchroomConfigSchema = exports_external.object({
14299
16343
  message: "Consumer name must be a path-safe slug (letters, digits, underscore, hyphen)"
14300
16344
  }).describe("Socket-path identity; binds at /run/switchroom/auth-broker/<name>/sock"),
14301
16345
  account: exports_external.string().min(1).describe("Pinned account label for this consumer. `get-credentials` returns " + "this account's credentials; `mark-exhausted` from this consumer " + "only affects this account."),
14302
- uid: exports_external.number().int().nonnegative().optional().describe("Optional UID to chown the consumer socket to (defaults to 0 = root, " + "suitable for sibling containers running as root).")
14303
- })).optional().describe("Non-agent peers that hold a broker socket (RFC H §4.8). Each gets " + "its own `/run/switchroom/auth-broker/<name>/sock` chowned to its UID. " + "Consumers cannot be admins; a consumer name that collides with an " + "agent (whether that agent has `admin: true` or not) is a config " + "error caught at schema validation.")
16346
+ uid: exports_external.number().int().nonnegative().optional().describe("Optional UID to chown the consumer socket to (defaults to 0 = root, " + "suitable for sibling containers running as root)."),
16347
+ mirror_dir: exports_external.string().optional().describe("Optional host-side directory path. When set, the broker actively " + "writes the consumer's effective-account `.credentials.json` mirror " + "here — in addition to serving creds on demand via `get-credentials`. " + "Use this to eliminate the pull-latency gap: without a mirror the " + "consumer only gets failover creds at its next scheduled re-fetch " + "(up to 30 min). With a mirror the broker pushes failover creds " + "immediately when it detects exhaustion (consumer-quota-sensor tick, " + "or a mark-exhausted RPC on the pinned account). The directory must " + "be accessible to the broker container (bind-mounted from the host) " + "and to the consumer container; the broker writes " + "`<mirror_dir>/.credentials.json` atomically. Chown is attempted to " + "`uid` (default 0) swallowed when CAP_CHOWN is absent.")
16348
+ })).optional().describe("Non-agent peers that hold a broker socket (RFC H §4.8). Each gets " + "its own `/run/switchroom/auth-broker/<name>/sock` chowned to its UID. " + "Consumers cannot be admins; a consumer name that collides with an " + "agent (whether that agent has `admin: true` or not) is a config " + "error caught at schema validation."),
16349
+ allow_overage_accounts: exports_external.array(exports_external.string().min(1)).optional().describe("Opt-in list of account labels (bare strings matching `auth.active` / " + "`auth.fallback_order` entries) that may be served PAST the weekly " + "utilization wall when Anthropic overage billing is available for the " + "account (`overageStatus === 'allowed'`). Overage is REAL MONEY — " + "default is empty (no account gets this). An account in this list is " + "only kept eligible when its fresh quota snapshot reports " + "`overageStatus: 'allowed'` AND `overageDisabledReason` is NOT " + "'out_of_credits' (i.e. the overage credit has not been exhausted). " + "As soon as `overageDisabledReason` becomes 'out_of_credits', the " + "account is blocked immediately regardless of this flag. Overage lifts " + "ONLY the utilization wall — it cannot lift an active exhaustion mark " + "written by a real 429 (`mark-exhausted`).")
14304
16350
  }).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)."),
14305
16351
  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."),
14306
16352
  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)."),
16353
+ litellm: LiteLLMConfigSchema.describe("Top-level LiteLLM routing infra — global base_url, admin_key (the " + "LiteLLM master key, supports a `vault:` ref), team alias, and " + "small_fast_model shared by every agent that opts in. Set `enabled: " + "true` here to default the whole fleet on (each agent can still set " + "`litellm.enabled: false` to opt out). Default OFF."),
14307
16354
  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."),
14308
16355
  notion_workspace: NotionWorkspaceConfigSchema.describe("RFC reference/rfcs/notion-integration.md. Top-level Notion integration " + "config — vault key for the integration token, friendly-name → " + "database UUID map, optional MCP-package version pin, and optional " + "global rate-limit override (default 3 rps, Notion's documented " + "public-API limit). Block is optional; when omitted no agent gets a " + "Notion MCP entry regardless of per-agent config."),
14309
16356
  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."),
@@ -14733,6 +16780,24 @@ function mergeAgentConfig(defaultsIn, agentIn) {
14733
16780
  ...merged.env ?? {}
14734
16781
  };
14735
16782
  }
16783
+ if (defaults.litellm || merged.litellm) {
16784
+ const base = defaults.litellm ?? {};
16785
+ const override = merged.litellm ?? {};
16786
+ const combined = { ...base };
16787
+ for (const [k, v] of Object.entries(override)) {
16788
+ if (v === undefined)
16789
+ continue;
16790
+ if (k === "tags" && base.tags && typeof v === "object" && v !== null && !Array.isArray(v)) {
16791
+ combined.tags = {
16792
+ ...base.tags,
16793
+ ...v
16794
+ };
16795
+ } else {
16796
+ combined[k] = v;
16797
+ }
16798
+ }
16799
+ merged.litellm = combined;
16800
+ }
14736
16801
  if (defaults.subagents || merged.subagents) {
14737
16802
  const dSub = defaults.subagents ?? {};
14738
16803
  const mSub = merged.subagents ?? {};
@@ -15082,6 +17147,14 @@ function resolveAgentsDir(config) {
15082
17147
  // src/agents/compose.ts
15083
17148
  import { createHash } from "node:crypto";
15084
17149
 
17150
+ // src/config/timezone.ts
17151
+ var CONTAINER_DEFAULT_UTC_ZONES = new Set([
17152
+ "UTC",
17153
+ "Etc/UTC",
17154
+ "Etc/Universal",
17155
+ "Universal"
17156
+ ]);
17157
+
15085
17158
  // src/vault/broker/peercred.ts
15086
17159
  var RESERVED_AGENT_NAMES = new Set(["operator", "hostd"]);
15087
17160
  function isReservedAgentName(name) {
@@ -15114,18 +17187,18 @@ import { spawn as spawn2, spawnSync as spawnSync3 } from "node:child_process";
15114
17187
  import { mkdir, chmod, chown, unlink, appendFile } from "node:fs/promises";
15115
17188
  import {
15116
17189
  readdirSync as readdirSync2,
15117
- existsSync as existsSync7,
15118
- readFileSync as readFileSync5,
17190
+ existsSync as existsSync8,
17191
+ readFileSync as readFileSync6,
15119
17192
  writeFileSync as writeFileSync3,
15120
- renameSync,
17193
+ renameSync as renameSync2,
15121
17194
  mkdirSync as mkdirSync2,
15122
- openSync as openSync2,
17195
+ openSync as openSync3,
15123
17196
  ftruncateSync,
15124
- writeSync,
15125
- fsyncSync,
15126
- closeSync as closeSync2
17197
+ writeSync as writeSync2,
17198
+ fsyncSync as fsyncSync2,
17199
+ closeSync as closeSync3
15127
17200
  } from "node:fs";
15128
- import { join as join3, dirname as dirname4, resolve as resolve5 } from "node:path";
17201
+ import { join as join5, dirname as dirname6, resolve as resolve6 } from "node:path";
15129
17202
  import { createHash as createHash5, randomUUID as randomUUID2, randomBytes } from "node:crypto";
15130
17203
 
15131
17204
  // src/host-control/protocol.ts
@@ -15178,6 +17251,16 @@ var ApplyRequestSchema = exports_external.object({
15178
17251
  op: exports_external.literal("apply"),
15179
17252
  args: exports_external.object({}).optional()
15180
17253
  });
17254
+ var RolloutRequestSchema = exports_external.object({
17255
+ ...RequestEnvelope,
17256
+ op: exports_external.literal("rollout"),
17257
+ args: exports_external.object({
17258
+ pin: exports_external.string().regex(/^v\d+\.\d+\.\d+$/),
17259
+ agents: exports_external.array(AgentNameSchema).min(1).optional(),
17260
+ skip_web: exports_external.boolean().optional(),
17261
+ allow_downgrade: exports_external.boolean().optional()
17262
+ }).required({ pin: true })
17263
+ });
15181
17264
  var AgentStartRequestSchema = exports_external.object({
15182
17265
  ...RequestEnvelope,
15183
17266
  op: exports_external.literal("agent_start"),
@@ -15251,6 +17334,7 @@ var RequestSchema = exports_external.discriminatedUnion("op", [
15251
17334
  UpdateCheckRequestSchema,
15252
17335
  UpdateApplyRequestSchema,
15253
17336
  ApplyRequestSchema,
17337
+ RolloutRequestSchema,
15254
17338
  AgentStartRequestSchema,
15255
17339
  AgentStopRequestSchema,
15256
17340
  AgentLogsRequestSchema,
@@ -15355,7 +17439,7 @@ function deniedResponse(request_id, error, duration_ms = 0) {
15355
17439
  // src/analytics/error-friction.ts
15356
17440
  import { createHash as createHash2 } from "node:crypto";
15357
17441
 
15358
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
17442
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
15359
17443
  import { dirname, posix, sep } from "path";
15360
17444
  function createModulerModifier() {
15361
17445
  const getModuleFromFileName = createGetModuleFromFilename();
@@ -15391,7 +17475,7 @@ function normalizeWindowsPath(path) {
15391
17475
  return path.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
15392
17476
  }
15393
17477
 
15394
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/featureFlagUtils.mjs
17478
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/featureFlagUtils.mjs
15395
17479
  var normalizeFlagsResponse = (flagsResponse) => {
15396
17480
  if ("flags" in flagsResponse) {
15397
17481
  const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
@@ -15462,7 +17546,7 @@ var parsePayload = (response) => {
15462
17546
  }
15463
17547
  };
15464
17548
 
15465
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/gzip.mjs
17549
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/gzip.mjs
15466
17550
  function isGzipSupported() {
15467
17551
  return "CompressionStream" in globalThis;
15468
17552
  }
@@ -15482,7 +17566,7 @@ async function gzipCompress(input, isDebug = true) {
15482
17566
  }
15483
17567
  }
15484
17568
 
15485
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
17569
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
15486
17570
  /*! For license information please see uuidv7.mjs.LICENSE.txt */
15487
17571
  var DIGITS = "0123456789abcdef";
15488
17572
 
@@ -15660,7 +17744,7 @@ var defaultGenerator;
15660
17744
  var uuidv7 = () => uuidv7obj().toString();
15661
17745
  var uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator)).generate();
15662
17746
 
15663
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/types.mjs
17747
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/types.mjs
15664
17748
  var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedProperty) {
15665
17749
  PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
15666
17750
  PostHogPersistedProperty["DistinctId"] = "distinct_id";
@@ -15693,7 +17777,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
15693
17777
  return PostHogPersistedProperty;
15694
17778
  }({});
15695
17779
 
15696
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bot-detection.mjs
17780
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bot-detection.mjs
15697
17781
  var DEFAULT_BLOCKED_UA_STRS = [
15698
17782
  "amazonbot",
15699
17783
  "amazonproductbot",
@@ -15782,7 +17866,7 @@ var isBlockedUA = function(ua, customBlockedUserAgents = []) {
15782
17866
  return uaLower.indexOf(blockedUaLower) !== -1;
15783
17867
  });
15784
17868
  };
15785
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/type-utils.mjs
17869
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/type-utils.mjs
15786
17870
  var nativeIsArray = Array.isArray;
15787
17871
  var ObjProto = Object.prototype;
15788
17872
  var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
@@ -15819,7 +17903,7 @@ function isInstanceOf(candidate, base) {
15819
17903
  }
15820
17904
  }
15821
17905
 
15822
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/number-utils.mjs
17906
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/number-utils.mjs
15823
17907
  function clampToRange(value, min, max, logger, fallbackValue) {
15824
17908
  if (min > max) {
15825
17909
  logger.warn("min cannot be greater than max.");
@@ -15839,7 +17923,7 @@ function clampToRange(value, min, max, logger, fallbackValue) {
15839
17923
  return clampToRange(fallbackValue || max, min, max, logger);
15840
17924
  }
15841
17925
 
15842
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
17926
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
15843
17927
  var ONE_DAY_IN_MS = 86400000;
15844
17928
 
15845
17929
  class BucketedRateLimiter {
@@ -15883,7 +17967,7 @@ class BucketedRateLimiter {
15883
17967
  this._buckets = {};
15884
17968
  }
15885
17969
  }
15886
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/promise-queue.mjs
17970
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/promise-queue.mjs
15887
17971
  class PromiseQueue {
15888
17972
  add(promise) {
15889
17973
  const promiseUUID = uuidv7();
@@ -15909,7 +17993,7 @@ class PromiseQueue {
15909
17993
  this.promiseByIds = {};
15910
17994
  }
15911
17995
  }
15912
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/logger.mjs
17996
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/logger.mjs
15913
17997
  function createConsole(consoleLike = console) {
15914
17998
  const lockedMethods = {
15915
17999
  log: consoleLike.log.bind(consoleLike),
@@ -15947,7 +18031,7 @@ var passThrough = (fn) => fn();
15947
18031
  function createLogger(prefix, maybeCall = passThrough) {
15948
18032
  return _createLogger(prefix, maybeCall, createConsole());
15949
18033
  }
15950
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
18034
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
15951
18035
  var MOBILE = "Mobile";
15952
18036
  var IOS = "iOS";
15953
18037
  var ANDROID = "Android";
@@ -16204,7 +18288,7 @@ var osMatchers = [
16204
18288
  ]
16205
18289
  ];
16206
18290
 
16207
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/index.mjs
18291
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/utils/index.mjs
16208
18292
  var STRING_FORMAT = "utf8";
16209
18293
  function assert(truthyValue, message) {
16210
18294
  if (!truthyValue || typeof truthyValue != "string" || isEmpty(truthyValue))
@@ -16252,7 +18336,7 @@ function allSettled(promises) {
16252
18336
  reason
16253
18337
  }))));
16254
18338
  }
16255
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/eventemitter.mjs
18339
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/eventemitter.mjs
16256
18340
  class SimpleEventEmitter {
16257
18341
  constructor() {
16258
18342
  this.events = {};
@@ -16274,7 +18358,7 @@ class SimpleEventEmitter {
16274
18358
  }
16275
18359
  }
16276
18360
 
16277
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
18361
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
16278
18362
  class PostHogFetchHttpError extends Error {
16279
18363
  constructor(response, reqByteLength) {
16280
18364
  super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
@@ -16989,7 +19073,7 @@ class PostHogCoreStateless {
16989
19073
  return this.shutdownPromise;
16990
19074
  }
16991
19075
  }
16992
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/index.mjs
19076
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/index.mjs
16993
19077
  var exports_error_tracking = {};
16994
19078
  __export(exports_error_tracking, {
16995
19079
  winjsStackLineParser: () => winjsStackLineParser,
@@ -17013,7 +19097,7 @@ __export(exports_error_tracking, {
17013
19097
  DOMExceptionCoercer: () => DOMExceptionCoercer
17014
19098
  });
17015
19099
 
17016
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
19100
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
17017
19101
  var parsedStackResults;
17018
19102
  var lastKeysCount;
17019
19103
  var cachedFilenameChunkIds;
@@ -17052,7 +19136,7 @@ function getFilenameToChunkIdMap(stackParser) {
17052
19136
  return cachedFilenameChunkIds;
17053
19137
  }
17054
19138
 
17055
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
19139
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
17056
19140
  var MAX_CAUSE_RECURSION = 4;
17057
19141
 
17058
19142
  class ErrorPropertiesBuilder {
@@ -17174,7 +19258,7 @@ class ErrorPropertiesBuilder {
17174
19258
  return context;
17175
19259
  }
17176
19260
  }
17177
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
19261
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
17178
19262
  var UNKNOWN_FUNCTION = "?";
17179
19263
  function createFrame(platform, filename, func, lineno, colno) {
17180
19264
  const frame = {
@@ -17190,7 +19274,7 @@ function createFrame(platform, filename, func, lineno, colno) {
17190
19274
  return frame;
17191
19275
  }
17192
19276
 
17193
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
19277
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
17194
19278
  var extractSafariExtensionDetails = (func, filename) => {
17195
19279
  const isSafariExtension = func.indexOf("safari-extension") !== -1;
17196
19280
  const isSafariWebExtension = func.indexOf("safari-web-extension") !== -1;
@@ -17203,7 +19287,7 @@ var extractSafariExtensionDetails = (func, filename) => {
17203
19287
  ];
17204
19288
  };
17205
19289
 
17206
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
19290
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
17207
19291
  var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
17208
19292
  var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
17209
19293
  var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
@@ -17229,7 +19313,7 @@ var chromeStackLineParser = (line, platform) => {
17229
19313
  }
17230
19314
  };
17231
19315
 
17232
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
19316
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
17233
19317
  var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
17234
19318
  var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
17235
19319
  var geckoStackLineParser = (line, platform) => {
@@ -17252,14 +19336,14 @@ var geckoStackLineParser = (line, platform) => {
17252
19336
  }
17253
19337
  };
17254
19338
 
17255
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
19339
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
17256
19340
  var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
17257
19341
  var winjsStackLineParser = (line, platform) => {
17258
19342
  const parts = winjsRegex.exec(line);
17259
19343
  return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined) : undefined;
17260
19344
  };
17261
19345
 
17262
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
19346
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
17263
19347
  var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
17264
19348
  var opera10StackLineParser = (line, platform) => {
17265
19349
  const parts = opera10Regex.exec(line);
@@ -17271,7 +19355,7 @@ var opera11StackLineParser = (line, platform) => {
17271
19355
  return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
17272
19356
  };
17273
19357
 
17274
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
19358
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
17275
19359
  var FILENAME_MATCH = /^\s*[-]{4,}$/;
17276
19360
  var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
17277
19361
  var nodeStackLineParser = (line, platform) => {
@@ -17340,7 +19424,7 @@ function _parseIntOrUndefined(input) {
17340
19424
  return parseInt(input || "", 10) || undefined;
17341
19425
  }
17342
19426
 
17343
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
19427
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
17344
19428
  var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
17345
19429
  var STACKTRACE_FRAME_LIMIT = 50;
17346
19430
  function reverseAndStripFrames(stack) {
@@ -17385,7 +19469,7 @@ function createStackParser(platform, ...parsers) {
17385
19469
  return reverseAndStripFrames(frames);
17386
19470
  };
17387
19471
  }
17388
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
19472
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
17389
19473
  class DOMExceptionCoercer {
17390
19474
  match(err) {
17391
19475
  return this.isDOMException(err) || this.isDOMError(err);
@@ -17415,7 +19499,7 @@ class DOMExceptionCoercer {
17415
19499
  return isBuiltin(err, "DOMError");
17416
19500
  }
17417
19501
  }
17418
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
19502
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
17419
19503
  class ErrorCoercer {
17420
19504
  match(err) {
17421
19505
  return isPlainError(err);
@@ -17442,7 +19526,7 @@ class ErrorCoercer {
17442
19526
  return err.stacktrace || err.stack || undefined;
17443
19527
  }
17444
19528
  }
17445
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
19529
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
17446
19530
  class ErrorEventCoercer {
17447
19531
  constructor() {}
17448
19532
  match(err) {
@@ -17460,7 +19544,7 @@ class ErrorEventCoercer {
17460
19544
  return exceptionLike;
17461
19545
  }
17462
19546
  }
17463
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
19547
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
17464
19548
  var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
17465
19549
 
17466
19550
  class StringCoercer {
@@ -17490,7 +19574,7 @@ class StringCoercer {
17490
19574
  ];
17491
19575
  }
17492
19576
  }
17493
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/types.mjs
19577
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/types.mjs
17494
19578
  var severityLevels = [
17495
19579
  "fatal",
17496
19580
  "error",
@@ -17500,7 +19584,7 @@ var severityLevels = [
17500
19584
  "debug"
17501
19585
  ];
17502
19586
 
17503
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
19587
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
17504
19588
  function extractExceptionKeysForMessage(err, maxLength = 40) {
17505
19589
  const keys = Object.keys(err);
17506
19590
  keys.sort();
@@ -17517,7 +19601,7 @@ function extractExceptionKeysForMessage(err, maxLength = 40) {
17517
19601
  return "";
17518
19602
  }
17519
19603
 
17520
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
19604
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
17521
19605
  class ObjectCoercer {
17522
19606
  match(candidate) {
17523
19607
  return typeof candidate == "object" && candidate !== null;
@@ -17570,7 +19654,7 @@ class ObjectCoercer {
17570
19654
  }
17571
19655
  }
17572
19656
  }
17573
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
19657
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
17574
19658
  class EventCoercer {
17575
19659
  match(err) {
17576
19660
  return isEvent(err);
@@ -17585,7 +19669,7 @@ class EventCoercer {
17585
19669
  };
17586
19670
  }
17587
19671
  }
17588
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
19672
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
17589
19673
  class PrimitiveCoercer {
17590
19674
  match(candidate) {
17591
19675
  return isPrimitive(candidate);
@@ -17599,7 +19683,7 @@ class PrimitiveCoercer {
17599
19683
  };
17600
19684
  }
17601
19685
  }
17602
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
19686
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
17603
19687
  class PromiseRejectionEventCoercer {
17604
19688
  match(err) {
17605
19689
  return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
@@ -17635,7 +19719,7 @@ class PromiseRejectionEventCoercer {
17635
19719
  return error;
17636
19720
  }
17637
19721
  }
17638
- // node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/utils.mjs
19722
+ // ../../switchroom/node_modules/.bun/@posthog+core@1.25.2/node_modules/@posthog/core/dist/error-tracking/utils.mjs
17639
19723
  class ReduceableCache {
17640
19724
  constructor(_maxSize) {
17641
19725
  this._maxSize = _maxSize;
@@ -17660,7 +19744,7 @@ class ReduceableCache {
17660
19744
  }
17661
19745
  }
17662
19746
  }
17663
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
19747
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
17664
19748
  import { createReadStream } from "node:fs";
17665
19749
  import { createInterface } from "node:readline";
17666
19750
  var LRU_FILE_CONTENTS_CACHE = new exports_error_tracking.ReduceableCache(25);
@@ -17878,7 +19962,7 @@ function snipLine(line, colno) {
17878
19962
  return newLine;
17879
19963
  }
17880
19964
 
17881
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
19965
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
17882
19966
  function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
17883
19967
  let calledFatalError = false;
17884
19968
  return Object.assign((error) => {
@@ -17910,7 +19994,7 @@ function addUnhandledRejectionListener(captureFn) {
17910
19994
  }));
17911
19995
  }
17912
19996
 
17913
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
19997
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
17914
19998
  var SHUTDOWN_TIMEOUT = 2000;
17915
19999
 
17916
20000
  class ErrorTracking {
@@ -17979,10 +20063,10 @@ class ErrorTracking {
17979
20063
  }
17980
20064
  }
17981
20065
 
17982
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/version.mjs
20066
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/version.mjs
17983
20067
  var version = "5.29.2";
17984
20068
 
17985
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/types.mjs
20069
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/types.mjs
17986
20070
  var FeatureFlagError2 = {
17987
20071
  ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
17988
20072
  FLAG_MISSING: "flag_missing",
@@ -17990,7 +20074,7 @@ var FeatureFlagError2 = {
17990
20074
  UNKNOWN_ERROR: "unknown_error"
17991
20075
  };
17992
20076
 
17993
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
20077
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
17994
20078
  async function hashSHA1(text) {
17995
20079
  const subtle = globalThis.crypto?.subtle;
17996
20080
  if (!subtle)
@@ -18000,7 +20084,7 @@ async function hashSHA1(text) {
18000
20084
  return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
18001
20085
  }
18002
20086
 
18003
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
20087
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
18004
20088
  var SIXTY_SECONDS = 60000;
18005
20089
  var LONG_SCALE = 1152921504606847000;
18006
20090
  var NULL_VALUES_ALLOWED_OPERATORS = [
@@ -18874,7 +20958,7 @@ function relativeDateParseForFeatureFlagMatching(value) {
18874
20958
  }
18875
20959
  }
18876
20960
 
18877
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/storage-memory.mjs
20961
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/storage-memory.mjs
18878
20962
  class PostHogMemoryStorage {
18879
20963
  getProperty(key) {
18880
20964
  return this._memoryStorage[key];
@@ -18887,7 +20971,7 @@ class PostHogMemoryStorage {
18887
20971
  }
18888
20972
  }
18889
20973
 
18890
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/client.mjs
20974
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/client.mjs
18891
20975
  var MINIMUM_POLLING_INTERVAL = 100;
18892
20976
  var THIRTY_SECONDS = 30000;
18893
20977
  var MAX_CACHE_SIZE = 50000;
@@ -19675,7 +21759,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
19675
21759
  }
19676
21760
  }
19677
21761
 
19678
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/context/context.mjs
21762
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/context/context.mjs
19679
21763
  import { AsyncLocalStorage } from "node:async_hooks";
19680
21764
 
19681
21765
  class PostHogContext {
@@ -19706,7 +21790,7 @@ class PostHogContext {
19706
21790
  }
19707
21791
  }
19708
21792
 
19709
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
21793
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
19710
21794
  var NAME = "posthog-node";
19711
21795
  function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
19712
21796
  "error"
@@ -19774,7 +21858,7 @@ class PostHogSentryIntegration {
19774
21858
  };
19775
21859
  }
19776
21860
  }
19777
- // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/entrypoints/index.node.mjs
21861
+ // ../../switchroom/node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/entrypoints/index.node.mjs
19778
21862
  ErrorTracking.errorPropertiesBuilder = new exports_error_tracking.ErrorPropertiesBuilder([
19779
21863
  new exports_error_tracking.EventCoercer,
19780
21864
  new exports_error_tracking.ErrorCoercer,
@@ -20442,63 +22526,309 @@ function redactedMarker(ruleId) {
20442
22526
  if (!trimmed || trimmed === "key_value" || trimmed === "kv_entropy") {
20443
22527
  return REDACTED_MARKER;
20444
22528
  }
20445
- return `[REDACTED:${trimmed}]`;
20446
- }
20447
- // src/cli/install-detect.ts
20448
- import * as fs from "node:fs";
20449
- import * as path from "node:path";
20450
- import * as os from "node:os";
20451
- var BIN_PATH = "/usr/local/bin/switchroom";
20452
- function sourceArtifactPath() {
20453
- return path.join(os.homedir(), "code", "switchroom", "dist", "cli", "switchroom.js");
20454
- }
20455
- function sourceDistPrefix() {
20456
- return path.join(os.homedir(), "code", "switchroom", "dist") + path.sep;
22529
+ return `[REDACTED:${trimmed}]`;
22530
+ }
22531
+ // src/cli/install-detect.ts
22532
+ import * as fs from "node:fs";
22533
+ import * as path from "node:path";
22534
+ import * as os from "node:os";
22535
+ var BIN_PATH = "/usr/local/bin/switchroom";
22536
+ function sourceArtifactPath() {
22537
+ return path.join(os.homedir(), "code", "switchroom", "dist", "cli", "switchroom.js");
22538
+ }
22539
+ function sourceDistPrefix() {
22540
+ return path.join(os.homedir(), "code", "switchroom", "dist") + path.sep;
22541
+ }
22542
+ function detectInstallType() {
22543
+ try {
22544
+ const repoArtifact = sourceArtifactPath();
22545
+ const distPrefix = sourceDistPrefix();
22546
+ const binExists = fs.existsSync(BIN_PATH);
22547
+ const repoExists = fs.existsSync(repoArtifact);
22548
+ if (binExists) {
22549
+ const lst = fs.lstatSync(BIN_PATH);
22550
+ if (lst.isSymbolicLink()) {
22551
+ const target = fs.readlinkSync(BIN_PATH);
22552
+ const resolved = path.isAbsolute(target) ? target : path.resolve(path.dirname(BIN_PATH), target);
22553
+ if (resolved.startsWith(distPrefix)) {
22554
+ return {
22555
+ install_type: "source",
22556
+ source_paths: { bin: BIN_PATH, repo: repoExists ? repoArtifact : undefined }
22557
+ };
22558
+ }
22559
+ return {
22560
+ install_type: "binary",
22561
+ source_paths: { bin: BIN_PATH }
22562
+ };
22563
+ }
22564
+ return {
22565
+ install_type: "binary",
22566
+ source_paths: { bin: BIN_PATH }
22567
+ };
22568
+ }
22569
+ if (repoExists) {
22570
+ return {
22571
+ install_type: "source-unlinked",
22572
+ source_paths: { repo: repoArtifact }
22573
+ };
22574
+ }
22575
+ return { install_type: "docker", source_paths: {} };
22576
+ } catch {
22577
+ return { install_type: "unknown", source_paths: {} };
22578
+ }
22579
+ }
22580
+
22581
+ // src/util/atomic.ts
22582
+ import { closeSync as closeSync2, constants, fsyncSync, openSync as openSync2, renameSync, rmSync, writeSync } from "node:fs";
22583
+ var TMP_OPEN_FLAGS = constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | (constants.O_NOFOLLOW ?? 0);
22584
+
22585
+ // src/cli/resolve-version.ts
22586
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
22587
+ import { dirname as dirname4, join as join2 } from "node:path";
22588
+
22589
+ // src/build-info.ts
22590
+ var VERSION = "0.16.4";
22591
+
22592
+ // src/cli/resolve-version.ts
22593
+ function readPackageVersion() {
22594
+ let dir = import.meta.dirname;
22595
+ for (let i = 0;i < 12 && dir && dir !== "/"; i++) {
22596
+ const p = join2(dir, "package.json");
22597
+ if (existsSync6(p)) {
22598
+ try {
22599
+ const pkg = JSON.parse(readFileSync4(p, "utf-8"));
22600
+ if (pkg?.name === "switchroom" && typeof pkg.version === "string") {
22601
+ return pkg.version;
22602
+ }
22603
+ } catch {}
22604
+ }
22605
+ dir = dirname4(dir);
22606
+ }
22607
+ return null;
22608
+ }
22609
+ var SWITCHROOM_VERSION = (() => {
22610
+ const pkgVersion = readPackageVersion();
22611
+ if (pkgVersion !== null && pkgVersion === VERSION) {
22612
+ return VERSION;
22613
+ }
22614
+ return VERSION ?? pkgVersion ?? "0.0.0";
22615
+ })();
22616
+
22617
+ // src/host-control/audit-reader.ts
22618
+ function parseAuditLine(line) {
22619
+ const trimmed = line.trim();
22620
+ if (trimmed.length === 0)
22621
+ return null;
22622
+ let obj;
22623
+ try {
22624
+ obj = JSON.parse(trimmed);
22625
+ } catch {
22626
+ return null;
22627
+ }
22628
+ if (typeof obj !== "object" || obj === null)
22629
+ return null;
22630
+ const o = obj;
22631
+ if (typeof o.ts !== "string" || typeof o.op !== "string")
22632
+ return null;
22633
+ if (typeof o.request_id !== "string" || typeof o.result !== "string")
22634
+ return null;
22635
+ if (typeof o.duration_ms !== "number")
22636
+ return null;
22637
+ const callerRaw = o.caller;
22638
+ let caller;
22639
+ if (callerRaw && callerRaw.kind === "agent" && typeof callerRaw.name === "string") {
22640
+ caller = { kind: "agent", name: callerRaw.name };
22641
+ } else if (callerRaw && callerRaw.kind === "operator") {
22642
+ caller = { kind: "operator" };
22643
+ } else {
22644
+ return null;
22645
+ }
22646
+ const exit_code = o.exit_code === null || typeof o.exit_code === "number" ? o.exit_code : null;
22647
+ const entry = {
22648
+ ts: o.ts,
22649
+ op: o.op,
22650
+ caller,
22651
+ request_id: o.request_id,
22652
+ result: o.result,
22653
+ exit_code,
22654
+ duration_ms: o.duration_ms
22655
+ };
22656
+ if (typeof o.error === "string")
22657
+ entry.error = o.error;
22658
+ if (typeof o.phase === "string")
22659
+ entry.phase = o.phase;
22660
+ if (typeof o.stdout_tail === "string")
22661
+ entry.stdout_tail = o.stdout_tail;
22662
+ if (typeof o.stderr_tail === "string")
22663
+ entry.stderr_tail = o.stderr_tail;
22664
+ if (typeof o.channel === "string")
22665
+ entry.channel = o.channel;
22666
+ if (typeof o.pin === "string")
22667
+ entry.pin = o.pin;
22668
+ if (o.resolved_sha && typeof o.resolved_sha === "object" && !Array.isArray(o.resolved_sha)) {
22669
+ const rs = {};
22670
+ for (const [k, v] of Object.entries(o.resolved_sha)) {
22671
+ if (typeof v === "string")
22672
+ rs[k] = v;
22673
+ }
22674
+ if (Object.keys(rs).length > 0)
22675
+ entry.resolved_sha = rs;
22676
+ }
22677
+ if (o.install_context && typeof o.install_context === "object" && !Array.isArray(o.install_context)) {
22678
+ const ic = o.install_context;
22679
+ if (typeof ic.install_type === "string" && typeof ic.detected_at === "string") {
22680
+ entry.install_context = {
22681
+ install_type: ic.install_type,
22682
+ detected_at: ic.detected_at
22683
+ };
22684
+ }
22685
+ }
22686
+ if (Array.isArray(o.rolled) && o.rolled.every((x) => typeof x === "string")) {
22687
+ entry.rolled = o.rolled;
22688
+ }
22689
+ if (typeof o.failed_step === "string")
22690
+ entry.failed_step = o.failed_step;
22691
+ if (typeof o.failed_agent === "string")
22692
+ entry.failed_agent = o.failed_agent;
22693
+ if (typeof o.prior_pin === "string")
22694
+ entry.prior_pin = o.prior_pin;
22695
+ return entry;
22696
+ }
22697
+
22698
+ // src/cli/rollout.ts
22699
+ function isVersionAssertable(target) {
22700
+ return /^v?\d+\.\d+\.\d+$/.test(target.trim());
22701
+ }
22702
+ var ROLLOUT_RESULT_SENTINEL = "SWITCHROOM_ROLLOUT_RESULT:";
22703
+ function parseRolloutResultLine(stdout) {
22704
+ const lines = stdout.split(`
22705
+ `);
22706
+ for (let i = lines.length - 1;i >= 0; i--) {
22707
+ const line = lines[i].trim();
22708
+ if (line.startsWith(ROLLOUT_RESULT_SENTINEL)) {
22709
+ try {
22710
+ return JSON.parse(line.slice(ROLLOUT_RESULT_SENTINEL.length));
22711
+ } catch {
22712
+ return null;
22713
+ }
22714
+ }
22715
+ }
22716
+ return null;
22717
+ }
22718
+
22719
+ // ../../switchroom/node_modules/.bun/commander@13.1.0/node_modules/commander/esm.mjs
22720
+ var import__3 = __toESM(require_commander(), 1);
22721
+
22722
+ // src/cli/update.ts
22723
+ import { join as join3, dirname as dirname5, resolve as resolve5 } from "node:path";
22724
+ import { homedir as homedir3 } from "node:os";
22725
+
22726
+ // src/agents/lifecycle.ts
22727
+ import { execFileSync, spawn, spawnSync } from "node:child_process";
22728
+
22729
+ // src/agents/tmux.ts
22730
+ var MAX_BYTES = 10 * 1024 * 1024;
22731
+
22732
+ // src/agents/lifecycle.ts
22733
+ function containerName(name) {
22734
+ return `switchroom-${name}`;
22735
+ }
22736
+ function getAllAgentStatuses(config) {
22737
+ const agentNames = Object.keys(config.agents);
22738
+ const statuses = {};
22739
+ if (agentNames.length === 0)
22740
+ return statuses;
22741
+ const cnByAgent = new Map;
22742
+ const agentByCn = new Map;
22743
+ for (const a of agentNames) {
22744
+ const cn = containerName(a);
22745
+ cnByAgent.set(a, cn);
22746
+ agentByCn.set(cn, a);
22747
+ statuses[a] = { active: "inactive", uptime: null, memory: null, pid: null };
22748
+ }
22749
+ const insp = spawnSync("docker", [
22750
+ "inspect",
22751
+ "--format",
22752
+ "{{.Name}}|{{.State.Status}}|{{.State.StartedAt}}|{{.State.Pid}}",
22753
+ ...cnByAgent.values()
22754
+ ], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], timeout: 15000 });
22755
+ for (const line of (insp.stdout ?? "").split(`
22756
+ `)) {
22757
+ const t = line.trim();
22758
+ if (!t)
22759
+ continue;
22760
+ const [rawName, status, startedAt, pidStr] = t.split("|");
22761
+ const cn = (rawName ?? "").replace(/^\//, "");
22762
+ const agent = agentByCn.get(cn);
22763
+ if (!agent)
22764
+ continue;
22765
+ const pidNum = parseInt(pidStr ?? "", 10);
22766
+ statuses[agent] = {
22767
+ active: status === "running" ? "active" : status || "inactive",
22768
+ uptime: startedAt && startedAt !== "0001-01-01T00:00:00Z" ? startedAt : null,
22769
+ memory: null,
22770
+ pid: Number.isFinite(pidNum) && pidNum > 0 ? pidNum : null
22771
+ };
22772
+ }
22773
+ const stats = spawnSync("docker", ["stats", "--no-stream", "--format", "{{.Name}}|{{.MemUsage}}"], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], timeout: 15000 });
22774
+ if (stats.status === 0) {
22775
+ for (const line of (stats.stdout ?? "").split(`
22776
+ `)) {
22777
+ const t = line.trim();
22778
+ if (!t)
22779
+ continue;
22780
+ const [cn, memUsage] = t.split("|");
22781
+ const agent = cn ? agentByCn.get(cn) : undefined;
22782
+ if (!agent || statuses[agent].active !== "active")
22783
+ continue;
22784
+ const first = (memUsage ?? "").split("/")[0]?.trim();
22785
+ if (!first)
22786
+ continue;
22787
+ const m = first.match(/([\d.]+)\s*([KMG]i?B)/i);
22788
+ if (m) {
22789
+ const val = parseFloat(m[1]);
22790
+ const unit = m[2].toUpperCase();
22791
+ let mb = val;
22792
+ if (unit.startsWith("K"))
22793
+ mb = val / 1024;
22794
+ else if (unit.startsWith("G"))
22795
+ mb = val * 1024;
22796
+ statuses[agent].memory = `${Math.round(mb)}MB`;
22797
+ } else {
22798
+ statuses[agent].memory = first;
22799
+ }
22800
+ }
22801
+ }
22802
+ return statuses;
20457
22803
  }
20458
- function detectInstallType() {
22804
+
22805
+ // src/cli/update.ts
22806
+ var DEFAULT_COMPOSE_PATH = join3(homedir3(), ".switchroom", "compose", "docker-compose.yml");
22807
+ var UPDATE_RESULT_SENTINEL = "SWITCHROOM_UPDATE_RESULT:";
22808
+ function parseUpdateResultLine(stdout) {
22809
+ const idx = stdout.lastIndexOf(UPDATE_RESULT_SENTINEL);
22810
+ if (idx === -1)
22811
+ return null;
22812
+ const raw = stdout.slice(idx + UPDATE_RESULT_SENTINEL.length).split(`
22813
+ `)[0];
22814
+ if (!raw)
22815
+ return null;
20459
22816
  try {
20460
- const repoArtifact = sourceArtifactPath();
20461
- const distPrefix = sourceDistPrefix();
20462
- const binExists = fs.existsSync(BIN_PATH);
20463
- const repoExists = fs.existsSync(repoArtifact);
20464
- if (binExists) {
20465
- const lst = fs.lstatSync(BIN_PATH);
20466
- if (lst.isSymbolicLink()) {
20467
- const target = fs.readlinkSync(BIN_PATH);
20468
- const resolved = path.isAbsolute(target) ? target : path.resolve(path.dirname(BIN_PATH), target);
20469
- if (resolved.startsWith(distPrefix)) {
20470
- return {
20471
- install_type: "source",
20472
- source_paths: { bin: BIN_PATH, repo: repoExists ? repoArtifact : undefined }
20473
- };
20474
- }
20475
- return {
20476
- install_type: "binary",
20477
- source_paths: { bin: BIN_PATH }
20478
- };
20479
- }
20480
- return {
20481
- install_type: "binary",
20482
- source_paths: { bin: BIN_PATH }
20483
- };
20484
- }
20485
- if (repoExists) {
20486
- return {
20487
- install_type: "source-unlinked",
20488
- source_paths: { repo: repoArtifact }
20489
- };
22817
+ const parsed = JSON.parse(raw);
22818
+ if (parsed !== null && typeof parsed === "object" && "ok" in parsed && "deferred" in parsed && typeof parsed.ok === "boolean" && Array.isArray(parsed.deferred)) {
22819
+ return parsed;
20490
22820
  }
20491
- return { install_type: "docker", source_paths: {} };
22821
+ return null;
20492
22822
  } catch {
20493
- return { install_type: "unknown", source_paths: {} };
22823
+ return null;
20494
22824
  }
20495
22825
  }
20496
22826
 
20497
22827
  // src/host-control/config-edit-validator.ts
20498
- import { mkdtempSync, writeFileSync as writeFileSync2, rmSync, existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
22828
+ import { mkdtempSync, writeFileSync as writeFileSync2, rmSync as rmSync2, existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
20499
22829
  import { tmpdir } from "node:os";
20500
- import { join as join2, isAbsolute as isAbsolute2, normalize } from "node:path";
20501
- import { spawnSync } from "node:child_process";
22830
+ import { join as join4, isAbsolute as isAbsolute2, normalize } from "node:path";
22831
+ import { spawnSync as spawnSync2 } from "node:child_process";
20502
22832
  import { isDeepStrictEqual } from "node:util";
20503
22833
  var MAX_PATCH_BYTES = 1024 * 1024;
20504
22834
  var UNLOCK_CARD_YAML_ALLOWLIST = new Set([
@@ -20583,20 +22913,20 @@ function validateShape(unifiedDiff, targetPath) {
20583
22913
  return null;
20584
22914
  }
20585
22915
  function applyPatch(unifiedDiff, configPath, gitBin) {
20586
- if (!existsSync6(configPath)) {
22916
+ if (!existsSync7(configPath)) {
20587
22917
  return {
20588
22918
  ok: false,
20589
22919
  code: "E_PATCH_APPLY_FAILED",
20590
22920
  detail: `target config not found at ${configPath}`
20591
22921
  };
20592
22922
  }
20593
- const liveContent = readFileSync4(configPath, "utf8");
20594
- const scratchDir = mkdtempSync(join2(tmpdir(), "config-propose-edit-"));
22923
+ const liveContent = readFileSync5(configPath, "utf8");
22924
+ const scratchDir = mkdtempSync(join4(tmpdir(), "config-propose-edit-"));
20595
22925
  try {
20596
22926
  const basename2 = configPath.split("/").pop() ?? "switchroom.yaml";
20597
- const scratchFile = join2(scratchDir, basename2);
22927
+ const scratchFile = join4(scratchDir, basename2);
20598
22928
  writeFileSync2(scratchFile, liveContent);
20599
- const patchFile = join2(scratchDir, "proposal.patch");
22929
+ const patchFile = join4(scratchDir, "proposal.patch");
20600
22930
  writeFileSync2(patchFile, unifiedDiff);
20601
22931
  const bin = gitBin ?? "git";
20602
22932
  const baseArgs = [
@@ -20605,10 +22935,10 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
20605
22935
  "--recount",
20606
22936
  "--unidiff-zero"
20607
22937
  ];
20608
- const checkP1 = spawnSync(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p1", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
22938
+ const checkP1 = spawnSync2(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p1", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
20609
22939
  let pStrip = "-p1";
20610
22940
  if (checkP1.status !== 0) {
20611
- const checkP0 = spawnSync(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p0", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
22941
+ const checkP0 = spawnSync2(bin, [...baseArgs.slice(0, 1), "--check", ...baseArgs.slice(1), "-p0", patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
20612
22942
  if (checkP0.status !== 0) {
20613
22943
  const stderr = (checkP1.stderr || "") + (checkP0.stderr || "");
20614
22944
  return {
@@ -20619,7 +22949,7 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
20619
22949
  }
20620
22950
  pStrip = "-p0";
20621
22951
  }
20622
- const real = spawnSync(bin, [...baseArgs, pStrip, patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
22952
+ const real = spawnSync2(bin, [...baseArgs, pStrip, patchFile], { cwd: scratchDir, encoding: "utf8", timeout: 1e4 });
20623
22953
  if (real.status !== 0) {
20624
22954
  return {
20625
22955
  ok: false,
@@ -20627,10 +22957,10 @@ function applyPatch(unifiedDiff, configPath, gitBin) {
20627
22957
  detail: `git apply failed: ${(real.stderr || "").trim().slice(0, 500)}`
20628
22958
  };
20629
22959
  }
20630
- const after = readFileSync4(scratchFile, "utf8");
22960
+ const after = readFileSync5(scratchFile, "utf8");
20631
22961
  return { ok: true, after };
20632
22962
  } finally {
20633
- rmSync(scratchDir, { recursive: true, force: true });
22963
+ rmSync2(scratchDir, { recursive: true, force: true });
20634
22964
  }
20635
22965
  }
20636
22966
  function failsafeParse(source) {
@@ -20825,7 +23155,7 @@ function validateConfigEdit(opts) {
20825
23155
  return schemaErr;
20826
23156
  let beforeData = {};
20827
23157
  try {
20828
- const beforeRaw = existsSync6(opts.configPath) ? readFileSync4(opts.configPath, "utf8") : "";
23158
+ const beforeRaw = existsSync7(opts.configPath) ? readFileSync5(opts.configPath, "utf8") : "";
20829
23159
  const beforeDoc = $parseDocument(beforeRaw, { merge: false, strict: false });
20830
23160
  beforeData = beforeDoc.toJS();
20831
23161
  } catch {
@@ -20978,85 +23308,6 @@ function classifyBlastRadius(beforeYaml, afterYaml) {
20978
23308
  };
20979
23309
  }
20980
23310
 
20981
- // src/agents/lifecycle.ts
20982
- import { execFileSync, spawn, spawnSync as spawnSync2 } from "node:child_process";
20983
-
20984
- // src/agents/tmux.ts
20985
- var MAX_BYTES = 10 * 1024 * 1024;
20986
-
20987
- // src/agents/lifecycle.ts
20988
- function containerName(name) {
20989
- return `switchroom-${name}`;
20990
- }
20991
- function getAllAgentStatuses(config) {
20992
- const agentNames = Object.keys(config.agents);
20993
- const statuses = {};
20994
- if (agentNames.length === 0)
20995
- return statuses;
20996
- const cnByAgent = new Map;
20997
- const agentByCn = new Map;
20998
- for (const a of agentNames) {
20999
- const cn = containerName(a);
21000
- cnByAgent.set(a, cn);
21001
- agentByCn.set(cn, a);
21002
- statuses[a] = { active: "inactive", uptime: null, memory: null, pid: null };
21003
- }
21004
- const insp = spawnSync2("docker", [
21005
- "inspect",
21006
- "--format",
21007
- "{{.Name}}|{{.State.Status}}|{{.State.StartedAt}}|{{.State.Pid}}",
21008
- ...cnByAgent.values()
21009
- ], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], timeout: 15000 });
21010
- for (const line of (insp.stdout ?? "").split(`
21011
- `)) {
21012
- const t = line.trim();
21013
- if (!t)
21014
- continue;
21015
- const [rawName, status, startedAt, pidStr] = t.split("|");
21016
- const cn = (rawName ?? "").replace(/^\//, "");
21017
- const agent = agentByCn.get(cn);
21018
- if (!agent)
21019
- continue;
21020
- const pidNum = parseInt(pidStr ?? "", 10);
21021
- statuses[agent] = {
21022
- active: status === "running" ? "active" : status || "inactive",
21023
- uptime: startedAt && startedAt !== "0001-01-01T00:00:00Z" ? startedAt : null,
21024
- memory: null,
21025
- pid: Number.isFinite(pidNum) && pidNum > 0 ? pidNum : null
21026
- };
21027
- }
21028
- const stats = spawnSync2("docker", ["stats", "--no-stream", "--format", "{{.Name}}|{{.MemUsage}}"], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"], timeout: 15000 });
21029
- if (stats.status === 0) {
21030
- for (const line of (stats.stdout ?? "").split(`
21031
- `)) {
21032
- const t = line.trim();
21033
- if (!t)
21034
- continue;
21035
- const [cn, memUsage] = t.split("|");
21036
- const agent = cn ? agentByCn.get(cn) : undefined;
21037
- if (!agent || statuses[agent].active !== "active")
21038
- continue;
21039
- const first = (memUsage ?? "").split("/")[0]?.trim();
21040
- if (!first)
21041
- continue;
21042
- const m = first.match(/([\d.]+)\s*([KMG]i?B)/i);
21043
- if (m) {
21044
- const val = parseFloat(m[1]);
21045
- const unit = m[2].toUpperCase();
21046
- let mb = val;
21047
- if (unit.startsWith("K"))
21048
- mb = val / 1024;
21049
- else if (unit.startsWith("G"))
21050
- mb = val * 1024;
21051
- statuses[agent].memory = `${Math.round(mb)}MB`;
21052
- } else {
21053
- statuses[agent].memory = first;
21054
- }
21055
- }
21056
- }
21057
- return statuses;
21058
- }
21059
-
21060
23311
  // src/scheduler/dispatch.ts
21061
23312
  import { createHash as createHash4 } from "node:crypto";
21062
23313
  function collectScheduleEntries(config) {
@@ -21139,11 +23390,11 @@ function resolveDigests(imageRefs) {
21139
23390
  return out;
21140
23391
  }
21141
23392
  function readCachedInstallType(bindRoot) {
21142
- const cacheDir = join3(bindRoot, ".switchroom");
21143
- const cachePath = join3(cacheDir, "install-type.json");
21144
- if (existsSync7(cachePath)) {
23393
+ const cacheDir = join5(bindRoot, ".switchroom");
23394
+ const cachePath = join5(cacheDir, "install-type.json");
23395
+ if (existsSync8(cachePath)) {
21145
23396
  try {
21146
- const raw = readFileSync5(cachePath, "utf-8");
23397
+ const raw = readFileSync6(cachePath, "utf-8");
21147
23398
  const parsed = JSON.parse(raw);
21148
23399
  if (parsed && typeof parsed.install_type === "string" && typeof parsed.detected_at === "string") {
21149
23400
  return parsed;
@@ -21163,7 +23414,7 @@ function readCachedInstallType(bindRoot) {
21163
23414
  mkdirSync2(cacheDir, { recursive: true });
21164
23415
  const tmp = `${cachePath}.tmp`;
21165
23416
  writeFileSync3(tmp, JSON.stringify(payload, null, 2), { mode: 420 });
21166
- renameSync(tmp, cachePath);
23417
+ renameSync2(tmp, cachePath);
21167
23418
  } catch {}
21168
23419
  return payload;
21169
23420
  }
@@ -21181,18 +23432,18 @@ function formatConfigApprovalDenyError(approval, approvalId) {
21181
23432
  }
21182
23433
  function writeFileInPlacePreservingInode(targetPath, content) {
21183
23434
  const buf = Buffer.from(content, "utf-8");
21184
- const fd = openSync2(targetPath, "r+");
23435
+ const fd = openSync3(targetPath, "r+");
21185
23436
  try {
21186
23437
  ftruncateSync(fd, 0);
21187
23438
  let off = 0;
21188
23439
  while (off < buf.length) {
21189
- off += writeSync(fd, buf, off, buf.length - off, off);
23440
+ off += writeSync2(fd, buf, off, buf.length - off, off);
21190
23441
  }
21191
- fsyncSync(fd);
23442
+ fsyncSync2(fd);
21192
23443
  } finally {
21193
- closeSync2(fd);
23444
+ closeSync3(fd);
21194
23445
  }
21195
- const readBack = readFileSync5(targetPath);
23446
+ const readBack = readFileSync6(targetPath);
21196
23447
  if (readBack.length !== buf.length) {
21197
23448
  throw new Error(`in-place write short: wrote ${buf.length} bytes but read back ${readBack.length}`);
21198
23449
  }
@@ -21200,6 +23451,7 @@ function writeFileInPlacePreservingInode(targetPath, content) {
21200
23451
  var STATUS_RETENTION_MS = 10 * 60 * 1000;
21201
23452
  var STATUS_MAX_ENTRIES = 256;
21202
23453
  var TAIL_BYTES = 4096;
23454
+ var ORPHAN_RECONCILE_AGE_MS = 15 * 60 * 1000;
21203
23455
 
21204
23456
  class HostdServer {
21205
23457
  opts;
@@ -21213,7 +23465,7 @@ class HostdServer {
21213
23465
  this.opts = opts;
21214
23466
  }
21215
23467
  async start() {
21216
- const hostdDir = join3(this.opts.homeDir, ".switchroom", "hostd");
23468
+ const hostdDir = join5(this.opts.homeDir, ".switchroom", "hostd");
21217
23469
  await mkdir(hostdDir, { recursive: true });
21218
23470
  await chmod(hostdDir, 493).catch(() => {
21219
23471
  return;
@@ -21224,13 +23476,13 @@ class HostdServer {
21224
23476
  }
21225
23477
  try {
21226
23478
  for (const name of agentNames) {
21227
- const dir = join3(hostdDir, name);
21228
- const sockPath = join3(dir, "sock");
23479
+ const dir = join5(hostdDir, name);
23480
+ const sockPath = join5(dir, "sock");
21229
23481
  await mkdir(dir, { recursive: true });
21230
23482
  await chmod(dir, 493).catch(() => {
21231
23483
  return;
21232
23484
  });
21233
- if (existsSync7(sockPath))
23485
+ if (existsSync8(sockPath))
21234
23486
  await unlink(sockPath).catch(() => {
21235
23487
  return;
21236
23488
  });
@@ -21239,8 +23491,8 @@ class HostdServer {
21239
23491
  process.stderr.write(`hostd: server error on ${sockPath}: ${err2.message}
21240
23492
  `);
21241
23493
  });
21242
- await new Promise((resolve6, reject) => {
21243
- server.listen(sockPath, () => resolve6());
23494
+ await new Promise((resolve7, reject) => {
23495
+ server.listen(sockPath, () => resolve7());
21244
23496
  server.once("error", reject);
21245
23497
  });
21246
23498
  await chmod(sockPath, 432).catch(() => {
@@ -21261,13 +23513,13 @@ class HostdServer {
21261
23513
  process.stderr.write(`hostd: SWITCHROOM_HOSTD_OPERATOR_UID='${opUidStr}' is not a positive integer; skipping operator listener
21262
23514
  `);
21263
23515
  } else {
21264
- const dir = join3(hostdDir, "operator");
21265
- const sockPath = join3(dir, "sock");
23516
+ const dir = join5(hostdDir, "operator");
23517
+ const sockPath = join5(dir, "sock");
21266
23518
  await mkdir(dir, { recursive: true });
21267
23519
  await chmod(dir, 493).catch(() => {
21268
23520
  return;
21269
23521
  });
21270
- if (existsSync7(sockPath))
23522
+ if (existsSync8(sockPath))
21271
23523
  await unlink(sockPath).catch(() => {
21272
23524
  return;
21273
23525
  });
@@ -21276,8 +23528,8 @@ class HostdServer {
21276
23528
  process.stderr.write(`hostd: server error on ${sockPath}: ${err2.message}
21277
23529
  `);
21278
23530
  });
21279
- await new Promise((resolve6, reject) => {
21280
- server.listen(sockPath, () => resolve6());
23531
+ await new Promise((resolve7, reject) => {
23532
+ server.listen(sockPath, () => resolve7());
21281
23533
  server.once("error", reject);
21282
23534
  });
21283
23535
  await chmod(sockPath, 384).catch(() => {
@@ -21296,11 +23548,72 @@ class HostdServer {
21296
23548
  await this.stop();
21297
23549
  throw err2;
21298
23550
  }
23551
+ await this.reconcileOrphanedFleetMutations().catch((e) => {
23552
+ process.stderr.write(`hostd: orphan-reconcile sweep failed (non-fatal): ${e.message}
23553
+ `);
23554
+ });
23555
+ }
23556
+ async reconcileOrphanedFleetMutations() {
23557
+ const path2 = this.auditLogPath();
23558
+ if (!existsSync8(path2))
23559
+ return;
23560
+ let raw;
23561
+ try {
23562
+ raw = readFileSync6(path2, "utf-8");
23563
+ } catch {
23564
+ return;
23565
+ }
23566
+ const FLEET_OPS = new Set(["update_apply", "apply", "rollout"]);
23567
+ const startedRows = new Map;
23568
+ for (const line of raw.split(`
23569
+ `)) {
23570
+ const e = parseAuditLine(line);
23571
+ if (!e)
23572
+ continue;
23573
+ if (e.phase === "orphan_reconciled") {
23574
+ startedRows.delete(e.request_id);
23575
+ continue;
23576
+ }
23577
+ if (!FLEET_OPS.has(e.op))
23578
+ continue;
23579
+ if (e.phase === "terminal") {
23580
+ startedRows.delete(e.request_id);
23581
+ continue;
23582
+ }
23583
+ if (e.result === "started" && e.phase === undefined) {
23584
+ const tsMs = Date.parse(e.ts);
23585
+ startedRows.set(e.request_id, {
23586
+ op: e.op,
23587
+ ts: Number.isFinite(tsMs) ? tsMs : Date.now(),
23588
+ caller_name: e.caller.kind === "agent" ? e.caller.name : undefined
23589
+ });
23590
+ }
23591
+ }
23592
+ const now = Date.now();
23593
+ for (const [request_id, info] of startedRows) {
23594
+ if (now - info.ts < ORPHAN_RECONCILE_AGE_MS)
23595
+ continue;
23596
+ const synthOp = info.op === "rollout" ? "rollout_orphaned" : "update_failed";
23597
+ process.stderr.write(`hostd: ORPHANED ${info.op} (request_id=${request_id}, ` + `started ${Math.floor((now - info.ts) / 60000)}m ago, no terminal ` + `row) — emitting ${synthOp}. The fleet may be half-rolled; verify ` + `host-side.
23598
+ `);
23599
+ await this.appendAuditRow({
23600
+ ts: new Date().toISOString(),
23601
+ op: synthOp,
23602
+ phase: "orphan_reconciled",
23603
+ request_id,
23604
+ original_op: info.op,
23605
+ caller: info.caller_name ? { kind: "agent", name: info.caller_name } : { kind: "operator" },
23606
+ result: "error",
23607
+ exit_code: null,
23608
+ duration_ms: now - info.ts,
23609
+ error: `${info.op} left a perpetual 'started' status with no terminal row ` + `(hostd likely SIGKILLed mid-mutation — brick scenario #1). ` + `Reconciled to a failure on hostd boot. The fleet may be ` + `half-rolled; verify versions host-side and re-run if needed.`
23610
+ });
23611
+ }
21299
23612
  }
21300
23613
  async stop() {
21301
23614
  const paths = [...this.servers.keys()];
21302
23615
  for (const [, server] of this.servers) {
21303
- await new Promise((resolve6) => server.close(() => resolve6()));
23616
+ await new Promise((resolve7) => server.close(() => resolve7()));
21304
23617
  }
21305
23618
  this.servers.clear();
21306
23619
  for (const s of paths) {
@@ -21406,6 +23719,9 @@ class HostdServer {
21406
23719
  case "apply":
21407
23720
  resp = this.handleApply(req, caller, started);
21408
23721
  break;
23722
+ case "rollout":
23723
+ resp = this.handleRollout(req, caller, started);
23724
+ break;
21409
23725
  case "agent_start":
21410
23726
  resp = await this.handleAgentStart(req, started);
21411
23727
  break;
@@ -21468,6 +23784,7 @@ class HostdServer {
21468
23784
  return null;
21469
23785
  case "update_apply":
21470
23786
  case "apply":
23787
+ case "rollout":
21471
23788
  return callerAdmin ? null : `${req.op} requires admin: true on caller "${caller.name}"`;
21472
23789
  case "agent_start":
21473
23790
  case "agent_stop":
@@ -21567,12 +23884,12 @@ class HostdServer {
21567
23884
  };
21568
23885
  }
21569
23886
  missingApplyAssets() {
21570
- const root = this.opts.applyAssetsRoot ?? resolve5(import.meta.dirname, "../..");
23887
+ const root = this.opts.applyAssetsRoot ?? resolve6(import.meta.dirname, "../..");
21571
23888
  return [
21572
- join3(root, "profiles"),
21573
- join3(root, "profiles", "default"),
21574
- join3(root, "vendor", "hindsight-memory")
21575
- ].filter((p) => !existsSync7(p));
23889
+ join5(root, "profiles"),
23890
+ join5(root, "profiles", "default"),
23891
+ join5(root, "vendor", "hindsight-memory")
23892
+ ].filter((p) => !existsSync8(p));
21576
23893
  }
21577
23894
  applyAssetPreflight(request_id, started) {
21578
23895
  const missing = this.missingApplyAssets();
@@ -21629,7 +23946,7 @@ class HostdServer {
21629
23946
  request_id: req.request_id,
21630
23947
  started_at: started
21631
23948
  };
21632
- this.spawnFleetMutation(req.op, args, entry);
23949
+ this.spawnFleetMutation(req.op, args, entry, { SWITCHROOM_HOSTD_CONTEXT: "1" });
21633
23950
  return {
21634
23951
  v: 1,
21635
23952
  request_id: req.request_id,
@@ -21672,6 +23989,62 @@ class HostdServer {
21672
23989
  duration_ms: Date.now() - started
21673
23990
  };
21674
23991
  }
23992
+ handleRollout(req, caller, started) {
23993
+ const denied = this.checkFleetMutationLock(req.op, req.request_id, started);
23994
+ if (denied)
23995
+ return denied;
23996
+ const assetDenied = this.applyAssetPreflight(req.request_id, started);
23997
+ if (assetDenied)
23998
+ return assetDenied;
23999
+ const args = ["rollout", "--pin", req.args.pin];
24000
+ if (req.args.agents && req.args.agents.length > 0) {
24001
+ args.push("--agents", req.args.agents.join(","));
24002
+ }
24003
+ if (req.args.skip_web)
24004
+ args.push("--skip-web");
24005
+ if (req.args.allow_downgrade)
24006
+ args.push("--allow-downgrade");
24007
+ const installCtx = readCachedInstallType(this.opts.bindRoot ?? this.opts.homeDir);
24008
+ let priorPin;
24009
+ try {
24010
+ const cfg = loadConfig(this.opts.configPath);
24011
+ const cfgPin = cfg.release?.pin;
24012
+ if (cfgPin && isVersionAssertable(cfgPin)) {
24013
+ priorPin = cfgPin.startsWith("v") ? cfgPin : `v${cfgPin}`;
24014
+ }
24015
+ } catch {}
24016
+ const entry = {
24017
+ request_id: req.request_id,
24018
+ caller,
24019
+ op: req.op,
24020
+ result: "started",
24021
+ exit_code: null,
24022
+ started_at: started,
24023
+ finished_at: null,
24024
+ stdout_tail: "",
24025
+ stderr_tail: "",
24026
+ pin: req.args.pin,
24027
+ install_context: {
24028
+ install_type: installCtx.install_type,
24029
+ detected_at: installCtx.detected_at
24030
+ },
24031
+ ...priorPin ? { prior_pin: priorPin } : {}
24032
+ };
24033
+ this.recordStatus(entry);
24034
+ this.fleetMutationInFlight = {
24035
+ op: "rollout",
24036
+ request_id: req.request_id,
24037
+ started_at: started
24038
+ };
24039
+ this.spawnRollout(args, entry);
24040
+ return {
24041
+ v: 1,
24042
+ request_id: req.request_id,
24043
+ result: "started",
24044
+ exit_code: null,
24045
+ duration_ms: Date.now() - started
24046
+ };
24047
+ }
21675
24048
  async handleAgentStart(req, started) {
21676
24049
  const res = await this.runSwitchroom(["agent", "start", req.args.name]);
21677
24050
  return {
@@ -21753,7 +24126,7 @@ class HostdServer {
21753
24126
  if (caller.kind === "agent" && this.opts.config.agents[caller.name]?.admin !== true) {
21754
24127
  let beforeContent;
21755
24128
  try {
21756
- beforeContent = readFileSync5(configPath, "utf-8");
24129
+ beforeContent = readFileSync6(configPath, "utf-8");
21757
24130
  } catch {
21758
24131
  beforeContent = "";
21759
24132
  }
@@ -21775,6 +24148,34 @@ class HostdServer {
21775
24148
  `);
21776
24149
  return await pending;
21777
24150
  }
24151
+ const rate = this.checkConfigEditRate(callerName, Date.now());
24152
+ if (!rate.ok) {
24153
+ const retryAtIso = new Date(rate.retryAtMs).toISOString();
24154
+ process.stderr.write(`hostd: config_propose_edit — RATE-LIMITED ${callerName} ` + `(>${rate.limit}/hour); next slot ${retryAtIso}
24155
+ `);
24156
+ this.appendAuditRow({
24157
+ ts: new Date().toISOString(),
24158
+ op: "config_propose_edit",
24159
+ phase: "rate_limited",
24160
+ request_id: req.request_id,
24161
+ caller: caller.kind === "agent" ? { kind: "agent", name: caller.name } : { kind: "operator" },
24162
+ result: "denied",
24163
+ exit_code: null,
24164
+ duration_ms: Date.now() - started,
24165
+ error: `E_RATE_LIMITED: >${rate.limit} config_propose_edit cards/hour`
24166
+ });
24167
+ return err("E_RATE_LIMITED", `config_propose_edit rate limit exceeded (max ${rate.limit}/hour for this agent)`).why(`next slot opens at ${retryAtIso}`).fixRetryAfter(retryAtIso).op("config_propose_edit").caller(caller.kind === "agent" ? "agent" : "operator").agentName(caller.kind === "agent" ? caller.name : undefined).asDenied().build(req.request_id, Date.now() - started);
24168
+ }
24169
+ this.appendAuditRow({
24170
+ ts: new Date().toISOString(),
24171
+ op: "config_propose_edit",
24172
+ phase: "requested",
24173
+ request_id: req.request_id,
24174
+ caller: caller.kind === "agent" ? { kind: "agent", name: caller.name } : { kind: "operator" },
24175
+ result: "started",
24176
+ exit_code: null,
24177
+ duration_ms: Date.now() - started
24178
+ });
21778
24179
  const run = this.runConfigProposeApprovalAndApply(req, caller, callerName, configPath, verdict.postApplyContent, started);
21779
24180
  this.inflightConfigProposals.set(dedupeKey, run);
21780
24181
  try {
@@ -21784,6 +24185,22 @@ class HostdServer {
21784
24185
  }
21785
24186
  }
21786
24187
  inflightConfigProposals = new Map;
24188
+ configEditPostTimes = new Map;
24189
+ static DEFAULT_CONFIG_EDIT_RATE_PER_HOUR = 3;
24190
+ checkConfigEditRate(callerName, now) {
24191
+ const limit = this.opts.config.hostd?.config_edit_rate_per_hour ?? HostdServer.DEFAULT_CONFIG_EDIT_RATE_PER_HOUR;
24192
+ const windowMs = 60 * 60 * 1000;
24193
+ const cutoff = now - windowMs;
24194
+ const prior = (this.configEditPostTimes.get(callerName) ?? []).filter((t) => t > cutoff);
24195
+ if (prior.length >= limit) {
24196
+ const retryAtMs = prior[0] + windowMs;
24197
+ this.configEditPostTimes.set(callerName, prior);
24198
+ return { ok: false, limit, retryAtMs };
24199
+ }
24200
+ prior.push(now);
24201
+ this.configEditPostTimes.set(callerName, prior);
24202
+ return { ok: true };
24203
+ }
21787
24204
  async runConfigProposeApprovalAndApply(req, caller, callerName, configPath, postApply, started) {
21788
24205
  const approvalId = (this.opts.generateApprovalId ?? defaultApprovalId)();
21789
24206
  const approval = await this.opts.approvalGateway.requestApproval({
@@ -21813,7 +24230,7 @@ class HostdServer {
21813
24230
  try {
21814
24231
  let snapshot;
21815
24232
  try {
21816
- snapshot = readFileSync5(configPath, "utf-8");
24233
+ snapshot = readFileSync6(configPath, "utf-8");
21817
24234
  } catch (e) {
21818
24235
  await approval.finalize({
21819
24236
  outcome: "reconcile_failed_rolled_back",
@@ -22007,7 +24424,7 @@ class HostdServer {
22007
24424
  const agentsDir = resolveAgentsDir(cfg);
22008
24425
  const recentByAgent = {};
22009
24426
  for (const agent of new Set(entries.map((e) => e.agent))) {
22010
- const rows = readRecentFires(resolve5(agentsDir, agent, "scheduler.jsonl"));
24427
+ const rows = readRecentFires(resolve6(agentsDir, agent, "scheduler.jsonl"));
22011
24428
  if (rows.length > 0)
22012
24429
  recentByAgent[agent] = rows;
22013
24430
  }
@@ -22032,7 +24449,7 @@ class HostdServer {
22032
24449
  }
22033
24450
  }
22034
24451
  runDocker(args) {
22035
- return new Promise((resolve6, reject) => {
24452
+ return new Promise((resolve7, reject) => {
22036
24453
  const bin = this.opts.dockerBin ?? "docker";
22037
24454
  const child = spawn2(bin, args, {
22038
24455
  stdio: ["ignore", "pipe", "pipe"],
@@ -22047,15 +24464,15 @@ class HostdServer {
22047
24464
  stderr += d.toString("utf8");
22048
24465
  });
22049
24466
  child.on("error", (err2) => reject(err2));
22050
- child.on("close", (code) => resolve6({ exit_code: code ?? -1, stdout, stderr }));
24467
+ child.on("close", (code) => resolve7({ exit_code: code ?? -1, stdout, stderr }));
22051
24468
  });
22052
24469
  }
22053
24470
  imageRefsForDigestCapture() {
22054
24471
  if (this.opts.imageRefsForDigests)
22055
24472
  return this.opts.imageRefsForDigests();
22056
24473
  try {
22057
- const composePath = join3(this.opts.bindRoot ?? this.opts.homeDir, ".switchroom", "compose", "docker-compose.yml");
22058
- if (!existsSync7(composePath))
24474
+ const composePath = join5(this.opts.bindRoot ?? this.opts.homeDir, ".switchroom", "compose", "docker-compose.yml");
24475
+ if (!existsSync8(composePath))
22059
24476
  return [];
22060
24477
  const r = spawnSync3("docker", [
22061
24478
  "compose",
@@ -22081,18 +24498,59 @@ class HostdServer {
22081
24498
  const ageMs = Date.now() - inFlight.started_at;
22082
24499
  return deniedResponse(request_id, `${op}: fleet-mutation lock held by ${inFlight.op} ` + `(request_id "${inFlight.request_id}", running ${Math.floor(ageMs / 1000)}s). ` + `Wait for it to complete (poll get_status with target_request_id="${inFlight.request_id}") ` + `before issuing another fleet mutation.`, Date.now() - started);
22083
24500
  }
22084
- spawnFleetMutation(op, args, entry) {
22085
- this.runSwitchroom(args).then((res) => {
24501
+ spawnFleetMutation(op, args, entry, extraEnv) {
24502
+ this.runSwitchroom(args, extraEnv).then((res) => {
22086
24503
  entry.result = res.exit_code === 0 ? "completed" : "error";
22087
24504
  entry.exit_code = res.exit_code;
22088
24505
  entry.finished_at = Date.now();
22089
24506
  entry.stdout_tail = tail(res.stdout);
22090
24507
  entry.stderr_tail = tail(res.stderr);
24508
+ if (op === "update_apply") {
24509
+ const parsed = parseUpdateResultLine(res.stdout);
24510
+ if (parsed && parsed.deferred.length > 0) {
24511
+ entry.deferred = parsed.deferred;
24512
+ }
24513
+ }
24514
+ }).catch((err2) => {
24515
+ entry.result = "error";
24516
+ entry.exit_code = null;
24517
+ entry.finished_at = Date.now();
24518
+ entry.error = err2.message;
24519
+ }).finally(() => {
24520
+ this.writeTerminalAudit(entry);
24521
+ if (this.fleetMutationInFlight && this.fleetMutationInFlight.request_id === entry.request_id) {
24522
+ this.fleetMutationInFlight = null;
24523
+ }
24524
+ });
24525
+ }
24526
+ spawnRollout(args, entry) {
24527
+ this.runSwitchroom(args, { SWITCHROOM_HOSTD_CONTEXT: "1" }).then((res) => {
24528
+ entry.exit_code = res.exit_code;
24529
+ entry.finished_at = Date.now();
24530
+ entry.stdout_tail = tail(res.stdout);
24531
+ entry.stderr_tail = tail(res.stderr);
24532
+ const parsed = parseRolloutResultLine(res.stdout);
24533
+ if (parsed) {
24534
+ entry.rolled = parsed.rolled;
24535
+ if (parsed.failedStep)
24536
+ entry.failed_step = parsed.failedStep;
24537
+ if (parsed.failedAgent)
24538
+ entry.failed_agent = parsed.failedAgent;
24539
+ if (parsed.got !== undefined)
24540
+ entry.got = parsed.got;
24541
+ entry.result = parsed.ok ? "completed" : "error";
24542
+ } else {
24543
+ entry.result = res.exit_code === 0 ? "completed" : "error";
24544
+ }
24545
+ if (entry.result !== "completed") {
24546
+ delete entry.prior_pin;
24547
+ }
22091
24548
  }).catch((err2) => {
22092
24549
  entry.result = "error";
22093
24550
  entry.exit_code = null;
22094
24551
  entry.finished_at = Date.now();
22095
24552
  entry.error = err2.message;
24553
+ delete entry.prior_pin;
22096
24554
  }).finally(() => {
22097
24555
  this.writeTerminalAudit(entry);
22098
24556
  if (this.fleetMutationInFlight && this.fleetMutationInFlight.request_id === entry.request_id) {
@@ -22110,6 +24568,19 @@ class HostdServer {
22110
24568
  return this.statusEntryToResponse(req.request_id, entry);
22111
24569
  }
22112
24570
  statusEntryToResponse(request_id, entry) {
24571
+ const rolloutPayload = entry.op === "rollout" && (entry.rolled !== undefined || entry.failed_step !== undefined || entry.failed_agent !== undefined) ? JSON.stringify({
24572
+ rolled: entry.rolled ?? [],
24573
+ ...entry.failed_step ? { failedStep: entry.failed_step } : {},
24574
+ ...entry.failed_agent ? { failedAgent: entry.failed_agent } : {},
24575
+ ...entry.got !== undefined ? { got: entry.got } : {},
24576
+ ...entry.pin ? { pin: entry.pin } : {}
24577
+ }) : undefined;
24578
+ const updatePayload = entry.op === "update_apply" && (entry.deferred !== undefined || entry.channel !== undefined || entry.pin !== undefined) ? {
24579
+ ...entry.deferred !== undefined ? { deferred: entry.deferred } : {},
24580
+ ...entry.pin !== undefined ? { pin: entry.pin } : {},
24581
+ ...entry.channel !== undefined ? { channel: entry.channel } : {}
24582
+ } : null;
24583
+ const payload = rolloutPayload ?? (updatePayload ? JSON.stringify(updatePayload) : undefined);
22113
24584
  return {
22114
24585
  v: 1,
22115
24586
  request_id,
@@ -22118,6 +24589,7 @@ class HostdServer {
22118
24589
  duration_ms: (entry.finished_at ?? Date.now()) - entry.started_at,
22119
24590
  stdout_tail: entry.stdout_tail || undefined,
22120
24591
  stderr_tail: entry.stderr_tail || undefined,
24592
+ ...payload ? { payload } : {},
22121
24593
  error: entry.error
22122
24594
  };
22123
24595
  }
@@ -22141,12 +24613,12 @@ class HostdServer {
22141
24613
  }
22142
24614
  }
22143
24615
  auditLogPath() {
22144
- return this.opts.auditLogPath ?? join3(this.opts.homeDir, ".switchroom", "host-control-audit.log");
24616
+ return this.opts.auditLogPath ?? join5(this.opts.homeDir, ".switchroom", "host-control-audit.log");
22145
24617
  }
22146
24618
  appendAuditRow(row) {
22147
24619
  const path2 = this.auditLogPath();
22148
24620
  this.auditAppendChain = this.auditAppendChain.then(async () => {
22149
- await mkdir(dirname4(path2), { recursive: true }).catch(() => {
24621
+ await mkdir(dirname6(path2), { recursive: true }).catch(() => {
22150
24622
  return;
22151
24623
  });
22152
24624
  if (this.auditChainState === undefined) {
@@ -22194,15 +24666,21 @@ class HostdServer {
22194
24666
  ...entry.channel ? { channel: entry.channel } : {},
22195
24667
  ...entry.pin ? { pin: entry.pin } : {},
22196
24668
  ...entry.resolved_sha ? { resolved_sha: entry.resolved_sha } : {},
22197
- ...entry.install_context ? { install_context: entry.install_context } : {}
24669
+ ...entry.install_context ? { install_context: entry.install_context } : {},
24670
+ ...entry.rolled ? { rolled: entry.rolled } : {},
24671
+ ...entry.failed_step ? { failed_step: entry.failed_step } : {},
24672
+ ...entry.failed_agent ? { failed_agent: entry.failed_agent } : {},
24673
+ ...entry.got !== undefined ? { got: entry.got } : {},
24674
+ ...entry.deferred ? { deferred: entry.deferred } : {},
24675
+ ...entry.prior_pin ? { prior_pin: entry.prior_pin } : {}
22198
24676
  });
22199
24677
  }
22200
- runSwitchroom(args) {
22201
- return new Promise((resolve6, reject) => {
24678
+ runSwitchroom(args, extraEnv) {
24679
+ return new Promise((resolve7, reject) => {
22202
24680
  const bin = this.opts.switchroomBin ?? "switchroom";
22203
24681
  const child = spawn2(bin, args, {
22204
24682
  stdio: ["ignore", "pipe", "pipe"],
22205
- env: { ...process.env }
24683
+ env: { ...process.env, ...extraEnv ?? {} }
22206
24684
  });
22207
24685
  let stdout = "";
22208
24686
  let stderr = "";
@@ -22213,7 +24691,7 @@ class HostdServer {
22213
24691
  stderr += d.toString("utf8");
22214
24692
  });
22215
24693
  child.on("error", (err2) => reject(err2));
22216
- child.on("close", (code) => resolve6({ exit_code: code ?? -1, stdout, stderr }));
24694
+ child.on("close", (code) => resolve7({ exit_code: code ?? -1, stdout, stderr }));
22217
24695
  });
22218
24696
  }
22219
24697
  }
@@ -22341,7 +24819,7 @@ class SocketApprovalGateway {
22341
24819
  finalize: async () => {}
22342
24820
  };
22343
24821
  }
22344
- return await new Promise((resolve6) => {
24822
+ return await new Promise((resolve7) => {
22345
24823
  const client2 = connect({ path: sockPath });
22346
24824
  let buffer = "";
22347
24825
  let resolved = false;
@@ -22380,7 +24858,7 @@ class SocketApprovalGateway {
22380
24858
  return;
22381
24859
  resolved = true;
22382
24860
  log(`request_config_approval write failed (requestId=${req.requestId}): ${err2.message}`);
22383
- resolve6({
24861
+ resolve7({
22384
24862
  verdict: "deny",
22385
24863
  reason: `request_config_approval write failed: ${err2.message}`,
22386
24864
  denySource: "dispatch_failure",
@@ -22409,7 +24887,7 @@ class SocketApprovalGateway {
22409
24887
  const verdict = obj.verdict;
22410
24888
  const reasonField = typeof obj.reason === "string" ? obj.reason : undefined;
22411
24889
  const denySource = verdict === "deny" ? obj.denySource === "dispatch_failure" ? "dispatch_failure" : "operator" : undefined;
22412
- resolve6({
24890
+ resolve7({
22413
24891
  verdict,
22414
24892
  ...reasonField !== undefined ? { reason: reasonField } : {},
22415
24893
  ...denySource !== undefined ? { denySource } : {},
@@ -22423,7 +24901,7 @@ class SocketApprovalGateway {
22423
24901
  return;
22424
24902
  resolved = true;
22425
24903
  log(`gateway socket error (requestId=${req.requestId}): ${err2.message}`);
22426
- resolve6({
24904
+ resolve7({
22427
24905
  verdict: "deny",
22428
24906
  reason: `gateway socket error: ${err2.message}`,
22429
24907
  denySource: "dispatch_failure",
@@ -22434,7 +24912,7 @@ class SocketApprovalGateway {
22434
24912
  if (resolved)
22435
24913
  return;
22436
24914
  resolved = true;
22437
- resolve6({
24915
+ resolve7({
22438
24916
  verdict: "deny",
22439
24917
  reason: "gateway socket closed before verdict",
22440
24918
  denySource: "dispatch_failure",
@@ -22709,17 +25187,17 @@ async function main() {
22709
25187
  `);
22710
25188
  process.exit(2);
22711
25189
  }
22712
- const agentsDir = process.env.SWITCHROOM_AGENTS_DIR ?? join4(homedir3(), ".switchroom", "agents");
25190
+ const agentsDir = process.env.SWITCHROOM_AGENTS_DIR ?? join6(homedir4(), ".switchroom", "agents");
22713
25191
  const approvalGateway = new SocketApprovalGateway({
22714
25192
  resolveGatewaySocket: (agentName) => {
22715
- const sock = resolve6(agentsDir, agentName, "telegram", "gateway.sock");
22716
- return existsSync8(sock) ? sock : null;
25193
+ const sock = resolve7(agentsDir, agentName, "telegram", "gateway.sock");
25194
+ return existsSync9(sock) ? sock : null;
22717
25195
  },
22718
25196
  log: (m) => process.stderr.write(`hostd: approval-gateway — ${m}
22719
25197
  `)
22720
25198
  });
22721
25199
  const server = new HostdServer({
22722
- homeDir: homedir3(),
25200
+ homeDir: homedir4(),
22723
25201
  agentUids,
22724
25202
  config: {
22725
25203
  agents: Object.fromEntries(Object.entries(config.agents).map(([n, a]) => [
@@ -22741,7 +25219,7 @@ async function main() {
22741
25219
  let releaseWatcher = null;
22742
25220
  const autoRel = config.host_control?.auto_release_check;
22743
25221
  if (autoRel?.enabled === true) {
22744
- const eventsLog = join4(homedir3(), ".switchroom", "release-watcher-events.jsonl");
25222
+ const eventsLog = join6(homedir4(), ".switchroom", "release-watcher-events.jsonl");
22745
25223
  releaseWatcher = new ReleaseWatcher({
22746
25224
  intervalMs: autoRel.interval_minutes * 60000,
22747
25225
  checkFn: makeReleaseCheck({