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
@@ -0,0 +1,516 @@
1
+ import { z } from "zod";
2
+ import { assertEngineSupports } from "../engine/index.js";
3
+ import { DEFAULT_SESSION_ID, } from "../session/registry.js";
4
+ import { clampTimeout, withDeadline, DEFAULT_ACTION_TIMEOUT_MS } from "../util/deadline.js";
5
+ import { estimateTokens } from "../util/tokens.js";
6
+ import { invariant } from "../util/invariant.js";
7
+ import { buildEvalJsCapture, redactArgs, } from "../util/diagnostics.js";
8
+ import { engineEntry } from "../engine/registry.js";
9
+ import { EgressSanitiser } from "../util/egress-sanitiser.js";
10
+ import { screenshotSave } from "../page/screenshot-save.js";
11
+ import { isToolEnabled, declareToolCapability, toolCapabilityMap, } from "../util/capabilities.js";
12
+ import { declareDeepTool } from "../engine/tool-gate.js";
13
+ /**
14
+ * The composition heart: assemble the shared helper closures + the `ToolHost`
15
+ * literal `createServer` hands to each `registerXxxTools(host)` module. Every
16
+ * closure body is byte-identical to the inline `createServer` version; the
17
+ * createServer locals they close over arrive through `deps`, and the
18
+ * intra-block references between closures (register → noteWedgeOutcome, the
19
+ * `*For` ports → ctxFor, …) stay as-is because they all move together.
20
+ */
21
+ export function buildHost(deps) {
22
+ const { server, toolHandlers, registry, config, configStore, resolvedConfig, caps, confirmHooks, originPolicy, approvals, isByob, workspace, diagnostics, credentialsResolved, pluginRecords, startOptions, describeTarget, asTarget, } = deps;
23
+ const entryFor = (sessionId) => registry.get(sessionId ?? DEFAULT_SESSION_ID);
24
+ const confirmCtxFor = (e) => ({
25
+ hooks: confirmHooks,
26
+ policy: originPolicy,
27
+ bridge: e.bridge,
28
+ isByob,
29
+ approvals,
30
+ });
31
+ /** Disabled-tool early-return shape. Used at the top of each handler:
32
+ * const g = gateCheck("foo"); if (g) return g;
33
+ * Returns null when the tool is enabled (handler proceeds). */
34
+ const gateCheck = (toolName) => {
35
+ if (isToolEnabled(toolName, caps))
36
+ return null;
37
+ return {
38
+ content: [
39
+ {
40
+ type: "text",
41
+ text: JSON.stringify({
42
+ ok: false,
43
+ error: `tool "${toolName}" is disabled — its capability is not in the server's ACTIVE set`,
44
+ requiredCapability: toolCapabilityMap().get(toolName) ?? null,
45
+ activeCapabilities: [...caps.enabled],
46
+ hint: "This tool's capability (`requiredCapability` above) is not in the server's active set. Fix: add it to `BROWX_CAPABILITIES` (or the `capabilities` config), then RESTART the browxai server — capabilities are resolved ONCE at server start, so `set_config` alone won't enable it. Two gotchas if it still doesn't take after a restart: (1) a persisted `set_config({capabilities})` layer REPLACES the BROWX_CAPABILITIES env value entirely (arrays don't merge), so a patch that omits this capability silently overrides the env var — include every capability you want, not just this one; (2) `get_config({scope:\"resolved\"}).capabilities` is the *live enforced* set (what this gate checks). See docs/threat-model.md.",
47
+ }, null, 2),
48
+ },
49
+ ],
50
+ };
51
+ };
52
+ /** Engine-dimension early-return shape — the headline of the multi-engine
53
+ * work. Composes with `gateCheck` (capability dimension): after the tool's
54
+ * capability is confirmed active and the session is resolved, this refuses a
55
+ * CDP-deep tool (audit class B + the live-CDP class-C tools) on an engine
56
+ * that declares no `deep` escape hatch (firefox), with a structured hint —
57
+ * the same refusal-with-hint pattern `pdf_save`-on-BYOB uses. Returns null
58
+ * when the engine supports the tool (the fast path on chromium and for every
59
+ * cross-browser tool).
60
+ *
61
+ * const eg = engineGate("perf_start", e); if (eg) return eg;
62
+ */
63
+ const engineGate = (toolName, e) => {
64
+ const refusal = assertEngineSupports(toolName, e.session.engine);
65
+ if (!refusal)
66
+ return null;
67
+ const body = {
68
+ ok: false,
69
+ error: refusal.error,
70
+ engine: e.session.engine,
71
+ hint: refusal.hint,
72
+ };
73
+ return {
74
+ content: [
75
+ {
76
+ type: "text",
77
+ text: JSON.stringify({ ...body, tokensEstimate: estimateTokens(JSON.stringify(body)) }, null, 2),
78
+ },
79
+ ],
80
+ };
81
+ };
82
+ /** Confirm-hook early-return helper. Returns the rejection content if denied, else null. */
83
+ const denyContent = (toolName, decision) => ({
84
+ content: [
85
+ {
86
+ type: "text",
87
+ text: JSON.stringify({
88
+ ok: false,
89
+ action: { type: toolName },
90
+ error: `policy: ${decision.reason}`,
91
+ hint: "This is NOT a human-approval wall and NOT a selector failure. As an MCP client, call `approve_actions({ scopes:[…], ttlSeconds })` once at session start to enable action tools for the session (e.g. scopes:[\"byob_action\"]). Alternatives: remove the entry from BROWX_CONFIRM_REQUIRED, or a human responds `true` to the page-side confirm. Don't mark the feature unverified — it's gated, not broken.",
92
+ }, null, 2),
93
+ },
94
+ ],
95
+ });
96
+ /** Reconstruct a `selectorHint` string the recorder can write into a flow file
97
+ * YAML. Mirrors `buildSelectorHint` for `ref`/`named`; passes through `selector`. */
98
+ const hintFromTarget = (e, target) => {
99
+ // Coords targets don't correspond to a stable locator the recorder can replay —
100
+ // skip the hint and let the recording layer omit the step's target metadata.
101
+ if (target.coords)
102
+ return undefined;
103
+ if (target.selector)
104
+ return { selectorHint: target.selector };
105
+ let ref = target.ref;
106
+ if (target.named)
107
+ ref = e.refs.refByNameLookup(target.named);
108
+ if (!ref)
109
+ return undefined;
110
+ const inputs = e.refs.locatorOf(ref);
111
+ if (!inputs)
112
+ return undefined;
113
+ if (inputs.testId) {
114
+ const attr = inputs.testIdAttr ?? "data-testid";
115
+ return { selectorHint: `[${attr}="${inputs.testId}"]`, stability: "high" };
116
+ }
117
+ if (inputs.name)
118
+ return { selectorHint: `role=${inputs.role}[name="${inputs.name}"]`, stability: "medium" };
119
+ return { selectorHint: `role=${inputs.role}`, stability: "low" };
120
+ };
121
+ const ctxFor = (e) => ({
122
+ page: e.session.page(),
123
+ // The action window mints its per-action network tap from this substrate
124
+ // by engine capability: chromium → the CDP NetworkTap; firefox/webkit → the
125
+ // Playwright context-event tap. So the envelope's network slice is real on
126
+ // every engine, not just chromium.
127
+ network: e.networkSubstrate,
128
+ snapshot: e.snapshotSubstrate,
129
+ refs: e.refs,
130
+ console: e.console,
131
+ pages: () => e.session.page().context().pages(),
132
+ testAttributes: config.testAttributes,
133
+ originPolicy,
134
+ recorder: e.recorder,
135
+ ws: e.ws,
136
+ dialog: e.dialog,
137
+ permission: e.permission,
138
+ notification: e.notification,
139
+ fsPicker: e.fsPicker,
140
+ // pass the secrets registry only when the capability is on; the
141
+ // registry exists per-session regardless (kept on SessionEntry so
142
+ // setters wired at creation can reference it), but the action layer
143
+ // only consults it when the capability gate is open.
144
+ ...(caps.enabled.has("secrets") ? { secrets: e.secrets } : {}),
145
+ // pass the downloads registry only when `file-io` is on. The registry
146
+ // exists per-session regardless (off-by-default state on SessionEntry),
147
+ // but the action-window only consults it when the capability gate is
148
+ // open so a server without `file-io` can never surface a downloads
149
+ // block.
150
+ ...(caps.enabled.has("file-io") ? { downloads: e.downloads } : {}),
151
+ });
152
+ // The five capability ports (actions / capture / storage / script / emulation)
153
+ // are now folded into the engine's `SubstrateBundle` (RFC 0004 D1): the
154
+ // Safari-vs-Playwright choice each selector used to make inline is the engine's
155
+ // own concern, declared once in its `makeSubstrates(deps)`. The Playwright bundle
156
+ // needs the host config the old `actionsFor`/`captureFor` closures closed over
157
+ // (`ctxFor` for the ActionContext; `describeTarget` + the screenshot `save` sink
158
+ // for capture). These deps close over THIS server's boundary — `ctxFor` carries
159
+ // the server's originPolicy / config.testAttributes / caps gating, `save` writes
160
+ // under the server's `workspace.root` — so the composition root threads its OWN
161
+ // per-server set at the `makeSubstrates(deps)` call site (a closure-owned local,
162
+ // NEVER a module-global, so a second `createServer()` in the same process can
163
+ // never overwrite this server's substrate deps). The five host ports then resolve
164
+ // through the bundle keyed on `e.session.engine`, byte-identical to the pre-fold
165
+ // closures.
166
+ const serverSubstrateDeps = {
167
+ ctxFor,
168
+ describeTarget,
169
+ save: (buf, args) => screenshotSave(buf, workspace.root, args),
170
+ };
171
+ const substratesFor = (e) => engineEntry(e.session.engine).makeSubstrates(serverSubstrateDeps);
172
+ const actionsFor = (e) => substratesFor(e).actions(e);
173
+ const captureFor = (e) => substratesFor(e).capture(e);
174
+ const storageFor = (e) => substratesFor(e).storage(e);
175
+ const scriptFor = (e) => substratesFor(e).script(e);
176
+ const emulationFor = (e) => substratesFor(e).emulation(e);
177
+ // The egress-masking chokepoint (RFC 0004 P3 / D4). The `secrets`-capability
178
+ // decision is made ONCE here: a `secrets`-off server hands every sink a
179
+ // sanitiser holding a null registry (URL-sanitisation still applies; deep/text
180
+ // secrets-masking is a no-op) — byte-identical to the prior per-sink
181
+ // `caps.enabled.has("secrets") ? e.secrets.applyMaskDeep(x) : x` hand-call.
182
+ const egressFor = (e) => new EgressSanitiser(caps.enabled.has("secrets") ? e.secrets : null);
183
+ // resolve the effective anti-wedge deadline for a call —
184
+ // per-call `timeoutMs` over config `actionTimeoutMs` over the 5000 default,
185
+ // clamped to [1, 3_600_000]. `warning` is non-empty when the caller asked
186
+ // for an over-ceiling (insane) value.
187
+ const cfgActionTimeout = () => {
188
+ const v = configStore.resolve().actionTimeoutMs;
189
+ return typeof v === "number" && v > 0 ? v : DEFAULT_ACTION_TIMEOUT_MS;
190
+ };
191
+ const actionTimeout = (args) => clampTimeout(args.timeoutMs, cfgActionTimeout());
192
+ // Wedge tracking. Only tools that actually exercise the page can
193
+ // wedge a session; session-management / config / coordination tools are
194
+ // excluded so their (always fast) results don't reset the streak.
195
+ const WEDGE_TRACKED_CAPABILITIES = new Set([
196
+ "read",
197
+ "navigation",
198
+ "action",
199
+ "eval",
200
+ "network-body",
201
+ "file-io",
202
+ ]);
203
+ /** First text item of a result, parsed as a JSON object — or null when the
204
+ * result has no leading JSON object (a plain-text snapshot, an image). */
205
+ const firstJsonResult = (res) => {
206
+ for (let i = 0; i < res.content.length; i++) {
207
+ const item = res.content[i];
208
+ if (item && item.type === "text") {
209
+ try {
210
+ const parsed = JSON.parse(item.text);
211
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
212
+ return { obj: parsed, idx: i };
213
+ }
214
+ }
215
+ catch {
216
+ /* not JSON — a plain-text result, e.g. a snapshot tree */
217
+ }
218
+ return null;
219
+ }
220
+ }
221
+ return null;
222
+ };
223
+ /** Update the session's wedge counter from a tool result and, once the
224
+ * session is wedged, splice `sessionWedged` + a recovery hint onto it.
225
+ * An anti-wedge timeout increments the streak; any responsive result
226
+ * (success, or a fast non-timeout error) clears it.
227
+ *
228
+ * Before stamping `sessionWedged: true`, the threshold-trip path probes
229
+ * the page with a 1s `evaluate(() => 1)` — if the page answers, the
230
+ * session is alive (the timeouts were action-shaped, not page-shaped:
231
+ * perpetually-busy SPAs hold WS keepalives / rAF loops that prevent
232
+ * Playwright actionability from settling, but the page itself responds
233
+ * fine to evaluate). A successful probe clears the streak instead of
234
+ * falsely tipping the caller into a session-discard. */
235
+ const noteWedgeOutcome = async (args, res) => {
236
+ const sessionId = args?.session ?? DEFAULT_SESSION_ID;
237
+ const entry = registry.peek(sessionId);
238
+ if (!entry)
239
+ return res;
240
+ const parsed = firstJsonResult(res);
241
+ const timedOut = !!parsed &&
242
+ parsed.obj.ok === false &&
243
+ typeof parsed.obj.error === "string" &&
244
+ /anti-wedge timeout/i.test(parsed.obj.error);
245
+ if (!timedOut || !parsed) {
246
+ entry.wedge.recordResponsive();
247
+ return res;
248
+ }
249
+ entry.wedge.recordTimeout();
250
+ if (!entry.wedge.wedged())
251
+ return res;
252
+ // Threshold tripped — confirm before stamping. Cheap liveness probe:
253
+ // if the page answers evaluate() within 1s, the session is alive and
254
+ // the timeouts were action-shaped (e.g. busy SPA blocks click
255
+ // actionability). Clear the streak rather than falsely wedge the
256
+ // caller. If the probe fails or times out, the session genuinely is
257
+ // wedged — stamp the response as before.
258
+ let aliveByProbe = false;
259
+ try {
260
+ const page = entry.session.page();
261
+ await withDeadline(page.evaluate(() => 1), 1_000, "wedge_probe");
262
+ aliveByProbe = true;
263
+ }
264
+ catch {
265
+ aliveByProbe = false;
266
+ }
267
+ if (aliveByProbe) {
268
+ entry.wedge.recordResponsive();
269
+ return res;
270
+ }
271
+ const obj = { ...parsed.obj, sessionWedged: true, sessionWedgedHint: entry.wedge.hint() };
272
+ return {
273
+ content: res.content.map((item, i) => i === parsed.idx ? { type: "text", text: JSON.stringify(obj, null, 2) } : item),
274
+ };
275
+ };
276
+ // Classify a dispatched tool result for the per-session metrics
277
+ // counter. We piggyback on `firstJsonResult` (already defined above) so we
278
+ // don't pay a second parse. A capability-denied result is the JSON shape the
279
+ // `gateCheck` helper emits (carries `requiredCapability`); any other
280
+ // `ok:false` result is an error; everything else is `ok`. The
281
+ // `tokensEstimate` field is read straight off the envelope when present —
282
+ // most tools surface it via the standard helper, but image-only / non-JSON
283
+ // results legitimately don't and that's fine (treated as 0).
284
+ const classifyOutcome = (res) => {
285
+ const parsed = firstJsonResult(res);
286
+ if (!parsed)
287
+ return { outcome: "ok" };
288
+ const obj = parsed.obj;
289
+ const tokens = typeof obj.tokensEstimate === "number" ? obj.tokensEstimate : undefined;
290
+ if (obj.ok === false) {
291
+ // Capability-denied shape (see `gateCheck`): carries `requiredCapability`.
292
+ // The denial path is a config-shape signal, not a tool-error signal —
293
+ // bucket it separately.
294
+ if (Object.prototype.hasOwnProperty.call(obj, "requiredCapability")) {
295
+ return { outcome: "denied", tokensEstimate: tokens };
296
+ }
297
+ return { outcome: "error", tokensEstimate: tokens };
298
+ }
299
+ return { outcome: "ok", tokensEstimate: tokens };
300
+ };
301
+ /** Record one dispatch on the session's metrics counter — peek-only on the
302
+ * registry. Calls against a not-yet-open session (e.g. a capability denial
303
+ * fired before the lazy session creation) are silently skipped: there's no
304
+ * SessionEntry to accumulate against, and the denial is still visible at the
305
+ * capability layer. Same posture as `noteWedgeOutcome` above. */
306
+ const noteMetrics = (toolName, args, res, startedAt) => {
307
+ const sessionId = args?.session ?? DEFAULT_SESSION_ID;
308
+ const entry = registry.peek(sessionId);
309
+ if (!entry)
310
+ return;
311
+ const { outcome, tokensEstimate } = classifyOutcome(res);
312
+ entry.metrics.record(toolName, outcome, Date.now() - startedAt, tokensEstimate);
313
+ };
314
+ /** Record one dispatched call into the diagnostics JSONL store. No-op when
315
+ * the diagnostics capability is OFF — the caller short-circuits on
316
+ * `diagnostics.enabled` BEFORE allocating anything. The recorder runs
317
+ * DOWNSTREAM of the URL sanitiser + secrets-masking chokepoint:
318
+ * by the time `res` lands here, every egress sink has already rewritten
319
+ * registered secret values back to `<NAME>` aliases. Args are additionally
320
+ * walked through `applyMaskDeep` so a secret echoed in the call args
321
+ * never reaches the JSONL raw. */
322
+ const noteDiagnostics = (toolName, args, res, startedAt) => {
323
+ if (!diagnostics.enabled)
324
+ return;
325
+ const sessionId = args?.session ?? DEFAULT_SESSION_ID;
326
+ const entry = registry.peek(sessionId);
327
+ // Apply the per-session secrets mask to args BEFORE structural redaction
328
+ // so a registered secret value echoed in the call args never lands raw
329
+ // in the JSONL store.
330
+ const maskedArgsIn = entry?.secrets ? entry.secrets.applyMaskDeep(args) : args;
331
+ const parsed = firstJsonResult(res);
332
+ const sizeBytes = res.content.reduce((n, item) => {
333
+ if (item.type === "text")
334
+ return n + Buffer.byteLength(item.text, "utf8");
335
+ if (item.type === "image")
336
+ return n + (typeof item.data === "string" ? item.data.length : 0);
337
+ return n;
338
+ }, 0);
339
+ const obj = parsed?.obj ?? null;
340
+ const ok = obj ? obj.ok !== false : true;
341
+ const warningsCount = obj && Array.isArray(obj.warnings) ? obj.warnings.length : 0;
342
+ let failureKind;
343
+ if (!ok && obj) {
344
+ if (Object.prototype.hasOwnProperty.call(obj, "requiredCapability")) {
345
+ failureKind = "capability-denied";
346
+ diagnostics.noteDenial();
347
+ }
348
+ else {
349
+ const err = typeof obj.error === "string" ? obj.error : "";
350
+ if (/anti-wedge timeout/i.test(err))
351
+ failureKind = "timeout";
352
+ else if (/not found|no element matches|ref not found|locator did not resolve/i.test(err))
353
+ failureKind = "target-not-found";
354
+ else if (/must |invalid |unknown |expected /i.test(err))
355
+ failureKind = "bad-arg";
356
+ else
357
+ failureKind = "internal";
358
+ }
359
+ }
360
+ const record = {
361
+ kind: "call",
362
+ ts: new Date(startedAt).toISOString(),
363
+ tool: toolName,
364
+ sessionId,
365
+ argsRedacted: redactArgs(maskedArgsIn),
366
+ resultMeta: {
367
+ ok,
368
+ sizeBytes,
369
+ warningsCount,
370
+ ...(failureKind ? { failureKind } : {}),
371
+ },
372
+ durationMs: Date.now() - startedAt,
373
+ capabilityDenials: diagnostics.denialsCount(),
374
+ };
375
+ const evalCap = buildEvalJsCapture(toolName, maskedArgsIn, obj);
376
+ if (evalCap)
377
+ record.evalJs = evalCap;
378
+ diagnostics.write(record);
379
+ };
380
+ // Wrapper that preserves the inner handler's parameter type for typechecking
381
+ // (destructuring inside each registration still works) but stores a
382
+ // type-erased copy for `batch` dispatch. Page-exercising tools additionally
383
+ // route their result through the wedge tracker; every tool is timed +
384
+ // counted on the session's per-session metrics rollup. When the
385
+ // `diagnostics` capability is on, each dispatch ALSO lands as a JSONL
386
+ // record under $BROWX_WORKSPACE/diagnostics/<sessionId>/<ISO>.jsonl;
387
+ // when off, the recorder is a zero-overhead gate check (no allocations,
388
+ // no file IO).
389
+ // Derived (RFC 0004 P2). Both are populated by `register` from the colocated
390
+ // `{ batchable }` / `{ capability, deep, inputSchema }` metadata each tool
391
+ // declares, so a tool's batchability, capability, deepness, and SDK type all
392
+ // trace back to its one registration call. `BATCH_ALLOWED_TOOLS` replaces the
393
+ // hand-maintained 71-entry literal; `await_human`, `batch`, the recording
394
+ // controls and the config mutators simply never declare `{ batchable: true }`,
395
+ // so they are excluded by construction rather than by an omission a human had
396
+ // to remember. The host exposes the batch set via `batchAllowedTools` and the
397
+ // full registration table via `registrations` (read by the SDK tool-types
398
+ // codegen, D7).
399
+ const BATCH_ALLOWED_TOOLS = new Set();
400
+ const registrations = new Map();
401
+ const register = (name, def, handler) => {
402
+ // L8/L2: a tool name registers EXACTLY once. The derived central maps
403
+ // (TOOL_CAPABILITY / BATCH_ALLOWED_TOOLS / DEEP_TOOLS) and `toolHandlers` all
404
+ // key on `name`, so a duplicate registration would silently shadow the
405
+ // handler AND desync the derived metadata from the live surface — the exact
406
+ // single-source-of-truth break L2 forbids. Every core family registers
407
+ // disjoint names (the registered-name freeze test pins the set), so this
408
+ // holds; the invariant turns "names are unique" from a convention into an
409
+ // asserted contract at the one seam every registration flows through.
410
+ invariant(!registrations.has(name), `tool "${name}" registered twice`);
411
+ // Colocated metadata → derived central maps (RFC 0004 P2 / D2). The
412
+ // capability/deep facts feed the lower-layer registries; `batchable` feeds the
413
+ // local batch allow-set; the whole record (incl. the zod schema) is kept for
414
+ // the SDK tool-types codegen (D7). The capability gate then reads `TOOL_CAPABILITY`
415
+ // (now derived from these declarations), so the assignment lives only here.
416
+ if (def.capability !== undefined)
417
+ declareToolCapability(name, def.capability);
418
+ if (def.deep)
419
+ declareDeepTool(name);
420
+ if (def.batchable)
421
+ BATCH_ALLOWED_TOOLS.add(name);
422
+ registrations.set(name, {
423
+ description: def.description,
424
+ inputSchema: def.inputSchema,
425
+ capability: def.capability,
426
+ batchable: def.batchable,
427
+ deep: def.deep,
428
+ });
429
+ const tracked = WEDGE_TRACKED_CAPABILITIES.has(def.capability ?? "");
430
+ const wrapped = async (rawArgs) => {
431
+ // MCP-wire boundary: the SDK parses + validates the inbound payload against
432
+ // this tool's `inputSchema` before dispatch, so the dispatched value IS the
433
+ // handler's declared arg shape. This is the one place that boundary narrows.
434
+ const args = rawArgs;
435
+ const startedAt = Date.now();
436
+ const inner = tracked
437
+ ? await noteWedgeOutcome(args, await handler(args))
438
+ : await handler(args);
439
+ noteMetrics(name, args, inner, startedAt);
440
+ noteDiagnostics(name, args, inner, startedAt);
441
+ return inner;
442
+ };
443
+ toolHandlers[name] = wrapped;
444
+ // The SDK's `registerTool` generic cannot relate its conditional-typed
445
+ // callback to a still-generic `S`; widening the config's schema to a concrete
446
+ // `ZodRawShape` lets that conditional resolve, so `wrapped` (whose args are
447
+ // narrowed at the wire boundary above and whose result is a CallToolResult)
448
+ // matches with no assertion.
449
+ const sdkConfig = def;
450
+ server.registerTool(name, sdkConfig, wrapped);
451
+ };
452
+ // ---------- action tools ----------
453
+ const asActionResultText = async (p) => {
454
+ const r = await p;
455
+ return { content: [{ type: "text", text: JSON.stringify(r, null, 2) }] };
456
+ };
457
+ /** JSON envelope for the non-action families: stringify with `tokensEstimate`. */
458
+ const okText = (body) => {
459
+ const json = JSON.stringify(body);
460
+ const tokensEstimate = estimateTokens(json);
461
+ return {
462
+ content: [
463
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
464
+ ],
465
+ };
466
+ };
467
+ /** Same shape for an `ok:false` rejection so callers see a uniform envelope. */
468
+ const errText = (tool, err) => okText({ ok: false, tool, error: err instanceof Error ? err.message : String(err) });
469
+ // The composition seam: bundle the shared state + helper closures into one
470
+ // host and hand it to each per-family tool module. createServer stays the
471
+ // registry composition root; the register() blocks live under src/tools/.
472
+ const host = {
473
+ register,
474
+ entryFor,
475
+ gateCheck,
476
+ engineGate,
477
+ confirmCtxFor,
478
+ ctxFor,
479
+ workspace,
480
+ denyContent,
481
+ asActionResultText,
482
+ okText,
483
+ errText,
484
+ asTarget,
485
+ hintFromTarget,
486
+ actionTimeout,
487
+ cfgActionTimeout,
488
+ actionsFor,
489
+ captureFor,
490
+ storageFor,
491
+ scriptFor,
492
+ emulationFor,
493
+ egressFor,
494
+ caps,
495
+ config,
496
+ configStore,
497
+ resolvedConfig,
498
+ startOptions,
499
+ z,
500
+ toolHandlers,
501
+ batchAllowedTools: BATCH_ALLOWED_TOOLS,
502
+ registrations,
503
+ registry,
504
+ diagnostics,
505
+ approvals,
506
+ credentialsResolved,
507
+ noteMetrics,
508
+ noteDiagnostics,
509
+ // `pluginRecords` is assigned after the host literal is built (plugin
510
+ // runtime starts later); expose it lazily so get_config sees the live set.
511
+ get pluginRecords() {
512
+ return pluginRecords();
513
+ },
514
+ };
515
+ return host;
516
+ }