diff --git a/frontend/src/lib/components/JsonInputs.svelte b/frontend/src/lib/components/JsonInputs.svelte index 2f4b04f8e4..546ab36069 100644 --- a/frontend/src/lib/components/JsonInputs.svelte +++ b/frontend/src/lib/components/JsonInputs.svelte @@ -13,13 +13,18 @@ * payload nobody has typed into tracks the schema instead of going stale. The first edit * hands the buffer to the user and later changes stop overwriting it. */ initialCode?: string + /** Show the payload without taking edits. For a caller that must keep this editor + * mounted while refusing writes: swapping it for the fields instead would mount the + * widgets, and a `password` field mints a variable from whatever literal it opens on. */ + readOnly?: boolean } let { updateOnBlur = true, placeholder = 'Write a JSON payload. The input schema will be inferred.

Example:

{
  "foo": "12"
}', selected = false, - initialCode = '' + initialCode = '', + readOnly = false }: Props = $props() let pendingJson = $state(untrack(() => initialCode)) @@ -130,6 +135,7 @@ bind:code={pendingJson} lang="json" class="h-full json-inputs-editor" + {readOnly} {placeholder} /> diff --git a/frontend/src/lib/components/RunForm.svelte b/frontend/src/lib/components/RunForm.svelte index cede84f394..c01f7598ca 100644 --- a/frontend/src/lib/components/RunForm.svelte +++ b/frontend/src/lib/components/RunForm.svelte @@ -135,10 +135,13 @@ } | undefined /** Set to refuse every write this form can make, and to say so when a run is - * attempted. No edits, no dynamic-select helper, no JSON, and no run — `run()` mints - * the `password` arguments it is about to send, so refusing in `runAction` is already - * too late. For a form standing in for a chat card under plan mode, which promised - * none of it. */ + * attempted: the fields are disabled, the dynamic-select helper is not wired, the JSON + * editor is read-only, and `run()` refuses before it mints the `password` arguments it + * would send — so a caller cannot gate this in `runAction`, which comes after that + * mint. For a form standing in for a chat card under plan mode, which promised none of + * it. The caller must also leave this form on the side it is showing: swapping fields + * for JSON or back mounts a `password` widget, which mints from the literal it opens + * on regardless of being disabled. */ runRefusal?: string runAction: ( scheduledForStr: string | undefined, @@ -349,6 +352,7 @@ > { // The other way into the arguments, and the one disabling the fields misses. if (argsReadonly) return diff --git a/frontend/src/lib/components/details/FlowDetail.svelte b/frontend/src/lib/components/details/FlowDetail.svelte index 8612f871f9..b9ca597f6d 100644 --- a/frontend/src/lib/components/details/FlowDetail.svelte +++ b/frontend/src/lib/components/details/FlowDetail.svelte @@ -865,6 +865,10 @@ {inputSelected} /> + {#if hasSchema && !pendingRun?.planModeActive} diff --git a/frontend/src/lib/components/details/ScriptDetail.svelte b/frontend/src/lib/components/details/ScriptDetail.svelte index acb61567f8..6d463434eb 100644 --- a/frontend/src/lib/components/details/ScriptDetail.svelte +++ b/frontend/src/lib/components/details/ScriptDetail.svelte @@ -1059,6 +1059,10 @@ }} {inputSelected} /> + {#if hasSchema && !pendingRun?.planModeActive}