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

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 (51) hide show
  1. package/AUTHORING.md +92 -0
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +5 -1
  4. package/SUBMISSION.md +1 -1
  5. package/bin/apifuse-check.ts +26 -1
  6. package/bin/apifuse-pack-check.ts +14 -0
  7. package/bin/apifuse-submit-check.ts +433 -15
  8. package/bin/apifuse-sync-assets.ts +117 -0
  9. package/dist/cli/commands.d.ts +1 -1
  10. package/dist/cli/commands.js +8 -0
  11. package/dist/cli/create.d.ts +3 -0
  12. package/dist/cli/create.js +34 -35
  13. package/dist/cli/prompt-assets.d.ts +80 -0
  14. package/dist/cli/prompt-assets.js +743 -0
  15. package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +1 -0
  18. package/dist/runtime/executor.js +7 -0
  19. package/dist/runtime/secrets.d.ts +27 -0
  20. package/dist/runtime/secrets.js +51 -0
  21. package/dist/server/index.d.ts +1 -1
  22. package/dist/server/index.js +1 -1
  23. package/dist/server/self-test.d.ts +101 -0
  24. package/dist/server/self-test.js +670 -112
  25. package/dist/server/serve.d.ts +5 -0
  26. package/dist/server/serve.js +41 -1
  27. package/package.json +1 -1
  28. package/src/cli/commands.ts +10 -0
  29. package/src/cli/create.ts +42 -35
  30. package/src/cli/prompt-assets.ts +865 -0
  31. package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
  32. package/src/index.ts +5 -0
  33. package/src/runtime/executor.ts +8 -0
  34. package/src/runtime/secrets.ts +64 -0
  35. package/src/server/index.ts +5 -0
  36. package/src/server/self-test.ts +852 -127
  37. package/src/server/serve.ts +60 -1
  38. package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
  39. package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
  40. /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  41. /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  42. /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  43. /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  44. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  45. /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
  46. /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
  47. /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
  48. /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
  49. /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
  50. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
  51. /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
@@ -4,8 +4,8 @@ You are building an APIFuse provider. APIFuse turns messy upstream APIs into
4
4
  normalized, typed, evidence-backed public APIs. A provider that merely proxies
5
5
  the upstream is a failed provider, even if every check passes.
6
6
 
7
- This file is the core contract. Detailed procedures live in `skills/` — load
8
- the matching skill BEFORE working on that area (index at the bottom).
7
+ This file is the core contract. Detailed procedures live in `.agents/skills/` —
8
+ load the matching skill BEFORE working on that area (index at the bottom).
9
9
 
10
10
  ## Non-negotiable principles
11
11
 
@@ -75,13 +75,22 @@ bun run submit-check # structural score; a high score does NOT prove quality
75
75
  `submit-check` is a structural gate. Every principle above can be violated
76
76
  while scoring 95/100 — reviewers and CI audit for exactly these classes.
77
77
 
78
+ ## Managed prompt assets
79
+
80
+ `AGENTS.md` and `.agents/skills/**` are generated by the SDK; `CLAUDE.md`,
81
+ `.claude`, and `.codex` are symlinks onto them so every agent CLI reads the
82
+ same contract. Do not hand-edit these files — regenerate them with
83
+ `bun run sync-assets` (or `bunx apifuse sync-assets .`). `apifuse check` and
84
+ `submit-check` enforce a freshness gate: stale or modified prompt assets
85
+ (tracked in `.apifuse/prompt-assets.json`) block submission until re-synced.
86
+
78
87
  ## Skill index — load before working on:
79
88
 
80
89
  | Area | Load |
81
90
  | --- | --- |
82
- | Output schemas, mappers, field naming, timestamps, enums | `skills/normalization-standards/SKILL.md` |
83
- | Upstream request params, new endpoint wiring, field mapping | `skills/upstream-contract-verification/SKILL.md` |
84
- | Recording fixtures, writing tests against fixtures | `skills/fixtures-and-recording/SKILL.md` |
85
- | List operations, paging, totals, client-side filtering | `skills/pagination-and-counts/SKILL.md` |
86
- | healthCheck blocks, error classification, fail-closed guards | `skills/health-checks-and-fail-closed/SKILL.md` |
87
- | Upstream-specific known pitfalls for THIS bounty | `skills/upstream-notes/` (read every file) |
91
+ | Output schemas, mappers, field naming, timestamps, enums | `.agents/skills/normalization-standards/SKILL.md` |
92
+ | Upstream request params, new endpoint wiring, field mapping | `.agents/skills/upstream-contract-verification/SKILL.md` |
93
+ | Recording fixtures, writing tests against fixtures | `.agents/skills/fixtures-and-recording/SKILL.md` |
94
+ | List operations, paging, totals, client-side filtering | `.agents/skills/pagination-and-counts/SKILL.md` |
95
+ | healthCheck blocks, error classification, fail-closed guards | `.agents/skills/health-checks-and-fail-closed/SKILL.md` |
96
+ | Upstream-specific known pitfalls for THIS bounty | `.agents/skills/upstream-notes/` (read every file) |
package/src/index.ts CHANGED
@@ -74,6 +74,11 @@ export {
74
74
  } from "./runtime/instrumentation.js";
75
75
  export { type PrevalidateResult, prevalidate } from "./runtime/prevalidate.js";
76
76
  export { getProviderBaseUrl } from "./runtime/provider.js";
