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,407 @@
1
+ // `browxai doctor` — environment + connectivity health-check ().
2
+ //
3
+ // Prints a ✓/✗ checklist + one-line fix per failing check (− marks purely
4
+ // informational rows). Exits 0 iff everything passes, 1 otherwise. Writes to
5
+ // stdout (this is a CLI subcommand, not the MCP server — stdout is fine here).
6
+ import { existsSync, statSync } from "node:fs";
7
+ import { dirname, resolve } from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+ import { resolveCapabilities, resolveConfirmHooks, DEFAULT_CAPABILITIES, } from "../util/capabilities.js";
10
+ import { resolveConfig } from "../util/config.js";
11
+ import { resolveOriginPolicy, describePolicy } from "../policy/origin.js";
12
+ import { resolveWorkspace } from "../util/workspace.js";
13
+ import { ConfigStore } from "../util/config-store.js";
14
+ import { pluginChecks } from "./doctor-plugins.js";
15
+ import { IMPLEMENTED_ENGINES, AndroidCdpAdapter, defaultAdbRunner, defaultFetcher, pickFreePort, forwardArgs, forwardRemoveArgs, versionUrl, extractWsUrl, resolveEngineSelection, UnknownEngineError, } from "../engine/index.js";
16
+ export async function runDoctor() {
17
+ const checks = [];
18
+ // 1. dist/cli.js built?
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const distCli = resolve(__dirname, "../cli.js");
21
+ if (existsSync(distCli)) {
22
+ const age = Math.floor((Date.now() - statSync(distCli).mtimeMs) / 86_400_000);
23
+ checks.push({ name: "build", ok: true, detail: `dist/cli.js exists (${age}d old)` });
24
+ }
25
+ else {
26
+ checks.push({
27
+ name: "build",
28
+ ok: false,
29
+ detail: `dist/cli.js missing at ${distCli}`,
30
+ fix: "run `pnpm build`",
31
+ });
32
+ }
33
+ // 2. $BROWX_WORKSPACE writable?
34
+ try {
35
+ const ws = resolveWorkspace();
36
+ const probe = ws.sub("doctor-probe");
37
+ if (existsSync(probe)) {
38
+ checks.push({ name: "workspace", ok: true, detail: `${ws.root} (writable)` });
39
+ }
40
+ else {
41
+ checks.push({
42
+ name: "workspace",
43
+ ok: false,
44
+ detail: `${ws.root} couldn't create subdir`,
45
+ fix: "check permissions; set BROWX_WORKSPACE to a writable dir",
46
+ });
47
+ }
48
+ }
49
+ catch (e) {
50
+ checks.push({
51
+ name: "workspace",
52
+ ok: false,
53
+ detail: e instanceof Error ? e.message : String(e),
54
+ fix: "set BROWX_WORKSPACE to an absolute path you own",
55
+ });
56
+ }
57
+ // 3. BROWX_TEST_ATTRIBUTES configured (default or explicit).
58
+ const config = resolveConfig();
59
+ const explicit = !!process.env.BROWX_TEST_ATTRIBUTES;
60
+ checks.push({
61
+ name: "test-attrs",
62
+ ok: true,
63
+ detail: `${config.testAttributes.join(",")}${explicit ? " (BROWX_TEST_ATTRIBUTES set)" : " (default)"}`,
64
+ fix: explicit
65
+ ? undefined
66
+ : "set BROWX_TEST_ATTRIBUTES if your codebase uses non-default conventions (e.g. add `data-type`)",
67
+ });
68
+ // 4. BROWX_ATTACH_CDP — if set, can we reach it?
69
+ const cdpEnv = process.env.BROWX_ATTACH_CDP?.trim();
70
+ if (cdpEnv) {
71
+ const reachable = await probeCdp(cdpEnv);
72
+ checks.push({
73
+ name: "cdp-attach",
74
+ ok: reachable.ok,
75
+ detail: reachable.ok
76
+ ? `${cdpEnv} reachable — ${reachable.version}`
77
+ : `${cdpEnv} unreachable (${reachable.error})`,
78
+ fix: reachable.ok
79
+ ? undefined
80
+ : "start a Chrome at this port — `browxai chrome start` or `chrome --remote-debugging-port=9222 …`",
81
+ });
82
+ }
83
+ else {
84
+ // Not configured. Probe the default port anyway — adopters with a Chrome
85
+ // already running may want to be told "you could attach to that, you know."
86
+ const reachable = await probeCdp("http://127.0.0.1:9222");
87
+ if (reachable.ok) {
88
+ checks.push({
89
+ name: "cdp-attach",
90
+ ok: true,
91
+ detail: `BROWX_ATTACH_CDP unset, but a Chrome is reachable at 127.0.0.1:9222 (${reachable.version}). Use the \`browxai-attached\` MCP entry to attach.`,
92
+ });
93
+ }
94
+ else {
95
+ checks.push({
96
+ name: "cdp-attach",
97
+ ok: true,
98
+ detail: "BROWX_ATTACH_CDP unset — managed-mode default. No --cdp Chrome to attach to.",
99
+ });
100
+ }
101
+ }
102
+ // 5. Capabilities ( security model).
103
+ let enabledCapabilities = new Set(DEFAULT_CAPABILITIES);
104
+ try {
105
+ const c = resolveCapabilities();
106
+ enabledCapabilities = c.enabled;
107
+ const explicit = !!process.env.BROWX_CAPABILITIES;
108
+ const dangerous = [...c.enabled].filter((x) => x === "eval" || x === "byob-attach");
109
+ const detail = `enabled=[${[...c.enabled].join(", ")}]${explicit ? "" : " (default)"}${dangerous.length ? " ⚠ dangerous: " + dangerous.join(", ") : ""}`;
110
+ checks.push({
111
+ name: "capabilities",
112
+ ok: true,
113
+ detail,
114
+ fix: dangerous.length
115
+ ? `${dangerous.join(",")} on — page text remains untrusted; review docs/threat-model.md`
116
+ : explicit
117
+ ? undefined
118
+ : "see docs/threat-model.md for the full set; default is " +
119
+ DEFAULT_CAPABILITIES.join(","),
120
+ });
121
+ }
122
+ catch (e) {
123
+ checks.push({
124
+ name: "capabilities",
125
+ ok: false,
126
+ detail: e instanceof Error ? e.message : String(e),
127
+ fix: "fix BROWX_CAPABILITIES (comma-separated, see docs/threat-model.md)",
128
+ });
129
+ }
130
+ // 6. Confirm-required hooks.
131
+ try {
132
+ const hooks = resolveConfirmHooks();
133
+ checks.push({
134
+ name: "confirm-hooks",
135
+ ok: true,
136
+ detail: hooks.size > 0 ? `[${[...hooks].join(", ")}]` : "(none)",
137
+ });
138
+ }
139
+ catch (e) {
140
+ checks.push({
141
+ name: "confirm-hooks",
142
+ ok: false,
143
+ detail: e instanceof Error ? e.message : String(e),
144
+ fix: "fix BROWX_CONFIRM_REQUIRED — see docs/threat-model.md",
145
+ });
146
+ }
147
+ // 7. Origin policy.
148
+ try {
149
+ const policy = resolveOriginPolicy();
150
+ const noAllowlist = policy.allowed.length === 0;
151
+ checks.push({
152
+ name: "origins",
153
+ ok: true,
154
+ detail: describePolicy(policy),
155
+ fix: noAllowlist
156
+ ? "no allowlist set — defense-in-depth not engaged. Set BROWX_ALLOWED_ORIGINS for the navigation gate."
157
+ : undefined,
158
+ });
159
+ }
160
+ catch (e) {
161
+ checks.push({
162
+ name: "origins",
163
+ ok: false,
164
+ detail: e instanceof Error ? e.message : String(e),
165
+ fix: "BROWX_ALLOWED_ORIGINS / BROWX_BLOCKED_ORIGINS: comma-separated absolute URLs (https://app.example.com or https://*.example.com)",
166
+ });
167
+ }
168
+ // 8. Chromium installed (managed-mode dependency).
169
+ try {
170
+ // Lazy import so this command doesn't pay the playwright-core cost on bare invocation.
171
+ const { chromium } = await import("playwright-core");
172
+ const path = chromium.executablePath();
173
+ if (path && existsSync(path)) {
174
+ checks.push({ name: "chromium", ok: true, detail: `${path}` });
175
+ }
176
+ else {
177
+ checks.push({
178
+ name: "chromium",
179
+ ok: false,
180
+ detail: "playwright-core has no Chromium binary cached",
181
+ fix: "run `pnpm install-browser`",
182
+ });
183
+ }
184
+ }
185
+ catch (e) {
186
+ checks.push({
187
+ name: "chromium",
188
+ ok: false,
189
+ detail: e instanceof Error ? e.message : String(e),
190
+ fix: "run `pnpm install` and `pnpm install-browser`",
191
+ });
192
+ }
193
+ // 8a2. Firefox binary (opt-in second engine — `browserType:"firefox"`).
194
+ // Informational: Firefox is opt-in, so a missing binary never FAILS doctor —
195
+ // it just tells the operator how to enable the engine. Mirrors the Chromium
196
+ // check above but against the Firefox build (Playwright's bundled Juggler).
197
+ try {
198
+ const { firefox } = await import("playwright-core");
199
+ const path = firefox.executablePath();
200
+ if (path && existsSync(path)) {
201
+ checks.push({ name: "firefox", ok: true, info: true, detail: `${path}` });
202
+ }
203
+ else {
204
+ checks.push({
205
+ name: "firefox",
206
+ ok: true,
207
+ info: true,
208
+ detail: 'not installed (opt-in second engine — browserType:"firefox")',
209
+ fix: "run `npx playwright install firefox` to enable the firefox engine",
210
+ });
211
+ }
212
+ }
213
+ catch (e) {
214
+ checks.push({
215
+ name: "firefox",
216
+ ok: true,
217
+ info: true,
218
+ detail: e instanceof Error ? e.message : String(e),
219
+ fix: "run `npx playwright install firefox` to enable the firefox engine",
220
+ });
221
+ }
222
+ // 8a3. WebKit binary (opt-in third engine — `browserType:"webkit"`).
223
+ // Informational: WebKit is opt-in, so a missing binary never FAILS doctor —
224
+ // it just tells the operator how to enable the engine. Mirrors the Chromium +
225
+ // Firefox checks above but against the WebKit build (Playwright's bundled
226
+ // WebKit — the WebKit-engine correctness lane, NOT Safari).
227
+ try {
228
+ const { webkit } = await import("playwright-core");
229
+ const path = webkit.executablePath();
230
+ if (path && existsSync(path)) {
231
+ checks.push({ name: "webkit", ok: true, info: true, detail: `${path}` });
232
+ }
233
+ else {
234
+ checks.push({
235
+ name: "webkit",
236
+ ok: true,
237
+ info: true,
238
+ detail: 'not installed (opt-in third engine — browserType:"webkit")',
239
+ fix: "run `npx playwright install webkit` to enable the webkit engine",
240
+ });
241
+ }
242
+ }
243
+ catch (e) {
244
+ checks.push({
245
+ name: "webkit",
246
+ ok: true,
247
+ info: true,
248
+ detail: e instanceof Error ? e.message : String(e),
249
+ fix: "run `npx playwright install webkit` to enable the webkit engine",
250
+ });
251
+ }
252
+ // 8a4. Android availability (opt-in fourth engine — `browserType:"android"`).
253
+ // The full-fidelity real-profile BYOB lane: real Chrome-on-Android over adb +
254
+ // CDP. Informational — Android is opt-in + needs a physically
255
+ // connected device, so a missing adb / no device / closed Chrome NEVER fails
256
+ // doctor; it just reports how far the chain reaches (adb present → device ready
257
+ // → Chrome socket reachable). Probes without opening a session: lists devices,
258
+ // and if one is ready, forwards the socket + probes /json/version, then removes
259
+ // the forward.
260
+ checks.push(await androidCheck());
261
+ // 8b. SELECTED browser engine. Resolves the operator's choice exactly as the
262
+ // MCP server does: explicit `--engine <kind>` > `BROWX_ENGINE` env > default
263
+ // chromium (see src/engine/select.ts). Reports which engine the server WOULD
264
+ // run on, and points at the per-engine availability row above (chromium /
265
+ // firefox / webkit / android — those checks always run) so the operator can see
266
+ // the selected engine's readiness in one glance. Chromium + Firefox + WebKit +
267
+ // Android are wired; the seam lets each engine be an adapter (see src/engine/).
268
+ // An invalid selection is reported here (and never fails doctor — it's the same
269
+ // structured "implemented engines: …" message the server prints, surfaced as a
270
+ // ✗ so the operator sees it). Informational otherwise.
271
+ let selectedEngine = "chromium";
272
+ let engineSelectionError;
273
+ try {
274
+ selectedEngine = resolveEngineSelection(process.argv.slice(2)) ?? "chromium";
275
+ }
276
+ catch (e) {
277
+ engineSelectionError =
278
+ e instanceof UnknownEngineError ? e.message : e instanceof Error ? e.message : String(e);
279
+ }
280
+ if (engineSelectionError) {
281
+ checks.push({
282
+ name: "engine",
283
+ ok: false,
284
+ detail: engineSelectionError,
285
+ fix: `set BROWX_ENGINE (or --engine) to one of: ${IMPLEMENTED_ENGINES.join(", ")}`,
286
+ });
287
+ }
288
+ else {
289
+ const explicit = !!process.env.BROWX_ENGINE?.trim() ||
290
+ process.argv.slice(2).some((a) => a === "--engine" || a.startsWith("--engine="));
291
+ // The availability row matching the selected engine ran above (chromium ✓,
292
+ // firefox/webkit/android −). Name it so doctor's engine line is self-contained.
293
+ const readinessRow = selectedEngine === "chromium"
294
+ ? "see `chromium` row above"
295
+ : `see \`${selectedEngine}\` row above`;
296
+ checks.push({
297
+ name: "engine",
298
+ ok: true,
299
+ info: true,
300
+ detail: `${selectedEngine}${explicit ? "" : " (default)"} — ${readinessRow}; ` +
301
+ `implemented: ${IMPLEMENTED_ENGINES.join(", ")}`,
302
+ });
303
+ }
304
+ // 9. Plugins — declaration / install drift / lock health / manifest
305
+ // sanity. Pure inspection of the same files the runtime's resolution
306
+ // stage reads; doctor NEVER executes a plugin's register module.
307
+ try {
308
+ const ws = resolveWorkspace();
309
+ const store = new ConfigStore(ws.root);
310
+ checks.push(...pluginChecks({
311
+ workspaceRoot: ws.root,
312
+ enabledCapabilities,
313
+ extraDeclared: store.resolve().plugins,
314
+ }));
315
+ }
316
+ catch (e) {
317
+ checks.push({
318
+ name: "plugins",
319
+ ok: false,
320
+ detail: e instanceof Error ? e.message : String(e),
321
+ fix: "inspect <workspace>/plugins.json, plugins-lock.json and plugins/node_modules/ by hand",
322
+ });
323
+ }
324
+ // Print + exit.
325
+ let allOk = true;
326
+ process.stdout.write("browxai doctor — environment & connectivity\n\n");
327
+ for (const c of checks) {
328
+ if (!c.ok)
329
+ allOk = false;
330
+ const glyph = c.info ? "−" : c.ok ? "✓" : "✗";
331
+ process.stdout.write(` ${glyph} ${c.name.padEnd(12)} ${c.detail}\n`);
332
+ if (!c.ok && c.fix)
333
+ process.stdout.write(` fix: ${c.fix}\n`);
334
+ }
335
+ process.stdout.write(`\n${allOk ? "all checks passed" : "fix the ✗ items above"}\n`);
336
+ return allOk ? 0 : 1;
337
+ }
338
+ // Android availability — how far the adb + CDP chain reaches, without opening a
339
+ // session. adb present? → a device ready? → the Chrome DevTools socket
340
+ // reachable? Always informational (Android is opt-in + device-gated). The probe
341
+ // forwards the socket to a transient loopback port, GETs /json/version, then
342
+ // removes the forward — no session, no leaked forward.
343
+ async function androidCheck() {
344
+ const name = "android";
345
+ const adapter = new AndroidCdpAdapter();
346
+ let serial;
347
+ try {
348
+ serial = await adapter.discoverDevice(process.env.BROWX_ANDROID_SERIAL?.trim() || undefined);
349
+ }
350
+ catch (e) {
351
+ // adb-missing / no-device / ambiguous — report the structured message's first
352
+ // clause; never fails doctor.
353
+ const msg = e instanceof Error ? e.message.split(".")[0] : String(e);
354
+ return {
355
+ name,
356
+ ok: true,
357
+ info: true,
358
+ detail: `${msg} (opt-in BYOB lane — browserType:"android")`,
359
+ fix: "connect an Android phone over USB, enable USB debugging, open Chrome",
360
+ };
361
+ }
362
+ // Device ready — try to reach the Chrome socket so the operator knows whether
363
+ // Chrome is open + web-debugging is on.
364
+ let localPort = 0;
365
+ try {
366
+ localPort = await pickFreePort();
367
+ await defaultAdbRunner(forwardArgs(localPort, serial));
368
+ const body = await defaultFetcher(versionUrl(localPort));
369
+ extractWsUrl(body);
370
+ const browser = body.Browser ?? "unknown";
371
+ return {
372
+ name,
373
+ ok: true,
374
+ info: true,
375
+ detail: `device ${serial} ready, Chrome reachable (${browser}) — browserType:"android" attach-ready`,
376
+ };
377
+ }
378
+ catch (e) {
379
+ const msg = e instanceof Error ? e.message.split(".")[0] : String(e);
380
+ return {
381
+ name,
382
+ ok: true,
383
+ info: true,
384
+ detail: `device ${serial} ready but Chrome socket not reachable: ${msg}`,
385
+ fix: "open Chrome on the device + enable USB web-debugging (chrome://inspect should list its tabs)",
386
+ };
387
+ }
388
+ finally {
389
+ if (localPort) {
390
+ await defaultAdbRunner(forwardRemoveArgs(localPort, serial)).catch(() => undefined);
391
+ }
392
+ }
393
+ }
394
+ async function probeCdp(endpoint) {
395
+ try {
396
+ const url = new URL(endpoint);
397
+ const probeUrl = `${url.origin}/json/version`;
398
+ const res = await fetch(probeUrl, { signal: AbortSignal.timeout(2000) });
399
+ if (!res.ok)
400
+ return { ok: false, error: `HTTP ${res.status}` };
401
+ const body = (await res.json());
402
+ return { ok: true, version: body.Browser ?? "unknown" };
403
+ }
404
+ catch (e) {
405
+ return { ok: false, error: e instanceof Error ? e.message : String(e) };
406
+ }
407
+ }
@@ -0,0 +1 @@
1
+ export declare function runInit(args: string[]): Promise<number>;
@@ -0,0 +1,200 @@
1
+ // `browxai init <workspace>` — bootstrap a per-app workspace ().
2
+ //
3
+ // Creates `<workspace>/.browxai/` (the consumer-co-located `BROWX_WORKSPACE`),
4
+ // emits a workspace-scope `.mcp.json` snippet the user can drop into their MCP
5
+ // client, and (if the workspace has a sibling source tree) heuristically sniffs
6
+ // the most-used test attribute convention so the printed `BROWX_TEST_ATTRIBUTES`
7
+ // order is right out of the gate.
8
+ //
9
+ // Stdout is fine — CLI subcommand.
10
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
11
+ import { dirname, join, resolve } from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+ export function runInit(args) {
14
+ const opts = parseArgs(args);
15
+ if (!opts) {
16
+ process.stderr.write("usage: browxai init <workspace> [--test-attrs data-testid,data-type,...] [--no-write]\n" +
17
+ " <workspace> per-app dir to host browxai state (e.g. ~/site-docs/<app>)\n" +
18
+ " --no-write print the .mcp.json snippet without creating files\n");
19
+ return Promise.resolve(2);
20
+ }
21
+ const workspace = resolve(opts.workspace);
22
+ const browxDir = join(workspace, ".browxai");
23
+ // Sniff test attrs (if not explicit).
24
+ let testAttrs = opts.testAttrs;
25
+ let sniffNote = "";
26
+ if (!testAttrs) {
27
+ const sniffed = sniffTestAttributes(workspace);
28
+ testAttrs = sniffed.attrs.join(",");
29
+ sniffNote = sniffed.note;
30
+ }
31
+ // Resolve the browxai dist/cli.js path (this script's repo).
32
+ const __dirname = dirname(fileURLToPath(import.meta.url));
33
+ const distCli = resolve(__dirname, "../cli.js");
34
+ const mcpJson = {
35
+ mcpServers: {
36
+ browxai: {
37
+ command: "node",
38
+ args: [distCli],
39
+ env: {
40
+ BROWX_WORKSPACE: browxDir,
41
+ BROWX_TEST_ATTRIBUTES: testAttrs,
42
+ },
43
+ },
44
+ "browxai-attached": {
45
+ command: "node",
46
+ args: [distCli],
47
+ env: {
48
+ BROWX_WORKSPACE: browxDir,
49
+ BROWX_ATTACH_CDP: "http://127.0.0.1:9222",
50
+ BROWX_TEST_ATTRIBUTES: testAttrs,
51
+ },
52
+ },
53
+ },
54
+ };
55
+ const mcpJsonText = JSON.stringify(mcpJson, null, 2);
56
+ process.stdout.write(`browxai init — bootstrap workspace at ${workspace}\n\n`);
57
+ if (!opts.noWrite) {
58
+ if (!existsSync(browxDir)) {
59
+ mkdirSync(browxDir, { recursive: true });
60
+ process.stdout.write(` ✓ created ${browxDir}\n`);
61
+ }
62
+ else {
63
+ process.stdout.write(` ✓ ${browxDir} already exists\n`);
64
+ }
65
+ const mcpPath = join(workspace, ".mcp.json");
66
+ if (existsSync(mcpPath)) {
67
+ process.stdout.write(` ⚠ ${mcpPath} exists — printing snippet below; merge manually so no existing entries are clobbered\n`);
68
+ }
69
+ else {
70
+ writeFileSync(mcpPath, mcpJsonText + "\n", "utf8");
71
+ process.stdout.write(` ✓ wrote ${mcpPath} (workspace-scope MCP config)\n`);
72
+ }
73
+ }
74
+ process.stdout.write(`\ntest-attributes order: ${testAttrs}\n`);
75
+ if (sniffNote)
76
+ process.stdout.write(` ${sniffNote}\n`);
77
+ process.stdout.write(`\n.mcp.json snippet (workspace-scope; pair with \`claude mcp add-json -s user\` for user-scope):\n\n${mcpJsonText}\n\n`);
78
+ process.stdout.write(`next steps:\n 1) open Claude Code with cwd=${workspace} so this .mcp.json is picked up\n` +
79
+ ` 2) (BYOB) \`browxai chrome start\` to launch the attachable Chrome\n` +
80
+ ` 3) use the \`browxai\` MCP server for managed mode, \`browxai-attached\` for BYOB\n`);
81
+ return Promise.resolve(0);
82
+ }
83
+ function parseArgs(args) {
84
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h")
85
+ return null;
86
+ const positional = [];
87
+ let testAttrs;
88
+ let noWrite = false;
89
+ for (let i = 0; i < args.length; i++) {
90
+ const a = args[i];
91
+ if (a === "--test-attrs") {
92
+ testAttrs = args[++i];
93
+ continue;
94
+ }
95
+ if (a === "--no-write") {
96
+ noWrite = true;
97
+ continue;
98
+ }
99
+ positional.push(a);
100
+ }
101
+ if (positional.length !== 1)
102
+ return null;
103
+ return { workspace: positional[0], testAttrs, noWrite };
104
+ }
105
+ /**
106
+ * Sniff a consumer codebase for which `data-*` attribute is dominant. Looks at
107
+ * the workspace's parent dir (typical layout: `~/site-docs/<app>/` and
108
+ * `~/Projects/<app>/`) for `src/` and counts occurrences of each conventional
109
+ * test attribute in `.ts` / `.tsx` / `.js` / `.jsx` files. Returns the attrs in
110
+ * descending frequency order (most-used first — `BROWX_TEST_ATTRIBUTES` is
111
+ * first-match-wins so the dominant convention should lead).
112
+ *
113
+ * Best-effort and bounded: walks at most 200 source files.
114
+ */
115
+ function sniffTestAttributes(workspace) {
116
+ const KNOWN = ["data-testid", "data-type", "data-test", "data-cy", "data-qa", "data-test-id"];
117
+ const counts = new Map(KNOWN.map((a) => [a, 0]));
118
+ const candidates = [
119
+ workspace, // in case workspace itself is a code repo
120
+ join(workspace, "../"), // parent: typical sibling layout
121
+ join(workspace, "src"),
122
+ join(workspace, "../src"),
123
+ ].filter((d) => existsSync(d));
124
+ if (candidates.length === 0) {
125
+ return { attrs: KNOWN.slice(0, 5), note: "(no sibling code dir found; default order)" };
126
+ }
127
+ let scanned = 0;
128
+ for (const root of candidates) {
129
+ walk(root, 4, (file) => {
130
+ if (scanned >= 200)
131
+ return false;
132
+ if (!/\.(t|j)sx?$/.test(file))
133
+ return true;
134
+ scanned++;
135
+ try {
136
+ const text = readFileSync(file, "utf8");
137
+ for (const a of KNOWN) {
138
+ const re = new RegExp(`${a}=`, "g");
139
+ const m = text.match(re);
140
+ if (m)
141
+ counts.set(a, (counts.get(a) ?? 0) + m.length);
142
+ }
143
+ }
144
+ catch {
145
+ /* unreadable file — skip */
146
+ }
147
+ return true;
148
+ });
149
+ if (scanned >= 200)
150
+ break;
151
+ }
152
+ const totalHits = [...counts.values()].reduce((a, b) => a + b, 0);
153
+ if (totalHits === 0) {
154
+ return {
155
+ attrs: KNOWN.slice(0, 5),
156
+ note: "(scanned but found 0 conventional attrs; default order)",
157
+ };
158
+ }
159
+ const sorted = [...counts.entries()]
160
+ .sort(([a, av], [b, bv]) => bv - av || KNOWN.indexOf(a) - KNOWN.indexOf(b))
161
+ .filter(([, v]) => v > 0)
162
+ .map(([k]) => k);
163
+ // Always keep `data-testid` as a fallback so consumers with mixed conventions don't lose it.
164
+ if (!sorted.includes("data-testid"))
165
+ sorted.push("data-testid");
166
+ const summary = [...counts.entries()]
167
+ .filter(([, v]) => v > 0)
168
+ .map(([k, v]) => `${k}×${v}`)
169
+ .join(", ");
170
+ return { attrs: sorted, note: `(sniffed ${scanned} source file(s); hits: ${summary})` };
171
+ }
172
+ function walk(dir, maxDepth, visit) {
173
+ if (maxDepth < 0)
174
+ return;
175
+ let entries;
176
+ try {
177
+ entries = readdirSync(dir);
178
+ }
179
+ catch {
180
+ return;
181
+ }
182
+ for (const e of entries) {
183
+ if (e === "node_modules" || e === ".git" || e === "dist" || e.startsWith("."))
184
+ continue;
185
+ const full = join(dir, e);
186
+ let st;
187
+ try {
188
+ st = statSync(full);
189
+ }
190
+ catch {
191
+ continue;
192
+ }
193
+ if (st.isDirectory())
194
+ walk(full, maxDepth - 1, visit);
195
+ else if (st.isFile()) {
196
+ if (!visit(full))
197
+ return;
198
+ }
199
+ }
200
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ // CLI subcommand registrations (RFC 0004 P4 / D6) — the one place the
2
+ // extensibility subcommands are wired into the registry. Importing this module
3
+ // for its side effect populates `command-registry.ts`'s map; `cli.ts` then
4
+ // dispatches through `commandFor(subcommand)` instead of a `switch`.
5
+ //
6
+ // Adding a subcommand is add-only: write its `runXxx(rest)` handler, then add a
7
+ // single `registerCommand("xxx", runXxx)` line here — no edit to the dispatch in
8
+ // `cli.ts`. Each registration binds the SAME handler the old `case` invoked, so
9
+ // the dispatch is byte-identical.
10
+ import { registerCommand } from "./command-registry.js";
11
+ import { runDoctor } from "./doctor.js";
12
+ import { runChrome } from "./chrome.js";
13
+ import { runInit } from "./init.js";
14
+ import { runServe } from "./serve.js";
15
+ import { runPlugin } from "../plugin/cli.js";
16
+ // `runDoctor` takes no argv (it ignored `rest`); the others consume `rest`.
17
+ // `runPlugin` accepts a `ReadonlyArray<string>`, which `string[]` satisfies.
18
+ registerCommand("doctor", () => runDoctor());
19
+ registerCommand("chrome", (rest) => runChrome(rest));
20
+ registerCommand("init", (rest) => runInit(rest));
21
+ registerCommand("serve", (rest) => runServe(rest));
22
+ registerCommand("plugin", (rest) => runPlugin(rest));
@@ -0,0 +1,14 @@
1
+ import { type Server } from "node:net";
2
+ interface ServeOptions {
3
+ readonly socketPath: string;
4
+ readonly attachCdp?: string;
5
+ readonly headless?: boolean;
6
+ }
7
+ export declare function runServe(rawArgs: string[]): Promise<number>;
8
+ /** Exposed for tests — programmatic `browxai serve` startup that returns the
9
+ * underlying net.Server so a test can `close()` it cleanly. */
10
+ export declare function startServeForTests(opts: ServeOptions): Promise<{
11
+ server: Server;
12
+ shutdown: () => Promise<void>;
13
+ }>;
14
+ export {};