diff --git a/Cargo.lock b/Cargo.lock index 8d343c0..4b427a4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2027,9 +2027,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", @@ -2382,9 +2382,9 @@ dependencies = [ [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc", diff --git a/Cargo.toml b/Cargo.toml index d83eb29..22df07b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,12 +38,12 @@ portable-pty = "0.9.0" serde = { version = "1", features = ["derive"] } serde_json = "1" sha2 = "0.10" -tar = "0.4" +tar = "0.4.45" tempfile = "3" thiserror = "2" time = { version = "0.3", features = ["formatting", "macros", "parsing", "serde", "serde-human-readable"] } tokio = { version = "1.50.0", features = ["io-util", "macros", "net", "rt-multi-thread", "sync", "time"] } -ureq = "2.12" +ureq = "2.12.1" uuid = { version = "1.22.0", features = ["serde", "v7"] } webkit6 = { version = "0.6.1", features = ["v2_50"] } xz2 = "0.1" diff --git a/crates/taskers-control/src/controller.rs b/crates/taskers-control/src/controller.rs index 3072887..382164f 100644 --- a/crates/taskers-control/src/controller.rs +++ b/crates/taskers-control/src/controller.rs @@ -382,12 +382,18 @@ impl InMemoryController { ) } ControlCommand::StartSurfaceAgentSession { - workspace_id, - pane_id, + workspace_id: _, + pane_id: _, surface_id, agent_kind, } => { - model.start_surface_agent_session(workspace_id, pane_id, surface_id, agent_kind)?; + let current = resolve_identify_context(model, None, None, Some(surface_id))?; + model.start_surface_agent_session( + current.workspace_id, + current.pane_id, + surface_id, + agent_kind, + )?; ( ControlResponse::Ack { message: "surface agent session started".into(), @@ -1087,6 +1093,94 @@ mod tests { ); } + #[test] + fn surface_agent_start_follows_a_moved_surface_even_with_stale_pane_context() { + let controller = InMemoryController::new(AppModel::new("Main")); + let snapshot = controller.snapshot(); + let source_workspace = snapshot.model.active_workspace().expect("workspace"); + let source_workspace_id = source_workspace.id; + let source_pane_id = source_workspace.active_pane; + + controller + .handle(ControlCommand::CreateSurface { + workspace_id: source_workspace_id, + pane_id: source_pane_id, + kind: PaneKind::Browser, + }) + .expect("create moved surface"); + let moved_surface_id = controller + .snapshot() + .model + .workspaces + .get(&source_workspace_id) + .and_then(|workspace| workspace.panes.get(&source_pane_id)) + .map(|pane| pane.active_surface) + .expect("moved surface"); + + controller + .handle(ControlCommand::CreateWorkspace { + label: "Docs".into(), + }) + .expect("create target workspace"); + let target_workspace_id = controller + .snapshot() + .model + .active_workspace_id() + .expect("target workspace"); + + controller + .handle(ControlCommand::MoveSurfaceToWorkspace { + source_workspace_id, + source_pane_id, + surface_id: moved_surface_id, + target_workspace_id, + }) + .expect("move surface"); + + controller + .handle(ControlCommand::StartSurfaceAgentSession { + workspace_id: source_workspace_id, + pane_id: source_pane_id, + surface_id: moved_surface_id, + agent_kind: "codex".into(), + }) + .expect("start moved surface agent session"); + + let snapshot = controller.snapshot(); + let target_surface = snapshot + .model + .workspaces + .values() + .flat_map(|workspace| { + workspace.panes.values().flat_map(move |pane| { + pane.surfaces + .values() + .map(move |surface| (workspace, pane, surface)) + }) + }) + .find(|(_, _, surface)| surface.id == moved_surface_id) + .expect("target surface"); + + assert_eq!(target_surface.0.id, target_workspace_id); + assert!(target_surface.2.agent_process.is_some()); + assert!(target_surface.2.agent_session.is_none()); + assert_eq!( + target_surface.2.metadata.agent_kind.as_deref(), + Some("codex") + ); + assert_eq!(target_surface.2.metadata.agent_active, true); + assert!( + snapshot + .model + .workspaces + .get(&source_workspace_id) + .and_then(|workspace| workspace.panes.get(&source_pane_id)) + .and_then(|pane| pane.active_surface()) + .and_then(|surface| surface.agent_process.as_ref()) + .is_none() + ); + } + #[test] fn surface_agent_stop_follows_a_moved_surface_even_with_stale_pane_context() { let controller = InMemoryController::new(AppModel::new("Main")); diff --git a/crates/taskers-ghostty/Cargo.toml b/crates/taskers-ghostty/Cargo.toml index f5121ff..aaf08c9 100644 --- a/crates/taskers-ghostty/Cargo.toml +++ b/crates/taskers-ghostty/Cargo.toml @@ -12,12 +12,12 @@ build = "build.rs" [dependencies] libloading = "0.8" serde.workspace = true -tar = "0.4" +tar.workspace = true taskers-domain = { version = "0.3.1", path = "../taskers-domain" } taskers-paths.workspace = true taskers-runtime = { version = "0.3.1", path = "../taskers-runtime" } thiserror.workspace = true -ureq = "2.12" +ureq.workspace = true xz2 = "0.1" [target.'cfg(target_os = "linux")'.dependencies]