feat(bootstrap): create temporary settings and config files to prevent data loss refactor(edit_log): switch from Vec to VecDeque for efficient memory management fix(gateway): ensure store directories are created before starting the API server refactor(bgbash): implement a global singleton for BashControl feat(auth): enhance session authentication middleware to use SessionRepository fix(edit_log_repo): update to use VecDeque for in-memory edit log storage fix(memory_repo): add newline escaping for frontmatter fields fix(session_lock_repo): improve error handling for lock file operations fix(bash_tools): prevent path traversal in job_id argument refactor(delete): enforce empty directory deletion in file system tools fix(edit): optimize string replacement to only replace the first occurrence fix(git_cred): improve credential management with piped input to git commands feat(git_operator): add safety filter to block destructive git operations fix(shell): register background jobs in Bash control feat(spawn): add access tier specification for pipeline stages refactor(hive_mind): run directives concurrently for improved performance fix(auth): update refresh token verification in the refresh handler fix(chat): optimize LLM client usage based on model matching fix(conversations): enhance message deletion to target specific indices feat(api): add JWT authentication middleware for all API routes fix(state): implement refresh token verification in JwtTokenService fix(daemon): improve usage tracking with saturating addition fix(tui): handle compacted messages in the TUI state management
79 lines
2.0 KiB
Rust
79 lines
2.0 KiB
Rust
//! Background bash control — list, cancel, and inspect background processes.
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::{Arc, Mutex, OnceLock};
|
|
|
|
use tracing::error;
|
|
|
|
use super::job::BashJob;
|
|
|
|
/// Global accessor for the shared BashControl singleton.
|
|
///
|
|
/// Used by the Bash tool (to register jobs) and BashKill (to look them up).
|
|
pub fn bash_control() -> &'static BashControl {
|
|
static BASH_CONTROL: OnceLock<BashControl> = OnceLock::new();
|
|
BASH_CONTROL.get_or_init(BashControl::new)
|
|
}
|
|
|
|
/// Central registry of all running background bash jobs.
|
|
pub struct BashControl {
|
|
jobs: Mutex<HashMap<String, Arc<BashJob>>>,
|
|
}
|
|
|
|
impl BashControl {
|
|
pub fn new() -> Self {
|
|
BashControl {
|
|
jobs: Mutex::new(HashMap::new()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for BashControl {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
impl BashControl {
|
|
/// Register a new background job.
|
|
pub fn register(&self, job: Arc<BashJob>) {
|
|
if let Ok(mut guard) = self.jobs.lock() {
|
|
guard.insert(job.id.clone(), job);
|
|
}
|
|
}
|
|
|
|
/// Cancel a job by ID.
|
|
pub fn cancel(&self, id: &str) -> bool {
|
|
if let Ok(mut guard) = self.jobs.lock() {
|
|
if let Some(job) = guard.remove(id) {
|
|
job.cancel();
|
|
return true;
|
|
}
|
|
}
|
|
false
|
|
}
|
|
|
|
/// List all active jobs.
|
|
pub fn list(&self) -> Vec<(String, String, bool)> {
|
|
let mut guard = match self.jobs.lock() {
|
|
Ok(g) => g,
|
|
Err(poisoned) => {
|
|
error!("bgbash jobs mutex poisoned, recovering");
|
|
poisoned.into_inner()
|
|
}
|
|
};
|
|
guard.retain(|_, j| j.is_running());
|
|
guard
|
|
.iter()
|
|
.map(|(id, job)| (id.clone(), job.command.clone(), job.is_running()))
|
|
.collect()
|
|
}
|
|
|
|
/// Clean up completed jobs.
|
|
pub fn prune(&self) {
|
|
if let Ok(mut guard) = self.jobs.lock() {
|
|
guard.retain(|_, j| j.is_running());
|
|
}
|
|
}
|
|
}
|