mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
Fix Ghostty session restore launch path (#1976)
* fix: launch Ghostty via shell command Use Ghostty's shell execution path instead of injecting raw terminal input so Claude resume commands run reliably when opening a session terminal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(ghostty): pass cwd via --working-directory instead of shell string Use Ghostty's native --working-directory flag to set the working directory, matching the pattern used by Alacritty. This avoids shell expansion of special characters (e.g. $VAR, spaces) in project paths. The command is now passed directly to -c without a cd prefix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -78,22 +78,7 @@ end tell"#
|
||||
}
|
||||
|
||||
fn launch_ghostty(command: &str, cwd: Option<&str>) -> Result<(), String> {
|
||||
let args = build_ghostty_args(command, cwd);
|
||||
|
||||
let status = Command::new("open")
|
||||
.args(args.iter().map(String::as_str))
|
||||
.status()
|
||||
.map_err(|e| format!("Failed to launch Ghostty: {e}"))?;
|
||||
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Failed to launch Ghostty. Make sure it is installed.".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn build_ghostty_args(command: &str, cwd: Option<&str>) -> Vec<String> {
|
||||
let input = ghostty_raw_input(command);
|
||||
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/zsh".to_string());
|
||||
|
||||
let mut args = vec![
|
||||
"-na".to_string(),
|
||||
@@ -108,22 +93,22 @@ fn build_ghostty_args(command: &str, cwd: Option<&str>) -> Vec<String> {
|
||||
}
|
||||
}
|
||||
|
||||
args.push(format!("--input={input}"));
|
||||
args
|
||||
}
|
||||
args.push("-e".to_string());
|
||||
args.push(shell);
|
||||
args.push("-l".to_string());
|
||||
args.push("-c".to_string());
|
||||
args.push(command.to_string());
|
||||
|
||||
fn ghostty_raw_input(command: &str) -> String {
|
||||
let mut escaped = String::from("raw:");
|
||||
for ch in command.chars() {
|
||||
match ch {
|
||||
'\\' => escaped.push_str("\\\\"),
|
||||
'\n' => escaped.push_str("\\n"),
|
||||
'\r' => escaped.push_str("\\r"),
|
||||
_ => escaped.push(ch),
|
||||
}
|
||||
let status = Command::new("open")
|
||||
.args(&args)
|
||||
.status()
|
||||
.map_err(|e| format!("Failed to launch Ghostty: {e}"))?;
|
||||
|
||||
if status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("Failed to launch Ghostty. Make sure it is installed.".to_string())
|
||||
}
|
||||
escaped.push_str("\\n");
|
||||
escaped
|
||||
}
|
||||
|
||||
fn launch_kitty(command: &str, cwd: Option<&str>) -> Result<(), String> {
|
||||
@@ -300,43 +285,10 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn ghostty_uses_shell_mode_for_resume_commands() {
|
||||
let args = build_ghostty_args("claude --resume abc-123", Some("/tmp/project dir"));
|
||||
|
||||
fn build_shell_command_keeps_command_without_cwd_prefix_when_not_provided() {
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"-na",
|
||||
"Ghostty",
|
||||
"--args",
|
||||
"--quit-after-last-window-closed=true",
|
||||
"--working-directory=/tmp/project dir",
|
||||
"--input=raw:claude --resume abc-123\\n",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ghostty_keeps_command_without_cwd_prefix_when_not_provided() {
|
||||
let args = build_ghostty_args("claude --resume abc-123", None);
|
||||
|
||||
assert_eq!(
|
||||
args,
|
||||
vec![
|
||||
"-na",
|
||||
"Ghostty",
|
||||
"--args",
|
||||
"--quit-after-last-window-closed=true",
|
||||
"--input=raw:claude --resume abc-123\\n",
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ghostty_escapes_newlines_and_backslashes_in_input() {
|
||||
assert_eq!(
|
||||
ghostty_raw_input("echo foo\\\\bar\npwd"),
|
||||
"raw:echo foo\\\\\\\\bar\\npwd\\n"
|
||||
build_shell_command("claude --resume abc-123", None),
|
||||
"claude --resume abc-123"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -365,4 +317,22 @@ mod tests {
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ghostty_uses_working_directory_arg_for_cwd() {
|
||||
// cwd should be passed as --working-directory, not embedded in the shell command string
|
||||
// This avoids shell expansion of special characters in directory paths
|
||||
let cwd = "/tmp/project dir";
|
||||
let command = "claude --resume abc-123";
|
||||
|
||||
// Verify build_shell_command does NOT include cwd when used in ghostty context
|
||||
// (ghostty passes cwd via --working-directory flag instead)
|
||||
assert_eq!(
|
||||
build_shell_command(command, None),
|
||||
"claude --resume abc-123"
|
||||
);
|
||||
|
||||
// Verify shell_escape works correctly for paths with spaces
|
||||
assert_eq!(shell_escape(cwd), "\"/tmp/project dir\"");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user