@peac/mappings-a2a 0.13.0 → 0.13.2
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.
- package/dist/auth/evidence.d.ts +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/auth/evidence.d.ts
CHANGED
|
@@ -33,10 +33,10 @@ export interface A2AAuthEvent {
|
|
|
33
33
|
readonly timestamp?: string;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
-
* Output structure for the access extension in a Wire 0.2
|
|
36
|
+
* Output structure for the access extension in a Wire 0.2 record.
|
|
37
37
|
*
|
|
38
38
|
* Uses `org.peacprotocol/access` extension group with `auth_event`
|
|
39
|
-
* set to `'observation'` to distinguish from access-decision
|
|
39
|
+
* set to `'observation'` to distinguish from access-decision records.
|
|
40
40
|
*/
|
|
41
41
|
export interface A2AAuthEvidenceResult {
|
|
42
42
|
/** Extension key for receipt `ext` field */
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/normalizers.ts","../src/attach.ts","../src/extract.ts","../src/carrier.ts","../src/header.ts","../src/discovery.ts","../src/auth/pkce.ts","../src/auth/oauth.ts","../src/auth/evidence.ts","../src/auth/errors.ts"],"names":["validateCarrierConstraints","PeacEvidenceCarrierSchema","verifyReceiptRefConsistency","PEAC_RECEIPT_HEADER","ERROR_CODES","ACCESS_EXTENSION_KEY"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * A2A v1.0.0 types.\n *\n * These types are defined locally rather than importing @a2a-js/sdk,\n * which brings protobuf + gRPC + express peer dependencies that are\n * not needed for evidence placement.\n *\n * A2A v0.3.0 compatibility (DD-186) was deprecated in v0.12.3 and\n * removed in v0.13.0 (DD-186 removal target honored). Agent Cards\n * carrying only a top-level `url` (the v0.3.0 shape) are no longer\n * accepted; every card must expose `supportedInterfaces[0].url`.\n * TaskState values must use the v1.0.0 prefixed SCREAMING_SNAKE_CASE\n * form; v0.3.0 kebab-case values are no longer mapped.\n */\n\nimport type { CarrierFormat, PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** PEAC traceability extension URI for A2A metadata */\nexport const PEAC_EXTENSION_URI = 'https://www.peacprotocol.org/ext/traceability/v1' as const;\n\n/** Maximum carrier size for A2A metadata (64 KB) */\nexport const A2A_MAX_CARRIER_SIZE = 65_536;\n\n// ---------------------------------------------------------------------------\n// A2A Agent Card types (v1.0.0)\n// ---------------------------------------------------------------------------\n\n/** A2A extension entry in capabilities.extensions[] */\nexport interface AgentCardExtension {\n uri: string;\n description?: string;\n required?: boolean;\n params?: Record<string, unknown>;\n}\n\n/** PEAC-specific extension entry for A2A Agent Card */\nexport interface AgentCardPeacExtension {\n uri: typeof PEAC_EXTENSION_URI;\n description: string;\n required: boolean;\n params?: {\n supported_kinds?: string[];\n carrier_formats?: CarrierFormat[];\n issuer_config_url?: string;\n };\n}\n\n/** A2A v1.0.0 supported interface entry */\nexport interface A2ASupportedInterface {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n}\n\n/**\n * Minimal A2A Agent Card shape (v1.0.0).\n *\n * v1.0.0 cards expose endpoint bindings via `supportedInterfaces[]`.\n * Every accepted card MUST carry a non-empty `supportedInterfaces[0].url`.\n *\n * The legacy v0.3.0 top-level `url` field is no longer a declared field\n * on this interface. Rejection is **runtime** (`normalizeAgentCard` returns\n * null and `discoverAgentCard` skips the card), not type-level. The\n * interface intentionally keeps a `[key: string]: unknown` index\n * signature so consumers may pass incoming JSON with unknown extra\n * fields without TypeScript errors, so a literal with a stray `url`\n * string property still typechecks. The v0.3.0 removal is enforced by\n * the normalization layer, not by the type system.\n */\nexport interface A2AAgentCard {\n name: string;\n supportedInterfaces?: A2ASupportedInterface[];\n capabilities?: {\n extensions?: AgentCardExtension[];\n extendedAgentCard?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A message types (minimal shapes)\n// ---------------------------------------------------------------------------\n\n/** A2A metadata map */\nexport type A2AMetadata = Record<string, unknown>;\n\n/** Minimal A2A TaskStatus shape */\nexport interface A2ATaskStatusLike {\n state: string;\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Message shape */\nexport interface A2AMessageLike {\n role: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Artifact shape */\nexport interface A2AArtifactLike {\n artifactId: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A v1.0.0 enum constants (reference values)\n// ---------------------------------------------------------------------------\n\n/** A2A v1.0.0 TaskState values (SCREAMING_SNAKE_CASE with type prefix) */\nexport const A2A_V1_TASK_STATE = {\n SUBMITTED: 'TASK_STATE_SUBMITTED',\n WORKING: 'TASK_STATE_WORKING',\n COMPLETED: 'TASK_STATE_COMPLETED',\n FAILED: 'TASK_STATE_FAILED',\n CANCELED: 'TASK_STATE_CANCELED',\n REJECTED: 'TASK_STATE_REJECTED',\n INPUT_REQUIRED: 'TASK_STATE_INPUT_REQUIRED',\n AUTH_REQUIRED: 'TASK_STATE_AUTH_REQUIRED',\n} as const;\n\n/** A2A v1.0.0 MessageRole values */\nexport const A2A_V1_MESSAGE_ROLE = {\n USER: 'ROLE_USER',\n AGENT: 'ROLE_AGENT',\n} as const;\n\n// The v0.3.0 → v1.0.0 TaskState mapping (previously TASK_STATE_V03_TO_V1)\n// was removed in v0.13.0 alongside the v0.3.0 compat path (DD-186).\n// Callers MUST supply v1.0.0 TaskState values directly.\n\n// ---------------------------------------------------------------------------\n// Carrier payload type\n// ---------------------------------------------------------------------------\n\n/**\n * A2A carrier payload: the value stored under metadata[PEAC_EXTENSION_URI].\n *\n * Contains an array of carriers (even for single-receipt cases) and\n * optional transport metadata.\n */\nexport interface A2APeacPayload {\n carriers: PeacEvidenceCarrier[];\n meta?: CarrierMeta;\n}\n","/**\n * A2A v1.0.0 Agent Card normalizers.\n *\n * The v0.3.0 compatibility path (DD-186; `url` top-level field plus\n * kebab-case TaskState mapping) was deprecated in v0.12.3 and removed\n * in v0.13.0. Every accepted Agent Card must expose a non-empty\n * `supportedInterfaces[0].url`; cards without it are rejected. The\n * v0.3.0-to-v1.0.0 TaskState mapping function was removed because its\n * only job was translating kebab-case inputs, which are no longer\n * accepted. TaskState values are now v1.0.0 SCREAMING_SNAKE_CASE\n * strings carried by the caller.\n */\n\nimport type { A2AAgentCard, A2ASupportedInterface } from './types';\n\n// ---------------------------------------------------------------------------\n// Agent Card normalizer\n// ---------------------------------------------------------------------------\n\n/** Normalized Agent Card with a resolved v1.0.0 URL. */\nexport interface NormalizedAgentCard {\n name: string;\n url: string;\n supportedInterfaces: A2ASupportedInterface[];\n original: A2AAgentCard;\n}\n\n/**\n * Returns true if the card satisfies the v1.0.0 Agent Card contract:\n * `supportedInterfaces[0].url` exists and is a non-empty string. Cards\n * that fail this check are rejected by `normalizeAgentCard` (they are\n * not v0.3.0 fallbacks, which are no longer accepted).\n */\nexport function isV1AgentCard(card: A2AAgentCard): boolean {\n return (\n Array.isArray(card.supportedInterfaces) &&\n card.supportedInterfaces.length > 0 &&\n typeof card.supportedInterfaces[0]?.url === 'string' &&\n card.supportedInterfaces[0].url.length > 0\n );\n}\n\n/**\n * Normalize an A2A v1.0.0 Agent Card.\n *\n * Returns a consistent shape with the resolved primary URL. Cards that\n * do not satisfy `isV1AgentCard(...)` return `null` (this includes the\n * legacy v0.3.0 shape with only a top-level `url`, which is no longer\n * supported). Callers receiving `null` should treat the card as invalid\n * and surface a structured error rather than falling back to v0.3.0.\n */\nexport function normalizeAgentCard(card: A2AAgentCard): NormalizedAgentCard | null {\n if (!isV1AgentCard(card)) return null;\n const iface = card.supportedInterfaces![0]!;\n return {\n name: card.name,\n url: iface.url,\n supportedInterfaces: card.supportedInterfaces!,\n original: card,\n };\n}\n\n/**\n * Select the best interface from a v1.0.0 Agent Card.\n *\n * Prefers the interface with the highest protocolVersion, then the first\n * entry as tiebreaker.\n */\nexport function selectBestInterface(\n interfaces: A2ASupportedInterface[]\n): A2ASupportedInterface | null {\n if (interfaces.length === 0) return null;\n return [...interfaces].sort((a, b) =>\n b.protocolVersion.localeCompare(a.protocolVersion, undefined, { numeric: true })\n )[0]!;\n}\n","/**\n * Attach PEAC evidence carriers to A2A metadata.\n *\n * Places carrier data under metadata[PEAC_EXTENSION_URI] per the A2A\n * extension-URI metadata convention (inherited from v0.3.0 and carried\n * forward in v1.0.0). Uses computeReceiptRef() from @peac/schema for\n * receipt reference computation.\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Default meta for A2A transport\n// ---------------------------------------------------------------------------\n\nfunction defaultA2AMeta(): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Core attach: metadata map\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A metadata map.\n *\n * Writes `metadata[PEAC_EXTENSION_URI] = { carriers: [...], meta }`.\n * Validates carrier constraints before attachment; throws on violation.\n *\n * @returns The modified metadata map (mutated in place and returned)\n */\nexport function attachReceiptToMetadata(\n metadata: A2AMetadata,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMetadata {\n const effectiveMeta = meta ?? defaultA2AMeta();\n\n for (const carrier of carriers) {\n const result = validateCarrierConstraints(carrier, effectiveMeta);\n if (!result.valid) {\n throw new Error(`Carrier constraint violation: ${result.violations.join('; ')}`);\n }\n }\n\n const payload: A2APeacPayload = { carriers, meta: effectiveMeta };\n metadata[PEAC_EXTENSION_URI] = payload;\n return metadata;\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: attach to A2A message types\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A TaskStatus.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToTaskStatus(\n status: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2ATaskStatusLike {\n if (!status.metadata) {\n status.metadata = {};\n }\n attachReceiptToMetadata(status.metadata, carriers, meta);\n return status;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Message.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToMessage(\n msg: A2AMessageLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMessageLike {\n if (!msg.metadata) {\n msg.metadata = {};\n }\n attachReceiptToMetadata(msg.metadata, carriers, meta);\n return msg;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Artifact.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToArtifact(\n artifact: A2AArtifactLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AArtifactLike {\n if (!artifact.metadata) {\n artifact.metadata = {};\n }\n attachReceiptToMetadata(artifact.metadata, carriers, meta);\n return artifact;\n}\n","/**\n * Extract PEAC evidence carriers from A2A metadata.\n *\n * Reads carrier data from metadata[PEAC_EXTENSION_URI] and validates\n * against PeacEvidenceCarrierSchema. Provides both sync (structural)\n * and async (receipt_ref consistency) extraction paths per .\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { PeacEvidenceCarrierSchema, verifyReceiptRefConsistency } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Result of carrier extraction */\nexport interface A2AExtractResult {\n receipts: PeacEvidenceCarrier[];\n meta: CarrierMeta;\n}\n\n/** Result of async extraction with consistency check */\nexport interface A2AExtractAsyncResult extends A2AExtractResult {\n /** Consistency violations (empty if all receipts are valid) */\n violations: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Core extract: metadata map (sync, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (sync).\n *\n * Performs structural validation only (schema check).\n * Returns null if no PEAC extension data is present.\n * Silently skips carriers that fail schema validation.\n */\nexport function extractReceiptFromMetadata(metadata: A2AMetadata): A2AExtractResult | null {\n const raw = metadata[PEAC_EXTENSION_URI];\n if (raw === undefined || raw === null) {\n return null;\n }\n\n // Validate payload shape\n if (typeof raw !== 'object' || !('carriers' in (raw as object))) {\n return null;\n }\n\n const payload = raw as A2APeacPayload;\n if (!Array.isArray(payload.carriers) || payload.carriers.length === 0) {\n return null;\n }\n\n // Validate each carrier against schema (validate at extraction)\n const validCarriers: PeacEvidenceCarrier[] = [];\n for (const carrier of payload.carriers) {\n const result = PeacEvidenceCarrierSchema.safeParse(carrier);\n if (result.success) {\n validCarriers.push(result.data as PeacEvidenceCarrier);\n }\n }\n\n if (validCarriers.length === 0) {\n return null;\n }\n\n const meta: CarrierMeta = payload.meta ?? {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n\n return { receipts: validCarriers, meta };\n}\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (async).\n *\n * Performs structural validation AND receipt_ref consistency check.\n * When receipt_jws is present, verifies sha256(receipt_jws) === receipt_ref.\n * Returns violations array for any carriers that fail the consistency check.\n */\nexport async function extractReceiptFromMetadataAsync(\n metadata: A2AMetadata\n): Promise<A2AExtractAsyncResult | null> {\n const syncResult = extractReceiptFromMetadata(metadata);\n if (syncResult === null) {\n return null;\n }\n\n const violations: string[] = [];\n const validCarriers: PeacEvidenceCarrier[] = [];\n\n for (const carrier of syncResult.receipts) {\n const error = await verifyReceiptRefConsistency(carrier);\n if (error !== null) {\n violations.push(error);\n } else {\n validCarriers.push(carrier);\n }\n }\n\n if (validCarriers.length === 0 && violations.length > 0) {\n return { receipts: [], meta: syncResult.meta, violations };\n }\n\n return { receipts: validCarriers, meta: syncResult.meta, violations };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: extract from A2A message types\n// ---------------------------------------------------------------------------\n\n/** Extract carriers from A2A TaskStatus (sync) */\nexport function extractReceiptFromTaskStatus(status: A2ATaskStatusLike): A2AExtractResult | null {\n if (!status.metadata) return null;\n return extractReceiptFromMetadata(status.metadata);\n}\n\n/** Extract carriers from A2A TaskStatus (async) */\nexport async function extractReceiptFromTaskStatusAsync(\n status: A2ATaskStatusLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!status.metadata) return null;\n return extractReceiptFromMetadataAsync(status.metadata);\n}\n\n/** Extract carriers from A2A Message (sync) */\nexport function extractReceiptFromMessage(msg: A2AMessageLike): A2AExtractResult | null {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadata(msg.metadata);\n}\n\n/** Extract carriers from A2A Message (async) */\nexport async function extractReceiptFromMessageAsync(\n msg: A2AMessageLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadataAsync(msg.metadata);\n}\n\n/** Extract carriers from A2A Artifact (sync) */\nexport function extractReceiptFromArtifact(artifact: A2AArtifactLike): A2AExtractResult | null {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadata(artifact.metadata);\n}\n\n/** Extract carriers from A2A Artifact (async) */\nexport async function extractReceiptFromArtifactAsync(\n artifact: A2AArtifactLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadataAsync(artifact.metadata);\n}\n","/**\n * A2A carrier adapter implementing CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike>.\n *\n * Bridges PeacEvidenceCarrier to A2A TaskStatus metadata per .\n */\n\nimport type {\n PeacEvidenceCarrier,\n CarrierMeta,\n CarrierValidationResult,\n CarrierAdapter,\n} from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type { A2ATaskStatusLike } from './types';\nimport { A2A_MAX_CARRIER_SIZE } from './types';\nimport { attachReceiptToTaskStatus } from './attach';\nimport { extractReceiptFromTaskStatus } from './extract';\n\n/**\n * CarrierAdapter implementation for A2A TaskStatus messages.\n *\n * Uses metadata[PEAC_EXTENSION_URI] = { carriers: [...] } layout.\n */\nexport class A2ACarrierAdapter implements CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike> {\n extract(input: A2ATaskStatusLike): { receipts: PeacEvidenceCarrier[]; meta: CarrierMeta } | null {\n return extractReceiptFromTaskStatus(input);\n }\n\n attach(\n output: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n ): A2ATaskStatusLike {\n return attachReceiptToTaskStatus(output, carriers, meta);\n }\n\n validateConstraints(carrier: PeacEvidenceCarrier, meta: CarrierMeta): CarrierValidationResult {\n return validateCarrierConstraints(carrier, meta);\n }\n}\n\n/** Default CarrierMeta for A2A transport */\nexport function createA2ACarrierMeta(overrides?: Partial<CarrierMeta>): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n ...overrides,\n };\n}\n","/**\n * A2A extension header utilities.\n *\n * Handles the A2A-Extensions header for advertising supported extensions\n * per (no X- prefix headers).\n */\n\n/**\n * Parse comma-separated A2A extension URIs from header value.\n *\n * @param header - Raw header value (e.g. \"https://example.com/ext/a, https://example.com/ext/b\")\n * @returns Array of trimmed, non-empty extension URIs\n */\nexport function parseA2AExtensionsHeader(header: string): string[] {\n return header\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Build comma-separated A2A-Extensions header value from URIs.\n *\n * @param extensions - Array of extension URIs\n * @returns Comma-separated header value\n */\nexport function buildA2AExtensionsHeader(extensions: string[]): string {\n return extensions.join(', ');\n}\n","/**\n * A2A agent discovery with SSRF hardening (Polish C).\n *\n * Discovers A2A Agent Cards and checks for PEAC extension support.\n * Implements literal-IP blocking, optional DNS resolution checks,\n * scheme allowlist, userinfo rejection, response size cap,\n * content-type check, and redirect rejection.\n */\n\nimport type { CarrierFormat } from '@peac/kernel';\nimport { PEAC_RECEIPT_HEADER } from '@peac/kernel';\n\nimport type { A2AAgentCard, AgentCardPeacExtension } from './types';\nimport { PEAC_EXTENSION_URI } from './types';\nimport { normalizeAgentCard } from './normalizers';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum response body size (256 KB) */\nconst MAX_RESPONSE_SIZE = 256 * 1024;\n\n/** Request timeout in milliseconds */\nconst DISCOVERY_TIMEOUT_MS = 5_000;\n\n/** Private/reserved IP ranges (RFC 1918, RFC 4193, loopback, link-local) */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // loopback\n /^10\\./, // RFC 1918 Class A\n /^172\\.(1[6-9]|2\\d|3[01])\\./, // RFC 1918 Class B\n /^192\\.168\\./, // RFC 1918 Class C\n /^169\\.254\\./, // link-local\n /^0\\./, // current network\n /^::1$/, // IPv6 loopback\n /^fd[0-9a-f]{2}:/, // RFC 4193 ULA\n /^fe80:/, // IPv6 link-local\n /^fc[0-9a-f]{2}:/, // RFC 4193 ULA\n];\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** Discovery options */\nexport interface DiscoveryOptions {\n /**\n * Allow HTTP (insecure) for localhost addresses only (dev mode).\n * Default: false (HTTPS only in production).\n */\n allowInsecureLocalhost?: boolean;\n\n /** Custom fetch implementation (for testing or strict environments) */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Optional DNS resolver for DNS rebinding defense.\n *\n * When provided, discovery resolves the hostname and checks all returned\n * IP addresses against private ranges before connecting. This provides\n * full DNS rebinding protection.\n *\n * When omitted, discovery checks only literal IP addresses in the URL\n * hostname (weaker posture, but portable across runtimes).\n */\n resolveHostname?: (hostname: string) => Promise<string[]>;\n}\n\n// ---------------------------------------------------------------------------\n// SSRF helpers\n// ---------------------------------------------------------------------------\n\nfunction isPrivateIP(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip));\n}\n\nfunction isLocalhostAddress(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';\n}\n\n/**\n * Validate URL scheme, hostname, and credentials for SSRF protection.\n *\n * - Only HTTPS in production (Polish C item 6)\n * - HTTP allowed only for localhost when allowInsecureLocalhost is true\n * - Rejects private IP ranges (literal check always; DNS resolution when resolver provided)\n * - Rejects URLs with userinfo (user:pass@host) to prevent confusion in allowlists\n */\nasync function validateUrlForDiscovery(url: string, options: DiscoveryOptions): Promise<void> {\n const parsed = new URL(url);\n\n // Reject URLs with userinfo (user:pass@host)\n if (parsed.username || parsed.password) {\n throw new Error('SSRF: URLs with userinfo (credentials) are not allowed');\n }\n\n // Scheme allowlist (Polish C item 6)\n if (parsed.protocol === 'http:') {\n if (!options.allowInsecureLocalhost || !isLocalhostAddress(parsed.hostname)) {\n throw new Error(\n `SSRF: HTTP scheme not allowed for ${parsed.hostname}. ` +\n 'Use HTTPS or enable allowInsecureLocalhost for local development.'\n );\n }\n } else if (parsed.protocol !== 'https:') {\n throw new Error(`SSRF: unsupported scheme ${parsed.protocol}`);\n }\n\n // Check for private IP in hostname (literal IP check)\n if (isPrivateIP(parsed.hostname) && !isLocalhostAddress(parsed.hostname)) {\n throw new Error(`SSRF: private IP address ${parsed.hostname} not allowed`);\n }\n\n // DNS rebinding defense: resolve hostname and check all IPs (when resolver provided)\n if (options.resolveHostname && !isLocalhostAddress(parsed.hostname)) {\n const resolvedIPs = await options.resolveHostname(parsed.hostname);\n for (const ip of resolvedIPs) {\n if (isPrivateIP(ip)) {\n throw new Error(`SSRF: hostname ${parsed.hostname} resolved to private IP ${ip}`);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover A2A Agent Card from a base URL.\n *\n * Fetches the A2A v1.0.0 canonical path `/.well-known/agent-card.json`.\n * The v0.3.0 legacy fallback `/.well-known/agent.json` was removed in\n * v0.13.0 (DD-186) alongside the rest of the v0.3.0 compatibility\n * surface; deployers still serving the legacy path should publish the\n * canonical path or upgrade to an A2A v1.0.0 implementation.\n *\n * SSRF protection per Polish C:\n * 1. Private IP blocking (literal check; DNS resolution when resolveHostname provided)\n * 2. Response size cap (256 KB)\n * 3. Content-Type check (application/json)\n * 4. Redirect rejection (redirect: \"error\")\n * 5. Timeout (5 seconds)\n * 6. Scheme allowlist (HTTPS only; HTTP for localhost dev only)\n * 7. Userinfo rejection (no credentials in URLs)\n */\nexport async function discoverAgentCard(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<A2AAgentCard | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const paths = ['/.well-known/agent-card.json'];\n\n for (const path of paths) {\n const url = new URL(path, baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error', // Polish C item 4\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n continue;\n }\n\n // Content-Type check (Polish C item 3)\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n continue;\n }\n\n // Response size cap (Polish C item 2)\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const card = JSON.parse(text) as A2AAgentCard;\n\n // v1.0.0 validation (DD-186; v0.3.0 rejected). Cards MUST expose a\n // valid `supportedInterfaces[0].url`. Cards carrying only a legacy\n // top-level `url` (the v0.3.0 shape) return null from\n // normalizeAgentCard and are skipped here.\n if (typeof card.name !== 'string') {\n continue;\n }\n const normalized = normalizeAgentCard(card);\n if (!normalized) {\n continue;\n }\n\n return card;\n } catch {\n // SSRF validation errors, network errors, parse errors: try next path\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Check if an A2A Agent Card advertises PEAC extension support.\n *\n * Looks for the PEAC extension URI in capabilities.extensions[].\n */\nexport function hasPeacExtension(card: A2AAgentCard): boolean {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return false;\n }\n return extensions.some(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n}\n\n/**\n * Extract PEAC extension parameters from an A2A Agent Card.\n *\n * Returns the PEAC extension entry or null if not present.\n */\nexport function getPeacExtension(card: A2AAgentCard): AgentCardPeacExtension | null {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return null;\n }\n const entry = extensions.find(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n return (entry as AgentCardPeacExtension) ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// PEAC discovery result\n// ---------------------------------------------------------------------------\n\n/** Source of PEAC capability discovery */\nexport type PeacDiscoverySource = 'agent_card' | 'well_known' | 'header_probe';\n\n/** Result of PEAC capability discovery */\nexport interface PeacDiscoveryResult {\n source: PeacDiscoverySource;\n kinds: string[];\n carrier_formats: CarrierFormat[];\n issuer_config_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// 3-step discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover PEAC capabilities from a base URL using a 3-step algorithm:\n *\n * 1. Agent Card: check `/.well-known/agent-card.json` for PEAC extension\n * 2. Well-known: check `/.well-known/peac.json` (standalone PEAC discovery)\n * 3. Header probe: HEAD request to base URL, check for `PEAC-Receipt` header\n *\n * Returns the first successful result or null if PEAC is not supported.\n * All steps apply SSRF protections per Polish C.\n */\nexport async function discoverPeacCapabilities(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<PeacDiscoveryResult | null> {\n // Step 1: Agent Card\n const card = await discoverAgentCard(baseUrl, options);\n if (card) {\n const ext = getPeacExtension(card);\n if (ext) {\n return {\n source: 'agent_card',\n kinds: ext.params?.supported_kinds ?? ['peac-receipt/0.1'],\n carrier_formats: ext.params?.carrier_formats ?? ['embed'],\n ...(ext.params?.issuer_config_url && {\n issuer_config_url: ext.params.issuer_config_url,\n }),\n };\n }\n }\n\n // Step 2: /.well-known/peac.json\n const wellKnown = await discoverPeacWellKnown(baseUrl, options);\n if (wellKnown) {\n return wellKnown;\n }\n\n // Step 3: Header probe\n const headerProbe = await discoverPeacViaHeaderProbe(baseUrl, options);\n if (headerProbe) {\n return headerProbe;\n }\n\n return null;\n}\n\n/**\n * Step 2: Discover PEAC support via `/.well-known/peac.json`.\n */\nasync function discoverPeacWellKnown(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const url = new URL('/.well-known/peac.json', baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) return null;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n return null;\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n return null;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) return null;\n\n const data = JSON.parse(text) as Record<string, unknown>;\n\n return {\n source: 'well_known',\n kinds: Array.isArray(data.supported_kinds)\n ? (data.supported_kinds as string[])\n : ['peac-receipt/0.1'],\n carrier_formats: Array.isArray(data.carrier_formats)\n ? (data.carrier_formats as CarrierFormat[])\n : ['embed'],\n ...(typeof data.issuer_config_url === 'string' && {\n issuer_config_url: data.issuer_config_url,\n }),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Step 3: Discover PEAC support via header probe.\n *\n * Sends a HEAD request and checks for the presence of a PEAC-Receipt header.\n * This is a lightweight probe; it indicates support but provides minimal detail.\n */\nasync function discoverPeacViaHeaderProbe(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n try {\n await validateUrlForDiscovery(baseUrl, options);\n\n const response = await fetchFn(baseUrl, {\n method: 'HEAD',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n const headerKey = [...response.headers.keys()].find(\n (k) => k.toLowerCase() === PEAC_RECEIPT_HEADER.toLowerCase()\n );\n\n if (headerKey) {\n return {\n source: 'header_probe',\n kinds: ['peac-receipt/0.1'],\n carrier_formats: ['embed'],\n };\n }\n } catch {\n // Network errors, SSRF: no PEAC support detected\n }\n\n return null;\n}\n","/**\n * PKCE (Proof Key for Code Exchange) utilities for A2A OAuth flows.\n *\n * Implements S256 challenge method per RFC 7636. Plain method is\n * rejected: S256 is the only method permitted by A2A v1.0.\n */\n\nimport { ERROR_CODES } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** RFC 7636 Section 4.1: verifier length range (43-128 unreserved chars) */\nconst VERIFIER_MIN_LENGTH = 43;\nconst VERIFIER_MAX_LENGTH = 128;\n\n/** RFC 7636 unreserved characters: [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\" */\nconst UNRESERVED_REGEX = /^[A-Za-z0-9\\-._~]+$/;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Result of PKCE challenge generation.\n */\nexport interface PKCEChallenge {\n /** High-entropy code verifier (43-128 unreserved chars) */\n readonly verifier: string;\n /** Base64url-encoded SHA-256 hash of the verifier */\n readonly challenge: string;\n /** Always 'S256' */\n readonly method: 'S256';\n}\n\n/**\n * Generate a PKCE code verifier and S256 challenge.\n *\n * Uses `crypto.getRandomValues()` for verifier entropy (32 bytes,\n * base64url-encoded to 43 chars). S256 only; plain method is not\n * supported per A2A v1.0 security requirements.\n *\n * @returns PKCE verifier + challenge pair\n */\nexport async function generatePKCEChallenge(): Promise<PKCEChallenge> {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n const verifier = base64urlEncodeBytes(bytes);\n const challenge = await computeS256Challenge(verifier);\n return { verifier, challenge, method: 'S256' };\n}\n\n/**\n * Compute the S256 challenge for a given verifier.\n *\n * `BASE64URL(SHA256(ASCII(code_verifier)))` per RFC 7636 Section 4.2.\n *\n * @param verifier - Code verifier string\n * @returns Base64url-encoded SHA-256 digest\n * @throws Error if verifier does not meet RFC 7636 requirements\n */\nexport async function computeS256Challenge(verifier: string): Promise<string> {\n validateVerifierFormat(verifier);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64urlEncodeBytes(new Uint8Array(digest));\n}\n\n/**\n * Validate that a PKCE code verifier meets RFC 7636 requirements.\n *\n * Checks length (43-128) and character set (unreserved per RFC 7636 Section 4.1).\n *\n * @param verifier - Code verifier to validate\n * @throws Error with code `E_PKCE_INVALID_VERIFIER` if invalid\n */\nexport function validatePKCEVerifier(verifier: string): void {\n validateVerifierFormat(verifier);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateVerifierFormat(verifier: string): void {\n if (verifier.length < VERIFIER_MIN_LENGTH || verifier.length > VERIFIER_MAX_LENGTH) {\n throw Object.assign(\n new Error(\n `PKCE verifier length ${verifier.length} outside allowed range [${VERIFIER_MIN_LENGTH}, ${VERIFIER_MAX_LENGTH}]`\n ),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n if (!UNRESERVED_REGEX.test(verifier)) {\n throw Object.assign(\n new Error('PKCE verifier contains characters outside RFC 7636 unreserved set'),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n}\n\n/**\n * Node-safe base64url encoding from raw bytes.\n *\n * Uses Buffer when available (Node.js), falls back to manual\n * byte-to-char conversion for non-Node runtimes.\n */\nfunction base64urlEncodeBytes(bytes: Uint8Array): string {\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n base64 = Array.from(bytes, (b) => String.fromCharCode(b)).join('');\n base64 = btoa(base64);\n }\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/**\n * OAuth 2.0 authorization code flow utilities for A2A v1.0.\n *\n * A2A v1.0 specifies OAuth 2.0 with PKCE as the preferred auth model.\n * All network calls accept a `fetchFn` parameter (no global fetch).\n *\n * Config field names mirror the A2A spec OAuth flow object:\n * authorizationUrl, tokenUrl, refreshUrl, scopes, pkceRequired.\n */\n\nimport { validatePKCEVerifier } from './pkce.js';\n\n// ---------------------------------------------------------------------------\n// Adapter-local fetch signature (not `typeof fetch`)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal fetch signature for OAuth network calls.\n *\n * Narrower than global `fetch` to avoid coupling to runtime-specific\n * fetch extensions (AbortSignal, Request objects, etc.).\n */\nexport type FetchFn = (\n url: string,\n init: {\n method: string;\n headers: Record<string, string>;\n body: string;\n }\n) => Promise<{\n ok: boolean;\n status: number;\n json: () => Promise<unknown>;\n text: () => Promise<string>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Types (A2A spec-faithful naming)\n// ---------------------------------------------------------------------------\n\n/**\n * OAuth 2.0 configuration for an A2A authorization server.\n *\n * Field names mirror the A2A spec OAuth flow object.\n */\nexport interface A2AOAuthConfig {\n /** Authorization endpoint URL (HTTPS required) */\n readonly authorizationUrl: string;\n /** Token endpoint URL (HTTPS required) */\n readonly tokenUrl: string;\n /** Refresh token endpoint URL (optional, HTTPS required) */\n readonly refreshUrl?: string;\n /** Client identifier */\n readonly clientId: string;\n /** Redirect URI for authorization code delivery (HTTPS required) */\n readonly redirectUri: string;\n /** Requested scopes */\n readonly scopes?: readonly string[];\n /** Whether PKCE is required (always true for A2A v1.0) */\n readonly pkceRequired?: boolean;\n /** Additional authorization parameters (must not override reserved params) */\n readonly extraParams?: Readonly<Record<string, string>>;\n}\n\n/**\n * Authorization request parameters for constructing the redirect URL.\n */\nexport interface AuthorizationRequest {\n /** Full authorization URL with query parameters */\n readonly url: string;\n /** PKCE code verifier (store securely; needed for token exchange) */\n readonly codeVerifier: string;\n /** State parameter for CSRF protection */\n readonly state: string;\n}\n\n/**\n * OAuth 2.0 token response from the authorization server.\n */\nexport interface TokenResponse {\n readonly access_token: string;\n readonly token_type: string;\n readonly expires_in?: number;\n readonly refresh_token?: string;\n readonly scope?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Reserved OAuth parameters that extraParams must not override\n// ---------------------------------------------------------------------------\n\nconst RESERVED_PARAMS = new Set([\n 'response_type',\n 'client_id',\n 'redirect_uri',\n 'code_challenge',\n 'code_challenge_method',\n 'state',\n 'scope',\n 'grant_type',\n 'code',\n 'code_verifier',\n]);\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build an authorization URL with PKCE challenge and state parameter.\n *\n * The caller must redirect the user-agent to the returned URL. The\n * `codeVerifier` must be stored securely for the subsequent token\n * exchange call.\n *\n * @param config - A2A OAuth server configuration\n * @param pkce - PKCE challenge pair (from `generatePKCEChallenge()`)\n * @returns Authorization request with URL, verifier, and state\n * @throws Error if endpoint URLs are not HTTPS or extraParams override reserved params\n */\nexport function buildAuthorizationRequest(\n config: A2AOAuthConfig,\n pkce: { readonly challenge: string; readonly verifier: string }\n): AuthorizationRequest {\n validateEndpointUrl(config.authorizationUrl, 'authorizationUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n\n if (config.extraParams) {\n for (const key of Object.keys(config.extraParams)) {\n if (RESERVED_PARAMS.has(key)) {\n throw new Error(`extraParams must not override reserved OAuth parameter: ${key}`);\n }\n }\n }\n\n const state = generateState();\n const authUrl = new URL(config.authorizationUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('client_id', config.clientId);\n authUrl.searchParams.set('redirect_uri', config.redirectUri);\n authUrl.searchParams.set('code_challenge', pkce.challenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('state', state);\n\n if (config.scopes && config.scopes.length > 0) {\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n }\n\n if (config.extraParams) {\n for (const [key, value] of Object.entries(config.extraParams)) {\n authUrl.searchParams.set(key, value);\n }\n }\n\n return { url: authUrl.toString(), codeVerifier: pkce.verifier, state };\n}\n\n/**\n * Exchange an authorization code for tokens.\n *\n * Sends a POST to the token endpoint with the authorization code and\n * PKCE code verifier. Validates the verifier format before sending.\n *\n * @param code - Authorization code from the redirect callback\n * @param verifier - PKCE code verifier from the authorization request\n * @param config - A2A OAuth server configuration\n * @param fetchFn - Fetch implementation (no global fetch)\n * @returns Token response from the authorization server\n * @throws Error if the token endpoint returns an error response\n */\nexport async function exchangeAuthorizationCode(\n code: string,\n verifier: string,\n config: A2AOAuthConfig,\n fetchFn: FetchFn\n): Promise<TokenResponse> {\n validateEndpointUrl(config.tokenUrl, 'tokenUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n validatePKCEVerifier(verifier);\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: config.redirectUri,\n client_id: config.clientId,\n code_verifier: verifier,\n });\n\n const response = await fetchFn(config.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw Object.assign(\n new Error(\n `Token exchange failed: HTTP ${response.status}${errorBody ? `: ${errorBody}` : ''}`\n ),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED', status: response.status }\n );\n }\n\n const tokenResponse = (await response.json()) as Record<string, unknown>;\n if (\n typeof tokenResponse.access_token !== 'string' ||\n typeof tokenResponse.token_type !== 'string'\n ) {\n throw Object.assign(\n new Error('Token response missing required fields (access_token, token_type)'),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED' }\n );\n }\n\n return tokenResponse as unknown as TokenResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateEndpointUrl(url: string, name: string): void {\n if (!url.startsWith('https://') && !isLocalhostHttp(url)) {\n throw new Error(`${name} must use HTTPS (got: ${url})`);\n }\n}\n\nfunction isLocalhostHttp(url: string): boolean {\n if (!url.startsWith('http://')) return false;\n try {\n const parsed = new URL(url);\n return parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n } catch {\n return false;\n }\n}\n\nfunction generateState(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","/**\n * A2A auth event to PEAC evidence mapping.\n *\n * Maps A2A OAuth authentication events to access extension observations.\n * Auth success produces an **observation** receipt, never an automatic\n * access-decision receipt. The caller must explicitly construct\n * access-decision receipts when a business-level decision is made.\n */\n\nimport type { JsonObject } from '@peac/kernel';\nimport { ACCESS_EXTENSION_KEY } from '@peac/schema';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported A2A auth methods */\nexport type A2AAuthMethod = 'oauth2_pkce' | 'oauth2_device_code' | 'oauth2_client_credentials';\n\n/**\n * Input event describing an A2A authentication occurrence.\n *\n * This represents what happened at the auth layer, not a business\n * decision about whether to grant access.\n */\nexport interface A2AAuthEvent {\n /** Auth method used */\n readonly method: A2AAuthMethod;\n /** Resource URI that was authenticated against */\n readonly resource: string;\n /** Action that was requested (e.g., 'authenticate', 'tasks/send') */\n readonly action: string;\n /** OAuth scopes that were granted (from token response) */\n readonly grantedScopes?: readonly string[];\n /** Authorization server that issued the token */\n readonly authServer?: string;\n /** Client identifier used */\n readonly clientId?: string;\n /** ISO 8601 timestamp of the auth event */\n readonly timestamp?: string;\n}\n\n/**\n * Output structure for the access extension in a Wire 0.2 receipt.\n *\n * Uses `org.peacprotocol/access` extension group with `auth_event`\n * set to `'observation'` to distinguish from access-decision receipts.\n */\nexport interface A2AAuthEvidenceResult {\n /** Extension key for receipt `ext` field */\n readonly extensionKey: typeof ACCESS_EXTENSION_KEY;\n /** Access extension fields for the receipt */\n readonly extension: {\n readonly resource: string;\n readonly action: string;\n readonly decision: 'review';\n };\n /** Additional evidence metadata for the receipt `evidence` field */\n readonly evidence: JsonObject;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Map an A2A auth event to access extension evidence.\n *\n * Produces an **observation** receipt: `decision` is always `'review'`,\n * indicating that authentication occurred but no access decision was\n * made by the evidence layer. Callers who need `'allow'` or `'deny'`\n * decisions must explicitly construct those receipts.\n *\n * Tokens are never included in the evidence. Only structural metadata\n * (method, scopes, server, client_id) is recorded.\n *\n * @param event - A2A auth event to map\n * @returns Extension data and evidence metadata for receipt construction\n */\nexport function fromA2AAuthEvent(event: A2AAuthEvent): A2AAuthEvidenceResult {\n if (!event.resource) {\n throw new Error('A2A auth event missing resource');\n }\n if (!event.action) {\n throw new Error('A2A auth event missing action');\n }\n\n const evidence: JsonObject = {\n auth_event: 'observation',\n auth_method: event.method,\n };\n\n if (event.grantedScopes && event.grantedScopes.length > 0) {\n evidence.granted_scopes = [...event.grantedScopes];\n }\n if (event.authServer) {\n evidence.auth_server = event.authServer;\n }\n if (event.clientId) {\n evidence.client_id = event.clientId;\n }\n if (event.timestamp) {\n evidence.timestamp = event.timestamp;\n }\n\n return {\n extensionKey: ACCESS_EXTENSION_KEY,\n extension: {\n resource: event.resource,\n action: event.action,\n decision: 'review',\n },\n evidence,\n };\n}\n","/**\n * A2A auth error mapping to google.rpc.Status with ErrorInfo.\n *\n * A2A v1.0 uses gRPC-style status codes for transport errors. For\n * A2A-specific errors, implementations include `google.rpc.ErrorInfo`\n * in `status.details[]`. This module produces the full Status + ErrorInfo\n * shape for auth-related A2A errors.\n */\n\n// ---------------------------------------------------------------------------\n// google.rpc canonical codes (subset relevant to auth)\n// ---------------------------------------------------------------------------\n\n/**\n * gRPC canonical status codes used in A2A auth error responses.\n * Values match google.rpc.Code numeric assignments.\n */\nexport const GrpcStatusCode = {\n OK: 0,\n INVALID_ARGUMENT: 3,\n NOT_FOUND: 5,\n PERMISSION_DENIED: 7,\n INTERNAL: 13,\n UNAVAILABLE: 14,\n UNAUTHENTICATED: 16,\n} as const;\n\nexport type GrpcStatusCodeValue = (typeof GrpcStatusCode)[keyof typeof GrpcStatusCode];\n\n// ---------------------------------------------------------------------------\n// google.rpc.ErrorInfo shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.ErrorInfo per https://cloud.google.com/apis/design/errors.\n *\n * Included in `status.details[]` for A2A-specific auth errors.\n */\nexport interface GrpcErrorInfo {\n /** Fully-qualified type URL for ErrorInfo */\n readonly '@type': 'type.googleapis.com/google.rpc.ErrorInfo';\n /** Machine-readable error reason (SCREAMING_SNAKE_CASE) */\n readonly reason: string;\n /** Domain for the error (always 'a2a-protocol.org' per A2A spec) */\n readonly domain: string;\n /** Key-value metadata providing additional error context */\n readonly metadata: Readonly<Record<string, string>>;\n}\n\n// ---------------------------------------------------------------------------\n// google.rpc.Status shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.Status with typed ErrorInfo detail.\n *\n * This is the wire shape returned in A2A gRPC error responses and\n * JSON-RPC error data objects.\n */\nexport interface GrpcStatus {\n /** gRPC canonical status code */\n readonly code: GrpcStatusCodeValue;\n /** Human-readable error message */\n readonly message: string;\n /** Structured error details (contains ErrorInfo for A2A-specific errors) */\n readonly details: readonly GrpcErrorInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// A2A auth error definitions\n// ---------------------------------------------------------------------------\n\n/** A2A error domain per spec: implementations use the protocol domain */\nconst A2A_AUTH_DOMAIN = 'a2a-protocol.org';\n\ninterface AuthErrorDef {\n readonly grpcCode: GrpcStatusCodeValue;\n readonly message: string;\n readonly reason: string;\n}\n\nconst AUTH_ERROR_DEFS = {\n PKCE_MISMATCH: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'PKCE code challenge verification failed',\n reason: 'PKCE_CHALLENGE_MISMATCH',\n },\n PKCE_INVALID_VERIFIER: {\n grpcCode: GrpcStatusCode.INVALID_ARGUMENT,\n message: 'PKCE code verifier does not meet RFC 7636 requirements',\n reason: 'PKCE_INVALID_VERIFIER',\n },\n TOKEN_EXCHANGE_FAILED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'OAuth token exchange failed',\n reason: 'TOKEN_EXCHANGE_FAILED',\n },\n AUTH_SERVER_UNAVAILABLE: {\n grpcCode: GrpcStatusCode.UNAVAILABLE,\n message: 'Authorization server is unavailable',\n reason: 'AUTH_SERVER_UNAVAILABLE',\n },\n INVALID_AUTH_CODE: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Authorization code is invalid or expired',\n reason: 'INVALID_AUTH_CODE',\n },\n INVALID_CLIENT: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Client authentication failed',\n reason: 'INVALID_CLIENT',\n },\n SCOPE_DENIED: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Requested scope was denied by the authorization server',\n reason: 'SCOPE_DENIED',\n },\n DEVICE_CODE_EXPIRED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Device authorization code has expired',\n reason: 'DEVICE_CODE_EXPIRED',\n },\n} as const satisfies Record<string, AuthErrorDef>;\n\nexport type A2AAuthErrorCode = keyof typeof AUTH_ERROR_DEFS;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a google.rpc.Status with ErrorInfo for an A2A auth error.\n *\n * Returns the full Status shape with `details[]` containing a single\n * `google.rpc.ErrorInfo` entry, as required by the A2A spec for\n * implementation-specific errors.\n *\n * @param errorCode - A2A auth error code\n * @param metadata - Additional key-value context for ErrorInfo.metadata\n * @returns google.rpc.Status with embedded ErrorInfo\n */\nexport function createA2AAuthStatus(\n errorCode: A2AAuthErrorCode,\n metadata?: Record<string, string>\n): GrpcStatus {\n const def = AUTH_ERROR_DEFS[errorCode];\n return {\n code: def.grpcCode,\n message: def.message,\n details: [\n {\n '@type': 'type.googleapis.com/google.rpc.ErrorInfo',\n reason: def.reason,\n domain: A2A_AUTH_DOMAIN,\n metadata: metadata ?? {},\n },\n ],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/normalizers.ts","../src/attach.ts","../src/extract.ts","../src/carrier.ts","../src/header.ts","../src/discovery.ts","../src/auth/pkce.ts","../src/auth/oauth.ts","../src/auth/evidence.ts","../src/auth/errors.ts"],"names":["validateCarrierConstraints","PeacEvidenceCarrierSchema","verifyReceiptRefConsistency","PEAC_RECEIPT_HEADER","ERROR_CODES","ACCESS_EXTENSION_KEY"],"mappings":";;;;;;AAsBO,IAAM,kBAAA,GAAqB;AAG3B,IAAM,oBAAA,GAAuB;AA8F7B,IAAM,iBAAA,GAAoB;AAAA,EAC/B,SAAA,EAAW,sBAAA;AAAA,EACX,OAAA,EAAS,oBAAA;AAAA,EACT,SAAA,EAAW,sBAAA;AAAA,EACX,MAAA,EAAQ,mBAAA;AAAA,EACR,QAAA,EAAU,qBAAA;AAAA,EACV,QAAA,EAAU,qBAAA;AAAA,EACV,cAAA,EAAgB,2BAAA;AAAA,EAChB,aAAA,EAAe;AACjB;AAGO,IAAM,mBAAA,GAAsB;AAAA,EACjC,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO;AACT;;;ACrGO,SAAS,cAAc,IAAA,EAA6B;AACzD,EAAA,OACE,KAAA,CAAM,QAAQ,IAAA,CAAK,mBAAmB,KACtC,IAAA,CAAK,mBAAA,CAAoB,SAAS,CAAA,IAClC,OAAO,KAAK,mBAAA,CAAoB,CAAC,GAAG,GAAA,KAAQ,QAAA,IAC5C,KAAK,mBAAA,CAAoB,CAAC,CAAA,CAAE,GAAA,CAAI,MAAA,GAAS,CAAA;AAE7C;AAWO,SAAS,mBAAmB,IAAA,EAAgD;AACjF,EAAA,IAAI,CAAC,aAAA,CAAc,IAAI,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,mBAAA,CAAqB,CAAC,CAAA;AACzC,EAAA,OAAO;AAAA,IACL,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,KAAK,KAAA,CAAM,GAAA;AAAA,IACX,qBAAqB,IAAA,CAAK,mBAAA;AAAA,IAC1B,QAAA,EAAU;AAAA,GACZ;AACF;AAQO,SAAS,oBACd,UAAA,EAC8B;AAC9B,EAAA,IAAI,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AACpC,EAAA,OAAO,CAAC,GAAG,UAAU,CAAA,CAAE,IAAA;AAAA,IAAK,CAAC,CAAA,EAAG,CAAA,KAC9B,CAAA,CAAE,eAAA,CAAgB,aAAA,CAAc,CAAA,CAAE,eAAA,EAAiB,MAAA,EAAW,EAAE,OAAA,EAAS,IAAA,EAAM;AAAA,IAC/E,CAAC,CAAA;AACL;AClDA,SAAS,cAAA,GAA8B;AACrC,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,KAAA;AAAA,IACX,MAAA,EAAQ,OAAA;AAAA,IACR,QAAA,EAAU;AAAA,GACZ;AACF;AAcO,SAAS,uBAAA,CACd,QAAA,EACA,QAAA,EACA,IAAA,EACa;AACb,EAAA,MAAM,aAAA,GAAgB,QAAQ,cAAA,EAAe;AAE7C,EAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,IAAA,MAAM,MAAA,GAASA,iCAAA,CAA2B,OAAA,EAAS,aAAa,CAAA;AAChE,IAAA,IAAI,CAAC,OAAO,KAAA,EAAO;AACjB,MAAA,MAAM,IAAI,MAAM,CAAA,8BAAA,EAAiC,MAAA,CAAO,WAAW,IAAA,CAAK,IAAI,CAAC,CAAA,CAAE,CAAA;AAAA,IACjF;AAAA,EACF;AAEA,EAAA,MAAM,OAAA,GAA0B,EAAE,QAAA,EAAU,IAAA,EAAM,aAAA,EAAc;AAChE,EAAA,QAAA,CAAS,kBAAkB,CAAA,GAAI,OAAA;AAC/B,EAAA,OAAO,QAAA;AACT;AAUO,SAAS,yBAAA,CACd,MAAA,EACA,QAAA,EACA,IAAA,EACmB;AACnB,EAAA,IAAI,CAAC,OAAO,QAAA,EAAU;AACpB,IAAA,MAAA,CAAO,WAAW,EAAC;AAAA,EACrB;AACA,EAAA,uBAAA,CAAwB,MAAA,CAAO,QAAA,EAAU,QAAA,EAAU,IAAI,CAAA;AACvD,EAAA,OAAO,MAAA;AACT;AAMO,SAAS,sBAAA,CACd,GAAA,EACA,QAAA,EACA,IAAA,EACgB;AAChB,EAAA,IAAI,CAAC,IAAI,QAAA,EAAU;AACjB,IAAA,GAAA,CAAI,WAAW,EAAC;AAAA,EAClB;AACA,EAAA,uBAAA,CAAwB,GAAA,CAAI,QAAA,EAAU,QAAA,EAAU,IAAI,CAAA;AACpD,EAAA,OAAO,GAAA;AACT;AAMO,SAAS,uBAAA,CACd,QAAA,EACA,QAAA,EACA,IAAA,EACiB;AACjB,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACtB,IAAA,QAAA,CAAS,WAAW,EAAC;AAAA,EACvB;AACA,EAAA,uBAAA,CAAwB,QAAA,CAAS,QAAA,EAAU,QAAA,EAAU,IAAI,CAAA;AACzD,EAAA,OAAO,QAAA;AACT;ACnEO,SAAS,2BAA2B,QAAA,EAAgD;AACzF,EAAA,MAAM,GAAA,GAAM,SAAS,kBAAkB,CAAA;AACvC,EAAA,IAAI,GAAA,KAAQ,MAAA,IAAa,GAAA,KAAQ,IAAA,EAAM;AACrC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,EAAE,cAAe,GAAA,CAAA,EAAiB;AAC/D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,GAAA;AAChB,EAAA,IAAI,CAAC,MAAM,OAAA,CAAQ,OAAA,CAAQ,QAAQ,CAAA,IAAK,OAAA,CAAQ,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AACrE,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,gBAAuC,EAAC;AAC9C,EAAA,KAAA,MAAW,OAAA,IAAW,QAAQ,QAAA,EAAU;AACtC,IAAA,MAAM,MAAA,GAASC,gCAAA,CAA0B,SAAA,CAAU,OAAO,CAAA;AAC1D,IAAA,IAAI,OAAO,OAAA,EAAS;AAClB,MAAA,aAAA,CAAc,IAAA,CAAK,OAAO,IAA2B,CAAA;AAAA,IACvD;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,IAAA,GAAoB,QAAQ,IAAA,IAAQ;AAAA,IACxC,SAAA,EAAW,KAAA;AAAA,IACX,MAAA,EAAQ,OAAA;AAAA,IACR,QAAA,EAAU;AAAA,GACZ;AAEA,EAAA,OAAO,EAAE,QAAA,EAAU,aAAA,EAAe,IAAA,EAAK;AACzC;AASA,eAAsB,gCACpB,QAAA,EACuC;AACvC,EAAA,MAAM,UAAA,GAAa,2BAA2B,QAAQ,CAAA;AACtD,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,aAAuB,EAAC;AAC9B,EAAA,MAAM,gBAAuC,EAAC;AAE9C,EAAA,KAAA,MAAW,OAAA,IAAW,WAAW,QAAA,EAAU;AACzC,IAAA,MAAM,KAAA,GAAQ,MAAMC,kCAAA,CAA4B,OAAO,CAAA;AACvD,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,UAAA,CAAW,KAAK,KAAK,CAAA;AAAA,IACvB,CAAA,MAAO;AACL,MAAA,aAAA,CAAc,KAAK,OAAO,CAAA;AAAA,IAC5B;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,CAAc,MAAA,KAAW,CAAA,IAAK,UAAA,CAAW,SAAS,CAAA,EAAG;AACvD,IAAA,OAAO,EAAE,QAAA,EAAU,IAAI,IAAA,EAAM,UAAA,CAAW,MAAM,UAAA,EAAW;AAAA,EAC3D;AAEA,EAAA,OAAO,EAAE,QAAA,EAAU,aAAA,EAAe,IAAA,EAAM,UAAA,CAAW,MAAM,UAAA,EAAW;AACtE;AAOO,SAAS,6BAA6B,MAAA,EAAoD;AAC/F,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,EAAU,OAAO,IAAA;AAC7B,EAAA,OAAO,0BAAA,CAA2B,OAAO,QAAQ,CAAA;AACnD;AAGA,eAAsB,kCACpB,MAAA,EACuC;AACvC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,EAAU,OAAO,IAAA;AAC7B,EAAA,OAAO,+BAAA,CAAgC,OAAO,QAAQ,CAAA;AACxD;AAGO,SAAS,0BAA0B,GAAA,EAA8C;AACtF,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,EAAU,OAAO,IAAA;AAC1B,EAAA,OAAO,0BAAA,CAA2B,IAAI,QAAQ,CAAA;AAChD;AAGA,eAAsB,+BACpB,GAAA,EACuC;AACvC,EAAA,IAAI,CAAC,GAAA,CAAI,QAAA,EAAU,OAAO,IAAA;AAC1B,EAAA,OAAO,+BAAA,CAAgC,IAAI,QAAQ,CAAA;AACrD;AAGO,SAAS,2BAA2B,QAAA,EAAoD;AAC7F,EAAA,IAAI,CAAC,QAAA,CAAS,QAAA,EAAU,OAAO,IAAA;AAC/B,EAAA,OAAO,0BAAA,CAA2B,SAAS,QAAQ,CAAA;AACrD;AAGA,eAAsB,gCACpB,QAAA,EACuC;AACvC,EAAA,IAAI,CAAC,QAAA,CAAS,QAAA,EAAU,OAAO,IAAA;AAC/B,EAAA,OAAO,+BAAA,CAAgC,SAAS,QAAQ,CAAA;AAC1D;AC3IO,IAAM,oBAAN,MAAwF;AAAA,EAC7F,QAAQ,KAAA,EAAyF;AAC/F,IAAA,OAAO,6BAA6B,KAAK,CAAA;AAAA,EAC3C;AAAA,EAEA,MAAA,CACE,MAAA,EACA,QAAA,EACA,IAAA,EACmB;AACnB,IAAA,OAAO,yBAAA,CAA0B,MAAA,EAAQ,QAAA,EAAU,IAAI,CAAA;AAAA,EACzD;AAAA,EAEA,mBAAA,CAAoB,SAA8B,IAAA,EAA4C;AAC5F,IAAA,OAAOF,iCAAAA,CAA2B,SAAS,IAAI,CAAA;AAAA,EACjD;AACF;AAGO,SAAS,qBAAqB,SAAA,EAA+C;AAClF,EAAA,OAAO;AAAA,IACL,SAAA,EAAW,KAAA;AAAA,IACX,MAAA,EAAQ,OAAA;AAAA,IACR,QAAA,EAAU,oBAAA;AAAA,IACV,GAAG;AAAA,GACL;AACF;;;ACrCO,SAAS,yBAAyB,MAAA,EAA0B;AACjE,EAAA,OAAO,OACJ,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAM,EACnB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,CAAC,CAAA;AAC/B;AAQO,SAAS,yBAAyB,UAAA,EAA8B;AACrE,EAAA,OAAO,UAAA,CAAW,KAAK,IAAI,CAAA;AAC7B;ACPA,IAAM,oBAAoB,GAAA,GAAM,IAAA;AAGhC,IAAM,oBAAA,GAAuB,GAAA;AAG7B,IAAM,mBAAA,GAAsB;AAAA,EAC1B,QAAA;AAAA;AAAA,EACA,OAAA;AAAA;AAAA,EACA,4BAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,MAAA;AAAA;AAAA,EACA,OAAA;AAAA;AAAA,EACA,iBAAA;AAAA;AAAA,EACA,QAAA;AAAA;AAAA,EACA;AAAA;AACF,CAAA;AAkCA,SAAS,YAAY,EAAA,EAAqB;AACxC,EAAA,OAAO,oBAAoB,IAAA,CAAK,CAAC,YAAY,OAAA,CAAQ,IAAA,CAAK,EAAE,CAAC,CAAA;AAC/D;AAEA,SAAS,mBAAmB,QAAA,EAA2B;AACrD,EAAA,OAAO,QAAA,KAAa,WAAA,IAAe,QAAA,KAAa,WAAA,IAAe,QAAA,KAAa,KAAA;AAC9E;AAUA,eAAe,uBAAA,CAAwB,KAAa,OAAA,EAA0C;AAC5F,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAG1B,EAAA,IAAI,MAAA,CAAO,QAAA,IAAY,MAAA,CAAO,QAAA,EAAU;AACtC,IAAA,MAAM,IAAI,MAAM,wDAAwD,CAAA;AAAA,EAC1E;AAGA,EAAA,IAAI,MAAA,CAAO,aAAa,OAAA,EAAS;AAC/B,IAAA,IAAI,CAAC,OAAA,CAAQ,sBAAA,IAA0B,CAAC,kBAAA,CAAmB,MAAA,CAAO,QAAQ,CAAA,EAAG;AAC3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,kCAAA,EAAqC,OAAO,QAAQ,CAAA,mEAAA;AAAA,OAEtD;AAAA,IACF;AAAA,EACF,CAAA,MAAA,IAAW,MAAA,CAAO,QAAA,KAAa,QAAA,EAAU;AACvC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,MAAA,CAAO,QAAQ,CAAA,CAAE,CAAA;AAAA,EAC/D;AAGA,EAAA,IAAI,WAAA,CAAY,OAAO,QAAQ,CAAA,IAAK,CAAC,kBAAA,CAAmB,MAAA,CAAO,QAAQ,CAAA,EAAG;AACxE,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,yBAAA,EAA4B,MAAA,CAAO,QAAQ,CAAA,YAAA,CAAc,CAAA;AAAA,EAC3E;AAGA,EAAA,IAAI,QAAQ,eAAA,IAAmB,CAAC,kBAAA,CAAmB,MAAA,CAAO,QAAQ,CAAA,EAAG;AACnE,IAAA,MAAM,WAAA,GAAc,MAAM,OAAA,CAAQ,eAAA,CAAgB,OAAO,QAAQ,CAAA;AACjE,IAAA,KAAA,MAAW,MAAM,WAAA,EAAa;AAC5B,MAAA,IAAI,WAAA,CAAY,EAAE,CAAA,EAAG;AACnB,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkB,OAAO,QAAQ,CAAA,wBAAA,EAA2B,EAAE,CAAA,CAAE,CAAA;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AACF;AAwBA,eAAsB,iBAAA,CACpB,OAAA,EACA,OAAA,GAA4B,EAAC,EACC;AAC9B,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC5C,EAAA,MAAM,KAAA,GAAQ,CAAC,8BAA8B,CAAA;AAE7C,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,MAAM,IAAI,GAAA,CAAI,IAAA,EAAM,OAAO,EAAE,QAAA,EAAS;AAE5C,IAAA,IAAI;AACF,MAAA,MAAM,uBAAA,CAAwB,KAAK,OAAO,CAAA;AAE1C,MAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK;AAAA,QAClC,MAAA,EAAQ,KAAA;AAAA,QACR,QAAA,EAAU,OAAA;AAAA;AAAA,QACV,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,oBAAoB;AAAA,OACjD,CAAA;AAED,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AAC5D,MAAA,IACE,CAAC,YAAY,QAAA,CAAS,kBAAkB,KACxC,CAAC,WAAA,CAAY,KAAA,CAAM,iCAAiC,CAAA,EACpD;AACA,QAAA;AAAA,MACF;AAGA,MAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AAC3D,MAAA,IAAI,aAAA,IAAiB,QAAA,CAAS,aAAA,EAAe,EAAE,IAAI,iBAAA,EAAmB;AACpE,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,MAAA,IAAI,IAAA,CAAK,SAAS,iBAAA,EAAmB;AACnC,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAM5B,MAAA,IAAI,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU;AACjC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,UAAA,GAAa,mBAAmB,IAAI,CAAA;AAC1C,MAAA,IAAI,CAAC,UAAA,EAAY;AACf,QAAA;AAAA,MACF;AAEA,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AAEN,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,iBAAiB,IAAA,EAA6B;AAC5D,EAAA,MAAM,UAAA,GAAa,KAAK,YAAA,EAAc,UAAA;AACtC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC9B,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,UAAA,CAAW,IAAA;AAAA,IAChB,CAAC,QAAQ,OAAO,GAAA,KAAQ,YAAY,GAAA,KAAQ,IAAA,IAAQ,IAAI,GAAA,KAAQ;AAAA,GAClE;AACF;AAOO,SAAS,iBAAiB,IAAA,EAAmD;AAClF,EAAA,MAAM,UAAA,GAAa,KAAK,YAAA,EAAc,UAAA;AACtC,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,MAAM,QAAQ,UAAA,CAAW,IAAA;AAAA,IACvB,CAAC,QAAQ,OAAO,GAAA,KAAQ,YAAY,GAAA,KAAQ,IAAA,IAAQ,IAAI,GAAA,KAAQ;AAAA,GAClE;AACA,EAAA,OAAQ,KAAA,IAAoC,IAAA;AAC9C;AA+BA,eAAsB,wBAAA,CACpB,OAAA,EACA,OAAA,GAA4B,EAAC,EACQ;AAErC,EAAA,MAAM,IAAA,GAAO,MAAM,iBAAA,CAAkB,OAAA,EAAS,OAAO,CAAA;AACrD,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,MAAM,GAAA,GAAM,iBAAiB,IAAI,CAAA;AACjC,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,YAAA;AAAA,QACR,KAAA,EAAO,GAAA,CAAI,MAAA,EAAQ,eAAA,IAAmB,CAAC,kBAAkB,CAAA;AAAA,QACzD,eAAA,EAAiB,GAAA,CAAI,MAAA,EAAQ,eAAA,IAAmB,CAAC,OAAO,CAAA;AAAA,QACxD,GAAI,GAAA,CAAI,MAAA,EAAQ,iBAAA,IAAqB;AAAA,UACnC,iBAAA,EAAmB,IAAI,MAAA,CAAO;AAAA;AAChC,OACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,MAAM,qBAAA,CAAsB,OAAA,EAAS,OAAO,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,MAAM,WAAA,GAAc,MAAM,0BAAA,CAA2B,OAAA,EAAS,OAAO,CAAA;AACrE,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,OAAO,WAAA;AAAA,EACT;AAEA,EAAA,OAAO,IAAA;AACT;AAKA,eAAe,qBAAA,CACb,SACA,OAAA,EACqC;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAC5C,EAAA,MAAM,MAAM,IAAI,GAAA,CAAI,wBAAA,EAA0B,OAAO,EAAE,QAAA,EAAS;AAEhE,EAAA,IAAI;AACF,IAAA,MAAM,uBAAA,CAAwB,KAAK,OAAO,CAAA;AAE1C,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,GAAA,EAAK;AAAA,MAClC,MAAA,EAAQ,KAAA;AAAA,MACR,QAAA,EAAU,OAAA;AAAA,MACV,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,oBAAoB;AAAA,KACjD,CAAA;AAED,IAAA,IAAI,CAAC,QAAA,CAAS,EAAA,EAAI,OAAO,IAAA;AAEzB,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AAC5D,IAAA,IACE,CAAC,YAAY,QAAA,CAAS,kBAAkB,KACxC,CAAC,WAAA,CAAY,KAAA,CAAM,iCAAiC,CAAA,EACpD;AACA,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AAC3D,IAAA,IAAI,aAAA,IAAiB,QAAA,CAAS,aAAA,EAAe,EAAE,IAAI,iBAAA,EAAmB;AACpE,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,QAAA,CAAS,IAAA,EAAK;AACjC,IAAA,IAAI,IAAA,CAAK,MAAA,GAAS,iBAAA,EAAmB,OAAO,IAAA;AAE5C,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAE5B,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,YAAA;AAAA,MACR,KAAA,EAAO,MAAM,OAAA,CAAQ,IAAA,CAAK,eAAe,CAAA,GACpC,IAAA,CAAK,eAAA,GACN,CAAC,kBAAkB,CAAA;AAAA,MACvB,eAAA,EAAiB,MAAM,OAAA,CAAQ,IAAA,CAAK,eAAe,CAAA,GAC9C,IAAA,CAAK,eAAA,GACN,CAAC,OAAO,CAAA;AAAA,MACZ,GAAI,OAAO,IAAA,CAAK,iBAAA,KAAsB,QAAA,IAAY;AAAA,QAChD,mBAAmB,IAAA,CAAK;AAAA;AAC1B,KACF;AAAA,EACF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAQA,eAAe,0BAAA,CACb,SACA,OAAA,EACqC;AACrC,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA;AAE5C,EAAA,IAAI;AACF,IAAA,MAAM,uBAAA,CAAwB,SAAS,OAAO,CAAA;AAE9C,IAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,OAAA,EAAS;AAAA,MACtC,MAAA,EAAQ,MAAA;AAAA,MACR,QAAA,EAAU,OAAA;AAAA,MACV,MAAA,EAAQ,WAAA,CAAY,OAAA,CAAQ,oBAAoB;AAAA,KACjD,CAAA;AAED,IAAA,MAAM,YAAY,CAAC,GAAG,SAAS,OAAA,CAAQ,IAAA,EAAM,CAAA,CAAE,IAAA;AAAA,MAC7C,CAAC,CAAA,KAAM,CAAA,CAAE,WAAA,EAAY,KAAMG,2BAAoB,WAAA;AAAY,KAC7D;AAEA,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,OAAO;AAAA,QACL,MAAA,EAAQ,cAAA;AAAA,QACR,KAAA,EAAO,CAAC,kBAAkB,CAAA;AAAA,QAC1B,eAAA,EAAiB,CAAC,OAAO;AAAA,OAC3B;AAAA,IACF;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,OAAO,IAAA;AACT;ACnYA,IAAM,mBAAA,GAAsB,EAAA;AAC5B,IAAM,mBAAA,GAAsB,GAAA;AAG5B,IAAM,gBAAA,GAAmB,qBAAA;AA2BzB,eAAsB,qBAAA,GAAgD;AACpE,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,MAAM,QAAA,GAAW,qBAAqB,KAAK,CAAA;AAC3C,EAAA,MAAM,SAAA,GAAY,MAAM,oBAAA,CAAqB,QAAQ,CAAA;AACrD,EAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,MAAA,EAAQ,MAAA,EAAO;AAC/C;AAWA,eAAsB,qBAAqB,QAAA,EAAmC;AAC5E,EAAA,sBAAA,CAAuB,QAAQ,CAAA;AAC/B,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AACpC,EAAA,MAAM,SAAS,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,WAAW,IAAI,CAAA;AACzD,EAAA,OAAO,oBAAA,CAAqB,IAAI,UAAA,CAAW,MAAM,CAAC,CAAA;AACpD;AAUO,SAAS,qBAAqB,QAAA,EAAwB;AAC3D,EAAA,sBAAA,CAAuB,QAAQ,CAAA;AACjC;AAMA,SAAS,uBAAuB,QAAA,EAAwB;AACtD,EAAA,IAAI,QAAA,CAAS,MAAA,GAAS,mBAAA,IAAuB,QAAA,CAAS,SAAS,mBAAA,EAAqB;AAClF,IAAA,MAAM,MAAA,CAAO,MAAA;AAAA,MACX,IAAI,KAAA;AAAA,QACF,wBAAwB,QAAA,CAAS,MAAM,CAAA,wBAAA,EAA2B,mBAAmB,KAAK,mBAAmB,CAAA,CAAA;AAAA,OAC/G;AAAA,MACA,EAAE,IAAA,EAAMC,kBAAA,CAAY,uBAAA;AAAwB,KAC9C;AAAA,EACF;AACA,EAAA,IAAI,CAAC,gBAAA,CAAiB,IAAA,CAAK,QAAQ,CAAA,EAAG;AACpC,IAAA,MAAM,MAAA,CAAO,MAAA;AAAA,MACX,IAAI,MAAM,mEAAmE,CAAA;AAAA,MAC7E,EAAE,IAAA,EAAMA,kBAAA,CAAY,uBAAA;AAAwB,KAC9C;AAAA,EACF;AACF;AAQA,SAAS,qBAAqB,KAAA,EAA2B;AACvD,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,IAAA,MAAA,GAAS,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,CAAE,SAAS,QAAQ,CAAA;AAAA,EAC/C,CAAA,MAAO;AACL,IAAA,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,CAAC,CAAA,KAAM,MAAA,CAAO,YAAA,CAAa,CAAC,CAAC,CAAA,CAAE,IAAA,CAAK,EAAE,CAAA;AACjE,IAAA,MAAA,GAAS,KAAK,MAAM,CAAA;AAAA,EACtB;AACA,EAAA,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACzE;;;AC3BA,IAAM,eAAA,uBAAsB,GAAA,CAAI;AAAA,EAC9B,eAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,uBAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAC,CAAA;AAkBM,SAAS,yBAAA,CACd,QACA,IAAA,EACsB;AACtB,EAAA,mBAAA,CAAoB,MAAA,CAAO,kBAAkB,kBAAkB,CAAA;AAC/D,EAAA,mBAAA,CAAoB,MAAA,CAAO,aAAa,aAAa,CAAA;AAErD,EAAA,IAAI,OAAO,WAAA,EAAa;AACtB,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA,EAAG;AACjD,MAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC5B,QAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wDAAA,EAA2D,GAAG,CAAA,CAAE,CAAA;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,QAAQ,aAAA,EAAc;AAC5B,EAAA,MAAM,OAAA,GAAU,IAAI,GAAA,CAAI,MAAA,CAAO,gBAAgB,CAAA;AAC/C,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAChD,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,WAAA,EAAa,MAAA,CAAO,QAAQ,CAAA;AACrD,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,MAAA,CAAO,WAAW,CAAA;AAC3D,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,IAAA,CAAK,SAAS,CAAA;AACzD,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AACxD,EAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AAEvC,EAAA,IAAI,MAAA,CAAO,MAAA,IAAU,MAAA,CAAO,MAAA,CAAO,SAAS,CAAA,EAAG;AAC7C,IAAA,OAAA,CAAQ,aAAa,GAAA,CAAI,OAAA,EAAS,OAAO,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAAA,EAC3D;AAEA,EAAA,IAAI,OAAO,WAAA,EAAa;AACtB,IAAA,KAAA,MAAW,CAAC,KAAK,KAAK,CAAA,IAAK,OAAO,OAAA,CAAQ,MAAA,CAAO,WAAW,CAAA,EAAG;AAC7D,MAAA,OAAA,CAAQ,YAAA,CAAa,GAAA,CAAI,GAAA,EAAK,KAAK,CAAA;AAAA,IACrC;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,KAAK,OAAA,CAAQ,QAAA,IAAY,YAAA,EAAc,IAAA,CAAK,UAAU,KAAA,EAAM;AACvE;AAeA,eAAsB,yBAAA,CACpB,IAAA,EACA,QAAA,EACA,MAAA,EACA,OAAA,EACwB;AACxB,EAAA,mBAAA,CAAoB,MAAA,CAAO,UAAU,UAAU,CAAA;AAC/C,EAAA,mBAAA,CAAoB,MAAA,CAAO,aAAa,aAAa,CAAA;AACrD,EAAA,oBAAA,CAAqB,QAAQ,CAAA;AAE7B,EAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB;AAAA,IAC/B,UAAA,EAAY,oBAAA;AAAA,IACZ,IAAA;AAAA,IACA,cAAc,MAAA,CAAO,WAAA;AAAA,IACrB,WAAW,MAAA,CAAO,QAAA;AAAA,IAClB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAA,CAAO,QAAA,EAAU;AAAA,IAC9C,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,KAAK,QAAA;AAAS,GACrB,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,YAAY,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACtD,IAAA,MAAM,MAAA,CAAO,MAAA;AAAA,MACX,IAAI,KAAA;AAAA,QACF,CAAA,4BAAA,EAA+B,SAAS,MAAM,CAAA,EAAG,YAAY,CAAA,EAAA,EAAK,SAAS,KAAK,EAAE,CAAA;AAAA,OACpF;AAAA,MACA,EAAE,IAAA,EAAM,kCAAA,EAAoC,MAAA,EAAQ,SAAS,MAAA;AAAO,KACtE;AAAA,EACF;AAEA,EAAA,MAAM,aAAA,GAAiB,MAAM,QAAA,CAAS,IAAA,EAAK;AAC3C,EAAA,IACE,OAAO,aAAA,CAAc,YAAA,KAAiB,YACtC,OAAO,aAAA,CAAc,eAAe,QAAA,EACpC;AACA,IAAA,MAAM,MAAA,CAAO,MAAA;AAAA,MACX,IAAI,MAAM,mEAAmE,CAAA;AAAA,MAC7E,EAAE,MAAM,kCAAA;AAAmC,KAC7C;AAAA,EACF;AAEA,EAAA,OAAO,aAAA;AACT;AAMA,SAAS,mBAAA,CAAoB,KAAa,IAAA,EAAoB;AAC5D,EAAA,IAAI,CAAC,IAAI,UAAA,CAAW,UAAU,KAAK,CAAC,eAAA,CAAgB,GAAG,CAAA,EAAG;AACxD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,IAAI,CAAA,sBAAA,EAAyB,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,EACxD;AACF;AAEA,SAAS,gBAAgB,GAAA,EAAsB;AAC7C,EAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,SAAS,GAAG,OAAO,KAAA;AACvC,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,OAAO,MAAA,CAAO,QAAA,KAAa,WAAA,IAAe,MAAA,CAAO,QAAA,KAAa,WAAA;AAAA,EAChE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,SAAS,aAAA,GAAwB;AAC/B,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,EAAE,CAAA;AAC/B,EAAA,MAAA,CAAO,gBAAgB,KAAK,CAAA;AAC5B,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,KAAA,EAAO,CAAC,MAAM,CAAA,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,SAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAC1E;ACnKO,SAAS,iBAAiB,KAAA,EAA4C;AAC3E,EAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACnB,IAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,EACnD;AACA,EAAA,IAAI,CAAC,MAAM,MAAA,EAAQ;AACjB,IAAA,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAAA,EACjD;AAEA,EAAA,MAAM,QAAA,GAAuB;AAAA,IAC3B,UAAA,EAAY,aAAA;AAAA,IACZ,aAAa,KAAA,CAAM;AAAA,GACrB;AAEA,EAAA,IAAI,KAAA,CAAM,aAAA,IAAiB,KAAA,CAAM,aAAA,CAAc,SAAS,CAAA,EAAG;AACzD,IAAA,QAAA,CAAS,cAAA,GAAiB,CAAC,GAAG,KAAA,CAAM,aAAa,CAAA;AAAA,EACnD;AACA,EAAA,IAAI,MAAM,UAAA,EAAY;AACpB,IAAA,QAAA,CAAS,cAAc,KAAA,CAAM,UAAA;AAAA,EAC/B;AACA,EAAA,IAAI,MAAM,QAAA,EAAU;AAClB,IAAA,QAAA,CAAS,YAAY,KAAA,CAAM,QAAA;AAAA,EAC7B;AACA,EAAA,IAAI,MAAM,SAAA,EAAW;AACnB,IAAA,QAAA,CAAS,YAAY,KAAA,CAAM,SAAA;AAAA,EAC7B;AAEA,EAAA,OAAO;AAAA,IACL,YAAA,EAAcC,2BAAA;AAAA,IACd,SAAA,EAAW;AAAA,MACT,UAAU,KAAA,CAAM,QAAA;AAAA,MAChB,QAAQ,KAAA,CAAM,MAAA;AAAA,MACd,QAAA,EAAU;AAAA,KACZ;AAAA,IACA;AAAA,GACF;AACF;;;ACjGO,IAAM,cAAA,GAAiB;AAAA,EAC5B,EAAA,EAAI,CAAA;AAAA,EACJ,gBAAA,EAAkB,CAAA;AAAA,EAClB,SAAA,EAAW,CAAA;AAAA,EACX,iBAAA,EAAmB,CAAA;AAAA,EACnB,QAAA,EAAU,EAAA;AAAA,EACV,WAAA,EAAa,EAAA;AAAA,EACb,eAAA,EAAiB;AACnB;AAgDA,IAAM,eAAA,GAAkB,kBAAA;AAQxB,IAAM,eAAA,GAAkB;AAAA,EACtB,aAAA,EAAe;AAAA,IACb,UAAU,cAAA,CAAe,eAAA;AAAA,IACzB,OAAA,EAAS,yCAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,qBAAA,EAAuB;AAAA,IACrB,UAAU,cAAA,CAAe,gBAAA;AAAA,IACzB,OAAA,EAAS,wDAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,qBAAA,EAAuB;AAAA,IACrB,UAAU,cAAA,CAAe,eAAA;AAAA,IACzB,OAAA,EAAS,6BAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,uBAAA,EAAyB;AAAA,IACvB,UAAU,cAAA,CAAe,WAAA;AAAA,IACzB,OAAA,EAAS,qCAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,iBAAA,EAAmB;AAAA,IACjB,UAAU,cAAA,CAAe,eAAA;AAAA,IACzB,OAAA,EAAS,0CAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,cAAA,EAAgB;AAAA,IACd,UAAU,cAAA,CAAe,iBAAA;AAAA,IACzB,OAAA,EAAS,8BAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,YAAA,EAAc;AAAA,IACZ,UAAU,cAAA,CAAe,iBAAA;AAAA,IACzB,OAAA,EAAS,wDAAA;AAAA,IACT,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,mBAAA,EAAqB;AAAA,IACnB,UAAU,cAAA,CAAe,eAAA;AAAA,IACzB,OAAA,EAAS,uCAAA;AAAA,IACT,MAAA,EAAQ;AAAA;AAEZ,CAAA;AAmBO,SAAS,mBAAA,CACd,WACA,QAAA,EACY;AACZ,EAAA,MAAM,GAAA,GAAM,gBAAgB,SAAS,CAAA;AACrC,EAAA,OAAO;AAAA,IACL,MAAM,GAAA,CAAI,QAAA;AAAA,IACV,SAAS,GAAA,CAAI,OAAA;AAAA,IACb,OAAA,EAAS;AAAA,MACP;AAAA,QACE,OAAA,EAAS,0CAAA;AAAA,QACT,QAAQ,GAAA,CAAI,MAAA;AAAA,QACZ,MAAA,EAAQ,eAAA;AAAA,QACR,QAAA,EAAU,YAAY;AAAC;AACzB;AACF,GACF;AACF","file":"index.cjs","sourcesContent":["/**\n * A2A v1.0.0 types.\n *\n * These types are defined locally rather than importing @a2a-js/sdk,\n * which brings protobuf + gRPC + express peer dependencies that are\n * not needed for evidence placement.\n *\n * A2A v0.3.0 compatibility (DD-186) was deprecated in v0.12.3 and\n * removed in v0.13.0 (DD-186 removal target honored). Agent Cards\n * carrying only a top-level `url` (the v0.3.0 shape) are no longer\n * accepted; every card must expose `supportedInterfaces[0].url`.\n * TaskState values must use the v1.0.0 prefixed SCREAMING_SNAKE_CASE\n * form; v0.3.0 kebab-case values are no longer mapped.\n */\n\nimport type { CarrierFormat, PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** PEAC traceability extension URI for A2A metadata */\nexport const PEAC_EXTENSION_URI = 'https://www.peacprotocol.org/ext/traceability/v1' as const;\n\n/** Maximum carrier size for A2A metadata (64 KB) */\nexport const A2A_MAX_CARRIER_SIZE = 65_536;\n\n// ---------------------------------------------------------------------------\n// A2A Agent Card types (v1.0.0)\n// ---------------------------------------------------------------------------\n\n/** A2A extension entry in capabilities.extensions[] */\nexport interface AgentCardExtension {\n uri: string;\n description?: string;\n required?: boolean;\n params?: Record<string, unknown>;\n}\n\n/** PEAC-specific extension entry for A2A Agent Card */\nexport interface AgentCardPeacExtension {\n uri: typeof PEAC_EXTENSION_URI;\n description: string;\n required: boolean;\n params?: {\n supported_kinds?: string[];\n carrier_formats?: CarrierFormat[];\n issuer_config_url?: string;\n };\n}\n\n/** A2A v1.0.0 supported interface entry */\nexport interface A2ASupportedInterface {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n}\n\n/**\n * Minimal A2A Agent Card shape (v1.0.0).\n *\n * v1.0.0 cards expose endpoint bindings via `supportedInterfaces[]`.\n * Every accepted card MUST carry a non-empty `supportedInterfaces[0].url`.\n *\n * The legacy v0.3.0 top-level `url` field is no longer a declared field\n * on this interface. Rejection is **runtime** (`normalizeAgentCard` returns\n * null and `discoverAgentCard` skips the card), not type-level. The\n * interface intentionally keeps a `[key: string]: unknown` index\n * signature so consumers may pass incoming JSON with unknown extra\n * fields without TypeScript errors, so a literal with a stray `url`\n * string property still typechecks. The v0.3.0 removal is enforced by\n * the normalization layer, not by the type system.\n */\nexport interface A2AAgentCard {\n name: string;\n supportedInterfaces?: A2ASupportedInterface[];\n capabilities?: {\n extensions?: AgentCardExtension[];\n extendedAgentCard?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A message types (minimal shapes)\n// ---------------------------------------------------------------------------\n\n/** A2A metadata map */\nexport type A2AMetadata = Record<string, unknown>;\n\n/** Minimal A2A TaskStatus shape */\nexport interface A2ATaskStatusLike {\n state: string;\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Message shape */\nexport interface A2AMessageLike {\n role: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Artifact shape */\nexport interface A2AArtifactLike {\n artifactId: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A v1.0.0 enum constants (reference values)\n// ---------------------------------------------------------------------------\n\n/** A2A v1.0.0 TaskState values (SCREAMING_SNAKE_CASE with type prefix) */\nexport const A2A_V1_TASK_STATE = {\n SUBMITTED: 'TASK_STATE_SUBMITTED',\n WORKING: 'TASK_STATE_WORKING',\n COMPLETED: 'TASK_STATE_COMPLETED',\n FAILED: 'TASK_STATE_FAILED',\n CANCELED: 'TASK_STATE_CANCELED',\n REJECTED: 'TASK_STATE_REJECTED',\n INPUT_REQUIRED: 'TASK_STATE_INPUT_REQUIRED',\n AUTH_REQUIRED: 'TASK_STATE_AUTH_REQUIRED',\n} as const;\n\n/** A2A v1.0.0 MessageRole values */\nexport const A2A_V1_MESSAGE_ROLE = {\n USER: 'ROLE_USER',\n AGENT: 'ROLE_AGENT',\n} as const;\n\n// The v0.3.0 → v1.0.0 TaskState mapping (previously TASK_STATE_V03_TO_V1)\n// was removed in v0.13.0 alongside the v0.3.0 compat path (DD-186).\n// Callers MUST supply v1.0.0 TaskState values directly.\n\n// ---------------------------------------------------------------------------\n// Carrier payload type\n// ---------------------------------------------------------------------------\n\n/**\n * A2A carrier payload: the value stored under metadata[PEAC_EXTENSION_URI].\n *\n * Contains an array of carriers (even for single-receipt cases) and\n * optional transport metadata.\n */\nexport interface A2APeacPayload {\n carriers: PeacEvidenceCarrier[];\n meta?: CarrierMeta;\n}\n","/**\n * A2A v1.0.0 Agent Card normalizers.\n *\n * The v0.3.0 compatibility path (DD-186; `url` top-level field plus\n * kebab-case TaskState mapping) was deprecated in v0.12.3 and removed\n * in v0.13.0. Every accepted Agent Card must expose a non-empty\n * `supportedInterfaces[0].url`; cards without it are rejected. The\n * v0.3.0-to-v1.0.0 TaskState mapping function was removed because its\n * only job was translating kebab-case inputs, which are no longer\n * accepted. TaskState values are now v1.0.0 SCREAMING_SNAKE_CASE\n * strings carried by the caller.\n */\n\nimport type { A2AAgentCard, A2ASupportedInterface } from './types';\n\n// ---------------------------------------------------------------------------\n// Agent Card normalizer\n// ---------------------------------------------------------------------------\n\n/** Normalized Agent Card with a resolved v1.0.0 URL. */\nexport interface NormalizedAgentCard {\n name: string;\n url: string;\n supportedInterfaces: A2ASupportedInterface[];\n original: A2AAgentCard;\n}\n\n/**\n * Returns true if the card satisfies the v1.0.0 Agent Card contract:\n * `supportedInterfaces[0].url` exists and is a non-empty string. Cards\n * that fail this check are rejected by `normalizeAgentCard` (they are\n * not v0.3.0 fallbacks, which are no longer accepted).\n */\nexport function isV1AgentCard(card: A2AAgentCard): boolean {\n return (\n Array.isArray(card.supportedInterfaces) &&\n card.supportedInterfaces.length > 0 &&\n typeof card.supportedInterfaces[0]?.url === 'string' &&\n card.supportedInterfaces[0].url.length > 0\n );\n}\n\n/**\n * Normalize an A2A v1.0.0 Agent Card.\n *\n * Returns a consistent shape with the resolved primary URL. Cards that\n * do not satisfy `isV1AgentCard(...)` return `null` (this includes the\n * legacy v0.3.0 shape with only a top-level `url`, which is no longer\n * supported). Callers receiving `null` should treat the card as invalid\n * and surface a structured error rather than falling back to v0.3.0.\n */\nexport function normalizeAgentCard(card: A2AAgentCard): NormalizedAgentCard | null {\n if (!isV1AgentCard(card)) return null;\n const iface = card.supportedInterfaces![0]!;\n return {\n name: card.name,\n url: iface.url,\n supportedInterfaces: card.supportedInterfaces!,\n original: card,\n };\n}\n\n/**\n * Select the best interface from a v1.0.0 Agent Card.\n *\n * Prefers the interface with the highest protocolVersion, then the first\n * entry as tiebreaker.\n */\nexport function selectBestInterface(\n interfaces: A2ASupportedInterface[]\n): A2ASupportedInterface | null {\n if (interfaces.length === 0) return null;\n return [...interfaces].sort((a, b) =>\n b.protocolVersion.localeCompare(a.protocolVersion, undefined, { numeric: true })\n )[0]!;\n}\n","/**\n * Attach PEAC evidence carriers to A2A metadata.\n *\n * Places carrier data under metadata[PEAC_EXTENSION_URI] per the A2A\n * extension-URI metadata convention (inherited from v0.3.0 and carried\n * forward in v1.0.0). Uses computeReceiptRef() from @peac/schema for\n * receipt reference computation.\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Default meta for A2A transport\n// ---------------------------------------------------------------------------\n\nfunction defaultA2AMeta(): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Core attach: metadata map\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A metadata map.\n *\n * Writes `metadata[PEAC_EXTENSION_URI] = { carriers: [...], meta }`.\n * Validates carrier constraints before attachment; throws on violation.\n *\n * @returns The modified metadata map (mutated in place and returned)\n */\nexport function attachReceiptToMetadata(\n metadata: A2AMetadata,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMetadata {\n const effectiveMeta = meta ?? defaultA2AMeta();\n\n for (const carrier of carriers) {\n const result = validateCarrierConstraints(carrier, effectiveMeta);\n if (!result.valid) {\n throw new Error(`Carrier constraint violation: ${result.violations.join('; ')}`);\n }\n }\n\n const payload: A2APeacPayload = { carriers, meta: effectiveMeta };\n metadata[PEAC_EXTENSION_URI] = payload;\n return metadata;\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: attach to A2A message types\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A TaskStatus.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToTaskStatus(\n status: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2ATaskStatusLike {\n if (!status.metadata) {\n status.metadata = {};\n }\n attachReceiptToMetadata(status.metadata, carriers, meta);\n return status;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Message.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToMessage(\n msg: A2AMessageLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMessageLike {\n if (!msg.metadata) {\n msg.metadata = {};\n }\n attachReceiptToMetadata(msg.metadata, carriers, meta);\n return msg;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Artifact.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToArtifact(\n artifact: A2AArtifactLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AArtifactLike {\n if (!artifact.metadata) {\n artifact.metadata = {};\n }\n attachReceiptToMetadata(artifact.metadata, carriers, meta);\n return artifact;\n}\n","/**\n * Extract PEAC evidence carriers from A2A metadata.\n *\n * Reads carrier data from metadata[PEAC_EXTENSION_URI] and validates\n * against PeacEvidenceCarrierSchema. Provides both sync (structural)\n * and async (receipt_ref consistency) extraction paths per .\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { PeacEvidenceCarrierSchema, verifyReceiptRefConsistency } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Result of carrier extraction */\nexport interface A2AExtractResult {\n receipts: PeacEvidenceCarrier[];\n meta: CarrierMeta;\n}\n\n/** Result of async extraction with consistency check */\nexport interface A2AExtractAsyncResult extends A2AExtractResult {\n /** Consistency violations (empty if all receipts are valid) */\n violations: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Core extract: metadata map (sync, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (sync).\n *\n * Performs structural validation only (schema check).\n * Returns null if no PEAC extension data is present.\n * Silently skips carriers that fail schema validation.\n */\nexport function extractReceiptFromMetadata(metadata: A2AMetadata): A2AExtractResult | null {\n const raw = metadata[PEAC_EXTENSION_URI];\n if (raw === undefined || raw === null) {\n return null;\n }\n\n // Validate payload shape\n if (typeof raw !== 'object' || !('carriers' in (raw as object))) {\n return null;\n }\n\n const payload = raw as A2APeacPayload;\n if (!Array.isArray(payload.carriers) || payload.carriers.length === 0) {\n return null;\n }\n\n // Validate each carrier against schema (validate at extraction)\n const validCarriers: PeacEvidenceCarrier[] = [];\n for (const carrier of payload.carriers) {\n const result = PeacEvidenceCarrierSchema.safeParse(carrier);\n if (result.success) {\n validCarriers.push(result.data as PeacEvidenceCarrier);\n }\n }\n\n if (validCarriers.length === 0) {\n return null;\n }\n\n const meta: CarrierMeta = payload.meta ?? {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n\n return { receipts: validCarriers, meta };\n}\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (async).\n *\n * Performs structural validation AND receipt_ref consistency check.\n * When receipt_jws is present, verifies sha256(receipt_jws) === receipt_ref.\n * Returns violations array for any carriers that fail the consistency check.\n */\nexport async function extractReceiptFromMetadataAsync(\n metadata: A2AMetadata\n): Promise<A2AExtractAsyncResult | null> {\n const syncResult = extractReceiptFromMetadata(metadata);\n if (syncResult === null) {\n return null;\n }\n\n const violations: string[] = [];\n const validCarriers: PeacEvidenceCarrier[] = [];\n\n for (const carrier of syncResult.receipts) {\n const error = await verifyReceiptRefConsistency(carrier);\n if (error !== null) {\n violations.push(error);\n } else {\n validCarriers.push(carrier);\n }\n }\n\n if (validCarriers.length === 0 && violations.length > 0) {\n return { receipts: [], meta: syncResult.meta, violations };\n }\n\n return { receipts: validCarriers, meta: syncResult.meta, violations };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: extract from A2A message types\n// ---------------------------------------------------------------------------\n\n/** Extract carriers from A2A TaskStatus (sync) */\nexport function extractReceiptFromTaskStatus(status: A2ATaskStatusLike): A2AExtractResult | null {\n if (!status.metadata) return null;\n return extractReceiptFromMetadata(status.metadata);\n}\n\n/** Extract carriers from A2A TaskStatus (async) */\nexport async function extractReceiptFromTaskStatusAsync(\n status: A2ATaskStatusLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!status.metadata) return null;\n return extractReceiptFromMetadataAsync(status.metadata);\n}\n\n/** Extract carriers from A2A Message (sync) */\nexport function extractReceiptFromMessage(msg: A2AMessageLike): A2AExtractResult | null {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadata(msg.metadata);\n}\n\n/** Extract carriers from A2A Message (async) */\nexport async function extractReceiptFromMessageAsync(\n msg: A2AMessageLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadataAsync(msg.metadata);\n}\n\n/** Extract carriers from A2A Artifact (sync) */\nexport function extractReceiptFromArtifact(artifact: A2AArtifactLike): A2AExtractResult | null {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadata(artifact.metadata);\n}\n\n/** Extract carriers from A2A Artifact (async) */\nexport async function extractReceiptFromArtifactAsync(\n artifact: A2AArtifactLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadataAsync(artifact.metadata);\n}\n","/**\n * A2A carrier adapter implementing CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike>.\n *\n * Bridges PeacEvidenceCarrier to A2A TaskStatus metadata per .\n */\n\nimport type {\n PeacEvidenceCarrier,\n CarrierMeta,\n CarrierValidationResult,\n CarrierAdapter,\n} from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type { A2ATaskStatusLike } from './types';\nimport { A2A_MAX_CARRIER_SIZE } from './types';\nimport { attachReceiptToTaskStatus } from './attach';\nimport { extractReceiptFromTaskStatus } from './extract';\n\n/**\n * CarrierAdapter implementation for A2A TaskStatus messages.\n *\n * Uses metadata[PEAC_EXTENSION_URI] = { carriers: [...] } layout.\n */\nexport class A2ACarrierAdapter implements CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike> {\n extract(input: A2ATaskStatusLike): { receipts: PeacEvidenceCarrier[]; meta: CarrierMeta } | null {\n return extractReceiptFromTaskStatus(input);\n }\n\n attach(\n output: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n ): A2ATaskStatusLike {\n return attachReceiptToTaskStatus(output, carriers, meta);\n }\n\n validateConstraints(carrier: PeacEvidenceCarrier, meta: CarrierMeta): CarrierValidationResult {\n return validateCarrierConstraints(carrier, meta);\n }\n}\n\n/** Default CarrierMeta for A2A transport */\nexport function createA2ACarrierMeta(overrides?: Partial<CarrierMeta>): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n ...overrides,\n };\n}\n","/**\n * A2A extension header utilities.\n *\n * Handles the A2A-Extensions header for advertising supported extensions\n * per (no X- prefix headers).\n */\n\n/**\n * Parse comma-separated A2A extension URIs from header value.\n *\n * @param header - Raw header value (e.g. \"https://example.com/ext/a, https://example.com/ext/b\")\n * @returns Array of trimmed, non-empty extension URIs\n */\nexport function parseA2AExtensionsHeader(header: string): string[] {\n return header\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Build comma-separated A2A-Extensions header value from URIs.\n *\n * @param extensions - Array of extension URIs\n * @returns Comma-separated header value\n */\nexport function buildA2AExtensionsHeader(extensions: string[]): string {\n return extensions.join(', ');\n}\n","/**\n * A2A agent discovery with SSRF hardening (Polish C).\n *\n * Discovers A2A Agent Cards and checks for PEAC extension support.\n * Implements literal-IP blocking, optional DNS resolution checks,\n * scheme allowlist, userinfo rejection, response size cap,\n * content-type check, and redirect rejection.\n */\n\nimport type { CarrierFormat } from '@peac/kernel';\nimport { PEAC_RECEIPT_HEADER } from '@peac/kernel';\n\nimport type { A2AAgentCard, AgentCardPeacExtension } from './types';\nimport { PEAC_EXTENSION_URI } from './types';\nimport { normalizeAgentCard } from './normalizers';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum response body size (256 KB) */\nconst MAX_RESPONSE_SIZE = 256 * 1024;\n\n/** Request timeout in milliseconds */\nconst DISCOVERY_TIMEOUT_MS = 5_000;\n\n/** Private/reserved IP ranges (RFC 1918, RFC 4193, loopback, link-local) */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // loopback\n /^10\\./, // RFC 1918 Class A\n /^172\\.(1[6-9]|2\\d|3[01])\\./, // RFC 1918 Class B\n /^192\\.168\\./, // RFC 1918 Class C\n /^169\\.254\\./, // link-local\n /^0\\./, // current network\n /^::1$/, // IPv6 loopback\n /^fd[0-9a-f]{2}:/, // RFC 4193 ULA\n /^fe80:/, // IPv6 link-local\n /^fc[0-9a-f]{2}:/, // RFC 4193 ULA\n];\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** Discovery options */\nexport interface DiscoveryOptions {\n /**\n * Allow HTTP (insecure) for localhost addresses only (dev mode).\n * Default: false (HTTPS only in production).\n */\n allowInsecureLocalhost?: boolean;\n\n /** Custom fetch implementation (for testing or strict environments) */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Optional DNS resolver for DNS rebinding defense.\n *\n * When provided, discovery resolves the hostname and checks all returned\n * IP addresses against private ranges before connecting. This provides\n * full DNS rebinding protection.\n *\n * When omitted, discovery checks only literal IP addresses in the URL\n * hostname (weaker posture, but portable across runtimes).\n */\n resolveHostname?: (hostname: string) => Promise<string[]>;\n}\n\n// ---------------------------------------------------------------------------\n// SSRF helpers\n// ---------------------------------------------------------------------------\n\nfunction isPrivateIP(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip));\n}\n\nfunction isLocalhostAddress(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';\n}\n\n/**\n * Validate URL scheme, hostname, and credentials for SSRF protection.\n *\n * - Only HTTPS in production (Polish C item 6)\n * - HTTP allowed only for localhost when allowInsecureLocalhost is true\n * - Rejects private IP ranges (literal check always; DNS resolution when resolver provided)\n * - Rejects URLs with userinfo (user:pass@host) to prevent confusion in allowlists\n */\nasync function validateUrlForDiscovery(url: string, options: DiscoveryOptions): Promise<void> {\n const parsed = new URL(url);\n\n // Reject URLs with userinfo (user:pass@host)\n if (parsed.username || parsed.password) {\n throw new Error('SSRF: URLs with userinfo (credentials) are not allowed');\n }\n\n // Scheme allowlist (Polish C item 6)\n if (parsed.protocol === 'http:') {\n if (!options.allowInsecureLocalhost || !isLocalhostAddress(parsed.hostname)) {\n throw new Error(\n `SSRF: HTTP scheme not allowed for ${parsed.hostname}. ` +\n 'Use HTTPS or enable allowInsecureLocalhost for local development.'\n );\n }\n } else if (parsed.protocol !== 'https:') {\n throw new Error(`SSRF: unsupported scheme ${parsed.protocol}`);\n }\n\n // Check for private IP in hostname (literal IP check)\n if (isPrivateIP(parsed.hostname) && !isLocalhostAddress(parsed.hostname)) {\n throw new Error(`SSRF: private IP address ${parsed.hostname} not allowed`);\n }\n\n // DNS rebinding defense: resolve hostname and check all IPs (when resolver provided)\n if (options.resolveHostname && !isLocalhostAddress(parsed.hostname)) {\n const resolvedIPs = await options.resolveHostname(parsed.hostname);\n for (const ip of resolvedIPs) {\n if (isPrivateIP(ip)) {\n throw new Error(`SSRF: hostname ${parsed.hostname} resolved to private IP ${ip}`);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover A2A Agent Card from a base URL.\n *\n * Fetches the A2A v1.0.0 canonical path `/.well-known/agent-card.json`.\n * The v0.3.0 legacy fallback `/.well-known/agent.json` was removed in\n * v0.13.0 (DD-186) alongside the rest of the v0.3.0 compatibility\n * surface; deployers still serving the legacy path should publish the\n * canonical path or upgrade to an A2A v1.0.0 implementation.\n *\n * SSRF protection per Polish C:\n * 1. Private IP blocking (literal check; DNS resolution when resolveHostname provided)\n * 2. Response size cap (256 KB)\n * 3. Content-Type check (application/json)\n * 4. Redirect rejection (redirect: \"error\")\n * 5. Timeout (5 seconds)\n * 6. Scheme allowlist (HTTPS only; HTTP for localhost dev only)\n * 7. Userinfo rejection (no credentials in URLs)\n */\nexport async function discoverAgentCard(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<A2AAgentCard | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const paths = ['/.well-known/agent-card.json'];\n\n for (const path of paths) {\n const url = new URL(path, baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error', // Polish C item 4\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n continue;\n }\n\n // Content-Type check (Polish C item 3)\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n continue;\n }\n\n // Response size cap (Polish C item 2)\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const card = JSON.parse(text) as A2AAgentCard;\n\n // v1.0.0 validation (DD-186; v0.3.0 rejected). Cards MUST expose a\n // valid `supportedInterfaces[0].url`. Cards carrying only a legacy\n // top-level `url` (the v0.3.0 shape) return null from\n // normalizeAgentCard and are skipped here.\n if (typeof card.name !== 'string') {\n continue;\n }\n const normalized = normalizeAgentCard(card);\n if (!normalized) {\n continue;\n }\n\n return card;\n } catch {\n // SSRF validation errors, network errors, parse errors: try next path\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Check if an A2A Agent Card advertises PEAC extension support.\n *\n * Looks for the PEAC extension URI in capabilities.extensions[].\n */\nexport function hasPeacExtension(card: A2AAgentCard): boolean {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return false;\n }\n return extensions.some(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n}\n\n/**\n * Extract PEAC extension parameters from an A2A Agent Card.\n *\n * Returns the PEAC extension entry or null if not present.\n */\nexport function getPeacExtension(card: A2AAgentCard): AgentCardPeacExtension | null {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return null;\n }\n const entry = extensions.find(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n return (entry as AgentCardPeacExtension) ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// PEAC discovery result\n// ---------------------------------------------------------------------------\n\n/** Source of PEAC capability discovery */\nexport type PeacDiscoverySource = 'agent_card' | 'well_known' | 'header_probe';\n\n/** Result of PEAC capability discovery */\nexport interface PeacDiscoveryResult {\n source: PeacDiscoverySource;\n kinds: string[];\n carrier_formats: CarrierFormat[];\n issuer_config_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// 3-step discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover PEAC capabilities from a base URL using a 3-step algorithm:\n *\n * 1. Agent Card: check `/.well-known/agent-card.json` for PEAC extension\n * 2. Well-known: check `/.well-known/peac.json` (standalone PEAC discovery)\n * 3. Header probe: HEAD request to base URL, check for `PEAC-Receipt` header\n *\n * Returns the first successful result or null if PEAC is not supported.\n * All steps apply SSRF protections per Polish C.\n */\nexport async function discoverPeacCapabilities(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<PeacDiscoveryResult | null> {\n // Step 1: Agent Card\n const card = await discoverAgentCard(baseUrl, options);\n if (card) {\n const ext = getPeacExtension(card);\n if (ext) {\n return {\n source: 'agent_card',\n kinds: ext.params?.supported_kinds ?? ['peac-receipt/0.1'],\n carrier_formats: ext.params?.carrier_formats ?? ['embed'],\n ...(ext.params?.issuer_config_url && {\n issuer_config_url: ext.params.issuer_config_url,\n }),\n };\n }\n }\n\n // Step 2: /.well-known/peac.json\n const wellKnown = await discoverPeacWellKnown(baseUrl, options);\n if (wellKnown) {\n return wellKnown;\n }\n\n // Step 3: Header probe\n const headerProbe = await discoverPeacViaHeaderProbe(baseUrl, options);\n if (headerProbe) {\n return headerProbe;\n }\n\n return null;\n}\n\n/**\n * Step 2: Discover PEAC support via `/.well-known/peac.json`.\n */\nasync function discoverPeacWellKnown(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const url = new URL('/.well-known/peac.json', baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) return null;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n return null;\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n return null;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) return null;\n\n const data = JSON.parse(text) as Record<string, unknown>;\n\n return {\n source: 'well_known',\n kinds: Array.isArray(data.supported_kinds)\n ? (data.supported_kinds as string[])\n : ['peac-receipt/0.1'],\n carrier_formats: Array.isArray(data.carrier_formats)\n ? (data.carrier_formats as CarrierFormat[])\n : ['embed'],\n ...(typeof data.issuer_config_url === 'string' && {\n issuer_config_url: data.issuer_config_url,\n }),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Step 3: Discover PEAC support via header probe.\n *\n * Sends a HEAD request and checks for the presence of a PEAC-Receipt header.\n * This is a lightweight probe; it indicates support but provides minimal detail.\n */\nasync function discoverPeacViaHeaderProbe(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n try {\n await validateUrlForDiscovery(baseUrl, options);\n\n const response = await fetchFn(baseUrl, {\n method: 'HEAD',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n const headerKey = [...response.headers.keys()].find(\n (k) => k.toLowerCase() === PEAC_RECEIPT_HEADER.toLowerCase()\n );\n\n if (headerKey) {\n return {\n source: 'header_probe',\n kinds: ['peac-receipt/0.1'],\n carrier_formats: ['embed'],\n };\n }\n } catch {\n // Network errors, SSRF: no PEAC support detected\n }\n\n return null;\n}\n","/**\n * PKCE (Proof Key for Code Exchange) utilities for A2A OAuth flows.\n *\n * Implements S256 challenge method per RFC 7636. Plain method is\n * rejected: S256 is the only method permitted by A2A v1.0.\n */\n\nimport { ERROR_CODES } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** RFC 7636 Section 4.1: verifier length range (43-128 unreserved chars) */\nconst VERIFIER_MIN_LENGTH = 43;\nconst VERIFIER_MAX_LENGTH = 128;\n\n/** RFC 7636 unreserved characters: [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\" */\nconst UNRESERVED_REGEX = /^[A-Za-z0-9\\-._~]+$/;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Result of PKCE challenge generation.\n */\nexport interface PKCEChallenge {\n /** High-entropy code verifier (43-128 unreserved chars) */\n readonly verifier: string;\n /** Base64url-encoded SHA-256 hash of the verifier */\n readonly challenge: string;\n /** Always 'S256' */\n readonly method: 'S256';\n}\n\n/**\n * Generate a PKCE code verifier and S256 challenge.\n *\n * Uses `crypto.getRandomValues()` for verifier entropy (32 bytes,\n * base64url-encoded to 43 chars). S256 only; plain method is not\n * supported per A2A v1.0 security requirements.\n *\n * @returns PKCE verifier + challenge pair\n */\nexport async function generatePKCEChallenge(): Promise<PKCEChallenge> {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n const verifier = base64urlEncodeBytes(bytes);\n const challenge = await computeS256Challenge(verifier);\n return { verifier, challenge, method: 'S256' };\n}\n\n/**\n * Compute the S256 challenge for a given verifier.\n *\n * `BASE64URL(SHA256(ASCII(code_verifier)))` per RFC 7636 Section 4.2.\n *\n * @param verifier - Code verifier string\n * @returns Base64url-encoded SHA-256 digest\n * @throws Error if verifier does not meet RFC 7636 requirements\n */\nexport async function computeS256Challenge(verifier: string): Promise<string> {\n validateVerifierFormat(verifier);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64urlEncodeBytes(new Uint8Array(digest));\n}\n\n/**\n * Validate that a PKCE code verifier meets RFC 7636 requirements.\n *\n * Checks length (43-128) and character set (unreserved per RFC 7636 Section 4.1).\n *\n * @param verifier - Code verifier to validate\n * @throws Error with code `E_PKCE_INVALID_VERIFIER` if invalid\n */\nexport function validatePKCEVerifier(verifier: string): void {\n validateVerifierFormat(verifier);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateVerifierFormat(verifier: string): void {\n if (verifier.length < VERIFIER_MIN_LENGTH || verifier.length > VERIFIER_MAX_LENGTH) {\n throw Object.assign(\n new Error(\n `PKCE verifier length ${verifier.length} outside allowed range [${VERIFIER_MIN_LENGTH}, ${VERIFIER_MAX_LENGTH}]`\n ),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n if (!UNRESERVED_REGEX.test(verifier)) {\n throw Object.assign(\n new Error('PKCE verifier contains characters outside RFC 7636 unreserved set'),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n}\n\n/**\n * Node-safe base64url encoding from raw bytes.\n *\n * Uses Buffer when available (Node.js), falls back to manual\n * byte-to-char conversion for non-Node runtimes.\n */\nfunction base64urlEncodeBytes(bytes: Uint8Array): string {\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n base64 = Array.from(bytes, (b) => String.fromCharCode(b)).join('');\n base64 = btoa(base64);\n }\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/**\n * OAuth 2.0 authorization code flow utilities for A2A v1.0.\n *\n * A2A v1.0 specifies OAuth 2.0 with PKCE as the preferred auth model.\n * All network calls accept a `fetchFn` parameter (no global fetch).\n *\n * Config field names mirror the A2A spec OAuth flow object:\n * authorizationUrl, tokenUrl, refreshUrl, scopes, pkceRequired.\n */\n\nimport { validatePKCEVerifier } from './pkce.js';\n\n// ---------------------------------------------------------------------------\n// Adapter-local fetch signature (not `typeof fetch`)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal fetch signature for OAuth network calls.\n *\n * Narrower than global `fetch` to avoid coupling to runtime-specific\n * fetch extensions (AbortSignal, Request objects, etc.).\n */\nexport type FetchFn = (\n url: string,\n init: {\n method: string;\n headers: Record<string, string>;\n body: string;\n }\n) => Promise<{\n ok: boolean;\n status: number;\n json: () => Promise<unknown>;\n text: () => Promise<string>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Types (A2A spec-faithful naming)\n// ---------------------------------------------------------------------------\n\n/**\n * OAuth 2.0 configuration for an A2A authorization server.\n *\n * Field names mirror the A2A spec OAuth flow object.\n */\nexport interface A2AOAuthConfig {\n /** Authorization endpoint URL (HTTPS required) */\n readonly authorizationUrl: string;\n /** Token endpoint URL (HTTPS required) */\n readonly tokenUrl: string;\n /** Refresh token endpoint URL (optional, HTTPS required) */\n readonly refreshUrl?: string;\n /** Client identifier */\n readonly clientId: string;\n /** Redirect URI for authorization code delivery (HTTPS required) */\n readonly redirectUri: string;\n /** Requested scopes */\n readonly scopes?: readonly string[];\n /** Whether PKCE is required (always true for A2A v1.0) */\n readonly pkceRequired?: boolean;\n /** Additional authorization parameters (must not override reserved params) */\n readonly extraParams?: Readonly<Record<string, string>>;\n}\n\n/**\n * Authorization request parameters for constructing the redirect URL.\n */\nexport interface AuthorizationRequest {\n /** Full authorization URL with query parameters */\n readonly url: string;\n /** PKCE code verifier (store securely; needed for token exchange) */\n readonly codeVerifier: string;\n /** State parameter for CSRF protection */\n readonly state: string;\n}\n\n/**\n * OAuth 2.0 token response from the authorization server.\n */\nexport interface TokenResponse {\n readonly access_token: string;\n readonly token_type: string;\n readonly expires_in?: number;\n readonly refresh_token?: string;\n readonly scope?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Reserved OAuth parameters that extraParams must not override\n// ---------------------------------------------------------------------------\n\nconst RESERVED_PARAMS = new Set([\n 'response_type',\n 'client_id',\n 'redirect_uri',\n 'code_challenge',\n 'code_challenge_method',\n 'state',\n 'scope',\n 'grant_type',\n 'code',\n 'code_verifier',\n]);\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build an authorization URL with PKCE challenge and state parameter.\n *\n * The caller must redirect the user-agent to the returned URL. The\n * `codeVerifier` must be stored securely for the subsequent token\n * exchange call.\n *\n * @param config - A2A OAuth server configuration\n * @param pkce - PKCE challenge pair (from `generatePKCEChallenge()`)\n * @returns Authorization request with URL, verifier, and state\n * @throws Error if endpoint URLs are not HTTPS or extraParams override reserved params\n */\nexport function buildAuthorizationRequest(\n config: A2AOAuthConfig,\n pkce: { readonly challenge: string; readonly verifier: string }\n): AuthorizationRequest {\n validateEndpointUrl(config.authorizationUrl, 'authorizationUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n\n if (config.extraParams) {\n for (const key of Object.keys(config.extraParams)) {\n if (RESERVED_PARAMS.has(key)) {\n throw new Error(`extraParams must not override reserved OAuth parameter: ${key}`);\n }\n }\n }\n\n const state = generateState();\n const authUrl = new URL(config.authorizationUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('client_id', config.clientId);\n authUrl.searchParams.set('redirect_uri', config.redirectUri);\n authUrl.searchParams.set('code_challenge', pkce.challenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('state', state);\n\n if (config.scopes && config.scopes.length > 0) {\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n }\n\n if (config.extraParams) {\n for (const [key, value] of Object.entries(config.extraParams)) {\n authUrl.searchParams.set(key, value);\n }\n }\n\n return { url: authUrl.toString(), codeVerifier: pkce.verifier, state };\n}\n\n/**\n * Exchange an authorization code for tokens.\n *\n * Sends a POST to the token endpoint with the authorization code and\n * PKCE code verifier. Validates the verifier format before sending.\n *\n * @param code - Authorization code from the redirect callback\n * @param verifier - PKCE code verifier from the authorization request\n * @param config - A2A OAuth server configuration\n * @param fetchFn - Fetch implementation (no global fetch)\n * @returns Token response from the authorization server\n * @throws Error if the token endpoint returns an error response\n */\nexport async function exchangeAuthorizationCode(\n code: string,\n verifier: string,\n config: A2AOAuthConfig,\n fetchFn: FetchFn\n): Promise<TokenResponse> {\n validateEndpointUrl(config.tokenUrl, 'tokenUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n validatePKCEVerifier(verifier);\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: config.redirectUri,\n client_id: config.clientId,\n code_verifier: verifier,\n });\n\n const response = await fetchFn(config.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw Object.assign(\n new Error(\n `Token exchange failed: HTTP ${response.status}${errorBody ? `: ${errorBody}` : ''}`\n ),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED', status: response.status }\n );\n }\n\n const tokenResponse = (await response.json()) as Record<string, unknown>;\n if (\n typeof tokenResponse.access_token !== 'string' ||\n typeof tokenResponse.token_type !== 'string'\n ) {\n throw Object.assign(\n new Error('Token response missing required fields (access_token, token_type)'),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED' }\n );\n }\n\n return tokenResponse as unknown as TokenResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateEndpointUrl(url: string, name: string): void {\n if (!url.startsWith('https://') && !isLocalhostHttp(url)) {\n throw new Error(`${name} must use HTTPS (got: ${url})`);\n }\n}\n\nfunction isLocalhostHttp(url: string): boolean {\n if (!url.startsWith('http://')) return false;\n try {\n const parsed = new URL(url);\n return parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n } catch {\n return false;\n }\n}\n\nfunction generateState(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","/**\n * A2A auth event to PEAC evidence mapping.\n *\n * Maps A2A OAuth authentication events to access extension observations.\n * Auth success produces an **observation** receipt, never an automatic\n * access-decision receipt. The caller must explicitly construct\n * access-decision receipts when a business-level decision is made.\n */\n\nimport type { JsonObject } from '@peac/kernel';\nimport { ACCESS_EXTENSION_KEY } from '@peac/schema';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported A2A auth methods */\nexport type A2AAuthMethod = 'oauth2_pkce' | 'oauth2_device_code' | 'oauth2_client_credentials';\n\n/**\n * Input event describing an A2A authentication occurrence.\n *\n * This represents what happened at the auth layer, not a business\n * decision about whether to grant access.\n */\nexport interface A2AAuthEvent {\n /** Auth method used */\n readonly method: A2AAuthMethod;\n /** Resource URI that was authenticated against */\n readonly resource: string;\n /** Action that was requested (e.g., 'authenticate', 'tasks/send') */\n readonly action: string;\n /** OAuth scopes that were granted (from token response) */\n readonly grantedScopes?: readonly string[];\n /** Authorization server that issued the token */\n readonly authServer?: string;\n /** Client identifier used */\n readonly clientId?: string;\n /** ISO 8601 timestamp of the auth event */\n readonly timestamp?: string;\n}\n\n/**\n * Output structure for the access extension in a Wire 0.2 record.\n *\n * Uses `org.peacprotocol/access` extension group with `auth_event`\n * set to `'observation'` to distinguish from access-decision records.\n */\nexport interface A2AAuthEvidenceResult {\n /** Extension key for receipt `ext` field */\n readonly extensionKey: typeof ACCESS_EXTENSION_KEY;\n /** Access extension fields for the receipt */\n readonly extension: {\n readonly resource: string;\n readonly action: string;\n readonly decision: 'review';\n };\n /** Additional evidence metadata for the receipt `evidence` field */\n readonly evidence: JsonObject;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Map an A2A auth event to access extension evidence.\n *\n * Produces an **observation** receipt: `decision` is always `'review'`,\n * indicating that authentication occurred but no access decision was\n * made by the evidence layer. Callers who need `'allow'` or `'deny'`\n * decisions must explicitly construct those receipts.\n *\n * Tokens are never included in the evidence. Only structural metadata\n * (method, scopes, server, client_id) is recorded.\n *\n * @param event - A2A auth event to map\n * @returns Extension data and evidence metadata for receipt construction\n */\nexport function fromA2AAuthEvent(event: A2AAuthEvent): A2AAuthEvidenceResult {\n if (!event.resource) {\n throw new Error('A2A auth event missing resource');\n }\n if (!event.action) {\n throw new Error('A2A auth event missing action');\n }\n\n const evidence: JsonObject = {\n auth_event: 'observation',\n auth_method: event.method,\n };\n\n if (event.grantedScopes && event.grantedScopes.length > 0) {\n evidence.granted_scopes = [...event.grantedScopes];\n }\n if (event.authServer) {\n evidence.auth_server = event.authServer;\n }\n if (event.clientId) {\n evidence.client_id = event.clientId;\n }\n if (event.timestamp) {\n evidence.timestamp = event.timestamp;\n }\n\n return {\n extensionKey: ACCESS_EXTENSION_KEY,\n extension: {\n resource: event.resource,\n action: event.action,\n decision: 'review',\n },\n evidence,\n };\n}\n","/**\n * A2A auth error mapping to google.rpc.Status with ErrorInfo.\n *\n * A2A v1.0 uses gRPC-style status codes for transport errors. For\n * A2A-specific errors, implementations include `google.rpc.ErrorInfo`\n * in `status.details[]`. This module produces the full Status + ErrorInfo\n * shape for auth-related A2A errors.\n */\n\n// ---------------------------------------------------------------------------\n// google.rpc canonical codes (subset relevant to auth)\n// ---------------------------------------------------------------------------\n\n/**\n * gRPC canonical status codes used in A2A auth error responses.\n * Values match google.rpc.Code numeric assignments.\n */\nexport const GrpcStatusCode = {\n OK: 0,\n INVALID_ARGUMENT: 3,\n NOT_FOUND: 5,\n PERMISSION_DENIED: 7,\n INTERNAL: 13,\n UNAVAILABLE: 14,\n UNAUTHENTICATED: 16,\n} as const;\n\nexport type GrpcStatusCodeValue = (typeof GrpcStatusCode)[keyof typeof GrpcStatusCode];\n\n// ---------------------------------------------------------------------------\n// google.rpc.ErrorInfo shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.ErrorInfo per https://cloud.google.com/apis/design/errors.\n *\n * Included in `status.details[]` for A2A-specific auth errors.\n */\nexport interface GrpcErrorInfo {\n /** Fully-qualified type URL for ErrorInfo */\n readonly '@type': 'type.googleapis.com/google.rpc.ErrorInfo';\n /** Machine-readable error reason (SCREAMING_SNAKE_CASE) */\n readonly reason: string;\n /** Domain for the error (always 'a2a-protocol.org' per A2A spec) */\n readonly domain: string;\n /** Key-value metadata providing additional error context */\n readonly metadata: Readonly<Record<string, string>>;\n}\n\n// ---------------------------------------------------------------------------\n// google.rpc.Status shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.Status with typed ErrorInfo detail.\n *\n * This is the wire shape returned in A2A gRPC error responses and\n * JSON-RPC error data objects.\n */\nexport interface GrpcStatus {\n /** gRPC canonical status code */\n readonly code: GrpcStatusCodeValue;\n /** Human-readable error message */\n readonly message: string;\n /** Structured error details (contains ErrorInfo for A2A-specific errors) */\n readonly details: readonly GrpcErrorInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// A2A auth error definitions\n// ---------------------------------------------------------------------------\n\n/** A2A error domain per spec: implementations use the protocol domain */\nconst A2A_AUTH_DOMAIN = 'a2a-protocol.org';\n\ninterface AuthErrorDef {\n readonly grpcCode: GrpcStatusCodeValue;\n readonly message: string;\n readonly reason: string;\n}\n\nconst AUTH_ERROR_DEFS = {\n PKCE_MISMATCH: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'PKCE code challenge verification failed',\n reason: 'PKCE_CHALLENGE_MISMATCH',\n },\n PKCE_INVALID_VERIFIER: {\n grpcCode: GrpcStatusCode.INVALID_ARGUMENT,\n message: 'PKCE code verifier does not meet RFC 7636 requirements',\n reason: 'PKCE_INVALID_VERIFIER',\n },\n TOKEN_EXCHANGE_FAILED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'OAuth token exchange failed',\n reason: 'TOKEN_EXCHANGE_FAILED',\n },\n AUTH_SERVER_UNAVAILABLE: {\n grpcCode: GrpcStatusCode.UNAVAILABLE,\n message: 'Authorization server is unavailable',\n reason: 'AUTH_SERVER_UNAVAILABLE',\n },\n INVALID_AUTH_CODE: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Authorization code is invalid or expired',\n reason: 'INVALID_AUTH_CODE',\n },\n INVALID_CLIENT: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Client authentication failed',\n reason: 'INVALID_CLIENT',\n },\n SCOPE_DENIED: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Requested scope was denied by the authorization server',\n reason: 'SCOPE_DENIED',\n },\n DEVICE_CODE_EXPIRED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Device authorization code has expired',\n reason: 'DEVICE_CODE_EXPIRED',\n },\n} as const satisfies Record<string, AuthErrorDef>;\n\nexport type A2AAuthErrorCode = keyof typeof AUTH_ERROR_DEFS;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a google.rpc.Status with ErrorInfo for an A2A auth error.\n *\n * Returns the full Status shape with `details[]` containing a single\n * `google.rpc.ErrorInfo` entry, as required by the A2A spec for\n * implementation-specific errors.\n *\n * @param errorCode - A2A auth error code\n * @param metadata - Additional key-value context for ErrorInfo.metadata\n * @returns google.rpc.Status with embedded ErrorInfo\n */\nexport function createA2AAuthStatus(\n errorCode: A2AAuthErrorCode,\n metadata?: Record<string, string>\n): GrpcStatus {\n const def = AUTH_ERROR_DEFS[errorCode];\n return {\n code: def.grpcCode,\n message: def.message,\n details: [\n {\n '@type': 'type.googleapis.com/google.rpc.ErrorInfo',\n reason: def.reason,\n domain: A2A_AUTH_DOMAIN,\n metadata: metadata ?? {},\n },\n ],\n };\n}\n"]}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/normalizers.ts","../src/attach.ts","../src/extract.ts","../src/carrier.ts","../src/header.ts","../src/discovery.ts","../src/auth/pkce.ts","../src/auth/oauth.ts","../src/auth/evidence.ts","../src/auth/errors.ts"],"names":["validateCarrierConstraints"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * A2A v1.0.0 types.\n *\n * These types are defined locally rather than importing @a2a-js/sdk,\n * which brings protobuf + gRPC + express peer dependencies that are\n * not needed for evidence placement.\n *\n * A2A v0.3.0 compatibility (DD-186) was deprecated in v0.12.3 and\n * removed in v0.13.0 (DD-186 removal target honored). Agent Cards\n * carrying only a top-level `url` (the v0.3.0 shape) are no longer\n * accepted; every card must expose `supportedInterfaces[0].url`.\n * TaskState values must use the v1.0.0 prefixed SCREAMING_SNAKE_CASE\n * form; v0.3.0 kebab-case values are no longer mapped.\n */\n\nimport type { CarrierFormat, PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** PEAC traceability extension URI for A2A metadata */\nexport const PEAC_EXTENSION_URI = 'https://www.peacprotocol.org/ext/traceability/v1' as const;\n\n/** Maximum carrier size for A2A metadata (64 KB) */\nexport const A2A_MAX_CARRIER_SIZE = 65_536;\n\n// ---------------------------------------------------------------------------\n// A2A Agent Card types (v1.0.0)\n// ---------------------------------------------------------------------------\n\n/** A2A extension entry in capabilities.extensions[] */\nexport interface AgentCardExtension {\n uri: string;\n description?: string;\n required?: boolean;\n params?: Record<string, unknown>;\n}\n\n/** PEAC-specific extension entry for A2A Agent Card */\nexport interface AgentCardPeacExtension {\n uri: typeof PEAC_EXTENSION_URI;\n description: string;\n required: boolean;\n params?: {\n supported_kinds?: string[];\n carrier_formats?: CarrierFormat[];\n issuer_config_url?: string;\n };\n}\n\n/** A2A v1.0.0 supported interface entry */\nexport interface A2ASupportedInterface {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n}\n\n/**\n * Minimal A2A Agent Card shape (v1.0.0).\n *\n * v1.0.0 cards expose endpoint bindings via `supportedInterfaces[]`.\n * Every accepted card MUST carry a non-empty `supportedInterfaces[0].url`.\n *\n * The legacy v0.3.0 top-level `url` field is no longer a declared field\n * on this interface. Rejection is **runtime** (`normalizeAgentCard` returns\n * null and `discoverAgentCard` skips the card), not type-level. The\n * interface intentionally keeps a `[key: string]: unknown` index\n * signature so consumers may pass incoming JSON with unknown extra\n * fields without TypeScript errors, so a literal with a stray `url`\n * string property still typechecks. The v0.3.0 removal is enforced by\n * the normalization layer, not by the type system.\n */\nexport interface A2AAgentCard {\n name: string;\n supportedInterfaces?: A2ASupportedInterface[];\n capabilities?: {\n extensions?: AgentCardExtension[];\n extendedAgentCard?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A message types (minimal shapes)\n// ---------------------------------------------------------------------------\n\n/** A2A metadata map */\nexport type A2AMetadata = Record<string, unknown>;\n\n/** Minimal A2A TaskStatus shape */\nexport interface A2ATaskStatusLike {\n state: string;\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Message shape */\nexport interface A2AMessageLike {\n role: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Artifact shape */\nexport interface A2AArtifactLike {\n artifactId: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A v1.0.0 enum constants (reference values)\n// ---------------------------------------------------------------------------\n\n/** A2A v1.0.0 TaskState values (SCREAMING_SNAKE_CASE with type prefix) */\nexport const A2A_V1_TASK_STATE = {\n SUBMITTED: 'TASK_STATE_SUBMITTED',\n WORKING: 'TASK_STATE_WORKING',\n COMPLETED: 'TASK_STATE_COMPLETED',\n FAILED: 'TASK_STATE_FAILED',\n CANCELED: 'TASK_STATE_CANCELED',\n REJECTED: 'TASK_STATE_REJECTED',\n INPUT_REQUIRED: 'TASK_STATE_INPUT_REQUIRED',\n AUTH_REQUIRED: 'TASK_STATE_AUTH_REQUIRED',\n} as const;\n\n/** A2A v1.0.0 MessageRole values */\nexport const A2A_V1_MESSAGE_ROLE = {\n USER: 'ROLE_USER',\n AGENT: 'ROLE_AGENT',\n} as const;\n\n// The v0.3.0 → v1.0.0 TaskState mapping (previously TASK_STATE_V03_TO_V1)\n// was removed in v0.13.0 alongside the v0.3.0 compat path (DD-186).\n// Callers MUST supply v1.0.0 TaskState values directly.\n\n// ---------------------------------------------------------------------------\n// Carrier payload type\n// ---------------------------------------------------------------------------\n\n/**\n * A2A carrier payload: the value stored under metadata[PEAC_EXTENSION_URI].\n *\n * Contains an array of carriers (even for single-receipt cases) and\n * optional transport metadata.\n */\nexport interface A2APeacPayload {\n carriers: PeacEvidenceCarrier[];\n meta?: CarrierMeta;\n}\n","/**\n * A2A v1.0.0 Agent Card normalizers.\n *\n * The v0.3.0 compatibility path (DD-186; `url` top-level field plus\n * kebab-case TaskState mapping) was deprecated in v0.12.3 and removed\n * in v0.13.0. Every accepted Agent Card must expose a non-empty\n * `supportedInterfaces[0].url`; cards without it are rejected. The\n * v0.3.0-to-v1.0.0 TaskState mapping function was removed because its\n * only job was translating kebab-case inputs, which are no longer\n * accepted. TaskState values are now v1.0.0 SCREAMING_SNAKE_CASE\n * strings carried by the caller.\n */\n\nimport type { A2AAgentCard, A2ASupportedInterface } from './types';\n\n// ---------------------------------------------------------------------------\n// Agent Card normalizer\n// ---------------------------------------------------------------------------\n\n/** Normalized Agent Card with a resolved v1.0.0 URL. */\nexport interface NormalizedAgentCard {\n name: string;\n url: string;\n supportedInterfaces: A2ASupportedInterface[];\n original: A2AAgentCard;\n}\n\n/**\n * Returns true if the card satisfies the v1.0.0 Agent Card contract:\n * `supportedInterfaces[0].url` exists and is a non-empty string. Cards\n * that fail this check are rejected by `normalizeAgentCard` (they are\n * not v0.3.0 fallbacks, which are no longer accepted).\n */\nexport function isV1AgentCard(card: A2AAgentCard): boolean {\n return (\n Array.isArray(card.supportedInterfaces) &&\n card.supportedInterfaces.length > 0 &&\n typeof card.supportedInterfaces[0]?.url === 'string' &&\n card.supportedInterfaces[0].url.length > 0\n );\n}\n\n/**\n * Normalize an A2A v1.0.0 Agent Card.\n *\n * Returns a consistent shape with the resolved primary URL. Cards that\n * do not satisfy `isV1AgentCard(...)` return `null` (this includes the\n * legacy v0.3.0 shape with only a top-level `url`, which is no longer\n * supported). Callers receiving `null` should treat the card as invalid\n * and surface a structured error rather than falling back to v0.3.0.\n */\nexport function normalizeAgentCard(card: A2AAgentCard): NormalizedAgentCard | null {\n if (!isV1AgentCard(card)) return null;\n const iface = card.supportedInterfaces![0]!;\n return {\n name: card.name,\n url: iface.url,\n supportedInterfaces: card.supportedInterfaces!,\n original: card,\n };\n}\n\n/**\n * Select the best interface from a v1.0.0 Agent Card.\n *\n * Prefers the interface with the highest protocolVersion, then the first\n * entry as tiebreaker.\n */\nexport function selectBestInterface(\n interfaces: A2ASupportedInterface[]\n): A2ASupportedInterface | null {\n if (interfaces.length === 0) return null;\n return [...interfaces].sort((a, b) =>\n b.protocolVersion.localeCompare(a.protocolVersion, undefined, { numeric: true })\n )[0]!;\n}\n","/**\n * Attach PEAC evidence carriers to A2A metadata.\n *\n * Places carrier data under metadata[PEAC_EXTENSION_URI] per the A2A\n * extension-URI metadata convention (inherited from v0.3.0 and carried\n * forward in v1.0.0). Uses computeReceiptRef() from @peac/schema for\n * receipt reference computation.\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Default meta for A2A transport\n// ---------------------------------------------------------------------------\n\nfunction defaultA2AMeta(): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Core attach: metadata map\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A metadata map.\n *\n * Writes `metadata[PEAC_EXTENSION_URI] = { carriers: [...], meta }`.\n * Validates carrier constraints before attachment; throws on violation.\n *\n * @returns The modified metadata map (mutated in place and returned)\n */\nexport function attachReceiptToMetadata(\n metadata: A2AMetadata,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMetadata {\n const effectiveMeta = meta ?? defaultA2AMeta();\n\n for (const carrier of carriers) {\n const result = validateCarrierConstraints(carrier, effectiveMeta);\n if (!result.valid) {\n throw new Error(`Carrier constraint violation: ${result.violations.join('; ')}`);\n }\n }\n\n const payload: A2APeacPayload = { carriers, meta: effectiveMeta };\n metadata[PEAC_EXTENSION_URI] = payload;\n return metadata;\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: attach to A2A message types\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A TaskStatus.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToTaskStatus(\n status: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2ATaskStatusLike {\n if (!status.metadata) {\n status.metadata = {};\n }\n attachReceiptToMetadata(status.metadata, carriers, meta);\n return status;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Message.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToMessage(\n msg: A2AMessageLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMessageLike {\n if (!msg.metadata) {\n msg.metadata = {};\n }\n attachReceiptToMetadata(msg.metadata, carriers, meta);\n return msg;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Artifact.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToArtifact(\n artifact: A2AArtifactLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AArtifactLike {\n if (!artifact.metadata) {\n artifact.metadata = {};\n }\n attachReceiptToMetadata(artifact.metadata, carriers, meta);\n return artifact;\n}\n","/**\n * Extract PEAC evidence carriers from A2A metadata.\n *\n * Reads carrier data from metadata[PEAC_EXTENSION_URI] and validates\n * against PeacEvidenceCarrierSchema. Provides both sync (structural)\n * and async (receipt_ref consistency) extraction paths per .\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { PeacEvidenceCarrierSchema, verifyReceiptRefConsistency } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Result of carrier extraction */\nexport interface A2AExtractResult {\n receipts: PeacEvidenceCarrier[];\n meta: CarrierMeta;\n}\n\n/** Result of async extraction with consistency check */\nexport interface A2AExtractAsyncResult extends A2AExtractResult {\n /** Consistency violations (empty if all receipts are valid) */\n violations: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Core extract: metadata map (sync, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (sync).\n *\n * Performs structural validation only (schema check).\n * Returns null if no PEAC extension data is present.\n * Silently skips carriers that fail schema validation.\n */\nexport function extractReceiptFromMetadata(metadata: A2AMetadata): A2AExtractResult | null {\n const raw = metadata[PEAC_EXTENSION_URI];\n if (raw === undefined || raw === null) {\n return null;\n }\n\n // Validate payload shape\n if (typeof raw !== 'object' || !('carriers' in (raw as object))) {\n return null;\n }\n\n const payload = raw as A2APeacPayload;\n if (!Array.isArray(payload.carriers) || payload.carriers.length === 0) {\n return null;\n }\n\n // Validate each carrier against schema (validate at extraction)\n const validCarriers: PeacEvidenceCarrier[] = [];\n for (const carrier of payload.carriers) {\n const result = PeacEvidenceCarrierSchema.safeParse(carrier);\n if (result.success) {\n validCarriers.push(result.data as PeacEvidenceCarrier);\n }\n }\n\n if (validCarriers.length === 0) {\n return null;\n }\n\n const meta: CarrierMeta = payload.meta ?? {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n\n return { receipts: validCarriers, meta };\n}\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (async).\n *\n * Performs structural validation AND receipt_ref consistency check.\n * When receipt_jws is present, verifies sha256(receipt_jws) === receipt_ref.\n * Returns violations array for any carriers that fail the consistency check.\n */\nexport async function extractReceiptFromMetadataAsync(\n metadata: A2AMetadata\n): Promise<A2AExtractAsyncResult | null> {\n const syncResult = extractReceiptFromMetadata(metadata);\n if (syncResult === null) {\n return null;\n }\n\n const violations: string[] = [];\n const validCarriers: PeacEvidenceCarrier[] = [];\n\n for (const carrier of syncResult.receipts) {\n const error = await verifyReceiptRefConsistency(carrier);\n if (error !== null) {\n violations.push(error);\n } else {\n validCarriers.push(carrier);\n }\n }\n\n if (validCarriers.length === 0 && violations.length > 0) {\n return { receipts: [], meta: syncResult.meta, violations };\n }\n\n return { receipts: validCarriers, meta: syncResult.meta, violations };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: extract from A2A message types\n// ---------------------------------------------------------------------------\n\n/** Extract carriers from A2A TaskStatus (sync) */\nexport function extractReceiptFromTaskStatus(status: A2ATaskStatusLike): A2AExtractResult | null {\n if (!status.metadata) return null;\n return extractReceiptFromMetadata(status.metadata);\n}\n\n/** Extract carriers from A2A TaskStatus (async) */\nexport async function extractReceiptFromTaskStatusAsync(\n status: A2ATaskStatusLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!status.metadata) return null;\n return extractReceiptFromMetadataAsync(status.metadata);\n}\n\n/** Extract carriers from A2A Message (sync) */\nexport function extractReceiptFromMessage(msg: A2AMessageLike): A2AExtractResult | null {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadata(msg.metadata);\n}\n\n/** Extract carriers from A2A Message (async) */\nexport async function extractReceiptFromMessageAsync(\n msg: A2AMessageLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadataAsync(msg.metadata);\n}\n\n/** Extract carriers from A2A Artifact (sync) */\nexport function extractReceiptFromArtifact(artifact: A2AArtifactLike): A2AExtractResult | null {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadata(artifact.metadata);\n}\n\n/** Extract carriers from A2A Artifact (async) */\nexport async function extractReceiptFromArtifactAsync(\n artifact: A2AArtifactLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadataAsync(artifact.metadata);\n}\n","/**\n * A2A carrier adapter implementing CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike>.\n *\n * Bridges PeacEvidenceCarrier to A2A TaskStatus metadata per .\n */\n\nimport type {\n PeacEvidenceCarrier,\n CarrierMeta,\n CarrierValidationResult,\n CarrierAdapter,\n} from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type { A2ATaskStatusLike } from './types';\nimport { A2A_MAX_CARRIER_SIZE } from './types';\nimport { attachReceiptToTaskStatus } from './attach';\nimport { extractReceiptFromTaskStatus } from './extract';\n\n/**\n * CarrierAdapter implementation for A2A TaskStatus messages.\n *\n * Uses metadata[PEAC_EXTENSION_URI] = { carriers: [...] } layout.\n */\nexport class A2ACarrierAdapter implements CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike> {\n extract(input: A2ATaskStatusLike): { receipts: PeacEvidenceCarrier[]; meta: CarrierMeta } | null {\n return extractReceiptFromTaskStatus(input);\n }\n\n attach(\n output: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n ): A2ATaskStatusLike {\n return attachReceiptToTaskStatus(output, carriers, meta);\n }\n\n validateConstraints(carrier: PeacEvidenceCarrier, meta: CarrierMeta): CarrierValidationResult {\n return validateCarrierConstraints(carrier, meta);\n }\n}\n\n/** Default CarrierMeta for A2A transport */\nexport function createA2ACarrierMeta(overrides?: Partial<CarrierMeta>): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n ...overrides,\n };\n}\n","/**\n * A2A extension header utilities.\n *\n * Handles the A2A-Extensions header for advertising supported extensions\n * per (no X- prefix headers).\n */\n\n/**\n * Parse comma-separated A2A extension URIs from header value.\n *\n * @param header - Raw header value (e.g. \"https://example.com/ext/a, https://example.com/ext/b\")\n * @returns Array of trimmed, non-empty extension URIs\n */\nexport function parseA2AExtensionsHeader(header: string): string[] {\n return header\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Build comma-separated A2A-Extensions header value from URIs.\n *\n * @param extensions - Array of extension URIs\n * @returns Comma-separated header value\n */\nexport function buildA2AExtensionsHeader(extensions: string[]): string {\n return extensions.join(', ');\n}\n","/**\n * A2A agent discovery with SSRF hardening (Polish C).\n *\n * Discovers A2A Agent Cards and checks for PEAC extension support.\n * Implements literal-IP blocking, optional DNS resolution checks,\n * scheme allowlist, userinfo rejection, response size cap,\n * content-type check, and redirect rejection.\n */\n\nimport type { CarrierFormat } from '@peac/kernel';\nimport { PEAC_RECEIPT_HEADER } from '@peac/kernel';\n\nimport type { A2AAgentCard, AgentCardPeacExtension } from './types';\nimport { PEAC_EXTENSION_URI } from './types';\nimport { normalizeAgentCard } from './normalizers';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum response body size (256 KB) */\nconst MAX_RESPONSE_SIZE = 256 * 1024;\n\n/** Request timeout in milliseconds */\nconst DISCOVERY_TIMEOUT_MS = 5_000;\n\n/** Private/reserved IP ranges (RFC 1918, RFC 4193, loopback, link-local) */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // loopback\n /^10\\./, // RFC 1918 Class A\n /^172\\.(1[6-9]|2\\d|3[01])\\./, // RFC 1918 Class B\n /^192\\.168\\./, // RFC 1918 Class C\n /^169\\.254\\./, // link-local\n /^0\\./, // current network\n /^::1$/, // IPv6 loopback\n /^fd[0-9a-f]{2}:/, // RFC 4193 ULA\n /^fe80:/, // IPv6 link-local\n /^fc[0-9a-f]{2}:/, // RFC 4193 ULA\n];\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** Discovery options */\nexport interface DiscoveryOptions {\n /**\n * Allow HTTP (insecure) for localhost addresses only (dev mode).\n * Default: false (HTTPS only in production).\n */\n allowInsecureLocalhost?: boolean;\n\n /** Custom fetch implementation (for testing or strict environments) */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Optional DNS resolver for DNS rebinding defense.\n *\n * When provided, discovery resolves the hostname and checks all returned\n * IP addresses against private ranges before connecting. This provides\n * full DNS rebinding protection.\n *\n * When omitted, discovery checks only literal IP addresses in the URL\n * hostname (weaker posture, but portable across runtimes).\n */\n resolveHostname?: (hostname: string) => Promise<string[]>;\n}\n\n// ---------------------------------------------------------------------------\n// SSRF helpers\n// ---------------------------------------------------------------------------\n\nfunction isPrivateIP(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip));\n}\n\nfunction isLocalhostAddress(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';\n}\n\n/**\n * Validate URL scheme, hostname, and credentials for SSRF protection.\n *\n * - Only HTTPS in production (Polish C item 6)\n * - HTTP allowed only for localhost when allowInsecureLocalhost is true\n * - Rejects private IP ranges (literal check always; DNS resolution when resolver provided)\n * - Rejects URLs with userinfo (user:pass@host) to prevent confusion in allowlists\n */\nasync function validateUrlForDiscovery(url: string, options: DiscoveryOptions): Promise<void> {\n const parsed = new URL(url);\n\n // Reject URLs with userinfo (user:pass@host)\n if (parsed.username || parsed.password) {\n throw new Error('SSRF: URLs with userinfo (credentials) are not allowed');\n }\n\n // Scheme allowlist (Polish C item 6)\n if (parsed.protocol === 'http:') {\n if (!options.allowInsecureLocalhost || !isLocalhostAddress(parsed.hostname)) {\n throw new Error(\n `SSRF: HTTP scheme not allowed for ${parsed.hostname}. ` +\n 'Use HTTPS or enable allowInsecureLocalhost for local development.'\n );\n }\n } else if (parsed.protocol !== 'https:') {\n throw new Error(`SSRF: unsupported scheme ${parsed.protocol}`);\n }\n\n // Check for private IP in hostname (literal IP check)\n if (isPrivateIP(parsed.hostname) && !isLocalhostAddress(parsed.hostname)) {\n throw new Error(`SSRF: private IP address ${parsed.hostname} not allowed`);\n }\n\n // DNS rebinding defense: resolve hostname and check all IPs (when resolver provided)\n if (options.resolveHostname && !isLocalhostAddress(parsed.hostname)) {\n const resolvedIPs = await options.resolveHostname(parsed.hostname);\n for (const ip of resolvedIPs) {\n if (isPrivateIP(ip)) {\n throw new Error(`SSRF: hostname ${parsed.hostname} resolved to private IP ${ip}`);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover A2A Agent Card from a base URL.\n *\n * Fetches the A2A v1.0.0 canonical path `/.well-known/agent-card.json`.\n * The v0.3.0 legacy fallback `/.well-known/agent.json` was removed in\n * v0.13.0 (DD-186) alongside the rest of the v0.3.0 compatibility\n * surface; deployers still serving the legacy path should publish the\n * canonical path or upgrade to an A2A v1.0.0 implementation.\n *\n * SSRF protection per Polish C:\n * 1. Private IP blocking (literal check; DNS resolution when resolveHostname provided)\n * 2. Response size cap (256 KB)\n * 3. Content-Type check (application/json)\n * 4. Redirect rejection (redirect: \"error\")\n * 5. Timeout (5 seconds)\n * 6. Scheme allowlist (HTTPS only; HTTP for localhost dev only)\n * 7. Userinfo rejection (no credentials in URLs)\n */\nexport async function discoverAgentCard(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<A2AAgentCard | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const paths = ['/.well-known/agent-card.json'];\n\n for (const path of paths) {\n const url = new URL(path, baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error', // Polish C item 4\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n continue;\n }\n\n // Content-Type check (Polish C item 3)\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n continue;\n }\n\n // Response size cap (Polish C item 2)\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const card = JSON.parse(text) as A2AAgentCard;\n\n // v1.0.0 validation (DD-186; v0.3.0 rejected). Cards MUST expose a\n // valid `supportedInterfaces[0].url`. Cards carrying only a legacy\n // top-level `url` (the v0.3.0 shape) return null from\n // normalizeAgentCard and are skipped here.\n if (typeof card.name !== 'string') {\n continue;\n }\n const normalized = normalizeAgentCard(card);\n if (!normalized) {\n continue;\n }\n\n return card;\n } catch {\n // SSRF validation errors, network errors, parse errors: try next path\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Check if an A2A Agent Card advertises PEAC extension support.\n *\n * Looks for the PEAC extension URI in capabilities.extensions[].\n */\nexport function hasPeacExtension(card: A2AAgentCard): boolean {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return false;\n }\n return extensions.some(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n}\n\n/**\n * Extract PEAC extension parameters from an A2A Agent Card.\n *\n * Returns the PEAC extension entry or null if not present.\n */\nexport function getPeacExtension(card: A2AAgentCard): AgentCardPeacExtension | null {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return null;\n }\n const entry = extensions.find(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n return (entry as AgentCardPeacExtension) ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// PEAC discovery result\n// ---------------------------------------------------------------------------\n\n/** Source of PEAC capability discovery */\nexport type PeacDiscoverySource = 'agent_card' | 'well_known' | 'header_probe';\n\n/** Result of PEAC capability discovery */\nexport interface PeacDiscoveryResult {\n source: PeacDiscoverySource;\n kinds: string[];\n carrier_formats: CarrierFormat[];\n issuer_config_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// 3-step discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover PEAC capabilities from a base URL using a 3-step algorithm:\n *\n * 1. Agent Card: check `/.well-known/agent-card.json` for PEAC extension\n * 2. Well-known: check `/.well-known/peac.json` (standalone PEAC discovery)\n * 3. Header probe: HEAD request to base URL, check for `PEAC-Receipt` header\n *\n * Returns the first successful result or null if PEAC is not supported.\n * All steps apply SSRF protections per Polish C.\n */\nexport async function discoverPeacCapabilities(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<PeacDiscoveryResult | null> {\n // Step 1: Agent Card\n const card = await discoverAgentCard(baseUrl, options);\n if (card) {\n const ext = getPeacExtension(card);\n if (ext) {\n return {\n source: 'agent_card',\n kinds: ext.params?.supported_kinds ?? ['peac-receipt/0.1'],\n carrier_formats: ext.params?.carrier_formats ?? ['embed'],\n ...(ext.params?.issuer_config_url && {\n issuer_config_url: ext.params.issuer_config_url,\n }),\n };\n }\n }\n\n // Step 2: /.well-known/peac.json\n const wellKnown = await discoverPeacWellKnown(baseUrl, options);\n if (wellKnown) {\n return wellKnown;\n }\n\n // Step 3: Header probe\n const headerProbe = await discoverPeacViaHeaderProbe(baseUrl, options);\n if (headerProbe) {\n return headerProbe;\n }\n\n return null;\n}\n\n/**\n * Step 2: Discover PEAC support via `/.well-known/peac.json`.\n */\nasync function discoverPeacWellKnown(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const url = new URL('/.well-known/peac.json', baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) return null;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n return null;\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n return null;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) return null;\n\n const data = JSON.parse(text) as Record<string, unknown>;\n\n return {\n source: 'well_known',\n kinds: Array.isArray(data.supported_kinds)\n ? (data.supported_kinds as string[])\n : ['peac-receipt/0.1'],\n carrier_formats: Array.isArray(data.carrier_formats)\n ? (data.carrier_formats as CarrierFormat[])\n : ['embed'],\n ...(typeof data.issuer_config_url === 'string' && {\n issuer_config_url: data.issuer_config_url,\n }),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Step 3: Discover PEAC support via header probe.\n *\n * Sends a HEAD request and checks for the presence of a PEAC-Receipt header.\n * This is a lightweight probe; it indicates support but provides minimal detail.\n */\nasync function discoverPeacViaHeaderProbe(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n try {\n await validateUrlForDiscovery(baseUrl, options);\n\n const response = await fetchFn(baseUrl, {\n method: 'HEAD',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n const headerKey = [...response.headers.keys()].find(\n (k) => k.toLowerCase() === PEAC_RECEIPT_HEADER.toLowerCase()\n );\n\n if (headerKey) {\n return {\n source: 'header_probe',\n kinds: ['peac-receipt/0.1'],\n carrier_formats: ['embed'],\n };\n }\n } catch {\n // Network errors, SSRF: no PEAC support detected\n }\n\n return null;\n}\n","/**\n * PKCE (Proof Key for Code Exchange) utilities for A2A OAuth flows.\n *\n * Implements S256 challenge method per RFC 7636. Plain method is\n * rejected: S256 is the only method permitted by A2A v1.0.\n */\n\nimport { ERROR_CODES } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** RFC 7636 Section 4.1: verifier length range (43-128 unreserved chars) */\nconst VERIFIER_MIN_LENGTH = 43;\nconst VERIFIER_MAX_LENGTH = 128;\n\n/** RFC 7636 unreserved characters: [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\" */\nconst UNRESERVED_REGEX = /^[A-Za-z0-9\\-._~]+$/;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Result of PKCE challenge generation.\n */\nexport interface PKCEChallenge {\n /** High-entropy code verifier (43-128 unreserved chars) */\n readonly verifier: string;\n /** Base64url-encoded SHA-256 hash of the verifier */\n readonly challenge: string;\n /** Always 'S256' */\n readonly method: 'S256';\n}\n\n/**\n * Generate a PKCE code verifier and S256 challenge.\n *\n * Uses `crypto.getRandomValues()` for verifier entropy (32 bytes,\n * base64url-encoded to 43 chars). S256 only; plain method is not\n * supported per A2A v1.0 security requirements.\n *\n * @returns PKCE verifier + challenge pair\n */\nexport async function generatePKCEChallenge(): Promise<PKCEChallenge> {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n const verifier = base64urlEncodeBytes(bytes);\n const challenge = await computeS256Challenge(verifier);\n return { verifier, challenge, method: 'S256' };\n}\n\n/**\n * Compute the S256 challenge for a given verifier.\n *\n * `BASE64URL(SHA256(ASCII(code_verifier)))` per RFC 7636 Section 4.2.\n *\n * @param verifier - Code verifier string\n * @returns Base64url-encoded SHA-256 digest\n * @throws Error if verifier does not meet RFC 7636 requirements\n */\nexport async function computeS256Challenge(verifier: string): Promise<string> {\n validateVerifierFormat(verifier);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64urlEncodeBytes(new Uint8Array(digest));\n}\n\n/**\n * Validate that a PKCE code verifier meets RFC 7636 requirements.\n *\n * Checks length (43-128) and character set (unreserved per RFC 7636 Section 4.1).\n *\n * @param verifier - Code verifier to validate\n * @throws Error with code `E_PKCE_INVALID_VERIFIER` if invalid\n */\nexport function validatePKCEVerifier(verifier: string): void {\n validateVerifierFormat(verifier);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateVerifierFormat(verifier: string): void {\n if (verifier.length < VERIFIER_MIN_LENGTH || verifier.length > VERIFIER_MAX_LENGTH) {\n throw Object.assign(\n new Error(\n `PKCE verifier length ${verifier.length} outside allowed range [${VERIFIER_MIN_LENGTH}, ${VERIFIER_MAX_LENGTH}]`\n ),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n if (!UNRESERVED_REGEX.test(verifier)) {\n throw Object.assign(\n new Error('PKCE verifier contains characters outside RFC 7636 unreserved set'),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n}\n\n/**\n * Node-safe base64url encoding from raw bytes.\n *\n * Uses Buffer when available (Node.js), falls back to manual\n * byte-to-char conversion for non-Node runtimes.\n */\nfunction base64urlEncodeBytes(bytes: Uint8Array): string {\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n base64 = Array.from(bytes, (b) => String.fromCharCode(b)).join('');\n base64 = btoa(base64);\n }\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/**\n * OAuth 2.0 authorization code flow utilities for A2A v1.0.\n *\n * A2A v1.0 specifies OAuth 2.0 with PKCE as the preferred auth model.\n * All network calls accept a `fetchFn` parameter (no global fetch).\n *\n * Config field names mirror the A2A spec OAuth flow object:\n * authorizationUrl, tokenUrl, refreshUrl, scopes, pkceRequired.\n */\n\nimport { validatePKCEVerifier } from './pkce.js';\n\n// ---------------------------------------------------------------------------\n// Adapter-local fetch signature (not `typeof fetch`)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal fetch signature for OAuth network calls.\n *\n * Narrower than global `fetch` to avoid coupling to runtime-specific\n * fetch extensions (AbortSignal, Request objects, etc.).\n */\nexport type FetchFn = (\n url: string,\n init: {\n method: string;\n headers: Record<string, string>;\n body: string;\n }\n) => Promise<{\n ok: boolean;\n status: number;\n json: () => Promise<unknown>;\n text: () => Promise<string>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Types (A2A spec-faithful naming)\n// ---------------------------------------------------------------------------\n\n/**\n * OAuth 2.0 configuration for an A2A authorization server.\n *\n * Field names mirror the A2A spec OAuth flow object.\n */\nexport interface A2AOAuthConfig {\n /** Authorization endpoint URL (HTTPS required) */\n readonly authorizationUrl: string;\n /** Token endpoint URL (HTTPS required) */\n readonly tokenUrl: string;\n /** Refresh token endpoint URL (optional, HTTPS required) */\n readonly refreshUrl?: string;\n /** Client identifier */\n readonly clientId: string;\n /** Redirect URI for authorization code delivery (HTTPS required) */\n readonly redirectUri: string;\n /** Requested scopes */\n readonly scopes?: readonly string[];\n /** Whether PKCE is required (always true for A2A v1.0) */\n readonly pkceRequired?: boolean;\n /** Additional authorization parameters (must not override reserved params) */\n readonly extraParams?: Readonly<Record<string, string>>;\n}\n\n/**\n * Authorization request parameters for constructing the redirect URL.\n */\nexport interface AuthorizationRequest {\n /** Full authorization URL with query parameters */\n readonly url: string;\n /** PKCE code verifier (store securely; needed for token exchange) */\n readonly codeVerifier: string;\n /** State parameter for CSRF protection */\n readonly state: string;\n}\n\n/**\n * OAuth 2.0 token response from the authorization server.\n */\nexport interface TokenResponse {\n readonly access_token: string;\n readonly token_type: string;\n readonly expires_in?: number;\n readonly refresh_token?: string;\n readonly scope?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Reserved OAuth parameters that extraParams must not override\n// ---------------------------------------------------------------------------\n\nconst RESERVED_PARAMS = new Set([\n 'response_type',\n 'client_id',\n 'redirect_uri',\n 'code_challenge',\n 'code_challenge_method',\n 'state',\n 'scope',\n 'grant_type',\n 'code',\n 'code_verifier',\n]);\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build an authorization URL with PKCE challenge and state parameter.\n *\n * The caller must redirect the user-agent to the returned URL. The\n * `codeVerifier` must be stored securely for the subsequent token\n * exchange call.\n *\n * @param config - A2A OAuth server configuration\n * @param pkce - PKCE challenge pair (from `generatePKCEChallenge()`)\n * @returns Authorization request with URL, verifier, and state\n * @throws Error if endpoint URLs are not HTTPS or extraParams override reserved params\n */\nexport function buildAuthorizationRequest(\n config: A2AOAuthConfig,\n pkce: { readonly challenge: string; readonly verifier: string }\n): AuthorizationRequest {\n validateEndpointUrl(config.authorizationUrl, 'authorizationUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n\n if (config.extraParams) {\n for (const key of Object.keys(config.extraParams)) {\n if (RESERVED_PARAMS.has(key)) {\n throw new Error(`extraParams must not override reserved OAuth parameter: ${key}`);\n }\n }\n }\n\n const state = generateState();\n const authUrl = new URL(config.authorizationUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('client_id', config.clientId);\n authUrl.searchParams.set('redirect_uri', config.redirectUri);\n authUrl.searchParams.set('code_challenge', pkce.challenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('state', state);\n\n if (config.scopes && config.scopes.length > 0) {\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n }\n\n if (config.extraParams) {\n for (const [key, value] of Object.entries(config.extraParams)) {\n authUrl.searchParams.set(key, value);\n }\n }\n\n return { url: authUrl.toString(), codeVerifier: pkce.verifier, state };\n}\n\n/**\n * Exchange an authorization code for tokens.\n *\n * Sends a POST to the token endpoint with the authorization code and\n * PKCE code verifier. Validates the verifier format before sending.\n *\n * @param code - Authorization code from the redirect callback\n * @param verifier - PKCE code verifier from the authorization request\n * @param config - A2A OAuth server configuration\n * @param fetchFn - Fetch implementation (no global fetch)\n * @returns Token response from the authorization server\n * @throws Error if the token endpoint returns an error response\n */\nexport async function exchangeAuthorizationCode(\n code: string,\n verifier: string,\n config: A2AOAuthConfig,\n fetchFn: FetchFn\n): Promise<TokenResponse> {\n validateEndpointUrl(config.tokenUrl, 'tokenUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n validatePKCEVerifier(verifier);\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: config.redirectUri,\n client_id: config.clientId,\n code_verifier: verifier,\n });\n\n const response = await fetchFn(config.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw Object.assign(\n new Error(\n `Token exchange failed: HTTP ${response.status}${errorBody ? `: ${errorBody}` : ''}`\n ),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED', status: response.status }\n );\n }\n\n const tokenResponse = (await response.json()) as Record<string, unknown>;\n if (\n typeof tokenResponse.access_token !== 'string' ||\n typeof tokenResponse.token_type !== 'string'\n ) {\n throw Object.assign(\n new Error('Token response missing required fields (access_token, token_type)'),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED' }\n );\n }\n\n return tokenResponse as unknown as TokenResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateEndpointUrl(url: string, name: string): void {\n if (!url.startsWith('https://') && !isLocalhostHttp(url)) {\n throw new Error(`${name} must use HTTPS (got: ${url})`);\n }\n}\n\nfunction isLocalhostHttp(url: string): boolean {\n if (!url.startsWith('http://')) return false;\n try {\n const parsed = new URL(url);\n return parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n } catch {\n return false;\n }\n}\n\nfunction generateState(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","/**\n * A2A auth event to PEAC evidence mapping.\n *\n * Maps A2A OAuth authentication events to access extension observations.\n * Auth success produces an **observation** receipt, never an automatic\n * access-decision receipt. The caller must explicitly construct\n * access-decision receipts when a business-level decision is made.\n */\n\nimport type { JsonObject } from '@peac/kernel';\nimport { ACCESS_EXTENSION_KEY } from '@peac/schema';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported A2A auth methods */\nexport type A2AAuthMethod = 'oauth2_pkce' | 'oauth2_device_code' | 'oauth2_client_credentials';\n\n/**\n * Input event describing an A2A authentication occurrence.\n *\n * This represents what happened at the auth layer, not a business\n * decision about whether to grant access.\n */\nexport interface A2AAuthEvent {\n /** Auth method used */\n readonly method: A2AAuthMethod;\n /** Resource URI that was authenticated against */\n readonly resource: string;\n /** Action that was requested (e.g., 'authenticate', 'tasks/send') */\n readonly action: string;\n /** OAuth scopes that were granted (from token response) */\n readonly grantedScopes?: readonly string[];\n /** Authorization server that issued the token */\n readonly authServer?: string;\n /** Client identifier used */\n readonly clientId?: string;\n /** ISO 8601 timestamp of the auth event */\n readonly timestamp?: string;\n}\n\n/**\n * Output structure for the access extension in a Wire 0.2 receipt.\n *\n * Uses `org.peacprotocol/access` extension group with `auth_event`\n * set to `'observation'` to distinguish from access-decision receipts.\n */\nexport interface A2AAuthEvidenceResult {\n /** Extension key for receipt `ext` field */\n readonly extensionKey: typeof ACCESS_EXTENSION_KEY;\n /** Access extension fields for the receipt */\n readonly extension: {\n readonly resource: string;\n readonly action: string;\n readonly decision: 'review';\n };\n /** Additional evidence metadata for the receipt `evidence` field */\n readonly evidence: JsonObject;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Map an A2A auth event to access extension evidence.\n *\n * Produces an **observation** receipt: `decision` is always `'review'`,\n * indicating that authentication occurred but no access decision was\n * made by the evidence layer. Callers who need `'allow'` or `'deny'`\n * decisions must explicitly construct those receipts.\n *\n * Tokens are never included in the evidence. Only structural metadata\n * (method, scopes, server, client_id) is recorded.\n *\n * @param event - A2A auth event to map\n * @returns Extension data and evidence metadata for receipt construction\n */\nexport function fromA2AAuthEvent(event: A2AAuthEvent): A2AAuthEvidenceResult {\n if (!event.resource) {\n throw new Error('A2A auth event missing resource');\n }\n if (!event.action) {\n throw new Error('A2A auth event missing action');\n }\n\n const evidence: JsonObject = {\n auth_event: 'observation',\n auth_method: event.method,\n };\n\n if (event.grantedScopes && event.grantedScopes.length > 0) {\n evidence.granted_scopes = [...event.grantedScopes];\n }\n if (event.authServer) {\n evidence.auth_server = event.authServer;\n }\n if (event.clientId) {\n evidence.client_id = event.clientId;\n }\n if (event.timestamp) {\n evidence.timestamp = event.timestamp;\n }\n\n return {\n extensionKey: ACCESS_EXTENSION_KEY,\n extension: {\n resource: event.resource,\n action: event.action,\n decision: 'review',\n },\n evidence,\n };\n}\n","/**\n * A2A auth error mapping to google.rpc.Status with ErrorInfo.\n *\n * A2A v1.0 uses gRPC-style status codes for transport errors. For\n * A2A-specific errors, implementations include `google.rpc.ErrorInfo`\n * in `status.details[]`. This module produces the full Status + ErrorInfo\n * shape for auth-related A2A errors.\n */\n\n// ---------------------------------------------------------------------------\n// google.rpc canonical codes (subset relevant to auth)\n// ---------------------------------------------------------------------------\n\n/**\n * gRPC canonical status codes used in A2A auth error responses.\n * Values match google.rpc.Code numeric assignments.\n */\nexport const GrpcStatusCode = {\n OK: 0,\n INVALID_ARGUMENT: 3,\n NOT_FOUND: 5,\n PERMISSION_DENIED: 7,\n INTERNAL: 13,\n UNAVAILABLE: 14,\n UNAUTHENTICATED: 16,\n} as const;\n\nexport type GrpcStatusCodeValue = (typeof GrpcStatusCode)[keyof typeof GrpcStatusCode];\n\n// ---------------------------------------------------------------------------\n// google.rpc.ErrorInfo shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.ErrorInfo per https://cloud.google.com/apis/design/errors.\n *\n * Included in `status.details[]` for A2A-specific auth errors.\n */\nexport interface GrpcErrorInfo {\n /** Fully-qualified type URL for ErrorInfo */\n readonly '@type': 'type.googleapis.com/google.rpc.ErrorInfo';\n /** Machine-readable error reason (SCREAMING_SNAKE_CASE) */\n readonly reason: string;\n /** Domain for the error (always 'a2a-protocol.org' per A2A spec) */\n readonly domain: string;\n /** Key-value metadata providing additional error context */\n readonly metadata: Readonly<Record<string, string>>;\n}\n\n// ---------------------------------------------------------------------------\n// google.rpc.Status shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.Status with typed ErrorInfo detail.\n *\n * This is the wire shape returned in A2A gRPC error responses and\n * JSON-RPC error data objects.\n */\nexport interface GrpcStatus {\n /** gRPC canonical status code */\n readonly code: GrpcStatusCodeValue;\n /** Human-readable error message */\n readonly message: string;\n /** Structured error details (contains ErrorInfo for A2A-specific errors) */\n readonly details: readonly GrpcErrorInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// A2A auth error definitions\n// ---------------------------------------------------------------------------\n\n/** A2A error domain per spec: implementations use the protocol domain */\nconst A2A_AUTH_DOMAIN = 'a2a-protocol.org';\n\ninterface AuthErrorDef {\n readonly grpcCode: GrpcStatusCodeValue;\n readonly message: string;\n readonly reason: string;\n}\n\nconst AUTH_ERROR_DEFS = {\n PKCE_MISMATCH: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'PKCE code challenge verification failed',\n reason: 'PKCE_CHALLENGE_MISMATCH',\n },\n PKCE_INVALID_VERIFIER: {\n grpcCode: GrpcStatusCode.INVALID_ARGUMENT,\n message: 'PKCE code verifier does not meet RFC 7636 requirements',\n reason: 'PKCE_INVALID_VERIFIER',\n },\n TOKEN_EXCHANGE_FAILED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'OAuth token exchange failed',\n reason: 'TOKEN_EXCHANGE_FAILED',\n },\n AUTH_SERVER_UNAVAILABLE: {\n grpcCode: GrpcStatusCode.UNAVAILABLE,\n message: 'Authorization server is unavailable',\n reason: 'AUTH_SERVER_UNAVAILABLE',\n },\n INVALID_AUTH_CODE: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Authorization code is invalid or expired',\n reason: 'INVALID_AUTH_CODE',\n },\n INVALID_CLIENT: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Client authentication failed',\n reason: 'INVALID_CLIENT',\n },\n SCOPE_DENIED: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Requested scope was denied by the authorization server',\n reason: 'SCOPE_DENIED',\n },\n DEVICE_CODE_EXPIRED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Device authorization code has expired',\n reason: 'DEVICE_CODE_EXPIRED',\n },\n} as const satisfies Record<string, AuthErrorDef>;\n\nexport type A2AAuthErrorCode = keyof typeof AUTH_ERROR_DEFS;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a google.rpc.Status with ErrorInfo for an A2A auth error.\n *\n * Returns the full Status shape with `details[]` containing a single\n * `google.rpc.ErrorInfo` entry, as required by the A2A spec for\n * implementation-specific errors.\n *\n * @param errorCode - A2A auth error code\n * @param metadata - Additional key-value context for ErrorInfo.metadata\n * @returns google.rpc.Status with embedded ErrorInfo\n */\nexport function createA2AAuthStatus(\n errorCode: A2AAuthErrorCode,\n metadata?: Record<string, string>\n): GrpcStatus {\n const def = AUTH_ERROR_DEFS[errorCode];\n return {\n code: def.grpcCode,\n message: def.message,\n details: [\n {\n '@type': 'type.googleapis.com/google.rpc.ErrorInfo',\n reason: def.reason,\n domain: A2A_AUTH_DOMAIN,\n metadata: metadata ?? {},\n },\n ],\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/normalizers.ts","../src/attach.ts","../src/extract.ts","../src/carrier.ts","../src/header.ts","../src/discovery.ts","../src/auth/pkce.ts","../src/auth/oauth.ts","../src/auth/evidence.ts","../src/auth/errors.ts"],"names":["validateCarrierConstraints"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * A2A v1.0.0 types.\n *\n * These types are defined locally rather than importing @a2a-js/sdk,\n * which brings protobuf + gRPC + express peer dependencies that are\n * not needed for evidence placement.\n *\n * A2A v0.3.0 compatibility (DD-186) was deprecated in v0.12.3 and\n * removed in v0.13.0 (DD-186 removal target honored). Agent Cards\n * carrying only a top-level `url` (the v0.3.0 shape) are no longer\n * accepted; every card must expose `supportedInterfaces[0].url`.\n * TaskState values must use the v1.0.0 prefixed SCREAMING_SNAKE_CASE\n * form; v0.3.0 kebab-case values are no longer mapped.\n */\n\nimport type { CarrierFormat, PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** PEAC traceability extension URI for A2A metadata */\nexport const PEAC_EXTENSION_URI = 'https://www.peacprotocol.org/ext/traceability/v1' as const;\n\n/** Maximum carrier size for A2A metadata (64 KB) */\nexport const A2A_MAX_CARRIER_SIZE = 65_536;\n\n// ---------------------------------------------------------------------------\n// A2A Agent Card types (v1.0.0)\n// ---------------------------------------------------------------------------\n\n/** A2A extension entry in capabilities.extensions[] */\nexport interface AgentCardExtension {\n uri: string;\n description?: string;\n required?: boolean;\n params?: Record<string, unknown>;\n}\n\n/** PEAC-specific extension entry for A2A Agent Card */\nexport interface AgentCardPeacExtension {\n uri: typeof PEAC_EXTENSION_URI;\n description: string;\n required: boolean;\n params?: {\n supported_kinds?: string[];\n carrier_formats?: CarrierFormat[];\n issuer_config_url?: string;\n };\n}\n\n/** A2A v1.0.0 supported interface entry */\nexport interface A2ASupportedInterface {\n url: string;\n protocolBinding: string;\n protocolVersion: string;\n}\n\n/**\n * Minimal A2A Agent Card shape (v1.0.0).\n *\n * v1.0.0 cards expose endpoint bindings via `supportedInterfaces[]`.\n * Every accepted card MUST carry a non-empty `supportedInterfaces[0].url`.\n *\n * The legacy v0.3.0 top-level `url` field is no longer a declared field\n * on this interface. Rejection is **runtime** (`normalizeAgentCard` returns\n * null and `discoverAgentCard` skips the card), not type-level. The\n * interface intentionally keeps a `[key: string]: unknown` index\n * signature so consumers may pass incoming JSON with unknown extra\n * fields without TypeScript errors, so a literal with a stray `url`\n * string property still typechecks. The v0.3.0 removal is enforced by\n * the normalization layer, not by the type system.\n */\nexport interface A2AAgentCard {\n name: string;\n supportedInterfaces?: A2ASupportedInterface[];\n capabilities?: {\n extensions?: AgentCardExtension[];\n extendedAgentCard?: boolean;\n [key: string]: unknown;\n };\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A message types (minimal shapes)\n// ---------------------------------------------------------------------------\n\n/** A2A metadata map */\nexport type A2AMetadata = Record<string, unknown>;\n\n/** Minimal A2A TaskStatus shape */\nexport interface A2ATaskStatusLike {\n state: string;\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Message shape */\nexport interface A2AMessageLike {\n role: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n/** Minimal A2A Artifact shape */\nexport interface A2AArtifactLike {\n artifactId: string;\n parts: unknown[];\n metadata?: A2AMetadata;\n [key: string]: unknown;\n}\n\n// ---------------------------------------------------------------------------\n// A2A v1.0.0 enum constants (reference values)\n// ---------------------------------------------------------------------------\n\n/** A2A v1.0.0 TaskState values (SCREAMING_SNAKE_CASE with type prefix) */\nexport const A2A_V1_TASK_STATE = {\n SUBMITTED: 'TASK_STATE_SUBMITTED',\n WORKING: 'TASK_STATE_WORKING',\n COMPLETED: 'TASK_STATE_COMPLETED',\n FAILED: 'TASK_STATE_FAILED',\n CANCELED: 'TASK_STATE_CANCELED',\n REJECTED: 'TASK_STATE_REJECTED',\n INPUT_REQUIRED: 'TASK_STATE_INPUT_REQUIRED',\n AUTH_REQUIRED: 'TASK_STATE_AUTH_REQUIRED',\n} as const;\n\n/** A2A v1.0.0 MessageRole values */\nexport const A2A_V1_MESSAGE_ROLE = {\n USER: 'ROLE_USER',\n AGENT: 'ROLE_AGENT',\n} as const;\n\n// The v0.3.0 → v1.0.0 TaskState mapping (previously TASK_STATE_V03_TO_V1)\n// was removed in v0.13.0 alongside the v0.3.0 compat path (DD-186).\n// Callers MUST supply v1.0.0 TaskState values directly.\n\n// ---------------------------------------------------------------------------\n// Carrier payload type\n// ---------------------------------------------------------------------------\n\n/**\n * A2A carrier payload: the value stored under metadata[PEAC_EXTENSION_URI].\n *\n * Contains an array of carriers (even for single-receipt cases) and\n * optional transport metadata.\n */\nexport interface A2APeacPayload {\n carriers: PeacEvidenceCarrier[];\n meta?: CarrierMeta;\n}\n","/**\n * A2A v1.0.0 Agent Card normalizers.\n *\n * The v0.3.0 compatibility path (DD-186; `url` top-level field plus\n * kebab-case TaskState mapping) was deprecated in v0.12.3 and removed\n * in v0.13.0. Every accepted Agent Card must expose a non-empty\n * `supportedInterfaces[0].url`; cards without it are rejected. The\n * v0.3.0-to-v1.0.0 TaskState mapping function was removed because its\n * only job was translating kebab-case inputs, which are no longer\n * accepted. TaskState values are now v1.0.0 SCREAMING_SNAKE_CASE\n * strings carried by the caller.\n */\n\nimport type { A2AAgentCard, A2ASupportedInterface } from './types';\n\n// ---------------------------------------------------------------------------\n// Agent Card normalizer\n// ---------------------------------------------------------------------------\n\n/** Normalized Agent Card with a resolved v1.0.0 URL. */\nexport interface NormalizedAgentCard {\n name: string;\n url: string;\n supportedInterfaces: A2ASupportedInterface[];\n original: A2AAgentCard;\n}\n\n/**\n * Returns true if the card satisfies the v1.0.0 Agent Card contract:\n * `supportedInterfaces[0].url` exists and is a non-empty string. Cards\n * that fail this check are rejected by `normalizeAgentCard` (they are\n * not v0.3.0 fallbacks, which are no longer accepted).\n */\nexport function isV1AgentCard(card: A2AAgentCard): boolean {\n return (\n Array.isArray(card.supportedInterfaces) &&\n card.supportedInterfaces.length > 0 &&\n typeof card.supportedInterfaces[0]?.url === 'string' &&\n card.supportedInterfaces[0].url.length > 0\n );\n}\n\n/**\n * Normalize an A2A v1.0.0 Agent Card.\n *\n * Returns a consistent shape with the resolved primary URL. Cards that\n * do not satisfy `isV1AgentCard(...)` return `null` (this includes the\n * legacy v0.3.0 shape with only a top-level `url`, which is no longer\n * supported). Callers receiving `null` should treat the card as invalid\n * and surface a structured error rather than falling back to v0.3.0.\n */\nexport function normalizeAgentCard(card: A2AAgentCard): NormalizedAgentCard | null {\n if (!isV1AgentCard(card)) return null;\n const iface = card.supportedInterfaces![0]!;\n return {\n name: card.name,\n url: iface.url,\n supportedInterfaces: card.supportedInterfaces!,\n original: card,\n };\n}\n\n/**\n * Select the best interface from a v1.0.0 Agent Card.\n *\n * Prefers the interface with the highest protocolVersion, then the first\n * entry as tiebreaker.\n */\nexport function selectBestInterface(\n interfaces: A2ASupportedInterface[]\n): A2ASupportedInterface | null {\n if (interfaces.length === 0) return null;\n return [...interfaces].sort((a, b) =>\n b.protocolVersion.localeCompare(a.protocolVersion, undefined, { numeric: true })\n )[0]!;\n}\n","/**\n * Attach PEAC evidence carriers to A2A metadata.\n *\n * Places carrier data under metadata[PEAC_EXTENSION_URI] per the A2A\n * extension-URI metadata convention (inherited from v0.3.0 and carried\n * forward in v1.0.0). Uses computeReceiptRef() from @peac/schema for\n * receipt reference computation.\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Default meta for A2A transport\n// ---------------------------------------------------------------------------\n\nfunction defaultA2AMeta(): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Core attach: metadata map\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A metadata map.\n *\n * Writes `metadata[PEAC_EXTENSION_URI] = { carriers: [...], meta }`.\n * Validates carrier constraints before attachment; throws on violation.\n *\n * @returns The modified metadata map (mutated in place and returned)\n */\nexport function attachReceiptToMetadata(\n metadata: A2AMetadata,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMetadata {\n const effectiveMeta = meta ?? defaultA2AMeta();\n\n for (const carrier of carriers) {\n const result = validateCarrierConstraints(carrier, effectiveMeta);\n if (!result.valid) {\n throw new Error(`Carrier constraint violation: ${result.violations.join('; ')}`);\n }\n }\n\n const payload: A2APeacPayload = { carriers, meta: effectiveMeta };\n metadata[PEAC_EXTENSION_URI] = payload;\n return metadata;\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: attach to A2A message types\n// ---------------------------------------------------------------------------\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A TaskStatus.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToTaskStatus(\n status: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2ATaskStatusLike {\n if (!status.metadata) {\n status.metadata = {};\n }\n attachReceiptToMetadata(status.metadata, carriers, meta);\n return status;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Message.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToMessage(\n msg: A2AMessageLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AMessageLike {\n if (!msg.metadata) {\n msg.metadata = {};\n }\n attachReceiptToMetadata(msg.metadata, carriers, meta);\n return msg;\n}\n\n/**\n * Attach PEAC evidence carrier(s) to an A2A Artifact.\n * Initializes `metadata` if absent.\n */\nexport function attachReceiptToArtifact(\n artifact: A2AArtifactLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n): A2AArtifactLike {\n if (!artifact.metadata) {\n artifact.metadata = {};\n }\n attachReceiptToMetadata(artifact.metadata, carriers, meta);\n return artifact;\n}\n","/**\n * Extract PEAC evidence carriers from A2A metadata.\n *\n * Reads carrier data from metadata[PEAC_EXTENSION_URI] and validates\n * against PeacEvidenceCarrierSchema. Provides both sync (structural)\n * and async (receipt_ref consistency) extraction paths per .\n */\n\nimport type { PeacEvidenceCarrier, CarrierMeta } from '@peac/kernel';\nimport { PeacEvidenceCarrierSchema, verifyReceiptRefConsistency } from '@peac/schema';\n\nimport type {\n A2AMetadata,\n A2ATaskStatusLike,\n A2AMessageLike,\n A2AArtifactLike,\n A2APeacPayload,\n} from './types';\nimport { PEAC_EXTENSION_URI, A2A_MAX_CARRIER_SIZE } from './types';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Result of carrier extraction */\nexport interface A2AExtractResult {\n receipts: PeacEvidenceCarrier[];\n meta: CarrierMeta;\n}\n\n/** Result of async extraction with consistency check */\nexport interface A2AExtractAsyncResult extends A2AExtractResult {\n /** Consistency violations (empty if all receipts are valid) */\n violations: string[];\n}\n\n// ---------------------------------------------------------------------------\n// Core extract: metadata map (sync, structural only)\n// ---------------------------------------------------------------------------\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (sync).\n *\n * Performs structural validation only (schema check).\n * Returns null if no PEAC extension data is present.\n * Silently skips carriers that fail schema validation.\n */\nexport function extractReceiptFromMetadata(metadata: A2AMetadata): A2AExtractResult | null {\n const raw = metadata[PEAC_EXTENSION_URI];\n if (raw === undefined || raw === null) {\n return null;\n }\n\n // Validate payload shape\n if (typeof raw !== 'object' || !('carriers' in (raw as object))) {\n return null;\n }\n\n const payload = raw as A2APeacPayload;\n if (!Array.isArray(payload.carriers) || payload.carriers.length === 0) {\n return null;\n }\n\n // Validate each carrier against schema (validate at extraction)\n const validCarriers: PeacEvidenceCarrier[] = [];\n for (const carrier of payload.carriers) {\n const result = PeacEvidenceCarrierSchema.safeParse(carrier);\n if (result.success) {\n validCarriers.push(result.data as PeacEvidenceCarrier);\n }\n }\n\n if (validCarriers.length === 0) {\n return null;\n }\n\n const meta: CarrierMeta = payload.meta ?? {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n };\n\n return { receipts: validCarriers, meta };\n}\n\n/**\n * Extract PEAC evidence carriers from A2A metadata (async).\n *\n * Performs structural validation AND receipt_ref consistency check.\n * When receipt_jws is present, verifies sha256(receipt_jws) === receipt_ref.\n * Returns violations array for any carriers that fail the consistency check.\n */\nexport async function extractReceiptFromMetadataAsync(\n metadata: A2AMetadata\n): Promise<A2AExtractAsyncResult | null> {\n const syncResult = extractReceiptFromMetadata(metadata);\n if (syncResult === null) {\n return null;\n }\n\n const violations: string[] = [];\n const validCarriers: PeacEvidenceCarrier[] = [];\n\n for (const carrier of syncResult.receipts) {\n const error = await verifyReceiptRefConsistency(carrier);\n if (error !== null) {\n violations.push(error);\n } else {\n validCarriers.push(carrier);\n }\n }\n\n if (validCarriers.length === 0 && violations.length > 0) {\n return { receipts: [], meta: syncResult.meta, violations };\n }\n\n return { receipts: validCarriers, meta: syncResult.meta, violations };\n}\n\n// ---------------------------------------------------------------------------\n// Convenience: extract from A2A message types\n// ---------------------------------------------------------------------------\n\n/** Extract carriers from A2A TaskStatus (sync) */\nexport function extractReceiptFromTaskStatus(status: A2ATaskStatusLike): A2AExtractResult | null {\n if (!status.metadata) return null;\n return extractReceiptFromMetadata(status.metadata);\n}\n\n/** Extract carriers from A2A TaskStatus (async) */\nexport async function extractReceiptFromTaskStatusAsync(\n status: A2ATaskStatusLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!status.metadata) return null;\n return extractReceiptFromMetadataAsync(status.metadata);\n}\n\n/** Extract carriers from A2A Message (sync) */\nexport function extractReceiptFromMessage(msg: A2AMessageLike): A2AExtractResult | null {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadata(msg.metadata);\n}\n\n/** Extract carriers from A2A Message (async) */\nexport async function extractReceiptFromMessageAsync(\n msg: A2AMessageLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!msg.metadata) return null;\n return extractReceiptFromMetadataAsync(msg.metadata);\n}\n\n/** Extract carriers from A2A Artifact (sync) */\nexport function extractReceiptFromArtifact(artifact: A2AArtifactLike): A2AExtractResult | null {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadata(artifact.metadata);\n}\n\n/** Extract carriers from A2A Artifact (async) */\nexport async function extractReceiptFromArtifactAsync(\n artifact: A2AArtifactLike\n): Promise<A2AExtractAsyncResult | null> {\n if (!artifact.metadata) return null;\n return extractReceiptFromMetadataAsync(artifact.metadata);\n}\n","/**\n * A2A carrier adapter implementing CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike>.\n *\n * Bridges PeacEvidenceCarrier to A2A TaskStatus metadata per .\n */\n\nimport type {\n PeacEvidenceCarrier,\n CarrierMeta,\n CarrierValidationResult,\n CarrierAdapter,\n} from '@peac/kernel';\nimport { validateCarrierConstraints } from '@peac/schema';\n\nimport type { A2ATaskStatusLike } from './types';\nimport { A2A_MAX_CARRIER_SIZE } from './types';\nimport { attachReceiptToTaskStatus } from './attach';\nimport { extractReceiptFromTaskStatus } from './extract';\n\n/**\n * CarrierAdapter implementation for A2A TaskStatus messages.\n *\n * Uses metadata[PEAC_EXTENSION_URI] = { carriers: [...] } layout.\n */\nexport class A2ACarrierAdapter implements CarrierAdapter<A2ATaskStatusLike, A2ATaskStatusLike> {\n extract(input: A2ATaskStatusLike): { receipts: PeacEvidenceCarrier[]; meta: CarrierMeta } | null {\n return extractReceiptFromTaskStatus(input);\n }\n\n attach(\n output: A2ATaskStatusLike,\n carriers: PeacEvidenceCarrier[],\n meta?: CarrierMeta\n ): A2ATaskStatusLike {\n return attachReceiptToTaskStatus(output, carriers, meta);\n }\n\n validateConstraints(carrier: PeacEvidenceCarrier, meta: CarrierMeta): CarrierValidationResult {\n return validateCarrierConstraints(carrier, meta);\n }\n}\n\n/** Default CarrierMeta for A2A transport */\nexport function createA2ACarrierMeta(overrides?: Partial<CarrierMeta>): CarrierMeta {\n return {\n transport: 'a2a',\n format: 'embed',\n max_size: A2A_MAX_CARRIER_SIZE,\n ...overrides,\n };\n}\n","/**\n * A2A extension header utilities.\n *\n * Handles the A2A-Extensions header for advertising supported extensions\n * per (no X- prefix headers).\n */\n\n/**\n * Parse comma-separated A2A extension URIs from header value.\n *\n * @param header - Raw header value (e.g. \"https://example.com/ext/a, https://example.com/ext/b\")\n * @returns Array of trimmed, non-empty extension URIs\n */\nexport function parseA2AExtensionsHeader(header: string): string[] {\n return header\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\n/**\n * Build comma-separated A2A-Extensions header value from URIs.\n *\n * @param extensions - Array of extension URIs\n * @returns Comma-separated header value\n */\nexport function buildA2AExtensionsHeader(extensions: string[]): string {\n return extensions.join(', ');\n}\n","/**\n * A2A agent discovery with SSRF hardening (Polish C).\n *\n * Discovers A2A Agent Cards and checks for PEAC extension support.\n * Implements literal-IP blocking, optional DNS resolution checks,\n * scheme allowlist, userinfo rejection, response size cap,\n * content-type check, and redirect rejection.\n */\n\nimport type { CarrierFormat } from '@peac/kernel';\nimport { PEAC_RECEIPT_HEADER } from '@peac/kernel';\n\nimport type { A2AAgentCard, AgentCardPeacExtension } from './types';\nimport { PEAC_EXTENSION_URI } from './types';\nimport { normalizeAgentCard } from './normalizers';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** Maximum response body size (256 KB) */\nconst MAX_RESPONSE_SIZE = 256 * 1024;\n\n/** Request timeout in milliseconds */\nconst DISCOVERY_TIMEOUT_MS = 5_000;\n\n/** Private/reserved IP ranges (RFC 1918, RFC 4193, loopback, link-local) */\nconst PRIVATE_IP_PATTERNS = [\n /^127\\./, // loopback\n /^10\\./, // RFC 1918 Class A\n /^172\\.(1[6-9]|2\\d|3[01])\\./, // RFC 1918 Class B\n /^192\\.168\\./, // RFC 1918 Class C\n /^169\\.254\\./, // link-local\n /^0\\./, // current network\n /^::1$/, // IPv6 loopback\n /^fd[0-9a-f]{2}:/, // RFC 4193 ULA\n /^fe80:/, // IPv6 link-local\n /^fc[0-9a-f]{2}:/, // RFC 4193 ULA\n];\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/** Discovery options */\nexport interface DiscoveryOptions {\n /**\n * Allow HTTP (insecure) for localhost addresses only (dev mode).\n * Default: false (HTTPS only in production).\n */\n allowInsecureLocalhost?: boolean;\n\n /** Custom fetch implementation (for testing or strict environments) */\n fetch?: typeof globalThis.fetch;\n\n /**\n * Optional DNS resolver for DNS rebinding defense.\n *\n * When provided, discovery resolves the hostname and checks all returned\n * IP addresses against private ranges before connecting. This provides\n * full DNS rebinding protection.\n *\n * When omitted, discovery checks only literal IP addresses in the URL\n * hostname (weaker posture, but portable across runtimes).\n */\n resolveHostname?: (hostname: string) => Promise<string[]>;\n}\n\n// ---------------------------------------------------------------------------\n// SSRF helpers\n// ---------------------------------------------------------------------------\n\nfunction isPrivateIP(ip: string): boolean {\n return PRIVATE_IP_PATTERNS.some((pattern) => pattern.test(ip));\n}\n\nfunction isLocalhostAddress(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';\n}\n\n/**\n * Validate URL scheme, hostname, and credentials for SSRF protection.\n *\n * - Only HTTPS in production (Polish C item 6)\n * - HTTP allowed only for localhost when allowInsecureLocalhost is true\n * - Rejects private IP ranges (literal check always; DNS resolution when resolver provided)\n * - Rejects URLs with userinfo (user:pass@host) to prevent confusion in allowlists\n */\nasync function validateUrlForDiscovery(url: string, options: DiscoveryOptions): Promise<void> {\n const parsed = new URL(url);\n\n // Reject URLs with userinfo (user:pass@host)\n if (parsed.username || parsed.password) {\n throw new Error('SSRF: URLs with userinfo (credentials) are not allowed');\n }\n\n // Scheme allowlist (Polish C item 6)\n if (parsed.protocol === 'http:') {\n if (!options.allowInsecureLocalhost || !isLocalhostAddress(parsed.hostname)) {\n throw new Error(\n `SSRF: HTTP scheme not allowed for ${parsed.hostname}. ` +\n 'Use HTTPS or enable allowInsecureLocalhost for local development.'\n );\n }\n } else if (parsed.protocol !== 'https:') {\n throw new Error(`SSRF: unsupported scheme ${parsed.protocol}`);\n }\n\n // Check for private IP in hostname (literal IP check)\n if (isPrivateIP(parsed.hostname) && !isLocalhostAddress(parsed.hostname)) {\n throw new Error(`SSRF: private IP address ${parsed.hostname} not allowed`);\n }\n\n // DNS rebinding defense: resolve hostname and check all IPs (when resolver provided)\n if (options.resolveHostname && !isLocalhostAddress(parsed.hostname)) {\n const resolvedIPs = await options.resolveHostname(parsed.hostname);\n for (const ip of resolvedIPs) {\n if (isPrivateIP(ip)) {\n throw new Error(`SSRF: hostname ${parsed.hostname} resolved to private IP ${ip}`);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover A2A Agent Card from a base URL.\n *\n * Fetches the A2A v1.0.0 canonical path `/.well-known/agent-card.json`.\n * The v0.3.0 legacy fallback `/.well-known/agent.json` was removed in\n * v0.13.0 (DD-186) alongside the rest of the v0.3.0 compatibility\n * surface; deployers still serving the legacy path should publish the\n * canonical path or upgrade to an A2A v1.0.0 implementation.\n *\n * SSRF protection per Polish C:\n * 1. Private IP blocking (literal check; DNS resolution when resolveHostname provided)\n * 2. Response size cap (256 KB)\n * 3. Content-Type check (application/json)\n * 4. Redirect rejection (redirect: \"error\")\n * 5. Timeout (5 seconds)\n * 6. Scheme allowlist (HTTPS only; HTTP for localhost dev only)\n * 7. Userinfo rejection (no credentials in URLs)\n */\nexport async function discoverAgentCard(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<A2AAgentCard | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const paths = ['/.well-known/agent-card.json'];\n\n for (const path of paths) {\n const url = new URL(path, baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error', // Polish C item 4\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) {\n continue;\n }\n\n // Content-Type check (Polish C item 3)\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n continue;\n }\n\n // Response size cap (Polish C item 2)\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) {\n continue;\n }\n\n const card = JSON.parse(text) as A2AAgentCard;\n\n // v1.0.0 validation (DD-186; v0.3.0 rejected). Cards MUST expose a\n // valid `supportedInterfaces[0].url`. Cards carrying only a legacy\n // top-level `url` (the v0.3.0 shape) return null from\n // normalizeAgentCard and are skipped here.\n if (typeof card.name !== 'string') {\n continue;\n }\n const normalized = normalizeAgentCard(card);\n if (!normalized) {\n continue;\n }\n\n return card;\n } catch {\n // SSRF validation errors, network errors, parse errors: try next path\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Check if an A2A Agent Card advertises PEAC extension support.\n *\n * Looks for the PEAC extension URI in capabilities.extensions[].\n */\nexport function hasPeacExtension(card: A2AAgentCard): boolean {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return false;\n }\n return extensions.some(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n}\n\n/**\n * Extract PEAC extension parameters from an A2A Agent Card.\n *\n * Returns the PEAC extension entry or null if not present.\n */\nexport function getPeacExtension(card: A2AAgentCard): AgentCardPeacExtension | null {\n const extensions = card.capabilities?.extensions;\n if (!Array.isArray(extensions)) {\n return null;\n }\n const entry = extensions.find(\n (ext) => typeof ext === 'object' && ext !== null && ext.uri === PEAC_EXTENSION_URI\n );\n return (entry as AgentCardPeacExtension) ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// PEAC discovery result\n// ---------------------------------------------------------------------------\n\n/** Source of PEAC capability discovery */\nexport type PeacDiscoverySource = 'agent_card' | 'well_known' | 'header_probe';\n\n/** Result of PEAC capability discovery */\nexport interface PeacDiscoveryResult {\n source: PeacDiscoverySource;\n kinds: string[];\n carrier_formats: CarrierFormat[];\n issuer_config_url?: string;\n}\n\n// ---------------------------------------------------------------------------\n// 3-step discovery\n// ---------------------------------------------------------------------------\n\n/**\n * Discover PEAC capabilities from a base URL using a 3-step algorithm:\n *\n * 1. Agent Card: check `/.well-known/agent-card.json` for PEAC extension\n * 2. Well-known: check `/.well-known/peac.json` (standalone PEAC discovery)\n * 3. Header probe: HEAD request to base URL, check for `PEAC-Receipt` header\n *\n * Returns the first successful result or null if PEAC is not supported.\n * All steps apply SSRF protections per Polish C.\n */\nexport async function discoverPeacCapabilities(\n baseUrl: string,\n options: DiscoveryOptions = {}\n): Promise<PeacDiscoveryResult | null> {\n // Step 1: Agent Card\n const card = await discoverAgentCard(baseUrl, options);\n if (card) {\n const ext = getPeacExtension(card);\n if (ext) {\n return {\n source: 'agent_card',\n kinds: ext.params?.supported_kinds ?? ['peac-receipt/0.1'],\n carrier_formats: ext.params?.carrier_formats ?? ['embed'],\n ...(ext.params?.issuer_config_url && {\n issuer_config_url: ext.params.issuer_config_url,\n }),\n };\n }\n }\n\n // Step 2: /.well-known/peac.json\n const wellKnown = await discoverPeacWellKnown(baseUrl, options);\n if (wellKnown) {\n return wellKnown;\n }\n\n // Step 3: Header probe\n const headerProbe = await discoverPeacViaHeaderProbe(baseUrl, options);\n if (headerProbe) {\n return headerProbe;\n }\n\n return null;\n}\n\n/**\n * Step 2: Discover PEAC support via `/.well-known/peac.json`.\n */\nasync function discoverPeacWellKnown(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n const url = new URL('/.well-known/peac.json', baseUrl).toString();\n\n try {\n await validateUrlForDiscovery(url, options);\n\n const response = await fetchFn(url, {\n method: 'GET',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n if (!response.ok) return null;\n\n const contentType = response.headers.get('content-type') ?? '';\n if (\n !contentType.includes('application/json') &&\n !contentType.match(/application\\/[a-z0-9.+-]*\\+json/)\n ) {\n return null;\n }\n\n const contentLength = response.headers.get('content-length');\n if (contentLength && parseInt(contentLength, 10) > MAX_RESPONSE_SIZE) {\n return null;\n }\n\n const text = await response.text();\n if (text.length > MAX_RESPONSE_SIZE) return null;\n\n const data = JSON.parse(text) as Record<string, unknown>;\n\n return {\n source: 'well_known',\n kinds: Array.isArray(data.supported_kinds)\n ? (data.supported_kinds as string[])\n : ['peac-receipt/0.1'],\n carrier_formats: Array.isArray(data.carrier_formats)\n ? (data.carrier_formats as CarrierFormat[])\n : ['embed'],\n ...(typeof data.issuer_config_url === 'string' && {\n issuer_config_url: data.issuer_config_url,\n }),\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Step 3: Discover PEAC support via header probe.\n *\n * Sends a HEAD request and checks for the presence of a PEAC-Receipt header.\n * This is a lightweight probe; it indicates support but provides minimal detail.\n */\nasync function discoverPeacViaHeaderProbe(\n baseUrl: string,\n options: DiscoveryOptions\n): Promise<PeacDiscoveryResult | null> {\n const fetchFn = options.fetch ?? globalThis.fetch;\n\n try {\n await validateUrlForDiscovery(baseUrl, options);\n\n const response = await fetchFn(baseUrl, {\n method: 'HEAD',\n redirect: 'error',\n signal: AbortSignal.timeout(DISCOVERY_TIMEOUT_MS),\n });\n\n const headerKey = [...response.headers.keys()].find(\n (k) => k.toLowerCase() === PEAC_RECEIPT_HEADER.toLowerCase()\n );\n\n if (headerKey) {\n return {\n source: 'header_probe',\n kinds: ['peac-receipt/0.1'],\n carrier_formats: ['embed'],\n };\n }\n } catch {\n // Network errors, SSRF: no PEAC support detected\n }\n\n return null;\n}\n","/**\n * PKCE (Proof Key for Code Exchange) utilities for A2A OAuth flows.\n *\n * Implements S256 challenge method per RFC 7636. Plain method is\n * rejected: S256 is the only method permitted by A2A v1.0.\n */\n\nimport { ERROR_CODES } from '@peac/kernel';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/** RFC 7636 Section 4.1: verifier length range (43-128 unreserved chars) */\nconst VERIFIER_MIN_LENGTH = 43;\nconst VERIFIER_MAX_LENGTH = 128;\n\n/** RFC 7636 unreserved characters: [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\" */\nconst UNRESERVED_REGEX = /^[A-Za-z0-9\\-._~]+$/;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Result of PKCE challenge generation.\n */\nexport interface PKCEChallenge {\n /** High-entropy code verifier (43-128 unreserved chars) */\n readonly verifier: string;\n /** Base64url-encoded SHA-256 hash of the verifier */\n readonly challenge: string;\n /** Always 'S256' */\n readonly method: 'S256';\n}\n\n/**\n * Generate a PKCE code verifier and S256 challenge.\n *\n * Uses `crypto.getRandomValues()` for verifier entropy (32 bytes,\n * base64url-encoded to 43 chars). S256 only; plain method is not\n * supported per A2A v1.0 security requirements.\n *\n * @returns PKCE verifier + challenge pair\n */\nexport async function generatePKCEChallenge(): Promise<PKCEChallenge> {\n const bytes = new Uint8Array(32);\n crypto.getRandomValues(bytes);\n const verifier = base64urlEncodeBytes(bytes);\n const challenge = await computeS256Challenge(verifier);\n return { verifier, challenge, method: 'S256' };\n}\n\n/**\n * Compute the S256 challenge for a given verifier.\n *\n * `BASE64URL(SHA256(ASCII(code_verifier)))` per RFC 7636 Section 4.2.\n *\n * @param verifier - Code verifier string\n * @returns Base64url-encoded SHA-256 digest\n * @throws Error if verifier does not meet RFC 7636 requirements\n */\nexport async function computeS256Challenge(verifier: string): Promise<string> {\n validateVerifierFormat(verifier);\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64urlEncodeBytes(new Uint8Array(digest));\n}\n\n/**\n * Validate that a PKCE code verifier meets RFC 7636 requirements.\n *\n * Checks length (43-128) and character set (unreserved per RFC 7636 Section 4.1).\n *\n * @param verifier - Code verifier to validate\n * @throws Error with code `E_PKCE_INVALID_VERIFIER` if invalid\n */\nexport function validatePKCEVerifier(verifier: string): void {\n validateVerifierFormat(verifier);\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateVerifierFormat(verifier: string): void {\n if (verifier.length < VERIFIER_MIN_LENGTH || verifier.length > VERIFIER_MAX_LENGTH) {\n throw Object.assign(\n new Error(\n `PKCE verifier length ${verifier.length} outside allowed range [${VERIFIER_MIN_LENGTH}, ${VERIFIER_MAX_LENGTH}]`\n ),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n if (!UNRESERVED_REGEX.test(verifier)) {\n throw Object.assign(\n new Error('PKCE verifier contains characters outside RFC 7636 unreserved set'),\n { code: ERROR_CODES.E_PKCE_INVALID_VERIFIER }\n );\n }\n}\n\n/**\n * Node-safe base64url encoding from raw bytes.\n *\n * Uses Buffer when available (Node.js), falls back to manual\n * byte-to-char conversion for non-Node runtimes.\n */\nfunction base64urlEncodeBytes(bytes: Uint8Array): string {\n let base64: string;\n if (typeof Buffer !== 'undefined') {\n base64 = Buffer.from(bytes).toString('base64');\n } else {\n base64 = Array.from(bytes, (b) => String.fromCharCode(b)).join('');\n base64 = btoa(base64);\n }\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n","/**\n * OAuth 2.0 authorization code flow utilities for A2A v1.0.\n *\n * A2A v1.0 specifies OAuth 2.0 with PKCE as the preferred auth model.\n * All network calls accept a `fetchFn` parameter (no global fetch).\n *\n * Config field names mirror the A2A spec OAuth flow object:\n * authorizationUrl, tokenUrl, refreshUrl, scopes, pkceRequired.\n */\n\nimport { validatePKCEVerifier } from './pkce.js';\n\n// ---------------------------------------------------------------------------\n// Adapter-local fetch signature (not `typeof fetch`)\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal fetch signature for OAuth network calls.\n *\n * Narrower than global `fetch` to avoid coupling to runtime-specific\n * fetch extensions (AbortSignal, Request objects, etc.).\n */\nexport type FetchFn = (\n url: string,\n init: {\n method: string;\n headers: Record<string, string>;\n body: string;\n }\n) => Promise<{\n ok: boolean;\n status: number;\n json: () => Promise<unknown>;\n text: () => Promise<string>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Types (A2A spec-faithful naming)\n// ---------------------------------------------------------------------------\n\n/**\n * OAuth 2.0 configuration for an A2A authorization server.\n *\n * Field names mirror the A2A spec OAuth flow object.\n */\nexport interface A2AOAuthConfig {\n /** Authorization endpoint URL (HTTPS required) */\n readonly authorizationUrl: string;\n /** Token endpoint URL (HTTPS required) */\n readonly tokenUrl: string;\n /** Refresh token endpoint URL (optional, HTTPS required) */\n readonly refreshUrl?: string;\n /** Client identifier */\n readonly clientId: string;\n /** Redirect URI for authorization code delivery (HTTPS required) */\n readonly redirectUri: string;\n /** Requested scopes */\n readonly scopes?: readonly string[];\n /** Whether PKCE is required (always true for A2A v1.0) */\n readonly pkceRequired?: boolean;\n /** Additional authorization parameters (must not override reserved params) */\n readonly extraParams?: Readonly<Record<string, string>>;\n}\n\n/**\n * Authorization request parameters for constructing the redirect URL.\n */\nexport interface AuthorizationRequest {\n /** Full authorization URL with query parameters */\n readonly url: string;\n /** PKCE code verifier (store securely; needed for token exchange) */\n readonly codeVerifier: string;\n /** State parameter for CSRF protection */\n readonly state: string;\n}\n\n/**\n * OAuth 2.0 token response from the authorization server.\n */\nexport interface TokenResponse {\n readonly access_token: string;\n readonly token_type: string;\n readonly expires_in?: number;\n readonly refresh_token?: string;\n readonly scope?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Reserved OAuth parameters that extraParams must not override\n// ---------------------------------------------------------------------------\n\nconst RESERVED_PARAMS = new Set([\n 'response_type',\n 'client_id',\n 'redirect_uri',\n 'code_challenge',\n 'code_challenge_method',\n 'state',\n 'scope',\n 'grant_type',\n 'code',\n 'code_verifier',\n]);\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Build an authorization URL with PKCE challenge and state parameter.\n *\n * The caller must redirect the user-agent to the returned URL. The\n * `codeVerifier` must be stored securely for the subsequent token\n * exchange call.\n *\n * @param config - A2A OAuth server configuration\n * @param pkce - PKCE challenge pair (from `generatePKCEChallenge()`)\n * @returns Authorization request with URL, verifier, and state\n * @throws Error if endpoint URLs are not HTTPS or extraParams override reserved params\n */\nexport function buildAuthorizationRequest(\n config: A2AOAuthConfig,\n pkce: { readonly challenge: string; readonly verifier: string }\n): AuthorizationRequest {\n validateEndpointUrl(config.authorizationUrl, 'authorizationUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n\n if (config.extraParams) {\n for (const key of Object.keys(config.extraParams)) {\n if (RESERVED_PARAMS.has(key)) {\n throw new Error(`extraParams must not override reserved OAuth parameter: ${key}`);\n }\n }\n }\n\n const state = generateState();\n const authUrl = new URL(config.authorizationUrl);\n authUrl.searchParams.set('response_type', 'code');\n authUrl.searchParams.set('client_id', config.clientId);\n authUrl.searchParams.set('redirect_uri', config.redirectUri);\n authUrl.searchParams.set('code_challenge', pkce.challenge);\n authUrl.searchParams.set('code_challenge_method', 'S256');\n authUrl.searchParams.set('state', state);\n\n if (config.scopes && config.scopes.length > 0) {\n authUrl.searchParams.set('scope', config.scopes.join(' '));\n }\n\n if (config.extraParams) {\n for (const [key, value] of Object.entries(config.extraParams)) {\n authUrl.searchParams.set(key, value);\n }\n }\n\n return { url: authUrl.toString(), codeVerifier: pkce.verifier, state };\n}\n\n/**\n * Exchange an authorization code for tokens.\n *\n * Sends a POST to the token endpoint with the authorization code and\n * PKCE code verifier. Validates the verifier format before sending.\n *\n * @param code - Authorization code from the redirect callback\n * @param verifier - PKCE code verifier from the authorization request\n * @param config - A2A OAuth server configuration\n * @param fetchFn - Fetch implementation (no global fetch)\n * @returns Token response from the authorization server\n * @throws Error if the token endpoint returns an error response\n */\nexport async function exchangeAuthorizationCode(\n code: string,\n verifier: string,\n config: A2AOAuthConfig,\n fetchFn: FetchFn\n): Promise<TokenResponse> {\n validateEndpointUrl(config.tokenUrl, 'tokenUrl');\n validateEndpointUrl(config.redirectUri, 'redirectUri');\n validatePKCEVerifier(verifier);\n\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: config.redirectUri,\n client_id: config.clientId,\n code_verifier: verifier,\n });\n\n const response = await fetchFn(config.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!response.ok) {\n const errorBody = await response.text().catch(() => '');\n throw Object.assign(\n new Error(\n `Token exchange failed: HTTP ${response.status}${errorBody ? `: ${errorBody}` : ''}`\n ),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED', status: response.status }\n );\n }\n\n const tokenResponse = (await response.json()) as Record<string, unknown>;\n if (\n typeof tokenResponse.access_token !== 'string' ||\n typeof tokenResponse.token_type !== 'string'\n ) {\n throw Object.assign(\n new Error('Token response missing required fields (access_token, token_type)'),\n { code: 'E_A2A_AUTH_TOKEN_EXCHANGE_FAILED' }\n );\n }\n\n return tokenResponse as unknown as TokenResponse;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction validateEndpointUrl(url: string, name: string): void {\n if (!url.startsWith('https://') && !isLocalhostHttp(url)) {\n throw new Error(`${name} must use HTTPS (got: ${url})`);\n }\n}\n\nfunction isLocalhostHttp(url: string): boolean {\n if (!url.startsWith('http://')) return false;\n try {\n const parsed = new URL(url);\n return parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n } catch {\n return false;\n }\n}\n\nfunction generateState(): string {\n const bytes = new Uint8Array(16);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');\n}\n","/**\n * A2A auth event to PEAC evidence mapping.\n *\n * Maps A2A OAuth authentication events to access extension observations.\n * Auth success produces an **observation** receipt, never an automatic\n * access-decision receipt. The caller must explicitly construct\n * access-decision receipts when a business-level decision is made.\n */\n\nimport type { JsonObject } from '@peac/kernel';\nimport { ACCESS_EXTENSION_KEY } from '@peac/schema';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported A2A auth methods */\nexport type A2AAuthMethod = 'oauth2_pkce' | 'oauth2_device_code' | 'oauth2_client_credentials';\n\n/**\n * Input event describing an A2A authentication occurrence.\n *\n * This represents what happened at the auth layer, not a business\n * decision about whether to grant access.\n */\nexport interface A2AAuthEvent {\n /** Auth method used */\n readonly method: A2AAuthMethod;\n /** Resource URI that was authenticated against */\n readonly resource: string;\n /** Action that was requested (e.g., 'authenticate', 'tasks/send') */\n readonly action: string;\n /** OAuth scopes that were granted (from token response) */\n readonly grantedScopes?: readonly string[];\n /** Authorization server that issued the token */\n readonly authServer?: string;\n /** Client identifier used */\n readonly clientId?: string;\n /** ISO 8601 timestamp of the auth event */\n readonly timestamp?: string;\n}\n\n/**\n * Output structure for the access extension in a Wire 0.2 record.\n *\n * Uses `org.peacprotocol/access` extension group with `auth_event`\n * set to `'observation'` to distinguish from access-decision records.\n */\nexport interface A2AAuthEvidenceResult {\n /** Extension key for receipt `ext` field */\n readonly extensionKey: typeof ACCESS_EXTENSION_KEY;\n /** Access extension fields for the receipt */\n readonly extension: {\n readonly resource: string;\n readonly action: string;\n readonly decision: 'review';\n };\n /** Additional evidence metadata for the receipt `evidence` field */\n readonly evidence: JsonObject;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Map an A2A auth event to access extension evidence.\n *\n * Produces an **observation** receipt: `decision` is always `'review'`,\n * indicating that authentication occurred but no access decision was\n * made by the evidence layer. Callers who need `'allow'` or `'deny'`\n * decisions must explicitly construct those receipts.\n *\n * Tokens are never included in the evidence. Only structural metadata\n * (method, scopes, server, client_id) is recorded.\n *\n * @param event - A2A auth event to map\n * @returns Extension data and evidence metadata for receipt construction\n */\nexport function fromA2AAuthEvent(event: A2AAuthEvent): A2AAuthEvidenceResult {\n if (!event.resource) {\n throw new Error('A2A auth event missing resource');\n }\n if (!event.action) {\n throw new Error('A2A auth event missing action');\n }\n\n const evidence: JsonObject = {\n auth_event: 'observation',\n auth_method: event.method,\n };\n\n if (event.grantedScopes && event.grantedScopes.length > 0) {\n evidence.granted_scopes = [...event.grantedScopes];\n }\n if (event.authServer) {\n evidence.auth_server = event.authServer;\n }\n if (event.clientId) {\n evidence.client_id = event.clientId;\n }\n if (event.timestamp) {\n evidence.timestamp = event.timestamp;\n }\n\n return {\n extensionKey: ACCESS_EXTENSION_KEY,\n extension: {\n resource: event.resource,\n action: event.action,\n decision: 'review',\n },\n evidence,\n };\n}\n","/**\n * A2A auth error mapping to google.rpc.Status with ErrorInfo.\n *\n * A2A v1.0 uses gRPC-style status codes for transport errors. For\n * A2A-specific errors, implementations include `google.rpc.ErrorInfo`\n * in `status.details[]`. This module produces the full Status + ErrorInfo\n * shape for auth-related A2A errors.\n */\n\n// ---------------------------------------------------------------------------\n// google.rpc canonical codes (subset relevant to auth)\n// ---------------------------------------------------------------------------\n\n/**\n * gRPC canonical status codes used in A2A auth error responses.\n * Values match google.rpc.Code numeric assignments.\n */\nexport const GrpcStatusCode = {\n OK: 0,\n INVALID_ARGUMENT: 3,\n NOT_FOUND: 5,\n PERMISSION_DENIED: 7,\n INTERNAL: 13,\n UNAVAILABLE: 14,\n UNAUTHENTICATED: 16,\n} as const;\n\nexport type GrpcStatusCodeValue = (typeof GrpcStatusCode)[keyof typeof GrpcStatusCode];\n\n// ---------------------------------------------------------------------------\n// google.rpc.ErrorInfo shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.ErrorInfo per https://cloud.google.com/apis/design/errors.\n *\n * Included in `status.details[]` for A2A-specific auth errors.\n */\nexport interface GrpcErrorInfo {\n /** Fully-qualified type URL for ErrorInfo */\n readonly '@type': 'type.googleapis.com/google.rpc.ErrorInfo';\n /** Machine-readable error reason (SCREAMING_SNAKE_CASE) */\n readonly reason: string;\n /** Domain for the error (always 'a2a-protocol.org' per A2A spec) */\n readonly domain: string;\n /** Key-value metadata providing additional error context */\n readonly metadata: Readonly<Record<string, string>>;\n}\n\n// ---------------------------------------------------------------------------\n// google.rpc.Status shape\n// ---------------------------------------------------------------------------\n\n/**\n * google.rpc.Status with typed ErrorInfo detail.\n *\n * This is the wire shape returned in A2A gRPC error responses and\n * JSON-RPC error data objects.\n */\nexport interface GrpcStatus {\n /** gRPC canonical status code */\n readonly code: GrpcStatusCodeValue;\n /** Human-readable error message */\n readonly message: string;\n /** Structured error details (contains ErrorInfo for A2A-specific errors) */\n readonly details: readonly GrpcErrorInfo[];\n}\n\n// ---------------------------------------------------------------------------\n// A2A auth error definitions\n// ---------------------------------------------------------------------------\n\n/** A2A error domain per spec: implementations use the protocol domain */\nconst A2A_AUTH_DOMAIN = 'a2a-protocol.org';\n\ninterface AuthErrorDef {\n readonly grpcCode: GrpcStatusCodeValue;\n readonly message: string;\n readonly reason: string;\n}\n\nconst AUTH_ERROR_DEFS = {\n PKCE_MISMATCH: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'PKCE code challenge verification failed',\n reason: 'PKCE_CHALLENGE_MISMATCH',\n },\n PKCE_INVALID_VERIFIER: {\n grpcCode: GrpcStatusCode.INVALID_ARGUMENT,\n message: 'PKCE code verifier does not meet RFC 7636 requirements',\n reason: 'PKCE_INVALID_VERIFIER',\n },\n TOKEN_EXCHANGE_FAILED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'OAuth token exchange failed',\n reason: 'TOKEN_EXCHANGE_FAILED',\n },\n AUTH_SERVER_UNAVAILABLE: {\n grpcCode: GrpcStatusCode.UNAVAILABLE,\n message: 'Authorization server is unavailable',\n reason: 'AUTH_SERVER_UNAVAILABLE',\n },\n INVALID_AUTH_CODE: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Authorization code is invalid or expired',\n reason: 'INVALID_AUTH_CODE',\n },\n INVALID_CLIENT: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Client authentication failed',\n reason: 'INVALID_CLIENT',\n },\n SCOPE_DENIED: {\n grpcCode: GrpcStatusCode.PERMISSION_DENIED,\n message: 'Requested scope was denied by the authorization server',\n reason: 'SCOPE_DENIED',\n },\n DEVICE_CODE_EXPIRED: {\n grpcCode: GrpcStatusCode.UNAUTHENTICATED,\n message: 'Device authorization code has expired',\n reason: 'DEVICE_CODE_EXPIRED',\n },\n} as const satisfies Record<string, AuthErrorDef>;\n\nexport type A2AAuthErrorCode = keyof typeof AUTH_ERROR_DEFS;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Create a google.rpc.Status with ErrorInfo for an A2A auth error.\n *\n * Returns the full Status shape with `details[]` containing a single\n * `google.rpc.ErrorInfo` entry, as required by the A2A spec for\n * implementation-specific errors.\n *\n * @param errorCode - A2A auth error code\n * @param metadata - Additional key-value context for ErrorInfo.metadata\n * @returns google.rpc.Status with embedded ErrorInfo\n */\nexport function createA2AAuthStatus(\n errorCode: A2AAuthErrorCode,\n metadata?: Record<string, string>\n): GrpcStatus {\n const def = AUTH_ERROR_DEFS[errorCode];\n return {\n code: def.grpcCode,\n message: def.message,\n details: [\n {\n '@type': 'type.googleapis.com/google.rpc.ErrorInfo',\n reason: def.reason,\n domain: A2A_AUTH_DOMAIN,\n metadata: metadata ?? {},\n },\n ],\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peac/mappings-a2a",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "Agent-to-Agent Protocol (A2A) integration for PEAC",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@peac/
|
|
27
|
-
"@peac/
|
|
26
|
+
"@peac/schema": "0.13.2",
|
|
27
|
+
"@peac/kernel": "0.13.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/node": "^22.19.11",
|