@adcp/sdk 12.0.5 → 12.0.6

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/protocols/transportDiagnostics.ts"],"sourcesContent":["import { globalAsyncLocalStorage } from '../utils/global-async-local-storage';\nimport { createHmac } from 'node:crypto';\n\nexport type TransportActivityType = 'request_started' | 'response_received' | 'request_failed';\n\nexport interface TransportActivityContext {\n agentId: string;\n protocol: 'mcp' | 'a2a';\n tool?: string;\n taskType?: string;\n operationId?: string;\n taskId?: string;\n contextId?: string;\n idempotencyKey?: string;\n}\n\nexport interface TransportActivity {\n type: TransportActivityType;\n agentId: string;\n protocol: 'mcp' | 'a2a';\n tool?: string;\n taskType?: string;\n operationId?: string;\n taskId?: string;\n contextId?: string;\n idempotencyKeyHash?: string;\n method: string;\n url: string;\n requestHeaders: Record<string, string>;\n requestBody?: string;\n requestBodyTruncated?: boolean;\n startedAt: string;\n timestamp: string;\n durationMs?: number;\n httpStatus?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: string;\n responseBodyTruncated?: boolean;\n errorName?: string;\n errorMessage?: string;\n}\n\nexport type TransportActivityHandler = (event: TransportActivity) => void | Promise<void>;\n\ninterface TransportDiagnosticsSlot extends TransportActivityContext {\n onTransportActivity?: TransportActivityHandler;\n pending: Promise<void>[];\n}\n\nconst BODY_SNIPPET_LIMIT = 64 * 1024;\nconst REDACTED = '[redacted]';\n\nconst SAFE_HEADER_NAMES = new Set([\n 'accept',\n 'accept-encoding',\n 'content-type',\n 'last-event-id',\n 'mcp-protocol-version',\n 'traceparent',\n 'tracestate',\n 'user-agent',\n 'x-adcp-agent-id',\n 'x-adcp-request-id',\n 'x-correlation-id',\n 'x-request-id',\n 'x-scope3-debug-id',\n]);\n\nconst SENSITIVE_HEADER_NAMES = new Set([\n 'authorization',\n 'cookie',\n 'proxy-authorization',\n 'set-cookie',\n 'x-adcp-auth',\n 'x-api-key',\n 'mcp-session-id',\n]);\n\nconst SENSITIVE_KEY_RE =\n /(^|[_-])(authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)([_-]|$)/i;\nconst SENSITIVE_TEXT_FIELD_RE =\n /((?:\"[^\"]*(?:authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)[^\"]*\"\\s*:\\s*)|(?:^|[&\\s])[^=&\\s]*(?:authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)[^=&\\s]*=)(\"[^\"]*\"|[^&\\s,}]+)/gi;\nconst URL_LIKE_RE = /\\bhttps?:\\/\\/[^\\s\"'<>]+/gi;\n\nexport const transportDiagnosticsStorage = globalAsyncLocalStorage<TransportDiagnosticsSlot>('transportDiagnostics');\n\nexport function withTransportDiagnostics<T>(\n context: TransportActivityContext & { onTransportActivity?: TransportActivityHandler },\n fn: () => Promise<T>\n): Promise<T> {\n if (!context.onTransportActivity) return fn();\n const slot: TransportDiagnosticsSlot = { ...context, pending: [] };\n return transportDiagnosticsStorage.run(slot, async () => {\n try {\n return await fn();\n } finally {\n await Promise.allSettled(slot.pending);\n }\n });\n}\n\nexport function sanitizeTransportUrl(value: string): string {\n try {\n const url = new URL(value);\n url.username = '';\n url.password = '';\n url.search = '';\n url.hash = '';\n return url.toString();\n } catch {\n return 'invalid_url';\n }\n}\n\nexport function sanitizeTransportHeaders(headers: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of headerEntries(headers)) {\n const lower = key.toLowerCase();\n if (SENSITIVE_HEADER_NAMES.has(lower) || SENSITIVE_KEY_RE.test(lower)) {\n out[lower] = REDACTED;\n } else if (SAFE_HEADER_NAMES.has(lower) || isSafeCorrelationHeader(lower)) {\n out[lower] = value;\n }\n }\n return out;\n}\n\nexport function wrapFetchWithTransportDiagnostics(upstream: typeof fetch): typeof fetch {\n const wrapped: typeof fetch = async (input, init) => {\n const slot = transportDiagnosticsStorage.getStore();\n if (!slot?.onTransportActivity) return upstream(input, init);\n\n const startedAtMs = Date.now();\n const startedAt = new Date(startedAtMs).toISOString();\n const method = getMethod(input, init);\n const url = sanitizeTransportUrl(getUrl(input));\n const requestHeaders = sanitizeTransportHeaders(mergeRequestHeaders(input, init));\n const requestBody = bodySnippet(init?.body);\n const baseEvent = {\n agentId: slot.agentId,\n protocol: slot.protocol,\n ...(slot.tool && { tool: slot.tool, taskType: slot.taskType ?? slot.tool }),\n ...(slot.operationId && { operationId: slot.operationId }),\n ...(slot.taskId && { taskId: slot.taskId }),\n ...(slot.contextId && { contextId: slot.contextId }),\n ...(slot.idempotencyKey && { idempotencyKeyHash: fingerprintDiagnosticValue(slot.idempotencyKey) }),\n method,\n url,\n requestHeaders,\n ...(requestBody && {\n requestBody: requestBody.body,\n requestBodyTruncated: requestBody.truncated,\n }),\n startedAt,\n };\n\n emitTransportActivity(slot.onTransportActivity, {\n type: 'request_started',\n ...baseEvent,\n timestamp: startedAt,\n });\n\n try {\n const response = await upstream(input, init);\n const durationMs = Date.now() - startedAtMs;\n const responseHeaders = sanitizeResponseHeaders(response.headers);\n const responseBody = await responseBodySnippet(response);\n emitTransportActivity(slot.onTransportActivity, {\n type: 'response_received',\n ...baseEvent,\n timestamp: new Date().toISOString(),\n durationMs,\n httpStatus: response.status,\n statusText: response.statusText,\n responseHeaders,\n ...(responseBody && {\n responseBody: responseBody.body,\n responseBodyTruncated: responseBody.truncated,\n }),\n });\n return response;\n } catch (error) {\n emitTransportActivity(slot.onTransportActivity, {\n type: 'request_failed',\n ...baseEvent,\n timestamp: new Date().toISOString(),\n durationMs: Date.now() - startedAtMs,\n errorName: error instanceof Error ? error.name : typeof error,\n errorMessage: sanitizeDiagnosticText(error instanceof Error ? error.message : String(error)),\n });\n throw error;\n }\n };\n return wrapped;\n}\n\nfunction emitTransportActivity(handler: TransportActivityHandler, event: TransportActivity): void {\n try {\n const slot = transportDiagnosticsStorage.getStore();\n const frozen = Object.freeze(structuredClone(event));\n const pending = Promise.resolve()\n .then(() => handler(frozen))\n .then(\n () => {},\n () => {}\n );\n slot?.pending.push(pending);\n } catch {\n // Observability hooks must not change protocol behavior.\n }\n}\n\nfunction getUrl(input: RequestInfo | URL): string {\n return typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n}\n\nfunction getMethod(input: RequestInfo | URL, init?: RequestInit): string {\n return (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n}\n\nfunction mergeRequestHeaders(input: RequestInfo | URL, init?: RequestInit): Headers {\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n if (init?.headers) {\n for (const [key, value] of headerEntries(init.headers)) {\n headers.set(key, value);\n }\n }\n return headers;\n}\n\nfunction sanitizeResponseHeaders(headers: Headers): Record<string, string> {\n return sanitizeTransportHeaders(headers);\n}\n\nfunction headerEntries(headers: HeadersInit | undefined): Array<[string, string]> {\n if (!headers) return [];\n if (headers instanceof Headers) {\n const entries: Array<[string, string]> = [];\n headers.forEach((value, key) => entries.push([key, value]));\n return entries;\n }\n if (Array.isArray(headers)) return headers.map(([key, value]) => [key, value]);\n return Object.entries(headers).map(([key, value]) => [key, String(value)]);\n}\n\nfunction isSafeCorrelationHeader(lower: string): boolean {\n if (!lower.startsWith('x-')) return false;\n return (\n lower.includes('correlation') || lower.includes('debug') || lower.includes('request-id') || lower.includes('trace')\n );\n}\n\nfunction bodySnippet(body: BodyInit | null | undefined): { body: string; truncated: boolean } | undefined {\n if (body == null) return undefined;\n if (typeof body === 'string') return sanitizeBodyText(body, BODY_SNIPPET_LIMIT);\n if (body instanceof URLSearchParams) return sanitizeBodyText(body.toString(), BODY_SNIPPET_LIMIT);\n if (body instanceof Blob) return { body: `[blob ${body.size} bytes]`, truncated: false };\n if (body instanceof ArrayBuffer) {\n return sanitizeBodyText(Buffer.from(body).toString('utf8'), BODY_SNIPPET_LIMIT);\n }\n if (ArrayBuffer.isView(body)) {\n return sanitizeBodyText(\n Buffer.from(body.buffer, body.byteOffset, body.byteLength).toString('utf8'),\n BODY_SNIPPET_LIMIT\n );\n }\n return undefined;\n}\n\nasync function responseBodySnippet(response: Response): Promise<{ body: string; truncated: boolean } | undefined> {\n const contentType = response.headers.get('content-type') ?? '';\n if (!isDiagnosticTextContentType(contentType)) return undefined;\n try {\n const { text, truncated } = await readResponseTextBounded(response.clone(), BODY_SNIPPET_LIMIT);\n return { body: redactSensitiveJsonOrText(text), truncated };\n } catch {\n return undefined;\n }\n}\n\nfunction sanitizeBodyText(text: string, limit: number): { body: string; truncated: boolean } {\n const truncated = text.length > limit;\n const bounded = truncated ? text.slice(0, limit) : text;\n return { body: redactSensitiveJsonOrText(bounded), truncated };\n}\n\nfunction redactSensitiveJsonOrText(text: string): string {\n try {\n return JSON.stringify(redactSensitiveValue(JSON.parse(text)));\n } catch {\n return sanitizeDiagnosticText(text);\n }\n}\n\nfunction redactSensitiveValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(redactSensitiveValue);\n if (typeof value === 'string') return sanitizeStringValue(value);\n if (!value || typeof value !== 'object') return value;\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n out[key] = isSensitiveKey(key) ? REDACTED : redactSensitiveValue(child);\n }\n return out;\n}\n\nfunction sanitizeDiagnosticText(text: string): string {\n return text\n .replace(URL_LIKE_RE, value => sanitizeTransportUrl(value))\n .replace(/Bearer\\s+[A-Za-z0-9._~+/=-]+/gi, 'Bearer [redacted]')\n .replace(/Basic\\s+[A-Za-z0-9+/=-]+/gi, 'Basic [redacted]')\n .replace(SENSITIVE_TEXT_FIELD_RE, (_match, prefix) => `${prefix}${REDACTED}`);\n}\n\nfunction sanitizeStringValue(value: string): string {\n return sanitizeDiagnosticText(value);\n}\n\nfunction normalizedKey(key: string): string {\n return key.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEY_RE.test(normalizedKey(key));\n}\n\nfunction isDiagnosticTextContentType(contentType: string): boolean {\n const lower = contentType.toLowerCase();\n if (!lower) return true;\n if (lower.includes('text/event-stream')) return false;\n return (\n lower.startsWith('text/') ||\n lower.includes('json') ||\n lower.includes('xml') ||\n lower.includes('javascript') ||\n lower.includes('x-www-form-urlencoded')\n );\n}\n\nasync function readResponseTextBounded(\n response: Response,\n limit: number\n): Promise<{ text: string; truncated: boolean }> {\n if (!response.body) {\n const text = await response.text();\n return { text: text.slice(0, limit), truncated: text.length > limit };\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let text = '';\n let truncated = false;\n\n try {\n while (text.length <= limit) {\n const { done, value } = await reader.read();\n if (done) break;\n text += decoder.decode(value, { stream: true });\n if (text.length > limit) {\n truncated = true;\n text = text.slice(0, limit);\n await reader.cancel();\n break;\n }\n }\n if (!truncated) text += decoder.decode();\n } finally {\n reader.releaseLock();\n }\n\n return { text, truncated };\n}\n\nfunction fingerprintDiagnosticValue(value: string): string {\n return createHmac('sha256', 'adcp-transport-diagnostics').update(value).digest('hex').slice(0, 16);\n}\n"],"mappings":"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","names":["text"]}
1
+ {"version":3,"sources":["../../../src/lib/protocols/transportDiagnostics.ts"],"sourcesContent":["import { fileURLToPath as __adcpFileURLToPath } from 'node:url';\nimport { dirname as __adcpDirname } from 'node:path';\nimport { createRequire as __adcpCreateRequire } from 'node:module';\nconst __dirname = __adcpDirname(__adcpFileURLToPath(import.meta.url));\nconst require = __adcpCreateRequire(import.meta.url);\nimport { globalAsyncLocalStorage } from '../utils/global-async-local-storage';\nimport { createHmac } from 'node:crypto';\n\nexport type TransportActivityType = 'request_started' | 'response_received' | 'request_failed';\n\nexport interface TransportActivityContext {\n agentId: string;\n protocol: 'mcp' | 'a2a';\n tool?: string;\n taskType?: string;\n operationId?: string;\n taskId?: string;\n contextId?: string;\n idempotencyKey?: string;\n}\n\nexport interface TransportActivity {\n type: TransportActivityType;\n agentId: string;\n protocol: 'mcp' | 'a2a';\n tool?: string;\n taskType?: string;\n operationId?: string;\n taskId?: string;\n contextId?: string;\n idempotencyKeyHash?: string;\n method: string;\n url: string;\n requestHeaders: Record<string, string>;\n requestBody?: string;\n requestBodyTruncated?: boolean;\n startedAt: string;\n timestamp: string;\n durationMs?: number;\n httpStatus?: number;\n statusText?: string;\n responseHeaders?: Record<string, string>;\n responseBody?: string;\n responseBodyTruncated?: boolean;\n errorName?: string;\n errorMessage?: string;\n}\n\nexport type TransportActivityHandler = (event: TransportActivity) => void | Promise<void>;\n\ninterface TransportDiagnosticsSlot extends TransportActivityContext {\n onTransportActivity?: TransportActivityHandler;\n pending: Promise<void>[];\n}\n\nconst BODY_SNIPPET_LIMIT = 64 * 1024;\nconst REDACTED = '[redacted]';\n\nconst SAFE_HEADER_NAMES = new Set([\n 'accept',\n 'accept-encoding',\n 'content-type',\n 'last-event-id',\n 'mcp-protocol-version',\n 'traceparent',\n 'tracestate',\n 'user-agent',\n 'x-adcp-agent-id',\n 'x-adcp-request-id',\n 'x-correlation-id',\n 'x-request-id',\n 'x-scope3-debug-id',\n]);\n\nconst SENSITIVE_HEADER_NAMES = new Set([\n 'authorization',\n 'cookie',\n 'proxy-authorization',\n 'set-cookie',\n 'x-adcp-auth',\n 'x-api-key',\n 'mcp-session-id',\n]);\n\nconst SENSITIVE_KEY_RE =\n /(^|[_-])(authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)([_-]|$)/i;\nconst SENSITIVE_TEXT_FIELD_RE =\n /((?:\"[^\"]*(?:authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)[^\"]*\"\\s*:\\s*)|(?:^|[&\\s])[^=&\\s]*(?:authorization|cookie|credentials?|secret|signature|token|api[_-]?key|private[_-]?key|idempotency[_-]?key|password)[^=&\\s]*=)(\"[^\"]*\"|[^&\\s,}]+)/gi;\nconst URL_LIKE_RE = /\\bhttps?:\\/\\/[^\\s\"'<>]+/gi;\n\nexport const transportDiagnosticsStorage = globalAsyncLocalStorage<TransportDiagnosticsSlot>('transportDiagnostics');\n\nexport function withTransportDiagnostics<T>(\n context: TransportActivityContext & { onTransportActivity?: TransportActivityHandler },\n fn: () => Promise<T>\n): Promise<T> {\n if (!context.onTransportActivity) return fn();\n const slot: TransportDiagnosticsSlot = { ...context, pending: [] };\n return transportDiagnosticsStorage.run(slot, async () => {\n try {\n return await fn();\n } finally {\n await Promise.allSettled(slot.pending);\n }\n });\n}\n\nexport function sanitizeTransportUrl(value: string): string {\n try {\n const url = new URL(value);\n url.username = '';\n url.password = '';\n url.search = '';\n url.hash = '';\n return url.toString();\n } catch {\n return 'invalid_url';\n }\n}\n\nexport function sanitizeTransportHeaders(headers: HeadersInit | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [key, value] of headerEntries(headers)) {\n const lower = key.toLowerCase();\n if (SENSITIVE_HEADER_NAMES.has(lower) || SENSITIVE_KEY_RE.test(lower)) {\n out[lower] = REDACTED;\n } else if (SAFE_HEADER_NAMES.has(lower) || isSafeCorrelationHeader(lower)) {\n out[lower] = value;\n }\n }\n return out;\n}\n\nexport function wrapFetchWithTransportDiagnostics(upstream: typeof fetch): typeof fetch {\n const wrapped: typeof fetch = async (input, init) => {\n const slot = transportDiagnosticsStorage.getStore();\n if (!slot?.onTransportActivity) return upstream(input, init);\n\n const startedAtMs = Date.now();\n const startedAt = new Date(startedAtMs).toISOString();\n const method = getMethod(input, init);\n const url = sanitizeTransportUrl(getUrl(input));\n const requestHeaders = sanitizeTransportHeaders(mergeRequestHeaders(input, init));\n const requestBody = bodySnippet(init?.body);\n const baseEvent = {\n agentId: slot.agentId,\n protocol: slot.protocol,\n ...(slot.tool && { tool: slot.tool, taskType: slot.taskType ?? slot.tool }),\n ...(slot.operationId && { operationId: slot.operationId }),\n ...(slot.taskId && { taskId: slot.taskId }),\n ...(slot.contextId && { contextId: slot.contextId }),\n ...(slot.idempotencyKey && { idempotencyKeyHash: fingerprintDiagnosticValue(slot.idempotencyKey) }),\n method,\n url,\n requestHeaders,\n ...(requestBody && {\n requestBody: requestBody.body,\n requestBodyTruncated: requestBody.truncated,\n }),\n startedAt,\n };\n\n emitTransportActivity(slot.onTransportActivity, {\n type: 'request_started',\n ...baseEvent,\n timestamp: startedAt,\n });\n\n try {\n const response = await upstream(input, init);\n const durationMs = Date.now() - startedAtMs;\n const responseHeaders = sanitizeResponseHeaders(response.headers);\n const responseBody = await responseBodySnippet(response);\n emitTransportActivity(slot.onTransportActivity, {\n type: 'response_received',\n ...baseEvent,\n timestamp: new Date().toISOString(),\n durationMs,\n httpStatus: response.status,\n statusText: response.statusText,\n responseHeaders,\n ...(responseBody && {\n responseBody: responseBody.body,\n responseBodyTruncated: responseBody.truncated,\n }),\n });\n return response;\n } catch (error) {\n emitTransportActivity(slot.onTransportActivity, {\n type: 'request_failed',\n ...baseEvent,\n timestamp: new Date().toISOString(),\n durationMs: Date.now() - startedAtMs,\n errorName: error instanceof Error ? error.name : typeof error,\n errorMessage: sanitizeDiagnosticText(error instanceof Error ? error.message : String(error)),\n });\n throw error;\n }\n };\n return wrapped;\n}\n\nfunction emitTransportActivity(handler: TransportActivityHandler, event: TransportActivity): void {\n try {\n const slot = transportDiagnosticsStorage.getStore();\n const frozen = Object.freeze(structuredClone(event));\n const pending = Promise.resolve()\n .then(() => handler(frozen))\n .then(\n () => {},\n () => {}\n );\n slot?.pending.push(pending);\n } catch {\n // Observability hooks must not change protocol behavior.\n }\n}\n\nfunction getUrl(input: RequestInfo | URL): string {\n return typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;\n}\n\nfunction getMethod(input: RequestInfo | URL, init?: RequestInit): string {\n return (init?.method ?? (input instanceof Request ? input.method : 'GET')).toUpperCase();\n}\n\nfunction mergeRequestHeaders(input: RequestInfo | URL, init?: RequestInit): Headers {\n const headers = new Headers(input instanceof Request ? input.headers : undefined);\n if (init?.headers) {\n for (const [key, value] of headerEntries(init.headers)) {\n headers.set(key, value);\n }\n }\n return headers;\n}\n\nfunction sanitizeResponseHeaders(headers: Headers): Record<string, string> {\n return sanitizeTransportHeaders(headers);\n}\n\nfunction headerEntries(headers: HeadersInit | undefined): Array<[string, string]> {\n if (!headers) return [];\n if (headers instanceof Headers) {\n const entries: Array<[string, string]> = [];\n headers.forEach((value, key) => entries.push([key, value]));\n return entries;\n }\n if (Array.isArray(headers)) return headers.map(([key, value]) => [key, value]);\n return Object.entries(headers).map(([key, value]) => [key, String(value)]);\n}\n\nfunction isSafeCorrelationHeader(lower: string): boolean {\n if (!lower.startsWith('x-')) return false;\n return (\n lower.includes('correlation') || lower.includes('debug') || lower.includes('request-id') || lower.includes('trace')\n );\n}\n\nfunction bodySnippet(body: BodyInit | null | undefined): { body: string; truncated: boolean } | undefined {\n if (body == null) return undefined;\n if (typeof body === 'string') return sanitizeBodyText(body, BODY_SNIPPET_LIMIT);\n if (body instanceof URLSearchParams) return sanitizeBodyText(body.toString(), BODY_SNIPPET_LIMIT);\n if (body instanceof Blob) return { body: `[blob ${body.size} bytes]`, truncated: false };\n if (body instanceof ArrayBuffer) {\n return sanitizeBodyText(Buffer.from(body).toString('utf8'), BODY_SNIPPET_LIMIT);\n }\n if (ArrayBuffer.isView(body)) {\n return sanitizeBodyText(\n Buffer.from(body.buffer, body.byteOffset, body.byteLength).toString('utf8'),\n BODY_SNIPPET_LIMIT\n );\n }\n return undefined;\n}\n\nasync function responseBodySnippet(response: Response): Promise<{ body: string; truncated: boolean } | undefined> {\n const contentType = response.headers.get('content-type') ?? '';\n if (!isDiagnosticTextContentType(contentType)) return undefined;\n try {\n const { text, truncated } = await readResponseTextBounded(response.clone(), BODY_SNIPPET_LIMIT);\n return { body: redactSensitiveJsonOrText(text), truncated };\n } catch {\n return undefined;\n }\n}\n\nfunction sanitizeBodyText(text: string, limit: number): { body: string; truncated: boolean } {\n const truncated = text.length > limit;\n const bounded = truncated ? text.slice(0, limit) : text;\n return { body: redactSensitiveJsonOrText(bounded), truncated };\n}\n\nfunction redactSensitiveJsonOrText(text: string): string {\n try {\n return JSON.stringify(redactSensitiveValue(JSON.parse(text)));\n } catch {\n return sanitizeDiagnosticText(text);\n }\n}\n\nfunction redactSensitiveValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(redactSensitiveValue);\n if (typeof value === 'string') return sanitizeStringValue(value);\n if (!value || typeof value !== 'object') return value;\n const out: Record<string, unknown> = {};\n for (const [key, child] of Object.entries(value)) {\n out[key] = isSensitiveKey(key) ? REDACTED : redactSensitiveValue(child);\n }\n return out;\n}\n\nfunction sanitizeDiagnosticText(text: string): string {\n return text\n .replace(URL_LIKE_RE, value => sanitizeTransportUrl(value))\n .replace(/Bearer\\s+[A-Za-z0-9._~+/=-]+/gi, 'Bearer [redacted]')\n .replace(/Basic\\s+[A-Za-z0-9+/=-]+/gi, 'Basic [redacted]')\n .replace(SENSITIVE_TEXT_FIELD_RE, (_match, prefix) => `${prefix}${REDACTED}`);\n}\n\nfunction sanitizeStringValue(value: string): string {\n return sanitizeDiagnosticText(value);\n}\n\nfunction normalizedKey(key: string): string {\n return key.replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase();\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return SENSITIVE_KEY_RE.test(normalizedKey(key));\n}\n\nfunction isDiagnosticTextContentType(contentType: string): boolean {\n const lower = contentType.toLowerCase();\n if (!lower) return true;\n if (lower.includes('text/event-stream')) return false;\n return (\n lower.startsWith('text/') ||\n lower.includes('json') ||\n lower.includes('xml') ||\n lower.includes('javascript') ||\n lower.includes('x-www-form-urlencoded')\n );\n}\n\nasync function readResponseTextBounded(\n response: Response,\n limit: number\n): Promise<{ text: string; truncated: boolean }> {\n if (!response.body) {\n const text = await response.text();\n return { text: text.slice(0, limit), truncated: text.length > limit };\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let text = '';\n let truncated = false;\n\n try {\n while (text.length <= limit) {\n const { done, value } = await reader.read();\n if (done) break;\n text += decoder.decode(value, { stream: true });\n if (text.length > limit) {\n truncated = true;\n text = text.slice(0, limit);\n await reader.cancel();\n break;\n }\n }\n if (!truncated) text += decoder.decode();\n } finally {\n reader.releaseLock();\n }\n\n return { text, truncated };\n}\n\nfunction fingerprintDiagnosticValue(value: string): string {\n return createHmac('sha256', 'adcp-transport-diagnostics').update(value).digest('hex').slice(0, 16);\n}\n"],"mappings":"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","names":["require","text"]}
@@ -4,5 +4,5 @@
4
4
  "source_sha": "4e553ad955f83b49c7d221ab5c3ff78237ad02e3",
