bake_agent_context/agent/context/
mod.rs1mod index;
5mod installer;
6mod skill;
7
8pub use index::AgentIndex;
9pub use installer::{ContextFile, ContextPackage, Installer};
10pub use skill::{Skill, install_skills, list_skills};
11
12use bake::{Context, Error, Result};
13
14fn installer(context: &mut Context) -> Result<Installer> {
15 if let Some(installer) = context.get::<Installer>() {
16 return Ok(installer.clone());
17 }
18
19 let installer = Installer::new(context.root())?;
20 context.insert(installer.clone());
21 Ok(installer)
22}
23
24#[bake::task]
26pub fn list(context: &mut Context, package: Option<String>) -> Result<String> {
27 let installer = installer(context)?;
28
29 if let Some(package) = package {
30 let Some(package) = installer.find_package(&package)? else {
31 return Ok(format!("No context found for crate '{package}'"));
32 };
33
34 let files = installer.list_context_files(&package)?;
35 if files.is_empty() {
36 return Ok(format!(
37 "No context files found for crate '{}'.",
38 package.selector()
39 ));
40 }
41 let mut output = format!("Context files for crate '{}':", package.selector());
42 for file in files {
43 output.push_str(&format!("\n {}", file.path.display()));
44 }
45 return Ok(output);
46 }
47
48 let mut packages = Vec::new();
49 for package in installer.packages() {
50 if !installer.list_context_files(package)?.is_empty() {
51 packages.push(package);
52 }
53 }
54 if packages.is_empty() {
55 return Ok("No dependency context files found".to_owned());
56 }
57
58 let mut output = String::from("Crates with context available:");
59 for package in packages {
60 output.push_str(&format!("\n {} ({})", package.selector(), package.version));
61 }
62 Ok(output)
63}
64
65#[bake::task]
67pub fn show(
68 context: &mut Context,
69 #[bake(named)] package: String,
70 #[bake(named)] file: String,
71) -> Result<String> {
72 let installer = installer(context)?;
73 let Some(content) = installer.show_context_file(&package, &file)? else {
74 return Err(Error::new(format!(
75 "context file {file:?} was not found in crate {package:?}"
76 )));
77 };
78 Ok(content)
79}
80
81#[bake::task]
83pub fn install(context: &mut Context, package: Option<String>) -> Result<String> {
84 let installer = installer(context)?;
85 let installed_context = if let Some(package) = package.as_deref() {
86 if installer.install_package(package)? {
87 vec![package.to_owned()]
88 } else {
89 Vec::new()
90 }
91 } else {
92 installer.install_all()?
93 };
94 let installed_skills = install_skills(&installer, package.as_deref(), None)?;
95
96 AgentIndex::new(context.root())
97 .with_packages(installer.packages())
98 .update_agents_md("agents.md")?;
99
100 let mut output = Vec::new();
101 if !installed_context.is_empty() {
102 output.push(format!(
103 "Installed context from: {}",
104 installed_context.join(", ")
105 ));
106 }
107 if !installed_skills.is_empty() {
108 output.push(format!("Installed skills: {}", installed_skills.join(", ")));
109 }
110
111 if output.is_empty() {
112 Ok("No dependency context or skills were installed".to_owned())
113 } else {
114 Ok(output.join("\n"))
115 }
116}
117
118#[bake::task(name = "agent:context:skill:list")]
120pub fn skill_list(context: &mut Context, package: Option<String>) -> Result<String> {
121 let installer = installer(context)?;
122 let skills = list_skills(&installer, package.as_deref())?;
123 if skills.is_empty() {
124 return Ok("No dependency skills found".to_owned());
125 }
126
127 let mut output = String::from("Available dependency skills:");
128 for skill in skills {
129 output.push_str(&format!(
130 "\n {} ({}) — {}",
131 skill.name,
132 skill.package_selector(),
133 skill.description
134 ));
135 }
136 Ok(output)
137}
138
139#[bake::task(name = "agent:context:skill:install")]
141pub fn skill_install(
142 context: &mut Context,
143 package: Option<String>,
144 skill: Option<String>,
145) -> Result<String> {
146 let installer = installer(context)?;
147 let installed = install_skills(&installer, package.as_deref(), skill.as_deref())?;
148 if installed.is_empty() {
149 Ok("No dependency skills were installed".to_owned())
150 } else {
151 Ok(format!("Installed skills: {}", installed.join(", ")))
152 }
153}
154
155#[bake::task(name = "agents-md")]
157pub fn agents_md(
158 context: &mut Context,
159 #[bake(default = "agents.md")] path: String,
160) -> Result<String> {
161 let installer = installer(context)?;
162 AgentIndex::new(context.root())
163 .with_packages(installer.packages())
164 .update_agents_md(&path)?;
165 Ok(format!("Updated {path}"))
166}