feat(daemon): RestartSurface honors resume — swap to resume_args when mapped
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -291,6 +291,23 @@ fn spawn_env(sid: &SurfaceId, spec: &spacesh_proto::workspace::SurfaceSpec) -> (
|
||||
(env, active)
|
||||
}
|
||||
|
||||
/// Build the spawn spec for a (re)start. When `resume` and the command has a
|
||||
/// resume mapping, its args are replaced with the resume args; otherwise the
|
||||
/// original spec args are kept.
|
||||
fn resume_spec(
|
||||
spec: &spacesh_proto::workspace::SurfaceSpec,
|
||||
resume: bool,
|
||||
cfg: &crate::config::Config,
|
||||
) -> spacesh_proto::workspace::SurfaceSpec {
|
||||
let mut out = spec.clone();
|
||||
if resume {
|
||||
if let Some(args) = cfg.resume_args(&spec.command) {
|
||||
out.args = args;
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
/// Emit a `layout_changed` event for a workspace's current tree.
|
||||
fn emit_layout(reg: &Registry, ws_id: &WorkspaceId, clients: &HashMap<ClientId, ClientTx>) {
|
||||
if let Some(w) = reg.workspace(ws_id) {
|
||||
@@ -475,13 +492,14 @@ async fn handle_request(
|
||||
let _ = out.send(ok(id, serde_json::json!({ "surface_ids": new_ids.iter().map(|s| s.0.clone()).collect::<Vec<_>>() }))).await;
|
||||
}
|
||||
|
||||
Cmd::RestartSurface { surface_id } => {
|
||||
Cmd::RestartSurface { surface_id, resume } => {
|
||||
if reg.is_running(&surface_id) {
|
||||
let _ = out.send(ok(id, serde_json::Value::Null)).await; return; // already running
|
||||
}
|
||||
let Some(spec) = reg.surface_spec(&surface_id) else {
|
||||
let _ = out.send(err(id, "NOT_FOUND", "surface")).await; return;
|
||||
};
|
||||
let spec = resume_spec(&spec, resume, config);
|
||||
let ws_id = reg.workspace_of(&surface_id).unwrap();
|
||||
let (env, hooks_active) = spawn_env(&surface_id, &spec);
|
||||
match crate::surface::spawn_from_spec(surface_id.clone(), ws_id.clone(), &spec, env, hooks_active, state_tx.clone(), exit_tx.clone(), snapshot_tx.clone()) {
|
||||
@@ -1607,4 +1625,25 @@ mod tests {
|
||||
let snap = data["snapshot"].as_str().unwrap_or("");
|
||||
assert!(snap.contains("SNAPDISK"), "on-disk snapshot should contain SNAPDISK, got: {snap:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resume_spec_swaps_args_when_mapped() {
|
||||
use spacesh_proto::workspace::SurfaceSpec;
|
||||
let spec = SurfaceSpec {
|
||||
command: "claude".into(), args: vec!["--foo".into()], cwd: "/tmp".into(),
|
||||
agent_label: Some("claude".into()), cols: 80, rows: 24, autostart: false,
|
||||
};
|
||||
let cfg = crate::config::Config::default();
|
||||
// resume=false → original args
|
||||
let plain = resume_spec(&spec, false, &cfg);
|
||||
assert_eq!(plain.args, vec!["--foo".to_string()]);
|
||||
// resume=true with a default mapping → resume args
|
||||
let resumed = resume_spec(&spec, true, &cfg);
|
||||
assert_eq!(resumed.args, vec!["--continue".to_string()]);
|
||||
// resume=true for an unmapped command → original args (graceful fallback)
|
||||
let mut shell = spec.clone();
|
||||
shell.command = "bash".into();
|
||||
let resumed_shell = resume_spec(&shell, true, &cfg);
|
||||
assert_eq!(resumed_shell.args, shell.args);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user