diff --git a/server/src/http/mcp.rs b/server/src/http/mcp.rs index 8aa4aae..30ebd5a 100644 --- a/server/src/http/mcp.rs +++ b/server/src/http/mcp.rs @@ -2121,7 +2121,8 @@ fn add_permission_rule(project_root: &std::path::Path, rule: &str) -> Result<(), /// Rebuild the server binary and re-exec. /// /// 1. Gracefully stops all running agents (kills PTY children). -/// 2. Runs `cargo build --release -p story-kit` from the workspace root. +/// 2. Runs `cargo build [-p story-kit]` from the workspace root, matching +/// the current build profile (debug or release). /// 3. If the build fails, returns the build error (server stays up). /// 4. If the build succeeds, re-execs the process with the new binary via /// `std::os::unix::process::CommandExt::exec()`. @@ -2152,12 +2153,19 @@ async fn tool_rebuild_and_restart(ctx: &AppContext) -> Result { workspace_root.display() ); - // 3. Run `cargo build --release -p story-kit`. + // 3. Build the server binary, matching the current build profile so the + // re-exec via current_exe() picks up the new binary. + let build_args: Vec<&str> = if cfg!(debug_assertions) { + vec!["build", "-p", "story-kit"] + } else { + vec!["build", "--release", "-p", "story-kit"] + }; + slog!("[rebuild] cargo {}", build_args.join(" ")); let output = tokio::task::spawn_blocking({ let workspace_root = workspace_root.to_path_buf(); move || { std::process::Command::new("cargo") - .args(["build", "--release", "-p", "story-kit"]) + .args(&build_args) .current_dir(&workspace_root) .output() } @@ -4298,4 +4306,24 @@ stage = "coder" assert_eq!(ctx.agents.list_agents().unwrap().len(), 0); ctx.agents.kill_all_children(); // should not panic on empty pool } + + #[test] + fn rebuild_uses_matching_build_profile() { + // The build must use the same profile (debug/release) as the running + // binary, otherwise cargo build outputs to a different target dir and + // current_exe() still points at the old binary. + let build_args: Vec<&str> = if cfg!(debug_assertions) { + vec!["build", "-p", "story-kit"] + } else { + vec!["build", "--release", "-p", "story-kit"] + }; + + // Tests always run in debug mode, so --release must NOT be present. + assert!( + !build_args.contains(&"--release"), + "In debug builds, rebuild must not pass --release (would put \ + the binary in target/release/ while current_exe() points to \ + target/debug/)" + ); + } }