@fusengine/browser-mcp 0.1.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 (353) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/dist/actions/act-by-ref.d.ts +13 -0
  4. package/dist/actions/act-by-ref.d.ts.map +1 -0
  5. package/dist/actions/act-by-ref.js +25 -0
  6. package/dist/actions/act-by-ref.js.map +1 -0
  7. package/dist/actions/human.d.ts +8 -0
  8. package/dist/actions/human.d.ts.map +1 -0
  9. package/dist/actions/human.js +6 -0
  10. package/dist/actions/human.js.map +1 -0
  11. package/dist/actions/login.d.ts +17 -0
  12. package/dist/actions/login.d.ts.map +1 -0
  13. package/dist/actions/login.js +11 -0
  14. package/dist/actions/login.js.map +1 -0
  15. package/dist/actions/navigation.d.ts +15 -0
  16. package/dist/actions/navigation.d.ts.map +1 -0
  17. package/dist/actions/navigation.js +33 -0
  18. package/dist/actions/navigation.js.map +1 -0
  19. package/dist/actions/perform.d.ts +15 -0
  20. package/dist/actions/perform.d.ts.map +1 -0
  21. package/dist/actions/perform.js +41 -0
  22. package/dist/actions/perform.js.map +1 -0
  23. package/dist/actions/smart-click.d.ts +9 -0
  24. package/dist/actions/smart-click.d.ts.map +1 -0
  25. package/dist/actions/smart-click.js +55 -0
  26. package/dist/actions/smart-click.js.map +1 -0
  27. package/dist/actions/smart-fill.d.ts +9 -0
  28. package/dist/actions/smart-fill.d.ts.map +1 -0
  29. package/dist/actions/smart-fill.js +46 -0
  30. package/dist/actions/smart-fill.js.map +1 -0
  31. package/dist/actions/wait-for.d.ts +21 -0
  32. package/dist/actions/wait-for.d.ts.map +1 -0
  33. package/dist/actions/wait-for.js +28 -0
  34. package/dist/actions/wait-for.js.map +1 -0
  35. package/dist/agent/actions-loop.d.ts +18 -0
  36. package/dist/agent/actions-loop.d.ts.map +1 -0
  37. package/dist/agent/actions-loop.js +44 -0
  38. package/dist/agent/actions-loop.js.map +1 -0
  39. package/dist/agent/browser-agent.d.ts +24 -0
  40. package/dist/agent/browser-agent.d.ts.map +1 -0
  41. package/dist/agent/browser-agent.js +36 -0
  42. package/dist/agent/browser-agent.js.map +1 -0
  43. package/dist/agent/compact.d.ts +8 -0
  44. package/dist/agent/compact.d.ts.map +1 -0
  45. package/dist/agent/compact.js +24 -0
  46. package/dist/agent/compact.js.map +1 -0
  47. package/dist/agent/config.d.ts +30 -0
  48. package/dist/agent/config.d.ts.map +1 -0
  49. package/dist/agent/config.js +49 -0
  50. package/dist/agent/config.js.map +1 -0
  51. package/dist/agent/detect.d.ts +17 -0
  52. package/dist/agent/detect.d.ts.map +1 -0
  53. package/dist/agent/detect.js +9 -0
  54. package/dist/agent/detect.js.map +1 -0
  55. package/dist/agent/network.d.ts +16 -0
  56. package/dist/agent/network.d.ts.map +1 -0
  57. package/dist/agent/network.js +16 -0
  58. package/dist/agent/network.js.map +1 -0
  59. package/dist/agent/probe-run.d.ts +6 -0
  60. package/dist/agent/probe-run.d.ts.map +1 -0
  61. package/dist/agent/probe-run.js +90 -0
  62. package/dist/agent/probe-run.js.map +1 -0
  63. package/dist/agent/report.d.ts +29 -0
  64. package/dist/agent/report.d.ts.map +1 -0
  65. package/dist/agent/report.js +53 -0
  66. package/dist/agent/report.js.map +1 -0
  67. package/dist/agent/run-steps.d.ts +22 -0
  68. package/dist/agent/run-steps.d.ts.map +1 -0
  69. package/dist/agent/run-steps.js +59 -0
  70. package/dist/agent/run-steps.js.map +1 -0
  71. package/dist/bin/cli.d.ts +3 -0
  72. package/dist/bin/cli.d.ts.map +1 -0
  73. package/dist/bin/cli.js +84 -0
  74. package/dist/bin/cli.js.map +1 -0
  75. package/dist/bin/mcp.d.ts +3 -0
  76. package/dist/bin/mcp.d.ts.map +1 -0
  77. package/dist/bin/mcp.js +28 -0
  78. package/dist/bin/mcp.js.map +1 -0
  79. package/dist/captcha/solve.d.ts +17 -0
  80. package/dist/captcha/solve.d.ts.map +1 -0
  81. package/dist/captcha/solve.js +42 -0
  82. package/dist/captcha/solve.js.map +1 -0
  83. package/dist/consent/booking-currency.d.ts +14 -0
  84. package/dist/consent/booking-currency.d.ts.map +1 -0
  85. package/dist/consent/booking-currency.js +82 -0
  86. package/dist/consent/booking-currency.js.map +1 -0
  87. package/dist/consent/consent.d.ts +11 -0
  88. package/dist/consent/consent.d.ts.map +1 -0
  89. package/dist/consent/consent.js +27 -0
  90. package/dist/consent/consent.js.map +1 -0
  91. package/dist/consent/currency-url.d.ts +10 -0
  92. package/dist/consent/currency-url.d.ts.map +1 -0
  93. package/dist/consent/currency-url.js +18 -0
  94. package/dist/consent/currency-url.js.map +1 -0
  95. package/dist/consent/currency.d.ts +14 -0
  96. package/dist/consent/currency.d.ts.map +1 -0
  97. package/dist/consent/currency.js +48 -0
  98. package/dist/consent/currency.js.map +1 -0
  99. package/dist/engine/cdp-engine.d.ts +21 -0
  100. package/dist/engine/cdp-engine.d.ts.map +1 -0
  101. package/dist/engine/cdp-engine.js +36 -0
  102. package/dist/engine/cdp-engine.js.map +1 -0
  103. package/dist/engine/cdp-launch.d.ts +11 -0
  104. package/dist/engine/cdp-launch.d.ts.map +1 -0
  105. package/dist/engine/cdp-launch.js +54 -0
  106. package/dist/engine/cdp-launch.js.map +1 -0
  107. package/dist/engine/context.d.ts +14 -0
  108. package/dist/engine/context.d.ts.map +1 -0
  109. package/dist/engine/context.js +22 -0
  110. package/dist/engine/context.js.map +1 -0
  111. package/dist/engine/launch.d.ts +6 -0
  112. package/dist/engine/launch.d.ts.map +1 -0
  113. package/dist/engine/launch.js +53 -0
  114. package/dist/engine/launch.js.map +1 -0
  115. package/dist/engine/loader.d.ts +13 -0
  116. package/dist/engine/loader.d.ts.map +1 -0
  117. package/dist/engine/loader.js +24 -0
  118. package/dist/engine/loader.js.map +1 -0
  119. package/dist/engine/patchright-engine.d.ts +4 -0
  120. package/dist/engine/patchright-engine.d.ts.map +1 -0
  121. package/dist/engine/patchright-engine.js +10 -0
  122. package/dist/engine/patchright-engine.js.map +1 -0
  123. package/dist/engine/playwright-engine.d.ts +8 -0
  124. package/dist/engine/playwright-engine.d.ts.map +1 -0
  125. package/dist/engine/playwright-engine.js +24 -0
  126. package/dist/engine/playwright-engine.js.map +1 -0
  127. package/dist/engine/registry.d.ts +13 -0
  128. package/dist/engine/registry.d.ts.map +1 -0
  129. package/dist/engine/registry.js +18 -0
  130. package/dist/engine/registry.js.map +1 -0
  131. package/dist/extraction/challenges.d.ts +9 -0
  132. package/dist/extraction/challenges.d.ts.map +1 -0
  133. package/dist/extraction/challenges.js +24 -0
  134. package/dist/extraction/challenges.js.map +1 -0
  135. package/dist/extraction/hotel-offers.d.ts +11 -0
  136. package/dist/extraction/hotel-offers.d.ts.map +1 -0
  137. package/dist/extraction/hotel-offers.js +63 -0
  138. package/dist/extraction/hotel-offers.js.map +1 -0
  139. package/dist/extraction/main-text.d.ts +13 -0
  140. package/dist/extraction/main-text.d.ts.map +1 -0
  141. package/dist/extraction/main-text.js +20 -0
  142. package/dist/extraction/main-text.js.map +1 -0
  143. package/dist/extraction/prices.d.ts +18 -0
  144. package/dist/extraction/prices.d.ts.map +1 -0
  145. package/dist/extraction/prices.js +74 -0
  146. package/dist/extraction/prices.js.map +1 -0
  147. package/dist/extraction/snapshot-diff.d.ts +28 -0
  148. package/dist/extraction/snapshot-diff.d.ts.map +1 -0
  149. package/dist/extraction/snapshot-diff.js +30 -0
  150. package/dist/extraction/snapshot-diff.js.map +1 -0
  151. package/dist/extraction/snapshot.d.ts +14 -0
  152. package/dist/extraction/snapshot.d.ts.map +1 -0
  153. package/dist/extraction/snapshot.js +26 -0
  154. package/dist/extraction/snapshot.js.map +1 -0
  155. package/dist/extraction/structured.d.ts +26 -0
  156. package/dist/extraction/structured.d.ts.map +1 -0
  157. package/dist/extraction/structured.js +28 -0
  158. package/dist/extraction/structured.js.map +1 -0
  159. package/dist/extraction/visual.d.ts +9 -0
  160. package/dist/extraction/visual.d.ts.map +1 -0
  161. package/dist/extraction/visual.js +29 -0
  162. package/dist/extraction/visual.js.map +1 -0
  163. package/dist/guardrails/preflight.d.ts +25 -0
  164. package/dist/guardrails/preflight.d.ts.map +1 -0
  165. package/dist/guardrails/preflight.js +27 -0
  166. package/dist/guardrails/preflight.js.map +1 -0
  167. package/dist/identity/country-profiles.d.ts +12 -0
  168. package/dist/identity/country-profiles.d.ts.map +1 -0
  169. package/dist/identity/country-profiles.js +58 -0
  170. package/dist/identity/country-profiles.js.map +1 -0
  171. package/dist/identity/identity.d.ts +19 -0
  172. package/dist/identity/identity.d.ts.map +1 -0
  173. package/dist/identity/identity.js +31 -0
  174. package/dist/identity/identity.js.map +1 -0
  175. package/dist/identity/resolve.d.ts +25 -0
  176. package/dist/identity/resolve.d.ts.map +1 -0
  177. package/dist/identity/resolve.js +21 -0
  178. package/dist/identity/resolve.js.map +1 -0
  179. package/dist/index.d.ts +12 -0
  180. package/dist/index.d.ts.map +1 -0
  181. package/dist/index.js +10 -0
  182. package/dist/index.js.map +1 -0
  183. package/dist/interfaces/engine-types.d.ts +15 -0
  184. package/dist/interfaces/engine-types.d.ts.map +1 -0
  185. package/dist/interfaces/engine-types.js +6 -0
  186. package/dist/interfaces/engine-types.js.map +1 -0
  187. package/dist/interfaces/engine.d.ts +30 -0
  188. package/dist/interfaces/engine.d.ts.map +1 -0
  189. package/dist/interfaces/engine.js +2 -0
  190. package/dist/interfaces/engine.js.map +1 -0
  191. package/dist/interfaces/extraction.d.ts +63 -0
  192. package/dist/interfaces/extraction.d.ts.map +1 -0
  193. package/dist/interfaces/extraction.js +6 -0
  194. package/dist/interfaces/extraction.js.map +1 -0
  195. package/dist/interfaces/net.d.ts +48 -0
  196. package/dist/interfaces/net.d.ts.map +1 -0
  197. package/dist/interfaces/net.js +6 -0
  198. package/dist/interfaces/net.js.map +1 -0
  199. package/dist/interfaces/report.d.ts +87 -0
  200. package/dist/interfaces/report.d.ts.map +1 -0
  201. package/dist/interfaces/report.js +2 -0
  202. package/dist/interfaces/report.js.map +1 -0
  203. package/dist/interfaces/types.d.ts +90 -0
  204. package/dist/interfaces/types.d.ts.map +1 -0
  205. package/dist/interfaces/types.js +6 -0
  206. package/dist/interfaces/types.js.map +1 -0
  207. package/dist/lib/errors.d.ts +19 -0
  208. package/dist/lib/errors.d.ts.map +1 -0
  209. package/dist/lib/errors.js +30 -0
  210. package/dist/lib/errors.js.map +1 -0
  211. package/dist/lib/evaluate.d.ts +17 -0
  212. package/dist/lib/evaluate.d.ts.map +1 -0
  213. package/dist/lib/evaluate.js +10 -0
  214. package/dist/lib/evaluate.js.map +1 -0
  215. package/dist/lib/fs.d.ts +11 -0
  216. package/dist/lib/fs.d.ts.map +1 -0
  217. package/dist/lib/fs.js +34 -0
  218. package/dist/lib/fs.js.map +1 -0
  219. package/dist/lib/logger.d.ts +14 -0
  220. package/dist/lib/logger.d.ts.map +1 -0
  221. package/dist/lib/logger.js +22 -0
  222. package/dist/lib/logger.js.map +1 -0
  223. package/dist/lib/output-dir.d.ts +12 -0
  224. package/dist/lib/output-dir.d.ts.map +1 -0
  225. package/dist/lib/output-dir.js +37 -0
  226. package/dist/lib/output-dir.js.map +1 -0
  227. package/dist/lib/retry.d.ts +28 -0
  228. package/dist/lib/retry.d.ts.map +1 -0
  229. package/dist/lib/retry.js +41 -0
  230. package/dist/lib/retry.js.map +1 -0
  231. package/dist/lib/text.d.ts +9 -0
  232. package/dist/lib/text.d.ts.map +1 -0
  233. package/dist/lib/text.js +13 -0
  234. package/dist/lib/text.js.map +1 -0
  235. package/dist/net/captcha-client.d.ts +10 -0
  236. package/dist/net/captcha-client.d.ts.map +1 -0
  237. package/dist/net/captcha-client.js +48 -0
  238. package/dist/net/captcha-client.js.map +1 -0
  239. package/dist/net/captcha-inject.d.ts +10 -0
  240. package/dist/net/captcha-inject.d.ts.map +1 -0
  241. package/dist/net/captcha-inject.js +24 -0
  242. package/dist/net/captcha-inject.js.map +1 -0
  243. package/dist/net/navigate.d.ts +19 -0
  244. package/dist/net/navigate.d.ts.map +1 -0
  245. package/dist/net/navigate.js +32 -0
  246. package/dist/net/navigate.js.map +1 -0
  247. package/dist/net/throttle.d.ts +3 -0
  248. package/dist/net/throttle.d.ts.map +1 -0
  249. package/dist/net/throttle.js +23 -0
  250. package/dist/net/throttle.js.map +1 -0
  251. package/dist/proxy/country-map.d.ts +13 -0
  252. package/dist/proxy/country-map.d.ts.map +1 -0
  253. package/dist/proxy/country-map.js +38 -0
  254. package/dist/proxy/country-map.js.map +1 -0
  255. package/dist/server/env-defaults.d.ts +11 -0
  256. package/dist/server/env-defaults.d.ts.map +1 -0
  257. package/dist/server/env-defaults.js +20 -0
  258. package/dist/server/env-defaults.js.map +1 -0
  259. package/dist/server/map-options.d.ts +6 -0
  260. package/dist/server/map-options.d.ts.map +1 -0
  261. package/dist/server/map-options.js +43 -0
  262. package/dist/server/map-options.js.map +1 -0
  263. package/dist/server/resources.d.ts +4 -0
  264. package/dist/server/resources.d.ts.map +1 -0
  265. package/dist/server/resources.js +28 -0
  266. package/dist/server/resources.js.map +1 -0
  267. package/dist/server/result.d.ts +12 -0
  268. package/dist/server/result.d.ts.map +1 -0
  269. package/dist/server/result.js +18 -0
  270. package/dist/server/result.js.map +1 -0
  271. package/dist/server/schemas.d.ts +191 -0
  272. package/dist/server/schemas.d.ts.map +1 -0
  273. package/dist/server/schemas.js +72 -0
  274. package/dist/server/schemas.js.map +1 -0
  275. package/dist/server/server.d.ts +14 -0
  276. package/dist/server/server.d.ts.map +1 -0
  277. package/dist/server/server.js +37 -0
  278. package/dist/server/server.js.map +1 -0
  279. package/dist/server/tools/act.d.ts +10 -0
  280. package/dist/server/tools/act.d.ts.map +1 -0
  281. package/dist/server/tools/act.js +62 -0
  282. package/dist/server/tools/act.js.map +1 -0
  283. package/dist/server/tools/connect.d.ts +10 -0
  284. package/dist/server/tools/connect.d.ts.map +1 -0
  285. package/dist/server/tools/connect.js +37 -0
  286. package/dist/server/tools/connect.js.map +1 -0
  287. package/dist/server/tools/extract-schema.d.ts +9 -0
  288. package/dist/server/tools/extract-schema.d.ts.map +1 -0
  289. package/dist/server/tools/extract-schema.js +29 -0
  290. package/dist/server/tools/extract-schema.js.map +1 -0
  291. package/dist/server/tools/extract.d.ts +9 -0
  292. package/dist/server/tools/extract.d.ts.map +1 -0
  293. package/dist/server/tools/extract.js +35 -0
  294. package/dist/server/tools/extract.js.map +1 -0
  295. package/dist/server/tools/navigate.d.ts +9 -0
  296. package/dist/server/tools/navigate.d.ts.map +1 -0
  297. package/dist/server/tools/navigate.js +27 -0
  298. package/dist/server/tools/navigate.js.map +1 -0
  299. package/dist/server/tools/probe.d.ts +8 -0
  300. package/dist/server/tools/probe.d.ts.map +1 -0
  301. package/dist/server/tools/probe.js +44 -0
  302. package/dist/server/tools/probe.js.map +1 -0
  303. package/dist/server/tools/run.d.ts +10 -0
  304. package/dist/server/tools/run.d.ts.map +1 -0
  305. package/dist/server/tools/run.js +30 -0
  306. package/dist/server/tools/run.js.map +1 -0
  307. package/dist/server/tools/screenshot.d.ts +10 -0
  308. package/dist/server/tools/screenshot.d.ts.map +1 -0
  309. package/dist/server/tools/screenshot.js +26 -0
  310. package/dist/server/tools/screenshot.js.map +1 -0
  311. package/dist/server/tools/session.d.ts +9 -0
  312. package/dist/server/tools/session.d.ts.map +1 -0
  313. package/dist/server/tools/session.js +33 -0
  314. package/dist/server/tools/session.js.map +1 -0
  315. package/dist/server/tools/snapshot.d.ts +12 -0
  316. package/dist/server/tools/snapshot.d.ts.map +1 -0
  317. package/dist/server/tools/snapshot.js +59 -0
  318. package/dist/server/tools/snapshot.js.map +1 -0
  319. package/dist/server/tools/wait.d.ts +9 -0
  320. package/dist/server/tools/wait.d.ts.map +1 -0
  321. package/dist/server/tools/wait.js +32 -0
  322. package/dist/server/tools/wait.js.map +1 -0
  323. package/dist/server/tools/with-session.d.ts +10 -0
  324. package/dist/server/tools/with-session.d.ts.map +1 -0
  325. package/dist/server/tools/with-session.js +16 -0
  326. package/dist/server/tools/with-session.js.map +1 -0
  327. package/dist/session/manager.d.ts +39 -0
  328. package/dist/session/manager.d.ts.map +1 -0
  329. package/dist/session/manager.js +76 -0
  330. package/dist/session/manager.js.map +1 -0
  331. package/dist/session/session.d.ts +28 -0
  332. package/dist/session/session.d.ts.map +1 -0
  333. package/dist/session/session.js +51 -0
  334. package/dist/session/session.js.map +1 -0
  335. package/dist/state/dom-signature.d.ts +8 -0
  336. package/dist/state/dom-signature.d.ts.map +1 -0
  337. package/dist/state/dom-signature.js +13 -0
  338. package/dist/state/dom-signature.js.map +1 -0
  339. package/dist/state/realtime.d.ts +11 -0
  340. package/dist/state/realtime.d.ts.map +1 -0
  341. package/dist/state/realtime.js +34 -0
  342. package/dist/state/realtime.js.map +1 -0
  343. package/dist/state/replay.d.ts +4 -0
  344. package/dist/state/replay.d.ts.map +1 -0
  345. package/dist/state/replay.js +21 -0
  346. package/dist/state/replay.js.map +1 -0
  347. package/dist/state/site-memory.d.ts +35 -0
  348. package/dist/state/site-memory.d.ts.map +1 -0
  349. package/dist/state/site-memory.js +56 -0
  350. package/dist/state/site-memory.js.map +1 -0
  351. package/package.json +70 -0
  352. package/proxies.example.json +9 -0
  353. package/scripts/postinstall.mjs +24 -0
