lifeloop-cli 0.1.0

Provider-neutral lifecycle abstraction and normalizer for AI harnesses
Documentation
//! CLI integration tests for `lifeloop telemetry snapshot` (issue #9).
//!
//! The telemetry readers need real env vars / log files to surface a
//! `PressureObservation`. These tests exercise the CLI's argument
//! parsing, error classification, and unsupported-host path. The
//! happy-path observation flow is covered in `tests/telemetry.rs`
//! (in-process) — this file proves the CLI plumbing.

use std::process::{Command, Stdio};

fn lifeloop_bin() -> std::path::PathBuf {
    std::path::PathBuf::from(env!("CARGO_BIN_EXE_lifeloop"))
}

fn run(args: &[&str]) -> (i32, String, String) {
    let out = Command::new(lifeloop_bin())
        .args(args)
        .stdin(Stdio::null())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .env_remove("LIFELOOP_CODEX_THREAD_ID")
        .env_remove("CODEX_THREAD_ID")
        .output()
        .expect("spawn lifeloop");
    (
        out.status.code().unwrap_or(-1),
        String::from_utf8_lossy(&out.stdout).into_owned(),
        String::from_utf8_lossy(&out.stderr).into_owned(),
    )
}

#[test]
fn telemetry_snapshot_unknown_host_is_validation_error() {
    let (code, _stdout, stderr) = run(&["telemetry", "snapshot", "--host", "wat"]);
    assert_eq!(code, 1, "expected validation exit (1), got {code}");
    assert!(stderr.contains("no telemetry reader"));
}

#[test]
fn telemetry_snapshot_missing_host_flag_is_usage_error() {
    let (code, _stdout, stderr) = run(&["telemetry", "snapshot"]);
    assert_eq!(code, 2, "expected usage exit (2), got {code}");
    assert!(stderr.contains("--host"));
}

#[test]
fn telemetry_snapshot_codex_with_no_thread_id_is_validation_error() {
    // No CODEX_THREAD_ID set -> reader returns Ok(None) -> CLI surfaces
    // a validation error rather than producing empty output.
    let (code, _stdout, stderr) = run(&["telemetry", "snapshot", "--host", "codex"]);
    assert_eq!(code, 1, "expected validation exit (1), got {code}");
    assert!(stderr.contains("no observation available"));
}

#[test]
fn telemetry_snapshot_unknown_subcommand_is_usage_error() {
    let (code, _stdout, stderr) = run(&["telemetry", "weird"]);
    assert_eq!(code, 2);
    assert!(stderr.contains("unknown subcommand"));
}