77
+ export {
78
+ assertRequiredSecretsPresent,
79
+ listMissingRequiredSecrets,
80
+ MISSING_SECRET_CODE,
81
+ } from "./runtime/secrets.js";
77
82
  export {
78
83
  createUnsupportedProviderRuntimeState,
79
84
  UnsupportedProviderStateError,
@@ -1,6 +1,7 @@
1
1
  import { isSessionExpiredError, ProviderError, SessionExpiredError } from "../errors.js";
2
2
  import { parseSchema } from "../schema.js";
3
3
  import type { ProviderContext, ProviderDefinition } from "../types.js";
4
+ import { assertRequiredSecretsPresent } from "./secrets.js";
4
5
 
5
6
  export function isStreamingOperation(provider: ProviderDefinition, operationId: string): boolean {
6
7
  const kind = provider.operations[operationId]?.transport?.kind ?? "json";
@@ -34,6 +35,13 @@ export async function executeOperation(
34
35
  });
35
36
  }
36
37
 
38
+ // SDK-owned secret presence gate (single source of truth): declared
39
+ // `required: true` secrets are validated here, before input parsing and the
40
+ // handler, so every invocation path (serve /v1, self-test probes, perf,
41
+ // record) fails with the same structured MISSING_SECRET error instead of a
42
+ // handler-specific crash. Providers must not re-check presence locally.
43
+ assertRequiredSecretsPresent(provider, ctx.env);
44
+
37
45
  const validatedInput = await parseSchema(
38
46
  operation.input,
39
47
  input,
@@ -0,0 +1,64 @@
1
+ import { ProviderSecretError } from "../errors.js";
2
+ import type { EnvContext, ProviderDefinition } from "../types.js";
3
+
4
+ /**
5
+ * Canonical error code for a declared-but-unprovisioned provider secret.
6
+ *
7
+ * The SDK is the single source of truth for env/secret presence validation:
8
+ * providers declare secrets in `defineProvider({ secrets: [...] })` and the
9
+ * runtime enforces presence before any handler or auth-flow code runs.
10
+ * Provider-local presence guards (requireServiceKey/requireApiKey style) are a
11
+ * deprecated antipattern — see the `sdk-owned-secret-presence` submit-check
12
+ * rule.
13
+ */
14
+ export const MISSING_SECRET_CODE = "MISSING_SECRET";
15
+
16
+ /**
17
+ * Names of declared `required: true` secrets whose env values are unset or
18
+ * whitespace-only. Whitespace-only values count as missing for parity with the
19
+ * `.trim()` guards well-built providers used before the SDK owned this check —
20
+ * a blank value provisioned by a broken secret pipeline must not pass the gate.
21
+ */
22
+ export function listMissingRequiredSecrets(
23
+ provider: ProviderDefinition,
24
+ env: EnvContext,
25
+ ): string[] {
26
+ const missing: string[] = [];
27
+ for (const secret of provider.secrets ?? []) {
28
+ if (secret.required !== true) {
29
+ continue;
30
+ }
31
+ const value = env.get(secret.name);
32
+ if (value === undefined || value.trim() === "") {
33
+ missing.push(secret.name);
34
+ }
35
+ }
36
+ return missing;
37
+ }
38
+
39
+ /**
40
+ * Throws the canonical structured missing-secret error when any declared
41
+ * `required: true` secret is absent. All missing names are reported in a
42
+ * single error so operators can provision the full set in one pass instead of
43
+ * discovering them one deploy at a time (the 2026-07-22 unprovisioned-secret
44
+ * incident failure mode).
45
+ */
46
+ export function assertRequiredSecretsPresent(
47
+ provider: ProviderDefinition,
48
+ env: EnvContext,
49
+ ): void {
50
+ const missing = listMissingRequiredSecrets(provider, env);
51
+ if (missing.length === 0) {
52
+ return;
53
+ }
54
+ const names = missing.join(", ");
55
+ throw new ProviderSecretError(
56
+ `Missing required provider secret${missing.length > 1 ? "s" : ""}: ${names}`,
57
+ {
58
+ code: MISSING_SECRET_CODE,
59
+ category: "credential_unavailable",
60
+ retryable: false,
61
+ fix: `Provision ${names} in the provider environment (e.g. Doppler). Declared in defineProvider({ secrets: [...] }).`,
62
+ },
63
+ );
64
+ }
@@ -2,15 +2,20 @@ export { createServerApp, type ServeOptions, serve } from "./serve.js";
2
2
  export {
3
3
  computeSelfTestPlanDigest,
4
4
  createSelfTestApp,
5
+ createSelfTestAuthFlowInvoke,
5
6
  createSelfTestInvoke,
6
7
  DEFAULT_SELF_TEST_REQUEST_BUDGET_MS,
7
8
  isSelfTestReadOnlyOperation,
8
9
  PROVIDER_RUNTIME_SELF_TEST_REQUEST_BUDGET_MS_ENV,
9
10
  resolveSelfTestPort,
11
+ SELF_TEST_AUTH_FLOW_MULTI_TURN_SKIP_REASON,
12
+ SELF_TEST_AUTH_FLOW_REJECTED_SKIP_REASON,
10
13
  SELF_TEST_HEALTHZ_PATH,
11
14
  SELF_TEST_PATH,
12
15
  SELF_TEST_SCHEMA_VERSION,
13
16
  type SelfTestAppOptions,
17
+ type SelfTestAuthFlowInvoke,
18
+ type SelfTestAuthFlowRoute,
14
19
  type SelfTestCaseResult,
15
20
  type SelfTestCaseStatus,
16
21
  type SelfTestOperationInvoke,