use clap_noun_verb::{NounVerbError, Result};
use clap_noun_verb_macros::verb;
use ggen_core::agent::{InstallRequest, PackAgent};
fn agent() -> Result<PackAgent> {
PackAgent::new()
.map_err(|e| NounVerbError::execution_error(format!("agent init failed: {}", e)))
}
fn agent_at(root: Option<String>) -> Result<PackAgent> {
match root {
Some(r) => Ok(PackAgent::at_root(r)),
None => agent(),
}
}
fn lift<T>(r: ggen_core::agent::AgentResult<T>) -> Result<T> {
r.map_err(|e| NounVerbError::execution_error(e.to_string()))
}
fn json<T: serde::Serialize>(value: T) -> Result<serde_json::Value> {
serde_json::to_value(value)
.map_err(|e| NounVerbError::execution_error(format!("serialization failed: {}", e)))
}
#[verb]
pub fn capabilities() -> Result<serde_json::Value> {
json(agent()?.capabilities())
}
#[verb]
pub fn search(#[arg(index = 1)] query: String, limit: Option<usize>) -> Result<serde_json::Value> {
json(lift(agent()?.search(&query, limit))?)
}
#[verb]
pub fn list(category: Option<String>) -> Result<serde_json::Value> {
json(lift(agent()?.list(category.as_deref()))?)
}
#[verb]
pub fn show(#[arg(index = 1)] pack_id: String) -> Result<serde_json::Value> {
json(lift(agent()?.show(&pack_id))?)
}
#[verb]
pub fn resolve(
#[arg(index = 1)] surface: String, projection: Option<String>, runtime: Option<String>,
) -> Result<serde_json::Value> {
json(lift(agent()?.resolve_capability(
&surface,
projection.as_deref(),
runtime.as_deref(),
))?)
}
#[verb]
pub fn compatibility(#[arg(index = 1)] packs: String) -> Result<serde_json::Value> {
let a = agent()?;
let ids: Vec<String> = packs
.split(',')
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.collect();
let res = crate::runtime::block_on(a.check_compatibility(&ids))
.map_err(|e| NounVerbError::execution_error(e.to_string()))?;
json(lift(res)?)
}
#[verb]
pub fn status(root: Option<String>) -> Result<serde_json::Value> {
json(lift(agent_at(root)?.status())?)
}
#[verb]
pub fn verify(
#[arg(index = 1)] receipt_path: String, root: Option<String>,
) -> Result<serde_json::Value> {
json(agent_at(root)?.verify(&receipt_path))
}
#[verb]
pub fn install(
#[arg(index = 1)] pack_id: String, force: Option<bool>, dry_run: Option<bool>,
) -> Result<serde_json::Value> {
let a = agent()?;
let req = InstallRequest {
pack_id,
force: force.unwrap_or(false),
dry_run: dry_run.unwrap_or(false),
emit_receipt: true,
};
let res = crate::runtime::block_on(a.install(req))
.map_err(|e| NounVerbError::execution_error(e.to_string()))?;
json(lift(res)?)
}
#[verb]
pub fn remove(#[arg(index = 1)] pack_id: String) -> Result<serde_json::Value> {
json(lift(agent()?.remove(&pack_id))?)
}