diff --git a/gadget-code/frontend/package.json b/gadget-code/frontend/package.json
index ee3d51e..dfa987f 100644
--- a/gadget-code/frontend/package.json
+++ b/gadget-code/frontend/package.json
@@ -30,6 +30,7 @@
"@replit/codemirror-lang-csharp": "^6.2.0",
"@uiw/codemirror-theme-tomorrow-night-blue": "^4.25.9",
"@uiw/react-codemirror": "^4.25.9",
+ "lucide-react": "^1.16.0",
"marked": "^16.4.2",
"react": "^19.2.5",
"react-dom": "^19.2.5",
diff --git a/gadget-code/frontend/src/components/ExpandedPromptEditor.tsx b/gadget-code/frontend/src/components/ExpandedPromptEditor.tsx
index 9a586cb..576b94b 100644
--- a/gadget-code/frontend/src/components/ExpandedPromptEditor.tsx
+++ b/gadget-code/frontend/src/components/ExpandedPromptEditor.tsx
@@ -5,6 +5,7 @@ interface ExpandedPromptEditorProps {
onPromptChange: (value: string) => void;
onSubmit: (e: React.FormEvent) => void;
onClose: () => void;
+ onClearPrompt: () => void;
disabled: boolean;
placeholder: string;
isProcessing: boolean;
@@ -17,6 +18,7 @@ export default function ExpandedPromptEditor({
onPromptChange,
onSubmit,
onClose,
+ onClearPrompt,
disabled,
placeholder,
isProcessing,
@@ -106,6 +108,15 @@ export default function ExpandedPromptEditor({
Prompt Editor
+
{isProcessing ? (
diff --git a/gadget-code/frontend/src/pages/ChatSessionView.tsx b/gadget-code/frontend/src/pages/ChatSessionView.tsx
index bcd2a29..32179eb 100644
--- a/gadget-code/frontend/src/pages/ChatSessionView.tsx
+++ b/gadget-code/frontend/src/pages/ChatSessionView.tsx
@@ -1,5 +1,6 @@
import { useState, useEffect, useRef, useContext, useCallback } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
+import { BrushCleaning, Maximize2 } from 'lucide-react';
import { socketClient } from '../lib/socket';
import { chatSessionApi, projectApi, providerApi, type ChatSession, type ChatTurn, type ChatTurnBlock, ChatTurnStats, ChatSessionMode, type AiProvider, type Project } from '../lib/api';
import { WorkspaceMode } from '../lib/types';
@@ -66,7 +67,13 @@ export default function ChatSessionView() {
const [project, setProject] = useState(null);
const [session, setSession] = useState(null);
const [turns, setTurns] = useState([]);
- const [promptInput, setPromptInput] = useState('');
+ const [promptInput, setPromptInput] = useState(() => {
+ if (sessionId) {
+ const saved = localStorage.getItem(`dtp_draft_prompt_${sessionId}`);
+ if (saved) return saved;
+ }
+ return '';
+ });
const [isProcessing, setIsProcessing] = useState(false);
const [isAborting, setIsAborting] = useState(false);
const [loading, setLoading] = useState(true);
@@ -125,6 +132,17 @@ export default function ChatSessionView() {
scrollToBottom();
}, [turns]);
+ // Persist draft prompt to localStorage so it survives page refreshes and navigation
+ useEffect(() => {
+ if (!sessionId) return;
+ const key = `dtp_draft_prompt_${sessionId}`;
+ if (promptInput) {
+ localStorage.setItem(key, promptInput);
+ } else {
+ localStorage.removeItem(key);
+ }
+ }, [promptInput, sessionId]);
+
useEffect(() => {
return () => {
if (toastTimerRef.current) {
@@ -1283,6 +1301,7 @@ export default function ChatSessionView() {
setIsExpandedEditor(false);
}}
onClose={() => setIsExpandedEditor(false)}
+ onClearPrompt={() => setPromptInput('')}
disabled={promptDisabled}
placeholder={promptPlaceholder}
isProcessing={isProcessing}
@@ -1315,17 +1334,26 @@ export default function ChatSessionView() {
{/* Prompt Input */}