@apifuse/provider-sdk 2.2.0-beta.7 → 2.2.0-beta.70

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 (478) hide show
  1. package/AUTHORING.md +943 -51
  2. package/CHANGELOG.md +273 -1
  3. package/LICENSE +21 -0
  4. package/README.md +117 -29
  5. package/SUBMISSION.md +3 -2
  6. package/bin/apifuse-check.ts +293 -13
  7. package/bin/apifuse-dev.ts +42 -19
  8. package/bin/apifuse-migrate-deployment.ts +200 -0
  9. package/bin/apifuse-migrate-operation-declaration.ts +55 -0
  10. package/bin/apifuse-migrate-shape.ts +202 -0
  11. package/bin/apifuse-pack-check.ts +19 -6
  12. package/bin/apifuse-pack-smoke.ts +57 -2
  13. package/bin/apifuse-pack-types.ts +736 -38
  14. package/bin/apifuse-perf.ts +59 -23
  15. package/bin/apifuse-record.ts +923 -94
  16. package/bin/apifuse-submit-check.ts +2313 -281
  17. package/bin/apifuse-test.ts +3 -1
  18. package/bin/submit-check-delimited-text.ts +50 -0
  19. package/dist/auth-turn/index.d.ts +3 -3
  20. package/dist/auth-turn/index.js +1 -1
  21. package/dist/auth.d.ts +14 -0
  22. package/dist/auth.js +67 -0
  23. package/dist/ceremonies/index.d.ts +16 -0
  24. package/dist/ceremonies/index.js +141 -36
  25. package/dist/cli/commands.d.ts +1 -1
  26. package/dist/cli/commands.js +30 -0
  27. package/dist/cli/create.d.ts +1 -1
  28. package/dist/cli/create.js +8 -2
  29. package/dist/cli/deployment-intent.d.ts +178 -0
  30. package/dist/cli/deployment-intent.js +277 -0
  31. package/dist/cli/local-connection.d.ts +111 -0
  32. package/dist/cli/local-connection.js +151 -0
  33. package/dist/cli/migrate-deployment-intent.d.ts +132 -0
  34. package/dist/cli/migrate-deployment-intent.js +1552 -0
  35. package/dist/cli/migrate-operation-declaration.d.ts +70 -0
  36. package/dist/cli/migrate-operation-declaration.js +2206 -0
  37. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  38. package/dist/cli/migrate-operation-shape.js +113 -0
  39. package/dist/cli/migrate-provider-shape.d.ts +56 -0
  40. package/dist/cli/migrate-provider-shape.js +580 -0
  41. package/dist/cli/resolver-runtime.d.ts +21 -0
  42. package/dist/cli/resolver-runtime.js +31 -0
  43. package/dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  44. package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
  45. package/dist/cli/templates/provider/README.md.tpl +41 -19
  46. package/dist/cli/templates/provider/index.ts.tpl +6 -3
  47. package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
  48. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  49. package/dist/config/loader.d.ts +202 -16
  50. package/dist/config/loader.js +491 -141
  51. package/dist/contract-serialization.js +4 -8
  52. package/dist/contract-types.d.ts +12 -5
  53. package/dist/contract.js +24 -10
  54. package/dist/declaration-validation.d.ts +34 -0
  55. package/dist/declaration-validation.js +305 -0
  56. package/dist/define.d.ts +71 -29
  57. package/dist/define.js +807 -69
  58. package/dist/dev.d.ts +5 -0
  59. package/dist/dev.js +8 -1
  60. package/dist/engine.d.ts +129 -0
  61. package/dist/engine.js +209 -0
  62. package/dist/error-observability.d.ts +7 -0
  63. package/dist/error-observability.js +61 -0
  64. package/dist/error-resolution.d.ts +18 -0
  65. package/dist/error-resolution.js +243 -0
  66. package/dist/errors.d.ts +74 -0
  67. package/dist/errors.js +99 -0
  68. package/dist/fixture-sanitization.d.ts +28 -0
  69. package/dist/fixture-sanitization.js +371 -0
  70. package/dist/handle-meta.d.ts +90 -0
  71. package/dist/handle-meta.js +73 -0
  72. package/dist/handle.d.ts +226 -0
  73. package/dist/handle.js +345 -0
  74. package/dist/health-scenario.d.ts +1901 -0
  75. package/dist/health-scenario.js +653 -0
  76. package/dist/i18n/catalog.js +21 -1
  77. package/dist/i18n/error-messages.d.ts +86 -0
  78. package/dist/i18n/error-messages.js +192 -0
  79. package/dist/i18n/index.d.ts +1 -0
  80. package/dist/i18n/index.js +1 -0
  81. package/dist/i18n/keys.d.ts +12 -0
  82. package/dist/i18n/keys.js +76 -5
  83. package/dist/i18n/operation-locale-namespace.d.ts +2 -0
  84. package/dist/i18n/operation-locale-namespace.js +7 -0
  85. package/dist/index.d.ts +40 -15
  86. package/dist/index.js +29 -11
  87. package/dist/lint.d.ts +43 -11
  88. package/dist/lint.js +2512 -177
  89. package/dist/native-address.d.ts +43 -0
  90. package/dist/native-address.js +281 -0
  91. package/dist/native-egress-policy.d.ts +31 -0
  92. package/dist/native-egress-policy.js +288 -0
  93. package/dist/observability.d.ts +5 -2
  94. package/dist/observability.js +48 -1
  95. package/dist/provider.d.ts +18 -8
  96. package/dist/provider.js +11 -6
  97. package/dist/runtime/auth-flow.d.ts +6 -1
  98. package/dist/runtime/auth-flow.js +8 -0
  99. package/dist/runtime/bounded-expiring-map.d.ts +21 -0
  100. package/dist/runtime/bounded-expiring-map.js +64 -0
  101. package/dist/runtime/browser-telemetry-binding.d.ts +5 -0
  102. package/dist/runtime/browser-telemetry-binding.js +83 -0
  103. package/dist/runtime/browser-telemetry.d.ts +76 -0
  104. package/dist/runtime/browser-telemetry.js +165 -0
  105. package/dist/runtime/browser.d.ts +4 -0
  106. package/dist/runtime/browser.js +688 -83
  107. package/dist/runtime/cache-telemetry.d.ts +71 -0
  108. package/dist/runtime/cache-telemetry.js +177 -0
  109. package/dist/runtime/cache.d.ts +3 -0
  110. package/dist/runtime/cache.js +245 -23
  111. package/dist/runtime/capability-response.d.ts +3 -0
  112. package/dist/runtime/capability-response.js +56 -0
  113. package/dist/runtime/capability-telemetry.d.ts +46 -0
  114. package/dist/runtime/capability-telemetry.js +68 -0
  115. package/dist/runtime/chrome149-header-order.d.ts +58 -0
  116. package/dist/runtime/chrome149-header-order.js +289 -0
  117. package/dist/runtime/diagnostic-env-values.d.ts +5 -0
  118. package/dist/runtime/diagnostic-env-values.js +57 -0
  119. package/dist/runtime/diagnostic-env.d.ts +14 -0
  120. package/dist/runtime/diagnostic-env.js +44 -0
  121. package/dist/runtime/diagnostic-redactor.d.ts +54 -0
  122. package/dist/runtime/diagnostic-redactor.js +571 -0
  123. package/dist/runtime/egress-lease.d.ts +65 -0
  124. package/dist/runtime/egress-lease.js +236 -0
  125. package/dist/runtime/engine-mode.d.ts +74 -0
  126. package/dist/runtime/engine-mode.js +152 -0
  127. package/dist/runtime/env.js +14 -1
  128. package/dist/runtime/executor.d.ts +3 -2
  129. package/dist/runtime/executor.js +23 -26
  130. package/dist/runtime/handle-wordlist.d.ts +43 -0
  131. package/dist/runtime/handle-wordlist.js +256 -0
  132. package/dist/runtime/handle.d.ts +71 -0
  133. package/dist/runtime/handle.js +908 -0
  134. package/dist/runtime/http-telemetry-binding.d.ts +10 -0
  135. package/dist/runtime/http-telemetry-binding.js +152 -0
  136. package/dist/runtime/http-telemetry-guard.d.ts +16 -0
  137. package/dist/runtime/http-telemetry-guard.js +202 -0
  138. package/dist/runtime/http-telemetry.d.ts +104 -0
  139. package/dist/runtime/http-telemetry.js +190 -0
  140. package/dist/runtime/http.d.ts +34 -0
  141. package/dist/runtime/http.js +680 -121
  142. package/dist/runtime/insights.js +2 -2
  143. package/dist/runtime/instrumentation.d.ts +2 -2
  144. package/dist/runtime/instrumentation.js +462 -19
  145. package/dist/runtime/native-network-errors.d.ts +33 -0
  146. package/dist/runtime/native-network-errors.js +69 -0
  147. package/dist/runtime/native-network.d.ts +105 -0
  148. package/dist/runtime/native-network.js +1433 -0
  149. package/dist/runtime/native-telemetry.d.ts +142 -0
  150. package/dist/runtime/native-telemetry.js +231 -0
  151. package/dist/runtime/ocr-telemetry.d.ts +82 -0
  152. package/dist/runtime/ocr-telemetry.js +192 -0
  153. package/dist/runtime/ocr.d.ts +29 -0
  154. package/dist/runtime/ocr.js +468 -0
  155. package/dist/runtime/otlp.d.ts +71 -2
  156. package/dist/runtime/otlp.js +398 -16
  157. package/dist/runtime/provider.d.ts +7 -0
  158. package/dist/runtime/provider.js +14 -0
  159. package/dist/runtime/proxy-errors.js +6 -2
  160. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  161. package/dist/runtime/proxy-nodemaven.js +147 -0
  162. package/dist/runtime/proxy-retry-policy.d.ts +4 -1
  163. package/dist/runtime/proxy-retry-policy.js +11 -2
  164. package/dist/runtime/proxy-telemetry.d.ts +133 -3
  165. package/dist/runtime/proxy-telemetry.js +218 -70
  166. package/dist/runtime/redirect-hop-headers.d.ts +19 -0
  167. package/dist/runtime/redirect-hop-headers.js +58 -0
  168. package/dist/runtime/redirects.d.ts +61 -0
  169. package/dist/runtime/redirects.js +149 -0
  170. package/dist/runtime/redis.d.ts +1 -1
  171. package/dist/runtime/redis.js +4 -2
  172. package/dist/runtime/request-options.d.ts +75 -1
  173. package/dist/runtime/request-options.js +588 -0
  174. package/dist/runtime/request-telemetry.d.ts +70 -0
  175. package/dist/runtime/request-telemetry.js +229 -0
  176. package/dist/runtime/resolver-config.d.ts +13 -0
  177. package/dist/runtime/resolver-config.js +14 -0
  178. package/dist/runtime/resolver-public.d.ts +3 -0
  179. package/dist/runtime/resolver-public.js +1 -0
  180. package/dist/runtime/resolver-runtime-options.d.ts +14 -0
  181. package/dist/runtime/resolver-runtime-options.js +33 -0
  182. package/dist/runtime/resolver-shared.d.ts +24 -0
  183. package/dist/runtime/resolver-shared.js +69 -0
  184. package/dist/runtime/resolver-span-attributes.d.ts +34 -0
  185. package/dist/runtime/resolver-span-attributes.js +93 -0
  186. package/dist/runtime/resolver-telemetry.d.ts +135 -0
  187. package/dist/runtime/resolver-telemetry.js +204 -0
  188. package/dist/runtime/resolver-usage.d.ts +32 -0
  189. package/dist/runtime/resolver-usage.js +54 -0
  190. package/dist/runtime/resolver-vendors/bindings.d.ts +53 -0
  191. package/dist/runtime/resolver-vendors/bindings.js +45 -0
  192. package/dist/runtime/resolver-vendors/browser.d.ts +24 -0
  193. package/dist/runtime/resolver-vendors/browser.js +423 -0
  194. package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
  195. package/dist/runtime/resolver-vendors/capsolver.js +544 -0
  196. package/dist/runtime/resolver-vendors/hosts.d.ts +23 -0
  197. package/dist/runtime/resolver-vendors/hosts.js +68 -0
  198. package/dist/runtime/resolver-vendors/hypersolutions.d.ts +27 -0
  199. package/dist/runtime/resolver-vendors/hypersolutions.js +369 -0
  200. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  201. package/dist/runtime/resolver-vendors/twocaptcha.js +425 -0
  202. package/dist/runtime/resolver-vendors/types.d.ts +125 -0
  203. package/dist/runtime/resolver-vendors/types.js +106 -0
  204. package/dist/runtime/resolver.d.ts +79 -0
  205. package/dist/runtime/resolver.js +1094 -0
  206. package/dist/runtime/state-telemetry.d.ts +79 -0
  207. package/dist/runtime/state-telemetry.js +194 -0
  208. package/dist/runtime/state.d.ts +10 -1
  209. package/dist/runtime/state.js +322 -82
  210. package/dist/runtime/stealth-akamai-sbsd.d.ts +54 -0
  211. package/dist/runtime/stealth-akamai-sbsd.js +142 -0
  212. package/dist/runtime/stealth-cookies.d.ts +24 -0
  213. package/dist/runtime/stealth-cookies.js +131 -0
  214. package/dist/runtime/stealth-owned-headers.d.ts +39 -0
  215. package/dist/runtime/stealth-owned-headers.js +57 -0
  216. package/dist/runtime/stealth-telemetry.d.ts +92 -0
  217. package/dist/runtime/stealth-telemetry.js +179 -0
  218. package/dist/runtime/stealth.d.ts +45 -6
  219. package/dist/runtime/stealth.js +1775 -320
  220. package/dist/runtime/stt-telemetry.d.ts +77 -0
  221. package/dist/runtime/stt-telemetry.js +176 -0
  222. package/dist/runtime/stt.js +18 -19
  223. package/dist/runtime/timeout.d.ts +5 -0
  224. package/dist/runtime/timeout.js +12 -0
  225. package/dist/runtime/trace-config.d.ts +12 -0
  226. package/dist/runtime/trace-config.js +62 -0
  227. package/dist/runtime/trace.d.ts +17 -0
  228. package/dist/runtime/trace.js +176 -25
  229. package/dist/runtime-boundary-lint.d.ts +137 -0
  230. package/dist/runtime-boundary-lint.js +590 -0
  231. package/dist/schema.d.ts +20 -0
  232. package/dist/schema.js +72 -2
  233. package/dist/serve.d.ts +1 -1
  234. package/dist/serve.js +1 -1
  235. package/dist/server/error-observability.d.ts +1 -0
  236. package/dist/server/error-observability.js +1 -0
  237. package/dist/server/error-stack-frames.d.ts +35 -0
  238. package/dist/server/error-stack-frames.js +219 -0
  239. package/dist/server/index.d.ts +21 -2
  240. package/dist/server/index.js +11 -2
  241. package/dist/server/runtime-diagnostics.d.ts +165 -0
  242. package/dist/server/runtime-diagnostics.js +360 -0
  243. package/dist/server/sdk-version.d.ts +3 -0
  244. package/dist/server/sdk-version.js +19 -0
  245. package/dist/server/self-test-input-tokens.d.ts +2 -1
  246. package/dist/server/self-test-input-tokens.js +18 -14
  247. package/dist/server/self-test-redaction.js +8 -33
  248. package/dist/server/self-test.d.ts +18 -3
  249. package/dist/server/self-test.js +139 -76
  250. package/dist/server/sensitive-values.d.ts +26 -0
  251. package/dist/server/sensitive-values.js +137 -0
  252. package/dist/server/serve-implementation.d.ts +285 -0
  253. package/dist/server/serve-implementation.js +3172 -0
  254. package/dist/server/serve.d.ts +1 -75
  255. package/dist/server/serve.js +1 -1170
  256. package/dist/server/state-backend-report.d.ts +70 -0
  257. package/dist/server/state-backend-report.js +113 -0
  258. package/dist/server/trace-output.d.ts +7 -0
  259. package/dist/server/trace-output.js +111 -0
  260. package/dist/server/types.d.ts +37 -5
  261. package/dist/server/types.js +34 -1
  262. package/dist/stateful/errors.d.ts +19 -0
  263. package/dist/stateful/errors.js +24 -0
  264. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  265. package/dist/stateful/http-provider-event-emitter.js +237 -0
  266. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  267. package/dist/stateful/http-session-owner-registry.js +210 -0
  268. package/dist/stateful/index.d.ts +18 -0
  269. package/dist/stateful/index.js +18 -0
  270. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  271. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  272. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  273. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  274. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  275. package/dist/stateful/provider-event-pipeline.js +1 -0
  276. package/dist/stateful/provider-events.d.ts +101 -0
  277. package/dist/stateful/provider-events.js +289 -0
  278. package/dist/stateful/session-key.d.ts +15 -0
  279. package/dist/stateful/session-key.js +86 -0
  280. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  281. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  282. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  283. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  284. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  285. package/dist/stateful/stateful-provider-adapter.js +287 -0
  286. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  287. package/dist/stateful/stateful-provider-observability.js +161 -0
  288. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  289. package/dist/stateful/stateful-provider-owner-forwarder.js +237 -0
  290. package/dist/stateful/stateful-provider-runtime-context.d.ts +35 -0
  291. package/dist/stateful/stateful-provider-runtime-context.js +61 -0
  292. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  293. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  294. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  295. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  296. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  297. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  298. package/dist/stateful-signing.d.ts +18 -0
  299. package/dist/stateful-signing.js +27 -0
  300. package/dist/stealth/profiles.d.ts +15 -4
  301. package/dist/stealth/profiles.js +169 -211
  302. package/dist/stream-evidence.d.ts +74 -0
  303. package/dist/stream-evidence.js +785 -0
  304. package/dist/stream.js +7 -1
  305. package/dist/testing/index.d.ts +2 -1
  306. package/dist/testing/index.js +2 -1
  307. package/dist/testing/run.d.ts +32 -2
  308. package/dist/testing/run.js +509 -25
  309. package/dist/trace-sanitization.d.ts +6 -0
  310. package/dist/trace-sanitization.js +68 -0
  311. package/dist/types.d.ts +899 -210
  312. package/dist/types.js +1 -0
  313. package/dist/typescript-module.d.ts +39 -0
  314. package/dist/typescript-module.js +72 -0
  315. package/package.json +52 -6
  316. package/src/auth-turn/index.ts +1 -1
  317. package/src/auth.ts +118 -0
  318. package/src/ceremonies/index.ts +189 -46
  319. package/src/cli/commands.ts +37 -0
  320. package/src/cli/create.ts +8 -2
  321. package/src/cli/deployment-intent.ts +364 -0
  322. package/src/cli/local-connection.ts +221 -0
  323. package/src/cli/migrate-deployment-intent.ts +1908 -0
  324. package/src/cli/migrate-operation-declaration.ts +3026 -0
  325. package/src/cli/migrate-operation-shape.ts +184 -0
  326. package/src/cli/migrate-provider-shape.ts +778 -0
  327. package/src/cli/resolver-runtime.ts +72 -0
  328. package/src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl +141 -23
  329. package/src/cli/templates/provider/Dockerfile.tpl +1 -1
  330. package/src/cli/templates/provider/README.md.tpl +41 -19
  331. package/src/cli/templates/provider/index.ts.tpl +6 -3
  332. package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
  333. package/src/cli/templates/provider/provider.json.tpl +6 -0
  334. package/src/config/loader.ts +774 -181
  335. package/src/contract-serialization.ts +5 -7
  336. package/src/contract-types.ts +12 -5
  337. package/src/contract.ts +24 -10
  338. package/src/declaration-validation.ts +376 -0
  339. package/src/define.ts +1105 -131
  340. package/src/dev.ts +13 -1
  341. package/src/engine.ts +390 -0
  342. package/src/error-observability.ts +64 -0
  343. package/src/error-resolution.ts +269 -0
  344. package/src/errors.ts +157 -0
  345. package/src/fixture-sanitization.ts +422 -0
  346. package/src/handle-meta.ts +143 -0
  347. package/src/handle.ts +694 -0
  348. package/src/health-scenario.ts +960 -0
  349. package/src/i18n/catalog.ts +23 -1
  350. package/src/i18n/error-messages.ts +255 -0
  351. package/src/i18n/index.ts +1 -0
  352. package/src/i18n/keys.ts +80 -6
  353. package/src/i18n/operation-locale-namespace.ts +10 -0
  354. package/src/index.ts +390 -23
  355. package/src/lint.ts +2975 -234
  356. package/src/native-address.ts +340 -0
  357. package/src/native-egress-policy.ts +358 -0
  358. package/src/observability.ts +51 -1
  359. package/src/provider.ts +207 -27
  360. package/src/runtime/auth-flow.ts +15 -0
  361. package/src/runtime/bounded-expiring-map.ts +67 -0
  362. package/src/runtime/browser-telemetry-binding.ts +92 -0
  363. package/src/runtime/browser-telemetry.ts +289 -0
  364. package/src/runtime/browser.ts +882 -99
  365. package/src/runtime/cache-telemetry.ts +247 -0
  366. package/src/runtime/cache.ts +258 -22
  367. package/src/runtime/capability-response.ts +53 -0
  368. package/src/runtime/capability-telemetry.ts +101 -0
  369. package/src/runtime/chrome149-header-order.ts +330 -0
  370. package/src/runtime/diagnostic-env-values.ts +56 -0
  371. package/src/runtime/diagnostic-env.ts +65 -0
  372. package/src/runtime/diagnostic-redactor.ts +668 -0
  373. package/src/runtime/egress-lease.ts +341 -0
  374. package/src/runtime/engine-mode.ts +233 -0
  375. package/src/runtime/env.ts +15 -1
  376. package/src/runtime/executor.ts +39 -32
  377. package/src/runtime/handle-wordlist.ts +266 -0
  378. package/src/runtime/handle.ts +1180 -0
  379. package/src/runtime/http-telemetry-binding.ts +162 -0
  380. package/src/runtime/http-telemetry-guard.ts +208 -0
  381. package/src/runtime/http-telemetry.ts +292 -0
  382. package/src/runtime/http.ts +896 -150
  383. package/src/runtime/insights.ts +2 -2
  384. package/src/runtime/instrumentation.ts +628 -28
  385. package/src/runtime/native-network-errors.ts +99 -0
  386. package/src/runtime/native-network.ts +1853 -0
  387. package/src/runtime/native-telemetry.ts +366 -0
  388. package/src/runtime/ocr-telemetry.ts +308 -0
  389. package/src/runtime/ocr.ts +564 -0
  390. package/src/runtime/otlp.ts +468 -21
  391. package/src/runtime/provider.ts +15 -0
  392. package/src/runtime/proxy-errors.ts +12 -4
  393. package/src/runtime/proxy-nodemaven.ts +222 -0
  394. package/src/runtime/proxy-retry-policy.ts +12 -1
  395. package/src/runtime/proxy-telemetry.ts +358 -103
  396. package/src/runtime/redirect-hop-headers.ts +71 -0
  397. package/src/runtime/redirects.ts +215 -0
  398. package/src/runtime/redis.ts +7 -2
  399. package/src/runtime/request-options.ts +728 -1
  400. package/src/runtime/request-telemetry.ts +375 -0
  401. package/src/runtime/resolver-config.ts +18 -0
  402. package/src/runtime/resolver-public.ts +44 -0
  403. package/src/runtime/resolver-runtime-options.ts +50 -0
  404. package/src/runtime/resolver-shared.ts +113 -0
  405. package/src/runtime/resolver-span-attributes.ts +139 -0
  406. package/src/runtime/resolver-telemetry.ts +362 -0
  407. package/src/runtime/resolver-usage.ts +99 -0
  408. package/src/runtime/resolver-vendors/bindings.ts +61 -0
  409. package/src/runtime/resolver-vendors/browser.ts +591 -0
  410. package/src/runtime/resolver-vendors/capsolver.ts +727 -0
  411. package/src/runtime/resolver-vendors/hosts.ts +81 -0
  412. package/src/runtime/resolver-vendors/hypersolutions.ts +480 -0
  413. package/src/runtime/resolver-vendors/twocaptcha.ts +555 -0
  414. package/src/runtime/resolver-vendors/types.ts +261 -0
  415. package/src/runtime/resolver.ts +1543 -0
  416. package/src/runtime/state-telemetry.ts +298 -0
  417. package/src/runtime/state.ts +435 -89
  418. package/src/runtime/stealth-akamai-sbsd.ts +207 -0
  419. package/src/runtime/stealth-cookies.ts +155 -0
  420. package/src/runtime/stealth-owned-headers.ts +67 -0
  421. package/src/runtime/stealth-telemetry.ts +309 -0
  422. package/src/runtime/stealth.ts +2275 -372
  423. package/src/runtime/stt-telemetry.ts +282 -0
  424. package/src/runtime/stt.ts +96 -91
  425. package/src/runtime/timeout.ts +18 -0
  426. package/src/runtime/trace-config.ts +78 -0
  427. package/src/runtime/trace.ts +257 -35
  428. package/src/runtime-boundary-lint.ts +707 -0
  429. package/src/schema.ts +80 -2
  430. package/src/serve.ts +6 -1
  431. package/src/server/error-observability.ts +1 -0
  432. package/src/server/error-stack-frames.ts +214 -0
  433. package/src/server/index.ts +184 -2
  434. package/src/server/runtime-diagnostics.ts +522 -0
  435. package/src/server/sdk-version.ts +22 -0
  436. package/src/server/self-test-input-tokens.ts +29 -14
  437. package/src/server/self-test-redaction.ts +10 -40
  438. package/src/server/self-test.ts +205 -89
  439. package/src/server/sensitive-values.ts +211 -0
  440. package/src/server/serve-implementation.ts +4596 -0
  441. package/src/server/serve.ts +1 -1685
  442. package/src/server/state-backend-report.ts +185 -0
  443. package/src/server/trace-output.ts +189 -0
  444. package/src/server/types.ts +34 -1
  445. package/src/stateful/README.md +146 -0
  446. package/src/stateful/errors.ts +35 -0
  447. package/src/stateful/http-provider-event-emitter.ts +314 -0
  448. package/src/stateful/http-session-owner-registry.ts +306 -0
  449. package/src/stateful/index.ts +18 -0
  450. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  451. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  452. package/src/stateful/provider-event-pipeline.ts +61 -0
  453. package/src/stateful/provider-events.ts +462 -0
  454. package/src/stateful/session-key.ts +111 -0
  455. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  456. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  457. package/src/stateful/stateful-provider-adapter.ts +562 -0
  458. package/src/stateful/stateful-provider-observability.ts +261 -0
  459. package/src/stateful/stateful-provider-owner-forwarder.ts +310 -0
  460. package/src/stateful/stateful-provider-runtime-context.ts +96 -0
  461. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  462. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  463. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  464. package/src/stateful-signing.ts +46 -0
  465. package/src/stealth/profiles.ts +212 -231
  466. package/src/stream-evidence.ts +988 -0
  467. package/src/stream.ts +8 -1
  468. package/src/testing/index.ts +10 -1
  469. package/src/testing/run.ts +685 -19
  470. package/src/trace-sanitization.ts +110 -0
  471. package/src/types.ts +1014 -273
  472. package/src/typescript-module.ts +100 -0
  473. package/dist/choice-token.d.ts +0 -24
  474. package/dist/choice-token.js +0 -74
  475. package/dist/runtime/choice.d.ts +0 -15
  476. package/dist/runtime/choice.js +0 -413
  477. package/src/choice-token.ts +0 -165
  478. package/src/runtime/choice.ts +0 -686
