@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.51

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 (368) hide show
  1. package/AUTHORING.md +537 -33
  2. package/CHANGELOG.md +205 -1
  3. package/README.md +83 -22
  4. package/SUBMISSION.md +2 -2
  5. package/bin/apifuse-check.ts +165 -11
  6. package/bin/apifuse-dev.ts +57 -13
  7. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  8. package/bin/apifuse-migrate-shape.ts +202 -0
  9. package/bin/apifuse-pack-check.ts +22 -2
  10. package/bin/apifuse-pack-smoke.ts +57 -2
  11. package/bin/apifuse-pack-types.ts +357 -38
  12. package/bin/apifuse-perf.ts +14 -13
  13. package/bin/apifuse-record.ts +709 -72
  14. package/bin/apifuse-submit-check.ts +2344 -324
  15. package/bin/apifuse-sync-assets.ts +117 -0
  16. package/bin/submit-check-delimited-text.ts +50 -0
  17. package/dist/auth-turn/index.d.ts +3 -3
  18. package/dist/auth-turn/index.js +1 -1
  19. package/dist/auth.d.ts +14 -0
  20. package/dist/auth.js +67 -0
  21. package/dist/ceremonies/index.d.ts +16 -0
  22. package/dist/ceremonies/index.js +141 -36
  23. package/dist/cli/commands.d.ts +1 -1
  24. package/dist/cli/commands.js +27 -0
  25. package/dist/cli/create.d.ts +4 -1
  26. package/dist/cli/create.js +42 -37
  27. package/dist/cli/migrate-operation-declaration.d.ts +59 -0
  28. package/dist/cli/migrate-operation-declaration.js +1249 -0
  29. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  30. package/dist/cli/migrate-operation-shape.js +113 -0
  31. package/dist/cli/migrate-provider-shape.d.ts +52 -0
  32. package/dist/cli/migrate-provider-shape.js +578 -0
  33. package/dist/cli/prompt-assets.d.ts +80 -0
  34. package/dist/cli/prompt-assets.js +743 -0
  35. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  36. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  37. package/dist/cli/templates/provider/README.md.tpl +5 -5
  38. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  39. package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
  40. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  41. package/dist/config/loader.d.ts +179 -16
  42. package/dist/config/loader.js +435 -127
  43. package/dist/contract-serialization.js +4 -8
  44. package/dist/contract-types.d.ts +12 -5
  45. package/dist/contract.js +24 -10
  46. package/dist/declaration-validation.d.ts +33 -0
  47. package/dist/declaration-validation.js +266 -0
  48. package/dist/define.d.ts +66 -29
  49. package/dist/define.js +778 -69
  50. package/dist/dev.d.ts +3 -0
  51. package/dist/dev.js +1 -1
  52. package/dist/engine.d.ts +78 -0
  53. package/dist/engine.js +133 -0
  54. package/dist/error-observability.d.ts +7 -0
  55. package/dist/error-observability.js +61 -0
  56. package/dist/error-resolution.d.ts +4 -0
  57. package/dist/error-resolution.js +122 -0
  58. package/dist/errors.d.ts +33 -0
  59. package/dist/errors.js +40 -0
  60. package/dist/fixture-sanitization.d.ts +28 -0
  61. package/dist/fixture-sanitization.js +227 -0
  62. package/dist/health-scenario.d.ts +1842 -0
  63. package/dist/health-scenario.js +624 -0
  64. package/dist/index.d.ts +21 -10
  65. package/dist/index.js +12 -7
  66. package/dist/lint.d.ts +23 -11
  67. package/dist/lint.js +572 -69
  68. package/dist/native-address.d.ts +43 -0
  69. package/dist/native-address.js +281 -0
  70. package/dist/native-egress-policy.d.ts +31 -0
  71. package/dist/native-egress-policy.js +288 -0
  72. package/dist/observability.d.ts +5 -2
  73. package/dist/observability.js +48 -1
  74. package/dist/provider.d.ts +10 -2
  75. package/dist/provider.js +4 -1
  76. package/dist/runtime/auth-flow.d.ts +5 -1
  77. package/dist/runtime/auth-flow.js +6 -0
  78. package/dist/runtime/browser.d.ts +1 -0
  79. package/dist/runtime/browser.js +492 -49
  80. package/dist/runtime/cache.d.ts +1 -0
  81. package/dist/runtime/cache.js +169 -15
  82. package/dist/runtime/choice-wordlist.d.ts +9 -0
  83. package/dist/runtime/choice-wordlist.js +138 -0
  84. package/dist/runtime/choice.d.ts +13 -1
  85. package/dist/runtime/choice.js +490 -102
  86. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  87. package/dist/runtime/chrome149-header-order.js +289 -0
  88. package/dist/runtime/env.js +12 -0
  89. package/dist/runtime/executor.d.ts +3 -2
  90. package/dist/runtime/executor.js +26 -25
  91. package/dist/runtime/http.d.ts +1 -0
  92. package/dist/runtime/http.js +515 -53
  93. package/dist/runtime/insights.js +2 -2
  94. package/dist/runtime/instrumentation.d.ts +2 -2
  95. package/dist/runtime/instrumentation.js +366 -8
  96. package/dist/runtime/native-network-errors.d.ts +33 -0
  97. package/dist/runtime/native-network-errors.js +69 -0
  98. package/dist/runtime/native-network.d.ts +96 -0
  99. package/dist/runtime/native-network.js +1232 -0
  100. package/dist/runtime/ocr.d.ts +29 -0
  101. package/dist/runtime/ocr.js +440 -0
  102. package/dist/runtime/otlp.d.ts +71 -2
  103. package/dist/runtime/otlp.js +397 -16
  104. package/dist/runtime/proxy-errors.js +6 -2
  105. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  106. package/dist/runtime/proxy-nodemaven.js +146 -0
  107. package/dist/runtime/proxy-telemetry.d.ts +80 -1
  108. package/dist/runtime/proxy-telemetry.js +154 -47
  109. package/dist/runtime/redirects.d.ts +29 -0
  110. package/dist/runtime/redirects.js +36 -0
  111. package/dist/runtime/redis.d.ts +1 -1
  112. package/dist/runtime/redis.js +4 -2
  113. package/dist/runtime/request-options.d.ts +68 -1
  114. package/dist/runtime/request-options.js +548 -0
  115. package/dist/runtime/resolver-config.d.ts +6 -0
  116. package/dist/runtime/resolver-config.js +6 -0
  117. package/dist/runtime/resolver-public.d.ts +1 -0
  118. package/dist/runtime/resolver-public.js +1 -0
  119. package/dist/runtime/resolver-shared.d.ts +14 -0
  120. package/dist/runtime/resolver-shared.js +12 -0
  121. package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
  122. package/dist/runtime/resolver-vendors/bindings.js +40 -0
  123. package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
  124. package/dist/runtime/resolver-vendors/browser.js +377 -0
  125. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  126. package/dist/runtime/resolver-vendors/capsolver.js +531 -0
  127. package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
  128. package/dist/runtime/resolver-vendors/hosts.js +33 -0
  129. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  130. package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
  131. package/dist/runtime/resolver-vendors/types.d.ts +94 -0
  132. package/dist/runtime/resolver-vendors/types.js +96 -0
  133. package/dist/runtime/resolver.d.ts +72 -0
  134. package/dist/runtime/resolver.js +771 -0
  135. package/dist/runtime/secrets.d.ts +27 -0
  136. package/dist/runtime/secrets.js +51 -0
  137. package/dist/runtime/state.d.ts +3 -0
  138. package/dist/runtime/state.js +277 -71
  139. package/dist/runtime/stealth-cookies.d.ts +20 -0
  140. package/dist/runtime/stealth-cookies.js +111 -0
  141. package/dist/runtime/stealth.d.ts +41 -5
  142. package/dist/runtime/stealth.js +997 -291
  143. package/dist/runtime/stt.js +1 -12
  144. package/dist/runtime/timeout.d.ts +5 -0
  145. package/dist/runtime/timeout.js +12 -0
  146. package/dist/runtime/trace-config.d.ts +12 -0
  147. package/dist/runtime/trace-config.js +62 -0
  148. package/dist/runtime/trace.d.ts +5 -0
  149. package/dist/runtime/trace.js +43 -10
  150. package/dist/serve.d.ts +1 -1
  151. package/dist/serve.js +1 -1
  152. package/dist/server/error-observability.d.ts +1 -0
  153. package/dist/server/error-observability.js +1 -0
  154. package/dist/server/index.d.ts +5 -2
  155. package/dist/server/index.js +2 -2
  156. package/dist/server/self-test-input-tokens.d.ts +2 -1
  157. package/dist/server/self-test-input-tokens.js +18 -14
  158. package/dist/server/self-test.d.ts +14 -3
  159. package/dist/server/self-test.js +129 -58
  160. package/dist/server/serve-implementation.d.ts +230 -0
  161. package/dist/server/serve-implementation.js +2265 -0
  162. package/dist/server/serve.d.ts +1 -70
  163. package/dist/server/serve.js +1 -1131
  164. package/dist/server/trace-output.d.ts +6 -0
  165. package/dist/server/trace-output.js +79 -0
  166. package/dist/server/types.d.ts +30 -5
  167. package/dist/server/types.js +13 -1
  168. package/dist/stateful/errors.d.ts +19 -0
  169. package/dist/stateful/errors.js +24 -0
  170. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  171. package/dist/stateful/http-provider-event-emitter.js +237 -0
  172. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  173. package/dist/stateful/http-session-owner-registry.js +210 -0
  174. package/dist/stateful/index.d.ts +18 -0
  175. package/dist/stateful/index.js +18 -0
  176. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  177. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  178. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  179. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  180. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  181. package/dist/stateful/provider-event-pipeline.js +1 -0
  182. package/dist/stateful/provider-events.d.ts +101 -0
  183. package/dist/stateful/provider-events.js +289 -0
  184. package/dist/stateful/session-key.d.ts +15 -0
  185. package/dist/stateful/session-key.js +86 -0
  186. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  187. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  188. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  189. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  190. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  191. package/dist/stateful/stateful-provider-adapter.js +287 -0
  192. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  193. package/dist/stateful/stateful-provider-observability.js +161 -0
  194. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  195. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  196. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  197. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  198. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  199. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  200. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  201. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  202. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  203. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  204. package/dist/stateful-signing.d.ts +18 -0
  205. package/dist/stateful-signing.js +27 -0
  206. package/dist/stealth/profiles.d.ts +9 -4
  207. package/dist/stealth/profiles.js +160 -211
  208. package/dist/stream-evidence.d.ts +74 -0
  209. package/dist/stream-evidence.js +785 -0
  210. package/dist/stream.js +7 -1
  211. package/dist/testing/index.d.ts +2 -1
  212. package/dist/testing/index.js +2 -1
  213. package/dist/testing/run.d.ts +32 -2
  214. package/dist/testing/run.js +489 -21
  215. package/dist/trace-sanitization.d.ts +5 -0
  216. package/dist/trace-sanitization.js +45 -0
  217. package/dist/types.d.ts +673 -131
  218. package/dist/types.js +1 -0
  219. package/package.json +45 -5
  220. package/src/auth-turn/index.ts +1 -1
  221. package/src/auth.ts +118 -0
  222. package/src/ceremonies/index.ts +189 -46
  223. package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
  224. package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
  225. package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
  226. package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
  227. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +15 -0
  228. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +9 -0
  229. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
  230. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +24 -0
  231. package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
  232. package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
  233. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
  234. package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
  235. package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
  236. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
  237. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
  238. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
  239. package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
  240. package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
  241. package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
  242. package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
  243. package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
  244. package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
  245. package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
  246. package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
  247. package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
  248. package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
  249. package/src/cli/commands.ts +33 -0
  250. package/src/cli/create.ts +50 -37
  251. package/src/cli/migrate-operation-declaration.ts +1751 -0
  252. package/src/cli/migrate-operation-shape.ts +184 -0
  253. package/src/cli/migrate-provider-shape.ts +772 -0
  254. package/src/cli/prompt-assets.ts +865 -0
  255. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  256. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  257. package/src/cli/templates/provider/README.md.tpl +5 -5
  258. package/src/cli/templates/provider/index.ts.tpl +6 -3
  259. package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
  260. package/src/cli/templates/provider/provider.json.tpl +6 -0
  261. package/src/config/loader.ts +690 -163
  262. package/src/contract-serialization.ts +5 -7
  263. package/src/contract-types.ts +12 -5
  264. package/src/contract.ts +24 -10
  265. package/src/declaration-validation.ts +330 -0
  266. package/src/define.ts +1048 -131
  267. package/src/dev.ts +4 -1
  268. package/src/engine.ts +279 -0
  269. package/src/error-observability.ts +64 -0
  270. package/src/error-resolution.ts +127 -0
  271. package/src/errors.ts +68 -0
  272. package/src/fixture-sanitization.ts +264 -0
  273. package/src/health-scenario.ts +875 -0
  274. package/src/index.ts +220 -13
  275. package/src/lint.ts +698 -90
  276. package/src/native-address.ts +340 -0
  277. package/src/native-egress-policy.ts +358 -0
  278. package/src/observability.ts +51 -1
  279. package/src/provider.ts +161 -3
  280. package/src/runtime/auth-flow.ts +12 -0
  281. package/src/runtime/browser.ts +661 -63
  282. package/src/runtime/cache.ts +189 -14
  283. package/src/runtime/choice-wordlist.ts +145 -0
  284. package/src/runtime/choice.ts +631 -120
  285. package/src/runtime/chrome149-header-order.ts +330 -0
  286. package/src/runtime/env.ts +13 -0
  287. package/src/runtime/executor.ts +43 -31
  288. package/src/runtime/http.ts +641 -61
  289. package/src/runtime/insights.ts +2 -2
  290. package/src/runtime/instrumentation.ts +520 -15
  291. package/src/runtime/native-network-errors.ts +99 -0
  292. package/src/runtime/native-network.ts +1605 -0
  293. package/src/runtime/ocr.ts +523 -0
  294. package/src/runtime/otlp.ts +467 -21
  295. package/src/runtime/proxy-errors.ts +12 -4
  296. package/src/runtime/proxy-nodemaven.ts +221 -0
  297. package/src/runtime/proxy-telemetry.ts +244 -75
  298. package/src/runtime/redirects.ts +66 -0
  299. package/src/runtime/redis.ts +7 -2
  300. package/src/runtime/request-options.ts +680 -1
  301. package/src/runtime/resolver-config.ts +6 -0
  302. package/src/runtime/resolver-public.ts +23 -0
  303. package/src/runtime/resolver-shared.ts +33 -0
  304. package/src/runtime/resolver-vendors/bindings.ts +56 -0
  305. package/src/runtime/resolver-vendors/browser.ts +533 -0
  306. package/src/runtime/resolver-vendors/capsolver.ts +707 -0
  307. package/src/runtime/resolver-vendors/hosts.ts +38 -0
  308. package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
  309. package/src/runtime/resolver-vendors/types.ts +212 -0
  310. package/src/runtime/resolver.ts +1157 -0
  311. package/src/runtime/secrets.ts +64 -0
  312. package/src/runtime/state.ts +394 -77
  313. package/src/runtime/stealth-cookies.ts +132 -0
  314. package/src/runtime/stealth.ts +1280 -336
  315. package/src/runtime/stt.ts +1 -19
  316. package/src/runtime/timeout.ts +18 -0
  317. package/src/runtime/trace-config.ts +78 -0
  318. package/src/runtime/trace.ts +57 -17
  319. package/src/serve.ts +6 -1
  320. package/src/server/error-observability.ts +1 -0
  321. package/src/server/index.ts +34 -2
  322. package/src/server/self-test-input-tokens.ts +29 -14
  323. package/src/server/self-test.ts +191 -68
  324. package/src/server/serve-implementation.ts +3378 -0
  325. package/src/server/serve.ts +1 -1632
  326. package/src/server/trace-output.ts +129 -0
  327. package/src/server/types.ts +13 -1
  328. package/src/stateful/README.md +146 -0
  329. package/src/stateful/errors.ts +35 -0
  330. package/src/stateful/http-provider-event-emitter.ts +314 -0
  331. package/src/stateful/http-session-owner-registry.ts +306 -0
  332. package/src/stateful/index.ts +18 -0
  333. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  334. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  335. package/src/stateful/provider-event-pipeline.ts +61 -0
  336. package/src/stateful/provider-events.ts +462 -0
  337. package/src/stateful/session-key.ts +111 -0
  338. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  339. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  340. package/src/stateful/stateful-provider-adapter.ts +562 -0
  341. package/src/stateful/stateful-provider-observability.ts +261 -0
  342. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  343. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  344. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  345. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  346. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  347. package/src/stateful-signing.ts +46 -0
  348. package/src/stealth/profiles.ts +202 -231
  349. package/src/stream-evidence.ts +988 -0
  350. package/src/stream.ts +8 -1
  351. package/src/testing/index.ts +10 -1
  352. package/src/testing/run.ts +658 -15
  353. package/src/trace-sanitization.ts +63 -0
  354. package/src/types.ts +788 -174
  355. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  356. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  357. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  358. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  359. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  360. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  361. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  362. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  363. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  364. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  365. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  366. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  367. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  368. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
