@adcp/sdk 14.0.0-beta.14 → 14.0.0-beta.15

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 (127) hide show
  1. package/dist/lib/auth/oauth/authorization-required.d.mts +25 -11
  2. package/dist/lib/auth/oauth/authorization-required.d.ts +25 -11
  3. package/dist/lib/auth/oauth/authorization-required.js +18 -4
  4. package/dist/lib/auth/oauth/authorization-required.mjs +17 -4
  5. package/dist/lib/auth/oauth/index.d.mts +1 -1
  6. package/dist/lib/auth/oauth/index.d.ts +1 -1
  7. package/dist/lib/auth/oauth/index.js +2 -0
  8. package/dist/lib/auth/oauth/index.mjs +2 -0
  9. package/dist/lib/auth/oauth/resource-url.d.mts +8 -0
  10. package/dist/lib/auth/oauth/resource-url.d.ts +8 -0
  11. package/dist/lib/auth/oauth/resource-url.js +42 -0
  12. package/dist/lib/auth/oauth/resource-url.mjs +40 -0
  13. package/dist/lib/core/ConversationTypes.d.mts +10 -0
  14. package/dist/lib/core/ConversationTypes.d.ts +10 -0
  15. package/dist/lib/core/SingleAgentClient.d.mts +5 -2
  16. package/dist/lib/core/SingleAgentClient.d.ts +5 -2
  17. package/dist/lib/core/SingleAgentClient.js +133 -28
  18. package/dist/lib/core/SingleAgentClient.mjs +138 -29
  19. package/dist/lib/core/TaskExecutor.d.mts +1 -0
  20. package/dist/lib/core/TaskExecutor.d.ts +1 -0
  21. package/dist/lib/core/TaskExecutor.js +7 -1
  22. package/dist/lib/core/TaskExecutor.mjs +7 -1
  23. package/dist/lib/core/webhook-registration.d.mts +8 -1
  24. package/dist/lib/core/webhook-registration.d.ts +8 -1
  25. package/dist/lib/core/webhook-registration.js +65 -5
  26. package/dist/lib/core/webhook-registration.mjs +61 -4
  27. package/dist/lib/errors/index.d.mts +9 -0
  28. package/dist/lib/errors/index.d.ts +9 -0
  29. package/dist/lib/errors/index.js +33 -0
  30. package/dist/lib/errors/index.mjs +32 -0
  31. package/dist/lib/index.d.mts +3 -2
  32. package/dist/lib/index.d.ts +3 -2
  33. package/dist/lib/index.js +4 -0
  34. package/dist/lib/index.mjs +4 -0
  35. package/dist/lib/media-buy/compatibility.js +14 -2
  36. package/dist/lib/media-buy/compatibility.mjs +14 -2
  37. package/dist/lib/protocols/index.js +23 -7
  38. package/dist/lib/protocols/index.mjs +24 -8
  39. package/dist/lib/protocols/mcp.js +8 -6
  40. package/dist/lib/protocols/mcp.mjs +9 -7
  41. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  42. package/dist/lib/server/decisioning/async-outcome.d.mts +11 -0
  43. package/dist/lib/server/decisioning/async-outcome.d.ts +11 -0
  44. package/dist/lib/server/decisioning/context.d.mts +11 -1
  45. package/dist/lib/server/decisioning/context.d.ts +11 -1
  46. package/dist/lib/server/decisioning/index.d.mts +3 -2
  47. package/dist/lib/server/decisioning/index.d.ts +3 -2
  48. package/dist/lib/server/decisioning/index.js +9 -0
  49. package/dist/lib/server/decisioning/index.mjs +10 -0
  50. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -2
  51. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -2
  52. package/dist/lib/server/decisioning/runtime/from-platform.js +40 -8
  53. package/dist/lib/server/decisioning/runtime/from-platform.mjs +40 -8
  54. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +8 -1
  55. package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +8 -1
  56. package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +10 -1
  57. package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +9 -1
  58. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +79 -0
  59. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +79 -0
  60. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +391 -0
  61. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +369 -0
  62. package/dist/lib/server/decisioning/runtime/task-registry.d.mts +2 -0
  63. package/dist/lib/server/decisioning/runtime/task-registry.d.ts +2 -0
  64. package/dist/lib/server/decisioning/runtime/task-registry.js +2 -1
  65. package/dist/lib/server/decisioning/runtime/task-registry.mjs +2 -1
  66. package/dist/lib/server/decisioning/runtime/to-context.js +15 -11
  67. package/dist/lib/server/decisioning/runtime/to-context.mjs +15 -11
  68. package/dist/lib/server/index.d.mts +2 -2
  69. package/dist/lib/server/index.d.ts +2 -2
  70. package/dist/lib/server/index.js +4 -0
  71. package/dist/lib/server/index.mjs +4 -0
  72. package/dist/lib/server/webhook-delivery/index.d.mts +2 -2
  73. package/dist/lib/server/webhook-delivery/index.d.ts +2 -2
  74. package/dist/lib/server/webhook-delivery/index.js +4 -0
  75. package/dist/lib/server/webhook-delivery/index.mjs +5 -1
  76. package/dist/lib/server/webhook-delivery/pg.d.mts +3 -1
  77. package/dist/lib/server/webhook-delivery/pg.d.ts +3 -1
  78. package/dist/lib/server/webhook-delivery/pg.js +25 -2
  79. package/dist/lib/server/webhook-delivery/pg.mjs +25 -2
  80. package/dist/lib/server/webhook-delivery/recovery.d.mts +44 -0
  81. package/dist/lib/server/webhook-delivery/recovery.d.ts +44 -0
  82. package/dist/lib/server/webhook-delivery/recovery.js +146 -43
  83. package/dist/lib/server/webhook-delivery/recovery.mjs +144 -43
  84. package/dist/lib/signing/agent-resolver/index.d.mts +1 -1
  85. package/dist/lib/signing/agent-resolver/index.d.ts +1 -1
  86. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +9 -0
  87. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +9 -0
  88. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +4 -1
  89. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +4 -1
  90. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +17 -4
  91. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +17 -4
  92. package/dist/lib/signing/jwks.d.mts +7 -0
  93. package/dist/lib/signing/jwks.d.ts +7 -0
  94. package/dist/lib/signing/server.d.mts +2 -2
  95. package/dist/lib/signing/server.d.ts +2 -2
  96. package/dist/lib/signing/webhook-verifier.d.mts +6 -0
  97. package/dist/lib/signing/webhook-verifier.d.ts +6 -0
  98. package/dist/lib/signing/webhook-verifier.js +38 -4
  99. package/dist/lib/signing/webhook-verifier.mjs +38 -4
  100. package/dist/lib/testing/client.d.mts +1 -0
  101. package/dist/lib/testing/client.d.ts +1 -0
  102. package/dist/lib/testing/client.js +6 -2
  103. package/dist/lib/testing/client.mjs +6 -2
  104. package/dist/lib/testing/compliance/comply.d.mts +2 -2
  105. package/dist/lib/testing/compliance/comply.d.ts +2 -2
  106. package/dist/lib/testing/compliance/comply.js +41 -31
  107. package/dist/lib/testing/compliance/comply.mjs +44 -21
  108. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.mts +1 -7
  109. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.ts +1 -7
  110. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.js +6 -42
  111. package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.mjs +10 -40
  112. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  113. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  114. package/dist/lib/utils/adcp-version-config.d.mts +2 -0
  115. package/dist/lib/utils/adcp-version-config.d.ts +2 -0
  116. package/dist/lib/utils/adcp-version-config.js +5 -0
  117. package/dist/lib/utils/adcp-version-config.mjs +4 -0
  118. package/dist/lib/version.d.mts +3 -3
  119. package/dist/lib/version.d.ts +3 -3
  120. package/dist/lib/version.js +3 -3
  121. package/dist/lib/version.mjs +3 -3
  122. package/docs/llms.txt +3 -1
  123. package/docs/migration-12-to-14.md +6 -5
  124. package/docs/migration-13-to-14.md +48 -7
  125. package/docs/migration-task-registry-scoping.md +164 -11
  126. package/package.json +1 -1
  127. package/skills/build-decisioning-platform/advanced/REFERENCE.md +1 -1