package/src/types.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  import type ms from "ms";
2
+ import type { HandleContext, HandleKind } from "./handle.js";
3
+ import type { HealthScenario } from "./health-scenario.js";
4
+ import type { SerializedCookieJar } from "tough-cookie";
2
5
 
3
6
  import type { infer as ZodInfer, ZodType } from "zod";
4
7
 
@@ -41,10 +44,10 @@ export type InferSchemaOutput<TSchema extends SchemaLike> =
41
44
  ? Output
42
45
  : unknown;
43
46
 
44
- export interface OperationInputExample {
45
- scenario: string;
47
+ export interface OperationExample {
48
+ scenarioKey: ProviderLocaleKeyInput;
46
49
  input: unknown;
47
- rationale?: string;
50
+ rationaleKey?: ProviderLocaleKeyInput;
48
51
  }
49
52
 
50
53
  export type OperationRiskClass =
@@ -55,19 +58,6 @@ export type OperationRiskClass =
55
58
 
56
59
  export type OperationApprovalPolicy = "never" | "risk-based" | "always";
57
60
 
58
- export interface OperationToolRouterMetadata {
59
- /** Optional MCP-safe override. Defaults to providerId__operationId. */
60
- name?: string;
61
- /** Safety class exposed to Tool Router clients and approval policy. */
62
- riskClass?: OperationRiskClass;
63
- /** OpenAI remote-MCP approval hint. Defaults from riskClass. */
64
- approval?: OperationApprovalPolicy;
65
- /** Override connection requirement when provider auth + openWorld inference is insufficient. */
66
- requiresConnection?: boolean;
67
- /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
68
- connectionExternalRefParam?: string;
69
- }
70
-
71
61
  export type OperationSensitivePath = string;
72
62
 
73
63
  export interface OperationObservabilitySensitiveConfig {
@@ -92,38 +82,6 @@ export interface OperationObservabilityConfig {
92
82
  sensitive?: OperationObservabilitySensitiveConfig;
93
83
  }
94
84
 
95
- export interface OperationAnnotations {
96
- readOnly?: boolean;
97
- destructive?: boolean;
98
- idempotent?: boolean;
99
- /**
100
- * Marks the operation as callable without provider-level authentication.
101
- *
102
- * Provider-level `auth.mode` describes the **majority** auth model of a
103
- * provider; individual operations can still opt out via `openWorld: true`
104
- * when their handler does not consume `ctx.credential`. This is the
105
- * canonical way to declare "this operation is public, even though the
106
- * provider is `credentials`-mode" without splitting the provider into two.
107
- *
108
- * Health-check projections treat `openWorld: true` operations as
109
- * connection-free probes (no `requiresConnection` required, no SA token
110
- * lookup). Future gateway work MAY extend this annotation to bypass
111
- * `X-ApiFuse-Connection-Id` enforcement at proxy time.
112
- *
113
- * Example: Naver Map's `search`, `geocode`, and directions operations
114
- * call public Naver endpoints with no cookies, while `collections` and
115
- * `export` consume the user's session cookie — the provider declares
116
- * `auth.mode: "credentials"` (for the latter) and the former mark
117
- * `openWorld: true`.
118
- */
119
- openWorld?: boolean;
120
- rateLimit?: {
121
- calls: number;
122
- window: "minute" | "hour" | "day";
123
- };
124
- timeoutMs?: number;
125
- }
126
-
127
85
  export const OPERATION_TIMEOUT_MS_MIN = 1;
128
86
  export const OPERATION_TIMEOUT_MS_MAX = 60_000;
129
87
 
@@ -210,14 +168,14 @@ export type SmsOrigin =
210
168
  kind: "e164";
211
169
  value: E164PhoneNumber;
212
170
  display?: string;
213
- }
171
+ }
214
172
  | {
215
173
  /** Country-local service sender, for example KR 1661-5270. */
216
174
  kind: "nationalServiceCode";
217
175
  country: Iso3166Alpha2CountryCode;
218
176
  value: string;
219
177
  display?: string;
220
- };
178
+ };
221
179
 
