diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-14 05:30:20 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-06-14 05:30:20 +0300 |
| commit | 226e87306deaba017d36583f51ae34e42b303aad (patch) | |
| tree | 2a1155689b75007c15d93735aedfa58db7a05edf /src/persist | |
| parent | 17544c36ee397233e2f7b3319d86e3b517e3b5d0 (diff) | |
fix: preserve tab identity across restored sessions
Diffstat (limited to 'src/persist')
| -rw-r--r-- | src/persist/restore.rs | 117 |
1 files changed, 112 insertions, 5 deletions
diff --git a/src/persist/restore.rs b/src/persist/restore.rs index 229d565d..7c046698 100644 --- a/src/persist/restore.rs +++ b/src/persist/restore.rs @@ -509,11 +509,7 @@ fn restore_tab( .map(|pane_id| { PaneLaunchEnv::from_extra(Vec::new()).with_identity( workspace_id.to_string(), - format!( - "{}:t{}", - workspace_id, - crate::workspace::encode_public_number(number) - ), + crate::workspace::public_tab_id_for_number(workspace_id, number), pane_id.to_string(), ) }) @@ -1312,6 +1308,117 @@ mod tests { assert_eq!(workspace.next_public_tab_number, 6); } + #[tokio::test] + async fn restore_with_gapped_public_tab_numbers_keeps_agent_panel_tab_indices() { + let cwd = std::env::current_dir().unwrap(); + let pane_snap = |id: &str| { + ( + id.parse::<u32>().unwrap(), + super::super::snapshot::PaneSnapshot { + cwd: cwd.clone(), + label: None, + agent_name: None, + agent_session: None, + launch_argv: None, + }, + ) + }; + let final_pane = super::super::snapshot::PaneSnapshot { + cwd: cwd.clone(), + label: Some("planner".into()), + agent_name: Some("planner".into()), + agent_session: Some(super::super::snapshot::PaneAgentSessionSnapshot { + source: "herdr:codex".into(), + agent: "codex".into(), + kind: crate::agent_resume::AgentSessionRefKind::Id, + value: "codex-session".into(), + }), + launch_argv: None, + }; + let snapshot = SessionSnapshot { + version: super::super::snapshot::SNAPSHOT_VERSION, + workspaces: vec![WorkspaceSnapshot { + id: Some("w1".into()), + custom_name: None, + identity_cwd: cwd.clone(), + worktree_space: None, + public_pane_numbers: HashMap::from([(10, 1), (11, 2), (12, 3), (13, 4)]), + next_public_pane_number: 5, + public_tab_numbers: vec![1, 3, 4, 5], + next_public_tab_number: 6, + tabs: vec![ + TabSnapshot { + custom_name: None, + layout: LayoutSnapshot::Pane(10), + panes: HashMap::from([pane_snap("10")]), + zoomed: false, + focused: Some(10), + root_pane: Some(10), + }, + TabSnapshot { + custom_name: None, + layout: LayoutSnapshot::Pane(11), + panes: HashMap::from([pane_snap("11")]), + zoomed: false, + focused: Some(11), + root_pane: Some(11), + }, + TabSnapshot { + custom_name: None, + layout: LayoutSnapshot::Pane(12), + panes: HashMap::from([pane_snap("12")]), + zoomed: false, + focused: Some(12), + root_pane: Some(12), + }, + TabSnapshot { + custom_name: None, + layout: LayoutSnapshot::Pane(13), + panes: HashMap::from([(13, final_pane)]), + zoomed: false, + focused: Some(13), + root_pane: Some(13), + }, + ], + active_tab: 3, + }], + active: Some(0), + selected: 0, + agent_panel_scope: Default::default(), + sidebar_width: None, + sidebar_section_split: None, + collapsed_space_keys: Default::default(), + }; + let (events, _event_rx) = mpsc::channel(4); + + let (workspaces, terminals, _runtimes) = restore( + &snapshot, + None, + 24, + 80, + 0, + test_restore_shell(), + crate::config::ShellModeConfig::NonLogin, + false, + events, + Arc::new(Notify::new()), + Arc::new(AtomicBool::new(false)), + ); + + let workspace = workspaces.first().expect("workspace should restore"); + let agent_pane = workspace.tabs[3].root_pane; + let detail = workspace + .pane_details(&terminals) + .into_iter() + .find(|detail| detail.pane_id == agent_pane) + .expect("restored agent pane should be listed"); + + assert_eq!(workspace.active_tab, 3); + assert_eq!(workspace.tabs[3].number, 5); + assert_eq!(detail.tab_idx, 3); + assert_eq!(detail.agent_label, "planner"); + } + #[test] fn legacy_restore_precomputes_missing_public_pane_numbers() { let cwd = std::env::current_dir().unwrap(); |
