bot-forge 1.0.2

Rust CLI for installing agent skills and developer tools from configurable forms.
Documentation
use crate::model::{EnvironmentDef, InstallConfig, InstallKind, SkillDef, ToolDef};
use crate::planning::ExecutionPlan;

pub(crate) fn from_plan(plan: &ExecutionPlan) -> InstallConfig {
    let mut tools = Vec::new();
    let mut skills = Vec::new();
    for component in &plan.components {
        match component.kind {
            InstallKind::Skill => {
                skills.push(SkillDef {
                    name: component.id.clone(),
                    display_name: component.display_name.clone(),
                    optional: component.optional,
                    source: component.source.clone().unwrap_or_default(),
                    agents: component.agents.clone(),
                    revision: component.revision.clone(),
                });
            }
            _ => {
                tools.push(ToolDef {
                    name: component.id.clone(),
                    display_name: component.display_name.clone(),
                    version: component.version.clone(),
                    optional: component.optional,
                    allow_insecure_hosts: component.allow_insecure_hosts.clone(),
                    detect: component.detect.clone(),
                    install: component.install.clone(),
                    verify: component.verify.clone(),
                });
            }
        }
    }
    let environment = EnvironmentDef {
        mutations: plan.environment.clone(),
    };
    InstallConfig {
        environment,
        apt_mirror: plan.apt_mirror.clone(),
        tools,
        skills,
    }
}

#[cfg(test)]
mod tests {
    use crate::config::schema::{ConfigDocument, OriginMap};
    use crate::execution::runtime::from_plan;
    use crate::planning::{PlanRequest, TargetPlatform, build_plan};

    #[test]
    fn runtime_component_set_is_frozen_by_plan() {
        let source = r#"
catalog = "rust-dev"
[profiles.selected]
components = ["first"]
[[components]]
id = "first"
allow_insecure_hosts = ["mirror.example.test", "redirect.example.test:8080"]
[components.detect]
kind = "command"
program = "true"
[components.install]
backend = "pip"
package = "first"
version = "1.0.0"
python = "python3"
environment = "$BOT_FORGE_HOME/python-tools/first"
"#;
        let mut document = ConfigDocument::parse(source).unwrap();
        let origins = OriginMap::default();
        let plan = build_plan(PlanRequest {
            document: &document,
            origins: &origins,
            profile: "selected",
            target: TargetPlatform::host(),
            only: &[],
            exclude: &[],
            source_root: None,
        })
        .unwrap();
        document
            .profiles
            .get_mut("selected")
            .unwrap()
            .components
            .clear();

        let runtime = from_plan(&plan);
        assert_eq!(runtime.tools.len(), 1);
        assert_eq!(
            runtime.tools[0].allow_insecure_hosts,
            ["mirror.example.test", "redirect.example.test:8080"]
        );
    }
}