Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions crates/jcode-config-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -865,3 +865,13 @@ impl Default for GatewayConfig {
}
}
}

/// Terminal / shell execution configuration
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(default)]
pub struct TerminalConfig {
/// Custom shell to use for executing commands (e.g. "nu", "zsh", "fish").
/// Overridden by the JCODE_SHELL environment variable.
/// On Unix, defaults to "bash". On Windows, defaults to "cmd.exe".
pub shell: Option<String>,
}
7 changes: 6 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ pub use jcode_config_types::{
DiffDisplayMode, DisplayConfig, FeatureConfig, GatewayConfig, KeybindingsConfig,
MarkdownSpacingMode, NamedProviderAuth, NamedProviderConfig, NamedProviderModelConfig,
NamedProviderType, NativeScrollbarConfig, ProviderConfig, SafetyConfig,
SessionPickerResumeAction, SwarmSpawnMode, UpdateChannel, WebSearchConfig, WebSearchEngine,
SessionPickerResumeAction, SwarmSpawnMode, TerminalConfig, UpdateChannel, WebSearchConfig,
WebSearchEngine,
};
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, BTreeSet, HashSet};
Expand Down Expand Up @@ -104,6 +105,7 @@ const CONFIG_ENV_KEYS: &[&str] = &[
"JCODE_SCROLL_PROMPT_UP_KEY",
"JCODE_SCROLL_UP_FALLBACK_KEY",
"JCODE_SCROLL_UP_KEY",
"JCODE_SHELL",
"JCODE_SHOW_DIFFS",
"JCODE_SHOW_THINKING",
"JCODE_SIDE_PANEL_NATIVE_SCROLLBAR",
Expand Down Expand Up @@ -383,6 +385,9 @@ pub struct Config {

/// Auto-judge configuration
pub autojudge: AutoJudgeConfig,

/// Terminal / shell execution configuration
pub terminal: TerminalConfig,
}

/// Agent Client Protocol adapter configuration.
Expand Down
5 changes: 5 additions & 0 deletions src/config/env_overrides.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,11 @@ impl Config {
crate::env::set_var("JCODE_COPILOT_PREMIUM", env_val);
}
}

// Terminal
if let Ok(v) = std::env::var("JCODE_SHELL") {
self.terminal.shell = Some(v);
}
}
}

Expand Down
17 changes: 12 additions & 5 deletions src/tool/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,10 @@ async fn handle_background_output_line(
file.flush().await.ok();
}

fn build_shell_command(cmd_str: &str) -> TokioCommand {
fn build_shell_command(shell: Option<&str>, cmd_str: &str) -> TokioCommand {
if let Some(shell_name) = shell {
return TokioCommand::new(shell_name);
}
#[cfg(windows)]
{
let mut cmd = TokioCommand::new("cmd.exe");
Expand Down Expand Up @@ -488,7 +491,7 @@ mod utf8_truncation_tests {
#[cfg(windows)]
#[tokio::test]
async fn build_shell_command_uses_cmd_and_executes_command() {
let output = build_shell_command("echo hello-from-cmd")
let output = build_shell_command(None, "echo hello-from-cmd")
.output()
.await
.expect("run cmd command");
Expand Down Expand Up @@ -627,7 +630,10 @@ impl BashTool {

let has_stdin_channel = ctx.stdin_request_tx.is_some();

let mut command = build_shell_command(&params.command);
let mut command = build_shell_command(
crate::config::config().terminal.shell.as_deref(),
&params.command,
);
command
.kill_on_drop(true)
.stdout(Stdio::piped())
Expand Down Expand Up @@ -899,8 +905,9 @@ impl BashTool {
&ctx.session_id,
notify,
wake,
move |output_path| async move {
let mut cmd = build_shell_command(&command);
move |output_path| async move {
let shell = crate::config::config().terminal.shell.clone();
let mut cmd = build_shell_command(shell.as_deref(), &command);
#[cfg(unix)]
unsafe {
cmd.pre_exec(|| {
Expand Down