fix: make a pending run form read-only while plan mode is active

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
AlexRV12
2026-09-03 16:30:09 +02:00
co-authored by Claude Opus 5
parent 0cab916a0e
commit 9679c404c7
2 changed files with 22 additions and 5 deletions
@@ -35,6 +35,9 @@
name: string
/** Workspace the helper script runs in; defaults to the nav workspace. */
workspace?: string
/** Reaches the fallback editor too, which is what renders when there is no
* `helperScript` — a caller disabling this argument means all of it. */
disabled?: boolean
}
let {
@@ -42,7 +45,8 @@
helperScript,
format,
otherArgs: otherArgs,
workspace = undefined
workspace = undefined,
disabled = false
}: Props = $props()
let [inputType, entrypoint] = $derived(format.includes('-') ? format.split('-', 2) : [format, ''])
@@ -190,7 +194,7 @@
items={safeSelectItems(items || [])}
placeholder="Select items"
noItemsMsg={_items.status === 'loading' ? 'Loading...' : 'No items found'}
disabled={_items.status === 'loading'}
disabled={disabled || _items.status === 'loading'}
/>
{:else if inputType === 'dynselect'}
<Select
@@ -199,6 +203,7 @@
{items}
bind:filterText
loading={!open && _items.status === 'loading'}
{disabled}
clearable
noItemsMsg={_items.status === 'loading' ? 'Loading...' : 'No items found'}
/>
@@ -222,7 +227,7 @@
{#await import('$lib/components/JsonEditor.svelte')}
<Loader2 class="animate-spin" />
{:then Module}
<Module.default code={JSON.stringify(value, null, 2)} bind:value />
<Module.default code={JSON.stringify(value, null, 2)} {disabled} bind:value />
{/await}
</div>
{/if}
@@ -41,6 +41,12 @@
let submitting = $state(false)
let cardNode = $state<HTMLDivElement | undefined>()
// The picker moves while a form sits open, so this is live state, not mount-time. Both
// writes the form makes on its own are held off it — the variable a password field
// mints on its first keystroke, the entrypoint a `dynselect-` argument runs — because
// neither waits for Run, and plan mode promised neither would happen.
const planMode = $derived(aiChatManager.planModeActive)
onMount(() => {
void tick().then(() => cardNode?.scrollIntoView({ block: 'nearest' }))
})
@@ -119,7 +125,10 @@
does not undo it. Everything else waits for the user; keep it that way. -->
<SchemaForm
bind:schema
helperScript={{ source: 'deployed', path: runForm.path, runnable_kind: 'script' }}
helperScript={planMode
? undefined
: { source: 'deployed', path: runForm.path, runnable_kind: 'script' }}
disabled={planMode}
{workspace}
prettifyHeader
lightHeader
@@ -153,6 +162,9 @@
<span class="font-mono">{runForm.strippedKeys.join(', ')}</span>
</p>
{/if}
{#if planMode}
<p class="mt-2 text-2xs text-secondary">{PLAN_MODE_MESSAGES.runFormRefused}</p>
{/if}
</div>
<!-- Both buttons rest while a submit is in flight: the ephemeral variables exist by
@@ -163,7 +175,7 @@
variant="accent"
unifiedSize="sm"
startIcon={{ icon: Play }}
disabled={!isValid || submitting}
disabled={!isValid || submitting || planMode}
onClick={run}
>
Run