cdk-local 0.69.0 → 0.71.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -2
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +27 -41
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-list-l2_7oGHF.js → local-list-B67vK97a.js} +354 -46
- package/dist/local-list-B67vK97a.js.map +1 -0
- package/dist/{local-list-9jAE7ClA.d.ts → local-list-Czcuil71.d.ts} +23 -2
- package/dist/local-list-Czcuil71.d.ts.map +1 -0
- package/package.json +1 -1
- package/dist/local-list-9jAE7ClA.d.ts.map +0 -1
- package/dist/local-list-l2_7oGHF.js.map +0 -1
|
@@ -19182,6 +19182,143 @@ function addInvokeAgentCoreSpecificOptions(cmd) {
|
|
|
19182
19182
|
return cmd.addOption(new Option("-e, --event <file>", "JSON event payload file (default: {})")).addOption(new Option("--event-stdin", "Read event JSON from stdin").default(false)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"LogicalId\":{\"KEY\":\"VALUE\"}})")).addOption(new Option("--session-id <id>", "AgentCore runtime session id header value (default: a random UUID)")).addOption(new Option("--ws", "Stream over the HTTP-protocol agent's bidirectional /ws WebSocket endpoint (on 8080) instead of POST /invocations: send --event as the first frame and print every received frame to stdout until the agent closes. Ignored for an MCP runtime.").default(false)).addOption(new Option("--ws-interactive", "REPL mode for --ws: after the initial --event frame, read additional frames from stdin (one frame per line, trailing newline stripped) and send each as a text frame until stdin EOFs (Ctrl-D) or the agent closes. Only meaningful with --ws.").default(false)).addOption(new Option("--bearer-token <jwt>", "Bearer JWT to present when the runtime declares a customJwtAuthorizer. Verified against the runtime OIDC discovery URL (signature / issuer / expiry / audience) before the container starts, then forwarded to /invocations as Authorization: Bearer <jwt>.")).addOption(new Option("--no-verify-auth", "Skip inbound JWT verification even when the runtime declares a customJwtAuthorizer (local-dev escape hatch). A --bearer-token, if given, is still forwarded.")).addOption(new Option("--sigv4", "Sign the /invocations POST with AWS SigV4 (service bedrock-agentcore) using the resolved credentials, matching the cloud default when the runtime declares no customJwtAuthorizer. Opt-in: default unsigned. Mutually exclusive with --bearer-token; ignored on a JWT-protected runtime.").default(false)).addOption(new Option("--platform <platform>", "docker --platform for the agent container (linux/amd64 or linux/arm64)").choices(["linux/amd64", "linux/arm64"]).default("linux/arm64")).addOption(new Option("--no-pull", "Skip docker pull (use cached image) — no-op for the local-build path")).addOption(new Option("--no-build", "Skip docker build on the local-asset path (use the previously-built tag). No-op for the ECR / registry pull paths.")).addOption(new Option("--container-host <host>", "Host to bind the agent port to").default("127.0.0.1")).addOption(new Option("--timeout <ms>", "Per-request timeout in milliseconds. Applied to POST /invocations, POST /mcp, and the /ws open-to-close window. Raise this for long-running agent calls that exceed the default.").default(12e4).argParser(parseTimeoutMs)).addOption(new Option("--assume-role [arn]", "Assume the runtime's execution role and forward STS-issued temp credentials to the container so the agent runs with the deployed role. Three forms: (1) `--assume-role <arn>` assumes the explicit ARN; (2) `--assume-role` (bare) uses the runtime's RoleArn when it is a literal ARN; (3) `--no-assume-role` opts out. Off by default — the developer's shell credentials are forwarded unchanged.")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries. Same-account / same-region pulls do not need this flag.")).addOption(new Option("--from-cfn-stack [cfn-stack-name]", "Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in env vars with the deployed physical IDs / exports. Bare form uses the resolved stack name; pass an explicit value when the CFn stack name differs.")).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
19183
19183
|
}
|
|
19184
19184
|
|
|
19185
|
+
//#endregion
|
|
19186
|
+
//#region src/local/container-log-streamer.ts
|
|
19187
|
+
/**
|
|
19188
|
+
* Spawn `docker logs -f <containerId>` and pipe its stdout / stderr to
|
|
19189
|
+
* the host's `process.stdout` / `process.stderr`, prefixing every emitted
|
|
19190
|
+
* line with the caller-supplied `prefix`. Returns a stop function that
|
|
19191
|
+
* drains any unterminated tail line and SIGTERMs the streamer process —
|
|
19192
|
+
* idempotent + safe to call from a `finally` or shutdown handler.
|
|
19193
|
+
*
|
|
19194
|
+
* Used by `cdkl run-task` (per-container prefix `[<container-name>]`) and
|
|
19195
|
+
* by `cdkl start-service` / `cdkl start-alb` (per-replica prefix
|
|
19196
|
+
* `[svc=<service> r=<i> c=<container>]`) so application `console.log`
|
|
19197
|
+
* output inside a replica is visible in the foreground terminal without
|
|
19198
|
+
* having to attach `docker logs -f` in a separate shell. The prefix shape
|
|
19199
|
+
* is the caller's concern: this helper only cares about line-buffered
|
|
19200
|
+
* pass-through.
|
|
19201
|
+
*
|
|
19202
|
+
* **Auto re-attach on `docker restart`** (Issue #227 + #214 soft-reload):
|
|
19203
|
+
* the docker daemon terminates `docker logs -f` when the container's
|
|
19204
|
+
* PID 1 exits — so a `docker restart` (the soft-reload primitive) ends
|
|
19205
|
+
* the follow stream even though the container ID is preserved across the
|
|
19206
|
+
* restart. The streamer detects an unsolicited child-exit and re-spawns
|
|
19207
|
+
* `docker logs -f` with `--since 0s` so only NEW output (from the
|
|
19208
|
+
* post-restart PID-1) is forwarded; the v1 prelude is not re-emitted.
|
|
19209
|
+
* `stop()` flips an internal "stopping" flag so the re-attach loop sees
|
|
19210
|
+
* the intentional teardown and does not respawn.
|
|
19211
|
+
*
|
|
19212
|
+
* **Cap-reached warning** (Issue #227 review fix — Code #2): the
|
|
19213
|
+
* re-attach budget is bounded at 50 to defend against a permanently-
|
|
19214
|
+
* broken `docker logs -f` (the container was removed out from under
|
|
19215
|
+
* us). When the cap is hit, the streamer surfaces ONE warning line via
|
|
19216
|
+
* `process.stderr` naming the prefix + the manual recovery so a long-
|
|
19217
|
+
* running `--watch` session does not lose its foreground log surface
|
|
19218
|
+
* silently.
|
|
19219
|
+
*
|
|
19220
|
+
* **Dying-container respawn skip** (Issue #227 review fix — Code #4):
|
|
19221
|
+
* when the child exits unsolicited and the container's `State.Status`
|
|
19222
|
+
* is `exited` / `dead` / `removing`, the streamer does NOT respawn —
|
|
19223
|
+
* the natural-exit path is the service-runner's `cleanupEcsRun(...)`
|
|
19224
|
+
* call (~1s after the wait resolves), and a respawn against a
|
|
19225
|
+
* dying container is just a wasted `docker logs -f` process + a
|
|
19226
|
+
* spurious cap-reached tick. A `docker restart` (the soft-reload
|
|
19227
|
+
* primitive) leaves the container in `restarting` / `running`, so
|
|
19228
|
+
* the soft-reload re-attach path is preserved. Falls open: an
|
|
19229
|
+
* inspect error treats the container as still alive (best-effort —
|
|
19230
|
+
* the cap+stop() invariants stay correct either way).
|
|
19231
|
+
*
|
|
19232
|
+
* The streamer is best-effort. A spawn / pipe error is silently swallowed
|
|
19233
|
+
* (the parent's `docker wait` already surfaces the underlying container
|
|
19234
|
+
* failure with full context); the loud surface stays on the runner's exit
|
|
19235
|
+
* path.
|
|
19236
|
+
*/
|
|
19237
|
+
function attachContainerLogStreamer(prefix, containerId) {
|
|
19238
|
+
let stopping = false;
|
|
19239
|
+
let current;
|
|
19240
|
+
let stdoutBuf = "";
|
|
19241
|
+
let stderrBuf = "";
|
|
19242
|
+
const maxReattaches = 50;
|
|
19243
|
+
let reattachCount = 0;
|
|
19244
|
+
let pendingRespawn;
|
|
19245
|
+
const spawnOnce = (sinceArg) => {
|
|
19246
|
+
const args = [
|
|
19247
|
+
"logs",
|
|
19248
|
+
"-f",
|
|
19249
|
+
...sinceArg !== void 0 ? ["--since", sinceArg] : [],
|
|
19250
|
+
containerId
|
|
19251
|
+
];
|
|
19252
|
+
const proc = spawn(getDockerCmd(), args, { stdio: [
|
|
19253
|
+
"ignore",
|
|
19254
|
+
"pipe",
|
|
19255
|
+
"pipe"
|
|
19256
|
+
] });
|
|
19257
|
+
current = proc;
|
|
19258
|
+
proc.stdout?.on("data", (chunk) => {
|
|
19259
|
+
stdoutBuf = writePrefixedLines(prefix, stdoutBuf + chunk.toString("utf-8"), process.stdout);
|
|
19260
|
+
});
|
|
19261
|
+
proc.stderr?.on("data", (chunk) => {
|
|
19262
|
+
stderrBuf = writePrefixedLines(prefix, stderrBuf + chunk.toString("utf-8"), process.stderr);
|
|
19263
|
+
});
|
|
19264
|
+
proc.on("error", () => {});
|
|
19265
|
+
proc.on("exit", () => {
|
|
19266
|
+
if (stopping) return;
|
|
19267
|
+
if (reattachCount >= maxReattaches) {
|
|
19268
|
+
process.stderr.write(`${prefix}cdkl: docker logs -f re-attached ${maxReattaches} times; giving up. Run \`docker logs -f ${containerId}\` manually to keep watching.\n`);
|
|
19269
|
+
return;
|
|
19270
|
+
}
|
|
19271
|
+
reattachCount += 1;
|
|
19272
|
+
execFile(getDockerCmd(), [
|
|
19273
|
+
"inspect",
|
|
19274
|
+
"--format",
|
|
19275
|
+
"{{.State.Status}}",
|
|
19276
|
+
containerId
|
|
19277
|
+
], (err, stdout) => {
|
|
19278
|
+
if (stopping) return;
|
|
19279
|
+
if (!err) {
|
|
19280
|
+
const status = stdout.trim().toLowerCase();
|
|
19281
|
+
if (status === "exited" || status === "dead" || status === "removing") return;
|
|
19282
|
+
}
|
|
19283
|
+
pendingRespawn = setTimeout(() => {
|
|
19284
|
+
pendingRespawn = void 0;
|
|
19285
|
+
if (stopping) return;
|
|
19286
|
+
spawnOnce("0s");
|
|
19287
|
+
}, 200);
|
|
19288
|
+
});
|
|
19289
|
+
});
|
|
19290
|
+
};
|
|
19291
|
+
spawnOnce(void 0);
|
|
19292
|
+
return () => {
|
|
19293
|
+
stopping = true;
|
|
19294
|
+
if (pendingRespawn !== void 0) {
|
|
19295
|
+
clearTimeout(pendingRespawn);
|
|
19296
|
+
pendingRespawn = void 0;
|
|
19297
|
+
}
|
|
19298
|
+
if (stdoutBuf) {
|
|
19299
|
+
process.stdout.write(prefix + stdoutBuf + "\n");
|
|
19300
|
+
stdoutBuf = "";
|
|
19301
|
+
}
|
|
19302
|
+
if (stderrBuf) {
|
|
19303
|
+
process.stderr.write(prefix + stderrBuf + "\n");
|
|
19304
|
+
stderrBuf = "";
|
|
19305
|
+
}
|
|
19306
|
+
if (current && !current.killed) current.kill("SIGTERM");
|
|
19307
|
+
};
|
|
19308
|
+
}
|
|
19309
|
+
/**
|
|
19310
|
+
* Write every complete line in `buffer` to `out`, prefixed with `prefix`.
|
|
19311
|
+
* Returns the trailing partial line (no `\n` yet) so the caller can
|
|
19312
|
+
* accumulate it with the next `data` chunk. Exported for unit tests; the
|
|
19313
|
+
* production callers should use {@link attachContainerLogStreamer}.
|
|
19314
|
+
*/
|
|
19315
|
+
function writePrefixedLines(prefix, buffer, out) {
|
|
19316
|
+
const lines = buffer.split("\n");
|
|
19317
|
+
const remainder = lines.pop() ?? "";
|
|
19318
|
+
for (const line of lines) out.write(prefix + line + "\n");
|
|
19319
|
+
return remainder;
|
|
19320
|
+
}
|
|
19321
|
+
|
|
19185
19322
|
//#endregion
|
|
19186
19323
|
//#region src/local/ecs-network.ts
|
|
19187
19324
|
const execFileAsync$3 = promisify(execFile);
|
|
@@ -19770,7 +19907,7 @@ async function runEcsTask(task, options, state) {
|
|
|
19770
19907
|
id,
|
|
19771
19908
|
container
|
|
19772
19909
|
});
|
|
19773
|
-
if (!options.detach) state.logStoppers.push(
|
|
19910
|
+
if (!options.detach) state.logStoppers.push(attachContainerLogStreamer(`[${container.name}] `, id));
|
|
19774
19911
|
}
|
|
19775
19912
|
if (options.detach) return {
|
|
19776
19913
|
exitCode: 0,
|
|
@@ -19910,42 +20047,6 @@ function sleep$1(ms) {
|
|
|
19910
20047
|
return new Promise((res) => setTimeout(res, ms));
|
|
19911
20048
|
}
|
|
19912
20049
|
/**
|
|
19913
|
-
* Stream `docker logs -f <id>` with `[<container-name>]` prefixes on
|
|
19914
|
-
* every line. Returns a stop function for the caller's `finally`.
|
|
19915
|
-
*/
|
|
19916
|
-
function streamContainerLogs(containerName, containerId) {
|
|
19917
|
-
const proc = spawn(getDockerCmd(), [
|
|
19918
|
-
"logs",
|
|
19919
|
-
"-f",
|
|
19920
|
-
containerId
|
|
19921
|
-
], { stdio: [
|
|
19922
|
-
"ignore",
|
|
19923
|
-
"pipe",
|
|
19924
|
-
"pipe"
|
|
19925
|
-
] });
|
|
19926
|
-
const prefix = `[${containerName}] `;
|
|
19927
|
-
let stdoutBuf = "";
|
|
19928
|
-
let stderrBuf = "";
|
|
19929
|
-
proc.stdout?.on("data", (chunk) => {
|
|
19930
|
-
stdoutBuf = writePrefixed(prefix, stdoutBuf + chunk.toString("utf-8"), process.stdout);
|
|
19931
|
-
});
|
|
19932
|
-
proc.stderr?.on("data", (chunk) => {
|
|
19933
|
-
stderrBuf = writePrefixed(prefix, stderrBuf + chunk.toString("utf-8"), process.stderr);
|
|
19934
|
-
});
|
|
19935
|
-
proc.on("error", () => {});
|
|
19936
|
-
return () => {
|
|
19937
|
-
if (stdoutBuf) process.stdout.write(prefix + stdoutBuf + "\n");
|
|
19938
|
-
if (stderrBuf) process.stderr.write(prefix + stderrBuf + "\n");
|
|
19939
|
-
if (!proc.killed) proc.kill("SIGTERM");
|
|
19940
|
-
};
|
|
19941
|
-
}
|
|
19942
|
-
function writePrefixed(prefix, buffer, out) {
|
|
19943
|
-
const lines = buffer.split("\n");
|
|
19944
|
-
const remainder = lines.pop() ?? "";
|
|
19945
|
-
for (const line of lines) out.write(prefix + line + "\n");
|
|
19946
|
-
return remainder;
|
|
19947
|
-
}
|
|
19948
|
-
/**
|
|
19949
20050
|
* Resolve every container's `Image` to a tag the runner can pass to
|
|
19950
20051
|
* `docker run`. The map is keyed by container name; entries are
|
|
19951
20052
|
* populated in parallel up to the asset-manifest bound (single
|
|
@@ -20577,6 +20678,7 @@ function extractServiceProperties(stack, serviceLogicalId, resource, stacks, con
|
|
|
20577
20678
|
const desiredCount = parseDesiredCount(props["DesiredCount"], serviceLogicalId);
|
|
20578
20679
|
const healthCheckGracePeriodSeconds = parseHealthCheckGrace(props["HealthCheckGracePeriodSeconds"], serviceLogicalId);
|
|
20579
20680
|
const serviceName = parseServiceName(props["ServiceName"], serviceLogicalId);
|
|
20681
|
+
const serviceDisplayName = deriveServiceDisplayName(props["ServiceName"], serviceLogicalId, resource.Metadata);
|
|
20580
20682
|
if (!options?.suppressLoadBalancerWarning && Array.isArray(props["LoadBalancers"]) && props["LoadBalancers"].length > 0) {
|
|
20581
20683
|
const { cliName } = getEmbedConfig();
|
|
20582
20684
|
warnings.push(`ECS Service '${serviceLogicalId}' declares LoadBalancers, but \`${cliName} start-service\` runs the replicas only; no local listener fronts them. Reach the containers via their published ports, or run \`${cliName} start-alb <Stack>/<Alb>\` to boot the same replicas behind a local front-door that round-robins the listener rules.`);
|
|
@@ -20587,6 +20689,7 @@ function extractServiceProperties(stack, serviceLogicalId, resource, stacks, con
|
|
|
20587
20689
|
serviceLogicalId,
|
|
20588
20690
|
resource,
|
|
20589
20691
|
serviceName,
|
|
20692
|
+
serviceDisplayName,
|
|
20590
20693
|
desiredCount,
|
|
20591
20694
|
healthCheckGracePeriodSeconds,
|
|
20592
20695
|
task,
|
|
@@ -20741,6 +20844,50 @@ function parseServiceName(raw, serviceLogicalId) {
|
|
|
20741
20844
|
return serviceLogicalId;
|
|
20742
20845
|
}
|
|
20743
20846
|
/**
|
|
20847
|
+
* Issue #227 review fix — derive a CLEAN display name for the per-replica
|
|
20848
|
+
* `[svc=<name> r=<i> c=<container>] ` log prefix. L2 constructs
|
|
20849
|
+
* (`FargateService`, `ApplicationLoadBalancedFargateService`) do NOT set
|
|
20850
|
+
* `ServiceName` explicitly, so the synthesized template's `ServiceName`
|
|
20851
|
+
* is absent and {@link parseServiceName} falls back to the
|
|
20852
|
+
* hash-suffixed logical id (e.g. `BackendApi5F9D8C32`). That ends up in
|
|
20853
|
+
* the foreground prefix as `[svc=BackendApi5F9D8C32 ...]` — noisy +
|
|
20854
|
+
* not what Issue #227's spec example showed.
|
|
20855
|
+
*
|
|
20856
|
+
* Resolution order (display ONLY — does NOT change `service.serviceName`):
|
|
20857
|
+
* 1. The explicit CFn `ServiceName` property, if the user set one.
|
|
20858
|
+
* 2. The last meaningful segment of the resource's `aws:cdk:path`
|
|
20859
|
+
* Metadata. For a typical L2, this is the construct id the user
|
|
20860
|
+
* wrote in CDK source (e.g. `AppStack/BackendApi/Service` →
|
|
20861
|
+
* `BackendApi`). Trailing CDK-internal segments (`/Service`,
|
|
20862
|
+
* `/Resource`, `/Default`) are stripped so the result matches the
|
|
20863
|
+
* construct id the user typed, not the per-resource CFn segment.
|
|
20864
|
+
* 3. The `serviceLogicalId` as today's fallback when neither is
|
|
20865
|
+
* available (synthetic / hand-rolled CFn).
|
|
20866
|
+
*
|
|
20867
|
+
* Pure helper — keep narrowly scoped to the log-prefix use case so
|
|
20868
|
+
* other call sites that rely on `service.serviceName` for awsvpc /
|
|
20869
|
+
* Cloud Map / discovery semantics keep their existing fallback
|
|
20870
|
+
* behavior.
|
|
20871
|
+
*/
|
|
20872
|
+
function deriveServiceDisplayName(rawServiceName, serviceLogicalId, metadata) {
|
|
20873
|
+
if (typeof rawServiceName === "string" && rawServiceName.length > 0) return rawServiceName;
|
|
20874
|
+
const cdkPath = typeof metadata?.["aws:cdk:path"] === "string" ? metadata["aws:cdk:path"] : "";
|
|
20875
|
+
if (cdkPath.length > 0) {
|
|
20876
|
+
const segments = cdkPath.split("/");
|
|
20877
|
+
while (segments.length > 1) {
|
|
20878
|
+
const tail = segments[segments.length - 1];
|
|
20879
|
+
if (tail === "Service" || tail === "Resource" || tail === "Default") {
|
|
20880
|
+
segments.pop();
|
|
20881
|
+
continue;
|
|
20882
|
+
}
|
|
20883
|
+
break;
|
|
20884
|
+
}
|
|
20885
|
+
const tail = segments[segments.length - 1];
|
|
20886
|
+
if (typeof tail === "string" && tail.length > 0) return tail;
|
|
20887
|
+
}
|
|
20888
|
+
return serviceLogicalId;
|
|
20889
|
+
}
|
|
20890
|
+
/**
|
|
20744
20891
|
* Local copy of the same `pickStack` helper used by the task resolver.
|
|
20745
20892
|
* Kept in-file rather than exported from `ecs-task-resolver.ts` so future
|
|
20746
20893
|
* service-specific extensions (e.g. cross-stack service-to-task refs)
|
|
@@ -20887,6 +21034,22 @@ var EcsServiceRunnerError = class EcsServiceRunnerError extends Error {
|
|
|
20887
21034
|
Object.setPrototypeOf(this, EcsServiceRunnerError.prototype);
|
|
20888
21035
|
}
|
|
20889
21036
|
};
|
|
21037
|
+
/**
|
|
21038
|
+
* Phase 4 (#214) — completion-log suffix the soft-reload primitive
|
|
21039
|
+
* emits AFTER `Soft-reloaded replica r<i> (gen <g>): ` to confirm
|
|
21040
|
+
* the docker restart + TCP-ready probe + Cloud Map / front-door
|
|
21041
|
+
* re-publish round trip is done.
|
|
21042
|
+
*
|
|
21043
|
+
* Exported so integ fixtures + unit tests can grep against the
|
|
21044
|
+
* canonical text instead of hand-copying the wording — a future
|
|
21045
|
+
* refactor that rewords this line stays detectable via the symbol
|
|
21046
|
+
* import instead of silently breaking every test's regex.
|
|
21047
|
+
*
|
|
21048
|
+
* Per-repo memory (#218 / test reviewer N4): log-line text is part
|
|
21049
|
+
* of the public contract for `--watch` integ scripts, so it earns a
|
|
21050
|
+
* constant.
|
|
21051
|
+
*/
|
|
21052
|
+
const SOFT_RELOAD_COMPLETION_LOG_SUFFIX = "restart + TCP-ready probe complete; Cloud Map + front-door re-published.";
|
|
20890
21053
|
function createServiceRunState() {
|
|
20891
21054
|
return {
|
|
20892
21055
|
replicas: [],
|
|
@@ -21139,8 +21302,33 @@ async function bootReplica(service, options, instance) {
|
|
|
21139
21302
|
};
|
|
21140
21303
|
logger.info(`Booting replica ${instance.index} (${perReplicaCluster})`);
|
|
21141
21304
|
await runEcsTask(service.task, perReplicaTaskOptions, instance.state);
|
|
21305
|
+
if (options.streamLogs !== false) for (const started of instance.state.startedContainers) {
|
|
21306
|
+
const prefix = `[svc=${service.serviceDisplayName} r=${instance.index} c=${started.name}] `;
|
|
21307
|
+
instance.state.logStoppers.push(attachContainerLogStreamer(prefix, started.id));
|
|
21308
|
+
}
|
|
21142
21309
|
if (options.discovery) await publishReplicaToCloudMap(service, instance, options.discovery, ownerKeyPrefix);
|
|
21143
21310
|
if (options.frontDoor) await publishReplicaToFrontDoor(service, instance, options.frontDoor, options.taskOptions.containerHost, ownerKeyPrefix);
|
|
21311
|
+
instance.lastDeployedAssetHash = pickEssentialAssetHash(service);
|
|
21312
|
+
}
|
|
21313
|
+
/**
|
|
21314
|
+
* Phase 4 follow-up (#218) — extract the CDK asset hash from a
|
|
21315
|
+
* resolved service's first essential container (with the same
|
|
21316
|
+
* fallback the watcher uses: first essential, else first container).
|
|
21317
|
+
* Returns `undefined` when the image isn't a CDK asset OR carries
|
|
21318
|
+
* no hash. Pure helper so the boot + rolling + soft-reload paths
|
|
21319
|
+
* share one source of truth for "what's running right now".
|
|
21320
|
+
*
|
|
21321
|
+
* Exported for unit tests; not part of the semver-covered public
|
|
21322
|
+
* surface.
|
|
21323
|
+
*
|
|
21324
|
+
* @internal
|
|
21325
|
+
*/
|
|
21326
|
+
function pickEssentialAssetHash(service) {
|
|
21327
|
+
const essential = service.task.containers.find((c) => c.essential) ?? service.task.containers[0];
|
|
21328
|
+
if (!essential) return void 0;
|
|
21329
|
+
const image = essential.image;
|
|
21330
|
+
if (image?.kind !== "cdk-asset") return void 0;
|
|
21331
|
+
return image.assetHash;
|
|
21144
21332
|
}
|
|
21145
21333
|
/**
|
|
21146
21334
|
* After the replica's main container is up, discover its docker
|
|
@@ -21515,6 +21703,7 @@ async function softReloadReplica(args) {
|
|
|
21515
21703
|
}
|
|
21516
21704
|
unregisterReplicaFromFrontDoor(instance, controllerOptions.frontDoor);
|
|
21517
21705
|
instance.softReloadInProgress = true;
|
|
21706
|
+
instance.softReloadGeneration = (instance.softReloadGeneration ?? 0) + 1;
|
|
21518
21707
|
try {
|
|
21519
21708
|
logger.info(`Soft-reloading replica r${instance.index} (gen ${instance.generation}): docker cp ${sourceDirToCopy} -> ${targets.length} essential container(s); restart.`);
|
|
21520
21709
|
for (const target of targets) {
|
|
@@ -21545,7 +21734,8 @@ async function softReloadReplica(args) {
|
|
|
21545
21734
|
const ownerKeyPrefix = `${newService.serviceLogicalId}:r${instance.index}${ownerKeyGenSuffix}`;
|
|
21546
21735
|
if (controllerOptions.discovery) await publishReplicaToCloudMap(newService, instance, controllerOptions.discovery, ownerKeyPrefix);
|
|
21547
21736
|
if (controllerOptions.frontDoor) await publishReplicaToFrontDoor(newService, instance, controllerOptions.frontDoor, controllerOptions.taskOptions.containerHost, ownerKeyPrefix);
|
|
21548
|
-
|
|
21737
|
+
instance.lastDeployedAssetHash = pickEssentialAssetHash(newService);
|
|
21738
|
+
logger.info(`Soft-reloaded replica r${instance.index} (gen ${instance.generation}): ${SOFT_RELOAD_COMPLETION_LOG_SUFFIX}`);
|
|
21549
21739
|
} finally {
|
|
21550
21740
|
instance.softReloadInProgress = false;
|
|
21551
21741
|
}
|
|
@@ -21740,6 +21930,7 @@ async function watchReplica(service, options, instance, runState) {
|
|
|
21740
21930
|
await sleep(500);
|
|
21741
21931
|
continue;
|
|
21742
21932
|
}
|
|
21933
|
+
const softReloadGenBeforeWait = instance.softReloadGeneration ?? 0;
|
|
21743
21934
|
let exitCode;
|
|
21744
21935
|
try {
|
|
21745
21936
|
exitCode = await waitForExitImpl(essentialId);
|
|
@@ -21748,7 +21939,8 @@ async function watchReplica(service, options, instance, runState) {
|
|
|
21748
21939
|
exitCode = -1;
|
|
21749
21940
|
}
|
|
21750
21941
|
if (instance.shuttingDown || runState.shuttingDown) return;
|
|
21751
|
-
|
|
21942
|
+
const softReloadHappenedMidWait = (instance.softReloadGeneration ?? 0) !== softReloadGenBeforeWait;
|
|
21943
|
+
if (instance.softReloadInProgress || softReloadHappenedMidWait) {
|
|
21752
21944
|
while (instance.softReloadInProgress && !instance.shuttingDown && !runState.shuttingDown) await sleep(100);
|
|
21753
21945
|
if (instance.shuttingDown || runState.shuttingDown) return;
|
|
21754
21946
|
continue;
|
|
@@ -22729,9 +22921,51 @@ function escapeRealmQuotes(realm) {
|
|
|
22729
22921
|
}
|
|
22730
22922
|
/** Reply 404 — an ALB listener with no matching rule and no default action. */
|
|
22731
22923
|
function reply404(req, res, opts) {
|
|
22732
|
-
writeError(res, 404,
|
|
22924
|
+
writeError(res, 404, buildNoRuleMatched404Body(req, opts));
|
|
22733
22925
|
return Promise.resolve();
|
|
22734
22926
|
}
|
|
22927
|
+
/**
|
|
22928
|
+
* Build the no-rule-matched 404 body. When the call site supplied a
|
|
22929
|
+
* {@link StartFrontDoorServerOptions.rulesSummary}, the body lists every
|
|
22930
|
+
* ALB condition field that WAS evaluated (method, host, path) plus every
|
|
22931
|
+
* configured rule's priority + conditions + action target — so a user
|
|
22932
|
+
* whose request missed on, say, the Host header can spot the mismatch
|
|
22933
|
+
* without inspecting the synthesized template. Header conditions are
|
|
22934
|
+
* NOT spelled out in the evaluated section (too noisy) but ARE listed
|
|
22935
|
+
* in each rule's condition row when the rule constrains them. Without a
|
|
22936
|
+
* summary the body falls back to the original path-only shape (preserves
|
|
22937
|
+
* the behavior for direct callers that wire the proxy with just a
|
|
22938
|
+
* `selectPool` / `selectTarget`).
|
|
22939
|
+
*/
|
|
22940
|
+
function buildNoRuleMatched404Body(req, opts) {
|
|
22941
|
+
const requestPath = req.url ?? "/";
|
|
22942
|
+
const summary = opts.rulesSummary;
|
|
22943
|
+
if (!summary) return `No listener rule matched '${requestPath}' on ${opts.label}, and the listener has no default action forwarding to a local target.`;
|
|
22944
|
+
const rawHost = req.headers.host;
|
|
22945
|
+
const hostValue = Array.isArray(rawHost) ? rawHost[0] : rawHost;
|
|
22946
|
+
const lines = [];
|
|
22947
|
+
lines.push(`No listener rule matched the request on ${opts.label}, and the listener has no default action forwarding to a local target.`);
|
|
22948
|
+
lines.push("");
|
|
22949
|
+
lines.push(" Evaluated:");
|
|
22950
|
+
lines.push(` Method: ${req.method ?? "(unknown)"}`);
|
|
22951
|
+
lines.push(` Host: ${hostValue ?? "(no Host header)"}`);
|
|
22952
|
+
lines.push(` Path: ${requestPath}`);
|
|
22953
|
+
lines.push("");
|
|
22954
|
+
if (summary.length === 0) lines.push(" Listener has 0 rule(s).");
|
|
22955
|
+
else {
|
|
22956
|
+
lines.push(` Listener has ${summary.length} rule(s):`);
|
|
22957
|
+
const ordered = [...summary].sort((a, b) => a.priority - b.priority);
|
|
22958
|
+
for (const rule of ordered) {
|
|
22959
|
+
const conditions = rule.conditions.length === 0 ? "(no condition)" : rule.conditions.map(formatRuleConditionSummary).join(" AND ");
|
|
22960
|
+
lines.push(` [priority=${rule.priority}] ${conditions} -> ${rule.action}`);
|
|
22961
|
+
}
|
|
22962
|
+
}
|
|
22963
|
+
return lines.join("\n");
|
|
22964
|
+
}
|
|
22965
|
+
/** Format one condition row of a {@link FrontDoorRuleSummary} for the 404 body. */
|
|
22966
|
+
function formatRuleConditionSummary(c) {
|
|
22967
|
+
return `${c.field} in [${c.values.join(", ")}]`;
|
|
22968
|
+
}
|
|
22735
22969
|
function handlePoolRequest(req, res, pool, opts) {
|
|
22736
22970
|
return new Promise((resolve) => {
|
|
22737
22971
|
const endpoint = pool.next();
|
|
@@ -24239,6 +24473,13 @@ async function reloadAllServices(args) {
|
|
|
24239
24473
|
* {@link AssetManifestLoader}) so the caller can fall back to rebuild
|
|
24240
24474
|
* with a warn line that explains why the classifier couldn't run.
|
|
24241
24475
|
*/
|
|
24476
|
+
/**
|
|
24477
|
+
* @internal — exported for unit tests of the fall-through branches
|
|
24478
|
+
* (the 6 `return undefined` paths + the catch arm on
|
|
24479
|
+
* `resolveEcsServiceTarget` throw). Not part of the semver-covered
|
|
24480
|
+
* public surface; the only legitimate caller is `reloadAllServices`
|
|
24481
|
+
* inside this file.
|
|
24482
|
+
*/
|
|
24242
24483
|
async function loadAssetContextForTarget(args) {
|
|
24243
24484
|
const { target, controller, stacks, cdkOutDir, assetLoader, logger } = args;
|
|
24244
24485
|
const candidate = pickCandidateStack(parseEcsTarget(target).stackPattern, stacks);
|
|
@@ -24261,8 +24502,12 @@ async function loadAssetContextForTarget(args) {
|
|
|
24261
24502
|
if (!newDockerImage.source.directory) return;
|
|
24262
24503
|
const newAssetSourceDir = path.resolve(cdkOutDir, newDockerImage.source.directory);
|
|
24263
24504
|
let oldAssetHash;
|
|
24264
|
-
const
|
|
24265
|
-
if (
|
|
24505
|
+
const liveReplica = controller.runState.replicas.find((r) => !r.shuttingDown);
|
|
24506
|
+
if (liveReplica?.lastDeployedAssetHash !== void 0) oldAssetHash = liveReplica.lastDeployedAssetHash;
|
|
24507
|
+
else {
|
|
24508
|
+
const oldEssential = controller.service.task.containers.find((c) => c.essential) ?? controller.service.task.containers[0];
|
|
24509
|
+
if (oldEssential?.image.kind === "cdk-asset") oldAssetHash = oldEssential.image.assetHash;
|
|
24510
|
+
}
|
|
24266
24511
|
return {
|
|
24267
24512
|
...oldAssetHash !== void 0 && { oldAssetHash },
|
|
24268
24513
|
newAssetHash,
|
|
@@ -24430,7 +24675,8 @@ async function resolveServiceAndRunnerOpts(boot, stacks, options, discovery, ski
|
|
|
24430
24675
|
restartPolicy: options.restartPolicy,
|
|
24431
24676
|
taskOptions: taskOpts,
|
|
24432
24677
|
discovery,
|
|
24433
|
-
...frontDoorPools && frontDoorPools.length > 0 ? { frontDoor: { pools: frontDoorPools } } : {}
|
|
24678
|
+
...frontDoorPools && frontDoorPools.length > 0 ? { frontDoor: { pools: frontDoorPools } } : {},
|
|
24679
|
+
streamLogs: options.logs !== false
|
|
24434
24680
|
}
|
|
24435
24681
|
};
|
|
24436
24682
|
}
|
|
@@ -24558,6 +24804,7 @@ async function buildFrontDoor(plan, options, logger) {
|
|
|
24558
24804
|
const tls = listener.protocol === "HTTPS" && wantTls ? tlsMaterials : void 0;
|
|
24559
24805
|
const forwardedProto = listener.protocol === "HTTPS" ? "https" : "http";
|
|
24560
24806
|
const degradedHttps = listener.protocol === "HTTPS" && !wantTls;
|
|
24807
|
+
const rulesSummary = listener.rules.map(buildRuleSummary);
|
|
24561
24808
|
const server = await startFrontDoorServer({
|
|
24562
24809
|
route,
|
|
24563
24810
|
port: listener.hostPort,
|
|
@@ -24565,6 +24812,7 @@ async function buildFrontDoor(plan, options, logger) {
|
|
|
24565
24812
|
listenerPort: listener.listenerPort,
|
|
24566
24813
|
label: `listener port ${listener.listenerPort}`,
|
|
24567
24814
|
forwardedProto,
|
|
24815
|
+
rulesSummary,
|
|
24568
24816
|
...tls ? { tls } : {}
|
|
24569
24817
|
});
|
|
24570
24818
|
servers.push(server);
|
|
@@ -24629,6 +24877,66 @@ function describeTarget(t) {
|
|
|
24629
24877
|
function describeTargetShort(t) {
|
|
24630
24878
|
return t.kind === "lambda" ? `Lambda ${t.lambda.logicalId}` : t.serviceTarget;
|
|
24631
24879
|
}
|
|
24880
|
+
/**
|
|
24881
|
+
* Build the per-rule summary the front-door surfaces in its no-rule-matched
|
|
24882
|
+
* 404 body (issue #228). One condition row per constrained ALB field, plus a
|
|
24883
|
+
* pre-formatted action target. Distinct from {@link describeConditions} /
|
|
24884
|
+
* {@link describeAction} (which produce a single-line boot-banner string) —
|
|
24885
|
+
* the 404 body needs the rule decomposed into its constituent fields so the
|
|
24886
|
+
* formatter can render `field in [values]` rows.
|
|
24887
|
+
*/
|
|
24888
|
+
function buildRuleSummary(rule) {
|
|
24889
|
+
const conditions = [];
|
|
24890
|
+
if (rule.pathPatterns.length > 0) conditions.push({
|
|
24891
|
+
field: "path-pattern",
|
|
24892
|
+
values: rule.pathPatterns
|
|
24893
|
+
});
|
|
24894
|
+
if (rule.hostPatterns.length > 0) conditions.push({
|
|
24895
|
+
field: "host-header",
|
|
24896
|
+
values: rule.hostPatterns
|
|
24897
|
+
});
|
|
24898
|
+
for (const h of rule.httpHeaderConditions) conditions.push({
|
|
24899
|
+
field: "http-header",
|
|
24900
|
+
values: [`${h.name}: ${h.values.join(", ")}`]
|
|
24901
|
+
});
|
|
24902
|
+
if (rule.httpRequestMethods.length > 0) conditions.push({
|
|
24903
|
+
field: "http-request-method",
|
|
24904
|
+
values: rule.httpRequestMethods
|
|
24905
|
+
});
|
|
24906
|
+
if (rule.queryStringConditions.length > 0) conditions.push({
|
|
24907
|
+
field: "query-string",
|
|
24908
|
+
values: rule.queryStringConditions.map(describeQueryStringCondition)
|
|
24909
|
+
});
|
|
24910
|
+
if (rule.sourceIpCidrs.length > 0) conditions.push({
|
|
24911
|
+
field: "source-ip",
|
|
24912
|
+
values: rule.sourceIpCidrs
|
|
24913
|
+
});
|
|
24914
|
+
return {
|
|
24915
|
+
priority: rule.priority,
|
|
24916
|
+
conditions,
|
|
24917
|
+
action: describeRuleActionForSummary(rule.action)
|
|
24918
|
+
};
|
|
24919
|
+
}
|
|
24920
|
+
/**
|
|
24921
|
+
* Describe a planned action for the no-rule-matched 404 body (issue #228).
|
|
24922
|
+
* Uses the `<ECS: ...>` / `<Lambda: ...>` shape the issue body proposes so a
|
|
24923
|
+
* user can read each rule's target at a glance.
|
|
24924
|
+
*/
|
|
24925
|
+
function describeRuleActionForSummary(action) {
|
|
24926
|
+
if (action.kind === "redirect") return `redirect ${action.statusCode}`;
|
|
24927
|
+
if (action.kind === "fixed-response") return `fixed-response ${action.statusCode}`;
|
|
24928
|
+
if (action.targets.length === 1) return `forward to ${describeForwardTargetForSummary(action.targets[0])}`;
|
|
24929
|
+
return `forward weighted [${action.targets.map((t) => `${describeForwardTargetForSummary(t)}@${t.weight}`).join(", ")}]`;
|
|
24930
|
+
}
|
|
24931
|
+
/**
|
|
24932
|
+
* One forward target named the way the 404 body shows it: `<ECS: Service>` or
|
|
24933
|
+
* `<Lambda: LogicalId>` — distinct from the boot-banner format (which also
|
|
24934
|
+
* prints the container / port / round-robin hint) so the 404 body stays
|
|
24935
|
+
* scannable.
|
|
24936
|
+
*/
|
|
24937
|
+
function describeForwardTargetForSummary(t) {
|
|
24938
|
+
return t.kind === "lambda" ? `<Lambda: ${t.lambda.logicalId}>` : `<ECS: ${t.serviceTarget}>`;
|
|
24939
|
+
}
|
|
24632
24940
|
async function resolvePlaceholderAccount(arn, region) {
|
|
24633
24941
|
if (!arn.includes("${AWS::AccountId}")) return arn;
|
|
24634
24942
|
const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
|
|
@@ -24821,7 +25129,7 @@ async function resolveSharedSidecarCredentials(options) {
|
|
|
24821
25129
|
* factory.
|
|
24822
25130
|
*/
|
|
24823
25131
|
function addCommonEcsServiceOptions(cmd) {
|
|
24824
|
-
cmd.addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default(getEmbedConfig().resourceNamePrefix)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries.")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--max-tasks <n>", `Hard cap on local replica count. Caps the template DesiredCount so local dev machines don't run an unbounded number of containers. Cannot exceed ${83} due to the per-replica link-local /24 subnet allocator's range.`).default(3).argParser(parseMaxTasks)).addOption(new Option("--restart-policy <policy>", "How to react when an essential container exits. 'on-failure' (default) restarts only on non-zero exit; 'always' restarts on every exit; 'none' shuts the replica down and runs the service degraded.").default("on-failure").argParser(parseRestartPolicy)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", `Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (\`cdk deploy\`). Bare form uses the ${getEmbedConfig().binaryName} stack name; pass an explicit value when the CFn stack name differs. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).`)).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region."));
|
|
25132
|
+
cmd.addOption(new Option("--cluster <name>", "Cluster name surfaced to ECS_CONTAINER_METADATA_URI_V4 and used as the docker network prefix").default(getEmbedConfig().resourceNamePrefix)).addOption(new Option("--env-vars <file>", "JSON env-var overrides (SAM-compatible: {\"ContainerName\":{\"KEY\":\"VALUE\"}, \"Parameters\":{}})")).addOption(new Option("--container-host <ip>", "Host IP to bind published container ports to. Must be a numeric IP (Docker rejects hostnames here)").default("127.0.0.1")).addOption(new Option("--assume-task-role [arn]", "Assume the task definition's TaskRoleArn (or the supplied ARN) and forward STS-issued temp credentials via the metadata sidecar so containers run with the deployed task role. Bare flag uses the template's TaskRoleArn; pass an explicit ARN to override.")).addOption(new Option("--no-pull", "Skip docker pull for every container image and the metadata sidecar")).addOption(new Option("--ecr-role-arn <arn>", "Role ARN to assume before authenticating against ECR for cross-account / centralized registries.")).addOption(new Option("--platform <platform>", "Force docker --platform (linux/amd64 or linux/arm64). Default: inferred from task RuntimePlatform.CpuArchitecture")).addOption(new Option("--max-tasks <n>", `Hard cap on local replica count. Caps the template DesiredCount so local dev machines don't run an unbounded number of containers. Cannot exceed ${83} due to the per-replica link-local /24 subnet allocator's range.`).default(3).argParser(parseMaxTasks)).addOption(new Option("--restart-policy <policy>", "How to react when an essential container exits. 'on-failure' (default) restarts only on non-zero exit; 'always' restarts on every exit; 'none' shuts the replica down and runs the service degraded.").default("on-failure").argParser(parseRestartPolicy)).addOption(new Option("--from-cfn-stack [cfn-stack-name]", `Read a deployed CloudFormation stack via ListStackResources and substitute Ref / Fn::ImportValue in container env vars / secrets / image URIs with the deployed physical IDs / exports. Use for CDK apps deployed via the upstream CDK CLI (\`cdk deploy\`). Bare form uses the ${getEmbedConfig().binaryName} stack name; pass an explicit value when the CFn stack name differs. Fn::GetAtt is warn-and-dropped in v1 (CFn ListStackResources does not return per-attribute values).`)).addOption(new Option("--stack-region <region>", "Region of the state record to read. Used with --from-cfn-stack as the CFn client region.")).addOption(new Option("--no-logs", "Disable foreground streaming of each replica container stdout/stderr. By default every booted replica streams its docker logs to the host terminal with a [svc=<service> r=<replica-index> c=<container>] prefix (parity with `run-task`). Pass --no-logs for multi-replica / multi-service runs whose interleaved log volume is unreadable; `docker logs -f <id>` in a separate terminal stays available."));
|
|
24825
25133
|
[
|
|
24826
25134
|
...commonOptions(),
|
|
24827
25135
|
...appOptions(),
|
|
@@ -25849,5 +26157,5 @@ function addListSpecificOptions(cmd) {
|
|
|
25849
26157
|
}
|
|
25850
26158
|
|
|
25851
26159
|
//#endregion
|
|
25852
|
-
export {
|
|
25853
|
-
//# sourceMappingURL=local-list-
|
|
26160
|
+
export { matchRoute as $, architectureToPlatform as $t, createLocalInvokeAgentCoreCommand as A, resolveLambdaArnIntrinsic as An, matchPreflight as At, filterRoutesByApiIdentifier as B, formatStateRemedy as Bn, AGENTCORE_SIGV4_SERVICE as Bt, classifySourceChange as C, countTargets as Cn, verifyJwtAuthorizer as Ct, createLocalRunTaskCommand as D, parseSelectionExpressionPath as Dn, buildCorsConfigByApiId as Dt, addRunTaskSpecificOptions as E, discoverWebSocketApisOrThrow as En, applyCorsResponseHeaders as Et, createAuthorizerCache as F, AGENTCORE_RUNTIME_TYPE as Fn, MCP_CONTAINER_PORT as Ft, resolveSelectionExpression as G, downloadAndExtractS3Bundle as Gt, groupRoutesByServer as H, tryResolveImageFnJoin as Hn, AGENTCORE_SESSION_ID_HEADER as Ht, createFileWatcher as I, AgentCoreResolutionError as In, MCP_PATH as It, buildMethodArn as J, computeCodeImageTag as Jt, resolveServiceIntegrationParameters as K, SUPPORTED_CODE_RUNTIMES as Kt, attachStageContext as L, pickAgentCoreCandidateStack as Ln, MCP_PROTOCOL_VERSION as Lt, createLocalStartApiCommand as M, AGENTCORE_AGUI_PROTOCOL as Mn, A2A_CONTAINER_PORT as Mt, createWatchPredicates as N, AGENTCORE_HTTP_PROTOCOL as Nn, A2A_PATH as Nt, attachContainerLogStreamer as O, discoverRoutes as On, buildCorsConfigFromCloudFrontChain as Ot, resolveApiTargetSubset as P, AGENTCORE_MCP_PROTOCOL as Pn, a2aInvokeOnce as Pt, invokeTokenAuthorizer as Q, createLocalInvokeCommand as Qt, buildStageMap as R, resolveAgentCoreTarget as Rn, mcpInvokeOnce as Rt, CloudMapRegistry as S, resolveSingleTarget as Sn, verifyCognitoJwt as St, getContainerNetworkIp as T, discoverWebSocketApis as Tn, attachAuthorizers as Tt, readMtlsMaterialsFromDisk as U, LocalInvokeBuildError as Un, invokeAgentCore as Ut, filterRoutesByApiIdentifiers as V, substituteImagePlaceholders as Vn, signAgentCoreInvocation as Vt, startApiServer as W, waitForAgentCorePing as Wt, evaluateCachedLambdaPolicy as X, toCmdArgv as Xt, computeRequestIdentityHash as Y, renderCodeDockerfile as Yt, invokeRequestAuthorizer as Z, addInvokeSpecificOptions as Zt, parseMaxTasks as _, resolveCfnStackName as _n, buildDisconnectEvent as _t, albStrategy as a, substituteAgainstState as an, pickResponseTemplate as at, runEcsServiceEmulator as b, resolveSsmParameters as bn, buildJwksUrlFromIssuer as bt, resolveAlbTarget as c, substituteEnvVarsFromStateAsync as cn, VtlEvaluationError as ct, addStartServiceSpecificOptions as d, LocalStateSourceError as dn, bufferToBody as dt, buildContainerImage as en, translateLambdaResponse as et, createLocalStartServiceCommand as f, createLocalStateProvider as fn, ConnectionRegistry as ft, buildEcsImageResolutionContext as g, resolveCfnRegion as gn, buildConnectEvent as gt, addCommonEcsServiceOptions as h, resolveCfnFallbackRegion as hn, parseConnectionsPath as ht, addAlbSpecificOptions as i, EcsTaskResolutionError as in, evaluateResponseParameters as it, addStartApiSpecificOptions as j, AGENTCORE_A2A_PROTOCOL as jn, invokeAgentCoreWs as jt, addInvokeAgentCoreSpecificOptions as k, pickRefLogicalId as kn, isFunctionUrlOacFronted as kt, isApplicationLoadBalancer as l, resolveEnvVars as ln, HOST_GATEWAY_MIN_VERSION as lt, MAX_TASKS_SUBNET_RANGE_CAP as m, rejectExplicitCfnStackWithMultipleStacks as mn, handleConnectionsRequest as mt, createLocalListCommand as n, resolveRuntimeFileExtension as nn, buildHttpApiV2Event as nt, createLocalStartAlbCommand as o, substituteAgainstStateAsync as on, selectIntegrationResponse as ot, serviceStrategy as p, isCfnFlagPresent as pn, buildMgmtEndpointEnvUrl as pt, defaultCredentialsLoader as q, buildAgentCoreCodeImage as qt, formatTargetListing as r, resolveRuntimeImage as rn, buildRestV1Event as rt, parseLbPortOverrides as s, substituteEnvVarsFromState as sn, tryParseStatus as st, addListSpecificOptions as t, resolveRuntimeCodeMountPath as tn, applyAuthorizerOverlay as tt, resolveAlbFrontDoor as u, materializeLayerFromArn as un, probeHostGatewaySupport as ut, parseRestartPolicy as v, CfnLocalStateProvider as vn, buildMessageEvent as vt, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as w, listTargets as wn, verifyJwtViaDiscovery as wt, buildCloudMapIndex as x, resolveWatchConfig as xn, createJwksCache as xt, resolveSharedSidecarCredentials as y, collectSsmParameterRefs as yn, buildCognitoJwksUrl as yt, availableApiIdentifiers as z, derivePseudoParametersFromRegion as zn, parseSseForJsonRpc as zt };
|
|
26161
|
+
//# sourceMappingURL=local-list-B67vK97a.js.map
|