cdk-local 0.48.0 → 0.49.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 +2 -2
- package/dist/cli.js +3 -3
- package/dist/{cloud-map-resolver-BHapzvlA.js → cloud-map-resolver-CW4Paz5K.js} +107 -11
- package/dist/cloud-map-resolver-CW4Paz5K.js.map +1 -0
- package/dist/{error-handler-BfysjFFj.d.ts → error-handler-GsADCf-H.d.ts} +6 -1
- package/dist/error-handler-GsADCf-H.d.ts.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/internal.d.ts +25 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-list-9MtupW0M.js → local-list-BovxL7PC.js} +60 -14
- package/dist/local-list-BovxL7PC.js.map +1 -0
- package/package.json +3 -1
- package/dist/cloud-map-resolver-BHapzvlA.js.map +0 -1
- package/dist/error-handler-BfysjFFj.d.ts.map +0 -1
- package/dist/local-list-9MtupW0M.js.map +0 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ cdkl list # every runnable target, grouped
|
|
|
58
58
|
|
|
59
59
|
- **`start-api`** serves one HTTP server per API; a bare `start-api` in a multi-stack app needs `--all-stacks` or `--stack <name>`. Add **`--watch`** to re-synth and hot-reload on CDK source changes ([details](docs/local-emulation.md#hot-reload---watch)).
|
|
60
60
|
- **`run-task`** / single-replica **`start-service`** publish declared container ports on the host and log `Reach it at 127.0.0.1:<port>` (`--host-port <container>=<host>` remaps; handy for privileged ports on macOS).
|
|
61
|
-
- **`invoke-agentcore`** runs the agent (a container, or a `fromCodeAsset` managed-runtime bundle — Python 3.10-3.14 / Node 22 — built from source), waits for `GET /ping`, POSTs your `--event` to `POST /invocations`, and streams an SSE response live. `--ws` streams over the agent's bidirectional `/ws` WebSocket endpoint instead. A `customJwtAuthorizer` is enforced locally — pass `--bearer-token <jwt>` (verified against the runtime's OIDC discovery URL). MCP-protocol runtimes (`ProtocolConfiguration = MCP`) are also served — the `POST /mcp` Streamable-HTTP contract on 8000, with one JSON-RPC request (`tools/list` by default, or `--event`'s `{"method":...,"params":...}`).
|
|
61
|
+
- **`invoke-agentcore`** runs the agent (a container, or a `fromCodeAsset` / `fromS3` managed-runtime bundle — Python 3.10-3.14 / Node 22 — built from source), waits for `GET /ping`, POSTs your `--event` to `POST /invocations`, and streams an SSE response live. `--ws` streams over the agent's bidirectional `/ws` WebSocket endpoint instead. A `customJwtAuthorizer` is enforced locally — pass `--bearer-token <jwt>` (verified against the runtime's OIDC discovery URL). MCP-protocol runtimes (`ProtocolConfiguration = MCP`) are also served — the `POST /mcp` Streamable-HTTP contract on 8000, with one JSON-RPC request (`tools/list` by default, or `--event`'s `{"method":...,"params":...}`).
|
|
62
62
|
- Non-TTY (CI / pipes): every command except a bare `start-api` needs an explicit target.
|
|
63
63
|
|
|
64
64
|
Full flags, precedence, and `--from-cfn-stack` resolution: [docs/cli-reference.md](docs/cli-reference.md) and [docs/local-emulation.md](docs/local-emulation.md).
|
|
@@ -105,7 +105,7 @@ Format + full precedence: [docs/cli-reference.md](docs/cli-reference.md).
|
|
|
105
105
|
| `AWS::ECS::Service` (start-service) | ✓ |
|
|
106
106
|
| `AWS::ServiceDiscovery::*` (Cloud Map / Service Connect) | ✓ |
|
|
107
107
|
| `AWS::ElasticLoadBalancingV2::*` (start-alb: ALB front-door; `path-pattern` + `host-header` rules, weighted forward, redirect / fixed-response; ECS + Lambda targets) | ✓ |
|
|
108
|
-
| `AWS::BedrockAgentCore::Runtime` (invoke-agentcore, container + fromCodeAsset artifacts, HTTP + MCP) | ✓ |
|
|
108
|
+
| `AWS::BedrockAgentCore::Runtime` (invoke-agentcore, container + fromCodeAsset/fromS3 artifacts, HTTP + MCP) | ✓ |
|
|
109
109
|
|
|
110
110
|
Lambda runs on every current AWS Lambda runtime — Node.js (18/20/22/24), Python (3.11–3.14), Ruby (3.2/3.3), Java (8.al2/11/17/21), .NET (6/8), and the OS-only `provided.al2` / `provided.al2023`. The retired `go1.x` runtime is rejected with a pointer to migrate to `provided.al2023`.
|
|
111
111
|
|
package/dist/cli.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as createLocalStartApiCommand } from "./cloud-map-resolver-
|
|
3
|
-
import { a as createLocalRunTaskCommand, i as createLocalStartServiceCommand, o as createLocalInvokeAgentCoreCommand, r as createLocalStartAlbCommand, s as createLocalInvokeCommand, t as createLocalListCommand } from "./local-list-
|
|
2
|
+
import { a as createLocalStartApiCommand } from "./cloud-map-resolver-CW4Paz5K.js";
|
|
3
|
+
import { a as createLocalRunTaskCommand, i as createLocalStartServiceCommand, o as createLocalInvokeAgentCoreCommand, r as createLocalStartAlbCommand, s as createLocalInvokeCommand, t as createLocalListCommand } from "./local-list-BovxL7PC.js";
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
|
|
6
6
|
//#region src/cli/index.ts
|
|
7
7
|
const program = new Command();
|
|
8
|
-
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.
|
|
8
|
+
program.name("cdkl").description("Run AWS CDK stacks locally with Docker.").version("0.49.0");
|
|
9
9
|
program.addCommand(createLocalInvokeCommand());
|
|
10
10
|
program.addCommand(createLocalInvokeAgentCoreCommand());
|
|
11
11
|
program.addCommand(createLocalStartApiCommand());
|
|
@@ -2,7 +2,7 @@ import { a as runDockerStreaming, c as getEmbedConfig, i as runDockerForeground,
|
|
|
2
2
|
import { cpSync, createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import { dirname, isAbsolute, join, normalize, resolve } from "node:path";
|
|
5
|
+
import { dirname, isAbsolute, join, normalize, resolve, sep } from "node:path";
|
|
6
6
|
import { Command, Option } from "commander";
|
|
7
7
|
import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
|
8
8
|
import { MultiSelectPrompt } from "@clack/core";
|
|
@@ -23,6 +23,7 @@ import { ECRClient, GetAuthorizationTokenCommand } from "@aws-sdk/client-ecr";
|
|
|
23
23
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
24
24
|
import { readFile } from "fs/promises";
|
|
25
25
|
import { join as join$1 } from "path";
|
|
26
|
+
import { unzipSync } from "fflate";
|
|
26
27
|
import { WebSocket, WebSocketServer } from "ws";
|
|
27
28
|
import { createServer as createServer$1 } from "node:http";
|
|
28
29
|
import { createServer as createServer$2 } from "node:https";
|
|
@@ -1367,11 +1368,13 @@ function extractArtifact(artifact, logicalId, stackName, resources, region, imag
|
|
|
1367
1368
|
}
|
|
1368
1369
|
/**
|
|
1369
1370
|
* Extract a `CodeConfiguration` (managed-runtime) artifact. Reads `Runtime`,
|
|
1370
|
-
* `EntryPoint`, and the
|
|
1371
|
-
* (
|
|
1372
|
-
*
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1371
|
+
* `EntryPoint`, and the `Code.S3` location. `Code.S3.Prefix` must be a literal
|
|
1372
|
+
* string (the object key) — it doubles as the cdk.out file-asset hash for the
|
|
1373
|
+
* `fromCodeAsset` shape (`<hash>.zip`). When `Code.S3.Bucket` is ALSO a literal
|
|
1374
|
+
* string, this is a `fromS3` bundle (a pre-existing S3 object — the CDK staging
|
|
1375
|
+
* bucket of a fromCodeAsset renders as an `Fn::Sub` intrinsic, not a literal),
|
|
1376
|
+
* captured in `s3Source` so the command downloads + extracts it. A non-literal
|
|
1377
|
+
* `Code.S3.Prefix` (an unresolved intrinsic) hard-errors.
|
|
1375
1378
|
*/
|
|
1376
1379
|
function extractCodeArtifact(codeConfig, logicalId, stackName) {
|
|
1377
1380
|
const cfg = codeConfig && typeof codeConfig === "object" && !Array.isArray(codeConfig) ? codeConfig : {};
|
|
@@ -1381,12 +1384,22 @@ function extractCodeArtifact(codeConfig, logicalId, stackName) {
|
|
|
1381
1384
|
const entryPoint = Array.isArray(entryPointRaw) ? entryPointRaw.filter((x) => typeof x === "string") : [];
|
|
1382
1385
|
if (entryPoint.length === 0) throw new AgentCoreResolutionError(`AgentCore Runtime '${logicalId}' in ${stackName} has a CodeConfiguration with no EntryPoint.`);
|
|
1383
1386
|
const s3 = cfg["Code"] && typeof cfg["Code"] === "object" ? cfg["Code"]["S3"] : void 0;
|
|
1384
|
-
const
|
|
1385
|
-
|
|
1387
|
+
const s3Obj = s3 && typeof s3 === "object" && !Array.isArray(s3) ? s3 : {};
|
|
1388
|
+
const prefix = s3Obj["Prefix"];
|
|
1389
|
+
if (typeof prefix !== "string" || prefix.length === 0) throw new AgentCoreResolutionError(`AgentCore Runtime '${logicalId}' in ${stackName} has a CodeConfiguration whose Code.S3.Prefix is not a literal string. ${getEmbedConfig().cliName} invoke-agentcore needs a literal object key — re-synthesize a fromCodeAsset bundle, or pass a literal bucket + key for a fromS3 bundle.`);
|
|
1390
|
+
const codeAssetHash = prefix.replace(/^.*\//, "").replace(/\.zip$/, "");
|
|
1391
|
+
const bucket = s3Obj["Bucket"];
|
|
1392
|
+
const versionId = s3Obj["VersionId"];
|
|
1393
|
+
const s3Source = typeof bucket === "string" && bucket.length > 0 ? {
|
|
1394
|
+
bucket,
|
|
1395
|
+
key: prefix,
|
|
1396
|
+
...typeof versionId === "string" && versionId.length > 0 && { versionId }
|
|
1397
|
+
} : void 0;
|
|
1386
1398
|
return {
|
|
1387
1399
|
runtime,
|
|
1388
1400
|
entryPoint,
|
|
1389
|
-
codeAssetHash
|
|
1401
|
+
codeAssetHash,
|
|
1402
|
+
...s3Source && { s3Source }
|
|
1390
1403
|
};
|
|
1391
1404
|
}
|
|
1392
1405
|
/**
|
|
@@ -7719,6 +7732,89 @@ function computeCodeImageTag(sourceDir, runtime, entryPoint, dockerfile) {
|
|
|
7719
7732
|
return `${getEmbedConfig().resourceNamePrefix}-agentcore-code-${hash}`;
|
|
7720
7733
|
}
|
|
7721
7734
|
|
|
7735
|
+
//#endregion
|
|
7736
|
+
//#region src/local/agentcore-s3-bundle.ts
|
|
7737
|
+
/**
|
|
7738
|
+
* Download the bundle object, unzip it to a fresh temp dir, and return the dir
|
|
7739
|
+
* (plus a `cleanup`). The caller feeds `dir` to {@link buildAgentCoreCodeImage}
|
|
7740
|
+
* and calls `cleanup()` once the build is done.
|
|
7741
|
+
*/
|
|
7742
|
+
async function downloadAndExtractS3Bundle(location, options = {}) {
|
|
7743
|
+
const ref = formatRef(location);
|
|
7744
|
+
getLogger().info(`Downloading fromS3 code bundle ${ref}...`);
|
|
7745
|
+
const bytes = await (options.fetchObject ?? defaultFetchObject(options))(location);
|
|
7746
|
+
let files;
|
|
7747
|
+
try {
|
|
7748
|
+
files = unzipSync(bytes);
|
|
7749
|
+
} catch (err) {
|
|
7750
|
+
throw new CdkLocalError(`Failed to unzip the fromS3 code bundle ${ref}: ${err instanceof Error ? err.message : String(err)}. The object must be a ZIP archive of the agent source.`, "LOCAL_INVOKE_AGENTCORE_S3_BUNDLE_UNZIP_FAILED");
|
|
7751
|
+
}
|
|
7752
|
+
const dir = await mkdtemp(join(tmpdir(), `${getEmbedConfig().resourceNamePrefix}-agentcore-s3-`));
|
|
7753
|
+
try {
|
|
7754
|
+
let wrote = 0;
|
|
7755
|
+
for (const [name, content] of Object.entries(files)) {
|
|
7756
|
+
if (name.endsWith("/")) continue;
|
|
7757
|
+
const dest = resolveSafeEntryPath(dir, name);
|
|
7758
|
+
await mkdir(dirname(dest), { recursive: true });
|
|
7759
|
+
await writeFile(dest, content);
|
|
7760
|
+
wrote += 1;
|
|
7761
|
+
}
|
|
7762
|
+
if (wrote === 0) throw new CdkLocalError(`The fromS3 code bundle ${ref} contained no files.`, "LOCAL_INVOKE_AGENTCORE_S3_BUNDLE_EMPTY");
|
|
7763
|
+
} catch (err) {
|
|
7764
|
+
await rm(dir, {
|
|
7765
|
+
recursive: true,
|
|
7766
|
+
force: true
|
|
7767
|
+
}).catch(() => void 0);
|
|
7768
|
+
throw err;
|
|
7769
|
+
}
|
|
7770
|
+
return {
|
|
7771
|
+
dir,
|
|
7772
|
+
cleanup: () => rm(dir, {
|
|
7773
|
+
recursive: true,
|
|
7774
|
+
force: true
|
|
7775
|
+
}).then(() => void 0)
|
|
7776
|
+
};
|
|
7777
|
+
}
|
|
7778
|
+
function formatRef(location) {
|
|
7779
|
+
const version = location.versionId ? `?versionId=${location.versionId}` : "";
|
|
7780
|
+
return `s3://${location.bucket}/${location.key}${version}`;
|
|
7781
|
+
}
|
|
7782
|
+
/**
|
|
7783
|
+
* Guard against zip-slip: reject an entry whose normalized path escapes the
|
|
7784
|
+
* extraction root (e.g. `../../etc/passwd`).
|
|
7785
|
+
*/
|
|
7786
|
+
function resolveSafeEntryPath(root, entry) {
|
|
7787
|
+
const dest = normalize(join(root, entry));
|
|
7788
|
+
const rootWithSep = root.endsWith(sep) ? root : root + sep;
|
|
7789
|
+
if (dest !== root && !dest.startsWith(rootWithSep)) throw new CdkLocalError(`Refusing to extract a fromS3 bundle entry that escapes the target dir: '${entry}'.`, "LOCAL_INVOKE_AGENTCORE_S3_BUNDLE_ZIP_SLIP");
|
|
7790
|
+
return dest;
|
|
7791
|
+
}
|
|
7792
|
+
function defaultFetchObject(options) {
|
|
7793
|
+
return async (location) => {
|
|
7794
|
+
const { S3Client, GetObjectCommand } = await import("@aws-sdk/client-s3");
|
|
7795
|
+
const client = new S3Client({
|
|
7796
|
+
...options.region && { region: options.region },
|
|
7797
|
+
...options.profile && !options.credentials && { profile: options.profile },
|
|
7798
|
+
...options.credentials && { credentials: {
|
|
7799
|
+
accessKeyId: options.credentials.accessKeyId,
|
|
7800
|
+
secretAccessKey: options.credentials.secretAccessKey,
|
|
7801
|
+
...options.credentials.sessionToken && { sessionToken: options.credentials.sessionToken }
|
|
7802
|
+
} }
|
|
7803
|
+
});
|
|
7804
|
+
try {
|
|
7805
|
+
const res = await client.send(new GetObjectCommand({
|
|
7806
|
+
Bucket: location.bucket,
|
|
7807
|
+
Key: location.key,
|
|
7808
|
+
...location.versionId && { VersionId: location.versionId }
|
|
7809
|
+
}));
|
|
7810
|
+
if (!res.Body) throw new CdkLocalError(`S3 GetObject for ${formatRef(location)} returned an empty body.`, "LOCAL_INVOKE_AGENTCORE_S3_BUNDLE_EMPTY_BODY");
|
|
7811
|
+
return await res.Body.transformToByteArray();
|
|
7812
|
+
} finally {
|
|
7813
|
+
client.destroy();
|
|
7814
|
+
}
|
|
7815
|
+
};
|
|
7816
|
+
}
|
|
7817
|
+
|
|
7722
7818
|
//#endregion
|
|
7723
7819
|
//#region src/local/agentcore-client.ts
|
|
7724
7820
|
/**
|
|
@@ -17475,5 +17571,5 @@ function extractDnsRecords(serviceProps) {
|
|
|
17475
17571
|
}
|
|
17476
17572
|
|
|
17477
17573
|
//#endregion
|
|
17478
|
-
export { attachAuthorizers as $,
|
|
17479
|
-
//# sourceMappingURL=cloud-map-resolver-
|
|
17574
|
+
export { attachAuthorizers as $, substituteAgainstState as $t, buildHttpApiV2Event as A, AGENTCORE_RUNTIME_TYPE as An, buildDockerImage as At, ConnectionRegistry as B, readCdkPathOrUndefined as Bn, streamLogs as Bt, computeRequestIdentityHash as C, discoverWebSocketApisOrThrow as Cn, getDockerImageBySourceHash as Ct, matchRoute as D, resolveLambdaArnIntrinsic as Dn, buildContainerImage as Dt, invokeTokenAuthorizer as E, pickRefLogicalId as En, architectureToPlatform as Et, tryParseStatus as F, derivePseudoParametersFromRegion as Fn, execEnvForSecrets as Ft, buildDisconnectEvent as G, withErrorHandling as Gn, TASK_ROLE_ACCOUNT_PLACEHOLDER as Gt, handleConnectionsRequest as H, CdkLocalError as Hn, resolveRuntimeFileExtension as Ht, VtlEvaluationError as I, substituteImagePlaceholders as In, pickFreePort as It, buildJwksUrlFromIssuer as J, commonOptions as Jn, derivePartitionAndUrlSuffix as Jt, buildMessageEvent as K, applyRoleArnIfSet as Kn, applyCrossStackResolverToTask as Kt, HOST_GATEWAY_MIN_VERSION as L, tryResolveImageFnJoin as Ln, pullImage as Lt, evaluateResponseParameters as M, pickAgentCoreCandidateStack as Mn, SENSITIVE_ENV_KEYS as Mt, pickResponseTemplate as N, resolveAgentCoreTarget as Nn, appendEnvFlags as Nt, translateLambdaResponse as O, AGENTCORE_HTTP_PROTOCOL as On, parseEcrUri as Ot, selectIntegrationResponse as P, resolveLambdaTarget as Pn, ensureDockerAvailable as Pt, verifyJwtViaDiscovery as Q, warnIfDeprecatedRegion as Qn, applyDeployedEnvFallback as Qt, probeHostGatewaySupport as R, matchStacks as Rn, removeContainer as Rt, buildMethodArn as S, discoverWebSocketApis as Sn, AssetManifestLoader as St, invokeRequestAuthorizer as T, discoverRoutes as Tn, waitForRieReady as Tt, parseConnectionsPath as U, LocalInvokeBuildError as Un, resolveRuntimeImage as Ut, buildMgmtEndpointEnvUrl as V, resolveCdkPathToLogicalIds as Vn, resolveRuntimeCodeMountPath as Vt, buildConnectEvent as W, LocalStartServiceError as Wn, EcsTaskResolutionError as Wt, verifyCognitoJwt as X, deprecatedRegionOption as Xn, parseEcsTarget as Xt, createJwksCache as Y, contextOptions as Yn, detectEcsImageResolutionNeeds as Yt, verifyJwtAuthorizer as Z, parseContextOptions as Zn, resolveEcsTaskTarget as Zt, readMtlsMaterialsFromDisk as _, Synthesizer as _n, computeCodeImageTag as _t, createLocalStartApiCommand as a, LocalStateSourceError as an, invokeAgentCoreWs as at, resolveServiceIntegrationParameters as b, countTargets as bn, writeProfileCredentialsFile as bt, resolveProfileCredentials as c, rejectExplicitCfnStackWithMultipleStacks as cn, MCP_PROTOCOL_VERSION as ct, attachStageContext as d, resolveCfnStackName as dn, AGENTCORE_SESSION_ID_HEADER as dt, substituteAgainstStateAsync as en, applyCorsResponseHeaders as et, buildStageMap as f, CfnLocalStateProvider as fn, invokeAgentCore as ft, groupRoutesByServer as g, resolveWatchConfig as gn, buildAgentCoreCodeImage as gt, filterRoutesByApiIdentifiers as h, resolveApp as hn, SUPPORTED_CODE_RUNTIMES as ht, getPublishedHostPort as i, materializeLayerFromArn as in, matchPreflight as it, buildRestV1Event as j, AgentCoreResolutionError as jn, DockerRunnerError as jt, applyAuthorizerOverlay as k, AGENTCORE_MCP_PROTOCOL as kn, pullEcrImage as kt, createAuthorizerCache as l, resolveCfnFallbackRegion as ln, mcpInvokeOnce as lt, filterRoutesByApiIdentifier as m, resolveSsmParameters as mn, downloadAndExtractS3Bundle as mt, CloudMapRegistry as n, substituteEnvVarsFromStateAsync as nn, buildCorsConfigFromCloudFrontChain as nt, createWatchPredicates as o, createLocalStateProvider as on, MCP_CONTAINER_PORT as ot, availableApiIdentifiers as p, collectSsmParameterRefs as pn, waitForAgentCorePing as pt, buildCognitoJwksUrl as q, appOptions as qn, checkVolumeHostPath as qt, getContainerNetworkIp as r, resolveEnvVars as rn, isFunctionUrlOacFronted as rt, resolveApiTargetSubset as s, isCfnFlagPresent as sn, MCP_PATH as st, buildCloudMapIndex as t, substituteEnvVarsFromState as tn, buildCorsConfigByApiId as tt, createFileWatcher as u, resolveCfnRegion as un, parseSseForJsonRpc as ut, startApiServer as v, resolveMultiTarget as vn, renderCodeDockerfile as vt, evaluateCachedLambdaPolicy as w, parseSelectionExpressionPath as wn, invokeRie as wt, defaultCredentialsLoader as x, listTargets as xn, singleFlight as xt, resolveSelectionExpression as y, resolveSingleTarget as yn, toCmdArgv as yt, bufferToBody as z, buildCdkPathIndex as zn, runDetached as zt };
|
|
17575
|
+
//# sourceMappingURL=cloud-map-resolver-CW4Paz5K.js.map
|