forge-orchestrator 1.8.0

Orchestration for Claude Code on shared repos, with Codex CLI and Antigravity CLI (agy) as task runners — single Rust binary, zero deps.
Documentation
use std::path::PathBuf;

/// Read and parse the master plan from .forge/plan.md
pub struct PlanManager {
    forge_dir: PathBuf,
}

impl PlanManager {
    /// A manager for the given `.forge/` directory.
    pub fn new(forge_dir: impl Into<PathBuf>) -> Self {
        Self {
            forge_dir: forge_dir.into(),
        }
    }

    fn plan_path(&self) -> PathBuf {
        self.forge_dir.join("plan.md")
    }

    /// Check if a plan exists
    pub fn has_plan(&self) -> bool {
        self.plan_path().exists()
    }

    /// Read the plan content
    pub fn read_plan(&self) -> anyhow::Result<String> {
        Ok(std::fs::read_to_string(self.plan_path())?)
    }

    /// Write a plan to .forge/plan.md
    pub fn write_plan(&self, content: &str) -> anyhow::Result<()> {
        std::fs::create_dir_all(&self.forge_dir)?;
        std::fs::write(self.plan_path(), content)?;
        Ok(())
    }

    /// Generate a default plan template
    pub fn generate_template(project_name: &str) -> String {
        format!(
            "# {project_name} — Master Plan\n\n\
             **Generated by:** Forge Orchestrator v0.1.0\n\
             **Date:** {date}\n\n\
             ---\n\n\
             ## Vision\n\n\
             _Describe the project vision here._\n\n\
             ## Tasks\n\n\
             No tasks yet. Run `forge plan --generate` to create tasks from your project context.\n\n\
             ## Notes\n\n\
             _Add any notes about the plan here._\n",
            date = chrono::Utc::now().format("%Y-%m-%d"),
        )
    }
}