mirror of
https://github.com/block/goose.git
synced 2026-07-03 14:15:10 +02:00
flag for login shell PATH (#9313)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: {
|
||||
|
||||
Reference in New Issue
Block a user