seher-cli 0.0.45

Seher CLI: pick the highest-priority coding agent and run a plan/build prompt
use crate::args::Args;
use crate::logger::Logger;
use crate::prompt;
use crate::run_mode::resolve_and_stream;

const PLAN_SYSTEM_PROMPT: &str = "You are an implementation planner. The user will give you a task. Your job is to produce a clear, step-by-step implementation plan in Markdown.\n\nStrict rules:\n- Output ONLY the plan in Markdown. No greetings, no questions, no commentary.\n- Do not write or modify any files. Do not call any tools.\n- Use sections like \"## Goal\", \"## Approach\", \"## Steps\", \"## Risks\" as appropriate.\n- The plan will be reviewed by the user in an editor and then executed by another agent.";

/// Plan mode: 1) generate a plan with the plan-mode provider, 2) edit it in
/// `$EDITOR`, 3) re-resolve under build mode and execute.
///
/// `-m/--model <key>` overrides both the plan-mode key (default `"plan"`) and
/// the subsequent build-mode key (default `"build"`).
///
/// # Errors
///
/// Stringified errors from any stage (resolve/timeout/editor/build run).
pub fn run(
    rt: &tokio::runtime::Runtime,
    prompt: &str,
    args: &Args,
    logger: &Logger,
) -> Result<(), String> {
    let plan_key = args.model.as_deref().unwrap_or("plan");
    let build_key = args.model.as_deref().unwrap_or("build");

    // 1) stream the plan
    let plan_text =
        resolve_and_stream(rt, prompt, args, plan_key, Some(PLAN_SYSTEM_PROMPT), logger)?;

    // 2) edit in $EDITOR seeded with the streamed plan
    let edited = prompt::edit_with_seed(&plan_text).map_err(|e| e.to_string())?;
    let trimmed = edited.trim();
    if trimmed.is_empty() {
        logger.info("Plan canceled");
        return Ok(());
    }

    // 3) re-resolve under build mode and run the approved plan
    let build_prompt = format!("<plan>\n{trimmed}\n</plan>\n\nExecute the plan above.");
    resolve_and_stream(rt, &build_prompt, args, build_key, None, logger)?;
    Ok(())
}