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,622 @@
1
+ // Pluggable credentials / TOTP hook (capability `credentials`, off by default).
2
+ //
3
+ // Why it exists: agents driving real auth flows routinely block on 2FA or
4
+ // stored-credential vault lookups. Without a hook here, the only escapes are
5
+ // (a) bake the seed/password into the prompt — which leaks into transcripts
6
+ // and eval datasets, defeating the SecretRegistry masking — or (b) hand-fly
7
+ // the step every time. Substrate-tier solution: a thin provider abstraction
8
+ // that reads from a configured vault, with no provider bundled by default.
9
+ //
10
+ // Posture: same as `eval` / `network-body` / `secrets`. Off by default, loud
11
+ // one-time warning at boot. Provider selection is per-deployment — NEVER
12
+ // bundled, NEVER auto-purchased (see no-auto-purchases rule).
13
+ //
14
+ // Provider matrix (selected via `BROWX_CREDENTIALS_PROVIDER`):
15
+ // - `oathtool` default backend; shells out to the system `oathtool`
16
+ // binary against seeds supplied by the operator (env or
17
+ // config file). No paid dependency. If the binary is
18
+ // missing, every call returns a structured failure with an
19
+ // install hint (Homebrew / apt) — never auto-installed.
20
+ // - `1password` shells out to the `op` CLI. The operator must run
21
+ // `op signin` out-of-band; this module never prompts.
22
+ // - `bitwarden` shells out to the `bw` CLI. Same out-of-band auth model;
23
+ // expects `BW_SESSION` in the server env.
24
+ // - `lastpass` shells out to the `lpass` CLI. Same out-of-band auth.
25
+ // - `none` explicit no-op provider; both tools return a structured
26
+ // refusal. Useful when the capability is on for testing the
27
+ // surface without wiring a real vault.
28
+ //
29
+ // All shell invocations: fixed argv, no shell interpolation, account name
30
+ // is passed as a discrete argv element (no injection surface). stdout is
31
+ // captured to a string, stderr is captured to a string for failure
32
+ // diagnostics, no exec-via-shell paths.
33
+ //
34
+ // Integration with SecretRegistry masking: `get_credential` does NOT echo
35
+ // the password back in cleartext. It auto-registers the password into the
36
+ // per-session SecretRegistry under an alias derived from the account name
37
+ // (`<PASSWORD_<account>>`), and the returned object carries the alias —
38
+ // the agent then uses `fill({value:"<PASSWORD_acct>"})` and Playwright
39
+ // receives the real value at dispatch via the registry's materialise path.
40
+ // The egress-masking layer also catches the value in every other sink.
41
+ // `get_totp` returns the 6-digit code directly (TOTPs are single-use and short-lived
42
+ // — the value is "spent" the moment it's typed, so masking buys little
43
+ // and complicates the agent's verify-step flow).
44
+ import { spawn } from "node:child_process";
45
+ export const ALL_PROVIDERS = [
46
+ "oathtool",
47
+ "1password",
48
+ "bitwarden",
49
+ "lastpass",
50
+ "none",
51
+ ];
52
+ /** Spawn a process with fixed argv (no shell). Returns combined result.
53
+ * Bounded by a 5s wall-clock — a hung CLI shouldn't block tool dispatch. */
54
+ export async function runArgv(argv, opts = {}) {
55
+ const timeoutMs = opts.timeoutMs ?? 5000;
56
+ return new Promise((resolve) => {
57
+ let settled = false;
58
+ const finish = (r) => {
59
+ if (settled)
60
+ return;
61
+ settled = true;
62
+ resolve(r);
63
+ };
64
+ try {
65
+ const cp = spawn(argv[0], argv.slice(1), {
66
+ env: opts.env ?? process.env,
67
+ stdio: ["pipe", "pipe", "pipe"],
68
+ });
69
+ let stdout = "";
70
+ let stderr = "";
71
+ const timer = setTimeout(() => {
72
+ try {
73
+ cp.kill("SIGKILL");
74
+ }
75
+ catch {
76
+ /* best-effort */
77
+ }
78
+ finish({
79
+ ok: false,
80
+ stdout,
81
+ stderr,
82
+ code: null,
83
+ spawnError: `timed out after ${timeoutMs}ms`,
84
+ });
85
+ }, timeoutMs);
86
+ cp.stdout.on("data", (d) => {
87
+ stdout += d.toString("utf8");
88
+ });
89
+ cp.stderr.on("data", (d) => {
90
+ stderr += d.toString("utf8");
91
+ });
92
+ cp.on("error", (e) => {
93
+ clearTimeout(timer);
94
+ finish({ ok: false, stdout, stderr, code: null, spawnError: e.message });
95
+ });
96
+ cp.on("close", (code) => {
97
+ clearTimeout(timer);
98
+ finish({ ok: code === 0, stdout, stderr, code });
99
+ });
100
+ if (opts.stdin !== undefined)
101
+ cp.stdin.end(opts.stdin);
102
+ else
103
+ cp.stdin.end();
104
+ }
105
+ catch (e) {
106
+ finish({
107
+ ok: false,
108
+ stdout: "",
109
+ stderr: "",
110
+ code: null,
111
+ spawnError: e instanceof Error ? e.message : String(e),
112
+ });
113
+ }
114
+ });
115
+ }
116
+ // ---------------------------------------------------------------------------
117
+ // Alias derivation
118
+ // ---------------------------------------------------------------------------
119
+ /** Turn an agent-facing account name into a SecretRegistry alias identifier.
120
+ * Result always matches `/^[A-Z][A-Z0-9_]*$/`. */
121
+ export function aliasFromAccount(account, prefix = "PASSWORD") {
122
+ const sanitised = account
123
+ .toUpperCase()
124
+ .replace(/[^A-Z0-9_]+/g, "_")
125
+ .replace(/^_+|_+$/g, "")
126
+ .replace(/_+/g, "_");
127
+ if (!sanitised)
128
+ return prefix;
129
+ // Guarantee leading letter (regex needs `[A-Z]` first).
130
+ const head = /^[A-Z]/.test(sanitised) ? sanitised : `X_${sanitised}`;
131
+ return `${prefix}_${head}`;
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // `none` provider — explicit no-op
135
+ // ---------------------------------------------------------------------------
136
+ class NoneProvider {
137
+ name = "none";
138
+ getTotp(_account) {
139
+ return Promise.resolve({
140
+ ok: false,
141
+ provider: "none",
142
+ error: "credentials provider is `none` — no vault backend is configured",
143
+ hint: "set BROWX_CREDENTIALS_PROVIDER to one of: oathtool, 1password, bitwarden, lastpass",
144
+ });
145
+ }
146
+ getCredential(_account) {
147
+ return Promise.resolve({
148
+ ok: false,
149
+ provider: "none",
150
+ error: "credentials provider is `none` — no vault backend is configured",
151
+ hint: "set BROWX_CREDENTIALS_PROVIDER to one of: oathtool, 1password, bitwarden, lastpass",
152
+ });
153
+ }
154
+ }
155
+ class OathtoolProvider {
156
+ cfg;
157
+ name = "oathtool";
158
+ constructor(cfg) {
159
+ this.cfg = cfg;
160
+ }
161
+ async getTotp(account) {
162
+ const seed = this.cfg.seeds[account];
163
+ if (!seed) {
164
+ return {
165
+ ok: false,
166
+ provider: "oathtool",
167
+ error: `oathtool: no seed registered for account "${account}"`,
168
+ hint: 'register the seed via BROWX_OATHTOOL_SEEDS="<account>=<BASE32SECRET>,…" or ' +
169
+ "BROWX_OATHTOOL_SEEDS_FILE=<path-to-json>, then restart the server",
170
+ };
171
+ }
172
+ const binary = this.cfg.binary ?? "oathtool";
173
+ // oathtool -b --totp <seed> — base32 input, default 6-digit, default 30s step
174
+ const r = await runArgv([binary, "-b", "--totp", seed], { timeoutMs: 3000 });
175
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
176
+ return {
177
+ ok: false,
178
+ provider: "oathtool",
179
+ error: `oathtool binary "${binary}" not found on PATH`,
180
+ hint: "install oathtool (macOS: `brew install oath-toolkit`; Debian/Ubuntu: `apt install oathtool`)",
181
+ };
182
+ }
183
+ if (!r.ok) {
184
+ return {
185
+ ok: false,
186
+ provider: "oathtool",
187
+ error: `oathtool failed (exit ${r.code ?? "?"})`,
188
+ hint: r.stderr.trim() || r.spawnError || "check the seed value is valid BASE32",
189
+ };
190
+ }
191
+ const code = r.stdout.trim();
192
+ if (!/^\d{6,8}$/.test(code)) {
193
+ return {
194
+ ok: false,
195
+ provider: "oathtool",
196
+ error: `oathtool returned unexpected output (not a 6-8 digit code)`,
197
+ hint: "verify the seed is BASE32 and oathtool's default options haven't been overridden",
198
+ };
199
+ }
200
+ return { ok: true, code, provider: "oathtool" };
201
+ }
202
+ getCredential(_account) {
203
+ return Promise.resolve({
204
+ ok: false,
205
+ provider: "oathtool",
206
+ error: "oathtool is a TOTP-only backend; it does not store username/password",
207
+ hint: "pair with another provider for credential lookup (1password, bitwarden, lastpass)",
208
+ });
209
+ }
210
+ }
211
+ /** Parse `acct1=SEED1,acct2=SEED2` into a record. Tolerates whitespace,
212
+ * rejects malformed entries silently (returns what parses). Internal — the
213
+ * full resolution flow surfaces a clean warning when nothing parses. */
214
+ export function parseSeedsEnv(raw) {
215
+ if (!raw)
216
+ return {};
217
+ const out = {};
218
+ for (const part of raw.split(",")) {
219
+ const trimmed = part.trim();
220
+ if (!trimmed)
221
+ continue;
222
+ const eq = trimmed.indexOf("=");
223
+ if (eq <= 0)
224
+ continue;
225
+ const k = trimmed.slice(0, eq).trim();
226
+ const v = trimmed.slice(eq + 1).trim();
227
+ if (k && v)
228
+ out[k] = v;
229
+ }
230
+ return out;
231
+ }
232
+ // ---------------------------------------------------------------------------
233
+ // `1password` provider — shells out to `op`
234
+ // ---------------------------------------------------------------------------
235
+ class OnePasswordProvider {
236
+ binary;
237
+ name = "1password";
238
+ constructor(binary = "op") {
239
+ this.binary = binary;
240
+ }
241
+ async getTotp(account) {
242
+ const r = await runArgv([this.binary, "item", "get", account, "--otp"], { timeoutMs: 5000 });
243
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
244
+ return {
245
+ ok: false,
246
+ provider: "1password",
247
+ error: `1password CLI "${this.binary}" not found on PATH`,
248
+ hint: "install the 1Password CLI from https://developer.1password.com/docs/cli/get-started/",
249
+ };
250
+ }
251
+ if (!r.ok) {
252
+ return {
253
+ ok: false,
254
+ provider: "1password",
255
+ error: `op item get --otp failed (exit ${r.code ?? "?"})`,
256
+ hint: r.stderr.trim() || "ensure you've run `op signin` and the item name is correct",
257
+ };
258
+ }
259
+ const code = r.stdout.trim();
260
+ if (!/^\d{6,8}$/.test(code)) {
261
+ return {
262
+ ok: false,
263
+ provider: "1password",
264
+ error: "1password returned unexpected output (not a 6-8 digit code)",
265
+ hint: "verify the item has a one-time-password field configured",
266
+ };
267
+ }
268
+ return { ok: true, code, provider: "1password" };
269
+ }
270
+ async getCredential(account) {
271
+ // `op item get <name> --fields label=username,label=password --format json`
272
+ const r = await runArgv([
273
+ this.binary,
274
+ "item",
275
+ "get",
276
+ account,
277
+ "--fields",
278
+ "label=username,label=password",
279
+ "--format",
280
+ "json",
281
+ ], { timeoutMs: 5000 });
282
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
283
+ return {
284
+ ok: false,
285
+ provider: "1password",
286
+ error: `1password CLI "${this.binary}" not found on PATH`,
287
+ hint: "install the 1Password CLI from https://developer.1password.com/docs/cli/get-started/",
288
+ };
289
+ }
290
+ if (!r.ok) {
291
+ return {
292
+ ok: false,
293
+ provider: "1password",
294
+ error: `op item get failed (exit ${r.code ?? "?"})`,
295
+ hint: r.stderr.trim() || "ensure you've run `op signin` and the item name is correct",
296
+ };
297
+ }
298
+ const parsed = parseFieldsJson(r.stdout);
299
+ if (!parsed.username || !parsed.password) {
300
+ return {
301
+ ok: false,
302
+ provider: "1password",
303
+ error: "1password item missing username or password field",
304
+ hint: "verify the item has both a `username` and `password` field labelled accordingly",
305
+ };
306
+ }
307
+ return {
308
+ ok: true,
309
+ provider: "1password",
310
+ username: parsed.username,
311
+ _password: parsed.password,
312
+ };
313
+ }
314
+ }
315
+ // ---------------------------------------------------------------------------
316
+ // `bitwarden` provider — shells out to `bw`
317
+ // ---------------------------------------------------------------------------
318
+ class BitwardenProvider {
319
+ binary;
320
+ name = "bitwarden";
321
+ constructor(binary = "bw") {
322
+ this.binary = binary;
323
+ }
324
+ async getTotp(account) {
325
+ const r = await runArgv([this.binary, "get", "totp", account], { timeoutMs: 5000 });
326
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
327
+ return {
328
+ ok: false,
329
+ provider: "bitwarden",
330
+ error: `bitwarden CLI "${this.binary}" not found on PATH`,
331
+ hint: "install the Bitwarden CLI: https://bitwarden.com/help/cli/",
332
+ };
333
+ }
334
+ if (!r.ok) {
335
+ return {
336
+ ok: false,
337
+ provider: "bitwarden",
338
+ error: `bw get totp failed (exit ${r.code ?? "?"})`,
339
+ hint: r.stderr.trim() || "ensure $BW_SESSION is set (`bw unlock`) and the item exists",
340
+ };
341
+ }
342
+ const code = r.stdout.trim();
343
+ if (!/^\d{6,8}$/.test(code)) {
344
+ return {
345
+ ok: false,
346
+ provider: "bitwarden",
347
+ error: "bitwarden returned unexpected output (not a 6-8 digit code)",
348
+ hint: "verify the item has a TOTP field configured",
349
+ };
350
+ }
351
+ return { ok: true, code, provider: "bitwarden" };
352
+ }
353
+ async getCredential(account) {
354
+ const r = await runArgv([this.binary, "get", "item", account], { timeoutMs: 5000 });
355
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
356
+ return {
357
+ ok: false,
358
+ provider: "bitwarden",
359
+ error: `bitwarden CLI "${this.binary}" not found on PATH`,
360
+ hint: "install the Bitwarden CLI: https://bitwarden.com/help/cli/",
361
+ };
362
+ }
363
+ if (!r.ok) {
364
+ return {
365
+ ok: false,
366
+ provider: "bitwarden",
367
+ error: `bw get item failed (exit ${r.code ?? "?"})`,
368
+ hint: r.stderr.trim() || "ensure $BW_SESSION is set (`bw unlock`) and the item exists",
369
+ };
370
+ }
371
+ try {
372
+ const item = JSON.parse(r.stdout);
373
+ const username = item.login?.username;
374
+ const password = item.login?.password;
375
+ if (!username || !password) {
376
+ return {
377
+ ok: false,
378
+ provider: "bitwarden",
379
+ error: "bitwarden item missing username or password",
380
+ hint: "verify the item has both fields populated",
381
+ };
382
+ }
383
+ return {
384
+ ok: true,
385
+ provider: "bitwarden",
386
+ username,
387
+ _password: password,
388
+ };
389
+ }
390
+ catch (e) {
391
+ return {
392
+ ok: false,
393
+ provider: "bitwarden",
394
+ error: "could not parse bw output as JSON",
395
+ hint: e instanceof Error ? e.message : String(e),
396
+ };
397
+ }
398
+ }
399
+ }
400
+ // ---------------------------------------------------------------------------
401
+ // `lastpass` provider — shells out to `lpass`
402
+ // ---------------------------------------------------------------------------
403
+ class LastpassProvider {
404
+ binary;
405
+ name = "lastpass";
406
+ constructor(binary = "lpass") {
407
+ this.binary = binary;
408
+ }
409
+ async getTotp(account) {
410
+ const r = await runArgv([this.binary, "show", "--field=otp", account], { timeoutMs: 5000 });
411
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
412
+ return {
413
+ ok: false,
414
+ provider: "lastpass",
415
+ error: `lastpass CLI "${this.binary}" not found on PATH`,
416
+ hint: "install lpass (macOS: `brew install lastpass-cli`)",
417
+ };
418
+ }
419
+ if (!r.ok) {
420
+ return {
421
+ ok: false,
422
+ provider: "lastpass",
423
+ error: `lpass show --field=otp failed (exit ${r.code ?? "?"})`,
424
+ hint: r.stderr.trim() || "ensure you've run `lpass login` and the item has an otp field",
425
+ };
426
+ }
427
+ const code = r.stdout.trim();
428
+ if (!/^\d{6,8}$/.test(code)) {
429
+ return {
430
+ ok: false,
431
+ provider: "lastpass",
432
+ error: "lastpass returned unexpected output (not a 6-8 digit code)",
433
+ hint: "verify the item has a TOTP field configured",
434
+ };
435
+ }
436
+ return { ok: true, code, provider: "lastpass" };
437
+ }
438
+ async getCredential(account) {
439
+ const r = await runArgv([this.binary, "show", "--username", "--password", account], {
440
+ timeoutMs: 5000,
441
+ });
442
+ if (r.spawnError && /ENOENT/.test(r.spawnError)) {
443
+ return {
444
+ ok: false,
445
+ provider: "lastpass",
446
+ error: `lastpass CLI "${this.binary}" not found on PATH`,
447
+ hint: "install lpass (macOS: `brew install lastpass-cli`)",
448
+ };
449
+ }
450
+ if (!r.ok) {
451
+ return {
452
+ ok: false,
453
+ provider: "lastpass",
454
+ error: `lpass show failed (exit ${r.code ?? "?"})`,
455
+ hint: r.stderr.trim() || "ensure you've run `lpass login` and the item exists",
456
+ };
457
+ }
458
+ // lpass emits the requested fields one per line in the order requested.
459
+ const lines = r.stdout
460
+ .split("\n")
461
+ .map((l) => l.trim())
462
+ .filter(Boolean);
463
+ const [username, password] = lines;
464
+ if (!username || !password) {
465
+ return {
466
+ ok: false,
467
+ provider: "lastpass",
468
+ error: "lastpass returned no username/password",
469
+ hint: "verify the item has both fields populated",
470
+ };
471
+ }
472
+ return {
473
+ ok: true,
474
+ provider: "lastpass",
475
+ username,
476
+ _password: password,
477
+ };
478
+ }
479
+ }
480
+ // ---------------------------------------------------------------------------
481
+ // JSON helpers
482
+ // ---------------------------------------------------------------------------
483
+ function parseFieldsJson(raw) {
484
+ try {
485
+ const parsed = JSON.parse(raw);
486
+ // `op item get --fields label=username,label=password --format json` emits
487
+ // an array of `{label, value, …}` entries.
488
+ if (Array.isArray(parsed)) {
489
+ const out = {};
490
+ for (const entry of parsed) {
491
+ const e = entry;
492
+ if (e.label === "username" && typeof e.value === "string")
493
+ out.username = e.value;
494
+ if (e.label === "password" && typeof e.value === "string")
495
+ out.password = e.value;
496
+ }
497
+ return out;
498
+ }
499
+ return {};
500
+ }
501
+ catch {
502
+ return {};
503
+ }
504
+ }
505
+ /**
506
+ * Resolve the configured provider from env. Returns the provider singleton
507
+ * + any non-fatal startup warnings (the caller logs these via `log.warn`).
508
+ *
509
+ * Env contract:
510
+ * BROWX_CREDENTIALS_PROVIDER=oathtool|1password|bitwarden|lastpass|none
511
+ * BROWX_OATHTOOL_BIN=/custom/path/to/oathtool
512
+ * BROWX_OATHTOOL_SEEDS="acct1=BASE32,acct2=BASE32"
513
+ * BROWX_1PASSWORD_BIN=/custom/path/to/op
514
+ * BROWX_BITWARDEN_BIN=/custom/path/to/bw
515
+ * BROWX_LASTPASS_BIN=/custom/path/to/lpass
516
+ *
517
+ * Default is `oathtool` (the self-managed, no-paid-dependency path). The
518
+ * provider object is constructed eagerly; if its CLI is missing, that
519
+ * surfaces per-call, never at startup (so the server still boots).
520
+ */
521
+ export function resolveCredentialsProvider(env = process.env) {
522
+ const raw = env.BROWX_CREDENTIALS_PROVIDER?.trim().toLowerCase();
523
+ const warnings = [];
524
+ const name = (() => {
525
+ if (!raw)
526
+ return "oathtool";
527
+ if (ALL_PROVIDERS.includes(raw))
528
+ return raw;
529
+ warnings.push(`BROWX_CREDENTIALS_PROVIDER: unknown provider "${raw}" — falling back to "oathtool". ` +
530
+ `Valid: ${ALL_PROVIDERS.join(", ")}.`);
531
+ return "oathtool";
532
+ })();
533
+ let provider;
534
+ switch (name) {
535
+ case "oathtool": {
536
+ const seeds = parseSeedsEnv(env.BROWX_OATHTOOL_SEEDS);
537
+ provider = new OathtoolProvider({
538
+ binary: env.BROWX_OATHTOOL_BIN?.trim() || undefined,
539
+ seeds,
540
+ });
541
+ break;
542
+ }
543
+ case "1password":
544
+ provider = new OnePasswordProvider(env.BROWX_1PASSWORD_BIN?.trim() || undefined);
545
+ break;
546
+ case "bitwarden":
547
+ provider = new BitwardenProvider(env.BROWX_BITWARDEN_BIN?.trim() || undefined);
548
+ break;
549
+ case "lastpass":
550
+ provider = new LastpassProvider(env.BROWX_LASTPASS_BIN?.trim() || undefined);
551
+ break;
552
+ case "none":
553
+ provider = new NoneProvider();
554
+ break;
555
+ }
556
+ return { provider, config: { provider: name, warnings } };
557
+ }
558
+ /**
559
+ * Test seam: build a provider instance directly from a callable pair.
560
+ * Used by the test suite to mock both endpoints without spawning a real
561
+ * binary. Not exported for runtime use.
562
+ */
563
+ export function makeFakeProvider(impl, name = "oathtool") {
564
+ return { name, getTotp: impl.getTotp, getCredential: impl.getCredential };
565
+ }
566
+ /**
567
+ * Apply a credential lookup to the per-session secrets registry:
568
+ * registers the password under an account-derived alias, then returns the
569
+ * public credential shape (username + aliasName only, NEVER the password).
570
+ *
571
+ * Callers pass `registry` only when the `secrets` capability is enabled.
572
+ * When it's not, the function returns a structured refusal — registering
573
+ * a password without the egress-masking layer engaged would leak the
574
+ * password into transcripts the first time the agent referenced it.
575
+ */
576
+ export function applyCredentialToRegistry(result, registry, account, pageUrl) {
577
+ if (!result.ok) {
578
+ // Surface refusal verbatim; never carries a password.
579
+ return stripInternal(result);
580
+ }
581
+ if (!result._password || !result.username) {
582
+ return {
583
+ ok: false,
584
+ provider: result.provider,
585
+ error: "provider returned incomplete credential (missing username or password)",
586
+ };
587
+ }
588
+ if (!registry) {
589
+ return {
590
+ ok: false,
591
+ provider: result.provider,
592
+ error: "credentials lookup refused: the `secrets` capability is not enabled. " +
593
+ "Returning a password without secrets-masking would leak it into transcripts. " +
594
+ "Add `secrets` to BROWX_CAPABILITIES alongside `credentials`, then restart.",
595
+ };
596
+ }
597
+ const aliasName = aliasFromAccount(account);
598
+ try {
599
+ registry.register({
600
+ name: aliasName,
601
+ value: result._password,
602
+ ...(pageUrl ? {} : {}),
603
+ });
604
+ }
605
+ catch (e) {
606
+ return {
607
+ ok: false,
608
+ provider: result.provider,
609
+ error: `could not register password into secrets registry: ${e instanceof Error ? e.message : String(e)}`,
610
+ };
611
+ }
612
+ return {
613
+ ok: true,
614
+ provider: result.provider,
615
+ username: result.username,
616
+ aliasName,
617
+ };
618
+ }
619
+ function stripInternal(r) {
620
+ const { _password, ...rest } = r;
621
+ return rest;
622
+ }
@@ -0,0 +1,22 @@
1
+ export declare const DEFAULT_ACTION_TIMEOUT_MS = 5000;
2
+ export declare const MIN_ACTION_TIMEOUT_MS = 1;
3
+ export declare const MAX_ACTION_TIMEOUT_MS = 3600000;
4
+ export declare class DeadlineError extends Error {
5
+ readonly label: string;
6
+ readonly ms: number;
7
+ constructor(label: string, ms: number);
8
+ }
9
+ /**
10
+ * Clamp a requested timeout into [MIN, MAX]. Returns the effective value plus
11
+ * an optional warning when the request was out of range (so the tool can
12
+ * surface "you asked for an insane timeout; clamped").
13
+ */
14
+ export declare function clampTimeout(requested: number | undefined, fallback: number): {
15
+ ms: number;
16
+ warning?: string;
17
+ };
18
+ /**
19
+ * Race `p` against `ms`. Rejects with `DeadlineError` on expiry. The timer is
20
+ * always cleared (no leaked handles) whichever side wins.
21
+ */
22
+ export declare function withDeadline<T>(p: Promise<T>, ms: number, label: string): Promise<T>;