cdk-local 0.163.0 → 0.163.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.
@@ -10504,6 +10504,97 @@ function createFileWatcher(options) {
10504
10504
  } };
10505
10505
  }
10506
10506
 
10507
+ //#endregion
10508
+ //#region src/local/reload-queue.ts
10509
+ async function stopWatchReloads(args) {
10510
+ const closing = args.watcher ? args.watcher.close().catch((err) => args.onWatcherCloseError?.(err)) : Promise.resolve();
10511
+ const draining = args.queue ? args.queue.stop() : Promise.resolve();
10512
+ await closing;
10513
+ await draining;
10514
+ }
10515
+ function createReloadQueue(options) {
10516
+ const abort = new AbortController();
10517
+ let stopped = false;
10518
+ let current;
10519
+ let pending;
10520
+ let started = 0;
10521
+ let finished = 0;
10522
+ const runBatch = async (batch) => {
10523
+ try {
10524
+ await (async () => options.run(batch, abort.signal))();
10525
+ } catch (err) {
10526
+ try {
10527
+ options.onError?.(err);
10528
+ } catch {}
10529
+ }
10530
+ };
10531
+ const start = (paths) => {
10532
+ (async () => {
10533
+ let next = paths;
10534
+ while (next) {
10535
+ started += 1;
10536
+ current = runBatch(next);
10537
+ await current;
10538
+ finished += 1;
10539
+ next = !stopped && pending ? [...pending] : void 0;
10540
+ pending = void 0;
10541
+ }
10542
+ current = void 0;
10543
+ })();
10544
+ };
10545
+ const idle = async () => {
10546
+ const target = started + (pending ? 1 : 0);
10547
+ while (current && finished < target) await current;
10548
+ };
10549
+ return {
10550
+ schedule(changedPaths) {
10551
+ if (stopped) return;
10552
+ if (!current) {
10553
+ start(changedPaths);
10554
+ return;
10555
+ }
10556
+ const wasPending = pending !== void 0;
10557
+ pending ??= /* @__PURE__ */ new Set();
10558
+ for (const p of changedPaths) pending.add(p);
10559
+ if (wasPending) options.onCoalesced?.(pending.size);
10560
+ },
10561
+ async stop() {
10562
+ if (!stopped) {
10563
+ stopped = true;
10564
+ pending = void 0;
10565
+ abort.abort();
10566
+ }
10567
+ await idle();
10568
+ },
10569
+ idle,
10570
+ get stopped() {
10571
+ return stopped;
10572
+ }
10573
+ };
10574
+ }
10575
+
10576
+ //#endregion
10577
+ //#region src/utils/shutdown-signal.ts
10578
+ function createShutdownSignalHandler(options) {
10579
+ const exit = options.exit ?? ((code) => process.exit(code));
10580
+ const writeStderr = options.writeStderr ?? ((text) => void process.stderr.write(text));
10581
+ let count = 0;
10582
+ return (signal, exitCode) => {
10583
+ count += 1;
10584
+ if (count === 1) {
10585
+ options.info(options.stoppingMessage(signal));
10586
+ options.cleanup().then(() => exit(exitCode));
10587
+ return;
10588
+ }
10589
+ if (count === 2) {
10590
+ 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).`);
10591
+ return;
10592
+ }
10593
+ writeStderr(`Force-exit on repeated ${signal}; container cleanup skipped. ${options.forceExitHint}\n`);
10594
+ exit(130);
10595
+ };
10596
+ }
10597
+
10507
10598
  //#endregion
10508
10599
  //#region src/local/authorizer-cache.ts
10509
10600
  function createAuthorizerCache(opts = {}) {
@@ -10897,7 +10988,7 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
10897
10988
  }
10898
10989
  process.stdout.write("^C to stop and clean up containers.\n");
10899
10990
  let watcher;
10900
- let reloadChain = Promise.resolve();
10991
+ let reloadQueue;
10901
10992
  if (options.watch) {
10902
10993
  const watchRoot = process.cwd();
10903
10994
  const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
@@ -10905,105 +10996,97 @@ async function localStartApiCommand(targets, options, extraStateProviders) {
10905
10996
  output: options.output,
10906
10997
  watchConfig: resolveWatchConfig()
10907
10998
  });
10999
+ const queue = createReloadQueue({
11000
+ run: (_changedPaths, signal) => reloadAllServers({
11001
+ synthesizeAndBuild,
11002
+ servers,
11003
+ buildPool,
11004
+ logger,
11005
+ signal
11006
+ }),
11007
+ onError: (err) => logger.warn(`Reload failed: ${err instanceof Error ? err.message : String(err)}`)
11008
+ });
11009
+ reloadQueue = queue;
10908
11010
  watcher = createFileWatcher({
10909
11011
  paths: [watchRoot],
10910
11012
  ignored,
10911
11013
  shouldTrigger,
10912
- onChange: () => {
11014
+ onChange: (changedPaths) => {
10913
11015
  logger.info("Detected source change; reloading...");
10914
- reloadChain = reloadChain.then(() => reloadAllServers({
10915
- synthesizeAndBuild,
10916
- servers,
10917
- buildPool,
10918
- logger
10919
- })).catch(() => void 0);
11016
+ queue.schedule(changedPaths);
10920
11017
  }
10921
11018
  });
10922
11019
  logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
10923
11020
  }
10924
- let shutdownStarted = false;
10925
- let firstSignal;
10926
- let firstExitCode = 0;
10927
- let forceExitArmed = false;
10928
- const runCleanup = singleFlight(async () => {
10929
- logger.info(`Received ${firstSignal}, shutting down...`);
10930
- if (watcher) try {
10931
- await watcher.close();
10932
- } catch (err) {
10933
- logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`);
10934
- }
10935
- await Promise.allSettled(wsServers.map(async (ws) => {
10936
- try {
10937
- await ws.attached.close();
10938
- } catch (err) {
10939
- logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
10940
- }
10941
- }));
10942
- await Promise.allSettled(servers.map(async ({ server, group }) => {
10943
- try {
10944
- await server.close();
10945
- } catch (err) {
10946
- logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
10947
- }
10948
- }));
10949
- await Promise.allSettled(wsServers.map(async (ws) => {
10950
- try {
10951
- await ws.server.close();
11021
+ const shutdown = createShutdownSignalHandler({
11022
+ cleanup: singleFlight(async () => {
11023
+ await stopWatchReloads({
11024
+ watcher,
11025
+ queue: reloadQueue,
11026
+ onWatcherCloseError: (err) => logger.warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
11027
+ });
11028
+ await Promise.allSettled(wsServers.map(async (ws) => {
11029
+ try {
11030
+ await ws.attached.close();
11031
+ } catch (err) {
11032
+ logger.warn(`WebSocket close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
11033
+ }
11034
+ }));
11035
+ await Promise.allSettled(servers.map(async ({ server, group }) => {
11036
+ try {
11037
+ await server.close();
11038
+ } catch (err) {
11039
+ logger.warn(`server.close() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
11040
+ }
11041
+ }));
11042
+ await Promise.allSettled(wsServers.map(async (ws) => {
11043
+ try {
11044
+ await ws.server.close();
11045
+ } catch (err) {
11046
+ logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
11047
+ }
11048
+ }));
11049
+ await Promise.allSettled(servers.map(async ({ server, group }) => {
11050
+ try {
11051
+ await server.getServerState().pool.dispose();
11052
+ } catch (err) {
11053
+ logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
11054
+ }
11055
+ }));
11056
+ await Promise.allSettled(wsServers.map(async (ws) => {
11057
+ try {
11058
+ await ws.server.getServerState().pool.dispose();
11059
+ } catch (err) {
11060
+ logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
11061
+ }
11062
+ }));
11063
+ for (const dir of inlineTmpDirs) try {
11064
+ rmSync(dir, {
11065
+ recursive: true,
11066
+ force: true
11067
+ });
10952
11068
  } catch (err) {
10953
- logger.warn(`WebSocket server.close() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
11069
+ logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
10954
11070
  }
10955
- }));
10956
- await Promise.allSettled(servers.map(async ({ server, group }) => {
10957
- try {
10958
- await server.getServerState().pool.dispose();
11071
+ for (const dir of layerTmpDirs) try {
11072
+ rmSync(dir, {
11073
+ recursive: true,
11074
+ force: true
11075
+ });
10959
11076
  } catch (err) {
10960
- logger.warn(`pool.dispose() failed for ${group.displayName}: ${err instanceof Error ? err.message : String(err)}`);
11077
+ logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
10961
11078
  }
10962
- }));
10963
- await Promise.allSettled(wsServers.map(async (ws) => {
10964
- try {
10965
- await ws.server.getServerState().pool.dispose();
11079
+ if (profileCredsFile) try {
11080
+ await profileCredsFile.dispose();
10966
11081
  } catch (err) {
10967
- logger.warn(`WebSocket pool.dispose() failed for ${ws.api.apiLogicalId}: ${err instanceof Error ? err.message : String(err)}`);
11082
+ logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
10968
11083
  }
10969
- }));
10970
- for (const dir of inlineTmpDirs) try {
10971
- rmSync(dir, {
10972
- recursive: true,
10973
- force: true
10974
- });
10975
- } catch (err) {
10976
- logger.warn(`Failed to remove inline-code tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
10977
- }
10978
- for (const dir of layerTmpDirs) try {
10979
- rmSync(dir, {
10980
- recursive: true,
10981
- force: true
10982
- });
10983
- } catch (err) {
10984
- logger.warn(`Failed to remove merged-layers tmpdir ${dir}: ${err instanceof Error ? err.message : String(err)}`);
10985
- }
10986
- if (profileCredsFile) try {
10987
- await profileCredsFile.dispose();
10988
- } catch (err) {
10989
- logger.warn(`Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${err instanceof Error ? err.message : String(err)}`);
10990
- }
11084
+ }),
11085
+ stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
11086
+ forceExitHint: `Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`,
11087
+ info: (m) => logger.info(m),
11088
+ warn: (m) => logger.warn(m)
10991
11089
  });
10992
- const shutdown = async (signal, exitCode) => {
10993
- if (shutdownStarted) {
10994
- if (!forceExitArmed) {
10995
- forceExitArmed = true;
10996
- logger.warn(`Received second ${signal}; force-exiting. Orphan containers may remain — run 'docker ps --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker rm -f' to clean up.`);
10997
- process.exit(130);
10998
- }
10999
- return;
11000
- }
11001
- shutdownStarted = true;
11002
- firstSignal = signal;
11003
- firstExitCode = exitCode;
11004
- await runCleanup();
11005
- process.exit(firstExitCode);
11006
- };
11007
11090
  process.on("SIGINT", () => {
11008
11091
  shutdown("SIGINT", 130);
11009
11092
  });
@@ -11721,7 +11804,7 @@ function warnSsrfRiskyIntegrations(routes, logger) {
11721
11804
  }
11722
11805
  }
11723
11806
  async function reloadAllServers(args) {
11724
- const { synthesizeAndBuild, servers, buildPool, logger } = args;
11807
+ const { synthesizeAndBuild, servers, buildPool, logger, signal } = args;
11725
11808
  let material;
11726
11809
  try {
11727
11810
  material = await synthesizeAndBuild();
@@ -11729,6 +11812,10 @@ async function reloadAllServers(args) {
11729
11812
  logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
11730
11813
  return;
11731
11814
  }
11815
+ if (signal?.aborted) {
11816
+ logger.info("Reload cancelled: shutting down.");
11817
+ return;
11818
+ }
11732
11819
  const newGroups = groupRoutesByServer(material.routes);
11733
11820
  const newByKey = new Map(newGroups.map((g) => [g.serverKey, g]));
11734
11821
  const oldKeys = new Set(servers.map((s) => s.group.serverKey));
@@ -13423,9 +13510,12 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
13423
13510
  let containerId;
13424
13511
  let stopLogs;
13425
13512
  let sigintHandler;
13513
+ let sigtermHandler;
13426
13514
  let profileCredsFile;
13427
13515
  let stateProvider;
13516
+ let stopWatch;
13428
13517
  const cleanup = singleFlight(async () => {
13518
+ if (stopWatch) await stopWatch();
13429
13519
  if (stateProvider) try {
13430
13520
  stateProvider.dispose();
13431
13521
  } catch (err) {
@@ -13530,10 +13620,17 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
13530
13620
  ...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
13531
13621
  });
13532
13622
  stopLogs = streamLogs(containerId);
13533
- sigintHandler = () => {
13534
- cleanup().then(() => process.exit(130));
13535
- };
13623
+ const onSignal = createShutdownSignalHandler({
13624
+ cleanup,
13625
+ stoppingMessage: (signal) => `Received ${signal}, removing the agent container...`,
13626
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
13627
+ info: (m) => logger.info(m),
13628
+ warn: (m) => logger.warn(m)
13629
+ });
13630
+ sigintHandler = () => onSignal("SIGINT", 130);
13631
+ sigtermHandler = () => onSignal("SIGTERM", 143);
13536
13632
  process.on("SIGINT", sigintHandler);
13633
+ process.on("SIGTERM", sigtermHandler);
13537
13634
  if (isMcp && mcpRequest) {
13538
13635
  logger.info(`MCP request: ${mcpRequest.method}`);
13539
13636
  const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, { requestTimeoutMs: options.timeout });
@@ -13560,7 +13657,10 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
13560
13657
  synthOpts,
13561
13658
  stacks,
13562
13659
  ...authorization && { authorization },
13563
- rebuild: async () => {
13660
+ registerStop: (stop) => {
13661
+ stopWatch = stop;
13662
+ },
13663
+ rebuild: async (signal) => {
13564
13664
  if (stopLogs) {
13565
13665
  try {
13566
13666
  stopLogs();
@@ -13581,6 +13681,7 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
13581
13681
  await resolveFromS3BucketIntrinsic(newResolved, stateProvider, newLoaded, newImageContext);
13582
13682
  const newImage = await resolveAgentCoreImage(newResolved, options, newLoaded, stateProvider);
13583
13683
  const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(newResolved, options, profileCredentials, profileCredsFile, stateProvider, newLoaded, newImageContext);
13684
+ if (signal?.aborted) throw new CdkLocalError("Reload cancelled: shutting down.", "LOCAL_INVOKE_AGENTCORE_WATCH_CANCELLED");
13584
13685
  const newHostPort = await pickFreePort();
13585
13686
  const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
13586
13687
  logger.info(`Reload: starting agent container (image=${newImage}, port=${newHostPort} -> 8080)...`);
@@ -13637,8 +13738,9 @@ async function localInvokeAgentCoreCommand(target, options, extraStateProviders)
13637
13738
  emitResult(result);
13638
13739
  }
13639
13740
  } finally {
13640
- if (sigintHandler) process.off("SIGINT", sigintHandler);
13641
13741
  await cleanup();
13742
+ if (sigintHandler) process.off("SIGINT", sigintHandler);
13743
+ if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
13642
13744
  }
13643
13745
  }
13644
13746
  async function resolveInboundAuthorization(resolved, options) {
@@ -14190,7 +14292,7 @@ async function runAgentCoreWatchLoop(args) {
14190
14292
  const waitForPing = args.__waitForPing ?? waitForAgentCorePing;
14191
14293
  let currentHostPort = args.hostPort;
14192
14294
  let currentStacks = args.stacks;
14193
- let reloadChain = Promise.resolve();
14295
+ let reloadQueue;
14194
14296
  let currentAbort;
14195
14297
  let pendingReload = false;
14196
14298
  let reloadFailed = false;
@@ -14211,8 +14313,8 @@ async function runAgentCoreWatchLoop(args) {
14211
14313
  });
14212
14314
  const cdkOutDir = args.options.output;
14213
14315
  const assetLoader = new AssetManifestLoader();
14214
- const watcher = watcherFactory((changedPaths) => {
14215
- reloadChain = reloadChain.then(async () => {
14316
+ reloadQueue = createReloadQueue({
14317
+ run: async (changedPaths, signal) => {
14216
14318
  let verdict = {
14217
14319
  kind: "rebuild",
14218
14320
  reason: "classifier not consulted"
@@ -14247,6 +14349,7 @@ async function runAgentCoreWatchLoop(args) {
14247
14349
  reason: "classifier context unavailable; falling back to rebuild"
14248
14350
  };
14249
14351
  }
14352
+ if (signal.aborted) return;
14250
14353
  pendingReload = true;
14251
14354
  logger.warn("cdkl invoke-agentcore --watch: source change detected; closing the active /ws socket so the client can reconnect to the rebuilt container.");
14252
14355
  currentAbort?.abort();
@@ -14256,20 +14359,32 @@ async function runAgentCoreWatchLoop(args) {
14256
14359
  currentStacks = newStacks;
14257
14360
  logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
14258
14361
  } else {
14259
- const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild();
14362
+ const { containerId: _newId, hostPort: newHostPort, stacks: newStacks } = await args.rebuild(signal);
14260
14363
  currentHostPort = newHostPort;
14261
14364
  currentStacks = newStacks;
14262
14365
  logger.info(`Reload: rebuilt the agent container.`);
14263
14366
  }
14264
14367
  } catch (err) {
14368
+ if (signal.aborted) {
14369
+ logger.info("Reload cancelled: shutting down.");
14370
+ reloadFailed = true;
14371
+ currentAbort?.abort();
14372
+ return;
14373
+ }
14265
14374
  logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The previous container may already be torn down; exiting --watch loop. Re-run cdkl invoke-agentcore --watch to recover.`);
14266
14375
  reloadFailed = true;
14267
14376
  currentAbort?.abort();
14268
14377
  }
14269
- }).catch((err) => {
14270
- logger.error(`Reload chain threw: ${err instanceof Error ? err.message : String(err)}`);
14271
- });
14378
+ },
14379
+ onError: (err) => logger.error(`Reload chain threw: ${err instanceof Error ? err.message : String(err)}`)
14272
14380
  });
14381
+ const queue = reloadQueue;
14382
+ const watcher = watcherFactory((changedPaths) => queue.schedule(changedPaths));
14383
+ args.registerStop?.(() => stopWatchReloads({
14384
+ watcher,
14385
+ queue,
14386
+ onWatcherCloseError: (err) => logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
14387
+ }));
14273
14388
  try {
14274
14389
  let firstIteration = true;
14275
14390
  while (true) {
@@ -14298,17 +14413,17 @@ async function runAgentCoreWatchLoop(args) {
14298
14413
  currentAbort = void 0;
14299
14414
  }
14300
14415
  if (!pendingReload) {
14301
- await reloadChain.catch(() => void 0);
14416
+ await queue.idle();
14302
14417
  if (!pendingReload) break;
14303
14418
  }
14304
- await reloadChain.catch(() => void 0);
14419
+ await queue.idle();
14305
14420
  }
14306
14421
  } finally {
14307
- try {
14308
- await watcher.close();
14309
- } catch (err) {
14310
- logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`);
14311
- }
14422
+ await stopWatchReloads({
14423
+ watcher,
14424
+ queue,
14425
+ onWatcherCloseError: (err) => logger.warn(`Watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
14426
+ });
14312
14427
  }
14313
14428
  }
14314
14429
  const execFileAsync$6 = promisify(execFile);
@@ -15135,7 +15250,8 @@ async function runEcsTask(task, options, state) {
15135
15250
  ...mergedAddHostFlags.length > 0 ? { addHostFlags: mergedAddHostFlags } : {},
15136
15251
  ...(options.networkAliasesByContainer?.get(container.name)?.length ?? 0) > 0 ? { networkAliases: options.networkAliasesByContainer.get(container.name) } : {},
15137
15252
  ...options.containerNameAliasOmitted?.has(container.name) ? { omitContainerNameAlias: true } : {},
15138
- ...options.profileCredentialsFile && { profileCredentialsFile: options.profileCredentialsFile }
15253
+ ...options.profileCredentialsFile && { profileCredentialsFile: options.profileCredentialsFile },
15254
+ ...options.defaultCredentials && { defaultCredentials: options.defaultCredentials }
15139
15255
  });
15140
15256
  dockerCmds.set(container.name, {
15141
15257
  args: built.args,
@@ -15473,6 +15589,16 @@ async function resolvePrivilegedHostPortRemaps(opts) {
15473
15589
  }
15474
15590
  return remaps;
15475
15591
  }
15592
+ const OWN_CREDENTIAL_SOURCE_KEYS = [
15593
+ "AWS_ACCESS_KEY_ID",
15594
+ "AWS_SECRET_ACCESS_KEY",
15595
+ "AWS_SESSION_TOKEN",
15596
+ "AWS_PROFILE",
15597
+ "AWS_SHARED_CREDENTIALS_FILE",
15598
+ "AWS_WEB_IDENTITY_TOKEN_FILE",
15599
+ "AWS_CONTAINER_CREDENTIALS_FULL_URI",
15600
+ "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
15601
+ ];
15476
15602
  function buildDockerRunArgs(opts) {
15477
15603
  const { task, container, image, network, volumeByName, secrets, containerHost, roleArn } = opts;
15478
15604
  const args = ["run", "-d"];
@@ -15581,6 +15707,13 @@ function buildDockerRunArgs(opts) {
15581
15707
  applyEnvOverrideMap(finalEnv, overrides["Parameters"]);
15582
15708
  applyEnvOverrideMap(finalEnv, overrides[container.name]);
15583
15709
  }
15710
+ const defaultCredentials = opts.defaultCredentials;
15711
+ const optedOut = [overrides?.["Parameters"], overrides?.[container.name]].some((m) => m !== void 0 && Object.hasOwn(m, "AWS_ACCESS_KEY_ID") && m["AWS_ACCESS_KEY_ID"] === null);
15712
+ if (defaultCredentials && wiring?.mode !== "emulator" && !optedOut && !OWN_CREDENTIAL_SOURCE_KEYS.some((k) => finalEnv[k])) {
15713
+ finalEnv["AWS_ACCESS_KEY_ID"] = defaultCredentials.accessKeyId;
15714
+ finalEnv["AWS_SECRET_ACCESS_KEY"] = defaultCredentials.secretAccessKey;
15715
+ if (defaultCredentials.sessionToken) finalEnv["AWS_SESSION_TOKEN"] = defaultCredentials.sessionToken;
15716
+ }
15584
15717
  if (wiring) finalEnv = applyWorkloadAwsWiringToEnv(finalEnv, wiring.mode === "emulator" ? wiring : {
15585
15718
  ...wiring,
15586
15719
  env: {}
@@ -19011,24 +19144,21 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
19011
19144
  setShadowReadyTimeoutMs(resolveShadowReadyTimeoutMs(options, getEmbedConfig().envPrefix));
19012
19145
  let perTarget = [];
19013
19146
  let sigintHandler;
19014
- let sigintCount = 0;
19147
+ let sigtermHandler;
19015
19148
  let sharedNetwork;
19016
19149
  let profileCredsFile;
19017
19150
  let frontDoorServers = [];
19018
19151
  let frontDoorByService = /* @__PURE__ */ new Map();
19019
19152
  let frontDoorLambdaRunners = [];
19020
19153
  let watcher;
19021
- let reloadChain = Promise.resolve();
19154
+ let reloadQueue;
19022
19155
  const cleanup = singleFlight(async () => {
19023
- if (watcher) {
19024
- try {
19025
- await watcher.close();
19026
- } catch (err) {
19027
- getLogger().warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`);
19028
- }
19029
- watcher = void 0;
19030
- }
19031
- await reloadChain.catch(() => void 0);
19156
+ await stopWatchReloads({
19157
+ watcher,
19158
+ queue: reloadQueue,
19159
+ onWatcherCloseError: (err) => getLogger().warn(`watcher.close() failed: ${err instanceof Error ? err.message : String(err)}`)
19160
+ });
19161
+ watcher = void 0;
19032
19162
  await Promise.allSettled(perTarget.map(async (pt) => {
19033
19163
  if (pt.controller) await pt.controller.shutdown();
19034
19164
  else {
@@ -19126,17 +19256,17 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
19126
19256
  frontDoorByService = built.frontDoorByService;
19127
19257
  frontDoorLambdaRunners = built.lambdaRunners;
19128
19258
  }
19129
- sigintHandler = () => {
19130
- sigintCount += 1;
19131
- if (sigintCount >= 2) {
19132
- process.stderr.write("Force-exit on second ^C; container cleanup skipped.\n");
19133
- process.exit(130);
19134
- }
19135
- logger.info("Stopping service(s)...");
19136
- cleanup().then(() => process.exit(130));
19137
- };
19259
+ const onSignal = createShutdownSignalHandler({
19260
+ cleanup,
19261
+ stoppingMessage: () => "Stopping service(s)...",
19262
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
19263
+ info: (m) => logger.info(m),
19264
+ warn: (m) => logger.warn(m)
19265
+ });
19266
+ sigintHandler = () => onSignal("SIGINT", 130);
19267
+ sigtermHandler = () => onSignal("SIGTERM", 130);
19138
19268
  process.on("SIGINT", sigintHandler);
19139
- process.on("SIGTERM", sigintHandler);
19269
+ process.on("SIGTERM", sigtermHandler);
19140
19270
  const { tags: imageOverrideTags, overrides: imageOverrideMap } = await resolveAndBuildImageOverrides({
19141
19271
  perTarget: perTarget.map((pt) => pt.boot.target),
19142
19272
  stacks,
@@ -19170,47 +19300,50 @@ async function runEcsServiceEmulator(targets, options, strategy, extraStateProvi
19170
19300
  output: options.output,
19171
19301
  watchConfig: resolveWatchConfig()
19172
19302
  });
19303
+ reloadQueue = createReloadQueue({
19304
+ run: (changedPaths, signal) => reloadAllServices({
19305
+ perTarget,
19306
+ synthesizer,
19307
+ synthOpts,
19308
+ strategy,
19309
+ resolvedTargets,
19310
+ cloudMapIndexByStack,
19311
+ options,
19312
+ discovery,
19313
+ skipPull,
19314
+ extraStateProviders,
19315
+ profileCredsFile,
19316
+ frontDoorByService,
19317
+ changedPaths,
19318
+ imageOverrideTags,
19319
+ imageOverrideMap,
19320
+ logger,
19321
+ signal
19322
+ }),
19323
+ onError: (err) => logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`),
19324
+ onCoalesced: (n) => logger.debug(`Reload in progress; ${n} changed path(s) queued for one follow-up reload.`)
19325
+ });
19326
+ const queue = reloadQueue;
19173
19327
  watcher = createFileWatcher({
19174
19328
  paths: [watchRoot],
19175
19329
  ignored,
19176
19330
  shouldTrigger,
19177
19331
  onChange: (changedPaths) => {
19178
19332
  logger.info(`Detected source change (${changedPaths.length} path(s)); reloading service(s)...`);
19179
- reloadChain = reloadChain.then(() => reloadAllServices({
19180
- perTarget,
19181
- synthesizer,
19182
- synthOpts,
19183
- strategy,
19184
- resolvedTargets,
19185
- cloudMapIndexByStack,
19186
- options,
19187
- discovery,
19188
- skipPull,
19189
- extraStateProviders,
19190
- profileCredsFile,
19191
- frontDoorByService,
19192
- changedPaths,
19193
- imageOverrideTags,
19194
- imageOverrideMap,
19195
- logger
19196
- })).catch((err) => {
19197
- logger.error(`reloadAllServices threw: ${err instanceof Error ? err.message : String(err)}`);
19198
- });
19333
+ queue.schedule(changedPaths);
19199
19334
  }
19200
19335
  });
19201
19336
  logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
19202
19337
  }
19203
19338
  await new Promise(() => {});
19204
19339
  } finally {
19205
- if (sigintHandler) {
19206
- process.off("SIGINT", sigintHandler);
19207
- process.off("SIGTERM", sigintHandler);
19208
- }
19209
19340
  await cleanup();
19341
+ if (sigintHandler) process.off("SIGINT", sigintHandler);
19342
+ if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
19210
19343
  }
19211
19344
  }
19212
19345
  async function reloadAllServices(args) {
19213
- const { perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
19346
+ const { signal, perTarget, synthesizer, synthOpts, strategy, resolvedTargets, cloudMapIndexByStack, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorByService, changedPaths, imageOverrideTags: boottimeImageOverrideTags, imageOverrideMap, logger } = args;
19214
19347
  let stacks;
19215
19348
  try {
19216
19349
  let checkSelectedStacks;
@@ -19220,12 +19353,16 @@ async function reloadAllServices(args) {
19220
19353
  logger.warn(`cdk synth failed during reload; keeping previous version. (${err instanceof Error ? err.message : String(err)})`);
19221
19354
  return;
19222
19355
  }
19356
+ if (reloadCancelled(signal, logger)) return;
19223
19357
  const imageOverrideTags = new Map(boottimeImageOverrideTags);
19224
- for (const [target, entry] of imageOverrideMap.entries()) try {
19225
- const newTag = (await runImageOverrideBuilds(/* @__PURE__ */ new Map([[target, entry]]))).get(target);
19226
- if (newTag !== void 0) imageOverrideTags.set(target, newTag);
19227
- } catch (err) {
19228
- logger.warn(`Reload of ${displayStackName(target)}: --image-override rebuild failed; keeping the previous local image. (${err instanceof Error ? err.message : String(err)})`);
19358
+ for (const [target, entry] of imageOverrideMap.entries()) {
19359
+ if (reloadCancelled(signal, logger)) return;
19360
+ try {
19361
+ const newTag = (await runImageOverrideBuilds(/* @__PURE__ */ new Map([[target, entry]]))).get(target);
19362
+ if (newTag !== void 0) imageOverrideTags.set(target, newTag);
19363
+ } catch (err) {
19364
+ logger.warn(`Reload of ${displayStackName(target)}: --image-override rebuild failed; keeping the previous local image. (${err instanceof Error ? err.message : String(err)})`);
19365
+ }
19229
19366
  }
19230
19367
  const { boots: newBoots, warnings } = strategy.resolveBoots(stacks, resolvedTargets);
19231
19368
  for (const w of warnings) logger.warn(w);
@@ -19239,6 +19376,7 @@ async function reloadAllServices(args) {
19239
19376
  const cdkOutDir = options.output;
19240
19377
  const assetLoader = new AssetManifestLoader();
19241
19378
  for (const pt of perTarget) {
19379
+ if (reloadCancelled(signal, logger)) return;
19242
19380
  const newBoot = newBootByTarget.get(pt.boot.target);
19243
19381
  if (!newBoot) {
19244
19382
  logger.warn(`Reload: target ${displayStackName(pt.boot.target)} no longer resolves to a service in the synthesized app; keeping the previous replica(s) serving.`);
@@ -19287,11 +19425,18 @@ async function reloadAllServices(args) {
19287
19425
  suppressLoadBalancerWarning: strategy.suppressLoadBalancerWarning === true,
19288
19426
  verdict,
19289
19427
  ...imageOverrideTags.get(newBoot.target) !== void 0 && { imageOverrideTag: imageOverrideTags.get(newBoot.target) },
19290
- logger
19428
+ logger,
19429
+ ...signal && { signal }
19291
19430
  });
19292
19431
  }
19432
+ if (reloadCancelled(signal, logger)) return;
19293
19433
  logger.info("Reload complete.");
19294
19434
  }
19435
+ function reloadCancelled(signal, logger) {
19436
+ if (!signal?.aborted) return false;
19437
+ logger.info("Reload cancelled: shutting down.");
19438
+ return true;
19439
+ }
19295
19440
  async function loadAssetContextForTarget(args) {
19296
19441
  const { target, controller, stacks, cdkOutDir, assetLoader, logger } = args;
19297
19442
  const parsed = parseEcsTarget(target);
@@ -19358,7 +19503,7 @@ async function loadAssetContextForTarget(args) {
19358
19503
  };
19359
19504
  }
19360
19505
  async function rollOneTarget(args) {
19361
- const { controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
19506
+ const { signal, controller, newBoot, stacks, options, discovery, skipPull, extraStateProviders, profileCredsFile, frontDoorPools, suppressLoadBalancerWarning, verdict, imageOverrideTag, logger } = args;
19362
19507
  const candidate = pickCandidateStack$1(newBoot.target, stacks);
19363
19508
  const stateProvider = createLocalStateProvider(options, candidate?.stackName ?? "", await resolveCfnFallbackRegion(options, candidate?.region), extraStateProviders);
19364
19509
  try {
@@ -19383,6 +19528,7 @@ async function rollOneTarget(args) {
19383
19528
  if (verdict.kind === "soft-reload") logger.info(`Reload of ${displayStackName(newBoot.target)}: soft-reloading ${oldReplicas.length} replica(s) one at a time (docker cp source → restart → TCP-ready probe; no rebuild).`);
19384
19529
  else logger.info(`Reload of ${displayStackName(newBoot.target)}: rolling ${oldReplicas.length} replica(s) one at a time (start new shadow → swap registrations → stop old).`);
19385
19530
  for (const oldInstance of oldReplicas) {
19531
+ if (signal?.aborted) return;
19386
19532
  const idx = controller.runState.replicas.indexOf(oldInstance);
19387
19533
  if (idx === -1) {
19388
19534
  logger.warn(`Reload of ${displayStackName(newBoot.target)}: replica r${oldInstance.index} (gen ${oldInstance.generation}) vanished before its roll; skipping.`);
@@ -20083,9 +20229,10 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20083
20229
  if (options.verbose) logger.setLevel("debug");
20084
20230
  const state = createEcsRunState();
20085
20231
  let sigintHandler;
20086
- let sigintCount = 0;
20232
+ let sigtermHandler;
20087
20233
  let stateProvider;
20088
20234
  let profileCredsFile;
20235
+ let detachedTaskStarted = false;
20089
20236
  let cleanupPromise;
20090
20237
  const cleanup = async () => {
20091
20238
  if (!cleanupPromise) cleanupPromise = (async () => {
@@ -20160,17 +20307,17 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20160
20307
  }
20161
20308
  }
20162
20309
  } else if (!stateProvider && taskNeeds.needsCrossStackResolver) logger.warn("Container Environment / Secrets entries contain Fn::ImportValue / Fn::GetStackOutput intrinsics. Pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to substitute them against deployed state.");
20163
- sigintHandler = () => {
20164
- sigintCount += 1;
20165
- if (sigintCount >= 2) {
20166
- process.stderr.write("Force-exit on second stop signal; container cleanup skipped.\n");
20167
- process.exit(130);
20168
- }
20169
- logger.info("Stopping task...");
20170
- cleanup().then(() => process.exit(130));
20171
- };
20310
+ const onSignal = createShutdownSignalHandler({
20311
+ cleanup,
20312
+ stoppingMessage: () => "Stopping task...",
20313
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' and 'docker network ls --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
20314
+ info: (m) => logger.info(m),
20315
+ warn: (m) => logger.warn(m)
20316
+ });
20317
+ sigintHandler = () => onSignal("SIGINT", 130);
20318
+ sigtermHandler = () => onSignal("SIGTERM", 130);
20172
20319
  process.on("SIGINT", sigintHandler);
20173
- process.on("SIGTERM", sigintHandler);
20320
+ process.on("SIGTERM", sigtermHandler);
20174
20321
  const effectiveAssumeRole = resolveEcsAssumeRoleOption(options);
20175
20322
  let assumedCredentials;
20176
20323
  let resolvedRoleArn;
@@ -20183,7 +20330,7 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20183
20330
  assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region, options.profile);
20184
20331
  }
20185
20332
  const sidecarCredentials = await resolveSidecarCredentials(options, assumedCredentials);
20186
- if (options.profile && sidecarCredentials && !assumedCredentials) profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);
20333
+ const credsDelivery = containerCredentialDelivery(options, sidecarCredentials, assumedCredentials);
20187
20334
  const envOverrides = readEnvOverridesFile(options.envVars);
20188
20335
  const runOpts = {
20189
20336
  cluster: options.cluster,
@@ -20203,11 +20350,7 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20203
20350
  if (options.profile) runOpts.profile = options.profile;
20204
20351
  const hostPortOverrides = parseHostPortOverrides(options.hostPort);
20205
20352
  if (Object.keys(hostPortOverrides).length > 0) runOpts.hostPortOverrides = hostPortOverrides;
20206
- if (profileCredsFile) runOpts.profileCredentialsFile = {
20207
- hostPath: profileCredsFile.hostPath,
20208
- containerPath: profileCredsFile.containerPath,
20209
- profileName: profileCredsFile.profileName
20210
- };
20353
+ if (credsDelivery === "env" && sidecarCredentials) runOpts.defaultCredentials = sidecarCredentials;
20211
20354
  const imageOverrideResult = await resolveRunTaskImageOverride({
20212
20355
  task,
20213
20356
  target: resolvedTarget,
@@ -20222,7 +20365,16 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20222
20365
  };
20223
20366
  const hostGatewayExtraHosts = await resolveHostGatewayExtraHosts();
20224
20367
  if (hostGatewayExtraHosts.length > 0) runOpts.hostGatewayExtraHosts = hostGatewayExtraHosts;
20368
+ if (credsDelivery === "profile-file" && options.profile && sidecarCredentials) {
20369
+ profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);
20370
+ runOpts.profileCredentialsFile = {
20371
+ hostPath: profileCredsFile.hostPath,
20372
+ containerPath: profileCredsFile.containerPath,
20373
+ profileName: profileCredsFile.profileName
20374
+ };
20375
+ }
20225
20376
  const result = await runEcsTask(task, runOpts, state);
20377
+ detachedTaskStarted = options.detach;
20226
20378
  if (options.detach) {
20227
20379
  logger.info(`Task containers started in detached mode; ${getEmbedConfig().binaryName} is exiting.`);
20228
20380
  logger.info(`Use 'docker ps --filter network=${result.state.network?.networkName ?? "<network>"}' to inspect; tear down with 'docker rm -f' and 'docker network rm'.`);
@@ -20232,18 +20384,17 @@ async function localRunTaskCommand(target, options, extraStateProviders) {
20232
20384
  const containers = result.state.startedContainers.filter((c) => joinedNames.has(c.name)).map((c) => c.id.slice(0, 12)).join(", ");
20233
20385
  logger.info(`Under the loopback AWS endpoint, task containers share the network of a forwarder container, so that filter does not list them. Task container ids: ${containers}. Remove them before the forwarders (${joinedForwarders.map((f) => f.name).join(", ")}).`);
20234
20386
  }
20235
- sigintCount = 99;
20387
+ if (profileCredsFile) logger.info(`The task containers read the --profile credentials from ${path.dirname(profileCredsFile.hostPath)}; remove that directory after removing them.`);
20236
20388
  return;
20237
20389
  }
20238
20390
  if (result.essentialContainerName) logger.info(`Essential container ${displayIdent(result.essentialContainerName)} exited with code ${result.exitCode}.`);
20239
20391
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
20240
20392
  } finally {
20241
- if (sigintHandler) {
20242
- process.off("SIGINT", sigintHandler);
20243
- process.off("SIGTERM", sigintHandler);
20244
- }
20245
20393
  if (stateProvider) stateProvider.dispose();
20246
20394
  if (!options.detach) await cleanup();
20395
+ else if (!detachedTaskStarted && profileCredsFile) await profileCredsFile.dispose().catch(() => void 0);
20396
+ if (sigintHandler) process.off("SIGINT", sigintHandler);
20397
+ if (sigtermHandler) process.off("SIGTERM", sigtermHandler);
20247
20398
  }
20248
20399
  }
20249
20400
  var PlaceholderAccountError = class PlaceholderAccountError extends Error {
@@ -20369,6 +20520,11 @@ async function resolveSidecarCredentials(options, assumedCredentials) {
20369
20520
  if (options.profile) return resolveProfileCredentials(options.profile);
20370
20521
  return resolveHostDefaultCredentials();
20371
20522
  }
20523
+ function containerCredentialDelivery(options, sidecarCredentials, assumedCredentials) {
20524
+ if (!sidecarCredentials || assumedCredentials) return void 0;
20525
+ if (getActiveWorkloadAwsWiring()?.mode === "emulator") return void 0;
20526
+ return options.profile ? "profile-file" : "env";
20527
+ }
20372
20528
  function createLocalRunTaskCommand(opts = {}) {
20373
20529
  setEmbedConfig(opts.embedConfig);
20374
20530
  const cmd = new Command("run-task").description("Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID (MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix. Omit <target> in an interactive terminal to pick the task definition from a list.").argument("[target]", "CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run (omit to pick interactively in a TTY)").action(withErrorHandling(async (target, options) => {
@@ -24414,7 +24570,7 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
24414
24570
  process.stdout.write(`CloudFront distribution serving on ${server.url} (${displayIdent(initial.distribution.logicalId)})\n`);
24415
24571
  process.stdout.write("^C to stop.\n");
24416
24572
  let watcher;
24417
- let reloadChain = Promise.resolve();
24573
+ let reloadQueue;
24418
24574
  if (options.watch) {
24419
24575
  const watchRoot = process.cwd();
24420
24576
  const { ignored, shouldTrigger, excludePatterns } = createWatchPredicates({
@@ -24422,37 +24578,37 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
24422
24578
  output: options.output,
24423
24579
  watchConfig: resolveWatchConfig()
24424
24580
  });
24581
+ const queue = createReloadQueue({ run: async (_changedPaths, signal) => {
24582
+ try {
24583
+ const reloaded = await synthAndResolve();
24584
+ if (signal.aborted) return;
24585
+ annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
24586
+ for (const reader of deployedS3.readers.values()) reader.clearCache();
24587
+ warnUnsupported(reloaded.distribution, extraStateProviders);
24588
+ await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
24589
+ server.update(reloaded.distribution);
24590
+ logger.info("Reload complete.");
24591
+ } catch (err) {
24592
+ logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
24593
+ }
24594
+ } });
24595
+ reloadQueue = queue;
24425
24596
  watcher = createFileWatcher({
24426
24597
  paths: [watchRoot],
24427
24598
  ignored,
24428
24599
  shouldTrigger,
24429
- onChange: () => {
24600
+ onChange: (changedPaths) => {
24430
24601
  logger.info("Detected source change; reloading...");
24431
- reloadChain = reloadChain.then(async () => {
24432
- try {
24433
- const reloaded = await synthAndResolve();
24434
- annotateDeployedS3Origins(reloaded.distribution, deployedS3.buckets);
24435
- for (const reader of deployedS3.readers.values()) reader.clearCache();
24436
- warnUnsupported(reloaded.distribution, extraStateProviders);
24437
- await attachKvsModules(reloaded.distribution, reloaded.stacks, options, profileCredentials, logger, extraStateProviders);
24438
- server.update(reloaded.distribution);
24439
- logger.info("Reload complete.");
24440
- } catch (err) {
24441
- logger.warn(`Reload failed; keeping the previous version serving: ${err instanceof Error ? err.message : String(err)}`);
24442
- }
24443
- }).catch(() => void 0);
24602
+ queue.schedule(changedPaths);
24444
24603
  }
24445
24604
  });
24446
24605
  logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}).`);
24447
24606
  }
24448
- let shuttingDown = false;
24449
- const shutdown = async (signal, exitCode) => {
24450
- if (shuttingDown) return;
24451
- shuttingDown = true;
24452
- logger.info(`Received ${signal}, shutting down...`);
24453
- if (watcher) try {
24454
- await watcher.close();
24455
- } catch {}
24607
+ const teardown = async () => {
24608
+ await stopWatchReloads({
24609
+ watcher,
24610
+ queue: reloadQueue
24611
+ });
24456
24612
  try {
24457
24613
  await server.close();
24458
24614
  } catch {}
@@ -24462,10 +24618,16 @@ async function localStartCloudFrontCommand(target, options, extraStateProviders,
24462
24618
  logger.debug(`Web function server teardown failed: ${err instanceof Error ? err.message : String(err)}`);
24463
24619
  }))]);
24464
24620
  await Promise.all([...deployedS3.readers.values()].map((reader) => reader.close()));
24465
- process.exit(exitCode);
24466
24621
  };
24467
- process.on("SIGINT", () => void shutdown("SIGINT", 130));
24468
- process.on("SIGTERM", () => void shutdown("SIGTERM", 0));
24622
+ const shutdown = createShutdownSignalHandler({
24623
+ cleanup: () => teardown().catch(() => void 0),
24624
+ stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
24625
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
24626
+ info: (m) => logger.info(m),
24627
+ warn: (m) => logger.warn(m)
24628
+ });
24629
+ process.on("SIGINT", () => shutdown("SIGINT", 130));
24630
+ process.on("SIGTERM", () => shutdown("SIGTERM", 0));
24469
24631
  await new Promise(() => void 0);
24470
24632
  }
24471
24633
  function createLocalStartCloudFrontCommand(opts = {}) {
@@ -24836,20 +24998,17 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
24836
24998
  let profileCredsFile;
24837
24999
  let stateProvider;
24838
25000
  let watcher;
24839
- let reloadChain = Promise.resolve();
25001
+ let reloadQueue;
24840
25002
  let shuttingDown = false;
24841
25003
  let tornDown = false;
24842
25004
  const teardown = async () => {
24843
25005
  if (tornDown) return;
24844
25006
  tornDown = true;
24845
- if (watcher) try {
24846
- await watcher.close();
24847
- } catch (err) {
24848
- logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`);
24849
- }
24850
- try {
24851
- await reloadChain;
24852
- } catch {}
25007
+ await stopWatchReloads({
25008
+ watcher,
25009
+ queue: reloadQueue,
25010
+ onWatcherCloseError: (err) => logger.debug(`watcher close failed: ${err instanceof Error ? err.message : String(err)}`)
25011
+ });
24853
25012
  if (server) try {
24854
25013
  await server.close();
24855
25014
  } catch (err) {
@@ -24934,15 +25093,18 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
24934
25093
  ...sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }
24935
25094
  });
24936
25095
  stopLogs = streamLogs(containerId);
24937
- const shutdown = async (signal, exitCode) => {
24938
- if (shuttingDown) return;
24939
- shuttingDown = true;
24940
- logger.info(`Received ${signal}, shutting down...`);
24941
- await teardown();
24942
- process.exit(exitCode);
24943
- };
24944
- process.on("SIGINT", () => void shutdown("SIGINT", 130));
24945
- process.on("SIGTERM", () => void shutdown("SIGTERM", 0));
25096
+ const shutdown = createShutdownSignalHandler({
25097
+ cleanup: async () => {
25098
+ shuttingDown = true;
25099
+ await teardown().catch(() => void 0);
25100
+ },
25101
+ stoppingMessage: (signal) => `Received ${signal}, shutting down...`,
25102
+ forceExitHint: `Run 'docker ps -a --filter name=${getEmbedConfig().resourceNamePrefix}-' to find what is left.`,
25103
+ info: (m) => logger.info(m),
25104
+ warn: (m) => logger.warn(m)
25105
+ });
25106
+ process.on("SIGINT", () => shutdown("SIGINT", 130));
25107
+ process.on("SIGTERM", () => shutdown("SIGTERM", 0));
24946
25108
  try {
24947
25109
  if (plan.readyPath === void 0) await waitForAgentCorePing(containerHost, containerHostPort, options.timeout);
24948
25110
  else await waitForAgentCoreHttpReady(containerHost, containerHostPort, plan.readyPath, options.timeout);
@@ -25012,95 +25174,99 @@ async function localStartAgentCoreCommand(target, options, extraStateProviders,
25012
25174
  watchConfig: resolveWatchConfig()
25013
25175
  });
25014
25176
  logger.info(`Watching ${watchRoot} for source changes (excluding ${excludePatterns.join(", ")}). The warm container reloads in place; the serve stays up.`);
25177
+ reloadQueue = createReloadQueue({
25178
+ run: async (changedPaths) => {
25179
+ if (tornDown || shuttingDown) return;
25180
+ let freshStacks;
25181
+ let freshResolved;
25182
+ let freshLoaded;
25183
+ let freshImageContext;
25184
+ let verdict;
25185
+ let nextAssetHash = currentAssetHash;
25186
+ try {
25187
+ const synthRes = await synthesizer.synthesize(synthOpts);
25188
+ freshStacks = synthRes.stacks;
25189
+ synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
25190
+ const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
25191
+ const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
25192
+ context: void 0,
25193
+ loaded: void 0
25194
+ };
25195
+ freshImageContext = ctx.context;
25196
+ freshLoaded = ctx.loaded;
25197
+ freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
25198
+ await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
25199
+ const assetCtx = await loadAgentCoreAssetContext({
25200
+ resolvedTarget,
25201
+ resolved: freshResolved,
25202
+ stacks: freshStacks,
25203
+ cdkOutDir,
25204
+ assetLoader,
25205
+ oldAssetHash: currentAssetHash
25206
+ });
25207
+ if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
25208
+ verdict = classifySourceChange(changedPaths, assetCtx);
25209
+ logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
25210
+ } catch (err) {
25211
+ logger.error(`Reload: re-synth / classify failed (${err instanceof Error ? err.message : String(err)}); skipping this change. The serve stays up against the current container.`);
25212
+ return;
25213
+ }
25214
+ if (tornDown || shuttingDown) return;
25215
+ try {
25216
+ if (verdict.kind === "soft-reload") {
25217
+ if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
25218
+ await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
25219
+ await waitReady(containerHostPort);
25220
+ logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
25221
+ } else {
25222
+ if (stopLogs) {
25223
+ try {
25224
+ stopLogs();
25225
+ } catch {}
25226
+ stopLogs = void 0;
25227
+ }
25228
+ if (containerId) {
25229
+ await removeContainer(containerId);
25230
+ containerId = void 0;
25231
+ }
25232
+ const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
25233
+ const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
25234
+ if (tornDown || shuttingDown) return;
25235
+ const newPort = await pickFreePort();
25236
+ const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
25237
+ logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
25238
+ containerId = await runDetached({
25239
+ image: newImage,
25240
+ mounts: [],
25241
+ env: newEnv,
25242
+ cmd: [],
25243
+ hostPort: newPort,
25244
+ host: containerHost,
25245
+ platform: options.platform,
25246
+ name: newName,
25247
+ ...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
25248
+ ...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
25249
+ });
25250
+ stopLogs = streamLogs(containerId);
25251
+ containerHostPort = newPort;
25252
+ await waitReady(newPort);
25253
+ server?.setContainerPort(newPort);
25254
+ logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
25255
+ }
25256
+ currentAssetHash = nextAssetHash;
25257
+ logger.info("Reload complete.");
25258
+ } catch (err) {
25259
+ logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
25260
+ }
25261
+ },
25262
+ onError: (err) => logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}.`)
25263
+ });
25264
+ const queue = reloadQueue;
25015
25265
  watcher = createFileWatcher({
25016
25266
  paths: [watchRoot],
25017
25267
  ignored,
25018
25268
  shouldTrigger,
25019
- onChange: (changedPaths) => {
25020
- reloadChain = reloadChain.then(async () => {
25021
- if (tornDown || shuttingDown) return;
25022
- let freshStacks;
25023
- let freshResolved;
25024
- let freshLoaded;
25025
- let freshImageContext;
25026
- let verdict;
25027
- let nextAssetHash = currentAssetHash;
25028
- try {
25029
- const synthRes = await synthesizer.synthesize(synthOpts);
25030
- freshStacks = synthRes.stacks;
25031
- synthRes.checkSelectedStacks?.([resolved.stack.stackName]);
25032
- const freshCandidate = pickAgentCoreCandidateStack(resolvedTarget, freshStacks);
25033
- const ctx = stateProvider && freshCandidate ? await buildAgentCoreImageContext(freshCandidate, stateProvider, options) : {
25034
- context: void 0,
25035
- loaded: void 0
25036
- };
25037
- freshImageContext = ctx.context;
25038
- freshLoaded = ctx.loaded;
25039
- freshResolved = resolveAgentCoreTarget(resolvedTarget, freshStacks, freshImageContext);
25040
- await resolveFromS3BucketIntrinsic(freshResolved, stateProvider, freshLoaded, freshImageContext);
25041
- const assetCtx = await loadAgentCoreAssetContext({
25042
- resolvedTarget,
25043
- resolved: freshResolved,
25044
- stacks: freshStacks,
25045
- cdkOutDir,
25046
- assetLoader,
25047
- oldAssetHash: currentAssetHash
25048
- });
25049
- if (assetCtx?.newAssetHash !== void 0) nextAssetHash = assetCtx.newAssetHash;
25050
- verdict = classifySourceChange(changedPaths, assetCtx);
25051
- logger.info(`Detected source change (${changedPaths.length} path(s)); verdict=${verdict.kind} (${verdict.reason}).`);
25052
- } catch (err) {
25053
- logger.error(`Reload: re-synth / classify failed (${err instanceof Error ? err.message : String(err)}); skipping this change. The serve stays up against the current container.`);
25054
- return;
25055
- }
25056
- if (tornDown || shuttingDown) return;
25057
- try {
25058
- if (verdict.kind === "soft-reload") {
25059
- if (!containerId) throw new CdkLocalError("Reload: no live container to docker cp / docker restart into.", "LOCAL_START_AGENTCORE_WATCH_NO_CONTAINER");
25060
- await softReloadAgentContainer(containerId, verdict.newAssetSourceDir);
25061
- await waitReady(containerHostPort);
25062
- logger.info("Reload: soft-reloaded the agent container (docker cp + docker restart; container ID + host port preserved).");
25063
- } else {
25064
- if (stopLogs) {
25065
- try {
25066
- stopLogs();
25067
- } catch {}
25068
- stopLogs = void 0;
25069
- }
25070
- if (containerId) {
25071
- await removeContainer(containerId);
25072
- containerId = void 0;
25073
- }
25074
- const newImage = await resolveAgentCoreImage(freshResolved, options, freshLoaded, stateProvider);
25075
- const { env: newEnv, sensitiveEnvKeys: newSensitive } = await buildContainerEnv(freshResolved, options, profileCredentials, profileCredsFile, stateProvider, freshLoaded, freshImageContext);
25076
- const newPort = await pickFreePort();
25077
- const newName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;
25078
- logger.info(`Reload: starting agent container (image=${newImage}, port=${newPort} -> ${plan.containerPortLabel})...`);
25079
- containerId = await runDetached({
25080
- image: newImage,
25081
- mounts: [],
25082
- env: newEnv,
25083
- cmd: [],
25084
- hostPort: newPort,
25085
- host: containerHost,
25086
- platform: options.platform,
25087
- name: newName,
25088
- ...plan.containerPort !== void 0 && { containerPort: plan.containerPort },
25089
- ...newSensitive.size > 0 && { sensitiveEnvKeys: newSensitive }
25090
- });
25091
- stopLogs = streamLogs(containerId);
25092
- containerHostPort = newPort;
25093
- await waitReady(newPort);
25094
- server?.setContainerPort(newPort);
25095
- logger.info(`Reload: rebuilt the agent container; serve re-pointed to port ${newPort}.`);
25096
- }
25097
- currentAssetHash = nextAssetHash;
25098
- logger.info("Reload complete.");
25099
- } catch (err) {
25100
- logger.error(`Reload failed: ${err instanceof Error ? err.message : String(err)}. The serve stays up; edit + save again to retry.`);
25101
- }
25102
- });
25103
- }
25269
+ onChange: (changedPaths) => queue.schedule(changedPaths)
25104
25270
  });
25105
25271
  }
25106
25272
  await new Promise(() => void 0);
@@ -31773,4 +31939,4 @@ function addStudioSpecificOptions(cmd) {
31773
31939
 
31774
31940
  //#endregion
31775
31941
  export { postHook as $, addAwsEndpointOptions as $a, parseConnectionsPath as $i, addImageOverrideOptions as $n, addStartApiSpecificOptions as $r, classifyS3Error as $t, microvmFidelityWarnings as A, parseSelectionExpressionPath as Aa, applyCorsResponseHeaders as Ai, stripCloudFrontImport as An, A2A_CONTAINER_PORT as Ar, readContainerLogTail as At, MICROVM_WS_BASE_PROTOCOL as B, AgentCoreResolutionError as Ba, evaluateResponseParameters as Bi, createLocalStartAlbCommand as Bn, AGENTCORE_SESSION_ID_HEADER as Br, parseWebFunctionBuildConfig as Bt, addListSpecificOptions as C, resolveSingleTarget as Ca, verifyJwtViaDiscovery as Ci, WEB_FUNCTION_REVISION_TYPE as Cn, setShadowReadyTimeoutMs as Cr, parseKvsFileOverrides as Ct, buildMicrovmLambdaView as D, discoverWebSocketApis as Da, invokeRequestAuthorizer as Di, compileCloudFrontFunction as Dn, createLocalInvokeAgentCoreCommand as Dr, WEB_FUNCTION_CONTAINER_PORT as Dt, addStartMicrovmSpecificOptions as E, availableWebSocketApiIdentifiers as Ea, evaluateCachedLambdaPolicy as Ei, resolveWebFunctionTarget as En, addInvokeAgentCoreSpecificOptions as Er, RecentOutput as Et, microvmImageTag as F, AGENTCORE_A2A_PROTOCOL as Fa, matchRoute as Fi, findFileAssetForObjectKey as Fn, MCP_PROTOCOL_VERSION as Fr, buildNodeEntryFileStart as Ft, startMicrovmFrontDoor as G, containsDynamicReference as Ga, HOST_DOCKER_INTERNAL_GATEWAY as Gi, addStartServiceSpecificOptions as Gn, SUPPORTED_CODE_RUNTIMES as Gr, readWebFunctionServiceConfig as Gt, PROXY_PORT_HEADER as H, resolveAgentCoreTarget as Ha, selectIntegrationResponse as Hi, resolveAlbTarget as Hn, waitForAgentCoreHttpReady as Hr, WEB_FUNCTION_HTTP_ENDPOINT_ENV as Ht, planMicrovmPorts as I, AGENTCORE_AGUI_PROTOCOL as Ia, translateLambdaResponse as Ii, isBucketDeploymentResource as In, mcpInvokeOnce as Ir, defaultWebFunctionPlatform as It, MICROVM_HOOK_PATH_PREFIX as J, keysNotFromTemplate as Ja, resolveHostGatewayExtraHosts as Ji, addRunTaskSpecificOptions as Jn, renderCodeDockerfile as Jr, idFromArn as Jt, stripMicrovmProxyHeaders as K, deployedFillMayBeSecret as Ka, HOST_GATEWAY_MIN_VERSION as Ki, createLocalStartServiceCommand as Kn, buildAgentCoreCodeImage as Kr, webFunctionAssumeRole as Kt, readExposedPorts as L, AGENTCORE_HTTP_PROTOCOL as La, applyAuthorizerOverlay as Li, resolveBucketDeploymentObjectKey as Ln, parseSseForJsonRpc as Lr, resolveWebFunctionRuntime as Lt, DEFAULT_TERMINATE_HOOK_TIMEOUT_MS as M, discoverRoutes as Ma, buildCorsConfigFromCloudFrontChain as Mi, createLocalFileKvsDataSource as Mn, a2aInvokeOnce as Mr, waitForWebFunctionReady as Mt, LocalMicrovm as N, pickRefLogicalId as Na, isFunctionUrlOacFronted as Ni, createUnboundCloudFrontModule as Nn, MCP_CONTAINER_PORT as Nr, watchContainerExit as Nt, createLocalStartMicrovmCommand as O, discoverWebSocketApisOrThrow as Oa, invokeTokenAuthorizer as Oi, runViewerRequest as On, bridgeAgentCoreWs as Or, containerFailure as Ot, buildMicrovmImage as P, resolveLambdaArnIntrinsic as Pa, matchPreflight as Pi, bucketDeploymentSourceObjectKeys as Pn, MCP_PATH as Pr, WEB_FUNCTION_RUNTIMES as Pt, pollBuildHook as Q, withoutKeys as Qa, handleConnectionsRequest as Qi, addEcsAssumeRoleOptions as Qn, createLocalInvokeCommand as Qr, resolveDeployedOriginBucket as Qt, setContainerPaused as R, AGENTCORE_MCP_PROTOCOL as Ra, buildHttpApiV2Event as Ri, addAlbSpecificOptions as Rn, AGENTCORE_SIGV4_SERVICE as Rr, supportedWebFunctionRuntimes as Rt, StudioEventBus as S, resolveWatchConfig as Sa, verifyJwtAuthorizer as Si, WEB_FUNCTION_ENDPOINT_TYPE as Sn, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Sr, normalizeKvsFileKeys as St, formatTargetListing as T, listTargets as Ta, computeRequestIdentityHash as Ti, WebFunctionResolutionError as Tn, attachContainerLogStreamer as Tr, resolveCloudFrontTarget as Tt, rewriteUpgradeResponseHead as U, DynamicReferenceResolutionError as Ua, tryParseStatus as Ui, isApplicationLoadBalancer as Un, waitForAgentCorePing as Ur, buildWebFunctionLambdaView as Ut, MicrovmStateError as V, pickAgentCoreCandidateStack as Va, pickResponseTemplate as Vi, parseLbPortOverrides as Vn, invokeAgentCore as Vr, resolveWebFunctionArtifact as Vt, selectTargetPort as W, DynamicReferenceResolver as Wa, VtlEvaluationError as Wi, resolveAlbFrontDoor as Wn, downloadAndExtractS3Bundle as Wr, finalizeWebFunctionEnv as Wt, callRuntimeHook as X, parseDynamicReference as Xa, ConnectionRegistry as Xi, MAX_TASKS_SUBNET_RANGE_CAP as Xn, classifySourceChange as Xr, createDeployedKvsDataSource as Xt, MicrovmHookError as Y, keysOverriddenBy as Ya, bufferToBody as Yi, createLocalRunTaskCommand as Yn, toCmdArgv as Yr, resolveKvsModulesForDistribution as Yt, generateMicrovmId as Z, resolveDynamicReferencesInEnv as Za, buildMgmtEndpointEnvUrl as Zi, addCommonEcsServiceOptions as Zn, addInvokeSpecificOptions as Zr, resolveDeployedKvsArnByName as Zt, filterStudioTargetGroups as _, resolveCfnRegion as _a, defaultCredentialsLoader as _i, pickKvsLogicalIdFromArn as _n, isLocalCdkAssetImage as _r, attachAgentCoreWsBridge as _t, createLocalStudioCommand as a, resolveRuntimeImage as aa, attachStageContext as ai, serveLambdaUrlOrigin as an, resolveSharedSidecarCredentials as ar, disposeMicrovmCodeArtifact as at, renderStudioHtml as b, collectSsmParameterRefs as ba, createJwksCache as bi, pickWebFunctionEndpointLogicalIdFromOrigin as bn, CloudMapRegistry as br, addStartCloudFrontSpecificOptions as bt, startStudioProxy as c, substituteAgainstState as ca, resolveEnvVars$1 as ci, buildEdgeRequestEvent as cn, buildImageOverrideTag as cr, resolveMicrovmImageTarget as ct, createStudioDispatcher as d, substituteEnvVarsFromStateAsync as da, filterRoutesByApiIdentifiers as di, httpHeadersToEdge as dn, mergeForService as dr, createLocalStartWebFunctionCommand as dt, buildConnectEvent as ea, createLocalStartApiCommand as ei, createS3OriginReader as en, awsEndpointOptions as eo, buildEcsImageResolutionContext$1 as er, runHookBody as et, filterStudioCustomResources as f, LocalStateSourceError as fa, groupRoutesByServer as fi, CLOUDFRONT_DISTRIBUTION_TYPE as fn, parseImageOverrideFlags as fr, addStartAgentCoreSpecificOptions as ft, annotatePinnedEcsTargets as g, resolveCfnFallbackRegion as ga, resolveServiceIntegrationParameters as gi, pickFunctionUrlLogicalIdFromOrigin as gn, imageOverrideKeyAliases as gr, startAgentCoreHttpServer as gt, annotateEcsTaskPinnedTargets as h, rejectExplicitCfnStackWithMultipleStacks as ha, resolveSelectionExpression as hi, isCloudFrontDistribution as hn, describePinnedImageUri as hr, selectServeInboundAuth as ht, coerceStopRequest as i, resolveRuntimeFileExtension as ia, createFileWatcher as ii, serveFromStaticOrigin as in, resolveEcsAssumeRoleOption as ir, MicrovmResolutionError as it, readRunHookPayload as j, webSocketApiMatchesIdentifier as ja, buildCorsConfigByApiId as ji, createCloudFrontModule as jn, A2A_PATH as jr, startWebFunctionContainer as jt, finalizeMicrovmEnv as k, filterWebSocketApisByIdentifiers as ka, attachAuthorizers as ki, runViewerResponse as kn, invokeAgentCoreWs as kr, planWebFunctionContainer as kt, relayServeRequest as l, substituteAgainstStateAsync as la, availableApiIdentifiers as li, buildEdgeResponseEvent as ln, canonicalizeImageOverrideKeys as lr, s3KeyOfUri as lt, annotateAlbPinnedBackingServices as m, isCfnFlagPresent as ma, startApiServer as mi, extractKvsAssociations as mn, runImageOverrideBuilds as mr, buildAgentCoreServeAuthCheck as mt, coerceRunRequest as n, buildMessageEvent as na, resolveApiTargetSubset as ni, startCloudFrontServer as nn, parseMaxTasks as nr, MICROVM_DEFAULT_INGRESS_PORT as nt, resolveServeBaseUrl as o, EcsTaskResolutionError as oa, buildStageMap as oi, applyEdgeRequestResult as on, runEcsServiceEmulator as or, readMicrovmImageConfig as ot, isCustomResourceLambdaTarget as p, createLocalStateProvider as pa, readMtlsMaterialsFromDisk as pi, describeS3OriginDomain as pn, resolveImageOverrides as pr, createLocalStartAgentCoreCommand as pt, MAX_RUN_HOOK_PAYLOAD_BYTES as q, firstUsableRegion as qa, probeHostGatewaySupport as qi, serviceStrategy as qn, computeCodeImageTag as qr, webFunctionFidelityWarnings as qt, coerceServeRequest as r, resolveRuntimeCodeMountPath as ra, createAuthorizerCache as ri, resolveErrorResponseCandidates as rn, parseRestartPolicy as rr, MICROVM_IMAGE_TYPE as rt, createStudioServeManager as s, assertEcsTaskImagesResolvable as sa, materializeLayerFromArn as si, applyEdgeResponseResult as sn, ImageOverrideError as sr, resolveMicrovmCodeArtifact as st, addStudioSpecificOptions as t, buildDisconnectEvent as ta, createWatchPredicates as ti, matchBehavior as tn, ecsClusterOption as tr, waitForAppAnswer as tt, reinvoke as u, substituteEnvVarsFromState as ua, filterRoutesByApiIdentifier as ui, edgeHeadersToHttp as un, enforceImageOverrideOrphans as ur, addStartWebFunctionSpecificOptions as ut, startStudioServer as v, resolveCfnStackName as va, buildCognitoJwksUrl as vi, pickLambdaEdgeFunctionLogicalId as vn, listPinnedTargets as vr, startAgentCoreWsBridge as vt, createLocalListCommand as w, countTargets as wa, buildMethodArn as wi, WEB_FUNCTION_TYPE as wn, getContainerNetworkIp as wr, parseOriginOverrides as wt, createStudioStore as x, resolveSsmParameters as xa, verifyCognitoJwt as xi, resolveCloudFrontDistribution as xn, DEFAULT_SHADOW_READY_TIMEOUT_MS as xr, createLocalStartCloudFrontCommand as xt, toStudioTargetGroups as y, CfnLocalStateProvider as ya, buildJwksUrlFromIssuer as yi, pickTargetFunctionLogicalId as yn, buildCloudMapIndex as yr, LocalStartCloudFrontError as yt, MICROVM_CONTROL_PATH as z, AGENTCORE_RUNTIME_TYPE as za, buildRestV1Event as zi, albStrategy as zn, signAgentCoreInvocation as zr, disposeWebFunctionArtifact as zt };
31776
- //# sourceMappingURL=local-studio-aUkwJL4M.js.map
31942
+ //# sourceMappingURL=local-studio-LTgy7a7a.js.map