diff --git a/.claude/launch.json b/.claude/launch.json
new file mode 100644
index 0000000000..f39dfd1f15
--- /dev/null
+++ b/.claude/launch.json
@@ -0,0 +1,29 @@
+{
+ "version": "0.0.1",
+ "configurations": [
+ {
+ "name": "frontend",
+ "runtimeExecutable": "npm",
+ "runtimeArgs": ["run", "dev", "--", "--port", "3100"],
+ "port": 3100,
+ "cwd": "frontend",
+ "env": {
+ "REMOTE": "https://app.windmill.dev"
+ }
+ },
+ {
+ "name": "backend",
+ "runtimeExecutable": "cargo",
+ "runtimeArgs": ["run"],
+ "port": 8000,
+ "cwd": "backend"
+ },
+ {
+ "name": "multiplayer",
+ "runtimeExecutable": "npm",
+ "runtimeArgs": ["run", "dev"],
+ "port": 3002,
+ "cwd": "multiplayer"
+ }
+ ]
+}
diff --git a/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte b/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
index 140f20f140..c7999fc489 100644
--- a/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
+++ b/frontend/src/lib/components/copilot/chat/AIChatDisplay.svelte
@@ -2,6 +2,7 @@
import AIChatMessage from './AIChatMessage.svelte'
import { type Snippet } from 'svelte'
import {
+ ArrowUp,
CheckIcon,
Code2,
FileCode,
@@ -122,58 +123,54 @@
{#snippet trigger()}
-
-
{/if}
- 0} class="relative">
+
{#if aiChatManager.loading}
{/if}
-
-
-
- {#if aiChatManager.mode === 'script' && hasDiff}
-
- {/if}
- {#if disabled}
-
-
-
- {:else}
-
+
+
+
+
+ {#if aiChatManager.mode === 'script' && hasDiff}
+
+ {/if}
+ {#if disabled}
+
+
+
+ {:else}
{#if aiChatManager.mode === AIMode.APP}
@@ -367,12 +364,35 @@
{/if}
{/if}
-
+ {/if}
+
+
+ {#if !disabled}
+
{
+ if (aiChatManager.loading) {
+ cancel()
+ } else {
+ aiChatInput?.triggerSend()
+ }
+ }}
+ >
+ {#if aiChatManager.loading}
+
+ {:else}
+
+ {/if}
+
{/if}
{#if (aiChatManager.mode === AIMode.NAVIGATOR || aiChatManager.mode === AIMode.ASK) && suggestions.length > 0 && messages.filter((m) => m.role === 'user').length === 0 && !disabled}
-
+
{#each suggestions as suggestion}
0
+ }
+
$effect(() => {
if (editingMessageIndex !== null) {
focusInput()
@@ -364,29 +375,25 @@