flag for login shell PATH (#9313)

This commit is contained in:
Jack Amadeo
2026-05-19 09:57:49 -04:00
committed by GitHub
parent 259b04d1d4
commit 7dbdfa43fa
12 changed files with 49 additions and 6 deletions
+16 -1
View File
@@ -244,6 +244,7 @@ pub struct GooseAcpAgent {
client_fs_capabilities: OnceCell<FileSystemCapabilities>,
client_terminal: OnceCell<bool>,
client_mcp_host_info: OnceCell<GooseMcpHostInfo>,
use_login_shell_path: OnceCell<bool>,
config_dir: std::path::PathBuf,
session_manager: Arc<SessionManager>,
permission_manager: Arc<PermissionManager>,
@@ -479,6 +480,14 @@ fn extract_client_mcp_host_info(args: &InitializeRequest) -> GooseMcpHostInfo {
}
}
fn extract_use_login_shell_path(args: &InitializeRequest) -> bool {
args.meta
.as_ref()
.and_then(|meta| meta.get("goose/useLoginShellPath"))
.and_then(|v| v.as_bool())
.unwrap_or(false)
}
fn mcp_server_to_extension_config(mcp_server: McpServer) -> Result<ExtensionConfig, String> {
match mcp_server {
McpServer::Stdio(stdio) => {
@@ -1179,6 +1188,7 @@ impl GooseAcpAgent {
client_fs_capabilities: OnceCell::new(),
client_terminal: OnceCell::new(),
client_mcp_host_info: OnceCell::new(),
use_login_shell_path: OnceCell::new(),
config_dir: options.config_dir,
session_manager,
permission_manager,
@@ -1421,6 +1431,7 @@ impl GooseAcpAgent {
.unwrap_or_default();
let client_terminal = self.client_terminal.get().copied().unwrap_or(false);
let client_mcp_host_info = self.client_mcp_host_info.get().cloned();
let use_login_shell_path = self.use_login_shell_path.get().copied().unwrap_or(false);
let provider_factory = Arc::clone(&self.provider_factory);
let disable_session_naming = self.disable_session_naming;
let goose_platform = self.goose_platform.clone();
@@ -1454,7 +1465,8 @@ impl GooseAcpAgent {
goose_platform,
)
.with_mcp_host_info(client_mcp_host_info)
.with_session_name_update_tx(session_name_update_tx),
.with_session_name_update_tx(session_name_update_tx)
.with_use_login_shell_path(use_login_shell_path),
));
// Init provider — reuse the pre-resolved name + model when
@@ -2511,6 +2523,9 @@ impl GooseAcpAgent {
let _ = self
.client_mcp_host_info
.set(extract_client_mcp_host_info(&args));
let _ = self
.use_login_shell_path
.set(extract_use_login_shell_path(&args));
let capabilities = AgentCapabilities::new()
.load_session(true)
+11
View File
@@ -150,6 +150,7 @@ pub struct AgentConfig {
pub goose_platform: GoosePlatform,
pub mcp_host_info: Option<GooseMcpHostInfo>,
pub session_name_update_tx: Option<mpsc::UnboundedSender<SessionNameUpdate>>,
pub use_login_shell_path: Option<bool>,
}
impl AgentConfig {
@@ -170,6 +171,7 @@ impl AgentConfig {
goose_platform,
mcp_host_info: None,
session_name_update_tx: None,
use_login_shell_path: None,
}
}
@@ -185,6 +187,11 @@ impl AgentConfig {
self.session_name_update_tx = tx;
self
}
pub fn with_use_login_shell_path(mut self, use_login_shell_path: bool) -> Self {
self.use_login_shell_path = Some(use_login_shell_path);
self
}
}
/// The main goose Agent
@@ -295,6 +302,9 @@ impl Agent {
.unwrap_or_else(|| goose_platform.to_string());
let session_manager = Arc::clone(&config.session_manager);
let permission_manager = Arc::clone(&config.permission_manager);
let use_login_shell_path = config
.use_login_shell_path
.unwrap_or(matches!(goose_platform, GoosePlatform::GooseDesktop));
Self {
provider: provider.clone(),
config,
@@ -304,6 +314,7 @@ impl Agent {
session_manager,
client_name,
capabilities,
use_login_shell_path,
)),
final_output_tool: Arc::new(Mutex::new(None)),
frontend_extensions: Mutex::new(HashMap::new()),
@@ -741,6 +741,7 @@ impl ExtensionManager {
session_manager: Arc<crate::session::SessionManager>,
client_name: String,
capabilities: ExtensionManagerCapabilities,
use_login_shell_path: bool,
) -> Self {
Self {
extensions: Mutex::new(HashMap::new()),
@@ -748,6 +749,7 @@ impl ExtensionManager {
extension_manager: None,
session_manager,
session: None,
use_login_shell_path,
},
provider,
tools_cache: Mutex::new(None),
@@ -767,6 +769,7 @@ impl ExtensionManager {
mcpui: false,
host_info: None,
},
false,
)
}
@@ -278,6 +278,7 @@ mod tests {
extension_manager: None,
session_manager: Arc::new(SessionManager::new(std::env::temp_dir())),
session: None,
use_login_shell_path: false,
}
}
@@ -64,14 +64,14 @@ fn developer_instructions() -> &'static str {
}
impl DeveloperClient {
pub fn new(_context: PlatformExtensionContext) -> Result<Self> {
pub fn new(context: PlatformExtensionContext) -> Result<Self> {
let info = InitializeResult::new(ServerCapabilities::builder().enable_tools().build())
.with_server_info(Implementation::new(EXTENSION_NAME, "1.0.0").with_title("Developer"))
.with_instructions(developer_instructions());
Ok(Self {
info,
shell_tool: Arc::new(ShellTool::new()?),
shell_tool: Arc::new(ShellTool::new(context.use_login_shell_path)?),
edit_tools: Arc::new(EditTools::new()),
tree_tool: Arc::new(TreeTool::new()),
})
@@ -240,6 +240,7 @@ mod tests {
extension_manager: None,
session_manager: Arc::new(SessionManager::new(data_dir)),
session: None,
use_login_shell_path: false,
}
}
@@ -284,7 +284,6 @@ impl LoginPath {
}
}
#[cfg(test)]
fn resolved(value: Option<String>) -> Self {
let cell = OnceCell::new();
let _ = cell.set(value.map(Arc::from));
@@ -320,12 +319,16 @@ pub struct ShellTool {
}
impl ShellTool {
pub fn new() -> std::io::Result<Self> {
pub fn new(use_login_shell_path: bool) -> std::io::Result<Self> {
Ok(Self {
output_dir: tempfile::tempdir()?,
call_index: AtomicUsize::new(0),
#[cfg(not(windows))]
login_path: LoginPath::spawn(),
login_path: if use_login_shell_path {
LoginPath::spawn()
} else {
LoginPath::resolved(None)
},
})
}
@@ -212,6 +212,7 @@ pub struct PlatformExtensionContext {
Option<std::sync::Weak<crate::agents::extension_manager::ExtensionManager>>,
pub session_manager: std::sync::Arc<crate::session::SessionManager>,
pub session: Option<std::sync::Arc<Session>>,
pub use_login_shell_path: bool,
}
impl PlatformExtensionContext {
@@ -1715,6 +1715,7 @@ mod tests {
extension_manager: None,
session_manager: Arc::new(crate::session::SessionManager::instance()),
session: None,
use_login_shell_path: false,
}
}
@@ -435,6 +435,7 @@ mod tests {
extension_manager: None,
session_manager,
session: Some(Arc::new(session)),
use_login_shell_path: false,
};
let mut extensions: Vec<ExtensionInfo> = PLATFORM_EXTENSIONS
+2
View File
@@ -285,6 +285,7 @@ mod tests {
extension_manager: None,
session_manager: Arc::new(crate::session::SessionManager::instance()),
session: Some(session),
use_login_shell_path: false,
})
.unwrap();
@@ -311,6 +312,7 @@ mod tests {
extension_manager: None,
session_manager: Arc::new(crate::session::SessionManager::instance()),
session: None,
use_login_shell_path: false,
})
.unwrap();
@@ -265,6 +265,7 @@ async fn test_replayed_session(
mcpui: true,
host_info: None,
},
true,
));
#[allow(clippy::redundant_closure_call)]
@@ -86,6 +86,9 @@ async function initializeConnection(): Promise<GooseClient> {
const tInit = performance.now();
await client.initialize({
protocolVersion: PROTOCOL_VERSION,
_meta: {
"goose/useLoginShellPath": true,
},
clientCapabilities: {
_meta: {
goose: {