cdk-local 0.62.1 → 0.64.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.
- package/README.md +9 -9
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +1 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal.d.ts +2 -55
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-list-BPbd4EMs.js → local-list-BNkoH5tV.js} +3 -187
- package/dist/local-list-BNkoH5tV.js.map +1 -0
- package/dist/{elb-front-door-resolver-CsCmMUqz.js → local-start-alb-CIE0TMpn.js} +304 -24
- package/dist/local-start-alb-CIE0TMpn.js.map +1 -0
- package/dist/{ecs-service-emulator-D4aFpgn1.d.ts → local-start-alb-CTu5lvrU.d.ts} +71 -2
- package/dist/local-start-alb-CTu5lvrU.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/ecs-service-emulator-D4aFpgn1.d.ts.map +0 -1
- package/dist/elb-front-door-resolver-CsCmMUqz.js.map +0 -1
- package/dist/local-list-BPbd4EMs.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-list-BNkoH5tV.js","names":["readEnvOverridesFile","readEvent","parseEvent","readStdin","forwardAwsEnv","resolveProfileCredentials","readEnvOverridesFile","resolveCallerAccountId","resolveProfileCredentials"],"sources":["../src/cli/commands/local-invoke.ts","../src/cli/commands/local-invoke-agentcore.ts","../src/cli/commands/local-run-task.ts","../src/cli/commands/local-start-service.ts","../src/cli/commands/local-list.ts"],"sourcesContent":["import { cpSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';\nimport { tmpdir } from 'node:os';\nimport { dirname } from 'node:path';\nimport * as path from 'node:path';\nimport { Command, Option } from 'commander';\nimport {\n appOptions,\n commonOptions,\n contextOptions,\n deprecatedRegionOption,\n parseContextOptions,\n warnIfDeprecatedRegion,\n} from '../options.js';\nimport { getLogger } from '../../utils/logger.js';\nimport { applyRoleArnIfSet } from '../../utils/role-arn.js';\nimport { CdkLocalError, withErrorHandling } from '../../utils/error-handler.js';\nimport { listTargets } from '../../local/target-lister.js';\nimport { resolveSingleTarget } from '../../local/target-picker.js';\nimport { Synthesizer, type SynthesisOptions } from '../../synthesis/synthesizer.js';\nimport { resolveApp } from '../config-loader.js';\nimport { readCdkPathOrUndefined } from '../cdk-path.js';\nimport {\n createLocalStateProvider,\n resolveCfnFallbackRegion,\n type ExtraStateProviders,\n} from './local-state-source.js';\nimport type { LocalStateProvider } from '../../local/local-state-provider.js';\nimport {\n getEmbedConfig,\n setEmbedConfig,\n type CdkLocalEmbedConfig,\n} from '../../local/embed-config.js';\nimport {\n resolveLambdaTarget,\n type ResolvedImageLambda,\n type ResolvedLambda,\n type ResolvedLambdaLayer,\n type ResolvedZipLambda,\n} from '../../local/lambda-resolver.js';\nimport { materializeLayerFromArn } from '../../local/layer-arn-materializer.js';\nimport { resolveEnvVars, type EnvOverrideFile } from '../../local/env-resolver.js';\nimport {\n applyDeployedEnvFallback,\n substituteEnvVarsFromStateAsync,\n type StateEnvSubstitutionAudit,\n type SubstitutionContext,\n} from '../../local/state-resolver.js';\nimport { derivePartitionAndUrlSuffix } from '../../local/ecs-task-resolver.js';\nimport {\n resolveRuntimeCodeMountPath,\n resolveRuntimeFileExtension,\n resolveRuntimeImage,\n} from '../../local/runtime-image.js';\nimport {\n ensureDockerAvailable,\n pickFreePort,\n pullImage,\n removeContainer,\n runDetached,\n streamLogs,\n} from '../../local/docker-runner.js';\nimport { architectureToPlatform, buildContainerImage } from '../../local/docker-image-builder.js';\nimport { pullEcrImage, parseEcrUri } from '../../local/ecr-puller.js';\nimport { invokeRie, waitForRieReady } from '../../local/rie-client.js';\nimport {\n AssetManifestLoader,\n getDockerImageBySourceHash,\n} from '../../assets/asset-manifest-loader.js';\nimport { singleFlight } from '../../utils/single-flight.js';\nimport {\n writeProfileCredentialsFile,\n type ProfileCredentialsFile,\n} from './local-profile-credentials-file.js';\nimport type { StackState } from '../../types/state.js';\n\ninterface LocalInvokeOptions {\n app?: string;\n output: string;\n verbose: boolean;\n region?: string;\n profile?: string;\n roleArn?: string;\n context?: string[];\n event?: string;\n eventStdin?: boolean;\n envVars?: string;\n /**\n * Commander maps `--no-pull` to `pull: boolean` (default `true`). When\n * the user passes `--no-pull` the value flips to `false` and we skip\n * `docker pull`.\n */\n pull: boolean;\n /**\n * Commander maps `--no-build` to `build: boolean` (default `true`).\n * When the user passes `--no-build` the value flips to `false` and we\n * skip `docker build` on the IMAGE local-build path.\n */\n build: boolean;\n debugPort?: string;\n containerHost: string;\n /**\n * Optional Lambda execution role to assume before invoking. Commander's\n * `[arn]` syntax maps to `string | boolean` here:\n * - flag absent → `undefined` (pass dev creds through; SAM-compatible default)\n * - `--assume-role` (bare) → `true` (auto-resolve from state if a host extension is active)\n * - `--assume-role <arn>` → `'<arn>'` (explicit ARN; precedence wins)\n * - `--no-assume-role` → `false` (explicit opt-out)\n */\n assumeRole?: string | boolean;\n /**\n * Issue #448: explicit role to `sts:AssumeRole` into before calling\n * `lambda:GetLayerVersion` for every literal-ARN entry in a Lambda's\n * `Properties.Layers`.\n */\n layerRoleArn?: string;\n /**\n * Optional role ARN passed to `pullEcrImage` when the IMAGE ECR-pull\n * path fires.\n */\n ecrRoleArn?: string;\n /**\n * Issue #606: alternative state source for CDK apps deployed via the\n * upstream CDK CLI (`cdk deploy` → CloudFormation). Reads the named\n * CFn stack via `ListStackResources` to populate physical IDs.\n * Commander maps:\n * - flag absent → `undefined`\n * - `--from-cfn-stack` (bare) → `true` (use the resolved stack name)\n * - `--from-cfn-stack <name>` → `'<name>'`\n */\n fromCfnStack?: string | boolean;\n /**\n * Region of the state record to read. Drives the CFn client's region\n * when `--from-cfn-stack` is set.\n */\n stackRegion?: string;\n /** Host-injected extra state-source flag fields. */\n [key: string]: unknown;\n}\n\n/**\n * Factory options for {@link createLocalInvokeCommand}.\n */\nexport interface CreateLocalInvokeCommandOptions {\n extraStateProviders?: ExtraStateProviders;\n /** Embed-time branding overrides for a host wrapping this factory. */\n embedConfig?: CdkLocalEmbedConfig;\n}\n\n/**\n * `cdkl invoke <target>` — run a Lambda function locally inside a\n * Docker container that bundles the AWS Lambda Runtime Interface\n * Emulator (RIE). Modeled on `sam local invoke` but reusing cdk-local's\n * synthesis / asset / construct-path plumbing.\n */\nasync function localInvokeCommand(\n target: string | undefined,\n options: LocalInvokeOptions,\n extraStateProviders: ExtraStateProviders | undefined\n): Promise<void> {\n const logger = getLogger();\n if (options.verbose) {\n logger.setLevel('debug');\n }\n\n warnIfDeprecatedRegion(options);\n\n let imagePlan: ImagePlan | undefined;\n let containerId: string | undefined;\n let stopLogs: (() => void) | undefined;\n let sigintHandler: (() => void) | undefined;\n // Synthesized AWS shared credentials file (one INI section) bind-mounted\n // into the container so handlers using `fromIni({ profile })` explicitly\n // resolve to the same creds. Disposed in the shared `cleanup` single-flight.\n let profileCredsFile: ProfileCredentialsFile | undefined;\n\n /**\n * Unified cleanup for both the success / failure unwind path AND the\n * SIGINT handler.\n */\n const cleanup = singleFlight(\n async (): Promise<void> => {\n if (stopLogs) {\n try {\n stopLogs();\n } catch (err) {\n getLogger().debug(\n `streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n if (containerId) {\n try {\n await removeContainer(containerId);\n } catch (err) {\n getLogger().debug(\n `removeContainer(${containerId}) failed: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n if (imagePlan?.inlineTmpDir) {\n try {\n rmSync(imagePlan.inlineTmpDir, { recursive: true, force: true });\n } catch (err) {\n getLogger().debug(\n `Failed to remove inline-code tmpdir ${imagePlan.inlineTmpDir}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n if (imagePlan?.layersTmpDir) {\n try {\n rmSync(imagePlan.layersTmpDir, { recursive: true, force: true });\n } catch (err) {\n getLogger().debug(\n `Failed to remove merged-layers tmpdir ${imagePlan.layersTmpDir}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n if (imagePlan?.layerArnTmpDirs) {\n for (const dir of imagePlan.layerArnTmpDirs) {\n try {\n rmSync(dir, { recursive: true, force: true });\n } catch (err) {\n getLogger().debug(\n `Failed to remove ARN-layer tmpdir ${dir}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n }\n if (profileCredsFile) {\n try {\n await profileCredsFile.dispose();\n } catch (err) {\n getLogger().debug(\n `Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n },\n (err) => {\n getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n );\n\n try {\n await applyRoleArnIfSet({ roleArn: options.roleArn, region: options.region });\n\n await ensureDockerAvailable();\n\n // When `--profile <p>` is set, resolve the profile to a concrete\n // credential set ONCE up-front so it can be overlaid onto the Lambda\n // container's env after `forwardAwsEnv`.\n const profileCredentials = options.profile\n ? await resolveProfileCredentials(options.profile)\n : undefined;\n\n // Synthesize an AWS shared credentials file with the resolved creds\n // under `[<options.profile>]` so handler code that uses\n // `fromIni({ profile: '<options.profile>' })` explicitly (instead of\n // the default credential chain) resolves to the same creds locally.\n // Mounted read-only into the container at the path pointed to by\n // `AWS_SHARED_CREDENTIALS_FILE` (set below). The default-chain path\n // (most handlers) keeps working through the existing env-var\n // injection; this file is the additive layer for the explicit-\n // profile case. Disposed in the shared `cleanup` single-flight above.\n if (options.profile && profileCredentials) {\n profileCredsFile = await writeProfileCredentialsFile(options.profile, profileCredentials);\n }\n\n const appCmd = resolveApp(options.app);\n if (!appCmd) {\n throw new Error(\n `No CDK app specified. Pass --app, set ${getEmbedConfig().envPrefix}_APP, or add \"app\" to cdk.json.`\n );\n }\n\n logger.info('Synthesizing CDK app...');\n const synthesizer = new Synthesizer();\n const context = parseContextOptions(options.context);\n const synthOpts: SynthesisOptions = {\n app: appCmd,\n output: options.output,\n ...(options.region && { region: options.region }),\n ...(options.profile && { profile: options.profile }),\n ...(Object.keys(context).length > 0 && { context }),\n };\n const { stacks } = await synthesizer.synthesize(synthOpts);\n\n const resolvedTarget = await resolveSingleTarget(target, {\n entries: listTargets(stacks).lambdas,\n message: 'Select a Lambda function to invoke',\n noun: 'Lambda functions',\n onMissing: () =>\n new CdkLocalError(\n `${getEmbedConfig().cliName} invoke requires a <target> (a Lambda display path or logical ID). ` +\n `Run \\`${getEmbedConfig().cliName} list\\` to see them, or run it in a TTY to pick interactively.`,\n 'LOCAL_INVOKE_TARGET_REQUIRED'\n ),\n });\n\n const lambda = resolveLambdaTarget(resolvedTarget, stacks);\n const targetLabel = lambda.kind === 'zip' ? lambda.runtime : 'container image';\n logger.info(`Target: ${lambda.stack.stackName}/${lambda.logicalId} (${targetLabel})`);\n\n imagePlan = await resolveImagePlan(lambda, options);\n\n let stateAudit: StateEnvSubstitutionAudit | undefined;\n let templateEnv = getTemplateEnv(lambda.resource);\n let stateForRoleHint: StackState | undefined;\n // Pick the right LocalStateProvider for the supplied flags. Returns\n // `undefined` when no state-source flag is set.\n const stateProvider = createLocalStateProvider(\n options,\n lambda.stack.stackName,\n await resolveCfnFallbackRegion(options, lambda.stack.region),\n extraStateProviders\n );\n if (stateProvider) {\n try {\n const loaded = await stateProvider.load(lambda.stack.stackName, lambda.stack.region);\n if (loaded) {\n // Synthetic StackState shape consumed by the legacy\n // `--assume-role` hint path. Sufficient for\n // `resolveExecutionRoleArnFromState`, which only touches\n // `state.resources[...].properties.Role` /\n // `attributes.Arn`.\n stateForRoleHint = {\n version: 1,\n stackName: lambda.stack.stackName,\n resources: loaded.resources,\n outputs: loaded.outputs,\n lastModified: 0,\n };\n const subContext: SubstitutionContext = {\n resources: loaded.resources,\n consumerRegion: loaded.region,\n };\n if (envHasIntrinsicValue(templateEnv)) {\n const pseudo = await resolvePseudoParametersForInvoke(lambda.stack.region, options);\n if (pseudo) subContext.pseudoParameters = pseudo;\n }\n // Resolve SSM-backed template parameters\n // (`AWS::SSM::Parameter::Value<String>`) so a `Ref` to such a\n // parameter in an env var resolves to its SSM value instead of\n // being warn-and-dropped (issue #94). Only the CFn provider\n // implements this; the resolved map feeds the substitution\n // context's `parameters` field consulted by `resolveRef`.\n if (envHasIntrinsicValue(templateEnv) && stateProvider.resolveTemplateSsmParameters) {\n const ssmParams = await stateProvider.resolveTemplateSsmParameters(\n lambda.stack.template\n );\n if (Object.keys(ssmParams.values).length > 0) subContext.parameters = ssmParams.values;\n // Flag decrypted SecureString parameters so the consuming env\n // keys are kept off the `docker run` argv (issue #99).\n if (ssmParams.secureStringLogicalIds.length > 0) {\n subContext.sensitiveParameters = new Set(ssmParams.secureStringLogicalIds);\n }\n }\n if (envHasCrossStackIntrinsic(templateEnv)) {\n const resolver = await stateProvider.buildCrossStackResolver(loaded.region);\n if (resolver) {\n subContext.crossStackResolver = resolver;\n }\n }\n const { env, audit } = await substituteEnvVarsFromStateAsync(templateEnv, subContext);\n templateEnv = env;\n const label = stateProvider.label;\n for (const key of audit.resolvedKeys) {\n logger.debug(`${label}: substituted env var ${key}`);\n }\n // Deployed-env fallback: keys whose intrinsic value the static\n // substituter could not resolve (e.g. `Fn::GetAtt <Sibling>.Arn`)\n // are filled from the consumer function's deploy-time-resolved\n // `Environment.Variables`. Only the CFn provider implements\n // `resolveDeployedFunctionEnv`; the S3 provider's state already\n // carries deploy-time attributes so its GetAtt resolves above.\n let unresolved = audit.unresolved;\n const resolvedKeys = [...audit.resolvedKeys];\n if (unresolved.length > 0 && stateProvider.resolveDeployedFunctionEnv) {\n const physicalId = loaded.resources[lambda.logicalId]?.physicalId;\n if (physicalId) {\n const deployedEnv = await stateProvider.resolveDeployedFunctionEnv(physicalId);\n const fb = applyDeployedEnvFallback(templateEnv, unresolved, deployedEnv);\n templateEnv = fb.env;\n unresolved = fb.stillUnresolved;\n for (const key of fb.filled) {\n resolvedKeys.push(key);\n logger.debug(`${label}: filled env var ${key} from deployed function config`);\n }\n }\n }\n stateAudit = { resolvedKeys, unresolved, sensitiveKeys: audit.sensitiveKeys };\n for (const { key, reason } of unresolved) {\n logger.warn(\n `${label}: could not substitute env var ${key} (${reason}). ` +\n `Override it via --env-vars or it will be dropped.`\n );\n }\n }\n } catch (err) {\n // Ensure the provider is released if the substitution pass threw.\n // The success path defers dispose until after the assume-role\n // resolution below so the issue-#181 fallback can still use it.\n stateProvider.dispose();\n throw err;\n }\n }\n\n // Resolve env vars. Intrinsic-valued template entries are warned about\n // and dropped; the user can override them via --env-vars (SAM-shape).\n const overrides = readEnvOverridesFile(options.envVars);\n const lambdaCdkPath = readCdkPathOrUndefined(lambda.resource);\n const envResult = resolveEnvVars(lambda.logicalId, lambdaCdkPath, templateEnv, overrides);\n for (const key of envResult.unresolved) {\n if (stateAudit && stateAudit.unresolved.some((u) => u.key === key)) continue;\n // Prefer the L2 form (`MyStack/MyFn`) in the suggestion since that\n // matches the README guidance and `cdkl invoke` target shape; the\n // resolver's prefix rule accepts either form.\n const overrideKeyExample = lambdaCdkPath?.replace(/\\/Resource$/, '') ?? lambda.logicalId;\n logger.warn(\n `Environment variable ${key} contains a CloudFormation intrinsic and was dropped. ` +\n `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.`\n );\n }\n\n // Resolve the role ARN to assume (if any). Three forms — explicit\n // ARN, bare (auto-resolve from state, with a #181 fallback to\n // GetFunctionConfiguration.Role when state misses), or absent.\n // The state provider's dispose is deferred until after this call so\n // the issue-#181 fallback can still use it.\n let resolvedAssumeRoleArn: string | undefined;\n try {\n resolvedAssumeRoleArn = await resolveAssumeRoleArnForLambda(\n options.assumeRole,\n stateForRoleHint,\n stateProvider,\n lambda.logicalId\n );\n } finally {\n stateProvider?.dispose();\n }\n if (options.assumeRole === undefined && stateForRoleHint) {\n // Legacy hint path: surface the deployed role ARN so they can re-run\n // with `--assume-role`.\n suggestAssumeRoleFromState(stateForRoleHint, lambda.logicalId);\n }\n\n // Read the event payload. Default to {} (matches SAM).\n const event = await readEvent(options);\n\n const dockerEnv: Record<string, string> = {\n AWS_LAMBDA_FUNCTION_NAME: lambda.logicalId,\n AWS_LAMBDA_FUNCTION_MEMORY_SIZE: String(lambda.memoryMb),\n AWS_LAMBDA_FUNCTION_TIMEOUT: String(lambda.timeoutSec),\n AWS_LAMBDA_FUNCTION_VERSION: '$LATEST',\n AWS_LAMBDA_LOG_GROUP_NAME: `/aws/lambda/${lambda.logicalId}`,\n AWS_LAMBDA_LOG_STREAM_NAME: 'local',\n ...envResult.resolved,\n };\n let assumeSucceeded = false;\n if (resolvedAssumeRoleArn) {\n const stsRegion =\n options.region ?? process.env['AWS_REGION'] ?? process.env['AWS_DEFAULT_REGION'];\n try {\n const creds = await assumeLambdaExecutionRole(resolvedAssumeRoleArn, stsRegion);\n dockerEnv['AWS_ACCESS_KEY_ID'] = creds.accessKeyId;\n dockerEnv['AWS_SECRET_ACCESS_KEY'] = creds.secretAccessKey;\n dockerEnv['AWS_SESSION_TOKEN'] = creds.sessionToken;\n if (stsRegion) dockerEnv['AWS_REGION'] = stsRegion;\n assumeSucceeded = true;\n } catch (err) {\n const reason = err instanceof Error ? err.message : String(err);\n logger.warn(\n `--assume-role: STS AssumeRole(${resolvedAssumeRoleArn}) failed: ${reason}. ` +\n \"Falling back to the developer's shell credentials.\"\n );\n }\n }\n if (!assumeSucceeded) {\n forwardAwsEnv(dockerEnv);\n applyProfileCredentialsOverlay(dockerEnv, profileCredentials, false);\n // Point the container's SDK chain at the bind-mounted credentials\n // file so\n // `fromIni({ profile })` calls inside the handler resolve to the\n // same creds. `AWS_PROFILE` makes `fromIni()` (no explicit arg)\n // ALSO use this profile.\n if (profileCredsFile) {\n dockerEnv['AWS_SHARED_CREDENTIALS_FILE'] = profileCredsFile.containerPath;\n dockerEnv['AWS_PROFILE'] = profileCredsFile.profileName;\n }\n }\n\n let debugPort: number | undefined;\n if (options.debugPort) {\n debugPort = Number(options.debugPort);\n if (!Number.isInteger(debugPort) || debugPort <= 0 || debugPort > 65535) {\n throw new Error(`--debug-port must be an integer in 1..65535, got '${options.debugPort}'`);\n }\n dockerEnv['NODE_OPTIONS'] = `--inspect-brk=0.0.0.0:${debugPort}`;\n if (lambda.kind === 'image') {\n logger.warn(\n '--debug-port sets NODE_OPTIONS unconditionally on container Lambdas. ' +\n \"If the image's runtime is not Node.js, this flag is a no-op.\"\n );\n }\n }\n\n const hostPort = await pickFreePort();\n const containerHost = options.containerHost;\n\n if (lambda.layers.length > 0) {\n logger.info(\n `Mounting ${lambda.layers.length} Lambda layer${lambda.layers.length === 1 ? '' : 's'} at /opt`\n );\n }\n logger.info(`Starting container (image=${imagePlan.image}, port=${hostPort})...`);\n // Append the profile credentials file bind-mount to the existing\n // extraMounts (which\n // already carry the /opt layer mount when present). Read-only — the\n // container has no business writing to its credentials file; a\n // writable mount would let a compromised handler tamper with the\n // host-side temp file.\n const extraMountsWithProfile = profileCredsFile\n ? [\n ...(imagePlan.extraMounts ?? []),\n {\n hostPath: profileCredsFile.hostPath,\n containerPath: profileCredsFile.containerPath,\n readOnly: true,\n },\n ]\n : imagePlan.extraMounts;\n containerId = await runDetached({\n image: imagePlan.image,\n mounts: imagePlan.mounts,\n extraMounts: extraMountsWithProfile,\n env: dockerEnv,\n ...(stateAudit &&\n stateAudit.sensitiveKeys.length > 0 && {\n sensitiveEnvKeys: new Set(stateAudit.sensitiveKeys),\n }),\n cmd: imagePlan.cmd,\n hostPort,\n host: containerHost,\n ...(debugPort !== undefined && { debugPort }),\n ...(imagePlan.platform !== undefined && { platform: imagePlan.platform }),\n ...(imagePlan.entryPoint !== undefined && { entryPoint: imagePlan.entryPoint }),\n ...(imagePlan.workingDir !== undefined && { workingDir: imagePlan.workingDir }),\n ...(imagePlan.tmpfs !== undefined && { tmpfs: imagePlan.tmpfs }),\n });\n\n stopLogs = streamLogs(containerId);\n\n sigintHandler = (): void => {\n void cleanup().then(() => {\n process.exit(130);\n });\n };\n process.on('SIGINT', sigintHandler);\n\n await waitForRieReady(containerHost, hostPort, 5000);\n\n const invokeTimeoutMs = Math.max(30_000, lambda.timeoutSec * 2 * 1000);\n const result = await invokeRie(containerHost, hostPort, event, invokeTimeoutMs);\n\n // Settle a few hundred ms so logs fully flush before we tear down.\n await new Promise((resolveDelay) => setTimeout(resolveDelay, 250));\n process.stdout.write(`${result.raw}\\n`);\n } finally {\n if (sigintHandler) process.off('SIGINT', sigintHandler);\n await cleanup();\n }\n}\n\ninterface ImagePlan {\n image: string;\n mounts: { hostPath: string; containerPath: string; readOnly?: boolean }[];\n extraMounts: { hostPath: string; containerPath: string; readOnly?: boolean }[];\n cmd: string[];\n platform?: string;\n entryPoint?: string[];\n workingDir?: string;\n inlineTmpDir?: string;\n layersTmpDir?: string;\n layerArnTmpDirs?: string[];\n tmpfs?: { target: string; sizeMb: number };\n}\n\nasync function resolveImagePlan(\n lambda: ResolvedLambda,\n options: LocalInvokeOptions\n): Promise<ImagePlan> {\n if (lambda.kind === 'zip') {\n return resolveZipImagePlan(lambda, options);\n }\n return resolveContainerImagePlan(lambda, options);\n}\n\nasync function resolveZipImagePlan(\n lambda: ResolvedZipLambda,\n options: LocalInvokeOptions\n): Promise<ImagePlan> {\n let inlineTmpDir: string | undefined;\n let codeDir = lambda.codePath;\n if (codeDir === null) {\n inlineTmpDir = materializeInlineCode(\n lambda.handler,\n lambda.inlineCode ?? '',\n resolveRuntimeFileExtension(lambda.runtime)\n );\n codeDir = inlineTmpDir;\n }\n\n const image = resolveRuntimeImage(lambda.runtime);\n\n await pullImage(image, options.pull === false);\n\n const layerPlan = await materializeLambdaLayersIncludingArns(lambda.layers, options);\n\n // provided.al2 / provided.al2023 require the deployment package at\n // /var/runtime; every other runtime expects /var/task.\n const containerCodePath = resolveRuntimeCodeMountPath(lambda.runtime);\n\n const tmpfs = resolveTmpfsForLambda(lambda);\n\n return {\n image,\n mounts: [{ hostPath: codeDir, containerPath: containerCodePath, readOnly: true }],\n extraMounts: layerPlan.mount ? [layerPlan.mount] : [],\n cmd: [lambda.handler],\n ...(inlineTmpDir !== undefined && { inlineTmpDir }),\n ...(layerPlan.tmpDir !== undefined && { layersTmpDir: layerPlan.tmpDir }),\n ...(layerPlan.extraTmpDirs.length > 0 && { layerArnTmpDirs: layerPlan.extraTmpDirs }),\n ...(tmpfs !== undefined && { tmpfs }),\n };\n}\n\nexport async function materializeLambdaLayersIncludingArns(\n layers: ResolvedLambdaLayer[],\n options: LocalInvokeOptions\n): Promise<{\n mount?: { hostPath: string; containerPath: string; readOnly: boolean };\n tmpDir?: string;\n extraTmpDirs: string[];\n}> {\n const extraTmpDirs: string[] = [];\n const flat: { logicalId: string; assetPath: string }[] = [];\n for (const layer of layers) {\n if (layer.kind === 'asset') {\n flat.push({ logicalId: layer.logicalId, assetPath: layer.assetPath });\n continue;\n }\n const dir = await materializeLayerFromArn(layer, {\n ...(options.layerRoleArn !== undefined && { roleArn: options.layerRoleArn }),\n });\n extraTmpDirs.push(dir);\n flat.push({ logicalId: layer.arn, assetPath: dir });\n }\n const plan = materializeLambdaLayers(flat);\n return { ...plan, extraTmpDirs };\n}\n\nexport function resolveTmpfsForLambda(\n lambda: ResolvedLambda\n): { target: string; sizeMb: number } | undefined {\n if (lambda.ephemeralStorageMb === undefined) return undefined;\n const logger = getLogger();\n if (lambda.kind === 'image') {\n logger.info(\n `Lambda ${lambda.logicalId}: capping /tmp at ${lambda.ephemeralStorageMb} MiB via --tmpfs (overlays any base-image /tmp content)`\n );\n } else {\n logger.debug(\n `Lambda ${lambda.logicalId}: applying EphemeralStorage cap via --tmpfs /tmp:size=${lambda.ephemeralStorageMb}m`\n );\n }\n return { target: '/tmp', sizeMb: lambda.ephemeralStorageMb };\n}\n\nexport function materializeLambdaLayers(layers: { logicalId: string; assetPath: string }[]): {\n mount?: { hostPath: string; containerPath: string; readOnly: boolean };\n tmpDir?: string;\n} {\n if (layers.length === 0) return {};\n if (layers.length === 1) {\n return {\n mount: { hostPath: layers[0]!.assetPath, containerPath: '/opt', readOnly: true },\n };\n }\n const tmpDir = mkdtempSync(\n path.join(tmpdir(), `${getEmbedConfig().resourceNamePrefix}-invoke-layers-`)\n );\n for (const layer of layers) {\n cpSync(layer.assetPath, tmpDir, { recursive: true, force: true });\n }\n return {\n mount: { hostPath: tmpDir, containerPath: '/opt', readOnly: true },\n tmpDir,\n };\n}\n\nexport async function resolveContainerImagePlan(\n lambda: ResolvedImageLambda,\n options: LocalInvokeOptions\n): Promise<ImagePlan> {\n const logger = getLogger();\n const platform = architectureToPlatform(lambda.architecture);\n\n const localBuild = await resolveLocalBuildPlan(lambda);\n let imageRef: string;\n if (localBuild) {\n imageRef = await buildContainerImage(localBuild.asset, localBuild.cdkOutDir, {\n architecture: lambda.architecture,\n noBuild: options.build === false,\n });\n } else {\n if (!parseEcrUri(lambda.imageUri)) {\n throw new Error(\n `Container Lambda '${lambda.logicalId}' has no matching asset in cdk.out, and Code.ImageUri ` +\n `'${lambda.imageUri}' is not an ECR URI ${getEmbedConfig().binaryName} can authenticate against. ` +\n 'Re-synthesize the CDK app (so cdk.out includes the build context) or deploy the image to ECR first.'\n );\n }\n logger.info(\n `No matching cdk.out asset for ${lambda.imageUri}; falling back to ECR pull (same-acct/region only)...`\n );\n imageRef = await pullEcrImage(lambda.imageUri, {\n skipPull: options.pull === false,\n ...(options.region !== undefined && { region: options.region }),\n ...(options.ecrRoleArn !== undefined && { ecrRoleArn: options.ecrRoleArn }),\n ...(options.profile !== undefined && { profile: options.profile }),\n });\n }\n\n const tmpfs = resolveTmpfsForLambda(lambda);\n\n return {\n image: imageRef,\n mounts: [],\n extraMounts: [],\n cmd: lambda.imageConfig.command ?? [],\n platform,\n ...(lambda.imageConfig.entryPoint &&\n lambda.imageConfig.entryPoint.length > 0 && {\n entryPoint: lambda.imageConfig.entryPoint,\n }),\n ...(lambda.imageConfig.workingDirectory !== undefined && {\n workingDir: lambda.imageConfig.workingDirectory,\n }),\n ...(tmpfs !== undefined && { tmpfs }),\n };\n}\n\nasync function resolveLocalBuildPlan(\n lambda: ResolvedImageLambda\n): Promise<\n | { asset: { source: import('../../types/assets.js').DockerImageAssetSource }; cdkOutDir: string }\n | undefined\n> {\n const manifestPath = lambda.stack.assetManifestPath;\n if (!manifestPath) return undefined;\n const cdkOutDir = dirname(manifestPath);\n\n const loader = new AssetManifestLoader();\n const manifest = await loader.loadManifest(cdkOutDir, lambda.stack.stackName);\n if (!manifest) return undefined;\n\n const entry = getDockerImageBySourceHash(manifest, lambda.imageUri);\n if (!entry) return undefined;\n return { asset: entry.asset, cdkOutDir };\n}\n\nexport function envHasIntrinsicValue(templateEnv: Record<string, unknown> | undefined): boolean {\n if (!templateEnv) return false;\n for (const v of Object.values(templateEnv)) {\n if (v === undefined || v === null) continue;\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') continue;\n return true;\n }\n return false;\n}\n\nexport function envHasCrossStackIntrinsic(\n templateEnv: Record<string, unknown> | undefined\n): boolean {\n if (!templateEnv) return false;\n for (const v of Object.values(templateEnv)) {\n if (!v || typeof v !== 'object') continue;\n const obj = v as Record<string, unknown>;\n if ('Fn::ImportValue' in obj || 'Fn::GetStackOutput' in obj) return true;\n }\n return false;\n}\n\nasync function resolvePseudoParametersForInvoke(\n stackRegion: string | undefined,\n options: LocalInvokeOptions\n): Promise<\n { accountId?: string; region?: string; partition?: string; urlSuffix?: string } | undefined\n> {\n const logger = getLogger();\n const region =\n options.region ?? process.env['AWS_REGION'] ?? process.env['AWS_DEFAULT_REGION'] ?? stackRegion;\n if (!region) {\n logger.warn(\n `Resolver references \\${AWS::Region} but ${getEmbedConfig().binaryName} could not determine the target region. ` +\n 'Pass --region, set AWS_REGION, or declare env.region on the CDK stack.'\n );\n }\n let accountId: string | undefined;\n try {\n const { STSClient, GetCallerIdentityCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }) });\n try {\n const identity = await sts.send(new GetCallerIdentityCommand({}));\n accountId = identity.Account;\n } finally {\n sts.destroy();\n }\n } catch (err) {\n logger.warn(\n `Resolver needs \\${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. ` +\n 'Substitution will be skipped; affected env entries will be dropped with per-key warnings.'\n );\n }\n const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : undefined;\n const bag: {\n accountId?: string;\n region?: string;\n partition?: string;\n urlSuffix?: string;\n } = {\n ...(accountId !== undefined && { accountId }),\n ...(region !== undefined && { region }),\n ...(partitionAndSuffix && {\n partition: partitionAndSuffix.partition,\n urlSuffix: partitionAndSuffix.urlSuffix,\n }),\n };\n return Object.keys(bag).length === 0 ? undefined : bag;\n}\n\nfunction getTemplateEnv(resource: {\n Properties?: Record<string, unknown>;\n}): Record<string, unknown> | undefined {\n const props = resource.Properties ?? {};\n const env = props['Environment'];\n if (!env || typeof env !== 'object') return undefined;\n const vars = (env as Record<string, unknown>)['Variables'];\n if (!vars || typeof vars !== 'object') return undefined;\n return vars as Record<string, unknown>;\n}\n\nfunction readEnvOverridesFile(filePath: string | undefined): EnvOverrideFile | undefined {\n if (!filePath) return undefined;\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (err) {\n throw new Error(\n `Failed to read --env-vars file '${filePath}': ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Failed to parse --env-vars file '${filePath}' as JSON: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`--env-vars file '${filePath}' must contain a JSON object at the top level.`);\n }\n return parsed as EnvOverrideFile;\n}\n\nasync function readEvent(options: LocalInvokeOptions): Promise<unknown> {\n if (options.event && options.eventStdin) {\n throw new Error('--event and --event-stdin are mutually exclusive.');\n }\n if (options.eventStdin) {\n const raw = await readStdin();\n return parseEvent(raw, '<stdin>');\n }\n if (options.event) {\n const raw = readFileSync(options.event, 'utf-8');\n return parseEvent(raw, options.event);\n }\n return {};\n}\n\nfunction parseEvent(raw: string, source: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Failed to parse event payload from ${source} as JSON: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin as AsyncIterable<Buffer | string>) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\nasync function assumeLambdaExecutionRole(\n roleArn: string,\n region: string | undefined\n): Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken: string }> {\n const { STSClient, AssumeRoleCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }) });\n try {\n const response = await sts.send(\n new AssumeRoleCommand({\n RoleArn: roleArn,\n RoleSessionName: `${getEmbedConfig().resourceNamePrefix}-invoke-${Date.now()}`,\n DurationSeconds: 3600,\n })\n );\n const creds = response.Credentials;\n if (!creds?.AccessKeyId || !creds.SecretAccessKey || !creds.SessionToken) {\n throw new Error(`AssumeRole(${roleArn}) returned no usable credentials.`);\n }\n return {\n accessKeyId: creds.AccessKeyId,\n secretAccessKey: creds.SecretAccessKey,\n sessionToken: creds.SessionToken,\n };\n } finally {\n sts.destroy();\n }\n}\n\nfunction forwardAwsEnv(env: Record<string, string>): void {\n const passThrough = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n ] as const;\n for (const key of passThrough) {\n const value = process.env[key];\n if (value !== undefined) env[key] = value;\n }\n}\n\n/**\n * Resolve `--profile <p>` to a concrete credential set. Mirrors the\n * helper in `local-start-api.ts`.\n */\nasync function resolveProfileCredentials(\n profile: string\n): Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken?: string }> {\n const { STSClient } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ profile });\n try {\n const credsProvider = sts.config.credentials;\n const creds = typeof credsProvider === 'function' ? await credsProvider() : credsProvider;\n if (!creds || !creds.accessKeyId || !creds.secretAccessKey) {\n throw new Error(\n `--profile '${profile}': credential provider chain resolved without usable credentials. ` +\n 'Check `aws sso login --profile ' +\n profile +\n '` for SSO profiles, or `~/.aws/credentials` / `~/.aws/config` for regular profiles.'\n );\n }\n return {\n accessKeyId: creds.accessKeyId,\n secretAccessKey: creds.secretAccessKey,\n ...(creds.sessionToken && { sessionToken: creds.sessionToken }),\n };\n } finally {\n sts.destroy();\n }\n}\n\nexport function applyProfileCredentialsOverlay(\n env: Record<string, string>,\n profileCreds: { accessKeyId: string; secretAccessKey: string; sessionToken?: string } | undefined,\n assumeRoleActive: boolean\n): void {\n if (!profileCreds) return;\n if (assumeRoleActive) return;\n env['AWS_ACCESS_KEY_ID'] = profileCreds.accessKeyId;\n env['AWS_SECRET_ACCESS_KEY'] = profileCreds.secretAccessKey;\n if (profileCreds.sessionToken) {\n env['AWS_SESSION_TOKEN'] = profileCreds.sessionToken;\n } else {\n delete env['AWS_SESSION_TOKEN'];\n }\n}\n\nfunction materializeInlineCode(handler: string, source: string, fileExtension: string): string {\n const lastDot = handler.lastIndexOf('.');\n if (lastDot <= 0) {\n throw new Error(`Handler '${handler}' is malformed: expected '<modulePath>.<exportName>'.`);\n }\n const modulePath = handler.substring(0, lastDot);\n const dir = mkdtempSync(path.join(tmpdir(), `${getEmbedConfig().resourceNamePrefix}-invoke-`));\n const filePath = path.join(dir, `${modulePath}${fileExtension}`);\n mkdirSync(path.dirname(filePath), { recursive: true });\n writeFileSync(filePath, source, 'utf-8');\n return dir;\n}\n\nfunction suggestAssumeRoleFromState(state: StackState, logicalId: string): void {\n const logger = getLogger();\n const roleArn = resolveExecutionRoleArnFromState(state, logicalId);\n if (roleArn) {\n logger.info(\n `Hint: the deployed function uses execution role ${roleArn}. ` +\n `Re-run with --assume-role to invoke under the deployed function's narrow permissions.`\n );\n }\n}\n\n/**\n * Resolve the role ARN to assume for a Lambda invoke, honoring the three\n * `--assume-role` forms:\n *\n * - `--assume-role <arn>` (explicit) → return `<arn>`.\n * - `--assume-role` (bare, no value) → resolve from CFn state first;\n * if that misses, fall back to\n * `stateProvider.resolveLambdaExecutionRoleArn(<physicalId>)`\n * (a `lambda:GetFunctionConfiguration` call) so a sibling-stack\n * execution role still resolves (issue #181 — `ListStackResources`\n * returns the role's name, not its ARN, so `attributes.Arn` is\n * empty on the CFn state map and the state-only lookup misses).\n * - `--assume-role` absent → return undefined (no assume).\n *\n * Logs the resolution path (info on success, warn on miss) so the user\n * can tell why the container did or did not get assumed-role creds.\n *\n * Exported for unit testing.\n */\nexport async function resolveAssumeRoleArnForLambda(\n assumeRole: string | boolean | undefined,\n stateForRoleHint: StackState | undefined,\n stateProvider: Pick<LocalStateProvider, 'resolveLambdaExecutionRoleArn'> | undefined,\n lambdaLogicalId: string\n): Promise<string | undefined> {\n const logger = getLogger();\n if (typeof assumeRole === 'string') {\n return assumeRole;\n }\n if (assumeRole !== true) {\n return undefined;\n }\n // Bare --assume-role from here on.\n if (!stateForRoleHint) {\n logger.warn(\n '--assume-role passed without an ARN, but no state was loaded. ' +\n 'Pair it with a state-source flag, or pass the ARN explicitly: --assume-role <arn>. ' +\n \"Falling back to the developer's shell credentials.\"\n );\n return undefined;\n }\n const fromState = resolveExecutionRoleArnFromState(stateForRoleHint, lambdaLogicalId);\n if (fromState) {\n logger.info(`--assume-role: auto-resolved execution role from state: ${fromState}`);\n return fromState;\n }\n const fnPhysicalId = stateForRoleHint.resources[lambdaLogicalId]?.physicalId;\n if (stateProvider?.resolveLambdaExecutionRoleArn && fnPhysicalId) {\n // Issue #181 fallback: state-only lookup misses for sibling-stack\n // exec roles because `ListStackResources` returns the role's name,\n // not its ARN. The function's deploy-time `Configuration.Role`\n // carries the full ARN.\n const liveArn = await stateProvider.resolveLambdaExecutionRoleArn(fnPhysicalId);\n if (liveArn) {\n logger.info(\n `--assume-role: auto-resolved execution role from GetFunctionConfiguration: ${liveArn}`\n );\n return liveArn;\n }\n }\n logger.warn(\n `--assume-role: could not resolve the execution role ARN for '${lambdaLogicalId}'. ` +\n \"Pass the ARN explicitly: --assume-role <arn>. Falling back to the developer's shell credentials.\"\n );\n return undefined;\n}\n\nexport function resolveExecutionRoleArnFromState(\n state: Pick<StackState, 'resources'>,\n logicalId: string,\n roleProperty = 'Role'\n): string | undefined {\n const lambda = state.resources[logicalId];\n if (!lambda) return undefined;\n\n const roleRef = lambda.properties?.[roleProperty] ?? lambda.observedProperties?.[roleProperty];\n if (typeof roleRef === 'string' && roleRef.startsWith('arn:')) {\n return roleRef;\n }\n if (typeof roleRef === 'object' && roleRef !== null) {\n const refLogicalId = pickReferencedLogicalId(roleRef as Record<string, unknown>);\n if (refLogicalId) {\n const roleResource = state.resources[refLogicalId];\n const cached = roleResource?.attributes?.['Arn'];\n if (typeof cached === 'string' && cached.startsWith('arn:')) {\n return cached;\n }\n }\n }\n return undefined;\n}\n\nfunction pickReferencedLogicalId(intrinsic: Record<string, unknown>): string | undefined {\n if ('Ref' in intrinsic && typeof intrinsic['Ref'] === 'string') return intrinsic['Ref'];\n if ('Fn::GetAtt' in intrinsic) {\n const arg = intrinsic['Fn::GetAtt'];\n if (Array.isArray(arg) && typeof arg[0] === 'string') return arg[0];\n if (typeof arg === 'string') return arg.split('.')[0];\n }\n return undefined;\n}\n\nexport function createLocalInvokeCommand(opts: CreateLocalInvokeCommandOptions = {}): Command {\n setEmbedConfig(opts.embedConfig);\n const invoke = new Command('invoke')\n .description(\n 'Run a Lambda function locally in a Docker container (RIE-backed). ' +\n 'Target accepts a CDK display path (MyStack/MyApi/Handler) or stack-qualified logical ID ' +\n '(MyStack:MyApiHandler1234ABCD). Single-stack apps may omit the stack prefix. ' +\n 'Omit <target> in an interactive terminal to pick the Lambda from a list.'\n )\n .argument(\n '[target]',\n 'CDK display path or stack-qualified logical ID of the Lambda to invoke (omit to pick interactively in a TTY)'\n )\n .addOption(new Option('-e, --event <file>', 'JSON event payload file (default: {})'))\n .addOption(new Option('--event-stdin', 'Read event JSON from stdin').default(false))\n .addOption(\n new Option(\n '--env-vars <file>',\n 'JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})'\n )\n )\n .addOption(\n new Option(\n '--no-pull',\n 'Skip docker pull (use cached image) — no-op for IMAGE local-build path; ' +\n '`docker build` does not pull base layers by default'\n )\n )\n .addOption(\n new Option(\n '--no-build',\n 'Skip docker build on the IMAGE local-build path (use the previously-built tag). ' +\n 'Requires the deterministic tag to already be in the local registry; errors with ' +\n 'an actionable message when missing. No-op for ZIP Lambdas and the IMAGE ECR-pull path. ' +\n 'Compatible with --no-pull.'\n )\n )\n .addOption(new Option('--debug-port <port>', 'Node --inspect-brk port (default: off)'))\n .addOption(\n new Option('--container-host <host>', 'Host to bind the RIE port to').default('127.0.0.1')\n )\n .addOption(\n new Option(\n '--assume-role [arn]',\n \"Assume the Lambda's deployed execution role and forward STS-issued temp credentials \" +\n \"to the container so the handler runs with the deployed function's narrow permissions. \" +\n 'Three forms: ' +\n '(1) `--assume-role <arn>` assumes the explicit ARN; ' +\n \"(2) `--assume-role` (bare) auto-resolves the function's execution role ARN from state \" +\n '(requires an active state source); ' +\n '(3) `--no-assume-role` explicitly opts out. ' +\n \"Off by default — when omitted, the developer's shell credentials are forwarded \" +\n 'unchanged (SAM-compatible default). STS failures degrade to a warn + dev-creds fallback.'\n )\n )\n .addOption(\n new Option(\n '--layer-role-arn <arn>',\n 'Role to sts:AssumeRole before calling lambda:GetLayerVersion on every literal-ARN ' +\n 'entry in Properties.Layers. Use only when the dev credentials cannot ' +\n 'read the layer — typically cross-account layers. AWS-published public layers (e.g. ' +\n 'Lambda Powertools) are readable from every account and need no role.'\n )\n )\n .addOption(\n new Option(\n '--ecr-role-arn <arn>',\n 'Role ARN to assume before authenticating against ECR for cross-account / centralized ' +\n 'registries. Issues sts:AssumeRole via the default credential chain and uses the ' +\n 'temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the ' +\n 'caller does not have direct cross-account access to the target repository. ' +\n 'Same-account / same-region pulls do not need this flag.'\n )\n )\n .addOption(\n new Option(\n '--from-cfn-stack [cfn-stack-name]',\n 'Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue ' +\n 'in env vars with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream ' +\n 'CDK CLI (`cdk deploy`). Bare form uses the resolved stack name; pass an explicit value when CFn stack name differs. ' +\n 'Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).'\n )\n )\n .addOption(\n new Option(\n '--stack-region <region>',\n 'Region of the state record to read. Used with --from-cfn-stack as the CFn client region.'\n )\n )\n .action(\n withErrorHandling(async (target: string | undefined, options: LocalInvokeOptions) => {\n await localInvokeCommand(target, options, opts.extraStateProviders);\n })\n );\n\n [...commonOptions(), ...appOptions(), ...contextOptions].forEach((option) =>\n invoke.addOption(option)\n );\n invoke.addOption(deprecatedRegionOption);\n\n return invoke;\n}\n","import { randomUUID } from 'node:crypto';\nimport { existsSync, readFileSync, statSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { Command, Option } from 'commander';\nimport {\n appOptions,\n commonOptions,\n contextOptions,\n deprecatedRegionOption,\n parseContextOptions,\n warnIfDeprecatedRegion,\n} from '../options.js';\nimport { getLogger } from '../../utils/logger.js';\nimport { applyRoleArnIfSet } from '../../utils/role-arn.js';\nimport { CdkLocalError, withErrorHandling } from '../../utils/error-handler.js';\nimport { listTargets } from '../../local/target-lister.js';\nimport { resolveSingleTarget } from '../../local/target-picker.js';\nimport { Synthesizer, type SynthesisOptions } from '../../synthesis/synthesizer.js';\nimport { resolveApp } from '../config-loader.js';\nimport { readCdkPathOrUndefined } from '../cdk-path.js';\nimport {\n createLocalStateProvider,\n resolveCfnFallbackRegion,\n type ExtraStateProviders,\n} from './local-state-source.js';\nimport type { LocalStateProvider, LocalStateRecord } from '../../local/local-state-provider.js';\nimport type { StackInfo } from '../../synthesis/assembly-reader.js';\nimport {\n getEmbedConfig,\n setEmbedConfig,\n type CdkLocalEmbedConfig,\n} from '../../local/embed-config.js';\nimport {\n AGENTCORE_A2A_PROTOCOL,\n AGENTCORE_AGUI_PROTOCOL,\n AGENTCORE_MCP_PROTOCOL,\n pickAgentCoreCandidateStack,\n resolveAgentCoreTarget,\n type AgentCoreCodeArtifact,\n type ResolvedAgentCoreRuntime,\n} from '../../local/agentcore-resolver.js';\nimport { buildAgentCoreCodeImage } from '../../local/agentcore-code-build.js';\nimport { downloadAndExtractS3Bundle } from '../../local/agentcore-s3-bundle.js';\nimport {\n signAgentCoreInvocation,\n type SigV4Credentials,\n} from '../../local/agentcore-sigv4-sign.js';\nimport {\n invokeAgentCore,\n waitForAgentCorePing,\n type AgentCoreInvokeResult,\n} from '../../local/agentcore-client.js';\nimport {\n mcpInvokeOnce,\n MCP_CONTAINER_PORT,\n MCP_PATH,\n type McpInvokeResult,\n type McpJsonRpcRequest,\n} from '../../local/agentcore-mcp-client.js';\nimport {\n a2aInvokeOnce,\n A2A_CONTAINER_PORT,\n A2A_PATH,\n type A2aInvokeResult,\n type A2aJsonRpcRequest,\n} from '../../local/agentcore-a2a-client.js';\nimport { invokeAgentCoreWs, type AgentCoreWsResult } from '../../local/agentcore-ws-client.js';\nimport { createJwksCache, verifyJwtViaDiscovery } from '../../local/cognito-jwt.js';\nimport { resolveEnvVars, type EnvOverrideFile } from '../../local/env-resolver.js';\nimport {\n substituteAgainstStateAsync,\n substituteEnvVarsFromStateAsync,\n type SubstitutionContext,\n} from '../../local/state-resolver.js';\nimport {\n derivePseudoParametersFromRegion,\n type ImageResolutionContext,\n} from '../../local/intrinsic-image.js';\nimport {\n ensureDockerAvailable,\n pickFreePort,\n pullImage,\n removeContainer,\n runDetached,\n streamLogs,\n} from '../../local/docker-runner.js';\nimport { buildContainerImage } from '../../local/docker-image-builder.js';\nimport { parseEcrUri, pullEcrImage } from '../../local/ecr-puller.js';\nimport {\n AssetManifestLoader,\n getDockerImageBySourceHash,\n} from '../../assets/asset-manifest-loader.js';\nimport type { FileAsset } from '../../types/assets.js';\nimport { singleFlight } from '../../utils/single-flight.js';\nimport { resolveProfileCredentials } from './local-start-api.js';\nimport {\n applyProfileCredentialsOverlay,\n resolveExecutionRoleArnFromState,\n} from './local-invoke.js';\nimport {\n writeProfileCredentialsFile,\n type ProfileCredentialsFile,\n} from './local-profile-credentials-file.js';\n\ninterface LocalInvokeAgentCoreOptions {\n app?: string;\n output: string;\n verbose: boolean;\n region?: string;\n profile?: string;\n roleArn?: string;\n context?: string[];\n event?: string;\n eventStdin?: boolean;\n envVars?: string;\n pull: boolean;\n build: boolean;\n containerHost: string;\n /** `--platform <linux/amd64|linux/arm64>`. Defaults to AgentCore's required arm64. */\n platform: string;\n /**\n * `--ws`: use the HTTP-protocol agent's bidirectional `/ws` WebSocket\n * endpoint (on 8080) instead of `POST /invocations` — send `--event` as the\n * first frame and stream received frames to stdout until the agent closes.\n */\n ws?: boolean;\n /**\n * `--ws-interactive`: after the initial `--event` frame, read additional\n * frames from stdin (one frame per line, trailing newline stripped) and\n * send each as a text frame to the agent until stdin EOFs (Ctrl-D) or the\n * agent closes the connection. Only meaningful with `--ws`.\n */\n wsInteractive?: boolean;\n /** Session id forwarded via the AgentCore session-id header (auto-generated when omitted). */\n sessionId?: string;\n /**\n * Bearer JWT to present when the runtime declares a `customJwtAuthorizer`.\n * Verified against the runtime's OIDC discovery URL before the container\n * starts, then forwarded to `/invocations` as `Authorization: Bearer <jwt>`.\n */\n bearerToken?: string;\n /**\n * Commander maps `--no-verify-auth` to `verifyAuth: boolean` (default\n * `true`). When `false`, skip inbound JWT verification entirely (local-dev\n * escape hatch) — the token, if any, is still forwarded.\n */\n verifyAuth: boolean;\n /**\n * `--sigv4`: sign the `/invocations` POST with AWS SigV4 (service\n * `bedrock-agentcore`) using the resolved credentials — matching the\n * cloud's default IAM-auth behavior when the runtime declares no\n * `customJwtAuthorizer`. The local agent receives the same `Authorization:\n * AWS4-HMAC-SHA256 ...` + `X-Amz-Date` / `X-Amz-Content-Sha256` /\n * `X-Amz-Security-Token` headers it would in the cloud. Opt-in: default\n * unsigned (preserves existing behavior). Mutually exclusive with\n * `--bearer-token` and ignored on a JWT-protected runtime.\n */\n sigv4?: boolean;\n /**\n * Optional execution role to assume before invoking. Commander's `[arn]`\n * maps to `string | boolean`:\n * - absent → `undefined` (dev creds pass through; SAM-compatible default)\n * - `--assume-role` (bare) → `true` (use the runtime's literal RoleArn)\n * - `--assume-role <arn>` → `'<arn>'`\n * - `--no-assume-role` → `false`\n */\n assumeRole?: string | boolean;\n /** Role ARN to assume before authenticating against ECR for the container image pull. */\n ecrRoleArn?: string;\n fromCfnStack?: string | boolean;\n stackRegion?: string;\n /**\n * Per-request timeout in milliseconds, applied to the HTTP `/invocations`\n * POST, the MCP `POST /mcp` request, and the `/ws` open-to-close window.\n * Default 120000 (120s). Raise this for long-running agent calls that\n * exceed the default — the cloud's AgentCore quota goes well above 120s.\n */\n timeout: number;\n /** Host-injected extra state-source flag fields. */\n [key: string]: unknown;\n}\n\n/**\n * Parser for `--timeout <ms>`. Accepts a positive integer; rejects 0,\n * negatives, fractions, and non-numeric input.\n */\nexport function parseTimeoutMs(raw: string): number {\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new CdkLocalError(\n `--timeout must be a positive integer number of milliseconds (got '${raw}').`,\n 'LOCAL_INVOKE_AGENTCORE_TIMEOUT_INVALID'\n );\n }\n return parsed;\n}\n\n/**\n * Factory options for {@link createLocalInvokeAgentCoreCommand}.\n */\nexport interface CreateLocalInvokeAgentCoreCommandOptions {\n extraStateProviders?: ExtraStateProviders;\n /** Embed-time branding overrides for a host wrapping this factory. */\n embedConfig?: CdkLocalEmbedConfig;\n}\n\n/**\n * `cdkl invoke-agentcore <target>` — run a Bedrock AgentCore Runtime container\n * locally and invoke it once over the AgentCore HTTP contract. Resolves\n * the `AWS::BedrockAgentCore::Runtime`, pulls / builds its container,\n * starts it on port 8080, waits for `GET /ping`, POSTs the event to\n * `POST /invocations`, prints the response, and tears down. Covers the\n * container artifact and the CodeConfiguration managed-runtime artifact\n * (fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent's\n * calls to real AWS go to real AWS (credentials injected like `cdkl invoke`).\n */\nasync function localInvokeAgentCoreCommand(\n target: string | undefined,\n options: LocalInvokeAgentCoreOptions,\n extraStateProviders: ExtraStateProviders | undefined\n): Promise<void> {\n const logger = getLogger();\n if (options.verbose) logger.setLevel('debug');\n\n warnIfDeprecatedRegion(options);\n\n let containerId: string | undefined;\n let stopLogs: (() => void) | undefined;\n let sigintHandler: (() => void) | undefined;\n let profileCredsFile: ProfileCredentialsFile | undefined;\n let stateProvider: LocalStateProvider | undefined;\n\n const cleanup = singleFlight(\n async (): Promise<void> => {\n if (stateProvider) {\n try {\n stateProvider.dispose();\n } catch (err) {\n getLogger().debug(\n `state provider dispose failed: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n if (stopLogs) {\n try {\n stopLogs();\n } catch (err) {\n getLogger().debug(\n `streamLogs stop failed: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n if (containerId) {\n try {\n await removeContainer(containerId);\n } catch (err) {\n getLogger().debug(\n `removeContainer(${containerId}) failed: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n if (profileCredsFile) {\n try {\n await profileCredsFile.dispose();\n } catch (err) {\n getLogger().debug(\n `Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n },\n (err) => {\n getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n );\n\n try {\n await applyRoleArnIfSet({ roleArn: options.roleArn, region: options.region });\n await ensureDockerAvailable();\n\n const profileCredentials = options.profile\n ? await resolveProfileCredentials(options.profile)\n : undefined;\n if (options.profile && profileCredentials) {\n profileCredsFile = await writeProfileCredentialsFile(options.profile, profileCredentials);\n }\n\n const appCmd = resolveApp(options.app);\n if (!appCmd) {\n throw new Error(\n `No CDK app specified. Pass --app, set ${getEmbedConfig().envPrefix}_APP, or add \"app\" to cdk.json.`\n );\n }\n\n logger.info('Synthesizing CDK app...');\n const synthesizer = new Synthesizer();\n const context = parseContextOptions(options.context);\n const synthOpts: SynthesisOptions = {\n app: appCmd,\n output: options.output,\n ...(options.region && { region: options.region }),\n ...(options.profile && { profile: options.profile }),\n ...(Object.keys(context).length > 0 && { context }),\n };\n const { stacks } = await synthesizer.synthesize(synthOpts);\n\n const resolvedTarget = await resolveSingleTarget(target, {\n entries: listTargets(stacks).agentCoreRuntimes,\n message: 'Select an AgentCore Runtime to invoke',\n noun: 'AgentCore Runtimes',\n onMissing: () =>\n new CdkLocalError(\n `${getEmbedConfig().cliName} invoke-agentcore requires a <target> (an AgentCore Runtime display path or logical ID). ` +\n `Run \\`${getEmbedConfig().cliName} list\\` to see them, or run it in a TTY to pick interactively.`,\n 'LOCAL_INVOKE_AGENTCORE_TARGET_REQUIRED'\n ),\n });\n\n // Build a `--from-cfn-stack` image-resolution context BEFORE resolving the\n // target, so a same-stack AWS::ECR::Repository Fn::Join ContainerUri (or an\n // Fn::Sub asset URI) reduces to the deployed image URI. The state load is\n // shared with the env-substitution + role-from-state steps below.\n const candidate = pickAgentCoreCandidateStack(resolvedTarget, stacks);\n stateProvider = createLocalStateProvider(\n options,\n candidate?.stackName ?? '',\n await resolveCfnFallbackRegion(options, candidate?.region),\n extraStateProviders\n );\n const { context: imageContext, loaded: loadedState } =\n stateProvider && candidate\n ? await buildAgentCoreImageContext(candidate, stateProvider, options)\n : { context: undefined, loaded: undefined };\n\n const resolved = resolveAgentCoreTarget(resolvedTarget, stacks, imageContext);\n logger.info(`Target: ${resolved.stack.stackName}/${resolved.logicalId} (${resolved.protocol})`);\n const isMcp = resolved.protocol === AGENTCORE_MCP_PROTOCOL;\n const isA2a = resolved.protocol === AGENTCORE_A2A_PROTOCOL;\n const isAgui = resolved.protocol === AGENTCORE_AGUI_PROTOCOL;\n if (isAgui) {\n // AG-UI's wire shape is HTTP-compatible: SSE on `POST /invocations` and a\n // bidirectional WebSocket on `/ws`, both on port 8080. So an AG-UI\n // runtime routes through the same client path as HTTP — the existing\n // SSE / WS handlers stream bytes transparently. Surface this in the\n // log so users aren't surprised the AGUI runtime \"becomes\" HTTP.\n logger.info(\n 'AGUI runtime: routing through the HTTP /invocations + /ws path (AG-UI wire is SSE / WebSocket on port 8080).'\n );\n }\n if ((isMcp || isA2a) && options.ws) {\n logger.warn(\n `--ws applies only to the HTTP / AGUI protocols; ignoring it for this ${resolved.protocol} runtime.`\n );\n }\n if (options.wsInteractive && !options.ws) {\n logger.warn('--ws-interactive is meaningful only with --ws; ignoring.');\n }\n if (options.sigv4 && (isMcp || isA2a || options.ws)) {\n logger.warn(\n '--sigv4 signs the HTTP /invocations request only; ignoring it for the ' +\n (isMcp ? 'MCP' : isA2a ? 'A2A' : '/ws WebSocket') +\n ' path.'\n );\n }\n\n // Read + validate the event (and resolve the session id) BEFORE any\n // Docker work, so a bad --event / --event-stdin fails fast instead of\n // after paying for an image build + container boot.\n const sessionId = options.sessionId ?? randomUUID();\n const event = await readEvent(options);\n // For MCP, parse the event into a JSON-RPC request up front so a malformed\n // one fails fast too (default: tools/list).\n const mcpRequest = isMcp ? buildMcpRequest(event) : undefined;\n // A2A is JSON-RPC 2.0 too: parse the event up front into a method/params\n // (default: agent/getCard — the agent's discovery card).\n const a2aRequest = isA2a ? buildA2aRequest(event) : undefined;\n\n // Inbound JWT auth: when the runtime declares a customJwtAuthorizer,\n // verify the supplied bearer token against its OIDC discovery URL BEFORE\n // any Docker work — rejecting a missing / invalid token the way AgentCore\n // does. Returns the `Authorization` header to forward to the container.\n // MCP / A2A talk vanilla JSON-RPC directly to the container; their\n // bearer / session is an AgentCore managed-plane concern the front door\n // layers on top, so it is not applied to a direct local POST.\n let authorization: string | undefined;\n if (isMcp || isA2a) {\n if (resolved.jwtAuthorizer || options.bearerToken) {\n const pathLabel = isMcp ? MCP_PATH : A2A_PATH;\n logger.info(\n `${resolved.protocol} runtime: invoking the local container's ${pathLabel} directly (vanilla ${resolved.protocol}). ` +\n `An inbound JWT / --bearer-token is an AgentCore managed-plane concern and is not applied locally.`\n );\n }\n } else {\n authorization = await resolveInboundAuthorization(resolved, options);\n }\n\n // If the fromS3 bundle's Code.S3.Bucket is an intrinsic (Ref /\n // Fn::ImportValue / Fn::GetStackOutput), resolve it against --from-cfn-stack\n // state BEFORE the image step (which needs a literal bucket for the S3\n // download). Reuses the same substitution machinery env vars use, so\n // every cross-stack intrinsic the env path supports is supported here too.\n await resolveFromS3BucketIntrinsic(resolved, stateProvider, loadedState, imageContext);\n\n const image = await resolveAgentCoreImage(resolved, options, loadedState, stateProvider);\n\n const { env: dockerEnv, sensitiveEnvKeys } = await buildContainerEnv(\n resolved,\n options,\n profileCredentials,\n profileCredsFile,\n stateProvider,\n loadedState,\n imageContext\n );\n\n const hostPort = await pickFreePort();\n const containerHost = options.containerHost;\n // Stable `cdkl-`-prefixed name so the orphan sweep (`docker ps --filter\n // name=cdkl-`) used by `/cleanup` + `/run-integ` can find this container\n // if the process is killed before teardown — unlike a one-shot Lambda\n // invoke, the agent container runs a long-lived HTTP server.\n const containerName = `${getEmbedConfig().resourceNamePrefix}-agentcore-${process.pid}-${Math.random().toString(36).slice(2, 8)}`;\n const containerPort = isMcp ? MCP_CONTAINER_PORT : isA2a ? A2A_CONTAINER_PORT : undefined;\n const containerPortLabel = isMcp\n ? `${MCP_CONTAINER_PORT}${MCP_PATH}`\n : isA2a\n ? `${A2A_CONTAINER_PORT}${A2A_PATH}`\n : '8080';\n logger.info(\n `Starting agent container (image=${image}, port=${hostPort} -> ${containerPortLabel})...`\n );\n containerId = await runDetached({\n image,\n mounts: [],\n env: dockerEnv,\n cmd: [],\n hostPort,\n host: containerHost,\n platform: options.platform,\n name: containerName,\n ...(containerPort !== undefined && { containerPort }),\n // Keep decrypted SecureString SSM env values off the `docker run` argv.\n ...(sensitiveEnvKeys.size > 0 && { sensitiveEnvKeys }),\n });\n\n stopLogs = streamLogs(containerId);\n\n sigintHandler = (): void => {\n void cleanup().then(() => process.exit(130));\n };\n process.on('SIGINT', sigintHandler);\n\n if (isMcp && mcpRequest) {\n // MCP has no /ping: mcpInvokeOnce folds the boot-wait into a retried\n // `initialize`, then runs the session handshake + the one request.\n logger.info(`MCP request: ${mcpRequest.method}`);\n const mcp = await mcpInvokeOnce(containerHost, hostPort, mcpRequest, {\n requestTimeoutMs: options.timeout,\n });\n // Settle so container logs flush before teardown.\n await new Promise((r) => setTimeout(r, 250));\n emitMcpResult(mcp);\n } else if (isA2a && a2aRequest) {\n // A2A has no /ping either: a2aInvokeOnce folds the boot-wait into a\n // retried POST. One JSON-RPC round-trip — vanilla A2A.\n logger.info(`A2A request: ${a2aRequest.method}`);\n const a2a = await a2aInvokeOnce(containerHost, hostPort, a2aRequest, {\n requestTimeoutMs: options.timeout,\n });\n await new Promise((r) => setTimeout(r, 250));\n emitA2aResult(a2a);\n } else if (options.ws) {\n // Bidirectional `/ws` (same 8080 container as /invocations): send the\n // event as the first frame, stream every received frame to stdout, then\n // resolve when the agent closes the stream. With `--ws-interactive` we\n // additionally wire `process.stdin` (line-buffered) as a frame source,\n // so each typed line becomes a follow-up text frame until EOF / agent\n // close — a REPL on top of the same connection.\n await waitForAgentCorePing(containerHost, hostPort);\n const frameSource = options.wsInteractive ? readStdinLines() : undefined;\n logger.info(\n options.wsInteractive\n ? 'Opening the agent /ws WebSocket (interactive — stdin lines = follow-up frames; Ctrl-D to end)...'\n : 'Opening the agent /ws WebSocket and streaming frames...'\n );\n const wsResult = await invokeAgentCoreWs(containerHost, hostPort, event, {\n sessionId,\n timeoutMs: options.timeout,\n onMessage: (text) => process.stdout.write(text),\n ...(authorization && { authorization }),\n ...(frameSource && { frameSource }),\n });\n // Settle so container logs flush before teardown.\n await new Promise((r) => setTimeout(r, 250));\n emitWsResult(wsResult);\n } else {\n await waitForAgentCorePing(containerHost, hostPort);\n\n // `--sigv4` opt-in: sign the request with the resolved host credentials\n // (service `bedrock-agentcore`) so the agent receives the same\n // Authorization + X-Amz-* headers it would in the cloud. Mutually\n // exclusive with `--bearer-token`; ignored when a customJwtAuthorizer is\n // declared (the JWT path takes precedence).\n const additionalHeaders = await buildSigV4HeadersIfRequested(\n options,\n resolved,\n loadedState,\n containerHost,\n hostPort,\n event,\n sessionId,\n stateProvider\n );\n\n const result = await invokeAgentCore(containerHost, hostPort, event, {\n sessionId,\n timeoutMs: options.timeout,\n // Stream a text/event-stream response to stdout as it arrives, so a\n // token-streaming agent shows incrementally rather than all at once.\n onChunk: (text) => process.stdout.write(text),\n ...(authorization && { authorization }),\n ...(additionalHeaders && { additionalHeaders }),\n });\n\n // Settle so container logs flush before teardown.\n await new Promise((r) => setTimeout(r, 250));\n emitResult(result);\n }\n } finally {\n if (sigintHandler) process.off('SIGINT', sigintHandler);\n await cleanup();\n }\n}\n\n/**\n * Enforce the runtime's inbound JWT authorizer (when declared) and return\n * the `Authorization` header to forward to `/invocations`.\n *\n * - No authorizer → forward the token verbatim if one was given (no-op\n * otherwise).\n * - `--no-verify-auth` → warn + forward without verifying (local-dev escape).\n * - Authorizer + no token → reject (AgentCore returns 401).\n * - Authorizer + token → verify against the OIDC discovery URL; reject on\n * failure (AgentCore returns 403); forward on success. An unreachable\n * discovery URL falls back to pass-through accept (offline-dev fallback in\n * {@link verifyJwtViaDiscovery}).\n *\n * Exported so a unit test can drive the gate without the full Docker pipeline.\n */\nexport async function resolveInboundAuthorization(\n resolved: ResolvedAgentCoreRuntime,\n options: { bearerToken?: string; verifyAuth: boolean }\n): Promise<string | undefined> {\n const logger = getLogger();\n const authorizer = resolved.jwtAuthorizer;\n const header = options.bearerToken ? `Bearer ${options.bearerToken}` : undefined;\n\n if (!authorizer) return header;\n\n if (options.verifyAuth === false) {\n logger.warn(\n `Runtime '${resolved.logicalId}' declares a customJwtAuthorizer, but --no-verify-auth was set — ` +\n `skipping inbound JWT verification (local-dev escape hatch).`\n );\n return header;\n }\n\n if (!header) {\n throw new CdkLocalError(\n `Runtime '${resolved.logicalId}' requires an inbound JWT (customJwtAuthorizer). ` +\n `Pass --bearer-token <jwt>, or --no-verify-auth to skip verification for local dev.`,\n 'LOCAL_INVOKE_AGENTCORE_AUTH_REQUIRED'\n );\n }\n\n const result = await verifyJwtViaDiscovery(\n {\n discoveryUrl: authorizer.discoveryUrl,\n ...(authorizer.allowedAudience && { allowedAudience: authorizer.allowedAudience }),\n ...(authorizer.allowedClients && { allowedClients: authorizer.allowedClients }),\n ...(authorizer.allowedScopes && { allowedScopes: authorizer.allowedScopes }),\n ...(authorizer.customClaims && { customClaims: authorizer.customClaims }),\n },\n header,\n createJwksCache(),\n { warned: new Set() }\n );\n if (!result.allow) {\n throw new CdkLocalError(\n `Inbound JWT rejected by the runtime's customJwtAuthorizer ` +\n `(signature / issuer / expiry / audience check failed against ${authorizer.discoveryUrl}).`,\n 'LOCAL_INVOKE_AGENTCORE_AUTH_DENIED'\n );\n }\n logger.info(`Inbound JWT verified against ${authorizer.discoveryUrl}.`);\n return header;\n}\n\n/**\n * Compute the SigV4 headers for the `/invocations` POST when `--sigv4` is\n * requested. Returns `undefined` (no header overlay) when:\n *\n * - `--sigv4` is not set,\n * - the runtime declares a `customJwtAuthorizer` (the JWT path wins; warns),\n *\n * Throws a {@link CdkLocalError} when `--sigv4` conflicts with\n * `--bearer-token`, or when no AWS credentials are resolvable for signing.\n *\n * Exported so a unit test can drive the gate without the full Docker pipeline.\n */\nexport async function buildSigV4HeadersIfRequested(\n options: LocalInvokeAgentCoreOptions,\n resolved: ResolvedAgentCoreRuntime,\n loaded: LocalStateRecord | undefined,\n host: string,\n port: number,\n event: unknown,\n sessionId: string,\n stateProvider?: LocalStateProvider\n): Promise<Record<string, string> | undefined> {\n if (!options.sigv4) return undefined;\n if (options.bearerToken) {\n throw new CdkLocalError(\n `--sigv4 and --bearer-token are mutually exclusive: pick one inbound auth.`,\n 'LOCAL_INVOKE_AGENTCORE_AUTH_CONFLICT'\n );\n }\n if (resolved.jwtAuthorizer) {\n getLogger().warn(\n `Runtime '${resolved.logicalId}' declares a customJwtAuthorizer; --sigv4 ignored (JWT path takes precedence).`\n );\n return undefined;\n }\n const region =\n options.region ??\n options.stackRegion ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n resolved.stack.region;\n if (!region) {\n throw new CdkLocalError(\n `--sigv4: no region resolved for the AgentCore signing scope. ` +\n `Pass --region <region>, set AWS_REGION, or use --from-cfn-stack with a region-bound stack.`,\n 'LOCAL_INVOKE_AGENTCORE_SIGV4_NO_REGION'\n );\n }\n const credentials = await resolveHostCredentialsForSigV4(\n options,\n resolved,\n loaded,\n region,\n stateProvider\n );\n const signed = await signAgentCoreInvocation({\n credentials,\n region,\n host,\n port,\n path: '/invocations',\n body: JSON.stringify(event ?? {}),\n sessionId,\n });\n const headers: Record<string, string> = {\n Authorization: signed.authorization,\n 'X-Amz-Date': signed.amzDate,\n 'X-Amz-Content-Sha256': signed.amzContentSha256,\n };\n if (signed.amzSecurityToken) headers['X-Amz-Security-Token'] = signed.amzSecurityToken;\n getLogger().info(`Signed /invocations with SigV4 (region=${region}).`);\n return headers;\n}\n\n/**\n * Resolve credentials for host-side SigV4 signing. Precedence:\n * 1. `--assume-role` → STS temp creds (warn + fall through on STS failure);\n * 2. `--profile` → profile creds (sessionToken when the profile carries one);\n * 3. shell env (`AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / optional\n * `AWS_SESSION_TOKEN`).\n *\n * Throws a {@link CdkLocalError} when none are available — `--sigv4` cannot\n * proceed without credentials, unlike the unsigned path.\n */\nasync function resolveHostCredentialsForSigV4(\n options: LocalInvokeAgentCoreOptions,\n resolved: ResolvedAgentCoreRuntime,\n loaded: LocalStateRecord | undefined,\n region: string,\n stateProvider: LocalStateProvider | undefined\n): Promise<SigV4Credentials> {\n const logger = getLogger();\n const assumeRoleArn = await resolveAssumeRoleArn(options, resolved, loaded, stateProvider);\n if (assumeRoleArn) {\n try {\n return await assumeAgentCoreExecutionRole(assumeRoleArn, region);\n } catch (err) {\n logger.warn(\n `--assume-role: STS AssumeRole(${assumeRoleArn}) failed for --sigv4 signing: ` +\n `${err instanceof Error ? err.message : String(err)}. ` +\n `Falling back to ${options.profile ? `--profile ${options.profile}` : 'shell credentials'}.`\n );\n }\n }\n if (options.profile) {\n const creds = await resolveProfileCredentials(options.profile);\n if (creds?.accessKeyId && creds.secretAccessKey) {\n return {\n accessKeyId: creds.accessKeyId,\n secretAccessKey: creds.secretAccessKey,\n ...(creds.sessionToken && { sessionToken: creds.sessionToken }),\n };\n }\n }\n const accessKeyId = process.env['AWS_ACCESS_KEY_ID'];\n const secretAccessKey = process.env['AWS_SECRET_ACCESS_KEY'];\n if (accessKeyId && secretAccessKey) {\n const sessionToken = process.env['AWS_SESSION_TOKEN'];\n return {\n accessKeyId,\n secretAccessKey,\n ...(sessionToken && { sessionToken }),\n };\n }\n throw new CdkLocalError(\n `--sigv4: no AWS credentials available to sign the request. ` +\n `Set AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY, pass --profile <name>, or pass --assume-role <arn>.`,\n 'LOCAL_INVOKE_AGENTCORE_SIGV4_NO_CREDENTIALS'\n );\n}\n\n/**\n * Acquire the agent image. A CODE artifact (managed runtime) is built from\n * source — a fromCodeAsset bundle from its cdk.out asset, a fromS3 bundle\n * downloaded + extracted from S3. A CONTAINER artifact mirrors the\n * container-Lambda path: build from a local cdk.out asset when the URI matches\n * one, else pull from ECR, else pull a plain registry image.\n *\n * `loaded` is the `--from-cfn-stack` state record (when available) — threaded\n * through so a bare `--assume-role` can resolve the execution-role ARN from\n * state for the fromS3 download. `stateProvider` enables the issue-#187\n * live-fallback to `bedrock-agentcore-control:GetAgentRuntime` when the\n * static state lookup misses.\n */\nexport async function resolveAgentCoreImage(\n resolved: ResolvedAgentCoreRuntime,\n options: LocalInvokeAgentCoreOptions,\n loaded?: LocalStateRecord,\n stateProvider?: LocalStateProvider\n): Promise<string> {\n const logger = getLogger();\n const architecture = platformToArchitecture(options.platform);\n\n if (resolved.codeArtifact) {\n return resolveAgentCoreCodeImage(\n resolved,\n resolved.codeArtifact,\n options,\n architecture,\n loaded,\n stateProvider\n );\n }\n\n const containerUri = resolved.containerUri;\n if (containerUri === undefined) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' has neither a container image nor a code artifact to run.`,\n 'LOCAL_INVOKE_AGENTCORE_NO_ARTIFACT'\n );\n }\n\n const manifestPath = resolved.stack.assetManifestPath;\n if (manifestPath) {\n const cdkOutDir = dirname(manifestPath);\n const loader = new AssetManifestLoader();\n const manifest = await loader.loadManifest(cdkOutDir, resolved.stack.stackName);\n if (manifest) {\n const entry = getDockerImageBySourceHash(manifest, containerUri);\n if (entry) {\n return buildContainerImage(entry.asset, cdkOutDir, {\n architecture,\n noBuild: options.build === false,\n });\n }\n }\n }\n\n if (parseEcrUri(containerUri)) {\n logger.info(`Pulling agent image from ECR: ${containerUri}`);\n return pullEcrImage(containerUri, {\n skipPull: options.pull === false,\n ...(options.region !== undefined && { region: options.region }),\n ...(options.ecrRoleArn !== undefined && { ecrRoleArn: options.ecrRoleArn }),\n ...(options.profile !== undefined && { profile: options.profile }),\n });\n }\n\n await pullImage(containerUri, options.pull === false);\n return containerUri;\n}\n\n/**\n * Build a local image from a `CodeConfiguration` (managed-runtime) bundle.\n *\n * - fromS3 (`code.s3Source` set, a literal S3 object): download + extract the\n * bundle, then run the from-source build over the extracted dir.\n * - fromCodeAsset: locate the source dir in cdk.out via its asset hash, then\n * run the same from-source build (generated Dockerfile → install deps → run\n * EntryPoint).\n */\nasync function resolveAgentCoreCodeImage(\n resolved: ResolvedAgentCoreRuntime,\n code: AgentCoreCodeArtifact,\n options: LocalInvokeAgentCoreOptions,\n architecture: 'x86_64' | 'arm64',\n loaded?: LocalStateRecord,\n stateProvider?: LocalStateProvider\n): Promise<string> {\n if (code.s3Source) {\n return resolveAgentCoreCodeImageFromS3(\n resolved,\n code,\n code.s3Source,\n options,\n architecture,\n loaded,\n stateProvider\n );\n }\n\n const manifestPath = resolved.stack.assetManifestPath;\n if (!manifestPath) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' uses a code artifact, but its stack has no asset ` +\n `manifest in cdk.out to read the bundle source from.`,\n 'LOCAL_INVOKE_AGENTCORE_CODE_NO_MANIFEST'\n );\n }\n const cdkOutDir = dirname(manifestPath);\n const loader = new AssetManifestLoader();\n const manifest = await loader.loadManifest(cdkOutDir, resolved.stack.stackName);\n const fileAssets = manifest ? loader.getFileAssets(manifest) : undefined;\n // The manifest's `files` are keyed by SOURCE hash; for the default\n // synthesizer that equals the destination objectKey hash (`<hash>.zip`), so a\n // direct key lookup hits. Fall back to matching the destination objectKey so\n // a synthesizer that emits a prefixed / differing objectKey still resolves.\n const asset = fileAssets\n ? (fileAssets.get(code.codeAssetHash) ??\n findFileAssetByObjectKey(fileAssets, code.codeAssetHash))\n : undefined;\n if (!asset) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' code bundle (asset ${code.codeAssetHash}) was not found ` +\n `in the cdk.out asset manifest. ${getEmbedConfig().cliName} invoke-agentcore runs a local from-source ` +\n `build of a fromCodeAsset bundle — re-synthesize the app so the asset is staged in cdk.out and retry. ` +\n `(A fromS3 bundle is downloaded from S3 instead; this runtime has no literal Code.S3.Bucket.)`,\n 'LOCAL_INVOKE_AGENTCORE_CODE_ASSET_NOT_FOUND'\n );\n }\n const sourceDir = loader.getAssetSourcePath(cdkOutDir, asset);\n if (!existsSync(sourceDir) || !statSync(sourceDir).isDirectory()) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' code bundle source '${sourceDir}' does not exist or is not a ` +\n `directory. Re-synthesize the app and retry.`,\n 'LOCAL_INVOKE_AGENTCORE_CODE_SOURCE_MISSING'\n );\n }\n return buildAgentCoreCodeImage({\n sourceDir,\n runtime: code.runtime,\n entryPoint: code.entryPoint,\n architecture,\n noBuild: options.build === false,\n });\n}\n\n/**\n * Build a local image from a fromS3 CodeConfiguration bundle: download +\n * extract the S3 object, run the from-source build over the extracted dir, then\n * clean up the temp dir.\n *\n * Credentials mirror the rest of the command: an `--assume-role` ARN (explicit,\n * or resolved from `--from-cfn-stack` state for the bare form) yields STS temp\n * creds for the download; otherwise `--profile` / the default chain is used.\n * The region is `--region` / `--stack-region` / env / the stack's region.\n */\nasync function resolveAgentCoreCodeImageFromS3(\n resolved: ResolvedAgentCoreRuntime,\n code: AgentCoreCodeArtifact,\n s3Source: NonNullable<AgentCoreCodeArtifact['s3Source']>,\n options: LocalInvokeAgentCoreOptions,\n architecture: 'x86_64' | 'arm64',\n loaded: LocalStateRecord | undefined,\n stateProvider: LocalStateProvider | undefined\n): Promise<string> {\n const logger = getLogger();\n // The bucket should be a literal string by this point — a template-literal\n // bucket falls through from the resolver, an intrinsic bucket was resolved by\n // `resolveFromS3BucketIntrinsic` in the outer command before we got here.\n if (typeof s3Source.bucket !== 'string' || s3Source.bucket.length === 0) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' fromS3 bundle reached the image step with no literal bucket. ` +\n `This is a cdk-local bug — please report it.`,\n 'LOCAL_INVOKE_AGENTCORE_FROMS3_BUCKET_UNRESOLVED'\n );\n }\n const location = {\n bucket: s3Source.bucket,\n key: s3Source.key,\n ...(s3Source.versionId !== undefined && { versionId: s3Source.versionId }),\n };\n const region =\n options.region ??\n options.stackRegion ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n resolved.stack.region;\n\n const assumeRoleArn = await resolveAssumeRoleArn(options, resolved, loaded, stateProvider);\n let credentials:\n | { accessKeyId: string; secretAccessKey: string; sessionToken: string }\n | undefined;\n if (assumeRoleArn) {\n try {\n credentials = await assumeAgentCoreExecutionRole(assumeRoleArn, region);\n } catch (err) {\n logger.warn(\n `--assume-role: STS AssumeRole(${assumeRoleArn}) failed for the fromS3 bundle download: ` +\n `${err instanceof Error ? err.message : String(err)}. ` +\n `Falling back to ${options.profile ? `--profile ${options.profile}` : 'the default credentials'}.`\n );\n }\n }\n\n const bundle = await downloadAndExtractS3Bundle(location, {\n ...(region !== undefined && { region }),\n ...(options.profile !== undefined && { profile: options.profile }),\n ...(credentials !== undefined && { credentials }),\n });\n try {\n return await buildAgentCoreCodeImage({\n sourceDir: bundle.dir,\n runtime: code.runtime,\n entryPoint: code.entryPoint,\n architecture,\n noBuild: options.build === false,\n });\n } finally {\n await bundle.cleanup();\n }\n}\n\n/**\n * Find the file asset whose destination objectKey is `<hash>.zip` (matching the\n * `Code.S3.Prefix`'s hash) when the source-hash-keyed lookup misses — covers a\n * synthesizer whose source hash differs from the destination objectKey.\n */\nfunction findFileAssetByObjectKey(\n fileAssets: Map<string, FileAsset>,\n hash: string\n): FileAsset | undefined {\n const zip = `${hash}.zip`;\n for (const asset of fileAssets.values()) {\n const hit = Object.values(asset.destinations).some(\n (d) => d.objectKey === zip || d.objectKey.endsWith(`/${zip}`)\n );\n if (hit) return asset;\n }\n return undefined;\n}\n\n/**\n * Build the container env + the set of env keys to keep off the `docker run`\n * argv. Substitutes `--from-cfn-stack` state into the template env (reusing the\n * shared state load + image-resolution context — Ref / Fn::Sub / Fn::Join +\n * SSM parameters, with decrypted SecureString values flagged sensitive),\n * applies `--env-vars` overrides, then injects AWS credentials (`--assume-role`\n * STS temp creds — resolving an intrinsic RoleArn from state for bare\n * `--assume-role` — else `--profile` / dev creds).\n *\n * The state provider + loaded record + image context are built once by the\n * caller and shared here, so this does not re-load state.\n */\nexport async function buildContainerEnv(\n resolved: ResolvedAgentCoreRuntime,\n options: LocalInvokeAgentCoreOptions,\n profileCredentials:\n | { accessKeyId: string; secretAccessKey: string; sessionToken?: string }\n | undefined,\n profileCredsFile: ProfileCredentialsFile | undefined,\n stateProvider: LocalStateProvider | undefined,\n loaded: LocalStateRecord | undefined,\n imageContext: ImageResolutionContext | undefined\n): Promise<{ env: Record<string, string>; sensitiveEnvKeys: Set<string> }> {\n const logger = getLogger();\n let templateEnv: Record<string, unknown> = resolved.environmentVariables;\n const sensitiveEnvKeys = new Set<string>();\n\n if (stateProvider && loaded) {\n const subContext: SubstitutionContext = {\n resources: imageContext?.stateResources ?? loaded.resources,\n consumerRegion: loaded.region,\n };\n const pseudo =\n imageContext?.pseudoParameters ?? derivePseudoParametersFromRegion(loaded.region);\n if (pseudo) subContext.pseudoParameters = pseudo;\n if (imageContext?.stateParameters) subContext.parameters = imageContext.stateParameters;\n if (imageContext?.stateSensitiveParameters?.length) {\n subContext.sensitiveParameters = new Set(imageContext.stateSensitiveParameters);\n }\n const resolver = await stateProvider.buildCrossStackResolver(loaded.region);\n if (resolver) subContext.crossStackResolver = resolver;\n const { env, audit } = await substituteEnvVarsFromStateAsync(templateEnv, subContext);\n templateEnv = env;\n for (const key of audit.resolvedKeys) {\n logger.debug(`${stateProvider.label}: substituted env var ${key}`);\n }\n // Decrypted SecureString SSM values: keep them off the `docker run` argv.\n for (const key of audit.sensitiveKeys) sensitiveEnvKeys.add(key);\n for (const { key, reason } of audit.unresolved) {\n logger.warn(\n `${stateProvider.label}: could not substitute env var ${key} (${reason}). ` +\n `Override it via --env-vars or it will be dropped.`\n );\n }\n }\n\n const overrides = readEnvOverridesFile(options.envVars);\n const cdkPath = readCdkPathOrUndefined(resolved.resource);\n const envResult = resolveEnvVars(resolved.logicalId, cdkPath, templateEnv, overrides);\n for (const key of envResult.unresolved) {\n const overrideKeyExample = cdkPath?.replace(/\\/Resource$/, '') ?? resolved.logicalId;\n logger.warn(\n `Environment variable ${key} contains a CloudFormation intrinsic and was dropped. ` +\n `Override it with --env-vars (e.g. {\"${overrideKeyExample}\":{\"${key}\":\"<literal>\"}}), ` +\n `or pass a state-source flag (e.g. --from-cfn-stack) to recover deployed values.`\n );\n }\n\n const dockerEnv: Record<string, string> = { ...envResult.resolved };\n const assumeRoleArn = await resolveAssumeRoleArn(options, resolved, loaded, stateProvider);\n await applyAgentCoreCredentialEnv(dockerEnv, {\n ...(assumeRoleArn !== undefined && { assumeRoleArn }),\n ...(options.region !== undefined && { region: options.region }),\n ...(profileCredentials !== undefined && { profileCredentials }),\n ...(profileCredsFile !== undefined && {\n profileCredsFile: {\n containerPath: profileCredsFile.containerPath,\n profileName: profileCredsFile.profileName,\n },\n }),\n });\n return { env: dockerEnv, sensitiveEnvKeys };\n}\n\n/**\n * Resolve a fromS3 bundle's intrinsic `Code.S3.Bucket` to a literal bucket\n * name in place on `resolved.codeArtifact.s3Source.bucket`. Uses the SAME\n * state-substitution machinery env vars use under `--from-cfn-stack`, so\n * every cross-stack intrinsic that path supports (`Ref` / `Fn::ImportValue` /\n * `Fn::GetStackOutput`) is supported transparently here.\n *\n * No-op when there is no intrinsic to resolve. Errors when no state is\n * available, or when the substitution returns a non-string / unresolved value.\n *\n * Exported so a unit test can drive the gate without the full Docker pipeline.\n */\nexport async function resolveFromS3BucketIntrinsic(\n resolved: ResolvedAgentCoreRuntime,\n stateProvider: LocalStateProvider | undefined,\n loaded: LocalStateRecord | undefined,\n imageContext: ImageResolutionContext | undefined\n): Promise<void> {\n const s3Source = resolved.codeArtifact?.s3Source;\n if (!s3Source || s3Source.bucketIntrinsic === undefined) return;\n if (s3Source.bucket !== undefined) return; // already resolved\n\n if (!stateProvider || !loaded) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' fromS3 bundle's Code.S3.Bucket is an unresolved intrinsic ` +\n `(${describeIntrinsic(s3Source.bucketIntrinsic)}). ` +\n `Pass --from-cfn-stack so its physical bucket name can be resolved against the deployed stack state.`,\n 'LOCAL_INVOKE_AGENTCORE_FROMS3_BUCKET_INTRINSIC_NO_STATE'\n );\n }\n\n const subContext: SubstitutionContext = {\n resources: imageContext?.stateResources ?? loaded.resources,\n consumerRegion: loaded.region,\n };\n const pseudo = imageContext?.pseudoParameters ?? derivePseudoParametersFromRegion(loaded.region);\n if (pseudo) subContext.pseudoParameters = pseudo;\n const crossStackResolver = await stateProvider.buildCrossStackResolver(loaded.region);\n if (crossStackResolver) subContext.crossStackResolver = crossStackResolver;\n\n const result = await substituteAgainstStateAsync(s3Source.bucketIntrinsic, subContext);\n if (result.kind !== 'literal') {\n throw new CdkLocalError(\n `Could not resolve AgentCore Runtime '${resolved.logicalId}' fromS3 Code.S3.Bucket intrinsic ` +\n `(${describeIntrinsic(s3Source.bucketIntrinsic)}) against the --from-cfn-stack state: ${result.reason}. ` +\n `Confirm the referenced resource / export exists in the deployed stack.`,\n 'LOCAL_INVOKE_AGENTCORE_FROMS3_BUCKET_INTRINSIC_UNRESOLVED'\n );\n }\n if (typeof result.value !== 'string' || result.value.length === 0) {\n throw new CdkLocalError(\n `AgentCore Runtime '${resolved.logicalId}' fromS3 Code.S3.Bucket intrinsic resolved to a ` +\n `${typeof result.value} value, not a bucket name string. ` +\n `(${describeIntrinsic(s3Source.bucketIntrinsic)})`,\n 'LOCAL_INVOKE_AGENTCORE_FROMS3_BUCKET_INTRINSIC_NOT_STRING'\n );\n }\n s3Source.bucket = result.value;\n getLogger().info(\n `Resolved fromS3 Code.S3.Bucket from state: ${describeIntrinsic(s3Source.bucketIntrinsic)} -> ${result.value}`\n );\n}\n\n/** Render the intrinsic key for an error / log message (e.g. `Ref:Bucket1`). */\nfunction describeIntrinsic(value: unknown): string {\n if (!value || typeof value !== 'object') return String(value);\n const obj = value as Record<string, unknown>;\n const key = Object.keys(obj)[0] ?? '?';\n const arg = obj[key];\n if (typeof arg === 'string') return `${key}:${arg}`;\n return key;\n}\n\n/**\n * Build the `--from-cfn-stack` image-resolution context + return the loaded\n * state record (loaded once, reused by env substitution + role resolution).\n * Mirrors `run-task`'s `buildEcsImageResolutionContext`: pseudo parameters\n * (region + STS account id), the deployed resources, and SSM template\n * parameters (decrypted SecureString logical ids flagged sensitive).\n */\nexport async function buildAgentCoreImageContext(\n candidate: StackInfo,\n stateProvider: LocalStateProvider,\n options: LocalInvokeAgentCoreOptions\n): Promise<{ context: ImageResolutionContext | undefined; loaded: LocalStateRecord | undefined }> {\n const logger = getLogger();\n const region =\n options.region ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n candidate.region;\n\n let accountId: string | undefined;\n try {\n accountId = await resolveCallerAccountId(region, options.profile);\n } catch (err) {\n logger.warn(\n `--from-cfn-stack: STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. ` +\n 'A same-stack ECR image URI referencing ${AWS::AccountId} may not resolve.'\n );\n }\n\n const context: ImageResolutionContext = {};\n const pseudo = derivePseudoParametersFromRegion(region, accountId);\n if (pseudo) context.pseudoParameters = pseudo;\n\n const loaded = await stateProvider.load(candidate.stackName, candidate.region);\n if (loaded) {\n context.stateResources = loaded.resources;\n if (stateProvider.resolveTemplateSsmParameters) {\n const ssm = await stateProvider.resolveTemplateSsmParameters(candidate.template);\n if (Object.keys(ssm.values).length > 0) context.stateParameters = ssm.values;\n if (ssm.secureStringLogicalIds.length > 0) {\n context.stateSensitiveParameters = ssm.secureStringLogicalIds;\n }\n }\n }\n return { context, loaded: loaded ?? undefined };\n}\n\n/** STS `GetCallerIdentity` for the `${AWS::AccountId}` pseudo parameter (threads `--profile`). */\nasync function resolveCallerAccountId(\n region: string | undefined,\n profile: string | undefined\n): Promise<string | undefined> {\n const { STSClient, GetCallerIdentityCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }), ...(profile && { profile }) });\n try {\n const identity = await sts.send(new GetCallerIdentityCommand({}));\n return identity.Account;\n } finally {\n sts.destroy();\n }\n}\n\n/**\n * Inject AWS credentials into the container env. Precedence:\n * 1. `--assume-role` → STS-issued temp creds for the resolved ARN (on\n * STS failure, warn + fall through to dev creds).\n * 2. dev shell creds (`forwardAwsEnv`) + `--profile` overlay\n * ({@link applyProfileCredentialsOverlay}) + the bind-mounted\n * credentials-file env so handler `fromIni({ profile })` resolves.\n *\n * Exported so a unit test can lock the binding (mock STS) without driving\n * the full synth + docker pipeline.\n */\nexport async function applyAgentCoreCredentialEnv(\n dockerEnv: Record<string, string>,\n args: {\n assumeRoleArn?: string;\n region?: string;\n profileCredentials?: { accessKeyId: string; secretAccessKey: string; sessionToken?: string };\n profileCredsFile?: { containerPath: string; profileName: string };\n }\n): Promise<void> {\n const logger = getLogger();\n let assumeSucceeded = false;\n if (args.assumeRoleArn) {\n const stsRegion = args.region ?? process.env['AWS_REGION'] ?? process.env['AWS_DEFAULT_REGION'];\n try {\n const creds = await assumeAgentCoreExecutionRole(args.assumeRoleArn, stsRegion);\n dockerEnv['AWS_ACCESS_KEY_ID'] = creds.accessKeyId;\n dockerEnv['AWS_SECRET_ACCESS_KEY'] = creds.secretAccessKey;\n dockerEnv['AWS_SESSION_TOKEN'] = creds.sessionToken;\n if (stsRegion) dockerEnv['AWS_REGION'] = stsRegion;\n assumeSucceeded = true;\n } catch (err) {\n logger.warn(\n `--assume-role: STS AssumeRole(${args.assumeRoleArn}) failed: ${err instanceof Error ? err.message : String(err)}. ` +\n \"Falling back to the developer's shell credentials.\"\n );\n }\n }\n if (!assumeSucceeded) {\n forwardAwsEnv(dockerEnv);\n applyProfileCredentialsOverlay(dockerEnv, args.profileCredentials, false);\n if (args.profileCredsFile) {\n dockerEnv['AWS_SHARED_CREDENTIALS_FILE'] = args.profileCredsFile.containerPath;\n dockerEnv['AWS_PROFILE'] = args.profileCredsFile.profileName;\n }\n }\n}\n\n/**\n * Resolve the role ARN to assume, honoring the three `--assume-role` forms.\n * Bare `--assume-role` uses the runtime's literal `RoleArn`; when that is an\n * intrinsic (the common L2 case — `Fn::GetAtt` to an auto-created role) it\n * resolves the execution-role ARN from `--from-cfn-stack` state first; when\n * that misses (issue #187 — `ListStackResources` returns the role's name,\n * not its ARN, so `attributes.Arn` is empty on the CFn state map) it falls\n * back to `stateProvider.resolveAgentCoreRuntimeRoleArn(<physicalId>)`\n * (a `bedrock-agentcore-control:GetAgentRuntime` call) so a same-stack\n * execution role still resolves. Only warns + falls back to dev creds\n * when all of those miss.\n */\nexport async function resolveAssumeRoleArn(\n options: LocalInvokeAgentCoreOptions,\n resolved: ResolvedAgentCoreRuntime,\n loaded: LocalStateRecord | undefined,\n stateProvider?: Pick<LocalStateProvider, 'resolveAgentCoreRuntimeRoleArn'>\n): Promise<string | undefined> {\n if (typeof options.assumeRole === 'string') return options.assumeRole;\n if (options.assumeRole !== true) return undefined;\n // Bare --assume-role from here on.\n if (resolved.roleArn) return resolved.roleArn;\n if (loaded) {\n const fromState = resolveExecutionRoleArnFromState(loaded, resolved.logicalId, 'RoleArn');\n if (fromState) {\n getLogger().debug(`--assume-role: resolved RoleArn from state: ${fromState}`);\n return fromState;\n }\n // Issue #187 fallback: state-only lookup misses for sibling-stack\n // exec roles because `ListStackResources` returns the role's name,\n // not its ARN. The runtime's deploy-time `roleArn` carries the\n // full ARN — read it via `bedrock-agentcore-control:GetAgentRuntime`.\n const runtimePhysicalId = loaded.resources[resolved.logicalId]?.physicalId;\n if (stateProvider?.resolveAgentCoreRuntimeRoleArn && runtimePhysicalId) {\n const liveArn = await stateProvider.resolveAgentCoreRuntimeRoleArn(runtimePhysicalId);\n if (liveArn) {\n getLogger().info(\n `--assume-role: auto-resolved execution role from GetAgentRuntime: ${liveArn}`\n );\n return liveArn;\n }\n }\n }\n getLogger().warn(\n \"--assume-role passed without an ARN, but the runtime's RoleArn is not a literal ARN in the template \" +\n (loaded\n ? 'and could not be resolved from the deployed stack state. '\n : 'and no --from-cfn-stack state is available to resolve it. ') +\n 'Pass the ARN explicitly: --assume-role <arn>. ' +\n \"Falling back to the developer's shell credentials.\"\n );\n return undefined;\n}\n\nexport function emitResult(result: AgentCoreInvokeResult): void {\n const logger = getLogger();\n if (result.status >= 400) {\n logger.warn(`Agent /invocations returned HTTP ${result.status}.`);\n process.exitCode = 1;\n }\n if (result.streamed) {\n // The SSE body was already written chunk-by-chunk via the onChunk sink;\n // just terminate with a newline so the shell prompt resumes cleanly.\n process.stdout.write('\\n');\n return;\n }\n process.stdout.write(`${result.raw}\\n`);\n}\n\n/**\n * Finish a `/ws` exchange: the frames were already streamed to stdout via the\n * onMessage sink, so just terminate with a newline (so the shell prompt resumes\n * cleanly) and note the frame count at debug level.\n */\nexport function emitWsResult(result: AgentCoreWsResult): void {\n process.stdout.write('\\n');\n getLogger().debug(`Agent /ws closed after ${result.frames} frame(s).`);\n}\n\n/**\n * Build the JSON-RPC request to send to an MCP runtime from `--event`:\n * - no `--event` (empty object) → `tools/list` (discover the server's tools),\n * - an object with a string `method` → that method + its `params`,\n * - anything else → a fail-fast error.\n *\n * Exported for unit testing.\n */\nexport function buildMcpRequest(event: unknown): McpJsonRpcRequest {\n if (event === undefined || event === null) return { method: 'tools/list', params: {} };\n if (typeof event !== 'object' || Array.isArray(event)) {\n throw new CdkLocalError(\n 'MCP --event must be a JSON object describing a JSON-RPC request ' +\n '(e.g. {\"method\":\"tools/call\",\"params\":{\"name\":\"...\",\"arguments\":{...}}}).',\n 'LOCAL_INVOKE_AGENTCORE_MCP_EVENT_INVALID'\n );\n }\n const obj = event as Record<string, unknown>;\n if (Object.keys(obj).length === 0) return { method: 'tools/list', params: {} };\n if (typeof obj['method'] !== 'string') {\n throw new CdkLocalError(\n 'MCP --event must include a string \"method\" (a JSON-RPC method such as ' +\n `\"tools/list\" or \"tools/call\"). Got keys: ${Object.keys(obj).join(', ')}.`,\n 'LOCAL_INVOKE_AGENTCORE_MCP_EVENT_INVALID'\n );\n }\n return {\n method: obj['method'],\n ...(obj['params'] !== undefined && { params: obj['params'] }),\n };\n}\n\n/** Print the MCP JSON-RPC response; exit 1 when it carried a JSON-RPC error. */\nexport function emitMcpResult(result: McpInvokeResult): void {\n if (!result.ok) {\n getLogger().warn('MCP server returned a JSON-RPC error.');\n process.exitCode = 1;\n }\n process.stdout.write(`${result.raw}\\n`);\n}\n\n/**\n * Build the JSON-RPC request to send to an A2A runtime from `--event`:\n * - no `--event` (empty object) → `agent/getCard` (discover the agent's card),\n * - an object with a string `method` → that method + its `params`,\n * - anything else → a fail-fast error.\n *\n * Exported for unit testing.\n */\nexport function buildA2aRequest(event: unknown): A2aJsonRpcRequest {\n if (event === undefined || event === null) return { method: 'agent/getCard', params: {} };\n if (typeof event !== 'object' || Array.isArray(event)) {\n throw new CdkLocalError(\n 'A2A --event must be a JSON object describing a JSON-RPC request ' +\n '(e.g. {\"method\":\"tasks/send\",\"params\":{\"id\":\"...\",\"message\":{...}}}).',\n 'LOCAL_INVOKE_AGENTCORE_A2A_EVENT_INVALID'\n );\n }\n const obj = event as Record<string, unknown>;\n if (Object.keys(obj).length === 0) return { method: 'agent/getCard', params: {} };\n if (typeof obj['method'] !== 'string') {\n throw new CdkLocalError(\n 'A2A --event must include a string \"method\" (a JSON-RPC method such as ' +\n `\"agent/getCard\" or \"tasks/send\"). Got keys: ${Object.keys(obj).join(', ')}.`,\n 'LOCAL_INVOKE_AGENTCORE_A2A_EVENT_INVALID'\n );\n }\n return {\n method: obj['method'],\n ...(obj['params'] !== undefined && { params: obj['params'] }),\n };\n}\n\n/** Print the A2A JSON-RPC response; exit 1 when it carried a JSON-RPC error. */\nexport function emitA2aResult(result: A2aInvokeResult): void {\n if (!result.ok) {\n getLogger().warn('A2A server returned a JSON-RPC error.');\n process.exitCode = 1;\n }\n process.stdout.write(`${result.raw}\\n`);\n}\n\n/** Map a `--platform` value to the architecture `buildContainerImage` expects. */\nexport function platformToArchitecture(platform: string): 'x86_64' | 'arm64' {\n return platform === 'linux/amd64' ? 'x86_64' : 'arm64';\n}\n\nfunction forwardAwsEnv(env: Record<string, string>): void {\n const passThrough = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n ] as const;\n for (const key of passThrough) {\n const value = process.env[key];\n if (value !== undefined) env[key] = value;\n }\n}\n\nasync function assumeAgentCoreExecutionRole(\n roleArn: string,\n region: string | undefined\n): Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken: string }> {\n const { STSClient, AssumeRoleCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }) });\n try {\n const response = await sts.send(\n new AssumeRoleCommand({\n RoleArn: roleArn,\n RoleSessionName: `${getEmbedConfig().resourceNamePrefix}-invoke-agentcore-${Date.now()}`,\n DurationSeconds: 3600,\n })\n );\n const creds = response.Credentials;\n if (!creds?.AccessKeyId || !creds.SecretAccessKey || !creds.SessionToken) {\n throw new Error(`AssumeRole(${roleArn}) returned no usable credentials.`);\n }\n return {\n accessKeyId: creds.AccessKeyId,\n secretAccessKey: creds.SecretAccessKey,\n sessionToken: creds.SessionToken,\n };\n } finally {\n sts.destroy();\n }\n}\n\nexport async function readEvent(options: LocalInvokeAgentCoreOptions): Promise<unknown> {\n if (options.event && options.eventStdin) {\n throw new Error('--event and --event-stdin are mutually exclusive.');\n }\n if (options.eventStdin) {\n return parseEvent(await readStdin(), '<stdin>');\n }\n if (options.event) {\n let raw: string;\n try {\n raw = readFileSync(options.event, 'utf-8');\n } catch (err) {\n throw new Error(\n `Failed to read --event file '${options.event}': ${err instanceof Error ? err.message : String(err)}`\n );\n }\n return parseEvent(raw, options.event);\n }\n return {};\n}\n\nfunction parseEvent(raw: string, source: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Failed to parse event payload from ${source} as JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n}\n\nasync function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin as AsyncIterable<Buffer | string>) {\n chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk);\n }\n return Buffer.concat(chunks).toString('utf-8');\n}\n\n/**\n * Read `process.stdin` line-buffered and yield each line as a string (trailing\n * `\\r?\\n` stripped). The async iterable completes when stdin EOFs (Ctrl-D /\n * end-of-pipe), and surrenders the underlying stream when its `return()` is\n * called — so the WS client can close down the source when the server closes\n * first without leaving stdin held open.\n *\n * Exported so a unit test can drive the iterable shape directly.\n */\nexport async function* readStdinLines(): AsyncIterable<string> {\n const { createInterface } = await import('node:readline');\n const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });\n try {\n for await (const line of rl) {\n yield line;\n }\n } finally {\n rl.close();\n }\n}\n\nexport function readEnvOverridesFile(filePath: string | undefined): EnvOverrideFile | undefined {\n if (!filePath) return undefined;\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (err) {\n throw new Error(\n `Failed to read --env-vars file '${filePath}': ${err instanceof Error ? err.message : String(err)}`\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Failed to parse --env-vars file '${filePath}' as JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`--env-vars file '${filePath}' must contain a JSON object at the top level.`);\n }\n return parsed as EnvOverrideFile;\n}\n\nexport function createLocalInvokeAgentCoreCommand(\n opts: CreateLocalInvokeAgentCoreCommandOptions = {}\n): Command {\n setEmbedConfig(opts.embedConfig);\n const cmd = new Command('invoke-agentcore')\n .description(\n 'Run a Bedrock AgentCore Runtime container locally and invoke it once over its protocol ' +\n 'contract: HTTP (POST /invocations + GET /ping on 8080) or MCP (POST /mcp Streamable HTTP ' +\n 'on 8000). Resolves the AWS::BedrockAgentCore::Runtime, pulls/builds its container, injects ' +\n 'env vars + AWS credentials, and prints the response. For an MCP runtime, runs the session ' +\n 'handshake then sends one JSON-RPC request (tools/list by default, or the method/params from ' +\n '--event). Target accepts a CDK display path (MyStack/MyAgent) or stack-qualified logical ID ' +\n '(MyStack:MyAgentRuntime1234). Single-stack apps may omit the stack prefix. ' +\n 'Omit <target> in an interactive terminal to pick from a list. ' +\n 'Supports the container artifact and the CodeConfiguration managed-runtime artifact ' +\n '(fromCodeAsset, built from source) on the HTTP + MCP protocols; the agent calls real AWS for managed services.'\n )\n .argument(\n '[target]',\n 'CDK display path or stack-qualified logical ID of the AgentCore Runtime to invoke (omit to pick interactively in a TTY)'\n )\n .addOption(new Option('-e, --event <file>', 'JSON event payload file (default: {})'))\n .addOption(new Option('--event-stdin', 'Read event JSON from stdin').default(false))\n .addOption(\n new Option(\n '--env-vars <file>',\n 'JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})'\n )\n )\n .addOption(\n new Option(\n '--session-id <id>',\n 'AgentCore runtime session id header value (default: a random UUID)'\n )\n )\n .addOption(\n new Option(\n '--ws',\n \"Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) \" +\n 'instead of POST /invocations: send --event as the first frame and print every received ' +\n 'frame to stdout until the agent closes. Ignored for an MCP runtime.'\n ).default(false)\n )\n .addOption(\n new Option(\n '--ws-interactive',\n 'REPL mode for --ws: after the initial --event frame, read additional frames from stdin ' +\n '(one frame per line, trailing newline stripped) and send each as a text frame until ' +\n 'stdin EOFs (Ctrl-D) or the agent closes. Only meaningful with --ws.'\n ).default(false)\n )\n .addOption(\n new Option(\n '--bearer-token <jwt>',\n 'Bearer JWT to present when the runtime declares a customJwtAuthorizer. ' +\n 'Verified against the runtime OIDC discovery URL (signature / issuer / expiry / ' +\n 'audience) before the container starts, then forwarded to /invocations as ' +\n 'Authorization: Bearer <jwt>.'\n )\n )\n .addOption(\n new Option(\n '--no-verify-auth',\n 'Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer ' +\n '(local-dev escape hatch). A --bearer-token, if given, is still forwarded.'\n )\n )\n .addOption(\n new Option(\n '--sigv4',\n 'Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved ' +\n 'credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. ' +\n 'Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.'\n ).default(false)\n )\n .addOption(\n new Option(\n '--platform <platform>',\n 'docker --platform for the agent container (linux/amd64 or linux/arm64)'\n )\n .choices(['linux/amd64', 'linux/arm64'])\n .default('linux/arm64')\n )\n .addOption(\n new Option(\n '--no-pull',\n 'Skip docker pull (use cached image) — no-op for the local-build path'\n )\n )\n .addOption(\n new Option(\n '--no-build',\n 'Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.'\n )\n )\n .addOption(\n new Option('--container-host <host>', 'Host to bind the agent port to').default('127.0.0.1')\n )\n .addOption(\n new Option(\n '--timeout <ms>',\n 'Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the ' +\n '/ws open-to-close window. Raise this for long-running agent calls that exceed the default.'\n )\n .default(120000)\n .argParser(parseTimeoutMs)\n )\n .addOption(\n new Option(\n '--assume-role [arn]',\n \"Assume the runtime's execution role and forward STS-issued temp credentials to the container \" +\n 'so the agent runs with the deployed role. Three forms: ' +\n '(1) `--assume-role <arn>` assumes the explicit ARN; ' +\n \"(2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; \" +\n '(3) `--no-assume-role` opts out. ' +\n \"Off by default — the developer's shell credentials are forwarded unchanged.\"\n )\n )\n .addOption(\n new Option(\n '--ecr-role-arn <arn>',\n 'Role ARN to assume before authenticating against ECR for cross-account / centralized registries. ' +\n 'Same-account / same-region pulls do not need this flag.'\n )\n )\n .addOption(\n new Option(\n '--from-cfn-stack [cfn-stack-name]',\n 'Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue ' +\n 'in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name; ' +\n 'pass an explicit value when the CFn stack name differs.'\n )\n )\n .addOption(\n new Option(\n '--stack-region <region>',\n 'Region of the state record to read. Used with --from-cfn-stack as the CFn client region.'\n )\n )\n .action(\n withErrorHandling(\n async (target: string | undefined, options: LocalInvokeAgentCoreOptions) => {\n await localInvokeAgentCoreCommand(target, options, opts.extraStateProviders);\n }\n )\n );\n\n [...commonOptions(), ...appOptions(), ...contextOptions].forEach((opt) => cmd.addOption(opt));\n cmd.addOption(deprecatedRegionOption);\n return cmd;\n}\n","import { readFileSync } from 'node:fs';\nimport { Command, Option } from 'commander';\nimport {\n appOptions,\n commonOptions,\n contextOptions,\n deprecatedRegionOption,\n parseContextOptions,\n warnIfDeprecatedRegion,\n} from '../options.js';\nimport { getLogger } from '../../utils/logger.js';\nimport { applyRoleArnIfSet } from '../../utils/role-arn.js';\nimport { CdkLocalError, withErrorHandling } from '../../utils/error-handler.js';\nimport { listTargets } from '../../local/target-lister.js';\nimport { resolveSingleTarget } from '../../local/target-picker.js';\nimport { Synthesizer, type SynthesisOptions } from '../../synthesis/synthesizer.js';\nimport { resolveApp } from '../config-loader.js';\nimport { ensureDockerAvailable } from '../../local/docker-runner.js';\nimport { resolveProfileCredentials } from './local-start-api.js';\nimport {\n writeProfileCredentialsFile,\n type ProfileCredentialsFile,\n} from './local-profile-credentials-file.js';\nimport {\n applyCrossStackResolverToTask,\n derivePartitionAndUrlSuffix,\n detectEcsImageResolutionNeeds,\n parseEcsTarget,\n resolveEcsTaskTarget,\n TASK_ROLE_ACCOUNT_PLACEHOLDER,\n type EcsImageResolutionContext,\n} from '../../local/ecs-task-resolver.js';\nimport type { StackInfo } from '../../synthesis/assembly-reader.js';\nimport {\n cleanupEcsRun,\n createEcsRunState,\n parseHostPortOverrides,\n runEcsTask,\n type EcsRunState,\n type RunEcsTaskOptions,\n} from '../../local/ecs-task-runner.js';\nimport { matchStacks } from '../stack-matcher.js';\nimport {\n createLocalStateProvider,\n resolveCfnFallbackRegion,\n type ExtraStateProviders,\n} from './local-state-source.js';\nimport {\n getEmbedConfig,\n setEmbedConfig,\n type CdkLocalEmbedConfig,\n} from '../../local/embed-config.js';\nimport type { LocalStateProvider } from '../../local/local-state-provider.js';\nimport type { SubstitutionContext } from '../../local/state-resolver.js';\n\ninterface LocalRunTaskOptions {\n app?: string;\n output: string;\n verbose: boolean;\n region?: string;\n profile?: string;\n roleArn?: string;\n context?: string[];\n cluster: string;\n envVars?: string;\n containerHost: string;\n /**\n * Commander's `[<arg>]` syntax maps to `string | boolean` here:\n * - flag absent → `undefined`\n * - `--assume-task-role` (bare) → `true`\n * - `--assume-task-role <arn>` → `'<arn>'`\n * The runner branches on `typeof options.assumeTaskRole`.\n */\n assumeTaskRole?: string | boolean;\n pull: boolean;\n /**\n * Optional role ARN passed to `pullEcrImage` for cross-account /\n * centralized registry pulls. Issues `sts:AssumeRole` via the\n * default credential chain and uses the resulting temp credentials to\n * authenticate against the target ECR repository.\n */\n ecrRoleArn?: string;\n /** `--host-port <containerPort=hostPort>` overrides (repeatable; variadic array). */\n hostPort?: string[];\n platform?: string;\n keepRunning: boolean;\n detach: boolean;\n /**\n * Issue #606: alternative state source. Reads physical IDs from a\n * deployed CloudFormation stack via `ListStackResources`.\n */\n fromCfnStack?: string | boolean;\n /**\n * Region of the state record to read. Used as the CFn client region\n * for `--from-cfn-stack`.\n */\n stackRegion?: string;\n /** Host-injected extra state-source flag fields. */\n [key: string]: unknown;\n}\n\n/**\n * Factory options for {@link createLocalRunTaskCommand}. Hosts embedding\n * cdk-local can supply additional state-source factories via\n * `extraStateProviders` (forwarded to every `createLocalStateProvider`\n * call inside the command).\n */\nexport interface CreateLocalRunTaskCommandOptions {\n extraStateProviders?: ExtraStateProviders;\n /** Embed-time branding overrides for a host wrapping this factory. */\n embedConfig?: CdkLocalEmbedConfig;\n}\n\n/**\n * `cdkl run-task <target>` — Phase 1 of the ECS local-execution\n * trilogy. Synthesizes the CDK app, locates the target\n * `AWS::ECS::TaskDefinition`, stands up a per-task docker network with\n * the AWS-published `amazon-ecs-local-container-endpoints` sidecar, and\n * starts every container in `dependsOn` order. The essential\n * container's exit code drives the CLI's exit.\n */\nasync function localRunTaskCommand(\n target: string | undefined,\n options: LocalRunTaskOptions,\n extraStateProviders: ExtraStateProviders | undefined\n): Promise<void> {\n const logger = getLogger();\n if (options.verbose) logger.setLevel('debug');\n\n warnIfDeprecatedRegion(options);\n\n const state: EcsRunState = createEcsRunState();\n let sigintHandler: (() => void) | undefined;\n let sigintCount = 0;\n // The active state provider (--from-cfn-stack or a host-injected\n // extra). Hoisted so the outer `finally` can dispose it even if the\n // body throws between provider creation and the normal exit path.\n let stateProvider: LocalStateProvider | undefined;\n // ECS analogue of the Lambda-container credential fix: synthesized AWS\n // shared credentials file (one INI section) bind-mounted into every\n // user container so\n // handlers using `fromIni({ profile })` resolve to the same creds.\n // Disposed in the cleanup chain below.\n let profileCredsFile: ProfileCredentialsFile | undefined;\n\n // Single-flight cleanup: the SIGINT handler AND the outer `finally` both\n // call this, so we await the first invocation's promise on every later\n // call rather than running concurrently against the shared mutable\n // `state` arrays (which would otherwise double-`docker rm -f` containers\n // and corrupt the entries map mid-iteration).\n let cleanupPromise: Promise<void> | undefined;\n const cleanup = async (): Promise<void> => {\n if (!cleanupPromise) {\n cleanupPromise = (async () => {\n try {\n await cleanupEcsRun(state, { keepRunning: options.keepRunning });\n } catch (err) {\n getLogger().debug(`cleanup failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n if (profileCredsFile) {\n try {\n await profileCredsFile.dispose();\n } catch (err) {\n getLogger().debug(\n `Failed to remove profile credentials tmpdir ${profileCredsFile.hostPath}: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n })();\n }\n await cleanupPromise;\n };\n\n try {\n await applyRoleArnIfSet({ roleArn: options.roleArn, region: options.region });\n await ensureDockerAvailable();\n\n const appCmd = resolveApp(options.app);\n if (!appCmd) {\n throw new Error(\n `No CDK app specified. Pass --app, set ${getEmbedConfig().envPrefix}_APP, or add \"app\" to cdk.json.`\n );\n }\n\n logger.info('Synthesizing CDK app...');\n const synthesizer = new Synthesizer();\n const context = parseContextOptions(options.context);\n const synthOpts: SynthesisOptions = {\n app: appCmd,\n output: options.output,\n ...(options.region && { region: options.region }),\n ...(options.profile && { profile: options.profile }),\n ...(Object.keys(context).length > 0 && { context }),\n };\n const { stacks } = await synthesizer.synthesize(synthOpts);\n\n const resolvedTarget = await resolveSingleTarget(target, {\n entries: listTargets(stacks).ecsTaskDefinitions,\n message: 'Select an ECS task definition to run',\n noun: 'ECS task definitions',\n onMissing: () =>\n new CdkLocalError(\n `${getEmbedConfig().cliName} run-task requires a <target> (an ECS task definition display path or logical ID). ` +\n `Run \\`${getEmbedConfig().cliName} list\\` to see them, or run it in a TTY to pick interactively.`,\n 'LOCAL_RUN_TASK_TARGET_REQUIRED'\n ),\n });\n\n // Pick a LocalStateProvider for whichever flag the user passed\n // (--from-cfn-stack OR a host-injected extra). Constructed BEFORE the\n // candidate-stack picker so the same provider drives both the\n // image-context state-load AND the post-pass cross-stack resolver.\n const parsed = parseEcsTarget(resolvedTarget);\n const candidate = pickCandidateStack(parsed.stackPattern, stacks);\n stateProvider = createLocalStateProvider(\n options,\n candidate?.stackName ?? '',\n await resolveCfnFallbackRegion(options, candidate?.region),\n extraStateProviders\n );\n\n // Build the optional substitution context BEFORE resolving the\n // target, so `Fn::Sub`-shaped ECR image URIs (pseudo parameters +\n // same-stack ECR Repository refs) get rewritten in-place during\n // `parseContainerImage`. STS / state-load are lazy — we only fire\n // them when at least one stack's template references the\n // placeholders.\n const imageContext = await buildEcsImageResolutionContext(candidate, stateProvider, options);\n const task = resolveEcsTaskTarget(resolvedTarget, stacks, imageContext);\n logger.info(\n `Target: ${task.stack.stackName}/${task.taskDefinitionLogicalId} (family=${task.family}, containers=${task.containers.length})`\n );\n\n // Cross-stack `Fn::ImportValue` / `Fn::GetStackOutput` resolution in\n // env vars / secrets. The sync `parseContainerDefinition` pass\n // dropped these with a warn-and-drop entry; the async post-pass\n // re-attempts them via the active state provider when the template\n // actually references a cross-stack output.\n const taskStack = stacks.find((s) => s.stackName === task.stack.stackName) ?? task.stack;\n const taskNeeds = detectEcsImageResolutionNeeds(taskStack);\n if (stateProvider && taskNeeds.needsCrossStackResolver) {\n const consumerRegion =\n options.region ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n task.stack.region ??\n 'us-east-1';\n const resolver = await stateProvider.buildCrossStackResolver(consumerRegion);\n if (resolver) {\n const subContext: SubstitutionContext = {\n resources: imageContext?.stateResources ?? {},\n ...(imageContext?.pseudoParameters && {\n pseudoParameters: imageContext.pseudoParameters,\n }),\n ...(imageContext?.stateParameters && {\n parameters: imageContext.stateParameters,\n }),\n ...(imageContext?.stateSensitiveParameters?.length && {\n sensitiveParameters: new Set(imageContext.stateSensitiveParameters),\n }),\n consumerRegion,\n crossStackResolver: resolver,\n };\n await applyCrossStackResolverToTask(task, subContext);\n }\n } else if (!stateProvider && taskNeeds.needsCrossStackResolver) {\n logger.warn(\n 'Container Environment / Secrets entries contain Fn::ImportValue / Fn::GetStackOutput intrinsics. ' +\n 'Pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to substitute them against deployed state.'\n );\n }\n\n // Double-^C exits 130 immediately.\n sigintHandler = (): void => {\n sigintCount += 1;\n if (sigintCount >= 2) {\n process.stderr.write('Force-exit on second ^C; container cleanup skipped.\\n');\n process.exit(130);\n }\n logger.info('Stopping task...');\n void cleanup().then(() => process.exit(130));\n };\n process.on('SIGINT', sigintHandler);\n\n // `--assume-task-role` branches: bare flag (boolean `true`) uses the\n // task definition's resolved `TaskRoleArn`; otherwise the\n // user-supplied ARN is used. The resolver emits a synth-time\n // placeholder ARN (`arn:aws:iam::${AWS::AccountId}:role/<LogicalId>`)\n // when TaskRoleArn references an inline same-stack IAM Role; we fill\n // in the account segment lazily via STS only when bare\n // `--assume-task-role` is set, so the STS round-trip does not fire\n // on the common pass-through path.\n let assumedCredentials: RunEcsTaskOptions['taskCredentials'];\n let resolvedRoleArn: string | undefined;\n if (options.assumeTaskRole === true) {\n if (!task.taskRoleArn) {\n throw new Error(\n `--assume-task-role passed without an ARN but the task definition has no resolvable TaskRoleArn. ` +\n `Either the task definition does not set TaskRoleArn, or it points at a resource ${getEmbedConfig().binaryName} cannot resolve to an IAM Role at synth time. ` +\n `Pass the ARN explicitly: --assume-task-role <arn>`\n );\n }\n resolvedRoleArn = await resolvePlaceholderAccount(task.taskRoleArn, options.region);\n assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region);\n } else if (typeof options.assumeTaskRole === 'string') {\n resolvedRoleArn = options.assumeTaskRole;\n assumedCredentials = await assumeTaskRole(resolvedRoleArn, options.region);\n }\n\n // When `--assume-task-role` is NOT effective but `--profile <p>` IS\n // set, resolve the profile via the SDK's default\n // credential provider chain (SSO / IAM Identity Center / fromIni /\n // role-assumption) and forward the resulting `{AKID, SAK,\n // sessionToken?}` to the metadata-endpoints sidecar. Without this,\n // the sidecar starts inside a fresh container with no SSO config and\n // no `~/.aws/credentials`, so every user container that hits\n // `169.254.170.2/role/<role>` gets a credential-provider failure.\n // Same gap class as the equivalent forward for `cdkl start-api`'s\n // Lambda container path.\n const sidecarCredentials = await resolveSidecarCredentials(options, assumedCredentials);\n\n // ECS analogue of the Lambda-container credential fix-back:\n // when `--profile <p>` is set AND `--assume-task-role` did NOT\n // produce credentials for this task, synthesize a host-side AWS\n // shared credentials file under `[<options.profile>]` and bind-\n // mount it read-only into every user container. Handler code\n // calling `fromIni({ profile: '<options.profile>' })` then\n // resolves to the same creds the metadata sidecar serves —\n // without this, the SDK looks for `[<options.profile>]` in\n // `~/.aws/credentials` inside the container and fails.\n //\n // Gating `!assumedCredentials` preserves the documented\n // precedence (assume-task-role > profile-file > sidecar): when\n // `--assume-task-role` won, the sidecar's `/role/<arn>` endpoint\n // already serves the assumed creds and the file env vars must\n // NOT override them.\n if (options.profile && sidecarCredentials && !assumedCredentials) {\n profileCredsFile = await writeProfileCredentialsFile(options.profile, sidecarCredentials);\n }\n\n const envOverrides = readEnvOverridesFile(options.envVars);\n\n const runOpts: RunEcsTaskOptions = {\n cluster: options.cluster,\n containerHost: options.containerHost,\n skipPull: options.pull === false,\n keepRunning: options.keepRunning,\n detach: options.detach,\n };\n if (envOverrides) runOpts.envOverrides = envOverrides;\n if (sidecarCredentials) runOpts.taskCredentials = sidecarCredentials;\n if (resolvedRoleArn) runOpts.taskRoleArn = resolvedRoleArn;\n if (options.platform) runOpts.platformOverride = options.platform;\n if (options.region) runOpts.region = options.region;\n if (options.ecrRoleArn) runOpts.ecrRoleArn = options.ecrRoleArn;\n if (options.profile) runOpts.profile = options.profile;\n const hostPortOverrides = parseHostPortOverrides(options.hostPort);\n if (Object.keys(hostPortOverrides).length > 0) runOpts.hostPortOverrides = hostPortOverrides;\n if (profileCredsFile) {\n runOpts.profileCredentialsFile = {\n hostPath: profileCredsFile.hostPath,\n containerPath: profileCredsFile.containerPath,\n profileName: profileCredsFile.profileName,\n };\n }\n\n const result = await runEcsTask(task, runOpts, state);\n\n if (options.detach) {\n logger.info(\n `Task containers started in detached mode; ${getEmbedConfig().binaryName} is exiting.`\n );\n logger.info(\n `Use 'docker ps --filter network=${result.state.network?.networkName ?? '<network>'}' to inspect; ` +\n `tear down with 'docker rm -f' and 'docker network rm'.`\n );\n // Detach mode skips cleanup — the caller manages container lifecycle.\n sigintCount = 99;\n return;\n }\n\n if (result.essentialContainerName) {\n logger.info(\n `Essential container '${result.essentialContainerName}' exited with code ${result.exitCode}.`\n );\n }\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n } finally {\n if (sigintHandler) process.off('SIGINT', sigintHandler);\n if (stateProvider) stateProvider.dispose();\n if (!options.detach) await cleanup();\n }\n}\n\n/**\n * If `arn` contains the `${AWS::AccountId}` placeholder emitted by the\n * resolver for inline same-stack IAM Roles, substitute the live caller\n * account via STS `GetCallerIdentity`. Otherwise pass through unchanged.\n */\nasync function resolvePlaceholderAccount(arn: string, region: string | undefined): Promise<string> {\n if (!arn.includes(TASK_ROLE_ACCOUNT_PLACEHOLDER)) return arn;\n const { STSClient, GetCallerIdentityCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }) });\n try {\n const identity = await sts.send(new GetCallerIdentityCommand({}));\n const account = identity.Account;\n if (!account) {\n throw new Error(\n `--assume-task-role: GetCallerIdentity returned no Account; cannot resolve placeholder ARN '${arn}'. ` +\n `Pass the ARN explicitly: --assume-task-role <arn>`\n );\n }\n return arn.split(TASK_ROLE_ACCOUNT_PLACEHOLDER).join(account);\n } finally {\n sts.destroy();\n }\n}\n\n/**\n * Assume `roleArn` and return temp credentials.\n */\nasync function assumeTaskRole(\n roleArn: string,\n region: string | undefined\n): Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken: string }> {\n const { STSClient, AssumeRoleCommand } = await import('@aws-sdk/client-sts');\n const sts = new STSClient({ ...(region && { region }) });\n try {\n const response = await sts.send(\n new AssumeRoleCommand({\n RoleArn: roleArn,\n RoleSessionName: `${getEmbedConfig().resourceNamePrefix}-run-task-${Date.now()}`,\n DurationSeconds: 3600,\n })\n );\n const creds = response.Credentials;\n if (!creds?.AccessKeyId || !creds.SecretAccessKey || !creds.SessionToken) {\n throw new Error(`AssumeRole(${roleArn}) returned no usable credentials.`);\n }\n return {\n accessKeyId: creds.AccessKeyId,\n secretAccessKey: creds.SecretAccessKey,\n sessionToken: creds.SessionToken,\n };\n } finally {\n sts.destroy();\n }\n}\n\n/**\n * Build the substitution context the ECS task resolver consumes.\n * Returns `undefined` when no container's `Image` field needs\n * substitution — the resolver behaves as before in that case.\n */\nexport async function buildEcsImageResolutionContext(\n candidate: StackInfo | undefined,\n stateProvider: LocalStateProvider | undefined,\n options: LocalRunTaskOptions\n): Promise<EcsImageResolutionContext | undefined> {\n const logger = getLogger();\n if (!candidate) return undefined;\n\n const needs = detectEcsImageResolutionNeeds(candidate);\n if (\n !needs.needsPseudoParameters &&\n !needs.needsStateResources &&\n !needs.needsEnvOrSecretSubstitution\n ) {\n return undefined;\n }\n\n const ctx: EcsImageResolutionContext = {};\n\n const wantsPseudoForEnvOrSecret = !!stateProvider && needs.needsEnvOrSecretSubstitution;\n if (needs.needsPseudoParameters || wantsPseudoForEnvOrSecret) {\n const region =\n options.region ??\n process.env['AWS_REGION'] ??\n process.env['AWS_DEFAULT_REGION'] ??\n candidate.region;\n if (!region) {\n logger.warn(\n `Resolver references \\${AWS::Region} but ${getEmbedConfig().binaryName} could not determine the target region. ` +\n 'Pass --region, set AWS_REGION, or declare env.region on the CDK stack.'\n );\n }\n let accountId: string | undefined;\n try {\n accountId = await resolveCallerAccountId(region, options.profile);\n } catch (err) {\n logger.warn(\n `Resolver needs \\${AWS::AccountId} but STS GetCallerIdentity failed: ${err instanceof Error ? err.message : String(err)}. ` +\n 'Substitution will be skipped; affected env / secret entries will be dropped with per-key warnings.'\n );\n }\n const partitionAndSuffix = region ? derivePartitionAndUrlSuffix(region) : undefined;\n ctx.pseudoParameters = {\n ...(accountId !== undefined && { accountId }),\n ...(region !== undefined && { region }),\n ...(partitionAndSuffix && {\n partition: partitionAndSuffix.partition,\n urlSuffix: partitionAndSuffix.urlSuffix,\n }),\n };\n }\n\n const wantsState = needs.needsStateResources || needs.needsEnvOrSecretSubstitution;\n if (stateProvider && wantsState) {\n const loaded = await stateProvider.load(candidate.stackName, candidate.region);\n if (loaded) {\n ctx.stateResources = loaded.resources;\n }\n // Resolve SSM-backed template parameters\n // (`AWS::SSM::Parameter::Value<String>`) so a `Ref` to such a\n // parameter in a container Environment / Secrets entry resolves to\n // its SSM value instead of being warn-and-dropped (issue #94). Only\n // the CFn provider implements this; gated on env/secret substitution\n // being needed so image-only resolutions skip the SSM round-trip.\n if (needs.needsEnvOrSecretSubstitution && stateProvider.resolveTemplateSsmParameters) {\n const ssmParameters = await stateProvider.resolveTemplateSsmParameters(candidate.template);\n if (Object.keys(ssmParameters.values).length > 0) ctx.stateParameters = ssmParameters.values;\n // Flag decrypted SecureString parameters so the consuming container\n // env keys are kept off the `docker run` argv (issue #99).\n if (ssmParameters.secureStringLogicalIds.length > 0) {\n ctx.stateSensitiveParameters = ssmParameters.secureStringLogicalIds;\n }\n }\n } else if (!stateProvider && needs.needsStateResources) {\n logger.warn(\n 'Container Image references a same-stack AWS::ECR::Repository. Pass a state-source flag ' +\n '(e.g. --from-cfn-stack or a host-provided extension) to substitute the deployed repository URI. ' +\n 'Otherwise the resolver will surface its existing error.'\n );\n } else if (!stateProvider && needs.needsEnvOrSecretSubstitution) {\n logger.warn(\n 'Container Environment / Secrets entries contain CloudFormation intrinsics (Ref / Fn::GetAtt / Fn::Sub / Fn::Join). ' +\n 'Pass a state-source flag (e.g. --from-cfn-stack or a host-provided extension) to substitute them against deployed state. ' +\n 'Without a state source these entries are dropped (per-key warnings will follow).'\n );\n }\n\n return ctx;\n}\n\nfunction pickCandidateStack(\n stackPattern: string | null,\n stacks: StackInfo[]\n): StackInfo | undefined {\n if (stackPattern === null) {\n if (stacks.length === 1) return stacks[0];\n return undefined;\n }\n const matched = matchStacks(stacks, [stackPattern]);\n if (matched.length === 1) return matched[0];\n return undefined;\n}\n\nasync function resolveCallerAccountId(\n region: string | undefined,\n profile: string | undefined\n): Promise<string | undefined> {\n const { STSClient, GetCallerIdentityCommand } = await import('@aws-sdk/client-sts');\n // Thread `--profile` so the resolved account is the profile's account\n // (e.g. the deployed account behind `--from-cfn-stack`), not whatever\n // the default credential chain points at. Without this, the\n // `${AWS::AccountId}` substitution that builds same-stack ECR image\n // URIs picks the wrong account and the subsequent `docker pull` 404s.\n const sts = new STSClient({ ...(region && { region }), ...(profile && { profile }) });\n try {\n const identity = await sts.send(new GetCallerIdentityCommand({}));\n return identity.Account;\n } finally {\n sts.destroy();\n }\n}\n\n/**\n * Read the `--env-vars` JSON file using the same SAM-style shape as\n * `cdkl invoke --env-vars`: top-level keys are container names, with\n * `Parameters` reserved for global entries.\n */\nfunction readEnvOverridesFile(\n filePath: string | undefined\n): Record<string, Record<string, string | null> | undefined> | undefined {\n if (!filePath) return undefined;\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (err) {\n throw new Error(\n `Failed to read --env-vars file '${filePath}': ${err instanceof Error ? err.message : String(err)}`\n );\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new Error(\n `Failed to parse --env-vars file '${filePath}' as JSON: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(`--env-vars file '${filePath}' must contain a JSON object at the top level.`);\n }\n return parsed as Record<string, Record<string, string | null> | undefined>;\n}\n\n/**\n * Pick the credentials forwarded to the AWS-published\n * `amazon-ecs-local-container-endpoints` sidecar. Precedence:\n * 1. `--assume-task-role <arn>` (or bare `--assume-task-role` against\n * a resolvable `TaskRoleArn`) → STS-assumed temp creds. Highest\n * priority — when the user opted in to IAM emulation, those creds\n * drive the sidecar regardless of `--profile`.\n * 2. `--profile <p>` → resolved via {@link resolveProfileCredentials}\n * (the SDK's default credential provider chain — SSO / IAM\n * Identity Center / fromIni / role-assumption). NEW in this PR.\n * 3. Neither set → `undefined`; the sidecar runs with its own\n * default credential chain (typically empty inside a fresh\n * container — user containers will get 4xx from the credentials\n * endpoint, mimicking IAM-misconfigured prod).\n *\n * Extracted as an exported helper so a unit test can exercise every\n * branch without having to mock the full Synth + Docker + AWS pipeline\n * (the strategy used for the Lambda container path).\n */\nexport async function resolveSidecarCredentials(\n options: { profile?: string },\n assumedCredentials:\n | { accessKeyId: string; secretAccessKey: string; sessionToken?: string }\n | undefined\n): Promise<{ accessKeyId: string; secretAccessKey: string; sessionToken?: string } | undefined> {\n if (assumedCredentials) return assumedCredentials;\n if (options.profile) return resolveProfileCredentials(options.profile);\n return undefined;\n}\n\nexport function createLocalRunTaskCommand(opts: CreateLocalRunTaskCommandOptions = {}): Command {\n setEmbedConfig(opts.embedConfig);\n const cmd = new Command('run-task')\n .description(\n 'Run an AWS::ECS::TaskDefinition locally — pulls/builds images, sets up a per-task docker network ' +\n 'with the AWS-published metadata-endpoints sidecar, and starts every container in dependsOn order. ' +\n 'Target accepts a CDK display path (MyStack/MyService/TaskDef) or stack-qualified logical ID ' +\n '(MyStack:MyServiceTaskDefXYZ1234). Single-stack apps may omit the stack prefix. ' +\n 'Omit <target> in an interactive terminal to pick the task definition from a list.'\n )\n .argument(\n '[target]',\n 'CDK display path or stack-qualified logical ID of the AWS::ECS::TaskDefinition to run (omit to pick interactively in a TTY)'\n )\n .addOption(\n new Option(\n '--cluster <name>',\n 'Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix'\n ).default(getEmbedConfig().resourceNamePrefix)\n )\n .addOption(\n new Option(\n '--env-vars <file>',\n 'JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})'\n )\n )\n .addOption(\n new Option(\n '--container-host <ip>',\n 'Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)'\n ).default('127.0.0.1')\n )\n .addOption(\n new Option(\n '--host-port <containerPort=hostPort...>',\n 'Publish a container port on a specific host port (e.g. 80=8080); repeatable. ' +\n 'Default: host port == container port. Use this on macOS to map a privileged ' +\n 'container port (< 1024) to a non-privileged host port and avoid the Docker ' +\n 'Desktop admin-password prompt.'\n )\n )\n .addOption(\n new Option(\n '--assume-task-role [arn]',\n \"Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp \" +\n 'credentials via the metadata sidecar so containers run with the deployed function role. ' +\n \"Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.\"\n )\n )\n .addOption(\n new Option('--no-pull', 'Skip docker pull for every container image and the metadata sidecar')\n )\n .addOption(\n new Option(\n '--ecr-role-arn <arn>',\n 'Role ARN to assume before authenticating against ECR for cross-account / centralized ' +\n 'registries. Issues sts:AssumeRole via the default credential chain and uses the ' +\n 'temporary credentials for ecr:GetAuthorizationToken + docker pull. Required when the ' +\n 'caller does not have direct cross-account access to the target repository. ' +\n 'Same-account / same-region pulls do not need this flag.'\n )\n )\n .addOption(\n new Option(\n '--platform <platform>',\n 'Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture'\n )\n )\n .addOption(\n new Option(\n '--keep-running',\n \"Don't docker rm -f the user containers on task exit (network + sidecar are still torn down). \" +\n 'Use when you want to docker exec into a stopped container for post-mortems.'\n ).default(false)\n )\n .addOption(\n new Option(\n '--detach',\n 'Start the containers in the background and exit (skip log streaming + auto teardown). ' +\n 'Useful in CI smoke tests; caller manages container lifecycle.'\n ).default(false)\n )\n .addOption(\n new Option(\n '--from-cfn-stack [cfn-stack-name]',\n 'Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue ' +\n 'in container env vars / secrets / image URIs with the deployed physical IDs / exports. ' +\n 'Use for CDK apps deployed via the upstream CDK CLI (`cdk deploy`). ' +\n `Bare form uses the ${getEmbedConfig().binaryName} stack name; pass an explicit value when the CFn stack name differs. ` +\n 'Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).'\n )\n )\n .addOption(\n new Option(\n '--stack-region <region>',\n 'Region of the state record to read. Used with --from-cfn-stack as the CFn client region.'\n )\n )\n .action(\n withErrorHandling(async (target: string | undefined, options: LocalRunTaskOptions) => {\n await localRunTaskCommand(target, options, opts.extraStateProviders);\n })\n );\n\n [...commonOptions(), ...appOptions(), ...contextOptions].forEach((opt) => cmd.addOption(opt));\n cmd.addOption(deprecatedRegionOption);\n return cmd;\n}\n","import { Command, Option } from 'commander';\nimport { withErrorHandling, LocalStartServiceError } from '../../utils/error-handler.js';\nimport { listTargets } from '../../local/target-lister.js';\nimport {\n getEmbedConfig,\n setEmbedConfig,\n type CdkLocalEmbedConfig,\n} from '../../local/embed-config.js';\nimport type { ExtraStateProviders } from './local-state-source.js';\nimport {\n addCommonEcsServiceOptions,\n runEcsServiceEmulator,\n type EcsServiceEmulatorOptions,\n type EmulatorStrategy,\n} from './ecs-service-emulator.js';\n\n// Re-exported for existing unit tests that import these from this module.\nexport {\n resolveSharedSidecarCredentials,\n buildEcsImageResolutionContext,\n MAX_TASKS_SUBNET_RANGE_CAP,\n} from './ecs-service-emulator.js';\n\n/**\n * Factory options for {@link createLocalStartServiceCommand}.\n */\nexport interface CreateLocalStartServiceCommandOptions {\n extraStateProviders?: ExtraStateProviders;\n /** Embed-time branding overrides for a host wrapping this factory. */\n embedConfig?: CdkLocalEmbedConfig;\n}\n\n/**\n * `cdkl start-service` strategy — a pure ECS replica runner. It picks\n * `AWS::ECS::Service` targets and boots each with NO front-door (the ALB\n * front-door is its own command, `cdkl start-alb`). This keeps `start-service`\n * a leaf compute runner, symmetric with `invoke` / `run-task`.\n */\nexport function serviceStrategy(): EmulatorStrategy {\n return {\n pickEntries: (stacks) => listTargets(stacks).ecsServices,\n pickerMessage: 'Select one or more ECS services to run',\n pickerNoun: 'ECS services',\n onMissing: () =>\n new LocalStartServiceError(\n `${getEmbedConfig().cliName} start-service requires at least one <target>. ` +\n \"Pass one or more service paths like 'Stack/Orders' 'Stack/Frontend', \" +\n 'or run it in a TTY to pick interactively.'\n ),\n resolveBoots: (_stacks, chosenTargets) => ({\n boots: chosenTargets.map((target) => ({ target })),\n warnings: [],\n }),\n lbPortOverrides: {},\n };\n}\n\n/**\n * `cdkl start-service <Stack/Service>` — Phase 2 of #262. Spins up\n * `DesiredCount` task replicas locally (clamped by `--max-tasks`) using the\n * existing `ecs-task-runner` per replica. Long-running; ^C cleans every replica\n * + sidecar + shared network. Pure compute: to put a local ALB front-door in\n * front of an ALB-fronted service, use `cdkl start-alb`.\n */\nexport function createLocalStartServiceCommand(\n opts: CreateLocalStartServiceCommandOptions = {}\n): Command {\n setEmbedConfig(opts.embedConfig);\n const cmd = new Command('start-service')\n .description(\n 'Run one or more AWS::ECS::Service resources locally as a long-running emulator. Spins up ' +\n 'DesiredCount task replicas per service (clamped by --max-tasks) using the same per-task ' +\n `docker network + metadata sidecar pattern as \\`${getEmbedConfig().cliName} run-task\\`, then keeps each ` +\n 'replica running and restarts it on exit per --restart-policy. ^C tears every replica + ' +\n 'sidecar + network down. Each <target> accepts a CDK display path (MyStack/MyService) ' +\n 'or stack-qualified logical ID (MyStack:MyServiceXYZ); single-stack apps may omit the ' +\n 'stack prefix. When two or more <target>s are supplied, every service is booted into a ' +\n 'shared Cloud Map / Service Connect registry so peer services discover each other via ' +\n 'docker --add-host overlay. Omit <targets> in an interactive terminal to ' +\n `multi-select the services from a list. To put a local ALB front-door in front of an ` +\n `ALB-fronted service, use \\`${getEmbedConfig().cliName} start-alb\\` instead.`\n )\n .argument(\n '[targets...]',\n 'One or more CDK display paths or stack-qualified logical IDs of the AWS::ECS::Service resources to run (omit to multi-select interactively in a TTY)'\n )\n .addOption(\n new Option(\n '--host-port <containerPort=hostPort...>',\n 'Publish a container port on a specific host port (e.g. 80=8080); repeatable. ' +\n 'Default: host port == container port. Use this on macOS to map a privileged ' +\n 'container port (< 1024) to a non-privileged host port and avoid the Docker ' +\n 'Desktop admin-password prompt. (Single-replica services only — multi-replica ' +\n 'services do not publish host ports.)'\n )\n )\n .action(\n withErrorHandling(async (targets: string[], options: EcsServiceEmulatorOptions) => {\n await runEcsServiceEmulator(targets, options, serviceStrategy(), opts.extraStateProviders);\n })\n );\n\n return addCommonEcsServiceOptions(cmd);\n}\n","import { Command, Option } from 'commander';\nimport {\n appOptions,\n commonOptions,\n contextOptions,\n deprecatedRegionOption,\n parseContextOptions,\n warnIfDeprecatedRegion,\n} from '../options.js';\nimport { getLogger } from '../../utils/logger.js';\nimport { applyRoleArnIfSet } from '../../utils/role-arn.js';\nimport { withErrorHandling } from '../../utils/error-handler.js';\nimport { Synthesizer, type SynthesisOptions } from '../../synthesis/synthesizer.js';\nimport { resolveApp } from '../config-loader.js';\nimport {\n getEmbedConfig,\n setEmbedConfig,\n type CdkLocalEmbedConfig,\n} from '../../local/embed-config.js';\nimport {\n countTargets,\n listTargets,\n type TargetEntry,\n type TargetListing,\n} from '../../local/target-lister.js';\n\ninterface LocalListOptions {\n app?: string;\n output: string;\n verbose: boolean;\n profile?: string;\n roleArn?: string;\n context?: string[];\n region?: string;\n /** `-l/--long`: also print each target's stack-qualified logical ID. */\n long: boolean;\n}\n\n/**\n * Factory options for {@link createLocalListCommand}.\n */\nexport interface CreateLocalListCommandOptions {\n /** Embed-time branding overrides for a host wrapping this factory. */\n embedConfig?: CdkLocalEmbedConfig;\n}\n\nasync function localListCommand(options: LocalListOptions): Promise<void> {\n const logger = getLogger();\n if (options.verbose) logger.setLevel('debug');\n\n warnIfDeprecatedRegion(options);\n\n await applyRoleArnIfSet({ roleArn: options.roleArn, region: undefined });\n\n const appCmd = resolveApp(options.app);\n if (!appCmd) {\n throw new Error(\n `No CDK app specified. Pass --app, set ${getEmbedConfig().envPrefix}_APP, or add \"app\" to cdk.json.`\n );\n }\n\n // Status goes to stderr so `cdkl list` stdout is ONLY the target list\n // (clean for `cdkl list | ...`). Synthesis progress from toolkit-lib is\n // routed to stderr too (see CdklIoHost).\n process.stderr.write('Synthesizing CDK app...\\n');\n const synthesizer = new Synthesizer();\n const context = parseContextOptions(options.context);\n const synthOpts: SynthesisOptions = {\n app: appCmd,\n output: options.output,\n ...(options.profile && { profile: options.profile }),\n ...(Object.keys(context).length > 0 && { context }),\n };\n const { stacks } = await synthesizer.synthesize(synthOpts);\n\n const listing = listTargets(stacks);\n process.stdout.write(\n `${formatTargetListing(listing, getEmbedConfig().cliName, { long: options.long })}\\n`\n );\n}\n\n/** Options for {@link formatTargetListing}. */\nexport interface FormatTargetListingOptions {\n /**\n * Also print each target's stack-qualified logical ID (`-l/--long`).\n * Off by default: the CDK display path alone is the recommended,\n * readable target form, and the wide two-column layout wrapped badly\n * for the long auto-generated names CDK emits.\n */\n long?: boolean;\n}\n\n/**\n * Render a {@link TargetListing} as the grouped text list `cdkl list`\n * prints. Each non-empty category is preceded by a blank line and a\n * header naming the command that runs it, then one target per line by\n * CDK display path. With {@link FormatTargetListingOptions.long}, each\n * target's stack-qualified logical ID is printed on an indented line\n * beneath it. Exported so a unit test can assert the output shape\n * without running synthesis.\n */\nexport function formatTargetListing(\n listing: TargetListing,\n cliName: string,\n options: FormatTargetListingOptions = {}\n): string {\n if (countTargets(listing) === 0) {\n return `No runnable targets (Lambda functions, APIs, ECS services / tasks, AgentCore Runtimes, load balancers) found in this CDK app.`;\n }\n\n const long = options.long ?? false;\n const sections: string[][] = [\n formatSection('Lambda Functions', `${cliName} invoke <target>`, listing.lambdas, long),\n formatSection('APIs', `${cliName} start-api [target...]`, listing.apis, long),\n formatSection(\n 'ECS Services',\n `${cliName} start-service <target...>`,\n listing.ecsServices,\n long\n ),\n formatSection(\n 'ECS Task Definitions',\n `${cliName} run-task <target>`,\n listing.ecsTaskDefinitions,\n long\n ),\n formatSection(\n 'AgentCore Runtimes',\n `${cliName} invoke-agentcore <target>`,\n listing.agentCoreRuntimes,\n long\n ),\n formatSection(\n 'Application Load Balancers',\n `${cliName} start-alb <target...>`,\n listing.loadBalancers,\n long\n ),\n ];\n\n // Leading blank line + a blank line between groups so each header is a\n // clear landmark (and the first group is separated from the synth\n // status that precedes it on stderr).\n return (\n '\\n' +\n sections\n .filter((lines) => lines.length > 0)\n .map((lines) => lines.join('\\n'))\n .join('\\n\\n')\n );\n}\n\nfunction formatSection(\n title: string,\n command: string,\n entries: TargetEntry[],\n long: boolean\n): string[] {\n if (entries.length === 0) return [];\n const lines = [`${title} -> ${command}`];\n for (const entry of entries) {\n const primary = entry.displayPath ?? entry.qualifiedId;\n // Append the API surface kind (REST API v1 / HTTP API v2 / Function URL\n // / WebSocket) so the API group's otherwise-similar paths are\n // distinguishable; only `apis` entries carry a kind.\n lines.push(entry.kind ? ` ${primary} (${entry.kind})` : ` ${primary}`);\n // The qualified ID is only extra info when a display path was shown;\n // when it IS the primary, don't repeat it.\n if (long && entry.displayPath) {\n lines.push(` ${entry.qualifiedId}`);\n }\n }\n return lines;\n}\n\nexport function createLocalListCommand(opts: CreateLocalListCommandOptions = {}): Command {\n setEmbedConfig(opts.embedConfig);\n const cmd = new Command('list')\n .alias('ls')\n .description(\n 'List the runnable targets in the synthesized CDK app, grouped by the command that runs them: ' +\n 'Lambda functions (invoke), API Gateway REST v1 / HTTP v2 / Function URL / WebSocket surfaces ' +\n '(start-api), ECS services (start-service), ECS task definitions (run-task), AgentCore ' +\n 'Runtimes (invoke-agentcore), and Application Load Balancers (start-alb). Each target is ' +\n 'shown by its CDK display path; pass -l to also print the stack-qualified logical ID. Tip: you ' +\n 'usually do not need to copy these — just run the command (e.g. `invoke`) with no target in a ' +\n 'terminal and pick from the list.'\n )\n .addOption(\n new Option(\n '-l, --long',\n \"Also print each target's stack-qualified logical ID (<Stack>:<LogicalId>) beneath it\"\n ).default(false)\n )\n .action(\n withErrorHandling(async (options: LocalListOptions) => {\n await localListCommand(options);\n })\n );\n\n [...commonOptions(), ...appOptions(), ...contextOptions].forEach((opt) => cmd.addOption(opt));\n cmd.addOption(deprecatedRegionOption);\n return cmd;\n}\n"],"mappings":"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"}
|