222
180
  export interface SmsOtpExtractionPattern {
223
181
  /** RegExp or source string containing exactly one usable OTP capture. */
@@ -240,6 +198,80 @@ export interface SmsOtpMatcherDefinition {
240
198
  extractOtp(body: string): string | null;
241
199
  }
242
200
 
201
+ export interface ProviderOcrConfig {
202
+ readonly mode: "required" | "optional";
203
+ }
204
+
205
+ export type OcrImageInput =
206
+ | { readonly kind: "base64"; readonly data: string; readonly mediaType?: string }
207
+ | { readonly kind: "url"; readonly url: string };
208
+
209
+ export interface OcrRecognizeRequest {
210
+ readonly image: OcrImageInput;
211
+ readonly hint?: "captcha" | "document" | "generic";
212
+ readonly prompt?: string;
213
+ readonly maxTokens?: number;
214
+ readonly timeoutMs?: number;
215
+ }
216
+
217
+ export interface OcrWarning {
218
+ readonly code: string;
219
+ readonly message: string;
220
+ }
221
+
222
+ export interface OcrResult {
223
+ readonly text: string;
224
+ readonly model: string;
225
+ readonly warnings?: readonly OcrWarning[];
226
+ }
227
+
228
+ export interface OcrCaptchaOptions {
229
+ readonly length?: number;
230
+ /** Allowed characters. A RegExp is applied to each character, not to the whole text. */
231
+ readonly charset?: string | RegExp;
232
+ readonly caseSensitive?: boolean;
233
+ readonly maxCandidates?: number;
234
+ }
235
+
236
+ export interface OcrCaptchaCandidate {
237
+ readonly text: string;
238
+ readonly satisfiesConstraints: boolean;
239
+ }
240
+
241
+ export interface OcrCaptchaResult {
242
+ readonly text: string;
243
+ readonly candidates: readonly OcrCaptchaCandidate[];
244
+ readonly satisfiesConstraints: boolean;
245
+ readonly model: string;
246
+ }
247
+
248
+ export interface OcrContext {
249
+ /**
250
+ * Whether this context is backed by a configured OCR backend.
251
+ *
252
+ * The SDK owns this verdict: clients built by `createOcrClientFromEnv` for a
253
+ * configured backend report `true`; the unsupported/error clients handed to
254
+ * undeclared or misconfigured providers report `false`. Providers branch on
255
+ * this flag (for example, "require manual CAPTCHA input") instead of probing
256
+ * the engine-owned `APIFUSE__OCR__*` environment names themselves.
257
+ *
258
+ * `true` promises a configured backend, not a successful call: upstream
259
+ * failures still surface as errors from `recognize` / `extractCaptchaText`.
260
+ *
261
+ * Implementations must expose this as an own enumerable data property (not a
262
+ * getter or prototype member) so that wrappers which spread the context, such
263
+ * as `bindOcrTelemetry`, preserve it. Custom `OcrContext` overrides passed to
264
+ * `serve({ ocr })`, `createFlowContext({ ocr })`, or test contexts must set it
265
+ * explicitly.
266
+ */
267
+ readonly available: boolean;
268
+ recognize(request: OcrRecognizeRequest): Promise<OcrResult>;
269
+ extractCaptchaText(
270
+ image: OcrImageInput,
271
+ options?: OcrCaptchaOptions,
272
+ ): Promise<OcrCaptchaResult>;
273
+ }
274
+
243
275
  export type SttTranscribeMode = "general" | "otp";
244
276
  export type SttPromptPolicy = "none" | "default-hint" | "custom-hint";
245
277
  export type SttUnsupportedOptionPolicy = "warn" | "error";
@@ -249,6 +281,171 @@ export interface ProviderSttConfig {
249
281
  mode: ProviderSttMode;
250
282
  }
251
283
 
284
+ /**
285
+ * Union order is documentation only.
286
+ *
287
+ * The SDK owns the default hosted-vendor fallback policy and derives the chain
288
+ * from each provider's declared challenge kinds. Hosted solvers are preferred
289
+ * with `capsolver` ahead of `2captcha` in that policy.
290
+ *
291
+ * `browser` is the in-house CDP pool and remains opt-in; it is excluded from the
292
+ * default chain. `custom` is likewise reserved for provider-specific configuration.
293
+ *
294
+ * `ProviderResolverConfig.vendors` overrides the SDK policy when declared.
295
+ */
296
+ export type ProviderResolverVendor =
297
+ | "browser"
298
+ | "capsolver"
299
+ | "capmonster"
300
+ | "2captcha"
301
+ | "hypersolutions"
302
+ | "custom";
303
+
304
+ /**
305
+ * Token-family kinds resolve to `{ form: "token" }`. Cookie-family kinds resolve
306
+ * to `{ form: "cookies" }`; network-identity binding is defined per kind. `aws_waf`
307
+ * was measured portable across residential leases on buyee, while `cf_clearance`
308
+ * remains unmeasured here and is treated as identity-scoped because it is widely
309
+ * described as IP-bound.
310
+ */
311
+ export type ProviderChallenge =
312
+ | {
313
+ readonly kind: "turnstile";
314
+ readonly siteKey: string;
315
+ readonly pageUrl: string;
316
+ readonly action?: string;
317
+ readonly cdata?: string;
318
+ }
319
+ | {
320
+ readonly kind: "recaptcha_v2";
321
+ readonly siteKey: string;
322
+ readonly pageUrl: string;
323
+ }
324
+ | {
325
+ readonly kind: "recaptcha_v3";
326
+ readonly siteKey: string;
327
+ readonly pageUrl: string;
328
+ readonly action: string;
329
+ readonly minScore?: number;
330
+ }
331
+ | {
332
+ readonly kind: "hcaptcha";
333
+ readonly siteKey: string;
334
+ readonly pageUrl: string;
335
+ }
336
+ | {
337
+ readonly kind: "cloudflare_interstitial";
338
+ readonly pageUrl: string;
339
+ readonly blockedHtml?: string;
340
+ }
341
+ | {
342
+ readonly kind: "aws_waf";
343
+ readonly pageUrl: string;
344
+ /** `window.gokuProps.key`; solver vendors require it, while `"browser"` does not. */
345
+ readonly siteKey?: string;
346
+ readonly captchaScript?: string;
347
+ readonly context?: string;
348
+ readonly iv?: string;
349
+ }
350
+ | {
351
+ readonly kind: "akamai_sec_cpt";
352
+ readonly pageUrl: string;
353
+ /** The admitted challenge document, needed for tile/context extraction. */
354
+ readonly challengeHtml?: string;
355
+ }
356
+ | {
357
+ readonly kind: "akamai_sensor";
358
+ readonly pageUrl: string;
359
+ /** Upstream sensor script URL the payload must be POSTed to. */
360
+ readonly scriptUrl: string;
361
+ /** Current `_abck` cookie value, rotates each round. */
362
+ readonly abck?: string;
363
+ /** Current `bm_sz` / `ak_bmsc` value when the upstream set one. */
364
+ readonly bmsz?: string;
365
+ /** Bot Manager major version when known ("3" measured on zozo.jp). */
366
+ readonly version?: string;
367
+ }
368
+ | {
369
+ readonly kind: "akamai_sbsd";
370
+ readonly pageUrl: string;
371
+ /**
372
+ * Discovered SBSD script URL. `?v=&t=` is a hard challenge and `?v=`
373
+ * is passive or a remembered script. A later challenge token never
374
+ * changes this URL.
375
+ */
376
+ readonly scriptUrl: string;
377
+ readonly stateCookieName: "sbsd_o" | "bm_so";
378
+ /**
379
+ * Token returned by a later `cpr_chlge` response. When present with a
380
+ * remembered v-only script, it selects index 0 and is appended only to
381
+ * the payload POST URL.
382
+ */
383
+ readonly challengeToken?: string;
384
+ };
385
+
386
+ export type ProviderChallengeKind = ProviderChallenge["kind"];
387
+
388
+ /**
389
+ * Token solutions carry no network-identity binding. Cookie-solution binding is
390
+ * per challenge kind: `aws_waf` was measured portable across residential leases
391
+ * on buyee, while `cf_clearance` is unmeasured here and treated as scoped to the
392
+ * identity that produced it. The provider attaches the returned cookies to its
393
+ * own requests. `cookie_state` solutions carry no values: SBSD state lives only
394
+ * in the engine-owned bound jar, and a 2xx payload POST is not proof of a solve;
395
+ * only the next protected GET can verify it (the safe refetch is Phase 2).
396
+ */
397
+ export type ChallengeSolution =
398
+ | { readonly form: "token"; readonly token: string }
399
+ | {
400
+ readonly form: "cookies";
401
+ readonly cookies: Readonly<Record<string, string>>;
402
+ readonly userAgent: string;
403
+ /** Epoch seconds copied from the upstream cookie's own expiry attribute; never a constant. */
404
+ readonly expires?: number;
405
+ /**
406
+ * Epoch seconds conservatively estimated by the SDK when a resolver vendor omits
407
+ * the upstream cookie's expiry. `expires` takes precedence when both are present.
408
+ */
409
+ readonly sdkEstimatedExpires?: number;
410
+ }
411
+ | {
412
+ readonly form: "cookie_state";
413
+ readonly kind: "akamai_sbsd";
414
+ readonly outcome: "payload_accepted";
415
+ /** Always false until a later protected GET verifies the bound jar (Phase 2). */
416
+ readonly verified: false;
417
+ /** Name only; the identity-bound cookie value remains in the engine-owned jar. */
418
+ readonly stateCookieName: "sbsd_o" | "bm_so";
419
+ /** Epoch seconds observed on the updated state cookie, when supplied upstream. */
420
+ readonly expires?: number;
421
+ };
422
+
423
+ /**
424
+ * `akamai_sbsd` declarations require a transport-owned client profile because the
425
+ * solve runs on the provider's admitted session. Other kinds may omit it.
426
+ */
427
+ export type ProviderResolverConfig =
428
+ | {
429
+ /** Optional ordered override for the SDK-owned vendor fallback chain. */
430
+ readonly vendors?: readonly ProviderResolverVendor[];
431
+ /** Challenge kinds this provider is permitted to request. */
432
+ readonly kinds: readonly Exclude<ProviderChallengeKind, "akamai_sbsd">[];
433
+ readonly clientProfile?: string;
434
+ }
435
+ | {
436
+ /** Optional ordered override for the SDK-owned vendor fallback chain. */
437
+ readonly vendors?: readonly ProviderResolverVendor[];
438
+ /** Challenge kinds this provider is permitted to request. */
439
+ readonly kinds: readonly ProviderChallengeKind[];
440
+ /**
441
+ * Client fingerprint profile the SDK must use when reaching this upstream.
442
+ * Measured on zozo.jp: Chrome/Firefox profiles are refused 403 before any
443
+ * challenge is served, while a Safari profile is admitted. Provider-declared
444
+ * because only the provider knows its upstream's admission rule.
445
+ */
446
+ readonly clientProfile: string;
447
+ };
448
+
252
449
  export type SttAudioInput = {
253
450
  kind: "base64";
254
451
  data: string;
@@ -327,6 +524,10 @@ export interface SttContext {
327
524
  ): VerificationCodeExtractionResult;
328
525
  }
329
526
 
527
+ export interface ResolverContext {
528
+ solve(challenge: ProviderChallenge, signal?: AbortSignal): Promise<ChallengeSolution>;
529
+ }
530
+
330
531
  export interface HealthJourneySchedule {
331
532
  kind: "interval";
332
533
  /** ISO 8601 duration, for example PT8H. */
@@ -339,11 +540,11 @@ export type HealthScheduleRandomization =
339
540
  | {
340
541
  mode: "centered";
341
542
  maxOffset: Iso8601Duration;
342
- }
543
+ }
343
544
  | {
344
545
  mode: "delayed";
345
546
  maxDelay: Iso8601Duration;
346
- };
547
+ };
347
548
 
