From 9679c404c73c575fdb6e848fb24d936452c30db9 Mon Sep 17 00:00:00 2001
From: AlexRV12 <71396855+AlexRV12@users.noreply.github.com>
Date: Wed, 26 Aug 2026 10:26:09 +0200
Subject: [PATCH] fix: make a pending run form read-only while plan mode is
active
Co-Authored-By: Claude Opus 5 (1M context)
---
frontend/src/lib/components/DynamicInput.svelte | 11 ++++++++---
.../copilot/chat/RunArgsFormDisplay.svelte | 16 ++++++++++++++--
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/frontend/src/lib/components/DynamicInput.svelte b/frontend/src/lib/components/DynamicInput.svelte
index 9f6f3b8261..76395f397f 100644
--- a/frontend/src/lib/components/DynamicInput.svelte
+++ b/frontend/src/lib/components/DynamicInput.svelte
@@ -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'}
@@ -222,7 +227,7 @@
{#await import('$lib/components/JsonEditor.svelte')}
{:then Module}
-
+
{/await}
{/if}
diff --git a/frontend/src/lib/components/copilot/chat/RunArgsFormDisplay.svelte b/frontend/src/lib/components/copilot/chat/RunArgsFormDisplay.svelte
index edac4033b8..beab7e6f6b 100644
--- a/frontend/src/lib/components/copilot/chat/RunArgsFormDisplay.svelte
+++ b/frontend/src/lib/components/copilot/chat/RunArgsFormDisplay.svelte
@@ -41,6 +41,12 @@
let submitting = $state(false)
let cardNode = $state()
+ // 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. -->
{runForm.strippedKeys.join(', ')}