Skip to content

Commit 946a9c1

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/port-provider-test-to-ts' into port-provider-test-to-ts
2 parents 532468d + 33aee21 commit 946a9c1

34 files changed

Lines changed: 989 additions & 386 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/goose-acp/Cargo.toml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,6 @@ license.workspace = true
77
repository.workspace = true
88
description.workspace = true
99

10-
[[bin]]
11-
name = "goose-acp-server"
12-
path = "src/bin/server.rs"
13-
1410
[[bin]]
1511
name = "generate-acp-schema"
1612
path = "src/bin/generate_acp_schema.rs"
@@ -44,10 +40,8 @@ url = { workspace = true }
4440

4541
# HTTP server dependencies
4642
axum = { workspace = true, features = ["ws"] }
47-
clap = { workspace = true }
4843
serde = { workspace = true, features = ["derive"] }
4944
tower-http = { workspace = true, features = ["cors"] }
50-
tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
5145
async-stream = { workspace = true }
5246
http-body-util = "0.1.3"
5347
uuid = { workspace = true, features = ["v7"] }

crates/goose-acp/src/bin/server.rs

Lines changed: 0 additions & 57 deletions
This file was deleted.

crates/goose-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ clap_complete = "4.5.62"
6363
comfy-table = "7.2.2"
6464
sha2 = { workspace = true }
6565
sigstore-verify = { version = "0.6", default-features = false }
66+
axum.workspace = true
6667

6768
[target.'cfg(target_os = "windows")'.dependencies]
6869
winapi = { workspace = true }

crates/goose-cli/src/cli.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,26 @@ enum Command {
732732
builtins: Vec<String>,
733733
},
734734

735+
/// Start ACP server over HTTP and WebSocket
736+
#[command(about = "Start ACP server over HTTP and WebSocket")]
737+
Serve {
738+
#[arg(long, default_value = "127.0.0.1")]
739+
host: String,
740+
741+
#[arg(long, default_value = "3284")]
742+
port: u16,
743+
744+
#[arg(
745+
long = "with-builtin",
746+
value_name = "NAME",
747+
help = "Add builtin extensions by name (e.g., 'developer' or multiple: 'developer,github')",
748+
long_help = "Add one or more builtin extensions that are bundled with goose by specifying their names, comma-separated",
749+
value_delimiter = ',',
750+
action = clap::ArgAction::Append
751+
)]
752+
builtins: Vec<String>,
753+
},
754+
735755
/// Start or resume interactive chat sessions
736756
#[command(
737757
about = "Start or resume interactive chat sessions",
@@ -1009,6 +1029,7 @@ fn get_command_name(command: &Option<Command>) -> &'static str {
10091029
Some(Command::Info { .. }) => "info",
10101030
Some(Command::Mcp { .. }) => "mcp",
10111031
Some(Command::Acp { .. }) => "acp",
1032+
Some(Command::Serve { .. }) => "serve",
10121033
Some(Command::Session { .. }) => "session",
10131034
Some(Command::Project {}) => "project",
10141035
Some(Command::Projects) => "projects",
@@ -1038,6 +1059,35 @@ async fn handle_mcp_command(server: McpCommand) -> Result<()> {
10381059
Ok(())
10391060
}
10401061

