openmausbot 0.1.94 → 0.1.96

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 (188) hide show
  1. package/dist/assets/{DesktopViewer-bxM7NV3N.js → DesktopViewer-DsnA23KM.js} +1 -1
  2. package/dist/assets/{abnfDiagram-O67JEVCF-BhMdJhRJ.js → abnfDiagram-O67JEVCF-Dkbd2hcj.js} +1 -1
  3. package/dist/assets/{arc-B5itKDcx.js → arc-Duj5Coy2.js} +1 -1
  4. package/dist/assets/{architectureDiagram-NJMV4G6O-C5d7UY6U.js → architectureDiagram-NJMV4G6O-uYUsDawP.js} +1 -1
  5. package/dist/assets/{blockDiagram-BEXU5L5S-BrZIhMmu.js → blockDiagram-BEXU5L5S-CWDlTpXe.js} +1 -1
  6. package/dist/assets/{c4Diagram-YGBWAQC7-7I0ArfbD.js → c4Diagram-YGBWAQC7-B0t15PDc.js} +1 -1
  7. package/dist/assets/channel-BZxwC-Gw.js +1 -0
  8. package/dist/assets/{chunk-2Q5K7J3B-BnEsyN36.js → chunk-2Q5K7J3B-BJSCL-HV.js} +1 -1
  9. package/dist/assets/{chunk-3FUC2YCW-BXATQ52s.js → chunk-3FUC2YCW-D3_ILccd.js} +2 -2
  10. package/dist/assets/{chunk-5VM5RSS4-B0BpTkEx.js → chunk-5VM5RSS4-D3dmwT_S.js} +1 -1
  11. package/dist/assets/{chunk-GTNCS2PH-BtLTz6FR.js → chunk-GTNCS2PH-Br73HFPD.js} +1 -1
  12. package/dist/assets/{chunk-GWA4HPMP-D6gcZOYt.js → chunk-GWA4HPMP-uSsjxubC.js} +1 -1
  13. package/dist/assets/{chunk-JWPE2WC7-DCLrosvf.js → chunk-JWPE2WC7-C40VWFyr.js} +1 -1
  14. package/dist/assets/{chunk-NETBCI7D-B9JsknV9.js → chunk-NETBCI7D-D6WNNYwU.js} +1 -1
  15. package/dist/assets/{chunk-WEXAMYUT-CsoTxw7z.js → chunk-WEXAMYUT-DOEhq64P.js} +1 -1
  16. package/dist/assets/{chunk-XXDRQBXY-0F_frB0c.js → chunk-XXDRQBXY-BqJEi6Pi.js} +1 -1
  17. package/dist/assets/{classDiagram-v2-NBCMYWYE-DkrpnflX.js → classDiagram-v2-NBCMYWYE-ByU_GnxT.js} +1 -1
  18. package/dist/assets/{cose-bilkent-JH36ORCC-BNDwYBt9.js → cose-bilkent-JH36ORCC-D-Uglxqq.js} +1 -1
  19. package/dist/assets/{cynefin-OW5HDTMX-JUkNr1Mk.js → cynefin-OW5HDTMX-CZWO7aYj.js} +1 -1
  20. package/dist/assets/{cynefinDiagram-VND7K2PF-DKeh9N4M.js → cynefinDiagram-VND7K2PF-C70-w0la.js} +1 -1
  21. package/dist/assets/{dagre-6A5THRUB-ve-6T_wX.js → dagre-6A5THRUB-CnhjhExB.js} +1 -1
  22. package/dist/assets/{diagram-22UHCM2B-BuJ2d8rT.js → diagram-22UHCM2B-bnjWCNb4.js} +1 -1
  23. package/dist/assets/{diagram-3UASUU5V-BgOs_Ni-.js → diagram-3UASUU5V-A4uTWoFV.js} +1 -1
  24. package/dist/assets/{diagram-ATOU4E4O-DMK6VmcP.js → diagram-ATOU4E4O-Zi6m3NUl.js} +1 -1
  25. package/dist/assets/{diagram-CDSNMT55-DksASlcY.js → diagram-CDSNMT55-DtCcmd5k.js} +1 -1
  26. package/dist/assets/{diagram-MLGK6HIB-Bgn8I5k6.js → diagram-MLGK6HIB-DofuETS3.js} +1 -1
  27. package/dist/assets/{diagram-MPIPVDR6-zK0jqO8N.js → diagram-MPIPVDR6-Dw2T9PuU.js} +1 -1
  28. package/dist/assets/{ebnfDiagram-ZINNZB2B-vKrbzTwr.js → ebnfDiagram-ZINNZB2B-DbrwPiem.js} +1 -1
  29. package/dist/assets/{elk-276RUBZZ-Bzv2mPNf.js → elk-276RUBZZ-BvCt1dCb.js} +1 -1
  30. package/dist/assets/{erDiagram-OPXOYQCR-CvOyYuxu.js → erDiagram-OPXOYQCR-Y-QKqPnU.js} +1 -1
  31. package/dist/assets/{flowDiagram-KWPJA3E3-CtbnDbc0.js → flowDiagram-KWPJA3E3-CDkL1B5w.js} +1 -1
  32. package/dist/assets/{ganttDiagram-FUAMR5RP-c4dMRYyG.js → ganttDiagram-FUAMR5RP-CKV5D2F6.js} +1 -1
  33. package/dist/assets/{gitGraphDiagram-X574FWY7-B34uaQho.js → gitGraphDiagram-X574FWY7-nL9iFTCv.js} +1 -1
  34. package/dist/assets/{index-CPiqc_DN.js → index-DreDnjOu.js} +1 -1
  35. package/dist/assets/index-Du7o6Dsf.js +610 -0
  36. package/dist/assets/index-KxG4bWSr.css +1 -0
  37. package/dist/assets/{infoDiagram-VRGFBTTK-o64ma4CI.js → infoDiagram-VRGFBTTK-C7aHjzsf.js} +1 -1
  38. package/dist/assets/{ishikawaDiagram-OU5B5YK6-DV4C9BAm.js → ishikawaDiagram-OU5B5YK6-KUZsNBTh.js} +1 -1
  39. package/dist/assets/{journeyDiagram-ZHPQQLJL-Bf0AHk1H.js → journeyDiagram-ZHPQQLJL-CGUuodFl.js} +1 -1
  40. package/dist/assets/{kanban-definition-PNTS6WVX-B1UMSKmE.js → kanban-definition-PNTS6WVX-Cy6r868Z.js} +1 -1
  41. package/dist/assets/{linear-BpKhuyLm.js → linear-Bl669148.js} +1 -1
  42. package/dist/assets/{mermaid.core-B_BKNCw5.js → mermaid.core-86Xqz5Mr.js} +5 -5
  43. package/dist/assets/{mindmap-definition-NLK3R4M7-DeARruT1.js → mindmap-definition-NLK3R4M7-G4DzHLrd.js} +1 -1
  44. package/dist/assets/{pegDiagram-GJSIUBJH-BOQEk_1D.js → pegDiagram-GJSIUBJH-K4eruzY0.js} +1 -1
  45. package/dist/assets/{pieDiagram-5QR66LMP-EIfoiTZo.js → pieDiagram-5QR66LMP-DYdR9PPq.js} +1 -1
  46. package/dist/assets/{quadrantDiagram-O4NWA36T-GgZwT-fi.js → quadrantDiagram-O4NWA36T-BCAh0nEy.js} +1 -1
  47. package/dist/assets/{railroadDiagram-XR7U4H2S-D9rDQomj.js → railroadDiagram-XR7U4H2S-p0dGRc4g.js} +1 -1
  48. package/dist/assets/{requirementDiagram-PLB6GJNP-DAh1MIeo.js → requirementDiagram-PLB6GJNP-tLeBG0aL.js} +1 -1
  49. package/dist/assets/{sankeyDiagram-IPEJSGJF-CPr6Uz64.js → sankeyDiagram-IPEJSGJF-QRuN16rV.js} +1 -1
  50. package/dist/assets/{sequenceDiagram-PO4LG4MO-BU6VIdcm.js → sequenceDiagram-PO4LG4MO-ueT1nVoa.js} +1 -1
  51. package/dist/assets/{sizeCapture-INFHLROL-qF2HO41r.js → sizeCapture-INFHLROL-wRS2zWg2.js} +1 -1
  52. package/dist/assets/{stateDiagram-v2-GCMORJYK-DlJ8G4MD.js → stateDiagram-v2-GCMORJYK-CYzA_hE1.js} +1 -1
  53. package/dist/assets/{swimlanes-2SLR337P-DzYE8I54.js → swimlanes-2SLR337P-kDnv6LMc.js} +1 -1
  54. package/dist/assets/swimlanesDiagram-TC7HE7FX-C7voMDle.js +8 -0
  55. package/dist/assets/{timeline-definition-EJHVYXUP-B7wzEQ0A.js → timeline-definition-EJHVYXUP-D1y2UbbH.js} +1 -1
  56. package/dist/assets/{usecaseDiagram-POWQR4AR-BvGgrxIP.js → usecaseDiagram-POWQR4AR-IqB4v9HX.js} +1 -1
  57. package/dist/assets/{vennDiagram-UO4OBE2U-CEECdgQg.js → vennDiagram-UO4OBE2U-BEi7KYVF.js} +1 -1
  58. package/dist/assets/{wardleyDiagram-VNRHLVJA-XQHA0P_P.js → wardleyDiagram-VNRHLVJA-Dkybo-Yf.js} +1 -1
  59. package/dist/assets/{xychartDiagram-PMCCYNJV-B5mLcZI2.js → xychartDiagram-PMCCYNJV-BAPFJLpg.js} +1 -1
  60. package/dist/index.html +2 -2
  61. package/dist-server/cloud-home-start.js +27 -13
  62. package/dist-server/companion/src/listener.js +39 -18
  63. package/dist-server/companion/src/routes.js +39 -0
  64. package/dist-server/container-mcp.js +16 -29
  65. package/dist-server/drivers/agents-proxy.js +161 -82
  66. package/dist-server/enterprise/server/index.js +2 -1
  67. package/dist-server/{browser-proxy.js → harness-mcp-proxy.js} +34 -19
  68. package/dist-server/index.js +4991 -4908
  69. package/dist-server/local-computer.js +2 -1
  70. package/dist-server/openmausbot.js +906 -1785
  71. package/dist-server/pair-cli.js +906 -1785
  72. package/dist-server/proxy-paths.js +2 -1
  73. package/dist-server/server/account-signin.js +0 -2
  74. package/dist-server/server/activity.js +201 -0
  75. package/dist-server/server/admin-activity.js +1 -4
  76. package/dist-server/server/auto-approve.js +25 -4
  77. package/dist-server/server/automatic-recovery.js +1 -1
  78. package/dist-server/server/boat-create-idempotency.js +0 -7
  79. package/dist-server/server/boat-delete-journal.js +0 -4
  80. package/dist-server/server/boat.js +4 -4
  81. package/dist-server/server/bot-package.js +1 -19
  82. package/dist-server/server/browser-runtime.js +1 -2
  83. package/dist-server/server/checkpoints.js +90 -148
  84. package/dist-server/server/chief-of-staff.js +9 -9
  85. package/dist-server/server/cli.js +33 -26
  86. package/dist-server/server/cloud-backend.js +0 -4
  87. package/dist-server/server/cloud-computer-tools.js +110 -0
  88. package/dist-server/server/cloud-home-start.js +12 -15
  89. package/dist-server/server/cloud-home.js +0 -5
  90. package/dist-server/server/cloud-lending.js +0 -3
  91. package/dist-server/server/cloud-move-http.js +44 -30
  92. package/dist-server/server/cloud-move.js +20 -18
  93. package/dist-server/server/composio.js +41 -5
  94. package/dist-server/server/computer-control.js +0 -15
  95. package/dist-server/server/computer-observation.js +0 -74
  96. package/dist-server/server/config.js +121 -65
  97. package/dist-server/server/container-computer.js +23 -24
  98. package/dist-server/server/control-client.js +4 -10
  99. package/dist-server/server/decider/jev.js +1 -4
  100. package/dist-server/server/decider/log.js +1 -3
  101. package/dist-server/server/decision-log.js +1 -4
  102. package/dist-server/server/delegations.js +3 -2
  103. package/dist-server/server/drivers/acp/core.js +11 -8
  104. package/dist-server/server/drivers/acp/opencode-go.js +17 -16
  105. package/dist-server/server/drivers/agents-call.js +88 -92
  106. package/dist-server/server/drivers/agents-catalog.js +90 -11
  107. package/dist-server/server/drivers/agents-proxy.js +10 -31
  108. package/dist-server/server/drivers/antigravity.js +1 -4
  109. package/dist-server/server/drivers/boatagent.js +23 -4
  110. package/dist-server/server/drivers/cerebras.js +3 -3
  111. package/dist-server/server/drivers/chat-mcp-tools.js +4 -7
  112. package/dist-server/server/drivers/claude-login-auth.js +2 -11
  113. package/dist-server/server/drivers/claude.js +16 -14
  114. package/dist-server/server/drivers/codex-device-auth.js +3 -1
  115. package/dist-server/server/drivers/codex.js +5 -4
  116. package/dist-server/server/drivers/grok.js +1 -1
  117. package/dist-server/server/drivers/openai-chat-protocol.js +4 -2
  118. package/dist-server/server/drivers/openai-chat.js +18 -11
  119. package/dist-server/server/drivers/prompt-split.js +4 -4
  120. package/dist-server/server/drivers/retry.js +8 -4
  121. package/dist-server/server/engine-install.js +1 -5
  122. package/dist-server/server/harness/bus.js +49 -0
  123. package/dist-server/server/harness/registry.js +0 -1
  124. package/dist-server/server/{browser-proxy.js → harness-mcp-proxy.js} +40 -20
  125. package/dist-server/server/index.js +1190 -971
  126. package/dist-server/server/lending-memory.js +12 -8
  127. package/dist-server/server/mcp-registry.js +35 -0
  128. package/dist-server/server/memory-entries.js +38 -8
  129. package/dist-server/server/memory-organize.js +1 -8
  130. package/dist-server/server/memory-topics.js +4 -4
  131. package/dist-server/server/memory-upkeep.js +13 -15
  132. package/dist-server/server/message-file.js +9 -13
  133. package/dist-server/server/outbound-counts.js +79 -0
  134. package/dist-server/server/outbound-requests.js +60 -0
  135. package/dist-server/server/package-import.js +1 -1
  136. package/dist-server/server/peer-delivery.js +5 -19
  137. package/dist-server/server/peer-roster.js +30 -4
  138. package/dist-server/server/profile-versions.js +0 -31
  139. package/dist-server/server/provider-key-check.js +2 -1
  140. package/dist-server/server/proxy-paths.js +2 -1
  141. package/dist-server/server/restart.js +40 -0
  142. package/dist-server/server/room-handoffs.js +17 -13
  143. package/dist-server/server/routes/bot-memory.js +0 -24
  144. package/dist-server/server/routine-requests.js +2 -5
  145. package/dist-server/server/routines.js +10 -5
  146. package/dist-server/server/server-launcher.js +53 -0
  147. package/dist-server/server/setup-mode.js +0 -2
  148. package/dist-server/server/skill-learn.js +0 -1
  149. package/dist-server/server/skill-library.js +0 -15
  150. package/dist-server/server/store.js +10 -2
  151. package/dist-server/server/surface.js +69 -28
  152. package/dist-server/server/system-prompt.js +17 -7
  153. package/dist-server/server/team-manifest.js +1 -6
  154. package/dist-server/server/team-memory.js +209 -0
  155. package/dist-server/server/thread-events.js +2 -2
  156. package/dist-server/server/tunnel.js +4 -1
  157. package/dist-server/server/turn-images.js +1 -21
  158. package/dist-server/server/turn-resources.js +19 -150
  159. package/dist-server/server/usage-ledger.js +3 -1
  160. package/dist-server/server/vps-computer.js +4 -14
  161. package/dist-server/server/workspace.js +87 -50
  162. package/dist-server/server-launcher.js +72 -0
  163. package/dist-server/shared/activity.js +3 -0
  164. package/dist-server/shared/ask-question.js +1 -1
  165. package/dist-server/shared/bot-avatar.js +8 -0
  166. package/dist-server/shared/cloud-computer.js +12 -0
  167. package/dist-server/shared/connector-scopes.js +78 -0
  168. package/dist-server/shared/failed-turn.js +25 -0
  169. package/dist-server/shared/live-approval.js +2 -2
  170. package/dist-server/shared/outbound.js +128 -0
  171. package/dist-server/shared/package-format.js +3 -3
  172. package/dist-server/shared/pairing-link.js +144 -0
  173. package/dist-server/shared/tool-surface.js +3 -2
  174. package/dist-server/vps-container-mcp.js +16 -29
  175. package/dist-server/workspace-backup.worker.js +14 -27
  176. package/enterprise/server/index.js +2 -1
  177. package/package.json +1 -1
  178. package/dist/assets/channel-CdJX6i8k.js +0 -1
  179. package/dist/assets/index-CPYrGsv1.js +0 -610
  180. package/dist/assets/index-CzT42GR8.css +0 -1
  181. package/dist/assets/swimlanesDiagram-TC7HE7FX-D-U4GtLQ.js +0 -8
  182. package/dist-server/server/claim-idle.js +0 -33
  183. package/dist-server/server/cloud-overflow.js +0 -167
  184. package/dist-server/server/drivers/chat-boat-tools.js +0 -90
  185. package/dist-server/server/drivers/grokagent.js +0 -4
  186. package/dist-server/server/openmaus-status-capsule.js +0 -329
  187. package/dist-server/server/tightening-requests.js +0 -435
  188. package/dist-server/shared/tightening-request.js +0 -87
