feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
//! Background bash control — list, cancel, and inspect background processes.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use super::job::BashJob;
|
||||
|
||||
/// 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()),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 = self.jobs.lock().unwrap();
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
//! Background bash job — spawns a `bash -c` subprocess and tracks its life.
|
||||
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
/// A handle to a spawned background bash job.
|
||||
pub struct BashJob {
|
||||
pub id: String,
|
||||
pub command: String,
|
||||
pub process: Mutex<Option<Child>>,
|
||||
pub cancelled: AtomicBool,
|
||||
}
|
||||
|
||||
/// Spawn a background bash job and return a handle.
|
||||
///
|
||||
/// The job runs until completion or until `cancel()` is called.
|
||||
pub fn spawn_bash_job(cmd: String) -> Arc<BashJob> {
|
||||
let child = Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(&cmd)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.ok();
|
||||
|
||||
let job = Arc::new(BashJob {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
command: cmd,
|
||||
process: Mutex::new(child),
|
||||
cancelled: AtomicBool::new(false),
|
||||
});
|
||||
|
||||
// Spawn a monitor thread (in production this would use an async task)
|
||||
let job_clone = Arc::clone(&job);
|
||||
std::thread::spawn(move || {
|
||||
let mut guard = job_clone.process.lock().unwrap();
|
||||
if let Some(ref mut child) = *guard {
|
||||
let _ = child.wait();
|
||||
}
|
||||
});
|
||||
|
||||
job
|
||||
}
|
||||
|
||||
impl BashJob {
|
||||
pub fn cancel(&self) {
|
||||
self.cancelled.store(true, Ordering::SeqCst);
|
||||
if let Ok(mut guard) = self.process.lock() {
|
||||
if let Some(ref mut child) = *guard {
|
||||
let _ = child.kill();
|
||||
let _ = child.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_running(&self) -> bool {
|
||||
if self.cancelled.load(Ordering::SeqCst) {
|
||||
return false;
|
||||
}
|
||||
let Ok(mut guard) = self.process.lock() else {
|
||||
return false;
|
||||
};
|
||||
guard.as_mut().map_or(false, |c| {
|
||||
matches!(c.try_wait(), Ok(None))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
//! Background bash job management — spawn, track, and query long-running
|
||||
//! shell processes.
|
||||
|
||||
pub mod control;
|
||||
pub mod job;
|
||||
Reference in New Issue
Block a user