cdk-local 0.101.0 → 0.102.1
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 +1 -1
- package/dist/index.js +1 -1
- package/dist/internal.d.ts +14 -2
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +2 -2
- package/dist/{local-studio-DBZ8hF5H.js → local-studio-CbHZKVYj.js} +218 -25
- package/dist/local-studio-CbHZKVYj.js.map +1 -0
- package/dist/{local-studio-BGHLCa1m.d.ts → local-studio-D6G31cfP.d.ts} +2 -1
- package/dist/{local-studio-BGHLCa1m.d.ts.map → local-studio-D6G31cfP.d.ts.map} +1 -1
- package/package.json +1 -1
- package/dist/local-studio-DBZ8hF5H.js.map +0 -1
|
@@ -28434,7 +28434,7 @@ const STUDIO_CSS = `
|
|
|
28434
28434
|
#session-bar .sess-bind { color: #bbb; display: inline-flex; align-items: center; gap: 4px; }
|
|
28435
28435
|
#session-bar input[type=text] {
|
|
28436
28436
|
background: #111; color: #ddd; border: 1px solid #333; border-radius: 3px;
|
|
28437
|
-
padding: 3px 6px; font: 12px ui-monospace, Menlo, monospace; min-width:
|
|
28437
|
+
padding: 3px 6px; font: 12px ui-monospace, Menlo, monospace; min-width: 240px;
|
|
28438
28438
|
}
|
|
28439
28439
|
#session-bar input:focus { outline: none; border-color: #4ec97a; }
|
|
28440
28440
|
#session-bar button {
|
|
@@ -28483,7 +28483,10 @@ const STUDIO_CSS = `
|
|
|
28483
28483
|
}
|
|
28484
28484
|
/* Zebra-stripe rows so each target box reads as its own block (the borderless
|
|
28485
28485
|
rows otherwise blur together); the kind label stays readable on both. */
|
|
28486
|
-
|
|
28486
|
+
/* Zebra: alternate rows get a clearly lighter background than the base
|
|
28487
|
+
(#1a1a1a) so adjacent target boxes read as distinct — a 1-step shade was
|
|
28488
|
+
imperceptible. The kind label (#8f8f8f) still reads on both shades. */
|
|
28489
|
+
.group-body .target:nth-child(2n) { background: #242424; }
|
|
28487
28490
|
.target.runnable { cursor: pointer; }
|
|
28488
28491
|
.target.runnable:hover { background: #292929; }
|
|
28489
28492
|
.target.sel, .group-body .target.sel:nth-child(2n) { background: #2a3550; }
|
|
@@ -28511,6 +28514,7 @@ const STUDIO_CSS = `
|
|
|
28511
28514
|
.row.sel { background: #2a3550; }
|
|
28512
28515
|
.row .ts { color: #777; }
|
|
28513
28516
|
.row .label { color: #ddd; flex: 1; overflow: hidden; text-overflow: ellipsis; }
|
|
28517
|
+
.row.reinvoke .label::before { content: '\\21A9 '; color: #6aa0ff; margin-right: 2px; }
|
|
28514
28518
|
.row .status { color: #7bd88f; }
|
|
28515
28519
|
.row .status.err { color: #e0707a; }
|
|
28516
28520
|
#workspace { padding: 0 0 24px; }
|
|
@@ -28542,6 +28546,13 @@ const STUDIO_CSS = `
|
|
|
28542
28546
|
.req-composer .req-status { margin-top: 8px; font: 12px ui-monospace, Menlo, monospace; }
|
|
28543
28547
|
.req-composer .req-result pre { background: #0e0e0e; }
|
|
28544
28548
|
.composer button:disabled { background: #333; color: #888; cursor: default; }
|
|
28549
|
+
.composer .reinvoke-btn { margin-top: 6px; padding: 4px 14px; }
|
|
28550
|
+
.log-head { display: flex; align-items: center; justify-content: space-between; }
|
|
28551
|
+
.log-clear {
|
|
28552
|
+
background: #1d1d1d; color: #bbb; border: 1px solid #333; border-radius: 3px;
|
|
28553
|
+
padding: 2px 10px; font-size: 11px; cursor: pointer; margin: 0;
|
|
28554
|
+
}
|
|
28555
|
+
.log-clear:hover { background: #262626; color: #ddd; }
|
|
28545
28556
|
.composer .err { color: #e0707a; margin-top: 6px; min-height: 18px; }
|
|
28546
28557
|
.section { padding: 8px 12px; border-bottom: 1px solid #222; }
|
|
28547
28558
|
.section h3 { margin: 0 0 6px; font-size: 11px; color: #888; text-transform: uppercase; }
|
|
@@ -28639,6 +28650,7 @@ const STUDIO_SCRIPT = `
|
|
|
28639
28650
|
let shownInvId = null; // lambda invocation whose result is in the workspace
|
|
28640
28651
|
let shownServeId = null; // serve target whose workspace is shown
|
|
28641
28652
|
let shownDetailId = null; // captured request whose read-only detail is shown
|
|
28653
|
+
let pendingReqPrefill = null; // {method,path,headers,body} to seed the next serve request composer (re-invoke)
|
|
28642
28654
|
let studioDockerfiles = []; // Dockerfiles scanned at boot (pinned-ecs image-override picker)
|
|
28643
28655
|
|
|
28644
28656
|
function el(tag, cls, text) {
|
|
@@ -29206,7 +29218,18 @@ const STUDIO_SCRIPT = `
|
|
|
29206
29218
|
|
|
29207
29219
|
const logs = logsById.get(id) || [];
|
|
29208
29220
|
const logSec = el('div', 'section');
|
|
29209
|
-
|
|
29221
|
+
// Logs header carries a Clear button (issue #338): hammering a serve piles
|
|
29222
|
+
// up log lines, so let the user empty the panel (display-only — the
|
|
29223
|
+
// server-side store / history is untouched).
|
|
29224
|
+
const logHead = el('div', 'log-head');
|
|
29225
|
+
logHead.appendChild(el('h3', null, 'Logs'));
|
|
29226
|
+
const logClear = el('button', 'log-clear', 'Clear');
|
|
29227
|
+
logClear.onclick = function () {
|
|
29228
|
+
logsById.set(id, []);
|
|
29229
|
+
renderServeWorkspace(id);
|
|
29230
|
+
};
|
|
29231
|
+
logHead.appendChild(logClear);
|
|
29232
|
+
logSec.appendChild(logHead);
|
|
29210
29233
|
// A proxy-fronted serve (api / alb) streams its child start-* logs here,
|
|
29211
29234
|
// which advertise the child internal 127.0.0.1 port — a DIFFERENT port
|
|
29212
29235
|
// than the capture-proxy URL in Endpoints above. Flag it so the child
|
|
@@ -29271,6 +29294,34 @@ const STUDIO_SCRIPT = `
|
|
|
29271
29294
|
bodyTa.spellcheck = false;
|
|
29272
29295
|
sec.appendChild(bodyTa);
|
|
29273
29296
|
|
|
29297
|
+
// Re-invoke prefill (issue #284): seed the fields from a captured request
|
|
29298
|
+
// when the user clicked [Re-invoke] on a served-request detail. The prefill
|
|
29299
|
+
// is address-tagged with its target; consume it UNCONDITIONALLY (so a stray
|
|
29300
|
+
// one from a since-stopped serve never lingers) but only APPLY it when the
|
|
29301
|
+
// target matches this composer.
|
|
29302
|
+
if (pendingReqPrefill) {
|
|
29303
|
+
const pending = pendingReqPrefill;
|
|
29304
|
+
pendingReqPrefill = null;
|
|
29305
|
+
if (pending.targetId === id && pending.req && typeof pending.req === 'object') {
|
|
29306
|
+
const pf = pending.req;
|
|
29307
|
+
if (pf.method) method.value = String(pf.method).toUpperCase();
|
|
29308
|
+
if (pf.path != null) path.value = pf.path;
|
|
29309
|
+
if (pf.headers && typeof pf.headers === 'object') {
|
|
29310
|
+
// Drop hop-by-hop / transport headers the proxy captured verbatim
|
|
29311
|
+
// (host / content-length / etc.) — they are noise in the editor and
|
|
29312
|
+
// the relay sets them itself.
|
|
29313
|
+
const SKIP = ['host', 'connection', 'content-length', 'transfer-encoding', 'accept-encoding'];
|
|
29314
|
+
headers.value = Object.keys(pf.headers)
|
|
29315
|
+
.filter(function (k) { return SKIP.indexOf(k.toLowerCase()) === -1; })
|
|
29316
|
+
.map(function (k) { return k + ': ' + pf.headers[k]; })
|
|
29317
|
+
.join('\\n');
|
|
29318
|
+
}
|
|
29319
|
+
if (pf.body != null) {
|
|
29320
|
+
bodyTa.value = typeof pf.body === 'string' ? pf.body : JSON.stringify(pf.body);
|
|
29321
|
+
}
|
|
29322
|
+
}
|
|
29323
|
+
}
|
|
29324
|
+
|
|
29274
29325
|
const sendRow = el('div', 'req-send');
|
|
29275
29326
|
const btn = el('button', null, 'Send');
|
|
29276
29327
|
sendRow.appendChild(btn);
|
|
@@ -29471,21 +29522,31 @@ const STUDIO_SCRIPT = `
|
|
|
29471
29522
|
return sec;
|
|
29472
29523
|
}
|
|
29473
29524
|
|
|
29474
|
-
function renderComposer(id, kind, eventText) {
|
|
29525
|
+
function renderComposer(id, kind, eventText, reinvokeOf) {
|
|
29475
29526
|
const ws = document.getElementById('workspace');
|
|
29476
29527
|
ws.innerHTML = '';
|
|
29477
29528
|
|
|
29478
29529
|
const composer = el('div', 'composer');
|
|
29479
|
-
composer.appendChild(el('div', 'target-name', 'Invoke ' + id));
|
|
29530
|
+
composer.appendChild(el('div', 'target-name', (reinvokeOf ? 'Re-invoke ' : 'Invoke ') + id));
|
|
29480
29531
|
const ta = el('textarea');
|
|
29481
29532
|
ta.value = eventText;
|
|
29482
29533
|
ta.spellcheck = false;
|
|
29483
29534
|
composer.appendChild(ta);
|
|
29484
|
-
//
|
|
29485
|
-
|
|
29486
|
-
|
|
29535
|
+
// A re-invoke (issue #284) re-runs the EDITED event against the same
|
|
29536
|
+
// target; per-run options are not carried over, so the options section is
|
|
29537
|
+
// omitted (the payload is the thing being tweaked). A fresh invoke keeps
|
|
29538
|
+
// the per-run options (e.g. env vars) below the event, above Invoke.
|
|
29539
|
+
let opt = { collect: undefined, collectRaw: undefined };
|
|
29540
|
+
if (reinvokeOf) {
|
|
29541
|
+
composer.appendChild(
|
|
29542
|
+
el('div', 'opt-hint', 'Re-invoke runs the edited event through the same target (per-run options use defaults).')
|
|
29543
|
+
);
|
|
29544
|
+
} else {
|
|
29545
|
+
opt = buildOptions(kind);
|
|
29546
|
+
if (opt.node) composer.appendChild(opt.node);
|
|
29547
|
+
}
|
|
29487
29548
|
composer.appendChild(document.createElement('br'));
|
|
29488
|
-
const btn = el('button', null, 'Invoke');
|
|
29549
|
+
const btn = el('button', null, reinvokeOf ? 'Re-invoke' : 'Invoke');
|
|
29489
29550
|
const msg = el('div', 'err');
|
|
29490
29551
|
composer.appendChild(btn);
|
|
29491
29552
|
composer.appendChild(msg);
|
|
@@ -29495,7 +29556,17 @@ const STUDIO_SCRIPT = `
|
|
|
29495
29556
|
ws.appendChild(composer);
|
|
29496
29557
|
ws.appendChild(result);
|
|
29497
29558
|
|
|
29498
|
-
active = {
|
|
29559
|
+
active = {
|
|
29560
|
+
id,
|
|
29561
|
+
kind,
|
|
29562
|
+
ta,
|
|
29563
|
+
btn,
|
|
29564
|
+
msg,
|
|
29565
|
+
result,
|
|
29566
|
+
collectOpts: opt.collect,
|
|
29567
|
+
collectRaw: opt.collectRaw,
|
|
29568
|
+
reinvokeOf: reinvokeOf || null,
|
|
29569
|
+
};
|
|
29499
29570
|
btn.onclick = () => runInvoke();
|
|
29500
29571
|
shownInvId = null;
|
|
29501
29572
|
shownDetailId = null;
|
|
@@ -29512,17 +29583,29 @@ const STUDIO_SCRIPT = `
|
|
|
29512
29583
|
msg.textContent = 'Invalid JSON: ' + err.message;
|
|
29513
29584
|
return;
|
|
29514
29585
|
}
|
|
29586
|
+
const isReinvoke = !!active.reinvokeOf;
|
|
29515
29587
|
msg.textContent = '';
|
|
29516
29588
|
btn.disabled = true;
|
|
29517
|
-
btn.textContent = 'Invoking...';
|
|
29589
|
+
btn.textContent = isReinvoke ? 'Re-invoking...' : 'Invoking...';
|
|
29518
29590
|
result.innerHTML = '';
|
|
29519
29591
|
try {
|
|
29520
|
-
|
|
29521
|
-
|
|
29522
|
-
|
|
29523
|
-
|
|
29524
|
-
|
|
29525
|
-
|
|
29592
|
+
// A re-invoke (issue #284) re-runs a recorded row by id with the edited
|
|
29593
|
+
// payload through POST /api/reinvoke; a fresh invoke runs the target by
|
|
29594
|
+
// POST /api/run with the composed options.
|
|
29595
|
+
let url;
|
|
29596
|
+
let body;
|
|
29597
|
+
if (isReinvoke) {
|
|
29598
|
+
url = '/api/reinvoke';
|
|
29599
|
+
body = { invocationId: active.reinvokeOf, payload: event };
|
|
29600
|
+
} else {
|
|
29601
|
+
url = '/api/run';
|
|
29602
|
+
body = { targetId: id, kind, event };
|
|
29603
|
+
const options = active.collectOpts ? active.collectOpts() : undefined;
|
|
29604
|
+
if (options) body.options = options;
|
|
29605
|
+
const rawArgs = active.collectRaw ? active.collectRaw() : undefined;
|
|
29606
|
+
if (rawArgs) body.rawArgs = rawArgs;
|
|
29607
|
+
}
|
|
29608
|
+
const res = await fetch(url, {
|
|
29526
29609
|
method: 'POST',
|
|
29527
29610
|
headers: { 'content-type': 'application/json' },
|
|
29528
29611
|
body: JSON.stringify(body),
|
|
@@ -29533,13 +29616,14 @@ const STUDIO_SCRIPT = `
|
|
|
29533
29616
|
renderResult(shownInvId);
|
|
29534
29617
|
}
|
|
29535
29618
|
if (!res.ok || data.ok === false) {
|
|
29536
|
-
|
|
29619
|
+
const verb = isReinvoke ? 'Re-invoke' : 'Invoke';
|
|
29620
|
+
msg.textContent = verb + ' failed: ' + (data.error || ('HTTP ' + res.status));
|
|
29537
29621
|
}
|
|
29538
29622
|
} catch (err) {
|
|
29539
29623
|
msg.textContent = 'Request failed: ' + err;
|
|
29540
29624
|
} finally {
|
|
29541
29625
|
btn.disabled = false;
|
|
29542
|
-
btn.textContent = 'Invoke';
|
|
29626
|
+
btn.textContent = isReinvoke ? 'Re-invoke' : 'Invoke';
|
|
29543
29627
|
}
|
|
29544
29628
|
}
|
|
29545
29629
|
|
|
@@ -29597,6 +29681,12 @@ const STUDIO_SCRIPT = `
|
|
|
29597
29681
|
const d = new Date(merged.ts);
|
|
29598
29682
|
row.querySelector('.ts').textContent = d.toLocaleTimeString();
|
|
29599
29683
|
row.querySelector('.label').textContent = (merged.target || '') + ' ' + (merged.label || '');
|
|
29684
|
+
// A re-invoke (issue #284) row is visually linked to its source: a CSS
|
|
29685
|
+
// marker on the label + a tooltip naming the source invocation.
|
|
29686
|
+
if (merged.reinvokeOf) {
|
|
29687
|
+
row.classList.add('reinvoke');
|
|
29688
|
+
row.title = 'Re-invoke of ' + merged.reinvokeOf;
|
|
29689
|
+
}
|
|
29600
29690
|
const statusEl = row.querySelector('.status');
|
|
29601
29691
|
statusEl.textContent =
|
|
29602
29692
|
merged.status != null
|
|
@@ -29619,10 +29709,11 @@ const STUDIO_SCRIPT = `
|
|
|
29619
29709
|
highlightTarget(ev.target);
|
|
29620
29710
|
if (INVOKE_KINDS.includes(ev.kind)) {
|
|
29621
29711
|
// A single-shot invocation row (Lambda or AgentCore) reloads into the
|
|
29622
|
-
// re-invokable composer
|
|
29712
|
+
// re-invokable composer, pre-filled with the captured event and wired to
|
|
29713
|
+
// POST /api/reinvoke (issue #284) so the new row links to this source.
|
|
29623
29714
|
shownDetailId = null;
|
|
29624
29715
|
shownServeId = null;
|
|
29625
|
-
renderComposer(ev.target, ev.kind, ev.request != null ? fmt(ev.request) : '{}');
|
|
29716
|
+
renderComposer(ev.target, ev.kind, ev.request != null ? fmt(ev.request) : '{}', id);
|
|
29626
29717
|
shownInvId = id;
|
|
29627
29718
|
renderResult(id);
|
|
29628
29719
|
} else {
|
|
@@ -29645,6 +29736,36 @@ const STUDIO_SCRIPT = `
|
|
|
29645
29736
|
|
|
29646
29737
|
const head = el('div', 'composer');
|
|
29647
29738
|
head.appendChild(el('div', 'target-name', (ev.label || 'request') + ' — ' + (ev.target || '')));
|
|
29739
|
+
// Re-invoke (issue #284): a captured served request is re-sent through the
|
|
29740
|
+
// live front door by reusing that serve's request composer. Clicking
|
|
29741
|
+
// navigates to the running serve and pre-fills it with this request; the
|
|
29742
|
+
// serve must be running (restart it first if it has stopped).
|
|
29743
|
+
const serveSt = serveState.get(ev.target);
|
|
29744
|
+
const serveRunning = serveSt && serveSt.status === 'running';
|
|
29745
|
+
const reBtn = el('button', 'reinvoke-btn', 'Re-invoke');
|
|
29746
|
+
if (serveRunning) {
|
|
29747
|
+
reBtn.onclick = function () {
|
|
29748
|
+
// Re-check running at CLICK time: the serve may have stopped since the
|
|
29749
|
+
// detail was rendered (the button is not re-rendered on a stop). If so,
|
|
29750
|
+
// do NOT seed a prefill (it would otherwise leak into the next serve
|
|
29751
|
+
// composer). The prefill is address-tagged with the target so a stray
|
|
29752
|
+
// one is dropped on mismatch (see renderRequestComposer).
|
|
29753
|
+
const cur = serveState.get(ev.target);
|
|
29754
|
+
if (!cur || cur.status !== 'running') {
|
|
29755
|
+
renderCapturedDetail(id); // re-render to reflect the now-stopped state
|
|
29756
|
+
return;
|
|
29757
|
+
}
|
|
29758
|
+
pendingReqPrefill =
|
|
29759
|
+
ev.request && typeof ev.request === 'object'
|
|
29760
|
+
? { targetId: ev.target, req: ev.request }
|
|
29761
|
+
: null;
|
|
29762
|
+
selectTarget(ev.target, ev.kind);
|
|
29763
|
+
};
|
|
29764
|
+
} else {
|
|
29765
|
+
reBtn.disabled = true;
|
|
29766
|
+
reBtn.title = 'Start the serve to re-invoke this request.';
|
|
29767
|
+
}
|
|
29768
|
+
head.appendChild(reBtn);
|
|
29648
29769
|
ws.appendChild(head);
|
|
29649
29770
|
|
|
29650
29771
|
const reqSec = el('div', 'section');
|
|
@@ -30132,6 +30253,10 @@ function handleRequest(req, res, bus, html, targetsJson, options) {
|
|
|
30132
30253
|
handleDispatch(req, res, options.onRun);
|
|
30133
30254
|
return;
|
|
30134
30255
|
}
|
|
30256
|
+
if (req.method === "POST" && path === "/api/reinvoke") {
|
|
30257
|
+
handleDispatch(req, res, options.onReinvoke);
|
|
30258
|
+
return;
|
|
30259
|
+
}
|
|
30135
30260
|
if (req.method === "POST" && path === "/api/request") {
|
|
30136
30261
|
handleDispatch(req, res, options.onServeRequest);
|
|
30137
30262
|
return;
|
|
@@ -30458,7 +30583,8 @@ function createStudioDispatcher(config) {
|
|
|
30458
30583
|
target: req.targetId,
|
|
30459
30584
|
kind: req.kind,
|
|
30460
30585
|
label: "invoke",
|
|
30461
|
-
request: req.event
|
|
30586
|
+
request: req.event,
|
|
30587
|
+
...req.reinvokeOf ? { reinvokeOf: req.reinvokeOf } : {}
|
|
30462
30588
|
});
|
|
30463
30589
|
let dir;
|
|
30464
30590
|
try {
|
|
@@ -30511,7 +30637,8 @@ function createStudioDispatcher(config) {
|
|
|
30511
30637
|
request: req.event,
|
|
30512
30638
|
response,
|
|
30513
30639
|
status,
|
|
30514
|
-
durationMs
|
|
30640
|
+
durationMs,
|
|
30641
|
+
...req.reinvokeOf ? { reinvokeOf: req.reinvokeOf } : {}
|
|
30515
30642
|
});
|
|
30516
30643
|
const result = {
|
|
30517
30644
|
invocationId,
|
|
@@ -30683,6 +30810,45 @@ function tryParseJson(raw) {
|
|
|
30683
30810
|
}
|
|
30684
30811
|
}
|
|
30685
30812
|
|
|
30813
|
+
//#endregion
|
|
30814
|
+
//#region src/local/studio-reinvoke.ts
|
|
30815
|
+
/**
|
|
30816
|
+
* The target kinds a timeline row can be re-invoked through the dispatcher.
|
|
30817
|
+
* Single-shot invoke kinds only — a served request (api / alb / ecs) is
|
|
30818
|
+
* re-sent client-side through the request composer + the live front door
|
|
30819
|
+
* (issue #322), not re-dispatched here, so the proxy still captures it.
|
|
30820
|
+
*/
|
|
30821
|
+
const REINVOKABLE_KINDS = new Set(["lambda", "agentcore"]);
|
|
30822
|
+
/**
|
|
30823
|
+
* Re-invoke a past timeline row with an edited payload (issue #284, studio
|
|
30824
|
+
* Phase 3). Resolves the original target from the recorded invocation and
|
|
30825
|
+
* re-fires the edited payload through the SAME single-shot dispatcher
|
|
30826
|
+
* `POST /api/run` uses, threading `reinvokeOf` so the new row links to its
|
|
30827
|
+
* source. The payload REPLACES the original event (the edit IS the point);
|
|
30828
|
+
* run options are not carried over (re-invoke edits the payload, not the
|
|
30829
|
+
* flags).
|
|
30830
|
+
*
|
|
30831
|
+
* Only `lambda` / `agentcore` rows are re-invokable here — a served request
|
|
30832
|
+
* is re-sent through the request composer instead, so this throws for serve
|
|
30833
|
+
* kinds (and for an id that has aged out of the bounded history window).
|
|
30834
|
+
*
|
|
30835
|
+
* Host-side use case: consumed by `cdkl studio`'s `POST /api/reinvoke`
|
|
30836
|
+
* handler; a host CLI embedding the studio building blocks reuses it to wire
|
|
30837
|
+
* the same re-invoke route over its own store + dispatcher.
|
|
30838
|
+
*/
|
|
30839
|
+
async function reinvoke(input, deps) {
|
|
30840
|
+
const original = deps.store.invocation(input.invocationId);
|
|
30841
|
+
if (!original) throw new Error(`No recorded invocation '${input.invocationId}' to re-invoke (it may have aged out of the history window).`);
|
|
30842
|
+
if (!REINVOKABLE_KINDS.has(original.kind)) throw new Error(`Re-invoke from the timeline is server-side only for Lambda / AgentCore targets; re-send a '${original.kind}' request with the request composer instead.`);
|
|
30843
|
+
const req = {
|
|
30844
|
+
targetId: original.target,
|
|
30845
|
+
kind: original.kind,
|
|
30846
|
+
event: input.payload,
|
|
30847
|
+
reinvokeOf: input.invocationId
|
|
30848
|
+
};
|
|
30849
|
+
return deps.dispatcher.run(req);
|
|
30850
|
+
}
|
|
30851
|
+
|
|
30686
30852
|
//#endregion
|
|
30687
30853
|
//#region src/local/studio-request-relay.ts
|
|
30688
30854
|
const DEFAULT_TIMEOUT_MS = 3e4;
|
|
@@ -31367,6 +31533,23 @@ function coerceServeRequest(body) {
|
|
|
31367
31533
|
return out;
|
|
31368
31534
|
}
|
|
31369
31535
|
/**
|
|
31536
|
+
* Validate the `POST /api/reinvoke` body at the HTTP boundary (issue #284):
|
|
31537
|
+
* a non-empty `invocationId` string and a `payload` (the edited event — any
|
|
31538
|
+
* JSON value, including `null`, but the key must be present so an omitted
|
|
31539
|
+
* payload is a clean 4xx rather than a silent re-invoke with `undefined`).
|
|
31540
|
+
*/
|
|
31541
|
+
function coerceReinvokeRequest(body) {
|
|
31542
|
+
if (typeof body !== "object" || body === null) throw new Error("Request body must be a JSON object.");
|
|
31543
|
+
const record = body;
|
|
31544
|
+
const { invocationId } = record;
|
|
31545
|
+
if (typeof invocationId !== "string" || invocationId.trim() === "") throw new Error("Request body must include a non-empty \"invocationId\" string.");
|
|
31546
|
+
if (!("payload" in record)) throw new Error("Request body must include a \"payload\" (the edited event).");
|
|
31547
|
+
return {
|
|
31548
|
+
invocationId,
|
|
31549
|
+
payload: record["payload"]
|
|
31550
|
+
};
|
|
31551
|
+
}
|
|
31552
|
+
/**
|
|
31370
31553
|
* Validate a `PATCH /api/config` body and apply the editable run-time
|
|
31371
31554
|
* bindings (`fromCfnStack` / `assumeRole`) onto `target` in place. Only the
|
|
31372
31555
|
* keys PRESENT in the body are touched (a partial update); `null` / `false` /
|
|
@@ -31545,6 +31728,16 @@ async function localStudioCommand(options) {
|
|
|
31545
31728
|
...req.body !== void 0 ? { body: req.body } : {}
|
|
31546
31729
|
});
|
|
31547
31730
|
},
|
|
31731
|
+
onReinvoke: (body) => {
|
|
31732
|
+
const { invocationId, payload } = coerceReinvokeRequest(body);
|
|
31733
|
+
return reinvoke({
|
|
31734
|
+
invocationId,
|
|
31735
|
+
payload
|
|
31736
|
+
}, {
|
|
31737
|
+
store,
|
|
31738
|
+
dispatcher
|
|
31739
|
+
});
|
|
31740
|
+
},
|
|
31548
31741
|
getRunning: () => ({ running: serveManager.list() }),
|
|
31549
31742
|
getConfig: () => sessionConfigSnapshot(),
|
|
31550
31743
|
patchConfig: (body) => {
|
|
@@ -31627,5 +31820,5 @@ function addStudioSpecificOptions(cmd) {
|
|
|
31627
31820
|
}
|
|
31628
31821
|
|
|
31629
31822
|
//#endregion
|
|
31630
|
-
export {
|
|
31631
|
-
//# sourceMappingURL=local-studio-
|
|
31823
|
+
export { runImageOverrideBuilds as $, resolveCfnStackName as $n, defaultCredentialsLoader as $t, resolveAlbFrontDoor as A, ConnectionRegistry as An, resolveProfileCredentials as Ar, renderCodeDockerfile as At, buildEcsImageResolutionContext$1 as B, resolveRuntimeFileExtension as Bn, createFileWatcher as Bt, formatTargetListing as C, pickResponseTemplate as Cn, resolveAgentCoreTarget as Cr, AGENTCORE_SESSION_ID_HEADER as Ct, parseLbPortOverrides as D, HOST_GATEWAY_MIN_VERSION as Dn, tryResolveImageFnJoin as Dr, SUPPORTED_CODE_RUNTIMES as Dt, createLocalStartAlbCommand as E, VtlEvaluationError as En, substituteImagePlaceholders as Er, downloadAndExtractS3Bundle as Et, createLocalRunTaskCommand as F, buildDisconnectEvent as Fn, addStartApiSpecificOptions as Ft, resolveSharedSidecarCredentials as G, substituteEnvVarsFromState as Gn, availableApiIdentifiers as Gt, parseMaxTasks as H, EcsTaskResolutionError as Hn, buildStageMap as Ht, MAX_TASKS_SUBNET_RANGE_CAP as I, buildMessageEvent as In, createLocalStartApiCommand as It, buildImageOverrideTag as J, createLocalStateProvider as Jn, groupRoutesByServer as Jt, runEcsServiceEmulator as K, substituteEnvVarsFromStateAsync as Kn, filterRoutesByApiIdentifier as Kt, addCommonEcsServiceOptions as L, architectureToPlatform as Ln, createWatchPredicates as Lt, createLocalStartServiceCommand as M, handleConnectionsRequest as Mn, classifySourceChange as Mt, serviceStrategy as N, parseConnectionsPath as Nn, addInvokeSpecificOptions as Nt, resolveAlbTarget as O, probeHostGatewaySupport as On, LocalInvokeBuildError as Or, buildAgentCoreCodeImage as Ot, addRunTaskSpecificOptions as P, buildConnectEvent as Pn, createLocalInvokeCommand as Pt, resolveImageOverrides as Q, resolveCfnRegion as Qn, resolveServiceIntegrationParameters as Qt, addEcsAssumeRoleOptions as R, buildContainerImage as Rn, resolveApiTargetSubset as Rt, createLocalListCommand as S, evaluateResponseParameters as Sn, pickAgentCoreCandidateStack as Sr, signAgentCoreInvocation as St, albStrategy as T, tryParseStatus as Tn, formatStateRemedy as Tr, waitForAgentCorePing as Tt, parseRestartPolicy as U, substituteAgainstState as Un, materializeLayerFromArn as Ut, ecsClusterOption as V, resolveRuntimeImage as Vn, attachStageContext as Vt, resolveEcsAssumeRoleOption as W, substituteAgainstStateAsync as Wn, resolveEnvVars$1 as Wt, mergeForService as X, rejectExplicitCfnStackWithMultipleStacks as Xn, startApiServer as Xt, enforceImageOverrideOrphans as Y, isCfnFlagPresent as Yn, readMtlsMaterialsFromDisk as Yt, parseImageOverrideFlags as Z, resolveCfnFallbackRegion as Zn, resolveSelectionExpression as Zt, toStudioTargetGroups as _, matchRoute as _n, AGENTCORE_AGUI_PROTOCOL as _r, MCP_PATH as _t, createLocalStudioCommand as a, verifyJwtViaDiscovery as an, countTargets as ar, DEFAULT_SHADOW_READY_TIMEOUT_MS as at, StudioEventBus as b, buildHttpApiV2Event as bn, AGENTCORE_RUNTIME_TYPE as br, parseSseForJsonRpc as bt, startStudioProxy as c, evaluateCachedLambdaPolicy as cn, discoverWebSocketApis as cr, getContainerNetworkIp as ct, createStudioDispatcher as d, attachAuthorizers as dn, parseSelectionExpressionPath as dr, createLocalInvokeAgentCoreCommand as dt, buildCognitoJwksUrl as en, CfnLocalStateProvider as er, describePinnedImageUri as et, filterStudioCustomResources as f, applyCorsResponseHeaders as fn, webSocketApiMatchesIdentifier as fr, invokeAgentCoreWs as ft, startStudioServer as g, matchPreflight as gn, AGENTCORE_A2A_PROTOCOL as gr, MCP_CONTAINER_PORT as gt, filterStudioTargetGroups as h, isFunctionUrlOacFronted as hn, resolveLambdaArnIntrinsic as hr, a2aInvokeOnce as ht, coerceStopRequest as i, verifyJwtAuthorizer as in, resolveSingleTarget as ir, CloudMapRegistry as it, addStartServiceSpecificOptions as j, buildMgmtEndpointEnvUrl as jn, toCmdArgv as jt, isApplicationLoadBalancer as k, bufferToBody as kn, buildStsClientConfig as kr, computeCodeImageTag as kt, relayServeRequest as l, invokeRequestAuthorizer as ln, discoverWebSocketApisOrThrow as lr, attachContainerLogStreamer as lt, annotatePinnedEcsTargets as m, buildCorsConfigFromCloudFrontChain as mn, pickRefLogicalId as mr, A2A_PATH as mt, coerceRunRequest as n, createJwksCache as nn, resolveSsmParameters as nr, listPinnedTargets as nt, resolveServeBaseUrl as o, buildMethodArn as on, listTargets as or, SOFT_RELOAD_COMPLETION_LOG_SUFFIX as ot, isCustomResourceLambdaTarget as p, buildCorsConfigByApiId as pn, discoverRoutes as pr, A2A_CONTAINER_PORT as pt, ImageOverrideError as q, LocalStateSourceError as qn, filterRoutesByApiIdentifiers as qt, coerceServeRequest as r, verifyCognitoJwt as rn, resolveWatchConfig as rr, buildCloudMapIndex as rt, createStudioServeManager as s, computeRequestIdentityHash as sn, availableWebSocketApiIdentifiers as sr, setShadowReadyTimeoutMs as st, addStudioSpecificOptions as t, buildJwksUrlFromIssuer as tn, collectSsmParameterRefs as tr, isLocalCdkAssetImage as tt, reinvoke as u, invokeTokenAuthorizer as un, filterWebSocketApisByIdentifiers as ur, addInvokeAgentCoreSpecificOptions as ut, renderStudioHtml as v, translateLambdaResponse as vn, AGENTCORE_HTTP_PROTOCOL as vr, MCP_PROTOCOL_VERSION as vt, addAlbSpecificOptions as w, selectIntegrationResponse as wn, derivePseudoParametersFromRegion as wr, invokeAgentCore as wt, addListSpecificOptions as x, buildRestV1Event as xn, AgentCoreResolutionError as xr, AGENTCORE_SIGV4_SERVICE as xt, createStudioStore as y, applyAuthorizerOverlay as yn, AGENTCORE_MCP_PROTOCOL as yr, mcpInvokeOnce as yt, addImageOverrideOptions as z, resolveRuntimeCodeMountPath as zn, createAuthorizerCache as zt };
|
|
31824
|
+
//# sourceMappingURL=local-studio-CbHZKVYj.js.map
|