Files
buzz/desktop/src-tauri/src/managed_agents/mod.rs
2026-07-14 13:05:25 -04:00

107 lines
3.3 KiB
Rust

mod agent_env;
pub(crate) mod agent_events;
pub(crate) mod agent_snapshot;
pub(crate) mod team_snapshot;
pub(crate) use agent_env::{
baked_build_env, build_buzz_agent_provider_defaults, discovery_env_with_baked_floor,
};
mod backend;
pub(crate) mod config_bridge;
mod discovery;
mod env_vars;
pub(crate) mod git_bash;
pub(crate) mod global_config;
mod nest;
mod persona_avatars;
mod persona_card;
pub(crate) mod persona_events;
mod personas;
#[cfg(windows)]
mod process_lifecycle;
pub(crate) mod readiness;
pub(crate) mod reconcile;
#[cfg(feature = "mesh-llm")]
mod relay_mesh;
mod repos;
mod restore;
pub mod retention;
mod runtime;
pub(crate) mod spawn_hash;
mod storage;
pub(crate) mod team_events;
mod team_repair;
mod teams;
mod types;
// Shared guard for tests that mutate or read process-global PATH.
#[cfg(test)]
static PATH_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());
#[cfg(test)]
pub(crate) fn lock_path_mutex() -> std::sync::MutexGuard<'static, ()> {
PATH_MUTEX.lock().unwrap_or_else(|e| e.into_inner())
}
pub use backend::*;
pub use discovery::*;
pub use env_vars::*;
#[cfg(windows)]
pub(crate) use git_bash::git_bash_available;
pub(crate) use git_bash::{discover_git_bash, GitBashPrerequisite};
pub(crate) use global_config::{
load_global_agent_config, resolve_effective_model_provider, save_global_agent_config,
validate_global_config, GlobalAgentConfig,
};
pub use nest::*;
pub use persona_card::find_plugin_json;
pub use personas::*;
#[cfg(windows)]
pub use process_lifecycle::*;
pub(crate) use readiness::{
agent_readiness, resolve_effective_agent_env, AgentReadiness, Requirement,
};
#[cfg(feature = "mesh-llm")]
pub use relay_mesh::*;
pub use repos::{
effective_repos_dir, ensure_repos_symlink, resolve_repos_at_boot, validate_repos_dir,
write_persisted_repos_dir,
};
pub use restore::*;
pub use runtime::*;
pub use storage::*;
pub use team_repair::{sync_team_personas, team_persona_key};
pub use teams::*;
pub use types::*;
/// Returns the Buzz nest directory (`~/.buzz`) if it exists as a real
/// directory (not a symlink), falling back to the user's home directory.
///
/// Used as the default working directory for spawned agent processes.
/// `ensure_nest()` must be called during app setup before this is first
/// invoked, so that `~/.buzz` exists and gets cached.
///
/// Cached for the process lifetime via `OnceLock`.
/// Returns `None` in sandboxed/containerized environments where `$HOME` is
/// unset or points to a non-existent path; callers fall back to inheriting
/// the parent's CWD.
pub fn default_agent_workdir() -> Option<std::path::PathBuf> {
use std::sync::OnceLock;
static WORKDIR: OnceLock<Option<std::path::PathBuf>> = OnceLock::new();
WORKDIR
.get_or_init(|| {
// Prefer ~/.buzz if it exists (created by ensure_nest()).
// Reject symlinks to prevent redirect attacks — is_dir()
// follows symlinks, so check symlink_metadata() first.
// Fall back to $HOME for resilience.
nest_dir()
.filter(|p| is_real_dir(p))
.or_else(|| dirs::home_dir().filter(|p| p.is_dir()))
})
.clone()
}
/// Returns `true` if `path` is a real directory (not a symlink).
fn is_real_dir(path: &std::path::Path) -> bool {
path.symlink_metadata().map(|m| m.is_dir()).unwrap_or(false)
}