@@ -15,7 +15,8 @@ const WEBHOOK_MANDATORY_COMPONENTS = [
15
15
  "content-digest"
16
16
  ];
17
17
  async function verifyWebhookSignature(request, options) {
18
- const now = options.now ? options.now() : Math.floor(Date.now() / 1e3);
18
+ const currentTime = options.now ?? (() => Date.now() / 1e3);
19
+ const now = currentTime();
19
20
  const requiredTag = options.requiredTag ?? WEBHOOK_SIGNING_TAG;
20
21
  const sigInputHeader = getHeaderValue(request.headers, "Signature-Input");
21
22
  const sigHeader = getHeaderValue(request.headers, "Signature");
@@ -56,7 +57,8 @@ async function verifyWebhookSignature(request, options) {
56
57
  validateWindow(parsedInput.params.created, parsedInput.params.expires, now);
57
58
  validateCoveredComponents(parsedInput.components);
58
59
  const canonicalWebhookTarget = validateTargetUri(request.url);
59
- const jwk = await options.jwks.resolve(parsedInput.params.keyid);
60
+ const keyResolution = options.jwks.resolveWithMetadata ? await options.jwks.resolveWithMetadata(parsedInput.params.keyid) : { jwk: await options.jwks.resolve(parsedInput.params.keyid) };
61
+ const jwk = keyResolution.jwk;
60
62
  if (!jwk) {
61
63
  throw new WebhookSignatureError(
62
64
  "webhook_signature_key_unknown",
@@ -71,6 +73,9 @@ async function verifyWebhookSignature(request, options) {
71
73
  `JWKS resolver returned a JWK whose kid "${jwk.kid}" does not match requested keyid "${parsedInput.params.keyid}".`
72
74
  );
73
75
  }
76
+ if (keyResolution.operatorAuthorizationValidUntil !== void 0) {
77
+ assertDelegatedOperatorAuthorizationActive(keyResolution.operatorAuthorizationValidUntil, currentTime());
78
+ }
74
79
  if (jwk.adcp_use === void 0 || !jwk.key_ops?.includes("verify") || jwk.adcp_use !== "request-signing" && jwk.adcp_use !== "webhook-signing") {
75
80
  throw new WebhookSignatureError(
76
81
  "webhook_signature_key_purpose_invalid",
@@ -88,7 +93,7 @@ async function verifyWebhookSignature(request, options) {
88
93
  }
89
94
  throw err;
90
95
  }
91
- const replayScope = canonicalWebhookTarget;
96
+ const replayScope = replayScopeForWebhook(canonicalWebhookTarget, options.replayScopeBinding);
92
97
  if (await options.replayStore.has(jwk.kid, replayScope, parsedInput.params.nonce, now)) {
93
98
  throw new WebhookSignatureError(
94
99
  "webhook_signature_replayed",
@@ -134,6 +139,9 @@ async function verifyWebhookSignature(request, options) {
134
139
  "Content-Digest header does not match recomputed body hash."
135
140
  );
136
141
  }
142
+ if (keyResolution.operatorAuthorizationValidUntil !== void 0) {
143
+ assertDelegatedOperatorAuthorizationActive(keyResolution.operatorAuthorizationValidUntil, currentTime());
144
+ }
137
145
  const remaining = parsedInput.params.expires - now + CLOCK_SKEW_TOLERANCE_SECONDS;
138
146
  const ttl = Math.max(remaining, MAX_SIGNATURE_WINDOW_SECONDS + CLOCK_SKEW_TOLERANCE_SECONDS);
139
147
  const insertResult = await options.replayStore.insert(jwk.kid, replayScope, parsedInput.params.nonce, ttl, now);
@@ -151,8 +159,34 @@ async function verifyWebhookSignature(request, options) {
151
159
  `Per-keyid replay cache cap exceeded on commit for keyid=${jwk.kid}.`
152
160
  );
153
161
  }
162
+ if (keyResolution.operatorAuthorizationValidUntil !== void 0) {
163
+ assertDelegatedOperatorAuthorizationActive(keyResolution.operatorAuthorizationValidUntil, currentTime());
164
+ }
154
165
  const agent_url = options.agentUrlForKeyid?.(jwk.kid);
155
- return { status: "verified", keyid: jwk.kid, ...agent_url !== void 0 && { agent_url }, verified_at: now };
166
+ return {
167
+ status: "verified",
168
+ keyid: jwk.kid,
169
+ ...agent_url !== void 0 && { agent_url },
170
+ // Keep the established whole-second credential timestamp while using the
171
+ // fractional clock above for exact authorization-expiry enforcement.
172
+ verified_at: Math.floor(now)
173
+ };
174
+ }
175
+ function assertDelegatedOperatorAuthorizationActive(validUntil, now) {
176
+ if (validUntil !== void 0 && (!Number.isFinite(validUntil) || now >= validUntil)) {
177
+ throw new WebhookSignatureError(
178
+ "webhook_signature_key_unknown",
179
+ 7,
180
+ "The signing key is no longer authorized for this webhook registration."
181
+ );
182
+ }
183
+ }
184
+ function replayScopeForWebhook(canonicalTarget, binding) {
185
+ if (binding === void 0) return canonicalTarget;
186
+ if (binding.length === 0 || binding.length > 1024 || binding.includes("\0")) {
187
+ throw new TypeError("replayScopeBinding must be a non-empty string of at most 1024 characters without NUL.");
188
+ }
189
+ return JSON.stringify([canonicalTarget, binding]);
156
190
  }
157
191
  function requireParams(parsed) {
158
192
  const required = ["created", "expires", "nonce", "keyid", "alg", "tag"];
@@ -94,6 +94,7 @@ export declare function discoverAgentProfile(client: TestClient, signal?: AbortS
94
94
  schemaAdcpVersion?: string): Promise<{
95
95
  profile: AgentProfile;
96
96
  step: TestStepResult;
97
+ caughtError?: unknown;
97
98
  }>;
98
99
  /**
99
100
  * Discover what channels, pricing models, formats the agent supports
@@ -94,6 +94,7 @@ export declare function discoverAgentProfile(client: TestClient, signal?: AbortS
94
94
  schemaAdcpVersion?: string): Promise<{
95
95
  profile: AgentProfile;
96
96
  step: TestStepResult;
97
+ caughtError?: unknown;
97
98
  }>;
98
99
  /**
99
100
  * Discover what channels, pricing models, formats the agent supports
@@ -359,7 +359,11 @@ function describeVersionUnsupported(result, requestedVersion) {
359
359
  return `VERSION_UNSUPPORTED: ${requestedText}${supportedText}`;
360
360
  }
361
361
  async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
362
- const { result: agentInfo, step } = await runStep(
362
+ const {
363
+ result: agentInfo,
364
+ step,
365
+ caughtError
366
+ } = await runStep(
363
367
  "Discover agent capabilities",
364
368
  "getAgentInfo",
365
369
  () => raceWithSignal(client.getAgentInfo({ signal }), signal)
@@ -425,7 +429,7 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
425
429
  }
426
430
  }
427
431
  seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
428
- return { profile, step };
432
+ return { profile, step, ...caughtError !== void 0 && { caughtError } };
429
433
  }
430
434
  async function discoverAgentCapabilities(client, profile, options) {
431
435
  const steps = [];
@@ -321,7 +321,11 @@ function describeVersionUnsupported(result, requestedVersion) {
321
321
  return `VERSION_UNSUPPORTED: ${requestedText}${supportedText}`;
322
322
  }
323
323
  async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
324
- const { result: agentInfo, step } = await runStep(
324
+ const {
325
+ result: agentInfo,
326
+ step,
327
+ caughtError
328
+ } = await runStep(
325
329
  "Discover agent capabilities",
326
330
  "getAgentInfo",
327
331
  () => raceWithSignal(client.getAgentInfo({ signal }), signal)
@@ -387,7 +391,7 @@ async function discoverAgentProfile(client, signal, schemaAdcpVersion) {
387
391
  }
388
392
  }
389
393
  seedTestClientSigningCapability(client, profile, schemaAdcpVersion);
390
- return { profile, step };
394
+ return { profile, step, ...caughtError !== void 0 && { caughtError } };
391
395
  }
392
396
  async function discoverAgentCapabilities(client, profile, options) {
393
397
  const steps = [];
@@ -139,10 +139,10 @@ export declare function rotateStoryboardsForOffset<T>(items: readonly T[], offse
139
139
  * Centralized so the "run security.yaml against 401-happy agents" path and
140
140
  * the fallback "unreachable result" path share the same truth.
141
141
  *
142
- * Exported for direct unit tests of the keyword classifier — callers inside
142
+ * Exported for direct unit tests of the auth classifier — callers inside
143
143
  * the library should go through `comply()`, not this helper.
144
144
  */
145
- export declare function detectAuthRejection(agentUrl: string, errorMsg: string | undefined, signal?: AbortSignal, fetchFn?: typeof fetch): Promise<{
145
+ export declare function detectAuthRejection(agentUrl: string, errorMsg: string | undefined, signal?: AbortSignal, fetchFn?: typeof fetch, caughtError?: unknown, allowPrivateIp?: boolean): Promise<{
146
146
  isAuth: boolean;
147
147
  observations: AdvisoryObservation[];
148
148
  }>;
@@ -139,10 +139,10 @@ export declare function rotateStoryboardsForOffset<T>(items: readonly T[], offse
139
139
  * Centralized so the "run security.yaml against 401-happy agents" path and
140
140
  * the fallback "unreachable result" path share the same truth.
141
141
  *
142
- * Exported for direct unit tests of the keyword classifier — callers inside
142
+ * Exported for direct unit tests of the auth classifier — callers inside
143
143
  * the library should go through `comply()`, not this helper.
144
144
  */
145
- export declare function detectAuthRejection(agentUrl: string, errorMsg: string | undefined, signal?: AbortSignal, fetchFn?: typeof fetch): Promise<{
145
+ export declare function detectAuthRejection(agentUrl: string, errorMsg: string | undefined, signal?: AbortSignal, fetchFn?: typeof fetch, caughtError?: unknown, allowPrivateIp?: boolean): Promise<{
146
146
  isAuth: boolean;
147
147
  observations: AdvisoryObservation[];
148
148
  }>;
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
  var comply_exports = {};
30
20
  __export(comply_exports, {
@@ -55,7 +45,8 @@ var import_schema_loader = require('../../validation/schema-loader.js');
55
45
  var import_oauth_metadata_graph = require('../storyboard/oauth-metadata-graph/index.js');
56
46
  var import_version = require('../../version.js');
57
47
  var import_validations = require('../storyboard/validations.js');
58
- var import_address_guards = require('../../net/address-guards.js');
48
+ var import_agent_transport_fetch = require('../../net/agent-transport-fetch.js');
49
+ var import_authorization_required = require('../../auth/oauth/authorization-required.js');
59
50
  var import_functional_dispatch = require('../storyboard/request-signing/functional-dispatch.js');
60
51
  (0, import_default_invariants.registerDefaultInvariants)();
61
52
  const TRACK_ORDER = [
@@ -816,11 +807,11 @@ async function complyImpl(agentUrl, options) {
816
807
  const allObservations = [];
817
808
  let discoveryOptions = effectiveOptions;
818
809
  let discoveryClient = (0, import_client.createTestClient)(agentUrl, effectiveOptions.protocol ?? "mcp", discoveryOptions);
819
- let { profile, step: profileStep } = await (0, import_client.discoverAgentProfile)(
820
- discoveryClient,
821
- signal,
822
- complianceIndex.adcp_version
823
- );
810
+ let {
811
+ profile,
812
+ step: profileStep,
813
+ caughtError: profileCaughtError
814
+ } = await (0, import_client.discoverAgentProfile)(discoveryClient, signal, complianceIndex.adcp_version);
824
815
  if (testOptions.versionEnvelope === void 0 && profile.tools.includes("get_adcp_capabilities") && profile.raw_capabilities === void 0 && !profileStep.error?.startsWith("VERSION_UNSUPPORTED:")) {
825
816
  const legacyDiscoveryOptions = { ...effectiveOptions, versionEnvelope: "major-only" };
826
817
  const legacyDiscoveryClient = (0, import_client.createTestClient)(
@@ -834,6 +825,7 @@ async function complyImpl(agentUrl, options) {
834
825
  discoveryClient = legacyDiscoveryClient;
835
826
  profile = legacyDiscovery.profile;
836
827
  profileStep = legacyDiscovery.step;
828
+ profileCaughtError = legacyDiscovery.caughtError;
837
829
  }
838
830
  }
839
831
  effectiveOptions = applyNegotiatedComplianceVersionOptions(profile, effectiveOptions, {
@@ -889,7 +881,14 @@ async function complyImpl(agentUrl, options) {
889
881
  }
890
882
  if (!profileStep.passed) {
891
883
  const isVersionUnsupported = profileStep.error?.startsWith("VERSION_UNSUPPORTED:") === true;
892
- const authCheck = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(agentUrl, profileStep.error, signal, effectiveOptions.transport?.trustedFetchFn);
884
+ const authCheck = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(
885
+ agentUrl,
886
+ profileStep.error,
887
+ signal,
888
+ effectiveOptions.transport?.trustedFetchFn,
889
+ profileCaughtError,
890
+ effectiveOptions.transport?.allowPrivateIp
891
+ );
893
892
  if (authCheck.isAuth) {
894
893
  const degraded = { name: profile.name || "Unknown (auth required)", tools: [] };
895
894
  const candidate = explicitStoryboards?.length ? resolveExplicitStoryboards(explicitStoryboards, resolveOptions) : resolveFromCapabilities(degraded, resolveOptions).storyboards;
@@ -917,6 +916,7 @@ async function complyImpl(agentUrl, options) {
917
916
  start,
918
917
  effectiveOptions,
919
918
  complianceIndex.adcp_version,
919
+ profileCaughtError,
920
920
  signal
921
921
  );
922
922
  }
@@ -1106,17 +1106,22 @@ function buildComplyTimeoutBudgetObservation(timeout_ms, storyboardsExecuted, st
1106
1106
  source: { kind: "profile", code: "timeout-budget-exceeded" }
1107
1107
  };
1108
1108
  }
1109
- async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn) {
1109
+ async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn, caughtError, allowPrivateIp) {
1110
1110
  const err = errorMsg || "Unknown error";
1111
1111
  const observations = [];
1112
1112
  const lower = err.toLowerCase();
1113
- const hasOAuthSignal = lower.includes("oauth authorization") || lower.includes("requires oauth") || lower.includes("requires authorization") || lower.includes("oauth flow") || lower.includes("oauthflowhandler") || lower.includes("needsauthorizationerror") || lower.includes("www-authenticate") || lower.includes("bearer realm");
1114
- const isExplicitAuthError = lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || hasOAuthSignal || lower.includes("jws") || lower.includes("jwt") || lower.includes("signature verification");
1113
+ const hasLegacyAuthSignal = lower.includes("oauth authorization") || lower.includes("requires oauth") || lower.includes("requires authorization") || lower.includes("oauth flow") || lower.includes("oauthflowhandler") || lower.includes("needsauthorizationerror") || lower.includes("www-authenticate") || lower.includes("bearer realm");
1114
+ const hasValidatedOAuthSignal = caughtError instanceof import_authorization_required.NeedsAuthorizationError && (0, import_authorization_required.hasValidatedMcpAuthorizationRequirements)(caughtError.requirements, agentUrl);
1115
+ const isExplicitAuthError = lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || hasLegacyAuthSignal || hasValidatedOAuthSignal || lower.includes("jws") || lower.includes("jwt") || lower.includes("signature verification");
1115
1116
  let isAuth = isExplicitAuthError;
1116
1117
  if (!isAuth) {
1117
1118
  try {
1118
1119
  const probeSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3);
1119
- const probe = await (fetchFn ?? fetch)(agentUrl, {
1120
+ const transportFetch = (0, import_agent_transport_fetch.createAgentTransportFetch)(agentUrl, {
1121
+ trustedFetchFn: fetchFn,
1122
+ allowPrivateIp: allowPrivateIp ?? false
1123
+ });
1124
+ const probe = await transportFetch(agentUrl, {
1120
1125
  method: "POST",
1121
1126
  headers: { "Content-Type": "application/json" },
1122
1127
  redirect: "manual",
@@ -1127,20 +1132,18 @@ async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn) {
1127
1132
  }
1128
1133
  }
1129
1134
  if (isAuth) {
1130
- const { discoverOAuthMetadata } = await import("../../auth/oauth/discovery.js");
1131
- const oauthMeta = await discoverOAuthMetadata(agentUrl, {
1132
- trustedFetchFn: fetchFn,
1133
- allowPrivateIp: (0, import_address_guards.isLikelyPrivateUrl)(agentUrl)
1134
- });
1135
- const looksOAuth = oauthMeta !== null || hasOAuthSignal;
1135
+ const oauthRequirements = hasValidatedOAuthSignal ? caughtError.requirements : void 0;
1136
+ const looksOAuth = oauthRequirements !== void 0;
1136
1137
  if (looksOAuth) {
1137
- const issuer = oauthMeta?.issuer ? fenceAgentText((0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(oauthMeta.issuer), 200) : "(unknown)";
1138
+ const issuer = oauthRequirements?.authorizationServer ? fenceAgentText((0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(oauthRequirements.authorizationServer), 200) : "(unknown)";
1138
1139
  const safeAgentUrl = (0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(agentUrl);
1139
1140
  observations.push({
1140
1141
  category: "auth",
1141
1142
  severity: "error",
1142
1143
  message: `Agent requires OAuth (issuer: ${issuer}). Inline: adcp storyboard run ${safeAgentUrl} --oauth (requires a saved alias). Save once: adcp --save-auth <alias> ${safeAgentUrl} --oauth.`,
1143
- ...oauthMeta?.issuer && { evidence: { oauth_issuer: (0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(oauthMeta.issuer) } },
1144
+ ...oauthRequirements?.authorizationServer && {
1145
+ evidence: { oauth_issuer: (0, import_oauth_metadata_graph.redactOAuthUrlForOutput)(oauthRequirements.authorizationServer) }
1146
+ },
1144
1147
  source: { kind: "probe", code: "auth-oauth-required" }
1145
1148
  });
1146
1149
  } else {
@@ -1256,9 +1259,16 @@ async function runWithDegradedProfile(agentUrl, profile, storyboards, options, e
1256
1259
  notices: []
1257
1260
  };
1258
1261
  }
1259
- async function buildUnreachableResult(agentUrl, profile, errorMsg, start, effectiveOptions, adcpVersion, signal) {
1262
+ async function buildUnreachableResult(agentUrl, profile, errorMsg, start, effectiveOptions, adcpVersion, caughtError, signal) {
1260
1263
  const isVersionUnsupported = errorMsg?.startsWith("VERSION_UNSUPPORTED:") === true;
1261
- const { isAuth, observations } = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(agentUrl, errorMsg, signal, effectiveOptions.transport?.trustedFetchFn);
1264
+ const { isAuth, observations } = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(
1265
+ agentUrl,
1266
+ errorMsg,
1267
+ signal,
1268
+ effectiveOptions.transport?.trustedFetchFn,
1269
+ caughtError,
1270
+ effectiveOptions.transport?.allowPrivateIp
1271
+ );
1262
1272
  const err = (0, import_oauth_metadata_graph.redactOAuthUrlsInText)(errorMsg || "Unknown error");
1263
1273
  const headline = isAuth ? `Authentication required` : `Agent unreachable \u2014 ${err}`;
1264
1274
  return {
@@ -21,7 +21,11 @@ import { withExternalSchemaRoot } from "../../validation/schema-loader.mjs";
21
21
  import { redactOAuthUrlForOutput, redactOAuthUrlsInText } from "../storyboard/oauth-metadata-graph/index.mjs";
22
22
  import { LIBRARY_VERSION } from "../../version.mjs";
23
23
  import { validationFailsStep } from "../storyboard/validations.mjs";
24
- import { isLikelyPrivateUrl } from "../../net/address-guards.mjs";
24
+ import { createAgentTransportFetch } from "../../net/agent-transport-fetch.mjs";
25
+ import {
26
+ hasValidatedMcpAuthorizationRequirements,
27
+ NeedsAuthorizationError
28
+ } from "../../auth/oauth/authorization-required.mjs";
25
29
  import { applyFunctionalRequestSigning } from "../storyboard/request-signing/functional-dispatch.mjs";
26
30
  const TRACK_ORDER = [
27
31
  "core",
@@ -781,11 +785,11 @@ async function complyImpl(agentUrl, options) {
781
785
  const allObservations = [];
782
786
  let discoveryOptions = effectiveOptions;
783
787
  let discoveryClient = createTestClient(agentUrl, effectiveOptions.protocol ?? "mcp", discoveryOptions);
784
- let { profile, step: profileStep } = await discoverAgentProfile(
785
- discoveryClient,
786
- signal,
787
- complianceIndex.adcp_version
788
- );
788
+ let {
789
+ profile,
790
+ step: profileStep,
791
+ caughtError: profileCaughtError
792
+ } = await discoverAgentProfile(discoveryClient, signal, complianceIndex.adcp_version);
789
793
  if (testOptions.versionEnvelope === void 0 && profile.tools.includes("get_adcp_capabilities") && profile.raw_capabilities === void 0 && !profileStep.error?.startsWith("VERSION_UNSUPPORTED:")) {
790
794
  const legacyDiscoveryOptions = { ...effectiveOptions, versionEnvelope: "major-only" };
791
795
  const legacyDiscoveryClient = createTestClient(
@@ -799,6 +803,7 @@ async function complyImpl(agentUrl, options) {
799
803
  discoveryClient = legacyDiscoveryClient;
800
804
  profile = legacyDiscovery.profile;
801
805
  profileStep = legacyDiscovery.step;
806
+ profileCaughtError = legacyDiscovery.caughtError;
802
807
  }
803
808
  }
804
809
  effectiveOptions = applyNegotiatedComplianceVersionOptions(profile, effectiveOptions, {
@@ -854,7 +859,14 @@ async function complyImpl(agentUrl, options) {
854
859
  }
855
860
  if (!profileStep.passed) {
856
861
  const isVersionUnsupported = profileStep.error?.startsWith("VERSION_UNSUPPORTED:") === true;
857
- const authCheck = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(agentUrl, profileStep.error, signal, effectiveOptions.transport?.trustedFetchFn);
862
+ const authCheck = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(
863
+ agentUrl,
864
+ profileStep.error,
865
+ signal,
866
+ effectiveOptions.transport?.trustedFetchFn,
867
+ profileCaughtError,
868
+ effectiveOptions.transport?.allowPrivateIp
869
+ );
858
870
  if (authCheck.isAuth) {
859
871
  const degraded = { name: profile.name || "Unknown (auth required)", tools: [] };
860
872
  const candidate = explicitStoryboards?.length ? resolveExplicitStoryboards(explicitStoryboards, resolveOptions) : resolveFromCapabilities(degraded, resolveOptions).storyboards;
@@ -882,6 +894,7 @@ async function complyImpl(agentUrl, options) {
882
894
  start,
883
895
  effectiveOptions,
884
896
  complianceIndex.adcp_version,
897
+ profileCaughtError,
885
898
  signal
886
899
  );
887
900
  }
@@ -1071,17 +1084,22 @@ function buildComplyTimeoutBudgetObservation(timeout_ms, storyboardsExecuted, st
1071
1084
  source: { kind: "profile", code: "timeout-budget-exceeded" }
1072
1085
  };
1073
1086
  }
1074
- async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn) {
1087
+ async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn, caughtError, allowPrivateIp) {
1075
1088
  const err = errorMsg || "Unknown error";
1076
1089
  const observations = [];
1077
1090
  const lower = err.toLowerCase();
1078
- const hasOAuthSignal = lower.includes("oauth authorization") || lower.includes("requires oauth") || lower.includes("requires authorization") || lower.includes("oauth flow") || lower.includes("oauthflowhandler") || lower.includes("needsauthorizationerror") || lower.includes("www-authenticate") || lower.includes("bearer realm");
1079
- const isExplicitAuthError = lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || hasOAuthSignal || lower.includes("jws") || lower.includes("jwt") || lower.includes("signature verification");
1091
+ const hasLegacyAuthSignal = lower.includes("oauth authorization") || lower.includes("requires oauth") || lower.includes("requires authorization") || lower.includes("oauth flow") || lower.includes("oauthflowhandler") || lower.includes("needsauthorizationerror") || lower.includes("www-authenticate") || lower.includes("bearer realm");
1092
+ const hasValidatedOAuthSignal = caughtError instanceof NeedsAuthorizationError && hasValidatedMcpAuthorizationRequirements(caughtError.requirements, agentUrl);
1093
+ const isExplicitAuthError = lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || hasLegacyAuthSignal || hasValidatedOAuthSignal || lower.includes("jws") || lower.includes("jwt") || lower.includes("signature verification");
1080
1094
  let isAuth = isExplicitAuthError;
1081
1095
  if (!isAuth) {
1082
1096
  try {
1083
1097
  const probeSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3);
1084
- const probe = await (fetchFn ?? fetch)(agentUrl, {
1098
+ const transportFetch = createAgentTransportFetch(agentUrl, {
1099
+ trustedFetchFn: fetchFn,
1100
+ allowPrivateIp: allowPrivateIp ?? false
1101
+ });
1102
+ const probe = await transportFetch(agentUrl, {
1085
1103
  method: "POST",
1086
1104
  headers: { "Content-Type": "application/json" },
1087
1105
  redirect: "manual",
@@ -1092,20 +1110,18 @@ async function detectAuthRejection(agentUrl, errorMsg, signal, fetchFn) {
1092
1110
  }
1093
1111
  }
1094
1112
  if (isAuth) {
1095
- const { discoverOAuthMetadata } = await import("../../auth/oauth/discovery.mjs");
1096
- const oauthMeta = await discoverOAuthMetadata(agentUrl, {
1097
- trustedFetchFn: fetchFn,
1098
- allowPrivateIp: isLikelyPrivateUrl(agentUrl)
1099
- });
1100
- const looksOAuth = oauthMeta !== null || hasOAuthSignal;
1113
+ const oauthRequirements = hasValidatedOAuthSignal ? caughtError.requirements : void 0;
1114
+ const looksOAuth = oauthRequirements !== void 0;
1101
1115
  if (looksOAuth) {
1102
- const issuer = oauthMeta?.issuer ? fenceAgentText(redactOAuthUrlForOutput(oauthMeta.issuer), 200) : "(unknown)";
1116
+ const issuer = oauthRequirements?.authorizationServer ? fenceAgentText(redactOAuthUrlForOutput(oauthRequirements.authorizationServer), 200) : "(unknown)";
1103
1117
  const safeAgentUrl = redactOAuthUrlForOutput(agentUrl);
1104
1118
  observations.push({
1105
1119
  category: "auth",
1106
1120
  severity: "error",
1107
1121
  message: `Agent requires OAuth (issuer: ${issuer}). Inline: adcp storyboard run ${safeAgentUrl} --oauth (requires a saved alias). Save once: adcp --save-auth <alias> ${safeAgentUrl} --oauth.`,
1108
- ...oauthMeta?.issuer && { evidence: { oauth_issuer: redactOAuthUrlForOutput(oauthMeta.issuer) } },
1122
+ ...oauthRequirements?.authorizationServer && {
1123
+ evidence: { oauth_issuer: redactOAuthUrlForOutput(oauthRequirements.authorizationServer) }
1124
+ },
1109
1125
  source: { kind: "probe", code: "auth-oauth-required" }
1110
1126
  });
1111
1127
  } else {
@@ -1221,9 +1237,16 @@ async function runWithDegradedProfile(agentUrl, profile, storyboards, options, e
1221
1237
  notices: []
1222
1238
  };
1223
1239
  }
1224
- async function buildUnreachableResult(agentUrl, profile, errorMsg, start, effectiveOptions, adcpVersion, signal) {
1240
+ async function buildUnreachableResult(agentUrl, profile, errorMsg, start, effectiveOptions, adcpVersion, caughtError, signal) {
1225
1241
  const isVersionUnsupported = errorMsg?.startsWith("VERSION_UNSUPPORTED:") === true;
1226
- const { isAuth, observations } = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(agentUrl, errorMsg, signal, effectiveOptions.transport?.trustedFetchFn);
1242
+ const { isAuth, observations } = isVersionUnsupported ? { isAuth: false, observations: [] } : await detectAuthRejection(
1243
+ agentUrl,
1244
+ errorMsg,
1245
+ signal,
1246
+ effectiveOptions.transport?.trustedFetchFn,
1247
+ caughtError,
1248
+ effectiveOptions.transport?.allowPrivateIp
1249
+ );
1227
1250
  const err = redactOAuthUrlsInText(errorMsg || "Unknown error");
1228
1251
  const headline = isAuth ? `Authentication required` : `Agent unreachable \u2014 ${err}`;
1229
1252
  return {
@@ -1,3 +1,4 @@
1
+ export { buildProtectedResourceMetadataUrl, normalizeOAuthResourceForComparison, } from '../../../auth/oauth/resource-url.mjs';
1
2
  import type { OAuthMetadataGraphGrade } from './types.mjs';
2
3
  export interface GradeOAuthMetadataGraphOptions {
3
4
  /** Explicit local-development opt-in. Production grading remains HTTPS-only. */
@@ -6,16 +7,9 @@ export interface GradeOAuthMetadataGraphOptions {
6
7
  /** Trusted scoped fetch supplied by a hosted runner; it must enforce peer-address binding. */
7
8
  trustedFetchFn?: typeof fetch;
8
9
  }
9
- /**
10
- * Shared RFC 9728 comparison semantics used by security.yaml and oauth_setup.
11
- * Only scheme and host are case-folded and default ports are elided. The
12
- * path, query, fragment, userinfo, and trailing slash remain significant.
13
- */
14
- export declare function normalizeOAuthResourceForComparison(value: string): string;
15
10
  /** Redact sensitive URL components before including a URL in a report. */
16
11
  export declare function redactOAuthUrlForOutput(value: string): string;
17
12
  /** Redact absolute URLs embedded in diagnostic text before report serialization. */
18
13
  export declare function redactOAuthUrlsInText(value: string): string;
19
- export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
20
14
  export declare function buildAuthorizationServerMetadataUrl(issuer: string): string;
21
15
  export declare function gradeOAuthMetadataGraph(agentUrl: string, options?: GradeOAuthMetadataGraphOptions): Promise<OAuthMetadataGraphGrade>;
@@ -1,3 +1,4 @@
1
+ export { buildProtectedResourceMetadataUrl, normalizeOAuthResourceForComparison, } from '../../../auth/oauth/resource-url';
1
2
  import type { OAuthMetadataGraphGrade } from './types';
2
3
  export interface GradeOAuthMetadataGraphOptions {
3
4
  /** Explicit local-development opt-in. Production grading remains HTTPS-only. */
@@ -6,16 +7,9 @@ export interface GradeOAuthMetadataGraphOptions {
6
7
  /** Trusted scoped fetch supplied by a hosted runner; it must enforce peer-address binding. */
7
8
  trustedFetchFn?: typeof fetch;
8
9
  }
9
- /**
10
- * Shared RFC 9728 comparison semantics used by security.yaml and oauth_setup.
11
- * Only scheme and host are case-folded and default ports are elided. The
12
- * path, query, fragment, userinfo, and trailing slash remain significant.
13
- */
14
- export declare function normalizeOAuthResourceForComparison(value: string): string;
15
10
  /** Redact sensitive URL components before including a URL in a report. */
16
11
  export declare function redactOAuthUrlForOutput(value: string): string;
17
12
  /** Redact absolute URLs embedded in diagnostic text before report serialization. */
18
13
  export declare function redactOAuthUrlsInText(value: string): string;
19
- export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
20
14
  export declare function buildAuthorizationServerMetadataUrl(issuer: string): string;
21
15
  export declare function gradeOAuthMetadataGraph(agentUrl: string, options?: GradeOAuthMetadataGraphOptions): Promise<OAuthMetadataGraphGrade>;
@@ -19,16 +19,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var grader_exports = {};
20
20
  __export(grader_exports, {
21
21
  buildAuthorizationServerMetadataUrl: () => buildAuthorizationServerMetadataUrl,
22
- buildProtectedResourceMetadataUrl: () => buildProtectedResourceMetadataUrl,
22
+ buildProtectedResourceMetadataUrl: () => import_resource_url.buildProtectedResourceMetadataUrl,
23
23
  gradeOAuthMetadataGraph: () => gradeOAuthMetadataGraph,
24
24
  gradeOAuthMetadataGraphWithTransport: () => gradeOAuthMetadataGraphWithTransport,
25
- normalizeOAuthResourceForComparison: () => normalizeOAuthResourceForComparison,
25
+ normalizeOAuthResourceForComparison: () => import_resource_url.normalizeOAuthResourceForComparison,
26
26
  redactOAuthUrlForOutput: () => redactOAuthUrlForOutput,
27
27
  redactOAuthUrlsInText: () => redactOAuthUrlsInText
28
28
  });
29
29
  module.exports = __toCommonJS(grader_exports);
30
30
  var import_address_guards = require('../../../net/address-guards.js');
31
31
  var import_ssrf_fetch = require('../../../net/ssrf-fetch.js');
32
+ var import_resource_url = require('../../../auth/oauth/resource-url.js');
33
+ var import_resource_url2 = require('../../../auth/oauth/resource-url.js');
32
34
  const LIMITS = Object.freeze({
33
35
  authorizationServers: 16,
34
36
  uniqueUrls: 64,
@@ -53,40 +55,6 @@ const DIAGNOSTIC_ORDER = Object.freeze([
53
55
  "oauth_endpoint_unreachable",
54
56
  "oauth_jwks_unavailable"
55
57
  ]);
56
- function normalizeOAuthResourceForComparison(value) {
57
- const match = /^([A-Za-z][A-Za-z\d+.-]*):\/\/([^/?#]*)([\s\S]*)$/.exec(value);
58
- if (!match) return value;
59
- const scheme = match[1].toLowerCase();
60
- const authority = match[2];
61
- const remainder = match[3];
62
- const at = authority.lastIndexOf("@");
63
- const userinfo = at >= 0 ? authority.slice(0, at + 1) : "";
64
- const hostAndPort = at >= 0 ? authority.slice(at + 1) : authority;
65
- let host;
66
- let port = "";
67
- if (hostAndPort.startsWith("[")) {
68
- const bracket = hostAndPort.indexOf("]");
69
- if (bracket < 0) return value;
70
- host = hostAndPort.slice(0, bracket + 1).toLowerCase();
71
- const suffix = hostAndPort.slice(bracket + 1);
72
- if (suffix && !/^:\d+$/.test(suffix)) return value;
73
- port = suffix.slice(1);
74
- } else {
75
- const colon = hostAndPort.lastIndexOf(":");
76
- if (colon >= 0) {
77
- const suffix = hostAndPort.slice(colon + 1);
78
- if (!/^\d+$/.test(suffix)) return value;
79
- host = hostAndPort.slice(0, colon).toLowerCase();
80
- port = suffix;
81
- } else {
82
- host = hostAndPort.toLowerCase();
83
- }
84
- }
85
- if (!host) return value;
86
- const defaultPort = scheme === "https" ? "443" : scheme === "http" ? "80" : void 0;
87
- const renderedPort = port && port !== defaultPort ? `:${port}` : "";
88
- return `${scheme}://${userinfo}${host}${renderedPort}${remainder}`;
89
- }
90
58
  function redactOAuthUrlForOutput(value) {
91
59
  try {
92
60
  const u = new URL(value);
@@ -104,10 +72,6 @@ function redactOAuthUrlForOutput(value) {
104
72
  function redactOAuthUrlsInText(value) {
105
73
  return value.replace(/https?:\/\/[^\s"'<>]+/gi, (url) => redactOAuthUrlForOutput(url));
106
74
  }
107
- function buildProtectedResourceMetadataUrl(agentUrl) {
108
- const u = new URL(agentUrl);
109
- return `${u.origin}/.well-known/oauth-protected-resource${u.pathname}`;
110
- }
111
75
  function buildAuthorizationServerMetadataUrl(issuer) {
112
76
  const u = new URL(issuer);
113
77
  const issuerPath = u.pathname === "/" ? "" : u.pathname;
@@ -132,7 +96,7 @@ async function gradeOAuthMetadataGraphWithTransport(agentUrl, options = {}) {
132
96
  const findings = [];
133
97
  let protectedResourceUrl;
134
98
  try {
135
- protectedResourceUrl = buildProtectedResourceMetadataUrl(agentUrl);
99
+ protectedResourceUrl = (0, import_resource_url2.buildProtectedResourceMetadataUrl)(agentUrl);
136
100
  } catch {
137
101
  protectedResourceUrl = redactOAuthUrlForOutput(agentUrl);
138
102
  findings.push(finding("oauth_protected_resource_metadata_invalid", "Agent URL is not an absolute URL."));
@@ -177,7 +141,7 @@ async function gradeOAuthMetadataGraphWithTransport(agentUrl, options = {}) {
177
141
  "resource"
178
142
  )
179
143
  );
180
- } else if (normalizeOAuthResourceForComparison(resource) !== normalizeOAuthResourceForComparison(agentUrl)) {
144
+ } else if ((0, import_resource_url2.normalizeOAuthResourceForComparison)(resource) !== (0, import_resource_url2.normalizeOAuthResourceForComparison)(agentUrl)) {
181
145
  findings.push(
182
146
  finding(
183
147
  "oauth_resource_mismatch",