@apifuse/provider-sdk 2.2.0-beta.3 → 2.2.0-beta.31

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 (342) hide show
  1. package/AUTHORING.md +493 -5
  2. package/CHANGELOG.md +131 -1
  3. package/README.md +52 -6
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +106 -62
  6. package/bin/apifuse-create.ts +1 -1
  7. package/bin/apifuse-dev.ts +63 -55
  8. package/bin/apifuse-pack-check.ts +22 -2
  9. package/bin/apifuse-pack-smoke.ts +78 -82
  10. package/bin/apifuse-pack-types.ts +583 -0
  11. package/bin/apifuse-perf.ts +59 -140
  12. package/bin/apifuse-record.ts +698 -113
  13. package/bin/apifuse-submit-check.ts +517 -44
  14. package/bin/apifuse-sync-assets.ts +117 -0
  15. package/bin/apifuse.ts +1 -1
  16. package/bin/submit-check-delimited-text.ts +50 -0
  17. package/bin/submit-check-xml.ts +1 -1
  18. package/dist/auth-turn/index.d.ts +4 -4
  19. package/dist/auth-turn/index.js +1 -1
  20. package/dist/auth.d.ts +16 -2
  21. package/dist/auth.js +76 -18
  22. package/dist/ceremonies/index.d.ts +9 -1
  23. package/dist/ceremonies/index.js +117 -29
  24. package/dist/cli/commands.d.ts +1 -1
  25. package/dist/cli/commands.js +8 -0
  26. package/dist/cli/create.d.ts +3 -0
  27. package/dist/cli/create.js +34 -35
  28. package/dist/cli/prompt-assets.d.ts +80 -0
  29. package/dist/cli/prompt-assets.js +743 -0
  30. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  31. package/dist/cli/templates/provider/README.md.tpl +4 -4
  32. package/dist/config/loader.d.ts +176 -17
  33. package/dist/config/loader.js +434 -161
  34. package/dist/contract-serialization.d.ts +2 -2
  35. package/dist/contract-serialization.js +7 -14
  36. package/dist/contract-types.d.ts +3 -2
  37. package/dist/contract.d.ts +3 -3
  38. package/dist/contract.js +6 -6
  39. package/dist/declaration-validation.d.ts +23 -0
  40. package/dist/declaration-validation.js +159 -0
  41. package/dist/define.d.ts +13 -1
  42. package/dist/define.js +391 -122
  43. package/dist/dev.d.ts +1 -1
  44. package/dist/dev.js +1 -1
  45. package/dist/error-resolution.d.ts +4 -0
  46. package/dist/error-resolution.js +123 -0
  47. package/dist/errors.d.ts +19 -1
  48. package/dist/errors.js +41 -3
  49. package/dist/fixture-sanitization.d.ts +26 -0
  50. package/dist/fixture-sanitization.js +216 -0
  51. package/dist/i18n/catalog.d.ts +2 -2
  52. package/dist/i18n/catalog.js +4 -10
  53. package/dist/i18n/index.d.ts +2 -2
  54. package/dist/i18n/index.js +2 -2
  55. package/dist/i18n/keys.d.ts +2 -2
  56. package/dist/index.d.ts +50 -42
  57. package/dist/index.js +41 -37
  58. package/dist/lint.d.ts +6 -1
  59. package/dist/lint.js +370 -18
  60. package/dist/native-address.d.ts +43 -0
  61. package/dist/native-address.js +281 -0
  62. package/dist/native-egress-policy.d.ts +31 -0
  63. package/dist/native-egress-policy.js +288 -0
  64. package/dist/observability.d.ts +5 -2
  65. package/dist/observability.js +48 -1
  66. package/dist/provider.d.ts +13 -11
  67. package/dist/provider.js +10 -9
  68. package/dist/public-schema-field-lint.d.ts +1 -1
  69. package/dist/recipes/gov-api.js +1 -1
  70. package/dist/runtime/auth-flow.d.ts +3 -1
  71. package/dist/runtime/auth-flow.js +8 -3
  72. package/dist/runtime/browser.d.ts +1 -1
  73. package/dist/runtime/browser.js +138 -40
  74. package/dist/runtime/cache.d.ts +2 -1
  75. package/dist/runtime/cache.js +173 -23
  76. package/dist/runtime/choice-wordlist.d.ts +9 -0
  77. package/dist/runtime/choice-wordlist.js +138 -0
  78. package/dist/runtime/choice.d.ts +14 -1
  79. package/dist/runtime/choice.js +566 -101
  80. package/dist/runtime/credential.d.ts +1 -1
  81. package/dist/runtime/credential.js +1 -1
  82. package/dist/runtime/env.d.ts +1 -1
  83. package/dist/runtime/executor.d.ts +1 -1
  84. package/dist/runtime/executor.js +25 -3
  85. package/dist/runtime/http.d.ts +3 -2
  86. package/dist/runtime/http.js +517 -55
  87. package/dist/runtime/insights.d.ts +1 -1
  88. package/dist/runtime/insights.js +6 -13
  89. package/dist/runtime/instrumentation.d.ts +2 -2
  90. package/dist/runtime/instrumentation.js +371 -23
  91. package/dist/runtime/keyring.js +1 -1
  92. package/dist/runtime/namespace.js +1 -1
  93. package/dist/runtime/native-network-errors.d.ts +33 -0
  94. package/dist/runtime/native-network-errors.js +69 -0
  95. package/dist/runtime/native-network.d.ts +96 -0
  96. package/dist/runtime/native-network.js +1232 -0
  97. package/dist/runtime/ocr.d.ts +29 -0
  98. package/dist/runtime/ocr.js +440 -0
  99. package/dist/runtime/otlp.d.ts +1 -1
  100. package/dist/runtime/perf.d.ts +1 -1
  101. package/dist/runtime/provider.d.ts +1 -1
  102. package/dist/runtime/provider.js +1 -2
  103. package/dist/runtime/proxy-errors.d.ts +1 -1
  104. package/dist/runtime/proxy-errors.js +9 -7
  105. package/dist/runtime/proxy-nodemaven.d.ts +56 -0
  106. package/dist/runtime/proxy-nodemaven.js +146 -0
  107. package/dist/runtime/proxy-retry-policy.d.ts +2 -2
  108. package/dist/runtime/proxy-retry-policy.js +2 -2
  109. package/dist/runtime/proxy-telemetry.d.ts +2 -1
  110. package/dist/runtime/proxy-telemetry.js +58 -52
  111. package/dist/runtime/redirects.d.ts +29 -0
  112. package/dist/runtime/redirects.js +36 -0
  113. package/dist/runtime/redis.d.ts +1 -1
  114. package/dist/runtime/redis.js +5 -5
  115. package/dist/runtime/request-options.d.ts +68 -1
  116. package/dist/runtime/request-options.js +548 -0
  117. package/dist/runtime/resolver-config.d.ts +6 -0
  118. package/dist/runtime/resolver-config.js +6 -0
  119. package/dist/runtime/resolver-public.d.ts +1 -0
  120. package/dist/runtime/resolver-public.js +1 -0
  121. package/dist/runtime/resolver-shared.d.ts +3 -0
  122. package/dist/runtime/resolver-shared.js +12 -0
  123. package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
  124. package/dist/runtime/resolver-vendors/bindings.js +40 -0
  125. package/dist/runtime/resolver-vendors/browser.d.ts +20 -0
  126. package/dist/runtime/resolver-vendors/browser.js +282 -0
  127. package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
  128. package/dist/runtime/resolver-vendors/hosts.js +33 -0
  129. package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
  130. package/dist/runtime/resolver-vendors/twocaptcha.js +368 -0
  131. package/dist/runtime/resolver-vendors/types.d.ts +83 -0
  132. package/dist/runtime/resolver-vendors/types.js +69 -0
  133. package/dist/runtime/resolver.d.ts +59 -0
  134. package/dist/runtime/resolver.js +705 -0
  135. package/dist/runtime/secrets.d.ts +27 -0
  136. package/dist/runtime/secrets.js +51 -0
  137. package/dist/runtime/state.d.ts +5 -2
  138. package/dist/runtime/state.js +280 -74
  139. package/dist/runtime/stealth-cookies.d.ts +20 -0
  140. package/dist/runtime/stealth-cookies.js +111 -0
  141. package/dist/runtime/stealth.d.ts +30 -5
  142. package/dist/runtime/stealth.js +523 -259
  143. package/dist/runtime/stt.d.ts +1 -1
  144. package/dist/runtime/stt.js +12 -27
  145. package/dist/runtime/timeout.d.ts +5 -0
  146. package/dist/runtime/timeout.js +12 -0
  147. package/dist/runtime/trace.d.ts +2 -2
  148. package/dist/runtime/trace.js +2 -4
  149. package/dist/runtime/waterfall.d.ts +1 -1
  150. package/dist/schema.d.ts +1 -1
  151. package/dist/schema.js +7 -15
  152. package/dist/serve.d.ts +1 -1
  153. package/dist/serve.js +1 -1
  154. package/dist/server/index.d.ts +7 -7
  155. package/dist/server/index.js +6 -6
  156. package/dist/server/self-test-input-tokens.d.ts +2 -1
  157. package/dist/server/self-test-input-tokens.js +18 -14
  158. package/dist/server/self-test-redaction.d.ts +1 -1
  159. package/dist/server/self-test-redaction.js +1 -1
  160. package/dist/server/self-test.d.ts +117 -3
  161. package/dist/server/self-test.js +787 -151
  162. package/dist/server/serve-implementation.d.ts +210 -0
  163. package/dist/server/serve-implementation.js +2078 -0
  164. package/dist/server/serve.d.ts +1 -70
  165. package/dist/server/serve.js +1 -1143
  166. package/dist/server/types.d.ts +34 -9
  167. package/dist/server/types.js +8 -1
  168. package/dist/stateful/errors.d.ts +19 -0
  169. package/dist/stateful/errors.js +24 -0
  170. package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
  171. package/dist/stateful/http-provider-event-emitter.js +237 -0
  172. package/dist/stateful/http-session-owner-registry.d.ts +44 -0
  173. package/dist/stateful/http-session-owner-registry.js +210 -0
  174. package/dist/stateful/index.d.ts +18 -0
  175. package/dist/stateful/index.js +18 -0
  176. package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
  177. package/dist/stateful/provider-event-delivery-failures.js +43 -0
  178. package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
  179. package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
  180. package/dist/stateful/provider-event-pipeline.d.ts +50 -0
  181. package/dist/stateful/provider-event-pipeline.js +1 -0
  182. package/dist/stateful/provider-events.d.ts +101 -0
  183. package/dist/stateful/provider-events.js +289 -0
  184. package/dist/stateful/session-key.d.ts +15 -0
  185. package/dist/stateful/session-key.js +86 -0
  186. package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
  187. package/dist/stateful/stateful-provider-adapter-context.js +42 -0
  188. package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
  189. package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
  190. package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
  191. package/dist/stateful/stateful-provider-adapter.js +287 -0
  192. package/dist/stateful/stateful-provider-observability.d.ts +62 -0
  193. package/dist/stateful/stateful-provider-observability.js +161 -0
  194. package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
  195. package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
  196. package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
  197. package/dist/stateful/stateful-provider-runtime-context.js +60 -0
  198. package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
  199. package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
  200. package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
  201. package/dist/stateful/stateful-provider-session-routing.js +345 -0
  202. package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
  203. package/dist/stateful/stateful-provider-session-runtime.js +245 -0
  204. package/dist/stateful-signing.d.ts +18 -0
  205. package/dist/stateful-signing.js +27 -0
  206. package/dist/stealth/profiles.d.ts +1 -1
  207. package/dist/stealth/profiles.js +21 -21
  208. package/dist/stream-evidence.d.ts +74 -0
  209. package/dist/stream-evidence.js +785 -0
  210. package/dist/stream.d.ts +1 -1
  211. package/dist/stream.js +7 -1
  212. package/dist/testing/index.d.ts +3 -2
  213. package/dist/testing/index.js +3 -2
  214. package/dist/testing/run.d.ts +32 -2
  215. package/dist/testing/run.js +488 -28
  216. package/dist/types.d.ts +566 -19
  217. package/dist/types.js +1 -0
  218. package/dist/user-input.d.ts +30 -0
  219. package/dist/user-input.js +66 -0
  220. package/package.json +42 -7
  221. package/src/auth-turn/index.ts +2 -2
  222. package/src/auth.ts +146 -86
  223. package/src/ceremonies/index.ts +167 -92
  224. package/src/cli/commands.ts +10 -0
  225. package/src/cli/create.ts +42 -35
  226. package/src/cli/prompt-assets.ts +865 -0
  227. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  228. package/src/cli/templates/provider/README.md.tpl +4 -4
  229. package/src/config/loader.ts +667 -289
  230. package/src/contract-serialization.ts +10 -18
  231. package/src/contract-types.ts +3 -2
  232. package/src/contract.ts +14 -28
  233. package/src/declaration-validation.ts +202 -0
  234. package/src/define.ts +631 -495
  235. package/src/dev.ts +4 -9
  236. package/src/error-resolution.ts +128 -0
  237. package/src/errors.ts +56 -11
  238. package/src/fixture-sanitization.ts +247 -0
  239. package/src/i18n/catalog.ts +10 -32
  240. package/src/i18n/index.ts +2 -2
  241. package/src/i18n/keys.ts +5 -11
  242. package/src/index.ts +158 -44
  243. package/src/lint.ts +488 -154
  244. package/src/native-address.ts +340 -0
  245. package/src/native-egress-policy.ts +358 -0
  246. package/src/observability.ts +51 -1
  247. package/src/provider.ts +66 -11
  248. package/src/public-schema-field-lint.ts +7 -33
  249. package/src/recipes/gov-api.ts +2 -5
  250. package/src/runtime/auth-flow.ts +13 -7
  251. package/src/runtime/browser.ts +252 -207
  252. package/src/runtime/cache.ts +209 -81
  253. package/src/runtime/choice-wordlist.ts +145 -0
  254. package/src/runtime/choice.ts +758 -197
  255. package/src/runtime/credential.ts +2 -2
  256. package/src/runtime/env.ts +1 -1
  257. package/src/runtime/executor.ts +37 -19
  258. package/src/runtime/http.ts +645 -65
  259. package/src/runtime/insights.ts +15 -53
  260. package/src/runtime/instrumentation.ts +530 -67
  261. package/src/runtime/keyring.ts +7 -19
  262. package/src/runtime/namespace.ts +2 -7
  263. package/src/runtime/native-network-errors.ts +99 -0
  264. package/src/runtime/native-network.ts +1605 -0
  265. package/src/runtime/ocr.ts +523 -0
  266. package/src/runtime/otlp.ts +12 -23
  267. package/src/runtime/perf.ts +1 -1
  268. package/src/runtime/provider.ts +4 -9
  269. package/src/runtime/proxy-errors.ts +29 -42
  270. package/src/runtime/proxy-nodemaven.ts +221 -0
  271. package/src/runtime/proxy-retry-policy.ts +3 -3
  272. package/src/runtime/proxy-telemetry.ts +84 -77
  273. package/src/runtime/redirects.ts +66 -0
  274. package/src/runtime/redis.ts +10 -13
  275. package/src/runtime/request-options.ts +679 -9
  276. package/src/runtime/resolver-config.ts +6 -0
  277. package/src/runtime/resolver-public.ts +18 -0
  278. package/src/runtime/resolver-shared.ts +17 -0
  279. package/src/runtime/resolver-vendors/bindings.ts +56 -0
  280. package/src/runtime/resolver-vendors/browser.ts +408 -0
  281. package/src/runtime/resolver-vendors/hosts.ts +38 -0
  282. package/src/runtime/resolver-vendors/twocaptcha.ts +500 -0
  283. package/src/runtime/resolver-vendors/types.ts +173 -0
  284. package/src/runtime/resolver.ts +1060 -0
  285. package/src/runtime/secrets.ts +64 -0
  286. package/src/runtime/state.ts +399 -161
  287. package/src/runtime/stealth-cookies.ts +132 -0
  288. package/src/runtime/stealth.ts +681 -295
  289. package/src/runtime/stt.ts +39 -113
  290. package/src/runtime/timeout.ts +18 -0
  291. package/src/runtime/trace.ts +14 -44
  292. package/src/runtime/waterfall.ts +5 -18
  293. package/src/schema.ts +23 -84
  294. package/src/serve.ts +6 -1
  295. package/src/server/index.ts +30 -7
  296. package/src/server/self-test-input-tokens.ts +29 -14
  297. package/src/server/self-test-redaction.ts +2 -2
  298. package/src/server/self-test.ts +1030 -180
  299. package/src/server/serve-implementation.ts +3062 -0
  300. package/src/server/serve.ts +1 -1781
  301. package/src/server/types.ts +12 -13
  302. package/src/stateful/README.md +146 -0
  303. package/src/stateful/errors.ts +35 -0
  304. package/src/stateful/http-provider-event-emitter.ts +314 -0
  305. package/src/stateful/http-session-owner-registry.ts +306 -0
  306. package/src/stateful/index.ts +18 -0
  307. package/src/stateful/provider-event-delivery-failures.ts +80 -0
  308. package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
  309. package/src/stateful/provider-event-pipeline.ts +61 -0
  310. package/src/stateful/provider-events.ts +462 -0
  311. package/src/stateful/session-key.ts +111 -0
  312. package/src/stateful/stateful-provider-adapter-context.ts +59 -0
  313. package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
  314. package/src/stateful/stateful-provider-adapter.ts +562 -0
  315. package/src/stateful/stateful-provider-observability.ts +261 -0
  316. package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
  317. package/src/stateful/stateful-provider-runtime-context.ts +92 -0
  318. package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
  319. package/src/stateful/stateful-provider-session-routing.ts +546 -0
  320. package/src/stateful/stateful-provider-session-runtime.ts +403 -0
  321. package/src/stateful-signing.ts +46 -0
  322. package/src/stealth/profiles.ts +27 -33
  323. package/src/stream-evidence.ts +988 -0
  324. package/src/stream.ts +16 -20
  325. package/src/testing/index.ts +11 -2
  326. package/src/testing/run.ts +668 -74
  327. package/src/types.ts +665 -35
  328. package/src/user-input.ts +118 -0
  329. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  330. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  331. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  332. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  333. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  334. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  335. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  336. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  337. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  338. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  339. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  340. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  341. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  342. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
