Files
darman 9929941748 Add project documentation and reference materials
Include Luna AI Assistant design docs covering channels, configuration,
core architecture, memory, scheduler, and skills. Add reference docs
from OpenClaw and ZeroClaw projects, plus Mistral and OpenAI API specs.
2026-04-04 04:14:06 +02:00

5.3 KiB

Skills

The ZeroClaw skills system enables the extension of agent capabilities through modular, audited packages. Each skill can define custom prompts, tools (shell, HTTP, or scripts), and metadata. This system serves as the reference architecture for Skills in Luna.


Skill Struct

ZeroClaw defines skills and their associated tools using robust Rust structures. A Skill is the top-level container, while SkillTool defines specific executable capabilities.

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Skill {
    pub name: String,
    pub description: String,
    pub version: String,
    #[serde(default)]
    pub author: Option<String>,
    #[serde(default)]
    pub tags: Vec<String>,
    #[serde(default)]
    pub tools: Vec<SkillTool>,
    #[serde(default)]
    pub prompts: Vec<String>,
    #[serde(skip)]
    pub location: Option<PathBuf>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SkillTool {
    pub name: String,
    pub description: String,
    /// "shell", "http", "script"
    pub kind: String,
    /// The command/URL/script to execute
    pub command: String,
    #[serde(default)]
    pub args: HashMap<String, String>,
}

SKILL.toml Manifest

The preferred way to define a skill is via a SKILL.toml manifest. ZeroClaw also supports a legacy SKILL.md fallback for prompt-only skills.

#[derive(Debug, Clone, Serialize, Deserialize)]
struct SkillManifest {
    skill: SkillMeta,
    #[serde(default)]
    tools: Vec<SkillTool>,
    #[serde(default)]
    prompts: Vec<String>,
}

Example SKILL.toml

[skill]
name = "weather"
description = "Fetch weather forecasts"
version = "0.1.0"
author = "Luna-Team"
tags = ["utility", "api"]

[[tools]]
name = "get_weather"
description = "Fetch forecast from wttr.in"
kind = "shell"
command = "curl -s wttr.in/$CITY"

Security Audit on Install

Security is a first-class citizen in ZeroClaw. The load_skills() function enforces a security gate via audit::audit_skill_directory().

What gets blocked:

  • Symlinks (both for the directory itself and files within)
  • Unsafe path patterns (traversal attempts)
  • Insecure script patterns

The copy_dir_recursive_secure function ensures that no symlinks are introduced during the installation process:

fn copy_dir_recursive_secure(src: &Path, dest: &Path) -> Result<()> {
    let src_meta = std::fs::symlink_metadata(src)?;
    if src_meta.file_type().is_symlink() {
        anyhow::bail!("Refusing to copy symlinked skill source path: {}", src.display());
    }
    // ... recursive copy logic ...
    if metadata.file_type().is_symlink() {
        anyhow::bail!("Refusing to copy symlink within skill source: {}", src_path.display());
    }
}

Open-Skills Repository Sync

ZeroClaw supports a community-driven repository of skills. The system performs a weekly shallow clone to discover and update these capabilities.

  • URL: https://github.com/besoeasy/open-skills
  • Sync Interval: 7 days (60 * 60 * 24 * 7 seconds)
  • Mechanism: git clone --depth 1 for initialization, followed by periodic git pull --ff-only.

The ensure_open_skills_repo function manages this lifecycle, checking a .zeroclaw-open-skills-sync marker file to determine if a sync is required.


Skill Prompt Injection

Skills are surfaced to the LLM through XML-structured injection in the system prompt. This is handled by skills_to_prompt_with_mode().

Full vs Compact Mode

  • Full: Injects name, description, location, all instructions, and tool metadata.
  • Compact: Injects only name, description, and location. Instructions and tools are loaded on demand by the LLM reading the file.
pub fn skills_to_prompt_with_mode(
    skills: &[Skill],
    workspace_dir: &Path,
    mode: crate::config::SkillsPromptInjectionMode,
) -> String {
    // ...
    for skill in skills {
        let _ = writeln!(prompt, "  <skill>");
        write_xml_text_element(&mut prompt, 4, "name", &skill.name);
        write_xml_text_element(&mut prompt, 4, "description", &skill.description);
        // ...
        if matches!(mode, crate::config::SkillsPromptInjectionMode::Full) {
            // Injects <instructions> and <tools> tags
        }
    }
}

CLI Management

The handle_command() function provides a CLI interface for managing the skills lifecycle:

  • list: Displays installed skills, versions, tools, and tags.
  • audit: Manually runs the security audit on a local or installed skill.
  • install: Clones from git or copies from a local path, followed by a mandatory audit.
  • remove: Securely deletes a skill directory, preventing path traversal.

Secure Install

When installing a skill, ZeroClaw uses install_git_skill_source or install_local_skill_source. Both paths terminate in a mandatory enforce_skill_security_audit() call. If the audit fails, the installed files are immediately rolled back (deleted).


Relevance to Luna

Luna's skills system is a planned feature that will adopt the ZeroClaw architecture:

  • Manifest: Adopt the SKILL.toml format for interoperability.
  • Security: Implement the same mandatory audit gate and symlink rejection policy.
  • Injection: Use the XML-structured prompt injection pattern to give the LLM clear boundaries for skill usage.

Cross-links: Skills, Core, Configuration.