5
5
  "source_tarball_sha256": "580656d6466ef9f0d1119985e6726c2efea718dc671e2ad30957fcb2fd54af0f",
6
6
  "upstream_adcp_version": "2.5.3",
7
- "synced_at": "2026-07-23T00:22:46.176Z"
7
+ "synced_at": "2026-07-23T20:20:53.569Z"
8
8
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "12.0.5";
4
+ export declare const LIBRARY_VERSION = "12.0.6";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "12.0.5";
36
+ readonly library: "12.0.6";
37
37
  readonly adcp: "3.1.2";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.1.0", "3.1", "3.1.1", "3.1.2"];
39
- readonly generatedAt: "2026-07-23T00:10:47.630Z";
39
+ readonly generatedAt: "2026-07-23T20:01:20.705Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "12.0.5";
4
+ export declare const LIBRARY_VERSION = "12.0.6";
5
5
  /**
6
6
  * AdCP specification version this library is built for
7
7
  */
@@ -33,10 +33,10 @@ export type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];
33
33
  * Full version information
34
34
  */
35
35
  export declare const VERSION_INFO: {
36
- readonly library: "12.0.5";
36
+ readonly library: "12.0.6";
37
37
  readonly adcp: "3.1.2";
38
38
  readonly compatibleVersions: readonly ["v2.5", "v2.6", "v3", "3.0.0-beta.1", "3.0-beta.1", "3.0-beta", "3.0.0-beta.3", "3.0-beta.3", "3.0.0", "3.0", "3.0.1", "3.0.2", "3.0.3", "3.0.4", "3.0.5", "3.0.6", "3.0.7", "3.0.8", "3.0.9", "3.0.10", "3.0.11", "3.0.12", "3.1.0", "3.1", "3.1.1", "3.1.2"];
39
- readonly generatedAt: "2026-07-23T00:10:47.630Z";
39
+ readonly generatedAt: "2026-07-23T20:01:20.705Z";
40
40
  };
