cdk-local 0.95.0 → 0.96.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 +19 -1
- package/dist/cli.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +5 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-studio-D4xCanIE.d.ts → local-studio-BOLwXNkK.d.ts} +3 -1
- package/dist/{local-studio-D4xCanIE.d.ts.map → local-studio-BOLwXNkK.d.ts.map} +1 -1
- package/dist/{local-studio-Dd271q0Z.js → local-studio-DMYaMyCf.js} +106 -8
- package/dist/{local-studio-Dd271q0Z.js.map → local-studio-DMYaMyCf.js.map} +1 -1
- package/package.json +1 -1
|
@@ -28561,6 +28561,9 @@ const STUDIO_CSS = `
|
|
|
28561
28561
|
.pair-add { align-self: flex-start; background: #1d1d1d; color: #7bd88f; border: 1px solid #2f4030;
|
|
28562
28562
|
border-radius: 3px; cursor: pointer; padding: 3px 9px; font: 12px ui-monospace, monospace; }
|
|
28563
28563
|
.pair-add:hover { background: #243024; }
|
|
28564
|
+
.options select { flex: 1; background: #111; color: #ddd; border: 1px solid #333; border-radius: 3px;
|
|
28565
|
+
padding: 4px 6px; font: 12px ui-monospace, Menlo, monospace; min-width: 0; }
|
|
28566
|
+
.options select:focus { outline: none; border-color: #4ec97a; }
|
|
28564
28567
|
details.all-options { margin: 8px 0; border-top: 1px solid #2a2a2a; padding-top: 6px; }
|
|
28565
28568
|
details.all-options > summary { color: #8a8a8a; font-size: 12px; cursor: pointer; user-select: none; }
|
|
28566
28569
|
details.all-options > summary:hover { color: #bbb; }
|
|
@@ -28599,6 +28602,7 @@ const STUDIO_SCRIPT = `
|
|
|
28599
28602
|
let shownInvId = null; // lambda invocation whose result is in the workspace
|
|
28600
28603
|
let shownServeId = null; // serve target whose workspace is shown
|
|
28601
28604
|
let shownDetailId = null; // captured request whose read-only detail is shown
|
|
28605
|
+
let studioDockerfiles = []; // Dockerfiles scanned at boot (pinned-ecs image-override picker)
|
|
28602
28606
|
|
|
28603
28607
|
function el(tag, cls, text) {
|
|
28604
28608
|
const e = document.createElement(tag);
|
|
@@ -28798,11 +28802,48 @@ const STUDIO_SCRIPT = `
|
|
|
28798
28802
|
};
|
|
28799
28803
|
}
|
|
28800
28804
|
|
|
28805
|
+
// Image-override picker for a pinned ECS service (issue #301): a select of
|
|
28806
|
+
// the Dockerfiles discovered at boot. Picking one threads an
|
|
28807
|
+
// --image-override flag to start-service so the deployed-registry-pinned
|
|
28808
|
+
// image is rebuilt from local source. Default "(keep pinned image)" => no
|
|
28809
|
+
// override.
|
|
28810
|
+
function buildImageOverridePicker() {
|
|
28811
|
+
const sec = el('div', 'section options');
|
|
28812
|
+
sec.appendChild(el('h3', null, 'Image override'));
|
|
28813
|
+
const row = el('div', 'opt-row');
|
|
28814
|
+
row.appendChild(el('span', 'opt-label', 'Local Dockerfile'));
|
|
28815
|
+
const sel = el('select', 'image-override-select');
|
|
28816
|
+
const none = el('option', null, '(keep pinned image)');
|
|
28817
|
+
none.value = '';
|
|
28818
|
+
sel.appendChild(none);
|
|
28819
|
+
studioDockerfiles.forEach(function (df) {
|
|
28820
|
+
const o = el('option', null, df);
|
|
28821
|
+
o.value = df;
|
|
28822
|
+
sel.appendChild(o);
|
|
28823
|
+
});
|
|
28824
|
+
row.appendChild(sel);
|
|
28825
|
+
sec.appendChild(row);
|
|
28826
|
+
const hint = studioDockerfiles.length
|
|
28827
|
+
? 'This image is pinned to a deployed registry — local edits do not take effect. Pick a Dockerfile to rebuild it locally.'
|
|
28828
|
+
: 'This image is pinned to a deployed registry, but no Dockerfile was found under the app directory.';
|
|
28829
|
+
sec.appendChild(el('div', 'opt-hint', hint));
|
|
28830
|
+
return {
|
|
28831
|
+
node: sec,
|
|
28832
|
+
collect: function () {
|
|
28833
|
+
const v = sel.value.trim();
|
|
28834
|
+
return v === '' ? undefined : v;
|
|
28835
|
+
},
|
|
28836
|
+
};
|
|
28837
|
+
}
|
|
28838
|
+
|
|
28801
28839
|
async function loadTargets() {
|
|
28802
28840
|
const pane = document.getElementById('targets');
|
|
28803
28841
|
try {
|
|
28804
28842
|
const res = await fetch('/api/targets');
|
|
28805
28843
|
const data = await res.json();
|
|
28844
|
+
// Dockerfiles discovered at boot — offered in a pinned ecs service's
|
|
28845
|
+
// image-override picker (issue #301).
|
|
28846
|
+
studioDockerfiles = Array.isArray(data.dockerfiles) ? data.dockerfiles : [];
|
|
28806
28847
|
pane.querySelectorAll('.group-title,.target,.empty').forEach((n) => n.remove());
|
|
28807
28848
|
let total = 0;
|
|
28808
28849
|
for (const group of data.groups) {
|
|
@@ -28836,7 +28877,7 @@ const STUDIO_SCRIPT = `
|
|
|
28836
28877
|
t.appendChild(btnSlot);
|
|
28837
28878
|
t.onclick = () => selectTarget(entry.id, group.kind);
|
|
28838
28879
|
targetEls.set(entry.id, t);
|
|
28839
|
-
serveMeta.set(entry.id, { dot, btnSlot, kind: group.kind });
|
|
28880
|
+
serveMeta.set(entry.id, { dot, btnSlot, kind: group.kind, pinned: entry.pinned === true });
|
|
28840
28881
|
updateServeRow(entry.id);
|
|
28841
28882
|
}
|
|
28842
28883
|
pane.appendChild(t);
|
|
@@ -28919,7 +28960,7 @@ const STUDIO_SCRIPT = `
|
|
|
28919
28960
|
}
|
|
28920
28961
|
}
|
|
28921
28962
|
|
|
28922
|
-
async function startServe(id, options, rawArgs) {
|
|
28963
|
+
async function startServe(id, options, rawArgs, imageOverride) {
|
|
28923
28964
|
// The serve kind (api / alb / ecs) drives which headless command the
|
|
28924
28965
|
// server spawns; it is recorded on the row when the target list loads.
|
|
28925
28966
|
const meta = serveMeta.get(id);
|
|
@@ -28930,6 +28971,7 @@ const STUDIO_SCRIPT = `
|
|
|
28930
28971
|
const body = { targetId: id, kind };
|
|
28931
28972
|
if (options) body.options = options;
|
|
28932
28973
|
if (rawArgs) body.rawArgs = rawArgs;
|
|
28974
|
+
if (imageOverride) body.imageOverride = imageOverride;
|
|
28933
28975
|
const res = await fetch('/api/run', {
|
|
28934
28976
|
method: 'POST',
|
|
28935
28977
|
headers: { 'content-type': 'application/json' },
|
|
@@ -28987,7 +29029,8 @@ const STUDIO_SCRIPT = `
|
|
|
28987
29029
|
// Per-run options are only set before a start; collected on the Start click.
|
|
28988
29030
|
let collectOpts = function () { return undefined; };
|
|
28989
29031
|
let collectRaw = function () { return undefined; };
|
|
28990
|
-
|
|
29032
|
+
let collectImageOverride = function () { return undefined; };
|
|
29033
|
+
btn.onclick = () => { if (running || starting) stopServe(id); else startServe(id, collectOpts(), collectRaw(), collectImageOverride()); };
|
|
28991
29034
|
head.appendChild(btn);
|
|
28992
29035
|
if (errMsg) {
|
|
28993
29036
|
const m = el('div', 'err', errMsg);
|
|
@@ -28996,6 +29039,15 @@ const STUDIO_SCRIPT = `
|
|
|
28996
29039
|
ws.appendChild(head);
|
|
28997
29040
|
|
|
28998
29041
|
if (!running && !starting) {
|
|
29042
|
+
// A pinned ECS service (deployed-registry image) does not pick up local
|
|
29043
|
+
// source edits — offer an image-override Dockerfile picker so it can be
|
|
29044
|
+
// rebuilt locally (issue #301). Local-asset services hot-reload under
|
|
29045
|
+
// --watch and get no picker.
|
|
29046
|
+
if (meta && meta.kind === 'ecs' && meta.pinned) {
|
|
29047
|
+
const io = buildImageOverridePicker();
|
|
29048
|
+
ws.appendChild(io.node);
|
|
29049
|
+
collectImageOverride = io.collect;
|
|
29050
|
+
}
|
|
28999
29051
|
const opt = buildOptions(kind);
|
|
29000
29052
|
if (opt.node) ws.appendChild(opt.node);
|
|
29001
29053
|
collectOpts = opt.collect;
|
|
@@ -29681,6 +29733,33 @@ function toStudioTargetGroups(listing) {
|
|
|
29681
29733
|
}
|
|
29682
29734
|
];
|
|
29683
29735
|
}
|
|
29736
|
+
/**
|
|
29737
|
+
* Annotate the servable `ecs` service entries of `groups` with `pinned: true`
|
|
29738
|
+
* when `classify(targetId)` returns true (issue #301). `classify` decides
|
|
29739
|
+
* pinned (deployed-registry image) vs local CDK asset for one service id; the
|
|
29740
|
+
* caller supplies it (studio's boot does `resolveEcsServiceTarget` +
|
|
29741
|
+
* `isLocalCdkAssetImage`, swallowing resolution failures as "not pinned").
|
|
29742
|
+
* Mutates the entries in place and returns whether ANY service was pinned, so
|
|
29743
|
+
* the caller can skip the (otherwise pointless) Dockerfile scan for an
|
|
29744
|
+
* all-local-asset app. Non-ecs groups and non-servable entries (task defs) are
|
|
29745
|
+
* left untouched. Exported so a host CLI building its own studio can reuse the
|
|
29746
|
+
* same pinned-target annotation, and so the boot logic is unit-testable
|
|
29747
|
+
* without a real synth.
|
|
29748
|
+
*/
|
|
29749
|
+
function annotatePinnedEcsTargets(groups, classify) {
|
|
29750
|
+
let anyPinned = false;
|
|
29751
|
+
for (const group of groups) {
|
|
29752
|
+
if (group.kind !== "ecs") continue;
|
|
29753
|
+
for (const entry of group.entries) {
|
|
29754
|
+
if (!entry.servable) continue;
|
|
29755
|
+
if (classify(entry.id)) {
|
|
29756
|
+
entry.pinned = true;
|
|
29757
|
+
anyPinned = true;
|
|
29758
|
+
}
|
|
29759
|
+
}
|
|
29760
|
+
}
|
|
29761
|
+
return anyPinned;
|
|
29762
|
+
}
|
|
29684
29763
|
/** Compile a `*` / `?` glob to an anchored RegExp matched against a target id. */
|
|
29685
29764
|
function globToRegExp(glob) {
|
|
29686
29765
|
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
@@ -29714,7 +29793,10 @@ async function startStudioServer(options) {
|
|
|
29714
29793
|
const host = options.host ?? "127.0.0.1";
|
|
29715
29794
|
const maxBump = options.maxPortBump ?? 20;
|
|
29716
29795
|
const html = renderStudioHtml(options.appLabel, options.cliName);
|
|
29717
|
-
const targetsJson = JSON.stringify({
|
|
29796
|
+
const targetsJson = JSON.stringify({
|
|
29797
|
+
groups: options.targetGroups,
|
|
29798
|
+
dockerfiles: options.dockerfiles ?? []
|
|
29799
|
+
});
|
|
29718
29800
|
const server = createServer$1((req, res) => handleRequest(req, res, options.bus, html, targetsJson, options));
|
|
29719
29801
|
const boundPort = await listenWithBump(server, host, options.port, maxBump);
|
|
29720
29802
|
return {
|
|
@@ -30530,6 +30612,7 @@ function createStudioServeManager(config) {
|
|
|
30530
30612
|
...spec.portArgs,
|
|
30531
30613
|
...buildSharedChildArgs(config),
|
|
30532
30614
|
...buildPerRunArgs(req.kind, req.options),
|
|
30615
|
+
...req.imageOverride && req.imageOverride.trim() !== "" ? ["--image-override", req.targetId + "=" + req.imageOverride.trim()] : [],
|
|
30533
30616
|
...config.watch === true ? ["--watch"] : [],
|
|
30534
30617
|
...tokenizeRawArgs(req.rawArgs)
|
|
30535
30618
|
];
|
|
@@ -30752,7 +30835,7 @@ const STUDIO_TARGET_KINDS = [
|
|
|
30752
30835
|
*/
|
|
30753
30836
|
function coerceRunRequest(body) {
|
|
30754
30837
|
if (typeof body !== "object" || body === null) throw new Error("Request body must be a JSON object.");
|
|
30755
|
-
const { targetId, kind, event, options, rawArgs } = body;
|
|
30838
|
+
const { targetId, kind, event, options, rawArgs, imageOverride } = body;
|
|
30756
30839
|
if (typeof targetId !== "string" || targetId.trim() === "") throw new Error("Request body must include a non-empty \"targetId\" string.");
|
|
30757
30840
|
if (typeof kind !== "string" || !STUDIO_TARGET_KINDS.includes(kind)) throw new Error(`Request body "kind" must be one of: ${STUDIO_TARGET_KINDS.join(", ")}.`);
|
|
30758
30841
|
let runOptions;
|
|
@@ -30768,12 +30851,18 @@ function coerceRunRequest(body) {
|
|
|
30768
30851
|
tokenizeRawArgs(rawArgs);
|
|
30769
30852
|
runRawArgs = rawArgs;
|
|
30770
30853
|
}
|
|
30854
|
+
let runImageOverride;
|
|
30855
|
+
if (imageOverride !== void 0) {
|
|
30856
|
+
if (typeof imageOverride !== "string") throw new Error("Request body \"imageOverride\" must be a string.");
|
|
30857
|
+
if (imageOverride.trim() !== "") runImageOverride = imageOverride;
|
|
30858
|
+
}
|
|
30771
30859
|
return {
|
|
30772
30860
|
targetId,
|
|
30773
30861
|
kind,
|
|
30774
30862
|
event,
|
|
30775
30863
|
...runOptions !== void 0 ? { options: runOptions } : {},
|
|
30776
|
-
...runRawArgs !== void 0 ? { rawArgs: runRawArgs } : {}
|
|
30864
|
+
...runRawArgs !== void 0 ? { rawArgs: runRawArgs } : {},
|
|
30865
|
+
...runImageOverride !== void 0 ? { imageOverride: runImageOverride } : {}
|
|
30777
30866
|
};
|
|
30778
30867
|
}
|
|
30779
30868
|
/**
|
|
@@ -30859,6 +30948,14 @@ async function localStudioCommand(options) {
|
|
|
30859
30948
|
}
|
|
30860
30949
|
const appLabel = stacks.map((s) => s.stackName).join(", ") || appCmd;
|
|
30861
30950
|
const servableEcs = new Set(targetGroups.filter((g) => g.kind === "ecs").flatMap((g) => g.entries.filter((e) => e.servable).map((e) => e.id)));
|
|
30951
|
+
const dockerfiles = annotatePinnedEcsTargets(targetGroups, (id) => {
|
|
30952
|
+
try {
|
|
30953
|
+
return !isLocalCdkAssetImage(resolveEcsServiceTarget(id, stacks));
|
|
30954
|
+
} catch (err) {
|
|
30955
|
+
logger.debug(`studio: could not classify pin status for '${id}': ${err instanceof Error ? err.message : String(err)}`);
|
|
30956
|
+
return false;
|
|
30957
|
+
}
|
|
30958
|
+
}) ? discoverDockerfiles(process.cwd()) : [];
|
|
30862
30959
|
const bus = new StudioEventBus();
|
|
30863
30960
|
const childConfig = {
|
|
30864
30961
|
cliEntry: process.argv[1] ?? "",
|
|
@@ -30889,6 +30986,7 @@ async function localStudioCommand(options) {
|
|
|
30889
30986
|
port,
|
|
30890
30987
|
bus,
|
|
30891
30988
|
targetGroups,
|
|
30989
|
+
dockerfiles,
|
|
30892
30990
|
appLabel,
|
|
30893
30991
|
cliName: getEmbedConfig().cliName,
|
|
30894
30992
|
store,
|
|
@@ -30984,5 +31082,5 @@ function addStudioSpecificOptions(cmd) {
|
|
|
30984
31082
|
}
|
|
30985
31083
|
|
|
30986
31084
|
//#endregion
|
|
30987
|
-
export {
|
|
30988
|
-
//# sourceMappingURL=local-studio-
|
|
31085
|
+
export { DEFAULT_SHADOW_READY_TIMEOUT_MS as $, countTargets as $n, verifyJwtViaDiscovery as $t, MAX_TASKS_SUBNET_RANGE_CAP as A, buildMessageEvent as An, createLocalStartApiCommand as At, runEcsServiceEmulator as B, substituteEnvVarsFromStateAsync as Bn, filterRoutesByApiIdentifier as Bt, isApplicationLoadBalancer as C, bufferToBody as Cn, buildStsClientConfig as Cr, computeCodeImageTag as Ct, serviceStrategy as D, parseConnectionsPath as Dn, addInvokeSpecificOptions as Dt, createLocalStartServiceCommand as E, handleConnectionsRequest as En, classifySourceChange as Et, ecsClusterOption as F, resolveRuntimeImage as Fn, attachStageContext as Ft, parseImageOverrideFlags as G, resolveCfnFallbackRegion as Gn, resolveSelectionExpression as Gt, buildImageOverrideTag as H, createLocalStateProvider as Hn, groupRoutesByServer as Ht, parseMaxTasks as I, EcsTaskResolutionError as In, buildStageMap as It, describePinnedImageUri as J, CfnLocalStateProvider as Jn, buildCognitoJwksUrl as Jt, resolveImageOverrides as K, resolveCfnRegion as Kn, resolveServiceIntegrationParameters as Kt, parseRestartPolicy as L, substituteAgainstState as Ln, materializeLayerFromArn as Lt, addEcsAssumeRoleOptions as M, buildContainerImage as Mn, resolveApiTargetSubset as Mt, addImageOverrideOptions as N, resolveRuntimeCodeMountPath as Nn, createAuthorizerCache as Nt, addRunTaskSpecificOptions as O, buildConnectEvent as On, createLocalInvokeCommand as Ot, buildEcsImageResolutionContext$1 as P, resolveRuntimeFileExtension as Pn, createFileWatcher as Pt, CloudMapRegistry as Q, resolveSingleTarget as Qn, verifyJwtAuthorizer as Qt, resolveEcsAssumeRoleOption as R, substituteAgainstStateAsync as Rn, resolveEnvVars$1 as Rt, resolveAlbTarget as S, probeHostGatewaySupport as Sn, LocalInvokeBuildError as Sr, buildAgentCoreCodeImage as St, addStartServiceSpecificOptions as T, buildMgmtEndpointEnvUrl as Tn, toCmdArgv as Tt, enforceImageOverrideOrphans as U, isCfnFlagPresent as Un, readMtlsMaterialsFromDisk as Ut, ImageOverrideError as V, LocalStateSourceError as Vn, filterRoutesByApiIdentifiers as Vt, mergeForService as W, rejectExplicitCfnStackWithMultipleStacks as Wn, startApiServer as Wt, listPinnedTargets as X, resolveSsmParameters as Xn, createJwksCache as Xt, isLocalCdkAssetImage as Y, collectSsmParameterRefs as Yn, buildJwksUrlFromIssuer as Yt, buildCloudMapIndex as Z, resolveWatchConfig as Zn, verifyCognitoJwt as Zt, formatTargetListing as _, pickResponseTemplate as _n, resolveAgentCoreTarget as _r, AGENTCORE_SESSION_ID_HEADER as _t, createStudioServeManager as a, attachAuthorizers as an, parseSelectionExpressionPath as ar, createLocalInvokeAgentCoreCommand as at, createLocalStartAlbCommand as b, VtlEvaluationError as bn, substituteImagePlaceholders as br, downloadAndExtractS3Bundle as bt, annotatePinnedEcsTargets as c, buildCorsConfigFromCloudFrontChain as cn, pickRefLogicalId as cr, A2A_PATH as ct, toStudioTargetGroups as d, matchRoute as dn, AGENTCORE_AGUI_PROTOCOL as dr, MCP_PATH as dt, buildMethodArn as en, listTargets as er, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as et, renderStudioHtml as f, translateLambdaResponse as fn, AGENTCORE_HTTP_PROTOCOL as fr, MCP_PROTOCOL_VERSION as ft, createLocalListCommand as g, evaluateResponseParameters as gn, pickAgentCoreCandidateStack as gr, signAgentCoreInvocation as gt, addListSpecificOptions as h, buildRestV1Event as hn, AgentCoreResolutionError as hr, AGENTCORE_SIGV4_SERVICE as ht, createLocalStudioCommand as i, invokeTokenAuthorizer as in, filterWebSocketApisByIdentifiers as ir, addInvokeAgentCoreSpecificOptions as it, addCommonEcsServiceOptions as j, architectureToPlatform as jn, createWatchPredicates as jt, createLocalRunTaskCommand as k, buildDisconnectEvent as kn, addStartApiSpecificOptions as kt, filterStudioTargetGroups as l, isFunctionUrlOacFronted as ln, resolveLambdaArnIntrinsic as lr, a2aInvokeOnce as lt, StudioEventBus as m, buildHttpApiV2Event as mn, AGENTCORE_RUNTIME_TYPE as mr, parseSseForJsonRpc as mt, coerceRunRequest as n, evaluateCachedLambdaPolicy as nn, discoverWebSocketApis as nr, getContainerNetworkIp as nt, startStudioProxy as o, applyCorsResponseHeaders as on, webSocketApiMatchesIdentifier as or, invokeAgentCoreWs as ot, createStudioStore as p, applyAuthorizerOverlay as pn, AGENTCORE_MCP_PROTOCOL as pr, mcpInvokeOnce as pt, runImageOverrideBuilds as q, resolveCfnStackName as qn, defaultCredentialsLoader as qt, coerceStopRequest as r, invokeRequestAuthorizer as rn, discoverWebSocketApisOrThrow as rr, attachContainerLogStreamer as rt, createStudioDispatcher as s, buildCorsConfigByApiId as sn, discoverRoutes as sr, A2A_CONTAINER_PORT as st, addStudioSpecificOptions as t, computeRequestIdentityHash as tn, availableWebSocketApiIdentifiers as tr, setShadowReadyTimeoutMs as tt, startStudioServer as u, matchPreflight as un, AGENTCORE_A2A_PROTOCOL as ur, MCP_CONTAINER_PORT as ut, addAlbSpecificOptions as v, selectIntegrationResponse as vn, derivePseudoParametersFromRegion as vr, invokeAgentCore as vt, resolveAlbFrontDoor as w, ConnectionRegistry as wn, resolveProfileCredentials as wr, renderCodeDockerfile as wt, parseLbPortOverrides as x, HOST_GATEWAY_MIN_VERSION as xn, tryResolveImageFnJoin as xr, SUPPORTED_CODE_RUNTIMES as xt, albStrategy as y, tryParseStatus as yn, formatStateRemedy as yr, waitForAgentCorePing as yt, resolveSharedSidecarCredentials as z, substituteEnvVarsFromState as zn, availableApiIdentifiers as zt };
|
|
31086
|
+
//# sourceMappingURL=local-studio-DMYaMyCf.js.map
|