use super::{Error, Fx, Outcome};
use crate::prompt::retarget::preflight;
use crate::template::RealGit;
use crate::workspace::{self, DEFAULT_CONFIG_NAME};
use std::path::PathBuf;
#[derive(clap::Args, Debug)]
pub struct Args {
pub workspace: PathBuf,
pub agent: String,
#[arg(long)]
pub config: Option<String>,
#[arg(long)]
pub role: Option<String>,
}
pub fn run(args: Args, _fx: &mut Fx) -> Result<Outcome, Error> {
let e = |source: &dyn std::fmt::Display| Error::new("retarget", source);
crate::name::require_agent_id(&args.agent).map_err(|s| e(&s))?;
let name = args.config.as_deref().unwrap_or(DEFAULT_CONFIG_NAME);
let git = RealGit::new();
let marks = preflight(
&args.workspace,
&args.agent,
name,
args.role.as_deref(),
&git,
)
.map_err(|s| e(&s))?;
if marks.is_noop() {
let as_role = args
.role
.as_deref()
.map_or_else(String::new, |r| format!(" as role {r:?}"));
eprintln!(
"litany: {} already governs [{}]{as_role} — nothing to retarget",
workspace::config_ref(name),
args.agent,
);
return Ok(Outcome::Quiet);
}
if let Some(commit) = &marks.commit {
workspace::retarget::write(&args.workspace, &args.agent, commit, &git)
.map_err(|s| e(&s))?;
eprintln!(
"litany: [{}] marked for retarget onto {} ({})",
args.agent,
&commit[..commit.len().min(12)],
workspace::config_ref(name),
);
}
if let Some(role) = &marks.role {
workspace::retarget::write_role(&args.workspace, &args.agent, role, &git)
.map_err(|s| e(&s))?;
eprintln!("litany: [{}] marked to settle as role {role:?}", args.agent);
}
eprintln!("litany: it lands at the agent's next step (ARCH §2.2)");
Ok(Outcome::Quiet)
}