systemprompt_sync/export/
skills.rs1use super::escape_yaml;
2use anyhow::Result;
3use std::fs;
4use std::path::Path;
5use systemprompt_agent::models::Skill;
6
7const DEFAULT_SKILL_CATEGORY: &str = "skills";
8
9pub fn generate_skill_markdown(skill: &Skill) -> String {
10 let tags_str = skill.tags.join(", ");
11 let category = skill.category_id.as_ref().map_or(
12 DEFAULT_SKILL_CATEGORY,
13 systemprompt_identifiers::CategoryId::as_str,
14 );
15
16 format!(
17 r#"---
18title: "{}"
19slug: "{}"
20description: "{}"
21author: "systemprompt"
22published_at: "{}"
23type: "skill"
24category: "{}"
25keywords: "{}"
26---
27
28{}"#,
29 escape_yaml(&skill.name),
30 skill.skill_id.as_str().replace('_', "-"),
31 escape_yaml(&skill.description),
32 skill.created_at.format("%Y-%m-%d"),
33 category,
34 tags_str,
35 &skill.instructions
36 )
37}
38
39pub fn generate_skill_config(skill: &Skill) -> String {
40 let tags_yaml = if skill.tags.is_empty() {
41 "[]".to_string()
42 } else {
43 skill
44 .tags
45 .iter()
46 .map(|t| format!(" - {}", t))
47 .collect::<Vec<_>>()
48 .join("\n")
49 };
50
51 format!(
52 r#"id: {}
53name: "{}"
54description: "{}"
55enabled: {}
56version: "1.0.0"
57file: "index.md"
58assigned_agents:
59 - content
60tags:
61{}"#,
62 skill.skill_id.as_str(),
63 escape_yaml(&skill.name),
64 escape_yaml(&skill.description),
65 skill.enabled,
66 tags_yaml
67 )
68}
69
70pub fn export_skill_to_disk(skill: &Skill, base_path: &Path) -> Result<()> {
71 let skill_dir_name = skill.skill_id.as_str().replace('_', "-");
72 let skill_dir = base_path.join(&skill_dir_name);
73 fs::create_dir_all(&skill_dir)?;
74
75 let index_content = generate_skill_markdown(skill);
76 fs::write(skill_dir.join("index.md"), index_content)?;
77
78 let config_content = generate_skill_config(skill);
79 fs::write(skill_dir.join("config.yaml"), config_content)?;
80
81 Ok(())
82}