@@ -2,22 +2,27 @@
2
2
 
3
3
  import { existsSync } from "node:fs";
4
4
  import { dirname, relative, resolve } from "node:path";
5
- import type { ProviderDefinition } from "../src";
6
5
  import {
7
- createBrowserClient,
8
6
  createCredentialContext,
9
7
  createEnvContext,
10
8
  createHttpClient,
9
+ createOcrClientFromEnv,
11
10
  createProviderCache,
12
11
  createProviderChoiceContext,
13
- createStealthClient,
12
+ createUnsupportedResolverClient,
14
13
  createSttClientFromEnv,
15
14
  PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV,
15
+ type ProviderDefinition,
16
16
  ProviderError,
17
- } from "../src";
18
- import { createMemoryProviderRuntimeState } from "../src/runtime/state";
19
- import { createTraceContext } from "../src/runtime/trace";
20
- import type { BrowserClient, ProviderContext } from "../src/types";
17
+ type ProviderProxyPolicy,
18
+ } from "../src/index.js";
19
+ import { createBrowserClient } from "../src/runtime/browser.js";
20
+ import { createResolverClientFromEnv } from "../src/runtime/resolver.js";
21
+ import { createMemoryProviderRuntimeState } from "../src/runtime/state.js";
22
+ import { createStealthClient } from "../src/runtime/stealth.js";
23
+ import { createTraceContext } from "../src/runtime/trace.js";
24
+ import { getStealthProfile } from "../src/stealth/profiles.js";
25
+ import type { BrowserClient, ProviderContext } from "../src/types.js";
21
26
 
