Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
54 lines
1.7 KiB
Rust
54 lines
1.7 KiB
Rust
//! [`LocalProcessSpawner`] — local [`ProcessSpawner`] over `tokio::process`
|
|
//! (ARCHITECTURE §5).
|
|
//!
|
|
//! Runs a **non-interactive** process to completion and captures
|
|
//! stdout/stderr/exit code. Used by `DetectProfiles` (via [`CliAgentRuntime`])
|
|
//! and any future short-lived command (git fallbacks, scripts). Interactive
|
|
//! processes go through the PTY port instead.
|
|
|
|
use async_trait::async_trait;
|
|
use tokio::process::Command;
|
|
|
|
use domain::ports::{ExitStatus, Output, ProcessError, ProcessSpawner, SpawnSpec};
|
|
|
|
/// Process spawner backed by the local OS via `tokio::process::Command`.
|
|
#[derive(Debug, Default, Clone, Copy)]
|
|
pub struct LocalProcessSpawner;
|
|
|
|
impl LocalProcessSpawner {
|
|
/// Creates a new [`LocalProcessSpawner`].
|
|
#[must_use]
|
|
pub const fn new() -> Self {
|
|
Self
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl ProcessSpawner for LocalProcessSpawner {
|
|
async fn run(&self, spec: SpawnSpec) -> Result<Output, ProcessError> {
|
|
let mut cmd = Command::new(&spec.command);
|
|
cmd.args(&spec.args);
|
|
// `cwd` is "/" for detection probes; only set a real working directory
|
|
// when the spec points at a concrete project path.
|
|
if spec.cwd.as_str() != "/" {
|
|
cmd.current_dir(spec.cwd.as_str());
|
|
}
|
|
for (key, value) in &spec.env {
|
|
cmd.env(key, value);
|
|
}
|
|
|
|
let output = cmd
|
|
.output()
|
|
.await
|
|
.map_err(|e| ProcessError::Spawn(format!("{}: {e}", spec.command)))?;
|
|
|
|
Ok(Output {
|
|
status: ExitStatus {
|
|
code: output.status.code(),
|
|
},
|
|
stdout: output.stdout,
|
|
stderr: output.stderr,
|
|
})
|
|
}
|
|
}
|