@xopcai/xopc 0.0.251 → 0.0.252

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 (329) hide show
  1. package/README.md +8 -5
  2. package/README.zh-CN.md +8 -5
  3. package/dist/browser-ext/dist/background.js +358 -768
  4. package/dist/browser-ext/manifest.json +1 -2
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/{activity-store-DfBjTSo9.js → activity-store-w3eq3YpP.js} +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-Bo_dmLv8.js → agent-avatar-dicebear-k039rbUz.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-kILWelNb.js → agent-defaults-settings-panel-D4J4oq8p.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agents-yuUn8n-f.js → agents-Bmth_bSQ.js} +1 -1
  10. package/dist/gateway/static/root/assets/{api-zxpcJfgj.js → api-2joIfbrH.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-Cz56nrVF.js → app-management-settings-panel-ByJ4kiD0.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-DxSws5U4.js → appearance-settings-BK2Jga-B.js} +1 -1
  13. package/dist/gateway/static/root/assets/apps-page-B3ky7cWU.js +1 -0
  14. package/dist/gateway/static/root/assets/{archive-plugin-7k15-hqo.js → archive-plugin-DMDKtYpi.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-B-SFpjd9.js → attachment-load-B764Ql3Z.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automations-page-Qy36j19q.js → automations-page-D-sO8CZe.js} +1 -1
  17. package/dist/gateway/static/root/assets/automations-workspace-Ds5-_-9z.js +6 -0
  18. package/dist/gateway/static/root/assets/{binary-plugins-CPOZQt8F.js → binary-plugins-fxtzYRpv.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-DhvVlIp9.js → block-editor-Bcjtvckh.js} +3 -3
  20. package/dist/gateway/static/root/assets/browser-automation-inputs-BSmnusjD.js +1 -0
  21. package/dist/gateway/static/root/assets/browser-automations-page-DC_OQIBk.js +3 -0
  22. package/dist/gateway/static/root/assets/browser-settings-page-C1FojyG6.js +3 -0
  23. package/dist/gateway/static/root/assets/capabilities-settings-panel-Bs59UCut.js +7 -0
  24. package/dist/gateway/static/root/assets/channels-settings-CM9vNmoo.js +1 -0
  25. package/dist/gateway/static/root/assets/{channels-status-swr-CX-yWwLD.js → channels-status-swr-BuWjIG_a.js} +1 -1
  26. package/dist/gateway/static/root/assets/{chat-terminal-dock-1PJoxRuV.js → chat-terminal-dock-5SevEo_I.js} +2 -2
  27. package/dist/gateway/static/root/assets/connectors-page-BPZ44D-V.js +2 -0
  28. package/dist/gateway/static/root/assets/{cron-expression-CBCc6zFA.js → cron-expression-DtsfalBM.js} +1 -1
  29. package/dist/gateway/static/root/assets/{date-picker-u8K5Kt_N.js → date-picker-tDEQV5TP.js} +1 -1
  30. package/dist/gateway/static/root/assets/{dependency-picker-y_i_cnpz.js → dependency-picker-HhNwg0Y2.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-DyL0JxLm.js → desktop-pet-acU4Li-C.js} +1 -1
  32. package/dist/gateway/static/root/assets/{desktop-pet-settings-d2d_IsyP.js → desktop-pet-settings-R84AR0Pe.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-DqIBKJwl.js → extension-debug-page-CrLlRkSN.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-DUW1xxj2.js → extension-page-BH5lmZXE.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-BHY9qaNw.js → extension-settings-page-BscjNAd1.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-swr-CMNbl0FZ.js → gateway-config-swr-9HidFZUd.js} +1 -1
  37. package/dist/gateway/static/root/assets/gateway-settings-BxLcW6ij.js +1 -0
  38. package/dist/gateway/static/root/assets/{gateway-startup-retry-CR7Xg8As.js → gateway-startup-retry-DRCPXONr.js} +1 -1
  39. package/dist/gateway/static/root/assets/{heartbeat-settings-7CD9iPR7.js → heartbeat-settings-K5Zhl2rx.js} +1 -1
  40. package/dist/gateway/static/root/assets/home-page-CZAg9RBv.js +1 -0
  41. package/dist/gateway/static/root/assets/{image-generation-api-C5mn73ca.js → image-generation-api-CR6Kle8H.js} +1 -1
  42. package/dist/gateway/static/root/assets/index-D4Ykja-U.js +72 -0
  43. package/dist/gateway/static/root/assets/index-zIJ3AXgR.css +2 -0
  44. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BtlqMleF.js → keyboard-shortcuts-settings-B1QR49-7.js} +1 -1
  45. package/dist/gateway/static/root/assets/{local-app-workbench-page-BjxfkjxE.js → local-app-workbench-page-wicoV-ti.js} +2 -2
  46. package/dist/gateway/static/root/assets/{local-apps-page-B7xqQe2s.js → local-apps-page-C74It-T8.js} +1 -1
  47. package/dist/gateway/static/root/assets/{locale-store-CF4erhjB.js → locale-store-BfZGZKSs.js} +1 -1
  48. package/dist/gateway/static/root/assets/{logs-page-kACaPZKL.js → logs-page-xX-7S49A.js} +2 -2
  49. package/dist/gateway/static/root/assets/{management-settings-A432siER.js → management-settings-1kNnYL97.js} +1 -1
  50. package/dist/gateway/static/root/assets/{markdown-view-CQvzsE24.js → markdown-view-DjiwT28p.js} +2 -2
  51. package/dist/gateway/static/root/assets/{media-plugins-CpvYiauZ.js → media-plugins-B5c0AoS1.js} +1 -1
  52. package/dist/gateway/static/root/assets/messages-DaIwVWar.js +3 -0
  53. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DyjVGngO.js → mobile-pairing-wizard-CsIZqK51.js} +1 -1
  54. package/dist/gateway/static/root/assets/note-detail-panel-CfWxopl4.js +5 -0
  55. package/dist/gateway/static/root/assets/notes-page-CYN-LCHJ.js +8 -0
  56. package/dist/gateway/static/root/assets/{page-tabs-B3FKzjR6.js → page-tabs-CqJN6Ljz.js} +1 -1
  57. package/dist/gateway/static/root/assets/{preview-open-alternatives-DnjrwAHD.js → preview-open-alternatives-DqRIGxf4.js} +1 -1
  58. package/dist/gateway/static/root/assets/{product-open-page-COcr_NUJ.js → product-open-page-DE2nPE_K.js} +1 -1
  59. package/dist/gateway/static/root/assets/project-detail-page-B5G3LzDq.js +1 -0
  60. package/dist/gateway/static/root/assets/{projects-page-BzH8pjEz.js → projects-page-CuVK2mKu.js} +1 -1
  61. package/dist/gateway/static/root/assets/{registry-api-BsRBlji7.js → registry-api-Bpy8XX-5.js} +1 -1
  62. package/dist/gateway/static/root/assets/remote-access-hub-Dnd73xWt.js +1 -0
  63. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-LO4wZ_dO.js → runtime-tools-settings-panel-Bb4b74-P.js} +2 -2
  64. package/dist/gateway/static/root/assets/{schema-form-crcj4-Pm.js → schema-form-DoPU5j3J.js} +1 -1
  65. package/dist/gateway/static/root/assets/sessions-page-XL4LyKZe.js +1 -0
  66. package/dist/gateway/static/root/assets/settings-advanced-gate-0ForzDSS.js +1 -0
  67. package/dist/gateway/static/root/assets/{settings-form-section-Bl4MvTmq.js → settings-form-section-Ci-9WajJ.js} +1 -1
  68. package/dist/gateway/static/root/assets/{settings-page-DplrjZ6x.js → settings-page-CL_2F95D.js} +1 -1
  69. package/dist/gateway/static/root/assets/setup-status-panel-DVws6XZc.js +1 -0
  70. package/dist/gateway/static/root/assets/{share-preview-page-CJP1kURj.js → share-preview-page-XUA3oKQX.js} +1 -1
  71. package/dist/gateway/static/root/assets/shares-settings-BwDvcacF.js +1 -0
  72. package/dist/gateway/static/root/assets/skill-reload-api-BJjrATqE.js +1 -0
  73. package/dist/gateway/static/root/assets/{skills-page-DsjcKg9Q.js → skills-page-sXXAZDc9.js} +1 -1
  74. package/dist/gateway/static/root/assets/{skills-page.utils-D6gWBbvy.js → skills-page.utils-DD79Bl1I.js} +1 -1
  75. package/dist/gateway/static/root/assets/{system-settings-panel-_eCXfqCo.js → system-settings-panel-BEH64qBV.js} +1 -1
  76. package/dist/gateway/static/root/assets/task-detail-page-0jxMi75O.js +1 -0
  77. package/dist/gateway/static/root/assets/{theme-store-BOgkc_9D.js → theme-store-CISSxU1c.js} +1 -1
  78. package/dist/gateway/static/root/assets/{tunnel-api-W5mktxl1.js → tunnel-api-DrKDhnJm.js} +1 -1
  79. package/dist/gateway/static/root/assets/{use-autosave-Na2DYzT3.js → use-autosave-CPYePL-Q.js} +1 -1
  80. package/dist/gateway/static/root/assets/user-model-page-B6zLDfDl.js +2 -0
  81. package/dist/gateway/static/root/assets/{voice-api-key-field-OXweUxS_.js → voice-api-key-field-DKqzrCXx.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-config-api-C-ryeIxj.js → voice-config-api-e9xWjwBX.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-BqOsO47I.js → work-discovery-overlay-kTQug6bq.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-B9S_lfT1.js → workflow-run-setup-panel-m9SKj_GT.js} +2 -2
  85. package/dist/gateway/static/root/assets/workflows-page-Bcd1XqP7.js +5 -0
  86. package/dist/gateway/static/root/index.html +10 -10
  87. package/dist/package.js +1 -1
  88. package/dist/packages/gateway-contract/src/new-session.js +9 -0
  89. package/dist/src/agent/agent-manager.d.ts +2 -1
  90. package/dist/src/agent/agent-manager.js +6 -5
  91. package/dist/src/agent/background-review/run-background-review.js +1 -1
  92. package/dist/src/agent/coding/repository-instructions.js +2 -2
  93. package/dist/src/agent/coding/workspace-revision.js +2 -2
  94. package/dist/src/agent/commands/command-isolation.js +2 -2
  95. package/dist/src/agent/embedded/model-runtime.js +1 -1
  96. package/dist/src/agent/embedded/run-for-session.js +1 -1
  97. package/dist/src/agent/external-tools/composio-provider.d.ts +1 -0
  98. package/dist/src/agent/external-tools/composio-provider.js +64 -34
  99. package/dist/src/agent/external-tools/search-error.js +5 -3
  100. package/dist/src/agent/image/tool-model-config.js +1 -1
  101. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  102. package/dist/src/agent/service.js +4 -3
  103. package/dist/src/agent/service.types.d.ts +2 -1
  104. package/dist/src/agent/session/session-inspector.js +1 -1
  105. package/dist/src/agent/skills/hub-lock.js +1 -1
  106. package/dist/src/agent/skills/marketplace/adapters/store/store-api-client.js +4 -0
  107. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  108. package/dist/src/agent/tool-manuals/browser.d.ts +1 -1
  109. package/dist/src/agent/tool-manuals/browser.js +15 -226
  110. package/dist/src/agent/tools/browser/tool/browser-use-tool.d.ts +4 -21
  111. package/dist/src/agent/tools/browser/tool/browser-use-tool.js +48 -165
  112. package/dist/src/agent/tools/browser/tool/schemas.d.ts +203 -16
  113. package/dist/src/agent/tools/browser/tool/schemas.js +146 -16
  114. package/dist/src/agent/tools/browser-automation-tool.d.ts +121 -0
  115. package/dist/src/agent/tools/browser-automation-tool.js +197 -0
  116. package/dist/src/agent/tools/factory.d.ts +6 -9
  117. package/dist/src/agent/tools/factory.js +28 -55
  118. package/dist/src/agent/tools/index.d.ts +2 -2
  119. package/dist/src/agent/tools/index.js +3 -3
  120. package/dist/src/agent/tools/review-workspace.js +2 -2
  121. package/dist/src/ai-assist/text-assist.js +1 -1
  122. package/dist/src/auth/credentials.js +2 -2
  123. package/dist/src/auth/oauth/xopc-cloud.js +3 -1
  124. package/dist/src/auth/profiles/store.js +1 -1
  125. package/dist/src/auth/sync-provider-auth.js +2 -2
  126. package/dist/src/automations/domain/defaults.js +1 -1
  127. package/dist/src/automations/domain/types.d.ts +5 -5
  128. package/dist/src/automations/domain/validation.d.ts +12 -12
  129. package/dist/src/automations/domain/validation.js +3 -3
  130. package/dist/src/automations/draft/automation-draft-validator.d.ts +3 -3
  131. package/dist/src/automations/draft/automation-draft-validator.js +1 -1
  132. package/dist/src/automations/service/action-executor.d.ts +1 -1
  133. package/dist/src/automations/service/action-executor.js +7 -7
  134. package/dist/src/browser/{recipes → automations}/index.d.ts +1 -0
  135. package/dist/src/browser/automations/index.js +4 -0
  136. package/dist/src/browser/automations/repository.d.ts +13 -0
  137. package/dist/src/browser/automations/repository.js +60 -0
  138. package/dist/src/browser/automations/runner.d.ts +17 -0
  139. package/dist/src/browser/automations/runner.js +173 -0
  140. package/dist/src/browser/automations/runtime-service.d.ts +6 -0
  141. package/dist/src/browser/automations/runtime-service.js +37 -0
  142. package/dist/src/browser/automations/schema.d.ts +144 -0
  143. package/dist/src/browser/automations/schema.js +135 -0
  144. package/dist/src/browser/automations/service.d.ts +146 -0
  145. package/dist/src/browser/automations/service.js +168 -0
  146. package/dist/src/browser/automations/types.d.ts +90 -0
  147. package/dist/src/browser/cache-dir-policy.d.ts +1 -1
  148. package/dist/src/browser/cache-dir-policy.js +1 -4
  149. package/dist/src/browser/drivers/browser-driver.d.ts +17 -0
  150. package/dist/src/browser/drivers/create-driver.d.ts +3 -0
  151. package/dist/src/browser/drivers/create-driver.js +84 -0
  152. package/dist/src/browser/drivers/extension-driver.d.ts +20 -0
  153. package/dist/src/browser/drivers/extension-driver.js +47 -0
  154. package/dist/src/browser/drivers/playwright-driver.d.ts +38 -0
  155. package/dist/src/browser/drivers/playwright-driver.js +406 -0
  156. package/dist/src/browser/index.d.ts +10 -15
  157. package/dist/src/browser/index.js +10 -15
  158. package/dist/src/browser/install-lock.d.ts +1 -2
  159. package/dist/src/browser/install-lock.js +3 -9
  160. package/dist/src/browser/install-progress.d.ts +1 -1
  161. package/dist/src/browser/observation/format.d.ts +2 -0
  162. package/dist/src/browser/observation/format.js +26 -0
  163. package/dist/src/browser/policy/approval-store.d.ts +17 -0
  164. package/dist/src/browser/policy/approval-store.js +62 -0
  165. package/dist/src/browser/policy/browser-policy.d.ts +3 -0
  166. package/dist/src/browser/policy/browser-policy.js +27 -0
  167. package/dist/src/browser/providers/browser-ext-install.d.ts +1 -1
  168. package/dist/src/browser/providers/browser-ext-install.js +4 -6
  169. package/dist/src/browser/providers/browser-use.js +1 -1
  170. package/dist/src/browser/providers/browserbase.js +1 -1
  171. package/dist/src/browser/providers/extension-ws-acquire.d.ts +1 -4
  172. package/dist/src/browser/providers/extension-ws-acquire.js +1 -13
  173. package/dist/src/browser/providers/extension.d.ts +3 -22
  174. package/dist/src/browser/providers/extension.js +7 -15
  175. package/dist/src/browser/providers/index.d.ts +2 -2
  176. package/dist/src/browser/providers/index.js +3 -3
  177. package/dist/src/browser/providers/types.d.ts +0 -94
  178. package/dist/src/browser/readiness.d.ts +4 -22
  179. package/dist/src/browser/readiness.js +55 -118
  180. package/dist/src/browser/runtime/browser-runtime.d.ts +30 -0
  181. package/dist/src/browser/runtime/browser-runtime.js +362 -0
  182. package/dist/src/browser/url-policy.d.ts +3 -3
  183. package/dist/src/browser/url-policy.js +7 -6
  184. package/dist/src/browser/verification/expectation.d.ts +2 -0
  185. package/dist/src/browser/verification/expectation.js +17 -0
  186. package/dist/src/cli/command-loaders.js +1 -0
  187. package/dist/src/cli/command-manifest.js +5 -1
  188. package/dist/src/cli/commands/browser-cli-helpers.d.ts +0 -6
  189. package/dist/src/cli/commands/browser-cli-helpers.js +11 -144
  190. package/dist/src/cli/commands/browser.d.ts +0 -5
  191. package/dist/src/cli/commands/browser.js +11 -152
  192. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  193. package/dist/src/cli/commands/doctor/checks/node-version.js +25 -9
  194. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  195. package/dist/src/cli/commands/models.js +1 -1
  196. package/dist/src/cli/commands/platform.d.ts +1 -0
  197. package/dist/src/cli/commands/platform.js +111 -0
  198. package/dist/src/config/index.js +4 -4
  199. package/dist/src/config/loader.js +10 -4
  200. package/dist/src/config/models-json.js +1 -1
  201. package/dist/src/config/schema.d.ts +131 -84
  202. package/dist/src/config/schema.js +112 -59
  203. package/dist/src/connectors/composio-sessions.js +1 -3
  204. package/dist/src/extensions/lockfile.js +1 -1
  205. package/dist/src/extensions/marketplace.js +4 -0
  206. package/dist/src/gateway/agents-admin.js +1 -1
  207. package/dist/src/gateway/file-path-classifier.js +1 -1
  208. package/dist/src/gateway/heartbeat/service.js +1 -1
  209. package/dist/src/gateway/hono/lib/config-payload.d.ts +12 -26
  210. package/dist/src/gateway/hono/lib/config-payload.js +11 -40
  211. package/dist/src/gateway/hono/routes/browser-automations.d.ts +3 -0
  212. package/dist/src/gateway/hono/routes/browser-automations.js +77 -0
  213. package/dist/src/gateway/hono/routes/browser-install.js +0 -32
  214. package/dist/src/gateway/hono/routes/browser.d.ts +0 -17
  215. package/dist/src/gateway/hono/routes/browser.js +46 -568
  216. package/dist/src/gateway/hono/routes/config-patch/misc.js +8 -1
  217. package/dist/src/gateway/hono/routes/config.js +0 -11
  218. package/dist/src/gateway/hono/routes/lazy-bundles.js +5 -5
  219. package/dist/src/gateway/hono/routes/models.js +1 -1
  220. package/dist/src/gateway/service/config-coordinator.js +1 -1
  221. package/dist/src/gateway/service.d.ts +4 -6
  222. package/dist/src/gateway/service.js +24 -27
  223. package/dist/src/heartbeat/index.js +1 -1
  224. package/dist/src/platform/client.d.ts +121 -0
  225. package/dist/src/platform/client.js +108 -0
  226. package/dist/src/platform/contracts.d.ts +194 -0
  227. package/dist/src/platform/contracts.js +150 -0
  228. package/dist/src/platform/index.d.ts +4 -0
  229. package/dist/src/platform/index.js +9 -0
  230. package/dist/src/platform/resolution.d.ts +4 -0
  231. package/dist/src/platform/resolution.js +16 -0
  232. package/dist/src/platform/worker.d.ts +6 -0
  233. package/dist/src/platform/worker.js +75 -0
  234. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  235. package/dist/src/providers/index.js +2 -2
  236. package/dist/src/providers/model-registry.js +1 -1
  237. package/dist/src/providers/register-runtime-providers.js +1 -1
  238. package/dist/src/providers/xopc-cloud-config.js +3 -1
  239. package/dist/src/session/session-context-for-llm.js +41 -1
  240. package/dist/src/share/hosted-session-share.js +3 -1
  241. package/dist/src/share/share-thumbnail.js +1 -1
  242. package/dist/src/storage/sqlite/migrations/153_browser_control_v2.sql +45 -0
  243. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  244. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  245. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  246. package/dist/src/storage/sqlite/schema.js +1 -1
  247. package/dist/src/storage/sqlite/schema.sql +16 -20
  248. package/dist/src/tasks/home-query-service.js +1 -1
  249. package/dist/src/tui/tui-startup-resources.js +1 -1
  250. package/dist/src/tui/tui.js +1 -1
  251. package/dist/src/tunnel/env.js +3 -1
  252. package/dist/src/work-discovery/service.js +1 -1
  253. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  254. package/package.json +6 -6
  255. package/dist/gateway/static/root/assets/apps-page-BnizTdgs.js +0 -1
  256. package/dist/gateway/static/root/assets/automations-workspace-CZRKqSqY.js +0 -6
  257. package/dist/gateway/static/root/assets/browser-settings-page-pN5LbChY.js +0 -8
  258. package/dist/gateway/static/root/assets/browser-workflow-inputs-BX1-uM9L.js +0 -1
  259. package/dist/gateway/static/root/assets/browser-workflows-page-C65MI57t.js +0 -3
  260. package/dist/gateway/static/root/assets/capabilities-settings-panel-CJw2e16J.js +0 -7
  261. package/dist/gateway/static/root/assets/channels-settings-CRgjb4Ck.js +0 -1
  262. package/dist/gateway/static/root/assets/connectors-page-Dcpdy06y.js +0 -2
  263. package/dist/gateway/static/root/assets/gateway-config-api-e3BRcgDx.js +0 -1
  264. package/dist/gateway/static/root/assets/gateway-settings-Cheo0Rkc.js +0 -1
  265. package/dist/gateway/static/root/assets/home-page-DVrTRqNc.js +0 -1
  266. package/dist/gateway/static/root/assets/index-B7CX4Qob.css +0 -2
  267. package/dist/gateway/static/root/assets/index-BHrpyJ4t.js +0 -72
  268. package/dist/gateway/static/root/assets/messages-Cf5hpZE6.js +0 -3
  269. package/dist/gateway/static/root/assets/note-detail-panel-CUd8O4K7.js +0 -5
  270. package/dist/gateway/static/root/assets/notes-page-BLQwd39W.js +0 -8
  271. package/dist/gateway/static/root/assets/project-detail-page-NttW338u.js +0 -1
  272. package/dist/gateway/static/root/assets/remote-access-hub-BxpjSDnL.js +0 -1
  273. package/dist/gateway/static/root/assets/sessions-page-BLMaibOb.js +0 -1
  274. package/dist/gateway/static/root/assets/settings-advanced-gate-BRvvKhoH.js +0 -1
  275. package/dist/gateway/static/root/assets/setup-status-panel-DTOsxQC1.js +0 -1
  276. package/dist/gateway/static/root/assets/shares-settings-CemgzEi4.js +0 -1
  277. package/dist/gateway/static/root/assets/skill-reload-api-BWYanBlQ.js +0 -1
  278. package/dist/gateway/static/root/assets/task-detail-page-D0Z_K5JT.js +0 -1
  279. package/dist/gateway/static/root/assets/user-model-page-B_-SNat-.js +0 -2
  280. package/dist/gateway/static/root/assets/workflows-page-CNOT2Coo.js +0 -5
  281. package/dist/src/agent/tools/browser-recipe-tool.d.ts +0 -12
  282. package/dist/src/agent/tools/browser-recipe-tool.js +0 -113
  283. package/dist/src/browser/actions/extension-registry-bridge.d.ts +0 -5
  284. package/dist/src/browser/actions/extension-registry-bridge.js +0 -312
  285. package/dist/src/browser/actions/registry.d.ts +0 -5
  286. package/dist/src/browser/actions/registry.js +0 -741
  287. package/dist/src/browser/actions/types.d.ts +0 -65
  288. package/dist/src/browser/backend-from-config.d.ts +0 -22
  289. package/dist/src/browser/backend-from-config.js +0 -99
  290. package/dist/src/browser/browser-command-timeout.d.ts +0 -2
  291. package/dist/src/browser/browser-command-timeout.js +0 -11
  292. package/dist/src/browser/cdp-local-launcher.d.ts +0 -35
  293. package/dist/src/browser/cdp-local-launcher.js +0 -154
  294. package/dist/src/browser/cdp-supervisor.d.ts +0 -58
  295. package/dist/src/browser/cdp-supervisor.js +0 -133
  296. package/dist/src/browser/humanize.d.ts +0 -80
  297. package/dist/src/browser/humanize.js +0 -363
  298. package/dist/src/browser/manager.d.ts +0 -50
  299. package/dist/src/browser/manager.js +0 -251
  300. package/dist/src/browser/pipeline/output.d.ts +0 -35
  301. package/dist/src/browser/pipeline/output.js +0 -74
  302. package/dist/src/browser/pipeline/runner.d.ts +0 -27
  303. package/dist/src/browser/pipeline/runner.js +0 -453
  304. package/dist/src/browser/pipeline/schema.d.ts +0 -42
  305. package/dist/src/browser/pipeline/schema.js +0 -116
  306. package/dist/src/browser/pipeline/template.d.ts +0 -30
  307. package/dist/src/browser/pipeline/template.js +0 -112
  308. package/dist/src/browser/providers/cloakbrowser.d.ts +0 -83
  309. package/dist/src/browser/providers/cloakbrowser.js +0 -612
  310. package/dist/src/browser/recipes/index.js +0 -3
  311. package/dist/src/browser/recipes/repository.d.ts +0 -13
  312. package/dist/src/browser/recipes/repository.js +0 -81
  313. package/dist/src/browser/recipes/runtime-service.d.ts +0 -6
  314. package/dist/src/browser/recipes/runtime-service.js +0 -30
  315. package/dist/src/browser/recipes/service.d.ts +0 -36
  316. package/dist/src/browser/recipes/service.js +0 -186
  317. package/dist/src/browser/recipes/types.d.ts +0 -36
  318. package/dist/src/browser/schemas.d.ts +0 -53
  319. package/dist/src/browser/schemas.js +0 -68
  320. package/dist/src/browser/session-lifecycle.d.ts +0 -40
  321. package/dist/src/browser/session-lifecycle.js +0 -136
  322. package/dist/src/browser/snapshot-helpers.d.ts +0 -24
  323. package/dist/src/browser/snapshot-helpers.js +0 -70
  324. package/dist/src/browser/stealth.d.ts +0 -46
  325. package/dist/src/browser/stealth.js +0 -163
  326. package/dist/src/gateway/hono/routes/browser-workflows.d.ts +0 -3
  327. package/dist/src/gateway/hono/routes/browser-workflows.js +0 -78
  328. /package/dist/src/browser/{actions → automations}/types.js +0 -0
  329. /package/dist/src/browser/{recipes/types.js → drivers/browser-driver.js} +0 -0
