diff options
Diffstat (limited to 'src/app')
| -rw-r--r-- | src/app/agent_resume.rs | 58 | ||||
| -rw-r--r-- | src/app/creation.rs | 1 | ||||
| -rw-r--r-- | src/app/session.rs | 6 |
3 files changed, 62 insertions, 3 deletions
diff --git a/src/app/agent_resume.rs b/src/app/agent_resume.rs index 2cbd93ab..9bf2157f 100644 --- a/src/app/agent_resume.rs +++ b/src/app/agent_resume.rs @@ -233,6 +233,15 @@ impl App { return false; }; + if !cwd.is_dir() { + if let Some(terminal) = self.state.terminals.get_mut(&terminal_id) { + terminal.pending_agent_resume_plan = None; + terminal.restore_error = Some("Saved directory is unavailable. Restore the directory and restart this session.".into()); + terminal.revision = terminal.revision.saturating_add(1); + } + return true; + } + let runtime = match crate::terminal::TerminalRuntime::spawn( pane_id, rows, @@ -257,9 +266,11 @@ impl App { "failed to start shell for deferred agent resume" ); if let Some(terminal) = self.state.terminals.get_mut(&terminal_id) { - terminal.clear_agent_runtime_identity_after_respawn(); + terminal.pending_agent_resume_plan = None; + terminal.restore_error = Some(format!("Could not start the saved shell: {err}. Fix the shell configuration and restart this session.")); + terminal.revision = terminal.revision.saturating_add(1); } - return false; + return true; } }; @@ -380,6 +391,49 @@ mod tests { #[cfg(unix)] #[tokio::test] + async fn failed_deferred_restore_keeps_session_reference_without_retrying_elsewhere() { + for missing_shell in [false, true] { + let mut app = test_app(); + let workspace = crate::workspace::Workspace::test_new("unavailable"); + let pane_id = workspace.tabs[0].root_pane; + let terminal_id = workspace.terminal_id(pane_id).unwrap().clone(); + app.state.workspaces = vec![workspace]; + app.state.active = Some(0); + app.state.ensure_test_terminals(); + if missing_shell { + app.state.default_shell = "__herdr_missing_resume_shell__".into(); + } + let terminal = app.state.terminals.get_mut(&terminal_id).unwrap(); + if !missing_shell { + terminal.cwd = std::env::current_dir() + .unwrap() + .join("__herdr_missing_resume_cwd__"); + assert!(!terminal.cwd.exists()); + } + let session = crate::agent_resume::PersistedAgentSession { + source: "herdr:codex".into(), + agent: "codex".into(), + session_ref: crate::agent_resume::AgentSessionRef::id("resume-test").unwrap(), + }; + terminal.persisted_agent_session = Some(session.clone()); + terminal.pending_agent_resume_plan = Some(crate::agent_resume::AgentResumePlan { + agent: "codex".into(), + argv: long_running_test_argv(), + dedupe_key: "resume-test".into(), + }); + app.start_pending_agent_resume_for_terminal(&terminal_id, 24, 80, true); + assert!(app.terminal_runtimes.get(&terminal_id).is_none()); + let terminal = &app.state.terminals[&terminal_id]; + assert!(terminal.pending_agent_resume_plan.is_none()); + assert_eq!(terminal.persisted_agent_session.as_ref(), Some(&session)); + assert!(terminal.restore_error.is_some()); + assert!(!app.has_pending_agent_resumes()); + assert!(!app.start_pending_agent_resume_for_terminal(&terminal_id, 24, 80, true)); + } + } + + #[cfg(unix)] + #[tokio::test] async fn pending_agent_resume_waits_for_host_theme_before_launch() { let mut app = test_app(); let workspace = crate::workspace::Workspace::test_new("restored"); diff --git a/src/app/creation.rs b/src/app/creation.rs index af34e540..05736fe5 100644 --- a/src/app/creation.rs +++ b/src/app/creation.rs @@ -340,6 +340,7 @@ impl App { foreground_cwd: ws.tabs[tab_idx] .foreground_cwd_for_pane(pane_id, &self.terminal_runtimes) .map(|cwd| cwd.display().to_string()), + restore_error: terminal.restore_error.clone(), label: terminal.manual_label.clone(), agent: terminal.effective_agent_label().map(str::to_string), title: presentation.title, diff --git a/src/app/session.rs b/src/app/session.rs index 08c4cd44..509d4050 100644 --- a/src/app/session.rs +++ b/src/app/session.rs @@ -49,7 +49,11 @@ impl App { self.state.selected, ); let history = self.persist_pane_history.then(|| { - crate::persist::capture_history(&self.state.workspaces, &self.terminal_runtimes) + crate::persist::capture_history( + &snapshot, + &self.state.workspaces, + &self.terminal_runtimes, + ) }); SessionSaveJob::Save { snapshot, history } } |
