browxai 0.7.0

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 (520) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/THIRD_PARTY_NOTICES.md +45 -0
  4. package/dist/cli/chrome.d.ts +1 -0
  5. package/dist/cli/chrome.js +130 -0
  6. package/dist/cli/command-registry.d.ts +15 -0
  7. package/dist/cli/command-registry.js +35 -0
  8. package/dist/cli/doctor-plugins.d.ts +18 -0
  9. package/dist/cli/doctor-plugins.js +338 -0
  10. package/dist/cli/doctor.d.ts +9 -0
  11. package/dist/cli/doctor.js +407 -0
  12. package/dist/cli/init.d.ts +1 -0
  13. package/dist/cli/init.js +200 -0
  14. package/dist/cli/register-commands.d.ts +1 -0
  15. package/dist/cli/register-commands.js +22 -0
  16. package/dist/cli/serve.d.ts +14 -0
  17. package/dist/cli/serve.js +151 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.js +129 -0
  20. package/dist/engine/adapters/adb.d.ts +72 -0
  21. package/dist/engine/adapters/adb.js +200 -0
  22. package/dist/engine/adapters/android-cdp.d.ts +54 -0
  23. package/dist/engine/adapters/android-cdp.js +110 -0
  24. package/dist/engine/adapters/android.engine.d.ts +1 -0
  25. package/dist/engine/adapters/android.engine.js +31 -0
  26. package/dist/engine/adapters/chromium.engine.d.ts +1 -0
  27. package/dist/engine/adapters/chromium.engine.js +44 -0
  28. package/dist/engine/adapters/firefox.engine.d.ts +1 -0
  29. package/dist/engine/adapters/firefox.engine.js +43 -0
  30. package/dist/engine/adapters/playwright-chromium.d.ts +43 -0
  31. package/dist/engine/adapters/playwright-chromium.js +56 -0
  32. package/dist/engine/adapters/playwright-firefox.d.ts +52 -0
  33. package/dist/engine/adapters/playwright-firefox.js +97 -0
  34. package/dist/engine/adapters/playwright-webkit.d.ts +40 -0
  35. package/dist/engine/adapters/playwright-webkit.js +79 -0
  36. package/dist/engine/adapters/safari/bidi-client.d.ts +46 -0
  37. package/dist/engine/adapters/safari/bidi-client.js +130 -0
  38. package/dist/engine/adapters/safari/launch.d.ts +56 -0
  39. package/dist/engine/adapters/safari/launch.js +104 -0
  40. package/dist/engine/adapters/safari/webdriver-client.d.ts +102 -0
  41. package/dist/engine/adapters/safari/webdriver-client.js +175 -0
  42. package/dist/engine/adapters/safari.engine.d.ts +1 -0
  43. package/dist/engine/adapters/safari.engine.js +52 -0
  44. package/dist/engine/adapters/safaridriver-hybrid.d.ts +56 -0
  45. package/dist/engine/adapters/safaridriver-hybrid.js +127 -0
  46. package/dist/engine/adapters/webkit.engine.d.ts +1 -0
  47. package/dist/engine/adapters/webkit.engine.js +47 -0
  48. package/dist/engine/capabilities.d.ts +53 -0
  49. package/dist/engine/capabilities.js +122 -0
  50. package/dist/engine/capability-registry.d.ts +9 -0
  51. package/dist/engine/capability-registry.js +20 -0
  52. package/dist/engine/index.d.ts +18 -0
  53. package/dist/engine/index.js +14 -0
  54. package/dist/engine/register-engines.d.ts +5 -0
  55. package/dist/engine/register-engines.js +16 -0
  56. package/dist/engine/registry.d.ts +145 -0
  57. package/dist/engine/registry.js +67 -0
  58. package/dist/engine/select.d.ts +48 -0
  59. package/dist/engine/select.js +128 -0
  60. package/dist/engine/session-cdp.d.ts +13 -0
  61. package/dist/engine/session-cdp.js +22 -0
  62. package/dist/engine/tool-gate.d.ts +19 -0
  63. package/dist/engine/tool-gate.js +226 -0
  64. package/dist/engine/types.d.ts +71 -0
  65. package/dist/engine/types.js +16 -0
  66. package/dist/helper/bridge.d.ts +48 -0
  67. package/dist/helper/bridge.js +200 -0
  68. package/dist/helper/browx-page.d.ts +1 -0
  69. package/dist/helper/browx-page.js +47 -0
  70. package/dist/helper/overlay-hide.d.ts +9 -0
  71. package/dist/helper/overlay-hide.js +49 -0
  72. package/dist/helper/stealth.d.ts +10 -0
  73. package/dist/helper/stealth.js +88 -0
  74. package/dist/index.d.ts +7 -0
  75. package/dist/index.js +15 -0
  76. package/dist/page/a11y.d.ts +81 -0
  77. package/dist/page/a11y.js +219 -0
  78. package/dist/page/action-substrate.d.ts +64 -0
  79. package/dist/page/action-substrate.js +118 -0
  80. package/dist/page/actionresult-blocks.d.ts +99 -0
  81. package/dist/page/actionresult-blocks.js +144 -0
  82. package/dist/page/actionresult-shape.d.ts +48 -0
  83. package/dist/page/actionresult-shape.js +155 -0
  84. package/dist/page/actionresult-types.d.ts +368 -0
  85. package/dist/page/actionresult-types.js +4 -0
  86. package/dist/page/actionresult.d.ts +4 -0
  87. package/dist/page/actionresult.js +299 -0
  88. package/dist/page/actions-probe.d.ts +32 -0
  89. package/dist/page/actions-probe.js +294 -0
  90. package/dist/page/actions-scroll.d.ts +40 -0
  91. package/dist/page/actions-scroll.js +53 -0
  92. package/dist/page/actions.d.ts +132 -0
  93. package/dist/page/actions.js +453 -0
  94. package/dist/page/archive-assets.d.ts +39 -0
  95. package/dist/page/archive-assets.js +187 -0
  96. package/dist/page/archive.d.ts +47 -0
  97. package/dist/page/archive.js +349 -0
  98. package/dist/page/asset-export.d.ts +122 -0
  99. package/dist/page/asset-export.js +376 -0
  100. package/dist/page/await_network.d.ts +16 -0
  101. package/dist/page/await_network.js +23 -0
  102. package/dist/page/bbox.d.ts +37 -0
  103. package/dist/page/bbox.js +115 -0
  104. package/dist/page/canvas-capture.d.ts +82 -0
  105. package/dist/page/canvas-capture.js +257 -0
  106. package/dist/page/canvas-diff.d.ts +51 -0
  107. package/dist/page/canvas-diff.js +131 -0
  108. package/dist/page/canvas-gesture.d.ts +53 -0
  109. package/dist/page/canvas-gesture.js +167 -0
  110. package/dist/page/canvas-transform.d.ts +96 -0
  111. package/dist/page/canvas-transform.js +150 -0
  112. package/dist/page/canvas.d.ts +8 -0
  113. package/dist/page/canvas.js +50 -0
  114. package/dist/page/capture-substrate.d.ts +111 -0
  115. package/dist/page/capture-substrate.js +139 -0
  116. package/dist/page/clipboard.d.ts +25 -0
  117. package/dist/page/clipboard.js +50 -0
  118. package/dist/page/clock.d.ts +36 -0
  119. package/dist/page/clock.js +167 -0
  120. package/dist/page/compose.d.ts +55 -0
  121. package/dist/page/compose.js +169 -0
  122. package/dist/page/console.d.ts +39 -0
  123. package/dist/page/console.js +73 -0
  124. package/dist/page/coverage.d.ts +97 -0
  125. package/dist/page/coverage.js +280 -0
  126. package/dist/page/dom-export.d.ts +41 -0
  127. package/dist/page/dom-export.js +193 -0
  128. package/dist/page/dom-walk.d.ts +91 -0
  129. package/dist/page/dom-walk.js +267 -0
  130. package/dist/page/dom_diff.d.ts +48 -0
  131. package/dist/page/dom_diff.js +121 -0
  132. package/dist/page/downloads.d.ts +80 -0
  133. package/dist/page/downloads.js +244 -0
  134. package/dist/page/drop-files.d.ts +78 -0
  135. package/dist/page/drop-files.js +310 -0
  136. package/dist/page/element-export-discovery.d.ts +64 -0
  137. package/dist/page/element-export-discovery.js +346 -0
  138. package/dist/page/element-export.d.ts +46 -0
  139. package/dist/page/element-export.js +251 -0
  140. package/dist/page/emulation-substrate.d.ts +53 -0
  141. package/dist/page/emulation-substrate.js +87 -0
  142. package/dist/page/emulation.d.ts +60 -0
  143. package/dist/page/emulation.js +162 -0
  144. package/dist/page/export-playwright-script.d.ts +47 -0
  145. package/dist/page/export-playwright-script.js +304 -0
  146. package/dist/page/extract-resolve.d.ts +22 -0
  147. package/dist/page/extract-resolve.js +341 -0
  148. package/dist/page/extract-schema.d.ts +20 -0
  149. package/dist/page/extract-schema.js +200 -0
  150. package/dist/page/extract-types.d.ts +127 -0
  151. package/dist/page/extract-types.js +8 -0
  152. package/dist/page/extract-warnings.d.ts +8 -0
  153. package/dist/page/extract-warnings.js +56 -0
  154. package/dist/page/extract.d.ts +9 -0
  155. package/dist/page/extract.js +174 -0
  156. package/dist/page/fill-form.d.ts +58 -0
  157. package/dist/page/fill-form.js +261 -0
  158. package/dist/page/find.d.ts +158 -0
  159. package/dist/page/find.js +470 -0
  160. package/dist/page/frames.d.ts +45 -0
  161. package/dist/page/frames.js +133 -0
  162. package/dist/page/generate-locator.d.ts +57 -0
  163. package/dist/page/generate-locator.js +136 -0
  164. package/dist/page/gestures.d.ts +128 -0
  165. package/dist/page/gestures.js +198 -0
  166. package/dist/page/har.d.ts +91 -0
  167. package/dist/page/har.js +174 -0
  168. package/dist/page/heap.d.ts +97 -0
  169. package/dist/page/heap.js +285 -0
  170. package/dist/page/inspect.d.ts +34 -0
  171. package/dist/page/inspect.js +75 -0
  172. package/dist/page/layout-thrash.d.ts +34 -0
  173. package/dist/page/layout-thrash.js +232 -0
  174. package/dist/page/learning.d.ts +21 -0
  175. package/dist/page/learning.js +84 -0
  176. package/dist/page/locator.d.ts +54 -0
  177. package/dist/page/locator.js +142 -0
  178. package/dist/page/memory-diff.d.ts +48 -0
  179. package/dist/page/memory-diff.js +105 -0
  180. package/dist/page/network-mask.d.ts +8 -0
  181. package/dist/page/network-mask.js +18 -0
  182. package/dist/page/network-playwright.d.ts +96 -0
  183. package/dist/page/network-playwright.js +353 -0
  184. package/dist/page/network-substrate-select.d.ts +18 -0
  185. package/dist/page/network-substrate-select.js +32 -0
  186. package/dist/page/network-substrate.d.ts +109 -0
  187. package/dist/page/network-substrate.js +161 -0
  188. package/dist/page/network-ws.d.ts +46 -0
  189. package/dist/page/network-ws.js +113 -0
  190. package/dist/page/network.d.ts +194 -0
  191. package/dist/page/network.js +415 -0
  192. package/dist/page/overflow-detect.d.ts +102 -0
  193. package/dist/page/overflow-detect.js +449 -0
  194. package/dist/page/pdf.d.ts +69 -0
  195. package/dist/page/pdf.js +109 -0
  196. package/dist/page/perf-audit-analysers.d.ts +40 -0
  197. package/dist/page/perf-audit-analysers.js +369 -0
  198. package/dist/page/perf-audit-runner.d.ts +20 -0
  199. package/dist/page/perf-audit-runner.js +195 -0
  200. package/dist/page/perf-audit-types.d.ts +41 -0
  201. package/dist/page/perf-audit-types.js +5 -0
  202. package/dist/page/perf-audit.d.ts +37 -0
  203. package/dist/page/perf-audit.js +377 -0
  204. package/dist/page/perf.d.ts +127 -0
  205. package/dist/page/perf.js +373 -0
  206. package/dist/page/plan.d.ts +192 -0
  207. package/dist/page/plan.js +308 -0
  208. package/dist/page/point_probe.d.ts +46 -0
  209. package/dist/page/point_probe.js +99 -0
  210. package/dist/page/recording.d.ts +67 -0
  211. package/dist/page/recording.js +172 -0
  212. package/dist/page/refs.d.ts +92 -0
  213. package/dist/page/refs.js +134 -0
  214. package/dist/page/regions.d.ts +23 -0
  215. package/dist/page/regions.js +32 -0
  216. package/dist/page/routes.d.ts +40 -0
  217. package/dist/page/routes.js +87 -0
  218. package/dist/page/safari-actions.d.ts +12 -0
  219. package/dist/page/safari-actions.js +144 -0
  220. package/dist/page/sample.d.ts +64 -0
  221. package/dist/page/sample.js +216 -0
  222. package/dist/page/screenshot-on.d.ts +51 -0
  223. package/dist/page/screenshot-on.js +150 -0
  224. package/dist/page/screenshot-save.d.ts +36 -0
  225. package/dist/page/screenshot-save.js +53 -0
  226. package/dist/page/screenshot-schedule.d.ts +50 -0
  227. package/dist/page/screenshot-schedule.js +155 -0
  228. package/dist/page/script-substrate.d.ts +32 -0
  229. package/dist/page/script-substrate.js +47 -0
  230. package/dist/page/seed-random.d.ts +45 -0
  231. package/dist/page/seed-random.js +144 -0
  232. package/dist/page/set-of-marks.d.ts +96 -0
  233. package/dist/page/set-of-marks.js +245 -0
  234. package/dist/page/shadow.d.ts +136 -0
  235. package/dist/page/shadow.js +400 -0
  236. package/dist/page/shortcut.d.ts +50 -0
  237. package/dist/page/shortcut.js +147 -0
  238. package/dist/page/snapshot-substrate-safari.d.ts +30 -0
  239. package/dist/page/snapshot-substrate-safari.js +84 -0
  240. package/dist/page/snapshot-substrate-select.d.ts +24 -0
  241. package/dist/page/snapshot-substrate-select.js +34 -0
  242. package/dist/page/snapshot-substrate.d.ts +58 -0
  243. package/dist/page/snapshot-substrate.js +135 -0
  244. package/dist/page/snapshot.d.ts +24 -0
  245. package/dist/page/snapshot.js +162 -0
  246. package/dist/page/solve-captcha.d.ts +76 -0
  247. package/dist/page/solve-captcha.js +286 -0
  248. package/dist/page/storage-substrate-types.d.ts +221 -0
  249. package/dist/page/storage-substrate-types.js +6 -0
  250. package/dist/page/storage-substrate.d.ts +215 -0
  251. package/dist/page/storage-substrate.js +280 -0
  252. package/dist/page/structural.d.ts +9 -0
  253. package/dist/page/structural.js +152 -0
  254. package/dist/page/substrate-bundle-safari.d.ts +8 -0
  255. package/dist/page/substrate-bundle-safari.js +42 -0
  256. package/dist/page/substrate-bundle.d.ts +6 -0
  257. package/dist/page/substrate-bundle.js +53 -0
  258. package/dist/page/text_search.d.ts +44 -0
  259. package/dist/page/text_search.js +90 -0
  260. package/dist/page/upload.d.ts +28 -0
  261. package/dist/page/upload.js +62 -0
  262. package/dist/page/verify.d.ts +63 -0
  263. package/dist/page/verify.js +451 -0
  264. package/dist/page/video.d.ts +115 -0
  265. package/dist/page/video.js +169 -0
  266. package/dist/page/visibility.d.ts +22 -0
  267. package/dist/page/visibility.js +94 -0
  268. package/dist/page/watch.d.ts +29 -0
  269. package/dist/page/watch.js +99 -0
  270. package/dist/page/workers.d.ts +126 -0
  271. package/dist/page/workers.js +490 -0
  272. package/dist/page/ws-interactive.d.ts +82 -0
  273. package/dist/page/ws-interactive.js +318 -0
  274. package/dist/plugin/cli.d.ts +45 -0
  275. package/dist/plugin/cli.js +496 -0
  276. package/dist/plugin/command-registry.d.ts +9 -0
  277. package/dist/plugin/command-registry.js +23 -0
  278. package/dist/plugin/depgraph.d.ts +37 -0
  279. package/dist/plugin/depgraph.js +186 -0
  280. package/dist/plugin/manifest.d.ts +182 -0
  281. package/dist/plugin/manifest.js +219 -0
  282. package/dist/plugin/package-manager.d.ts +22 -0
  283. package/dist/plugin/package-manager.js +40 -0
  284. package/dist/plugin/resolver.d.ts +85 -0
  285. package/dist/plugin/resolver.js +166 -0
  286. package/dist/plugin/runtime.d.ts +77 -0
  287. package/dist/plugin/runtime.js +402 -0
  288. package/dist/plugin/types.d.ts +113 -0
  289. package/dist/plugin/types.js +4 -0
  290. package/dist/policy/confirm.d.ts +76 -0
  291. package/dist/policy/confirm.js +162 -0
  292. package/dist/policy/origin.d.ts +17 -0
  293. package/dist/policy/origin.js +79 -0
  294. package/dist/sdk/client.d.ts +21 -0
  295. package/dist/sdk/client.js +174 -0
  296. package/dist/sdk/index.d.ts +32 -0
  297. package/dist/sdk/index.js +61 -0
  298. package/dist/sdk/plugin-types.d.ts +33 -0
  299. package/dist/sdk/plugin-types.js +22 -0
  300. package/dist/sdk/registry.d.ts +17 -0
  301. package/dist/sdk/registry.js +94 -0
  302. package/dist/sdk/socket-transport.d.ts +20 -0
  303. package/dist/sdk/socket-transport.js +90 -0
  304. package/dist/sdk/tool-types.d.ts +634 -0
  305. package/dist/sdk/tool-types.js +28 -0
  306. package/dist/sdk/transport-in-process.d.ts +21 -0
  307. package/dist/sdk/transport-in-process.js +44 -0
  308. package/dist/sdk/transport-registry.d.ts +19 -0
  309. package/dist/sdk/transport-registry.js +31 -0
  310. package/dist/sdk/transport-socket.d.ts +12 -0
  311. package/dist/sdk/transport-socket.js +77 -0
  312. package/dist/sdk/transport-stdio-child.d.ts +10 -0
  313. package/dist/sdk/transport-stdio-child.js +47 -0
  314. package/dist/sdk/transport.d.ts +10 -0
  315. package/dist/sdk/transport.js +35 -0
  316. package/dist/sdk/types.d.ts +176 -0
  317. package/dist/sdk/types.js +10 -0
  318. package/dist/server.d.ts +33 -0
  319. package/dist/server.js +327 -0
  320. package/dist/session/artifacts.d.ts +52 -0
  321. package/dist/session/artifacts.js +177 -0
  322. package/dist/session/byob-attach.d.ts +26 -0
  323. package/dist/session/byob-attach.js +187 -0
  324. package/dist/session/byob.d.ts +8 -0
  325. package/dist/session/byob.js +20 -0
  326. package/dist/session/cache-storage.d.ts +100 -0
  327. package/dist/session/cache-storage.js +166 -0
  328. package/dist/session/device-emu.d.ts +149 -0
  329. package/dist/session/device-emu.js +545 -0
  330. package/dist/session/device.d.ts +14 -0
  331. package/dist/session/device.js +44 -0
  332. package/dist/session/dialog.d.ts +62 -0
  333. package/dist/session/dialog.js +164 -0
  334. package/dist/session/emulation.d.ts +69 -0
  335. package/dist/session/emulation.js +168 -0
  336. package/dist/session/extensions.d.ts +113 -0
  337. package/dist/session/extensions.js +237 -0
  338. package/dist/session/fs-picker.d.ts +144 -0
  339. package/dist/session/fs-picker.js +666 -0
  340. package/dist/session/idb-storage.d.ts +86 -0
  341. package/dist/session/idb-storage.js +229 -0
  342. package/dist/session/incognito.d.ts +3 -0
  343. package/dist/session/incognito.js +20 -0
  344. package/dist/session/launch-options.d.ts +41 -0
  345. package/dist/session/launch-options.js +200 -0
  346. package/dist/session/managed.d.ts +3 -0
  347. package/dist/session/managed.js +16 -0
  348. package/dist/session/metrics.d.ts +45 -0
  349. package/dist/session/metrics.js +75 -0
  350. package/dist/session/notification.d.ts +122 -0
  351. package/dist/session/notification.js +426 -0
  352. package/dist/session/permission.d.ts +144 -0
  353. package/dist/session/permission.js +600 -0
  354. package/dist/session/playwright-post-wire.d.ts +8 -0
  355. package/dist/session/playwright-post-wire.js +148 -0
  356. package/dist/session/policy-buffer.d.ts +21 -0
  357. package/dist/session/policy-buffer.js +47 -0
  358. package/dist/session/profile-snapshot.d.ts +11 -0
  359. package/dist/session/profile-snapshot.js +53 -0
  360. package/dist/session/registry.d.ts +365 -0
  361. package/dist/session/registry.js +98 -0
  362. package/dist/session/safari-post-wire.d.ts +8 -0
  363. package/dist/session/safari-post-wire.js +28 -0
  364. package/dist/session/safari-session.d.ts +10 -0
  365. package/dist/session/safari-session.js +39 -0
  366. package/dist/session/storage.d.ts +148 -0
  367. package/dist/session/storage.js +350 -0
  368. package/dist/session/types.d.ts +113 -0
  369. package/dist/session/types.js +5 -0
  370. package/dist/session/wedge.d.ts +15 -0
  371. package/dist/session/wedge.js +41 -0
  372. package/dist/tools/action-core-tools.d.ts +13 -0
  373. package/dist/tools/action-core-tools.js +156 -0
  374. package/dist/tools/action-form-tools.d.ts +12 -0
  375. package/dist/tools/action-form-tools.js +179 -0
  376. package/dist/tools/action-gesture-tools.d.ts +9 -0
  377. package/dist/tools/action-gesture-tools.js +115 -0
  378. package/dist/tools/action-history-tools.d.ts +8 -0
  379. package/dist/tools/action-history-tools.js +67 -0
  380. package/dist/tools/action-tool.d.ts +42 -0
  381. package/dist/tools/action-tool.js +58 -0
  382. package/dist/tools/action-tools.d.ts +20 -0
  383. package/dist/tools/action-tools.js +28 -0
  384. package/dist/tools/batch-act-tools.d.ts +10 -0
  385. package/dist/tools/batch-act-tools.js +276 -0
  386. package/dist/tools/batch-human-tools.d.ts +8 -0
  387. package/dist/tools/batch-human-tools.js +148 -0
  388. package/dist/tools/canvas-tools.d.ts +40 -0
  389. package/dist/tools/canvas-tools.js +368 -0
  390. package/dist/tools/capture-report-diagnostics-tools.d.ts +7 -0
  391. package/dist/tools/capture-report-diagnostics-tools.js +318 -0
  392. package/dist/tools/capture-report-element-export-tools.d.ts +8 -0
  393. package/dist/tools/capture-report-element-export-tools.js +197 -0
  394. package/dist/tools/capture-report-export-tools.d.ts +8 -0
  395. package/dist/tools/capture-report-export-tools.js +246 -0
  396. package/dist/tools/capture-report-marks-tools.d.ts +9 -0
  397. package/dist/tools/capture-report-marks-tools.js +221 -0
  398. package/dist/tools/capture-report-upload-tools.d.ts +8 -0
  399. package/dist/tools/capture-report-upload-tools.js +277 -0
  400. package/dist/tools/config-approval-tools.d.ts +8 -0
  401. package/dist/tools/config-approval-tools.js +166 -0
  402. package/dist/tools/deep-coverage-tools.d.ts +8 -0
  403. package/dist/tools/deep-coverage-tools.js +325 -0
  404. package/dist/tools/deep-determinism-tools.d.ts +8 -0
  405. package/dist/tools/deep-determinism-tools.js +276 -0
  406. package/dist/tools/deep-perf-tools.d.ts +19 -0
  407. package/dist/tools/deep-perf-tools.js +324 -0
  408. package/dist/tools/device-emulation-tools.d.ts +9 -0
  409. package/dist/tools/device-emulation-tools.js +137 -0
  410. package/dist/tools/extensions-batch-tools.d.ts +18 -0
  411. package/dist/tools/extensions-batch-tools.js +24 -0
  412. package/dist/tools/extensions-rebuild.d.ts +22 -0
  413. package/dist/tools/extensions-rebuild.js +208 -0
  414. package/dist/tools/extensions-tools.d.ts +2 -0
  415. package/dist/tools/extensions-tools.js +331 -0
  416. package/dist/tools/forms-fill-tools.d.ts +8 -0
  417. package/dist/tools/forms-fill-tools.js +109 -0
  418. package/dist/tools/forms-plan-tools.d.ts +7 -0
  419. package/dist/tools/forms-plan-tools.js +159 -0
  420. package/dist/tools/forms-recording-mode-tools.d.ts +8 -0
  421. package/dist/tools/forms-recording-mode-tools.js +71 -0
  422. package/dist/tools/forms-recording-tools.d.ts +14 -0
  423. package/dist/tools/forms-recording-tools.js +22 -0
  424. package/dist/tools/forms-refs-tools.d.ts +8 -0
  425. package/dist/tools/forms-refs-tools.js +90 -0
  426. package/dist/tools/gesture-coord-tools.d.ts +8 -0
  427. package/dist/tools/gesture-coord-tools.js +168 -0
  428. package/dist/tools/gesture-emulation-tools.d.ts +8 -0
  429. package/dist/tools/gesture-emulation-tools.js +135 -0
  430. package/dist/tools/gesture-network-tools.d.ts +17 -0
  431. package/dist/tools/gesture-network-tools.js +27 -0
  432. package/dist/tools/gesture-route-tools.d.ts +8 -0
  433. package/dist/tools/gesture-route-tools.js +142 -0
  434. package/dist/tools/gesture-websocket-tools.d.ts +8 -0
  435. package/dist/tools/gesture-websocket-tools.js +122 -0
  436. package/dist/tools/gesture-worker-tools.d.ts +9 -0
  437. package/dist/tools/gesture-worker-tools.js +200 -0
  438. package/dist/tools/host-build.d.ts +76 -0
  439. package/dist/tools/host-build.js +516 -0
  440. package/dist/tools/host.d.ts +287 -0
  441. package/dist/tools/host.js +1 -0
  442. package/dist/tools/input-tools.d.ts +10 -0
  443. package/dist/tools/input-tools.js +176 -0
  444. package/dist/tools/live-emulation-tools.d.ts +9 -0
  445. package/dist/tools/live-emulation-tools.js +353 -0
  446. package/dist/tools/plugin-runtime.d.ts +36 -0
  447. package/dist/tools/plugin-runtime.js +274 -0
  448. package/dist/tools/read-observe-buffer-tools.d.ts +9 -0
  449. package/dist/tools/read-observe-buffer-tools.js +385 -0
  450. package/dist/tools/read-observe-capture-tools.d.ts +12 -0
  451. package/dist/tools/read-observe-capture-tools.js +376 -0
  452. package/dist/tools/read-observe-dom-tools.d.ts +8 -0
  453. package/dist/tools/read-observe-dom-tools.js +308 -0
  454. package/dist/tools/read-observe-extract-tools.d.ts +8 -0
  455. package/dist/tools/read-observe-extract-tools.js +232 -0
  456. package/dist/tools/read-observe-verify-tools.d.ts +8 -0
  457. package/dist/tools/read-observe-verify-tools.js +316 -0
  458. package/dist/tools/schemas.d.ts +29 -0
  459. package/dist/tools/schemas.js +58 -0
  460. package/dist/tools/secrets-captcha-tools.d.ts +9 -0
  461. package/dist/tools/secrets-captcha-tools.js +231 -0
  462. package/dist/tools/session-dialog-permission-tools.d.ts +9 -0
  463. package/dist/tools/session-dialog-permission-tools.js +287 -0
  464. package/dist/tools/session-lifecycle-tools.d.ts +8 -0
  465. package/dist/tools/session-lifecycle-tools.js +314 -0
  466. package/dist/tools/session-notification-device-tools.d.ts +9 -0
  467. package/dist/tools/session-notification-device-tools.js +156 -0
  468. package/dist/tools/session-policy-tools.d.ts +16 -0
  469. package/dist/tools/session-policy-tools.js +22 -0
  470. package/dist/tools/session-registry.d.ts +28 -0
  471. package/dist/tools/session-registry.js +427 -0
  472. package/dist/tools/storage-artifact-har-video-tools.d.ts +8 -0
  473. package/dist/tools/storage-artifact-har-video-tools.js +311 -0
  474. package/dist/tools/storage-cache-idb-tools.d.ts +8 -0
  475. package/dist/tools/storage-cache-idb-tools.js +347 -0
  476. package/dist/tools/storage-state-cookies-tools.d.ts +8 -0
  477. package/dist/tools/storage-state-cookies-tools.js +223 -0
  478. package/dist/tools/storage-tools.d.ts +17 -0
  479. package/dist/tools/storage-tools.js +25 -0
  480. package/dist/tools/storage-web-auth-tools.d.ts +10 -0
  481. package/dist/tools/storage-web-auth-tools.js +230 -0
  482. package/dist/tools/tool-metadata.d.ts +8 -0
  483. package/dist/tools/tool-metadata.js +185 -0
  484. package/dist/util/batch.d.ts +83 -0
  485. package/dist/util/batch.js +191 -0
  486. package/dist/util/capabilities.d.ts +504 -0
  487. package/dist/util/capabilities.js +254 -0
  488. package/dist/util/config-store.d.ts +103 -0
  489. package/dist/util/config-store.js +206 -0
  490. package/dist/util/config.d.ts +11 -0
  491. package/dist/util/config.js +28 -0
  492. package/dist/util/credentials.d.ts +136 -0
  493. package/dist/util/credentials.js +622 -0
  494. package/dist/util/deadline.d.ts +22 -0
  495. package/dist/util/deadline.js +62 -0
  496. package/dist/util/diagnostics.d.ts +161 -0
  497. package/dist/util/diagnostics.js +579 -0
  498. package/dist/util/egress-sanitiser.d.ts +29 -0
  499. package/dist/util/egress-sanitiser.js +52 -0
  500. package/dist/util/failure.d.ts +8 -0
  501. package/dist/util/failure.js +50 -0
  502. package/dist/util/flake-check.d.ts +109 -0
  503. package/dist/util/flake-check.js +342 -0
  504. package/dist/util/invariant.d.ts +25 -0
  505. package/dist/util/invariant.js +66 -0
  506. package/dist/util/logging.d.ts +6 -0
  507. package/dist/util/logging.js +12 -0
  508. package/dist/util/predicates.d.ts +62 -0
  509. package/dist/util/predicates.js +340 -0
  510. package/dist/util/secrets.d.ts +104 -0
  511. package/dist/util/secrets.js +219 -0
  512. package/dist/util/tokens.d.ts +6 -0
  513. package/dist/util/tokens.js +24 -0
  514. package/dist/util/url-sanitizer.d.ts +19 -0
  515. package/dist/util/url-sanitizer.js +70 -0
  516. package/dist/util/version.d.ts +2 -0
  517. package/dist/util/version.js +21 -0
  518. package/dist/util/workspace.d.ts +7 -0
  519. package/dist/util/workspace.js +22 -0
  520. package/package.json +120 -0