41
41
  /**
42
42
  * Get the AdCP specification version this library is built for
@@ -31,7 +31,7 @@ __export(version_exports, {
31
31
  toReleasePrecisionVersion: () => toReleasePrecisionVersion
32
32
  });
33
33
  module.exports = __toCommonJS(version_exports);
34
- const LIBRARY_VERSION = "12.0.5";
34
+ const LIBRARY_VERSION = "12.0.6";
35
35
  const ADCP_VERSION = "3.1.2";
36
36
  const ADCP_MAJOR_VERSION = 3;
37
37
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -63,10 +63,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
63
63
  "3.1.2"
64
64
  ];
65
65
  const VERSION_INFO = {
66
- library: "12.0.5",
66
+ library: "12.0.6",
67
67
  adcp: "3.1.2",
68
68
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
69
- generatedAt: "2026-07-23T00:10:47.630Z"
69
+ generatedAt: "2026-07-23T20:01:20.705Z"
70
70
  };
71
71
  function getAdcpVersion() {
72
72
  return ADCP_VERSION;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.5';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.5',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-23T00:10:47.630Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.6';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.6',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-23T20:01:20.705Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "12.0.5";
1
+ const LIBRARY_VERSION = "12.0.6";
2
2
  const ADCP_VERSION = "3.1.2";
3
3
  const ADCP_MAJOR_VERSION = 3;
4
4
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -30,10 +30,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
30
30
  "3.1.2"
31
31
  ];
32
32
  const VERSION_INFO = {
33
- library: "12.0.5",
33
+ library: "12.0.6",
34
34
  adcp: "3.1.2",
35
35
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
36
- generatedAt: "2026-07-23T00:10:47.630Z"
36
+ generatedAt: "2026-07-23T20:01:20.705Z"
37
37
  };
38
38
  function getAdcpVersion() {
39
39
  return ADCP_VERSION;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.5';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.5',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-23T00:10:47.630Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":"AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../src/lib/version.ts"],"sourcesContent":["// Generated version information\n// This file is auto-generated by sync-version.ts\n\n/**\n * AdCP SDK library version\n */\nexport const LIBRARY_VERSION = '12.0.6';\n\n/**\n * AdCP specification version this library is built for\n */\nexport const ADCP_VERSION = '3.1.2';\n\n/**\n * AdCP major version sent with every request (adcp_major_version field).\n * Sellers validate this against their supported versions and return\n * VERSION_UNSUPPORTED if the version is not in range.\n */\nexport const ADCP_MAJOR_VERSION = 3;\n\n/**\n * AdCP versions this library maintains backward compatibility with.\n *\n * Auto-derived from `ADCP_VERSION` by scripts/sync-version.ts. Do not edit\n * this list by hand; bumping the AdCP pin via `npm run sync-version`\n * extends it.\n */\nexport const COMPATIBLE_ADCP_VERSIONS = [\n 'v2.5',\n 'v2.6',\n 'v3',\n '3.0.0-beta.1',\n '3.0-beta.1',\n '3.0-beta',\n '3.0.0-beta.3',\n '3.0-beta.3',\n '3.0.0',\n '3.0',\n '3.0.1',\n '3.0.2',\n '3.0.3',\n '3.0.4',\n '3.0.5',\n '3.0.6',\n '3.0.7',\n '3.0.8',\n '3.0.9',\n '3.0.10',\n '3.0.11',\n '3.0.12',\n '3.1.0',\n '3.1',\n '3.1.1',\n '3.1.2',\n] as const;\n\n/**\n * String literal union of every AdCP version the SDK formally supports.\n *\n * Used by the per-instance `adcpVersion` constructor option to give callers\n * autocomplete in editors. The intersection with `(string & {})` in the\n * config type preserves the escape hatch — any string is still accepted at\n * the type level — while the literal union surfaces canonical values first.\n */\nexport type AdcpVersion = (typeof COMPATIBLE_ADCP_VERSIONS)[number];\n\n/**\n * Full version information\n */\nexport const VERSION_INFO = {\n library: '12.0.6',\n adcp: '3.1.2',\n compatibleVersions: COMPATIBLE_ADCP_VERSIONS,\n generatedAt: '2026-07-23T20:01:20.705Z',\n} as const;\n\n/**\n * Get the AdCP specification version this library is built for\n */\nexport function getAdcpVersion(): string {\n return ADCP_VERSION;\n}\n\n/**\n * Get the library version\n */\nexport function getLibraryVersion(): string {\n return LIBRARY_VERSION;\n}\n\n/**\n * Check if this library version is compatible with a given AdCP version\n */\nexport function isCompatibleWith(adcpVersion: string): boolean {\n return (COMPATIBLE_ADCP_VERSIONS as readonly string[]).includes(adcpVersion);\n}\n\n/**\n * Get all AdCP versions this library is compatible with\n */\nexport function getCompatibleVersions(): readonly string[] {\n return COMPATIBLE_ADCP_VERSIONS;\n}\n\n/**\n * Extract the major version number from an AdCP version string.\n *\n * Accepts:\n * - Semver: '3.0.0', '3.0.1', '3.1.0-beta.1' → 3\n * - Legacy aliases: 'v3' → 3, 'v2.5' / 'v2.6' → 2\n *\n * Returns NaN for unrecognized strings — callers should validate before passing.\n */\nexport function parseAdcpMajorVersion(version: string): number {\n const trimmed = version.trim();\n const semverLike = trimmed.startsWith('v') ? trimmed.slice(1) : trimmed;\n const major = parseInt(semverLike.split('.')[0] ?? '', 10);\n return Number.isFinite(major) ? major : NaN;\n}\n\n/**\n * Normalize a full-semver AdCP version (`MAJOR.MINOR.PATCH[-prerelease]`) to\n * the release-precision form that AdCP 3.1+ requires on the wire:\n * `MAJOR.MINOR[-prerelease]` — the patch digit is dropped.\n *\n * Per the spec note on `adcp_version`: \"SDKs that read full-semver values\n * from bundle metadata (e.g. `ComplianceIndex.published_version =\n * \"3.1.0-beta.1\"`) MUST normalize to release-precision (`\"3.1-beta.1\"`)\n * before emitting on the wire — meta-field values are NOT valid wire\n * values.\" The wire regex (`^\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?$`) rejects strings\n * with a patch digit.\n *\n * Behavior:\n * - `\"3.1.0-beta.7\"` → `\"3.1-beta.7\"`\n * - `\"3.1.0\"` → `\"3.1\"`\n * - `\"3.0.12\"` → `\"3.0\"`\n * - Already-release-precision input (`\"3.1\"`, `\"3.1-beta.7\"`) passes through\n * - Legacy aliases (`\"v2.5\"`, `\"v3\"`) pass through unchanged — the wire\n * regex doesn't accept them anyway; the v2.5 path uses\n * `adcp_major_version` instead of `adcp_version` for transport.\n * - Unrecognized strings pass through unchanged so callers can detect drift\n * via the wire validator rather than have it masked by this helper.\n */\nexport function toReleasePrecisionVersion(version: string): string {\n const trimmed = version.trim();\n // Pre-release form `MAJOR.MINOR.PATCH-prerelease` → `MAJOR.MINOR-prerelease`\n const semverMatch = trimmed.match(/^(\\d+)\\.(\\d+)\\.\\d+(-[A-Za-z0-9.-]+)?$/);\n if (semverMatch) {\n const [, major, minor, pre = ''] = semverMatch;\n return `${major}.${minor}${pre}`;\n }\n // Already release-precision (no patch digit). Includes `3.1`, `3.1-beta.7`.\n if (/^\\d+\\.\\d+(-[A-Za-z0-9.-]+)?$/.test(trimmed)) return trimmed;\n // Legacy aliases (`v3`, `v2.5`, `v2.6`) and anything we don't recognize —\n // pass through so the wire validator can flag genuine drift.\n return version;\n}\n"],"mappings":"AAMO,MAAM,kBAAkB;AAKxB,MAAM,eAAe;AAOrB,MAAM,qBAAqB;AAS3B,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAeO,MAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,MAAM;AAAA,EACN,oBAAoB;AAAA,EACpB,aAAa;AACf;AAKO,SAAS,iBAAyB;AACvC,SAAO;AACT;AAKO,SAAS,oBAA4B;AAC1C,SAAO;AACT;AAKO,SAAS,iBAAiB,aAA8B;AAC7D,SAAQ,yBAA+C,SAAS,WAAW;AAC7E;AAKO,SAAS,wBAA2C;AACzD,SAAO;AACT;AAWO,SAAS,sBAAsB,SAAyB;AAC7D,QAAM,UAAU,QAAQ,KAAK;AAC7B,QAAM,aAAa,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,QAAM,QAAQ,SAAS,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE;AACzD,SAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAC1C;AAyBO,SAAS,0BAA0B,SAAyB;AACjE,QAAM,UAAU,QAAQ,KAAK;AAE7B,QAAM,cAAc,QAAQ,MAAM,uCAAuC;AACzE,MAAI,aAAa;AACf,UAAM,CAAC,EAAE,OAAO,OAAO,MAAM,EAAE,IAAI;AACnC,WAAO,GAAG,KAAK,IAAI,KAAK,GAAG,GAAG;AAAA,EAChC;AAEA,MAAI,+BAA+B,KAAK,OAAO,EAAG,QAAO;AAGzD,SAAO;AACT;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "12.0.5",
3
+ "version": "12.0.6",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",