Skill System
A skill is a loadable markdown instruction pack that switches the agent into a specific execution mode (e.g., commit message generation, code review, README generation).
Skill format
A skill is a markdown file with YAML frontmatter for metadata:
***
name: code-reviewer
description: Deep code review covering quality, security, and architecture
version: 1.0.0
***
You are now a strict code reviewer...
The frontmatter name is the trigger keyword. The body is rendered into the system prompt when the skill activates.
Trigger paths
/skill-name slash command
Prefix any input with /<skill-name>:
/code-reviewer review the diff in this PR
runtime.MatchSkill runs inside exec.Prepare at execution startup (a skill passed by name is resolved in exec.Start instead, and fails the run when excluded or missing). When it hits, agenvoy synthesizes a run_skill tool_call and corresponding tool_result (containing the skill body) directly into ToolHistories — byte-identical to the natural-language activation path, preserving prefix cache.
If the user passed args (/code-reviewer review src/parser.go), the user message strips the /<skill-name> prefix and only the args remain. With no args, the user message keeps the literal /<skill-name> so the LLM still sees the activation context.
Natural-language activation
If an agent decides a task needs a skill mid-execution, it calls run_skill directly. This is the LLM-initiated path and uses the same render pipeline.
Skill activation is designed as a tool call (lazy load) rather than a startup-time pre-selection — it avoids paying skill-body tokens for tasks that don't need them.
Multi-skill in one conversation
A conversation can activate multiple skills sequentially. Each run_skill call appends to the existing instruction stack; later skills augment or override earlier ones via system-prompt section ordering.
User message is binding context
skill_execution.md Mandatory Principle #5: the user message that triggered the skill is binding context, not noise. The LLM treats it as user-supplied parameters/hints to weave into the output.
Concretely:
- SKILL.md describes default behavior
- User message overrides or augments default behavior
- "Steps in SKILL.md are commands" is not a rigid one-way reading
Example: /readme-generate private MIT — SKILL.md defines the README structure; the user message specifies private mode + MIT license, both of which override defaults.
Skill locations
The scanner walks eight directories, so skills written for other agents load without conversion:
| Path | Source label |
|---|---|
<cwd>/.skills |
local |
<cwd>/.claude/skills |
claude |
~/.config/agenvoy/skills/.system |
system (bundled, refreshed by make build from extensions/skills/) |
~/.config/agenvoy/skills |
agenvoy |
~/.claude/skills |
claude |
~/.codex/skills |
codex |
~/.opencode/skills |
opencode |
~/.openai/skills |
openai |
Each skill is a directory containing SKILL.md plus optional scripts and templates. The source label shows next to the skill in the TUI slash picker, so it is obvious whether /code-reviewer came from this project, from Agenvoy's own storage, or from another agent's config.
The system prompt's ## Skills block lists what is available; run_skill loads a body on demand.
Always-allow list
A skill can be marked always-allow so its tool calls skip the confirm gate: /allow-skill in the TUI (the /dangerous command was removed), or POST /v1/allowlist with a {skill: {name, scope, work_dir}} block (scope=global|project). Global entries live in ~/.config/agenvoy/allow_skill, project entries in <project>/.agenvoy/allow_skill, and the two are unioned at load time.
Skill execution prompt
The execution loop is driven by configs/prompts/skill_execution.md, which carries the rules every skill obeys (output discipline, tool-name mapping, mandatory principles).
Tool-name mapping example: external skills written for the Anthropic SDK may reference AskUserQuestion; agenvoy maps these to ask_user automatically through the Tool Name Mapping table in skill_execution.md. No alias registration in Go is needed.