@@ -12,20 +12,34 @@
12
12
  import { execFile } from "node:child_process";
13
13
  import { homedir, networkInterfaces } from "node:os";
14
14
  import { delimiter, join } from "node:path";
15
- /** Interfaces that exist to tunnel, bridge or mesh traffic — utun (Tailscale
16
- * and every other VPN), vmnet/bridge (VMs, containers, internet sharing),
17
- * awdl/llw (AirDrop's side channels), feth/tap/tun. Their addresses stay in
18
- * the list, because the tailnet one is exactly what a phone off-network
19
- * dials — but a phone on the same wifi can reach none of them, so none of
20
- * them may come first. */
21
- const VIRTUAL_INTERFACES = /^(utun|tun|tap|bridge|vmnet|awdl|llw|feth)/;
22
- /** Lower sorts earlier. `en0`, `en1`, … are macOS's built-in wifi and
23
- * ethernet — the networks a phone is actually standing on. */
15
+ /** Interfaces that exist to tunnel, bridge, virtualize or mesh traffic.
16
+ * Their addresses stay in the list — the tailnet one is exactly what a phone
17
+ * off-network dials, and a Hyper-V external switch moves the PC's real address
18
+ * onto a "vEthernet (…)" adapter — but a phone on the same Wi-Fi can reach
19
+ * none of the usual ones, so none of them may come first.
20
+ *
21
+ * Matched by name, case-insensitively, because that is all Node reports:
22
+ * - macOS: utun (every VPN, Tailscale), bridge/vmnet (VMs, internet
23
+ * sharing), awdl/llw (AirDrop), feth, anpi.
24
+ * - Linux: docker0, br-<id> (Docker networks), veth, virbr (libvirt),
25
+ * vboxnet, cni/flannel/lxc/lxd, tun/tap, wg, zt (ZeroTier), tailscale0.
26
+ * - Windows names adapters rather than numbering them: "vEthernet (WSL)",
27
+ * "vEthernet (Default Switch)", "VirtualBox Host-Only Network", "VMware
28
+ * Network Adapter VMnet8", "Tailscale", "ZeroTier One", anything with VPN
29
+ * or Bluetooth in its name. */
30
+ const VIRTUAL_INTERFACE = /^(utun|tun|tap|bridge|br-|vmnet|vboxnet|virbr|veth|docker|cni|flannel|lxc|lxd|zt|wg|tailscale|awdl|llw|feth|anpi)|vethernet|virtual|vmware|hyper-v|wsl|zerotier|vpn|loopback|bluetooth/i;
31
+ /** The networks a phone is actually standing on: macOS en0/en1, Linux
32
+ * eth0/enp3s0/eno1/wlan0/wlp2s0, Windows "Wi-Fi", "Ethernet 2", and the
33
+ * German/Chinese "WLAN". */
34
+ const PHYSICAL_INTERFACE = /^(en|eth|wl)[a-z0-9]*$|^(wi-?fi|wlan|ethernet)\b/i;
35
+ /** Lower sorts earlier: physical, then anything unrecognized (a localized
36
+ * Windows name, a hotspot), then virtual. Virtual is checked first so
37
+ * "vEthernet" is never mistaken for "Ethernet". */
24
38
  const interfaceRank = (name) => {
25
- if (/^en\d+$/.test(name))
26
- return 0;
27
- if (VIRTUAL_INTERFACES.test(name))
39
+ if (VIRTUAL_INTERFACE.test(name))
28
40
  return 2;
41
+ if (PHYSICAL_INTERFACE.test(name))
42
+ return 0;
29
43
  return 1;
30
44
  };