@@ -15,7 +15,7 @@ function toResourceBody(body) {
15
15
  return Buffer.from(body);
16
16
  }
17
17
  function isResourceMethod(method) {
18
- return method === "GET" || method === "HEAD";
18
+ return method === "GET" || method === "HEAD" || method === "POST";
19
19
  }
20
20
  async function toResourceRequest(request) {
21
21
  const method = request.method().toUpperCase();
@@ -59,6 +59,68 @@ function getCdpPausedRequestId(params) {
59
59
  }
60
60
  return params.requestId;
61
61
  }
62
+ function isCdpResponseStage(params) {
63
+ return (isRecord(params) &&
64
+ (typeof params.responseStatusCode === "number" ||
65
+ typeof params.responseErrorReason === "string"));
66
+ }
67
+ function toCdpPausedDocumentResponse(params) {
68
+ if (!isRecord(params) ||
69
+ typeof params.requestId !== "string" ||
70
+ typeof params.responseStatusCode !== "number" ||
71
+ params.resourceType !== "Document" ||
72
+ !isRecord(params.request)) {
73
+ return null;
74
+ }
75
+ const responseCode = params.responseStatusCode;
76
+ const responseHeaders = Array.isArray(params.responseHeaders)
77
+ ? params.responseHeaders.flatMap((header) => {
78
+ if (!isRecord(header) ||
79
+ typeof header.name !== "string" ||
80
+ typeof header.value !== "string") {
81
+ return [];
82
+ }
83
+ return [{ name: header.name, value: header.value }];
84
+ })
85
+ : [];
86
+ return {
87
+ hasBody: String(params.request.method ?? "").toUpperCase() !== "HEAD" &&
88
+ responseCode >= 200 &&
89
+ (responseCode < 300 || responseCode >= 400) &&
90
+ responseCode !== 204 &&
91
+ responseCode !== 205 &&
92
+ responseCode !== 304,
93
+ requestId: params.requestId,
94
+ responseCode,
95
+ responseHeaders,
96
+ };
97
+ }
98
+ function toCdpDocumentFulfillParams(response, body, contentSecurityPolicy) {
99
+ const responseBody = typeof body.body === "string" ? body.body : "";
100
+ return {
101
+ body: body.base64Encoded ? responseBody : Buffer.from(responseBody).toString("base64"),
102
+ requestId: response.requestId,
103
+ responseCode: response.responseCode,
104
+ responseHeaders: [
105
+ ...response.responseHeaders,
106
+ { name: "Content-Security-Policy", value: contentSecurityPolicy },
107
+ ],
108
+ };
109
+ }
110
+ function resourcePolicyFetchPatterns(policy) {
111
+ return [
112
+ { requestStage: "Request", urlPattern: "*" },
113
+ ...(policy.documentContentSecurityPolicy
114
+ ? [
115
+ {
116
+ requestStage: "Response",
117
+ resourceType: "Document",
118
+ urlPattern: "*",
119
+ },
120
+ ]
121
+ : []),
122
+ ];
123
+ }
62
124
  function toCdpResourceHeaders(value) {
63
125
  if (!isRecord(value)) {
64
126
  return {};
@@ -104,6 +166,128 @@ async function fulfillResourceRoute(route, decision) {
104
166
  status: decision.status ?? 200,
105
167
  });
106
168
  }