@@ -0,0 +1,51 @@
1
+ import { attachListeners } from "../agent/network.js";
2
+ import { selectEngineForConfig } from "../engine/registry.js";
3
+ /** Open a new live session with listeners attached. */
4
+ export async function openSession(id, config, ttlMs) {
5
+ const opened = await selectEngineForConfig(config).open(config);
6
+ const page = opened.page ?? (await opened.context.newPage());
7
+ const logs = attachListeners(page);
8
+ const now = Date.now();
9
+ return {
10
+ id,
11
+ context: opened.context,
12
+ browser: opened.browser,
13
+ page,
14
+ config,
15
+ logs,
16
+ connected: opened.connected ?? false,
17
+ createdAt: now,
18
+ expiresAt: now + ttlMs,
19
+ };
20
+ }
21
+ /**
22
+ * Close a session. For launched browsers, close context + browser. For a CDP
23
+ * attach (`connected`), only drop the link — never close the user's browser
24
+ * or its default context.
25
+ */
26
+ export async function closeSession(session) {
27
+ if (session.connected) {
28
+ try {
29
+ await session.browser?.close();
30
+ }
31
+ catch {
32
+ /* ignore: detaching from a user browser */
33
+ }
34
+ return;
35
+ }
36
+ try {
37
+ await session.context.close();
38
+ }
39
+ catch {
40
+ /* ignore */
41
+ }
42
+ if (session.browser) {
43
+ try {
44
+ await session.browser.close();
45
+ }
46
+ catch {
47
+ /* ignore */
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/session/session.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAmB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAe9D,uDAAuD;AACvD,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,EAAU,EACV,MAAsB,EACtB,KAAa;IAEb,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO;QACL,EAAE;QACF,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI;QACJ,MAAM;QACN,IAAI;QACJ,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,KAAK;QACpC,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG,GAAG,KAAK;KACvB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAoB;IACrD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,YAAY;QACd,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * DOM signature: stable fingerprint of content + interactive elements.
3
+ * @module state/dom-signature
4
+ */
5
+ import type { Page } from "playwright";
6
+ /** Compute a SHA-1 fingerprint of the current DOM state. */
7
+ export declare function domSignature(page: Page): Promise<string>;
8
+ //# sourceMappingURL=dom-signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-signature.d.ts","sourceRoot":"","sources":["../../src/state/dom-signature.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAUvC,4DAA4D;AAC5D,wBAAsB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAG9D"}
@@ -0,0 +1,13 @@
1
+ import { evalScript } from "../lib/evaluate.js";
2
+ import { sha1 } from "../lib/fs.js";
3
+ const SIGNATURE_SCRIPT = `() => JSON.stringify({
4
+ text: document.body?.innerText || '',
5
+ buttons: [...document.querySelectorAll('button,a,input,select,textarea')]
6
+ .map(el => [el.tagName, el.innerText, el.value, el.getAttribute('aria-label'), el.id, el.className])
7
+ })`;
8
+ /** Compute a SHA-1 fingerprint of the current DOM state. */
9
+ export async function domSignature(page) {
10
+ const raw = await evalScript(page, SIGNATURE_SCRIPT);
11
+ return sha1(raw);
12
+ }
13
+ //# sourceMappingURL=dom-signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dom-signature.js","sourceRoot":"","sources":["../../src/state/dom-signature.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,MAAM,gBAAgB,GAAG;;;;GAItB,CAAC;AAEJ,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAU;IAC3C,MAAM,GAAG,GAAG,MAAM,UAAU,CAAS,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Wait for real-time stabilization after an action.
3
+ * @module state/realtime
4
+ */
5
+ import type { Page } from "playwright";
6
+ /**
7
+ * Wait until JS mutations settle (2 identical ticks) or the max delay elapses.
8
+ * A full navigation is handled without failing the mission.
9
+ */
10
+ export declare function waitForRealtimeSettle(page: Page, totalMs?: number, intervalMs?: number): Promise<void>;
11
+ //# sourceMappingURL=realtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.d.ts","sourceRoot":"","sources":["../../src/state/realtime.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAavC;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,IAAI,EACV,OAAO,SAAQ,EACf,UAAU,SAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAef"}
@@ -0,0 +1,34 @@
1
+ import { domSignature } from "./dom-signature.js";
2
+ /** Recompute the DOM signature, surviving a full navigation. */
3
+ async function safeSignature(page) {
4
+ try {
5
+ return await domSignature(page);
6
+ }
7
+ catch {
8
+ await page.waitForLoadState("domcontentloaded", { timeout: 10_000 });
9
+ return domSignature(page);
10
+ }
11
+ }
12
+ /**
13
+ * Wait until JS mutations settle (2 identical ticks) or the max delay elapses.
14
+ * A full navigation is handled without failing the mission.
15
+ */
16
+ export async function waitForRealtimeSettle(page, totalMs = 2_500, intervalMs = 150) {
17
+ let last = await safeSignature(page);
18
+ let stableTicks = 0;
19
+ const deadline = Date.now() + totalMs;
20
+ while (Date.now() < deadline) {
21
+ await page.waitForTimeout(intervalMs);
22
+ const current = await safeSignature(page);
23
+ if (current === last) {
24
+ stableTicks += 1;
25
+ if (stableTicks >= 2)
26
+ return;
27
+ }
28
+ else {
29
+ stableTicks = 0;
30
+ last = current;
31
+ }
32
+ }
33
+ }
34
+ //# sourceMappingURL=realtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime.js","sourceRoot":"","sources":["../../src/state/realtime.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,gEAAgE;AAChE,KAAK,UAAU,aAAa,CAAC,IAAU;IACrC,IAAI,CAAC;QACH,OAAO,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAU,EACV,OAAO,GAAG,KAAK,EACf,UAAU,GAAG,GAAG;IAEhB,IAAI,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,WAAW,IAAI,CAAC,CAAC;YACjB,IAAI,WAAW,IAAI,CAAC;gBAAE,OAAO;QAC/B,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,CAAC,CAAC;YAChB,IAAI,GAAG,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Page } from "playwright";
2
+ /** Capture a replay screenshot; returns the path or null if disabled/failed. */
3
+ export declare function captureReplayScreenshot(page: Page, dir: string, enabled: boolean, runId: string, index: number, phase: "before" | "after"): Promise<string | null>;
4
+ //# sourceMappingURL=replay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/state/replay.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,gFAAgF;AAChF,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,QAAQ,GAAG,OAAO,GACxB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Replay: before/after screenshots for each action.
3
+ * @module state/replay
4
+ */
5
+ import { join } from "node:path";
6
+ import { ensureDir } from "../lib/fs.js";
7
+ /** Capture a replay screenshot; returns the path or null if disabled/failed. */
8
+ export async function captureReplayScreenshot(page, dir, enabled, runId, index, phase) {
9
+ if (!enabled)
10
+ return null;
11
+ ensureDir(dir);
12
+ const path = join(dir, `${runId}-${String(index).padStart(2, "0")}-${phase}.png`);
13
+ try {
14
+ await page.screenshot({ path, fullPage: true });
15
+ return path;
16
+ }
17
+ catch {
18
+ return null;
19
+ }
20
+ }
21
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/state/replay.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAU,EACV,GAAW,EACX,OAAgB,EAChB,KAAa,EACb,KAAa,EACb,KAAyB;IAEzB,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,SAAS,CAAC,GAAG,CAAC,CAAC;IACf,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAClF,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { ActionResult } from "../interfaces/types.js";
2
+ /** Stored entry for a successful action. */
3
+ export interface MemoryEntry {
4
+ strategy: string;
5
+ lastOkAt: number;
6
+ target?: string;
7
+ type?: string;
8
+ }
9
+ /** A site's memory contents. */
10
+ export interface SiteMemory {
11
+ site: string;
12
+ actions: Record<string, MemoryEntry>;
13
+ }
14
+ /** Stable site key derived from the host (or "data" for data: URLs). */
15
+ export declare function siteKey(url: string): string;
16
+ /** Memory file path for a given URL. */
17
+ export declare function siteMemoryFilePath(dir: string, url: string): string;
18
+ /** Load a site's memory (empty structure if absent/unreadable). */
19
+ export declare function loadSiteMemory(dir: string, url: string): SiteMemory;
20
+ /** Memory key for an action (only click/fill are memorized). */
21
+ export declare function actionMemoryKey(action: {
22
+ type?: string;
23
+ target?: string;
24
+ }): string | null;
25
+ /** Return the stored entry matching an action, if any. */
26
+ export declare function rememberedAction(memory: SiteMemory, action: {
27
+ type?: string;
28
+ target?: string;
29
+ }): MemoryEntry | null;
30
+ /** Persist the winning strategy of an action; returns true if written. */
31
+ export declare function rememberActionStrategy(dir: string, url: string, action: {
32
+ type?: string;
33
+ target?: string;
34
+ }, result: ActionResult): boolean;
35
+ //# sourceMappingURL=site-memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-memory.d.ts","sourceRoot":"","sources":["../../src/state/site-memory.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAG3D,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtC;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS3C;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,CAInE;AAED,gEAAgE;AAChE,wBAAgB,eAAe,CAAC,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAGzF;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,WAAW,GAAG,IAAI,CAGpB;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,MAAM,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1C,MAAM,EAAE,YAAY,GACnB,OAAO,CAYT"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Per-site memory: reuse winning action strategies across runs.
3
+ * @module state/site-memory
4
+ */
5
+ import { join } from "node:path";
6
+ import { readJsonSafe, writeJson } from "../lib/fs.js";
7
+ /** Stable site key derived from the host (or "data" for data: URLs). */
8
+ export function siteKey(url) {
9
+ if (url.startsWith("data:"))
10
+ return "data";
11
+ let host = "";
12
+ try {
13
+ host = new URL(url).hostname.toLowerCase();
14
+ }
15
+ catch {
16
+ host = "";
17
+ }
18
+ return host.replace(/[^a-z0-9.-]+/g, "-") || "unknown";
19
+ }
20
+ /** Memory file path for a given URL. */
21
+ export function siteMemoryFilePath(dir, url) {
22
+ return join(dir, `${siteKey(url)}.json`);
23
+ }
24
+ /** Load a site's memory (empty structure if absent/unreadable). */
25
+ export function loadSiteMemory(dir, url) {
26
+ const fallback = { site: siteKey(url), actions: {} };
27
+ const data = readJsonSafe(siteMemoryFilePath(dir, url), fallback);
28
+ return { site: data.site ?? siteKey(url), actions: data.actions ?? {} };
29
+ }
30
+ /** Memory key for an action (only click/fill are memorized). */
31
+ export function actionMemoryKey(action) {
32
+ if (action.type !== "click" && action.type !== "fill")
33
+ return null;
34
+ return `${action.type}:${action.target ?? ""}`;
35
+ }
36
+ /** Return the stored entry matching an action, if any. */
37
+ export function rememberedAction(memory, action) {
38
+ const key = actionMemoryKey(action);
39
+ return key ? (memory.actions[key] ?? null) : null;
40
+ }
41
+ /** Persist the winning strategy of an action; returns true if written. */
42
+ export function rememberActionStrategy(dir, url, action, result) {
43
+ const key = actionMemoryKey(action);
44
+ if (!key || !result.strategy)
45
+ return false;
46
+ const memory = loadSiteMemory(dir, url);
47
+ memory.actions[key] = {
48
+ strategy: result.strategy,
49
+ lastOkAt: Math.floor(Date.now() / 1000),
50
+ target: action.target,
51
+ type: action.type,
52
+ };
53
+ writeJson(siteMemoryFilePath(dir, url), memory);
54
+ return true;
55
+ }
56
+ //# sourceMappingURL=site-memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site-memory.js","sourceRoot":"","sources":["../../src/state/site-memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAgBvD,wEAAwE;AACxE,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,MAAM,CAAC;IAC3C,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,IAAI,SAAS,CAAC;AACzD,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,GAAW;IACzD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,GAAW;IACrD,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACjE,MAAM,IAAI,GAAG,YAAY,CAAsB,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvF,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;AAC1E,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,eAAe,CAAC,MAA0C;IACxE,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACnE,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;AACjD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,gBAAgB,CAC9B,MAAkB,EAClB,MAA0C;IAE1C,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACpD,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CACpC,GAAW,EACX,GAAW,EACX,MAA0C,EAC1C,MAAoB;IAEpB,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG;QACpB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;QACvC,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI;KAClB,CAAC;IACF,SAAS,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;IAChD,OAAO,IAAI,CAAC;AACd,CAAC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@fusengine/browser-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server + CLI giving AI agents a real, stealth browser (Patchright/Playwright) — per-country identity, self-healing actions, snapshots, multi-step plans, structured extraction, CDP attach.",
5
+ "license": "MIT",
6
+ "author": "Fusengine",
7
+ "homepage": "https://github.com/fusengine/fuse-browser#readme",
8
+ "repository": { "type": "git", "url": "git+https://github.com/fusengine/fuse-browser.git" },
9
+ "bugs": { "url": "https://github.com/fusengine/fuse-browser/issues" },
10
+ "keywords": [
11
+ "mcp",
12
+ "model-context-protocol",
13
+ "ai-agents",
14
+ "browser-automation",
15
+ "playwright",
16
+ "patchright",
17
+ "stealth",
18
+ "web-scraping",
19
+ "cli",
20
+ "typescript"
21
+ ],
22
+ "type": "module",
23
+ "publishConfig": { "access": "public" },
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "bin": {
28
+ "fuse-browser": "dist/bin/cli.js",
29
+ "browser-mcp": "dist/bin/mcp.js"
30
+ },
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "scripts/postinstall.mjs",
40
+ "proxies.example.json",
41
+ "README.md",
42
+ "LICENSE"
43
+ ],
44
+ "scripts": {
45
+ "postinstall": "node scripts/postinstall.mjs",
46
+ "prepublishOnly": "npm run build",
47
+ "build": "tsc -p tsconfig.json",
48
+ "typecheck": "tsc -p tsconfig.json --noEmit",
49
+ "test": "bun test tests/unit",
50
+ "test:integration": "node --test --import tsx tests/integration/mcp.test.ts tests/integration/probe.test.ts tests/integration/snapshot.test.ts tests/integration/run.test.ts tests/integration/extract-schema.test.ts",
51
+ "browsers": "patchright install chromium",
52
+ "mcp": "node --import tsx src/bin/mcp.ts",
53
+ "cli": "node --import tsx src/bin/cli.ts"
54
+ },
55
+ "trustedDependencies": [
56
+ "patchright",
57
+ "playwright"
58
+ ],
59
+ "dependencies": {
60
+ "@modelcontextprotocol/sdk": "^1.29.0",
61
+ "patchright": "^1.60.1",
62
+ "playwright": "^1.60.0",
63
+ "zod": "^4.4.3"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^25.9.1",
67
+ "tsx": "^4.22.4",
68
+ "typescript": "^6.0.3"
69
+ }
70
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "CH": "http://user:password@ch-proxy.example:8080",
3
+ "US": "http://user:password@us-proxy.example:8080",
4
+ "GB": "http://user:password@gb-proxy.example:8080",
5
+ "FR": "http://user:password@fr-proxy.example:8080",
6
+ "DE": "http://user:password@de-proxy.example:8080",
7
+ "JP": "http://user:password@jp-proxy.example:8080",
8
+ "AE": "http://user:password@ae-proxy.example:8080"
9
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Soft post-install: attempt to download the Chromium binary so the package
3
+ * works out of the box. Never fails the install (CI / offline safe) and can be
4
+ * skipped with PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 or FUSE_SKIP_BROWSER_DOWNLOAD=1.
5
+ */
6
+ import { execSync } from "node:child_process";
7
+
8
+ const skip =
9
+ process.env.PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD || process.env.FUSE_SKIP_BROWSER_DOWNLOAD;
10
+
11
+ if (skip) {
12
+ console.log("[fuse-browser] Skipping Chromium download (skip env set).");
13
+ process.exit(0);
14
+ }
15
+
16
+ try {
17
+ console.log("[fuse-browser] Installing Chromium (patchright)…");
18
+ execSync("npx --no-install patchright install chromium", { stdio: "inherit" });
19
+ console.log("[fuse-browser] Chromium ready.");
20
+ } catch (err) {
21
+ console.warn(`[fuse-browser] Chromium auto-install failed (non-fatal): ${err?.message ?? err}`);
22
+ console.warn("[fuse-browser] Install manually: npx patchright install chromium");
23
+ process.exit(0);
24
+ }