openmausbot 0.1.91 → 0.1.93

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 (164) hide show
  1. package/dist/assets/DesktopViewer-CKNR3SEW.js +5 -0
  2. package/dist/assets/{abnfDiagram-O67JEVCF-yP-w8pRq.js → abnfDiagram-O67JEVCF-Ckrm1I1X.js} +1 -1
  3. package/dist/assets/{arc-DsivfZEh.js → arc-BBdBuCgB.js} +1 -1
  4. package/dist/assets/{architectureDiagram-NJMV4G6O-CILw7lzT.js → architectureDiagram-NJMV4G6O-CDdA3Hjs.js} +1 -1
  5. package/dist/assets/{blockDiagram-BEXU5L5S-DEQUV3HF.js → blockDiagram-BEXU5L5S-AUrsx1YR.js} +1 -1
  6. package/dist/assets/{c4Diagram-YGBWAQC7-lSXCZoKA.js → c4Diagram-YGBWAQC7-BEqQ0Unh.js} +1 -1
  7. package/dist/assets/channel-BU94VpxE.js +1 -0
  8. package/dist/assets/{chunk-2Q5K7J3B-QCD5bgWP.js → chunk-2Q5K7J3B-CEEuvd4C.js} +1 -1
  9. package/dist/assets/{chunk-3FUC2YCW-C5-iZJuL.js → chunk-3FUC2YCW-DyANCiHl.js} +2 -2
  10. package/dist/assets/{chunk-5VM5RSS4-cxsawMpY.js → chunk-5VM5RSS4-Dx_Slpw9.js} +1 -1
  11. package/dist/assets/{chunk-GTNCS2PH-DV8tV8H7.js → chunk-GTNCS2PH-Dl7h7iiD.js} +1 -1
  12. package/dist/assets/{chunk-GWA4HPMP-CJFZyfbW.js → chunk-GWA4HPMP-BLx07SPb.js} +1 -1
  13. package/dist/assets/{chunk-JWPE2WC7-BigbMXco.js → chunk-JWPE2WC7-BMxDj3n7.js} +1 -1
  14. package/dist/assets/{chunk-NETBCI7D-oVxTfpDy.js → chunk-NETBCI7D-CN66PT4H.js} +1 -1
  15. package/dist/assets/{chunk-WEXAMYUT-CH4BiroW.js → chunk-WEXAMYUT-6HwhsDKw.js} +1 -1
  16. package/dist/assets/{chunk-XXDRQBXY-KEDa6gax.js → chunk-XXDRQBXY-gWnLt7SN.js} +1 -1
  17. package/dist/assets/{classDiagram-v2-NBCMYWYE-BiPjfqVv.js → classDiagram-v2-NBCMYWYE-CMS5l2ea.js} +1 -1
  18. package/dist/assets/{cose-bilkent-JH36ORCC-Caxew3OY.js → cose-bilkent-JH36ORCC-CV7sQwIG.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-B_Pui369.js → cynefin-OW5HDTMX-CSyl-7vl.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-VND7K2PF-X64ydIhP.js → cynefinDiagram-VND7K2PF-BCLKL6az.js} +1 -1
  21. package/dist/assets/{dagre-6A5THRUB-TqYCI1E1.js → dagre-6A5THRUB-DiaZs6S1.js} +1 -1
  22. package/dist/assets/{diagram-22UHCM2B-TeOt3rAQ.js → diagram-22UHCM2B-BeTtmt3I.js} +1 -1
  23. package/dist/assets/{diagram-3UASUU5V-D70BLhDA.js → diagram-3UASUU5V-CsdBG-QQ.js} +1 -1
  24. package/dist/assets/{diagram-ATOU4E4O-BbQDLwUC.js → diagram-ATOU4E4O-BczvdbR1.js} +1 -1
  25. package/dist/assets/{diagram-CDSNMT55-ChNJZ1u-.js → diagram-CDSNMT55-DHTTTMhi.js} +1 -1
  26. package/dist/assets/{diagram-MLGK6HIB-DMBl2APa.js → diagram-MLGK6HIB-RTjHyd8z.js} +1 -1
  27. package/dist/assets/{diagram-MPIPVDR6-CEqDchOp.js → diagram-MPIPVDR6-BDenHEH_.js} +1 -1
  28. package/dist/assets/{ebnfDiagram-ZINNZB2B-BVDKRp_-.js → ebnfDiagram-ZINNZB2B-BSiRSbtL.js} +1 -1
  29. package/dist/assets/{elk-276RUBZZ-CRkofO9B.js → elk-276RUBZZ-BCAElss-.js} +1 -1
  30. package/dist/assets/{erDiagram-OPXOYQCR-DruOMh5e.js → erDiagram-OPXOYQCR-C4_1ZPJe.js} +1 -1
  31. package/dist/assets/{flowDiagram-KWPJA3E3-8GMQeB7t.js → flowDiagram-KWPJA3E3-Bcb4Z75S.js} +1 -1
  32. package/dist/assets/{ganttDiagram-FUAMR5RP-ORE9jcsM.js → ganttDiagram-FUAMR5RP-BiPOzxzb.js} +1 -1
  33. package/dist/assets/{gitGraphDiagram-X574FWY7-BmsedsWh.js → gitGraphDiagram-X574FWY7-B1wtF3ZS.js} +1 -1
  34. package/dist/assets/index-Biji-bfL.css +1 -0
  35. package/dist/assets/{index-DKNEM8Q6.js → index-BkYwilkG.js} +1 -1
  36. package/dist/assets/index-DZlhoES0.js +597 -0
  37. package/dist/assets/{infoDiagram-VRGFBTTK-E_p7AooJ.js → infoDiagram-VRGFBTTK-A19No71U.js} +1 -1
  38. package/dist/assets/{ishikawaDiagram-OU5B5YK6-Y-B2mKda.js → ishikawaDiagram-OU5B5YK6-BQsqJ_cV.js} +1 -1
  39. package/dist/assets/{journeyDiagram-ZHPQQLJL-eA8RELcK.js → journeyDiagram-ZHPQQLJL-DAO0pVan.js} +1 -1
  40. package/dist/assets/{kanban-definition-PNTS6WVX-DqIL2e8e.js → kanban-definition-PNTS6WVX-NepmKEe2.js} +1 -1
  41. package/dist/assets/{linear-yC_29R6e.js → linear-bq1PTDTW.js} +1 -1
  42. package/dist/assets/{mermaid.core-VhEMkSND.js → mermaid.core-s4LTbQle.js} +5 -5
  43. package/dist/assets/{mindmap-definition-NLK3R4M7-oJ7kyQZy.js → mindmap-definition-NLK3R4M7-LtdbgHFH.js} +1 -1
  44. package/dist/assets/{pegDiagram-GJSIUBJH-BmfYcY0O.js → pegDiagram-GJSIUBJH-tdbaCxiK.js} +1 -1
  45. package/dist/assets/{pieDiagram-5QR66LMP-DKvgP7w9.js → pieDiagram-5QR66LMP-DvkbpW8l.js} +1 -1
  46. package/dist/assets/{quadrantDiagram-O4NWA36T-BEKL3W0L.js → quadrantDiagram-O4NWA36T-Do4KaH-E.js} +1 -1
  47. package/dist/assets/{railroadDiagram-XR7U4H2S-BEsiqR5s.js → railroadDiagram-XR7U4H2S-BQWULOAs.js} +1 -1
  48. package/dist/assets/{requirementDiagram-PLB6GJNP-DWBcWvAP.js → requirementDiagram-PLB6GJNP-w9kei1FU.js} +1 -1
  49. package/dist/assets/{sankeyDiagram-IPEJSGJF-rpZ2_O4s.js → sankeyDiagram-IPEJSGJF-D2gRy0e8.js} +1 -1
  50. package/dist/assets/{sequenceDiagram-PO4LG4MO-B99HQdJR.js → sequenceDiagram-PO4LG4MO-a2sO5_Eo.js} +1 -1
  51. package/dist/assets/{sizeCapture-INFHLROL-BjN0qT5T.js → sizeCapture-INFHLROL-CiPJmFEB.js} +1 -1
  52. package/dist/assets/{stateDiagram-v2-GCMORJYK-BbsVgGsC.js → stateDiagram-v2-GCMORJYK-DAkUUlL7.js} +1 -1
  53. package/dist/assets/{swimlanes-2SLR337P-DG3gKkeR.js → swimlanes-2SLR337P-DANf2R8Y.js} +1 -1
  54. package/dist/assets/swimlanesDiagram-TC7HE7FX-CdHxG8aM.js +8 -0
  55. package/dist/assets/{timeline-definition-EJHVYXUP-BTHOdtF_.js → timeline-definition-EJHVYXUP-BKpQmzrT.js} +1 -1
  56. package/dist/assets/{usecaseDiagram-POWQR4AR-acLSLFwc.js → usecaseDiagram-POWQR4AR-BtI7qLN-.js} +1 -1
  57. package/dist/assets/{vennDiagram-UO4OBE2U-C5JzNX9G.js → vennDiagram-UO4OBE2U-gXJXrAG_.js} +1 -1
  58. package/dist/assets/{wardleyDiagram-VNRHLVJA-DL1-PrR_.js → wardleyDiagram-VNRHLVJA-GU8Po5-n.js} +1 -1
  59. package/dist/assets/{xychartDiagram-PMCCYNJV-Bvr1477p.js → xychartDiagram-PMCCYNJV-BF4J30g6.js} +1 -1
  60. package/dist/index.html +2 -2
  61. package/dist/novnc-NOTICE.txt +118 -0
  62. package/dist-server/cloud-home-start.js +112 -14
  63. package/dist-server/companion/src/routes.js +24 -1
  64. package/dist-server/container-mcp.js +201 -16
  65. package/dist-server/drivers/agents-proxy.js +7 -4
  66. package/dist-server/enterprise/server/index.js +5 -1
  67. package/dist-server/index.js +10698 -4737
  68. package/dist-server/local-computer-proxy.js +133 -8
  69. package/dist-server/mcp-gate.js +16 -6
  70. package/dist-server/model-catalog/models-dev.snapshot.json +7299 -0
  71. package/dist-server/openmausbot.js +4656 -1258
  72. package/dist-server/pair-cli.js +4656 -1258
  73. package/dist-server/server/boat.js +5 -5
  74. package/dist-server/server/browser-engine.js +10 -1
  75. package/dist-server/server/browser-live.js +46 -2
  76. package/dist-server/server/browser-runtime.js +74 -8
  77. package/dist-server/server/browser-tool-shape.js +6 -4
  78. package/dist-server/server/chief-of-staff.js +1 -1
  79. package/dist-server/server/cloud-home-start.js +118 -26
  80. package/dist-server/server/cloud-home.js +39 -3
  81. package/dist-server/server/cloud-lending.js +74 -10
  82. package/dist-server/server/cloud-owner.js +196 -0
  83. package/dist-server/server/cloud-secrets-boot.js +6 -0
  84. package/dist-server/server/cloud-secrets.js +65 -0
  85. package/dist-server/server/computer-control.js +6 -0
  86. package/dist-server/server/config.js +187 -14
  87. package/dist-server/server/container-computer.js +46 -34
  88. package/dist-server/server/desktop-viewer-targets.js +26 -0
  89. package/dist-server/server/digest.js +12 -2
  90. package/dist-server/server/drivers/acp/core.js +339 -33
  91. package/dist-server/server/drivers/acp/cursor.js +13 -1
  92. package/dist-server/server/drivers/acp/opencode-go.js +614 -85
  93. package/dist-server/server/drivers/acp/quiet-status.js +257 -0
  94. package/dist-server/server/drivers/acp/qwen.js +18 -0
  95. package/dist-server/server/drivers/agents-catalog.js +6 -6
  96. package/dist-server/server/drivers/antigravity-acp.js +69 -11
  97. package/dist-server/server/drivers/antigravity-temp.js +360 -0
  98. package/dist-server/server/drivers/antigravity.js +21 -0
  99. package/dist-server/server/drivers/builtIn.js +2 -0
  100. package/dist-server/server/drivers/cerebras.js +108 -0
  101. package/dist-server/server/drivers/chat-mcp-tools.js +20 -3
  102. package/dist-server/server/drivers/chatgpt-plan-auth.js +481 -0
  103. package/dist-server/server/drivers/claude.js +329 -37
  104. package/dist-server/server/drivers/codex.js +228 -18
  105. package/dist-server/server/drivers/grok.js +2 -2
  106. package/dist-server/server/drivers/mistral.js +4 -3
  107. package/dist-server/server/drivers/openai-chat-protocol.js +4 -3
  108. package/dist-server/server/drivers/openai-chat.js +66 -4
  109. package/dist-server/server/drivers/openai-compat.js +73 -23
  110. package/dist-server/server/drivers/prompt-split.js +2 -0
  111. package/dist-server/server/engine-install.js +46 -12
  112. package/dist-server/server/env-path.js +21 -5
  113. package/dist-server/server/harness/registry.js +2 -2
  114. package/dist-server/server/index.js +1545 -238
  115. package/dist-server/server/lending-memory.js +479 -0
  116. package/dist-server/server/local-vm-idle.js +24 -6
  117. package/dist-server/server/local-vm-stop-reason.js +26 -0
  118. package/dist-server/server/managed-desktop.js +3 -0
  119. package/dist-server/server/mcp-bridge.js +5 -3
  120. package/dist-server/server/mcp-http.js +6 -3
  121. package/dist-server/server/mcp-oauth-discovery.js +133 -0
  122. package/dist-server/server/mcp-oauth-store.js +70 -0
  123. package/dist-server/server/mcp-oauth.js +550 -0
  124. package/dist-server/server/mcp-probe.js +14 -1
  125. package/dist-server/server/mcp-registry.js +43 -0
  126. package/dist-server/server/memory-upkeep.js +94 -84
  127. package/dist-server/server/model-catalog/catalog.js +374 -0
  128. package/dist-server/server/model-catalog/presets.js +176 -0
  129. package/dist-server/server/model-catalog/trim.js +219 -0
  130. package/dist-server/server/provider-key-check.js +5 -2
  131. package/dist-server/server/recent-work.js +1 -1
  132. package/dist-server/server/request-auth.js +23 -0
  133. package/dist-server/server/routes/antigravity-leftovers.js +45 -0
  134. package/dist-server/server/routes/bot-memory.js +31 -6
  135. package/dist-server/server/routes/desktop-viewer.js +238 -0
  136. package/dist-server/server/routine-requests.js +1 -1
  137. package/dist-server/server/routines.js +6 -3
  138. package/dist-server/server/sessions.js +56 -9
  139. package/dist-server/server/skills.js +25 -10
  140. package/dist-server/server/store.js +116 -122
  141. package/dist-server/server/thread-events.js +2 -0
  142. package/dist-server/server/thread-starters.js +33 -0
  143. package/dist-server/server/thread-title.js +46 -0
  144. package/dist-server/server/tts/fish.js +4 -5
  145. package/dist-server/server/tts/index.js +5 -3
  146. package/dist-server/server/vps-computer.js +80 -13
  147. package/dist-server/server/webhooks.js +18 -1
  148. package/dist-server/server/workspace-backup-policy.js +3 -0
  149. package/dist-server/server/workspace-backup.js +25 -0
  150. package/dist-server/server/workspace.js +66 -16
  151. package/dist-server/shared/approval-mode.js +1 -1
  152. package/dist-server/shared/redact.js +1 -0
  153. package/dist-server/shared/tool-name.js +22 -0
  154. package/dist-server/shared/workspace-backup-client.js +1 -0
  155. package/dist-server/src/lib/citations.js +177 -0
  156. package/dist-server/src/lib/composer-attachments.js +7 -1
  157. package/dist-server/vps-container-mcp.js +202 -16
  158. package/dist-server/workspace-backup.worker.js +87 -9
  159. package/enterprise/server/index.js +5 -1
  160. package/package.json +1 -1
  161. package/dist/assets/channel-DrfGMu7X.js +0 -1
  162. package/dist/assets/index-BlnCEcU6.js +0 -588
  163. package/dist/assets/index-DVxjOvID.css +0 -1
  164. package/dist/assets/swimlanesDiagram-TC7HE7FX-BCZhxl7e.js +0 -8