22
27
  const HELP_TEXT = `Usage: apifuse dev [path]
23
28
  Example: apifuse dev providers/korea-air-quality
@@ -33,12 +38,9 @@ export async function main() {
33
38
 
34
39
  const providerPath = resolveProviderPath(args[0] ?? ".");
35
40
  const providerModule = await import(resolve(providerPath, "index.ts"));
36
- const provider = assertProviderDefinition(
37
- providerModule.default,
38
- providerPath,
39
- );
41
+ const provider = assertProviderDefinition(providerModule.default, providerPath);
40
42
 
41
- const { startDevServer } = await import("../src/dev");
43
+ const { startDevServer } = await import("../src/dev.js");
42
44
  const port = Number(process.env.APIFUSE__RUNTIME__PORT) || 3900;
43
45
 
44
46
  startDevServer(provider, { port });
@@ -57,8 +59,7 @@ export async function main() {
57
59
 
58
60
  const firstOperation = Object.keys(provider.operations)[0];
59
61
  if (firstOperation) {
60
- const sampleInput =
61
- provider.operations[firstOperation]?.fixtures?.request ?? {};
62
+ const sampleInput = provider.operations[firstOperation]?.fixtures?.request ?? {};
62
63
  const sampleBody = JSON.stringify({
63
64
  requestId: `req_local_${firstOperation}`,
64
65
  input: sampleInput,
@@ -84,6 +85,11 @@ export function createProviderContext(provider: ProviderDefinition): {
84
85
  ]);
85
86
  const credential = createCredentialContext();
86
87
  const state = createMemoryProviderRuntimeState();
88
+ const cache = createProviderCache({ providerId: provider.id });
89
+ const proxyPolicy = resolveNativeProxyPolicy(provider);
90
+ const stealthProfile = provider.stealth?.profile
91
+ ? getStealthProfile(provider.stealth.profile)
92
+ : undefined;
87
93
  const ctx: ProviderContext = {
88
94
  env,
89
95
  credential,
@@ -96,11 +102,27 @@ export function createProviderContext(provider: ProviderDefinition): {
96
102
  })
97
103
  : createUnsupportedBrowserStub(),
98
104
  http: createHttpClient(),
99
- cache: createProviderCache({ providerId: provider.id }),
105
+ cache,
100
106
  state,
101
107
  trace: createTraceContext(),
102
108
  stealth: createStealthClient("http://localhost"),
109
+ ocr: createOcrClientFromEnv(provider.ocr),
103
110
  stt: createSttClientFromEnv(provider.stt),
111
+ resolver: provider.resolver
112
+ ? createResolverClientFromEnv(provider.resolver, undefined, {
113
+ allowedHosts: provider.allowedHosts,
114
+ cache,
115
+ ...(proxyPolicy
116
+ ? {
117
+ proxyIntent: {
118
+ mode: proxyPolicy.mode,
119
+ upstream: { proxy: provider.proxy },
120
+ ...(stealthProfile ? { userAgent: stealthProfile.userAgent } : {}),
121
+ },
122
+ }
123
+ : {}),
124
+ })
125
+ : createUnsupportedResolverClient("Provider does not declare resolver capability"),
104
126
  choice: createProviderChoiceContext({
105
127
  providerId: provider.id,
106
128
  env,
@@ -112,6 +134,13 @@ export function createProviderContext(provider: ProviderDefinition): {
112
134
  return { ctx };
113
135
  }
114
136
 
137
+ function resolveNativeProxyPolicy(provider: ProviderDefinition): ProviderProxyPolicy | undefined {
138
+ if (typeof provider.proxy === "object") return provider.proxy;
139
+ if (provider.proxy === true) return { mode: "optional" };
140
+ if (provider.proxy === false) return { mode: "disabled" };
141
+ return undefined;
142
+ }
143
+
115
144
  function normalizeArgs(argv: string[]): string[] {
116
145
  return argv[0] === "dev" ? argv.slice(1) : argv;
117
146
  }
@@ -149,9 +178,7 @@ function renderHotReloadCommand(providerPath: string, port: number): string {
149
178
  const devEntry = resolve(providerPath, "dev.ts");
150
179
  if (existsSync(devEntry)) {
151
180
  const relativeDevEntry = relative(process.cwd(), devEntry) || "dev.ts";
152
- const portPrefix = process.env.APIFUSE__RUNTIME__PORT
153
- ? `APIFUSE__RUNTIME__PORT=${port} `
154
- : "";
181
+ const portPrefix = process.env.APIFUSE__RUNTIME__PORT ? `APIFUSE__RUNTIME__PORT=${port} ` : "";
155
182
  return `${portPrefix}bun --hot ${relativeDevEntry}`;
156
183
  }
157
184
  return "rerun `apifuse dev` after edits (no dev.ts entrypoint found)";
@@ -166,40 +193,28 @@ function createUnsupportedBrowserStub(): BrowserClient {
166
193
  engine: "playwright-stealth",
167
194
  async close() {},
168
195
  async newPage() {
169
- throw new ProviderError(
170
- "Browser runtime is not enabled for this provider",
171
- {
172
- code: "BROWSER_RUNTIME_UNSUPPORTED",
173
- fix: 'Set provider runtime to "browser" to use ctx.browser',
174
- },
175
- );
196
+ throw new ProviderError("Browser runtime is not enabled for this provider", {
197
+ code: "BROWSER_RUNTIME_UNSUPPORTED",
198
+ fix: 'Set provider runtime to "browser" to use ctx.browser',
199
+ });
176
200
  },
177
201
  async rawPage() {
178
- throw new ProviderError(
179
- "Browser runtime is not enabled for this provider",
180
- {
181
- code: "BROWSER_RUNTIME_UNSUPPORTED",
182
- fix: 'Set provider runtime to "browser" and APIFUSE__CDP_POOL__URL to use ctx.browser.rawPage',
183
- },
184
- );
202
+ throw new ProviderError("Browser runtime is not enabled for this provider", {
203
+ code: "BROWSER_RUNTIME_UNSUPPORTED",
204
+ fix: 'Set provider runtime to "browser" and APIFUSE__CDP_POOL__URL to use ctx.browser.rawPage',
205
+ });
185
206
  },
186
207
  async withIsolatedContext() {
187
- throw new ProviderError(
188
- "Browser runtime is not enabled for this provider",
189
- {
190
- code: "BROWSER_RUNTIME_UNSUPPORTED",
191
- fix: 'Set provider runtime to "browser" to use ctx.browser.withIsolatedContext',
192
- },
193
- );
208
+ throw new ProviderError("Browser runtime is not enabled for this provider", {
209
+ code: "BROWSER_RUNTIME_UNSUPPORTED",
210
+ fix: 'Set provider runtime to "browser" to use ctx.browser.withIsolatedContext',
211
+ });
194
212
  },
195
213
  async solveChallenge() {
196
- throw new ProviderError(
197
- "Browser runtime is not enabled for this provider",
198
- {
199
- code: "BROWSER_RUNTIME_UNSUPPORTED",
200
- fix: 'Set provider runtime to "browser" to use ctx.browser.solveChallenge',
201
- },
202
- );
214
+ throw new ProviderError("Browser runtime is not enabled for this provider", {
215
+ code: "BROWSER_RUNTIME_UNSUPPORTED",
216
+ fix: 'Set provider runtime to "browser" to use ctx.browser.solveChallenge',
217
+ });
203
218
  },
204
219
  };
205
220
  }
@@ -216,10 +231,7 @@ function createUnsupportedAuthStub() {
216
231
  };
217
232
  }
218
233
 
219
- function assertProviderDefinition(
220
- value: unknown,
221
- providerPath: string,
222
- ): ProviderDefinition {
234
+ function assertProviderDefinition(value: unknown, providerPath: string): ProviderDefinition {
223
235
  if (!isProviderDefinition(value)) {
224
236
  throw new Error(
225
237
  `Expected ${resolve(providerPath, "index.ts")} to export default defineProvider(...)`,
@@ -230,11 +242,7 @@ function assertProviderDefinition(
230
242
  }
231
243
 
232
244
  function isProviderDefinition(value: unknown): value is ProviderDefinition {
233
- if (
234
- !isRecord(value) ||
235
- !isRecord(value.meta) ||
236
- !isRecord(value.operations)
237
- ) {
245
+ if (!isRecord(value) || !isRecord(value.meta) || !isRecord(value.operations)) {
238
246
  return false;
239
247
  }
240
248
 
@@ -48,6 +48,13 @@ const requiredPaths = [
48
48
  "src/cli/templates/provider/operations/ping.ts.tpl",
49
49
  "src/cli/templates/provider/schemas/ping.ts.tpl",
50
50
  "src/cli/templates/provider/upstream/README.md.tpl",
51
+ "src/cli/templates/provider/AGENTS.md.tpl",
52
+ "src/cli/templates/provider/.agents/skills/normalization-standards/SKILL.md.tpl",
53
+ "src/cli/templates/provider/.agents/skills/upstream-contract-verification/SKILL.md.tpl",
54
+ "src/cli/templates/provider/.agents/skills/fixtures-and-recording/SKILL.md.tpl",
55
+ "src/cli/templates/provider/.agents/skills/pagination-and-counts/SKILL.md.tpl",
56
+ "src/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl",
57
+ "src/cli/templates/provider/.agents/skills/upstream-notes/README.md.tpl",
51
58
  "dist/cli/templates/provider/.dockerignore.tpl",
52
59
  "dist/cli/templates/provider/.gitignore.tpl",
53
60
  "dist/cli/templates/provider/Dockerfile.tpl",
@@ -60,6 +67,13 @@ const requiredPaths = [
60
67
  "dist/cli/templates/provider/operations/ping.ts.tpl",
61
68
  "dist/cli/templates/provider/schemas/ping.ts.tpl",
62
69
  "dist/cli/templates/provider/upstream/README.md.tpl",
70
+ "dist/cli/templates/provider/AGENTS.md.tpl",
71
+ "dist/cli/templates/provider/.agents/skills/normalization-standards/SKILL.md.tpl",
72
+ "dist/cli/templates/provider/.agents/skills/upstream-contract-verification/SKILL.md.tpl",
73
+ "dist/cli/templates/provider/.agents/skills/fixtures-and-recording/SKILL.md.tpl",
74
+ "dist/cli/templates/provider/.agents/skills/pagination-and-counts/SKILL.md.tpl",
75
+ "dist/cli/templates/provider/.agents/skills/health-checks-and-fail-closed/SKILL.md.tpl",
76
+ "dist/cli/templates/provider/.agents/skills/upstream-notes/README.md.tpl",
63
77
  "dist/auth-turn/index.js",
64
78
  "dist/auth-turn/index.d.ts",
65
79
  "dist/auth-turn/auth-turn.v1.schema.json",
@@ -142,9 +156,9 @@ function assertPublicSmokeDocs(label: string, content: string): void {
142
156
  );
143
157
  }
144
158
 
145
- if (!content.includes("impit")) {
159
+ if (!content.includes("wreq-js")) {
146
160
  throw new Error(
147
- `${label} must include impit stealth runtime guidance for TLS/browser bounties.`,
161
+ `${label} must include wreq-js stealth runtime guidance for TLS/browser bounties.`,
148
162
  );
149
163
  }
150
164
 
@@ -154,6 +168,12 @@ function assertPublicSmokeDocs(label: string, content: string): void {
154
168
  );
155
169
  }
156
170
 
171
+ if (!content.includes("Chrome, Firefox, and Safari")) {
172
+ throw new Error(
173
+ `${label} must document the browser families supported by the TypeScript stealth runtime.`,
174
+ );
175
+ }
176
+
157
177
  if (
158
178
  !content.includes('browser.engine: "playwright-stealth"') ||
159
179
  !content.includes("nodriver")
@@ -1,19 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import {
4
- type ChildProcess,
5
- execFileSync,
6
- spawn,
7
- spawnSync,
8
- } from "node:child_process";
9
- import {
10
- existsSync,
11
- mkdirSync,
12
- mkdtempSync,
13
- readFileSync,
14
- rmSync,
15
- writeFileSync,
16
- } from "node:fs";
3
+ import { type ChildProcess, execFileSync, spawn, spawnSync } from "node:child_process";
4
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
17
5
  import { createServer } from "node:net";
18
6
  import { tmpdir } from "node:os";
19
7
  import { join, resolve } from "node:path";
@@ -41,9 +29,7 @@ const PING_RESPONSE_SCHEMA = z.object({
41
29
 
42
30
  const KEEP_TEMP = process.env.APIFUSE__PACK_SMOKE__KEEP_TEMP === "1";
43
31
 
44
- const tempRoot = mkdtempSync(
45
- join(tmpdir(), "apifuse-provider-sdk-pack-smoke-"),
46
- );
32
+ const tempRoot = mkdtempSync(join(tmpdir(), "apifuse-provider-sdk-pack-smoke-"));
47
33
  const packDir = join(tempRoot, "pack");
48
34
  const consumerDir = join(tempRoot, "consumer");
49
35
  const externalWorkspaceDir = join(tempRoot, "external-workspace");
@@ -73,6 +59,21 @@ try {
73
59
  );
74
60
 
75
61
  run("bun", ["install"], consumerDir);
62
+ run(
63
+ "bun",
64
+ [
65
+ "--eval",
66
+ [
67
+ 'import { resolveProxy } from "@apifuse/provider-sdk";',
68
+ 'if (typeof resolveProxy !== "function") throw new Error("resolveProxy is not exported");',
69
+ 'const resolved = await resolveProxy({ proxy: "http://127.0.0.1:8080" });',
70
+ 'if (resolved.url !== "http://127.0.0.1:8080") throw new Error("resolveProxy returned the wrong URL");',
71
+ 'console.log("packed root resolveProxy export OK");',
72
+ ].join("\n"),
73
+ ],
74
+ consumerDir,
75
+ );
76
+ smokePackedStealthNative(consumerDir);
76
77
 
77
78
  const cliBin = join(consumerDir, "node_modules", ".bin", "apifuse");
78
79
  if (!existsSync(cliBin)) {
@@ -81,15 +82,7 @@ try {
81
82
 
82
83
  run(
83
84
  "bun",
84
- [
85
- cliBin,
86
- "create",
87
- "dx-smoke",
88
- "--yes",
89
- "--json",
90
- "--sdk-specifier",
91
- tarballSpecifier,
92
- ],
85
+ [cliBin, "create", "dx-smoke", "--yes", "--json", "--sdk-specifier", tarballSpecifier],
93
86
  consumerDir,
94
87
  );
95
88
 
@@ -99,11 +92,7 @@ try {
99
92
  run("bun", ["run", "test"], generatedProviderDir);
100
93
  assertGeneratedReadme(generatedProviderDir);
101
94
  await smokeGeneratedDevServer(generatedProviderDir);
102
- assertExternalWorkspaceTopology(
103
- cliBin,
104
- externalWorkspaceDir,
105
- tarballSpecifier,
106
- );
95
+ assertExternalWorkspaceTopology(cliBin, externalWorkspaceDir, tarballSpecifier);
107
96
 
108
97
  console.log(
109
98
  `Provider SDK packed-artifact smoke passed: ${tarballPath} -> ${generatedProviderDir}`,
@@ -148,15 +137,8 @@ function assertExternalWorkspaceTopology(
148
137
  externalWorkspaceDir,
149
138
  );
150
139
 
151
- const generatedProviderDir = join(
152
- externalWorkspaceDir,
153
- "external-workspace-smoke",
154
- );
155
- const forbiddenProviderDir = join(
156
- externalWorkspaceDir,
157
- "providers",
158
- "external-workspace-smoke",
159
- );
140
+ const generatedProviderDir = join(externalWorkspaceDir, "external-workspace-smoke");
141
+ const forbiddenProviderDir = join(externalWorkspaceDir, "providers", "external-workspace-smoke");
160
142
  if (!existsSync(generatedProviderDir)) {
161
143
  throw new Error(
162
144
  "Public create must generate a one-provider repository at <name>/ even when providers/ exists.",
@@ -168,9 +150,7 @@ function assertExternalWorkspaceTopology(
168
150
  );
169
151
  }
170
152
 
171
- const packageJson = JSON.parse(
172
- readFileSync(join(generatedProviderDir, "package.json"), "utf8"),
173
- );
153
+ const packageJson = JSON.parse(readFileSync(join(generatedProviderDir, "package.json"), "utf8"));
174
154
  const sdkDependency = packageJson?.dependencies?.["@apifuse/provider-sdk"];
175
155
  if (sdkDependency !== tarballSpecifier) {
176
156
  throw new Error(
@@ -178,9 +158,7 @@ function assertExternalWorkspaceTopology(
178
158
  );
179
159
  }
180
160
  if (JSON.stringify(packageJson).includes("workspace:")) {
181
- throw new Error(
182
- "External bounty workspace scaffold must not contain workspace: dependencies.",
183
- );
161
+ throw new Error("External bounty workspace scaffold must not contain workspace: dependencies.");
184
162
  }
185
163
 
186
164
  run("bun", ["install"], generatedProviderDir);
@@ -199,30 +177,20 @@ function assertExternalWorkspaceTopology(
199
177
  },
200
178
  );
201
179
  if (monorepoAttempt.status === 0) {
202
- throw new Error(
203
- "--preset monorepo must reject outside the private APIFuse monorepo.",
204
- );
180
+ throw new Error("--preset monorepo must reject outside the private APIFuse monorepo.");
205
181
  }
206
182
  const rejectionOutput = `${monorepoAttempt.stdout}\n${monorepoAttempt.stderr}`;
207
- if (
208
- !rejectionOutput.includes(
209
- "Monorepo preset is internal to the APIFuse repository",
210
- )
211
- ) {
183
+ if (!rejectionOutput.includes("Monorepo preset is internal to the APIFuse repository")) {
212
184
  throw new Error(`Unexpected monorepo rejection output: ${rejectionOutput}`);
213
185
  }
214
186
  }
215
187
 
216
188
  function packSdk(destination: string): { filename: string } {
217
- const raw = execFileSync(
218
- "npm",
219
- ["pack", "--json", "--pack-destination", destination],
220
- {
221
- cwd: process.cwd(),
222
- encoding: "utf8",
223
- stdio: ["ignore", "pipe", "inherit"],
224
- },
225
- );
189
+ const raw = execFileSync("npm", ["pack", "--json", "--pack-destination", destination], {
190
+ cwd: process.cwd(),
191
+ encoding: "utf8",
192
+ stdio: ["ignore", "pipe", "inherit"],
193
+ });
226
194
  const parsed = PACK_RESULT_SCHEMA.parse(JSON.parse(raw));
227
195
  const first = parsed[0];
228
196
  if (!first) {
@@ -249,32 +217,62 @@ function run(command: string, args: string[], cwd: string): void {
249
217
  }
250
218
  }
251
219
 
220
+ function smokePackedStealthNative(consumerDir: string): void {
221
+ run(
222
+ "bun",
223
+ [
224
+ "--eval",
225
+ [
226
+ 'import { createServer } from "node:http";',
227
+ 'import { createStealthClient } from "@apifuse/provider-sdk/runtime/stealth";',
228
+ "const server = createServer((_request, response) => {",
229
+ ' response.setHeader("set-cookie", "pack_native_cookie=landed; Path=/");',
230
+ ' response.end("packed native stealth ok");',
231
+ "});",
232
+ "await new Promise((resolve, reject) => {",
233
+ ' server.once("error", reject);',
234
+ ' server.listen(0, "127.0.0.1", resolve);',
235
+ "});",
236
+ "const address = server.address();",
237
+ 'if (!address || typeof address === "string") throw new Error("Local server has no TCP address");',
238
+ 'const baseUrl = "http://127.0.0.1:" + address.port;',
239
+ 'const session = createStealthClient(baseUrl).createSession({ profile: "safari-17" });',
240
+ "try {",
241
+ ' const response = await session.fetch("/native");',
242
+ ' if (response.body !== "packed native stealth ok") throw new Error("Unexpected stealth body: " + response.body);',
243
+ ' if (session.cookies.get("pack_native_cookie", baseUrl + "/native") !== "landed") {',
244
+ ' throw new Error("Packed stealth Set-Cookie did not land in the SDK jar");',
245
+ " }",
246
+ ' console.log("packed native Safari stealth request OK");',
247
+ "} finally {",
248
+ " session.close();",
249
+ " await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));",
250
+ "}",
251
+ ].join("\n"),
252
+ ],
253
+ consumerDir,
254
+ );
255
+ }
256
+
252
257
  function assertGeneratedReadme(providerDir: string): void {
253
258
  const readme = readFileSync(join(providerDir, "README.md"), "utf8");
254
259
  if (!readme.includes('"requestId":"req_local_ping"')) {
255
- throw new Error(
256
- "Generated README is missing requestId in local smoke docs.",
257
- );
260
+ throw new Error("Generated README is missing requestId in local smoke docs.");
258
261
  }
259
262
  if (readme.includes('"connection":null')) {
260
- throw new Error(
261
- "Generated README must not document connection:null for no-auth local smoke.",
262
- );
263
+ throw new Error("Generated README must not document connection:null for no-auth local smoke.");
263
264
  }
264
265
  if (!readme.includes("bunx playwright install chromium")) {
265
- throw new Error(
266
- "Generated README is missing browser runtime troubleshooting guidance.",
267
- );
266
+ throw new Error("Generated README is missing browser runtime troubleshooting guidance.");
268
267
  }
269
- if (!readme.includes("impit")) {
270
- throw new Error(
271
- "Generated README is missing impit stealth runtime guidance.",
272
- );
268
+ if (!readme.includes("wreq-js")) {
269
+ throw new Error("Generated README is missing wreq-js stealth runtime guidance.");
270
+ }
271
+ if (!readme.includes("Chrome, Firefox, and Safari")) {
272
+ throw new Error("Generated README is missing supported stealth browser families.");
273
273
  }
274
274
  if (!readme.includes("bun run submit-check")) {
275
- throw new Error(
276
- "Generated README must document the submit-check pre-submission workflow.",
277
- );
275
+ throw new Error("Generated README must document the submit-check pre-submission workflow.");
278
276
  }
279
277
  if (!readme.includes("bun run record -- --operation <operation>")) {
280
278
  throw new Error(
@@ -368,9 +366,7 @@ async function waitForHttp(
368
366
 
369
367
  while (Date.now() < deadline) {
370
368
  if (server.exitCode !== null) {
371
- throw new Error(
372
- `Dev server exited early with code ${server.exitCode}\n${getOutput()}`,
373
- );
369
+ throw new Error(`Dev server exited early with code ${server.exitCode}\n${getOutput()}`);
374
370
  }
375
371
 
376
372
  try {