openlatch-client 0.6.3

OpenLatch runtime enforcement node — the capture-and-enforce adapter that evaluates every covered action against a coding agent's Autonomy Zone before it runs
//! macOS: the per-user launchd environment (`launchctl setenv`), which every app launchd starts afterwards inherits.
//! It does not survive a logout or reboot on its own: the daemon re-applies it on every start and tick (INDEX D-09,
//! no second LaunchAgent).

use super::run_checked;

pub(super) const MANUAL_CLEAR: &str =
    "`launchctl unsetenv CLINE_WRAPPER_PATH` and `launchctl unsetenv CLINE_JS_RUNTIME_PATH`";

/// `launchctl getenv K` prints the value and a newline, or nothing when unset.
pub(super) fn read(name: &str) -> Result<Option<String>, String> {
    let out = run_checked("launchctl", &["getenv", name])?;
    let value = out.strip_suffix('\n').unwrap_or(&out);
    Ok((!value.is_empty()).then(|| value.to_string()))
}

pub(super) fn apply(name: &str, value: &str) -> Result<(), String> {
    run_checked("launchctl", &["setenv", name, value]).map(|_| ())
}

pub(super) fn clear(name: &str) -> Result<(), String> {
    run_checked("launchctl", &["unsetenv", name]).map(|_| ())
}