cdk-local 0.107.1 → 0.109.0

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.
@@ -17201,123 +17201,14 @@ async function localInvokeCommand(target, options, extraStateProviders) {
17201
17201
  const targetLabel = lambda.kind === "zip" ? lambda.runtime : "container image";
17202
17202
  logger.info(`Target: ${lambda.stack.stackName}/${lambda.logicalId} (${targetLabel})`);
17203
17203
  imagePlan = await resolveImagePlan(lambda, options);
17204
- let stateAudit;
17205
- let templateEnv = getTemplateEnv(lambda.resource);
17206
- let stateForRoleHint;
17207
- const stateProvider = createLocalStateProvider(options, lambda.stack.stackName, await resolveCfnFallbackRegion(options, lambda.stack.region), extraStateProviders);
17208
- if (stateProvider) try {
17209
- const loaded = await stateProvider.load(lambda.stack.stackName, lambda.stack.region);
17210
- if (loaded) {
17211
- stateForRoleHint = {
17212
- version: 1,
17213
- stackName: lambda.stack.stackName,
17214
- resources: loaded.resources,
17215
- outputs: loaded.outputs,
17216
- lastModified: 0
17217
- };
17218
- const subContext = {
17219
- resources: loaded.resources,
17220
- consumerRegion: loaded.region
17221
- };
17222
- if (envHasIntrinsicValue(templateEnv)) {
17223
- const pseudo = await resolvePseudoParametersForInvoke(lambda.stack.region, options);
17224
- if (pseudo) subContext.pseudoParameters = pseudo;
17225
- }
17226
- if (envHasIntrinsicValue(templateEnv) && stateProvider.resolveTemplateSsmParameters) {
17227
- const ssmParams = await stateProvider.resolveTemplateSsmParameters(lambda.stack.template);
17228
- if (Object.keys(ssmParams.values).length > 0) subContext.parameters = ssmParams.values;
17229
- if (ssmParams.secureStringLogicalIds.length > 0) subContext.sensitiveParameters = new Set(ssmParams.secureStringLogicalIds);
17230
- }
17231
- if (envHasCrossStackIntrinsic(templateEnv)) {
17232
- const resolver = await stateProvider.buildCrossStackResolver(loaded.region);
17233
- if (resolver) subContext.crossStackResolver = resolver;
17234
- }
17235
- const { env, audit } = await substituteEnvVarsFromStateAsync(templateEnv, subContext);
17236
- templateEnv = env;
17237
- const label = stateProvider.label;
17238
- for (const key of audit.resolvedKeys) logger.debug(`${label}: substituted env var ${key}`);
17239
- let unresolved = audit.unresolved;
17240
- const resolvedKeys = [...audit.resolvedKeys];
17241
- if (unresolved.length > 0 && stateProvider.resolveDeployedFunctionEnv) {
17242
- const physicalId = loaded.resources[lambda.logicalId]?.physicalId;
17243
- if (physicalId) {
17244
- const deployedEnv = await stateProvider.resolveDeployedFunctionEnv(physicalId);
17245
- const fb = applyDeployedEnvFallback(templateEnv, unresolved, deployedEnv);
17246
- templateEnv = fb.env;
17247
- unresolved = fb.stillUnresolved;
17248
- for (const key of fb.filled) {
17249
- resolvedKeys.push(key);
17250
- logger.debug(`${label}: filled env var ${key} from deployed function config`);
17251
- }
17252
- }
17253
- }
17254
- stateAudit = {
17255
- resolvedKeys,
17256
- unresolved,
17257
- sensitiveKeys: audit.sensitiveKeys
17258
- };
17259
- for (const { key, reason } of unresolved) logger.warn(`${label}: could not substitute env var ${key} (${reason}). Override it via --env-vars or it will be dropped.`);
17260
- }
17261
- } catch (err) {
17262
- stateProvider.dispose();
17263
- throw err;
17264
- }
17265
- const overrides = readEnvOverridesFile$3(options.envVars);
17266
- const lambdaCdkPath = readCdkPathOrUndefined(lambda.resource);
17267
- const envResult = resolveEnvVars$1(lambda.logicalId, lambdaCdkPath, templateEnv, overrides);
17268
- for (const key of envResult.unresolved) {
17269
- if (stateAudit && stateAudit.unresolved.some((u) => u.key === key)) continue;
17270
- const overrideKeyExample = lambdaCdkPath?.replace(/\/Resource$/, "") ?? lambda.logicalId;
17271
- logger.warn(`Environment variable ${key} contains a CloudFormation intrinsic and was dropped. Override it with --env-vars (e.g. {"${overrideKeyExample}":{"${key}":"<literal>"}}), or pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to recover deployed values.`);
17272
- }
17273
- let resolvedAssumeRoleArn;
17274
- try {
17275
- resolvedAssumeRoleArn = await resolveAssumeRoleArnForLambda(options.assumeRole, stateForRoleHint, stateProvider, lambda.logicalId);
17276
- } finally {
17277
- stateProvider?.dispose();
17204
+ const containerEnv = await resolveLambdaContainerEnv(lambda, options, profileCredentials, extraStateProviders);
17205
+ const dockerEnv = containerEnv.env;
17206
+ if (options.assumeRole === void 0 && containerEnv.stateForRoleHint) suggestAssumeRoleFromState(containerEnv.stateForRoleHint, lambda.logicalId);
17207
+ if (!containerEnv.assumeRoleApplied && profileCredsFile) {
17208
+ dockerEnv["AWS_SHARED_CREDENTIALS_FILE"] = profileCredsFile.containerPath;
17209
+ dockerEnv["AWS_PROFILE"] = profileCredsFile.profileName;
17278
17210
  }
17279
- if (options.assumeRole === void 0 && stateForRoleHint) suggestAssumeRoleFromState(stateForRoleHint, lambda.logicalId);
17280
17211
  const event = await readEvent$1(options);
17281
- const dockerEnv = {
17282
- AWS_LAMBDA_FUNCTION_NAME: lambda.logicalId,
17283
- AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(lambda.memoryMb),
17284
- AWS_LAMBDA_FUNCTION_TIMEOUT: String(lambda.timeoutSec),
17285
- AWS_LAMBDA_FUNCTION_VERSION: "$LATEST",
17286
- AWS_LAMBDA_LOG_GROUP_NAME: `/aws/lambda/${lambda.logicalId}`,
17287
- AWS_LAMBDA_LOG_STREAM_NAME: "local",
17288
- ...envResult.resolved
17289
- };
17290
- let assumeSucceeded = false;
17291
- if (resolvedAssumeRoleArn) {
17292
- const stsRegion = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"];
17293
- try {
17294
- const creds = await assumeLambdaExecutionRole(resolvedAssumeRoleArn, stsRegion, options.profile);
17295
- dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
17296
- dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
17297
- dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
17298
- if (stsRegion) dockerEnv["AWS_REGION"] = stsRegion;
17299
- assumeSucceeded = true;
17300
- } catch (err) {
17301
- const reason = err instanceof Error ? err.message : String(err);
17302
- logger.warn(`--assume-role: STS AssumeRole(${resolvedAssumeRoleArn}) failed: ${reason}. Falling back to the developer's shell credentials.`);
17303
- }
17304
- }
17305
- if (!assumeSucceeded) {
17306
- forwardAwsEnv$2(dockerEnv);
17307
- applyProfileCredentialsOverlay(dockerEnv, profileCredentials, false);
17308
- if (profileCredsFile) {
17309
- dockerEnv["AWS_SHARED_CREDENTIALS_FILE"] = profileCredsFile.containerPath;
17310
- dockerEnv["AWS_PROFILE"] = profileCredsFile.profileName;
17311
- }
17312
- }
17313
- if (!dockerEnv["AWS_REGION"] && !dockerEnv["AWS_DEFAULT_REGION"]) {
17314
- const fallbackRegion = resolveContainerFallbackRegion({
17315
- stackRegionOverride: options.region,
17316
- synthRegion: lambda.stack.region,
17317
- profileRegion: profileCredentials?.region
17318
- });
17319
- if (fallbackRegion) dockerEnv["AWS_REGION"] = fallbackRegion;
17320
- }
17321
17212
  let debugPort;
17322
17213
  if (options.debugPort) {
17323
17214
  debugPort = Number(options.debugPort);
@@ -17339,7 +17230,7 @@ async function localInvokeCommand(target, options, extraStateProviders) {
17339
17230
  mounts: imagePlan.mounts,
17340
17231
  extraMounts: extraMountsWithProfile,
17341
17232
  env: dockerEnv,
17342
- ...stateAudit && stateAudit.sensitiveKeys.length > 0 && { sensitiveEnvKeys: new Set(stateAudit.sensitiveKeys) },
17233
+ ...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) },
17343
17234
  cmd: imagePlan.cmd,
17344
17235
  hostPort,
17345
17236
  host: containerHost,
@@ -17627,6 +17518,141 @@ function applyProfileCredentialsOverlay(env, profileCreds, assumeRoleActive) {
17627
17518
  if (profileCreds.sessionToken) env["AWS_SESSION_TOKEN"] = profileCreds.sessionToken;
17628
17519
  else delete env["AWS_SESSION_TOKEN"];
17629
17520
  }
17521
+ /**
17522
+ * Resolve the full container environment for a Lambda: its declared env vars
17523
+ * (literal + `--env-vars` overrides + intrinsic values substituted against a
17524
+ * `--from-cfn-stack` deployed stack — SSM / cross-stack / deployed-env
17525
+ * fallback included), the `AWS_LAMBDA_*` runtime vars, and AWS credentials
17526
+ * (an `--assume-role` STS assume, else the dev shell's forwarded creds + a
17527
+ * `--profile` overlay), plus a fallback `AWS_REGION`.
17528
+ *
17529
+ * This is the single source of truth shared by `cdkl invoke` AND the
17530
+ * front-door Lambda boot path (`start-cloudfront`'s Function URL origin,
17531
+ * `start-alb`'s Lambda targets — issue #380), so a CDN- / ALB-fronted Lambda
17532
+ * reaches the same deployed resources as a direct `cdkl invoke`. The caller
17533
+ * layers any command-specific concerns (a `--profile` credentials-file
17534
+ * bind-mount, `--debug-port`) on top of `env`.
17535
+ */
17536
+ async function resolveLambdaContainerEnv(lambda, options, profileCredentials, extraStateProviders) {
17537
+ const logger = getLogger();
17538
+ let stateAudit;
17539
+ let templateEnv = getTemplateEnv(lambda.resource);
17540
+ let stateForRoleHint;
17541
+ const stateProvider = createLocalStateProvider(options, lambda.stack.stackName, await resolveCfnFallbackRegion(options, lambda.stack.region), extraStateProviders);
17542
+ if (stateProvider) try {
17543
+ const loaded = await stateProvider.load(lambda.stack.stackName, lambda.stack.region);
17544
+ if (loaded) {
17545
+ stateForRoleHint = {
17546
+ version: 1,
17547
+ stackName: lambda.stack.stackName,
17548
+ resources: loaded.resources,
17549
+ outputs: loaded.outputs,
17550
+ lastModified: 0
17551
+ };
17552
+ const subContext = {
17553
+ resources: loaded.resources,
17554
+ consumerRegion: loaded.region
17555
+ };
17556
+ if (envHasIntrinsicValue(templateEnv)) {
17557
+ const pseudo = await resolvePseudoParametersForInvoke(lambda.stack.region, options);
17558
+ if (pseudo) subContext.pseudoParameters = pseudo;
17559
+ }
17560
+ if (envHasIntrinsicValue(templateEnv) && stateProvider.resolveTemplateSsmParameters) {
17561
+ const ssmParams = await stateProvider.resolveTemplateSsmParameters(lambda.stack.template);
17562
+ if (Object.keys(ssmParams.values).length > 0) subContext.parameters = ssmParams.values;
17563
+ if (ssmParams.secureStringLogicalIds.length > 0) subContext.sensitiveParameters = new Set(ssmParams.secureStringLogicalIds);
17564
+ }
17565
+ if (envHasCrossStackIntrinsic(templateEnv)) {
17566
+ const resolver = await stateProvider.buildCrossStackResolver(loaded.region);
17567
+ if (resolver) subContext.crossStackResolver = resolver;
17568
+ }
17569
+ const { env, audit } = await substituteEnvVarsFromStateAsync(templateEnv, subContext);
17570
+ templateEnv = env;
17571
+ const label = stateProvider.label;
17572
+ for (const key of audit.resolvedKeys) logger.debug(`${label}: substituted env var ${key}`);
17573
+ let unresolved = audit.unresolved;
17574
+ const resolvedKeys = [...audit.resolvedKeys];
17575
+ if (unresolved.length > 0 && stateProvider.resolveDeployedFunctionEnv) {
17576
+ const physicalId = loaded.resources[lambda.logicalId]?.physicalId;
17577
+ if (physicalId) {
17578
+ const deployedEnv = await stateProvider.resolveDeployedFunctionEnv(physicalId);
17579
+ const fb = applyDeployedEnvFallback(templateEnv, unresolved, deployedEnv);
17580
+ templateEnv = fb.env;
17581
+ unresolved = fb.stillUnresolved;
17582
+ for (const key of fb.filled) {
17583
+ resolvedKeys.push(key);
17584
+ logger.debug(`${label}: filled env var ${key} from deployed function config`);
17585
+ }
17586
+ }
17587
+ }
17588
+ stateAudit = {
17589
+ resolvedKeys,
17590
+ unresolved,
17591
+ sensitiveKeys: audit.sensitiveKeys
17592
+ };
17593
+ for (const { key, reason } of unresolved) logger.warn(`${label}: could not substitute env var ${key} (${reason}). Override it via --env-vars or it will be dropped.`);
17594
+ }
17595
+ } catch (err) {
17596
+ stateProvider.dispose();
17597
+ throw err;
17598
+ }
17599
+ const overrides = readEnvOverridesFile$3(options.envVars);
17600
+ const lambdaCdkPath = readCdkPathOrUndefined(lambda.resource);
17601
+ const envResult = resolveEnvVars$1(lambda.logicalId, lambdaCdkPath, templateEnv, overrides);
17602
+ for (const key of envResult.unresolved) {
17603
+ if (stateAudit && stateAudit.unresolved.some((u) => u.key === key)) continue;
17604
+ const overrideKeyExample = lambdaCdkPath?.replace(/\/Resource$/, "") ?? lambda.logicalId;
17605
+ logger.warn(`Environment variable ${key} contains a CloudFormation intrinsic and was dropped. Override it with --env-vars (e.g. {"${overrideKeyExample}":{"${key}":"<literal>"}}), or pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to recover deployed values.`);
17606
+ }
17607
+ let resolvedAssumeRoleArn;
17608
+ try {
17609
+ resolvedAssumeRoleArn = await resolveAssumeRoleArnForLambda(options.assumeRole, stateForRoleHint, stateProvider, lambda.logicalId);
17610
+ } finally {
17611
+ stateProvider?.dispose();
17612
+ }
17613
+ const dockerEnv = {
17614
+ AWS_LAMBDA_FUNCTION_NAME: lambda.logicalId,
17615
+ AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(lambda.memoryMb),
17616
+ AWS_LAMBDA_FUNCTION_TIMEOUT: String(lambda.timeoutSec),
17617
+ AWS_LAMBDA_FUNCTION_VERSION: "$LATEST",
17618
+ AWS_LAMBDA_LOG_GROUP_NAME: `/aws/lambda/${lambda.logicalId}`,
17619
+ AWS_LAMBDA_LOG_STREAM_NAME: "local",
17620
+ ...envResult.resolved
17621
+ };
17622
+ let assumeSucceeded = false;
17623
+ if (resolvedAssumeRoleArn) {
17624
+ const stsRegion = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"];
17625
+ try {
17626
+ const creds = await assumeLambdaExecutionRole(resolvedAssumeRoleArn, stsRegion, options.profile);
17627
+ dockerEnv["AWS_ACCESS_KEY_ID"] = creds.accessKeyId;
17628
+ dockerEnv["AWS_SECRET_ACCESS_KEY"] = creds.secretAccessKey;
17629
+ dockerEnv["AWS_SESSION_TOKEN"] = creds.sessionToken;
17630
+ if (stsRegion) dockerEnv["AWS_REGION"] = stsRegion;
17631
+ assumeSucceeded = true;
17632
+ } catch (err) {
17633
+ const reason = err instanceof Error ? err.message : String(err);
17634
+ logger.warn(`--assume-role: STS AssumeRole(${resolvedAssumeRoleArn}) failed: ${reason}. Falling back to the developer's shell credentials.`);
17635
+ }
17636
+ }
17637
+ if (!assumeSucceeded) {
17638
+ forwardAwsEnv$2(dockerEnv);
17639
+ applyProfileCredentialsOverlay(dockerEnv, profileCredentials, false);
17640
+ }
17641
+ if (!dockerEnv["AWS_REGION"] && !dockerEnv["AWS_DEFAULT_REGION"]) {
17642
+ const fallbackRegion = resolveContainerFallbackRegion({
17643
+ stackRegionOverride: options.region,
17644
+ synthRegion: lambda.stack.region,
17645
+ profileRegion: profileCredentials?.region
17646
+ });
17647
+ if (fallbackRegion) dockerEnv["AWS_REGION"] = fallbackRegion;
17648
+ }
17649
+ return {
17650
+ env: dockerEnv,
17651
+ sensitiveEnvKeys: stateAudit?.sensitiveKeys ?? [],
17652
+ ...stateForRoleHint !== void 0 && { stateForRoleHint },
17653
+ assumeRoleApplied: assumeSucceeded
17654
+ };
17655
+ }
17630
17656
  function materializeInlineCode$1(handler, source, fileExtension) {
17631
17657
  const lastDot = handler.lastIndexOf(".");
17632
17658
  if (lastDot <= 0) throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);
@@ -24435,7 +24461,7 @@ function createFrontDoorLambdaRunner(lambda, opts) {
24435
24461
  const port = await pickFreePort();
24436
24462
  hostPort = port;
24437
24463
  const name = `${getEmbedConfig().resourceNamePrefix}-alblambda-${lambda.logicalId}-${process.pid}-${Math.floor(Math.random() * 1e6)}`;
24438
- const env = {
24464
+ const env = opts.containerEnv ? { ...opts.containerEnv } : {
24439
24465
  AWS_LAMBDA_FUNCTION_NAME: lambda.logicalId,
24440
24466
  AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(lambda.memoryMb),
24441
24467
  AWS_LAMBDA_FUNCTION_TIMEOUT: String(lambda.timeoutSec),
@@ -24449,6 +24475,7 @@ function createFrontDoorLambdaRunner(lambda, opts) {
24449
24475
  image: plan.image,
24450
24476
  mounts: plan.mounts,
24451
24477
  env,
24478
+ ...opts.sensitiveEnvKeys && opts.sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys: opts.sensitiveEnvKeys },
24452
24479
  cmd: plan.cmd,
24453
24480
  hostPort: port,
24454
24481
  host: opts.containerHost,
@@ -28959,10 +28986,14 @@ async function bootLambdaUrlOrigins(distribution, stacks, opts) {
28959
28986
  for (const functionLogicalId of functionLogicalIds) {
28960
28987
  let runner;
28961
28988
  try {
28962
- runner = createFrontDoorLambdaRunner(resolveLambdaTarget(functionLogicalId, stacks), {
28989
+ const lambda = resolveLambdaTarget(functionLogicalId, stacks);
28990
+ const containerEnv = await resolveLambdaContainerEnv(lambda, opts.envOptions, opts.profileCredentials);
28991
+ runner = createFrontDoorLambdaRunner(lambda, {
28963
28992
  containerHost: opts.containerHost,
28964
28993
  skipPull: opts.skipPull,
28965
- ...opts.region !== void 0 && { region: opts.region }
28994
+ ...opts.envOptions.region !== void 0 && { region: opts.envOptions.region },
28995
+ containerEnv: containerEnv.env,
28996
+ ...containerEnv.sensitiveEnvKeys.length > 0 && { sensitiveEnvKeys: new Set(containerEnv.sensitiveEnvKeys) }
28966
28997
  });
28967
28998
  logger.info(`Booting Lambda Function URL origin container for ${functionLogicalId} (the backing Lambda runs locally via RIE)...`);
28968
28999
  await runner.start();
@@ -29030,10 +29061,19 @@ async function localStartCloudFrontCommand(target, options) {
29030
29061
  };
29031
29062
  const initial = await synthAndResolve();
29032
29063
  warnUnsupported(initial.distribution);
29064
+ const profileCredentials = options.profile ? await resolveProfileCredentials(options.profile) : void 0;
29065
+ const envOptions = {
29066
+ ...options.fromCfnStack !== void 0 && { fromCfnStack: options.fromCfnStack },
29067
+ ...options.assumeRole !== void 0 && { assumeRole: options.assumeRole },
29068
+ ...options.region !== void 0 && { region: options.region },
29069
+ ...options.profile !== void 0 && { profile: options.profile },
29070
+ ...options.stackRegion !== void 0 && { stackRegion: options.stackRegion }
29071
+ };
29033
29072
  const { invokers: lambdaInvokers, runners: lambdaRunners } = await bootLambdaUrlOrigins(initial.distribution, initial.stacks, {
29034
29073
  containerHost: options.host,
29035
29074
  skipPull: options.pull === false,
29036
- ...options.region !== void 0 && { region: options.region }
29075
+ envOptions,
29076
+ ...profileCredentials !== void 0 && { profileCredentials }
29037
29077
  });
29038
29078
  let tls;
29039
29079
  if (tlsRequested) tls = await resolveFrontDoorTlsMaterials({
@@ -29121,7 +29161,7 @@ function createLocalStartCloudFrontCommand(opts = {}) {
29121
29161
  * `cmd`.
29122
29162
  */
29123
29163
  function addStartCloudFrontSpecificOptions(cmd) {
29124
- return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--no-pull", "Skip 'docker pull' for a Lambda Function URL origin's base image (use the locally cached image).")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
29164
+ return cmd.addOption(new Option("--port <port>", "HTTP server port (default: auto-allocate)").default("0")).addOption(new Option("--host <host>", "Bind address").default("127.0.0.1")).addOption(new Option("--origin <originId=dir>", "Point a distribution origin at a local directory (repeatable). Use when cdk-local cannot resolve the origin's BucketDeployment source automatically (content uploaded out of band, or a non-CDK bucket).").argParser((value, prev) => [...prev ?? [], value])).addOption(new Option("--tls", "Terminate real TLS (HTTPS). Uses --tls-cert / --tls-key when supplied, else an auto-generated self-signed cert.").default(false)).addOption(new Option("--tls-cert <path>", "PEM server certificate for --tls (implies --tls).")).addOption(new Option("--tls-key <path>", "PEM server private key for --tls (implies --tls).")).addOption(new Option("--no-pull", "Skip 'docker pull' for a Lambda Function URL origin's base image (use the locally cached image).")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Bind a Lambda Function URL origin's backing Lambda to a deployed CloudFormation stack so its env vars resolve to the deployed physical IDs / exports (ListStackResources). Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass a value when the CFn stack name differs. No effect on a pure-S3 distribution.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--assume-role [arn]", "Assume a Lambda Function URL origin's deployed execution role and forward STS-issued temp credentials into its container so the handler runs with the deployed permissions. Three forms: `--assume-role <arn>` (explicit ARN); `--assume-role` (bare, auto-resolves from state — requires --from-cfn-stack); `--no-assume-role` (opt out). Off by default (the dev shell credentials are forwarded).")).addOption(new Option("--watch", "Hot-reload: re-synth + re-resolve the distribution when the CDK app's source changes (honors cdk.json watch.include/exclude; cdk.out, node_modules, .git are always excluded). The server keeps the previous version serving when synth fails mid-reload.").default(false));
29125
29165
  }
29126
29166
 
29127
29167
  //#endregion
@@ -30236,11 +30276,12 @@ const STUDIO_SCRIPT = `
30236
30276
  // --image-override flag to start-service so the deployed-registry-pinned
30237
30277
  // image is rebuilt from local source. Default "(keep pinned image)" => no
30238
30278
  // override.
30239
- function buildImageOverridePicker() {
30240
- const sec = el('div', 'section options');
30241
- sec.appendChild(el('h3', null, 'Image override'));
30279
+ // One labeled Dockerfile <select> row (the discovered Dockerfiles + a
30280
+ // "(keep pinned image)" default). Shared by the ecs single picker and the
30281
+ // alb per-backing-service pickers.
30282
+ function buildImageOverrideRow(labelText) {
30242
30283
  const row = el('div', 'opt-row');
30243
- row.appendChild(el('span', 'opt-label', 'Local Dockerfile'));
30284
+ row.appendChild(el('span', 'opt-label', labelText));
30244
30285
  const sel = el('select', 'image-override-select');
30245
30286
  const none = el('option', null, '(keep pinned image)');
30246
30287
  none.value = '';
@@ -30251,7 +30292,19 @@ const STUDIO_SCRIPT = `
30251
30292
  sel.appendChild(o);
30252
30293
  });
30253
30294
  row.appendChild(sel);
30254
- sec.appendChild(row);
30295
+ return {
30296
+ row: row,
30297
+ getValue: function () {
30298
+ return sel.value.trim();
30299
+ },
30300
+ };
30301
+ }
30302
+
30303
+ function buildImageOverridePicker() {
30304
+ const sec = el('div', 'section options');
30305
+ sec.appendChild(el('h3', null, 'Image override'));
30306
+ const r = buildImageOverrideRow('Local Dockerfile');
30307
+ sec.appendChild(r.row);
30255
30308
  const hint = studioDockerfiles.length
30256
30309
  ? 'This image is pinned to a deployed registry — local edits do not take effect. Pick a Dockerfile to rebuild it locally.'
30257
30310
  : 'This image is pinned to a deployed registry, but no Dockerfile was found under the app directory.';
@@ -30259,12 +30312,41 @@ const STUDIO_SCRIPT = `
30259
30312
  return {
30260
30313
  node: sec,
30261
30314
  collect: function () {
30262
- const v = sel.value.trim();
30315
+ const v = r.getValue();
30263
30316
  return v === '' ? undefined : v;
30264
30317
  },
30265
30318
  };
30266
30319
  }
30267
30320
 
30321
+ // Per-backing-service image-override pickers for a pinned ALB (issue #382):
30322
+ // one Dockerfile select per deployed-registry-pinned service the ALB fronts.
30323
+ // collect() returns a { [serviceId]: dockerfile } map threaded as
30324
+ // imageOverrides (one --image-override service=df per entry).
30325
+ function buildAlbImageOverridePicker(services) {
30326
+ const sec = el('div', 'section options');
30327
+ sec.appendChild(el('h3', null, 'Image override (pinned backing services)'));
30328
+ const rows = services.map(function (svc) {
30329
+ const r = buildImageOverrideRow(svc.label);
30330
+ sec.appendChild(r.row);
30331
+ return { id: svc.id, getValue: r.getValue };
30332
+ });
30333
+ const hint = studioDockerfiles.length
30334
+ ? 'These services behind the ALB are pinned to a deployed registry — local edits do not take effect. Pick a Dockerfile to rebuild one from local source.'
30335
+ : 'These services behind the ALB are pinned to a deployed registry, but no Dockerfile was found under the app directory.';
30336
+ sec.appendChild(el('div', 'opt-hint', hint));
30337
+ return {
30338
+ node: sec,
30339
+ collect: function () {
30340
+ const map = {};
30341
+ rows.forEach(function (r) {
30342
+ const v = r.getValue();
30343
+ if (v !== '') map[r.id] = v;
30344
+ });
30345
+ return Object.keys(map).length ? map : undefined;
30346
+ },
30347
+ };
30348
+ }
30349
+
30268
30350
  // Toggle one target group's body open/closed (groups are collapsed by
30269
30351
  // default so a big Lambda list does not push the APIs below the fold).
30270
30352
  function toggleGroup(titleEl, bodyEl) {
@@ -30350,7 +30432,13 @@ const STUDIO_SCRIPT = `
30350
30432
  t.appendChild(btnSlot);
30351
30433
  t.onclick = () => selectTarget(entry.id, group.kind);
30352
30434
  targetEls.set(entry.id, t);
30353
- serveMeta.set(entry.id, { dot, btnSlot, kind: group.kind, pinned: entry.pinned === true });
30435
+ serveMeta.set(entry.id, {
30436
+ dot,
30437
+ btnSlot,
30438
+ kind: group.kind,
30439
+ pinned: entry.pinned === true,
30440
+ backingPinnedServices: entry.backingPinnedServices || [],
30441
+ });
30354
30442
  updateServeRow(entry.id);
30355
30443
  }
30356
30444
  body.appendChild(t);
@@ -30487,6 +30575,14 @@ const STUDIO_SCRIPT = `
30487
30575
  if (applied && applied.imageOverride) {
30488
30576
  lines.push('--image-override ' + applied.imageOverride);
30489
30577
  }
30578
+ // An alb serve threads a per-backing-service imageOverrides map (issue
30579
+ // #382); surface one --image-override line each so the picks do not
30580
+ // silently vanish from the running view (the issue #356 contract).
30581
+ if (applied && applied.imageOverrides) {
30582
+ Object.keys(applied.imageOverrides).forEach(function (svc) {
30583
+ lines.push('--image-override ' + svc + '=' + applied.imageOverrides[svc]);
30584
+ });
30585
+ }
30490
30586
  if (applied && applied.rawArgs) {
30491
30587
  const raw = String(applied.rawArgs).trim();
30492
30588
  if (raw !== '') lines.push(raw);
@@ -30494,7 +30590,7 @@ const STUDIO_SCRIPT = `
30494
30590
  return lines;
30495
30591
  }
30496
30592
 
30497
- async function startServe(id, options, rawArgs, imageOverride) {
30593
+ async function startServe(id, options, rawArgs, imageOverride, imageOverrides) {
30498
30594
  // The serve kind (api / alb / ecs) drives which headless command the
30499
30595
  // server spawns; it is recorded on the row when the target list loads.
30500
30596
  const meta = serveMeta.get(id);
@@ -30502,7 +30598,12 @@ const STUDIO_SCRIPT = `
30502
30598
  // Remember what this serve was Started with so the running workspace can
30503
30599
  // show a read-only "Started with" summary (issue #356) — the per-run
30504
30600
  // option inputs are gone once the composer is replaced by the running view.
30505
- serveApplied.set(id, { options: options, rawArgs: rawArgs, imageOverride: imageOverride });
30601
+ serveApplied.set(id, {
30602
+ options: options,
30603
+ rawArgs: rawArgs,
30604
+ imageOverride: imageOverride,
30605
+ imageOverrides: imageOverrides,
30606
+ });
30506
30607
  serveState.set(id, { status: 'starting', endpoints: [] });
30507
30608
  updateServeRow(id);
30508
30609
  try {
@@ -30510,6 +30611,7 @@ const STUDIO_SCRIPT = `
30510
30611
  if (options) body.options = options;
30511
30612
  if (rawArgs) body.rawArgs = rawArgs;
30512
30613
  if (imageOverride) body.imageOverride = imageOverride;
30614
+ if (imageOverrides) body.imageOverrides = imageOverrides;
30513
30615
  const res = await fetch('/api/run', {
30514
30616
  method: 'POST',
30515
30617
  headers: { 'content-type': 'application/json' },
@@ -30585,6 +30687,7 @@ const STUDIO_SCRIPT = `
30585
30687
  let collectOpts = function () { return undefined; };
30586
30688
  let collectRaw = function () { return undefined; };
30587
30689
  let collectImageOverride = function () { return undefined; };
30690
+ let collectImageOverrides = function () { return undefined; };
30588
30691
  btn.onclick = () => {
30589
30692
  if (running || starting) {
30590
30693
  stopServe(id);
@@ -30595,7 +30698,7 @@ const STUDIO_SCRIPT = `
30595
30698
  serveState.set(id, { status: 'stopped', endpoints: [] });
30596
30699
  renderServeWorkspace(id);
30597
30700
  } else {
30598
- startServe(id, collectOpts(), collectRaw(), collectImageOverride());
30701
+ startServe(id, collectOpts(), collectRaw(), collectImageOverride(), collectImageOverrides());
30599
30702
  }
30600
30703
  };
30601
30704
  head.appendChild(btn);
@@ -30615,6 +30718,15 @@ const STUDIO_SCRIPT = `
30615
30718
  ws.appendChild(io.node);
30616
30719
  collectImageOverride = io.collect;
30617
30720
  }
30721
+ // An ALB boots its backing ECS services (issue #382); a pinned backing
30722
+ // service has the same "local edits do not take effect" problem, so offer
30723
+ // a per-service Dockerfile picker that threads
30724
+ // --image-override service=dockerfile to start-alb.
30725
+ if (meta && meta.kind === 'alb' && meta.backingPinnedServices && meta.backingPinnedServices.length) {
30726
+ const io = buildAlbImageOverridePicker(meta.backingPinnedServices);
30727
+ ws.appendChild(io.node);
30728
+ collectImageOverrides = io.collect;
30729
+ }
30618
30730
  const opt = buildOptions(kind);
30619
30731
  if (opt.node) ws.appendChild(opt.node);
30620
30732
  collectOpts = opt.collect;
@@ -31798,6 +31910,34 @@ function annotatePinnedEcsTargets(groups, classify) {
31798
31910
  }
31799
31911
  return anyPinned;
31800
31912
  }
31913
+ /**
31914
+ * Annotate each `alb` entry of `groups` with the deployed-registry-pinned ECS
31915
+ * services that ALB fronts (issue #382), so the alb composer can offer a
31916
+ * per-service image-override Dockerfile picker. `resolveBackingPinned` maps one
31917
+ * ALB entry to its pinned backing services (`{ id, label }`, where `id` is the
31918
+ * `--image-override` key — `start-alb`'s `Stack:LogicalId` service-boot
31919
+ * target); the caller supplies it (studio's boot resolves the ALB via
31920
+ * `resolveAlbFrontDoor` and intersects the backing services with the already-
31921
+ * classified pinned `ecs` set). Mutates the entries in place and returns whether
31922
+ * ANY ALB fronts a pinned service, so the caller can include the Dockerfile
31923
+ * scan even when no standalone `ecs` service was pinned. Non-alb groups are
31924
+ * left untouched. Exported so a host CLI can reuse it + so the boot logic is
31925
+ * unit-testable without a real synth.
31926
+ */
31927
+ function annotateAlbPinnedBackingServices(groups, resolveBackingPinned) {
31928
+ let any = false;
31929
+ for (const group of groups) {
31930
+ if (group.kind !== "alb") continue;
31931
+ for (const entry of group.entries) {
31932
+ const pinned = resolveBackingPinned(entry);
31933
+ if (pinned.length > 0) {
31934
+ entry.backingPinnedServices = pinned;
31935
+ any = true;
31936
+ }
31937
+ }
31938
+ }
31939
+ return any;
31940
+ }
31801
31941
  /** Compile a `*` / `?` glob to an anchored RegExp matched against a target id. */
31802
31942
  function globToRegExp(glob) {
31803
31943
  const escaped = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
@@ -32911,6 +33051,7 @@ function createStudioServeManager(config) {
32911
33051
  ...buildPerRunArgs(req.kind, req.options),
32912
33052
  ...envFile ? ["--env-vars", envFile] : [],
32913
33053
  ...req.imageOverride && req.imageOverride.trim() !== "" ? ["--image-override", req.targetId + "=" + req.imageOverride.trim()] : [],
33054
+ ...Object.entries(req.imageOverrides ?? {}).flatMap(([svc, df]) => df && df.trim() !== "" ? ["--image-override", svc + "=" + df.trim()] : []),
32914
33055
  ...config.watch === true ? ["--watch"] : [],
32915
33056
  ...tokenizeRawArgs(req.rawArgs)
32916
33057
  ];
@@ -33156,7 +33297,7 @@ const STUDIO_TARGET_KINDS = [
33156
33297
  */
33157
33298
  function coerceRunRequest(body) {
33158
33299
  if (typeof body !== "object" || body === null) throw new Error("Request body must be a JSON object.");
33159
- const { targetId, kind, event, options, rawArgs, imageOverride } = body;
33300
+ const { targetId, kind, event, options, rawArgs, imageOverride, imageOverrides } = body;
33160
33301
  if (typeof targetId !== "string" || targetId.trim() === "") throw new Error("Request body must include a non-empty \"targetId\" string.");
33161
33302
  if (typeof kind !== "string" || !STUDIO_TARGET_KINDS.includes(kind)) throw new Error(`Request body "kind" must be one of: ${STUDIO_TARGET_KINDS.join(", ")}.`);
33162
33303
  let runOptions;
@@ -33177,13 +33318,24 @@ function coerceRunRequest(body) {
33177
33318
  if (typeof imageOverride !== "string") throw new Error("Request body \"imageOverride\" must be a string.");
33178
33319
  if (imageOverride.trim() !== "") runImageOverride = imageOverride;
33179
33320
  }
33321
+ let runImageOverrides;
33322
+ if (imageOverrides !== void 0) {
33323
+ if (typeof imageOverrides !== "object" || imageOverrides === null || Array.isArray(imageOverrides)) throw new Error("Request body \"imageOverrides\" must be a JSON object keyed by service id.");
33324
+ const collected = {};
33325
+ for (const [svc, df] of Object.entries(imageOverrides)) {
33326
+ if (typeof df !== "string") throw new Error(`Request body "imageOverrides.${svc}" must be a string.`);
33327
+ if (df.trim() !== "") collected[svc] = df.trim();
33328
+ }
33329
+ if (Object.keys(collected).length > 0) runImageOverrides = collected;
33330
+ }
33180
33331
  return {
33181
33332
  targetId,
33182
33333
  kind,
33183
33334
  event,
33184
33335
  ...runOptions !== void 0 ? { options: runOptions } : {},
33185
33336
  ...runRawArgs !== void 0 ? { rawArgs: runRawArgs } : {},
33186
- ...runImageOverride !== void 0 ? { imageOverride: runImageOverride } : {}
33337
+ ...runImageOverride !== void 0 ? { imageOverride: runImageOverride } : {},
33338
+ ...runImageOverrides !== void 0 ? { imageOverrides: runImageOverrides } : {}
33187
33339
  };
33188
33340
  }
33189
33341
  /**
@@ -33463,6 +33615,48 @@ function makePinClassifier(args) {
33463
33615
  }
33464
33616
  };
33465
33617
  }
33618
+ /**
33619
+ * Build the boot-time resolver `annotateAlbPinnedBackingServices` calls per
33620
+ * `alb` entry (issue #382). It resolves the ALB to its backing ECS services
33621
+ * (`resolveAlbFrontDoor`, template-only) and returns the subset that is in
33622
+ * `pinnedEcsByQualifiedId` — the `ecs` services already classified as a
33623
+ * deployed-registry pin by {@link makePinClassifier}. Each returned `id` is the
33624
+ * service's `Stack:LogicalId` (the `--image-override` key `start-alb` matches
33625
+ * against its own service-boot target); `label` is the pinned service's display
33626
+ * id. An ALB that cannot be resolved is WARN-logged + contributes no pickers
33627
+ * (the start-alb run still works; only the picker is absent). Exported for
33628
+ * testing.
33629
+ */
33630
+ function makeAlbBackingPinnedResolver(args) {
33631
+ const { stacks, pinnedEcsByQualifiedId, logger } = args;
33632
+ return (albEntry) => {
33633
+ if (pinnedEcsByQualifiedId.size === 0) return [];
33634
+ try {
33635
+ const { stack, albLogicalId } = resolveAlbTarget(albEntry.id, stacks);
33636
+ const resolution = resolveAlbFrontDoor(stack, albLogicalId);
33637
+ const serviceQualifiedIds = /* @__PURE__ */ new Set();
33638
+ for (const listener of resolution.listeners) {
33639
+ const actions = [...listener.defaultAction ? [listener.defaultAction] : [], ...listener.rules.map((r) => r.action)];
33640
+ for (const action of actions) {
33641
+ if (action.kind !== "forward") continue;
33642
+ for (const t of action.targets) if (t.kind === "ecs") serviceQualifiedIds.add(`${stack.stackName}:${t.serviceLogicalId}`);
33643
+ }
33644
+ }
33645
+ const out = [];
33646
+ for (const qid of serviceQualifiedIds) {
33647
+ const label = pinnedEcsByQualifiedId.get(qid);
33648
+ if (label !== void 0) out.push({
33649
+ id: qid,
33650
+ label
33651
+ });
33652
+ }
33653
+ return out;
33654
+ } catch (err) {
33655
+ logger.warn(`studio: could not resolve ALB '${albEntry.id}' backing services for the image-override picker; the alb composer will not offer one. ${err instanceof Error ? err.message : String(err)}`);
33656
+ return [];
33657
+ }
33658
+ };
33659
+ }
33466
33660
  async function localStudioCommand(options) {
33467
33661
  const logger = getLogger();
33468
33662
  if (options.verbose) logger.setLevel("debug");
@@ -33499,7 +33693,7 @@ async function localStudioCommand(options) {
33499
33693
  }
33500
33694
  const appLabel = stacks.map((s) => s.stackName).join(", ") || appCmd;
33501
33695
  const servableEcs = new Set(targetGroups.filter((g) => g.kind === "ecs").flatMap((g) => g.entries.filter((e) => e.servable).map((e) => e.id)));
33502
- const dockerfiles = annotatePinnedEcsTargets(targetGroups, makePinClassifier({
33696
+ const anyPinned = annotatePinnedEcsTargets(targetGroups, makePinClassifier({
33503
33697
  stacks,
33504
33698
  contextByStack: await prepareEcsImageContexts({
33505
33699
  serviceIds: [...servableEcs],
@@ -33508,7 +33702,18 @@ async function localStudioCommand(options) {
33508
33702
  logger
33509
33703
  }),
33510
33704
  logger
33511
- })) ? discoverDockerfiles(process.cwd()) : [];
33705
+ }));
33706
+ const pinnedEcsByQualifiedId = /* @__PURE__ */ new Map();
33707
+ for (const g of targetGroups) {
33708
+ if (g.kind !== "ecs") continue;
33709
+ for (const e of g.entries) if (e.pinned) pinnedEcsByQualifiedId.set(e.qualifiedId, e.id);
33710
+ }
33711
+ const anyAlbBackingPinned = annotateAlbPinnedBackingServices(targetGroups, makeAlbBackingPinnedResolver({
33712
+ stacks,
33713
+ pinnedEcsByQualifiedId,
33714
+ logger
33715
+ }));
33716
+ const dockerfiles = anyPinned || anyAlbBackingPinned ? discoverDockerfiles(process.cwd()) : [];
33512
33717
  const bus = new StudioEventBus();
33513
33718
  const childConfig = {
33514
33719
  cliEntry: process.argv[1] ?? "",
@@ -33690,5 +33895,5 @@ function addStudioSpecificOptions(cmd) {
33690
33895
  }
33691
33896
 
33692
33897
  //#endregion
33693
- export { MAX_TASKS_SUBNET_RANGE_CAP as $, buildMessageEvent as $n, createLocalStartApiCommand as $t, startCloudFrontServer as A, buildCorsConfigByApiId as An, discoverRoutes as Ar, A2A_CONTAINER_PORT as At, runViewerResponse as B, pickResponseTemplate as Bn, resolveAgentCoreTarget as Br, AGENTCORE_SESSION_ID_HEADER as Bt, formatTargetListing as C, buildMethodArn as Cn, listTargets as Cr, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as Ct, parseOriginOverrides as D, invokeTokenAuthorizer as Dn, filterWebSocketApisByIdentifiers as Dr, addInvokeAgentCoreSpecificOptions as Dt, createLocalStartCloudFrontCommand as E, invokeRequestAuthorizer as En, discoverWebSocketApisOrThrow as Er, attachContainerLogStreamer as Et, pickFunctionUrlLogicalIdFromOrigin as F, translateLambdaResponse as Fn, AGENTCORE_HTTP_PROTOCOL as Fr, MCP_PROTOCOL_VERSION as Ft, resolveAlbTarget as G, probeHostGatewaySupport as Gn, LocalInvokeBuildError as Gr, buildAgentCoreCodeImage as Gt, albStrategy as H, tryParseStatus as Hn, formatStateRemedy as Hr, waitForAgentCorePing as Ht, pickTargetFunctionLogicalId as I, applyAuthorizerOverlay as In, AGENTCORE_MCP_PROTOCOL as Ir, mcpInvokeOnce as It, addStartServiceSpecificOptions as J, buildMgmtEndpointEnvUrl as Jn, toCmdArgv as Jt, isApplicationLoadBalancer as K, bufferToBody as Kn, buildStsClientConfig as Kr, computeCodeImageTag as Kt, resolveCloudFrontDistribution as L, buildHttpApiV2Event as Ln, AGENTCORE_RUNTIME_TYPE as Lr, parseSseForJsonRpc as Lt, serveLambdaUrlOrigin as M, isFunctionUrlOacFronted as Mn, resolveLambdaArnIntrinsic as Mr, a2aInvokeOnce as Mt, CLOUDFRONT_DISTRIBUTION_TYPE as N, matchPreflight as Nn, AGENTCORE_A2A_PROTOCOL as Nr, MCP_CONTAINER_PORT as Nt, resolveCloudFrontTarget as O, attachAuthorizers as On, parseSelectionExpressionPath as Or, createLocalInvokeAgentCoreCommand as Ot, isCloudFrontDistribution as P, matchRoute as Pn, AGENTCORE_AGUI_PROTOCOL as Pr, MCP_PATH as Pt, createLocalRunTaskCommand as Q, buildDisconnectEvent as Qn, addStartApiSpecificOptions as Qt, compileCloudFrontFunction as R, buildRestV1Event as Rn, AgentCoreResolutionError as Rr, AGENTCORE_SIGV4_SERVICE as Rt, createLocalListCommand as S, verifyJwtViaDiscovery as Sn, countTargets as Sr, DEFAULT_SHADOW_READY_TIMEOUT_MS as St, addStartCloudFrontSpecificOptions as T, evaluateCachedLambdaPolicy as Tn, discoverWebSocketApis as Tr, getContainerNetworkIp as Tt, createLocalStartAlbCommand as U, VtlEvaluationError as Un, substituteImagePlaceholders as Ur, downloadAndExtractS3Bundle as Ut, addAlbSpecificOptions as V, selectIntegrationResponse as Vn, derivePseudoParametersFromRegion as Vr, invokeAgentCore as Vt, parseLbPortOverrides as W, HOST_GATEWAY_MIN_VERSION as Wn, tryResolveImageFnJoin as Wr, SUPPORTED_CODE_RUNTIMES as Wt, serviceStrategy as X, parseConnectionsPath as Xn, addInvokeSpecificOptions as Xt, createLocalStartServiceCommand as Y, handleConnectionsRequest as Yn, classifySourceChange as Yt, addRunTaskSpecificOptions as Z, buildConnectEvent as Zn, createLocalInvokeCommand as Zt, toStudioTargetGroups as _, buildCognitoJwksUrl as _n, CfnLocalStateProvider as _r, describePinnedImageUri as _t, createLocalStudioCommand as a, buildStageMap as an, EcsTaskResolutionError as ar, parseMaxTasks as at, StudioEventBus as b, verifyCognitoJwt as bn, resolveWatchConfig as br, buildCloudMapIndex as bt, startStudioProxy as c, availableApiIdentifiers as cn, substituteEnvVarsFromState as cr, resolveSharedSidecarCredentials as ct, createStudioDispatcher as d, groupRoutesByServer as dn, createLocalStateProvider as dr, buildImageOverrideTag as dt, createWatchPredicates as en, architectureToPlatform as er, addCommonEcsServiceOptions as et, filterStudioCustomResources as f, readMtlsMaterialsFromDisk as fn, isCfnFlagPresent as fr, enforceImageOverrideOrphans as ft, startStudioServer as g, defaultCredentialsLoader as gn, resolveCfnStackName as gr, runImageOverrideBuilds as gt, filterStudioTargetGroups as h, resolveServiceIntegrationParameters as hn, resolveCfnRegion as hr, resolveImageOverrides as ht, coerceStopRequest as i, attachStageContext as in, resolveRuntimeImage as ir, ecsClusterOption as it, serveFromStaticOrigin as j, buildCorsConfigFromCloudFrontChain as jn, pickRefLogicalId as jr, A2A_PATH as jt, matchBehavior as k, applyCorsResponseHeaders as kn, webSocketApiMatchesIdentifier as kr, invokeAgentCoreWs as kt, relayServeRequest as l, filterRoutesByApiIdentifier as ln, substituteEnvVarsFromStateAsync as lr, runEcsServiceEmulator as lt, annotatePinnedEcsTargets as m, resolveSelectionExpression as mn, resolveCfnFallbackRegion as mr, parseImageOverrideFlags as mt, coerceRunRequest as n, createAuthorizerCache as nn, resolveRuntimeCodeMountPath as nr, addImageOverrideOptions as nt, resolveServeBaseUrl as o, materializeLayerFromArn as on, substituteAgainstState as or, parseRestartPolicy as ot, isCustomResourceLambdaTarget as p, startApiServer as pn, rejectExplicitCfnStackWithMultipleStacks as pr, mergeForService as pt, resolveAlbFrontDoor as q, ConnectionRegistry as qn, resolveProfileCredentials as qr, renderCodeDockerfile as qt, coerceServeRequest as r, createFileWatcher as rn, resolveRuntimeFileExtension as rr, buildEcsImageResolutionContext$1 as rt, createStudioServeManager as s, resolveEnvVars$1 as sn, substituteAgainstStateAsync as sr, resolveEcsAssumeRoleOption as st, addStudioSpecificOptions as t, resolveApiTargetSubset as tn, buildContainerImage as tr, addEcsAssumeRoleOptions as tt, reinvoke as u, filterRoutesByApiIdentifiers as un, LocalStateSourceError as ur, ImageOverrideError as ut, renderStudioHtml as v, buildJwksUrlFromIssuer as vn, collectSsmParameterRefs as vr, isLocalCdkAssetImage as vt, LocalStartCloudFrontError as w, computeRequestIdentityHash as wn, availableWebSocketApiIdentifiers as wr, setShadowReadyTimeoutMs as wt, addListSpecificOptions as x, verifyJwtAuthorizer as xn, resolveSingleTarget as xr, CloudMapRegistry as xt, createStudioStore as y, createJwksCache as yn, resolveSsmParameters as yr, listPinnedTargets as yt, runViewerRequest as z, evaluateResponseParameters as zn, pickAgentCoreCandidateStack as zr, signAgentCoreInvocation as zt };
33694
- //# sourceMappingURL=local-studio-BWrmJblg.js.map
33898
+ export { createLocalRunTaskCommand as $, buildDisconnectEvent as $n, addStartApiSpecificOptions as $t, matchBehavior as A, applyCorsResponseHeaders as An, webSocketApiMatchesIdentifier as Ar, invokeAgentCoreWs as At, runViewerRequest as B, evaluateResponseParameters as Bn, pickAgentCoreCandidateStack as Br, signAgentCoreInvocation as Bt, createLocalListCommand as C, verifyJwtViaDiscovery as Cn, countTargets as Cr, DEFAULT_SHADOW_READY_TIMEOUT_MS as Ct, createLocalStartCloudFrontCommand as D, invokeRequestAuthorizer as Dn, discoverWebSocketApisOrThrow as Dr, attachContainerLogStreamer as Dt, addStartCloudFrontSpecificOptions as E, evaluateCachedLambdaPolicy as En, discoverWebSocketApis as Er, getContainerNetworkIp as Et, isCloudFrontDistribution as F, matchRoute as Fn, AGENTCORE_AGUI_PROTOCOL as Fr, MCP_PATH as Ft, parseLbPortOverrides as G, HOST_GATEWAY_MIN_VERSION as Gn, tryResolveImageFnJoin as Gr, SUPPORTED_CODE_RUNTIMES as Gt, addAlbSpecificOptions as H, selectIntegrationResponse as Hn, derivePseudoParametersFromRegion as Hr, invokeAgentCore as Ht, pickFunctionUrlLogicalIdFromOrigin as I, translateLambdaResponse as In, AGENTCORE_HTTP_PROTOCOL as Ir, MCP_PROTOCOL_VERSION as It, resolveAlbFrontDoor as J, ConnectionRegistry as Jn, resolveProfileCredentials as Jr, renderCodeDockerfile as Jt, resolveAlbTarget as K, probeHostGatewaySupport as Kn, LocalInvokeBuildError as Kr, buildAgentCoreCodeImage as Kt, pickTargetFunctionLogicalId as L, applyAuthorizerOverlay as Ln, AGENTCORE_MCP_PROTOCOL as Lr, mcpInvokeOnce as Lt, serveFromStaticOrigin as M, buildCorsConfigFromCloudFrontChain as Mn, pickRefLogicalId as Mr, A2A_PATH as Mt, serveLambdaUrlOrigin as N, isFunctionUrlOacFronted as Nn, resolveLambdaArnIntrinsic as Nr, a2aInvokeOnce as Nt, parseOriginOverrides as O, invokeTokenAuthorizer as On, filterWebSocketApisByIdentifiers as Or, addInvokeAgentCoreSpecificOptions as Ot, CLOUDFRONT_DISTRIBUTION_TYPE as P, matchPreflight as Pn, AGENTCORE_A2A_PROTOCOL as Pr, MCP_CONTAINER_PORT as Pt, addRunTaskSpecificOptions as Q, buildConnectEvent as Qn, createLocalInvokeCommand as Qt, resolveCloudFrontDistribution as R, buildHttpApiV2Event as Rn, AGENTCORE_RUNTIME_TYPE as Rr, parseSseForJsonRpc as Rt, addListSpecificOptions as S, verifyJwtAuthorizer as Sn, resolveSingleTarget as Sr, CloudMapRegistry as St, LocalStartCloudFrontError as T, computeRequestIdentityHash as Tn, availableWebSocketApiIdentifiers as Tr, setShadowReadyTimeoutMs as Tt, albStrategy as U, tryParseStatus as Un, formatStateRemedy as Ur, waitForAgentCorePing as Ut, runViewerResponse as V, pickResponseTemplate as Vn, resolveAgentCoreTarget as Vr, AGENTCORE_SESSION_ID_HEADER as Vt, createLocalStartAlbCommand as W, VtlEvaluationError as Wn, substituteImagePlaceholders as Wr, downloadAndExtractS3Bundle as Wt, createLocalStartServiceCommand as X, handleConnectionsRequest as Xn, classifySourceChange as Xt, addStartServiceSpecificOptions as Y, buildMgmtEndpointEnvUrl as Yn, toCmdArgv as Yt, serviceStrategy as Z, parseConnectionsPath as Zn, addInvokeSpecificOptions as Zt, startStudioServer as _, defaultCredentialsLoader as _n, resolveCfnStackName as _r, runImageOverrideBuilds as _t, createLocalStudioCommand as a, attachStageContext as an, resolveRuntimeImage as ar, ecsClusterOption as at, createStudioStore as b, createJwksCache as bn, resolveSsmParameters as br, listPinnedTargets as bt, startStudioProxy as c, resolveEnvVars$1 as cn, substituteAgainstStateAsync as cr, resolveEcsAssumeRoleOption as ct, createStudioDispatcher as d, filterRoutesByApiIdentifiers as dn, LocalStateSourceError as dr, ImageOverrideError as dt, createLocalStartApiCommand as en, buildMessageEvent as er, MAX_TASKS_SUBNET_RANGE_CAP as et, filterStudioCustomResources as f, groupRoutesByServer as fn, createLocalStateProvider as fr, buildImageOverrideTag as ft, filterStudioTargetGroups as g, resolveServiceIntegrationParameters as gn, resolveCfnRegion as gr, resolveImageOverrides as gt, annotatePinnedEcsTargets as h, resolveSelectionExpression as hn, resolveCfnFallbackRegion as hr, parseImageOverrideFlags as ht, coerceStopRequest as i, createFileWatcher as in, resolveRuntimeFileExtension as ir, buildEcsImageResolutionContext$1 as it, startCloudFrontServer as j, buildCorsConfigByApiId as jn, discoverRoutes as jr, A2A_CONTAINER_PORT as jt, resolveCloudFrontTarget as k, attachAuthorizers as kn, parseSelectionExpressionPath as kr, createLocalInvokeAgentCoreCommand as kt, relayServeRequest as l, availableApiIdentifiers as ln, substituteEnvVarsFromState as lr, resolveSharedSidecarCredentials as lt, annotateAlbPinnedBackingServices as m, startApiServer as mn, rejectExplicitCfnStackWithMultipleStacks as mr, mergeForService as mt, coerceRunRequest as n, resolveApiTargetSubset as nn, buildContainerImage as nr, addEcsAssumeRoleOptions as nt, resolveServeBaseUrl as o, buildStageMap as on, EcsTaskResolutionError as or, parseMaxTasks as ot, isCustomResourceLambdaTarget as p, readMtlsMaterialsFromDisk as pn, isCfnFlagPresent as pr, enforceImageOverrideOrphans as pt, isApplicationLoadBalancer as q, bufferToBody as qn, buildStsClientConfig as qr, computeCodeImageTag as qt, coerceServeRequest as r, createAuthorizerCache as rn, resolveRuntimeCodeMountPath as rr, addImageOverrideOptions as rt, createStudioServeManager as s, materializeLayerFromArn as sn, substituteAgainstState as sr, parseRestartPolicy as st, addStudioSpecificOptions as t, createWatchPredicates as tn, architectureToPlatform as tr, addCommonEcsServiceOptions as tt, reinvoke as u, filterRoutesByApiIdentifier as un, substituteEnvVarsFromStateAsync as ur, runEcsServiceEmulator as ut, toStudioTargetGroups as v, buildCognitoJwksUrl as vn, CfnLocalStateProvider as vr, describePinnedImageUri as vt, formatTargetListing as w, buildMethodArn as wn, listTargets as wr, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as wt, StudioEventBus as x, verifyCognitoJwt as xn, resolveWatchConfig as xr, buildCloudMapIndex as xt, renderStudioHtml as y, buildJwksUrlFromIssuer as yn, collectSsmParameterRefs as yr, isLocalCdkAssetImage as yt, compileCloudFrontFunction as z, buildRestV1Event as zn, AgentCoreResolutionError as zr, AGENTCORE_SIGV4_SERVICE as zt };
33899
+ //# sourceMappingURL=local-studio-CxVVLdJw.js.map