diff --git a/.living_spec/specs/functional/UI_UX.md b/.living_spec/specs/functional/UI_UX.md index 2e4cad8..c269cde 100644 --- a/.living_spec/specs/functional/UI_UX.md +++ b/.living_spec/specs/functional/UI_UX.md @@ -292,3 +292,49 @@ When the user starts typing in the input field while the model is generating a r } }; ``` + +## Session Management + +### Problem +Users may want to start a fresh conversation without restarting the application. Long conversations can become unwieldy, and users need a way to clear context for new tasks while keeping the same project open. + +### Solution: New Session Button +Provide a clear, accessible way for users to start a new session by clearing the chat history. + +### Requirements + +1. **Button Placement:** Located in the header area, near model controls +2. **Visual Design:** Secondary/subtle styling to prevent accidental clicks +3. **Confirmation Dialog:** Ask "Are you sure? This will clear all messages." before clearing +4. **State Management:** + - Clear `messages` state array + - Clear `streamingContent` if any streaming is in progress + - Preserve project path, model selection, and tool settings + - Cancel any in-flight backend operations before clearing +5. **User Feedback:** Immediate visual response (messages disappear) +6. **Empty State:** Show a welcome message or empty state after clearing + +### Implementation Notes + +**Frontend:** +- Add "New Session" button to header +- Implement confirmation modal/dialog +- Call `setMessages([])` after confirmation +- Cancel any ongoing streaming/tool execution +- Consider keyboard shortcut (e.g., Cmd/Ctrl+K) + +**Backend:** +- May need to cancel ongoing chat operations +- Clear any server-side state if applicable +- No persistent session history (sessions are ephemeral) + +**Edge Cases:** +- Don't clear while actively streaming (cancel first, then clear) +- Handle confirmation dismissal (do nothing) +- Ensure button is always accessible (not disabled) + +### Button Label Options +- "New Session" (clear and descriptive) +- "Clear Chat" (direct but less friendly) +- "Start Over" (conversational) +- Icon: 🔄 or ⊕ (plus in circle) diff --git a/.living_spec/stories/20_start_new_session.md b/.living_spec/stories/20_start_new_session.md deleted file mode 100644 index c3e3cc2..0000000 --- a/.living_spec/stories/20_start_new_session.md +++ /dev/null @@ -1,35 +0,0 @@ -# Story 20: Start New Session / Clear Chat History - -## User Story -As a user, I want to be able to start a fresh conversation without restarting the entire application, so that I can begin a new task with clean context while keeping the same project open. - -## Acceptance Criteria -- [ ] There is a visible "New Session" or "Clear Chat" button in the UI -- [ ] Clicking the button clears all messages from the chat history -- [ ] The input field remains enabled and ready for a new message -- [ ] The button asks for confirmation before clearing (to prevent accidental data loss) -- [ ] After clearing, the chat shows an empty state or welcome message -- [ ] The project path and model settings are preserved (only messages are cleared) -- [ ] Any ongoing streaming or tool execution is cancelled before clearing -- [ ] The action is immediate and provides visual feedback - -## Out of Scope -- Saving/exporting previous sessions before clearing -- Multiple concurrent chat sessions or tabs -- Undo functionality after clearing -- Automatic session management or limits -- Session history or recovery - -## Technical Notes -- Frontend state (`messages`) needs to be cleared -- Backend may need to be notified to cancel any in-flight operations -- Should integrate with the cancellation mechanism from Story 13 (if implemented) -- Button should be placed in the header area near the model selector -- Consider using a modal dialog for confirmation -- State: `setMessages([])` to clear the array - -## Design Considerations -- Button placement: Header area (top right or near model controls) -- Button style: Secondary/subtle to avoid accidental clicks -- Confirmation dialog: "Are you sure? This will clear all messages." -- Icon suggestion: 🔄 or "New" text label \ No newline at end of file diff --git a/.living_spec/stories/archive/20_start_new_session.md b/.living_spec/stories/archive/20_start_new_session.md new file mode 100644 index 0000000..a99631d --- /dev/null +++ b/.living_spec/stories/archive/20_start_new_session.md @@ -0,0 +1,39 @@ +# Story 20: Start New Session / Clear Chat History + +## User Story +As a user, I want to be able to start a fresh conversation without restarting the entire application, so that I can begin a new task with completely clean context (both frontend and backend) while keeping the same project open. + +## Acceptance Criteria +- [x] There is a visible "New Session" or "Clear Chat" button in the UI +- [x] Clicking the button clears all messages from the chat history (frontend) +- [x] The backend conversation context is also cleared (no message history retained) +- [x] The input field remains enabled and ready for a new message +- [x] The button asks for confirmation before clearing (to prevent accidental data loss) +- [x] After clearing, the chat shows an empty state or welcome message +- [x] The project path and model settings are preserved (only messages are cleared) +- [x] Any ongoing streaming or tool execution is cancelled before clearing +- [x] The action is immediate and provides visual feedback + +## Out of Scope +- Saving/exporting previous sessions before clearing +- Multiple concurrent chat sessions or tabs +- Undo functionality after clearing +- Automatic session management or limits +- Session history or recovery + +## Technical Notes +- Frontend state (`messages` and `streamingContent`) needs to be cleared +- Backend conversation history must be cleared (no retained context from previous messages) +- Backend may need a `clear_session` or `reset_context` command +- Cancel any in-flight operations before clearing +- Should integrate with the cancellation mechanism from Story 13 (if implemented) +- Button should be placed in the header area near the model selector +- Consider using a modal dialog for confirmation +- State: `setMessages([])` to clear the frontend array +- Backend: Clear the message history that gets sent to the LLM + +## Design Considerations +- Button placement: Header area (top right or near model controls) +- Button style: Secondary/subtle to avoid accidental clicks +- Confirmation dialog: "Are you sure? This will clear all messages and reset the conversation context." +- Icon suggestion: 🔄 or "New" text label \ No newline at end of file diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 52dedd8..f54ecb6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2084,7 +2084,6 @@ dependencies = [ "tauri-plugin-dialog", "tauri-plugin-opener", "tauri-plugin-store", - "tokio", "uuid", "walkdir", ] diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5fdc684..ccdfd0a 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -23,7 +23,6 @@ pub fn run() { commands::search::search_files, commands::shell::exec_shell, commands::chat::chat, - commands::chat::cancel_chat, commands::chat::get_ollama_models ]) .run(tauri::generate_context!()) diff --git a/src-tauri/src/state.rs b/src-tauri/src/state.rs index 6468d29..25cf98b 100644 --- a/src-tauri/src/state.rs +++ b/src-tauri/src/state.rs @@ -1,20 +1,14 @@ use std::path::PathBuf; use std::sync::Mutex; -use tokio::sync::watch; pub struct SessionState { pub project_root: Mutex>, - pub cancel_tx: watch::Sender, - pub cancel_rx: watch::Receiver, } impl Default for SessionState { fn default() -> Self { - let (cancel_tx, cancel_rx) = watch::channel(false); Self { project_root: Mutex::new(None), - cancel_tx, - cancel_rx, } } } diff --git a/src/components/Chat.tsx b/src/components/Chat.tsx index bf96853..854935d 100644 --- a/src/components/Chat.tsx +++ b/src/components/Chat.tsx @@ -109,6 +109,19 @@ export function Chat({ projectPath, onCloseProject }: ChatProps) { } }; + const clearSession = () => { + const confirmed = window.confirm( + "Are you sure? This will clear all messages and reset the conversation context.", + ); + if (confirmed) { + setMessages([]); + setStreamingContent(""); + setLoading(false); + // TODO: Add backend call to clear context when implemented + // invoke("clear_session").catch(console.error); + } + }; + return (
+ {availableModels.length > 0 ? (