netsky 0.1.4

netsky CLI: the viable system launcher and subcommand dispatcher
Documentation
//! `netsky morning` — overnight briefing: doctor verdict + git log +
//! brief iteration tail + loop-resume + watchdog log tail.

use std::fs;
use std::path::Path;
use std::process::Command;

use netsky_core::consts::{NETSKY_BIN, TICKER_LOG_PATH};
use netsky_core::paths::{agent0_hang_marker, agentinit_escalation_marker, loop_resume_file};

const LEGACY_LOOP_RESUME: &str = "/tmp/netsky-loop-resume.txt";
const BRIEF_PATH: &str = "briefs/overnight-resilience-adversarial-review.md";

pub fn run(send: bool) -> netsky_core::Result<()> {
    section("health");
    let out = Command::new(NETSKY_BIN)
        .args(["doctor", "--brief"])
        .output()?;
    print!("{}", String::from_utf8_lossy(&out.stdout));
    if !out.status.success() {
        println!();
        println!(
            "doctor exited {} — full output:",
            out.status.code().unwrap_or(-1)
        );
        let full = Command::new(NETSKY_BIN).arg("doctor").output()?;
        let text = String::from_utf8_lossy(&full.stdout);
        for l in text
            .lines()
            .rev()
            .take(30)
            .collect::<Vec<_>>()
            .into_iter()
            .rev()
        {
            println!("{l}");
        }
    }

    let hang = agent0_hang_marker();
    let esc = agentinit_escalation_marker();
    let markers: Vec<_> = [&hang, &esc].into_iter().filter(|p| p.exists()).collect();
    if !markers.is_empty() {
        section("ACTIVE MARKERS (owner action needed)");
        for m in markers {
            println!("{}", m.display());
            if let Ok(body) = fs::read_to_string(m) {
                for l in body.lines() {
                    println!("  {l}");
                }
            }
        }
    }

    section("overnight commits (last 12h)");
    let log = Command::new("git")
        .args(["log", "--since=12 hours ago", "--pretty=format:%h %s"])
        .output()?;
    for l in String::from_utf8_lossy(&log.stdout).lines().take(30) {
        println!("{l}");
    }
    println!();

    if Path::new(BRIEF_PATH).exists() {
        section("brief: latest iterations");
        if let Ok(content) = fs::read_to_string(BRIEF_PATH) {
            let it_lines: Vec<_> = content
                .lines()
                .filter(|l| l.starts_with("### iteration"))
                .collect();
            for l in it_lines
                .iter()
                .rev()
                .take(8)
                .collect::<Vec<_>>()
                .into_iter()
                .rev()
            {
                println!("{l}");
            }
        }
    }

    for resume in [
        loop_resume_file(),
        Path::new(LEGACY_LOOP_RESUME).to_path_buf(),
    ] {
        if resume.exists() {
            let name = resume
                .file_name()
                .and_then(|s| s.to_str())
                .unwrap_or("loop-resume");
            section(&format!("loop-resume PENDING ({name})"));
            if let Ok(body) = fs::read_to_string(&resume) {
                let mut flag = false;
                let mut printed = 0;
                for l in body.lines() {
                    if l.starts_with("PENDING") {
                        flag = true;
                        continue;
                    }
                    if l.starts_with("Stop conditions:") {
                        flag = false;
                    }
                    if flag && printed < 20 {
                        println!("{l}");
                        printed += 1;
                    }
                }
            }
            break;
        }
    }

    section("watchdog (last 5 lines)");
    match fs::read_to_string(TICKER_LOG_PATH) {
        Ok(body) => {
            let lines: Vec<_> = body.lines().collect();
            let start = lines.len().saturating_sub(5);
            for l in &lines[start..] {
                println!("{l}");
            }
        }
        Err(_) => println!("(log not present)"),
    }

    if send {
        println!();
        println!("--send requested; agent0 should pipe this into a reply tool call.");
    }

    Ok(())
}

fn section(label: &str) {
    println!();
    println!("── {label} ──");
}