@adcp/sdk 14.0.0-beta.19 → 14.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/bin/adcp.js +154 -6
  2. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  3. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +10 -0
  4. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +10 -0
  5. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +21 -0
  6. package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +21 -0
  7. package/dist/lib/server/serve.d.mts +11 -0
  8. package/dist/lib/server/serve.d.ts +11 -0
  9. package/dist/lib/server/serve.js +35 -5
  10. package/dist/lib/server/serve.mjs +35 -5
  11. package/dist/lib/signing/brand-jwks.d.mts +44 -1
  12. package/dist/lib/signing/brand-jwks.d.ts +44 -1
  13. package/dist/lib/signing/brand-jwks.js +53 -15
  14. package/dist/lib/signing/brand-jwks.mjs +51 -14
  15. package/dist/lib/signing/server.d.mts +1 -1
  16. package/dist/lib/signing/server.d.ts +1 -1
  17. package/dist/lib/signing/server.js +2 -0
  18. package/dist/lib/signing/server.mjs +3 -1
  19. package/dist/lib/testing/storyboard/runner.js +6 -2
  20. package/dist/lib/testing/storyboard/runner.mjs +6 -2
  21. package/dist/lib/testing/storyboard/types.d.mts +6 -0
  22. package/dist/lib/testing/storyboard/types.d.ts +6 -0
  23. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  24. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  25. package/dist/lib/testing/storyboard/webhook-assertions.js +6 -1
  26. package/dist/lib/testing/storyboard/webhook-assertions.mjs +6 -1
  27. package/dist/lib/testing/storyboard/webhook-receiver.d.mts +15 -0
  28. package/dist/lib/testing/storyboard/webhook-receiver.d.ts +15 -0
  29. package/dist/lib/testing/storyboard/webhook-receiver.js +55 -15
  30. package/dist/lib/testing/storyboard/webhook-receiver.mjs +55 -15
  31. package/dist/lib/version.d.mts +3 -3
  32. package/dist/lib/version.d.ts +3 -3
  33. package/dist/lib/version.js +3 -3
  34. package/dist/lib/version.mjs +3 -3
  35. package/docs/llms.txt +1 -1
  36. package/package.json +1 -1
@@ -22,7 +22,9 @@ __export(webhook_receiver_exports, {
22
22
  });
23
23
  module.exports = __toCommonJS(webhook_receiver_exports);
24
24
  var import_node_http = require("node:http");
25
+ var import_node_https = require("node:https");
25
26
  var import_node_crypto = require("node:crypto");
27
+ var import_node_net = require("node:net");
26
28
  var import_schema_loader = require('../../validation/schema-loader.js');
27
29
  const MAX_BODY_BYTES = 1048576;
28
30
  const MAX_CHALLENGE_BODY_BYTES = 16384;
@@ -35,7 +37,7 @@ const MAX_CONNECTIONS = 64;
35
37
  const MAX_HEADERS_COUNT = 64;
36
38
  const STEP_PATH_RE = /^\/step\/([A-Za-z0-9_]+)\/([A-Za-z0-9_-]+)\/?$/;
37
39
  const SECRET_HEADER_PATTERN = /^(authorization|credentials?|token|api[_-]?key|x-api[_-]?key|x-auth[_-]?token|password|secret|client[_-]secret|refresh[_-]token|access[_-]token|bearer|session[_-]token|cookie|set[_-]cookie)$/i;
