cdk-local 0.167.1 → 0.167.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.
@@ -2502,6 +2502,32 @@ async function resolveProfileRegion(profile) {
2502
2502
  return resolveSdkDefaultRegion(profile);
2503
2503
  }
2504
2504
 
2505
+ // src/utils/shutdown-signal.ts
2506
+ function signalExitCode(signal) {
2507
+ return signal === "SIGINT" ? 130 : 143;
2508
+ }
2509
+ function createShutdownSignalHandler(options) {
2510
+ const exit = options.exit ?? ((code) => process.exit(code));
2511
+ const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
2512
+ let count = 0;
2513
+ const handler = (signal, exitCode) => {
2514
+ const code = exitCode ?? signalExitCode(signal === "SIGINT" ? "SIGINT" : "SIGTERM");
2515
+ count += 1;
2516
+ if (count === 1) {
2517
+ options.info(options.stoppingMessage(signal));
2518
+ options.cleanup().then(() => exit(code));
2519
+ return;
2520
+ }
2521
+ if (count === 2) {
2522
+ options.warn(`Received ${signal} again; still shutting down — waiting for the cleanup to remove the containers and networks. Send it once more to force-exit (that skips the cleanup).`);
2523
+ return;
2524
+ }
2525
+ writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
2526
+ exit(code);
2527
+ };
2528
+ return handler;
2529
+ }
2530
+
2505
2531
  // src/utils/error-handler.ts
2506
2532
  var CdkLocalError = class CdkLocalError extends Error {
2507
2533
  code;
@@ -7247,10 +7273,43 @@ function getAttReads(node, out = []) {
7247
7273
  }
7248
7274
  return out;
7249
7275
  }
7276
+ function computedAttributeRead(node) {
7277
+ if (node === null || typeof node !== "object") return void 0;
7278
+ if (Array.isArray(node)) {
7279
+ for (const item of node) {
7280
+ const r = computedAttributeRead(item);
7281
+ if (r !== void 0) return r;
7282
+ }
7283
+ return;
7284
+ }
7285
+ for (const [key, value] of Object.entries(node)) {
7286
+ if (key === "Fn::GetAtt" && isCrossStackIntrinsic(value)) return "a Fn::GetAtt whose logical ID or attribute name is a cross-stack reference, which CloudFormation does not accept";
7287
+ if (key === "Fn::Sub") {
7288
+ if (isCrossStackIntrinsic(Array.isArray(value) ? value[0] : value)) return "a Fn::Sub whose template is a cross-stack reference, which CloudFormation does not accept";
7289
+ }
7290
+ const r = computedAttributeRead(value);
7291
+ if (r !== void 0) return r;
7292
+ }
7293
+ }
7294
+ function withMaskWatch(context, masked) {
7295
+ const inner = context.crossStackResolver;
7296
+ if (!inner) return context;
7297
+ const watch = (v) => {
7298
+ if (v === STATE_SECRET_MASK) masked.hit = true;
7299
+ return v;
7300
+ };
7301
+ return {
7302
+ ...context,
7303
+ crossStackResolver: {
7304
+ resolveImport: async (exportName) => watch(await inner.resolveImport(exportName)),
7305
+ resolveGetStackOutput: async (stack, region, output) => watch(await inner.resolveGetStackOutput(stack, region, output))
7306
+ }
7307
+ };
7308
+ }
7250
7309
  const CROSS_STACK_ARGV_REASON = "a cross-stack reference (Fn::ImportValue / Fn::GetStackOutput): it resolves only from a state source with the producer stack deployed";
