cdk-local 0.147.13 → 0.147.15
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/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/local-studio-BBA_8Xvk.d.ts.map +1 -1
- package/dist/{local-studio-5iIuMtjd.js → local-studio-BJxBmC75.js} +401 -56
- package/dist/local-studio-BJxBmC75.js.map +1 -0
- package/package.json +1 -1
- package/dist/local-studio-5iIuMtjd.js.map +0 -1
|
@@ -322,13 +322,15 @@ function buildStsClientConfig(args) {
|
|
|
322
322
|
*
|
|
323
323
|
* # What this does NOT close
|
|
324
324
|
*
|
|
325
|
-
* A single-LINE forged string still reaches readers other than a human.
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
325
|
+
* A single-LINE forged string still reaches readers other than a human. It no
|
|
326
|
+
* longer redirects the studio capture proxy: issue #578 anchored every
|
|
327
|
+
* `cdkl studio` ready pattern to the start of the line, made the serve manager
|
|
328
|
+
* skip a line carrying cdk-local's own `WARN: ` / `ERROR: ` decoration
|
|
329
|
+
* outright, and bounded the resolved upstream to loopback — so a message
|
|
330
|
+
* containing `Server listening on http://...` is neither read as a banner nor
|
|
331
|
+
* usable as a destination. What remains is the reader this sanitizer was
|
|
332
|
+
* always aimed at: a HUMAN scanning the log, for whom a forged-looking line is
|
|
333
|
+
* still misleading text, which is why the flattening + capping stay.
|
|
332
334
|
*/
|
|
333
335
|
/**
|
|
334
336
|
* Longest service-exception message relayed into a `warn` line, in
|
|
@@ -5160,16 +5162,25 @@ async function fetchAllExports(client) {
|
|
|
5160
5162
|
* S3-bucket-specific (it rewrites the synthetic `Unknown`/`UnknownError`
|
|
5161
5163
|
* with bucket / region context), so the CFn provider extracts the
|
|
5162
5164
|
* pieces directly here.
|
|
5165
|
+
*
|
|
5166
|
+
* Issue #578 — the result is FLATTENED TO ONE LINE via
|
|
5167
|
+
* {@link flattenToOneLine}, the same helper `credential-error` applies to
|
|
5168
|
+
* every other wire-derived value that lands on a log line, rather than a
|
|
5169
|
+
* second spelling of it. Both `err.name` and `err.message` come off the wire,
|
|
5170
|
+
* and this warn is relayed onto a `cdkl studio` serve child's stdout, where
|
|
5171
|
+
* `studio-serve-manager` splits on `\n`: an embedded newline puts line 2 on
|
|
5172
|
+
* the stream with no `WARN: ` prefix, so it clears the diagnostic bound and
|
|
5173
|
+
* matches a ready pattern at `^`. One line in, one line out.
|
|
5163
5174
|
*/
|
|
5164
5175
|
function formatAwsErrorForWarn(err) {
|
|
5165
|
-
if (!(err instanceof Error)) return String(err);
|
|
5176
|
+
if (!(err instanceof Error)) return flattenToOneLine(String(err));
|
|
5166
5177
|
const name = err.name && err.name !== "Error" ? err.name : void 0;
|
|
5167
5178
|
const status = err.$metadata?.httpStatusCode;
|
|
5168
5179
|
const prefixParts = [];
|
|
5169
5180
|
if (name !== void 0) prefixParts.push(name);
|
|
5170
5181
|
if (status !== void 0) prefixParts.push(`HTTP ${status}`);
|
|
5171
|
-
if (prefixParts.length === 0) return err.message;
|
|
5172
|
-
return `${prefixParts.join(" ")}: ${err.message}
|
|
5182
|
+
if (prefixParts.length === 0) return flattenToOneLine(err.message);
|
|
5183
|
+
return flattenToOneLine(`${prefixParts.join(" ")}: ${err.message}`);
|
|
5173
5184
|
}
|
|
5174
5185
|
|
|
5175
5186
|
//#endregion
|
|
@@ -36990,6 +37001,154 @@ async function relayServeRequest(input, fetchFn = fetch, clock = Date.now) {
|
|
|
36990
37001
|
//#region src/local/studio-proxy.ts
|
|
36991
37002
|
let proxyIdCounter = 0;
|
|
36992
37003
|
/**
|
|
37004
|
+
* True when `hostname` names this machine's loopback interface: `localhost`,
|
|
37005
|
+
* an IPv4 address in `127.0.0.0/8`, IPv6 `::1`, or an IPv4-mapped loopback
|
|
37006
|
+
* (`::ffff:127.0.0.1`, which `URL.hostname` renders in hex as
|
|
37007
|
+
* `[::ffff:7f00:1]`). Surrounding brackets, as `URL.hostname` keeps them for
|
|
37008
|
+
* an IPv6 literal, are tolerated. The match is EXACT — `localhost.example.com`
|
|
37009
|
+
* and `127.0.0.1.example.com` are ordinary DNS names that resolve wherever
|
|
37010
|
+
* their owner points them, and are NOT loopback.
|
|
37011
|
+
*
|
|
37012
|
+
* A `cdkl` serve child always listens on this machine, so this is the bound
|
|
37013
|
+
* studio puts on where it will ever forward a composer request (issue #578).
|
|
37014
|
+
* A destination that is not loopback did not come from a genuine serve, and
|
|
37015
|
+
* forwarding to it would carry the developer's request — headers and body —
|
|
37016
|
+
* off-box.
|
|
37017
|
+
*/
|
|
37018
|
+
function isLoopbackHostname(hostname) {
|
|
37019
|
+
const h = hostname.trim().replace(/^\[/, "").replace(/\]$/, "").toLowerCase();
|
|
37020
|
+
if (h === "localhost") return true;
|
|
37021
|
+
if (h === "::1" || h === "0:0:0:0:0:0:0:1") return true;
|
|
37022
|
+
const mapped = /^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/.exec(h);
|
|
37023
|
+
if (mapped) return parseInt(mapped[1], 16) >> 8 === 127;
|
|
37024
|
+
const dotted = /^(?:::ffff:)?(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(h);
|
|
37025
|
+
if (!dotted) return false;
|
|
37026
|
+
const octets = dotted.slice(1).map(Number);
|
|
37027
|
+
if (octets.some((o) => o > 255)) return false;
|
|
37028
|
+
return octets[0] === 127;
|
|
37029
|
+
}
|
|
37030
|
+
/**
|
|
37031
|
+
* Drop the brackets `URL.hostname` keeps around an IPv6 literal (`[::1]`), so
|
|
37032
|
+
* the host can be handed to `node:http` / `node:net`.
|
|
37033
|
+
*
|
|
37034
|
+
* Those two disagree with `URL` about the spelling: `http.request({ host:
|
|
37035
|
+
* '[::1]' })` fails with `ENOTFOUND` (it is looked up as a NAME), while `'::1'`
|
|
37036
|
+
* connects. {@link isLoopbackHostname} already tolerates the bracketed form —
|
|
37037
|
+
* so `--host ::1` on a serve child yields an upstream this proxy ACCEPTS and
|
|
37038
|
+
* then 502s every request through, which is the worst of the three outcomes.
|
|
37039
|
+
* Bracket-stripping is safe for every other spelling: a dotted IPv4, a name
|
|
37040
|
+
* and a bare hextet form carry no brackets to remove.
|
|
37041
|
+
*/
|
|
37042
|
+
function stripHostBrackets(hostname) {
|
|
37043
|
+
return hostname.replace(/^\[/, "").replace(/\]$/, "");
|
|
37044
|
+
}
|
|
37045
|
+
/**
|
|
37046
|
+
* True when `hostname` is the UNSPECIFIED (wildcard) address: IPv4 `0.0.0.0`,
|
|
37047
|
+
* IPv6 `::` (`URL` normalises `0:0:0:0:0:0:0:0` to it), or the IPv4-mapped
|
|
37048
|
+
* `::ffff:0.0.0.0` (which `URL.hostname` renders as `[::ffff:0:0]`).
|
|
37049
|
+
*
|
|
37050
|
+
* A wildcard is a BIND address, not a destination — a server bound to it IS
|
|
37051
|
+
* reachable on loopback, and `--container-host 0.0.0.0` is an ordinary value
|
|
37052
|
+
* for `start-service` / `run-task` (default `127.0.0.1`) that `cdkl studio`
|
|
37053
|
+
* auto-renders in its "All options" section. So a wildcard is normalised to
|
|
37054
|
+
* loopback rather than refused; the security property is untouched, because a
|
|
37055
|
+
* line naming a real foreign host still names a real foreign host, and no
|
|
37056
|
+
* spelling of the wildcard reaches anywhere but this machine.
|
|
37057
|
+
*/
|
|
37058
|
+
function isWildcardHostname(hostname) {
|
|
37059
|
+
const h = hostname.trim().replace(/^\[/, "").replace(/\]$/, "").toLowerCase();
|
|
37060
|
+
return h === "0.0.0.0" || h === "::" || h === "0:0:0:0:0:0:0:0" || h === "::ffff:0.0.0.0" || h === "::ffff:0:0";
|
|
37061
|
+
}
|
|
37062
|
+
/**
|
|
37063
|
+
* Rewrite the HOST TOKEN of a wildcard-bound URL to `127.0.0.1`, leaving
|
|
37064
|
+
* scheme, userinfo, port, path, query and fragment byte-for-byte (rather than
|
|
37065
|
+
* re-serialising the `URL`, which would append a `/` the child never printed).
|
|
37066
|
+
*
|
|
37067
|
+
* This is string surgery over an authority the WHATWG parser has ALREADY
|
|
37068
|
+
* accepted, and the two parsers do not agree on where the authority ends —
|
|
37069
|
+
* `\` terminates it for the parser and not for the `[/?#]` scan here, and any
|
|
37070
|
+
* future terminator will diverge the same way. So this is deliberately NOT the
|
|
37071
|
+
* decision-maker: {@link normalizeLocalUpstream} re-parses whatever comes back
|
|
37072
|
+
* and refuses it unless the RESULT is loopback. Returning a wrong string here
|
|
37073
|
+
* costs a refusal, never a foreign destination.
|
|
37074
|
+
*/
|
|
37075
|
+
function rewriteWildcardHostToken(upstream) {
|
|
37076
|
+
const schemeEnd = upstream.indexOf("://");
|
|
37077
|
+
if (schemeEnd === -1) return void 0;
|
|
37078
|
+
const head = upstream.slice(0, schemeEnd + 3);
|
|
37079
|
+
const rest = upstream.slice(schemeEnd + 3);
|
|
37080
|
+
const cut = rest.search(/[/?#]/);
|
|
37081
|
+
const authority = cut === -1 ? rest : rest.slice(0, cut);
|
|
37082
|
+
const tail = cut === -1 ? "" : rest.slice(cut);
|
|
37083
|
+
const at = authority.lastIndexOf("@");
|
|
37084
|
+
const userinfo = at === -1 ? "" : authority.slice(0, at + 1);
|
|
37085
|
+
const hostPort = at === -1 ? authority : authority.slice(at + 1);
|
|
37086
|
+
const portAt = hostPort.startsWith("[") ? hostPort.indexOf("]") + 1 : hostPort.indexOf(":");
|
|
37087
|
+
return `${head}${userinfo}127.0.0.1${portAt > 0 ? hostPort.slice(portAt) : ""}${tail}`;
|
|
37088
|
+
}
|
|
37089
|
+
/**
|
|
37090
|
+
* Resolve an upstream URL a serve child named into the URL studio may
|
|
37091
|
+
* actually use, or `undefined` when it must be refused (issue #578).
|
|
37092
|
+
*
|
|
37093
|
+
* A wildcard host is REWRITTEN to `127.0.0.1` (see
|
|
37094
|
+
* {@link isWildcardHostname}) and the rewritten URL is what gets adopted as
|
|
37095
|
+
* the endpoint and handed to the proxy, so the destination really is
|
|
37096
|
+
* loopback rather than merely tolerated. Everything else must already be
|
|
37097
|
+
* loopback; a foreign host or an unparseable URL resolves to `undefined`.
|
|
37098
|
+
*
|
|
37099
|
+
* # The answer is CHECKED, not asserted
|
|
37100
|
+
*
|
|
37101
|
+
* Whatever string this is about to return — the input verbatim, or the
|
|
37102
|
+
* host-token rewrite of {@link rewriteWildcardHostToken} — is re-parsed with
|
|
37103
|
+
* `new URL` and its `hostname` must satisfy {@link isLoopbackHostname}. That
|
|
37104
|
+
* single post-condition is the whole guarantee, and it is stated over the
|
|
37105
|
+
* VALUE HANDED BACK rather than over the value inspected on the way in, so it
|
|
37106
|
+
* cannot be outrun by a spelling nobody enumerated.
|
|
37107
|
+
*
|
|
37108
|
+
* It has to be, because the string surgery and the URL parser disagree about
|
|
37109
|
+
* where an authority ends. `http://0.0.0.0\@attacker.example/` parses to host
|
|
37110
|
+
* `0.0.0.0` (WHATWG treats `\` as an authority terminator) but the `[/?#]`
|
|
37111
|
+
* scan reads `0.0.0.0\@attacker.example` as one authority, so the rewrite
|
|
37112
|
+
* lands on the wrong token and produces `http://0.0.0.0\@127.0.0.1/` — which
|
|
37113
|
+
* re-parses to host `0.0.0.0`, NOT loopback, and is refused here. Adding `\`
|
|
37114
|
+
* to the cut set would close exactly that spelling and leave the next one
|
|
37115
|
+
* open; the post-condition closes the shape.
|
|
37116
|
+
*
|
|
37117
|
+
* Userinfo rides through byte-for-byte on the accepted path
|
|
37118
|
+
* (`http://tok@0.0.0.0:51234/` -> `http://tok@127.0.0.1:51234/`) — verified,
|
|
37119
|
+
* not assumed, since the post-condition now proves the destination that
|
|
37120
|
+
* string actually names.
|
|
37121
|
+
*/
|
|
37122
|
+
function normalizeLocalUpstream(upstream) {
|
|
37123
|
+
let parsed;
|
|
37124
|
+
try {
|
|
37125
|
+
parsed = new URL(upstream);
|
|
37126
|
+
} catch {
|
|
37127
|
+
return;
|
|
37128
|
+
}
|
|
37129
|
+
const candidate = isWildcardHostname(parsed.hostname) ? rewriteWildcardHostToken(upstream) : upstream;
|
|
37130
|
+
if (candidate === void 0) return void 0;
|
|
37131
|
+
let confirmed;
|
|
37132
|
+
try {
|
|
37133
|
+
confirmed = new URL(candidate);
|
|
37134
|
+
} catch {
|
|
37135
|
+
return;
|
|
37136
|
+
}
|
|
37137
|
+
return isLoopbackHostname(confirmed.hostname) ? candidate : void 0;
|
|
37138
|
+
}
|
|
37139
|
+
/**
|
|
37140
|
+
* Render an UNTRUSTED endpoint string for a human-readable message. The
|
|
37141
|
+
* string reached studio from a child's stdout, so it can carry control
|
|
37142
|
+
* characters (ANSI escapes, a bare CR) that would forge extra output, and it
|
|
37143
|
+
* can be arbitrarily long. Non-printable-ASCII bytes become `?` and the result
|
|
37144
|
+
* is length-capped, the same shape `credential-error` applies to a relayed
|
|
37145
|
+
* service message.
|
|
37146
|
+
*/
|
|
37147
|
+
function describeEndpointForMessage(value) {
|
|
37148
|
+
const flat = value.replace(/[^\x20-\x7e]/g, "?");
|
|
37149
|
+
return flat.length > 120 ? `${flat.slice(0, 120)}...` : flat;
|
|
37150
|
+
}
|
|
37151
|
+
/**
|
|
36993
37152
|
* Start a capturing reverse proxy in front of a studio serve target
|
|
36994
37153
|
* (decision D4a: because every request to the served port flows through
|
|
36995
37154
|
* `cdkl studio`, the timeline observes them regardless of source —
|
|
@@ -37006,6 +37165,12 @@ let proxyIdCounter = 0;
|
|
|
37006
37165
|
* Studio is a control plane over the CLI, so this proxy sits in front of
|
|
37007
37166
|
* the long-running `cdkl start-api` child the serve manager spawned; it
|
|
37008
37167
|
* does NOT re-implement any routing — it forwards verbatim.
|
|
37168
|
+
*
|
|
37169
|
+
* Throws SYNCHRONOUSLY (rather than rejecting) when `upstream` is unparseable
|
|
37170
|
+
* or names a non-loopback host (issue #578) — a refusal to attempt the proxy
|
|
37171
|
+
* at all, rather than a runtime failure of one. A wildcard bind address
|
|
37172
|
+
* (`0.0.0.0` / `::`) is not a refusal: it is rewritten to `127.0.0.1` and
|
|
37173
|
+
* forwarded there ({@link normalizeLocalUpstream}).
|
|
37009
37174
|
*/
|
|
37010
37175
|
function startStudioProxy(config) {
|
|
37011
37176
|
const host = config.host ?? "127.0.0.1";
|
|
@@ -37015,8 +37180,10 @@ function startStudioProxy(config) {
|
|
|
37015
37180
|
proxyIdCounter += 1;
|
|
37016
37181
|
return `req-${clock()}-${proxyIdCounter}`;
|
|
37017
37182
|
});
|
|
37018
|
-
const
|
|
37019
|
-
|
|
37183
|
+
const resolvedUpstream = normalizeLocalUpstream(config.upstream);
|
|
37184
|
+
if (resolvedUpstream === void 0) throw new Error(`studio proxy refuses the non-loopback upstream '${describeEndpointForMessage(config.upstream)}': a serve child always listens on this machine, so a request forwarded there would leave it.`);
|
|
37185
|
+
const upstreamUrl = new URL(resolvedUpstream);
|
|
37186
|
+
const upstreamHost = stripHostBrackets(upstreamUrl.hostname);
|
|
37020
37187
|
const upstreamPort = Number(upstreamUrl.port) || 80;
|
|
37021
37188
|
const server = createServer$1((clientReq, clientRes) => {
|
|
37022
37189
|
const id = idFactory();
|
|
@@ -37198,25 +37365,27 @@ const SERVE_SPECS = {
|
|
|
37198
37365
|
"--host",
|
|
37199
37366
|
"127.0.0.1"
|
|
37200
37367
|
],
|
|
37201
|
-
readyRe:
|
|
37202
|
-
capturesHttp: true
|
|
37368
|
+
readyRe: /^Server listening on (\S+)/,
|
|
37369
|
+
capturesHttp: true,
|
|
37370
|
+
readyRepeats: true
|
|
37203
37371
|
},
|
|
37204
37372
|
alb: {
|
|
37205
37373
|
command: "start-alb",
|
|
37206
37374
|
portArgs: [],
|
|
37207
|
-
readyRe:
|
|
37208
|
-
capturesHttp: true
|
|
37375
|
+
readyRe: /^ALB front-door: (https?:\/\/\S+)/,
|
|
37376
|
+
capturesHttp: true,
|
|
37377
|
+
readyRepeats: true
|
|
37209
37378
|
},
|
|
37210
37379
|
ecs: {
|
|
37211
37380
|
command: "start-service",
|
|
37212
37381
|
portArgs: [],
|
|
37213
|
-
readyRe:
|
|
37382
|
+
readyRe: /^Service\(s\) running:/,
|
|
37214
37383
|
capturesHttp: false
|
|
37215
37384
|
},
|
|
37216
37385
|
"ecs-task": {
|
|
37217
37386
|
command: "run-task",
|
|
37218
37387
|
portArgs: [],
|
|
37219
|
-
readyRe:
|
|
37388
|
+
readyRe: /^Task running \(family=/,
|
|
37220
37389
|
capturesHttp: false
|
|
37221
37390
|
},
|
|
37222
37391
|
cloudfront: {
|
|
@@ -37227,7 +37396,7 @@ const SERVE_SPECS = {
|
|
|
37227
37396
|
"--host",
|
|
37228
37397
|
"127.0.0.1"
|
|
37229
37398
|
],
|
|
37230
|
-
readyRe:
|
|
37399
|
+
readyRe: /^CloudFront distribution serving on (https?:\/\/\S+)/,
|
|
37231
37400
|
capturesHttp: true
|
|
37232
37401
|
},
|
|
37233
37402
|
"agentcore-ws": {
|
|
@@ -37238,27 +37407,119 @@ const SERVE_SPECS = {
|
|
|
37238
37407
|
"--host",
|
|
37239
37408
|
"127.0.0.1"
|
|
37240
37409
|
],
|
|
37241
|
-
readyRe:
|
|
37410
|
+
readyRe: /^Server listening on (\S+)/,
|
|
37242
37411
|
capturesHttp: true,
|
|
37243
|
-
extraEndpointRe:
|
|
37412
|
+
extraEndpointRe: /^HTTP contract served on (https?:\/\/\S+)/
|
|
37244
37413
|
}
|
|
37245
37414
|
};
|
|
37246
37415
|
/**
|
|
37247
37416
|
* Parse an auto-published replica host endpoint from an `ecs` serve child's
|
|
37248
37417
|
* stdout (issue #392). `start-service` publishes each replica's declared
|
|
37249
37418
|
* container port on the host — auto-remapping a privileged port (< 1024) to a
|
|
37250
|
-
* free high port (issue #357) — and logs
|
|
37251
|
-
*
|
|
37252
|
-
* surfaces the FIRST such
|
|
37253
|
-
*
|
|
37254
|
-
*
|
|
37255
|
-
*
|
|
37419
|
+
* free high port (issue #357) — and logs the WHOLE line
|
|
37420
|
+
* `Container 'web' container port 80 published on 127.0.0.1:54321. Reach it at
|
|
37421
|
+
* 127.0.0.1:54321.` (`ecs-task-runner`). studio surfaces the FIRST such
|
|
37422
|
+
* endpoint as the serve's `hostUrl` so the in-workspace request composer can
|
|
37423
|
+
* target it even when the user passed no explicit `--host-port`. Returns
|
|
37424
|
+
* `http://<ip>:<port>` or `undefined` when the line is not that banner.
|
|
37425
|
+
* Exported for unit testing.
|
|
37426
|
+
*
|
|
37427
|
+
* ANCHORED to the whole banner (issue #578), not just the `published on`
|
|
37428
|
+
* phrase: `hostUrl` is a destination the request composer posts to DIRECTLY,
|
|
37429
|
+
* with no proxy in between, so a mid-message occurrence of the phrase — in a
|
|
37430
|
+
* relayed error, or in a replica's own application output — must not be able
|
|
37431
|
+
* to name it. Pass the decoration-stripped line ({@link classifyChildLine}).
|
|
37432
|
+
* The loopback bound is applied by the CALLER (a parsed endpoint is still only
|
|
37433
|
+
* adopted when {@link normalizeLocalUpstream} accepts it), so this stays a pure
|
|
37434
|
+
* reader of the banner.
|
|
37256
37435
|
*/
|
|
37257
37436
|
function parsePublishedHostEndpoint(line) {
|
|
37258
|
-
const m =
|
|
37437
|
+
const m = /^Container '[^']*' container port \d+ published on (\d{1,3}(?:\.\d{1,3}){3}:\d+)/.exec(line);
|
|
37259
37438
|
return m ? `http://${m[1]}` : void 0;
|
|
37260
37439
|
}
|
|
37261
37440
|
/**
|
|
37441
|
+
* The one wording for "studio will not send requests to that destination"
|
|
37442
|
+
* (issue #578), shared by every site that resolves a relay target: the ready
|
|
37443
|
+
* line, the agentcore extra-endpoint line, the ecs replica publish banner, and
|
|
37444
|
+
* the `--host-port` mapping. `endpoint` is untrusted text (child stdout, or a
|
|
37445
|
+
* user-supplied flag value), so it is flattened + length-capped before being
|
|
37446
|
+
* quoted back.
|
|
37447
|
+
*/
|
|
37448
|
+
function describeForeignEndpointRefusal(targetId, endpoint, what) {
|
|
37449
|
+
const quoted = `'${describeEndpointForMessage(endpoint)}'`;
|
|
37450
|
+
const outcome = "No endpoint was adopted and no capture proxy was started.";
|
|
37451
|
+
if (!parsesAsUrl(endpoint)) return `refused an unparseable ${what} ${quoted} from '${targetId}': it is not a URL, so studio cannot tell where a request to it would go. ${outcome}`;
|
|
37452
|
+
return `refused a non-loopback ${what} ${quoted} from '${targetId}': a serve child always listens on this machine, so studio will not send requests there. ${outcome}`;
|
|
37453
|
+
}
|
|
37454
|
+
/** True when `value` is a URL the WHATWG parser accepts. */
|
|
37455
|
+
function parsesAsUrl(value) {
|
|
37456
|
+
try {
|
|
37457
|
+
new URL(value);
|
|
37458
|
+
return true;
|
|
37459
|
+
} catch {
|
|
37460
|
+
return false;
|
|
37461
|
+
}
|
|
37462
|
+
}
|
|
37463
|
+
/** ANSI SGR colour escapes, as the logger wraps a warn / error line with. */
|
|
37464
|
+
const ANSI_SGR_RE = /\u001b\[[0-9;]*m/g;
|
|
37465
|
+
/** The verbose-mode preamble `<iso-timestamp> <LEVEL> ` (`utils/logger`). */
|
|
37466
|
+
const VERBOSE_PREAMBLE_RE = /^\d{4}-\d{2}-\d{2}T[\d:.]+Z\s+(DEBUG|INFO|WARN|ERROR)\s+/;
|
|
37467
|
+
/**
|
|
37468
|
+
* A child logger's `[module] ` tag (`utils/logger`'s `ChildLogger`).
|
|
37469
|
+
*
|
|
37470
|
+
* Stripped ONLY after a verbose preamble, and ONLY for the ecs publish banner
|
|
37471
|
+
* ({@link ClassifiedChildLine.untagged}) — never for the ready-banner match.
|
|
37472
|
+
* `ChildLogger` emits the tag exclusively at `debug` level (`logger.ts`
|
|
37473
|
+
* `info` / `warn` / `error` prefix only when `getLevel() === 'debug'`), which
|
|
37474
|
+
* is also the level that renders the `<timestamp> <LEVEL>` preamble, so a BARE
|
|
37475
|
+
* `[tag] ` at column 0 is never cdk-local's. It IS how relayed third-party
|
|
37476
|
+
* container output arrives — `[<container>] ` (`ecs-task-runner`) and
|
|
37477
|
+
* `[svc=... r=... c=...] ` (`ecs-service-runner`) — so stripping it
|
|
37478
|
+
* unconditionally re-anchored an application's own log line to `^` and let it
|
|
37479
|
+
* impersonate a ready banner (issue #578).
|
|
37480
|
+
*/
|
|
37481
|
+
const MODULE_TAG_RE = /^\[[^\]]*\]\s+/;
|
|
37482
|
+
/** The compact-mode level prefix `WARN: ` / `ERROR: ` (`utils/logger`). */
|
|
37483
|
+
const COMPACT_LEVEL_RE = /^(WARN|ERROR):\s/;
|
|
37484
|
+
/**
|
|
37485
|
+
* Read the log decoration off one child stdout line (issue #578).
|
|
37486
|
+
*
|
|
37487
|
+
* `cdkl studio` runs its serve children with `CDKL_LOG_STREAM=stdout` (issue
|
|
37488
|
+
* #403), so cdk-local's own warn / error lines share the stream the ready
|
|
37489
|
+
* banners arrive on. Those lines relay wire-derived text (an AWS SDK error's
|
|
37490
|
+
* `message`), which is exactly the text that must never be able to name the
|
|
37491
|
+
* endpoint studio proxies to. The compact renderer prefixes them `WARN: ` /
|
|
37492
|
+
* `ERROR: ` (the same signal `studio-ui`'s `logLineClass` colours off) and the
|
|
37493
|
+
* verbose renderer (`--verbose` / `CDKL_LOG_LEVEL=debug`, both reachable in a
|
|
37494
|
+
* studio-spawned child) writes `<timestamp> <LEVEL> [module] `. Both shapes
|
|
37495
|
+
* are recognised here, so the caller can skip a diagnostic line AND anchor its
|
|
37496
|
+
* patterns against `text` without the mode deciding whether the anchor holds.
|
|
37497
|
+
*/
|
|
37498
|
+
function classifyChildLine(line) {
|
|
37499
|
+
let text = line.replace(ANSI_SGR_RE, "");
|
|
37500
|
+
let diagnostic = false;
|
|
37501
|
+
const verbose = VERBOSE_PREAMBLE_RE.exec(text);
|
|
37502
|
+
if (verbose) {
|
|
37503
|
+
if (verbose[1] === "WARN" || verbose[1] === "ERROR") diagnostic = true;
|
|
37504
|
+
text = text.slice(verbose[0].length);
|
|
37505
|
+
}
|
|
37506
|
+
const level = COMPACT_LEVEL_RE.exec(text);
|
|
37507
|
+
if (level) {
|
|
37508
|
+
diagnostic = true;
|
|
37509
|
+
text = text.slice(level[0].length);
|
|
37510
|
+
}
|
|
37511
|
+
let untagged = text;
|
|
37512
|
+
if (verbose) {
|
|
37513
|
+
const tag = MODULE_TAG_RE.exec(text);
|
|
37514
|
+
if (tag) untagged = text.slice(tag[0].length);
|
|
37515
|
+
}
|
|
37516
|
+
return {
|
|
37517
|
+
diagnostic,
|
|
37518
|
+
text,
|
|
37519
|
+
untagged
|
|
37520
|
+
};
|
|
37521
|
+
}
|
|
37522
|
+
/**
|
|
37262
37523
|
* Build the studio serve manager. Slice C1 drives a long-running
|
|
37263
37524
|
* `cdkl start-api <target>` child — studio is a control plane over the
|
|
37264
37525
|
* CLI (the same pattern as the single-shot invoke dispatcher), so it
|
|
@@ -37301,8 +37562,9 @@ function createStudioServeManager(config) {
|
|
|
37301
37562
|
* leaks when a serve stops / errors / times out.
|
|
37302
37563
|
*/
|
|
37303
37564
|
async function closeProxies(e) {
|
|
37304
|
-
const proxies = e.proxies.
|
|
37305
|
-
|
|
37565
|
+
const proxies = [...e.proxies.values()];
|
|
37566
|
+
e.proxies.clear();
|
|
37567
|
+
await Promise.all(proxies.map((p) => p.then((x) => x.close()).catch(() => void 0)));
|
|
37306
37568
|
if (e.envDir) {
|
|
37307
37569
|
try {
|
|
37308
37570
|
rmSync(e.envDir, {
|
|
@@ -37392,7 +37654,7 @@ function createStudioServeManager(config) {
|
|
|
37392
37654
|
endpoints: [],
|
|
37393
37655
|
startedAt,
|
|
37394
37656
|
child,
|
|
37395
|
-
proxies:
|
|
37657
|
+
proxies: /* @__PURE__ */ new Map()
|
|
37396
37658
|
};
|
|
37397
37659
|
if (child.pid !== void 0) entry.pid = child.pid;
|
|
37398
37660
|
if (envDir) entry.envDir = envDir;
|
|
@@ -37400,7 +37662,15 @@ function createStudioServeManager(config) {
|
|
|
37400
37662
|
const hp = req.options?.["--host-port"];
|
|
37401
37663
|
if (Array.isArray(hp)) {
|
|
37402
37664
|
const first = hp.find((r) => r && typeof r === "object" && typeof r.right === "string" && r.right.trim() !== "");
|
|
37403
|
-
if (first)
|
|
37665
|
+
if (first) {
|
|
37666
|
+
const candidate = "http://127.0.0.1:" + first.right.trim();
|
|
37667
|
+
const local = normalizeLocalUpstream(candidate);
|
|
37668
|
+
if (local === void 0) {
|
|
37669
|
+
const msg = describeForeignEndpointRefusal(req.targetId, candidate, "--host-port mapping");
|
|
37670
|
+
emitLog(config.bus, clock, req.targetId, `WARN: ${msg}`, "stderr");
|
|
37671
|
+
getLogger().warn(msg);
|
|
37672
|
+
} else entry.hostUrl = local;
|
|
37673
|
+
}
|
|
37404
37674
|
}
|
|
37405
37675
|
}
|
|
37406
37676
|
entries.set(req.targetId, entry);
|
|
@@ -37410,13 +37680,13 @@ function createStudioServeManager(config) {
|
|
|
37410
37680
|
child.stdout.setEncoding("utf8");
|
|
37411
37681
|
child.stderr.setEncoding("utf8");
|
|
37412
37682
|
const timer = setTimeoutFn(() => {
|
|
37413
|
-
if (settled) return;
|
|
37683
|
+
if (settled || entry.stopping) return;
|
|
37414
37684
|
settled = true;
|
|
37415
37685
|
entry.status = "error";
|
|
37416
37686
|
emitServe(entry, `Timed out after ${readyTimeoutMs}ms waiting for the serve to be ready.`);
|
|
37417
37687
|
stopChild(child, stopGraceMs, setTimeoutFn, clearTimeoutFn);
|
|
37418
37688
|
closeProxies(entry);
|
|
37419
|
-
entries.delete(req.targetId);
|
|
37689
|
+
if (entries.get(req.targetId) === entry) entries.delete(req.targetId);
|
|
37420
37690
|
reject(/* @__PURE__ */ new Error(`'${req.targetId}' did not start within ${readyTimeoutMs}ms.`));
|
|
37421
37691
|
}, readyTimeoutMs);
|
|
37422
37692
|
timer.unref?.();
|
|
@@ -37428,19 +37698,87 @@ function createStudioServeManager(config) {
|
|
|
37428
37698
|
emitServe(entry);
|
|
37429
37699
|
resolve(publicState(entry));
|
|
37430
37700
|
};
|
|
37431
|
-
|
|
37701
|
+
/**
|
|
37702
|
+
* Refuse a destination a child's stdout named that is not on this
|
|
37703
|
+
* machine (issue #578), and say so loudly: on the bus, so the studio
|
|
37704
|
+
* LOGS panel shows it (rendered with the same `WARN: ` prefix the
|
|
37705
|
+
* compact logger emits, which `studio-ui` colours), and on the studio
|
|
37706
|
+
* process's own logger, for a user watching the terminal. The endpoint
|
|
37707
|
+
* is untrusted text, so it is flattened + length-capped before being
|
|
37708
|
+
* quoted back.
|
|
37709
|
+
*/
|
|
37710
|
+
const refuseForeignEndpoint = (endpoint, what) => {
|
|
37711
|
+
const msg = describeForeignEndpointRefusal(req.targetId, endpoint, what);
|
|
37712
|
+
emitLog(config.bus, clock, req.targetId, `WARN: ${msg}`, "stderr");
|
|
37713
|
+
getLogger().warn(msg);
|
|
37714
|
+
return msg;
|
|
37715
|
+
};
|
|
37716
|
+
/**
|
|
37717
|
+
* Fail the serve NOW with `reason`, instead of leaving it `starting`
|
|
37718
|
+
* until `readyTimeoutMs` expires (issue #578 review).
|
|
37719
|
+
*
|
|
37720
|
+
* A refused ready line is terminal: the child named the only endpoint it
|
|
37721
|
+
* is going to name, and studio will not use it. Waiting out the default
|
|
37722
|
+
* 120 s and then reporting `did not start within 120000ms` buries the
|
|
37723
|
+
* real cause in the LOGS panel, and it is a live configuration rather
|
|
37724
|
+
* than an attack that lands here — `cdkl start-alb --container-host
|
|
37725
|
+
* <non-loopback>` makes the front-door banner the refused line. Mirrors
|
|
37726
|
+
* the timeout path exactly (graceful SIGTERM so the child tears its own
|
|
37727
|
+
* containers down, proxies closed, entry dropped) but carries the
|
|
37728
|
+
* refusal text as the failure reason, so the UI error banner says why.
|
|
37729
|
+
*
|
|
37730
|
+
* The trade: a serve that would have recovered — a foreign-looking line
|
|
37731
|
+
* arriving BEFORE the genuine banner — now dies instead of waiting. That
|
|
37732
|
+
* line has to clear bound 1 (not a WARN / ERROR), bound 2 (column 0, and
|
|
37733
|
+
* as of this change not tag-stripped) and still name a non-loopback,
|
|
37734
|
+
* non-wildcard host, which is the misconfiguration case far more than
|
|
37735
|
+
* the coincidence case; and the old outcome for it was a 120 s wait
|
|
37736
|
+
* ending in the same failure with a worse message.
|
|
37737
|
+
*/
|
|
37738
|
+
const failServe = (reason) => {
|
|
37739
|
+
if (settled || entry.stopping) return;
|
|
37740
|
+
settled = true;
|
|
37741
|
+
clearTimeoutFn(timer);
|
|
37742
|
+
entry.status = "error";
|
|
37743
|
+
emitServe(entry, reason);
|
|
37744
|
+
stopChild(child, stopGraceMs, setTimeoutFn, clearTimeoutFn);
|
|
37745
|
+
closeProxies(entry);
|
|
37746
|
+
entries.delete(req.targetId);
|
|
37747
|
+
reject(new Error(reason));
|
|
37748
|
+
};
|
|
37749
|
+
const onReady = async (readyUrl) => {
|
|
37750
|
+
let childUrl = readyUrl;
|
|
37751
|
+
if (readyUrl !== void 0) {
|
|
37752
|
+
const local = normalizeLocalUpstream(readyUrl);
|
|
37753
|
+
if (local === void 0) {
|
|
37754
|
+
const msg = refuseForeignEndpoint(readyUrl, "ready line");
|
|
37755
|
+
failServe(msg);
|
|
37756
|
+
return;
|
|
37757
|
+
}
|
|
37758
|
+
childUrl = local;
|
|
37759
|
+
}
|
|
37432
37760
|
let endpoint = childUrl;
|
|
37433
37761
|
if (childUrl && spec.capturesHttp && captureRequests && /^https?:/i.test(childUrl)) try {
|
|
37434
|
-
|
|
37435
|
-
|
|
37436
|
-
|
|
37437
|
-
|
|
37438
|
-
|
|
37439
|
-
|
|
37440
|
-
|
|
37441
|
-
|
|
37762
|
+
let pending = entry.proxies.get(childUrl);
|
|
37763
|
+
if (pending === void 0) {
|
|
37764
|
+
pending = proxyFactory({
|
|
37765
|
+
bus: config.bus,
|
|
37766
|
+
target: req.targetId,
|
|
37767
|
+
kind: req.kind,
|
|
37768
|
+
upstream: childUrl
|
|
37769
|
+
});
|
|
37770
|
+
entry.proxies.set(childUrl, pending);
|
|
37771
|
+
}
|
|
37772
|
+
endpoint = (await pending).url;
|
|
37442
37773
|
} catch {
|
|
37443
|
-
|
|
37774
|
+
entry.proxies.delete(childUrl);
|
|
37775
|
+
const direct = normalizeLocalUpstream(childUrl);
|
|
37776
|
+
if (direct === void 0) {
|
|
37777
|
+
const msg = refuseForeignEndpoint(childUrl, "ready line");
|
|
37778
|
+
failServe(msg);
|
|
37779
|
+
return;
|
|
37780
|
+
}
|
|
37781
|
+
endpoint = direct;
|
|
37444
37782
|
}
|
|
37445
37783
|
if (entry.stopping || settled && !entries.has(req.targetId)) {
|
|
37446
37784
|
await closeProxies(entry);
|
|
@@ -37451,17 +37789,24 @@ function createStudioServeManager(config) {
|
|
|
37451
37789
|
else becomeRunning();
|
|
37452
37790
|
};
|
|
37453
37791
|
streamLines(child.stdout, (line) => {
|
|
37454
|
-
const
|
|
37455
|
-
if (
|
|
37456
|
-
|
|
37457
|
-
|
|
37458
|
-
if (
|
|
37459
|
-
|
|
37460
|
-
|
|
37461
|
-
|
|
37462
|
-
if (
|
|
37463
|
-
|
|
37464
|
-
if (
|
|
37792
|
+
const parsed = classifyChildLine(line);
|
|
37793
|
+
if (!parsed.diagnostic) {
|
|
37794
|
+
const m = spec.readyRepeats || !settled ? spec.readyRe.exec(parsed.text) : null;
|
|
37795
|
+
if (m) onReady(m[1]);
|
|
37796
|
+
if (spec.extraEndpointRe) {
|
|
37797
|
+
const me = spec.extraEndpointRe.exec(parsed.text);
|
|
37798
|
+
if (me) onReady(me[1]);
|
|
37799
|
+
}
|
|
37800
|
+
if (req.kind === "ecs" && entry.hostUrl === void 0) {
|
|
37801
|
+
const endpoint = parsePublishedHostEndpoint(parsed.untagged);
|
|
37802
|
+
if (endpoint) {
|
|
37803
|
+
const local = normalizeLocalUpstream(endpoint);
|
|
37804
|
+
if (local === void 0) refuseForeignEndpoint(endpoint, "published replica endpoint");
|
|
37805
|
+
else {
|
|
37806
|
+
entry.hostUrl = local;
|
|
37807
|
+
if (entry.status === "running") emitServe(entry);
|
|
37808
|
+
}
|
|
37809
|
+
}
|
|
37465
37810
|
}
|
|
37466
37811
|
}
|
|
37467
37812
|
emitLog(config.bus, clock, req.targetId, line, "stdout");
|
|
@@ -38491,4 +38836,4 @@ function addStudioSpecificOptions(cmd) {
|
|
|
38491
38836
|
|
|
38492
38837
|
//#endregion
|
|
38493
38838
|
export { applyEdgeResponseResult as $, buildJwksUrlFromIssuer as $n, resolveCfnStackName as $r, buildCloudMapIndex as $t, startAgentCoreHttpServer as A, describeCredentialLoadFailure as Ai, classifySourceChange as An, ConnectionRegistry as Ar, addRunTaskSpecificOptions as At, idFromArn as B, buildStageMap as Bn, resolveRuntimeFileExtension as Br, resolveEcsAssumeRoleOption as Bt, addListSpecificOptions as C, resolveAgentCoreTarget as Ci, waitForAgentCorePing as Cn, tryParseStatus as Cr, parseLbPortOverrides as Ct, createLocalStartAgentCoreCommand as D, tryResolveImageFnJoin as Di, computeCodeImageTag as Dn, probeHostGatewaySupport as Dr, addStartServiceSpecificOptions as Dt, addStartAgentCoreSpecificOptions as E, substituteImagePlaceholders as Ei, buildAgentCoreCodeImage as En, HOST_GATEWAY_MIN_VERSION as Er, resolveAlbFrontDoor as Et, createLocalStartCloudFrontCommand as F, createWatchPredicates as Fn, buildDisconnectEvent as Fr, addImageOverrideOptions as Ft, classifyS3Error as G, filterRoutesByApiIdentifiers as Gn, substituteEnvVarsFromState as Gr, enforceImageOverrideOrphans as Gt, createDeployedKvsDataSource as H, resolveEnvVars$1 as Hn, EcsTaskResolutionError as Hr, runEcsServiceEmulator as Ht, normalizeKvsFileKeys as I, resolveApiTargetSubset as In, buildMessageEvent as Ir, buildEcsImageResolutionContext$1 as It, startCloudFrontServer as J, startApiServer as Jn, createLocalStateProvider as Jr, resolveImageOverrides as Jt, createS3OriginReader as K, groupRoutesByServer as Kn, substituteEnvVarsFromStateAsync as Kr, mergeForService as Kt, parseKvsFileOverrides as L, createAuthorizerCache as Ln, architectureToPlatform as Lr, ecsClusterOption as Lt, startAgentCoreWsBridge as M, resolveProfileCredentials as Mi, createLocalInvokeCommand as Mn, handleConnectionsRequest as Mr, MAX_TASKS_SUBNET_RANGE_CAP as Mt, LocalStartCloudFrontError as N, addStartApiSpecificOptions as Nn, parseConnectionsPath as Nr, addCommonEcsServiceOptions as Nt, buildAgentCoreServeAuthCheck as O, LocalInvokeBuildError as Oi, renderCodeDockerfile as On, resolveHostGatewayExtraHosts as Or, createLocalStartServiceCommand as Ot, addStartCloudFrontSpecificOptions as P, createLocalStartApiCommand as Pn, buildConnectEvent as Pr, addEcsAssumeRoleOptions as Pt, applyEdgeRequestResult as Q, buildCognitoJwksUrl as Qn, resolveCfnRegion as Qr, listPinnedTargets as Qt, parseOriginOverrides as R, createFileWatcher as Rn, buildContainerImage as Rr, parseMaxTasks as Rt, StudioEventBus as S, pickAgentCoreCandidateStack as Si, waitForAgentCoreHttpReady as Sn, selectIntegrationResponse as Sr, createLocalStartAlbCommand as St, formatTargetListing as T, formatStateRemedy as Ti, SUPPORTED_CODE_RUNTIMES as Tn, HOST_DOCKER_INTERNAL_GATEWAY as Tr, isApplicationLoadBalancer as Tt, resolveDeployedKvsArnByName as U, availableApiIdentifiers as Un, substituteAgainstState as Ur, ImageOverrideError as Ut, resolveKvsModulesForDistribution as V, materializeLayerFromArn as Vn, resolveRuntimeImage as Vr, resolveSharedSidecarCredentials as Vt, resolveDeployedOriginBucket as W, filterRoutesByApiIdentifier as Wn, substituteAgainstStateAsync as Wr, buildImageOverrideTag as Wt, serveFromStaticOrigin as X, resolveServiceIntegrationParameters as Xn, rejectExplicitCfnStackWithMultipleStacks as Xr, describePinnedImageUri as Xt, resolveErrorResponseCandidates as Y, resolveSelectionExpression as Yn, isCfnFlagPresent as Yr, runImageOverrideBuilds as Yt, serveLambdaUrlOrigin as Z, defaultCredentialsLoader as Zn, resolveCfnFallbackRegion as Zr, isLocalCdkAssetImage as Zt, filterStudioTargetGroups as _, AGENTCORE_AGUI_PROTOCOL as _i, parseSseForJsonRpc as _n, applyAuthorizerOverlay as _r, createCloudFrontModule as _t, createLocalStudioCommand as a, countTargets as ai, attachContainerLogStreamer as an, computeRequestIdentityHash as ar, describeS3OriginDomain as at, renderStudioHtml as b, AGENTCORE_RUNTIME_TYPE as bi, AGENTCORE_SESSION_ID_HEADER as bn, evaluateResponseParameters as br, addAlbSpecificOptions as bt, startStudioProxy as c, discoverWebSocketApis as ci, bridgeAgentCoreWs as cn, invokeTokenAuthorizer as cr, pickFunctionUrlLogicalIdFromOrigin as ct, createStudioDispatcher as d, parseSelectionExpressionPath as di, A2A_PATH as dn, buildCorsConfigByApiId as dr, pickTargetFunctionLogicalId as dt, CfnLocalStateProvider as ei, CloudMapRegistry as en, createJwksCache as er, buildEdgeRequestEvent as et, filterStudioCustomResources as f, webSocketApiMatchesIdentifier as fi, a2aInvokeOnce as fn, buildCorsConfigFromCloudFrontChain as fr, resolveCloudFrontDistribution as ft, annotatePinnedEcsTargets as g, AGENTCORE_A2A_PROTOCOL as gi, mcpInvokeOnce as gn, translateLambdaResponse as gr, stripCloudFrontImport as gt, annotateEcsTaskPinnedTargets as h, resolveLambdaArnIntrinsic as hi, MCP_PROTOCOL_VERSION as hn, matchRoute as hr, runViewerResponse as ht, coerceStopRequest as i, resolveSingleTarget as ii, getContainerNetworkIp as in, buildMethodArn as ir, CLOUDFRONT_DISTRIBUTION_TYPE as it, attachAgentCoreWsBridge as j, buildStsClientConfig as ji, addInvokeSpecificOptions as jn, buildMgmtEndpointEnvUrl as jr, createLocalRunTaskCommand as jt, selectServeInboundAuth as k, describeAwsFailureForWarn as ki, toCmdArgv as kn, bufferToBody as kr, serviceStrategy as kt, relayServeRequest as l, discoverWebSocketApisOrThrow as li, invokeAgentCoreWs as ln, attachAuthorizers as lr, pickKvsLogicalIdFromArn as lt, annotateAlbPinnedBackingServices as m, pickRefLogicalId as mi, MCP_PATH as mn, matchPreflight as mr, runViewerRequest as mt, coerceRunRequest as n, resolveSsmParameters as ni, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as nn, verifyJwtAuthorizer as nr, edgeHeadersToHttp as nt, resolveServeBaseUrl as o, listTargets as oi, addInvokeAgentCoreSpecificOptions as on, evaluateCachedLambdaPolicy as or, extractKvsAssociations as ot, isCustomResourceLambdaTarget as p, discoverRoutes as pi, MCP_CONTAINER_PORT as pn, isFunctionUrlOacFronted as pr, compileCloudFrontFunction as pt, matchBehavior as q, readMtlsMaterialsFromDisk as qn, LocalStateSourceError as qr, parseImageOverrideFlags as qt, coerceServeRequest as r, resolveWatchConfig as ri, setShadowReadyTimeoutMs as rn, verifyJwtViaDiscovery as rr, httpHeadersToEdge as rt, createStudioServeManager as s, availableWebSocketApiIdentifiers as si, createLocalInvokeAgentCoreCommand as sn, invokeRequestAuthorizer as sr, isCloudFrontDistribution as st, addStudioSpecificOptions as t, collectSsmParameterRefs as ti, DEFAULT_SHADOW_READY_TIMEOUT_MS as tn, verifyCognitoJwt as tr, buildEdgeResponseEvent as tt, reinvoke as u, filterWebSocketApisByIdentifiers as ui, A2A_CONTAINER_PORT as un, applyCorsResponseHeaders as ur, pickLambdaEdgeFunctionLogicalId as ut, startStudioServer as v, AGENTCORE_HTTP_PROTOCOL as vi, AGENTCORE_SIGV4_SERVICE as vn, buildHttpApiV2Event as vr, createLocalFileKvsDataSource as vt, createLocalListCommand as w, derivePseudoParametersFromRegion as wi, downloadAndExtractS3Bundle as wn, VtlEvaluationError as wr, resolveAlbTarget as wt, createStudioStore as x, AgentCoreResolutionError as xi, invokeAgentCore as xn, pickResponseTemplate as xr, albStrategy as xt, toStudioTargetGroups as y, AGENTCORE_MCP_PROTOCOL as yi, signAgentCoreInvocation as yn, buildRestV1Event as yr, createUnboundCloudFrontModule as yt, resolveCloudFrontTarget as z, attachStageContext as zn, resolveRuntimeCodeMountPath as zr, parseRestartPolicy as zt };
|
|
38494
|
-
//# sourceMappingURL=local-studio-
|
|
38839
|
+
//# sourceMappingURL=local-studio-BJxBmC75.js.map
|