mirror of
https://github.com/block/goose.git
synced 2026-07-17 12:56:20 +02:00
More no-window flags (#7122)
This commit is contained in:
@@ -5,8 +5,10 @@ use goose::recipe::RECIPE_FILE_EXTENSIONS;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use goose::recipe::read_recipe_file_content::RecipeFile;
|
||||
use goose::subprocess::SubprocessExt;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
@@ -104,6 +106,7 @@ pub fn ensure_gh_authenticated() -> Result<()> {
|
||||
// Check authentication status
|
||||
let status = Command::new("gh")
|
||||
.args(["auth", "status"])
|
||||
.set_no_window()
|
||||
.status()
|
||||
.map_err(|_| {
|
||||
anyhow::anyhow!("Failed to run `gh auth status`. Make sure you have `gh` installed.")
|
||||
@@ -151,6 +154,7 @@ fn ensure_repo_cloned(recipe_repo_full_name: &str) -> Result<PathBuf> {
|
||||
let status = Command::new("gh")
|
||||
.args(["repo", "clone", recipe_repo_full_name])
|
||||
.current_dir(local_repo_parent_path.clone())
|
||||
.set_no_window()
|
||||
.status()
|
||||
.map_err(|_: std::io::Error| anyhow::anyhow!(error_message.clone()))?;
|
||||
|
||||
@@ -167,6 +171,7 @@ fn fetch_origin(local_repo_path: &Path) -> Result<()> {
|
||||
let status = Command::new("git")
|
||||
.args(["fetch", "origin"])
|
||||
.current_dir(local_repo_path)
|
||||
.set_no_window()
|
||||
.status()
|
||||
.map_err(|_| anyhow::anyhow!(error_message.clone()))?;
|
||||
|
||||
@@ -190,6 +195,7 @@ fn get_folder_from_github(local_repo_path: &Path, recipe_name: &str) -> Result<P
|
||||
.args(["archive", &ref_and_path])
|
||||
.current_dir(local_repo_path)
|
||||
.stdout(Stdio::piped())
|
||||
.set_no_window()
|
||||
.spawn()?;
|
||||
|
||||
let stdout = archive_output
|
||||
@@ -230,6 +236,7 @@ fn discover_github_recipes(repo: &str) -> Result<Vec<RecipeInfo>> {
|
||||
// Get repository contents using GitHub CLI
|
||||
let output = Command::new("gh")
|
||||
.args(["api", &format!("repos/{}/contents", repo)])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.map_err(|e| anyhow!("Failed to fetch repository contents using 'gh api' command (executed when GOOSE_RECIPE_GITHUB_REPO is configured). This requires GitHub CLI (gh) to be installed and authenticated. Error: {}", e))?;
|
||||
|
||||
@@ -269,6 +276,7 @@ fn check_github_directory_for_recipe(repo: &str, dir_name: &str) -> Result<Recip
|
||||
// Check directory contents for recipe files
|
||||
let output = Command::new("gh")
|
||||
.args(["api", &format!("repos/{}/contents/{}", repo, dir_name)])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.map_err(|e| anyhow!("Failed to check directory contents: {}", e))?;
|
||||
|
||||
@@ -306,6 +314,7 @@ fn get_github_recipe_info(repo: &str, dir_name: &str, recipe_filename: &str) ->
|
||||
"api",
|
||||
&format!("repos/{}/contents/{}/{}", repo, dir_name, recipe_filename),
|
||||
])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.map_err(|e| anyhow!("Failed to get recipe file content: {}", e))?;
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ use goose::conversation::message::{
|
||||
ActionRequiredData, Message, MessageContent, ToolRequest, ToolResponse,
|
||||
};
|
||||
use goose::providers::canonical::maybe_get_canonical_model;
|
||||
#[cfg(target_os = "windows")]
|
||||
use goose::subprocess::SubprocessExt;
|
||||
use goose::utils::safe_truncate;
|
||||
use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
|
||||
use rmcp::model::{CallToolRequestParams, JsonObject, PromptArgument};
|
||||
@@ -179,6 +181,7 @@ pub fn run_status_hook(status: &str) {
|
||||
.stdin(std::process::Stdio::null())
|
||||
.stdout(std::process::Stdio::null())
|
||||
.stderr(std::process::Stdio::null())
|
||||
.set_no_window()
|
||||
.status();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use indoc::{formatdoc, indoc};
|
||||
use reqwest::{Client, Url};
|
||||
@@ -710,6 +711,7 @@ impl ComputerControllerServer {
|
||||
.arg(&command)
|
||||
.env("GOOSE_TERMINAL", "1")
|
||||
.env("AGENT", "goose")
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
@@ -725,6 +727,7 @@ impl ComputerControllerServer {
|
||||
.arg(&command)
|
||||
.env("GOOSE_TERMINAL", "1")
|
||||
.env("AGENT", "goose")
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use super::SystemAutomation;
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
@@ -13,6 +14,7 @@ impl SystemAutomation for WindowsAutomation {
|
||||
.arg(script)
|
||||
.env("GOOSE_TERMINAL", "1")
|
||||
.env("AGENT", "goose")
|
||||
.set_no_window()
|
||||
.output()?;
|
||||
|
||||
Ok(String::from_utf8_lossy(&output.stdout).into_owned())
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use anyhow::Result;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
@@ -81,12 +82,14 @@ async fn get_windows_path_async(shell: &str) -> Result<String> {
|
||||
"pwsh" | "powershell" => {
|
||||
Command::new(shell)
|
||||
.args(["-NoLogo", "-Command", "$env:PATH"])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await
|
||||
}
|
||||
_ => {
|
||||
Command::new(shell)
|
||||
.args(["/c", "echo %PATH%"])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use std::{env, ffi::OsString, process::Stdio};
|
||||
|
||||
#[cfg(unix)]
|
||||
@@ -111,6 +112,7 @@ pub fn configure_shell_command(
|
||||
working_dir: Option<&std::path::Path>,
|
||||
) -> tokio::process::Command {
|
||||
let mut command_builder = tokio::process::Command::new(&shell_config.executable);
|
||||
command_builder.set_no_window();
|
||||
|
||||
if let Some(dir) = working_dir {
|
||||
command_builder.current_dir(dir);
|
||||
@@ -177,6 +179,7 @@ pub async fn kill_process_group(
|
||||
// Use taskkill to kill the process tree on Windows
|
||||
let _kill_result = tokio::process::Command::new("taskkill")
|
||||
.args(&["/F", "/T", "/PID", &pid.to_string()])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ pub mod computercontroller;
|
||||
pub mod developer;
|
||||
pub mod mcp_server_runner;
|
||||
mod memory;
|
||||
pub mod subprocess;
|
||||
pub mod tutorial;
|
||||
|
||||
pub use autovisualiser::AutoVisualiserRouter;
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
use tokio::process::Command;
|
||||
|
||||
#[cfg(windows)]
|
||||
const CREATE_NO_WINDOW_FLAG: u32 = 0x08000000;
|
||||
|
||||
pub trait SubprocessExt {
|
||||
fn set_no_window(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl SubprocessExt for Command {
|
||||
fn set_no_window(&mut self) -> &mut Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
self.creation_flags(CREATE_NO_WINDOW_FLAG);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SubprocessExt for std::process::Command {
|
||||
fn set_no_window(&mut self) -> &mut Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
self.creation_flags(CREATE_NO_WINDOW_FLAG);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ use tokio::process::Command;
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::{debug, info, warn};
|
||||
|
||||
use crate::subprocess::SubprocessExt;
|
||||
|
||||
use crate::agents::types::SessionConfig;
|
||||
use crate::agents::types::{
|
||||
RetryConfig, SuccessCheck, DEFAULT_ON_FAILURE_TIMEOUT_SECONDS, DEFAULT_RETRY_TIMEOUT_SECONDS,
|
||||
@@ -243,6 +245,8 @@ pub async fn execute_shell_command(
|
||||
cmd
|
||||
};
|
||||
|
||||
cmd.set_no_window();
|
||||
|
||||
let output = cmd
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
|
||||
@@ -4,6 +4,8 @@ use crate::config::paths::Paths;
|
||||
use crate::config::{get_enabled_extensions, Config};
|
||||
use crate::session::session_manager::CURRENT_SCHEMA_VERSION;
|
||||
use crate::session::SessionManager;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use chrono::{DateTime, Utc};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -141,6 +143,7 @@ fn get_platform_version() -> Option<String> {
|
||||
{
|
||||
std::process::Command::new("cmd")
|
||||
.args(["/C", "ver"])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.ok()
|
||||
.and_then(|o| String::from_utf8(o.stdout).ok())
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::subprocess::SubprocessExt;
|
||||
use chrono;
|
||||
use serde::Deserialize;
|
||||
use std::sync::Arc;
|
||||
@@ -134,6 +135,7 @@ impl AzureAuth {
|
||||
"--resource",
|
||||
"https://cognitiveservices.azure.com",
|
||||
])
|
||||
.set_no_window()
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| AuthError::TokenExchange(format!("Failed to execute Azure CLI: {}", e)))?;
|
||||
|
||||
@@ -3,13 +3,37 @@ use tokio::process::Command;
|
||||
#[cfg(windows)]
|
||||
const CREATE_NO_WINDOW_FLAG: u32 = 0x08000000;
|
||||
|
||||
pub trait SubprocessExt {
|
||||
fn set_no_window(&mut self) -> &mut Self;
|
||||
}
|
||||
|
||||
impl SubprocessExt for Command {
|
||||
fn set_no_window(&mut self) -> &mut Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
self.creation_flags(CREATE_NO_WINDOW_FLAG);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl SubprocessExt for std::process::Command {
|
||||
fn set_no_window(&mut self) -> &mut Self {
|
||||
#[cfg(windows)]
|
||||
{
|
||||
use std::os::windows::process::CommandExt;
|
||||
self.creation_flags(CREATE_NO_WINDOW_FLAG);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn configure_subprocess(command: &mut Command) {
|
||||
// Isolate subprocess into its own process group so it does not receive
|
||||
// SIGINT when the user presses Ctrl+C in the terminal.
|
||||
#[cfg(unix)]
|
||||
command.process_group(0);
|
||||
|
||||
#[cfg(windows)]
|
||||
command.creation_flags(CREATE_NO_WINDOW_FLAG);
|
||||
command.set_no_window();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user