169
+ async function decideResourceRequest(policy, request) {
170
+ for (const resourceRoute of policy.routes) {
171
+ if (matchesResourceRoute(resourceRoute.match, request)) {
172
+ return await resourceRoute.handle(request);
173
+ }
174
+ }
175
+ return { action: "block" };
176
+ }
177
+ async function abortResourceRoute(route) {
178
+ await route.abort("blockedbyclient");
179
+ }
180
+ async function handleCdpResourceRequest(session, policy, allowedMethods, params) {
181
+ const paused = toCdpResourceRequest(params);
182
+ const requestId = paused?.requestId ?? getCdpPausedRequestId(params);
183
+ if (!requestId)
184
+ return;
185
+ try {
186
+ if (!paused || !allowedMethods.has(paused.request.method)) {
187
+ await session.send("Fetch.failRequest", { errorReason: "BlockedByClient", requestId });
188
+ return;
189
+ }
190
+ const decision = await decideResourceRequest(policy, paused.request);
191
+ switch (decision.action) {
192
+ case "continue":
193
+ await session.send("Fetch.continueRequest", { requestId });
194
+ return;
195
+ case "fulfill":
196
+ await session.send("Fetch.fulfillRequest", toCdpFulfillParams(requestId, decision));
197
+ return;
198
+ case "block":
199
+ await session.send("Fetch.failRequest", { errorReason: "BlockedByClient", requestId });
200
+ return;
201
+ }
202
+ }
203
+ catch {
204
+ await session
205
+ .send("Fetch.failRequest", { errorReason: "BlockedByClient", requestId })
206
+ .catch(() => undefined);
207
+ }
208
+ }
209
+ async function handleCdpDocumentResponse(session, contentSecurityPolicy, params) {
210
+ const requestId = getCdpPausedRequestId(params);
211
+ if (!requestId)
212
+ return;
213
+ try {
214
+ const response = toCdpPausedDocumentResponse(params);
215
+ if (!response)
216
+ throw new Error("CDP document response metadata is unavailable");
217
+ if (!response.hasBody) {
218
+ await session.send("Fetch.continueResponse", {
219
+ requestId,
220
+ responseCode: response.responseCode,
221
+ responseHeaders: [...response.responseHeaders],
222
+ });
223
+ return;
224
+ }
225
+ const body = await session.send("Fetch.getResponseBody", {
226
+ requestId: response.requestId,
227
+ });
228
+ await session.send("Fetch.fulfillRequest", toCdpDocumentFulfillParams(response, body, contentSecurityPolicy));
229
+ }
230
+ catch {
231
+ await session
232
+ .send("Fetch.failRequest", { errorReason: "BlockedByClient", requestId })
233
+ .catch(() => undefined);
234
+ }
235
+ }
236
+ function getCdpAuthRequiredRequestId(params) {
237
+ if (!isRecord(params) || typeof params.requestId !== "string") {
238
+ return null;
239
+ }
240
+ return params.requestId;
241
+ }
242
+ function isCdpProxyAuthChallenge(params) {
243
+ return (isRecord(params) &&
244
+ isRecord(params.authChallenge) &&
245
+ params.authChallenge.source === "Proxy");
246
+ }
247
+ async function handleCdpAuthRequired(session, proxy, authAttempts, params) {
248
+ const requestId = getCdpAuthRequiredRequestId(params);
249
+ if (!requestId)
250
+ return;
251
+ // Chromium can emit another challenge after rejected credentials. Cancel a
252
+ // retry so incorrect credentials fail promptly instead of looping forever.
253
+ const response = isCdpProxyAuthChallenge(params) && !authAttempts.has(requestId)
254
+ ? (() => {
255
+ authAttempts.add(requestId);
256
+ return {
257
+ authChallengeResponse: {
258
+ password: proxy.password,
259
+ response: "ProvideCredentials",
260
+ username: proxy.username,
261
+ },
262
+ requestId,
263
+ };
264
+ })()
265
+ : {
266
+ authChallengeResponse: { response: "CancelAuth" },
267
+ requestId,
268
+ };
269
+ await session.send("Fetch.continueWithAuth", response).catch(() => undefined);
270
+ }
271
+ function createResourcePolicyHandler(policy, allowedMethods) {
272
+ return async (route) => {
273
+ const request = await toResourceRequest(route.request());
274
+ if (!request || !allowedMethods.has(request.method)) {
275
+ await abortResourceRoute(route);
276
+ return;
277
+ }
278
+ const decision = await decideResourceRequest(policy, request);
279
+ switch (decision.action) {
280
+ case "continue":
281
+ await route.continue();
282
+ return;
283
+ case "fulfill":
284
+ await fulfillResourceRoute(route, decision);
285
+ return;
286
+ case "block":
287
+ await abortResourceRoute(route);
288
+ }
289
+ };
290
+ }
107
291
  function getDefaultCdpPoolUrl(env = process.env) {
108
292
  return env.APIFUSE__CDP_POOL__URL;
109
293
  }