@@ -22,6 +22,9 @@ function nvmBinDirs() {
22
22
  return [];
23
23
  }
24
24
  }
25
+ function sealedFixture() {
26
+ return process.env.OMB_TEST_SEALED_PATH === "1";
27
+ }
25
28
  function knownDirs() {
26
29
  const home = homedir();
27
30
  return [
@@ -37,10 +40,13 @@ function knownDirs() {
37
40
  // opencode installer
38
41
  join(home, ".claude", "local"),
39
42
  // claude "local install"
40
- "/opt/homebrew/bin",
41
- // brew, Apple silicon
42
- "/usr/local/bin",
43
- // brew Intel / classic installs
43
+ // Machine-wide rather than under the (possibly temporary) home.
44
+ ...sealedFixture() ? [] : [
45
+ "/opt/homebrew/bin",
46
+ // brew, Apple silicon
47
+ "/usr/local/bin"
48
+ // brew Intel / classic installs
49
+ ],
44
50
  join(home, ".volta", "bin"),
45
51
  join(home, ".bun", "bin"),
46
52
  join(home, ".asdf", "shims"),
@@ -62,6 +68,8 @@ function windowsKnownDirs() {
62
68
  // x.ai installer
63
69
  join(localAppData, "agy", "bin"),
64
70
  // Antigravity installer
71
+ // Cursor installer: cursor-agent.* and its `agent` copies (MOCA-272)
72
+ join(localAppData, "cursor-agent"),
65
73
  join(home, ".local", "bin"),
66
74
  // claude native installer
67
75
  join(home, ".claude", "local"),
@@ -69,7 +77,9 @@ function windowsKnownDirs() {
69
77
  // Factory droid installer (%USERPROFILE%\bin)
70
78
  join(home, ".bun", "bin"),
71
79
  join(home, ".deno", "bin"),
72
- join(home, "go", "bin")
80
+ join(home, "go", "bin"),
81
+ join(process.env.ProgramFiles ?? "C:\\Program Files", "Docker", "Docker", "resources", "bin")
82
+ // Docker Desktop installer
73
83
  ];
74
84
  }
75
85
  var cached = null;
@@ -92,7 +102,7 @@ function augmentedPath() {
92
102
  ...(process.platform === "win32" ? windowsKnownDirs() : knownDirs()).filter((d) => existsSync(d))
93
103
  ]);
94
104
  }
95
- if (!probed && !process.env.VITEST && process.platform !== "win32") {
105
+ if (!probed && !process.env.VITEST && !sealedFixture() && process.platform !== "win32") {
96
106
  probed = true;
97
107
  probeLoginShellPath();
98
108
  }
@@ -116,6 +126,119 @@ function probeLoginShellPath() {
116
126
  }
117
127
  );
118
128
  }