348
549
  export interface HealthJourneyStep {
349
550
  id: string;
@@ -458,7 +659,7 @@ export type HealthJourneyManualTriggerPolicy =
458
659
  /** ISO 8601 duration. Minimum time between manual executions. */
459
660
  minManualInterval: Iso8601Duration;
460
661
  publicRationale: string;
461
- };
662
+ };
462
663
 
463
664
  export interface HealthJourneyRunResult {
464
665
  status?: "ok" | "degraded" | "down" | "unknown";
@@ -466,7 +667,7 @@ export interface HealthJourneyRunResult {
466
667
  metadata?: Record<string, unknown>;
467
668
  }
468
669
 
469
- export interface HealthJourneyDefinition {
670
+ interface HealthJourneyDefinitionBase {
470
671
  id: string;
471
672
  title?: string;
472
673
  description?: string;
@@ -478,11 +679,17 @@ export interface HealthJourneyDefinition {
478
679
  requiredSecrets?: readonly string[];
479
680
  manualTrigger?: HealthJourneyManualTriggerPolicy;
480
681
  steps: readonly [HealthJourneyStep, ...HealthJourneyStep[]];
481
- run?: (
482
- ctx: HealthJourneyRunContext,
483
- ) => Promise<HealthJourneyRunResult | undefined>;
484
682
  }
485
683
 
684
+ export type HealthJourneyDefinition = HealthJourneyDefinitionBase &
685
+ (
686
+ | {
687
+ run: (ctx: HealthJourneyRunContext) => Promise<HealthJourneyRunResult | undefined>;
688
+ scenario?: never;
689
+ }
690
+ | { scenario: HealthScenario; run?: never }
691
+ );
692
+
486
693
  /**
487
694
  * Health-check authoring surface owned by `@apifuse/provider-sdk`.
488
695
  *
@@ -574,38 +781,13 @@ export interface HealthCheckCaseResult {
574
781
  * so authors get IntelliSense and compile-time errors when accessing fields
575
782
  * that do not exist on the operation's declared output schema.
576
783
  */
577
- export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
784
+ export type HealthCheckCase<TInput = unknown, TOutput = unknown> = {
578
785
  /** Human-readable case name; unique within the suite. */
579
786
  name: string;
580
787
  /** Optional longer description shown on ops dashboards. */
581
788
  description?: string;
582
789
  /** Input passed to the operation handler for this case. */
583
790
  input: TInput;
584
- /**
585
- * Optional runtime input preparation hook for volatile probes. Use this when
586
- * the durable probe input must be derived from a live read-only operation
587
- * immediately before the checked operation executes.
588
- */
589
- prepareInput?: (
590
- ctx: HealthCheckInputPreparationContext<TInput>,
591
- ) => TInput | Promise<TInput>;
592
- /**
593
- * Assertion executed against the operation's response and timing.
594
- *
595
- * - Throw to fail the case (recorded as `down`).
596
- * - Return `{ status: "degraded", label }` to flag without failing.
597
- * - Return `void` (implicit) for `ok`.
598
- *
599
- * MUST NOT access scheduler, recorder, or any runtime type — pure data
600
- * + lambda only.
601
- */
602
- assertions: (
603
- ctx: HealthCheckAssertionContext<TOutput>,
604
- ) =>
605
- | void
606
- | Promise<void>
607
- | HealthCheckCaseResult
608
- | Promise<HealthCheckCaseResult>;
609
791
  /** Override per-case degradation threshold (ms); falls back to the suite default. */
610
792
  degradedThresholdMs?: number;
611
793
  /** Override per-case timeout in milliseconds; falls back to the suite/provider/runtime default. */
@@ -614,7 +796,53 @@ export interface HealthCheckCase<TInput = unknown, TOutput = unknown> {
614
796
  expectedStatus?: "ok" | "degraded";
615
797
  /** Runtime gate (env-driven); if returns false the case is skipped & logged. */
616
798
  enabled?: () => boolean;
617
- }
799
+ } & (
800
+ | {
801
+ /**
802
+ * Optional runtime input preparation hook for volatile probes. Use this when
803
+ * the durable probe input must be derived from a live read-only operation
804
+ * immediately before the checked operation executes.
805
+ */
806
+ prepareInput?: (
807
+ ctx: HealthCheckInputPreparationContext<TInput>,
808
+ ) => TInput | Promise<TInput>;
809
+ /**
810
+ * Assertion executed against the operation's response and timing.
811
+ *
812
+ * - Throw to fail the case (recorded as `down`).
813
+ * - Return `{ status: "degraded", label }` to flag without failing.
814
+ * - Return `void` (implicit) for `ok`.
815
+ *
816
+ * MUST NOT access scheduler, recorder, or any runtime type — pure data
817
+ * + lambda only.
818
+ *
819
+ * NOTE: a closure cannot cross the registry's serialization boundary, so
820
+ * the platform health monitor cannot execute this hook — it runs a case's
821
+ * serialized `scenario` and nothing else. A case that carries only
822
+ * `assertions` is still published as a probe, but its outcome is
823
+ * permanently `unknown` / `monitoring_unavailable`, so the operation
824
+ * reads as monitored while nothing is being checked. This hook runs only
825
+ * in the provider runtime's own self-test
826
+ * (`/internal/health/self-test`). Express anything that must be
827
+ * monitored in production as a `scenario`.
828
+ */
829
+ assertions: (
830
+ ctx: HealthCheckAssertionContext<TOutput>,
831
+ ) =>
832
+ | void
833
+ | Promise<void>
834
+ | HealthCheckCaseResult
835
+ | Promise<HealthCheckCaseResult>;
836
+ /** Declarative scenarios replace the imperative preparation and assertion hooks. */
837
+ scenario?: never;
838
+ }
839
+ | {
840
+ /** Declarative scenario executed by the health-monitor runtime. */
841
+ scenario: HealthScenario;
842
+ prepareInput?: never;
843
+ assertions?: never;
844
+ }
845
+ );
618
846
 
619
847
  /**
620
848
  * Operation-level health-check suite. At least one case is required when
@@ -718,26 +946,55 @@ export interface HealthMonitorProbeOverride {
718
946
  degradedThresholdMs?: number;
719
947
  }
720
948
 
949
+ export const VALID_OPERATION_ERROR_STATUSES = [400, 401, 404, 409, 410, 422, 429, 500, 502, 503, 504] as const;
950
+
951
+ export type ProviderErrorStatus = (typeof VALID_OPERATION_ERROR_STATUSES)[number];
952
+
721
953
  export interface OperationErrorCode {
722
954
  code: string;
723
- status?: number;
955
+ status?: ProviderErrorStatus;
956
+ /** Developer-facing English prose for docs and MCP tool text. Never localized. */
724
957
  description: string;
725
958
  retryable?: boolean;
726
- }
727
-
728
- export interface OperationDocMeta {
729
- titleKey?: ProviderLocaleKeyInput;
730
- descriptionKey?: ProviderLocaleKeyInput;
731
- summaryKey?: ProviderLocaleKeyInput;
732
- markdownKey?: ProviderLocaleKeyInput;
733
- normalizationNotesKeys?: ProviderLocaleKeyInput[];
734
- requestExample?: Record<string, unknown>;
735
- responseExample?: unknown;
736
- errorCodes?: OperationErrorCode[];
959
+ /**
960
+ * Locale catalog key for the client-facing `message` of every error thrown
961
+ * with this `code`. A throw site's own `messageKey` wins; when neither is
962
+ * present the SDK derives `errors.<code>.message`.
963
+ */
964
+ messageKey?: ProviderLocaleKeyInput;
965
+ /** Locale catalog key for the client-facing `fix`. Derived default: `errors.<code>.fix`. */
966
+ fixKey?: ProviderLocaleKeyInput;
737
967
  }
738
968
 
739
969
  export type StealthPlatform = "macos" | "windows" | "linux" | "android" | "ios";
740
970
 
971
+ export type StealthBrowser = "chrome" | "firefox" | "safari";
972
+
973
+ export type StealthOS = "windows" | "macos" | "linux" | "ios";
974
+
975
+ /** A supported, fully resolved browser/OS fingerprint pair. */
976
+ export type StealthProfileDescriptor =
977
+ | { browser: "chrome"; os: "windows" | "macos" | "linux" }
978
+ | { browser: "firefox"; os: "windows" | "macos" | "linux" }
979
+ | { browser: "safari"; os: "macos" | "ios" };
980
+
981
+ /**
982
+ * Browser/OS fingerprint selection. Chrome and macOS are the named defaults
983
+ * when their respective axes are omitted.
984
+ */
985
+ export type StealthProfileSelection =
986
+ | { browser?: "chrome"; os?: "windows" | "macos" | "linux" }
987
+ | { browser: "firefox"; os?: "windows" | "macos" | "linux" }
988
+ | { browser: "safari"; os?: "macos" | "ios" };
989
+
990
+ /** Provider-owned opt-ins layered onto the transport-owned browser/OS profile. */
991
+ export type ProviderStealthConfig = StealthProfileSelection & {
992
+ readonly challengeDetection?: {
993
+ /** Classify SBSD responses even when no resolver is declared (detect/report mode). */
994
+ readonly akamaiSbsd?: boolean;
995
+ };
996
+ };
997
+
741
998
  export type BrowserEngine = "playwright-stealth" | "nodriver" | "selenium-uc";
742
999
  export interface BrowserOptions {
743
1000
  headless?: boolean;
@@ -747,9 +1004,7 @@ export interface BrowserOptions {
747
1004
  requireCdpPool?: boolean;
748
1005
  }
749
1006
 
750
- export interface StealthProfile {
751
- name: string;
752
- platform: StealthPlatform;
1007
+ export type StealthProfile = StealthProfileDescriptor & {
753
1008
  version: string;
754
1009
  userAgent: string;
755
1010
  tlsClientIdentifier?: string;
@@ -757,9 +1012,14 @@ export interface StealthProfile {
757
1012
  ja4?: string;
758
1013
  h2Settings?: Record<string, unknown>;
759
1014
  headerOrder?: string[];
760
- }
1015
+ };
761
1016
 
762
- export type AuthMode = "none" | "platform-managed" | "credentials" | "oauth2";
1017
+ export type AuthMode =
1018
+ | "none"
1019
+ | "platform-managed"
1020
+ | "credentials"
1021
+ | "oauth2"
1022
+ | "oauth2_proxied";
763
1023
 
764
1024
  export type ConnectionMode = AuthMode;
765
1025
 
@@ -769,7 +1029,27 @@ export type ProviderAccessVisibility = "public" | "early_access";
769
1029
 
770
1030
  export type ProviderProxyMode = "disabled" | "optional" | "required";
771
1031
 
772
- export type ProviderProxyProvider = "smartproxy" | "decodo" | "custom";
1032
+ /**
1033
+ * Proxy egress vendors. These are FOUR DISTINCT services — do not conflate them
1034
+ * (a common mistake because the names collide with a well-known rebrand):
1035
+ *
1036
+ * - `smartproxy` — **api.smartproxy.org**, a residential proxy with an IP
1037
+ * *extraction/allocation* API (app_key → a pool of raw `ip:port` CONNECT
1038
+ * endpoints). This is our own vendor. It is NOT the company formerly named
1039
+ * "Smartproxy". Credentials: `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
1040
+ * - `nodemaven` — **gate.nodemaven.com**, a *gateway* proxy with static
1041
+ * credentials; geo/session encoded in the username, no allocation API.
1042
+ * - `decodo` — **decodo.com**, the *gateway* proxy that was named "Smartproxy"
1043
+ * (smartproxy.com) before its 2025 rebrand to Decodo. Sticky sessions via
1044
+ * username params. A different company from `smartproxy` above.
1045
+ * **@deprecated** — unused; no managed adapter. Declare a
1046
+ * `ProviderProxyPolicy` using `smartproxy` or `nodemaven` instead; the
1047
+ * `smartproxy` allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
1048
+ * - `custom` — **@deprecated** static proxy marker with no managed adapter.
1049
+ * Use `ProviderProxyPolicy` with `smartproxy`/`nodemaven`; the `smartproxy`
1050
+ * allocator requires `APIFUSE__PROXY__SMARTPROXY_APP_KEY`.
1051
+ */
1052
+ export type ProviderProxyProvider = "smartproxy" | "nodemaven" | "decodo" | "custom";
773
1053
 
774
1054
  export type ProviderProxySessionAffinity =
775
1055
  | "request"
@@ -783,7 +1063,18 @@ export interface ProviderProxyPolicy {
783
1063
  * certificate verification, and vendor allocator endpoints are SDK-owned.
784
1064
  */
785
1065
  mode: ProviderProxyMode;
1066
+ /**
1067
+ * @deprecated Use `providers: [...]` to declare an ordered vendor fallback
1068
+ * chain. A single-element `providers` list is equivalent to this field.
1069
+ */
786
1070
  provider?: ProviderProxyProvider;
1071
+ /**
1072
+ * Ordered proxy-vendor fallback chain. The SDK tries each vendor in order and
1073
+ * fails over to the next when a vendor lacks credentials or its allocation /
1074
+ * transport is exhausted. When omitted, `provider` (or the platform default)
1075
+ * is used as a single-vendor chain.
1076
+ */
1077
+ providers?: ProviderProxyProvider[];
787
1078
  geo?: {
788
1079
  /** ISO 3166-1 alpha-2 country code, for example KR or US. */
789
1080
  country?: Iso3166Alpha2CountryCode;
@@ -794,6 +1085,12 @@ export interface ProviderProxyPolicy {
794
1085
  affinity?: ProviderProxySessionAffinity;
795
1086
  lifetimeMinutes?: number;
796
1087
  poolSize?: number;
1088
+ /**
1089
+ * Seconds before hard sticky expiry at which native connections receive
1090
+ * the `expiring` event so the provider can drain and reconnect cleanly.
1091
+ * Declared by the provider; the SDK does not assume a default cut point.
1092
+ */
1093
+ drainLeadSeconds?: number;
797
1094
  };
798
1095
  }
799
1096
 
@@ -804,13 +1101,12 @@ export interface ProviderAccessConfig {
804
1101
  * Provider-level rollout visibility.
805
1102
  *
806
1103
  * - `public`: visible in public docs/catalog/OpenAPI and callable through
807
- * the existing provider policy stack.
1104
+ * the existing provider policy stack.
808
1105
  * - `early_access`: hidden from public discovery and callable only when the
809
- * active customer organization has a provider-level access grant.
1106
+ * active customer organization has a provider-level access grant.
810
1107
  *
811
1108
  * This is intentionally provider-level only. It does not alter auth mode,
812
- * operation schemas, health-check authoring, `openWorld`, or Connection
813
- * requirements.
1109
+ * operation schemas, health-check authoring, or Connection requirements.
814
1110
  */
815
1111
  visibility?: ProviderAccessVisibility;
816
1112
  }
@@ -828,12 +1124,12 @@ export type ProviderLogoProfile =
828
1124
  */
829
1125
  url?: string;
830
1126
  background?: string;
831
- }
1127
+ }
832
1128
  | {
833
1129
  source: "monogram" | "none";
834
1130
  background?: string;
835
1131
  fallbackReason: string;
836
- };
1132
+ };
837
1133
 
838
1134
  export type ProviderPublicConnectionMode =
839
1135
  | "apifuse_managed"
@@ -887,6 +1183,10 @@ export interface ProviderMeta {
887
1183
  publicProfile?: ProviderPublicProfile;
888
1184
  contract?: {
889
1185
  publicSchemaFieldNames?: "normalized";
1186
+ readonly pinnedWireFieldPaths?: readonly {
1187
+ readonly path: string;
1188
+ readonly reason: string;
1189
+ }[];
890
1190
  };
891
1191
  }
892
1192
 
@@ -967,19 +1267,104 @@ export interface HttpRetrySummary {
967
1267
  lastStatus?: number;
968
1268
  }
969
1269
 
1270
+ /** Per-attempt input for a `RequestOptions.headers` factory. */
1271
+ export interface HttpAttemptContext {
1272
+ /**
1273
+ * 1-based number of this request build: the first request is `1`, its first
1274
+ * retry `2`. Only attempts that reach header resolution count; a failed
1275
+ * proxy allocation or a skipped duplicate proxy offset builds no request
1276
+ * and is not numbered.
1277
+ */
1278
+ attempt: number;
1279
+ /**
1280
+ * Resolved request URL: `baseUrl` + path + `params` + `sensitiveParams`.
1281
+ * It is the exact URL the attempt is issued against, so bind signature
1282
+ * targets to it rather than to a URL the caller rebuilds. Strip the query
1283
+ * and fragment for fields that are defined without them — RFC 9449 §4.2
1284
+ * requires that of DPoP `htu`. It carries any sensitive query values, so
1285
+ * never log it and never copy it verbatim into a signed field that a
1286
+ * verifier logs.
1287
+ */
1288
+ url: string;
1289
+ /** Normalized upper-case HTTP method of the request. */
1290
+ method: Uppercase<HttpMethod>;
1291
+ }
1292
+
1293
+ /**
1294
+ * Builds the request headers for one issued attempt. Managed retry calls it
1295
+ * again for every retry, so request-bound single-use proofs (DPoP `jti`,
1296
+ * HTTP message signatures, HMAC nonces) can be re-minted instead of replayed.
1297
+ * A throw is raised as a non-retryable `TransportError` with code
1298
+ * `http_header_factory_failed`.
1299
+ */
1300
+ export type HttpHeadersFactory = (
1301
+ attempt: HttpAttemptContext,
1302
+ ) => Record<string, string> | Promise<Record<string, string>>;
1303
+
970
1304
  export interface RequestOptions {
971
- headers?: Record<string, string>;
1305
+ /**
1306
+ * Request headers, or a factory resolved once per issued attempt (see
1307
+ * `HttpHeadersFactory`). The factory runs after proxy resolution, before the
1308
+ * first redirect hop of that attempt; redirect hops reuse the attempt's
1309
+ * headers. `ctx.stealth` declares its own header option and is not affected.
1310
+ */
1311
+ headers?: Record<string, string> | HttpHeadersFactory;
972
1312
  params?: RequestParams;
1313
+ /**
1314
+ * Query parameters whose values contain credentials or other secret material.
1315
+ * They are sent like `params`, but redacted from SDK errors, traces, and recorded fixtures.
1316
+ */
1317
+ sensitiveParams?: Record<string, string>;
973
1318
  proxy?: string;
1319
+ /**
1320
+ * Per-attempt timeout for the response-header phase. It is disarmed once a
1321
+ * successful response's headers arrive, so it never bounds consumption of
1322
+ * that body — on the buffered path as well as on streams; use `signal` for
1323
+ * that. A non-2xx body the transport discards on the caller's behalf is
1324
+ * still drained under this deadline, so a wedged error body cannot hang the
1325
+ * attempt.
1326
+ */
974
1327
  timeout?: number;
1328
+ /**
1329
+ * Cancels this request only — its retries, its backoff sleep and its
1330
+ * response-body consumption — leaving the client's other in-flight requests
1331
+ * untouched. Merged with the client-level `signal`, so a rejection reads as
1332
+ * `transport_cancelled` either way; inspect `signal.reason` to tell a
1333
+ * per-request abort from a fleet-wide one.
1334
+ */
1335
+ signal?: AbortSignal;
975
1336
  /**
976
1337
  * Defaults to true. Set to false when callers need to inspect upstream
977
1338
  * non-2xx bodies themselves instead of converting them to TransportError.
978
1339
  */
979
1340
  throwOnHttpError?: boolean;
980
1341
  retry?: boolean | HttpRetryPreset | HttpRetryOptions;
1342
+ /**
1343
+ * Opt-in redirect-hop enforcement for ctx.http. When present, redirects are
1344
+ * evaluated before the next request is issued. Existing callers that omit
1345
+ * this policy retain the native fetch redirect behavior.
1346
+ */
1347
+ redirectPolicy?: HttpRedirectPolicy;
981
1348
  }
982
1349
 
1350
+ export type RedirectRunReason =
1351
+ | "completed"
1352
+ | "stopped"
1353
+ | "max_hops"
1354
+ | "missing_location"
1355
+ | "loop";
1356
+
1357
+ export type HttpRedirectPolicyMode = "same-origin";
1358
+
1359
+ export interface HttpRedirectPolicy {
1360
+ /** Only follow redirects whose canonical scheme, host, and port match the initial URL. */
1361
+ mode: HttpRedirectPolicyMode;
1362
+ /** Maximum number of redirect hops that may be followed. Must be an integer from 0 to 20. */
1363
+ maxHops: number;
1364
+ }
1365
+
1366
+ export type HttpRedirectFailureReason = Exclude<RedirectRunReason, "completed">;
1367
+
983
1368
  export type HttpMethod =
984
1369
  | "HEAD"
985
1370
  | "head"
@@ -998,10 +1383,60 @@ export type HttpMethod =
998
1383
  | "PATCH"
999
1384
  | "patch";
1000
1385
 
1001
- export interface StealthFetchOptions extends RequestOptions {
1386
+ export interface StealthFetchOptions extends Omit<RequestOptions, "redirectPolicy" | "headers"> {
1387
+ /**
1388
+ * Not supported by the stealth transport, which observes only the
1389
+ * client-level `signal` passed to `createStealthClient`. Typed as `never` so
1390
+ * a per-request signal fails to compile instead of being silently ignored;
1391
+ * threading one through the stealth session is a separate change.
1392
+ */
1393
+ signal?: never;
1394
+ /**
1395
+ * Defaults to true. Set to false when callers need to inspect upstream
1396
+ * non-2xx bodies themselves instead of converting them to TransportError.
1397
+ *
1398
+ * Documented exception: a non-2xx response that an opted-in SDK challenge
1399
+ * detector classified (`response.challenge` is set) is returned, not thrown,
1400
+ * whatever this flag says, so the classification stays observable. Callers
1401
+ * that need the failure semantics check `response.challenge` first.
1402
+ */
1403
+ throwOnHttpError?: boolean;
1404
+ /**
1405
+ * Request headers. Array values and case-insensitive duplicate names are
1406
+ * combined in caller order using `", "`, matching Chrome's Fetch behavior.
1407
+ *
1408
+ * The stealth transport owns `host`, `connection`, `user-agent`, `sec-ch-ua`,
1409
+ * `sec-ch-ua-mobile`, `sec-ch-ua-platform`, `accept-encoding`, and every
1410
+ * `sec-fetch-*` header. Supplying any of them throws
1411
+ * `STEALTH_HEADER_OVERRIDE_UNSUPPORTED` at request time; declare the request
1412
+ * shape with `stealth.requestClass` instead.
1413
+ */
1414
+ headers?: Record<string, string | string[]>;
1002
1415
  method?: HttpMethod;
1003
1416
  body?: string | Buffer;
1417
+ /**
1418
+ * Defaults to `"follow"`. Every followed hop drops the request-body headers
1419
+ * when the method changes, `Authorization` and `Proxy-Authorization` when it
1420
+ * leaves the current origin, and an explicit `Cookie` when it leaves the
1421
+ * current site (scheme plus registrable domain); after that the session
1422
+ * cookie jar supplies cookies for the new site.
1423
+ */
1004
1424
  redirect?: "follow" | "manual" | "error";
1425
+ /**
1426
+ * Opt-in same-origin redirect enforcement, the ctx.http `redirectPolicy`
1427
+ * for the stealth transport. A redirect whose target leaves the initial
1428
+ * origin, exceeds `maxHops` (at most 10, the stealth redirect limit),
1429
+ * loops, or has no usable `Location` throws `HttpRedirectError` before any
1430
+ * request is sent to that target. Requires the default
1431
+ * `redirect: "follow"`.
1432
+ */
1433
+ redirectPolicy?: HttpRedirectPolicy;
1434
+ /**
1435
+ * Maximum decoded response-body bytes to buffer. When set, the stealth
1436
+ * transport aborts the response and throws `response_too_large` if the
1437
+ * declared or streamed body exceeds this limit.
1438
+ */
1439
+ maxBodyBytes?: number;
1005
1440
  /**
1006
1441
  * Offsets policy-managed proxy pool selection for caller-managed retries.
1007
1442
  * Use when a request receives an upstream challenge page rather than a
@@ -1009,31 +1444,83 @@ export interface StealthFetchOptions extends RequestOptions {
1009
1444
  * operation-affinity proxy.
1010
1445
  */
1011
1446
  proxyAttemptOffset?: number;
1012
- /** Override the configured browser-like stealth profile for this request. */
1013
- profile?: string;
1014
1447
  /**
1015
- * Stealth transport certificate controls. Use only for proxy products that
1016
- * terminate CONNECT with a private CA instead of tunneling the origin
1017
- * certificate chain.
1448
+ * SDK-specific stealth controls, including a per-request browser and/or OS
1449
+ * override. Standard HTTP metadata such as language, referrer, and content
1450
+ * type belongs in `headers`.
1018
1451
  */
1019
- stealth?: {
1452
+ stealth?: StealthProfileSelection & {
1453
+ /**
1454
+ * Declare the Chrome request class when it cannot be inferred from the
1455
+ * method (`POST` infers `post`, everything else `navigation`). This is the
1456
+ * replacement for hand-set `Sec-Fetch-*` headers, which the transport
1457
+ * rejects; it drives `Sec-Fetch-Mode`/`Dest`/`User`, `Accept`, `Priority`,
1458
+ * and `Upgrade-Insecure-Requests`.
1459
+ *
1460
+ * `form-post` is an HTML `<form method="post">` submission: a navigation
1461
+ * (`navigate`/`document`, the document `Accept`, `Upgrade-Insecure-Requests`)
1462
+ * that carries a body, in the header order Chrome uses for it, with
1463
+ * `Cache-Control: max-age=0` and the caller's `Content-Type`, `Origin` and
1464
+ * `Referer` in place. It is never inferred, since a form submission and a
1465
+ * script `fetch()` POST look the same to the transport.
1466
+ */
1467
+ requestClass?: "navigation" | "form-post" | "xhr" | "post";
1468
+ /**
1469
+ * Whether a `navigation` or `form-post` request carries a user gesture and
1470
+ * therefore `Sec-Fetch-User: ?1` (default `true`). Set `false` for
1471
+ * script-driven navigations such as `location.replace` or
1472
+ * `form.submit()`, which Chrome sends without it. Ignored for the `xhr` and
1473
+ * `post` request classes.
1474
+ */
1475
+ userActivation?: boolean;
1476
+ /**
1477
+ * Use only for proxy products that terminate CONNECT with a private CA
1478
+ * instead of tunneling the origin certificate chain.
1479
+ */
1020
1480
  insecureSkipVerify?: boolean;
1021
1481
  };
1022
1482
  }
1023
1483
 
1024
1484
  export interface CookieJar {
1025
- get(name: string): string | undefined;
1026
- getAll(): Record<string, string>;
1027
- toString(): string;
1028
- find?(predicate: (cookie: string) => boolean): string | undefined;
1485
+ /** URL-less reads use the jar's response URL or session base URL. */
1486
+ get(name: string, url?: string): string | undefined;
1487
+ getAll(url?: string): Record<string, string>;
1488
+ toString(url?: string): string;
1489
+ find?(predicate: (cookie: string) => boolean, url?: string): string | undefined;
1029
1490
  }
1030
1491
 
1492
+ /**
1493
+ * Version 1 of the JSON-safe, attribute-preserving stealth cookie store.
1494
+ * The nested jar is tough-cookie's serialized form and retains cookie origin,
1495
+ * Path, Secure, expiry, host-only, and other RFC attributes.
1496
+ */
1497
+ export interface StealthCookieStoreV1 {
1498
+ readonly version: 1;
1499
+ readonly jar: SerializedCookieJar;
1500
+ }
1501
+
1502
+ /** Cookie persistence formats understood by this SDK version. */
1503
+ export type StealthCookieStore = StealthCookieStoreV1;
1504
+
1031
1505
  export interface StealthSessionCookies extends CookieJar {
1032
- has(name: string): boolean;
1033
- setFromCookieStrings(cookieStrings: readonly string[]): void;
1034
- toHeader(): string;
1506
+ has(name: string, url?: string): boolean;
1507
+ /** URL-less writes are scoped to the session base URL. */
1508
+ setFromCookieStrings(cookieStrings: readonly string[], url?: string): void;
1509
+ toHeader(url?: string): string;
1510
+ /**
1511
+ * Returns every cookie as a flat name/value map, collapsing duplicate names.
1512
+ * @deprecated Use serialize() for lossless, attribute-preserving persistence.
1513
+ */
1035
1514
  snapshot(): Record<string, string>;
1515
+ /**
1516
+ * Restores flat values as host-only, Path=/ cookies on the session base URL.
1517
+ * @deprecated Use deserialize() with state produced by serialize().
1518
+ */
1036
1519
  restore(cookies: Record<string, string>): void;
1520
+ /** Returns a versioned, JSON-safe, attribute-preserving representation of every cookie. */
1521
+ serialize(): StealthCookieStoreV1;
1522
+ /** Replaces the jar with a previously serialized, attribute-preserving cookie store. */
1523
+ deserialize(state: StealthCookieStore): void;
1037
1524
  clear(): void;
1038
1525
  }
1039
1526
 
@@ -1045,6 +1532,8 @@ export interface DeclarativeStealthResponse {
1045
1532
  headers: Record<string, string>;
1046
1533
  rawHeaders: [string, string][];
1047
1534
  body: string;
1535
+ /** Present only when an opted-in SDK detector returned an unresolved challenge response. */
1536
+ challenge?: StealthChallengeClassification;
1048
1537
  httpVersion?: string;
1049
1538
  tlsInfo?: { protocol?: string; cipher?: string; [key: string]: unknown };
1050
1539
  cookies: CookieJar;
@@ -1055,6 +1544,23 @@ export interface DeclarativeStealthResponse {
1055
1544
 
1056
1545
  export type StealthResponse = DeclarativeStealthResponse;
1057
1546
 
1547
+ /** Why a detected challenge response was returned to the caller instead of being solved and refetched. */
1548
+ export type StealthChallengeClassification = {
1549
+ readonly challenge: Extract<ProviderChallenge, { readonly kind: "akamai_sbsd" }>;
1550
+ /**
1551
+ * `resolver_unavailable`: detect-only provider or no solver configured.
1552
+ * `replay_required`: the request is not a plain GET, so it is never solved or replayed
1553
+ * automatically. `solve_failed`: a concurrent request on the same session owned the
1554
+ * solve and it rejected (that owner receives the error). `challenge_persisted`: the
1555
+ * single refetch after a solve was challenged again.
1556
+ */
1557
+ readonly outcome:
1558
+ | "resolver_unavailable"
1559
+ | "replay_required"
1560
+ | "solve_failed"
1561
+ | "challenge_persisted";
1562
+ };
1563
+
1058
1564
  export type RequestWithMethodOptions = RequestOptions & {
1059
1565
  method?: string;
1060
1566
  body?: unknown;
@@ -1069,7 +1575,7 @@ export interface StealthRedirectHop {
1069
1575
  }
1070
1576
 
1071
1577
  export interface StealthRedirectRunOptions
1072
- extends Omit<StealthFetchOptions, "redirect"> {
1578
+ extends Omit<StealthFetchOptions, "redirect" | "redirectPolicy"> {
1073
1579
  url: string;
1074
1580
  maxHops?: number;
1075
1581
  stopWhen?: (hop: StealthRedirectHop) => boolean | Promise<boolean>;
@@ -1078,12 +1584,24 @@ export interface StealthRedirectRunOptions
1078
1584
  export interface StealthRedirectRunResult {
1079
1585
  final: StealthResponse;
1080
1586
  hops: StealthRedirectHop[];
1081
- reason: "completed" | "stopped" | "max_hops" | "missing_location" | "loop";
1587
+ reason: RedirectRunReason;
1588
+ /**
1589
+ * Complete flat view across all redirect hosts. Attributes and duplicate names are lost.
1590
+ * @deprecated Use cookieStore for lossless persistence.
1591
+ */
1082
1592
  cookies: Record<string, string>;
1593
+ /** Versioned, attribute-preserving cookie state accumulated across the redirect chain. */
1594
+ cookieStore: StealthCookieStoreV1;
1083
1595
  }
1084
1596
 
1085
1597
  export interface StealthSession {
1086
1598
  fetch(url: string, options?: StealthFetchOptions): Promise<StealthResponse>;
1599
+ /**
1600
+ * Explicitly solve and replay one unsafe request previously classified as
1601
+ * `replay_required`. The original method, URL, headers, and body bytes are
1602
+ * retained by this session and may be replayed exactly once.
1603
+ */
1604
+ replayChallenged(response: StealthResponse): Promise<StealthResponse>;
1087
1605
  cookies: StealthSessionCookies;
1088
1606
  redirects: {
1089
1607
  run(options: StealthRedirectRunOptions): Promise<StealthRedirectRunResult>;
@@ -1169,11 +1687,191 @@ export interface HttpClient {
1169
1687
  ): Promise<AsyncIterable<SseMessage>>;
1170
1688
  }
1171
1689
 
1690
+ /** Request-scoped file reference accepted by provider operation inputs. */
1691
+ export interface ProviderFileRef {
1692
+ readonly type: "request_file";
1693
+ readonly id: string;
1694
+ readonly filename: string;
1695
+ readonly mime_type?: string;
1696
+ readonly size: number;
1697
+ readonly sha256?: string;
1698
+ }
1699
+
1700
+ /** File body resolved from a request-scoped {@link ProviderFileRef}. */
1701
+ export type ProviderResolvedFile = Omit<ProviderFileRef, "mime_type"> & {
1702
+ readonly mimeType?: string;
1703
+ arrayBuffer(): Promise<ArrayBuffer>;
1704
+ bytes(): Promise<Uint8Array>;
1705
+ stream(): ReadableStream<Uint8Array>;
1706
+ };
1707
+
1708
+ /** Resolver supplied by runtimes that accept request-scoped file inputs. */
1709
+ export interface ProviderFilesContext {
1710
+ has(input: string | ProviderFileRef): boolean;
1711
+ resolve(input: string | ProviderFileRef): Promise<ProviderResolvedFile>;
1712
+ }
1713
+
1714
+ /** Where provider business logic executes relative to the capability engine. */
1715
+ export type ProviderRuntimeTarget = "vanilla" | "engine";
1716
+
1717
+ export type NativeTcpTlsMode = "required" | "allowed" | "disabled";
1718
+
1719
+ export interface NativeTcpPortRange {
1720
+ readonly start: number;
1721
+ readonly end: number;
1722
+ }
1723
+
1724
+ /** Static native TCP egress declared by a provider. */
1725
+ export interface NativeTcpEgressRule {
1726
+ readonly host: string;
1727
+ readonly ports: readonly number[];
1728
+ readonly tls: NativeTcpTlsMode;
1729
+ }
1730
+
1731
+ /**
1732
+ * Bounded native TCP egress discovered through a declared bootstrap endpoint.
1733
+ * Host suffixes are exact DNS suffixes, not wildcard patterns.
1734
+ * Dynamic rules must declare at least one target host selector through
1735
+ * targetHostSuffixes, targetIpv4Cidrs, and/or targetIpv6Cidrs. Literal grant
1736
+ * sources and targets match only same-family selectors (except exact
1737
+ * sourceHost); DNS names match only host/suffix selectors. IPv4-mapped and
1738
+ * IPv4-compatible IPv6 literals are authorized only by IPv4 CIDRs.
1739
+ *
1740
+ * Dynamic rules are ordered. The first rule whose source, target, port, and TLS
1741
+ * selectors match exclusively owns the grant; its ttlMs and maxGrants bounds
1742
+ * apply, and an exhausted/shorter rule never falls through to a later overlap.
1743
+ * Every rule must declare a source host selector, source port list/range, and
1744
+ * target port list/range; omitted ttlMs/maxGrants remain unbounded.
1745
+ */
1746
+ export interface NativeTcpDynamicEgressRule {
1747
+ readonly sourceHost?: string;
1748
+ readonly sourceHostSuffixes?: readonly string[];
1749
+ readonly sourceIpv4Cidrs?: readonly string[];
1750
+ readonly sourceIpv6Cidrs?: readonly string[];
1751
+ readonly sourcePorts?: readonly number[];
1752
+ readonly sourcePortRanges?: readonly NativeTcpPortRange[];
1753
+ readonly targetHostSuffixes?: readonly string[];
1754
+ readonly targetIpv4Cidrs?: readonly string[];
1755
+ readonly targetIpv6Cidrs?: readonly string[];
1756
+ readonly targetPorts?: readonly number[];
1757
+ readonly targetPortRanges?: readonly NativeTcpPortRange[];
1758
+ readonly tls: NativeTcpTlsMode;
1759
+ readonly ttlMs?: number;
1760
+ readonly maxGrants?: number;
1761
+ }
1762
+
1763
+ /** Common TCP/TLS connection input supported by the native runtime. */
1764
+ export interface NativeNetworkConnectInput {
1765
+ readonly host: string;
1766
+ readonly port: number;
1767
+ readonly serverName?: string;
1768
+ readonly rejectUnauthorized?: boolean;
1769
+ /**
1770
+ * Maximum time without a successful socket read before the connection is
1771
+ * closed. Opt-in; when absent, reads can remain pending indefinitely.
1772
+ */
1773
+ readonly idleTimeoutMs?: number;
1774
+ /** Maximum time allowed to establish the TCP/SOCKS/TLS connection. */
1775
+ readonly timeoutMs?: number;
1776
+ readonly signal?: AbortSignal;
1777
+ /** Overrides the credential-derived sticky affinity key. */
1778
+ readonly affinityKey?: string;
1779
+ }
1780
+
1781
+ export type NativeNetworkConnectOptions = Omit<
1782
+ NativeNetworkConnectInput,
1783
+ "serverName" | "rejectUnauthorized"
1784
+ >;
1785
+
1786
+ export type NativeTlsConnectOptions = NativeNetworkConnectInput;
1787
+
1788
+ export interface NativeNetworkDynamicGrantOptions {
1789
+ readonly sourceHost: string;
1790
+ readonly sourcePort: number;
1791
+ readonly host: string;
1792
+ readonly port: number;
1793
+ readonly tls: NativeTcpTlsMode;
1794
+ readonly ttlMs?: number;
1795
+ }
1796
+
1797
+ export interface NativeNetworkEgressGrant {
1798
+ revoke(): void;
1799
+ }
1800
+
1801
+ /** Consumer-facing alias used by native TCP providers. */
1802
+ export type NativeTcpEgressGrant = NativeNetworkEgressGrant;
1803
+
1804
+ /** Resolved egress identity for a native connection routed through a proxy. */
1805
+ export interface NativeProxyEgressInfo {
1806
+ readonly vendor: ProviderProxyProvider;
1807
+ readonly sticky: boolean;
1808
+ /** Vendor sticky session id (sid). Absent for rotating sessions. */
1809
+ readonly sessionId?: string;
1810
+ /** Hard expiry of the sticky binding, ISO 8601. */
1811
+ readonly expiresAt?: string;
1812
+ }
1813
+
1814
+ export type NativeProxyExpiringReason = "sticky_expiry";
1815
+
1816
+ export interface NativeProxyExpiringEvent {
1817
+ readonly expiresAt: string;
1818
+ readonly leadSeconds: number;
1819
+ readonly reason: NativeProxyExpiringReason;
1820
+ }
1821
+
1822
+ /**
1823
+ * Cooperative drain handler. The SDK awaits this before closing a socket whose
1824
+ * sticky proxy binding is about to expire, then force-closes at hard expiry.
1825
+ */
1826
+ export type NativeProxyDrainHandler = (
1827
+ event: NativeProxyExpiringEvent,
1828
+ ) => void | Promise<void>;
1829
+
1830
+ /** Typed reason recorded when the SDK closes a native connection intentionally. */
1831
+ export interface NativeNetworkCloseReason {
1832
+ readonly code: string;
1833
+ readonly message: string;
1834
+ }
1835
+
1836
+ /** Byte-oriented connection returned by the native TCP/TLS runtime. */
1837
+ export interface NativeNetworkConnection {
1838
+ /** Present when the connection was routed through a proxy. */
1839
+ readonly proxy?: NativeProxyEgressInfo;
1840
+ /** Present after an SDK-planned close, such as sticky proxy expiry. */
1841
+ readonly closeReason?: NativeNetworkCloseReason;
1842
+ /** Register a cooperative drain handler for sticky-expiry reconnects. */
1843
+ onExpiring?(handler: NativeProxyDrainHandler): void;
1844
+ read(): Promise<Uint8Array | null>;
1845
+ write(data: Uint8Array): Promise<void>;
1846
+ close(): Promise<void>;
1847
+ }
1848
+
1849
+ export interface NativeNetworkClient {
1850
+ connectTcp(
1851
+ input: NativeNetworkConnectOptions,
1852
+ ): Promise<NativeNetworkConnection>;
1853
+ connectTls(input: NativeTlsConnectOptions): Promise<NativeNetworkConnection>;
1854
+ grantTcpEgress(
1855
+ input: NativeNetworkDynamicGrantOptions,
1856
+ ): NativeNetworkEgressGrant;
1857
+ }
1858
+
1859
+ export interface NativeContext {
1860
+ readonly network: NativeNetworkClient;
1861
+ }
1862
+
1863
+ export interface NativeProviderConfig {
1864
+ readonly network?: {
1865
+ readonly tcp?: readonly NativeTcpEgressRule[];
1866
+ readonly dynamicTcp?: readonly NativeTcpDynamicEgressRule[];
1867
+ };
1868
+ }
1869
+
1172
1870
  export interface ProviderCacheKeyOptions {
1173
1871
  /**
1174
- * Additional field names to omit from stable key material. The SDK always
1175
- * omits known secret-bearing names such as serviceKey, authorization,
1176
- * cookie, token, password, and secret.
1872
+ * Additional field names whose values are hashed in stable key material. The
1873
+ * SDK always hashes values under known secret-bearing names such as serviceKey,
1874
+ * authorization, cookie, token, password, and secret.
1177
1875
  */
1178
1876
  redactFields?: string[];
1179
1877
  }
@@ -1233,7 +1931,7 @@ export interface ProviderCache {
1233
1931
 
1234
1932
  export interface StealthClient {
1235
1933
  fetch(url: string, options?: StealthFetchOptions): Promise<StealthResponse>;
1236
- createSession(opts?: { profile?: string }): StealthSession;
1934
+ createSession(opts?: { stealth?: StealthProfileSelection }): StealthSession;
1237
1935
  close?(): void;
1238
1936
  }
1239
1937
 
@@ -1268,7 +1966,19 @@ export interface BrowserFrame {
1268
1966
  locator(selector: string): BrowserLocator;
1269
1967
  }
1270
1968
 
1271
- export type BrowserResourceMethod = "GET" | "HEAD";
1969
+ export interface BrowserCookie {
1970
+ readonly name: string;
1971
+ readonly value: string;
1972
+ readonly domain: string;
1973
+ readonly path: string;
1974
+ /** Unix seconds. Absent for a session cookie. */
1975
+ readonly expires?: number;
1976
+ readonly httpOnly: boolean;
1977
+ readonly secure: boolean;
1978
+ readonly sameSite?: "Strict" | "Lax" | "None";
1979
+ }
1980
+
1981
+ export type BrowserResourceMethod = "GET" | "HEAD" | "POST";
1272
1982
 
1273
1983
  export type BrowserResourceRequest = {
1274
1984
  readonly url: string;
@@ -1280,16 +1990,19 @@ export type BrowserResourceRequest = {
1280
1990
  export type BrowserResourceBody = Buffer | Uint8Array | ArrayBuffer | string;
1281
1991
 
1282
1992
  export type BrowserResourceDecision =
1993
+ | {
1994
+ readonly action: "continue";
1995
+ }
1283
1996
  | {
1284
1997
  readonly action: "fulfill";
1285
1998
  readonly status?: number;
1286
1999
  readonly headers?: Readonly<Record<string, string>>;
1287
2000
  readonly body?: BrowserResourceBody;
1288
- }
2001
+ }
1289
2002
  | {
1290
2003
  readonly action: "block";
1291
2004
  readonly reason?: string;
1292
- };
2005
+ };
1293
2006
 
1294
2007
  export type BrowserResourceRoute = {
1295
2008
  readonly match:
@@ -1304,13 +2017,30 @@ export type BrowserResourceRoute = {
1304
2017
  export type BrowserResourcePolicy = {
1305
2018
  readonly defaultAction?: "block";
1306
2019
  readonly allowedMethods?: readonly BrowserResourceMethod[];
2020
+ /**
2021
+ * Appends an enforcing CSP header to every renderable document response
2022
+ * while the policy is active. Existing CSP headers are retained, so this
2023
+ * can only further restrict the document.
2024
+ */
2025
+ readonly documentContentSecurityPolicy?: string;
1307
2026
  readonly routes: readonly BrowserResourceRoute[];
1308
2027
  };
1309
2028
 
1310
2029
  export interface BrowserPage extends BrowserFrame {
1311
2030
  close(): Promise<void>;
2031
+ /** Returns the user agent used by this page's browser context. */
2032
+ userAgent(): Promise<string>;
2033
+ /**
2034
+ * Reads the browser context's cookie jar, including httpOnly cookies.
2035
+ * Cookie expiry values are Unix seconds and are absent for session cookies.
2036
+ */
2037
+ cookies(): Promise<readonly BrowserCookie[]>;
1312
2038
  fill(selector: string, text: string): Promise<void>;
1313
2039
  goto(url: string): Promise<void>;
2040
+ goto(
2041
+ url: string,
2042
+ options?: { readonly timeout?: number; readonly waitUntil?: "load" | "domcontentloaded" },
2043
+ ): Promise<void>;
1314
2044
  pageId?: string;
1315
2045
  screenshot(options?: { fullPage?: boolean }): Promise<Buffer>;
1316
2046
  click(selector: string): Promise<void>;
@@ -1359,7 +2089,7 @@ export interface TraceConfig {
1359
2089
  exporter?: "console" | "json" | "otlp" | "none";
1360
2090
  endpoint?: string;
1361
2091
  otlp?: {
1362
- endpoint: string;
2092
+ endpoint?: string;
1363
2093
  headers?: Record<string, string>;
1364
2094
  timeout?: number;
1365
2095
  };
@@ -1390,110 +2120,19 @@ export interface CredentialContext {
1390
2120
 
1391
2121
  export interface ProviderRequestContext {
1392
2122
  connectionId?: string;
2123
+ /**
2124
+ * Gateway-asserted principal scope of the operation request: the
2125
+ * organization id for customer subjects, the service-account id for
2126
+ * platform service accounts. `undefined` on direct calls and self-test
2127
+ * (unlike `FlowContext.tenantId`, which is coerced to `""`); an empty
2128
+ * string on the wire is normalised to `undefined` like `connectionId`.
2129
+ * Key per-principal policy (quota, fairness, correlation) for
2130
+ * connectionless operations on it. It does not scope `ctx.state`.
2131
+ */
2132
+ tenantId?: string;
1393
2133
  headers: Record<string, string>;
1394
2134
  }
1395
2135
 
1396
- export interface ProviderChoiceBindingOptions {
1397
- connection?: boolean;
1398
- credentialKeys?: readonly string[];
1399
- }
1400
-
1401
- export type ProviderChoiceStorageOptions =
1402
- | {
1403
- readonly mode: "inline";
1404
- }
1405
- | {
1406
- readonly mode: "server";
1407
- readonly namespace: string;
1408
- readonly state?: ProviderRuntimeState;
1409
- readonly ttl?: ProviderStateDurationString;
1410
- readonly maxEntries: number;
1411
- readonly maxValueBytes: number;
1412
- readonly unavailable?: "reject";
1413
- }
1414
- | {
1415
- readonly mode: "auto";
1416
- readonly namespace: string;
1417
- readonly state?: ProviderRuntimeState;
1418
- readonly ttl?: ProviderStateDurationString;
1419
- readonly maxInlineBytes: number;
1420
- readonly maxEntries: number;
1421
- readonly maxValueBytes: number;
1422
- readonly unavailable?: "reject";
1423
- };
1424
-
1425
- export interface ProviderChoiceIssueOptions<
1426
- TPayload extends Record<string, unknown>,
1427
- > {
1428
- prefix: string;
1429
- purpose: string;
1430
- payload: TPayload;
1431
- ttlMs: number;
1432
- nowMs?: number;
1433
- bind?: ProviderChoiceBindingOptions;
1434
- storage?: ProviderChoiceStorageOptions;
1435
- }
1436
-
1437
- export interface ProviderChoiceParseOptions {
1438
- token: string;
1439
- prefix: string;
1440
- purpose: string;
1441
- ttlMs?: number;
1442
- nowMs?: number;
1443
- futureToleranceMs?: number;
1444
- bind?: ProviderChoiceBindingOptions;
1445
- storage?: ProviderChoiceStorageOptions;
1446
- }
1447
-
1448
- export interface ProviderChoiceContext {
1449
- issue<TPayload extends Record<string, unknown>>(
1450
- options: ProviderChoiceIssueOptions<TPayload> & {
1451
- readonly storage?: { readonly mode: "inline" };
1452
- },
1453
- ): string;
1454
- issue<TPayload extends Record<string, unknown>>(
1455
- options: ProviderChoiceIssueOptions<TPayload> & {
1456
- readonly storage: Extract<
1457
- ProviderChoiceStorageOptions,
1458
- { readonly mode: "server" }
1459
- >;
1460
- },
1461
- ): Promise<string>;
1462
- issue<TPayload extends Record<string, unknown>>(
1463
- options: ProviderChoiceIssueOptions<TPayload> & {
1464
- readonly storage: Extract<
1465
- ProviderChoiceStorageOptions,
1466
- { readonly mode: "auto" }
1467
- >;
1468
- },
1469
- ): string | Promise<string>;
1470
- issue<TPayload extends Record<string, unknown>>(
1471
- options: ProviderChoiceIssueOptions<TPayload>,
1472
- ): string | Promise<string>;
1473
- parse(
1474
- options: ProviderChoiceParseOptions & {
1475
- readonly storage?: { readonly mode: "inline" };
1476
- },
1477
- ): Record<string, unknown>;
1478
- parse(
1479
- options: ProviderChoiceParseOptions & {
1480
- readonly storage: Extract<
1481
- ProviderChoiceStorageOptions,
1482
- { readonly mode: "server" }
1483
- >;
1484
- },
1485
- ): Promise<Record<string, unknown>>;
1486
- parse(
1487
- options: ProviderChoiceParseOptions & {
1488
- readonly storage: Extract<
1489
- ProviderChoiceStorageOptions,
1490
- { readonly mode: "auto" }
1491
- >;
1492
- },
1493
- ): Record<string, unknown> | Promise<Record<string, unknown>>;
1494
- parse(options: ProviderChoiceParseOptions): Record<string, unknown>;
1495
- }
1496
-
1497
2136
  export interface ContextScratchpad {
1498
2137
  get(key: string): unknown;
1499
2138
  set(key: string, value: unknown): void;
@@ -1564,11 +2203,11 @@ export interface AuthFlowTerminalContext {
1564
2203
  }
1565
2204
  >;
1566
2205
  readonly expectedInput?: never;
1567
- }
2206
+ }
1568
2207
  | {
1569
2208
  readonly expectedInput: Record<string, unknown>;
1570
2209
  readonly fields?: never;
1571
- }
2210
+ }
1572
2211
  ),
1573
2212
  ): AuthTurn;
1574
2213
  nextPoll(options?: {
@@ -1581,16 +2220,35 @@ export interface AuthFlowTerminalContext {
1581
2220
  }
1582
2221
 
1583
2222
  export interface FlowContext {
2223
+ /** Gateway auth-flow id. Required by flow-scoped auth ceremonies. */
2224
+ flowId?: string;
1584
2225
  connectionId?: string;
1585
2226
  externalRef?: string;
1586
2227
  tenantId: string;
1587
2228
  providerId: string;
2229
+ trace: TraceContext;
1588
2230
  http: HttpClient;
2231
+ /** Durable connection-scoped runtime state. Present when the host runtime
2232
+ * supplies one; auth ceremonies must fail closed when absent rather than
2233
+ * fall back to bypassable in-process storage.
2234
+ *
2235
+ * Scoped via `ProviderRuntimeState.forConnection`: requests that resolve no
2236
+ * connection id (pre-connection ceremonies such as first-time logins) share
2237
+ * the documented isolated missing-connection scope. That sharing is the
2238
+ * intended semantic — it lets counters keyed by caller identity (e.g. a
2239
+ * login email) persist across separate ceremonies for the same caller.
2240
+ * Flows storing entries in that scope MUST key them by caller identity;
2241
+ * un-keyed entries would be shared across all connectionless ceremonies. */
2242
+ readonly state?: ProviderRuntimeState;
2243
+ /** Present when the selected runtime supplies native network capabilities. */
2244
+ readonly native?: NativeContext;
1589
2245
  stealth: StealthClient;
1590
2246
  env: EnvContext;
1591
2247
  credential?: CredentialContext;
1592
2248
  context: ContextScratchpad;
2249
+ ocr: OcrContext;
1593
2250
  stt: SttContext;
2251
+ resolver: ResolverContext;
1594
2252
  auth: AuthFlowTerminalContext;
1595
2253
  }
1596
2254
 
@@ -1633,7 +2291,14 @@ export type ProviderStateDurationString =
1633
2291
  | `${number}${"ms" | "s" | "m" | "h" | "d"}`
1634
2292
  | `PT${string}`;
1635
2293
 
2294
+ export type StateNamespaceScope = "connection" | "provider";
2295
+
1636
2296
  export interface StateNamespaceOptions {
2297
+ /**
2298
+ * State isolation boundary. Connection scope is the default; provider scope
2299
+ * must be selected explicitly for provider-wide coordination state.
2300
+ */
2301
+ scope?: StateNamespaceScope;
1637
2302
  /** Default TTL used when a write omits ttl. Required to avoid unbounded state. */
1638
2303
  defaultTtl: ProviderStateDurationString;
1639
2304
  /** Maximum allowed TTL; writes are rejected when they exceed this policy. */
@@ -1694,36 +2359,88 @@ export interface ProviderStateNamespace {
1694
2359
  }
1695
2360
 
1696
2361
  export interface ProviderRuntimeState {
2362
+ /**
2363
+ * Returns an immutable view bound to one request connection. An unresolved
2364
+ * connection uses an isolated reserved sentinel, never the provider-global scope.
2365
+ */
2366
+ forConnection(connectionId: string | undefined): ProviderRuntimeState;
1697
2367
  namespace(
1698
2368
  name: string,
1699
2369
  options: StateNamespaceOptions,
1700
2370
  ): ProviderStateNamespace;
1701
2371
  }
1702
2372
 
1703
- export interface ProviderContext {
1704
- env: EnvContext;
1705
- credential: CredentialContext;
2373
+ /**
2374
+ * The operation context exposed for one provider declaration. Capability
2375
+ * bindings are present only when their corresponding declaration is present;
2376
+ * platform-managed auth itself declares the credential binding. Trace and
2377
+ * request remain ambient runtime bindings. Omitting the type parameter
2378
+ * preserves the legacy full context shape for existing annotations.
2379
+ */
2380
+ export type ProviderContext<TConfig = Record<string, unknown>> = {
1706
2381
  request?: ProviderRequestContext;
1707
- http: HttpClient;
1708
- cache: ProviderCache;
1709
- state: ProviderRuntimeState;
1710
- stealth: StealthClient;
1711
- browser: BrowserClient;
1712
2382
  trace: TraceContext;
1713
- auth: AuthContext;
1714
- stt: SttContext;
1715
- choice: ProviderChoiceContext;
2383
+ }
2384
+ & ("env" extends keyof TConfig ? { env: EnvContext } : Record<never, never>)
2385
+ & ("credential" extends keyof TConfig
2386
+ ? { credential: CredentialContext }
2387
+ : TConfig extends { auth: { mode: "platform-managed" } }
2388
+ ? { credential: CredentialContext }
2389
+ : Record<never, never>)
2390
+ & ("http" extends keyof TConfig ? { http: HttpClient } : Record<never, never>)
2391
+ & ("files" extends keyof TConfig
2392
+ ? string extends keyof TConfig
2393
+ ? { readonly files?: ProviderFilesContext }
2394
+ : { readonly files: ProviderFilesContext }
2395
+ : Record<never, never>)
2396
+ & ("native" extends keyof TConfig
2397
+ ? { readonly native: NativeContext }
2398
+ : Record<never, never>)
2399
+ & ("cache" extends keyof TConfig ? { cache: ProviderCache } : Record<never, never>)
2400
+ & ("state" extends keyof TConfig ? { state: ProviderRuntimeState } : Record<never, never>)
2401
+ & ("stealth" extends keyof TConfig ? { stealth: StealthClient } : Record<never, never>)
2402
+ & ("browser" extends keyof TConfig ? { browser: BrowserClient } : Record<never, never>)
2403
+ & ("auth" extends keyof TConfig ? { auth: AuthContext } : Record<never, never>)
2404
+ & ("ocr" extends keyof TConfig ? { ocr: OcrContext } : Record<never, never>)
2405
+ & ("stt" extends keyof TConfig ? { stt: SttContext } : Record<never, never>)
2406
+ & ("resolver" extends keyof TConfig ? { resolver: ResolverContext } : Record<never, never>)
2407
+ & ("handle" extends keyof TConfig
2408
+ ? { handle: HandleContext }
2409
+ : Record<never, never>);
2410
+
2411
+ /** Backwards-compatible name for a declaration-derived provider context. */
2412
+ export type ProviderContextFor<TConfig> = ProviderContext<TConfig>;
2413
+
2414
+ export interface ProxiedOAuthConfig {
2415
+ authorizeUrl: string;
2416
+ tokenUrl: string;
2417
+ customScheme: string;
2418
+ rewriteProfile: string;
2419
+ clientIdEnvKey: string;
2420
+ pkce?: "S256" | "none";
2421
+ authorizeParams?: Record<string, string>;
2422
+ tokenParams?: Record<string, string>;
1716
2423
  }
1717
2424
 
1718
2425
  export interface AuthConfig {
1719
2426
  mode: AuthMode;
2427
+ /** Browser reverse-proxy contract for providers with custom-scheme OAuth callbacks. */
2428
+ proxied?: ProxiedOAuthConfig;
1720
2429
  flow?: AuthFlowDefinition;
1721
2430
  }
1722
2431
 
2432
+ /** Who provisions a declared secret: the platform (`apifuse`) or the provider author (`contributor`). */
2433
+ export type ProviderSecretIssuer = "apifuse" | "contributor";
2434
+
1723
2435
  export interface ProviderSecretDeclaration {
1724
2436
  name: string;
1725
2437
  description?: string;
1726
2438
  required?: boolean;
2439
+ /**
2440
+ * Optional today; ADR-0011 D3 makes it required once every deployed provider
2441
+ * declares it. Metadata only: it does not change which secrets are projected.
2442
+ */
2443
+ issuer?: ProviderSecretIssuer;
1727
2444
  }
1728
2445
 
1729
2446
  export interface CredentialDeclaration {
@@ -1758,38 +2475,35 @@ export interface OperationContractMetadata {
1758
2475
  export interface OperationDefinition<
1759
2476
  TInput extends SchemaLike = SchemaLike,
1760
2477
  TOutput extends SchemaLike = SchemaLike,
2478
+ TContext = ProviderContext,
1761
2479
  > {
1762
- /**
1763
- * Short English display title for the operation. The SDK passes it through
1764
- * verbatim; the APIFuse registry derives the operation's en locale title
1765
- * baseline from it (`docs.titleKey` remains available as an explicit key
1766
- * override).
1767
- */
1768
- title?: string;
1769
- /**
1770
- * Raw English operation description. The SDK passes it through verbatim;
1771
- * keyed descriptions via `descriptionKey` remain the primary flow, and
1772
- * provider lint rules for raw prose descriptions still apply.
1773
- */
1774
- description?: string;
2480
+ /** Canonical operation-level connection requirement. */
2481
+ connectionMode?: "none" | "optional" | "required";
2482
+ /** Public argument used to resolve the tenant-owned connection. Defaults to externalRef. */
2483
+ connectionExternalRefParam?: string;
2484
+ /** Safety source of truth exposed to clients and approval policy. */
2485
+ riskClass: OperationRiskClass;
2486
+ /** Approval override. Omit when the risk-class default is correct. */
2487
+ approval?: OperationApprovalPolicy;
2488
+ timeoutMs?: number;
2489
+ titleKey?: ProviderLocaleKeyInput;
1775
2490
  descriptionKey?: ProviderLocaleKeyInput;
1776
- docs?: OperationDocMeta;
2491
+ summaryKey?: ProviderLocaleKeyInput;
2492
+ markdownKey?: ProviderLocaleKeyInput;
1777
2493
  whenToUseKeys?: readonly ProviderLocaleKeyInput[];
1778
2494
  whenNotToUseKeys?: readonly ProviderLocaleKeyInput[];
1779
- derivations?: Record<string, string>;
1780
- inputExamples?: readonly OperationInputExample[];
1781
- annotations?: OperationAnnotations;
2495
+ normalizationNotesKeys?: readonly ProviderLocaleKeyInput[];
2496
+ errorCodes?: readonly OperationErrorCode[];
2497
+ examples?: readonly OperationExample[];
1782
2498
  contract?: OperationContractMetadata;
1783
2499
  tags?: readonly string[];
1784
2500
  relatedOperations?: OperationRelationships;
1785
- toolRouter?: OperationToolRouterMetadata;
1786
2501
  observability?: OperationObservabilityConfig;
1787
2502
  transport?: OperationTransport;
1788
- retryOnAuthRefresh?: boolean;
1789
2503
  input: TInput;
1790
2504
  output: TOutput;
1791
2505
  handler(
1792
- ctx: ProviderContext,
2506
+ ctx: TContext,
1793
2507
  input: InferSchemaOutput<TInput>,
1794
2508
  ):
1795
2509
  | OperationHandlerResult<InferSchemaOutput<TOutput>>
@@ -1797,6 +2511,11 @@ export interface OperationDefinition<
1797
2511
  fixtures?: {
1798
2512
  request: InferSchemaOutput<TInput>;
1799
2513
  response: InferSchemaOutput<TOutput>;
2514
+ /**
2515
+ * KST calendar date when `response` evidence was captured. Date fields in
2516
+ * the response align with this date, not a resolved relative request date.
2517
+ */
2518
+ recordedAt?: string;
1800
2519
  };
1801
2520
  upstream?: {
1802
2521
  baseUrl?: string;
@@ -1822,6 +2541,14 @@ export interface OperationDefinition<
1822
2541
  * optional. Note that the deployment `runtime` axis
1823
2542
  * (`shared`/`dedicated`/`browser`) is distinct from the provider execution
1824
2543
  * `runtime` (`standard`/`shared`/`browser`).
2544
+ *
2545
+ * This key is the ONLY authored deployment surface. Declare it inside the
2546
+ * `defineProvider({...})` literal, not on a spread default export and not
2547
+ * in a standalone `deploy.ts` (legacy; `apifuse migrate-deployment` hoists
2548
+ * and deletes it). Write only what differs from the runtime profile —
2549
+ * shared `25m/128Mi`, browser `200m/256Mi`, `language: "typescript"`,
2550
+ * `replicas: 1`, HPA enabled 1-1 at 70% CPU — so most providers declare
2551
+ * nothing and `apifuse check` warns on restated defaults.
1825
2552
  */
1826
2553
  export interface ProviderDeploymentOverrides {
1827
2554
  runtime?: "shared" | "dedicated" | "browser";
@@ -1849,34 +2576,48 @@ export interface ProviderDeploymentOverrides {
1849
2576
  buildContext?: string;
1850
2577
  }
1851
2578
 
1852
- export interface ProviderDefinition {
2579
+ export interface ProviderDefinition<TContext = ProviderContext> {
1853
2580
  id: string;
1854
2581
  version: string;
1855
2582
  runtime: "standard" | "shared" | "browser";
2583
+ /**
2584
+ * `vanilla` executes provider business logic outside the engine; `engine`
2585
+ * keeps session-bearing provider logic in the engine process.
2586
+ *
2587
+ * Omitted only for definitions authored before the engine migration. New
2588
+ * providers should declare the target explicitly.
2589
+ */
2590
+ runtimeTarget?: ProviderRuntimeTarget;
1856
2591
  /**
1857
2592
  * Optional deployment overrides, passed through verbatim from
1858
2593
  * `defineProvider({ deployment })`. Validation and profile resolution are
1859
2594
  * owned by the APIFuse registry builder, not the SDK.
1860
2595
  */
1861
2596
  deployment?: ProviderDeploymentOverrides;
2597
+ http?: Record<string, never> | true;
1862
2598
  allowedHosts?: string[];
1863
- stealth?: {
1864
- profile: string;
1865
- platform: StealthPlatform;
1866
- };
2599
+ native?: NativeProviderConfig;
2600
+ stealth?: ProviderStealthConfig;
1867
2601
  proxy?: ProviderProxyConfig;
2602
+ ocr?: ProviderOcrConfig;
1868
2603
  stt?: ProviderSttConfig;
2604
+ resolver?: ProviderResolverConfig;
1869
2605
  browser?: {
1870
2606
  engine: BrowserEngine;
1871
2607
  };
1872
2608
  auth?: AuthConfig;
2609
+ handle?: readonly HandleKind[];
1873
2610
  reviewed?: ProviderReviewed;
1874
2611
  access?: ProviderAccessConfig;
1875
2612
  secrets?: ProviderSecretDeclaration[];
2613
+ env?: Record<string, never> | true;
1876
2614
  credential?: CredentialDeclaration;
1877
2615
  context?: ContextDeclaration;
2616
+ state?: Record<string, never> | true;
2617
+ cache?: Record<string, never> | true;
2618
+ files?: Record<string, never> | true;
1878
2619
  meta: ProviderMeta;
1879
- operations: Record<string, OperationDefinition<SchemaLike, SchemaLike>>;
2620
+ operations: Record<string, OperationDefinition<SchemaLike, SchemaLike, TContext>>;
1880
2621
  healthMonitor?: ProviderHealthMonitorConfig;
1881
2622
  /** Transitional alias for `healthMonitor`; `defineProvider` mirrors both. */
1882
2623
  healthProbe?: ProviderHealthProbeConfig;