use std::fs;
use roboticus_agent::skills::{LoadedSkill, SkillLoader};
use roboticus_agent::tools::{ScriptRunnerTool, ToolContext, ToolRegistry};
use roboticus_core::InputAuthority;
use roboticus_core::config::{FilesystemSecurityConfig, SkillsConfig};
#[tokio::test]
async fn hello_world_skill_loads_and_executes_via_run_script_tool() {
let dir = tempfile::tempdir().expect("tempdir");
let skills_dir = dir.path().join("skills");
fs::create_dir_all(&skills_dir).expect("create skills dir");
fs::write(
skills_dir.join("hello_world.md"),
r#"---
name: hello-world-skill
description: Says hello for integration test
triggers:
keywords: ["hello world skill"]
tool_names: []
regex_patterns: []
priority: 5
---
Use run_script with hello_world.sh for greeting tasks.
"#,
)
.expect("write instruction skill");
fs::write(
skills_dir.join("hello_world.sh"),
r#"#!/usr/bin/env bash
name="${1:-world}"
echo "hello skill ${name}"
"#,
)
.expect("write skill script");
let loaded = SkillLoader::load_from_dir(&skills_dir).expect("load skills");
assert!(
loaded
.iter()
.any(|s| matches!(s, LoadedSkill::Instruction(skill, _, _) if skill.name == "hello-world-skill")),
"expected hello-world instruction skill to load"
);
let skills_cfg = SkillsConfig {
skills_dir: skills_dir.clone(),
workspace_dir: Some(dir.path().to_path_buf()),
sandbox_env: false,
..SkillsConfig::default()
};
let fs_cfg = FilesystemSecurityConfig::for_tests();
let mut registry = ToolRegistry::new();
registry.register(Box::new(ScriptRunnerTool::new(skills_cfg, fs_cfg)));
let tool = registry
.get("run_script")
.expect("run_script tool should be registered");
let ctx = ToolContext {
session_id: "skill-int-test-session".to_string(),
agent_id: "skill-int-test-agent".to_string(),
agent_name: "Skill Integration Tester".to_string(),
authority: InputAuthority::Creator,
workspace_root: dir.path().to_path_buf(),
tool_allowed_paths: vec![],
channel: None,
db: None,
sandbox: roboticus_agent::tools::ToolSandboxSnapshot::default(),
};
let result = tool
.execute(
serde_json::json!({
"path": "hello_world.sh",
"args": ["roboticus"]
}),
&ctx,
)
.await
.expect("run_script should execute hello_world.sh");
assert!(
result.output.contains("hello skill roboticus"),
"unexpected run_script output: {}",
result.output
);
}