use crate::model::{Agent, Rule, Skill, ToolCap};
use anyhow::{Context, Result};
use serde_yaml_ng::{Mapping, Value};
pub fn skill_frontmatter(skill: &Skill) -> Result<String> {
super::build_skill_frontmatter(skill, skill.copilot.as_ref())
}
pub fn rule_frontmatter(rule: &Rule) -> Result<String> {
let mut map = Mapping::new();
map.insert(Value::from("name"), Value::from(rule.name.clone()));
map.insert(
Value::from("description"),
Value::from(rule.description.clone()),
);
let apply_to = match &rule.scope {
Some(scope) if !scope.paths.is_empty() => scope.paths.join(", "),
_ => "**".to_string(),
};
map.insert(Value::from("applyTo"), Value::from(apply_to));
if let Some(Value::Mapping(pt)) = rule.copilot.as_ref() {
for (k, v) in pt {
map.insert(k.clone(), v.clone());
}
}
serde_yaml_ng::to_string(&map).context("serializing copilot rule frontmatter")
}
pub fn agent_frontmatter(agent: &Agent) -> Result<String> {
let mut map = Mapping::new();
map.insert(Value::from("name"), Value::from(agent.name.clone()));
map.insert(
Value::from("description"),
Value::from(agent.description.clone()),
);
if let Some(model) = &agent.model {
map.insert(Value::from("model"), Value::from(model.clone()));
}
let tools: Vec<Value> = agent
.tools
.iter()
.filter_map(|t| map_tool(*t))
.map(Value::from)
.collect();
if !tools.is_empty() {
map.insert(Value::from("tools"), Value::Sequence(tools));
}
if let Some(Value::Mapping(pt)) = agent.copilot.as_ref() {
for (k, v) in pt {
map.insert(k.clone(), v.clone());
}
}
serde_yaml_ng::to_string(&map).context("serializing copilot agent frontmatter")
}
fn map_tool(t: ToolCap) -> Option<&'static str> {
match t {
ToolCap::Bash => Some("shell"),
ToolCap::WebFetch => Some("fetch"),
ToolCap::WebSearch => Some("web_search"),
ToolCap::Read | ToolCap::Write | ToolCap::Edit | ToolCap::Grep | ToolCap::Glob => None,
}
}