Documentation
¶
Overview ¶
Package skills discovers reusable instruction "skills" stored on disk as */SKILL.md files. Each skill is a directory containing a SKILL.md whose optional YAML-ish frontmatter carries a name/description and whose markdown body is the skill content the model can pull in on demand (PRD F15).
The loader is deliberately dependency-free: frontmatter is hand-parsed (no YAML library) and malformed files are skipped rather than failing the whole load, so a single bad skill never hides the good ones.
Index ¶
Constants ¶
const LockFileName = "skills.lock"
LockFileName is the name of the per-directory lockfile that maps an installed skill name to the source it was installed from and the content hash recorded at install time.
Variables ¶
var ErrNameClash = errors.New("a different skill with that name is already installed")
ErrNameClash is returned when an install would overwrite a skill that was installed from a DIFFERENT source, unless InstallOptions.Force is set. It is a safety guard so a remote source can never silently shadow a skill the user already trusts.
Functions ¶
func DefaultDir ¶
DefaultDir resolves the skills directory, mirroring sessions.DefaultRoot. An explicit ZERO_SKILLS_DIR override wins; otherwise it is $XDG_DATA_HOME/zero/skills or ~/.local/share/zero/skills. The directory is NOT created — a missing directory simply yields no skills.
Types ¶
type DuplicateName ¶
DuplicateName records two skills that resolved to the same frontmatter name. Winner is the SKILL.md path of the skill that was kept (the one in the lexicographically-first directory); Loser is the path that was dropped.
func Duplicates ¶
func Duplicates(dir string) ([]DuplicateName, error)
Duplicates returns the duplicate-name collisions Load resolved by the first-directory-wins rule, so a caller can warn the user that a shadowed skill was dropped. A missing directory yields no duplicates and no error.
type GitRunner ¶
GitRunner fetches the skill at source into destination. The default runner shallow-clones with the system git, which inherits the process environment (and therefore any proxy/egress settings). It is injectable so tests never hit the network. A runner must only fetch — it must never execute fetched content.
type InstallOptions ¶
type InstallOptions struct {
// Source is a git URL or a local filesystem path to a skill directory (one
// that contains a SKILL.md, or whose tree contains exactly one).
Source string
// Dir is the skills directory to install into (typically DefaultDir(env)).
Dir string
// Force allows overwriting a skill that was installed from a different source.
Force bool
// GitRunner overrides the fetch implementation (tests/proxy control). When
// nil, a git source is shallow-cloned with the system git.
GitRunner GitRunner
}
InstallOptions configures a single skill install.
type InstallResult ¶
type InstallResult struct {
Name string `json:"name"`
// Path is the absolute path to the installed SKILL.md.
Path string `json:"path"`
// Hash is the content hash recorded for the installed skill.
Hash string `json:"hash"`
// Source echoes the source the skill was installed from.
Source string `json:"source"`
// Updated is true when an existing install was replaced; PreviousHash then
// carries the prior recorded hash so a caller can show the change.
Updated bool `json:"updated"`
PreviousHash string `json:"previousHash,omitempty"`
}
InstallResult reports what an install did.
func Install ¶
func Install(ctx context.Context, options InstallOptions) (InstallResult, error)
Install fetches the skill at options.Source and copies its SKILL.md into options.Dir/<name>/, validating the frontmatter and recording a content hash in the lockfile. A git URL is fetched via the (injectable) GitRunner into a temp dir; a local path is read in place. Fetched content is never executed.
type Skill ¶
type Skill struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Content string `json:"content,omitempty"`
Path string `json:"path"`
}
Skill is a single discovered skill. Name and Description come from the SKILL.md frontmatter (Name falls back to the directory name); Content is the markdown body; Path is the absolute path to the SKILL.md file.
func List ¶
List loads the skills directory and returns each skill without its (possibly large) Content body — handy for `zero skills` listings.
func Load ¶
Load scans dir for */SKILL.md files and returns the parsed skills sorted by name. A missing directory yields an empty slice with no error; individual malformed skill files are skipped rather than failing the whole load.
When two skills declare the SAME frontmatter name, resolution is made DETERMINISTIC by a documented rule: the skill in the lexicographically-first directory name wins (os.ReadDir returns entries sorted by filename, so the first one encountered is kept and later same-name duplicates are dropped). This guarantees Load/List/Get always resolve a duplicated name to the same winner regardless of sort stability. Use Duplicates to surface a warning about any such collisions.
NOTE: Load currently scans a single root (ZERO_SKILLS_DIR / the data dir). Plugin-declared skill paths (the plugins manifest "skills" array) are NOT yet merged into this lookup; multi-root loading is tracked as a separate feature.