@@ -139,12 +323,60 @@ function formatExpression(fn) {
139
323
  }
140
324
  return `(${fn.toString()})()`;
141
325
  }
142
- function toLaunchOptions(options) {
326
+ function toLaunchOptions(options, proxy) {
143
327
  return {
144
- args: options.extraArgs,
328
+ // `extraArgs` is optional, but playwright-extra's stealth evasions mutate
329
+ // `options.args` unguarded (navigator.webdriver does
330
+ // `options.args.findIndex(...)` in beforeLaunch). Forwarding `undefined`
331
+ // therefore crashes every stealth launch that omits extraArgs with
332
+ // "TypeError: undefined is not an object (evaluating 'options.args.findIndex')".
333
+ // Always hand the launcher a concrete array.
334
+ args: options.extraArgs ?? [],
145
335
  executablePath: options.executablePath,
146
336
  headless: options.headless ?? true,
147
- proxy: options.proxy ? { server: options.proxy } : undefined,
337
+ proxy,
338
+ };
339
+ }
340
+ function hasProxyCredentials(proxy) {
341
+ return proxy?.username !== undefined && proxy.password !== undefined;
342
+ }
343
+ function toPlaywrightProxy(proxy) {
344
+ if (!proxy)
345
+ return undefined;
346
+ const schemeEnd = proxy.indexOf("://");
347
+ const authorityStart = schemeEnd >= 0 ? schemeEnd + 3 : 0;
348
+ const remainder = proxy.slice(authorityStart);
349
+ const authorityEnd = remainder.search(/[/?#]/);
350
+ const authority = remainder.slice(0, authorityEnd >= 0 ? authorityEnd : undefined);
351
+ if (!authority.includes("@")) {
352
+ return { server: proxy };
353
+ }
354
+ let parsed;
355
+ try {
356
+ parsed = new URL(proxy);
357
+ }
358
+ catch {
359
+ throw new ProviderError("Browser proxy URL is invalid", {
360
+ code: "BROWSER_PROXY_INVALID",
361
+ fix: "Use a valid proxy URL.",
362
+ });
363
+ }
364
+ let username;
365
+ let password;
366
+ try {
367
+ username = decodeURIComponent(parsed.username);
368
+ password = decodeURIComponent(parsed.password);
369
+ }
370
+ catch {
371
+ throw new ProviderError("Browser proxy credentials use invalid percent-encoding", {
372
+ code: "BROWSER_PROXY_INVALID",
373
+ fix: "Percent-encode the proxy username and password as URL userinfo.",
374
+ });
375
+ }
376
+ return {
377
+ server: `${parsed.protocol}//${parsed.host}`,
378
+ username,
379
+ password,
148
380
  };
149
381
  }
150
382
  class PlaywrightBrowserLocator {
@@ -309,13 +541,15 @@ async function loadSeleniumBase() {
309
541
  }
310
542
  class PlaywrightBrowserPage {
311
543
  page;
544
+ proxy;
312
545
  id = "main";
313
546
  pageId;
314
- constructor(page) {
547
+ constructor(page, proxy = undefined) {
315
548
  this.page = page;
549
+ this.proxy = proxy;
316
550
  }
317
- async goto(url) {
318
- await this.page.goto(url);
551
+ async goto(url, options) {
552
+ await this.page.goto(url, options);
319
553
  }
320
554
  async evaluate(fn) {
321
555
  if (typeof fn === "string") {
@@ -323,6 +557,9 @@ class PlaywrightBrowserPage {
323
557
  }
324
558
  return await this.page.evaluate(fn);
325
559
  }
560
+ async userAgent() {
561
+ return await this.evaluate("navigator.userAgent");
562
+ }
326
563
  async waitForSelector(selector, options) {
327
564
  await this.page.waitForSelector(selector, options);
328
565
  }
@@ -357,42 +594,107 @@ class PlaywrightBrowserPage {
357
594
  async close() {
358
595
  await this.page.close();
359
596
  }
597
+ async cookies() {
598
+ return (await this.page.context().cookies()).map(toBrowserCookie);
599
+ }
360
600
  async withResourcePolicy(policy, run) {
361
601
  const allowedMethods = new Set(policy.allowedMethods ?? DEFAULT_RESOURCE_METHODS);
602
+ const policyHandler = createResourcePolicyHandler(policy, allowedMethods);
603
+ const context = this.page.context();
362
604
  const handler = async (route) => {
363
- const request = await toResourceRequest(route.request());
364
- if (!request || !allowedMethods.has(request.method)) {
365
- await route.abort("blockedbyclient");
605
+ try {
606
+ // Context routing sees a popup's first request before the late `page`
607
+ // event. Fail every secondary page closed so no redirect can escape
608
+ // the per-page CDP interception while that session is being attached.
609
+ if (route.request().frame().page() !== this.page) {
610
+ await abortResourceRoute(route);
611
+ return;
612
+ }
613
+ }
614
+ catch {
615
+ await abortResourceRoute(route);
366
616
  return;
367
617
  }
368
- for (const resourceRoute of policy.routes) {
369
- if (!matchesResourceRoute(resourceRoute.match, request)) {
370
- continue;
618
+ await policyHandler(route);
619
+ };
620
+ const sessions = new Set();
621
+ const pendingAttachments = new Set();
622
+ const proxy = hasProxyCredentials(this.proxy) ? this.proxy : undefined;
623
+ let active = true;
624
+ const attachPage = async (page) => {
625
+ const session = await context.newCDPSession(page);
626
+ if (!active) {
627
+ await session.detach();
628
+ return;
629
+ }
630
+ const onRequestPaused = (params) => {
631
+ if (isCdpResponseStage(params) && policy.documentContentSecurityPolicy) {
632
+ void handleCdpDocumentResponse(session, policy.documentContentSecurityPolicy, params);
633
+ return;
371
634
  }
372
- const decision = await resourceRoute.handle(request);
373
- switch (decision.action) {
374
- case "fulfill":
375
- await fulfillResourceRoute(route, decision);
376
- return;
377
- case "block":
378
- await route.abort("blockedbyclient");
379
- return;
635
+ void handleCdpResourceRequest(session, policy, allowedMethods, params);
636
+ };
637
+ const authAttempts = new Set();
638
+ const onAuthRequired = (params) => {
639
+ if (!proxy)
640
+ return;
641
+ void handleCdpAuthRequired(session, proxy, authAttempts, params);
642
+ };
643
+ session.on("Fetch.requestPaused", onRequestPaused);
644
+ if (proxy) {
645
+ session.on("Fetch.authRequired", onAuthRequired);
646
+ }
647
+ try {
648
+ await session.send("Fetch.enable", {
649
+ ...(proxy ? { handleAuthRequests: true } : {}),
650
+ patterns: resourcePolicyFetchPatterns(policy),
651
+ });
652
+ sessions.add(session);
653
+ }
654
+ catch (error) {
655
+ session.off("Fetch.requestPaused", onRequestPaused);
656
+ if (proxy) {
657
+ session.off("Fetch.authRequired", onAuthRequired);
380
658
  }
659
+ await session.detach().catch(() => undefined);
660
+ throw error;
381
661
  }
382
- await route.abort("blockedbyclient");
383
662
  };
384
- await this.page.route(RESOURCE_POLICY_ROUTE_PATTERN, handler);
663
+ const onPage = (page) => {
664
+ const attachment = attachPage(page)
665
+ .catch(async () => {
666
+ await page.close().catch(() => undefined);
667
+ })
668
+ .finally(() => pendingAttachments.delete(attachment));
669
+ pendingAttachments.add(attachment);
670
+ };
671
+ await context.route(RESOURCE_POLICY_ROUTE_PATTERN, handler);
385
672
  try {
386
- return await run();
673
+ context.on("page", onPage);
674
+ try {
675
+ await attachPage(this.page);
676
+ return await run();
677
+ }
678
+ finally {
679
+ context.off("page", onPage);
680
+ }
387
681
  }
388
682
  finally {
389
- await this.page.unroute(RESOURCE_POLICY_ROUTE_PATTERN, handler);
683
+ active = false;
684
+ await context.unroute(RESOURCE_POLICY_ROUTE_PATTERN, handler);
685
+ await Promise.allSettled(pendingAttachments);
686
+ await Promise.all([...sessions].map(async (session) => {
687
+ await session.send("Fetch.disable").catch(() => undefined);
688
+ await session.detach().catch(() => undefined);
689
+ }));
390
690
  }
391
691
  }
392
692
  }
393
693
  class PlaywrightBrowserClient {
394
694
  options;
395
695
  browser = null;
696
+ parsedProxy;
697
+ proxyParsed = false;
396
698
  engine = "playwright-stealth";
397
699
  constructor(options = {}) {
398
700
  this.options = options;
@@ -402,13 +704,17 @@ class PlaywrightBrowserClient {
402
704
  return this.browser;
403
705
  }
404
706
  const chromium = await loadChromiumLauncher(this.options);
405
- this.browser = await chromium.launch(toLaunchOptions(this.options));
707
+ if (!this.proxyParsed) {
708
+ this.parsedProxy = toPlaywrightProxy(this.options.proxy);
709
+ this.proxyParsed = true;
710
+ }
711
+ this.browser = await chromium.launch(toLaunchOptions(this.options, this.parsedProxy));
406
712
  return this.browser;
407
713
  }
408
714
  async newPage() {
409
715
  const browser = await this.ensureBrowser();
410
716
  const page = await browser.newPage();
411
- return new PlaywrightBrowserPage(page);
717
+ return new PlaywrightBrowserPage(page, this.parsedProxy);
412
718
  }
413
719
  async rawPage() {
414
720
  throw new ProviderError("ctx.browser.rawPage() requires a CDP pool", {
@@ -418,9 +724,9 @@ class PlaywrightBrowserClient {
418
724
  }
419
725
  async withIsolatedContext(handler) {
420
726
  const browser = await this.ensureBrowser();
421
- const context = await browser.newContext();
727
+ const context = await browser.newContext({ serviceWorkers: this.options.serviceWorkers });
422
728
  const page = await context.newPage();
423
- const browserPage = new PlaywrightBrowserPage(page);
729
+ const browserPage = new PlaywrightBrowserPage(page, this.parsedProxy);
424
730
  try {
425
731
  return await handler(browserPage);
426
732
  }
@@ -457,7 +763,7 @@ function normalizeWebSocketEndpoint(endpoint) {
457
763
  }
458
764
  throw new Error(`Unsupported WebSocket endpoint protocol: ${url.protocol}`);
459
765
  }
460
- class JsonRpcWebSocketClient {
766
+ class WebSocketCommandClient {
461
767
  nextId = 1;
462
768
  endpoint;
463
769
  listeners = new Map();
@@ -483,12 +789,7 @@ class JsonRpcWebSocketClient {
483
789
  const id = this.nextId++;
484
790
  return await new Promise((resolve, reject) => {
485
791
  this.pending.set(id, { resolve, reject });
486
- socket.send(JSON.stringify({
487
- id,
488
- jsonrpc: "2.0",
489
- method,
490
- params,
491
- }));
792
+ socket.send(JSON.stringify(this.createCommandFrame(id, method, params)));
492
793
  });
493
794
  }
494
795
  async close() {
@@ -526,7 +827,11 @@ class JsonRpcWebSocketClient {
526
827
  }
527
828
  this.pending.delete(payload.id);
528
829
  if (payload.error) {
529
- pending.reject(new Error(payload.error.message ?? "JSON-RPC command failed"));
830
+ const error = new Error(payload.error.message ?? "JSON-RPC command failed");
831
+ if (typeof payload.error.code === "number") {
832
+ Object.assign(error, { code: payload.error.code });
833
+ }
834
+ pending.reject(error);
530
835
  return;
531
836
  }
532
837
  pending.resolve(payload.result ?? {});
@@ -554,6 +859,26 @@ class JsonRpcWebSocketClient {
554
859
  return this.socketPromise;
555
860
  }
556
861
  }
862
+ class CdpWebSocketClient extends WebSocketCommandClient {
863
+ sessionId;
864
+ constructor(endpoint, sessionId) {
865
+ super(endpoint);
866
+ this.sessionId = sessionId;
867
+ }
868
+ createCommandFrame(id, method, params) {
869
+ return {
870
+ id,
871
+ method,
872
+ params,
873
+ ...(this.sessionId === undefined ? {} : { sessionId: this.sessionId }),
874
+ };
875
+ }
876
+ }
877
+ class JsonRpcWebSocketClient extends WebSocketCommandClient {
878
+ createCommandFrame(id, method, params) {
879
+ return { id, jsonrpc: "2.0", method, params };
880
+ }
881
+ }
557
882
  function flattenCdpFrameTree(node, out = []) {
558
883
  if (!node) {
559
884
  return out;
@@ -567,6 +892,48 @@ function flattenCdpFrameTree(node, out = []) {
567
892
  function isRecord(value) {
568
893
  return value !== null && typeof value === "object" && !Array.isArray(value);
569
894
  }
895
+ function isBrowserCookieSameSite(value) {
896
+ return value === "Strict" || value === "Lax" || value === "None";
897
+ }
898
+ function toBrowserCookie(cookie) {
899
+ return {
900
+ name: cookie.name,
901
+ value: cookie.value,
902
+ domain: cookie.domain,
903
+ path: cookie.path,
904
+ ...(cookie.expires !== undefined && cookie.expires > 0 ? { expires: cookie.expires } : {}),
905
+ httpOnly: cookie.httpOnly,
906
+ secure: cookie.secure,
907
+ ...(isBrowserCookieSameSite(cookie.sameSite) ? { sameSite: cookie.sameSite } : {}),
908
+ };
909
+ }
910
+ function parseCdpCookies(value) {
911
+ if (!Array.isArray(value)) {
912
+ throw new Error("CDP Network.getCookies returned an invalid cookie list");
913
+ }
914
+ return value.map((cookie) => {
915
+ if (!isRecord(cookie) ||
916
+ typeof cookie.name !== "string" ||
917
+ typeof cookie.value !== "string" ||
918
+ typeof cookie.domain !== "string" ||
919
+ typeof cookie.path !== "string" ||
920
+ typeof cookie.expires !== "number" ||
921
+ typeof cookie.httpOnly !== "boolean" ||
922
+ typeof cookie.secure !== "boolean") {
923
+ throw new Error("CDP Network.getCookies returned an invalid cookie");
924
+ }
925
+ return toBrowserCookie({
926
+ name: cookie.name,
927
+ value: cookie.value,
928
+ domain: cookie.domain,
929
+ path: cookie.path,
930
+ expires: cookie.expires,
931
+ httpOnly: cookie.httpOnly,
932
+ secure: cookie.secure,
933
+ sameSite: cookie.sameSite,
934
+ });
935
+ });
936
+ }
570
937
  function parsePoolAcquireResponse(value) {
571
938
  if (!isRecord(value) ||
572
939
  typeof value.pageId !== "string" ||
@@ -620,6 +987,17 @@ function getCdpExecutionContext(params) {
620
987
  id: typeof contextId === "number" ? contextId : undefined,
621
988
  };
622
989
  }
990
+ function getCdpDestroyedExecutionContextId(params) {
991
+ if (!isRecord(params)) {
992
+ return undefined;
993
+ }
994
+ return typeof params.executionContextId === "number"
995
+ ? params.executionContextId
996
+ : undefined;
997
+ }
998
+ function isMissingExecutionContextError(error) {
999
+ return error instanceof Error && /\b(?:cannot|failed to) find context\b/i.test(error.message);
1000
+ }
623
1001
  class CdpBrowserLocator {
624
1002
  frame;
625
1003
  selector;
@@ -723,16 +1101,22 @@ class CdpPoolBrowserPage {
723
1101
  get id() {
724
1102
  return this.pageId;
725
1103
  }
726
- async goto(url) {
1104
+ async goto(url, options) {
727
1105
  await this.initialize();
728
1106
  const startedAt = Date.now();
729
- let loadEventSeen = false;
730
- const unsubscribe = this.pageClient.on("Page.loadEventFired", () => {
731
- loadEventSeen = true;
1107
+ const timeout = options?.timeout ?? DEFAULT_WAIT_TIMEOUT_MS;
1108
+ const waitUntil = options?.waitUntil ?? "load";
1109
+ let expectedEventSeen = false;
1110
+ const eventName = waitUntil === "domcontentloaded" ? "Page.domContentEventFired" : "Page.loadEventFired";
1111
+ const unsubscribe = this.pageClient.on(eventName, () => {
1112
+ expectedEventSeen = true;
732
1113
  });
733
1114
  try {
734
- await this.pageClient.send("Page.navigate", { url });
735
- await this.waitForDocumentReady(startedAt + DEFAULT_WAIT_TIMEOUT_MS, () => loadEventSeen);
1115
+ const navigation = (await this.pageClient.send("Page.navigate", { url }));
1116
+ if (typeof navigation.errorText === "string" && navigation.errorText.length > 0) {
1117
+ throw new Error(`Page.navigate failed: ${navigation.errorText} at ${url}`);
1118
+ }
1119
+ await this.waitForDocumentReady(startedAt + timeout, () => expectedEventSeen, waitUntil);
736
1120
  }
737
1121
  finally {
738
1122
  unsubscribe();
@@ -742,10 +1126,25 @@ class CdpPoolBrowserPage {
742
1126
  await this.initialize();
743
1127
  return await this.evaluateWithContext(fn);
744
1128
  }
1129
+ async userAgent() {
1130
+ return await this.evaluate("navigator.userAgent");
1131
+ }
745
1132
  async evaluateInFrame(frameId, fn) {
746
1133
  await this.initialize();
747
1134
  const contextId = await this.getFrameExecutionContextId(frameId);
748
- return await this.evaluateWithContext(fn, contextId);
1135
+ try {
1136
+ return await this.evaluateWithContext(fn, contextId);
1137
+ }
1138
+ catch (error) {
1139
+ if (!isMissingExecutionContextError(error)) {
1140
+ throw error;
1141
+ }
1142
+ if (this.frameExecutionContexts.get(frameId) === contextId) {
1143
+ this.frameExecutionContexts.delete(frameId);
1144
+ }
1145
+ const refreshedContextId = await this.getFrameExecutionContextId(frameId);
1146
+ return await this.evaluateWithContext(fn, refreshedContextId);
1147
+ }
749
1148
  }
750
1149
  async waitForSelectorInFrame(frameId, selector, options) {
751
1150
  const timeout = options?.timeout ?? DEFAULT_WAIT_TIMEOUT_MS;
@@ -845,6 +1244,11 @@ class CdpPoolBrowserPage {
845
1244
  });
846
1245
  return Buffer.from(String(result.data ?? ""), "base64");
847
1246
  }
1247
+ async cookies() {
1248
+ await this.initialize();
1249
+ const result = await this.pageClient.send("Network.getCookies");
1250
+ return parseCdpCookies(result.cookies);
1251
+ }
848
1252
  async close() {
849
1253
  if (this.closed) {
850
1254
  return;
@@ -868,7 +1272,7 @@ class CdpPoolBrowserPage {
868
1272
  const unsubscribe = this.pageClient.on("Fetch.requestPaused", handlePausedRequest);
869
1273
  try {
870
1274
  await this.pageClient.send("Fetch.enable", {
871
- patterns: [{ requestStage: "Request", urlPattern: "*" }],
1275
+ patterns: resourcePolicyFetchPatterns(policy),
872
1276
  });
873
1277
  }
874
1278
  catch (error) {
@@ -893,6 +1297,24 @@ class CdpPoolBrowserPage {
893
1297
  return;
894
1298
  }
895
1299
  try {
1300
+ if (isCdpResponseStage(params) && policy.documentContentSecurityPolicy) {
1301
+ const response = toCdpPausedDocumentResponse(params);
1302
+ if (!response)
1303
+ throw new Error("CDP document response metadata is unavailable");
1304
+ if (!response.hasBody) {
1305
+ await this.pageClient.send("Fetch.continueResponse", {
1306
+ requestId,
1307
+ responseCode: response.responseCode,
1308
+ responseHeaders: [...response.responseHeaders],
1309
+ });
1310
+ return;
1311
+ }
1312
+ const body = await this.pageClient.send("Fetch.getResponseBody", {
1313
+ requestId: response.requestId,
1314
+ });
1315
+ await this.pageClient.send("Fetch.fulfillRequest", toCdpDocumentFulfillParams(response, body, policy.documentContentSecurityPolicy));
1316
+ return;
1317
+ }
896
1318
  const parsed = toCdpResourceRequest(params);
897
1319
  if (!parsed || !allowedMethods.has(parsed.request.method)) {
898
1320
  await this.failCdpResourceRequest(requestId);
@@ -904,6 +1326,11 @@ class CdpPoolBrowserPage {
904
1326
  }
905
1327
  const decision = await resourceRoute.handle(parsed.request);
906
1328
  switch (decision.action) {
1329
+ case "continue":
1330
+ await this.pageClient.send("Fetch.continueRequest", {
1331
+ requestId: parsed.requestId,
1332
+ });
1333
+ return;
907
1334
  case "fulfill":
908
1335
  await this.pageClient.send("Fetch.fulfillRequest", toCdpFulfillParams(parsed.requestId, decision));
909
1336
  return;
@@ -941,6 +1368,20 @@ class CdpPoolBrowserPage {
941
1368
  this.frameExecutionContexts.set(context.frameId, context.id);
942
1369
  }
943
1370
  });
1371
+ this.pageClient.on("Runtime.executionContextDestroyed", (params) => {
1372
+ const destroyedContextId = getCdpDestroyedExecutionContextId(params);
1373
+ if (destroyedContextId === undefined) {
1374
+ return;
1375
+ }
1376
+ for (const [frameId, contextId] of this.frameExecutionContexts) {
1377
+ if (contextId === destroyedContextId) {
1378
+ this.frameExecutionContexts.delete(frameId);
1379
+ }
1380
+ }
1381
+ });
1382
+ this.pageClient.on("Runtime.executionContextsCleared", () => {
1383
+ this.frameExecutionContexts.clear();
1384
+ });
944
1385
  await this.pageClient.send("Page.enable");
945
1386
  await this.pageClient.send("Runtime.enable");
946
1387
  this.initialized = true;
@@ -962,11 +1403,13 @@ class CdpPoolBrowserPage {
962
1403
  this.frameExecutionContexts.set(frameId, contextId);
963
1404
  return contextId;
964
1405
  }
965
- async waitForDocumentReady(deadline, isLoadEventSeen) {
1406
+ async waitForDocumentReady(deadline, isExpectedEventSeen, waitUntil) {
966
1407
  while (Date.now() < deadline) {
967
1408
  const readyState = await this.evaluate("document.readyState");
968
- if (readyState === "complete" || readyState === "interactive") {
969
- if (isLoadEventSeen() || readyState === "complete") {
1409
+ const documentReady = readyState === "complete" ||
1410
+ (waitUntil === "domcontentloaded" && readyState === "interactive");
1411
+ if (documentReady) {
1412
+ if (isExpectedEventSeen() || readyState === "complete") {
970
1413
  return;
971
1414
  }
972
1415
  }
@@ -996,7 +1439,7 @@ class CdpPoolBrowserClient {
996
1439
  ...(this.allowedHosts.length > 0 ? { allowedHosts: this.allowedHosts } : {}),
997
1440
  ...(options?.isolatedContext ? { isolationMode: "browserContext" } : {}),
998
1441
  }));
999
- const pageClient = new JsonRpcWebSocketClient(acquireResult.wsEndpoint);
1442
+ const pageClient = new CdpWebSocketClient(acquireResult.wsEndpoint);
1000
1443
  const page = new CdpPoolBrowserPage(acquireResult.pageId, acquireResult.browserContextId, pageClient, async (request) => {
1001
1444
  await this.poolClient.send("release", request);
1002
1445
  });