use anyhow::{Context, Result};
use colored::Colorize;
use crate::keys;
use crate::store;
use crate::util::ok;
pub fn run_init() -> Result<()> {
let (priv_path, pub_path, kid) = keys::generate_keypair()?;
println!(" {} signing keypair initialized", ok());
println!(" Private key: {} (chmod 600)", priv_path.display());
println!(" Public key: {}", pub_path.display());
println!(" Key ID: {}", kid);
println!();
println!(" Future trace entries will be signed automatically after each commit.");
println!(" Run {} to verify the audit trail.", "agentdiff verify".cyan());
Ok(())
}
pub fn run_register(store: &crate::store::Store) -> Result<()> {
let vk = keys::load_verifying_key()
.context("no public key found — run 'agentdiff keys init' first")?;
let kid = keys::compute_key_id(&vk);
let pub_path = keys::public_key_path()?;
let pub_b64 = std::fs::read_to_string(&pub_path)
.with_context(|| format!("reading public key from {}", pub_path.display()))?;
let ref_name = format!("refs/agentdiff/keys/{kid}");
store::write_to_ref(
&store.repo_root,
&ref_name,
"pub.key",
pub_b64.trim(),
&format!("agentdiff: register key {kid}"),
)?;
println!(" {} key {} registered in local registry ({})", ok(), kid, ref_name);
println!(
" Run {} to push the key registry to GitHub so teammates can verify your signatures.",
"agentdiff push".cyan()
);
Ok(())
}
pub fn run_rotate(store: &crate::store::Store) -> Result<()> {
let priv_path = keys::private_key_path()?;
let pub_path = keys::public_key_path()?;
if priv_path.exists() {
let bak_priv = priv_path.with_extension("key.bak");
let bak_pub = pub_path.with_extension("key.bak");
std::fs::rename(&priv_path, &bak_priv)
.with_context(|| format!("backing up private key to {}", bak_priv.display()))?;
std::fs::rename(&pub_path, &bak_pub)
.with_context(|| format!("backing up public key to {}", bak_pub.display()))?;
println!(
" Old keys backed up to {} and {}",
bak_priv.display(),
bak_pub.display()
);
}
let (kid, _vk) = keys::generate_keypair_at(&priv_path, &pub_path)?;
println!(" {} new keypair generated", ok());
println!(" Private key: {} (chmod 600)", priv_path.display());
println!(" Public key: {}", pub_path.display());
println!(" Key ID: {}", kid);
let pub_b64 = std::fs::read_to_string(&pub_path)
.with_context(|| format!("reading new public key from {}", pub_path.display()))?;
let ref_name = format!("refs/agentdiff/keys/{kid}");
store::write_to_ref(
&store.repo_root,
&ref_name,
"pub.key",
pub_b64.trim(),
&format!("agentdiff: register rotated key {kid}"),
)?;
println!(" {} new key {} registered in local registry", ok(), kid);
println!(
" Run {} to push the updated key registry to GitHub.",
"agentdiff push".cyan()
);
Ok(())
}