38
- function validateProxyUrl(raw) {
40
+ function validateProxyUrl(raw, allowHttp) {
39
41
  if (/[\r\n\x00]/.test(raw)) {
40
42
  throw new Error("webhook_receiver.public_url must not contain CR/LF/NUL");
41
43
  }
@@ -48,10 +50,16 @@ function validateProxyUrl(raw) {
48
50
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
49
51
  throw new Error(`webhook_receiver.public_url must be http(s); got ${parsed.protocol}`);
50
52
  }
53
+ if (parsed.protocol === "http:" && !allowHttp) {
54
+ throw new Error("webhook_receiver.public_url must use https (set allowHttp only for controlled local development)");
55
+ }
51
56
  if (parsed.username || parsed.password) {
52
57
  throw new Error("webhook_receiver.public_url must not include userinfo");
53
58
  }
54
- return raw.replace(/\/$/, "");
59
+ if (parsed.search || parsed.hash) {
60
+ throw new Error("webhook_receiver.public_url must not include a query string or fragment");
61
+ }
62
+ return raw.replace(/\/+$/, "");
55
63
  }
56
64
  function retryKeyString(k) {
57
65
  return `${k.step_id}::${k.operation_id}`;
@@ -62,13 +70,18 @@ async function createWebhookReceiver(options = {}) {
62
70
  throw new Error("webhook_receiver.mode=proxy_url requires `public_url`");
63
71
  }
64
72
  const host = options.host ?? "127.0.0.1";
65
- if (mode === "loopback_mock" && (host === "0.0.0.0" || host === "::")) {
73
+ if (mode === "loopback_mock" && !isLoopbackHost(host)) {
66
74
  throw new Error(
67
75
  `webhook_receiver host ${host} is not permitted in loopback_mock mode. Use mode=proxy_url with an explicit public_url for publicly-reachable runs.`
68
76
  );
69
77
  }
70
78
  const port = options.port ?? 0;
71
- const proxyBase = mode === "proxy_url" ? validateProxyUrl(options.public_url) : void 0;
79
+ const proxyBase = mode === "proxy_url" ? validateProxyUrl(options.public_url, options.allowHttp === true) : void 0;
80
+ if (options.tls && proxyBase && new URL(proxyBase).protocol !== "https:") {
81
+ throw new Error("webhook_receiver.public_url must use https when local TLS is configured");
82
+ }
83
+ const publicRouteSuffix = mode === "proxy_url" ? `/_adcp_receiver/${(0, import_node_crypto.randomUUID)()}` : "";
84
+ const routePrefix = proxyBase ? `${new URL(proxyBase).pathname.replace(/\/+$/, "")}${publicRouteSuffix}` : "";
72
85
  const captured = [];
73
86
  const challenges = [];
74
87
  const waiters = [];
@@ -77,9 +90,23 @@ async function createWebhookReceiver(options = {}) {
77
90
  const deliveryCounts = /* @__PURE__ */ new Map();
78
91
  const challengeCounts = /* @__PURE__ */ new Map();
79
92
  let closed = false;
80
- const server = (0, import_node_http.createServer)(
81
- (req, res) => handleRequest(req, res, { captured, challenges, waiters, retryPolicies, deliveryCounts, challengeCounts })
82
- );
93
+ const requestListener = (req, res) => handleRequest(req, res, {
94
+ captured,
95
+ challenges,
96
+ waiters,
97
+ retryPolicies,
98
+ deliveryCounts,
99
+ challengeCounts,
100
+ routePrefix
101
+ });
102
+ const server = options.tls ? (0, import_node_https.createServer)(
103
+ {
104
+ cert: options.tls.cert,
105
+ key: options.tls.key,
106
+ ...options.tls.passphrase !== void 0 && { passphrase: options.tls.passphrase }
107
+ },
108
+ requestListener
109
+ ) : (0, import_node_http.createServer)(requestListener);
83
110
  server.headersTimeout = HEADERS_TIMEOUT_MS;
84
111
  server.requestTimeout = REQUEST_TIMEOUT_MS;
85
112
  server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MS;
@@ -94,10 +121,11 @@ async function createWebhookReceiver(options = {}) {
94
121
  });
95
122
  });
96
123
  const bound = server.address();
97
- const base_url = proxyBase ?? `http://${formatHost(bound.address)}:${bound.port}`;
124
+ const base_url = proxyBase ? `${proxyBase}${publicRouteSuffix}` : `${options.tls ? "https" : "http"}://${formatHost(bound.address)}:${bound.port}`;
98
125
  return {
99
126
  base_url,
100
127
  mode,
128
+ bind_host: host,
101
129
  all: () => captured.slice(),
102
130
  challenges: () => challenges.slice(),
103
131
  matching: (filter) => captured.filter((w) => matchesFilter(w, filter)),
@@ -116,19 +144,26 @@ async function createWebhookReceiver(options = {}) {
116
144
  }
117
145
  };
118
146
  }