package/dist/server.js ADDED
@@ -0,0 +1,327 @@
1
+ // MCP server wiring. Tools are registered here; their implementations live in
2
+ // page/* and helper/*. stdout is the MCP channel — all logging goes via util/logging.ts.
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { resolveCredentialsProvider } from "./util/credentials.js";
6
+ import { resolveConfig } from "./util/config.js";
7
+ import { resolveWorkspace } from "./util/workspace.js";
8
+ import { DiagnosticsRecorder, ensureDiagnosticsRoot, resolveRetentionDays, sweepRetention, } from "./util/diagnostics.js";
9
+ import { ConfigStore, resolvedToEnv } from "./util/config-store.js";
10
+ import { resolveCapabilities, resolveConfirmHooks } from "./util/capabilities.js";
11
+ import { resolveOriginPolicy, describePolicy } from "./policy/origin.js";
12
+ import { ApprovalStore } from "./policy/confirm.js";
13
+ import { log } from "./util/logging.js";
14
+ import { PACKAGE_VERSION } from "./util/version.js";
15
+ import { buildHost } from "./tools/host-build.js";
16
+ import { registerActionTools } from "./tools/action-tools.js";
17
+ import { registerReadObserveDomTools } from "./tools/read-observe-dom-tools.js";
18
+ import { registerReadObserveExtractTools } from "./tools/read-observe-extract-tools.js";
19
+ import { registerReadObserveVerifyTools } from "./tools/read-observe-verify-tools.js";
20
+ import { registerReadObserveCaptureTools } from "./tools/read-observe-capture-tools.js";
21
+ import { registerReadObserveBufferTools } from "./tools/read-observe-buffer-tools.js";
22
+ import { registerGestureNetworkTools } from "./tools/gesture-network-tools.js";
23
+ import { registerDeepPerfTools } from "./tools/deep-perf-tools.js";
24
+ import { registerDeepCoverageTools } from "./tools/deep-coverage-tools.js";
25
+ import { registerDeepDeterminismTools } from "./tools/deep-determinism-tools.js";
26
+ import { registerCaptureReportMarksTools } from "./tools/capture-report-marks-tools.js";
27
+ import { registerCaptureReportDiagnosticsTools } from "./tools/capture-report-diagnostics-tools.js";
28
+ import { registerCaptureReportUploadTools } from "./tools/capture-report-upload-tools.js";
29
+ import { registerCaptureReportExportTools } from "./tools/capture-report-export-tools.js";
30
+ import { registerCaptureReportElementExportTools } from "./tools/capture-report-element-export-tools.js";
31
+ import { registerCanvasTools } from "./tools/canvas-tools.js";
32
+ import { registerStorageTools } from "./tools/storage-tools.js";
33
+ import { registerFormsRecordingTools } from "./tools/forms-recording-tools.js";
34
+ import { registerSessionPolicyTools } from "./tools/session-policy-tools.js";
35
+ import { registerDeviceEmulationTools } from "./tools/device-emulation-tools.js";
36
+ import { registerLiveEmulationTools } from "./tools/live-emulation-tools.js";
37
+ import { registerConfigApprovalTools } from "./tools/config-approval-tools.js";
38
+ import { registerSecretsCaptchaTools } from "./tools/secrets-captcha-tools.js";
39
+ import { registerInputTools } from "./tools/input-tools.js";
40
+ import { registerExtensionsBatchTools } from "./tools/extensions-batch-tools.js";
41
+ import { wirePluginRuntime } from "./tools/plugin-runtime.js";
42
+ import { buildSessionRegistry } from "./tools/session-registry.js";
43
+ // RFC 0004 P2 / D1 (SECURITY-CRITICAL): importing the tool-metadata bootstrap is a
44
+ // side effect that EAGERLY populates the derived `TOOL_CAPABILITY` / `DEEP_TOOLS`
45
+ // maps. `createServer` calls `resolveCapabilities` BEFORE its own tool
46
+ // registrations run; this import guarantees the maps are already populated at that
47
+ // point (and that the gate's fail-safe never trips for a server-built process),
48
+ // independent of whether the consumer reached us via the package entry.
49
+ import "./tools/tool-metadata.js";
50
+ // Shared input-schema fragments live in a leaf module so the per-family tool
51
+ // modules and this composition root depend on them without an import cycle.
52
+ import { SESSION_ARG, TIMEOUT_ARG, ACTION_OPTS, REF_OR_SELECTOR } from "./tools/schemas.js";
53
+ export const NAME = "browxai";
54
+ // Derived from package.json — see src/util/version.ts. Never hand-bump.
55
+ export const VERSION = PACKAGE_VERSION;
56
+ // Re-exported (imported at the top with the other tool modules) to preserve the
57
+ // existing public surface — the definitions now live in `tools/schemas`.
58
+ export { SESSION_ARG, TIMEOUT_ARG, ACTION_OPTS, REF_OR_SELECTOR };
59
+ /** structured one-liner alongside an element screenshot. Skips
60
+ * vision-reading when the agent only needs to confirm "yes the button is there." */
61
+ async function describeTarget(loc, refs, target) {
62
+ const bits = [];
63
+ let inputs;
64
+ if ("ref" in target && target.ref) {
65
+ inputs = refs.locatorOf(target.ref);
66
+ if (inputs) {
67
+ bits.push(inputs.role);
68
+ if (inputs.name)
69
+ bits.push(`"${inputs.name}"`);
70
+ if (inputs.testId)
71
+ bits.push(`[${inputs.testIdAttr ?? "data-testid"}="${inputs.testId}"]`);
72
+ }
73
+ else {
74
+ bits.push(`ref=${target.ref}`);
75
+ }
76
+ }
77
+ else if ("selector" in target && target.selector) {
78
+ bits.push(`selector=${target.selector}`);
79
+ }
80
+ else if ("coords" in target && target.coords) {
81
+ bits.push(`coords=${target.coords.x},${target.coords.y}`);
82
+ return bits.join(" "); // no Locator to probe further for coords targets
83
+ }
84
+ try {
85
+ const box = await loc.boundingBox();
86
+ if (box)
87
+ bits.push(`bbox=${Math.round(box.x)},${Math.round(box.y)} ${Math.round(box.width)}×${Math.round(box.height)}`);
88
+ const visible = await loc.isVisible().catch(() => undefined);
89
+ if (visible === false)
90
+ bits.push("not-visible");
91
+ const enabled = await loc.isEnabled().catch(() => undefined);
92
+ if (enabled === false)
93
+ bits.push("disabled");
94
+ }
95
+ catch {
96
+ /* skip — fall back to whatever we have */
97
+ }
98
+ return bits.join(" ");
99
+ }
100
+ function asTarget(args, toolName, refs) {
101
+ const provided = [args.ref, args.selector, args.named, args.coords].filter(Boolean).length;
102
+ if (provided > 1)
103
+ throw new Error(`${toolName}: pass exactly one of \`ref\` / \`selector\` / \`named\` / \`coords\``);
104
+ if (args.ref)
105
+ return { ref: args.ref };
106
+ if (args.named) {
107
+ const resolved = refs.refByNameLookup(args.named);
108
+ if (!resolved)
109
+ throw new Error(`${toolName}: name "${args.named}" not bound. Call name_ref({name, ref}) first.`);
110
+ return { ref: resolved };
111
+ }
112
+ if (args.selector) {
113
+ return args.contextRef
114
+ ? { selector: args.selector, contextRef: args.contextRef }
115
+ : { selector: args.selector };
116
+ }
117
+ if (args.coords)
118
+ return { coords: args.coords };
119
+ throw new Error(`${toolName}: requires one of \`ref\` (from find/snapshot), \`selector\`, \`named\`, or \`coords\``);
120
+ }
121
+ export async function createServer(opts = {}) {
122
+ // config flows through the browxai-managed ConfigStore (precedence
123
+ // defaults < env(legacy) < user < project < session). The existing env-driven
124
+ // resolvers consume the *resolved* chain re-expressed as an env shape, so
125
+ // precedence is centralised in the store without rewriting each resolver.
126
+ const workspace = resolveWorkspace();
127
+ const configStore = new ConfigStore(workspace.root);
128
+ const resolvedConfig = configStore.resolve();
129
+ const cfgEnv = resolvedToEnv(resolvedConfig);
130
+ const config = resolveConfig(cfgEnv);
131
+ // approvals are session-independent policy state — server-level.
132
+ const approvals = new ApprovalStore();
133
+ // policy: capabilities, confirm-required hooks, origin allow/blocklist.
134
+ const caps = resolveCapabilities(cfgEnv);
135
+ const confirmHooks = resolveConfirmHooks(cfgEnv);
136
+ const originPolicy = resolveOriginPolicy(cfgEnv);
137
+ const isByob = !!opts.attachCdp;
138
+ log.info("browxai: policy", {
139
+ capabilities: [...caps.enabled],
140
+ confirmHooks: [...confirmHooks],
141
+ origins: describePolicy(originPolicy),
142
+ });
143
+ for (const w of caps.warnings)
144
+ log.warn(`browxai: ${w}`);
145
+ if (caps.enabled.has("eval"))
146
+ log.warn("browxai: eval capability is ENABLED — `eval_js` will execute page-side JS. Return values are page-controlled.");
147
+ if (caps.enabled.has("network-body"))
148
+ log.warn("browxai: network-body capability is ENABLED — `network_body` returns full response bodies, which can carry PII / auth tokens. Off by default for a reason.");
149
+ if (caps.enabled.has("secrets"))
150
+ log.warn("browxai: secrets capability is ENABLED — `register_secret` accepts sensitive values; once a secret is registered the egress masking layer engages on every sink (ActionResult.network, network_read, network_body, ws_read, console_read, snapshot, find). `screenshot` is a partial sink — see docs/tool-reference.md.");
151
+ // Credentials provider: resolved once at server start. The provider object
152
+ // is constructed even when the capability is off so per-deployment config
153
+ // validation (unknown provider name → warn) happens up front. Per-call
154
+ // failures (missing CLI binary, missing seed, etc.) surface as structured
155
+ // refusals on the tool result — never crash startup.
156
+ const credentialsResolved = resolveCredentialsProvider(cfgEnv);
157
+ for (const w of credentialsResolved.config.warnings)
158
+ log.warn(`browxai: ${w}`);
159
+ if (caps.enabled.has("credentials")) {
160
+ log.warn(`browxai: credentials capability is ENABLED — \`get_totp\` / \`get_credential\` will shell out to the configured "${credentialsResolved.config.provider}" backend per call. NEVER bundled, NEVER auto-installed — the operator supplies the CLI / seeds out-of-band. \`get_credential\` ADDITIONALLY requires the \`secrets\` capability so the looked-up password is auto-registered into the per-session secrets registry under \`<PASSWORD_<account>>\` and masked across every egress sink (without \`secrets\`, the lookup refuses rather than leak cleartext). Same posture class as \`eval\` / \`network-body\` / \`secrets\`. See docs/threat-model.md.`);
161
+ }
162
+ if (caps.enabled.has("extensions"))
163
+ log.warn("browxai: extensions capability is ENABLED — `extensions_install` loads unpacked Chromium extensions into managed (headed, persistent) sessions. Loaded extensions can READ every page the session visits and make ARBITRARY network requests; treat the extension code itself as in-scope trust. Headed + persistent only — incognito / attached sessions refuse. install/reload/uninstall REBUILD the underlying browser context, invalidating refs + console/network buffers (profile state on disk survives). Same posture class as `eval` / `network-body` / `secrets` — see docs/threat-model.md.");
164
+ if (caps.enabled.has("stealth"))
165
+ log.warn("browxai: stealth capability is ENABLED — every session's context loads init-script patches that override `navigator.webdriver` / `navigator.plugins` / `navigator.languages` / `window.chrome` to defeat the common Playwright fingerprint surface. CIRCUMVENTING AUTOMATION DETECTION MAY VIOLATE A SITE'S TERMS OF SERVICE; the operator carries the legal exposure. browxai does NOT bundle a full anti-fingerprinting library — only the four well-known patches above. Same posture class as `eval` / `network-body` / `secrets` / `extensions` — see docs/threat-model.md.");
166
+ if (caps.enabled.has("device-emulation"))
167
+ log.warn("browxai: device-emulation capability is ENABLED — `emulate_bluetooth` / `emulate_usb` / `emulate_hid` install init-script wrappers around `navigator.bluetooth.requestDevice` / `navigator.usb.requestDevice` / `navigator.hid.requestDevice` so the page resolves with synthetic device objects the agent staged. THE PAGE WILL BELIEVE IT HAS ACCESS TO PHYSICAL DEVICES THAT DON'T EXIST. v1 covers the picker-clear path only — GATT service emulation (Bluetooth), USB transfer endpoints, and HID input/output reports are stubs (resolve with empty/zero-byte results). Same posture class as `eval` / `network-body` / `secrets` / `extensions` / `stealth` / `captcha` — see docs/threat-model.md.");
168
+ if (caps.enabled.has("canvas"))
169
+ log.warn("browxai: canvas capability is ENABLED — `canvas_capture` reads framebuffer / 2D ImageData pixel bytes off `<canvas>` elements (subject to the platform's canvas-taint rules for cross-origin sources); `gesture_chain` dispatches multi-step pointer programs (custom paint strokes, lasso paths); `canvas_world_to_screen` / `canvas_screen_to_world` probe common app-side globals heuristically (Figma / Tldraw / Excalidraw shapes) when no explicit transform is supplied — confirm on a known landmark before relying on the result. `canvas_query` dispatches to canvas-app adapter plugins; the inner plugin tool's capability is enforced via the plugin call-graph gate. browxai is BYO-vision — `canvas_capture` is the pixel source, not a vision call; composition with the host agent's own multimodal vision is the loop. Same posture class as `eval` / `network-body` / `secrets` / `extensions` / `device-emulation` / `diagnostics` — see docs/threat-model.md.");
170
+ if (caps.enabled.has("captcha"))
171
+ log.warn("browxai: captcha capability is ENABLED — `solve_captcha` will delegate challenges to the provider configured via BROWX_CAPTCHA_PROVIDER + BROWX_CAPTCHA_API_KEY. SOLVING CAPTCHAS MAY VIOLATE THE TARGET SITE'S TERMS OF SERVICE and (depending on jurisdiction) computer-misuse / unauthorised-access law; the operator carries the legal exposure. browxai does NOT bundle a solver and does NOT auto-purchase credits — the operator chooses a provider, funds the account, configures the server. Same posture class as `eval` / `network-body` / `secrets` / `extensions` / `stealth` — see docs/threat-model.md.");
172
+ // diagnostics recorder. Constructed eagerly so the dispatch
173
+ // wrapper can reference it; the `enabled` flag is what gates every
174
+ // actual side-effect. OFF → zero allocations beyond a gate check on
175
+ // every tool call.
176
+ const diagnosticsEnabled = caps.enabled.has("diagnostics");
177
+ const diagRetentionDays = resolveRetentionDays(cfgEnv);
178
+ if (diagnosticsEnabled) {
179
+ log.warn("browxai: diagnostics capability is ENABLED — every MCP tool call is " +
180
+ `recorded as a JSONL line under $BROWX_WORKSPACE/diagnostics/<sessionId>/<ISO>.jsonl ` +
181
+ `(retention: ${diagRetentionDays} days; configure via BROWX_DIAGNOSTICS_RETENTION_DAYS). ` +
182
+ "Args are structurally redacted (large/sensitive payload fields → sha256 + byteLength); " +
183
+ "the recorder runs DOWNSTREAM of the URL sanitiser + secrets-masking egress " +
184
+ "chokepoint, so registered secret values never reach the store raw. The agent " +
185
+ "self-feedback tool `diagnostics_note` ALSO requires this capability; read-side " +
186
+ "queries (`diagnostics_search`, `diagnostics_report`) ride the `read` capability " +
187
+ "so a report can be pulled even when no further notes are being filed. Same posture " +
188
+ "class as `eval` / `network-body` / `secrets` / `extensions` / `stealth` / `captcha` / " +
189
+ "`device-emulation`. See docs/threat-model.md.");
190
+ // Create the diagnostics root + run the retention sweep up-front so a
191
+ // long-idle workspace doesn't keep months of stale JSONL.
192
+ try {
193
+ ensureDiagnosticsRoot(workspace.root);
194
+ }
195
+ catch {
196
+ /* best-effort */
197
+ }
198
+ try {
199
+ sweepRetention(workspace.root, diagRetentionDays);
200
+ }
201
+ catch {
202
+ /* best-effort */
203
+ }
204
+ }
205
+ const diagnostics = new DiagnosticsRecorder({
206
+ enabled: diagnosticsEnabled,
207
+ workspaceRoot: workspace.root,
208
+ retentionDays: diagRetentionDays,
209
+ });
210
+ if (resolvedConfig.disableWebSecurity)
211
+ log.warn("browxai: disableWebSecurity is ENABLED — managed/incognito sessions launch with SOP/CORS OFF (--disable-web-security). Use only against test/dev targets.");
212
+ if (process.env.BROWX_EXTRACT_STRICT === "1")
213
+ log.warn("browxai: BROWX_EXTRACT_STRICT=1 — extract() unknown-`x-browx-source`-key warnings are PROMOTED to hard `ok:false` invalid-schema rejections (v0.2.2's partialMisses-only behavior is bypassed). The integer→number coerce and array-`selector`-as-`collection` alias are NOT promoted; only typo-like unknown-key diagnostics are.");
214
+ if (isByob && !caps.enabled.has("byob-attach")) {
215
+ log.warn("browxai: BROWX_ATTACH_CDP is set but `byob-attach` capability is disabled. Add `byob-attach` to BROWX_CAPABILITIES to use it.");
216
+ }
217
+ // per-session state lives in the SessionRegistry. The "default"
218
+ // session is created lazily on the first browser-touching tool call — so
219
+ // list_tools / discovery still don't launch a browser, and every existing
220
+ // caller that omits `session` keeps working unchanged.
221
+ // The engine every session this server opens runs on. Defaults to chromium;
222
+ // firefox + webkit + android are also wired (the launch path drives each via
223
+ // its adapter). A future-declared engine without an adapter is rejected
224
+ // (engine-not-yet-supported) — there is no silent fallback to chromium.
225
+ const serverEngine = opts.browserType ?? "chromium";
226
+ // The server-level launch mode: BYOB when BROWX_ATTACH_CDP is set, else
227
+ // persistent. android is ATTACH-ONLY (the user's real Chrome-on-Android over
228
+ // adb + CDP), so it defaults to "attached" with no BROWX_ATTACH_CDP
229
+ // (the endpoint is DISCOVERED over adb, not configured). This is the default a
230
+ // lazily-created session inherits; an explicit open_session can override per id.
231
+ const serverDefaultMode = serverEngine === "android" || opts.attachCdp ? "attached" : "persistent";
232
+ const registry = buildSessionRegistry({
233
+ opts,
234
+ resolvedConfig,
235
+ configStore,
236
+ caps,
237
+ workspace,
238
+ serverEngine,
239
+ serverDefaultMode,
240
+ });
241
+ const server = new McpServer({ name: NAME, version: VERSION }, { capabilities: { tools: {} } });
242
+ // Side-table of handler functions, populated as we register each tool. Lets
243
+ // the `batch` tool dispatch a whitelist of inner calls without going through
244
+ // the MCP transport. Each handler accepts the inner tool's args and returns
245
+ // the same `{ content: [...] }` shape an MCP call would. `ToolResponse` is the
246
+ // shared seam type (src/tools/host.ts) so extracted tool modules and the
247
+ // composition root agree on the envelope.
248
+ const toolHandlers = {};
249
+ // populated AFTER every core tool registration when the plugin
250
+ // runtime fires. Declared here so `get_config({scope:"resolved"})` can
251
+ // reference it via closure (registered before plugin loading runs).
252
+ let pluginRecords = [];
253
+ // The composition seam: bundle the shared state + helper closures into one
254
+ // host and hand it to each per-family tool module. createServer stays the
255
+ // registry composition root; the closures + host literal live in buildHost.
256
+ const host = buildHost({
257
+ server,
258
+ toolHandlers,
259
+ registry,
260
+ config,
261
+ configStore,
262
+ resolvedConfig,
263
+ caps,
264
+ confirmHooks,
265
+ originPolicy,
266
+ approvals,
267
+ isByob,
268
+ workspace,
269
+ diagnostics,
270
+ credentialsResolved,
271
+ pluginRecords: () => pluginRecords,
272
+ startOptions: opts,
273
+ describeTarget,
274
+ asTarget,
275
+ });
276
+ registerReadObserveDomTools(host);
277
+ registerReadObserveExtractTools(host);
278
+ registerReadObserveVerifyTools(host);
279
+ registerReadObserveCaptureTools(host);
280
+ registerReadObserveBufferTools(host);
281
+ registerActionTools(host);
282
+ registerGestureNetworkTools(host);
283
+ registerDeepPerfTools(host);
284
+ registerDeepCoverageTools(host);
285
+ registerDeepDeterminismTools(host);
286
+ registerCaptureReportMarksTools(host);
287
+ registerCaptureReportDiagnosticsTools(host);
288
+ registerCaptureReportUploadTools(host);
289
+ registerCaptureReportExportTools(host);
290
+ registerCaptureReportElementExportTools(host);
291
+ registerCanvasTools(host);
292
+ registerStorageTools(host);
293
+ registerFormsRecordingTools(host);
294
+ registerSessionPolicyTools(host);
295
+ registerDeviceEmulationTools(host);
296
+ registerLiveEmulationTools(host);
297
+ registerConfigApprovalTools(host);
298
+ registerSecretsCaptchaTools(host);
299
+ registerInputTools(host);
300
+ // The extensions + batch/compound-primitive family registers through the
301
+ // shared ToolHost seam. It MUST run before the coreToolNames capture below
302
+ // so its tools count as core (plugin runtime loads last).
303
+ registerExtensionsBatchTools(host);
304
+ // Plugin runtime wiring — the LAST registration step, run after every core
305
+ // `register*Tools(host)` call so the `coreToolNames` snapshot taken inside
306
+ // counts the full core surface as "core" and plugins load on top of it.
307
+ // Returns the loaded records; assigning them to the createServer `let`
308
+ // keeps `get_config` reporting the live enabled-plugin set via the host
309
+ // getter.
310
+ pluginRecords = await wirePluginRuntime(host, {
311
+ server,
312
+ noteMetrics: host.noteMetrics,
313
+ noteDiagnostics: host.noteDiagnostics,
314
+ });
315
+ return {
316
+ start: async () => {
317
+ const transport = new StdioServerTransport();
318
+ await server.connect(transport);
319
+ log.info("browxai: MCP server up on stdio");
320
+ },
321
+ shutdown: async () => {
322
+ await registry.closeAll();
323
+ await server.close().catch(() => undefined);
324
+ },
325
+ handlers: toolHandlers,
326
+ };
327
+ }
@@ -0,0 +1,52 @@
1
+ /** Max number of artifacts kept per session. Oldest-write evicted past this. */
2
+ export declare const ARTIFACT_MAX_ENTRIES = 200;
3
+ /** Max total bytes kept per session (50 MiB). Oldest-write evicted to fit. */
4
+ export declare const ARTIFACT_MAX_BYTES: number;
5
+ export type ArtifactEncoding = "utf8" | "base64";
6
+ /** What `artifact_list` returns per entry. */
7
+ export interface ArtifactInfo {
8
+ name: string;
9
+ /** size on disk, bytes. */
10
+ size: number;
11
+ /** ISO timestamp of last write. */
12
+ mtime: string;
13
+ }
14
+ /** Per-session artifact registry. One instance per SessionEntry. */
15
+ export declare class ArtifactsRegistry {
16
+ /** Per-session storage dir: `$BROWX_WORKSPACE/.artifacts/<sessionId>/`. */
17
+ readonly storageDir: string;
18
+ constructor(
19
+ /** Per-session storage dir: `$BROWX_WORKSPACE/.artifacts/<sessionId>/`. */
20
+ storageDir: string);
21
+ /** Resolve + workspace-escape-check the on-disk path for a name. The name
22
+ * is asserted via `assertSafeName` first (no separators / no `..` — the
23
+ * shared validator from storage.ts) PLUS a no-leading-dot guard added
24
+ * here so we never write a hidden file into the artifacts dir; the path
25
+ * is then re-resolved + checked it stays inside `storageDir` as defence
26
+ * in depth. */
27
+ pathFor(name: string): string;
28
+ /** Write an artifact. Overwrites an existing entry of the same name.
29
+ * Evicts oldest-write entries to stay under the capacity caps. */
30
+ save(name: string, content: string, encoding?: ArtifactEncoding): ArtifactInfo;
31
+ /** Read an artifact's bytes back. Throws if the name is unknown or the
32
+ * file vanished. */
33
+ get(name: string, encoding?: ArtifactEncoding): {
34
+ content: string;
35
+ size: number;
36
+ mtime: string;
37
+ encoding: ArtifactEncoding;
38
+ };
39
+ /** Enumerate every artifact in this session (sorted by name asc).
40
+ * Read-only; never throws on a single bad entry — skip unreadable. */
41
+ list(): ArtifactInfo[];
42
+ /** Best-effort wipe of the entire storage dir. Called on session
43
+ * teardown — every artifact written during the session is removed.
44
+ * Idempotent; ignores missing-dir. */
45
+ clear(): void;
46
+ /** Evict oldest-write entries until both the entry-count and total-byte
47
+ * caps are satisfied. Called after every save. */
48
+ private enforceCaps;
49
+ /** stat every entry, sorted by mtime ascending (oldest first). */
50
+ private statsByMtime;
51
+ private evict;
52
+ }
@@ -0,0 +1,177 @@
1
+ // Per-session artifact KV — session-scoped workspace primitives.
2
+ //
3
+ // First-class `save_artifact(name, content)` / `list_artifacts` /
4
+ // `load_artifact(name)` for the "build your own library over time" loop.
5
+ // Before this lane agents were forced to round-trip scripts/files/blobs
6
+ // through `name_ref`/`name_region` — both ref-typed and a poor fit for
7
+ // raw byte/string payloads.
8
+ //
9
+ // Design notes:
10
+ // - **Per-session.** Each `SessionEntry` owns one registry; entries
11
+ // don't cross sessions. Storage dir is
12
+ // `$BROWX_WORKSPACE/.artifacts/<sessionId>/`.
13
+ // - **Workspace-rooted paths only.** The name is restricted to a safe
14
+ // character set (no path separators, no leading dots, no `..`) — same
15
+ // posture as `assertSafeName` in `src/session/storage.ts`. Even with
16
+ // that, the composed path is re-resolved + workspace-escape-rejected
17
+ // defensively (defence in depth — `path/posix.join` with the workspace
18
+ // prefix).
19
+ // - **Cleared on session close.** Teardown wipes the whole
20
+ // `<sessionId>/` subdir; sessions that never wrote an artifact leave
21
+ // no trace.
22
+ // - **Capacity-bounded.** Max 200 entries AND 50 MiB total. Oldest-write
23
+ // evicted on overflow (per-name `mtime` ordering — LRU-by-write).
24
+ // - **Encoding.** `utf8` (default) treats `content` as text; `base64`
25
+ // decodes binary. Reads return the same encoding the caller wrote
26
+ // with — round-trip-faithful for both text and binary payloads.
27
+ // - **Capability split.** `artifact_save` → `action` (writes a file).
28
+ // `artifact_get` / `artifact_list` → `read`.
29
+ import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync, } from "node:fs";
30
+ import { join, resolve, sep } from "node:path";
31
+ import { assertSafeName } from "./storage.js";
32
+ /** Max number of artifacts kept per session. Oldest-write evicted past this. */
33
+ export const ARTIFACT_MAX_ENTRIES = 200;
34
+ /** Max total bytes kept per session (50 MiB). Oldest-write evicted to fit. */
35
+ export const ARTIFACT_MAX_BYTES = 50 * 1024 * 1024;
36
+ /** Per-session artifact registry. One instance per SessionEntry. */
37
+ export class ArtifactsRegistry {
38
+ storageDir;
39
+ constructor(
40
+ /** Per-session storage dir: `$BROWX_WORKSPACE/.artifacts/<sessionId>/`. */
41
+ storageDir) {
42
+ this.storageDir = storageDir;
43
+ }
44
+ /** Resolve + workspace-escape-check the on-disk path for a name. The name
45
+ * is asserted via `assertSafeName` first (no separators / no `..` — the
46
+ * shared validator from storage.ts) PLUS a no-leading-dot guard added
47
+ * here so we never write a hidden file into the artifacts dir; the path
48
+ * is then re-resolved + checked it stays inside `storageDir` as defence
49
+ * in depth. */
50
+ pathFor(name) {
51
+ assertSafeName("artifact name", name);
52
+ if (name.startsWith(".")) {
53
+ throw new Error(`artifact name "${name}" invalid — names cannot start with '.'`);
54
+ }
55
+ const target = join(this.storageDir, name);
56
+ const resolved = resolve(target);
57
+ const root = resolve(this.storageDir);
58
+ if (resolved !== root && !resolved.startsWith(root + sep)) {
59
+ throw new Error(`artifact name "${name}" resolved outside its session storage dir — refusing.`);
60
+ }
61
+ return resolved;
62
+ }
63
+ /** Write an artifact. Overwrites an existing entry of the same name.
64
+ * Evicts oldest-write entries to stay under the capacity caps. */
65
+ save(name, content, encoding = "utf8") {
66
+ const dest = this.pathFor(name);
67
+ // `storageDir` is workspace-rooted by construction — the SessionEntry
68
+ // factory sets it via `workspace.sub('.artifacts/<id>')` (see server.ts).
69
+ // `dest` is the asserted-safe-name joined to that storageDir, with the
70
+ // workspace-escape re-check in `pathFor`.
71
+ if (!existsSync(this.storageDir))
72
+ mkdirSync(this.storageDir, { recursive: true });
73
+ const buf = encoding === "base64" ? Buffer.from(content, "base64") : Buffer.from(content, "utf8");
74
+ // workspace.sub-rooted by construction (see comment above).
75
+ writeFileSync(dest, buf);
76
+ this.enforceCaps();
77
+ const st = statSync(dest);
78
+ return { name, size: st.size, mtime: new Date(st.mtimeMs).toISOString() };
79
+ }
80
+ /** Read an artifact's bytes back. Throws if the name is unknown or the
81
+ * file vanished. */
82
+ get(name, encoding = "utf8") {
83
+ const dest = this.pathFor(name);
84
+ if (!existsSync(dest)) {
85
+ throw new Error(`artifact_get: no artifact "${name}" in this session — call artifact_save({ name, content }) first.`);
86
+ }
87
+ const buf = readFileSync(dest);
88
+ const st = statSync(dest);
89
+ return {
90
+ content: encoding === "base64" ? buf.toString("base64") : buf.toString("utf8"),
91
+ size: st.size,
92
+ mtime: new Date(st.mtimeMs).toISOString(),
93
+ encoding,
94
+ };
95
+ }
96
+ /** Enumerate every artifact in this session (sorted by name asc).
97
+ * Read-only; never throws on a single bad entry — skip unreadable. */
98
+ list() {
99
+ if (!existsSync(this.storageDir))
100
+ return [];
101
+ const out = [];
102
+ for (const entry of readdirSync(this.storageDir)) {
103
+ const p = join(this.storageDir, entry);
104
+ try {
105
+ const st = statSync(p);
106
+ if (!st.isFile())
107
+ continue;
108
+ out.push({ name: entry, size: st.size, mtime: new Date(st.mtimeMs).toISOString() });
109
+ }
110
+ catch {
111
+ /* skip unreadable */
112
+ }
113
+ }
114
+ return out.sort((a, b) => a.name.localeCompare(b.name));
115
+ }
116
+ /** Best-effort wipe of the entire storage dir. Called on session
117
+ * teardown — every artifact written during the session is removed.
118
+ * Idempotent; ignores missing-dir. */
119
+ clear() {
120
+ try {
121
+ if (existsSync(this.storageDir))
122
+ rmSync(this.storageDir, { recursive: true, force: true });
123
+ }
124
+ catch {
125
+ /* best-effort cleanup */
126
+ }
127
+ }
128
+ // ---- capacity enforcement -------------------------------------------------
129
+ /** Evict oldest-write entries until both the entry-count and total-byte
130
+ * caps are satisfied. Called after every save. */
131
+ enforceCaps() {
132
+ const entries = this.statsByMtime();
133
+ // entry-count cap
134
+ while (entries.length > ARTIFACT_MAX_ENTRIES) {
135
+ const victim = entries.shift();
136
+ if (!victim)
137
+ break;
138
+ this.evict(victim.path);
139
+ }
140
+ // byte cap
141
+ let totalBytes = entries.reduce((s, e) => s + e.size, 0);
142
+ while (totalBytes > ARTIFACT_MAX_BYTES) {
143
+ const victim = entries.shift();
144
+ if (!victim)
145
+ break;
146
+ this.evict(victim.path);
147
+ totalBytes -= victim.size;
148
+ }
149
+ }
150
+ /** stat every entry, sorted by mtime ascending (oldest first). */
151
+ statsByMtime() {
152
+ if (!existsSync(this.storageDir))
153
+ return [];
154
+ const out = [];
155
+ for (const name of readdirSync(this.storageDir)) {
156
+ const p = join(this.storageDir, name);
157
+ try {
158
+ const st = statSync(p);
159
+ if (!st.isFile())
160
+ continue;
161
+ out.push({ path: p, size: st.size, mtimeMs: st.mtimeMs });
162
+ }
163
+ catch {
164
+ /* skip */
165
+ }
166
+ }
167
+ return out.sort((a, b) => a.mtimeMs - b.mtimeMs);
168
+ }
169
+ evict(p) {
170
+ try {
171
+ rmSync(p, { force: true });
172
+ }
173
+ catch {
174
+ /* best-effort */
175
+ }
176
+ }
177
+ }
@@ -0,0 +1,26 @@
1
+ import type { BrowserSession, SessionOptions } from "./types.js";
2
+ /** Android BYOB — discover real Chrome-on-Android over adb + CDP and attach.
3
+ * Distinct from the desktop URL-attach path: the endpoint is DISCOVERED
4
+ * (adb forward → /json/version → wsUrl), not configured. The forwarded socket is
5
+ * loopback by construction (adb forwards to 127.0.0.1), so the same not-owned
6
+ * policy applies; close additionally removes the adb forward. Full CDP, so the
7
+ * session carries `cdp()` and the substrates pick the CDP path automatically. */
8
+ export declare function openAndroidByobSession(): Promise<BrowserSession>;
9
+ /** Assert the BYOB attach endpoint is present + loopback, returning it as a
10
+ * string. The firefox / webkit engine modules call this before surfacing their
11
+ * structured attach refusal, preserving the EXACT pre-relocation order (the
12
+ * `!attachCdp` throw, then the loopback assertion, then the per-engine refusal).
13
+ * Shared so the loopback policy lives in one place. */
14
+ export declare function assertByobAttach(opts: SessionOptions & {
15
+ attachCdp?: string;
16
+ }): string;
17
+ /** The Chromium CDP-attach (BYOB) lane — the desktop URL-attach path, extracted
18
+ * verbatim from the old `openByobSession` chromium body. Asserts the loopback
19
+ * endpoint, attaches over CDP, ensures a usable viewport, and builds the
20
+ * not-owned `BrowserSession`. The chromium engine module's `makeAdapter` byob
21
+ * branch calls this; firefox/webkit/safari surface their own structured attach
22
+ * refusals from their own engine modules, and android attaches over adb via
23
+ * `openAndroidByobSession` — so no engine-name branch survives here. */
24
+ export declare function attachByobChromium(opts: SessionOptions & {
25
+ attachCdp?: string;
26
+ }): Promise<BrowserSession>;