From 3c892b95cf66ab228b1986fbf986ee7fac2c66d7 Mon Sep 17 00:00:00 2001 From: Hikari Date: Fri, 20 Mar 2026 09:49:34 -0700 Subject: [PATCH] feat: expose --name CLI flag as session name at startup (#226) Adds session_name to ClaudeStartOptions and passes --name to Claude Code on initial session start, keeping tab names in sync with Claude Code. --- src-tauri/src/config.rs | 3 ++ src-tauri/src/wsl_bridge.rs | 56 +++++++++++++++++++++ src/lib/commands/slashCommands.ts | 2 + src/lib/components/ElicitationModal.svelte | 1 + src/lib/components/InputBar.svelte | 1 + src/lib/components/PermissionModal.svelte | 1 + src/lib/components/StatusBar.svelte | 3 ++ src/lib/components/TaskLoopPanel.svelte | 1 + src/lib/components/UserQuestionModal.svelte | 1 + 9 files changed, 69 insertions(+) diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index ab26da7..2fb18f4 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -51,6 +51,9 @@ pub struct ClaudeStartOptions { #[serde(default)] pub model_overrides: Option>, + + #[serde(default)] + pub session_name: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs index f8790f4..d8cf153 100644 --- a/src-tauri/src/wsl_bridge.rs +++ b/src-tauri/src/wsl_bridge.rs @@ -287,6 +287,13 @@ impl WslBridge { } } + // Pass session name to Claude Code if specified + if let Some(ref name) = options.session_name { + if !name.is_empty() { + cmd.args(["--name", name]); + } + } + // Add worktree flag if requested if options.use_worktree { cmd.arg("--worktree"); @@ -466,6 +473,14 @@ impl WslBridge { } } + // Pass session name to Claude Code if specified + if let Some(ref name) = options.session_name { + if !name.is_empty() { + let escaped = name.replace('\'', "'\\''"); + claude_cmd.push_str(&format!(" --name '{}'", escaped)); + } + } + // Add worktree flag if requested if options.use_worktree { claude_cmd.push_str(" --worktree"); @@ -3577,4 +3592,45 @@ mod tests { "Session stopped due to an unknown API error" ); } + + /// Build the --name argument string without executing a command (for testing) + #[cfg(test)] + fn build_session_name_arg(name: &str) -> Option<(String, String)> { + if name.is_empty() { + return None; + } + Some(("--name".to_string(), name.to_string())) + } + + #[test] + fn test_e2e_session_name_passed_when_set() { + let name = "Sakura"; + let result = build_session_name_arg(name); + assert!(result.is_some()); + let (flag, value) = result.unwrap(); + assert_eq!(flag, "--name"); + assert_eq!(value, "Sakura"); + } + + #[test] + fn test_e2e_session_name_not_passed_when_none() { + let options = ClaudeStartOptions { + session_name: None, + ..Default::default() + }; + // When session_name is None, no --name arg should be produced + let has_name = options.session_name.as_deref().map(|n| !n.is_empty()).unwrap_or(false); + assert!(!has_name); + } + + #[test] + fn test_e2e_session_name_not_passed_when_empty() { + let options = ClaudeStartOptions { + session_name: Some(String::new()), + ..Default::default() + }; + // When session_name is Some(""), no --name arg should be produced + let has_name = options.session_name.as_deref().map(|n| !n.is_empty()).unwrap_or(false); + assert!(!has_name); + } } diff --git a/src/lib/commands/slashCommands.ts b/src/lib/commands/slashCommands.ts index 78f1a10..d19e871 100644 --- a/src/lib/commands/slashCommands.ts +++ b/src/lib/commands/slashCommands.ts @@ -71,6 +71,7 @@ async function changeDirectory(path: string): Promise { enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, }); @@ -152,6 +153,7 @@ async function startNewConversation(): Promise { enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, }); diff --git a/src/lib/components/ElicitationModal.svelte b/src/lib/components/ElicitationModal.svelte index 47d82a3..0b3a4ca 100644 --- a/src/lib/components/ElicitationModal.svelte +++ b/src/lib/components/ElicitationModal.svelte @@ -72,6 +72,7 @@ enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, }); diff --git a/src/lib/components/InputBar.svelte b/src/lib/components/InputBar.svelte index fbb799f..718ebc2 100644 --- a/src/lib/components/InputBar.svelte +++ b/src/lib/components/InputBar.svelte @@ -406,6 +406,7 @@ User: ${formattedMessage}`; enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, }); diff --git a/src/lib/components/PermissionModal.svelte b/src/lib/components/PermissionModal.svelte index f4035f3..9f8f7e1 100644 --- a/src/lib/components/PermissionModal.svelte +++ b/src/lib/components/PermissionModal.svelte @@ -93,6 +93,7 @@ enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, }); diff --git a/src/lib/components/StatusBar.svelte b/src/lib/components/StatusBar.svelte index 9b69a63..a4d9887 100644 --- a/src/lib/components/StatusBar.svelte +++ b/src/lib/components/StatusBar.svelte @@ -160,6 +160,7 @@ if (!conversationId) { throw new Error("No active conversation"); } + const activeConversationForName = get(conversationsStore.activeConversation); await invoke("start_claude", { conversationId, options: { @@ -177,6 +178,7 @@ enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true, auto_memory_directory: currentConfig.auto_memory_directory || null, model_overrides: currentConfig.model_overrides || null, + session_name: activeConversationForName?.name || null, }, }); @@ -338,6 +340,7 @@ enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true, auto_memory_directory: currentConfig.auto_memory_directory || null, model_overrides: currentConfig.model_overrides || null, + session_name: null, }, }); diff --git a/src/lib/components/TaskLoopPanel.svelte b/src/lib/components/TaskLoopPanel.svelte index cacd72a..82daaba 100644 --- a/src/lib/components/TaskLoopPanel.svelte +++ b/src/lib/components/TaskLoopPanel.svelte @@ -222,6 +222,7 @@ enable_claudeai_mcp_servers: cfg.enable_claudeai_mcp_servers ?? true, auto_memory_directory: cfg.auto_memory_directory || null, model_overrides: cfg.model_overrides || null, + session_name: null, }, }); } catch (error) { diff --git a/src/lib/components/UserQuestionModal.svelte b/src/lib/components/UserQuestionModal.svelte index bcaf500..e887b7f 100644 --- a/src/lib/components/UserQuestionModal.svelte +++ b/src/lib/components/UserQuestionModal.svelte @@ -112,6 +112,7 @@ enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true, auto_memory_directory: config.auto_memory_directory || null, model_overrides: config.model_overrides || null, + session_name: null, }, });