147
+ function isLoopbackHost(host) {
148
+ const normalized = host.toLowerCase();
149
+ if (normalized === "localhost") return true;
150
+ if ((0, import_node_net.isIP)(host) === 4) return /^127(?:\.\d{1,3}){3}$/.test(host);
151
+ if ((0, import_node_net.isIP)(host) === 6) return normalized === "::1" || /^(?:0:){7}1$/.test(normalized);
152
+ return false;
153
+ }
119
154
  function handleRequest(req, res, state) {
120
155
  if (req.method !== "POST") {
121
156
  res.statusCode = 405;
122
157
  res.end();
123
158
  return;
124
159
  }
125
- const pathParts = parseStepPath(req.url ?? "");
160
+ const pathParts = parseStepPath(req.url ?? "", state.routePrefix);
126
161
  if (!pathParts) {
127
162
  res.statusCode = 404;
128
163
  res.end();
129
164
  return;
130
165
  }
131
- const { step_id, operation_id } = pathParts;
166
+ const { step_id, operation_id, logical_path } = pathParts;
132
167
  let size = 0;
133
168
  const chunks = [];
134
169
  let tooLarge = false;
@@ -181,7 +216,7 @@ function handleRequest(req, res, state) {
181
216
  operation_id,
182
217
  received_at: Date.now(),
183
218
  method: req.method ?? "POST",
184
- path: req.url ?? "/",
219
+ path: logical_path,
185
220
  headers: redactHeaders(headers),
186
221
  raw_body: raw,
187
222
  body: parsedBody.body,
@@ -210,7 +245,7 @@ function handleRequest(req, res, state) {
210
245
  delivery_index: deliveryIndex,
211
246
  received_at: Date.now(),
212
247
  method: req.method ?? "POST",
213
- path: req.url ?? "/",
248
+ path: logical_path,
214
249
  headers: redactHeaders(headers),
215
250
  raw_body: raw,
216
251
  ...parsedBody,
@@ -242,10 +277,15 @@ function requestPathname(reqUrl) {
242
277
  const q = reqUrl.indexOf("?");
243
278
  return q === -1 ? reqUrl : reqUrl.slice(0, q);
244
279
  }
245
- function parseStepPath(reqUrl) {
246
- const match = STEP_PATH_RE.exec(requestPathname(reqUrl));
280
+ function parseStepPath(reqUrl, routePrefix) {
281
+ const pathname = requestPathname(reqUrl);
282
+ if (routePrefix && !pathname.startsWith(`${routePrefix}/`)) return void 0;
283
+ const logicalPath = routePrefix ? pathname.slice(routePrefix.length) : pathname;
284
+ const match = STEP_PATH_RE.exec(logicalPath);
247
285
  if (!match) return void 0;
248
- return { step_id: match[1], operation_id: match[2] };
286
+ const queryIndex = reqUrl.indexOf("?");
287
+ const query = queryIndex === -1 ? "" : reqUrl.slice(queryIndex);
288
+ return { step_id: match[1], operation_id: match[2], logical_path: `${logicalPath}${query}` };
249
289
  }
250
290
  function normalizeHeaders(raw) {
251
291
  const out = {};
@@ -1,5 +1,7 @@
1
1
  import { createServer } from "node:http";
2
+ import { createServer as createHttpsServer } from "node:https";
2
3
  import { randomUUID } from "node:crypto";
4
+ import { isIP } from "node:net";
3
5
  import { getSchemaValidatorByRef } from "../../validation/schema-loader.mjs";
4
6
  const MAX_BODY_BYTES = 1048576;
5
7
  const MAX_CHALLENGE_BODY_BYTES = 16384;
@@ -12,7 +14,7 @@ const MAX_CONNECTIONS = 64;
12
14
  const MAX_HEADERS_COUNT = 64;
13
15
  const STEP_PATH_RE = /^\/step\/([A-Za-z0-9_]+)\/([A-Za-z0-9_-]+)\/?$/;
14
16
  const SECRET_HEADER_PATTERN = /^(authorization|credentials?|token|api[_-]?key|x-api[_-]?key|x-auth[_-]?token|password|secret|client[_-]secret|refresh[_-]token|access[_-]token|bearer|session[_-]token|cookie|set[_-]cookie)$/i;
15
- function validateProxyUrl(raw) {
17
+ function validateProxyUrl(raw, allowHttp) {
16
18
  if (/[\r\n\x00]/.test(raw)) {
17
19
  throw new Error("webhook_receiver.public_url must not contain CR/LF/NUL");
18
20
  }
@@ -25,10 +27,16 @@ function validateProxyUrl(raw) {
25
27
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
26
28
  throw new Error(`webhook_receiver.public_url must be http(s); got ${parsed.protocol}`);
27
29
  }
30
+ if (parsed.protocol === "http:" && !allowHttp) {
31
+ throw new Error("webhook_receiver.public_url must use https (set allowHttp only for controlled local development)");
32
+ }
28
33
  if (parsed.username || parsed.password) {
29
34
  throw new Error("webhook_receiver.public_url must not include userinfo");
30
35
  }
31
- return raw.replace(/\/$/, "");
36
+ if (parsed.search || parsed.hash) {
37
+ throw new Error("webhook_receiver.public_url must not include a query string or fragment");
38
+ }
39
+ return raw.replace(/\/+$/, "");
32
40
  }
33
41
  function retryKeyString(k) {
34
42
  return `${k.step_id}::${k.operation_id}`;
@@ -39,13 +47,18 @@ async function createWebhookReceiver(options = {}) {
39
47
  throw new Error("webhook_receiver.mode=proxy_url requires `public_url`");
40
48
  }
41
49
  const host = options.host ?? "127.0.0.1";
42
- if (mode === "loopback_mock" && (host === "0.0.0.0" || host === "::")) {
50
+ if (mode === "loopback_mock" && !isLoopbackHost(host)) {
43
51
  throw new Error(
44
52
  `webhook_receiver host ${host} is not permitted in loopback_mock mode. Use mode=proxy_url with an explicit public_url for publicly-reachable runs.`
45
53
  );
46
54
  }
47
55
  const port = options.port ?? 0;
48
- const proxyBase = mode === "proxy_url" ? validateProxyUrl(options.public_url) : void 0;
56
+ const proxyBase = mode === "proxy_url" ? validateProxyUrl(options.public_url, options.allowHttp === true) : void 0;
57
+ if (options.tls && proxyBase && new URL(proxyBase).protocol !== "https:") {
58
+ throw new Error("webhook_receiver.public_url must use https when local TLS is configured");
59
+ }
60
+ const publicRouteSuffix = mode === "proxy_url" ? `/_adcp_receiver/${randomUUID()}` : "";
61
+ const routePrefix = proxyBase ? `${new URL(proxyBase).pathname.replace(/\/+$/, "")}${publicRouteSuffix}` : "";
49
62
  const captured = [];
50
63
  const challenges = [];
51
64
  const waiters = [];
@@ -54,9 +67,23 @@ async function createWebhookReceiver(options = {}) {
54
67
  const deliveryCounts = /* @__PURE__ */ new Map();
55
68
  const challengeCounts = /* @__PURE__ */ new Map();
56
69
  let closed = false;
57
- const server = createServer(
58
- (req, res) => handleRequest(req, res, { captured, challenges, waiters, retryPolicies, deliveryCounts, challengeCounts })
59
- );
70
+ const requestListener = (req, res) => handleRequest(req, res, {
71
+ captured,
72
+ challenges,
73
+ waiters,
74
+ retryPolicies,
75
+ deliveryCounts,
76
+ challengeCounts,
77
+ routePrefix
78
+ });
79
+ const server = options.tls ? createHttpsServer(
80
+ {
81
+ cert: options.tls.cert,
82
+ key: options.tls.key,
83
+ ...options.tls.passphrase !== void 0 && { passphrase: options.tls.passphrase }
84
+ },
85
+ requestListener
86
+ ) : createServer(requestListener);
60
87
  server.headersTimeout = HEADERS_TIMEOUT_MS;
61
88
  server.requestTimeout = REQUEST_TIMEOUT_MS;
62
89
  server.keepAliveTimeout = KEEP_ALIVE_TIMEOUT_MS;
@@ -71,10 +98,11 @@ async function createWebhookReceiver(options = {}) {
71
98
  });
72
99
  });
73
100
  const bound = server.address();
74
- const base_url = proxyBase ?? `http://${formatHost(bound.address)}:${bound.port}`;
101
+ const base_url = proxyBase ? `${proxyBase}${publicRouteSuffix}` : `${options.tls ? "https" : "http"}://${formatHost(bound.address)}:${bound.port}`;
75
102
  return {
76
103
  base_url,
77
104
  mode,
105
+ bind_host: host,
78
106
  all: () => captured.slice(),
79
107
  challenges: () => challenges.slice(),
80
108
  matching: (filter) => captured.filter((w) => matchesFilter(w, filter)),
@@ -93,19 +121,26 @@ async function createWebhookReceiver(options = {}) {
93
121
  }
94
122
  };
95
123
  }
124
+ function isLoopbackHost(host) {
125
+ const normalized = host.toLowerCase();
126
+ if (normalized === "localhost") return true;
127
+ if (isIP(host) === 4) return /^127(?:\.\d{1,3}){3}$/.test(host);
128
+ if (isIP(host) === 6) return normalized === "::1" || /^(?:0:){7}1$/.test(normalized);
129
+ return false;
130
+ }
96
131
  function handleRequest(req, res, state) {
97
132
  if (req.method !== "POST") {
98
133
  res.statusCode = 405;
99
134
  res.end();
100
135
  return;
101
136
  }
102
- const pathParts = parseStepPath(req.url ?? "");
137
+ const pathParts = parseStepPath(req.url ?? "", state.routePrefix);
103
138
  if (!pathParts) {
104
139
  res.statusCode = 404;
105
140
  res.end();
106
141
  return;
107
142
  }
108
- const { step_id, operation_id } = pathParts;
143
+ const { step_id, operation_id, logical_path } = pathParts;
109
144
  let size = 0;
110
145
  const chunks = [];
111
146
  let tooLarge = false;
@@ -158,7 +193,7 @@ function handleRequest(req, res, state) {
158
193
  operation_id,
159
194
  received_at: Date.now(),
160
195
  method: req.method ?? "POST",
161
- path: req.url ?? "/",
196
+ path: logical_path,
162
197
  headers: redactHeaders(headers),
163
198
  raw_body: raw,
164
199
  body: parsedBody.body,
@@ -187,7 +222,7 @@ function handleRequest(req, res, state) {
187
222
  delivery_index: deliveryIndex,
188
223
  received_at: Date.now(),
189
224
  method: req.method ?? "POST",
190
- path: req.url ?? "/",
225
+ path: logical_path,
191
226
  headers: redactHeaders(headers),
192
227
  raw_body: raw,
193
228
  ...parsedBody,
@@ -219,10 +254,15 @@ function requestPathname(reqUrl) {
219
254
  const q = reqUrl.indexOf("?");
220
255
  return q === -1 ? reqUrl : reqUrl.slice(0, q);
221
256
  }
222
- function parseStepPath(reqUrl) {
223
- const match = STEP_PATH_RE.exec(requestPathname(reqUrl));
257
+ function parseStepPath(reqUrl, routePrefix) {
258
+ const pathname = requestPathname(reqUrl);
259
+ if (routePrefix && !pathname.startsWith(`${routePrefix}/`)) return void 0;
260
+ const logicalPath = routePrefix ? pathname.slice(routePrefix.length) : pathname;
261
+ const match = STEP_PATH_RE.exec(logicalPath);
224
262
  if (!match) return void 0;
225
- return { step_id: match[1], operation_id: match[2] };
263
+ const queryIndex = reqUrl.indexOf("?");
264
+ const query = queryIndex === -1 ? "" : reqUrl.slice(queryIndex);
265
+ return { step_id: match[1], operation_id: match[2], logical_path: `${logicalPath}${query}` };
226
266
  }
227
267
  function normalizeHeaders(raw) {
228
268
  const out = {};
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * AdCP SDK library version
3
3
  */
4
- export declare const LIBRARY_VERSION = "14.0.0-beta.19";
4
+ export declare const LIBRARY_VERSION = "14.0.0-beta.20";
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: "14.0.0-beta.19";
36
+ readonly library: "14.0.0-beta.20";
37
37
  readonly adcp: "3.2.0-beta.9";
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.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.2.0-beta.9", "3.2-beta.9"];
39
- readonly generatedAt: "2026-08-30T04:12:52.476Z";
39
+ readonly generatedAt: "2026-08-30T05:56:08.494Z";
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 = "14.0.0-beta.19";
4
+ export declare const LIBRARY_VERSION = "14.0.0-beta.20";
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: "14.0.0-beta.19";
36
+ readonly library: "14.0.0-beta.20";
37
37
  readonly adcp: "3.2.0-beta.9";
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.0.13", "3.0.14", "3.0.15", "3.0.16", "3.0.17", "3.0.18", "3.0.19", "3.0.20", "3.0.21", "3.0.22", "3.0.23", "3.0.24", "3.0.25", "3.1.0", "3.1", "3.1.1", "3.1.2", "3.1.3", "3.1.4", "3.1.5", "3.1.6", "3.1.7", "3.1.8", "3.1.9", "3.1.10", "3.1.11", "3.1.12", "3.1.13", "3.1.14", "3.1.15", "3.1.16", "3.1.17", "3.1.18", "3.2.0-beta.9", "3.2-beta.9"];
39
- readonly generatedAt: "2026-08-30T04:12:52.476Z";
39
+ readonly generatedAt: "2026-08-30T05:56:08.494Z";
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 = "14.0.0-beta.19";
34
+ const LIBRARY_VERSION = "14.0.0-beta.20";
35
35
  const ADCP_VERSION = "3.2.0-beta.9";
36
36
  const ADCP_MAJOR_VERSION = 3;
37
37
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -94,10 +94,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
94
94
  "3.2-beta.9"
95
95
  ];
96
96
  const VERSION_INFO = {
97
- library: "14.0.0-beta.19",
97
+ library: "14.0.0-beta.20",
98
98
  adcp: "3.2.0-beta.9",
99
99
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
100
- generatedAt: "2026-08-30T04:12:52.476Z"
100
+ generatedAt: "2026-08-30T05:56:08.494Z"
101
101
  };
102
102
  function getAdcpVersion() {
103
103
  return ADCP_VERSION;
@@ -1,4 +1,4 @@
1
- const LIBRARY_VERSION = "14.0.0-beta.19";
1
+ const LIBRARY_VERSION = "14.0.0-beta.20";
2
2
  const ADCP_VERSION = "3.2.0-beta.9";
3
3
  const ADCP_MAJOR_VERSION = 3;
4
4
  const COMPATIBLE_ADCP_VERSIONS = [
@@ -61,10 +61,10 @@ const COMPATIBLE_ADCP_VERSIONS = [
61
61
  "3.2-beta.9"
62
62
  ];
63
63
  const VERSION_INFO = {
64
- library: "14.0.0-beta.19",
64
+ library: "14.0.0-beta.20",
65
65
  adcp: "3.2.0-beta.9",
66
66
  compatibleVersions: COMPATIBLE_ADCP_VERSIONS,
67
- generatedAt: "2026-08-30T04:12:52.476Z"
67
+ generatedAt: "2026-08-30T05:56:08.494Z"
68
68
  };
69
69
  function getAdcpVersion() {
70
70
  return ADCP_VERSION;
package/docs/llms.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  # Ad Context Protocol (AdCP)
2
2
 
3
3
  > Generated at: 2026-08-30
4
- > Library: @adcp/sdk v14.0.0-beta.19
4
+ > Library: @adcp/sdk v14.0.0-beta.20
5
5
  > AdCP major version: 3
6
6
  > Canonical URL: https://adcontextprotocol.github.io/adcp-client/llms.txt
7
7
  > Note: the `Library` stamp reflects the package.json version at doc-generation time. The narrative below describes the surface that lands on the next-published minor — including any 6.7 helpers documented here ahead of the release tag.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adcp/sdk",
3
- "version": "14.0.0-beta.19",
3
+ "version": "14.0.0-beta.20",
4
4
  "description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
5
5
  "workspaces": [
6
6
  ".",