129
+ function splitCliString(cli) {
130
+ const out = [];
131
+ let cur = "";
132
+ let quote = null;
133
+ for (const ch of cli.trim()) {
134
+ if (quote) {
135
+ if (ch === quote) quote = null;
136
+ else cur += ch;
137
+ } else if (ch === '"' || ch === "'") {
138
+ quote = ch;
139
+ } else if (/\s/.test(ch)) {
140
+ if (cur) out.push(cur);
141
+ cur = "";
142
+ } else {
143
+ cur += ch;
144
+ }
145
+ }
146
+ if (cur) out.push(cur);
147
+ return out;
148
+ }
149
+ function isFile(p2) {
150
+ try {
151
+ return statSync(p2, { throwIfNoEntry: false })?.isFile() ?? false;
152
+ } catch {
153
+ return false;
154
+ }
155
+ }
156
+ function whichWin(cli, env) {
157
+ const exts = ((env ?? process.env).PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean);
158
+ const probe = (base) => {
159
+ const order = extname(base) ? [base, ...exts.map((e) => base + e)] : [...exts.map((e) => base + e), base];
160
+ return order.find(isFile) ?? null;
161
+ };
162
+ if (/[\\/]/.test(cli) || /^[a-zA-Z]:/.test(cli)) return probe(cli);
163
+ const path = env ? env.PATH ?? env.Path ?? "" : augmentedPath();
164
+ for (const dir of path.split(delimiter)) {
165
+ if (!dir) continue;
166
+ const hit = probe(join(dir, cli));
167
+ if (hit) return hit;
168
+ }
169
+ return null;
170
+ }
171
+ function nodeExe(near, env) {
172
+ const local = join(near, "node.exe");
173
+ if (isFile(local)) return local;
174
+ const onPath = whichWin("node.exe", env);
175
+ if (onPath && extname(onPath).toLowerCase() === ".exe") return onPath;
176
+ return process.versions.electron ? null : process.execPath;
177
+ }
178
+ function parseCmdShim(shim, env) {
179
+ let text;
180
+ try {
181
+ text = readFileSync(shim, "utf8");
182
+ } catch {
183
+ return null;
184
+ }
185
+ const dir = dirname(shim);
186
+ const npmEntry = /^SET "NP[MX]_CLI_JS=%~dp0\\([^"]+)"/im.exec(text);
187
+ const targets = [...npmEntry ? [npmEntry] : [], ...text.matchAll(/"%~?dp0%?\\?([^"]+)"/g)].map((m2) => join(dir, m2[1])).filter((p2) => isFile(p2) && basename(p2).toLowerCase() !== "node.exe");
188
+ const script = targets.find((p2) => /\.[cm]?js$/i.test(p2));
189
+ if (script) {
190
+ const node = nodeExe(dir, env);
191
+ if (node) return { command: node, args: [script] };
192
+ }
193
+ const exe = targets.find((p2) => extname(p2).toLowerCase() === ".exe");
194
+ return exe ? { command: exe, args: [] } : null;
195
+ }
196
+ function parseNodeShebang(file2, env) {
197
+ let head = "";
198
+ let fd = null;
199
+ try {
200
+ fd = openSync(file2, "r");
201
+ const buf = Buffer.alloc(128);
202
+ const n = readSync(fd, buf, 0, buf.length, 0);
203
+ head = buf.subarray(0, n).toString("utf8").split("\n", 1)[0];
204
+ } catch {
205
+ return null;
206
+ } finally {
207
+ if (fd !== null) {
208
+ try {
209
+ closeSync(fd);
210
+ } catch {
211
+ }
212
+ }
213
+ }
214
+ if (!/^#!.*\bnode(\.exe)?\b/.test(head)) return null;
215
+ const node = nodeExe(dirname(file2), env);
216
+ return node ? { command: node, args: [file2] } : null;
217
+ }
218
+ function resolveWord(cli, args, env) {
219
+ if (process.platform !== "win32") return { command: cli, args };
220
+ const file2 = whichWin(cli, env);
221
+ if (!file2) return { command: cli, args };
222
+ const ext = extname(file2).toLowerCase();
223
+ if (ext === ".cmd" || ext === ".bat") {
224
+ const direct = parseCmdShim(file2, env);
225
+ return direct ? { command: direct.command, args: [...direct.args, ...args] } : { command: file2, args };
226
+ }
227
+ if (ext === ".exe" || ext === ".com") return { command: file2, args };
228
+ const viaNode = parseNodeShebang(file2, env);
229
+ return viaNode ? { command: viaNode.command, args: [...viaNode.args, ...args] } : { command: file2, args };
230
+ }
231
+ function resolveCliSpawn(cli, args, env) {
232
+ const trimmed = cli.trim();
233
+ if (trimmed.includes(" ") && existsSync(trimmed)) return resolveWord(trimmed, args, env);
234
+ const split = splitCliString(cli);
235
+ if (split.length > 1 || split[0] !== trimmed) {
236
+ const [head, ...fixed] = split;
237
+ if (!head) return { command: cli, args };
238
+ return resolveWord(head, [...fixed, ...args], env);
239
+ }
240
+ return resolveWord(cli, args, env);
241
+ }
119
242
 
120
243
  // server/config.ts
121
244
  import { homedir as homedir2 } from "node:os";
@@ -15624,15 +15747,27 @@ var stdioEntrySchema = external_exports.object({
15624
15747
  var stdioMutationSchema = stdioEntrySchema.extend({
15625
15748
  env: external_exports.record(external_exports.string(), external_exports.union([external_exports.string().max(16384), external_exports.literal(true)])).optional()
15626
15749
  });
15750
+ var CLIENT_ID = /^[\x20-\x7e]+$/;
15751
+ var SCOPE = /^[\x21\x23-\x5b\x5d-\x7e]+$/;
15752
+ var CLIENT_SECRET_MAX = 4096;
15753
+ var oauthClientSchema = external_exports.object({
15754
+ clientId: external_exports.string().trim().min(1, "Enter the client ID of the app registered with this server's sign-in provider.").max(512).regex(CLIENT_ID, "A client ID is printable text on one line."),
15755
+ clientSecret: external_exports.string().min(1).max(CLIENT_SECRET_MAX).regex(CLIENT_ID, "A client secret is printable text on one line.").optional(),
15756
+ scopes: external_exports.array(external_exports.string().max(256).regex(SCOPE, "Scopes are single words, like offline_access or api://my-app/mcp.read.")).max(32).optional()
15757
+ }).strict();
15627
15758
  var remoteEntrySchema = external_exports.object({
15628
15759
  /** Streamable HTTP unless the entry says the older SSE transport. */
15629
15760
  type: external_exports.enum(["http", "sse"]).optional(),
15630
15761
  url: external_exports.string().trim().min(1).max(2048),
15631
15762
  headers: external_exports.record(external_exports.string(), external_exports.string().max(16384)).optional(),
15763
+ oauth: oauthClientSchema.optional(),
15632
15764
  enabled: external_exports.boolean().optional()
15633
15765
  }).strict();
15634
15766
  var remoteMutationSchema = remoteEntrySchema.extend({
15635
- headers: external_exports.record(external_exports.string(), external_exports.union([external_exports.string().max(16384), external_exports.literal(true)])).optional()
15767
+ headers: external_exports.record(external_exports.string(), external_exports.union([external_exports.string().max(16384), external_exports.literal(true)])).optional(),
15768
+ oauth: oauthClientSchema.extend({
15769
+ clientSecret: external_exports.union([external_exports.string().min(1).max(CLIENT_SECRET_MAX).regex(CLIENT_ID, "A client secret is printable text on one line."), external_exports.literal(true)]).optional()
15770
+ }).optional()
15636
15771
  });
15637
15772
 
15638
15773
  // server/cloud-overflow.ts
@@ -15698,7 +15833,11 @@ var sessionSchema = external_exports.object({
15698
15833
  userId: external_exports.string().max(256).optional(),
15699
15834
  email: external_exports.string().max(320).optional(),
15700
15835
  /** Set only by the internal verified-portal issuance path, never by email or pairing input. */
15701
- membershipAuthority: external_exports.literal("portal").optional()
15836
+ membershipAuthority: external_exports.literal("portal").optional(),
15837
+ /** A browser sign-in (PairingCode `browser`): accepted only as its browser's cookie, never as a bearer token. */
15838
+ cookieOnly: external_exports.literal(true).optional(),
15839
+ /** Whose OMB Cloud a browser sign-in signed in to (its PairingCode `owner`). */
15840
+ owner: external_exports.string().max(254).optional()
15702
15841
  });
15703
15842
  var fileSchema = external_exports.object({ version: external_exports.literal(1), sessions: external_exports.array(sessionSchema) });
15704
15843
 
@@ -15710,6 +15849,7 @@ var optionalText = external_exports.string().optional();
15710
15849
  var SSH_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
15711
15850
  var LEGACY_BROWSER_PROFILE_ID = /^[A-Za-z0-9_-]{1,40}$/;
15712
15851
  var BROWSER_PROFILE_ID = /^[a-z0-9_-]{1,40}$/;
15852
+ var FISH_TTS_MODELS = ["s2.1-pro", "s2.1-pro-free"];
15713
15853
  var MIN_ROOM_TURN_TIMEOUT_MINUTES = 1;
15714
15854
  var MAX_ROOM_TURN_TIMEOUT_MINUTES = 1440;
15715
15855
  var DEFAULT_ROOM_HANDOFF_LIFETIME_MINUTES = 30;
@@ -15720,6 +15860,8 @@ var MIN_THREAD_EVENT_LOG_BYTES = 256 * 1024;
15720
15860
  var MAX_THREAD_EVENT_LOG_BYTES = 4 * 1024 * 1024 * 1024;
15721
15861
  var MIN_LOCAL_VM_MAX_INSTANCES = 1;
15722
15862
  var MAX_LOCAL_VM_MAX_INSTANCES = 8;
15863
+ var MIN_LOCAL_VM_IDLE_TIMEOUT_MINUTES = 5;
15864
+ var MAX_LOCAL_VM_IDLE_TIMEOUT_MINUTES = 1440;
15723
15865
  function isValidSshAlias(value) {
15724
15866
  return typeof value === "string" && SSH_ALIAS.test(value);
15725
15867
  }
@@ -15757,7 +15899,8 @@ var roomConfigSchema = external_exports.object({
15757
15899
  );
15758
15900
  var localVmConfigSchema = external_exports.object({
15759
15901
  mode: external_exports.enum(["shared", "per-bot", "pool"]).optional(),
15760
- maxInstances: external_exports.number().int().min(MIN_LOCAL_VM_MAX_INSTANCES).max(MAX_LOCAL_VM_MAX_INSTANCES).optional()
15902
+ maxInstances: external_exports.number().int().min(MIN_LOCAL_VM_MAX_INSTANCES).max(MAX_LOCAL_VM_MAX_INSTANCES).optional(),
15903
+ idleTimeoutMinutes: external_exports.number().int().min(MIN_LOCAL_VM_IDLE_TIMEOUT_MINUTES).max(MAX_LOCAL_VM_IDLE_TIMEOUT_MINUTES).optional()
15761
15904
  });
15762
15905
  var browserProfileSchema = external_exports.object({
15763
15906
  // "guest" is the throwaway session's reserved id, never a saved profile
@@ -15916,7 +16059,11 @@ var onboardingConfigSchema = external_exports.object({
15916
16059
  /** Which welcome flow was completed; a newer flow may re-show itself. */
15917
16060
  version: external_exports.number().int().min(0).max(1e3).optional(),
15918
16061
  reelSeen: external_exports.boolean().optional(),
15919
- hintsSeen: external_exports.array(external_exports.string().trim().min(1).max(60)).max(100).optional()
16062
+ hintsSeen: external_exports.array(external_exports.string().trim().min(1).max(60)).max(100).optional(),
16063
+ /** OMB Cloud home only: when a bot's turn first finished on this machine
16064
+ * (cloud-home.ts firstCloudTurnPatch). Written by the server, read by the
16065
+ * Cloud's setup checklist. */
16066
+ firstTurnAt: external_exports.string().trim().max(40).optional()
15920
16067
  }).strict();
15921
16068
  var instanceConfigSchema = external_exports.object({
15922
16069
  driver: external_exports.string().min(1),
@@ -15928,6 +16075,7 @@ var instanceConfigSchema = external_exports.object({
15928
16075
  ]).optional(),
15929
16076
  environment: external_exports.record(external_exports.string(), external_exports.string()).optional(),
15930
16077
  enabled: external_exports.boolean().optional(),
16078
+ access: external_exports.enum(["subscription", "custom", "api"]).optional(),
15931
16079
  config: external_exports.json().optional()
15932
16080
  });
15933
16081
  var instanceConfigMapSchema = external_exports.record(external_exports.string(), instanceConfigSchema);
@@ -15985,11 +16133,17 @@ var appConfigSchema = external_exports.object({
15985
16133
  phone: external_exports.enum(["ios", "android"]).optional()
15986
16134
  }).optional(),
15987
16135
  mistral: external_exports.object({ key: optionalText }).optional(),
16136
+ cerebras: external_exports.object({ key: optionalText }).optional(),
15988
16137
  xai: external_exports.object({ key: optionalText, url: optionalText }).optional(),
15989
16138
  /** Anthropic API key for Claude Code billed per token, handed only to
15990
16139
  * Claude instances; `url` only for a proxy or a test double. Never a
15991
16140
  * personal-login OAuth token. */
15992
- anthropic: external_exports.object({ key: optionalText, url: optionalText }).optional(),
16141
+ anthropic: external_exports.object({ key: optionalText, url: optionalText, everyClaudeBot: external_exports.boolean().optional() }).optional(),
16142
+ /** OpenAI's own API key, for the `openai` instance only. Codex keeps its
16143
+ * own ChatGPT or API login and never reads this. */
16144
+ openai: external_exports.object({ key: optionalText }).optional(),
16145
+ /** OpenRouter key, for the `openrouter` instance only. */
16146
+ openrouter: external_exports.object({ key: optionalText }).optional(),
15993
16147
  /** Monthly spend limit for the whole workspace, against the cost engines
15994
16148
  * report to the usage ledger. Enforced only with the `budgets` entitlement. */
15995
16149
  budgets: external_exports.object({
@@ -16023,8 +16177,8 @@ var appConfigSchema = external_exports.object({
16023
16177
  opencodeGo: external_exports.object({ apiKey: optionalText }).optional(),
16024
16178
  /** Voice settings and the selected voice id. `provider` picks the
16025
16179
  * engine: "elevenlabs" (default; needs `key`), "fish" (needs its own
16026
- * `fishKey`), "system" (the Mac's built-in voices, no key), or
16027
- * "xai" (Grok TTS, reusing `xai.key`), or
16180
+ * `fishKey`; `fishModel` picks its speech model), "system" (the Mac's
16181
+ * built-in voices, no key), "xai" (Grok TTS, reusing `xai.key`), or
16028
16182
  * "chatterbox" (a local OpenAI-compatible Chatterbox server; `baseUrl`
16029
16183
  * and `model` are settings, not secrets). Cloud keys stay separate so
16030
16184
  * switching providers never overwrites or misuses the other key. */
@@ -16034,7 +16188,8 @@ var appConfigSchema = external_exports.object({
16034
16188
  voice: optionalText,
16035
16189
  provider: external_exports.enum(["elevenlabs", "fish", "system", "chatterbox", "xai"]).optional(),
16036
16190
  baseUrl: external_exports.string().trim().max(2048).refine((value) => !value || /^https?:\/\//i.test(value), "the Chatterbox server address must start with http:// or https://").optional(),
16037
- model: optionalText
16191
+ model: optionalText,
16192
+ fishModel: external_exports.enum(FISH_TTS_MODELS).optional()
16038
16193
  }).optional(),
16039
16194
  /** The decision model (server/decider): a fast classifier that picks
16040
16195
  * things for bots, starting with who answers a room message. `key` is
@@ -16122,6 +16277,34 @@ var DATA_DIR = process.env.OMB_DATA_DIR ?? join3(homedir2(), ".openmausbot");
16122
16277
  var LEGACY_DATA_DIR = join3(homedir2(), ".opengrokbot");
16123
16278
  var EVENTS_DIR = join3(DATA_DIR, "events");
16124
16279
  var NATIVE_DIR = join3(DATA_DIR, "native");
16280
+ var OPENAI_API_INSTANCE = "openai";
16281
+ var OPENROUTER_API_INSTANCE = "openrouter";
16282
+ var XAI_API_INSTANCE = "xaiApi";
16283
+ var CLAUDE_API_INSTANCE = "claudeApi";
16284
+ var API_KEY_FLEET = {
16285
+ [OPENAI_API_INSTANCE]: {
16286
+ driver: "openai-compat",
16287
+ displayName: "OpenAI",
16288
+ access: "api",
16289
+ icon: { kind: "preset", preset: "openai" },
16290
+ config: { url: "https://api.openai.com/v1", apiKeyEnv: "OMB_OPENAI_API_KEY", catalog: "openai" }
16291
+ },
16292
+ [CLAUDE_API_INSTANCE]: {
16293
+ driver: "claudeAgent",
16294
+ displayName: "Claude (API key)",
16295
+ access: "api",
16296
+ icon: { kind: "preset", preset: "anthropic" },
16297
+ config: { requireApiKey: true }
16298
+ },
16299
+ [XAI_API_INSTANCE]: { driver: "grok", displayName: "xAI", access: "api", icon: { kind: "preset", preset: "xai" } },
16300
+ [OPENROUTER_API_INSTANCE]: {
16301
+ driver: "openai-compat",
16302
+ displayName: "OpenRouter",
16303
+ access: "api",
16304
+ icon: { kind: "preset", preset: "openrouter" },
16305
+ config: { url: "https://openrouter.ai/api/v1", apiKeyEnv: "OMB_OPENROUTER_API_KEY" }
16306
+ }
16307
+ };
16125
16308
 
16126
16309
  // server/container-computer.ts
16127
16310
  var run = promisify(execFile2);
@@ -16454,9 +16637,11 @@ function createMcpBridgeInterceptor(options) {
16454
16637
  };
16455
16638
  }
16456
16639
  function runMcpBridge(options) {
16457
- const child = spawn(options.command, options.args, {
16640
+ const env = options.env ?? { ...process.env, PATH: augmentedPath() };
16641
+ const { command, args } = resolveCliSpawn(options.command, options.args, env);
16642
+ const child = spawn(command, args, {
16458
16643
  shell: false,
16459
- env: options.env ?? { ...process.env, PATH: augmentedPath() },
16644
+ env,
16460
16645
  stdio: ["pipe", "pipe", "pipe"]
16461
16646
  });
16462
16647
  child.stdin.on("error", () => {
@@ -130,6 +130,7 @@ function catalogProfileFromEnv(env) {
130
130
  sharedComputers: env.OMB_SHARED_COMPUTERS_ENABLED === "1",
131
131
  voiceNotes: env.OMB_VOICE_NOTES === "1",
132
132
  cloudHome: env.OMB_CLOUD_HOME === "1",
133
+ memoryEnabled: env.OMB_MEMORY_ENABLED !== "0",
133
134
  botId: env.OMB_BOT_ID ?? ""
134
135
  };
135
136
  }
@@ -310,14 +311,14 @@ var toolDefinitions = (externalRuntime) => [
310
311
  },
311
312
  {
312
313
  name: "coordinate_bots",
313
- description: "Ask existing OpenMausBot teammates for advice or assign concrete work. From normal chat every assignment you send a teammate continues your one standing conversation with that teammate, so they keep the context of what you asked before; from a room it defaults to this room. Use group_id from list_room_targets for a specific room. Give 1-4 bot_ids \u2014 teammate ids as list_bots or your roster prints them; a unique teammate name also resolves: they receive only your brief and use their own model, tools and permissions. Busy bots queue. They can consult their specialists; all results return here and resume you automatically. Include exact file paths, constraints and what must be verified. After sending all assignments, END your turn; do not poll or wait. On return, resolve tradeoffs, verify the requested outcome and request concrete corrections if necessary before giving one final answer. Do not send acknowledgements as new work.",
314
+ description: "Ask existing OpenMausBot teammates for advice or assign concrete work. From normal chat each distinct assignment starts a fresh thread for that teammate; from a room it defaults to this room. Give a self-contained brief. Use group_id from list_room_targets for a specific room. Give 1-4 bot_ids \u2014 teammate ids as list_bots or your roster prints them; a unique teammate name also resolves: they receive only your brief and use their own model, tools and permissions. Busy bots queue. They can consult their specialists; all results return here and resume you automatically. Include exact file paths, constraints and what must be verified. After sending all assignments, END your turn; do not poll or wait. On return, resolve tradeoffs, verify the requested outcome and request concrete corrections if necessary before giving one final answer. Do not send acknowledgements as new work.",
314
315
  inputSchema: { type: "object", additionalProperties: false, properties: {
315
- group_id: { type: "string", description: "Optional destination room. Omit for this room, or your standing conversation with each teammate when chatting directly." },
316
+ group_id: { type: "string", description: "Optional destination room. Omit for this room, or a fresh thread for each teammate when chatting directly." },
316
317
  bot_ids: { type: "array", items: { type: "string", description: "A teammate's id exactly as list_bots or your roster prints it ([id: \u2026]). A teammate's unique display name also resolves; a name shared by two reachable teammates is refused." }, minItems: 1, maxItems: 4, uniqueItems: true },
317
318
  message: { type: "string", minLength: 1, maxLength: 4e3, description: "Self-contained question or task for these teammates. Send separate requests when responsibilities differ." },
318
319
  request_key: { type: "string", description: "A short unique assignment key. Reuse for an identical retry." },
319
320
  rework: { type: "boolean", description: "True only for concrete additional work from someone who already completed a request." },
320
- label: { type: "string", description: "Optional short name (one line, at most 60 characters) for this job. Used only when the teammate is still working on your previous assignment and this one therefore runs in its own thread beside your standing conversation." }
321
+ label: { type: "string", description: "Optional short name (one line, at most 60 characters) for this job. Names the new direct assignment thread." }
321
322
  }, required: ["bot_ids", "message", "request_key"] }
322
323
  },
323
324
  {
@@ -866,7 +867,7 @@ function availableTools(profile) {
866
867
  }
867
868
  function catalogTools(profile) {
868
869
  const TOOLS = toolDefinitions(profile.externalRuntime);
869
- const BOT_SCOPED_TOOLS = profile.botId === WATCHER_OPTIONS_CARD_BOT_ID ? TOOLS : TOOLS.filter((tool) => !WATCHER_TOOL_NAMES.has(tool.name));
870
+ const BOT_SCOPED_TOOLS = TOOLS.filter((tool) => (profile.botId === WATCHER_OPTIONS_CARD_BOT_ID || !WATCHER_TOOL_NAMES.has(tool.name)) && (profile.memoryEnabled !== false || tool.name !== "memory_update" && tool.name !== "memory_log"));
870
871
  const AUTHORING_TOOLS = profile.skillAuthoring ? BOT_SCOPED_TOOLS : BOT_SCOPED_TOOLS.filter((tool) => !SKILL_TOOL_NAMES.has(tool.name));
871
872
  const SHAREABLE_TOOLS = profile.sharedComputers ? AUTHORING_TOOLS : AUTHORING_TOOLS.filter((tool) => !SHARED_COMPUTER_TOOL_NAMES.has(tool.name));
872
873
  const VOICE_READY_TOOLS = profile.voiceNotes ? SHAREABLE_TOOLS : SHAREABLE_TOOLS.filter((tool) => !VOICE_TOOL_NAMES.has(tool.name));
@@ -16167,6 +16168,8 @@ var KEY_PREFIXES = [
16167
16168
  // xai (grok)
16168
16169
  /\bgsk_[A-Za-z0-9]{40,}/g,
16169
16170
  // groq
16171
+ /\bcsk-[A-Za-z0-9]{32,}/g,
16172
+ // cerebras
16170
16173
  /\bhf_[A-Za-z0-9]{30,}/g,
16171
16174
  // hugging face
16172
16175
  /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}/g,
@@ -14728,7 +14728,11 @@ var sessionSchema = external_exports.object({
14728
14728
  userId: external_exports.string().max(256).optional(),
14729
14729
  email: external_exports.string().max(320).optional(),
14730
14730
  /** Set only by the internal verified-portal issuance path, never by email or pairing input. */
14731
- membershipAuthority: external_exports.literal("portal").optional()
14731
+ membershipAuthority: external_exports.literal("portal").optional(),
14732
+ /** A browser sign-in (PairingCode `browser`): accepted only as its browser's cookie, never as a bearer token. */
14733
+ cookieOnly: external_exports.literal(true).optional(),
14734
+ /** Whose OMB Cloud a browser sign-in signed in to (its PairingCode `owner`). */
14735
+ owner: external_exports.string().max(254).optional()
14732
14736
  });
14733
14737
  var fileSchema = external_exports.object({ version: external_exports.literal(1), sessions: external_exports.array(sessionSchema) });
14734
14738