cdk-local 0.149.4 → 0.149.5
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/dist/cli.js +2 -2
- package/dist/docker-cmd-B5yU__zC.js +1429 -0
- package/dist/docker-cmd-B5yU__zC.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/internal.js +2 -1
- package/dist/{local-studio-Cdq8klwg.js → local-studio-CV21zLBM.js} +14 -875
- package/dist/local-studio-CV21zLBM.js.map +1 -0
- package/package.json +1 -1
- package/dist/docker-cmd-SocNyC9q.js +0 -560
- package/dist/docker-cmd-SocNyC9q.js.map +0 -1
- package/dist/local-studio-Cdq8klwg.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker-cmd-B5yU__zC.js","names":["createSpinner"],"sources":["../src/local/embed-config.ts","../src/utils/logger.ts","../src/local/credential-error.ts","../src/utils/assembly-path.ts","../src/utils/docker-cmd.ts"],"sourcesContent":["/**\n * Embed-time branding configuration.\n *\n * cdk-local hardcodes its own branding (`cdkl` binary, `cdk-local`\n * product name, `cdkl-*` Docker / AWS resource names, `/cdk-local-aws`\n * credential bind-mount) into user-visible error messages and resource\n * identifiers. A host that embeds cdk-local's Commander factories (e.g.\n * cdkd, whose binary is `cdkd` and whose subcommand group is\n * `cdkd local`) passes a {@link CdkLocalEmbedConfig} so those strings\n * read in the host's own branding instead.\n *\n * The four command factories call {@link setEmbedConfig} before building\n * their Commander option tree, so both construction-time strings (option\n * descriptions / defaults) and action-time strings (errors, resource\n * names) read the resolved config via {@link getEmbedConfig}. When no\n * config is supplied every field falls back to cdk-local's own defaults,\n * leaving native `cdkl` behavior byte-identical.\n */\nexport interface CdkLocalEmbedConfig {\n /**\n * Command prefix for subcommand references in user-facing strings, e.g.\n * `${cliName} invoke` / `${cliName} start-api`. Default `'cdkl'`; cdkd\n * passes `'cdkd local'`.\n */\n cliName?: string;\n /**\n * Bare executable / process name for standalone references, e.g.\n * `${binaryName} is exiting` / `${binaryName} could not determine ...`,\n * the local request id, and the hyphen-free Cognito user-pool\n * placeholder id. Default `'cdkl'`; cdkd passes `'cdkd'`.\n */\n binaryName?: string;\n /**\n * Product name for prose references, e.g. `${productName} supports ...`.\n * Also seeds the profile-credentials tmpdir prefix. Default\n * `'cdk-local'`; cdkd passes `'cdkd'`.\n */\n productName?: string;\n /**\n * Prefix for generated Docker / AWS resource identifiers — container,\n * volume, network, image-tag, tmpdir names, STS `RoleSessionName`s, and\n * the example Cloud Map namespace. Default `'cdkl'`; cdkd passes\n * `'cdkd-local'`.\n */\n resourceNamePrefix?: string;\n /**\n * Container directory the host AWS shared-credentials file is\n * bind-mounted under. Default `'/cdk-local-aws'`; cdkd passes\n * `'/cdkd-aws'`.\n */\n awsBindMountPath?: string;\n /**\n * Prefix for the environment variables this CLI reads — `${envPrefix}_APP`\n * (the `--app` fallback) and `${envPrefix}_ROLE_ARN` (the `--role-arn`\n * fallback). Default `'CDKL'`; cdkd passes `'CDKD'`.\n */\n envPrefix?: string;\n /**\n * Whether this host fails-closed by default on unverifiable AWS_IAM SigV4\n * requests. cdk-local's default is warn-and-pass (`false`); a host like\n * cdkd that ships fail-closed-by-default passes `true`. Drives the polarity\n * of the SigV4 warn-message advice (whether the strictness flag reads as an\n * opt-IN or opt-OUT). Default `false`.\n */\n sigV4StrictByDefault?: boolean;\n /**\n * The CLI flag a user toggles to change SigV4 strictness. With\n * `sigV4StrictByDefault: false` it is an opt-IN flag (`'--strict-sigv4'`,\n * the default); with `sigV4StrictByDefault: true` it is the host's opt-OUT\n * flag (cdkd passes `'--allow-unverified-sigv4'`). Default `'--strict-sigv4'`.\n */\n sigV4OptFlag?: string;\n}\n\nexport interface ResolvedEmbedConfig {\n cliName: string;\n binaryName: string;\n productName: string;\n resourceNamePrefix: string;\n awsBindMountPath: string;\n envPrefix: string;\n sigV4StrictByDefault: boolean;\n sigV4OptFlag: string;\n}\n\nconst DEFAULTS: ResolvedEmbedConfig = {\n cliName: 'cdkl',\n binaryName: 'cdkl',\n productName: 'cdk-local',\n resourceNamePrefix: 'cdkl',\n awsBindMountPath: '/cdk-local-aws',\n envPrefix: 'CDKL',\n sigV4StrictByDefault: false,\n sigV4OptFlag: '--strict-sigv4',\n};\n\nlet current: ResolvedEmbedConfig = DEFAULTS;\n\n/**\n * Resolve and install the active embed config. Called once per command\n * factory with the host's overrides (or `undefined` for native cdkl\n * behavior). Idempotent: re-calling with the same overrides is a no-op,\n * which is why all four factories may safely set the same config.\n */\nexport function setEmbedConfig(config?: CdkLocalEmbedConfig): void {\n current = {\n cliName: config?.cliName ?? DEFAULTS.cliName,\n binaryName: config?.binaryName ?? DEFAULTS.binaryName,\n productName: config?.productName ?? DEFAULTS.productName,\n resourceNamePrefix: config?.resourceNamePrefix ?? DEFAULTS.resourceNamePrefix,\n awsBindMountPath: config?.awsBindMountPath ?? DEFAULTS.awsBindMountPath,\n envPrefix: config?.envPrefix ?? DEFAULTS.envPrefix,\n sigV4StrictByDefault: config?.sigV4StrictByDefault ?? DEFAULTS.sigV4StrictByDefault,\n sigV4OptFlag: config?.sigV4OptFlag ?? DEFAULTS.sigV4OptFlag,\n };\n}\n\n/** The active resolved embed config. */\nexport function getEmbedConfig(): ResolvedEmbedConfig {\n return current;\n}\n\n/** Restore cdk-local defaults. Primarily a test-isolation helper. */\nexport function resetEmbedConfig(): void {\n current = DEFAULTS;\n}\n","/**\n * Logger interface and console implementation for cdk-local.\n *\n * A minimal `Logger` / `LogLevel` interface with a `ConsoleLogger`\n * (`getLogger()` / `setLogger()` exports, `child(prefix)` for prefixed\n * sub-loggers). cdk-local invokes a single Lambda / API / task at a time,\n * so there is no parallel multi-stack output to interleave — a plain\n * console logger with no output buffer or live progress renderer suffices.\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface Logger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n setLevel(level: LogLevel): void;\n getLevel(): LogLevel;\n child(prefix: string): Logger;\n}\n\n/**\n * ANSI color codes\n *\n * Kept internal — `ConsoleLogger.formatMessage` references these for the\n * verbose/compact mode level prefixes.\n */\nconst colors = {\n reset: '\\x1b[0m',\n bright: '\\x1b[1m',\n dim: '\\x1b[2m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n} as const;\n\nfunction formatTimestamp(): string {\n const now = new Date();\n return now.toISOString();\n}\n\n/**\n * Resolve whether ANSI color should be emitted by default.\n *\n * Color is appropriate for an interactive terminal but is noise (literal\n * `\\x1b[31m...` escapes) when the output is a pipe — e.g. when `cdkl studio`\n * spawns `cdkl invoke` / a serve command as a child and captures its output to\n * render in the browser, where the raw escapes leak as visible text. So the\n * default tracks the stdout TTY-ness, with the two standard env overrides:\n *\n * - `NO_COLOR` (any non-empty value) forces colors OFF (https://no-color.org).\n * - `FORCE_COLOR` (non-empty, not `'0'` / `'false'`) forces colors ON, even\n * when not a TTY (the convention many CLIs honor for CI / log capture).\n * - otherwise: on when `process.stdout.isTTY`.\n *\n * We gate on `process.stdout.isTTY` even though warn / error go to stderr via\n * `console.error` / `console.warn`. In the case this fix targets — a piped\n * child (e.g. studio) — NEITHER stdout nor stderr is a TTY, so gating on stdout\n * still yields colorless output. Tracking stdout matches common CLI tooling and\n * keeps a single, predictable signal; an explicit `useColors` argument (passed\n * by child loggers) always overrides this default.\n */\nexport function resolveDefaultUseColors(): boolean {\n const noColor = process.env['NO_COLOR'];\n if (noColor !== undefined && noColor !== '') {\n return false;\n }\n const forceColor = process.env['FORCE_COLOR'];\n if (\n forceColor !== undefined &&\n forceColor !== '' &&\n forceColor !== '0' &&\n forceColor !== 'false'\n ) {\n return true;\n }\n return !!process.stdout.isTTY;\n}\n\n/**\n * Console logger implementation\n *\n * Supports two output modes:\n * - verbose (debug level): timestamps, module prefixes, all details\n * - compact (info level): clean output without timestamps or prefixes\n */\nexport class ConsoleLogger implements Logger {\n private level: LogLevel;\n private useColors: boolean;\n\n constructor(level: LogLevel = 'info', useColors: boolean = resolveDefaultUseColors()) {\n this.level = level;\n this.useColors = useColors;\n }\n\n private shouldLog(level: LogLevel): boolean {\n const levels: LogLevel[] = ['debug', 'info', 'warn', 'error'];\n const currentLevelIndex = levels.indexOf(this.level);\n const messageLevelIndex = levels.indexOf(level);\n return messageLevelIndex >= currentLevelIndex;\n }\n\n private formatMessage(level: LogLevel, message: string, ...args: unknown[]): string {\n const formattedArgs = args.length > 0 ? ' ' + args.map((a) => JSON.stringify(a)).join(' ') : '';\n\n if (this.level === 'debug') {\n const timestamp = formatTimestamp();\n const levelStr = level.toUpperCase().padEnd(5);\n\n if (this.useColors) {\n const levelColorMap: Record<LogLevel, string> = {\n debug: colors.gray,\n info: colors.blue,\n warn: colors.yellow,\n error: colors.red,\n };\n const levelColor = levelColorMap[level];\n\n return `${colors.dim}${timestamp}${colors.reset} ${levelColor}${levelStr}${colors.reset} ${message}${formattedArgs}`;\n }\n\n return `${timestamp} ${levelStr} ${message}${formattedArgs}`;\n }\n\n // Compact mode (info level) prefixes warn / error with an UPPERCASE level\n // tag so the severity is legible even when ANSI color is stripped — a\n // piped / redirected CLI run, `NO_COLOR`, or the `cdkl studio` serve child\n // (captured over a pipe, so colorless). Color, when available, still wraps\n // the whole line. info stays prefix-less so the common-case progress output\n // is unchanged. The prefix is the one severity signal that survives a pipe,\n // and studio's LOG panel re-colors off it (studio-ui).\n if (level === 'error') {\n const line = `ERROR: ${message}${formattedArgs}`;\n return this.useColors ? `${colors.red}${line}${colors.reset}` : line;\n }\n if (level === 'warn') {\n const line = `WARN: ${message}${formattedArgs}`;\n return this.useColors ? `${colors.yellow}${line}${colors.reset}` : line;\n }\n\n return `${message}${formattedArgs}`;\n }\n\n private emit(level: LogLevel, formatted: string): void {\n // `cdkl studio` sets `CDKL_LOG_STREAM=stdout` on its spawned serve children\n // (issue #403) so EVERY level routes to stdout instead of the default\n // warn/error -> stderr split. studio captures a child's stdout and stderr\n // via two separate OS pipes, and Node does NOT guarantee cross-pipe\n // delivery order — a warn written just before a stdout banner can surface\n // AFTER it in the studio LOG panel (e.g. the pinned-image WARN landing\n // below \"Press ^C to shut down.\"). Emitting one stream preserves emission\n // order for that consumer. Direct CLI use never sets the var, so the\n // warn/error -> stderr split is unchanged there.\n if (process.env['CDKL_LOG_STREAM'] === 'stdout') {\n console.log(formatted);\n return;\n }\n if (level === 'error') console.error(formatted);\n else if (level === 'warn') console.warn(formatted);\n else if (level === 'info') console.info(formatted);\n else console.debug(formatted);\n }\n\n debug(message: string, ...args: unknown[]): void {\n if (this.shouldLog('debug')) {\n this.emit('debug', this.formatMessage('debug', message, ...args));\n }\n }\n\n info(message: string, ...args: unknown[]): void {\n if (this.shouldLog('info')) {\n this.emit('info', this.formatMessage('info', message, ...args));\n }\n }\n\n warn(message: string, ...args: unknown[]): void {\n if (this.shouldLog('warn')) {\n this.emit('warn', this.formatMessage('warn', message, ...args));\n }\n }\n\n error(message: string, ...args: unknown[]): void {\n if (this.shouldLog('error')) {\n this.emit('error', this.formatMessage('error', message, ...args));\n }\n }\n\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n getLevel(): LogLevel {\n return this.level;\n }\n\n child(prefix: string): ChildLogger {\n return new ChildLogger(prefix, this.useColors);\n }\n}\n\n/**\n * Child logger that always syncs level from global logger\n */\nclass ChildLogger extends ConsoleLogger {\n private readonly prefix: string;\n\n constructor(prefix: string, useColors: boolean) {\n super('info', useColors);\n this.prefix = prefix;\n }\n\n private syncLevel(): void {\n if (globalLogger) {\n this.setLevel(globalLogger.getLevel());\n }\n }\n\n override debug(message: string, ...args: unknown[]): void {\n this.syncLevel();\n super.debug(`[${this.prefix}] ${message}`, ...args);\n }\n\n override info(message: string, ...args: unknown[]): void {\n this.syncLevel();\n const msg = this.getLevel() === 'debug' ? `[${this.prefix}] ${message}` : message;\n super.info(msg, ...args);\n }\n\n override warn(message: string, ...args: unknown[]): void {\n this.syncLevel();\n const msg = this.getLevel() === 'debug' ? `[${this.prefix}] ${message}` : message;\n super.warn(msg, ...args);\n }\n\n override error(message: string, ...args: unknown[]): void {\n this.syncLevel();\n const msg = this.getLevel() === 'debug' ? `[${this.prefix}] ${message}` : message;\n super.error(msg, ...args);\n }\n}\n\n/**\n * Resolve the initial log level from the `CDKL_LOG_LEVEL` env var, falling\n * back to `'info'`. This is primarily an internal contract: `cdkl studio`\n * spawns its single-shot `cdkl invoke` child with `CDKL_LOG_LEVEL=warn` so\n * cdk-local's OWN synth / orchestration progress (toolkit \"Successfully\n * synthesized to ...\", asset-bundling lines, info-level status) is silenced\n * in the child — leaving the studio LOGS panel showing only the Lambda\n * container's runtime logs (which stream straight from `docker logs` and are\n * unaffected by this level) plus the response. `--verbose` still overrides to\n * `debug` at the command layer. An invalid value is ignored.\n */\nexport function resolveConfiguredLogLevel(): LogLevel {\n const env = process.env['CDKL_LOG_LEVEL'];\n if (env === 'debug' || env === 'info' || env === 'warn' || env === 'error') {\n return env;\n }\n return 'info';\n}\n\nlet globalLogger: ConsoleLogger | null = null;\n\nexport function getLogger(): ConsoleLogger {\n if (!globalLogger) {\n globalLogger = new ConsoleLogger(resolveConfiguredLogLevel());\n }\n return globalLogger;\n}\n\nexport function setLogger(logger: ConsoleLogger): void {\n globalLogger = logger;\n}\n","/**\n * Rendering an AWS SDK failure into a log line cdk-local is willing to print\n * at DEFAULT level (issues #564, #570).\n *\n * # Why a shared module\n *\n * Issue #564 settled the policy for one site — the credential-chain failure\n * in {@link file://./sigv4-verify.ts} — and #570 found the same shape at nine\n * more, spread across five `src/cli/commands/*.ts` files. Every one of them\n * relays a third-party error's `message` into a `logger.warn`, so they share\n * one question and must not grow nine answers to it.\n *\n * SCOPE, stated so a later sweep finds a decision rather than an oversight:\n * this module governs those nine plus sigv4-verify's one, and its\n * {@link flattenToOneLine} additionally covers every other wire-derived value\n * printed on those lines (the role ARN, on the failure AND success paths).\n *\n * Issue #579 extended it to the AWS SDK error relays elsewhere under\n * `src/local/**` (plus `local-studio.ts`'s image-context warn), so the policy\n * is no longer scoped to `src/cli/commands/**`:\n * `cfn-local-state-provider.ts` (`formatAwsErrorForWarn`, six callers),\n * `ssm-parameter-resolver.ts` (whose `formatSsmError` was DELETED rather than\n * fixed — it was a second spelling of the same forging vector),\n * `state-resolver.ts`, `cloudfront-kvs-client.ts`, `cloudfront-s3-origin.ts`,\n * `layer-arn-materializer.ts`, `ecr-puller.ts`, `ecs-secrets-resolver.ts` and\n * `httpv2-service-integration.ts`. Each was decided on the SAME two axes below\n * rather than rewritten mechanically, and a `catch` around a purely LOCAL\n * operation was left alone: `agentcore-s3-bundle.ts`'s unzip and\n * `layer-arn-materializer.ts`'s presigned-URL download / unzip see no\n * credential chain and no service response, so there is nothing here for them.\n *\n * The test is what a `catch` CAN SEE, and applying it by LOCATION instead is\n * how the sweep first got `agentcore-s3-bundle.ts` wrong. Its `try` does wrap\n * `unzipSync` and nothing else — but that made the S3 `GetObject` above it\n * UNCOVERED, not out of scope: it had no `catch` at all, so the raw SDK error\n * propagated to `withErrorHandling` -> `formatError`, which prints\n * `${error.name}: ${error.message}` unflattened and unclamped at DEFAULT\n * level, and the default credential chain is what a run without\n * `--assume-role` uses. \"Outside that `catch`\" is not \"outside the sweep\";\n * ask which populations reach the site, and if the answer is \"nothing catches\n * it here\", follow it to the frame that does.\n *\n * #579 also widened what LEVEL means, and the widening is the useful part:\n * `httpv2-service-integration.ts`'s relay is not a log line at all, it is a\n * served HTTP RESPONSE BODY — the widest reader in the sweep, since it needs\n * neither `--verbose` nor access to the terminal, and the studio capture proxy\n * records it onto the timeline besides. The axis is about READERS, not about\n * logs.\n *\n * TWO CALLING CONVENTIONS this imposes, both found by #579 rather than\n * anticipated here:\n *\n * 1. Render each failure ONCE. {@link describeAwsFailureForWarn} EMITS the\n * `debug` line, so calling it twice for one error prints that line twice\n * (`cfn-local-state-provider.ts`'s `load` did, having rendered the same\n * failure for its warn and for `lastLoadError`).\n * 2. Re-raise cdk-local's OWN throws ABOVE the relay, with an identifiable\n * class. The discriminator is positive, so a `catch` that also catches\n * the caller's own `throw new Error('...')` withholds text cdk-local\n * wrote itself — which is the diagnostic loss this file's\n * {@link describeCredentialLoadFailure} note calls \"a real diagnostic\n * loss, accepted\". #579 stopped accepting it where it was cheap not to:\n * `layer-arn-materializer.ts`'s ARN-shape and missing-`Content.Location`\n * guards became `LayerMaterializationError`s and are re-raised, and\n * `httpv2-service-integration.ts`'s missing-RequestParameter 400 became a\n * `ServiceIntegrationRequestError` so an actionable 400 body did not\n * degrade into a class name and a character count.\n *\n * TWO CATCH-ALL relays remain outside it, and both are UNCOVERED. An earlier\n * revision of this note gave them opposite verdicts in adjacent paragraphs —\n * clearing one and rejecting the other on the same evidence — which was simply\n * wrong about the first, so both now read the same way:\n *\n * - `cloudfront-server.ts:129`'s `Request handling failed: ${err.message}`.\n * It is what makes `cloudfront-kvs-client.ts`'s throw a DEFAULT-level\n * line, and for THAT sub-path the text arrives pre-sanitized — but it is a\n * catch-all over the whole request pipeline, so an origin fetch, an\n * edge-function invoke or an SDK error raised anywhere below it still\n * reaches the line RAW.\n * - `ecs-service-emulator.ts`'s `logger.error` at three sites (`:909`,\n * `:1508`, `:1599`). One of them does carry\n * `ecs-secrets-resolver.ts`'s `EcsSecretsResolutionError`, which this\n * module sanitized on the way in — and reasoning from that to \"the relay\n * is safe\" is the SAME generalisation the bullet above rejects. All three\n * are catch-alls over a whole reload or replica roll, relaying\n * `err instanceof Error ? err.message : String(err)`, and what they\n * usually carry is docker CLI stderr, which is multi-line.\n *\n * So: one sub-path arriving pre-sanitized never clears a catch-all. Both need\n * the same per-occurrence call as everything else in this list. Neither is\n * done here — `cloudfront-server.ts` is out of this change's scope, and the\n * emulator's three are a different population (docker output, not SDK errors)\n * that wants the flattening half rather than the withholding half.\n *\n * # The two axes that decide it\n *\n * PROVENANCE alone says relay: a credential-chain error is about the\n * developer's own machine configuration, not something cdk-local fetched out\n * of a secret store (issue #555's criterion). Two further axes overrule it:\n *\n * LEVEL — these are `warn`, so they print on a plain `cdkl start-api` /\n * `cdkl invoke` run rather than only under `--verbose`, and `cdkl studio`\n * mirrors a serve child's output into a log ring it serves over HTTP.\n * Everybody sees a `warn`; only someone who asked sees a `debug`.\n *\n * RECONSTRUCTION — what can reach the string is not a hint about a secret,\n * it is the secret. `@aws-sdk/credential-provider-process` builds its\n * failure as `new CredentialsProviderError(error.message)` where `error` is\n * the rejection of `promisify(child_process.exec)`, i.e. Node's\n * `Command failed: <command line>\\n<stderr>`, and a passphrase written on a\n * `credential_process` command line is an ordinary thing to have. (Verified\n * at `@aws-sdk/credential-provider-process@3.972.{39,41,43}`\n * `dist-cjs/index.js:56` in this repo's tree.)\n *\n * # Where these sites DIFFER from sigv4-verify's, and why the answer differs\n *\n * {@link file://./sigv4-verify.ts}'s `catch` wraps `client.config.credentials()`\n * and nothing else: credential-chain resolution, with no AWS operation\n * cdk-local asked for. Nothing actionable is lost by withholding all of it,\n * so that site withholds unconditionally and keeps the text at `debug`.\n *\n * The #570 sites wrap an SDK call cdk-local DID make — STS\n * `GetCallerIdentity` or `AssumeRole` — so two unrelated error populations\n * land in one `catch`:\n *\n * 1. the credential chain failed before the request went out, which is\n * #564's population exactly, and\n * 2. STS answered with a modeled service exception — `ExpiredTokenException`,\n * `AccessDenied` — whose message IS the diagnosis the user needs, and\n * which never went near `credential_process`. (Spelled as the SDK\n * spells them: `@aws-sdk/client-sts` models `ExpiredTokenException`\n * (`dist-cjs/models/errors.js:6`), while `AccessDenied` is unmodeled and\n * arrives as the wire code verbatim — which is exactly why the name is\n * clamped rather than trusted.)\n *\n * Blanket-withholding would turn the single commonest failure of these\n * commands (`ExpiredTokenException: The security token included in the\n * request is expired`) into a class name and a character count. So the split\n * is by population, via {@link describeAwsFailureForWarn}.\n *\n * # The safe state is defined POSITIVELY\n *\n * The discriminator is not a deny-list of bad error shapes — #564 rejected\n * that reasoning for the `Command failed:` first line, and it loses the same\n * race here. It is the SDK's own structural test for \"this came off the wire\n * as a modeled service error\" ({@link isAwsServiceException}). Anything that\n * does not match — a chain failure, a socket error, a bare `throw 'x'` — is\n * withheld. An unrecognised shape therefore fails toward withholding.\n *\n * A hostile endpoint cannot steer the discriminator into disclosing MORE.\n * `$fault` / `$metadata` are set by the SDK from the HTTP response, not from\n * anything the body names, so forging `x-amzn-errortype:\n * CredentialsProviderError` only changes `err.name` — the response is still a\n * service response, so the error stays on the KEPT branch and its message is\n * still the sanitized, capped one the endpoint could have sent under any\n * other name. What the endpoint cannot do is move a `credential_process`\n * command line onto that branch: that text originates locally, inside a\n * `CredentialsProviderError` that never acquires `$fault`.\n *\n * # What this does NOT close\n *\n * A single-LINE forged string still reaches readers other than a human. It no\n * longer redirects the studio capture proxy: issue #578 anchored every\n * `cdkl studio` ready pattern to the start of the line, made the serve manager\n * skip a line carrying cdk-local's own `WARN: ` / `ERROR: ` decoration\n * outright, and bounded the resolved upstream to loopback — so a message\n * containing `Server listening on http://...` is neither read as a banner nor\n * usable as a destination. What remains is the reader this sanitizer was\n * always aimed at: a HUMAN scanning the log, for whom a forged-looking line is\n * still misleading text, which is why the flattening + capping stay.\n */\nimport { getLogger } from '../utils/logger.js';\n\n/**\n * Longest service-exception message relayed into a `warn` line, in\n * characters.\n *\n * A modeled STS error's message is WIRE-DERIVED — the SDK reads it out of the\n * response body — so its length is not cdk-local's to assume. Real ones run\n * to roughly 150 characters (`AccessDenied: User: arn:... is not authorized to\n * perform: sts:AssumeRole on resource: arn:...`), and the policy-quoting ones\n * are the longest, so the cap is set well above that: it exists to stop an\n * unbounded body from becoming an unbounded log line, not to trim ordinary\n * AWS text, which must survive intact or the branch buys nothing.\n *\n * Truncation is announced with the true length (see\n * {@link sanitizeServiceExceptionMessage}) so a capped line is never mistaken\n * for a complete one.\n */\nconst SERVICE_MESSAGE_MAX = 512;\n\n/**\n * Total stringification of a thrown value's message.\n *\n * `String(err)` is NOT total. That throw would escape the `catch` it is\n * called from and turn a warn-and-continue branch into a hard failure — a 500\n * from the SigV4 authorizer in #564's testing, and a dead `cdkl invoke` here.\n * One helper rather than an expression repeated per site, so the length\n * reported in a `warn` and the text printed at `debug` can never describe\n * different strings.\n *\n * CORRECTION to #564, measured on this repo's Node 24: `String(aSymbol)`\n * does NOT throw — it returns `'Symbol(x)'`, and it is template\n * INTERPOLATION (`` `${aSymbol}` ``) that raises\n * `TypeError: Cannot convert a Symbol value to a string`. Since both the old\n * code and this helper call `String()` explicitly, a `Symbol` throw was never\n * one of the reachable cases. The two that ARE reachable, both verified:\n * an object with a null prototype (`TypeError: Cannot convert object to\n * primitive value`, because it has no `toString`), and any value whose\n * `toString` / `Symbol.toPrimitive` throws — which a hostile or merely buggy\n * third-party error object is free to do.\n *\n * Named for what it does rather than for one caller: #564 shipped it as\n * `stringifyCredentialLoadFailure`, and #570 gave it a second population\n * (service exceptions) for which that name was simply wrong.\n */\nexport function stringifyThrown(err: unknown): string {\n try {\n return err instanceof Error ? String(err.message) : String(err);\n } catch {\n return '[unstringifiable throw]';\n }\n}\n\n/**\n * The throwing class's name, clamped to something no input can forge.\n *\n * `err.name` is NOT input-independent, which is the whole reason this is a\n * function and not an interpolation. For an AWS service exception it is\n * WIRE-DERIVED: `@aws-sdk/core` builds it from the `x-amzn-errortype` header\n * / the body's `code` / `__type` through `sanitizeErrorCode`, which splits on\n * ',' ':' and '#' and does nothing else — no length cap, no newline stripping\n * (read at `@aws-sdk/core@3.974.13` `protocols/index.js:324`). Such an\n * exception reaches these call sites, because `credential-provider-ini` calls\n * the STS `roleAssumer` unwrapped and because the #570 sites invoke STS\n * directly. So a hostile or hijacked credential endpoint\n * (`AWS_CONTAINER_CREDENTIALS_FULL_URI`, a redirected IMDS) answering\n * `x-amzn-errortype: Foo\\nWARN: signature verified` could FORGE log lines\n * into the `warn` stream — and into the studio ring served over HTTP.\n *\n * A bare identifier of at most 64 characters is what every real class name is\n * and what no injected value can be; anything else degrades to `'unknown'`,\n * which also covers a non-`Error` throw, so the field never names a class the\n * throw was not.\n *\n * Note the WRONG fix: `err.name.slice(0, 64)` keeps the newline, so the\n * forgery survives truncation.\n */\nexport function clampErrorName(err: unknown): string {\n // The READ is guarded, not just the value. `err` is a third-party object and\n // `name` can be an accessor that throws (or a Proxy trap that does), and such\n // a throw would escape the `catch` this is called from -- the same hazard\n // {@link stringifyThrown} exists to close, arriving through a different\n // property.\n let rawKind: unknown;\n try {\n rawKind = err instanceof Error ? err.name : 'unknown';\n } catch {\n return 'unknown';\n }\n return typeof rawKind === 'string' && /^[A-Za-z0-9_.-]{1,64}$/.test(rawKind)\n ? rawKind\n : 'unknown';\n}\n\n/**\n * The thrown value's `code`, when it is a bare identifier, else `undefined`.\n *\n * This exists because withholding by class name alone is not discriminating\n * enough for the population that actually reaches the withheld branch most\n * often. `Region is missing`, `getaddrinfo ENOTFOUND sts.<region>.amazonaws.com`\n * and `connect ETIMEDOUT 169.254.169.254:80` all arrive as a plain `Error`, so\n * all three render as `Error; N-character message withheld` and the reader\n * cannot tell a misconfiguration from an unreachable endpoint.\n *\n * Node sets `code` on its system errors (`ENOTFOUND`, `ETIMEDOUT`,\n * `ECONNREFUSED`) and there it is a fixed enum chosen by the runtime. It is\n * NOT input-independent in general, though, and the earlier draft of this note\n * claimed it was: `@smithy/core`'s `decorateServiceException`\n * (`dist-cjs/submodules/client/index.js:795-802`) copies every key of the\n * PARSED RESPONSE BODY onto the exception, so an unmodeled error from a\n * hostile endpoint can carry a `code` of its choosing. The clamp is therefore\n * load-bearing rather than belt-and-braces, exactly as it is for\n * {@link clampErrorName}: what survives is at most 64 characters matching\n * `[A-Za-z0-9_.-]`, which cannot forge a line, and which is the same residue\n * the class name already accepts.\n *\n * `undefined` rather than `'unknown'` when there is none, so the caller can\n * omit the field entirely instead of printing a placeholder that says less\n * than nothing.\n */\nexport function clampErrorCode(err: unknown): string | undefined {\n if (!err || typeof err !== 'object') return undefined;\n let raw: unknown;\n try {\n raw = (err as { code?: unknown }).code;\n } catch {\n return undefined;\n }\n if (typeof raw !== 'string') return undefined;\n return /^[A-Za-z0-9_.-]{1,64}$/.test(raw) ? raw : undefined;\n}\n\n/**\n * Is `err` a modeled AWS service exception — i.e. did the SDK parse it out of\n * a service RESPONSE, rather than raise it while assembling the request?\n *\n * This is `ServiceException.isInstance`'s own structural test, reproduced\n * rather than imported: cdk-local loads `@aws-sdk/client-sts` lazily at every\n * one of these call sites (a dynamic `import()` inside the `try`), so taking\n * a static dependency on `@smithy/core` purely to type-test an error would\n * pull the SDK into the CLI's startup path. The structural form also keeps\n * working across the several `@smithy/core` copies pnpm resolves in this\n * tree, where an `instanceof` against one copy's class fails for an error\n * minted by another.\n *\n * The test is deliberately the SDK's and not a name list: a name list would\n * have to be extended for every new STS error code, and a missing entry would\n * fail toward DISCLOSING less, which is safe, but also toward hiding the\n * actionable message, which is the regression this split exists to avoid.\n */\nexport function isAwsServiceException(err: unknown): boolean {\n if (!err || typeof err !== 'object') return false;\n const candidate = err as { $fault?: unknown; $metadata?: unknown };\n try {\n return (\n Boolean(candidate.$metadata) &&\n (candidate.$fault === 'client' || candidate.$fault === 'server')\n );\n } catch {\n // A throwing accessor means the shape cannot be established, and an\n // unestablished shape is the withheld bucket -- the same direction every\n // other unknown takes.\n return false;\n }\n}\n\n/**\n * Replace every character that could make one emitted line render as more than\n * one line, or render in an order it was not written in, with a space.\n *\n * Four Unicode categories, each measured rather than assumed (see the fixture\n * in `tests/unit/local/credential-error.test.ts`):\n *\n * - `Cc` — the C0/C1 controls, which is `\\n` / `\\r` (a forged extra line in\n * the studio ring) and `\\x1b` (an ANSI escape in a terminal). U+0085 NEL\n * lives here too.\n * - `Cf` — the format characters, which is U+202E RIGHT-TO-LEFT OVERRIDE and\n * friends: they forge how the REST of the line reads. The cost is that a\n * ZWJ inside an emoji or an Indic cluster is replaced too; an AWS error\n * message is ASCII, so that is a trade with no observed downside.\n * - `Zl` / `Zp` — U+2028 and U+2029. Neither is in `Cc` or `Cf`, and both are\n * forced line breaks in the studio UI's `<pre>`, so leaving them out would\n * have left the forged-line case open in HTML while closing it in a\n * terminal.\n * - `Cs` — a LONE surrogate, which is not a character at all and breaks JSON\n * encoding of the log event. With the `u` flag a well-formed pair is one\n * code point and does NOT match, so emoji survive.\n *\n * Used by both branches of {@link describeAwsFailureForWarn} — the kept\n * message, and the `debug` line carrying the withheld one, because the `debug`\n * stream is the SAME studio ring under `--verbose`, so a text unsafe to put on\n * a line at `warn` is unsafe at `debug` — and, since issue #570's review\n * rounds, by every OTHER wire-derived value that lands on one of these lines:\n * `sigv4-verify`'s own `debug` line, and the role ARN at the four warn sites\n * plus the five `info` / `debug` sites that print an ARN resolved from a live\n * `GetFunctionConfiguration` / `GetAgentRuntime` response. The last group is\n * the more reachable one — it fires on SUCCESS.\n */\nexport function flattenToOneLine(message: string): string {\n return message.replace(/[\\p{Cc}\\p{Cf}\\p{Zl}\\p{Zp}\\p{Cs}]/gu, ' ');\n}\n\n/**\n * Render a wire-derived service message safe to put on one log line.\n *\n * Two properties, and both are about the LINE rather than about secrecy — the\n * message itself is already judged safe to print by the time this is called:\n *\n * - No line breaks and no rendering-direction control, via\n * {@link flattenToOneLine}.\n * - Bounded length, with the true length named when it is exceeded. The\n * suffix names the character count of the SANITIZED message rather than\n * of the raw one, because the sanitized string is what the truncated\n * prefix is a prefix OF; quoting the raw length would describe a string\n * the reader can never see.\n *\n * The cut is made on CODE POINTS rather than UTF-16 units, so a truncation\n * landing inside an astral character cannot emit half of a surrogate pair. The\n * count in the suffix is the code-point count for the same reason: the prefix\n * and the number must describe the same string.\n */\nexport function sanitizeServiceExceptionMessage(message: string): string {\n // Code points are exactly the unit wanted here. `no-misused-spread`'s concern\n // is that spreading a string splits grapheme CLUSTERS (a ZWJ emoji sequence, a\n // combining mark), and that is accepted: the input is an AWS error message,\n // and the property being bought is that the cut cannot land inside a surrogate\n // PAIR and emit half of one. `Intl.Segmenter` would preserve clusters and is\n // what the rule suggests, but it makes the cap locale-dependent, which a\n // log-line bound must not be.\n // oxlint-disable-next-line typescript/no-misused-spread\n const points = [...flattenToOneLine(message)];\n if (points.length <= SERVICE_MESSAGE_MAX) return points.join('');\n return `${points.slice(0, SERVICE_MESSAGE_MAX).join('')}[... truncated; ${points.length}-character message]`;\n}\n\n/**\n * Describe a credential-chain failure for a default-level log line WITHOUT\n * relaying the chain's own message (issue #564).\n *\n * What is reported instead is input-INDEPENDENT: the clamped class name (see\n * {@link clampErrorName}), which is the same discriminator\n * `ecs-secrets-resolver.ts` reports for the JSON parse failure it must not\n * echo, plus the clamped {@link clampErrorCode} when the throw carries one.\n *\n * Withholding is NOT free, and the cost lands on cdk-local's own text as well\n * as on the SDK's. The worked example used to be `role-arn.ts`'s\n * `AssumeRole(<arn>) returned no usable credentials.`: a plain `Error` with no\n * `$fault`, so it was withheld like any other, and the note recorded that as a\n * real diagnostic loss accepted because the alternative — an allow-list of\n * messages that may print — is the deny-list this design rejects, wearing the\n * other sign. It also named the right fix: make cdk-local's own throws\n * IDENTIFIABLE rather than guess at their text.\n *\n * Issue #579 did that, for exactly this example. `role-arn.ts` now throws\n * `AssumeRoleFailure`, carrying a `detail` its relaying callers print verbatim\n * — and the same pattern closed the identical loss in\n * `layer-arn-materializer.ts`, `httpv2-service-integration.ts`,\n * `ecr-puller.ts`, `local-run-task.ts` and `ecs-service-emulator.ts`. The\n * general point stands and is what a new site should apply: the policy cannot\n * tell cdk-local's own sentence from a hostile endpoint's, so a `catch` that\n * can see both must make its own throws recognisable BEFORE the relay.\n *\n * The remaining ARN-length question — an ARN is structured, so the bound\n * belongs at the three resolution points rather than at the log line — is\n * tracked separately at\n * https://github.com/go-to-k/cdk-local/issues/607.\n *\n * The LENGTH is reported, unlike in `ecs-secrets-resolver.ts`, and the\n * difference is deliberate: there the user already knows which secret it is\n * and can read the value at its source, so a character count would be\n * disclosure buying nothing. Here the user cannot see the withheld message at\n * all, and the count is what separates a one-line\n * `Could not load credentials from any providers` (45 characters, measured\n * against `@aws-sdk/credential-provider-node@3.972.44` `dist-cjs/index.js:144`)\n * from a multi-hundred-character `Command failed:` dump — which is what tells\n * them whether their `credential_process` even ran.\n *\n * The count is a side channel, and a narrow one: against a KNOWN\n * `credential_process` template the number is `constant + len(passphrase)`, so\n * it yields the passphrase's LENGTH. That is accepted rather than overlooked.\n * It buys the one thing the user cannot otherwise see, the `Command failed:`\n * dump is not reachable on today's SDK versions anyway, and bucketing the\n * number would blur exactly the boilerplate-vs-dump distinction the field\n * exists for.\n */\nexport function describeCredentialLoadFailure(err: unknown): string {\n const code = clampErrorCode(err);\n const kind = code === undefined ? clampErrorName(err) : `${clampErrorName(err)} ${code}`;\n return `${kind}; ${stringifyThrown(err).length}-character message withheld, logged at debug level under --verbose`;\n}\n\n/**\n * Render an AWS SDK call failure for a `logger.warn` line, and emit the\n * withheld text at `debug` when it is withheld (issue #570).\n *\n * `operation` names the call for the `debug` line — e.g.\n * `'STS GetCallerIdentity'`. It is cdk-local's own literal at every call\n * site, never anything read off an error or a response.\n *\n * # Why this emits the `debug` line itself\n *\n * Because the alternative is nine call sites each free to withhold a message\n * and forget to print it anywhere. The pairing is the invariant — \"withheld\n * at `warn`\" is only acceptable while \"in full at `debug`\" holds — so it\n * lives in one function rather than in a convention nine sites must keep. A\n * tenth site gets it for free.\n *\n * The `debug` line fires ONLY on the withheld branch. On the service-exception\n * branch the `warn` already carries the message, and repeating it verbatim one\n * level down would say nothing the reader did not just read.\n *\n * It is FLATTENED (not capped). Flattened because the `debug` stream is not a\n * private channel: it is the same stdout `cdkl studio` mirrors into the log\n * ring it serves over HTTP, so a `\\n` in the withheld text would forge a line\n * there exactly as it would at `warn`. Not capped, because being able to read\n * the whole withheld message is the entire reason the line exists — the\n * `warn`'s character count is what tells the reader how much they are about to\n * see. Note that this puts the full text into that ring for a\n * `--verbose` studio run; see `docs/troubleshooting.md`.\n *\n * ORDERING: the `debug` line is emitted when THIS function runs, which is\n * before the `warn` at every site — inline in the `warn`'s template at eight of\n * them, and a couple of statements earlier at the one that hoists the result\n * into a `const reason`. Either way it prints immediately ABOVE the `warn` that\n * refers to it under `--verbose`. Left as is: restructuring every call site to\n * log afterwards would buy an ordering nobody reads top-down anyway.\n */\nexport function describeAwsFailureForWarn(err: unknown, operation: string): string {\n if (isAwsServiceException(err)) {\n return `${clampErrorName(err)}: ${sanitizeServiceExceptionMessage(stringifyThrown(err))}`;\n }\n getLogger().debug(\n `${operation}: the AWS SDK's own failure message was: ${flattenToOneLine(stringifyThrown(err))}`\n );\n return describeCredentialLoadFailure(err);\n}\n","import { readlinkSync, realpathSync } from 'node:fs';\nimport { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport { sanitizeServiceExceptionMessage } from '../local/credential-error.js';\n\n/**\n * Containment for a path a Cloud Assembly names.\n *\n * A Lambda's `Metadata['aws:asset:path']` is a string chosen by whoever WROTE\n * the assembly. `cdkl invoke -a <dir>` / `cdkl start-api -a <dir>` consume a\n * PRE-SYNTHESIZED assembly with no CDK subprocess in between, so nothing\n * upstream validates it, and the value ends up as a read-only BIND MOUNT at\n * `/var/task` (or `/opt` for a layer) in a container running handler code the\n * same assembly supplied.\n *\n * `path.join` does NOT honour a leading separator, so an ABSOLUTE value stays\n * inside the directory (`join('/tmp/cdk.out', '/abs/foo')` is\n * `/tmp/cdk.out/abs/foo`). The shape that leaves it is `..`:\n * `join('/tmp/cdk.out', '../../victim')` resolves outside the assembly. That\n * asymmetry is why {@link absoluteAssemblyPathEscape} exists beside\n * {@link resolveAssemblyPath} rather than falling out of it.\n *\n * EVERY path this module RENDERS goes through {@link displayUntrustedValue}, for\n * the reason the mitigation itself depends on: the warning and the refusal\n * exist FOR a hand-modified assembly, so the path is attacker-chosen and lands\n * on a log line. `path.resolve` preserves control characters, so an\n * unsanitized value can carry `\\x1b[2K\\r` and `\\n` and erase the warning it\n * appears in, forging benign lines in its place; and a value carrying a quote\n * can close a boundary the message drew around it and write a clause of its\n * own. Since the decision here is \"accept and WARN\", a forgeable warning is no\n * warning at all. Same direction as `src/utils/role-arn.ts`, which already\n * reaches into `credential-error.ts` for the one spelling of the line rule.\n */\n\nexport type ResolvedAssemblyPath =\n | {\n readonly contained: true;\n /** The path the caller should use — what `path.join` would have produced. */\n readonly path: string;\n }\n | {\n readonly contained: false;\n readonly escape: 'lexical';\n /** The lexically resolved path, for the refusal message. */\n readonly path: string;\n }\n | {\n readonly contained: false;\n readonly escape: 'symlink';\n readonly path: string;\n /** Where the symbolic link(s) actually lead. */\n readonly realPath: string;\n };\n\nexport type AssemblyPathEscape = Extract<ResolvedAssemblyPath, { contained: false }>;\n\n/**\n * `true` when `candidate` names something strictly beneath `base`, both given\n * as already-resolved absolute paths.\n *\n * The `..` test is SEPARATOR-AWARE rather than a bare `startsWith('..')`,\n * which would also reject a legitimate sibling named `..foo`. The empty-string\n * case is `base` itself; callers decide whether that counts as an escape,\n * because an asset path legitimately names a DIRECTORY while a template path\n * does not.\n */\nfunction isInside(base: string, candidate: string): boolean {\n const rel = relative(base, candidate);\n if (rel === '' || rel === '..') return false;\n if (rel.startsWith(`..${sep}`)) return false;\n // WIN32 ONLY, and unreachable on POSIX: `path.relative` returns an absolute\n // path when the two sides share no root, which needs drive letters or a UNC\n // prefix. Kept because `path` is the PLATFORM's here, so this file is the\n // Windows verdict too.\n return !isAbsolute(rel);\n}\n\n/**\n * `realpath(3)`, or `undefined` for a path that does not fully resolve.\n *\n * `.native` is load-bearing and must not be simplified to `fs.realpathSync`.\n * The plain form is a JavaScript walker that folds `..` LEXICALLY, so it\n * disagrees with the kernel on a target carrying a `..` after a symlinked\n * component — answering `ENOENT` for a path the kernel resolves, and on a\n * case-insensitive filesystem (APFS by default) it can spin on the same shape.\n * `.native` is libuv's `realpath(3)` and throws the same\n * `ENOENT` / `ELOOP` / `EACCES`.\n */\nfunction tryRealpath(p: string): string | undefined {\n try {\n return realpathSync.native(p);\n } catch {\n return undefined;\n }\n}\n\n/** `fs.readlinkSync`, or `undefined` when `p` is not a symbolic link. */\nfunction tryReadlink(p: string): string | undefined {\n try {\n return readlinkSync(p);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Link follows before the walk gives up and reports the path as unresolvable.\n * It does NOT refuse: an exhausted budget answers `undefined`, which leaves\n * the symlink arm silent and the lexical verdict standing. Safe because the OS\n * gives up first (macOS caps at 32, `ELOOP`), so a chain that reaches this cap\n * is one nothing can open anyway.\n */\nconst MAX_LINK_HOPS = 40;\n\n/**\n * Unresolvable path COMPONENTS the climb walks before giving up. Bounds the\n * recursion below, which is one frame per component, so a pathological value\n * cannot raise a `RangeError` from inside {@link tryRealpath}'s own `try` (its\n * `catch` would swallow the crash into a silent `undefined`).\n *\n * KNOW THAT EXHAUSTING THIS FAILS OPEN, and why that is accepted rather than\n * unnoticed. Unlike {@link MAX_LINK_HOPS}, which has the OS's own `ELOOP` cap\n * behind it, nothing else stops a path of 1 001 absent components: the climb\n * gives up, the symlink arm goes silent, and a value that would land outside\n * reads as CONTAINED on the lexical verdict alone. It is not reachable in\n * effect — such a path cannot exist, so `cdkl invoke`'s `existsSync` refuses it\n * and `start-api`'s `docker run` fails to mount it — but that safety lives in\n * the CONSUMERS, not here. A consumer that neither checks existence nor mounts\n * would need its own answer.\n */\nconst MAX_PATH_COMPONENTS = 1000;\n\n/**\n * Where `target` REALLY points, for a path that may not exist yet.\n *\n * `realpathSync` answers only for a path that fully resolves, and it throws\n * `ENOENT` for a DANGLING symbolic link exactly as it does for an absent file.\n * `cdkl start-api` resolves an asset path without an existence check, so an\n * absent or dangling component must not silence the symlink arm.\n *\n * Each unresolvable component is therefore handled by hand: climb to the\n * deepest ancestor that DOES resolve, then re-apply the remaining components,\n * following any symbolic link with `readlink` and re-resolving its target.\n * `undefined` means the walk could not resolve the path at all.\n *\n * For a path that FULLY RESOLVES the answer is the kernel's and is exact. For\n * one that does not exist yet this is a best-effort MODEL of kernel\n * resolution; the known edge is a `..` INSIDE an unresolvable link's target,\n * folded lexically here while the kernel folds it only after following each\n * preceding component. That edge is benign for THESE callers rather than in\n * general: it needs the target to be absent, and both consumers resolve the\n * path and then open or mount it, so the divergence is between this model and\n * a path nothing can reach. A caller that CREATED a file through such a path\n * would need an `lstat` of its own.\n *\n * `EACCES` is folded into \"does not resolve\" along with `ENOENT`, so a link\n * under a directory this process cannot traverse reads as contained. Same\n * bound: the consumer's own `existsSync` / mount runs as the same user and\n * fails identically.\n */\nfunction resolveThroughLinks(target: string, hops = 0, climbs = 0): string | undefined {\n const direct = tryRealpath(target);\n if (direct !== undefined) return direct;\n if (hops >= MAX_LINK_HOPS) return undefined;\n if (climbs >= MAX_PATH_COMPONENTS) return undefined;\n\n const parent = dirname(target);\n // `dirname` is idempotent at a root, which `realpathSync` above would have\n // resolved — so reaching here means there is nothing left to climb.\n if (parent === target) return undefined;\n\n // The climb costs no hop: `hops` bounds the LINK chain, and a deep path of\n // absent components is not one.\n const realParent = resolveThroughLinks(parent, hops, climbs + 1);\n if (realParent === undefined) return undefined;\n\n const link = tryReadlink(target);\n if (link === undefined) {\n // The component simply does not exist. Whatever lives there lands under\n // the real parent.\n return join(realParent, basename(target));\n }\n // A link whose target does not resolve yet: follow it by hand, relative to\n // the directory the link REALLY lives in (`realParent`, not\n // `dirname(target)`) — a target with a leading `..` folds against the real\n // directory, and folding it against the lexical parent reads an escape as\n // contained.\n return resolveThroughLinks(resolve(realParent, link), hops + 1, climbs);\n}\n\n/**\n * Resolve an assembly-supplied `candidate` against `dir` and report whether\n * the result stays inside it.\n *\n * The lexical arm joins exactly the way the call sites used to (`path.join`,\n * NOT `path.resolve`), so the verdict is about the path the caller will\n * actually use. `join`'s handling of an absolute candidate makes this arm\n * strictly more permissive than a `resolve`-based one would be; an absolute\n * value is therefore answered by {@link absoluteAssemblyPathEscape} instead,\n * because this function structurally cannot.\n *\n * The SYMLINK arm exists because the lexical arm alone leaves an equivalent\n * hole: `cdk.out/link -> /etc` plus a candidate of `link/passwd` is lexically\n * contained and still reaches `/etc/passwd`. Both sides go through\n * {@link resolveThroughLinks}, so an assembly directory REACHED through a link\n * (macOS spells `/tmp` as `/private/tmp`) is unaffected.\n *\n * The verdict is about the assembly AS IT SITS ON DISK. It is NOT a defence\n * against a process rewriting that directory concurrently — the caller uses\n * the path after this returns.\n */\nexport function resolveAssemblyPath(\n dir: string,\n candidate: string,\n options?: {\n /**\n * Contain within THIS directory instead of `dir`.\n *\n * A value still RESOLVES against `dir` — that part is the caller's own\n * `path.join` and must not change — but the containment test runs against\n * a wider root. The one case is an asset path below a `cdk.Stage`:\n * `cdk synth` stages a Stage's assets into the APP's outdir while the\n * Stage's manifest sits in `cdk.out/assembly-<Stage>/`, so upstream emits\n * `../asset.<hash>` by design.\n *\n * This widens the BASE, never the RULE: `path.relative` must still be\n * non-empty, non-`..`-prefixed and relative, so `../../victim` is refused\n * from a Stage manifest exactly as from a top-level one.\n *\n * `containWithin` must never carry an assembly-supplied value; it is the\n * user's own outdir. A WRONG bound is not uniformly safe — a DISJOINT one\n * refuses everything, but an ANCESTOR of the real one WIDENS\n * (`containWithin: '/'` admits `/etc/passwd`).\n */\n containWithin?: string;\n }\n): ResolvedAssemblyPath {\n const base = resolve(dir);\n const bound = options?.containWithin === undefined ? base : resolve(options.containWithin);\n const joined = resolve(join(base, candidate));\n\n if (!isInside(bound, joined)) {\n return { contained: false, escape: 'lexical', path: joined };\n }\n\n // The same resolver on the bound, so an assembly directory that is itself\n // reached through a link does not make every candidate look like an escape.\n const realBound = resolveThroughLinks(bound);\n if (realBound !== undefined) {\n const realTarget = resolveThroughLinks(joined);\n if (realTarget !== undefined && !isInside(realBound, realTarget)) {\n return { contained: false, escape: 'symlink', path: joined, realPath: realTarget };\n }\n }\n\n return { contained: true, path: joined };\n}\n\n/**\n * Whether an ALREADY-ABSOLUTE assembly-supplied path lies outside `bound`.\n *\n * {@link resolveAssemblyPath} cannot answer this, and the reason is structural\n * rather than an oversight: its lexical arm joins with `path.join`, which does\n * NOT honour a leading separator, so an absolute candidate is folded INTO the\n * directory and the verdict would describe a path no caller opens. A site that\n * HONOURS an absolute value needs the verdict about the value itself.\n *\n * The callers are `cdkl invoke`'s and `cdkl start-api`'s\n * `Metadata['aws:asset:path']` resolution. Those honour an absolute path\n * because `cdk synth --no-staging` emits one — CDK writes the asset's absolute\n * SOURCE directory under `aws:cdk:disable-asset-staging`, usually outside the\n * outdir — and they WARN rather than refuse when it leaves the bound, so this\n * returns a verdict rather than throwing. The asset-MANIFEST readers that\n * honour an absolute value take the same verdict: `'honour-warn'` (the\n * start-cloudfront origin) warns when the value is a folder inside the user's\n * project not under a credential or version-control directory, and refuses\n * otherwise, `'honour'` (the soft-reload\n * sources) refuses (#745).\n *\n * It lives HERE so the containment rule has one spelling: it reuses this\n * module's own {@link isInside} and {@link resolveThroughLinks}, symlink arm\n * included, rather than letting a caller re-spell `path.relative` and drift.\n *\n * `bound` itself is NOT an escape, unlike in {@link resolveAssemblyPath},\n * where an empty `path.relative` means \"names the directory rather than a file\n * inside it\". An asset path legitimately names a DIRECTORY, so a value equal\n * to the bound is inside it and reporting it as outside would be false.\n *\n * THE REAL PATHS DECIDE IN BOTH DIRECTIONS, which is the one place this\n * deliberately does more than {@link resolveAssemblyPath}'s lexical-first\n * ordering. The lexical verdict here is about a SPELLING, and two spellings of\n * the same directory are common rather than exotic: macOS resolves `/tmp` to\n * `/private/tmp` and `/var` to `/private/var`, and a user may symlink `cdk.out`\n * itself. With an outdir of `/tmp/cdk.out` and a `--no-staging` value of\n * `/private/tmp/cdk.out/src`, a lexical-only verdict cries \"pointing outside\n * the assembly ... treat this assembly as untrusted\" about an asset that is\n * plainly inside it — and this arm exists to make an UNEXPECTED path visible,\n * so a false alarm is the failure that costs it its meaning.\n *\n * Exonerating requires the kernel to answer for BOTH operands: an unresolvable\n * one leaves the lexical verdict standing, so the arm stays loud when it cannot\n * see. (`resolveAssemblyPath` cannot take the same shape: its verdict is about\n * a path built with `path.join`, and letting a real path overrule the lexical\n * `..` there would answer about a location the caller never opens.)\n */\nexport function absoluteAssemblyPathEscape(\n bound: string,\n absolutePath: string\n): AssemblyPathEscape | undefined {\n const resolvedBound = resolve(bound);\n const target = resolve(absolutePath);\n const lexicallyOutside = !isInside(resolvedBound, target) && target !== resolvedBound;\n\n const realBound = resolveThroughLinks(resolvedBound);\n const realTarget = resolveThroughLinks(target);\n const reallyOutside =\n realBound === undefined || realTarget === undefined\n ? undefined\n : !isInside(realBound, realTarget) && realTarget !== realBound;\n\n if (lexicallyOutside) {\n // `false` is the kernel saying the two spellings name the same place.\n // `undefined` is \"could not look\", which must not silence the arm.\n if (reallyOutside === false) return undefined;\n return { contained: false, escape: 'lexical', path: target };\n }\n if (reallyOutside === true) {\n return { contained: false, escape: 'symlink', path: target, realPath: realTarget! };\n }\n return undefined;\n}\n\n/**\n * Whether `candidate` names the SAME directory as `bound` — lexically, or\n * through a symbolic link on either side.\n *\n * An asset source legitimately names a DIRECTORY, so a value that resolves\n * onto the output directory itself is not an escape; but it hands the WHOLE\n * assembly to the sink, which is worth a line. A caller that re-spells this as\n * `resolve(a) === resolve(b)` misses every second spelling of the bound\n * (macOS `/tmp` vs `/private/tmp`, a symlinked `cdk.out`), and\n * {@link absoluteAssemblyPathEscape} exonerates exactly those spellings as\n * inside — so the equality beside it would stay silent for them.\n *\n * Conservative on failure: an unresolvable side answers from the lexical\n * comparison alone, so it can only say \"not the same\", never wrongly claim\n * identity.\n */\nexport function namesTheSameDirectory(bound: string, candidate: string): boolean {\n const resolvedBound = resolve(bound);\n const target = resolve(candidate);\n if (target === resolvedBound) return true;\n const realBound = resolveThroughLinks(resolvedBound);\n const realTarget = resolveThroughLinks(target);\n return realBound !== undefined && realTarget !== undefined && realBound === realTarget;\n}\n\n/**\n * The escape verdict for an assembly-supplied path WITHOUT throwing, taking\n * whichever arm the value's own shape calls for: {@link absoluteAssemblyPathEscape}\n * for an absolute value, {@link resolveAssemblyPath} for a relative one.\n *\n * For a caller that only WARNS and has many values to judge — the BuildKit\n * passthroughs in `src/assets/buildkit-passthrough-warnings.ts`. `base` is what\n * a relative value resolves against, `bound` what it must stay inside.\n * Returns `undefined` when the value is fine, including when it names `bound`\n * itself ({@link namesTheSameDirectory}).\n */\nexport function assemblyPathEscape(\n base: string,\n bound: string,\n candidate: string\n): AssemblyPathEscape | undefined {\n if (isAbsolute(candidate)) return absoluteAssemblyPathEscape(bound, candidate);\n const resolved = resolveAssemblyPath(base, candidate, { containWithin: bound });\n if (resolved.contained || namesTheSameDirectory(bound, resolved.path)) return undefined;\n return resolved;\n}\n\n/**\n * The shared tail of a containment refusal: what the value resolved to, what\n * it escaped, and why that means the assembly is not CDK-generated. The call\n * site supplies its own subject (\"Lambda 'X' has ... which \") and its own\n * error class. `action` completes \"Refusing to ...\" and is REQUIRED rather\n * than defaulted: a default is a branch no caller takes, so it can neither be\n * fenced nor be right for the next caller.\n *\n * `provenanceOverride` replaces that whole closing sentence for a caller that\n * does NOT refuse — the BuildKit passthrough warnings, where \"Refusing to ...\"\n * would be a false statement about a value that is forwarded anyway.\n */\nexport function renderAssemblyPathEscape(\n escape: AssemblyPathEscape,\n dir: string,\n action: string,\n provenanceOverride?: string\n): string {\n const provenance =\n provenanceOverride ??\n `CDK emits assembly paths that stay inside the assembly directory; one that leaves it ` +\n `indicates the synth output was hand-modified or generated by a non-CDK toolchain. ` +\n `Refusing to ${action}.`;\n const base = resolve(dir);\n // The SYMLINK arm compares against the base as the KERNEL sees it, because\n // that is what `escape.realPath` is. With `-a /tmp/cdk.out` on macOS\n // (`/tmp -> /private/tmp`) a link to the directory itself would otherwise\n // print \"outside '/tmp/cdk.out'\", a false clause about a path that IS the\n // directory.\n const realBase = resolveThroughLinks(base) ?? base;\n // Every rendered operand is attacker-chosen; see this module's header for\n // why each goes through `displayUntrustedValue`, with no quotes of ours.\n const shownPath = displayUntrustedValue(escape.path);\n const shownBase = displayUntrustedValue(base);\n if (escape.escape === 'symlink') {\n if (escape.realPath === realBase) {\n return (\n `resolves to ${shownPath}, a symbolic link to the directory ` +\n `${shownBase} itself rather than to a path inside it. ${provenance}`\n );\n }\n return (\n `resolves to ${shownPath}, which leads through a symbolic link to ` +\n `${displayUntrustedValue(escape.realPath)}, outside ${shownBase}. ${provenance}`\n );\n }\n if (escape.path === base) {\n return `names the directory ${shownBase} itself rather than a path inside it. ${provenance}`;\n }\n return `resolves to ${shownPath}, outside ${shownBase}. ${provenance}`;\n}\n\n/**\n * A letter or digit that neither draws as a blank nor reads as a quote.\n * `\\p{L}` alone admits both, so two classes are carved out: the\n * default-ignorables, which hold letters that draw as a blank (the Hangul\n * fillers U+3164 and U+FFA0), and the quote-shaped letters — the Spacing\n * Modifier Letters block (U+02BA reads as `\"`, U+02BC as `'`) plus the ones\n * outside it (U+0374, U+0559, U+07F4-U+07F5, U+A78B-U+A78C, and the halfwidth\n * sound marks U+FF9E-U+FF9F). Not all of `\\p{Lm}`: U+30FC is in it, and it is\n * an ordinary character of a Japanese directory name.\n */\nconst VISIBLE_LETTER = new RegExp(\n String.raw`^(?![\\p{Default_Ignorable_Code_Point}\\u02b0-\\u02ff\\u0374\\u0559\\u07f4\\u07f5\\ua78b\\ua78c\\uff9e\\uff9f])[\\p{L}\\p{N}]$`,\n 'u'\n);\n\n/**\n * A combining mark, which counts only DIRECTLY after a visible letter (or a\n * mark that itself counted): on a space or on punctuation it draws on its own,\n * and U+030B / U+030E there look like a quote.\n */\nconst COMBINING_MARK = /^\\p{M}$/u;\n\n/**\n * A default-ignorable code point, which draws as NOTHING. Tested before the\n * mark rule, because some are combining marks (U+034F, U+17B4, U+180B, the\n * variation selectors U+FE00-U+FE0F and U+E0100-U+E01EF): after a letter they\n * would otherwise pass as bare, and `/home/me/.ss\\u034fh` would print exactly\n * like `.ssh` while naming a different path. The host's classifier\n * (go-to-k/cdkd#3509) does not carve these out; this one does.\n */\nconst DEFAULT_IGNORABLE = /^\\p{Default_Ignorable_Code_Point}$/u;\n\n/**\n * The ASCII a bare value may carry besides letters and digits. Everything else\n * — any whitespace, any quote, any other symbol — takes the boundary, which\n * costs a legitimate path nothing but a pair of quotes.\n */\nconst BARE_PUNCTUATION = /^[/\\\\._~+@:=-]$/;\n\n/**\n * Classify each code point: `bare` (allowed in a bare value), `shown` (shown\n * as itself inside the boundary), or `escaped`. An ALLOWLIST, because a\n * denylist has to enumerate every character that draws as a blank or reads as\n * a quote.\n *\n * Each test is ONE character and this walks the value — never `^(...)+$` over\n * the whole of it: alternatives that overlap under a quantifier backtrack\n * exponentially on a long value that fails near its end.\n */\nfunction classify(chars: readonly string[]): Array<'bare' | 'shown' | 'escaped'> {\n let afterLetter = false;\n return chars.map((ch) => {\n if (DEFAULT_IGNORABLE.test(ch)) {\n afterLetter = false;\n return 'escaped';\n }\n if (COMBINING_MARK.test(ch)) return afterLetter ? 'bare' : 'escaped';\n afterLetter = VISIBLE_LETTER.test(ch);\n if (afterLetter || BARE_PUNCTUATION.test(ch)) return 'bare';\n return ch >= ' ' && ch <= '~' ? 'shown' : 'escaped';\n });\n}\n\n/**\n * Render an untrusted value — a filesystem path, identifier or command an\n * assembly chose, or a key a request supplied — into cdk-local's own prose\n * (go-to-k/cdk-local#758; the host's `displayAssemblyPath`, go-to-k/cdkd#3509).\n * The caller writes NO quotes around the result.\n *\n * `sanitizeServiceExceptionMessage` alone is not enough inside quotes of ours:\n * it flattens control characters and passes `'`, so a value carrying one\n * closed the quote and wrote a clause of its own into the message. This keeps\n * a plain value bare and puts any other one inside a JSON string literal.\n * Inside it, `\"` and `\\` are escaped as JSON escapes them, and so is every\n * character that is neither printable ASCII nor a visible letter — a curly or\n * fullwidth quote that could pass for the boundary's own closing `\"`, and a\n * blank that could pass for a space. The result stays valid JSON: `JSON.parse`\n * returns the sanitized value.\n *\n * A legitimate value with a space or any symbol outside `/ \\ . _ ~ + @ : = -`\n * (`/Users/me/My Project/cdk.out`) renders quoted; a non-ASCII letter is\n * shown as itself, and a non-letter non-ASCII character (an emoji, `©`) as\n * its `\\u` escape. A value the sanitizer ALTERED (a control character\n * flattened, an over-long value truncated) did not arrive plain, so it always\n * takes the boundary. The empty string renders as `\"\"`.\n *\n * The sanitizer also CAPS the value at 512 code points, so a longer path\n * prints truncated (inside the boundary, with its true length named). That\n * is deliberate: an unbounded assembly-chosen value would otherwise make the\n * log line as long as the attacker likes, and a real path is far shorter.\n */\nexport function displayUntrustedValue(value: string): string {\n const clean = sanitizeServiceExceptionMessage(value);\n // `Array.from` walks CODE POINTS, so a lone surrogate arrives alone and is\n // escaped rather than shown.\n const chars = Array.from(clean);\n const kinds = classify(chars);\n if (clean === value && chars.length > 0 && kinds.every((k) => k === 'bare')) return clean;\n let body = '';\n chars.forEach((ch, i) => {\n if (ch === '\"' || ch === '\\\\') body += `\\\\${ch}`;\n else if (kinds[i] !== 'escaped') body += ch;\n else {\n for (let u = 0; u < ch.length; u++) {\n body += `\\\\u${ch.charCodeAt(u).toString(16).padStart(4, '0')}`;\n }\n }\n });\n return `\"${body}\"`;\n}\n","import { spawn } from 'node:child_process';\nimport { spinner as createSpinner } from '@clack/prompts';\nimport { displayUntrustedValue } from './assembly-path.js';\nimport { getLogger } from './logger.js';\nimport { getEmbedConfig } from '../local/embed-config.js';\n\n/**\n * Shared helpers for invoking the docker-compatible CLI binary across cdk-local.\n *\n * Two parity decisions with `aws-cdk-cli`'s `cdk-assets-lib`:\n * 1. `CDK_DOCKER` env var swaps the binary so podman / finch users can\n * run cdk-local without code changes (`CDK_DOCKER=podman cdkl invoke`).\n * 2. `runDockerStreaming` uses streaming spawn rather than `execFile`'s\n * buffered `maxBuffer` ceiling. BuildKit's progress output can run to\n * tens of MB on multi-stage builds with `# syntax=docker/dockerfile:1`\n * frontend downloads + heredoc / `RUN --mount=...` features; the 50 MB\n * `execFile` ceiling cdk-local used to set silently killed those builds\n * with `ERR_CHILD_PROCESS_STDIO_MAXBUFFER`.\n *\n * Output handling: stdout/stderr are collected in memory unconditionally so\n * `runDockerStreaming` can return them to the caller for error wrapping.\n * When the logger is at debug level (i.e. the user passed `--verbose`),\n * the chunks are ALSO mirrored to `process.stdout` / `process.stderr` so\n * the user sees live build progress.\n */\n\n/**\n * Return the docker-compatible CLI binary to invoke. Matches CDK CLI:\n * `CDK_DOCKER` env var overrides the default `docker` so users on\n * podman / finch / nerdctl can swap without changing cdk-local code.\n */\nexport function getDockerCmd(): string {\n const override = process.env['CDK_DOCKER'];\n return override && override.length > 0 ? override : 'docker';\n}\n\n/**\n * Is the container client finch running its Lima VM (macOS / Windows)? There\n * the value-less `-e KEY` form (`appendEnvFlags` in `local/docker-runner.ts`)\n * does NOT keep a value off the process command line (issue #749): finch's\n * `handleEnv` resolves each bare `KEY` against its own environment and\n * re-emits `-e KEY=<value>` on the argv of the `limactl shell finch sudo -E\n * nerdctl ...` child it starts, and `--env-file` is read on the host and\n * re-emitted the same way (runfinch/finch `cmd/finch/nerdctl_remote.go`,\n * `handleEnv` / `handleEnvFile`). Its `passedEnvs` list also puts\n * `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN` from its\n * environment on that argv for every command. finch on Linux passes the argv\n * to nerdctl unchanged and is NOT matched.\n *\n * Detection is by the BASENAME of the resolved binary (`finch`, `finch.exe`,\n * any case): a wrapper script or a symlink under another name is not\n * recognised, and neither is Lima's own `nerdctl.lima`.\n */\nexport function isFinchVmClient(\n cmd: string = getDockerCmd(),\n platform: NodeJS.Platform = process.platform\n): boolean {\n if (platform !== 'darwin' && platform !== 'win32') return false;\n const base = (cmd.split(/[\\\\/]/).pop() ?? '').toLowerCase();\n return base === 'finch' || base === 'finch.exe';\n}\n\n/**\n * The env var that accepts, while it is set, that a container client puts\n * secret VALUES on a process command line ({@link finchSecretArgvRefusal}):\n * `<envPrefix>_ALLOW_SECRETS_ON_ARGV`, so `CDKL_ALLOW_SECRETS_ON_ARGV` for\n * `cdkl` and the embedding host's own prefix otherwise. Only `1` or `true`\n * (any case) opts in.\n */\nexport function allowSecretsOnArgvEnvName(): string {\n return `${getEmbedConfig().envPrefix}_ALLOW_SECRETS_ON_ARGV`;\n}\n\nfunction secretsOnArgvAllowed(): boolean {\n const v = process.env[allowSecretsOnArgvEnvName()];\n return v !== undefined && ['1', 'true'].includes(v.trim().toLowerCase());\n}\n\n// eslint-disable-next-line no-control-regex -- the control characters are exactly what is escaped.\nconst MESSAGE_UNSAFE_CHARS = /[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]/g;\n\n/**\n * Render template- or state-sourced text (an env var name, a container name,\n * an image URI) for a message: control and line-separator characters are\n * escaped as `\\uXXXX` so a hostile value cannot drive the terminal or forge a\n * log line. Plain text renders unchanged.\n */\nfunction escapeForMessage(text: string): string {\n return text.replace(\n MESSAGE_UNSAFE_CHARS,\n (c) => `\\\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`\n );\n}\n\n/**\n * The refusal text when template-sourced secrets (ECS `Secrets`, decrypted\n * `SecureString` values) would be forwarded under {@link isFinchVmClient}, or\n * `undefined` when they may be forwarded: another client, no such secret, or\n * {@link allowSecretsOnArgvEnvName} set. The caller throws it in its own error\n * class BEFORE any `docker run`. The AWS credential set is not refused here\n * but warned about by {@link warnFinchArgvExposure}: forwarding it is what puts\n * credentials that are not in this process's own environment (`--assume-role`,\n * `--profile`, the metadata sidecar's) on that argv, and the warning makes that\n * visible while keeping finch usable for containers that need AWS access. Names\n * only, never a value. `subject` is context such as the container name; it is\n * escaped like the names.\n */\nexport function finchSecretArgvRefusal(\n secretNames: readonly string[],\n subject: string\n): string | undefined {\n if (secretNames.length === 0 || !isFinchVmClient() || secretsOnArgvAllowed()) return undefined;\n const names = [...new Set(secretNames)];\n return (\n `${escapeForMessage(subject)}: refusing to forward secret(s) ${names.map(escapeForMessage).join(', ')} ` +\n `under CDK_DOCKER=finch on macOS / Windows. finch turns each value-less '-e KEY' into ` +\n `'-e KEY=<value>' on the command line of the limactl process it starts, where other local ` +\n `processes can read the plaintext. Use a container client that keeps the value off the command ` +\n `line (for example the default 'docker', by unsetting CDK_DOCKER), or set ` +\n `${allowSecretsOnArgvEnvName()}=1 to accept that exposure while it stays set.`\n );\n}\n\n/** Key sets already warned about by {@link warnFinchArgvExposure} in this process. */\nconst finchArgvWarned = new Set<string>();\n\n/** Test-only: forget which key sets {@link warnFinchArgvExposure} warned about. */\nexport function resetFinchArgvWarningsForTest(): void {\n finchArgvWarned.clear();\n}\n\n/**\n * Warn, once per process per distinct key set, that under\n * {@link isFinchVmClient} the values of `keys` (the sensitive env about to be\n * forwarded as value-less `-e KEY`) reach the `limactl` command line. Names\n * only, never a value.\n */\nexport function warnFinchArgvExposure(keys: readonly string[]): void {\n if (keys.length === 0 || !isFinchVmClient()) return;\n const names = [...new Set(keys)].sort();\n const latch = JSON.stringify(names);\n if (finchArgvWarned.has(latch)) return;\n finchArgvWarned.add(latch);\n getLogger().warn(\n `CDK_DOCKER=finch on macOS / Windows puts the values of ${names.map(escapeForMessage).join(', ')} ` +\n `on the command line of the limactl process it starts (finch turns a value-less '-e KEY' into ` +\n `'-e KEY=<value>'), where other local processes can read them. The default 'docker' client ` +\n `keeps them off the command line.`\n );\n}\n\nexport interface SpawnResult {\n stdout: string;\n stderr: string;\n}\n\nexport interface SpawnError extends Error {\n /** Captured stderr at the time of failure. */\n stderr: string;\n /** Captured stdout at the time of failure. */\n stdout: string;\n /** Process exit code (null when the process was killed by signal). */\n exitCode: number | null;\n}\n\nexport interface RunDockerOptions {\n /** Optional working directory for the subprocess. */\n cwd?: string;\n /**\n * Additional environment variables to set. Merged on top of `process.env`\n * (so the user's `DOCKER_BUILDKIT=1` and friends propagate through).\n */\n env?: Record<string, string | undefined>;\n /** When set, written to stdin (used by `docker login --password-stdin`). */\n input?: string;\n /**\n * When true, mirror stdout/stderr chunks to `process.stdout` / `process.stderr`\n * as they arrive. Useful for `docker pull` / `docker build` where live\n * progress is desirable. Defaults to \"true when the logger is at debug\n * level\" — matches the existing `--verbose` UX.\n */\n streamLive?: boolean;\n /**\n * When set, show an interactive {@link createSpinner | clack spinner}\n * with this label for the duration of the spawn — so a long-running\n * `docker build` / `docker pull` against a real-world image doesn't\n * look like cdk-local hung. The spinner only renders when:\n *\n * - `streamLive` is false (live BuildKit output already shows motion;\n * overlaying a spinner on top would visually clash and the line\n * overwriting would mangle the build log), AND\n * - `process.stdout` is a TTY (non-TTY callers such as integ-test\n * fixtures or CI runs already log linearly; a spinner there would\n * emit raw ANSI escapes into the captured log).\n *\n * In either skipped case the spawn proceeds as if `progressLabel` were\n * undefined — the caller's pre-spawn `logger.info(...)` \"Building X...\"\n * line continues to be the only progress signal, which is the\n * pre-spinner behavior and matches what scripts / CI expect.\n *\n * On exit code 0 the spinner stops with the same label and a check\n * mark; on non-zero exit it stops with an error mark before the\n * rejection propagates, so the caller's `try {} catch {}` wrap still\n * sees a clean spinner-less stderr.\n *\n * Concurrency: each `@clack/prompts` spinner instance registers its own\n * `SIGINT` / `SIGTERM` / `exit` / `uncaughtExceptionMonitor` /\n * `unhandledRejection` listeners against `process`. Callers must\n * serialize concurrent spinner-bearing `spawnStreaming` invocations on\n * the same `process.stdout` — two simultaneous spinners overwrite each\n * other's frame line AND accumulate listeners (Node trips its default\n * 10-listener warning at ~3 concurrent spinners). Every cdk-local call\n * site as of this PR is strictly sequential\n * (`runImageOverrideBuilds` for-of, `prepareImages` for-of, ECS\n * Lambda asset builds are one-per-invoke); the future parallel-build\n * path should either drop the label or memoize a single shared spinner.\n */\n progressLabel?: string;\n}\n\n/**\n * Spawn a docker-compatible CLI binary (resolved via `getDockerCmd`) with\n * streaming I/O. Collects stdout/stderr in memory and resolves with both\n * on exit code 0; rejects with a `SpawnError` carrying both streams on any\n * non-zero exit so the caller can wrap with its own error class without\n * losing the upstream output.\n *\n * No `maxBuffer` ceiling: BuildKit progress output frequently exceeds the\n * `child_process.execFile` default of 1 MB (cdk-local previously bumped to 50 MB\n * but BuildKit + frontend pulls can still exceed that on first-time builds).\n */\nexport async function runDockerStreaming(\n args: string[],\n options: RunDockerOptions = {}\n): Promise<SpawnResult> {\n return spawnStreaming(getDockerCmd(), args, options);\n}\n\n/**\n * Generic streaming spawn — used by `runDockerStreaming` AND by the\n * `executable` source mode in `docker-build.ts` (which runs an arbitrary\n * user-supplied build command, not docker).\n */\nexport async function spawnStreaming(\n cmd: string,\n args: string[],\n options: RunDockerOptions = {}\n): Promise<SpawnResult> {\n const streamLive = options.streamLive ?? getLogger().getLevel() === 'debug';\n const env = options.env ? mergeEnv(options.env) : undefined;\n const spin = startProgressSpinner(options.progressLabel, streamLive);\n\n return new Promise<SpawnResult>((resolve, reject) => {\n // Defensive: a synchronous throw from `spawn` (e.g. Node's\n // `ERR_INVALID_ARG_TYPE` on a non-string `cmd`) bypasses the close /\n // error handlers below — without this try/catch the spinner would be\n // left animating until process exit. Today unreachable\n // (`getDockerCmd()` always returns a string + all call-site `args`\n // are `string[]`), but the wrap is free defense-in-depth on a\n // process-launch helper.\n let child;\n try {\n child = spawn(cmd, args, {\n cwd: options.cwd,\n env,\n stdio: [options.input ? 'pipe' : 'ignore', 'pipe', 'pipe'],\n });\n } catch (err) {\n stopProgressSpinner(spin, options.progressLabel);\n reject(err as Error);\n return;\n }\n\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n child.stdout!.on('data', (chunk: Buffer) => {\n stdoutChunks.push(chunk);\n if (streamLive) process.stdout.write(chunk);\n });\n child.stderr!.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n if (streamLive) process.stderr.write(chunk);\n });\n\n child.once('error', (err: NodeJS.ErrnoException) => {\n stopProgressSpinner(spin, options.progressLabel);\n if (err.code === 'ENOENT') {\n const usingOverride = process.env['CDK_DOCKER'] === cmd && cmd !== 'docker';\n const shownCmd = displayUntrustedValue(cmd);\n reject(\n new Error(\n usingOverride\n ? `Failed to find and execute ${shownCmd} (resolved via CDK_DOCKER). ` +\n `Install ${shownCmd} or unset CDK_DOCKER to fall back to 'docker'.`\n : `Failed to find and execute ${shownCmd}. Install Docker (or set the ` +\n `'CDK_DOCKER' environment variable to a compatible binary such as podman / finch).`\n )\n );\n } else {\n // Node's own message is `spawn <cmd> <CODE>` with the command RAW, and\n // `cmd` is an asset's `source.executable[0]` when docker-build.ts runs\n // one (go-to-k/cdk-local#764). No `cause`: the error handler prints a\n // cause's message, which would carry the raw command back in.\n const wrapped = new Error(\n `Failed to execute ${displayUntrustedValue(cmd)} (${err.code ?? 'spawn error'})`\n ) as NodeJS.ErrnoException;\n if (err.code !== undefined) wrapped.code = err.code;\n reject(wrapped);\n }\n });\n\n child.once('close', (code) => {\n const stdout = Buffer.concat(stdoutChunks).toString('utf-8');\n const stderr = Buffer.concat(stderrChunks).toString('utf-8');\n if (code === 0) {\n stopProgressSpinner(spin, options.progressLabel);\n resolve({ stdout, stderr });\n } else {\n stopProgressSpinner(spin, options.progressLabel);\n // `cmd` is an asset's `source.executable[0]` when docker-build.ts runs\n // one, so it renders display-safe (go-to-k/cdk-local#764). Its\n // ARGUMENTS stay out: a build script's own `--token=...` matches no\n // argv masker, and the full argv is a `--verbose` detail (see\n // `warnManifestExecutable`).\n const message =\n stderr.trim() ||\n stdout.trim() ||\n `${displayUntrustedValue(cmd)} exited with code ${code}`;\n const err = new Error(message) as SpawnError;\n err.stderr = stderr;\n err.stdout = stdout;\n err.exitCode = code;\n reject(err);\n }\n });\n\n if (options.input !== undefined) {\n // Defensive: when spawn() fails (e.g. ENOENT race), the synchronous\n // write below could emit a stream 'error' event before the close /\n // error handlers above fire. Without a listener, Node escalates that\n // to \"Unhandled 'error' event\" on some versions. cdk-local's only `input`\n // call site is `docker login --password-stdin` with short payloads\n // that complete well within the syscall, so this is unlikely to fire\n // in practice — but the no-op listener is free.\n child.stdin!.on('error', () => {\n /* surfaced via the outer error/close handlers above */\n });\n child.stdin!.write(options.input);\n child.stdin!.end();\n }\n });\n}\n\ntype ClackSpinner = ReturnType<typeof createSpinner>;\n\n/**\n * Start an interactive clack spinner for the spawn, but only when the\n * current shell would actually render it (TTY) and the caller isn't\n * already streaming live output. Returns `undefined` when either\n * precondition fails — `stopProgressSpinner` then is a no-op.\n *\n * Test seam: the integration with `@clack/prompts` is mocked in\n * `tests/unit/utils/docker-cmd-progress-spinner.test.ts`.\n */\nfunction startProgressSpinner(\n label: string | undefined,\n streamLive: boolean\n): ClackSpinner | undefined {\n if (label === undefined || streamLive || process.stdout.isTTY !== true) return undefined;\n const spin = createSpinner();\n spin.start(label);\n return spin;\n}\n\nfunction stopProgressSpinner(spin: ClackSpinner | undefined, label: string | undefined): void {\n // `@clack/prompts`' `spinner().stop(message?)` only takes the message at\n // the TS-level signature (the runtime impl ignores the optional `code`\n // second arg, hard-coding success), so we mirror its public API. The\n // upstream caller's wrapped error / rejection still surfaces the\n // failure detail; the spinner's only job here is to stop animating\n // cleanly so the error stderr renders on its own fresh line.\n if (spin === undefined) return;\n spin.stop(label ?? '');\n}\n\n/**\n * Spawn a docker-compatible CLI binary (resolved via `getDockerCmd`) attached\n * to the parent process's stdio so the user sees live output (`docker pull`\n * layer progress, `docker login` interactive prompts that should never fire\n * with `--password-stdin` but still safe to inherit, etc.). Resolves on exit\n * code 0; rejects with a plain `Error` carrying the exit code on any non-zero\n * exit, so the caller can wrap with its own error class.\n *\n * Differs from {@link runDockerStreaming} in two ways:\n * 1. `stdio: 'inherit'` — output is NOT captured, so terminal control codes\n * (color, progress bar overwrites) flow through unchanged. This is the\n * load-bearing reason for the split: `docker pull`'s progress bars only\n * animate properly when stdout is a real TTY connected to the parent.\n * 2. No `input` / `streamLive` options — inherit-mode has nothing to\n * capture and nothing to mirror.\n *\n * Used by the `--verbose`-mode `docker pull` plumbing in `docker-runner.ts`\n * and `ecr-puller.ts` (visible layer progress). Non-verbose pulls go through\n * {@link runDockerStreaming} so stderr can be folded into the error message.\n */\nexport async function runDockerForeground(\n args: string[],\n options: ForegroundOptions = {}\n): Promise<void> {\n return spawnForeground(getDockerCmd(), args, options);\n}\n\nexport interface ForegroundOptions {\n /** Optional working directory for the subprocess. */\n cwd?: string;\n /**\n * Additional environment variables to set. Merged on top of `process.env`\n * (same semantics as {@link RunDockerOptions.env}).\n */\n env?: Record<string, string | undefined>;\n}\n\n/**\n * Foreground (stdio-inherit) spawn — the inherit-mode counterpart to\n * {@link spawnStreaming}. Used by {@link runDockerForeground} for docker-CLI\n * subprocesses.\n *\n * The ENOENT branch crafts a docker-specific install hint (\"Install Docker\n * (or set CDK_DOCKER ...)\"), so non-docker callers reusing this helper\n * would see a misleading error on missing-binary failures. Keep the binary\n * docker-shaped, or update the ENOENT message before adding a non-docker\n * call site.\n */\nexport async function spawnForeground(\n cmd: string,\n args: string[],\n options: ForegroundOptions = {}\n): Promise<void> {\n const env = options.env ? mergeEnv(options.env) : undefined;\n return new Promise<void>((resolve, reject) => {\n const child = spawn(cmd, args, {\n cwd: options.cwd,\n env,\n stdio: 'inherit',\n });\n child.once('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'ENOENT') {\n const usingOverride = process.env['CDK_DOCKER'] === cmd && cmd !== 'docker';\n const shownCmd = displayUntrustedValue(cmd);\n reject(\n new Error(\n usingOverride\n ? `Failed to find and execute ${shownCmd} (resolved via CDK_DOCKER). ` +\n `Install ${shownCmd} or unset CDK_DOCKER to fall back to 'docker'.`\n : `Failed to find and execute ${shownCmd}. Install Docker (or set the ` +\n `'CDK_DOCKER' environment variable to a compatible binary such as podman / finch).`\n )\n );\n } else {\n reject(new Error(`${cmd} failed: ${err.message}`));\n }\n });\n child.once('close', (code) => {\n if (code === 0) {\n resolve();\n } else {\n reject(new Error(`${cmd} exited with code ${code}`));\n }\n });\n });\n}\n\n/**\n * Format the stderr from a failed `docker login` so the surfaced cdk-local\n * error gives the user an actionable workaround when the underlying\n * failure is a credential-helper persistence bug (which has nothing to\n * do with cdk-local, AWS, or IAM perms — the docker CLI itself fails to\n * save the auth token to the platform's credential store). The most\n * common shape is `osxkeychain` on macOS rejecting an overwrite for\n * an existing entry, but `wincred` (Windows), `pass` (Linux), and\n * `secretservice` (Linux) hit the same class of `Error saving\n * credentials` failure, so the rewritten message stays platform-\n * agnostic — `docker logout <endpoint>` is the correct recovery on\n * every backend.\n *\n * Detected docker / docker-credential-* output patterns:\n * - `error storing credentials - err: exit status 1, out: \\`The\n * specified item already exists in the keychain.\\`` (osxkeychain)\n * - `Error saving credentials: ...` (any backend)\n *\n * Non-matching failures (genuine IAM / network / endpoint problems)\n * pass through with just the stderr trimmed — the original message\n * stays load-bearing for diagnosis.\n */\nexport function formatDockerLoginError(stderr: string, endpoint: string): string {\n const trimmed = stderr.trim();\n const isCredentialHelperFailure =\n trimmed.includes('already exists in the keychain') ||\n trimmed.includes('Error saving credentials');\n if (isCredentialHelperFailure) {\n return (\n `docker's credential helper (osxkeychain on macOS / wincred on Windows / pass / secretservice on Linux) ` +\n `failed to persist the ECR auth token. The \"already exists in the keychain\" / \"Error saving credentials\" ` +\n `output is a known docker-credential-helpers issue — unrelated to ${getEmbedConfig().productName}, AWS credentials, or IAM perms. ` +\n `Quick fix: run \\`docker logout ${endpoint}\\` to clear the stale entry, then retry the ${getEmbedConfig().productName} command. ` +\n `Permanent fix: edit ~/.docker/config.json and remove (or empty) the platform-specific \"credsStore\" entry ` +\n `(e.g. \"osxkeychain\" → \"\" or \"desktop\" on macOS Docker Desktop). ` +\n `Original docker stderr: ${trimmed}`\n );\n }\n return trimmed;\n}\n\nfunction mergeEnv(overrides: Record<string, string | undefined>): NodeJS.ProcessEnv {\n const merged: NodeJS.ProcessEnv = { ...process.env };\n for (const [k, v] of Object.entries(overrides)) {\n if (v === undefined) {\n delete merged[k];\n } else {\n merged[k] = v;\n }\n }\n return merged;\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { $r as resolveCfnStackName, D as createLocalStartAgentCoreCommand, F as createLocalStartCloudFrontCommand, Gr as substituteEnvVarsFromState, Jr as createLocalStateProvider, Kr as substituteEnvVarsFromStateAsync, Mn as createLocalInvokeCommand, Ot as createLocalStartServiceCommand, Pn as createLocalStartApiCommand, Qr as resolveCfnRegion, St as createLocalStartAlbCommand, T as formatTargetListing, Ur as substituteAgainstState, Wr as substituteAgainstStateAsync, Xr as rejectExplicitCfnStackWithMultipleStacks, Yr as isCfnFlagPresent, Zr as resolveCfnFallbackRegion, a as createLocalStudioCommand, ai as countTargets, ei as CfnLocalStateProvider, jt as createLocalRunTaskCommand, ni as resolveSsmParameters, oi as listTargets, qr as LocalStateSourceError, sn as createLocalInvokeAgentCoreCommand, ti as collectSsmParameterRefs, w as createLocalListCommand } from "./local-studio-
|
|
1
|
+
import { E as setEmbedConfig, T as resetEmbedConfig, w as getEmbedConfig } from "./docker-cmd-B5yU__zC.js";
|
|
2
|
+
import { $r as resolveCfnStackName, D as createLocalStartAgentCoreCommand, F as createLocalStartCloudFrontCommand, Gr as substituteEnvVarsFromState, Jr as createLocalStateProvider, Kr as substituteEnvVarsFromStateAsync, Mn as createLocalInvokeCommand, Ot as createLocalStartServiceCommand, Pn as createLocalStartApiCommand, Qr as resolveCfnRegion, St as createLocalStartAlbCommand, T as formatTargetListing, Ur as substituteAgainstState, Wr as substituteAgainstStateAsync, Xr as rejectExplicitCfnStackWithMultipleStacks, Yr as isCfnFlagPresent, Zr as resolveCfnFallbackRegion, a as createLocalStudioCommand, ai as countTargets, ei as CfnLocalStateProvider, jt as createLocalRunTaskCommand, ni as resolveSsmParameters, oi as listTargets, qr as LocalStateSourceError, sn as createLocalInvokeAgentCoreCommand, ti as collectSsmParameterRefs, w as createLocalListCommand } from "./local-studio-CV21zLBM.js";
|
|
3
3
|
|
|
4
4
|
export { CfnLocalStateProvider, LocalStateSourceError, collectSsmParameterRefs, countTargets, createLocalInvokeAgentCoreCommand, createLocalInvokeCommand, createLocalListCommand, createLocalRunTaskCommand, createLocalStartAgentCoreCommand, createLocalStartAlbCommand, createLocalStartApiCommand, createLocalStartCloudFrontCommand, createLocalStartServiceCommand, createLocalStateProvider, createLocalStudioCommand, formatTargetListing, getEmbedConfig, isCfnFlagPresent, listTargets, rejectExplicitCfnStackWithMultipleStacks, resetEmbedConfig, resolveCfnFallbackRegion, resolveCfnRegion, resolveCfnStackName, resolveSsmParameters, setEmbedConfig, substituteAgainstState, substituteAgainstStateAsync, substituteEnvVarsFromState, substituteEnvVarsFromStateAsync };
|
package/dist/internal.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _ as describeCredentialLoadFailure, g as describeAwsFailureForWarn } from "./docker-cmd-B5yU__zC.js";
|
|
2
|
+
import { $ as applyEdgeResponseResult, $n as buildJwksUrlFromIssuer, $t as buildCloudMapIndex, A as startAgentCoreHttpServer, Ai as resolveProfileCredentials, An as classifySourceChange, Ar as ConnectionRegistry, At as addRunTaskSpecificOptions, B as idFromArn, Bn as buildStageMap, Br as resolveRuntimeFileExtension, Bt as resolveEcsAssumeRoleOption, C as addListSpecificOptions, Ci as resolveAgentCoreTarget, Cn as waitForAgentCorePing, Cr as tryParseStatus, Ct as parseLbPortOverrides, Di as tryResolveImageFnJoin, Dn as computeCodeImageTag, Dr as probeHostGatewaySupport, Dt as addStartServiceSpecificOptions, E as addStartAgentCoreSpecificOptions, Ei as substituteImagePlaceholders, En as buildAgentCoreCodeImage, Er as HOST_GATEWAY_MIN_VERSION, Et as resolveAlbFrontDoor, Fn as createWatchPredicates, Fr as buildDisconnectEvent, Ft as addImageOverrideOptions, G as classifyS3Error, Gn as filterRoutesByApiIdentifiers, Gt as enforceImageOverrideOrphans, H as createDeployedKvsDataSource, Hn as resolveEnvVars, Hr as EcsTaskResolutionError, Ht as runEcsServiceEmulator, I as normalizeKvsFileKeys, In as resolveApiTargetSubset, Ir as buildMessageEvent, It as buildEcsImageResolutionContext, J as startCloudFrontServer, Jn as startApiServer, Jt as resolveImageOverrides, K as createS3OriginReader, Kn as groupRoutesByServer, Kt as mergeForService, L as parseKvsFileOverrides, Ln as createAuthorizerCache, Lr as architectureToPlatform, Lt as ecsClusterOption, M as startAgentCoreWsBridge, Mi as isProxyEnvConfigured, Mr as handleConnectionsRequest, Mt as MAX_TASKS_SUBNET_RANGE_CAP, N as LocalStartCloudFrontError, Nn as addStartApiSpecificOptions, Nr as parseConnectionsPath, Nt as addCommonEcsServiceOptions, O as buildAgentCoreServeAuthCheck, Oi as LocalInvokeBuildError, On as renderCodeDockerfile, Or as resolveHostGatewayExtraHosts, P as addStartCloudFrontSpecificOptions, Pr as buildConnectEvent, Pt as addEcsAssumeRoleOptions, Q as applyEdgeRequestResult, Qn as buildCognitoJwksUrl, Qt as listPinnedTargets, R as parseOriginOverrides, Rn as createFileWatcher, Rr as buildContainerImage, Rt as parseMaxTasks, S as StudioEventBus, Si as pickAgentCoreCandidateStack, Sn as waitForAgentCoreHttpReady, Sr as selectIntegrationResponse, Ti as formatStateRemedy, Tn as SUPPORTED_CODE_RUNTIMES, Tr as HOST_DOCKER_INTERNAL_GATEWAY, Tt as isApplicationLoadBalancer, U as resolveDeployedKvsArnByName, Un as availableApiIdentifiers, Ut as ImageOverrideError, V as resolveKvsModulesForDistribution, Vn as materializeLayerFromArn, Vr as resolveRuntimeImage, Vt as resolveSharedSidecarCredentials, W as resolveDeployedOriginBucket, Wn as filterRoutesByApiIdentifier, Wt as buildImageOverrideTag, X as serveFromStaticOrigin, Xn as resolveServiceIntegrationParameters, Xt as describePinnedImageUri, Y as resolveErrorResponseCandidates, Yn as resolveSelectionExpression, Yt as runImageOverrideBuilds, Z as serveLambdaUrlOrigin, Zn as defaultCredentialsLoader, Zt as isLocalCdkAssetImage, _ as filterStudioTargetGroups, _i as AGENTCORE_AGUI_PROTOCOL, _n as parseSseForJsonRpc, _r as applyAuthorizerOverlay, _t as createCloudFrontModule, an as attachContainerLogStreamer, ar as computeRequestIdentityHash, at as describeS3OriginDomain, b as renderStudioHtml, bi as AGENTCORE_RUNTIME_TYPE, bn as AGENTCORE_SESSION_ID_HEADER, br as evaluateResponseParameters, bt as addAlbSpecificOptions, c as startStudioProxy, ci as discoverWebSocketApis, cn as bridgeAgentCoreWs, cr as invokeTokenAuthorizer, ct as pickFunctionUrlLogicalIdFromOrigin, d as createStudioDispatcher, di as parseSelectionExpressionPath, dn as A2A_PATH, dr as buildCorsConfigByApiId, dt as pickTargetFunctionLogicalId, en as CloudMapRegistry, er as createJwksCache, et as buildEdgeRequestEvent, f as filterStudioCustomResources, fi as webSocketApiMatchesIdentifier, fn as a2aInvokeOnce, fr as buildCorsConfigFromCloudFrontChain, ft as resolveCloudFrontDistribution, g as annotatePinnedEcsTargets, gi as AGENTCORE_A2A_PROTOCOL, gn as mcpInvokeOnce, gr as translateLambdaResponse, gt as stripCloudFrontImport, h as annotateEcsTaskPinnedTargets, hi as resolveLambdaArnIntrinsic, hn as MCP_PROTOCOL_VERSION, hr as matchRoute, ht as runViewerResponse, i as coerceStopRequest, ii as resolveSingleTarget, in as getContainerNetworkIp, ir as buildMethodArn, it as CLOUDFRONT_DISTRIBUTION_TYPE, j as attachAgentCoreWsBridge, ji as buildProxyClientConfig, jn as addInvokeSpecificOptions, jr as buildMgmtEndpointEnvUrl, k as selectServeInboundAuth, ki as buildStsClientConfig, kn as toCmdArgv, kr as bufferToBody, kt as serviceStrategy, l as relayServeRequest, li as discoverWebSocketApisOrThrow, ln as invokeAgentCoreWs, lr as attachAuthorizers, lt as pickKvsLogicalIdFromArn, m as annotateAlbPinnedBackingServices, mi as pickRefLogicalId, mn as MCP_PATH, mr as matchPreflight, mt as runViewerRequest, n as coerceRunRequest, nn as SOFT_RELOAD_COMPLETION_LOG_SUFFIX, nr as verifyJwtAuthorizer, nt as edgeHeadersToHttp, o as resolveServeBaseUrl, on as addInvokeAgentCoreSpecificOptions, or as evaluateCachedLambdaPolicy, ot as extractKvsAssociations, p as isCustomResourceLambdaTarget, pi as discoverRoutes, pn as MCP_CONTAINER_PORT, pr as isFunctionUrlOacFronted, pt as compileCloudFrontFunction, q as matchBehavior, qn as readMtlsMaterialsFromDisk, qt as parseImageOverrideFlags, r as coerceServeRequest, ri as resolveWatchConfig, rn as setShadowReadyTimeoutMs, rr as verifyJwtViaDiscovery, rt as httpHeadersToEdge, s as createStudioServeManager, si as availableWebSocketApiIdentifiers, sr as invokeRequestAuthorizer, st as isCloudFrontDistribution, t as addStudioSpecificOptions, tn as DEFAULT_SHADOW_READY_TIMEOUT_MS, tr as verifyCognitoJwt, tt as buildEdgeResponseEvent, u as reinvoke, ui as filterWebSocketApisByIdentifiers, un as A2A_CONTAINER_PORT, ur as applyCorsResponseHeaders, ut as pickLambdaEdgeFunctionLogicalId, v as startStudioServer, vi as AGENTCORE_HTTP_PROTOCOL, vn as AGENTCORE_SIGV4_SERVICE, vr as buildHttpApiV2Event, vt as createLocalFileKvsDataSource, wi as derivePseudoParametersFromRegion, wn as downloadAndExtractS3Bundle, wr as VtlEvaluationError, wt as resolveAlbTarget, x as createStudioStore, xi as AgentCoreResolutionError, xn as invokeAgentCore, xr as pickResponseTemplate, xt as albStrategy, y as toStudioTargetGroups, yi as AGENTCORE_MCP_PROTOCOL, yn as signAgentCoreInvocation, yr as buildRestV1Event, yt as createUnboundCloudFrontModule, z as resolveCloudFrontTarget, zn as attachStageContext, zr as resolveRuntimeCodeMountPath, zt as parseRestartPolicy } from "./local-studio-CV21zLBM.js";
|
|
2
3
|
|
|
3
4
|
export { A2A_CONTAINER_PORT, A2A_PATH, AGENTCORE_A2A_PROTOCOL, AGENTCORE_AGUI_PROTOCOL, AGENTCORE_HTTP_PROTOCOL, AGENTCORE_MCP_PROTOCOL, AGENTCORE_RUNTIME_TYPE, AGENTCORE_SESSION_ID_HEADER, AGENTCORE_SIGV4_SERVICE, AgentCoreResolutionError, CLOUDFRONT_DISTRIBUTION_TYPE, CloudMapRegistry, ConnectionRegistry, DEFAULT_SHADOW_READY_TIMEOUT_MS, EcsTaskResolutionError, HOST_DOCKER_INTERNAL_GATEWAY, HOST_GATEWAY_MIN_VERSION, ImageOverrideError, LocalInvokeBuildError, LocalStartCloudFrontError, MAX_TASKS_SUBNET_RANGE_CAP, MCP_CONTAINER_PORT, MCP_PATH, MCP_PROTOCOL_VERSION, SOFT_RELOAD_COMPLETION_LOG_SUFFIX, SUPPORTED_CODE_RUNTIMES, StudioEventBus, VtlEvaluationError, a2aInvokeOnce, addAlbSpecificOptions, addCommonEcsServiceOptions, addEcsAssumeRoleOptions, addImageOverrideOptions, addInvokeAgentCoreSpecificOptions, addInvokeSpecificOptions, addListSpecificOptions, addRunTaskSpecificOptions, addStartAgentCoreSpecificOptions, addStartApiSpecificOptions, addStartCloudFrontSpecificOptions, addStartServiceSpecificOptions, addStudioSpecificOptions, albStrategy, annotateAlbPinnedBackingServices, annotateEcsTaskPinnedTargets, annotatePinnedEcsTargets, applyAuthorizerOverlay, applyCorsResponseHeaders, applyEdgeRequestResult, applyEdgeResponseResult, architectureToPlatform, attachAgentCoreWsBridge, attachAuthorizers, attachContainerLogStreamer, attachStageContext, availableApiIdentifiers, availableWebSocketApiIdentifiers, bridgeAgentCoreWs, bufferToBody, buildAgentCoreCodeImage, buildAgentCoreServeAuthCheck, buildCloudMapIndex, buildCognitoJwksUrl, buildConnectEvent, buildContainerImage, buildCorsConfigByApiId, buildCorsConfigFromCloudFrontChain, buildDisconnectEvent, buildEcsImageResolutionContext, buildEdgeRequestEvent, buildEdgeResponseEvent, buildHttpApiV2Event, buildImageOverrideTag, buildJwksUrlFromIssuer, buildMessageEvent, buildMethodArn, buildMgmtEndpointEnvUrl, buildProxyClientConfig, buildRestV1Event, buildStageMap, buildStsClientConfig, classifyS3Error, classifySourceChange, coerceRunRequest, coerceServeRequest, coerceStopRequest, compileCloudFrontFunction, computeCodeImageTag, computeRequestIdentityHash, createAuthorizerCache, createCloudFrontModule, createDeployedKvsDataSource, createFileWatcher, createJwksCache, createLocalFileKvsDataSource, createS3OriginReader, createStudioDispatcher, createStudioServeManager, createStudioStore, createUnboundCloudFrontModule, createWatchPredicates, defaultCredentialsLoader, derivePseudoParametersFromRegion, describeAwsFailureForWarn, describeCredentialLoadFailure, describePinnedImageUri, describeS3OriginDomain, discoverRoutes, discoverWebSocketApis, discoverWebSocketApisOrThrow, downloadAndExtractS3Bundle, ecsClusterOption, edgeHeadersToHttp, enforceImageOverrideOrphans, evaluateCachedLambdaPolicy, evaluateResponseParameters, extractKvsAssociations, filterRoutesByApiIdentifier, filterRoutesByApiIdentifiers, filterStudioCustomResources, filterStudioTargetGroups, filterWebSocketApisByIdentifiers, formatStateRemedy, getContainerNetworkIp, groupRoutesByServer, handleConnectionsRequest, httpHeadersToEdge, idFromArn, invokeAgentCore, invokeAgentCoreWs, invokeRequestAuthorizer, invokeTokenAuthorizer, isApplicationLoadBalancer, isCloudFrontDistribution, isCustomResourceLambdaTarget, isFunctionUrlOacFronted, isLocalCdkAssetImage, isProxyEnvConfigured, listPinnedTargets, matchBehavior, matchPreflight, matchRoute, materializeLayerFromArn, mcpInvokeOnce, mergeForService, normalizeKvsFileKeys, parseConnectionsPath, parseImageOverrideFlags, parseKvsFileOverrides, parseLbPortOverrides, parseMaxTasks, parseOriginOverrides, parseRestartPolicy, parseSelectionExpressionPath, parseSseForJsonRpc, pickAgentCoreCandidateStack, pickFunctionUrlLogicalIdFromOrigin, pickKvsLogicalIdFromArn, pickLambdaEdgeFunctionLogicalId, pickRefLogicalId, pickResponseTemplate, pickTargetFunctionLogicalId, probeHostGatewaySupport, readMtlsMaterialsFromDisk, reinvoke, relayServeRequest, renderCodeDockerfile, renderStudioHtml, resolveAgentCoreTarget, resolveAlbFrontDoor, resolveAlbTarget, resolveApiTargetSubset, resolveCloudFrontDistribution, resolveCloudFrontTarget, resolveDeployedKvsArnByName, resolveDeployedOriginBucket, resolveEcsAssumeRoleOption, resolveEnvVars, resolveErrorResponseCandidates, resolveHostGatewayExtraHosts, resolveImageOverrides, resolveKvsModulesForDistribution, resolveLambdaArnIntrinsic, resolveProfileCredentials, resolveRuntimeCodeMountPath, resolveRuntimeFileExtension, resolveRuntimeImage, resolveSelectionExpression, resolveServeBaseUrl, resolveServiceIntegrationParameters, resolveSharedSidecarCredentials, resolveSingleTarget, resolveWatchConfig, runEcsServiceEmulator, runImageOverrideBuilds, runViewerRequest, runViewerResponse, selectIntegrationResponse, selectServeInboundAuth, serveFromStaticOrigin, serveLambdaUrlOrigin, serviceStrategy, setShadowReadyTimeoutMs, signAgentCoreInvocation, startAgentCoreHttpServer, startAgentCoreWsBridge, startApiServer, startCloudFrontServer, startStudioProxy, startStudioServer, stripCloudFrontImport, substituteImagePlaceholders, toCmdArgv, toStudioTargetGroups, translateLambdaResponse, tryParseStatus, tryResolveImageFnJoin, verifyCognitoJwt, verifyJwtAuthorizer, verifyJwtViaDiscovery, waitForAgentCoreHttpReady, waitForAgentCorePing, webSocketApiMatchesIdentifier };
|