@@ -120,6 +120,12 @@ public struct ChatScreen: View {
120120 /// Controls the visibility of the delete confirmation dialog
121121 @State private var showDeleteConfirmation = false
122122
123+ /// Controls the visibility of the session options dialog (terminal vs new session)
124+ @State private var showSessionOptions = false
125+
126+ /// Controls the visibility of the session resumed alert
127+ @State private var showResumeAlert = false
128+
123129 /// Global preferences storage for observing default working directory changes
124130 @Environment ( GlobalPreferencesStorage . self) var globalPreferences
125131
@@ -190,6 +196,24 @@ public struct ChatScreen: View {
190196 Text ( " Are you sure you want to clear the conversation? This action cannot be undone. " )
191197 }
192198 }
199+ . confirmationDialog ( " Continue Session " , isPresented: $showSessionOptions) {
200+ Button ( " Resume in New Session " ) {
201+ resumeInNewSession ( )
202+ }
203+ Button ( " Follow on Terminal " ) {
204+ if let sessionId = viewModel. activeSessionId {
205+ launchTerminalWithSession ( sessionId)
206+ }
207+ }
208+ Button ( " Cancel " , role: . cancel) { }
209+ } message: {
210+ Text ( " Choose how to continue this conversation " )
211+ }
212+ . alert ( " Session Resumed! " , isPresented: $showResumeAlert) {
213+ // No buttons - will auto-dismiss
214+ } message: {
215+ Text ( " You can now continue your conversation " )
216+ }
193217 . onChange ( of: keyboardManager. capturedText, keyboardTextChanged)
194218 . onChange ( of: keyboardManager. shouldFocusTextEditor, focusTextEditorChanged)
195219 . onChange ( of: keyboardManager. shouldRefreshObservation, refreshObservationChanged)
@@ -305,14 +329,14 @@ public struct ChatScreen: View {
305329
306330 @ViewBuilder
307331 private var copySessionButton : some View {
308- if let sessionId = viewModel. activeSessionId {
332+ if viewModel. activeSessionId != nil {
309333 Button ( action: {
310- launchTerminalWithSession ( sessionId )
334+ showSessionOptions = true
311335 } ) {
312- Image ( systemName: isCopied ? " checkmark " : " terminal " )
336+ Image ( systemName: isCopied ? " checkmark " : " ellipsis.vertical.bubble " )
313337 . font ( . title2)
314338 }
315- . help ( " Continue in Terminal " )
339+ . help ( " Continue Session " )
316340 . disabled ( isCopied)
317341 }
318342 }
@@ -404,13 +428,50 @@ public struct ChatScreen: View {
404428 NSPasteboard . general. clearContents ( )
405429 NSPasteboard . general. setString ( text, forType: . string)
406430#endif
407-
431+
408432 isCopied = true
409- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 2 ) {
433+ Task { @MainActor in
434+ try ? await Task . sleep ( for: . seconds( 2 ) )
410435 isCopied = false
411436 }
412437 }
413438
439+ private func resumeInNewSession( ) {
440+ guard let sessionId = viewModel. activeSessionId else { return }
441+
442+ // Get the current working directory
443+ let workingDirectory = viewModel. projectPath
444+
445+ // Clear the current conversation UI (removes all visible messages)
446+ viewModel. clearConversation ( )
447+
448+ // Keep the session ID active so next message continues this conversation
449+ viewModel. sessionManager. selectSession ( id: sessionId)
450+
451+ // Set the working directory
452+ if !workingDirectory. isEmpty {
453+ viewModel. claudeClient. configuration. workingDirectory = workingDirectory
454+ viewModel. projectPath = workingDirectory
455+ viewModel. settingsStorage. setProjectPath ( workingDirectory)
456+ }
457+
458+ // Show success alert
459+ showResumeAlert = true
460+
461+ // Auto-dismiss alert after 1.5 seconds
462+ Task { @MainActor in
463+ try ? await Task . sleep ( for: . seconds( 1.5 ) )
464+ showResumeAlert = false
465+ }
466+
467+ // Show checkmark on button
468+ isCopied = true
469+ Task { @MainActor in
470+ try ? await Task . sleep ( for: . seconds( 2 ) )
471+ isCopied = false
472+ }
473+ }
474+
414475 private func launchTerminalWithSession( _ sessionId: String ) {
415476 // Use the TerminalLauncher helper to launch Terminal
416477 if let error = TerminalLauncher . launchTerminalWithSession (
@@ -423,7 +484,8 @@ public struct ChatScreen: View {
423484 } else {
424485 // Show success indicator
425486 isCopied = true
426- DispatchQueue . main. asyncAfter ( deadline: . now( ) + 2 ) {
487+ Task { @MainActor in
488+ try ? await Task . sleep ( for: . seconds( 2 ) )
427489 isCopied = false
428490 }
429491 }
0 commit comments