@@ -1,89 +1,29 @@
1
- import net from "node:net";
1
+ import { decideBrowserApproval, listBrowserApprovals } from "../../../browser/policy/approval-store.js";
2
+ import { isLoopbackClientIp } from "../../security/loopback.js";
3
+ import { getConnInfo } from "@hono/node-server/conninfo";
2
4
  //#region src/gateway/hono/routes/browser.ts
3
- const DEFAULT_EXTENSION_PORT = 19820;
4
- const DEFAULT_EXTENSION_HOST = "127.0.0.1";
5
- let manualExtensionHandle = null;
6
- function loopbackHostnameFromUrl(input) {
7
- let parsed;
5
+ /** Browser Control status, approvals, and driver diagnostics. */
6
+ const EXTENSION_ENDPOINT = "http://127.0.0.1:19820/";
7
+ function isLocalOwnerRequest(c, service) {
8
+ if (service.currentConfig.gateway?.bind === "loopback") return true;
8
9
  try {
9
- parsed = new URL(input);
10
+ return isLoopbackClientIp(getConnInfo(c).remote.address);
10
11
  } catch {
11
- return null;
12
+ return false;
12
13
  }
13
- const proto = parsed.protocol;
14
- if (proto !== "ws:" && proto !== "wss:" && proto !== "http:" && proto !== "https:") return null;
15
- const host = parsed.hostname.toLowerCase();
16
- if (host === "127.0.0.1" || host === "localhost" || host === "::1") return host;
17
- return null;
18
- }
19
- function isLoopbackHost(host) {
20
- const h = host.trim().toLowerCase();
21
- return h === "127.0.0.1" || h === "localhost" || h === "::1" || h === "[::1]";
22
- }
23
- function parseExtensionProbePort(raw) {
24
- if (!raw) return void 0;
25
- const n = Number.parseInt(raw, 10);
26
- if (!Number.isFinite(n) || n < 1024 || n > 65535) return void 0;
27
- return n;
28
- }
29
- function isLoopbackPortOpen(host, port, timeoutMs = 500) {
30
- return new Promise((resolve) => {
31
- const socket = net.connect({
32
- host,
33
- port
34
- });
35
- const finish = (open) => {
36
- socket.removeAllListeners();
37
- try {
38
- socket.destroy();
39
- } catch {}
40
- resolve(open);
41
- };
42
- socket.setTimeout(timeoutMs);
43
- socket.once("connect", () => finish(true));
44
- socket.once("timeout", () => finish(false));
45
- socket.once("error", () => finish(false));
46
- });
47
- }
48
- async function readExtensionBridgeSnapshot() {
49
- const { getExtensionBrowserServerSnapshot } = await import("../../../browser/providers/extension-ws-acquire.js");
50
- return getExtensionBrowserServerSnapshot();
51
- }
52
- async function stopExtensionBridgeFromSettings(service) {
53
- if (manualExtensionHandle) {
54
- try {
55
- await manualExtensionHandle.release();
56
- } catch {}
57
- manualExtensionHandle = null;
58
- }
59
- await service.releaseBrowserExtensionBridge();
60
- const { forceShutdownExtensionBrowserServer } = await import("../../../browser/providers/extension-ws-acquire.js");
61
- return { forcedShutdown: await forceShutdownExtensionBrowserServer() };
62
- }
63
- function resolveExtensionStatusTarget(browser, query) {
64
- const backend = typeof browser?.backend === "string" ? browser.backend : "extension";
65
- const probe = query.probe === "1" || query.probe === "true";
66
- if (!probe && backend !== "extension") return null;
67
- const ext = browser?.extension;
68
- const configPort = typeof ext?.port === "number" && ext.port >= 1024 && ext.port <= 65535 ? Math.floor(ext.port) : DEFAULT_EXTENSION_PORT;
69
- const configHost = typeof ext?.host === "string" && ext.host.trim() ? ext.host.trim() : DEFAULT_EXTENSION_HOST;
70
- const port = parseExtensionProbePort(query.port) ?? configPort;
71
- const host = typeof query.host === "string" && query.host.trim() ? query.host.trim() : configHost;
72
- if (!isLoopbackHost(host)) return null;
73
- return {
74
- host,
75
- port,
76
- backend: probe && backend !== "extension" ? "extension" : backend
77
- };
78
14
  }
79
15
  function registerBrowserRoutes(authenticated, deps) {
80
16
  const { service, strictRateLimitMiddleware } = deps;
81
17
  authenticated.get("/api/browser/extension-status", async (c) => {
82
- const target = resolveExtensionStatusTarget(void 0, {
83
- probe: c.req.query("probe"),
84
- host: c.req.query("host"),
85
- port: c.req.query("port")
86
- });
18
+ const { getExtensionBrowserServerSnapshot } = await import("../../../browser/providers/extension-ws-acquire.js");
19
+ const snapshot = getExtensionBrowserServerSnapshot();
20
+ let running = snapshot.active;
21
+ let connected = false;
22
+ try {
23
+ const payload = await (await fetch(EXTENSION_ENDPOINT, { signal: AbortSignal.timeout(2e3) })).json();
24
+ running ||= payload.ok === true;
25
+ connected = payload.connected === true;
26
+ } catch {}
87
27
  let artifacts;
88
28
  try {
89
29
  const { browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
@@ -97,518 +37,56 @@ function registerBrowserRoutes(authenticated, deps) {
97
37
  needsChromeReload: doctor.needsChromeReload
98
38
  };
99
39
  } catch {}
100
- if (!target) return c.json({
101
- running: false,
102
- connected: false,
103
- backend: "extension",
104
- artifacts
105
- });
106
- const snapshot = await readExtensionBridgeSnapshot();
107
- let probeRunning = false;
108
- let probeConnected = false;
109
- try {
110
- const data = await (await fetch(`http://${target.host}:${target.port}/`, { signal: AbortSignal.timeout(2e3) })).json();
111
- probeRunning = Boolean(data.ok);
112
- probeConnected = Boolean(data.connected);
113
- } catch {}
114
- const running = probeRunning || snapshot.active;
115
- const portConflict = !running && !snapshot.active ? await isLoopbackPortOpen(target.host, target.port) : false;
116
40
  return c.json({
117
41
  running,
118
- connected: probeConnected,
119
- backend: target.backend,
42
+ connected,
43
+ driverKind: "extension",
120
44
  artifacts,
121
45
  bridgeHeld: snapshot.active,
122
- refCount: snapshot.refCount,
123
- manualBridge: manualExtensionHandle !== null,
124
- portConflict
46
+ refCount: snapshot.refCount
125
47
  });
126
48
  });
127
- authenticated.get("/api/browser/extension/doctor", async (c) => {
128
- const cacheDirRaw = c.req.query("cacheDir");
129
- try {
130
- const { browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
131
- const status = await browserExtDoctor({ cacheDir: cacheDirRaw && cacheDirRaw.trim() ? cacheDirRaw.trim() : void 0 });
132
- return c.json({
133
- ok: true,
134
- payload: status
135
- });
136
- } catch (e) {
137
- const message = e instanceof Error ? e.message : String(e);
138
- return c.json({
139
- ok: false,
140
- error: message
141
- }, 400);
142
- }
143
- });
144
- authenticated.post("/api/browser/extension/install", strictRateLimitMiddleware, async (c) => {
145
- let body;
146
- try {
147
- body = await c.req.json();
148
- } catch {
149
- body = {};
150
- }
151
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
152
- const cacheDir = typeof input.cacheDir === "string" && input.cacheDir.trim() ? input.cacheDir.trim() : void 0;
153
- const force = input.force === true;
154
- try {
155
- const { ensureBrowserExtensionArtifacts, browserExtDoctor } = await import("../../../browser/providers/browser-ext-install.js");
156
- const result = await ensureBrowserExtensionArtifacts({
157
- cacheDir,
158
- force
159
- });
160
- const doctor = await browserExtDoctor({ cacheDir });
161
- return c.json({
162
- ok: true,
163
- payload: {
164
- ...result,
165
- doctor
166
- }
167
- });
168
- } catch (e) {
169
- const message = e instanceof Error ? e.message : String(e);
170
- return c.json({
171
- ok: false,
172
- error: message
173
- }, 500);
174
- }
175
- });
176
- authenticated.post("/api/browser/extension/open", strictRateLimitMiddleware, async (c) => {
177
- let body;
178
- try {
179
- body = await c.req.json();
180
- } catch {
181
- body = {};
182
- }
183
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
184
- const cacheDir = typeof input.cacheDir === "string" && input.cacheDir.trim() ? input.cacheDir.trim() : void 0;
185
- const actionRaw = typeof input.action === "string" ? input.action.trim() : "both";
186
- const action = actionRaw === "chrome" || actionRaw === "folder" || actionRaw === "both" ? actionRaw : "both";
187
- try {
188
- const { openBrowserExtensionInstallUi } = await import("../../../browser/providers/browser-ext-install.js");
189
- const result = await openBrowserExtensionInstallUi({
190
- action,
191
- cacheDir
192
- });
193
- return c.json({
194
- ok: true,
195
- payload: result
196
- });
197
- } catch (e) {
198
- const message = e instanceof Error ? e.message : String(e);
199
- return c.json({
200
- ok: false,
201
- error: message
202
- }, 500);
203
- }
204
- });
205
- authenticated.post("/api/browser/extension/start", strictRateLimitMiddleware, async (c) => {
206
- let body;
207
- try {
208
- body = await c.req.json();
209
- } catch {
210
- body = {};
211
- }
212
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
213
- const port = typeof input.port === "number" && input.port >= 1024 && input.port <= 65535 ? Math.floor(input.port) : DEFAULT_EXTENSION_PORT;
214
- const hostRaw = typeof input.host === "string" && input.host.trim() ? input.host.trim() : DEFAULT_EXTENSION_HOST;
215
- if (!isLoopbackHost(hostRaw)) return c.json({
49
+ authenticated.get("/api/browser/approvals", (c) => {
50
+ if (!isLocalOwnerRequest(c, service)) return c.json({
216
51
  ok: false,
217
- error: "extension bridge host must be loopback"
218
- }, 400);
219
- try {
220
- if (manualExtensionHandle && (manualExtensionHandle.host !== hostRaw || manualExtensionHandle.port !== port)) {
221
- await manualExtensionHandle.release();
222
- manualExtensionHandle = null;
223
- }
224
- if (!manualExtensionHandle) {
225
- const { acquireExtensionBrowserServer } = await import("../../../browser/providers/extension-ws-acquire.js");
226
- const { release } = await acquireExtensionBrowserServer({
227
- host: hostRaw,
228
- port
229
- });
230
- manualExtensionHandle = {
231
- release,
232
- host: hostRaw,
233
- port
234
- };
235
- }
236
- return c.json({
237
- ok: true,
238
- payload: {
239
- running: true,
240
- host: hostRaw,
241
- port
242
- }
243
- });
244
- } catch (e) {
245
- return c.json({
246
- ok: false,
247
- error: e instanceof Error ? e.message : String(e)
248
- }, 500);
249
- }
250
- });
251
- authenticated.post("/api/browser/extension/stop", strictRateLimitMiddleware, async (c) => {
252
- try {
253
- const { forcedShutdown } = await stopExtensionBridgeFromSettings(service);
254
- return c.json({
255
- ok: true,
256
- payload: {
257
- running: false,
258
- forcedShutdown
259
- }
260
- });
261
- } catch (e) {
262
- return c.json({
263
- ok: false,
264
- error: e instanceof Error ? e.message : String(e)
265
- }, 500);
266
- }
267
- });
268
- authenticated.post("/api/browser/extension/disconnect", strictRateLimitMiddleware, async (c) => {
269
- try {
270
- const { getExtensionBrowserProvider } = await import("../../../browser/providers/extension-ws-acquire.js");
271
- const provider = getExtensionBrowserProvider();
272
- if (!provider?.isConnected()) return c.json({
273
- ok: true,
274
- payload: {
275
- connected: false,
276
- alreadyDisconnected: true
277
- }
278
- });
279
- provider.disconnectClient();
280
- return c.json({
281
- ok: true,
282
- payload: { connected: false }
283
- });
284
- } catch (e) {
285
- return c.json({
286
- ok: false,
287
- error: e instanceof Error ? e.message : String(e)
288
- }, 500);
289
- }
290
- });
291
- authenticated.get("/api/browser/playwright/doctor", async (c) => {
292
- try {
293
- const { playwrightChromiumDoctor } = await import("../../../browser/providers/playwright-doctor.js");
294
- const payload = await playwrightChromiumDoctor();
295
- return c.json({
296
- ok: true,
297
- payload
298
- });
299
- } catch (e) {
300
- return c.json({
301
- ok: false,
302
- error: e instanceof Error ? e.message : String(e)
303
- }, 500);
304
- }
305
- });
306
- authenticated.get("/api/browser/cloakbrowser/doctor", async (c) => {
307
- const cacheDirRaw = c.req.query("cacheDir");
308
- const binaryPathRaw = c.req.query("binaryPath");
309
- try {
310
- const { cloakBrowserDoctor } = await import("../../../browser/providers/cloakbrowser.js");
311
- const status = await cloakBrowserDoctor({
312
- cacheDir: cacheDirRaw && cacheDirRaw.trim() ? cacheDirRaw.trim() : void 0,
313
- binaryPath: binaryPathRaw && binaryPathRaw.trim() ? binaryPathRaw.trim() : void 0
314
- });
315
- return c.json({
316
- ok: true,
317
- payload: status
318
- });
319
- } catch (e) {
320
- const message = e instanceof Error ? e.message : String(e);
321
- return c.json({
322
- ok: false,
323
- error: message
324
- }, 400);
325
- }
326
- });
327
- authenticated.get("/api/browser/cloakbrowser/status", async (c) => {
328
- try {
329
- const { cloakBrowserConfigFromAgentDefaults } = await import("../../../browser/backend-from-config.js");
330
- const { probeCloakBrowserRuntime } = await import("../../../browser/providers/cloakbrowser.js");
331
- const status = await probeCloakBrowserRuntime(cloakBrowserConfigFromAgentDefaults(service.currentConfig));
332
- return c.json({
333
- ok: true,
334
- payload: status
335
- });
336
- } catch (e) {
337
- const message = e instanceof Error ? e.message : String(e);
338
- return c.json({
339
- ok: false,
340
- error: message
341
- }, 500);
342
- }
343
- });
344
- authenticated.post("/api/browser/cloakbrowser/launch", strictRateLimitMiddleware, async (c) => {
345
- try {
346
- const { cloakBrowserConfigFromAgentDefaults } = await import("../../../browser/backend-from-config.js");
347
- const { launchCloakBrowser } = await import("../../../browser/providers/cloakbrowser.js");
348
- const config = cloakBrowserConfigFromAgentDefaults(service.currentConfig);
349
- const result = await launchCloakBrowser({
350
- ...config,
351
- skipPlaywrightConnect: true
352
- });
353
- return c.json({
354
- ok: true,
355
- payload: {
356
- running: true,
357
- reused: result.reused,
358
- port: result.cdpPort,
359
- pid: result.pid,
360
- userDataDir: result.userDataDir,
361
- temporaryProfile: config.temporaryProfile === true
362
- }
363
- });
364
- } catch (e) {
365
- const message = e instanceof Error ? e.message : String(e);
366
- return c.json({
367
- ok: false,
368
- error: message
369
- }, 500);
370
- }
371
- });
372
- authenticated.post("/api/browser/cdp/ping", strictRateLimitMiddleware, async (c) => {
373
- let body;
374
- try {
375
- body = await c.req.json();
376
- } catch {
377
- return c.json({
378
- ok: false,
379
- error: "invalid JSON body"
380
- }, 400);
381
- }
382
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
383
- const cdpUrl = typeof input.cdpUrl === "string" ? input.cdpUrl.trim() : "";
384
- if (!cdpUrl) return c.json({
385
- ok: false,
386
- error: "cdpUrl is required"
387
- }, 400);
388
- if (!loopbackHostnameFromUrl(cdpUrl)) return c.json({
389
- ok: false,
390
- error: "CDP ping only allowed for loopback hosts (127.0.0.1 / localhost / ::1)"
52
+ error: "Local owner access required."
391
53
  }, 403);
392
- let httpBase;
393
- try {
394
- httpBase = new URL(cdpUrl);
395
- httpBase.protocol = httpBase.protocol === "wss:" ? "https:" : "http:";
396
- httpBase.pathname = "/json/version";
397
- httpBase.search = "";
398
- httpBase.hash = "";
399
- } catch (e) {
400
- return c.json({
401
- ok: false,
402
- error: e instanceof Error ? e.message : "invalid cdpUrl"
403
- }, 400);
404
- }
405
- try {
406
- const res = await fetch(httpBase.toString(), { signal: AbortSignal.timeout(2e3) });
407
- if (!res.ok) return c.json({
408
- ok: true,
409
- payload: {
410
- reachable: false,
411
- status: res.status
412
- }
413
- });
414
- const data = await res.json();
415
- return c.json({
416
- ok: true,
417
- payload: {
418
- reachable: true,
419
- browser: data.Browser ?? null,
420
- protocolVersion: data["Protocol-Version"] ?? null,
421
- webSocketDebuggerUrl: data.webSocketDebuggerUrl ?? null
422
- }
423
- });
424
- } catch (e) {
425
- const message = e instanceof Error ? e.message : String(e);
426
- return c.json({
427
- ok: true,
428
- payload: {
429
- reachable: false,
430
- error: message
431
- }
432
- });
433
- }
434
- });
435
- authenticated.post("/api/browser/cdp/launch", strictRateLimitMiddleware, async (c) => {
436
- let body;
437
- try {
438
- body = await c.req.json();
439
- } catch {
440
- body = {};
441
- }
442
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
443
- const executablePath = typeof input.executablePath === "string" && input.executablePath.trim() ? input.executablePath.trim() : void 0;
444
- try {
445
- const { launchLocalCdpChrome } = await import("../../../browser/cdp-local-launcher.js");
446
- const result = await launchLocalCdpChrome({ executablePath });
447
- return c.json({
448
- ok: true,
449
- payload: result
450
- });
451
- } catch (e) {
452
- const message = e instanceof Error ? e.message : String(e);
453
- return c.json({
454
- ok: false,
455
- error: message
456
- }, 500);
457
- }
458
- });
459
- authenticated.post("/api/browser/cdp/stop", strictRateLimitMiddleware, async (c) => {
460
- let body;
461
- try {
462
- body = await c.req.json();
463
- } catch {
464
- return c.json({
465
- ok: false,
466
- error: "invalid JSON body"
467
- }, 400);
468
- }
469
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
470
- const port = typeof input.port === "number" && Number.isInteger(input.port) ? input.port : NaN;
471
- if (!Number.isFinite(port) || port < 1024 || port > 65535) return c.json({
472
- ok: false,
473
- error: "port must be an integer in [1024, 65535]"
474
- }, 400);
475
- const { stopLocalCdpChrome } = await import("../../../browser/cdp-local-launcher.js");
476
- const stopped = await stopLocalCdpChrome(port);
477
54
  return c.json({
478
55
  ok: true,
479
- payload: { stopped }
56
+ approvals: listBrowserApprovals(c.req.query("sessionKey"))
480
57
  });
481
58
  });
482
- authenticated.get("/api/browser/cdp/instances", async (c) => {
483
- const { listLocalCdpInstances } = await import("../../../browser/cdp-local-launcher.js");
59
+ authenticated.post("/api/browser/approvals/respond", strictRateLimitMiddleware, async (c) => {
60
+ if (!isLocalOwnerRequest(c, service)) return c.json({
61
+ ok: false,
62
+ error: "Local owner access required."
63
+ }, 403);
64
+ const body = await c.req.json().catch(() => null);
65
+ if (typeof body?.id !== "string" || body.decision !== "approved" && body.decision !== "denied") return c.json({
66
+ ok: false,
67
+ error: "id and decision are required."
68
+ }, 400);
69
+ const approval = decideBrowserApproval(body.id, body.decision);
70
+ if (!approval) return c.json({
71
+ ok: false,
72
+ error: "Approval not found."
73
+ }, 404);
484
74
  return c.json({
485
75
  ok: true,
486
- payload: { instances: listLocalCdpInstances() }
487
- });
488
- });
489
- authenticated.post("/api/browser/cloud/test-connection", strictRateLimitMiddleware, async (c) => {
490
- let body;
491
- try {
492
- body = await c.req.json();
493
- } catch {
494
- return c.json({
495
- ok: false,
496
- error: "invalid JSON body"
497
- }, 400);
498
- }
499
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
500
- const provider = input.provider;
501
- let apiKey = typeof input.apiKey === "string" ? input.apiKey.trim() : "";
502
- if (apiKey === "***" || apiKey === "••••••••••••") apiKey = "";
503
- if (!apiKey) {
504
- if (provider === "browserbase") apiKey = process.env.BROWSERBASE_API_KEY ?? "";
505
- else if (provider === "browser-use") apiKey = process.env.BROWSER_USE_API_KEY ?? "";
506
- }
507
- if (!apiKey) return c.json({
508
- ok: true,
509
- payload: {
510
- reachable: false,
511
- error: "No API key configured"
512
- }
76
+ approval
513
77
  });
514
- try {
515
- if (provider === "browserbase") {
516
- const res = await fetch("https://api.browserbase.com/v1/projects", {
517
- headers: { "x-bb-api-key": apiKey },
518
- signal: AbortSignal.timeout(5e3)
519
- });
520
- if (!res.ok) return c.json({
521
- ok: true,
522
- payload: {
523
- reachable: false,
524
- status: res.status,
525
- error: await res.text().catch(() => "")
526
- }
527
- });
528
- const data = await res.json().catch(() => null);
529
- const projects = Array.isArray(data) ? data : Array.isArray(data?.data) ? data.data : [];
530
- return c.json({
531
- ok: true,
532
- payload: {
533
- reachable: true,
534
- projectCount: projects.length
535
- }
536
- });
537
- }
538
- if (provider === "browser-use") {
539
- const res = await fetch("https://api.browser-use.com/api/v1/users/me", {
540
- headers: { Authorization: `Bearer ${apiKey}` },
541
- signal: AbortSignal.timeout(5e3)
542
- });
543
- if (!res.ok) return c.json({
544
- ok: true,
545
- payload: {
546
- reachable: false,
547
- status: res.status,
548
- error: await res.text().catch(() => "")
549
- }
550
- });
551
- return c.json({
552
- ok: true,
553
- payload: { reachable: true }
554
- });
555
- }
556
- return c.json({
557
- ok: false,
558
- error: "provider must be browserbase or browser-use"
559
- }, 400);
560
- } catch (e) {
561
- const message = e instanceof Error ? e.message : String(e);
562
- return c.json({
563
- ok: true,
564
- payload: {
565
- reachable: false,
566
- error: message
567
- }
568
- });
569
- }
570
- });
571
- authenticated.post("/api/browser/playwright/install", strictRateLimitMiddleware, async (c) => {
572
- try {
573
- const { installPlaywrightChromium } = await import("../../../browser/providers/playwright-install.js");
574
- const payload = await installPlaywrightChromium();
575
- return c.json({
576
- ok: true,
577
- payload
578
- });
579
- } catch (e) {
580
- const message = e instanceof Error ? e.message : String(e);
581
- return c.json({
582
- ok: false,
583
- error: message || "Failed to install Playwright Chromium"
584
- }, 500);
585
- }
586
78
  });
587
- authenticated.post("/api/browser/cloakbrowser/install", strictRateLimitMiddleware, async (c) => {
588
- let body;
589
- try {
590
- body = await c.req.json();
591
- } catch {
592
- body = {};
593
- }
594
- const input = body && typeof body === "object" && !Array.isArray(body) ? body : {};
595
- const cacheDir = typeof input.cacheDir === "string" && input.cacheDir.trim() ? input.cacheDir.trim() : void 0;
596
- const binaryPath = typeof input.binaryPath === "string" && input.binaryPath.trim() ? input.binaryPath.trim() : void 0;
79
+ authenticated.get("/api/browser/playwright/doctor", async (c) => {
597
80
  try {
598
- const { installCloakBrowser } = await import("../../../browser/providers/cloakbrowser.js");
599
- const status = await installCloakBrowser({
600
- cacheDir,
601
- binaryPath
602
- });
81
+ const { playwrightChromiumDoctor } = await import("../../../browser/providers/playwright-doctor.js");
603
82
  return c.json({
604
83
  ok: true,
605
- payload: status
84
+ payload: await playwrightChromiumDoctor()
606
85
  });
607
- } catch (e) {
608
- const message = e instanceof Error ? e.message : String(e);
86
+ } catch (error) {
609
87
  return c.json({
610
88
  ok: false,
611
- error: message
89
+ error: error instanceof Error ? error.message : String(error)
612
90
  }, 500);
613
91
  }
614
92
  });
@@ -126,7 +126,14 @@ async function applyMiscPatch(config, body) {
126
126
  }
127
127
  if (body.browser !== void 0) {
128
128
  if (typeof body.browser !== "object" || body.browser === null || Array.isArray(body.browser)) return patchError("browser must be an object");
129
- const parsed = BrowserConfigSchema.safeParse(body.browser);
129
+ const browserPatch = structuredClone(body.browser);
130
+ const driver = browserPatch.driver && typeof browserPatch.driver === "object" && !Array.isArray(browserPatch.driver) ? browserPatch.driver : void 0;
131
+ if (driver?.kind === "remote" && typeof driver.apiKey === "string" && isMaskedSecretPatchValue(driver.apiKey)) {
132
+ const currentKey = config.browser.driver.kind === "remote" ? config.browser.driver.apiKey : void 0;
133
+ if (currentKey) driver.apiKey = currentKey;
134
+ else delete driver.apiKey;
135
+ }
136
+ const parsed = BrowserConfigSchema.safeParse(browserPatch);
130
137
  if (!parsed.success) return patchError(parsed.error.issues.map((i) => i.message).join("; "));
131
138
  config.browser = parsed.data;
132
139
  }
@@ -116,17 +116,6 @@ function registerConfigRoutes(authenticated, deps) {
116
116
  */
117
117
  authenticated.post("/api/gateway/reveal-auth-secret/:field", strictRateLimitMiddleware, revealGatewayAuthSecretHandler);
118
118
  authenticated.post("/api/gateway/reveal-auth-secret", strictRateLimitMiddleware, revealGatewayAuthSecretHandler);
119
- /** POST /api/agents/browser/reveal-cloud-api-key — plaintext browser cloud apiKey from config only. */
120
- authenticated.post("/api/agents/browser/reveal-cloud-api-key", strictRateLimitMiddleware, async (c) => {
121
- const apiKey = service.currentConfig.browser?.cloud?.apiKey?.trim() || null;
122
- return c.json({
123
- ok: true,
124
- payload: {
125
- apiKey,
126
- source: apiKey ? "config" : "none"
127
- }
128
- });
129
- });
130
119
  /** POST /api/tools/web/reveal-search-api-key — plaintext search provider apiKey by index. */
131
120
  authenticated.post("/api/tools/web/reveal-search-api-key", strictRateLimitMiddleware, async (c) => {
132
121
  let index = -1;