1062+
async fn handle_serve_command(host: String, port: u16, builtins: Vec<String>) -> Result<()> {
1063+
use goose::config::paths::Paths;
1064+
use goose_acp::server_factory::{AcpServer, AcpServerFactoryConfig};
1065+
use std::net::SocketAddr;
1066+
use std::sync::Arc;
1067+
use tracing::info;
1068+
1069+
let builtins = if builtins.is_empty() {
1070+
vec!["developer".to_string()]
1071+
} else {
1072+
builtins
1073+
};
1074+
1075+
let server = Arc::new(AcpServer::new(AcpServerFactoryConfig {
1076+
builtins,
1077+
data_dir: Paths::data_dir(),
1078+
config_dir: Paths::config_dir(),
1079+
}));
1080+
let router = goose_acp::transport::create_router(server);
1081+
1082+
let addr: SocketAddr = format!("{}:{}", host, port).parse()?;
1083+
info!("Starting ACP server on {}", addr);
1084+
1085+
let listener = tokio::net::TcpListener::bind(addr).await?;
1086+
axum::serve(listener, router).await?;
1087+
1088+
Ok(())
1089+
}
1090+
10411091
async fn handle_session_subcommand(command: SessionCommand) -> Result<()> {
10421092
match command {
10431093
SessionCommand::List {
@@ -1708,6 +1758,11 @@ pub async fn cli() -> anyhow::Result<()> {
17081758
Some(Command::Info { verbose }) => handle_info(verbose),
17091759
Some(Command::Mcp { server }) => handle_mcp_command(server).await,
17101760
Some(Command::Acp { builtins }) => goose_acp::server::run(builtins).await,
1761+
Some(Command::Serve {
1762+
host,
1763+
port,
1764+
builtins,
1765+
}) => handle_serve_command(host, port, builtins).await,
17111766
Some(Command::Session {
17121767
command: Some(cmd), ..
17131768
}) => handle_session_subcommand(cmd).await,

crates/goose/src/agents/agent.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use crate::providers::errors::ProviderError;
4545
use crate::recipe::{Author, Recipe, Response, Settings};
4646
use crate::scheduler_trait::SchedulerTrait;
4747
use crate::security::adversary_inspector::AdversaryInspector;
48+
use crate::security::egress_inspector::EgressInspector;
4849
use crate::security::security_inspector::SecurityInspector;
4950
use crate::session::extension_data::{EnabledExtensionsState, ExtensionState};
5051
use crate::session::{Session, SessionManager};
@@ -262,6 +263,7 @@ impl Agent {
262263

263264
// Add security inspector (highest priority - runs first)
264265
tool_inspection_manager.add_inspector(Box::new(SecurityInspector::new()));
266+
tool_inspection_manager.add_inspector(Box::new(EgressInspector::new()));
265267

266268
// Add adversary inspector (LLM-based review, enabled by ~/.config/goose/adversary.md)
267269
tool_inspection_manager.add_inspector(Box::new(AdversaryInspector::new(provider.clone())));

crates/goose/src/agents/execute_commands.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,8 @@ impl Agent {
154154
if skills.is_empty() {
155155
output.push_str("No skills installed.\n\n");
156156
output.push_str("Skills are loaded from SKILL.md files in:\n");
157-
output.push_str(" - ~/.claude/skills/\n");
158-
output.push_str(" - ~/.config/agents/skills/\n");
159-
output.push_str(" - .goose/skills/ (in current directory)\n");
160-
output.push_str(" - .claude/skills/ (in current directory)\n");
161-
output.push_str(" - .agents/skills/ (in current directory)\n");
157+
output.push_str(" - ~/.agents/skills/ (global)\n");
158+
output.push_str(" - .agents/skills/ (in current project)\n");
162159
} else {
163160
output.push_str(&format!("**Installed skills ({}):**\n\n", skills.len()));
164161
for skill in &skills {

crates/goose/src/agents/platform_extensions/summon.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,7 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec<Source> {
410410
let local_recipe_dirs: Vec<PathBuf> = vec![
411411
working_dir.to_path_buf(),
412412
working_dir.join(".goose/recipes"),
413+
working_dir.join(".agents/recipes"),
413414
];
414415

415416
let global_recipe_dirs: Vec<PathBuf> = std::env::var("GOOSE_RECIPE_PATH")
@@ -419,7 +420,14 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec<Source> {
419420
let sep = if cfg!(windows) { ';' } else { ':' };
420421
p.split(sep).map(PathBuf::from).collect::<Vec<_>>()
421422
})
422-
.chain([config.join("recipes")])
423+
.chain(
424+
[
425+
Some(config.join("recipes")),
426+
home.as_ref().map(|h| h.join(".agents/recipes")),
427+
]
428+
.into_iter()
429+
.flatten(),
430+
)
423431
.collect();
424432

425433
let local_skill_dirs: Vec<PathBuf> = vec![
@@ -429,6 +437,7 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec<Source> {
429437
];
430438

431439
let global_skill_dirs: Vec<PathBuf> = [
440+
home.as_ref().map(|h| h.join(".agents/skills")),
432441
Some(config.join("skills")),
433442
home.as_ref().map(|h| h.join(".claude/skills")),
434443
home.as_ref().map(|h| h.join(".config/agents/skills")),
@@ -440,9 +449,11 @@ fn discover_filesystem_sources(working_dir: &Path) -> Vec<Source> {
440449
let local_agent_dirs: Vec<PathBuf> = vec![
441450
working_dir.join(".goose/agents"),
442451
working_dir.join(".claude/agents"),
452+
working_dir.join(".agents/agents"),
443453
];
444454

445455
let global_agent_dirs: Vec<PathBuf> = [
456+
home.as_ref().map(|h| h.join(".agents/agents")),
446457
Some(config.join("agents")),
447458
home.as_ref().map(|h| h.join(".claude/agents")),
448459
]
@@ -1108,8 +1119,8 @@ impl SummonClient {
11081119
"No sources available for load/delegate.\n\n\
11091120
Sources are discovered from:\n\
11101121
• Current recipe's sub_recipes\n\
1111-
• .goose/recipes/, .goose/skills/, .goose/agents/\n\
1112-
• ~/.config/goose/recipes/, skills/, agents/\n\
1122+
• .agents/skills/, .agents/recipes/, .agents/agents/ (project-level)\n\
1123+
• ~/.agents/skills/, ~/.agents/agents/ (global)\n\
11131124
• GOOSE_RECIPE_PATH directories\n\
11141125
• Builtin skills",
11151126
)]);

crates/goose/src/recipe/local_recipes.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ fn local_recipe_dirs() -> Vec<PathBuf> {
2828
local_dirs.push(get_recipe_library_dir(true));
2929
local_dirs.push(get_recipe_library_dir(false));
3030

31+
// Also scan .agents/recipes/ for consistency with the .agents/ convention
32+
if let Ok(cwd) = env::current_dir() {
33+
local_dirs.push(cwd.join(".agents/recipes"));
34+
}
35+
if let Some(home) = dirs::home_dir() {
36+
local_dirs.push(home.join(".agents/recipes"));
37+
}
38+
3139
let mut dirs: Vec<PathBuf> = local_dirs
3240
.into_iter()
3341
.map(|dir| dir.canonicalize().unwrap_or(dir))

0 commit comments

Comments
 (0)