cdk-local 0.148.0 → 0.148.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.
@@ -6,7 +6,8 @@ import path, { dirname, isAbsolute, join, normalize, relative, resolve, sep } fr
6
6
  import { Command, Option } from "commander";
7
7
  import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
8
8
  import { Agent, createServer, request } from "node:http";
9
- import { Agent as Agent$1, createServer as createServer$1 } from "node:https";
9
+ import { Agent as Agent$1, createServer as createServer$1, request as request$1 } from "node:https";
10
+ import { brotliDecompressSync, gunzipSync, inflateSync } from "node:zlib";
10
11
  import { NodeHttpHandler } from "@smithy/node-http-handler";
11
12
  import { Agent as Agent$2 } from "agent-base";
12
13
  import { HttpProxyAgent } from "http-proxy-agent";
@@ -195,6 +196,13 @@ function hostFromAuthority(authority) {
195
196
  * via `buildStsClientConfig` for the STS sites);
196
197
  * `tests/unit/utils/aws-proxy-client-audit.test.ts` fences the sweep so a new
197
198
  * construction site cannot silently skip it.
199
+ *
200
+ * Not every AWS-bound request is an SDK call, though — and the global
201
+ * `fetch` (undici) reads no proxy variable either (issue #647). The layer
202
+ * ZIP download and the Cognito JWKS / OIDC discovery reads are plain GETs,
203
+ * so `proxyAwareFetch()` is the second seam: same `NO_PROXY` decision, same
204
+ * "empty when unconfigured" contract, fenced by
205
+ * `tests/unit/utils/aws-proxy-fetch-audit.test.ts`.
198
206
  */
199
207
  /**
200
208
  * The SDK applies these defaults only when it builds its OWN agents from a
@@ -312,23 +320,305 @@ function buildProxyRequestHandler() {
312
320
  function buildProxyClientConfig(opts = {}) {
313
321
  if (!isProxyEnvConfigured()) return {};
314
322
  const profile = opts.profile;
315
- const chainHandler = buildProxyRequestHandler();
316
323
  let chain;
317
324
  const credentials = async (identityProperties) => {
318
- if (!chain) {
325
+ chain ??= (async () => {
319
326
  const { defaultProvider } = await import("@aws-sdk/credential-provider-node");
320
- chain = defaultProvider({
327
+ return defaultProvider({
321
328
  ...profile ? { profile } : {},
322
- clientConfig: { requestHandler: chainHandler }
329
+ clientConfig: { requestHandler: buildProxyRequestHandler() }
323
330
  });
324
- }
325
- return chain(identityProperties);
331
+ })().catch((err) => {
332
+ chain = void 0;
333
+ throw err;
334
+ });
335
+ return (await chain)(identityProperties);
326
336
  };
327
337
  return {
328
338
  requestHandler: buildProxyRequestHandler(),
329
339
  credentials
330
340
  };
331
341
  }
342
+ /**
343
+ * The fetch spec's redirect budget. Reached only by a redirect loop, which
344
+ * neither call site's endpoint produces — the bound exists so a
345
+ * misconfigured origin cannot spin forever.
346
+ */
347
+ const MAX_FETCH_REDIRECTS = 20;
348
+ /** Statuses whose response carries a null body per the fetch spec. */
349
+ const NULL_BODY_STATUSES = /* @__PURE__ */ new Set([
350
+ 204,
351
+ 205,
352
+ 304
353
+ ]);
354
+ /**
355
+ * Socket-inactivity bound for a proxied request, matching undici's
356
+ * `headersTimeout` / `bodyTimeout` defaults — because `node:http` has NO
357
+ * default timeout at all, and without one a proxy that accepts the
358
+ * connection and never answers hangs `cdkl` forever. That is strictly worse
359
+ * than the pre-#647 direct connection it replaced, and it would hang exactly
360
+ * the fallback (`docs/cli-reference.md`, "JWKS / OIDC discovery
361
+ * unreachable") that exists to keep local dev moving.
362
+ *
363
+ * Undici's separate 10 s CONNECT timeout is not reproduced: a black-holed
364
+ * proxy fails here in 300 s rather than 10. Bounded is the property that
365
+ * matters; the exempt path keeps undici's own timers (see the short-circuit
366
+ * in {@link proxyAwareFetch}). Enforced by a timer `getThroughAgent` re-arms
367
+ * on every byte — INACTIVITY, like undici's, not a wall-clock TOTAL, which
368
+ * would abort a slow-but-progressing transfer that `fetch` would have
369
+ * completed (a Lambda layer ZIP is up to 250 MB, and the whole point is that
370
+ * it is crossing a corporate proxy). See `getThroughAgent` for why a
371
+ * socket-level timer cannot bound the CONNECT tunnel.
372
+ */
373
+ const REQUEST_STALL_TIMEOUT_MS = 3e5;
374
+ function isRedirectStatus(status) {
375
+ return status === 301 || status === 302 || status === 303 || status === 307 || status === 308;
376
+ }
377
+ /**
378
+ * Whether `hostname` names THIS machine. `proxy-from-env` implements the
379
+ * standard `NO_PROXY` semantics faithfully, and the standard exempts nothing
380
+ * by default — so with `HTTP_PROXY` exported and no matching `NO_PROXY`
381
+ * entry, a request to `127.0.0.1` is sent to the corporate proxy, which
382
+ * cannot reach the caller's own loopback and refuses it.
383
+ *
384
+ * For an AWS SDK client that is unreachable in practice (every endpoint is a
385
+ * public AWS host), which is why {@link EnvRoutingProxyAgent} does not carry
386
+ * this rule. For `proxyAwareFetch` it is not: a JWT authorizer's issuer is
387
+ * routinely a loopback IdP in local dev — this repo's own
388
+ * `local-start-api-cognito-jwt` fixture is exactly that shape — and an
389
+ * unreachable JWKS does not fail the request, it degrades the verifier to
390
+ * ACCEPT EVERY TOKEN with a warn. So proxying loopback here converts a
391
+ * working local setup into a silent auth downgrade, and it cannot buy
392
+ * anything in exchange: a forward proxy has no route to the client's
393
+ * loopback. Every other loopback request in cdk-local (the RIE and AgentCore
394
+ * container clients) is unproxied for the same reason.
395
+ *
396
+ * Deliberately NOT extended to RFC 1918 / private ranges: a corporate proxy
397
+ * plausibly does reach those, so exempting them would be a guess rather
398
+ * than an impossibility. `NO_PROXY` remains the control for that case.
399
+ */
400
+ /**
401
+ * Whether `proxyUrl` names a proxy these agents can actually SPEAK to.
402
+ *
403
+ * `getProxyForUrl` honours `ALL_PROXY`, and `ALL_PROXY=socks5://...` is an
404
+ * ordinary spelling — but `http-proxy-agent` / `https-proxy-agent` speak HTTP
405
+ * `CONNECT`, not SOCKS. Measured: `new HttpsProxyAgent('socks5://127.0.0.1:1080')`
406
+ * constructs happily and then talks HTTP at a SOCKS port, so every request
407
+ * through it fails.
408
+ *
409
+ * Falling back to a DIRECT request is the right answer rather than a
410
+ * best-effort attempt, for a reason specific to this seam: before issue #647
411
+ * these reads went direct through undici and WORKED for a SOCKS user, and an
412
+ * unreachable JWKS does not deny requests — it caches `passThrough` and
413
+ * accepts every token for the failure TTL. Trying and failing would turn a
414
+ * working setup into a silent auth downgrade, which is the outcome the
415
+ * loopback rule below exists to prevent.
416
+ *
417
+ * The SDK-client half of this — `EnvRoutingProxyAgent`, which PR 646 built
418
+ * with the same blind spot, and whose failures are at least loud — is tracked
419
+ * in https://github.com/go-to-k/cdk-local/issues/663.
420
+ */
421
+ function isSpeakableProxy(proxyUrl) {
422
+ return /^https?:\/\//i.test(proxyUrl);
423
+ }
424
+ function isLoopbackHost(hostname) {
425
+ const host = hostname.trim().replace(/^\[|\]$/g, "").replace(/\.$/, "").toLowerCase();
426
+ if (host === "localhost" || host.endsWith(".localhost")) return true;
427
+ if (host === "::1" || host === "0:0:0:0:0:0:0:1") return true;
428
+ if (host === "0.0.0.0" || host === "::" || host === "0:0:0:0:0:0:0:0" || host === "::ffff:0.0.0.0" || host === "::ffff:0:0") return true;
429
+ const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(host);
430
+ if (mapped) return parseInt(mapped[1], 16) >> 8 === 127;
431
+ const dotted = /^(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(host);
432
+ if (!dotted) return false;
433
+ const octets = dotted.slice(1).map(Number);
434
+ if (octets.some((o) => o > 255)) return false;
435
+ return octets[0] === 127;
436
+ }
437
+ /**
438
+ * `http:` / `https:` only. The rejection names the PROTOCOL and never the
439
+ * URL: the presigned layer `Content.Location` carries an `X-Amz-Signature`
440
+ * in its query string, so a URL in an error message is a credential in a log
441
+ * line (the same reasoning `downloadPresignedZip`'s own HTTP-status throw
442
+ * applies).
443
+ */
444
+ function parseHttpUrl(href) {
445
+ const parsed = new URL(href);
446
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new TypeError(`Unsupported protocol for a proxied request: "${parsed.protocol}"`);
447
+ return parsed;
448
+ }
449
+ /**
450
+ * One GET through `agent`, with the whole body buffered. Buffering is what
451
+ * lets the result become a real `Response` (and is what both call sites do
452
+ * with the body anyway: `text()` for JWKS / discovery, `arrayBuffer()` for
453
+ * the layer ZIP).
454
+ */
455
+ function getThroughAgent(url, agent, timeoutMs = REQUEST_STALL_TIMEOUT_MS) {
456
+ return new Promise((resolve, reject) => {
457
+ let settled = false;
458
+ let timer;
459
+ let rearm = () => void 0;
460
+ const succeed = (value) => {
461
+ if (settled) return;
462
+ settled = true;
463
+ if (timer) clearTimeout(timer);
464
+ resolve(value);
465
+ };
466
+ const fail = (err) => {
467
+ if (settled) return;
468
+ settled = true;
469
+ if (timer) clearTimeout(timer);
470
+ reject(err);
471
+ };
472
+ const req = (url.protocol === "https:" ? request$1 : request)(url, {
473
+ agent,
474
+ headers: {
475
+ accept: "*/*",
476
+ "accept-encoding": "identity"
477
+ }
478
+ }, (res) => {
479
+ rearm();
480
+ const chunks = [];
481
+ res.on("data", (chunk) => {
482
+ rearm();
483
+ chunks.push(chunk);
484
+ });
485
+ res.on("error", fail);
486
+ res.on("end", () => {
487
+ if (res.statusCode === void 0) {
488
+ fail(/* @__PURE__ */ new Error("Malformed HTTP response: no status code"));
489
+ return;
490
+ }
491
+ succeed({
492
+ status: res.statusCode,
493
+ statusText: res.statusMessage ?? "",
494
+ headers: res.headers,
495
+ body: Buffer.concat(chunks)
496
+ });
497
+ });
498
+ });
499
+ req.on("error", fail);
500
+ rearm = () => {
501
+ if (settled) return;
502
+ if (timer) clearTimeout(timer);
503
+ timer = setTimeout(() => {
504
+ req.destroy();
505
+ fail(/* @__PURE__ */ new Error(`Proxied request stalled for ${timeoutMs} ms with no progress`));
506
+ }, timeoutMs);
507
+ timer.unref?.();
508
+ };
509
+ rearm();
510
+ req.end();
511
+ });
512
+ }
513
+ /**
514
+ * `fetch` decodes a `Content-Encoding` body before handing it to the caller;
515
+ * `node:http` does not. Node sends no `Accept-Encoding` of its own, so a
516
+ * compliant origin answers identity — but S3 replays an object's STORED
517
+ * `Content-Encoding`, so the case is reachable and a silently-still-
518
+ * compressed body would be a corrupt layer ZIP rather than an error.
519
+ *
520
+ * An encoding this cannot decode (or one that fails to decode) leaves the
521
+ * body and the header untouched, so the caller sees exactly what the origin
522
+ * sent instead of a truncated one.
523
+ */
524
+ function decodeContentEncoding(raw) {
525
+ const header = raw.headers["content-encoding"];
526
+ const encoding = (Array.isArray(header) ? header.join(",") : header ?? "").trim().toLowerCase();
527
+ if (encoding === "" || encoding === "identity") return {
528
+ body: raw.body,
529
+ decoded: false
530
+ };
531
+ try {
532
+ if (encoding === "gzip" || encoding === "x-gzip") return {
533
+ body: gunzipSync(raw.body),
534
+ decoded: true
535
+ };
536
+ if (encoding === "deflate" || encoding === "x-deflate") return {
537
+ body: inflateSync(raw.body),
538
+ decoded: true
539
+ };
540
+ if (encoding === "br") return {
541
+ body: brotliDecompressSync(raw.body),
542
+ decoded: true
543
+ };
544
+ } catch {
545
+ return {
546
+ body: raw.body,
547
+ decoded: false
548
+ };
549
+ }
550
+ return {
551
+ body: raw.body,
552
+ decoded: false
553
+ };
554
+ }
555
+ function toWebResponse(raw) {
556
+ if (raw.status < 200 || raw.status > 599) throw new Error(`Unsupported HTTP status in response: ${raw.status}`);
557
+ const { body, decoded } = decodeContentEncoding(raw);
558
+ const headers = new Headers();
559
+ for (const [name, value] of Object.entries(raw.headers)) {
560
+ if (value === void 0) continue;
561
+ if (decoded && (name === "content-encoding" || name === "content-length")) continue;
562
+ if (Array.isArray(value)) for (const one of value) headers.append(name, one);
563
+ else headers.append(name, value);
564
+ }
565
+ return new Response(NULL_BODY_STATUSES.has(raw.status) ? null : body, {
566
+ status: raw.status,
567
+ statusText: raw.statusText.replace(/[^\t\x20-\x7e\x80-\xff]/g, ""),
568
+ headers
569
+ });
570
+ }
571
+ /**
572
+ * GET a URL, honoring the standard proxy environment (issue #647).
573
+ *
574
+ * The global `fetch` (undici) reads no proxy variable, so cdk-local's
575
+ * non-SDK AWS-bound reads — the Lambda layer ZIP download from its
576
+ * presigned `Content.Location`, and the Cognito JWKS / OIDC discovery
577
+ * documents — connected DIRECT even where every SDK call was tunneled. On a
578
+ * machine whose only egress is a forward proxy that is a hang or a
579
+ * self-signed-certificate failure one step after `GetLayerVersion`
580
+ * succeeded.
581
+ *
582
+ * Contract mirrors {@link buildProxyClientConfig}: with no proxy variable
583
+ * set this IS `globalThis.fetch` (zero behavior change), and with one set
584
+ * the request goes through {@link EnvRoutingProxyAgent} — the same
585
+ * `NO_PROXY` decision, evaluated per request against the target host, that
586
+ * the SDK clients get. A target that `NO_PROXY` exempts is ALSO handed back
587
+ * to `globalThis.fetch`, so the hand-rolled path is entered only when it
588
+ * has something to add, and every direct request keeps undici's semantics
589
+ * (its timers included) exactly as before. A fresh agent per proxied
590
+ * request, destroyed the moment that request's body is in hand — see the
591
+ * loop below for why that is a correctness requirement and not only
592
+ * tidiness.
593
+ *
594
+ * `opts.timeoutMs` is a TEST SEAM only — production callers pass one
595
+ * argument and get {@link REQUEST_STALL_TIMEOUT_MS}, which no test can
596
+ * afford to wait out.
597
+ *
598
+ * GET-only by construction: both call sites are GETs, and a method with a
599
+ * request body needs redirect-replay semantics this deliberately does not
600
+ * guess at. A future POST caller extends this (with its tests) rather than
601
+ * falling back to a bare `fetch` —
602
+ * `tests/unit/utils/aws-proxy-fetch-audit.test.ts` refuses the fallback.
603
+ */
604
+ async function proxyAwareFetch(url, opts = {}) {
605
+ if (!isProxyEnvConfigured()) return globalThis.fetch(url);
606
+ let target = parseHttpUrl(url);
607
+ for (let hop = 0;; hop++) {
608
+ if (isLoopbackHost(target.hostname) || !isSpeakableProxy(getProxyForUrl(target.href))) return globalThis.fetch(target.href);
609
+ const agent = new EnvRoutingProxyAgent();
610
+ let raw;
611
+ try {
612
+ raw = await getThroughAgent(target, agent, opts.timeoutMs);
613
+ } finally {
614
+ agent.destroy();
615
+ }
616
+ const location = raw.headers["location"];
617
+ if (!isRedirectStatus(raw.status) || typeof location !== "string" || location === "") return toWebResponse(raw);
618
+ if (hop >= MAX_FETCH_REDIRECTS) throw new Error(`Too many redirects (more than ${MAX_FETCH_REDIRECTS})`);
619
+ target = parseHttpUrl(new URL(location, target).href);
620
+ }
621
+ }
332
622
 
333
623
  //#endregion
334
624
  //#region src/utils/profile-resolver.ts
@@ -14066,8 +14356,26 @@ const DEFAULT_JWKS_TTL_MS = 3600 * 1e3;
14066
14356
  * suppressing the per-request fetch storm a 0s TTL would cause.
14067
14357
  */
14068
14358
  const FAILURE_JWKS_TTL_MS = 60 * 1e3;
14359
+ /**
14360
+ * Stall bound for the JWKS / discovery reads specifically, well under
14361
+ * `proxyAwareFetch`'s 300 s default.
14362
+ *
14363
+ * Those reads are small documents, and — unlike the layer ZIP, which is up to
14364
+ * 250 MB and wants the long default — one of them sits on a PER-REQUEST path:
14365
+ * `agentcore-serve-auth`'s `buildAgentCoreServeAuthCheck` calls
14366
+ * `verifyJwtViaDiscovery` for every inbound request, and that function holds
14367
+ * no discovery cache. Behind a black-holed proxy each in-flight request would
14368
+ * otherwise hold a socket for 300 s where the pre-#647 direct read gave up in
14369
+ * about undici's 10 s connect timeout.
14370
+ *
14371
+ * Failing FAST is also the right bias here in a way it is not for a download:
14372
+ * an unreachable JWKS lands in the documented pass-through fallback
14373
+ * (`docs/cli-reference.md`), so a long hold buys nothing and costs a stuck
14374
+ * request.
14375
+ */
14376
+ const JWKS_FETCH_TIMEOUT_MS = 1e4;
14069
14377
  function createJwksCache(opts = {}) {
14070
- const fetchImpl = opts.fetchImpl ?? (async (url) => globalThis.fetch(url));
14378
+ const fetchImpl = opts.fetchImpl ?? ((url) => proxyAwareFetch(url, { timeoutMs: JWKS_FETCH_TIMEOUT_MS }));
14071
14379
  const now = opts.now ?? (() => Date.now());
14072
14380
  const ttlMs = opts.ttlMs ?? DEFAULT_JWKS_TTL_MS;
14073
14381
  const failureTtlMs = opts.failureTtlMs ?? FAILURE_JWKS_TTL_MS;
@@ -14104,7 +14412,7 @@ function createJwksCache(opts = {}) {
14104
14412
  map.set(jwksUrl, entry);
14105
14413
  return entry;
14106
14414
  } catch (err) {
14107
- logger.warn(`JWKS unreachable at ${jwksUrl}: ${err instanceof Error ? err.message : String(err)}. JWT validation will allow all tokens — local dev fallback. Configure network access to the JWKS URL to enable real signature verification.`);
14415
+ logger.warn(`JWKS unreachable at ${jwksUrl}: ${sanitizeServiceExceptionMessage(err instanceof Error ? err.message : String(err))}. JWT validation will allow all tokens — local dev fallback. Configure network access to the JWKS URL to enable real signature verification.`);
14108
14416
  const entry = {
14109
14417
  byKid: /* @__PURE__ */ new Map(),
14110
14418
  expiresAt: now() + failureTtlMs,
@@ -14241,7 +14549,7 @@ async function verifyJwtViaDiscovery(authorizer, authorizationHeader, jwksCache,
14241
14549
  identityHash: void 0,
14242
14550
  ttlSeconds: 0
14243
14551
  };
14244
- const fetchImpl = opts.fetchImpl ?? (async (url) => globalThis.fetch(url));
14552
+ const fetchImpl = opts.fetchImpl ?? ((url) => proxyAwareFetch(url, { timeoutMs: JWKS_FETCH_TIMEOUT_MS }));
14245
14553
  let issuer;
14246
14554
  let jwksUri;
14247
14555
  try {
@@ -14252,7 +14560,7 @@ async function verifyJwtViaDiscovery(authorizer, authorizationHeader, jwksCache,
14252
14560
  issuer = doc.issuer;
14253
14561
  jwksUri = doc.jwks_uri;
14254
14562
  } catch (err) {
14255
- if (shouldWarn(authorizer.discoveryUrl, opts.warnedAt, now)) getLogger().child("cognito-jwt").warn(`OIDC discovery unreachable at ${authorizer.discoveryUrl}: ${err instanceof Error ? err.message : String(err)}. Token accepted without verification — local dev fallback.`);
14563
+ if (shouldWarn(authorizer.discoveryUrl, opts.warnedAt, now)) getLogger().child("cognito-jwt").warn(`OIDC discovery unreachable at ${authorizer.discoveryUrl}: ${sanitizeServiceExceptionMessage(err instanceof Error ? err.message : String(err))}. Token accepted without verification — local dev fallback.`);
14256
14564
  const identityHash = buildIdentityHash([token]);
14257
14565
  const parsed = parseJwt(token);
14258
14566
  if (parsed) return shapeAllowResult(parsed, identityHash, now);
@@ -16645,7 +16953,7 @@ async function materializeLayerFromArn(layer, options = {}) {
16645
16953
  try {
16646
16954
  zipBytes = await downloadPresignedZip(presignedUrl, options);
16647
16955
  } catch (err) {
16648
- throw new LayerMaterializationError(`Layer ${layer.arn}: failed to download layer ZIP from the presigned URL: ${errMsg(err)}.`);
16956
+ throw new LayerMaterializationError(`Layer ${layer.arn}: failed to download layer ZIP from the presigned URL: ${sanitizeServiceExceptionMessage(errMsg(err))}.`);
16649
16957
  }
16650
16958
  const dir = await mkdtemp(join(tmpdir(), `${getEmbedConfig().resourceNamePrefix}-arn-layer-${layer.name}-${layer.version}-`));
16651
16959
  try {
@@ -16727,7 +17035,7 @@ async function buildAssumeRoleCommand(roleArn) {
16727
17035
  }
16728
17036
  async function downloadPresignedZip(presignedUrl, options) {
16729
17037
  if (options.fetchZip) return options.fetchZip(presignedUrl);
16730
- const response = await fetch(presignedUrl);
17038
+ const response = await proxyAwareFetch(presignedUrl);
16731
17039
  if (!response.ok) throw new Error(`HTTP ${response.status} ${flattenToOneLine(response.statusText)} from layer Content.Location URL`);
16732
17040
  const buf = await response.arrayBuffer();
16733
17041
  return new Uint8Array(buf);
@@ -16819,9 +17127,16 @@ async function inflateRaw(data) {
16819
17127
  * The download `catch` DOES see wire-derived text — `downloadPresignedZip`
16820
17128
  * raises `HTTP <status> <statusText> ...`, and the reason phrase is whatever
16821
17129
  * the presigned host sent. Nothing there needs WITHHOLDING (no credential
16822
- * chain, no secret), but it does need FLATTENING, which is applied at that
16823
- * throw rather than here, because `errMsg` is also used by the unzip `catch`
16824
- * whose input is a local `fflate` error.
17130
+ * chain, no secret), but it does need FLATTENING.
17131
+ *
17132
+ * CORRECTED AGAIN in issue #647: that flattening used to be applied at the
17133
+ * `HTTP <status>` throw alone, which was sufficient only while `fetch` was the
17134
+ * transport and its every failure was the fixed string `fetch failed`. The
17135
+ * download now goes through `proxyAwareFetch`, so the same `catch` also sees
17136
+ * `node:net` / OpenSSL / proxy-agent messages of arbitrary shape and length.
17137
+ * The download SITE therefore applies `sanitizeServiceExceptionMessage` to
17138
+ * whatever `errMsg` returns; `errMsg` itself stays bare because its other
17139
+ * caller is the unzip `catch`, whose input is a local `fflate` error.
16825
17140
  */
16826
17141
  function errMsg(err) {
16827
17142
  return err instanceof Error ? err.message : String(err);
@@ -37739,7 +38054,8 @@ function runChild(spawnFn, nodeBin, argv, cwd, invocationId, target, bus, clock)
37739
38054
  cwd,
37740
38055
  env: {
37741
38056
  ...process.env,
37742
- CDKL_LOG_LEVEL: "warn"
38057
+ CDKL_LOG_LEVEL: "warn",
38058
+ CDKL_LOG_STREAM: "stderr"
37743
38059
  }
37744
38060
  });
37745
38061
  } catch (err) {
@@ -39826,4 +40142,4 @@ function addStudioSpecificOptions(cmd) {
39826
40142
 
39827
40143
  //#endregion
39828
40144
  export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, describeCredentialLoadFailure as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, resolveProfileCredentials as Mi, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, buildProxyClientConfig as Ni, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, isProxyEnvConfigured as Pi, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, buildStsClientConfig as ji, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, describeAwsFailureForWarn as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
39829
- //# sourceMappingURL=local-studio-DoyRYZf6.js.map
40145
+ //# sourceMappingURL=local-studio-BVxRUfQV.js.map