Planck.Agent.Skill (Planck.Agent v0.1.0)

Copy Markdown View Source

Filesystem-based agent skills.

A skill is a subdirectory under a skills directory (e.g. .planck/skills/) containing a SKILL.md file. The file has YAML frontmatter with name and description, followed by usage instructions, resource references, and any other context the agent needs.

Directory layout

.planck/skills/
 n8n-expert/
     SKILL.md             required
     docs/
        node-types.md    lazily loaded by the agent via `read`
     scripts/
         validate.sh      runnable via `bash`

SKILL.md format

---
name: n8n-expert
description: Expert at building n8n workflows and automation.
---

# N8N Expert

You are an expert at n8n...

## Resources

- `docs/node-types.md`  reference for all n8n node types
- `scripts/validate.sh`  validates a workflow JSON file

Only name and description are parsed from the frontmatter. The rest of the file is plain Markdown consumed by the agent when it loads the skill.

Usage

skills = Planck.Agent.Skill.load_all(["~/.planck/skills"])

# Skills are typically threaded through AgentSpec.to_start_opts/2 via
# skill_pool:, which resolves spec.skills names and appends the skill
# section to system_prompt for the relevant agent.
start_opts = Planck.Agent.AgentSpec.to_start_opts(spec, skill_pool: skills)

The agent discovers skills from the system prompt index and loads SKILL.md via the read tool when a skill is relevant. Scripts are run via bash. No special runtime support is required — skills are just files.

Summary

Types

t()

A loaded skill.

Functions

Load a single skill from a SKILL.md file path.

Build a list_skills tool that returns all available skill names and descriptions.

Load all skills from a list of directories.

Build a load_skill tool that loads a skill's SKILL.md by name.

Generate a skills section for injection into an agent's system prompt.

Types

t()

@type t() :: %Planck.Agent.Skill{
  description: String.t(),
  name: String.t(),
  path: Path.t(),
  skill_file: Path.t()
}

A loaded skill.

  • :name — identifier used in the system prompt index
  • :description — one-line summary shown to the agent
  • :path — absolute path to the skill directory
  • :skill_file — absolute path to SKILL.md

Functions

from_file(skill_file)

@spec from_file(Path.t()) :: {:ok, t()} | {:error, String.t()}

Load a single skill from a SKILL.md file path.

Returns {:ok, skill} or {:error, reason}.

list_skills_tool(skills)

@spec list_skills_tool([t()]) :: Planck.Agent.Tool.t()

Build a list_skills tool that returns all available skill names and descriptions.

This is an opt-in discovery tool. Add "list_skills" to an agent's TEAM.json "tools" array when that agent needs to autonomously discover what skills exist. Workers that receive skill names from the orchestrator do not need this tool.

load_all(dirs)

@spec load_all([Path.t()]) :: [t()]

Load all skills from a list of directories.

Each directory is scanned for subdirectories containing a SKILL.md file. Directories that do not exist are silently skipped. Invalid SKILL.md files are skipped with a warning.

Paths are expanded via Path.expand/1 so ~ and relative paths resolve correctly.

load_skill_tool(skills)

@spec load_skill_tool([t()]) :: Planck.Agent.Tool.t()

Build a load_skill tool that loads a skill's SKILL.md by name.

The tool is a closure over the given skill pool. It is automatically added to every agent when skills are available — agents do not need to declare it in their TEAM.json "tools" array.

system_prompt_section(skills)

@spec system_prompt_section([t()]) :: String.t() | nil

Generate a skills section for injection into an agent's system prompt.

Produces a compact index of skill names and descriptions, followed by an instruction to load skills via the load_skill tool. Returns nil when the list is empty.