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,496 @@
1
+ // `browxai plugin` CLI subcommands — install, remove, list, info,
2
+ // upgrade, sync. Shells out to a package manager against the
3
+ // workspace-rooted install dir: `pnpm` when available (the project's
4
+ // native manager), falling back to `npm` for adopters who installed
5
+ // browxai with npm and have no pnpm on PATH. Never auto-restarts the
6
+ // server — every command emits a "Server restart required" advisory.
7
+ //
8
+ // Reproducibility surface:
9
+ // - <workspace>/plugins.json declarative truth
10
+ // - <workspace>/plugins-lock.json auto-generated pin + sha256
11
+ // - <workspace>/plugins/ install dir (with node_modules/)
12
+ //
13
+ // The lock file format is documented inline below — kept small and
14
+ // hand-readable.
15
+ import { spawn, spawnSync } from "node:child_process";
16
+ import { createHash } from "node:crypto";
17
+ import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
18
+ import { join, relative, sep } from "node:path";
19
+ import { resolveWorkspace } from "../util/workspace.js";
20
+ import { log } from "../util/logging.js";
21
+ import { pluginPaths } from "./resolver.js";
22
+ import { packageManagerAdapter, packageManagerAdaptersByPriority, } from "./package-manager.js";
23
+ import { registerPluginCommand, pluginCommandFor } from "./command-registry.js";
24
+ const RESTART_NOTICE = "Server restart required — plugins are resolved ONCE at server start, so changes only take effect after a fresh `browxai` start.";
25
+ function readPluginsJson(paths) {
26
+ if (!existsSync(paths.declarationFile))
27
+ return { plugins: {} };
28
+ try {
29
+ const raw = JSON.parse(readFileSync(paths.declarationFile, "utf8"));
30
+ if (raw && typeof raw === "object" && raw !== null) {
31
+ const r = raw;
32
+ if (Array.isArray(r.plugins)) {
33
+ // Normalise array → object form.
34
+ const obj = {};
35
+ for (const n of r.plugins) {
36
+ if (typeof n === "string")
37
+ obj[n] = { enabled: true };
38
+ }
39
+ return { plugins: obj };
40
+ }
41
+ if (r.plugins && typeof r.plugins === "object") {
42
+ return { plugins: r.plugins };
43
+ }
44
+ }
45
+ }
46
+ catch {
47
+ /* fall through */
48
+ }
49
+ return { plugins: {} };
50
+ }
51
+ function writePluginsJson(paths, data) {
52
+ mkdirSync(paths.root, { recursive: true });
53
+ writeFileSync(paths.declarationFile, JSON.stringify(data, null, 2) + "\n", "utf8");
54
+ }
55
+ /** Tolerant lock read — also consumed by `browxai doctor` for lock-health checks. */
56
+ export function readLock(paths) {
57
+ if (!existsSync(paths.lockFile))
58
+ return { lockfileVersion: 1, entries: {} };
59
+ try {
60
+ const raw = JSON.parse(readFileSync(paths.lockFile, "utf8"));
61
+ if (raw && raw.lockfileVersion === 1 && raw.entries) {
62
+ return { lockfileVersion: 1, entries: raw.entries };
63
+ }
64
+ }
65
+ catch {
66
+ /* fall through */
67
+ }
68
+ return { lockfileVersion: 1, entries: {} };
69
+ }
70
+ function writeLock(paths, data) {
71
+ mkdirSync(paths.root, { recursive: true });
72
+ writeFileSync(paths.lockFile, JSON.stringify(data, null, 2) + "\n", "utf8");
73
+ }
74
+ /** Content pin over an installed package — the same hash `plugins-lock.json`
75
+ * stores as `contentSha256`. Exported so `browxai doctor` can recompute it
76
+ * and detect drift against the pinned value. */
77
+ export function sha256OfPackage(pkgRoot) {
78
+ const hash = createHash("sha256");
79
+ // Hash package.json verbatim + every file referenced by `files`/`main`/
80
+ // `browxai.register`. Falls back to walking package.json + main entry
81
+ // when the field isn't there. Keep small + deterministic.
82
+ const pkgJsonPath = join(pkgRoot, "package.json");
83
+ if (!existsSync(pkgJsonPath))
84
+ return "";
85
+ const pkgJson = readFileSync(pkgJsonPath);
86
+ hash.update(pkgJson);
87
+ try {
88
+ const parsed = JSON.parse(pkgJson.toString("utf8"));
89
+ const targets = new Set();
90
+ if (parsed.browxai?.register)
91
+ targets.add(parsed.browxai.register);
92
+ if (parsed.main)
93
+ targets.add(parsed.main);
94
+ for (const f of parsed.files ?? [])
95
+ targets.add(f);
96
+ for (const rel of [...targets].sort()) {
97
+ const abs = join(pkgRoot, rel);
98
+ if (!existsSync(abs))
99
+ continue;
100
+ const st = statSync(abs);
101
+ if (st.isFile()) {
102
+ hash.update(rel);
103
+ hash.update(readFileSync(abs));
104
+ }
105
+ else if (st.isDirectory()) {
106
+ for (const sub of walkDir(abs)) {
107
+ const subRel = relative(pkgRoot, sub).split(sep).join("/");
108
+ hash.update(subRel);
109
+ hash.update(readFileSync(sub));
110
+ }
111
+ }
112
+ }
113
+ }
114
+ catch {
115
+ /* fall through — partial hash is still meaningful for drift detection */
116
+ }
117
+ return hash.digest("hex");
118
+ }
119
+ function* walkDir(dir) {
120
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
121
+ const p = join(dir, entry.name);
122
+ if (entry.isFile())
123
+ yield p;
124
+ else if (entry.isDirectory())
125
+ yield* walkDir(p);
126
+ }
127
+ }
128
+ /** Emitted when neither pnpm nor npm is on PATH — actionable, names the
129
+ * requirement. Exported for the CLI tests. */
130
+ export const NO_PACKAGE_MANAGER_ERROR = "browxai plugin: no package manager found. Managing workspace plugins requires `pnpm` (preferred) or `npm` on PATH — install one (https://pnpm.io/installation or https://nodejs.org) and re-run.";
131
+ function canSpawn(cmd) {
132
+ const r = spawnSync(cmd, ["--version"], { stdio: "ignore" });
133
+ return !r.error && r.status === 0;
134
+ }
135
+ /**
136
+ * Probe for an available package manager. The adapters are walked in ascending
137
+ * probe priority (pnpm at 0 wins — it is the project's declared manager and what
138
+ * CI uses; npm at 1 is the fallback so `npm install -g browxai` adopters aren't
139
+ * dead-ended with a bare ENOENT). Returns null when none is on PATH. Adding a
140
+ * manager is a new adapter registration, not an edit here.
141
+ */
142
+ export function detectPackageManager(probe = canSpawn) {
143
+ for (const adapter of packageManagerAdaptersByPriority()) {
144
+ if (probe(adapter.name))
145
+ return adapter.name;
146
+ }
147
+ return null;
148
+ }
149
+ /** Translate an operation (+ optional target spec) into manager argv. */
150
+ export function pmArgs(pm, op, target) {
151
+ const adapter = packageManagerAdapter(pm);
152
+ if (!adapter)
153
+ throw new Error(`browxai plugin: no adapter registered for package manager "${pm}"`);
154
+ const verb = adapter.verbs[op];
155
+ return target === undefined ? [verb] : [verb, target];
156
+ }
157
+ async function runPm(paths, op, target) {
158
+ const pm = detectPackageManager();
159
+ if (pm === null) {
160
+ process.stderr.write(`${NO_PACKAGE_MANAGER_ERROR}\n`);
161
+ return 127;
162
+ }
163
+ // paths.installDir is workspace-rooted by construction (see
164
+ // pluginPaths() in resolver.ts — `<workspace>/plugins/`).
165
+ mkdirSync(paths.installDir, { recursive: true });
166
+ // Create a stub package.json so the manager has a project root to write into.
167
+ const stub = join(paths.installDir, "package.json");
168
+ if (!existsSync(stub)) {
169
+ writeFileSync(stub, JSON.stringify({ name: "browxai-plugins", version: "0.0.0", private: true }, null, 2) + "\n", "utf8");
170
+ }
171
+ const args = pmArgs(pm, op, target);
172
+ return new Promise((resolve) => {
173
+ const child = spawn(pm, [...args], {
174
+ cwd: paths.installDir,
175
+ stdio: "inherit",
176
+ });
177
+ child.on("exit", (code) => resolve(code ?? 1));
178
+ child.on("error", (err) => {
179
+ log.error(`browxai plugin: ${pm} spawn failed — ${err.message}`);
180
+ process.stderr.write(`${NO_PACKAGE_MANAGER_ERROR}\n`);
181
+ resolve(127);
182
+ });
183
+ });
184
+ }
185
+ /**
186
+ * Pin entry for `plugins-lock.json` — recompute version + sha256 after
187
+ * an install / upgrade / sync operation.
188
+ */
189
+ function pinEntry(paths, name, source) {
190
+ const pkgRoot = join(paths.nodeModulesDir, name);
191
+ const pkgJsonPath = join(pkgRoot, "package.json");
192
+ if (!existsSync(pkgJsonPath))
193
+ return null;
194
+ try {
195
+ const parsed = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
196
+ return {
197
+ name,
198
+ version: parsed.version ?? "0.0.0",
199
+ source,
200
+ contentSha256: sha256OfPackage(pkgRoot),
201
+ };
202
+ }
203
+ catch {
204
+ return null;
205
+ }
206
+ }
207
+ function inferTrustFromSource(source) {
208
+ if (source.startsWith("file:"))
209
+ return "local";
210
+ if (source.startsWith("@browxai/"))
211
+ return "kalebtec";
212
+ return "community";
213
+ }
214
+ /** Resolve the plugin name a `pnpm add` spec installs.
215
+ * Heuristic: drop a leading `file:` (the dir name is what npm uses);
216
+ * otherwise strip a trailing `@<version>` range. The CLI logs the
217
+ * resolved name before writing it to plugins.json so an operator can
218
+ * see what was added. */
219
+ function resolveInstalledName(source) {
220
+ if (source.startsWith("file:")) {
221
+ const rel = source.slice("file:".length).replace(/\/+$/, "");
222
+ const base = rel.split("/").pop() ?? rel;
223
+ // For file: installs, the actual installed name in node_modules is
224
+ // the package's `name` field — not the directory base. Walk
225
+ // node_modules afterward and find the match. Best-effort fallback:
226
+ // use the dir base if the package.json isn't reachable yet.
227
+ return base;
228
+ }
229
+ // Strip trailing `@version` (but tolerate scoped names that start with `@`).
230
+ const at = source.lastIndexOf("@");
231
+ if (at <= 0)
232
+ return source;
233
+ // e.g. `@scope/pkg@^1.0.0` → keep `@scope/pkg`
234
+ return source.slice(0, at);
235
+ }
236
+ function findActualPackageName(paths, hint) {
237
+ // For file: installs the directory base may not match the package
238
+ // name — walk node_modules looking for a package.json whose own
239
+ // path matches.
240
+ const direct = join(paths.nodeModulesDir, hint, "package.json");
241
+ if (existsSync(direct))
242
+ return hint;
243
+ // Scoped: search one level deeper.
244
+ if (existsSync(paths.nodeModulesDir)) {
245
+ for (const entry of readdirSync(paths.nodeModulesDir, { withFileTypes: true })) {
246
+ if (!entry.isDirectory())
247
+ continue;
248
+ if (entry.name.startsWith("@")) {
249
+ const scopeDir = join(paths.nodeModulesDir, entry.name);
250
+ for (const sub of readdirSync(scopeDir, { withFileTypes: true })) {
251
+ if (sub.isDirectory()) {
252
+ const full = `${entry.name}/${sub.name}`;
253
+ const pj = join(paths.nodeModulesDir, full, "package.json");
254
+ if (existsSync(pj)) {
255
+ try {
256
+ const parsed = JSON.parse(readFileSync(pj, "utf8"));
257
+ if (parsed.name === hint || sub.name === hint)
258
+ return full;
259
+ }
260
+ catch {
261
+ /* */
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+ else {
268
+ const pj = join(paths.nodeModulesDir, entry.name, "package.json");
269
+ if (existsSync(pj)) {
270
+ try {
271
+ const parsed = JSON.parse(readFileSync(pj, "utf8"));
272
+ if (parsed.name === hint)
273
+ return entry.name;
274
+ }
275
+ catch {
276
+ /* */
277
+ }
278
+ }
279
+ }
280
+ }
281
+ }
282
+ return hint;
283
+ }
284
+ async function cmdInstall(spec) {
285
+ const ws = resolveWorkspace();
286
+ const paths = pluginPaths(ws.root);
287
+ process.stderr.write(`browxai plugin: installing "${spec}" into ${paths.installDir}\n`);
288
+ const code = await runPm(paths, "add", spec);
289
+ if (code !== 0) {
290
+ process.stderr.write(`browxai plugin: install failed (exit ${code})\n`);
291
+ return code;
292
+ }
293
+ const hintName = resolveInstalledName(spec);
294
+ const name = findActualPackageName(paths, hintName);
295
+ // Persist into plugins.json.
296
+ const data = readPluginsJson(paths);
297
+ const trust = inferTrustFromSource(spec.startsWith("file:") ? spec : name);
298
+ data.plugins[name] = { enabled: true, ...(trust === "local" ? { trust: "local" } : {}) };
299
+ writePluginsJson(paths, data);
300
+ // Persist into plugins-lock.json.
301
+ const lock = readLock(paths);
302
+ const pinned = pinEntry(paths, name, spec);
303
+ if (pinned)
304
+ lock.entries[name] = pinned;
305
+ writeLock(paths, lock);
306
+ process.stderr.write(`browxai plugin: installed ${name}@${pinned?.version ?? "?"} (trust=${trust})\n`);
307
+ process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
308
+ return 0;
309
+ }
310
+ async function cmdRemove(name) {
311
+ const ws = resolveWorkspace();
312
+ const paths = pluginPaths(ws.root);
313
+ process.stderr.write(`browxai plugin: removing "${name}"\n`);
314
+ const code = await runPm(paths, "remove", name);
315
+ if (code !== 0) {
316
+ process.stderr.write(`browxai plugin: remove failed (exit ${code})\n`);
317
+ return code;
318
+ }
319
+ const data = readPluginsJson(paths);
320
+ delete data.plugins[name];
321
+ writePluginsJson(paths, data);
322
+ const lock = readLock(paths);
323
+ delete lock.entries[name];
324
+ writeLock(paths, lock);
325
+ process.stderr.write(`browxai plugin: removed ${name}\n`);
326
+ process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
327
+ return 0;
328
+ }
329
+ function cmdList() {
330
+ const ws = resolveWorkspace();
331
+ const paths = pluginPaths(ws.root);
332
+ const data = readPluginsJson(paths);
333
+ const lock = readLock(paths);
334
+ const names = Object.keys(data.plugins).sort();
335
+ if (names.length === 0) {
336
+ process.stdout.write("browxai plugin: no plugins declared\n");
337
+ return 0;
338
+ }
339
+ process.stdout.write(`browxai plugin: ${names.length} declared\n`);
340
+ for (const name of names) {
341
+ const entry = data.plugins[name];
342
+ const pin = lock.entries[name];
343
+ const installed = pin ? `${pin.version}` : "(not installed)";
344
+ const enabled = entry.enabled === false ? " [disabled]" : "";
345
+ const trust = entry.trust ? ` trust=${entry.trust}` : "";
346
+ process.stdout.write(` - ${name}@${installed}${trust}${enabled}\n`);
347
+ }
348
+ return 0;
349
+ }
350
+ function cmdInfo(name) {
351
+ const ws = resolveWorkspace();
352
+ const paths = pluginPaths(ws.root);
353
+ const data = readPluginsJson(paths);
354
+ const lock = readLock(paths);
355
+ const entry = data.plugins[name];
356
+ if (!entry) {
357
+ process.stderr.write(`browxai plugin: "${name}" is not declared in plugins.json\n`);
358
+ return 1;
359
+ }
360
+ const pkgJsonPath = join(paths.nodeModulesDir, name, "package.json");
361
+ let manifestSummary = null;
362
+ if (existsSync(pkgJsonPath)) {
363
+ try {
364
+ const parsed = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
365
+ manifestSummary = {
366
+ name: parsed.name,
367
+ version: parsed.version,
368
+ description: parsed.description,
369
+ browxai: parsed.browxai,
370
+ };
371
+ }
372
+ catch {
373
+ manifestSummary = { error: "package.json malformed" };
374
+ }
375
+ }
376
+ const info = {
377
+ declared: entry,
378
+ lock: lock.entries[name] ?? null,
379
+ manifest: manifestSummary,
380
+ notes: manifestSummary === null
381
+ ? "Not installed. Run `browxai plugin install` or `browxai plugin sync`."
382
+ : null,
383
+ };
384
+ process.stdout.write(JSON.stringify(info, null, 2) + "\n");
385
+ return 0;
386
+ }
387
+ async function cmdUpgrade(name) {
388
+ const ws = resolveWorkspace();
389
+ const paths = pluginPaths(ws.root);
390
+ process.stderr.write(`browxai plugin: ${name ? `upgrading ${name}` : "upgrading all"}\n`);
391
+ const code = await runPm(paths, "update", name);
392
+ if (code !== 0) {
393
+ process.stderr.write(`browxai plugin: upgrade failed (exit ${code})\n`);
394
+ return code;
395
+ }
396
+ // Re-pin the lock for affected entries.
397
+ const lock = readLock(paths);
398
+ const targets = name ? [name] : Object.keys(lock.entries);
399
+ for (const t of targets) {
400
+ const prevSource = lock.entries[t]?.source ?? t;
401
+ const pinned = pinEntry(paths, t, prevSource);
402
+ if (pinned)
403
+ lock.entries[t] = pinned;
404
+ }
405
+ writeLock(paths, lock);
406
+ process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
407
+ return 0;
408
+ }
409
+ async function cmdSync() {
410
+ const ws = resolveWorkspace();
411
+ const paths = pluginPaths(ws.root);
412
+ const data = readPluginsJson(paths);
413
+ const declared = Object.keys(data.plugins);
414
+ if (declared.length === 0) {
415
+ process.stdout.write("browxai plugin: nothing to sync (no plugins declared)\n");
416
+ return 0;
417
+ }
418
+ process.stderr.write(`browxai plugin: syncing ${declared.length} declared plugin(s)\n`);
419
+ // Run a single bare `install` so the package manager reconciles
420
+ // everything against the install dir's package.json (covers file:
421
+ // entries, whose original spec we don't know).
422
+ const code = await runPm(paths, "install");
423
+ if (code !== 0) {
424
+ process.stderr.write(`browxai plugin: sync install failed (exit ${code})\n`);
425
+ return code;
426
+ }
427
+ // Refresh lock for everything.
428
+ const lock = readLock(paths);
429
+ for (const name of declared) {
430
+ const prevSource = lock.entries[name]?.source ?? name;
431
+ const pinned = pinEntry(paths, name, prevSource);
432
+ if (pinned)
433
+ lock.entries[name] = pinned;
434
+ }
435
+ writeLock(paths, lock);
436
+ process.stderr.write(`browxai plugin: sync done. ${RESTART_NOTICE}\n`);
437
+ return 0;
438
+ }
439
+ function help() {
440
+ process.stdout.write(`Usage: browxai plugin <subcommand>\n\n` +
441
+ ` install <pkg> install a plugin from npm (or file:./path) into the workspace\n` +
442
+ ` remove <pkg> remove a plugin\n` +
443
+ ` list list declared plugins\n` +
444
+ ` info <pkg> full manifest + lock entry for one plugin\n` +
445
+ ` upgrade [<pkg>] upgrade one plugin (or all when omitted)\n` +
446
+ ` sync reconcile installed node_modules with plugins.json\n\n` +
447
+ `Every command writes to <workspace>/. Plugin lifecycle is\n` +
448
+ `resolved ONCE at server start — restart the server after any change.\n`);
449
+ return 0;
450
+ }
451
+ // RFC 0004 P4 / D6 — the extensibility verbs are an add-only registry. Each
452
+ // handler owns its OWN argument validation (the install/remove/info missing-arg
453
+ // checks the old `case` performed) and returns the SAME exit code, so the
454
+ // dispatch in `runPlugin` is a pure registry lookup. Adding a verb is one
455
+ // `registerPluginCommand(...)` line here, not a new `switch` arm.
456
+ registerPluginCommand("install", (rest) => {
457
+ if (!rest[0]) {
458
+ process.stderr.write("browxai plugin install: missing <pkg> argument\n");
459
+ return 1;
460
+ }
461
+ return cmdInstall(rest[0]);
462
+ });
463
+ registerPluginCommand("remove", (rest) => {
464
+ if (!rest[0]) {
465
+ process.stderr.write("browxai plugin remove: missing <pkg> argument\n");
466
+ return 1;
467
+ }
468
+ return cmdRemove(rest[0]);
469
+ });
470
+ registerPluginCommand("list", () => cmdList());
471
+ registerPluginCommand("info", (rest) => {
472
+ if (!rest[0]) {
473
+ process.stderr.write("browxai plugin info: missing <pkg> argument\n");
474
+ return 1;
475
+ }
476
+ return cmdInfo(rest[0]);
477
+ });
478
+ registerPluginCommand("upgrade", (rest) => cmdUpgrade(rest[0]));
479
+ registerPluginCommand("sync", () => cmdSync());
480
+ /** CLI dispatcher — invoked by `src/cli.ts` for the `plugin` subcommand. The
481
+ * help branch (no verb / `help` / `--help` / `-h`) and the unknown-verb
482
+ * diagnostic stay inline — they are the subcommand's fixed contract; the
483
+ * extensibility verbs resolve through the add-only registry above. */
484
+ export async function runPlugin(args) {
485
+ const [sub, ...rest] = args;
486
+ if (sub === undefined || sub === "help" || sub === "--help" || sub === "-h") {
487
+ return help();
488
+ }
489
+ const handler = pluginCommandFor(sub);
490
+ if (handler) {
491
+ return handler(rest);
492
+ }
493
+ process.stderr.write(`browxai plugin: unknown subcommand "${sub}"\n`);
494
+ help();
495
+ return 2;
496
+ }
@@ -0,0 +1,9 @@
1
+ /** A plugin subcommand handler: receives the argv after the verb token, returns
2
+ * the process exit code. */
3
+ export type PluginCommandHandler = (rest: string[]) => Promise<number> | number;
4
+ /** Register a plugin subcommand handler. Add-only: a new verb is one
5
+ * `registerPluginCommand(...)` call, never a new `case` in `runPlugin`. */
6
+ export declare function registerPluginCommand(name: string, handler: PluginCommandHandler): void;
7
+ /** Resolve a plugin subcommand handler, or `undefined` when the token is not a
8
+ * registered verb (the caller then runs the help / unknown-verb path). */
9
+ export declare function pluginCommandFor(name: string): PluginCommandHandler | undefined;
@@ -0,0 +1,23 @@
1
+ // `browxai plugin` subcommand registry (RFC 0004 P4 / D6) — the add-only
2
+ // `Map<string, PluginCommandHandler>` that replaces the extensibility arms of
3
+ // the `switch (sub)` in `runPlugin` (`plugin/cli.ts`).
4
+ //
5
+ // Scope: the EXTENSIBILITY verbs (`install` / `remove` / `list` / `info` /
6
+ // `upgrade` / `sync`) — the ones a future verb is added alongside. The
7
+ // `undefined` / `help` / `--help` / `-h` help branch and the unknown-verb
8
+ // diagnostic stay inline in `runPlugin`: they are the subcommand's fixed CLI
9
+ // contract, not extension points. Each handler receives the argv after the verb
10
+ // token (`rest`) and returns the exit code, owning its OWN argument validation
11
+ // (the `install`/`remove`/`info` missing-arg checks moved into their handlers),
12
+ // so the dispatch resolves the SAME handler the old `case` did.
13
+ const PLUGIN_COMMANDS = new Map();
14
+ /** Register a plugin subcommand handler. Add-only: a new verb is one
15
+ * `registerPluginCommand(...)` call, never a new `case` in `runPlugin`. */
16
+ export function registerPluginCommand(name, handler) {
17
+ PLUGIN_COMMANDS.set(name, handler);
18
+ }
19
+ /** Resolve a plugin subcommand handler, or `undefined` when the token is not a
20
+ * registered verb (the caller then runs the help / unknown-verb path). */
21
+ export function pluginCommandFor(name) {
22
+ return PLUGIN_COMMANDS.get(name);
23
+ }
@@ -0,0 +1,37 @@
1
+ export interface DepGraphInput {
2
+ /** Plugin name → list of plugin names it depends on (declared, direct). */
3
+ readonly directDeps: ReadonlyMap<string, ReadonlyArray<string>>;
4
+ }
5
+ export interface DepGraphResult {
6
+ /**
7
+ * Plugin names in load order (deps before dependents). Acyclic graphs
8
+ * always produce a result; cyclic ones throw.
9
+ */
10
+ readonly loadOrder: ReadonlyArray<string>;
11
+ /**
12
+ * For each plugin, the FULL transitive set of plugins it may call into
13
+ * (its declared dependsOn, plus everything those deps reach). Does NOT
14
+ * include the plugin itself — a plugin calling its own tools is
15
+ * trivially allowed at the call-graph layer.
16
+ */
17
+ readonly transitiveDeps: ReadonlyMap<string, ReadonlySet<string>>;
18
+ }
19
+ export declare class DepGraphCycleError extends Error {
20
+ readonly cycles: ReadonlyArray<ReadonlyArray<string>>;
21
+ constructor(cycles: ReadonlyArray<ReadonlyArray<string>>);
22
+ }
23
+ /**
24
+ * Build the dep graph result. Throws {@link DepGraphCycleError} if any
25
+ * non-trivial strongly-connected component is found. The error names
26
+ * every plugin in every cycle.
27
+ *
28
+ * Self-edges (`pluginA -> pluginA`) are tolerated and ignored — a
29
+ * self-edge encodes "this plugin can call its own tools" which is
30
+ * always-true and harmless.
31
+ *
32
+ * Edges pointing at plugins that aren't in `directDeps.keys()` are
33
+ * tolerated at this layer; the runtime separately validates that
34
+ * dependsOn targets exist + satisfy their semver range. We only model
35
+ * what's in the graph here.
36
+ */
37
+ export declare function buildDepGraph(input: DepGraphInput): DepGraphResult;