Documentation
¶
Overview ¶
Package skill loads invokable playbooks ("skills") from Markdown files. A skill is a named, described prompt body the model can invoke via the run_skill tool (or the user via "/<name>"): an "inline" skill folds its body into the turn as a tool result, a "subagent" skill runs in an isolated child loop and returns only its final answer. Project scope wins over global; only names+descriptions enter the cache-stable system-prompt index (see index.go) — bodies load on demand. Discovery scans several conventions (.ok / .agents / .agent / .claude under the project root and the home dir — see config.ConventionDirs) so skills authored for other agent tools migrate in unchanged, and follows symlinks, so a linked skill directory or flat <name>.md is picked up like a real one.
Package skill — security validation for skill bodies.
Every skill body passes through these checks at load time (hand-written skills) and at auto-generation time (evolution skills). Layer 0 checks structural completeness; Layer 1 scans for dangerous shell patterns.
Unlike evolution.Engine's validation pipeline, these checks run before any skill enters the store — malicious skills are rejected at the gate.
Index ¶
- Constants
- func ApplyIndex(basePrompt string, skills []Skill) string
- func BuiltinNames() []string
- func BuiltinSubagentTools(store *Store, runner SubagentRunner) []tool.Tool
- func IsValidName(name string) bool
- func KnownTools() []string
- func LooksLikeToolName(s string) bool
- func NewInstallSkillTool(store *Store, onInstalled InstalledHook) tool.Tool
- func NewRunSkillTool(store *Store, runner SubagentRunner) tool.Tool
- func Render(sk Skill, args string) string
- func ValidateReferences(body string, knownTools []string) error
- func ValidateSafety(body string) error
- func ValidateStructure(body string) error
- type InstalledHook
- type Options
- type PathStatus
- type Root
- type RunAs
- type Scope
- type Skill
- type Store
- func (s *Store) Create(name string, scope Scope) (string, error)
- func (s *Store) CreateWithContent(name string, scope Scope, content string) (string, error)
- func (s *Store) HasProjectScope() bool
- func (s *Store) List() []Skill
- func (s *Store) Read(name string) (Skill, bool)
- func (s *Store) Roots() []Root
- type SubagentRunner
Constants ¶
const ( // SkillsDirname is the directory under each root that holds skills. SkillsDirname = "skills" // SkillFile is the canonical filename inside a directory-layout skill. SkillFile = "SKILL.md" )
const IndexMaxChars = 2000
IndexMaxChars caps the pinned skills-index block so it can't bloat the cache-stable system-prompt prefix; bodies never enter the prefix.
Variables ¶
This section is empty.
Functions ¶
func ApplyIndex ¶
ApplyIndex appends the skills index to basePrompt, or returns it unchanged when there are no skills. Only names + descriptions (+ a subagent tag) are listed; bodies load on demand via run_skill.
func BuiltinNames ¶
func BuiltinNames() []string
BuiltinNames returns the built-in skill names, used by callers that wire dedicated subagent tools for the subagent built-ins.
func BuiltinSubagentTools ¶
func BuiltinSubagentTools(store *Store, runner SubagentRunner) []tool.Tool
BuiltinSubagentTools returns top-level wrapper tools for the built-in subagent skills, named after the verb so the model picks them naturally (affordance > prompt rules). Each is skipped when its underlying skill isn't present (e.g. a user disabled it), so the tool set never advertises a phantom skill.
func IsValidName ¶
IsValidName reports whether name is a usable skill identifier.
func KnownTools ¶
func KnownTools() []string
KnownTools returns the canonical set of tool names a skill may reference.
func LooksLikeToolName ¶
func NewInstallSkillTool ¶
func NewInstallSkillTool(store *Store, onInstalled InstalledHook) tool.Tool
NewInstallSkillTool builds the skill-authoring tool. onInstalled may be nil.
func NewRunSkillTool ¶
func NewRunSkillTool(store *Store, runner SubagentRunner) tool.Tool
NewRunSkillTool builds the general skill-invocation tool. runner may be nil (subagent skills then error).
func Render ¶
Render builds a skill's invocation text: a header (name, description, source) followed by the body and any arguments. Used directly when a user invokes a skill via "/<name>" (sent as a turn); the run_skill tool wraps the same text in a skill-pin sentinel (see renderInline).
func ValidateReferences ¶
ValidateReferences checks that the skill body only references known tool names. Unknown tool references may indicate hallucination.
func ValidateSafety ¶
ValidateSafety scans the skill body for dangerous shell patterns. Returns nil when the skill appears safe.
func ValidateStructure ¶
ValidateStructure checks a skill body for structural completeness. Returns nil when the skill is well-formed enough to be installed.
Types ¶
type InstalledHook ¶
InstalledHook fires after install_skill writes a new file, so a host can refresh UI (e.g. a skills sidebar) without a reload. nil is fine.
type Options ¶
type Options struct {
HomeDir string
ProjectRoot string
CustomPaths []string
DisableBuiltins bool // suppress shipped built-ins (test-only knob)
}
Options configure a Store. ProjectRoot "" reads only the global + custom scopes. HomeDir "" resolves to the OS home dir (tests point it at a tmpdir).
type PathStatus ¶
type PathStatus string
PathStatus describes a root directory's readability, surfaced by `/skill paths`.
const ( StatusOK PathStatus = "ok" StatusMissing PathStatus = "missing" StatusNotDirectory PathStatus = "not-directory" StatusUnreadable PathStatus = "unreadable" )
type Root ¶
type Root struct {
Dir string
Scope Scope
Priority int
Status PathStatus
}
Root is one discovery directory with its scope, priority, and status.
type RunAs ¶
type RunAs string
RunAs selects how an invoked skill executes. Inline folds the body into the parent turn; subagent spawns an isolated child loop and returns only the final answer (its tool calls and reasoning never enter the parent context).
type Scope ¶
type Scope string
Scope records where a skill was loaded from. Higher-priority scopes win on a name collision: project > custom > global > builtin.
type Skill ¶
type Skill struct {
Name string // canonical identifier; matches the directory / filename stem
Description string // one-liner shown in the pinned index
Body string // full markdown body (post-frontmatter), loaded eagerly
Scope Scope // where it came from
Path string // absolute path to the SKILL.md / <name>.md, or "(builtin)"
// AllowedTools, when non-empty, scopes a subagent skill's tool registry to
// these literal tool names (from the `allowed-tools` frontmatter).
AllowedTools []string
RunAs RunAs // inline | subagent
Model string // optional model override for runAs=subagent (frontmatter `model:`)
}
Skill is a loaded playbook.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store resolves skills across the configured roots.
func New ¶
New builds a Store. Relative custom paths and a relative project root are made absolute; "~" in a custom path expands to the home dir.
func (*Store) CreateWithContent ¶
CreateWithContent writes caller-supplied file contents as a new flat <name>.md skill, refusing to clobber an existing flat or directory-layout skill of the same name. Returns the written path.
func (*Store) HasProjectScope ¶
HasProjectScope reports whether the store was configured with a project root.
func (*Store) List ¶
List returns every discoverable skill, deduped by name (first/highest-priority root wins) with built-ins folded in last, sorted by name so the prefix index stays stable and cacheable.
type SubagentRunner ¶
SubagentRunner runs a runAs=subagent skill: it spawns an isolated child loop with the skill body as system prompt and `task` as its only input, returning the final answer. boot wires this over the agent's sub-agent machinery; nil means subagent skills are unavailable in this session (they error rather than silently inlining, which would lose the isolation the author asked for).