use anyhow::{Context, Result};
use crate::schema::{Response, SchemaData};
pub struct SchemaOpts;
pub fn execute(_opts: SchemaOpts) -> Result<()> {
let schema_path = schema_file_path()?;
let raw = std::fs::read_to_string(&schema_path)
.with_context(|| format!("failed to read schema file: {}", schema_path.display()))?;
let schema: serde_json::Value =
serde_json::from_str(&raw).with_context(|| "schema file is not valid JSON")?;
let generated_at = schema
.get("$comment")
.and_then(|v| v.as_str())
.unwrap_or("unknown")
.to_string();
let data = SchemaData {
schema_format: "json-schema-draft-07".to_string(),
schema,
generated_at,
};
Response::new("schema", data).print();
Ok(())
}
fn schema_file_path() -> Result<std::path::PathBuf> {
let exe = std::env::current_exe().context("cannot determine binary path")?;
let bin_dir = exe.parent().context("binary has no parent directory")?;
for candidate in &[
bin_dir.to_path_buf(),
bin_dir.join(".."),
bin_dir.join("../.."),
bin_dir.join("../../.."),
] {
let p = candidate.join("schema").join("agent-exec.schema.json");
if p.exists() {
return Ok(p.canonicalize().unwrap_or(p));
}
}
let cwd_path = std::path::Path::new("schema").join("agent-exec.schema.json");
if cwd_path.exists() {
return Ok(cwd_path);
}
anyhow::bail!(
"schema file not found; expected schema/agent-exec.schema.json relative to the binary or current directory"
)
}