7251
7310
  function argvValue(sub, consumedSensitive) {
7252
- if (sub.kind !== "literal") return { reason: sub.reason };
7253
7311
  if (consumedSensitive) return { reason: "resolved from a SecureString parameter, which would put the secret on the docker run argv; move the value into an Environment variable or a Secrets entry" };
7312
+ if (sub.kind !== "literal") return { reason: sub.reason };
7254
7313
  const value = sub.value;
7255
7314
  if (typeof value === "number" || typeof value === "boolean") return { value: String(value) };
7256
7315
  if (value === STATE_SECRET_MASK) return { reason: "resolved to the secret mask (***), not the deployed value" };
@@ -7663,16 +7722,17 @@ async function applyCrossStackResolverToTask(task, context, containerState) {
7663
7722
  remaining.push(u);
7664
7723
  continue;
7665
7724
  }
7666
- const secret = secretAttributeRead(rawElement, argvContext.resources);
7667
- if (secret !== void 0) {
7725
+ const refusal = secretAttributeRead(rawElement, argvContext.resources) ?? computedAttributeRead(rawElement);
7726
+ if (refusal !== void 0) {
7668
7727
  remaining.push({
7669
7728
  ...u,
7670
- reason: secret
7729
+ reason: refusal
7671
7730
  });
7672
7731
  continue;
7673
7732
  }
7674
- const { result: sub, consumedSensitive } = await resolveWithSensitivityAsync(rawElement, argvContext);
7675
- const arg = argvValue(sub, consumedSensitive);
7733
+ const masked = { hit: false };
7734
+ const { result: sub, consumedSensitive } = await resolveWithSensitivityAsync(rawElement, withMaskWatch(argvContext, masked));
7735
+ const arg = masked.hit ? { reason: `resolved a cross-stack value recorded as the secret mask (${STATE_SECRET_MASK}), not the deployed value` } : argvValue(sub, consumedSensitive);
7676
7736
  if ("value" in arg) {
7677
7737
  target[u.index] = arg.value;
7678
7738
  continue;
@@ -8411,32 +8471,6 @@ function isMalformedEnvKey(key) {
8411
8471
  return !WELL_FORMED_ENV_KEY.test(key);
8412
8472
  }
8413
8473
 
8414
- // src/utils/shutdown-signal.ts
8415
- function signalExitCode(signal) {
8416
- return signal === "SIGINT" ? 130 : 143;
8417
- }
8418
- function createShutdownSignalHandler(options) {
8419
- const exit = options.exit ?? ((code) => process.exit(code));
8420
- const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
8421
- let count = 0;
8422
- const handler = (signal, exitCode) => {
8423
- const code = exitCode ?? signalExitCode(signal === "SIGINT" ? "SIGINT" : "SIGTERM");
8424
- count += 1;
8425
- if (count === 1) {
8426
- options.info(options.stoppingMessage(signal));
8427
- options.cleanup().then(() => exit(code));
8428
- return;
8429
- }
8430
- if (count === 2) {
8431
- options.warn(`Received ${signal} again; still shutting down — waiting for the cleanup to remove the containers and networks. Send it once more to force-exit (that skips the cleanup).`);
8432
- return;
8433
- }
8434
- writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
8435
- exit(code);
8436
- };
8437
- return handler;
8438
- }
8439
-
8440
8474
  // src/assets/asset-source-path.ts
8441
8475
  function resolveAssetSourcePath(opts) {
8442
8476
  const { manifestDir, value, assetOutdir, field, subject, action, wrapError } = opts;
@@ -9670,6 +9704,46 @@ function execEnvForSecrets(passthrough) {
9670
9704
  return { env };
9671
9705
  }
9672
9706
 
9707
+ // src/local/container-start-guard.ts
9708
+ const NAME_CONFLICT = /is already (?:in use|used) by|Conflict\. The container name/;
9709
+ function createContainerStartGuard(options) {
9710
+ const remove = options.remove ?? removeContainer;
9711
+ let stopping = false;
9712
+ const inFlight = /* @__PURE__ */ new Set();
9713
+ const cancelled = () => new CdkLocalError("Shutting down: the container is not used.", options.cancelledCode);
9714
+ const stopAll = async () => {
9715
+ stopping = true;
9716
+ return (await Promise.all([...inFlight])).filter((id) => id !== void 0);
9717
+ };
9718
+ return {
9719
+ async run(start, name) {
9720
+ if (stopping) throw cancelled();
9721
+ const started = start();
9722
+ const outcome = started.then((id) => id, async (err) => {
9723
+ const message = err instanceof Error ? err.message : String(err);
9724
+ if (name !== void 0 && !NAME_CONFLICT.test(message)) try {
9725
+ await remove(name);
9726
+ } catch {}
9727
+ });
9728
+ inFlight.add(outcome);
9729
+ try {
9730
+ const id = await started;
9731
+ if (stopping) throw cancelled();
9732
+ return id;
9733
+ } catch (err) {
9734
+ await outcome;
9735
+ throw err;
9736
+ } finally {
9737
+ inFlight.delete(outcome);
9738
+ }
9739
+ },
9740
+ async stop() {
9741
+ return (await stopAll())[0];
9742
+ },
9743
+ stopAll
9744
+ };
9745
+ }
9746
+
9673
9747
  // src/local/debug-timeout.ts
9674
9748
  const DEBUG_FUNCTION_TIMEOUT_SEC = 36e3;
9675
9749
  function applyDebuggerEnv(dockerEnv, debugPort) {
@@ -10404,13 +10478,17 @@ async function localInvokeCommand(target, options, extraStateProviders) {
10404
10478
  let containerId;
10405
10479
  let stopLogs;
10406
10480
  let sigintHandler;
10481
+ let sigtermHandler;
10407
10482
  let profileCredsFile;
10483
+ const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_INVOKE_CANCELLED" });
10408
10484
  const cleanup = singleFlight(async () => {
10485
+ const pendingContainer = startGuard.stop();
10409
10486
  if (stopLogs) try {
10410
10487
  stopLogs();
10411
10488
  } catch (err) {
10412
10489
  getLogger().debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
10413
10490
  }
10491
+ containerId ??= await pendingContainer;
10414
10492
  if (containerId) try {
10415
10493
  await removeContainer(containerId);
10416
10494
  } catch (err) {
@@ -10456,6 +10534,17 @@ async function localInvokeCommand(target, options, extraStateProviders) {
10456
10534
  }, (err) => {
10457
10535
  getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
10458
10536
  });
10537
+ const onSignal = createShutdownSignalHandler({
10538
+ cleanup,
10539
+ stoppingMessage: (signal) => `Received ${signal}, removing the Lambda container...`,
10540
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
10541
+ info: (m) => logger.info(m),
10542
+ warn: (m) => logger.warn(m)
10543
+ });
10544
+ sigintHandler = () => onSignal("SIGINT");
10545
+ sigtermHandler = () => onSignal("SIGTERM");
10546
+ process.on("SIGINT", sigintHandler);
10547
+ process.on("SIGTERM", sigtermHandler);
10459
10548
  try {
10460
10549
  await activateWorkloadAwsWiring({
10461
10550
  ...options,
@@ -10523,29 +10612,26 @@ async function localInvokeCommand(target, options, extraStateProviders) {
10523
10612
  readOnly: true
10524
10613
  }] : imagePlan.extraMounts;
10525
10614
  const hostGatewayExtraHosts = await resolveHostGatewayExtraHosts();
10526
- containerId = await runDetached({
10527
- image: imagePlan.image,
10528
- mounts: imagePlan.mounts,
10615
+ const containerName = `${getEmbedConfig().resourceNamePrefix}-invoke-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
10616
+ const runPlan = imagePlan;
10617
+ containerId = await startGuard.run(() => runDetached({
10618
+ name: containerName,
10619
+ image: runPlan.image,
10620
+ mounts: runPlan.mounts,
10529
10621
  extraMounts: extraMountsWithProfile,
10530
10622
  env: dockerEnv,
10531
10623
  ...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) },
10532
10624
  ...hostGatewayExtraHosts.length > 0 && { extraHosts: hostGatewayExtraHosts },
10533
- cmd: imagePlan.cmd,
10625
+ cmd: runPlan.cmd,
10534
10626
  hostPort,
10535
10627
  host: containerHost,
10536
10628
  ...debugPort !== void 0 && { debugPort },
10537
- ...imagePlan.platform !== void 0 && { platform: imagePlan.platform },
10538
- ...imagePlan.entryPoint !== void 0 && { entryPoint: imagePlan.entryPoint },
10539
- ...imagePlan.workingDir !== void 0 && { workingDir: imagePlan.workingDir },
10540
- ...imagePlan.tmpfs !== void 0 && { tmpfs: imagePlan.tmpfs }
10541
- });
10629
+ ...runPlan.platform !== void 0 && { platform: runPlan.platform },
10630
+ ...runPlan.entryPoint !== void 0 && { entryPoint: runPlan.entryPoint },
10631
+ ...runPlan.workingDir !== void 0 && { workingDir: runPlan.workingDir },
10632
+ ...runPlan.tmpfs !== void 0 && { tmpfs: runPlan.tmpfs }
10633
+ }), containerName);
10542
10634
  stopLogs = streamLogs(containerId);
10543
- sigintHandler = () => {
10544
- cleanup().then(() => {
10545
- process.exit(130);
10546
- });
10547
- };
10548
- process.on("SIGINT", sigintHandler);
10549
10635
  await waitForRieReady(containerHost, hostPort, 5e3);
10550
10636
  const invokeTimeoutMs = rieInvokeTimeoutMs(lambda.timeoutSec, debugPort !== void 0);
10551
10637
  const result = await invokeRie(containerHost, hostPort, event, invokeTimeoutMs);
@@ -10553,8 +10639,9 @@ async function localInvokeCommand(target, options, extraStateProviders) {
10553
10639
  process.stdout.write(`${result.raw}\n`);
10554
10640
  if (options.responseFile) writeFileSync(options.responseFile, result.raw);
10555
10641
  } finally {
10556
- if (sigintHandler) process.off("SIGINT", sigintHandler);
10557
10642
  await cleanup();
10643
+ if (sigintHandler) process.off("SIGINT", sigintHandler);
10644
+ if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
10558
10645
  }
10559
10646
  }
10560
10647
  async function resolveImagePlan(lambda, options) {
@@ -13058,6 +13145,8 @@ function createContainerPool(specs, options) {
13058
13145
  const entries = /* @__PURE__ */ new Map();
13059
13146
  let disposed = false;
13060
13147
  const inFlightStarts = /* @__PURE__ */ new Set();
13148
+ const startGuard = createContainerStartGuard({ cancelledCode: "CONTAINER_POOL_DISPOSED" });
13149
+ const startedNotReady = /* @__PURE__ */ new Set();
13061
13150
  for (const logicalId of specs.keys()) entries.set(logicalId, emptyEntry(logicalId));
13062
13151
  function emptyEntry(logicalId) {
13063
13152
  return {
@@ -13088,7 +13177,7 @@ function createContainerPool(specs, options) {
13088
13177
  }] : optMount;
13089
13178
  const containerCodePath = resolveRuntimeCodeMountPath(spec.lambda.runtime);
13090
13179
  const image = resolveRuntimeImage(spec.lambda.runtime);
13091
- containerId = await runDetached({
13180
+ containerId = await startGuard.run(() => runDetached({
13092
13181
  image,
13093
13182
  platform: architectureToPlatform(spec.lambda.architecture),
13094
13183
  mounts: [{
@@ -13106,8 +13195,8 @@ function createContainerPool(specs, options) {
13106
13195
  ...spec.debugPort !== void 0 && { debugPort: spec.debugPort },
13107
13196
  ...spec.tmpfs !== void 0 && { tmpfs: spec.tmpfs },
13108
13197
  ...spec.extraHosts !== void 0 && { extraHosts: spec.extraHosts }
13109
- });
13110
- } else containerId = await runDetached({
13198
+ }), name);
13199
+ } else containerId = await startGuard.run(() => runDetached({
13111
13200
  image: spec.image,
13112
13201
  mounts: [],
13113
13202
  extraMounts: [...spec.rieMount ? [spec.rieMount] : [], ...spec.profileCredentialsFile ? [{
@@ -13127,14 +13216,17 @@ function createContainerPool(specs, options) {
13127
13216
  ...spec.debugPort !== void 0 && { debugPort: spec.debugPort },
13128
13217
  ...spec.tmpfs !== void 0 && { tmpfs: spec.tmpfs },
13129
13218
  ...spec.extraHosts !== void 0 && { extraHosts: spec.extraHosts }
13130
- });
13219
+ }), name);
13131
13220
  const stopLogStream = streamingEnabled ? streamLogs(containerId) : () => void 0;
13221
+ startedNotReady.add(containerId);
13132
13222
  try {
13133
13223
  await waitForRieReady(spec.containerHost, hostPort, 3e4);
13134
13224
  } catch (err) {
13135
13225
  stopLogStream();
13136
13226
  await removeContainer(containerId).catch(() => void 0);
13137
13227
  throw err;
13228
+ } finally {
13229
+ startedNotReady.delete(containerId);
13138
13230
  }
13139
13231
  return {
13140
13232
  logicalId: spec.lambda.logicalId,
@@ -13191,6 +13283,7 @@ function createContainerPool(specs, options) {
13191
13283
  }
13192
13284
  return {
13193
13285
  async acquire(logicalId) {
13286
+ if (disposed) throw new Error(`Container pool disposed; not starting ${displayIdent(logicalId)}.`);
13194
13287
  const entry = entries.get(logicalId);
13195
13288
  if (!entry) throw new Error(`containerPool.acquire: no spec registered for Lambda ${displayIdent(logicalId)}. This is a bug — every reachable route's Lambda should be registered at server boot.`);
13196
13289
  if (entry.warm.length > 0) {
@@ -13257,6 +13350,7 @@ function createContainerPool(specs, options) {
13257
13350
  return;
13258
13351
  }
13259
13352
  disposed = true;
13353
+ const pendingRuns = startGuard.stopAll();
13260
13354
  logger.debug("Disposing container pool");
13261
13355
  for (const entry of entries.values()) {
13262
13356
  if (entry.idleTimer) {
@@ -13318,10 +13412,14 @@ function createContainerPool(specs, options) {
13318
13412
  let timedOut = 0;
13319
13413
  for (const r of results) if (r.kind === "ok") allHandles.push(r.handle);
13320
13414
  else if (r.kind === "timeout") timedOut++;
13321
- if (timedOut > 0) logger.warn(`Container pool disposed with ${timedOut} in-flight start(s) still pending after ${drainTimeoutMs}ms; relying on docker --rm + the verify.sh sweep to clean up.`);
13415
+ if (timedOut > 0) logger.debug(`${timedOut} in-flight start(s) still pending after ${drainTimeoutMs}ms; removing them by id once their docker run returns.`);
13322
13416
  inFlightStarts.clear();
13323
13417
  }
13324
- await Promise.allSettled(allHandles.map((h) => tearDown(h)));
13418
+ const interruptedIds = [...await pendingRuns, ...startedNotReady];
13419
+ startedNotReady.clear();
13420
+ await Promise.allSettled([...allHandles.map((h) => tearDown(h)), ...interruptedIds.map((id) => removeContainer(id).catch((err) => {
13421
+ logger.warn(`Failed to remove container ${id}: ${err instanceof Error ? err.message : String(err)}. Continuing cleanup.`);
13422
+ }))]);
13325
13423
  entries.clear();
13326
13424
  }
13327
13425
  };
@@ -16255,6 +16353,21 @@ function formatServerListeningBanner(scheme, host, port, pathSuffix, label) {
16255
16353
  return `Server listening on ${scheme}://${formatAuthority(host, port)}${pathSuffix} (${label})\n`;
16256
16354
  }
16257
16355
  async function localStartApiCommand(targets, options, extraStateProviders) {
16356
+ let boot;
16357
+ try {
16358
+ await serveStartApi(targets, options, extraStateProviders, (b) => {
16359
+ boot = b;
16360
+ });
16361
+ } catch (err) {
16362
+ if (boot) {
16363
+ await boot.teardown().catch(() => void 0);
16364
+ if (boot.signalled()) await new Promise(() => void 0);
16365
+ boot.detachSignals();
16366
+ }
16367
+ throw err;
16368
+ }
16369
+ }
16370
+ async function serveStartApi(targets, options, extraStateProviders, registerBoot) {
16258
16371
  const logger = getLogger();
16259
16372
  if (options.verbose) logger.setLevel("debug");
16260
16373
  let apiFilters = [...targets];
@@ -16291,6 +16404,106 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16291
16404
  const inlineTmpDirs = /* @__PURE__ */ new Set();
16292
16405
  const layerTmpDirs = /* @__PURE__ */ new Set();
16293
16406
  let profileCredsFile;
16407
+ const servers = [];
16408
+ const wsServers = [];
16409
+ const bootPools = [];
16410
+ let watcher;
16411
+ let reloadQueue;
16412
+ let shuttingDown = false;
16413
+ let signalled = false;
16414
+ const runCleanup = singleFlight(async () => {
16415
+ shuttingDown = true;
16416
+ await stopWatchReloads({
16417
+ watcher,
16418
+ queue: reloadQueue,
16419
+ onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
16420
+ });
16421
+ await Promise.allSettled(wsServers.map(async (ws) => {
16422
+ try {
16423
+ await ws.attached.close();
16424
+ } catch (err) {
16425
+ logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16426
+ }
16427
+ }));
16428
+ await Promise.allSettled(servers.map(async ({ server, group }) => {
16429
+ try {
16430
+ await server.close();
16431
+ } catch (err) {
16432
+ logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
16433
+ }
16434
+ }));
16435
+ await Promise.allSettled(wsServers.map(async (ws) => {
16436
+ try {
16437
+ await ws.server.close();
16438
+ } catch (err) {
16439
+ logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16440
+ }
16441
+ }));
16442
+ await Promise.allSettled(servers.map(async ({ server, group }) => {
16443
+ try {
16444
+ await server.getServerState().pool.dispose();
16445
+ } catch (err) {
16446
+ logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
16447
+ }
16448
+ }));
16449
+ await Promise.allSettled(wsServers.map(async (ws) => {
16450
+ try {
16451
+ await ws.server.getServerState().pool.dispose();
16452
+ } catch (err) {
16453
+ logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16454
+ }
16455
+ }));
16456
+ await Promise.allSettled(bootPools.map(async (pool) => {
16457
+ try {
16458
+ await pool.dispose();
16459
+ } catch (err) {
16460
+ logger.warn(`pool.dispose() failed: ${err instanceof Error ? err.message : String(err)}`);
16461
+ }
16462
+ }));
16463
+ for (const dir of inlineTmpDirs) try {
16464
+ rmSync(dir, {
16465
+ recursive: true,
16466
+ force: true
16467
+ });
16468
+ } catch (err) {
16469
+ logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
16470
+ }
16471
+ for (const dir of layerTmpDirs) try {
16472
+ rmSync(dir, {
16473
+ recursive: true,
16474
+ force: true
16475
+ });
16476
+ } catch (err) {
16477
+ logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
16478
+ }
16479
+ if (profileCredsFile) try {
16480
+ await profileCredsFile.dispose();
16481
+ } catch (err) {
16482
+ logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
16483
+ }
16484
+ });
16485
+ const shutdown = createShutdownSignalHandler({
16486
+ cleanup: async () => {
16487
+ signalled = true;
16488
+ await runCleanup();
16489
+ },
16490
+ stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
16491
+ forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
16492
+ info: (m) => logger.info(m),
16493
+ warn: (m) => logger.warn(m)
16494
+ });
16495
+ const onSigint = () => shutdown("SIGINT");
16496
+ const onSigterm = () => shutdown("SIGTERM");
16497
+ process.on("SIGINT", onSigint);
16498
+ process.on("SIGTERM", onSigterm);
16499
+ registerBoot({
16500
+ teardown: runCleanup,
16501
+ detachSignals: () => {
16502
+ process.off("SIGINT", onSigint);
16503
+ process.off("SIGTERM", onSigterm);
16504
+ },
16505
+ signalled: () => signalled
16506
+ });
16294
16507
  const authorizerCache = createAuthorizerCache();
16295
16508
  const jwksCache = createJwksCache();
16296
16509
  const jwksWarnedAt = /* @__PURE__ */ new Map();
@@ -16412,6 +16625,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16412
16625
  };
16413
16626
  };
16414
16627
  const buildPool = (specs) => {
16628
+ if (shuttingDown) throw new CdkLocalError("Shutting down: no container pool is built.", "LOCAL_START_API_CANCELLED");
16415
16629
  const pool = createContainerPool(specs, {
16416
16630
  perLambdaConcurrency,
16417
16631
  skipPull: options.pull === false
@@ -16437,11 +16651,11 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16437
16651
  const mtlsConfig = resolveMtlsConfig(options);
16438
16652
  if (mtlsConfig) logger.info("mTLS enabled: client certificates required (chain check against --mtls-truststore at TLS handshake).");
16439
16653
  const initialGroups = groupRoutesByServer(initialMaterial.routes);
16440
- const servers = [];
16441
16654
  let nextPort = basePort;
16442
16655
  for (const group of initialGroups) {
16443
16656
  const groupSpecs = filterSpecsForGroup(group, initialMaterial.specs);
16444
16657
  const groupPool = buildPool(groupSpecs);
16658
+ bootPools.push(groupPool);
16445
16659
  const groupState = {
16446
16660
  routes: group.routes,
16447
16661
  pool: groupPool,
@@ -16450,6 +16664,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16450
16664
  if (options.warm) {
16451
16665
  logger.info(`Pre-warming ${groupSpecs.size} container(s) for ${group.displayName}...`);
16452
16666
  const handles = await Promise.allSettled([...groupSpecs.keys()].map((id) => groupPool.acquire(id)));
16667
+ if (shuttingDown) throw new CdkLocalError("Shutting down: the boot is not continued.", "LOCAL_START_API_CANCELLED");
16453
16668
  for (const result of handles) if (result.status === "fulfilled") groupPool.release(result.value);
16454
16669
  else logger.warn(`Pre-warm failed for one Lambda in ${group.displayName} (cold start cost will apply on first request): ${result.reason instanceof Error ? result.reason.message : String(result.reason)}`);
16455
16670
  }
@@ -16474,7 +16689,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16474
16689
  });
16475
16690
  if (basePort !== 0) nextPort += 1;
16476
16691
  }
16477
- const wsServers = [];
16478
16692
  const initialWsApis = initialMaterial.webSocketApis ?? [];
16479
16693
  warnUnsupportedWebSocketApis(initialWsApis, logger);
16480
16694
  if (initialWsApis.filter((api) => !api.unsupported).length > 0) {
@@ -16495,6 +16709,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16495
16709
  continue;
16496
16710
  }
16497
16711
  const wsPool = buildPool(wsSpecs);
16712
+ bootPools.push(wsPool);
16498
16713
  const wsState = {
16499
16714
  routes: [],
16500
16715
  pool: wsPool,
@@ -16562,8 +16777,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16562
16777
  process.stdout.write(formatServerListeningBanner(scheme, ws.server.host, ws.server.port, ws.apiPath, `${ws.api.apiLogicalId} (WebSocket API)`));
16563
16778
  }
16564
16779
  process.stdout.write("^C to stop and clean up containers.\n");
16565
- let watcher;
16566
- let reloadQueue;
16567
16780
  if (options.watch) {
16568
16781
  const watchRoot = process.cwd();
16569
16782
  const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
@@ -16593,82 +16806,6 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
16593
16806
  });
16594
16807
  logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
16595
16808
  }
16596
- const runCleanup = singleFlight(async () => {
16597
- await stopWatchReloads({
16598
- watcher,
16599
- queue: reloadQueue,
16600
- onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
16601
- });
16602
- await Promise.allSettled(wsServers.map(async (ws) => {
16603
- try {
16604
- await ws.attached.close();
16605
- } catch (err) {
16606
- logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16607
- }
16608
- }));
16609
- await Promise.allSettled(servers.map(async ({ server, group }) => {
16610
- try {
16611
- await server.close();
16612
- } catch (err) {
16613
- logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
16614
- }
16615
- }));
16616
- await Promise.allSettled(wsServers.map(async (ws) => {
16617
- try {
16618
- await ws.server.close();
16619
- } catch (err) {
16620
- logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16621
- }
16622
- }));
16623
- await Promise.allSettled(servers.map(async ({ server, group }) => {
16624
- try {
16625
- await server.getServerState().pool.dispose();
16626
- } catch (err) {
16627
- logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
16628
- }
16629
- }));
16630
- await Promise.allSettled(wsServers.map(async (ws) => {
16631
- try {
16632
- await ws.server.getServerState().pool.dispose();
16633
- } catch (err) {
16634
- logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
16635
- }
16636
- }));
16637
- for (const dir of inlineTmpDirs) try {
16638
- rmSync(dir, {
16639
- recursive: true,
16640
- force: true
16641
- });
16642
- } catch (err) {
16643
- logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
16644
- }
16645
- for (const dir of layerTmpDirs) try {
16646
- rmSync(dir, {
16647
- recursive: true,
16648
- force: true
16649
- });
16650
- } catch (err) {
16651
- logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
16652
- }
16653
- if (profileCredsFile) try {
16654
- await profileCredsFile.dispose();
16655
- } catch (err) {
16656
- logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
16657
- }
16658
- });
16659
- const shutdown = createShutdownSignalHandler({
16660
- cleanup: runCleanup,
16661
- stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
16662
- forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
16663
- info: (m) => logger.info(m),
16664
- warn: (m) => logger.warn(m)
16665
- });
16666
- process.on("SIGINT", () => {
16667
- shutdown("SIGINT");
16668
- });
16669
- process.on("SIGTERM", () => {
16670
- shutdown("SIGTERM");
16671
- });
16672
16809
  process.on("uncaughtException", (err) => {
16673
16810
  logger.error(`Uncaught exception: ${err instanceof Error ? err.stack ?? err.message : String(err)}`);
16674
16811
  shutdown("uncaughtException", 1);
@@ -18381,7 +18518,9 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
18381
18518
  let profileCredsFile;
18382
18519
  let stateProvider;
18383
18520
  let stopWatch;
18521
+ const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_INVOKE_AGENTCORE_CANCELLED" });
18384
18522
  const cleanup = singleFlight(async () => {
18523
+ const pendingContainer = startGuard.stop();
18385
18524
  if (stopWatch) await stopWatch();
18386
18525
  if (stateProvider) try {
18387
18526
  stateProvider.dispose();
@@ -18393,6 +18532,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
18393
18532
  } catch (err) {
18394
18533
  getLogger().debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
18395
18534
  }
18535
+ containerId ??= await pendingContainer;
18396
18536
  if (containerId) try {
18397
18537
  await removeContainer(containerId);
18398
18538
  } catch (err) {
@@ -18406,6 +18546,17 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
18406
18546
  }, (err) => {
18407
18547
  getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
18408
18548
  });
18549
+ const onSignal = createShutdownSignalHandler({
18550
+ cleanup,
18551
+ stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
18552
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
18553
+ info: (m) => logger.info(m),
18554
+ warn: (m) => logger.warn(m)
18555
+ });
18556
+ sigintHandler = () => onSignal("SIGINT");
18557
+ sigtermHandler = () => onSignal("SIGTERM");
18558
+ process.on("SIGINT", sigintHandler);
18559
+ process.on("SIGTERM", sigtermHandler);
18409
18560
  try {
18410
18561
  await activateWorkloadAwsWiring({
18411
18562
  ...options,
@@ -18485,7 +18636,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
18485
18636
  const containerPort = isMcp ? MCP_CONTAINER_PORT : isA2a ? A2A_CONTAINER_PORT : void 0;
18486
18637
  const containerPortLabel = isMcp ? `${MCP_CONTAINER_PORT}${MCP_PATH}` : isA2a ? `${A2A_CONTAINER_PORT}${"/"}` : "8080";
18487
18638
  logger.info(`Starting agent container (image=${image}, port=${hostPort} -> ${containerPortLabel})...`);
18488
- containerId = await runDetached({
18639
+ containerId = await startGuard.run(() => runDetached({
18489
18640
  image,
18490
18641
  mounts: [],
18491
18642
  env: dockerEnv,
@@ -18496,19 +18647,8 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
18496
18647
  name: containerName,
18497
18648
  ...containerPort !== void 0 && { containerPort },
18498
18649
  ...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
18499
- });
18650
+ }), containerName);
18500
18651
  stopLogs = streamLogs(containerId);
18501
- const onSignal = createShutdownSignalHandler({
18502
- cleanup,
18503
- stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
18504
- forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
18505
- info: (m) => logger.info(m),
18506
- warn: (m) => logger.warn(m)
18507
- });
18508
- sigintHandler = () => onSignal("SIGINT");
18509
- sigtermHandler = () => onSignal("SIGTERM");
18510
- process.on("SIGINT", sigintHandler);
18511
- process.on("SIGTERM", sigtermHandler);
18512
18652
  if (isMcp && mcpRequest) {
18513
18653
  logger.info(`MCP request: ${mcpRequest.method}`);
18514
18654
  const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, { requestTimeoutMs: options.timeout });
@@ -23430,8 +23570,32 @@ function createFrontDoorLambdaRunner(lambda, opts) {
23430
23570
  let stopLogStream;
23431
23571
  let starting;
23432
23572
  let stopped = false;
23573
+ const startGuard = createContainerStartGuard({ cancelledCode: "FRONT_DOOR_LAMBDA_STOPPED" });
23574
+ function removePlanTmpDirs(p) {
23575
+ if (p?.inlineTmpDir) try {
23576
+ rmSync(p.inlineTmpDir, {
23577
+ recursive: true,
23578
+ force: true
23579
+ });
23580
+ } catch (err) {
23581
+ logger.debug(`Failed to remove inline-code tmpdir ${p.inlineTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
23582
+ }
23583
+ if (p?.assetTmpDir) try {
23584
+ rmSync(p.assetTmpDir, {
23585
+ recursive: true,
23586
+ force: true
23587
+ });
23588
+ } catch (err) {
23589
+ logger.debug(`Failed to remove zip-asset tmpdir ${p.assetTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
23590
+ }
23591
+ }
23433
23592
  async function doStart() {
23434
- plan = lambda.kind === "zip" ? await resolveZipImagePlan(lambda, opts) : await resolveContainerImagePlan(lambda, opts);
23593
+ const resolved = lambda.kind === "zip" ? await resolveZipImagePlan(lambda, opts) : await resolveContainerImagePlan(lambda, opts);
23594
+ if (stopped) {
23595
+ removePlanTmpDirs(resolved);
23596
+ throw new Error("FrontDoorLambdaRunner stopped while starting");
23597
+ }
23598
+ plan = resolved;
23435
23599
  const port = await pickFreePort();
23436
23600
  hostPort = port;
23437
23601
  const name = `${getEmbedConfig().resourceNamePrefix}-alblambda-${lambda.logicalId}-${process.pid}-${Math.floor(Math.random() * 1e6)}`;
@@ -23444,20 +23608,20 @@ function createFrontDoorLambdaRunner(lambda, opts) {
23444
23608
  AWS_LAMBDA_LOG_STREAM_NAME: "local",
23445
23609
  ...forwardAwsEnv()
23446
23610
  };
23447
- logger.info(`Starting Lambda target container for ${lambda.logicalId} (image=${plan.image}, port=${port})...`);
23448
- const id = await runDetached({
23449
- image: plan.image,
23450
- mounts: plan.mounts,
23611
+ logger.info(`Starting Lambda target container for ${lambda.logicalId} (image=${resolved.image}, port=${port})...`);
23612
+ const id = await startGuard.run(() => runDetached({
23613
+ image: resolved.image,
23614
+ mounts: resolved.mounts,
23451
23615
  env,
23452
23616
  ...opts.sensitiveEnvKeys && opts.sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys: opts.sensitiveEnvKeys },
23453
- cmd: plan.cmd,
23617
+ cmd: resolved.cmd,
23454
23618
  hostPort: port,
23455
23619
  host: opts.containerHost,
23456
23620
  name,
23457
- ...plan.platform !== void 0 && { platform: plan.platform },
23458
- ...plan.entryPoint !== void 0 && { entryPoint: plan.entryPoint },
23459
- ...plan.workingDir !== void 0 && { workingDir: plan.workingDir }
23460
- });
23621
+ ...resolved.platform !== void 0 && { platform: resolved.platform },
23622
+ ...resolved.entryPoint !== void 0 && { entryPoint: resolved.entryPoint },
23623
+ ...resolved.workingDir !== void 0 && { workingDir: resolved.workingDir }
23624
+ }), name);
23461
23625
  containerId = id;
23462
23626
  stopLogStream = opts.streamLogs === false ? void 0 : streamLogs(id);
23463
23627
  try {
@@ -23486,11 +23650,14 @@ function createFrontDoorLambdaRunner(lambda, opts) {
23486
23650
  async stop() {
23487
23651
  if (stopped) return;
23488
23652
  stopped = true;
23653
+ const pendingContainer = startGuard.stop();
23489
23654
  try {
23490
23655
  stopLogStream?.();
23491
23656
  } catch (err) {
23492
23657
  logger.debug(`stopLogStream(${displayIdent(lambda.logicalId)}) failed: ${err instanceof Error ? err.message : String(err)}`);
23493
23658
  }
23659
+ const pendingId = await pendingContainer;
23660
+ containerId ??= pendingId;
23494
23661
  if (containerId) {
23495
23662
  try {
23496
23663
  await removeContainer(containerId);
@@ -23499,22 +23666,7 @@ function createFrontDoorLambdaRunner(lambda, opts) {
23499
23666
  }
23500
23667
  containerId = void 0;
23501
23668
  }
23502
- if (plan?.inlineTmpDir) try {
23503
- rmSync(plan.inlineTmpDir, {
23504
- recursive: true,
23505
- force: true
23506
- });
23507
- } catch (err) {
23508
- logger.debug(`Failed to remove inline-code tmpdir ${plan.inlineTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
23509
- }
23510
- if (plan?.assetTmpDir) try {
23511
- rmSync(plan.assetTmpDir, {
23512
- recursive: true,
23513
- force: true
23514
- });
23515
- } catch (err) {
23516
- logger.debug(`Failed to remove zip-asset tmpdir ${plan.assetTmpDir}: ${err instanceof Error ? err.message : String(err)}`);
23517
- }
23669
+ removePlanTmpDirs(plan);
23518
23670
  }
23519
23671
  };
23520
23672
  }
@@ -24141,7 +24293,14 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24141
24293
  let frontDoorLambdaRunners = [];
24142
24294
  let watcher;
24143
24295
  let reloadQueue;
24296
+ let sharedNetworkPending;
24297
+ let signalled = false;
24298
+ let stopping = false;
24299
+ const throwIfStopping = () => {
24300
+ if (stopping) throw new LocalStartServiceError("Shutting down: the boot is not continued.");
24301
+ };
24144
24302
  const cleanup = singleFlight(async () => {
24303
+ stopping = true;
24145
24304
  await stopWatchReloads({
24146
24305
  watcher,
24147
24306
  queue: reloadQueue,
@@ -24159,6 +24318,9 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24159
24318
  frontDoorServers = [];
24160
24319
  await Promise.allSettled(frontDoorLambdaRunners.map((r) => r.stop().catch((err) => getLogger().warn(`front-door Lambda target teardown failed: ${err instanceof Error ? err.message : String(err)}`))));
24161
24320
  frontDoorLambdaRunners = [];
24321
+ const pendingNetwork = await sharedNetworkPending;
24322
+ sharedNetwork ??= pendingNetwork;
24323
+ sharedNetworkPending = void 0;
24162
24324
  if (profileCredsFile) {
24163
24325
  try {
24164
24326
  await profileCredsFile.dispose();
@@ -24177,6 +24339,20 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24177
24339
  }
24178
24340
  }, (err) => getLogger().warn(`service cleanup failed: ${err instanceof Error ? err.message : String(err)}`));
24179
24341
  try {
24342
+ const onSignal = createShutdownSignalHandler({
24343
+ cleanup: async () => {
24344
+ signalled = true;
24345
+ await cleanup();
24346
+ },
24347
+ stoppingMessage: () => "Stopping service(s)...",
24348
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
24349
+ info: (m) => logger.info(m),
24350
+ warn: (m) => logger.warn(m)
24351
+ });
24352
+ sigintHandler = () => onSignal("SIGINT");
24353
+ sigtermHandler = () => onSignal("SIGTERM");
24354
+ process.on("SIGINT", sigintHandler);
24355
+ process.on("SIGTERM", sigtermHandler);
24180
24356
  await activateWorkloadAwsWiring(options);
24181
24357
  warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
24182
24358
  roleFlag: "--assume-role",
@@ -24227,16 +24403,20 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24227
24403
  const taskRoleMode = isTaskRoleInEffect(options);
24228
24404
  const sidecarCredentials = taskRoleMode ? void 0 : await resolveSharedSidecarCredentials(options);
24229
24405
  try {
24230
- sharedNetwork = await createSharedSvcNetwork({
24406
+ const creating = createSharedSvcNetwork({
24231
24407
  prefix: options.cluster,
24232
24408
  skipPull,
24233
24409
  cluster: options.cluster,
24234
24410
  ...taskRoleMode && { taskRole: true },
24235
24411
  ...sidecarCredentials !== void 0 && { credentials: sidecarCredentials }
24236
24412
  });
24413
+ sharedNetworkPending = creating.catch(() => void 0);
24414
+ sharedNetwork = await creating;
24415
+ sharedNetworkPending = void 0;
24237
24416
  } catch (err) {
24238
24417
  throw new LocalStartServiceError(`Failed to create shared service network: ${err instanceof Error ? err.message : String(err)}`);
24239
24418
  }
24419
+ throwIfStopping();
24240
24420
  if (options.profile && sidecarCredentials) profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);
24241
24421
  const discovery = {
24242
24422
  registry,
@@ -24244,22 +24424,13 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24244
24424
  sharedNetwork
24245
24425
  };
24246
24426
  if (frontDoor && frontDoor.listeners.length > 0) {
24247
- const built = await buildFrontDoor(frontDoor, options, logger, extraStateProviders);
24427
+ const built = await buildFrontDoor(frontDoor, options, logger, extraStateProviders, (r) => {
24428
+ frontDoorLambdaRunners.push(r);
24429
+ if (stopping) r.stop().catch(() => void 0);
24430
+ });
24248
24431
  frontDoorServers = built.servers;
24249
24432
  frontDoorByService = built.frontDoorByService;
24250
- frontDoorLambdaRunners = built.lambdaRunners;
24251
24433
  }
24252
- const onSignal = createShutdownSignalHandler({
24253
- cleanup,
24254
- stoppingMessage: () => "Stopping service(s)...",
24255
- forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
24256
- info: (m) => logger.info(m),
24257
- warn: (m) => logger.warn(m)
24258
- });
24259
- sigintHandler = () => onSignal("SIGINT");
24260
- sigtermHandler = () => onSignal("SIGTERM");
24261
- process.on("SIGINT", sigintHandler);
24262
- process.on("SIGTERM", sigtermHandler);
24263
24434
  const { tags: imageOverrideTags, overrides: imageOverrideMap } = await resolveAndBuildImageOverrides({
24264
24435
  perTarget: perTarget.map((pt) => pt.boot.target),
24265
24436
  stacks,
@@ -24267,7 +24438,10 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24267
24438
  extraStateProviders,
24268
24439
  logger
24269
24440
  });
24270
- for (const pt of perTarget) pt.controller = await bootOneTarget(pt.boot, pt.runState, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService.get(pt.boot.target), strategy.suppressLoadBalancerWarning === true, imageOverrideTags.get(pt.boot.target));
24441
+ for (const pt of perTarget) {
24442
+ throwIfStopping();
24443
+ pt.controller = await bootOneTarget(pt.boot, pt.runState, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService.get(pt.boot.target), strategy.suppressLoadBalancerWarning === true, imageOverrideTags.get(pt.boot.target));
24444
+ }
24271
24445
  if (perTarget.length > 0) {
24272
24446
  const summary = perTarget.map((pt) => `${pt.controller.service.serviceName} (${pt.controller.activeReplicaCount()} replica(s))`).join(", ");
24273
24447
  logger.info(`Service(s) running: ${summary}.`);
@@ -24331,6 +24505,7 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
24331
24505
  await new Promise(() => {});
24332
24506
  } finally {
24333
24507
  await cleanup();
24508
+ if (signalled) await new Promise(() => void 0);
24334
24509
  if (sigintHandler) process.off("SIGINT", sigintHandler);
24335
24510
  if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
24336
24511
  }
@@ -24692,7 +24867,7 @@ async function resolveAlbLambdaTargetEnv(plan, options, extraStateProviders) {
24692
24867
  for (const [logicalId, lambda] of lambdas) out.set(logicalId, await resolveLambdaContainerEnv(lambda, envOptions, profileCredentials, extraStateProviders));
24693
24868
  return out;
24694
24869
  }
24695
- async function buildFrontDoor(plan, options, logger, extraStateProviders) {
24870
+ async function buildFrontDoor(plan, options, logger, extraStateProviders, onLambdaRunner) {
24696
24871
  const containerHost = options.containerHost;
24697
24872
  const servers = [];
24698
24873
  const poolRegistry = /* @__PURE__ */ new Map();
@@ -24713,6 +24888,7 @@ async function buildFrontDoor(plan, options, logger, extraStateProviders) {
24713
24888
  ...containerEnv !== void 0 && containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
24714
24889
  });
24715
24890
  lambdaRegistry.set(t.lambda.logicalId, runner);
24891
+ onLambdaRunner?.(runner);
24716
24892
  }
24717
24893
  const boundRunner = runner;
24718
24894
  return {
@@ -29344,6 +29520,7 @@ async function bootLambdaUrlOrigins(distribution, stacks, opts) {
29344
29520
  containerEnv: containerEnv.env,
29345
29521
  ...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
29346
29522
  });
29523
+ opts.runnerSink?.push(runner);
29347
29524
  logger.info(`Booting Lambda Function URL origin container for ${functionLogicalId} (the backing Lambda runs locally via RIE)...`);
29348
29525
  await runner.start();
29349
29526
  } catch (err) {
@@ -29366,6 +29543,14 @@ async function drainWebFunctionServes(serves) {
29366
29543
  await Promise.all(batch.map((s) => s.teardown().catch(() => void 0)));
29367
29544
  }
29368
29545
  }
29546
+ async function drainLambdaRunners(runners) {
29547
+ let done = 0;
29548
+ while (done < runners.length) {
29549
+ const batch = runners.slice(done);
29550
+ done = runners.length;
29551
+ await Promise.all(batch.map((r) => r.stop().catch(() => void 0)));
29552
+ }
29553
+ }
29369
29554
  const WEB_FUNCTION_ORIGIN_READY_TIMEOUT_MS = 6e4;
29370
29555
  async function bootWebFunctionOrigins(distribution, stacks, opts) {
29371
29556
  const logger = getLogger();
@@ -29434,6 +29619,7 @@ async function bootLambdaEdgeFunctions(distribution, stacks, opts) {
29434
29619
  containerEnv: containerEnv.env,
29435
29620
  ...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
29436
29621
  });
29622
+ opts.runnerSink?.push(runner);
29437
29623
  logger.info(`Booting Lambda@Edge container for ${functionLogicalId} (the function runs locally via RIE)...`);
29438
29624
  await runner.start();
29439
29625
  runners.push(runner);
@@ -29610,12 +29796,13 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
29610
29796
  await attachKvsModules(initial.distribution, initial.stacks, options, profileCredentials, logger, extraStateProviders);
29611
29797
  const bootOpts = buildLambdaBootOptions(options, profileCredentials, extraStateProviders);
29612
29798
  const webFunctionServes = [];
29799
+ const bootRunners = [];
29613
29800
  let bootAborted = false;
29614
29801
  const onBootSignal = (signal) => {
29615
29802
  if (bootAborted) return;
29616
29803
  bootAborted = true;
29617
- logger.info(`Received ${signal} during start-up; removing the web function containers...`);
29618
- drainWebFunctionServes(webFunctionServes).then(() => process.exit(signalExitCode(signal)));
29804
+ logger.info(`Received ${signal} during start-up; removing the web function containers and the Lambda containers started so far...`);
29805
+ Promise.all([drainWebFunctionServes(webFunctionServes), drainLambdaRunners(bootRunners)]).then(() => process.exit(signalExitCode(signal)));
29619
29806
  };
29620
29807
  const bootSigint = () => onBootSignal("SIGINT");
29621
29808
  const bootSigterm = () => onBootSignal("SIGTERM");
@@ -29623,14 +29810,18 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
29623
29810
  process.off("SIGINT", bootSigint);
29624
29811
  process.off("SIGTERM", bootSigterm);
29625
29812
  };
29626
- if ([...initial.distribution.origins.values()].some((o) => o.kind === "web-function")) {
29627
- process.on("SIGINT", bootSigint);
29628
- process.on("SIGTERM", bootSigterm);
29629
- }
29630
- const { invokers: lambdaInvokers, runners: lambdaRunners } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, bootOpts);
29631
- const { invokers: edgeInvokers, runners: edgeRunners } = await bootLambdaEdgeFunctions(initial.distribution, initial.stacks, bootOpts);
29813
+ process.on("SIGINT", bootSigint);
29814
+ process.on("SIGTERM", bootSigterm);
29632
29815
  let server;
29633
29816
  try {
29817
+ const { invokers: lambdaInvokers } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, {
29818
+ ...bootOpts,
29819
+ runnerSink: bootRunners
29820
+ });
29821
+ const { invokers: edgeInvokers } = await bootLambdaEdgeFunctions(initial.distribution, initial.stacks, {
29822
+ ...bootOpts,
29823
+ runnerSink: bootRunners
29824
+ });
29634
29825
  const webFunctions = await bootWebFunctionOrigins(initial.distribution, initial.stacks, {
29635
29826
  ...bootOpts,
29636
29827
  sink: webFunctionServes
@@ -29651,7 +29842,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
29651
29842
  ...webFunctions.targets.size > 0 && { webFunctionOrigins: webFunctions.targets }
29652
29843
  });
29653
29844
  } catch (err) {
29654
- await Promise.all([...[...lambdaRunners, ...edgeRunners].map((r) => r.stop().catch(() => void 0)), ...webFunctionServes.map((s) => s.teardown().catch(() => void 0))]);
29845
+ await Promise.all([...bootRunners.map((r) => r.stop().catch(() => void 0)), ...webFunctionServes.map((s) => s.teardown().catch(() => void 0))]);
29655
29846
  if (bootAborted) return await new Promise(() => void 0);
29656
29847
  disarmBootSignals();
29657
29848
  throw err;
@@ -29703,7 +29894,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
29703
29894
  try {
29704
29895
  await server.close();
29705
29896
  } catch {}
29706
- await Promise.all([...[...lambdaRunners, ...edgeRunners].map((r) => r.stop().catch((err) => {
29897
+ await Promise.all([...bootRunners.map((r) => r.stop().catch((err) => {
29707
29898
  logger.debug(`Lambda runner stop failed: ${err instanceof Error ? err.message : String(err)}`);
29708
29899
  })), ...webFunctionServes.map((s) => s.teardown().catch((err) => {
29709
29900
  logger.debug(`Web function server teardown failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -30077,6 +30268,21 @@ function resolveAgentCoreServePlan(protocol) {
30077
30268
  };
30078
30269
  }
30079
30270
  async function localStartAgentCoreCommand(target, options, extraStateProviders, hostSynthesizer) {
30271
+ let boot;
30272
+ try {
30273
+ await serveAgentCore(target, options, extraStateProviders, hostSynthesizer, (b) => {
30274
+ boot = b;
30275
+ });
30276
+ } catch (err) {
30277
+ if (boot) {
30278
+ await boot.teardown().catch(() => void 0);
30279
+ if (boot.signalled()) await new Promise(() => void 0);
30280
+ boot.detachSignals();
30281
+ }
30282
+ throw err;
30283
+ }
30284
+ }
30285
+ async function serveAgentCore(target, options, extraStateProviders, hostSynthesizer, registerBoot) {
30080
30286
  const logger = getLogger();
30081
30287
  if (options.verbose) logger.setLevel("debug");
30082
30288
  let containerId;
@@ -30088,9 +30294,12 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
30088
30294
  let reloadQueue;
30089
30295
  let shuttingDown = false;
30090
30296
  let tornDown = false;
30091
- const teardown = async () => {
30092
- if (tornDown) return;
30297
+ const startGuard = createContainerStartGuard({ cancelledCode: "LOCAL_START_AGENTCORE_CANCELLED" });
30298
+ let teardownPromise;
30299
+ const teardown = () => teardownPromise ??= doTeardown();
30300
+ const doTeardown = async () => {
30093
30301
  tornDown = true;
30302
+ const pendingContainer = startGuard.stop();
30094
30303
  await stopWatchReloads({
30095
30304
  watcher,
30096
30305
  queue: reloadQueue,
@@ -30106,6 +30315,7 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
30106
30315
  } catch (err) {
30107
30316
  logger.debug(`streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`);
30108
30317
  }
30318
+ containerId ??= await pendingContainer;
30109
30319
  if (containerId) try {
30110
30320
  await removeContainer(containerId);
30111
30321
  } catch (err) {
@@ -30118,6 +30328,28 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
30118
30328
  await profileCredsFile.dispose();
30119
30329
  } catch {}
30120
30330
  };
30331
+ const shutdown = createShutdownSignalHandler({
30332
+ cleanup: async () => {
30333
+ shuttingDown = true;
30334
+ await teardown().catch(() => void 0);
30335
+ },
30336
+ stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
30337
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
30338
+ info: (m) => logger.info(m),
30339
+ warn: (m) => logger.warn(m)
30340
+ });
30341
+ const onSigint = () => shutdown("SIGINT");
30342
+ const onSigterm = () => shutdown("SIGTERM");
30343
+ process.on("SIGINT", onSigint);
30344
+ process.on("SIGTERM", onSigterm);
30345
+ registerBoot({
30346
+ teardown,
30347
+ detachSignals: () => {
30348
+ process.off("SIGINT", onSigint);
30349
+ process.off("SIGTERM", onSigterm);
30350
+ },
30351
+ signalled: () => shuttingDown
30352
+ });
30121
30353
  await activateWorkloadAwsWiring(options);
30122
30354
  warnIfEmulateRoleViaUnused(options.emulateRoleVia, {
30123
30355
  roleFlag: "--assume-role",
@@ -30171,31 +30403,20 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
30171
30403
  const containerHost = options.containerHost;
30172
30404
  const containerName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
30173
30405
  logger.info(`Starting agent container (image=${image}, port=${containerHostPort} -> ${plan.containerPortLabel})...`);
30174
- containerId = await runDetached({
30406
+ const bootPort = containerHostPort;
30407
+ containerId = await startGuard.run(() => runDetached({
30175
30408
  image,
30176
30409
  mounts: [],
30177
30410
  env: dockerEnv,
30178
30411
  cmd: [],
30179
- hostPort: containerHostPort,
30412
+ hostPort: bootPort,
30180
30413
  host: containerHost,
30181
30414
  platform: options.platform,
30182
30415
  name: containerName,
30183
30416
  ...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
30184
30417
  ...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
30185
- });
30418
+ }), containerName);
30186
30419
  stopLogs = streamLogs(containerId);
30187
- const shutdown = createShutdownSignalHandler({
30188
- cleanup: async () => {
30189
- shuttingDown = true;
30190
- await teardown().catch(() => void 0);
30191
- },
30192
- stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
30193
- forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
30194
- info: (m) => logger.info(m),
30195
- warn: (m) => logger.warn(m)
30196
- });
30197
- process.on("SIGINT", () => shutdown("SIGINT"));
30198
- process.on("SIGTERM", () => shutdown("SIGTERM"));
30199
30420
  try {
30200
30421
  if (plan.readyPath === void 0) await waitForAgentCorePing(containerHost, containerHostPort, options.timeout);
30201
30422
  else await waitForAgentCoreHttpReady(containerHost, containerHostPort, plan.readyPath, options.timeout);
@@ -37022,4 +37243,4 @@ function addStudioSpecificOptions(cmd) {
37022
37243
  }
37023
37244
 
37024
37245
  export { postHook as $, AGENTCORE_A2A_PROTOCOL as $a, probeHostGatewaySupport as $i, addImageOverrideOptions as $n, loopbackForwarderPlan as $o, resolveApiTargetSubset as $r, classifyS3Error as $t, microvmFidelityWarnings as A, createLocalStateProvider as Aa, translateLambdaResponse as Ai, stripCloudFrontImport as An, readEnvCallerCredentials as Ao, A2A_CONTAINER_PORT as Ar, readContainerLogTail as At, MICROVM_WS_BASE_PROTOCOL as B, resolveWatchConfig as Ba, ConnectionRegistry as Bi, createLocalStartAlbCommand as Bn, HOST_DEFAULT_CREDENTIALS_MISS_TTL_MS as Bo, AGENTCORE_SESSION_ID_HEADER as Br, parseWebFunctionBuildConfig as Bt, addListSpecificOptions as C, substituteAgainstState as Ca, attachAuthorizers as Ci, WEB_FUNCTION_REVISION_TYPE as Cn, resolveDynamicReferencesInEnv as Co, setShadowReadyTimeoutMs as Cr, parseKvsFileOverrides as Ct, buildMicrovmLambdaView as D, materializeLayerFromArn as Da, isFunctionUrlOacFronted as Di, compileCloudFrontFunction as Dn, SECOND_ASSUME_MESSAGE as Do, createLocalInvokeAgentCoreCommand as Dr, WEB_FUNCTION_CONTAINER_PORT as Dt, addStartMicrovmSpecificOptions as E, substituteEnvVarsFromStateAsync as Ea, buildCorsConfigFromCloudFrontChain as Ei, resolveWebFunctionTarget as En, awsEndpointOptions as Eo, addInvokeAgentCoreSpecificOptions as Er, RecentOutput as Et, microvmImageTag as F, resolveCfnRegion as Fa, pickResponseTemplate as Fi, findFileAssetForObjectKey as Fn, AUTH_OFF_PLACEHOLDER_CREDENTIALS as Fo, MCP_PROTOCOL_VERSION as Fr, buildNodeEntryFileStart as Ft, startMicrovmFrontDoor as G, discoverWebSocketApis as Ga, buildDisconnectEvent as Gi, addStartServiceSpecificOptions as Gn, collectHostEndpointOverrides as Go, SUPPORTED_CODE_RUNTIMES as Gr, readWebFunctionServiceConfig as Gt, PROXY_PORT_HEADER as H, countTargets as Ha, handleConnectionsRequest as Hi, resolveAlbTarget as Hn, applyWorkloadAwsWiringToEnv as Ho, waitForAgentCoreHttpReady as Hr, WEB_FUNCTION_HTTP_ENDPOINT_ENV as Ht, planMicrovmPorts as I, resolveCfnStackName as Ia, selectIntegrationResponse as Ii, isBucketDeploymentResource as In, CA_TRUST_ENV_KEYS as Io, mcpInvokeOnce as Ir, defaultWebFunctionPlatform as It, MICROVM_HOOK_PATH_PREFIX as J, parseSelectionExpressionPath as Ja, createFileWatcher as Ji, addRunTaskSpecificOptions as Jn, getActiveWorkloadAwsWiring as Jo, renderCodeDockerfile as Jr, idFromArn as Jt, stripMicrovmProxyHeaders as K, discoverWebSocketApisOrThrow as Ka, buildMessageEvent as Ki, createLocalStartServiceCommand as Kn, displayEndpointValue as Ko, buildAgentCoreCodeImage as Kr, webFunctionAssumeRole as Kt, readExposedPorts as L, CfnLocalStateProvider as La, tryParseStatus as Li, resolveBucketDeploymentObjectKey as Ln, DEFAULT_AWS_EMULATOR_URL as Lo, parseSseForJsonRpc as Lr, resolveWebFunctionRuntime as Lt, DEFAULT_TERMINATE_HOOK_TIMEOUT_MS as M, isCfnFlagPresent as Ma, buildHttpApiV2Event as Mi, createLocalFileKvsDataSource as Mn, resetWorkloadIdentity as Mo, a2aInvokeOnce as Mr, waitForWebFunctionReady as Mt, LocalMicrovm as N, rejectExplicitCfnStackWithMultipleStacks as Na, buildRestV1Event as Ni, createUnboundCloudFrontModule as Nn, workloadClientConfig as No, MCP_CONTAINER_PORT as Nr, watchContainerExit as Nt, createLocalStartMicrovmCommand as O, LocalStateSourceError as Oa, matchPreflight as Oi, runViewerRequest as On, assumedRoleRecorded as Oo, bridgeAgentCoreWs as Or, containerFailure as Ot, buildMicrovmImage as P, resolveCfnFallbackRegion as Pa, evaluateResponseParameters as Pi, bucketDeploymentSourceObjectKeys as Pn, workloadStsClientConfig as Po, MCP_PATH as Pr, WEB_FUNCTION_RUNTIMES as Pt, pollBuildHook as Q, resolveLambdaArnIntrinsic as Qa, HOST_GATEWAY_MIN_VERSION as Qi, addEcsAssumeRoleOptions as Qn, logMixedModeForWorkload as Qo, createWatchPredicates as Qr, resolveDeployedOriginBucket as Qt, setContainerPaused as R, collectSsmParameterRefs as Ra, VtlEvaluationError as Ri, addAlbSpecificOptions as Rn, EMULATOR_SCRUBBED_ENV_KEYS as Ro, AGENTCORE_SIGV4_SERVICE as Rr, supportedWebFunctionRuntimes as Rt, StudioEventBus as S, containsCrossStackIntrinsic as Sa, invokeTokenAuthorizer as Si, WEB_FUNCTION_ENDPOINT_TYPE as Sn, parseDynamicReference as So, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Sr, normalizeKvsFileKeys as St, formatTargetListing as T, substituteEnvVarsFromState as Ta, buildCorsConfigByApiId as Ti, WebFunctionResolutionError as Tn, addAwsEndpointOptions as To, attachContainerLogStreamer as Tr, resolveCloudFrontTarget as Tt, rewriteUpgradeResponseHead as U, listTargets as Ua, parseConnectionsPath as Ui, isApplicationLoadBalancer as Un, awsEmulatorEnvName as Uo, waitForAgentCorePing as Ur, buildWebFunctionLambdaView as Ut, MicrovmStateError as V, resolveSingleTarget as Va, buildMgmtEndpointEnvUrl as Vi, parseLbPortOverrides as Vn, activateWorkloadAwsWiring as Vo, invokeAgentCore as Vr, resolveWebFunctionArtifact as Vt, selectTargetPort as W, availableWebSocketApiIdentifiers as Wa, buildConnectEvent as Wi, resolveAlbFrontDoor as Wn, awsEmulatorSqsHostBlocks as Wo, downloadAndExtractS3Bundle as Wr, finalizeWebFunctionEnv as Wt, callRuntimeHook as X, discoverRoutes as Xa, createLocalInvokeCommand as Xi, MAX_TASKS_SUBNET_RANGE_CAP as Xn, getContainerJavaTruststorePath as Xo, addStartApiSpecificOptions as Xr, createDeployedKvsDataSource as Xt, MicrovmHookError as Y, webSocketApiMatchesIdentifier as Ya, addInvokeSpecificOptions as Yi, createLocalRunTaskCommand as Yn, getContainerCaBundlePath as Yo, toCmdArgv as Yr, resolveKvsModulesForDistribution as Yt, generateMicrovmId as Z, pickRefLogicalId as Za, HOST_DOCKER_INTERNAL_GATEWAY as Zi, addCommonEcsServiceOptions as Zn, javaTruststoreToolOptions as Zo, createLocalStartApiCommand as Zr, resolveDeployedKvsArnByName as Zt, filterStudioTargetGroups as _, resolveRuntimeFileExtension as _a, verifyJwtViaDiscovery as _i, pickKvsLogicalIdFromArn as _n, containsDynamicReference as _o, isLocalCdkAssetImage as _r, sqsEmulatorOriginOf as _s, attachAgentCoreWsBridge as _t, createLocalStudioCommand as a, buildLoopbackForwarderDockerArgs as aa, filterRoutesByApiIdentifiers as ai, serveLambdaUrlOrigin as an, pickAgentCoreCandidateStack as ao, resolveSharedSidecarCredentials as ar, resolveAwsEmulatorOption as as, disposeMicrovmCodeArtifact as at, renderStudioHtml as b, assertEcsTaskCommandsResolved as ba, evaluateCachedLambdaPolicy as bi, pickWebFunctionEndpointLogicalIdFromOrigin as bn, keysNotFromTemplate as bo, CloudMapRegistry as br, buildStsClientConfig as bs, addStartCloudFrontSpecificOptions as bt, startStudioProxy as c, ensureForwarderImage as ca, startApiServer as ci, buildEdgeRequestEvent as cn, formatStateRemedy as co, buildImageOverrideTag as cr, setActiveWorkloadAwsWiring as cs, resolveMicrovmImageTarget as ct, createStudioDispatcher as d, buildContainerImage as da, defaultCredentialsLoader as di, httpHeadersToEdge as dn, LocalInvokeBuildError as do, mergeForService as dr, MIXED_MODE_RESIGN_BODY_CAP_BYTES as ds, createLocalStartWebFunctionCommand as dt, resolveHostGatewayExtraHosts as ea, createAuthorizerCache as ei, createS3OriginReader as en, AGENTCORE_AGUI_PROTOCOL as eo, buildEcsImageResolutionContext$1 as er, mergeJavaToolOptions as es, runHookBody as et, filterStudioCustomResources as f, dockerRegistryEnv as fa, buildCognitoJwksUrl as fi, CLOUDFRONT_DISTRIBUTION_TYPE as fn, ambientDefaultRegion as fo, parseImageOverrideFlags as fr, REAL_SQS_QUEUE_URL as fs, addStartAgentCoreSpecificOptions as ft, annotatePinnedEcsTargets as g, resolveRuntimeCodeMountPath as ga, verifyJwtAuthorizer as gi, pickFunctionUrlLogicalIdFromOrigin as gn, DynamicReferenceResolver as go, imageOverrideKeyAliases as gr, rewriteSqsQueueUrlsInEnv as gs, startAgentCoreHttpServer as gt, annotateEcsTaskPinnedTargets as h, stripEcrCredentials as ha, verifyCognitoJwt as hi, isCloudFrontDistribution as hn, DynamicReferenceResolutionError as ho, describePinnedImageUri as hr, repointLocalSqsQueueUrlsInEnv as hs, selectServeInboundAuth as ht, coerceStopRequest as i, awaitLoopbackForwarderStatus as ia, filterRoutesByApiIdentifier as ii, serveFromStaticOrigin as in, AgentCoreResolutionError as io, resolveEcsAssumeRoleOption as ir, readProfileEndpointSettings as is, MicrovmResolutionError as it, readRunHookPayload as j, groupWorkloadsRoutedApart as ja, applyAuthorizerOverlay as ji, createCloudFrontModule as jn, recordAssumedRole as jo, A2A_PATH as jr, startWebFunctionContainer as jt, finalizeMicrovmEnv as k, UNNAMED_WORKLOAD as ka, matchRoute as ki, runViewerResponse as kn, deployAccountStsClientConfig as ko, invokeAgentCoreWs as kr, planWebFunctionContainer as kt, relayServeRequest as l, startLoopbackForwarder as la, resolveSelectionExpression as li, buildEdgeResponseEvent as ln, substituteImagePlaceholders as lo, canonicalizeImageOverrideKeys as lr, takeAwsEmulatorStateSourceHint as ls, s3KeyOfUri as lt, annotateAlbPinnedBackingServices as m, noImplicitEcrPullArgs as ma, createJwksCache as mi, extractKvsAssociations as mn, setAmbientDefaultRegion as mo, runImageOverrideBuilds as mr, realSqsHostnames as ms, buildAgentCoreServeAuthCheck as mt, coerceRunRequest as n, withWorkloadAwsWiring as na, buildStageMap as ni, startCloudFrontServer as nn, AGENTCORE_MCP_PROTOCOL as no, parseMaxTasks as nr, probeAwsEmulatorHealth as ns, MICROVM_DEFAULT_INGRESS_PORT as nt, resolveServeBaseUrl as o, buildNamespaceOwnerForwarderDockerArgs as oa, groupRoutesByServer as oi, applyEdgeRequestResult as on, resolveAgentCoreTarget as oo, runEcsServiceEmulator as or, resolveHostDefaultCredentials as os, readMicrovmImageConfig as ot, isCustomResourceLambdaTarget as p, isEcrRegistryConfigKey as pa, buildJwksUrlFromIssuer as pi, describeS3OriginDomain as pn, namedEnvAwsRegion as po, resolveImageOverrides as pr, isRealAwsHost as ps, createLocalStartAgentCoreCommand as pt, MAX_RUN_HOOK_PAYLOAD_BYTES as q, filterWebSocketApisByIdentifiers as qa, classifySourceChange as qi, serviceStrategy as qn, effectiveLoopbackPorts as qo, computeCodeImageTag as qr, webFunctionFidelityWarnings as qt, coerceServeRequest as r, LOOPBACK_FORWARDER_IMAGE as ra, availableApiIdentifiers as ri, resolveErrorResponseCandidates as rn, AGENTCORE_RUNTIME_TYPE as ro, parseRestartPolicy as rr, readEmulatorRunFiles as rs, MICROVM_IMAGE_TYPE as rt, createStudioServeManager as s, describeForwarderFailure as sa, readMtlsMaterialsFromDisk as si, applyEdgeResponseResult as sn, derivePseudoParametersFromRegion as so, ImageOverrideError as sr, resolveWorkloadAwsWiring as ss, resolveMicrovmCodeArtifact as st, addStudioSpecificOptions as t, attachLoopbackForwarder as ta, attachStageContext as ti, matchBehavior as tn, AGENTCORE_HTTP_PROTOCOL as to, ecsClusterOption as tr, parseAwsEndpoint as ts, waitForAppAnswer as tt, reinvoke as u, architectureToPlatform as ua, resolveServiceIntegrationParameters as ui, edgeHeadersToHttp as un, tryResolveImageFnJoin as uo, enforceImageOverrideOrphans as ur, writeCaBundleFile as us, addStartWebFunctionSpecificOptions as ut, startStudioServer as v, resolveRuntimeImage as va, buildMethodArn as vi, pickLambdaEdgeFunctionLogicalId as vn, deployedFillMayBeSecret as vo, listPinnedTargets as vr, buildJavaTrustStore as vs, startAgentCoreWsBridge as vt, createLocalListCommand as w, substituteAgainstStateAsync as wa, applyCorsResponseHeaders as wi, WEB_FUNCTION_TYPE as wn, withoutKeys as wo, getContainerNetworkIp as wr, parseOriginOverrides as wt, createStudioStore as x, assertEcsTaskImagesResolvable as xa, invokeRequestAuthorizer as xi, resolveCloudFrontDistribution as xn, keysOverriddenBy as xo, DEFAULT_SHADOW_READY_TIMEOUT_MS as xr, resolveProfileCredentials as xs, createLocalStartCloudFrontCommand as xt, toStudioTargetGroups as y, EcsTaskResolutionError as ya, computeRequestIdentityHash as yi, pickTargetFunctionLogicalId as yn, firstUsableRegion as yo, buildCloudMapIndex as yr, createMixedModeTlsMaterials as ys, LocalStartCloudFrontError as yt, MICROVM_CONTROL_PATH as z, resolveSsmParameters as za, bufferToBody as zi, albStrategy as zn, HOST_CA_TRUST_ENV_KEYS as zo, signAgentCoreInvocation as zr, disposeWebFunctionArtifact as zt };
37025
- //# sourceMappingURL=local-studio-CrP4kia1.js.map
37246
+ //# sourceMappingURL=local-studio-B0Wlk_VO.js.map