Skip to main content

agent_profile/launch/
mod.rs

1// Copyright (c) 2026 Costas Kirgoussios
2//
3// This software is licensed under the PolyForm Noncommercial License 1.0.0.
4// You may obtain a copy of the License at:
5// https://polyformproject.org/licenses/noncommercial/1.0.0/
6
7//! `LaunchPlan` (spec §4), environment overrides (spec §22), launch semantics (spec §23, §24)
8//! and the launcher API (spec §25).
9
10use std::ffi::OsString;
11use std::path::PathBuf;
12use std::process::Command;
13
14use crate::error::Result;
15
16#[cfg(unix)]
17mod unix;
18#[cfg(windows)]
19mod windows;
20
21/// What an adapter asks the launcher to run (spec §4). `env` is an override set, not a full environment.
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct LaunchPlan {
24    pub executable: PathBuf,
25    pub args: Vec<OsString>,
26    pub env: Vec<(OsString, OsString)>,
27    pub cwd: Option<PathBuf>,
28}
29
30impl LaunchPlan {
31    /// The single conversion both launchers use: the inherited environment plus the overrides, the
32    /// arguments verbatim, the working directory only when set, and inherited stdio.
33    pub fn command(&self) -> Command {
34        let mut command = Command::new(&self.executable);
35        command.args(&self.args);
36        for (key, value) in &self.env {
37            command.env(key, value);
38        }
39        if let Some(cwd) = &self.cwd {
40            command.current_dir(cwd);
41        }
42        command
43    }
44}
45
46/// How a launch ended (spec §25).
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum LaunchOutcome {
49    /// Unix: `exec` never returns on success, so this is never constructed there. Kept for spec §25.
50    ReplacedProcess,
51    /// Windows: the child's full 32-bit exit code.
52    Exited(i32),
53}
54
55/// Launches the plan: `exec` on Unix, a waited child on Windows. `verbose` enables diagnostics on stderr.
56pub fn launch(plan: &LaunchPlan, verbose: bool) -> Result<LaunchOutcome> {
57    #[cfg(unix)]
58    {
59        let _ = verbose;
60        unix::launch(plan)
61    }
62    #[cfg(windows)]
63    {
64        windows::launch(plan, verbose)
65    }
66}