31
45
  /** Every IPv4 address a phone on the same network could dial, most reachable
@@ -33,12 +47,19 @@ const interfaceRank = (name) => {
33
47
  * will reach us.
34
48
  *
35
49
  * Ranked, not merely collected: `networkInterfaces()` promises nothing about
36
- * order, callers put the first non-tailnet entry into the pairing QR, and on
37
- * a Mac with a VPN or a VM running the first entry can be a utun or bridge100
38
- * address the phone cannot route to. Real interfaces lead, tunnels and
39
- * bridges trail; the sort is stable, so enumeration order still breaks ties.
50
+ * order, callers put the first non-tailnet entry into the pairing QR, and the
51
+ * first entry can be an address the phone cannot route to — a utun or
52
+ * bridge100 on a Mac, WSL's vEthernet on Windows, docker0 on Linux. Real
53
+ * interfaces lead, virtual ones trail; the sort is stable, so enumeration
54
+ * order still breaks ties.
40
55
  * The parameter exists for tests — the interface table is the machine's. */
41
56
  export function lanAddresses(interfaces = networkInterfaces()) {
57
+ return lanInterfaces(interfaces).map((entry) => entry.address);
58
+ }
59
+ /** `lanAddresses`, each with the interface it is on, in the same order. The
60
+ * name is what Windows calls the adapter ("Wi-Fi"), which is how the pairing
61
+ * panel asks whether Windows has that network down as Public. */
62
+ export function lanInterfaces(interfaces = networkInterfaces()) {
42
63
  const found = [];
43
64
  for (const [name, entries] of Object.entries(interfaces)) {
44
65
  for (const entry of entries ?? []) {
@@ -46,10 +67,10 @@ export function lanAddresses(interfaces = networkInterfaces()) {
46
67
  continue;
47
68
  if (entry.address.startsWith("169.254."))
48
69
  continue;
49
- found.push({ rank: interfaceRank(name), address: entry.address });
70
+ found.push({ rank: interfaceRank(name), name, address: entry.address });
50
71
  }
51
72
  }
52
- return found.sort((a, b) => a.rank - b.rank).map((entry) => entry.address);
73
+ return found.sort((a, b) => a.rank - b.rank).map(({ name, address }) => ({ name, address }));
53
74
  }
54
75
  /** Tailscale hands its nodes an address in 100.64.0.0/10 — the CGNAT range
55
76
  * RFC 6598 set aside, which is why it never collides with a home network.
@@ -35,6 +35,22 @@ export const CLOUD_DESKTOP_CONTROL_ROUTE = {
35
35
  method: "POST",
36
36
  path: /^\/api\/bots\/[\w-]+\/computer\/(?:control|screenshot|viewer-close)$/,
37
37
  };
38
+ /** Driving a bot's own browser: the frame stream, and the channel that sends
39
+ * pointer and keyboard events into it.
40
+ *
41
+ * Deliberately separate from the cloud-desktop classifier above rather than
42
+ * folded into it. A cloud desktop is a disposable VM; a bot's browser is
43
+ * normally signed into the person's real accounts, with their cookies and
44
+ * their sessions. A device trusted with a throwaway VM must not acquire the
45
+ * second permission because the two looked similar from here. */
46
+ export const BROWSER_LIVE_ROUTE = {
47
+ method: "GET",
48
+ path: /^\/api\/bots\/[\w-]+\/browser\/live$/,
49
+ };
50
+ export const BROWSER_ACTION_ROUTE = {
51
+ method: "POST",
52
+ path: /^\/api\/bots\/[\w-]+\/browser\/action$/,
53
+ };
38
54
  /** The Local VM's live desktop, relayed by the sidecar like a VPS viewer.
39
55
  * The harness grants it only while a person holds that bot's computer. */
40
56
  export const LOCAL_VM_JOIN_ROUTE = {
@@ -62,6 +78,13 @@ export function isCloudDesktopAccess(method, path) {
62
78
  || (method === LOCAL_VM_SCREENSHOT_ROUTE.method && LOCAL_VM_SCREENSHOT_ROUTE.path.test(path))
63
79
  || (method === LOCAL_VM_JOIN_ROUTE.method && LOCAL_VM_JOIN_ROUTE.path.test(path));
64
80
  }
81
+ /** Both halves of browser control, behind one capability. Watching the frames
82
+ * and driving them are the same permission: a viewer that can see a logged-in
83
+ * session is already past the line the capability is drawn at. */
84
+ export function isBrowserControlAccess(method, path) {
85
+ return (method === BROWSER_LIVE_ROUTE.method && BROWSER_LIVE_ROUTE.path.test(path))
86
+ || (method === BROWSER_ACTION_ROUTE.method && BROWSER_ACTION_ROUTE.path.test(path));
87
+ }
65
88
  /** Every request the iOS app makes, and nothing else.
66
89
  *
67
90
  * Ids are `[\w-]+`, matching the harness's own route patterns. The paths
@@ -111,6 +134,17 @@ const ALLOWED = [
111
134
  // recent activity. No settings, no transcript — read on open and on
112
135
  // pull-to-refresh.
113
136
  { method: "GET", path: /^\/api\/bots\/[\w-]+\/overview$/ },
137
+ // Read-only: what the bot did, with the outcome, built from logs that
138
+ // already exist (server/activity.ts). No settings reachable through it.
139
+ { method: "GET", path: /^\/api\/bots\/[\w-]+\/activity$/ },
140
+ // The section's shared team memory: people, places, decisions and terms.
141
+ // Reading, adding, answering a proposal, editing a detail, and removing
142
+ // are all content edits, not execution policy — the same line the profile
143
+ // and sidebar-section routes draw. The section rides as a query string.
144
+ { method: "GET", path: /^\/api\/team-memory$/ },
145
+ { method: "POST", path: /^\/api\/team-memory$/ },
146
+ { method: "PATCH", path: /^\/api\/team-memory\/[\w-]+$/ },
147
+ { method: "DELETE", path: /^\/api\/team-memory\/[\w-]+$/ },
114
148
  // Paired-safe profile subset. The harness route itself rejects fields
115
149
  // outside identity, standing instructions (soul, byte-capped), avatar,
116
150
  // notifications, and voice preferences.
@@ -123,6 +157,11 @@ const ALLOWED = [
123
157
  // second, per-device capability check before it reaches the harness.
124
158
  CLOUD_DESKTOP_JOIN_ROUTE,
125
159
  CLOUD_DESKTOP_CONTROL_ROUTE,
160
+ // A bot's browser, watched and driven from the phone. Like the cloud
161
+ // desktop above, the proxy applies a second per-device capability check
162
+ // before either of these reaches the harness.
163
+ BROWSER_LIVE_ROUTE,
164
+ BROWSER_ACTION_ROUTE,
126
165
  // A picture of the Local VM — not its lifecycle, which stays on the host.
127
166
  // Gated per device by the proxy like the cloud desktop above.
128
167
  LOCAL_VM_SCREENSHOT_ROUTE,
@@ -15816,10 +15816,6 @@ var remoteMutationSchema = remoteEntrySchema.extend({
15816
15816
  }).optional()
15817
15817
  });
15818
15818
 
15819
- // server/cloud-overflow.ts
15820
- var CLOUD_SEAT_IDLE_STOP_MS = 5 * 6e4;
15821
- var CLOUD_SEAT_SLEEP_RETRY_MAX_MS = 10 * 6e4;
15822
-
15823
15819
  // server/config.ts
15824
15820
  var optionalText = external_exports.string().optional();
15825
15821
  var SSH_ALIAS = /^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$/;
@@ -16017,17 +16013,6 @@ var featureConfigSchema = external_exports.object({
16017
16013
  * conversations that share words with the message ride into the turn.
16018
16014
  * Read-only; on unless explicitly switched off — see autoRecallEnabled. */
16019
16015
  autoRecall: external_exports.boolean().optional(),
16020
- /** Idle release for computer claims (#1653): a desktop seat that stays
16021
- * screen-quiet for 90 seconds is released to waiting turns while its
16022
- * holder's turn still lives; the previous holder re-claims directly
16023
- * for 10 minutes and yields to an occupied seat. Off until baked; see
16024
- * computerClaimIdleReleaseEnabled for how to enable it by hand. */
16025
- computerClaimIdleRelease: external_exports.boolean().optional(),
16026
- /** Consented cloud overflow for local computer waits (#1655): a wait
16027
- * may offer a per-second-billed cloud seat, but only through an explicit
16028
- * consent card or a configured allowlist — never a silent Auto default.
16029
- * Off until baked; see cloudOverflowEnabled for how to enable it by hand. */
16030
- cloudOverflow: external_exports.boolean().optional(),
16031
16016
  /** Opt-in shared skills library: one store at the data dir that bots
16032
16017
  * read by assignment instead of per-workspace copies. Off until
16033
16018
  * explicitly enabled — see skillsLibraryEnabled. */
@@ -16153,8 +16138,12 @@ var appConfigSchema = external_exports.object({
16153
16138
  * provider is Boat now and the key is kept for compatibility. */
16154
16139
  box: external_exports.object({ token: optionalText }).optional(),
16155
16140
  vps: vpsConfigSchema.optional(),
16156
- /** Optional OpenCode key; persisted write-only and passed only to its child. */
16157
- opencodeGo: external_exports.object({ apiKey: optionalText }).optional(),
16141
+ /** Optional OpenCode key; persisted write-only and passed only to its child.
16142
+ * `providerKeys`: keys for OpenCode's other providers (Venice, Groq…) by the
16143
+ * environment name OpenCode reads, also write-only and only for its child.
16144
+ * Settings changes go through mergeOpenCodeProviderKeys; the stored copy
16145
+ * is read loosely (storedAppConfigSchema). */
16146
+ opencodeGo: external_exports.object({ apiKey: optionalText, providerKeys: external_exports.record(external_exports.string(), external_exports.string()).optional() }).optional(),
16158
16147
  /** Voice settings and the selected voice id. `provider` picks the
16159
16148
  * engine: "elevenlabs" (default; needs `key`), "fish" (needs its own
16160
16149
  * `fishKey`; `fishModel` picks its speech model), "system" (the Mac's
@@ -16234,15 +16223,6 @@ var appConfigSchema = external_exports.object({
16234
16223
  /** The authorization decision log (server/decision-log.ts): days of month
16235
16224
  * files kept, at least; OMB_DECISION_RETENTION_DAYS wins when set. */
16236
16225
  decisions: external_exports.object({ retentionDays: external_exports.number().int().min(1).max(3650).optional() }).strict().optional(),
16237
- /** #1655 cloud-overflow settings. perSecondCostUsd is the operator's own
16238
- * verified rate: with no price configured the feature stays inert rather
16239
- * than show an invented one. allowlistedThreads carries standing consent
16240
- * for exact thread ids. */
16241
- cloudOverflow: external_exports.object({
16242
- perSecondCostUsd: external_exports.number().positive().max(10).optional(),
16243
- idleStopMs: external_exports.number().int().positive().max(24 * 60 * 6e4).optional(),
16244
- allowlistedThreads: external_exports.array(external_exports.string().min(1)).max(1e3).optional()
16245
- }).strict().optional(),
16246
16226
  localVm: localVmConfigSchema.optional(),
16247
16227
  features: featureConfigSchema.optional(),
16248
16228
  onboarding: onboardingConfigSchema.optional(),
@@ -16257,7 +16237,14 @@ var appConfigSchema = external_exports.object({
16257
16237
  mcpServers: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
16258
16238
  });
16259
16239
  var storedAppConfigSchema = appConfigSchema.extend({
16260
- browserProfiles: storedBrowserProfilesSchema.optional()
16240
+ browserProfiles: storedBrowserProfilesSchema.optional(),
16241
+ /** Read loosely, like mcpServers: a hand-edited provider key that isn't
16242
+ * text is dropped here, and a bad name or key later
16243
+ * (openCodeProviderKeys), never the whole file. */
16244
+ opencodeGo: external_exports.object({
16245
+ apiKey: optionalText,
16246
+ providerKeys: external_exports.record(external_exports.string(), external_exports.unknown()).catch({}).transform((keys) => Object.fromEntries(Object.entries(keys).filter((entry) => typeof entry[1] === "string"))).optional()
16247
+ }).optional()
16261
16248
  });
16262
16249
  var appConfigPatchSchema = appConfigSchema.omit({ instances: true, mcpServers: true, cliStartup: true, customDomain: true }).extend({ threads: threadsPatchSchema.optional(), newBots: newBotsPatchSchema.optional() });
16263
16250
  var jsonObjectSchema = external_exports.record(external_exports.string(), external_exports.json());
@@ -16305,7 +16292,8 @@ function resolveProxy(relative) {
16305
16292
  return existsSync2(source) ? source : join3(SERVER_ROOT, `${relative}.js`);
16306
16293
  }
16307
16294
  var SPAWNED_PROXIES = {
16308
- browser: resolveProxy("browser-proxy"),
16295
+ // The built-in browser and the cloud computer: argv[2] picks which.
16296
+ harnessMcp: resolveProxy("harness-mcp-proxy"),
16309
16297
  localComputer: resolveProxy("local-computer-proxy"),
16310
16298
  permission: resolveProxy("permission-proxy"),
16311
16299
  containerMcp: resolveProxy("container-mcp"),
@@ -16337,7 +16325,6 @@ var VM_WORKSPACE_DIR = join4(DATA_DIR, "vm-home");
16337
16325
  var DISPLAY = ":1";
16338
16326
  var CUA_EXECUTABLE = "/usr/local/libexec/openmausbot/cua-driver";
16339
16327
  var MEMORY_BYTES = 4 * 1024 * 1024 * 1024;
16340
- var SHM_BYTES = 512 * 1024 * 1024;
16341
16328
  function cuaExecArgs(args, options = {}) {
16342
16329
  return [
16343
16330
  "exec",