Documentation
¶
Overview ¶
Package skills provides a library for managing agent skills - reusable instruction sets that extend AI coding agent capabilities.
Skills are defined as SKILL.md files with YAML frontmatter containing name and description fields. They can be installed from various sources (GitHub, GitLab, well-known endpoints, local paths, or custom providers) into multiple agent directories.
Index ¶
- Constants
- func ComputeContentHash(content string) string
- func ComputeFolderHash(dir string) (string, error)
- func ComputeFolderHashFS(fsys fs.FS, dir string) (string, error)
- func DefaultAgents(homeDir string) map[AgentType]AgentConfig
- func GetPluginGroupings(basePath string) map[string]string
- func GlobalLockPath(homeDir string) string
- func ProjectLockPath(projectDir string) string
- func ResolveInstallPath(skillName string, agentType AgentType, dest *DestOptions) (string, error)
- func SanitizeName(name string) string
- func Uninstall(skillName string, agentTypes []AgentType, dest *DestOptions) error
- type AgentConfig
- type AgentType
- type DestOptions
- type DiscoverOptions
- type Fetcher
- type GlobalLock
- type GlobalLockEntry
- type HashProvider
- type InstallMode
- type InstallResult
- type InstalledSkill
- type ListScope
- type ParsedSource
- type PathTraversalError
- type ProjectLock
- type ProjectLockEntry
- type Providers
- type Skill
- func Discover(basePath string, subpath string, opts *DiscoverOptions) ([]*Skill, error)
- func DiscoverFS(fsys fs.FS, subpath string, opts *DiscoverOptions) ([]*Skill, error)
- func Filter(skills []*Skill, names []string) []*Skill
- func ParseSkill(r io.Reader) (*Skill, error)
- func ParseSkillBytes(data []byte) (*Skill, error)
- func ParseSkillFile(path string) (*Skill, error)
- type SkillMetadata
- type Source
- type SourceParser
- type SourceRef
- type SourceType
Constants ¶
const ( AgentsDir = ".agents" SkillsSubdir = "skills" UniversalSkillsDir = ".agents/skills" )
const GlobalLockVersion = 3
GlobalLockVersion is the current version of the global lock file format.
const ProjectLockVersion = 1
ProjectLockVersion is the current version of the project lock file format.
Variables ¶
This section is empty.
Functions ¶
func ComputeContentHash ¶
ComputeContentHash computes a SHA-256 hash of a string.
func ComputeFolderHash ¶
ComputeFolderHash computes a SHA-256 hash from all files in a directory. Files are sorted by relative path for deterministic output. Directories named .git and node_modules are skipped.
func ComputeFolderHashFS ¶
ComputeFolderHashFS computes a SHA-256 hash from all files in a directory within an fs.FS. Files are sorted by relative path for deterministic output. Directories named .git and node_modules are skipped.
func DefaultAgents ¶
func DefaultAgents(homeDir string) map[AgentType]AgentConfig
DefaultAgents returns all known agent configurations. homeDir is the user's home directory (e.g. from os.UserHomeDir()).
func GetPluginGroupings ¶
GetPluginGroupings returns a map of absolute skill directory path to plugin name.
func GlobalLockPath ¶
GlobalLockPath returns the default path for the global lock file. It checks XDG_STATE_HOME first, then falls back to ~/.agents/.skill-lock.json. homeDir is the user's home directory.
func ProjectLockPath ¶
ProjectLockPath returns the path for the project lock file in the given directory.
func ResolveInstallPath ¶
func ResolveInstallPath(skillName string, agentType AgentType, dest *DestOptions) (string, error)
ResolveInstallPath returns the directory where a skill would be installed for the given agent type and options, without actually installing anything.
func SanitizeName ¶
SanitizeName sanitizes a skill name for use as a directory name.
Types ¶
type AgentConfig ¶
type AgentConfig struct {
Name string
DisplayName string
SkillsDir string // relative to project root
GlobalSkillsDir string // absolute path, empty if global not supported
ShowInUniversalList bool
DetectInstalled func() bool
}
AgentConfig describes where an agent stores skills.
type AgentType ¶
type AgentType = string
AgentType is a string identifier for a supported agent.
const ( AgentAmp AgentType = "amp" AgentAntigravity AgentType = "antigravity" AgentAugment AgentType = "augment" AgentClaudeCode AgentType = "claude-code" AgentOpenClaw AgentType = "openclaw" AgentCline AgentType = "cline" AgentCodeBuddy AgentType = "codebuddy" AgentCodex AgentType = "codex" AgentCommandCode AgentType = "command-code" AgentContinue AgentType = "continue" AgentCortex AgentType = "cortex" AgentCrush AgentType = "crush" AgentCursor AgentType = "cursor" AgentDeepAgents AgentType = "deepagents" AgentDroid AgentType = "droid" AgentFirebender AgentType = "firebender" AgentGeminiCLI AgentType = "gemini-cli" AgentGitHubCopilot AgentType = "github-copilot" AgentGoose AgentType = "goose" AgentJunie AgentType = "junie" AgentIFlowCLI AgentType = "iflow-cli" AgentKilo AgentType = "kilo" AgentKimiCLI AgentType = "kimi-cli" AgentKiroCLI AgentType = "kiro-cli" AgentKode AgentType = "kode" AgentMCPJam AgentType = "mcpjam" AgentMistralVibe AgentType = "mistral-vibe" AgentMux AgentType = "mux" AgentNeovate AgentType = "neovate" AgentOpenCode AgentType = "opencode" AgentOpenHands AgentType = "openhands" AgentPi AgentType = "pi" AgentQoder AgentType = "qoder" AgentQwenCode AgentType = "qwen-code" AgentReplit AgentType = "replit" AgentRoo AgentType = "roo" AgentTrae AgentType = "trae" AgentTraeCN AgentType = "trae-cn" AgentWarp AgentType = "warp" AgentWindsurf AgentType = "windsurf" AgentZencoder AgentType = "zencoder" AgentPochi AgentType = "pochi" AgentAdal AgentType = "adal" AgentUniversal AgentType = "universal" )
Known agent types.
func DetectInstalledAgents ¶
func DetectInstalledAgents(agents map[AgentType]AgentConfig) []AgentType
DetectInstalledAgents returns agent types that appear to be installed.
func NonUniversalAgents ¶
func NonUniversalAgents(agents map[AgentType]AgentConfig) []AgentType
NonUniversalAgents returns agent types that use agent-specific directories.
func UniversalAgents ¶
func UniversalAgents(agents map[AgentType]AgentConfig) []AgentType
UniversalAgents returns agent types that use the universal .agents/skills directory.
type DestOptions ¶
type DestOptions struct {
Global bool
Cwd string
HomeDir string
Mode InstallMode
Agents map[AgentType]AgentConfig
// Scope controls which scopes ListInstalled searches.
// Default (ScopeAll) returns project+global when Global=false, global-only when Global=true.
Scope ListScope
}
DestOptions configures where and how skills are installed.
type DiscoverOptions ¶
type DiscoverOptions struct {
IncludeInternal bool
FullDepth bool
// Agents is used to derive priority search directories from AgentConfig.SkillsDir.
// If nil, DefaultAgents with the current user's home directory is used.
Agents map[AgentType]AgentConfig
// OnParseError is called when a SKILL.md file cannot be parsed.
// If nil, parse errors are silently ignored (legacy behavior).
OnParseError func(path string, err error)
// OnDuplicate is called when a skill with the same name is found in multiple directories.
// path1 is the path of the first occurrence, path2 is the duplicate being skipped.
// If nil, duplicates are silently ignored (legacy behavior).
OnDuplicate func(name, path1, path2 string)
}
DiscoverOptions controls skill discovery behavior.
type Fetcher ¶
type Fetcher interface {
// Fetch retrieves skills from the given parsed source into a local directory.
// It returns the path to the local directory containing the fetched content.
// The caller is responsible for calling Cleanup when done.
Fetch(ctx context.Context, source ParsedSource) (localDir string, cleanup func(), err error)
}
Fetcher is the core abstraction for fetching skills from a source. This replaces the direct git dependency, allowing any storage backend.
func MultiFetcher ¶
MultiFetcher combines multiple Fetchers. Each is tried in order; the first that succeeds is used.
type GlobalLock ¶
type GlobalLock struct {
Version int `json:"version"`
Skills map[string]GlobalLockEntry `json:"skills"`
Dismissed map[string]bool `json:"dismissed,omitempty"`
LastSelectedAgents []string `json:"lastSelectedAgents,omitempty"`
}
GlobalLock represents the global skill lock file (~/.agents/.skill-lock.json).
func NewGlobalLock ¶
func NewGlobalLock() *GlobalLock
NewGlobalLock creates a new empty global lock.
func ReadGlobalLock ¶
func ReadGlobalLock(r io.Reader) (*GlobalLock, error)
ReadGlobalLock decodes a global lock from an io.Reader.
func ReadGlobalLockFile ¶
func ReadGlobalLockFile(path string) (*GlobalLock, error)
ReadGlobalLockFile reads the global lock file from the given path.
func (*GlobalLock) ApplyResults ¶
func (l *GlobalLock) ApplyResults(results []InstallResult)
ApplyResults applies successful install results to the global lock. It does not write to disk; the caller is responsible for persistence.
func (*GlobalLock) RemoveSkill ¶
func (l *GlobalLock) RemoveSkill(name string)
RemoveSkill removes a skill entry from the global lock.
func (*GlobalLock) SetSkill ¶
func (l *GlobalLock) SetSkill(name string, entry GlobalLockEntry)
SetSkill adds or updates a skill entry in the global lock.
func (*GlobalLock) WriteFile ¶
func (l *GlobalLock) WriteFile(path string) error
WriteFile writes the global lock file to the given path.
type GlobalLockEntry ¶
type GlobalLockEntry struct {
Source string `json:"source"`
SourceType string `json:"sourceType"`
SourceURL string `json:"sourceUrl"`
SkillPath string `json:"skillPath"`
SkillFolderHash string `json:"skillFolderHash,omitempty"`
InstalledAt string `json:"installedAt"`
UpdatedAt string `json:"updatedAt"`
PluginName string `json:"pluginName,omitempty"`
}
GlobalLockEntry represents a single skill entry in the global lock file.
type HashProvider ¶
type HashProvider interface {
// FetchFolderHash returns the hash for a skill folder in a remote source.
// ownerRepo is "owner/repo", skillPath is the path within the repo.
FetchFolderHash(ctx context.Context, ownerRepo string, skillPath string) (string, error)
}
HashProvider abstracts how skill folder hashes are obtained for update checking.
func MultiHashProvider ¶
func MultiHashProvider(providers ...HashProvider) HashProvider
MultiHashProvider combines multiple HashProviders. Each is tried in order; the first that succeeds is used.
type InstallMode ¶
type InstallMode string
InstallMode determines how skills are installed.
const ( InstallSymlink InstallMode = "symlink" InstallCopy InstallMode = "copy" )
type InstallResult ¶
type InstallResult struct {
Success bool
Path string
CanonicalPath string
Mode InstallMode
SymlinkFailed bool
Error string
// SkillName is the name of the skill that was installed.
SkillName string
// Err is the structured error (nil on success). Use this for errors.Is/As.
Err error
// SkippedFiles lists files that were skipped during remote install (e.g. unsafe paths).
SkippedFiles []string
// GlobalLockEntry is populated when a global install succeeds, for lock file updates.
GlobalLockEntry *GlobalLockEntry
// ProjectLockEntry is populated when a project install succeeds, for lock file updates.
ProjectLockEntry *ProjectLockEntry
}
InstallResult describes the outcome of an install operation.
func Install ¶
func Install(skill *Skill, agentType AgentType, src *SourceRef, dest *DestOptions) InstallResult
Install installs a skill for a single agent. If skill.Files is set, the in-memory file contents are written to disk. Otherwise, the skill directory at skill.Path is copied (or symlinked).
type InstalledSkill ¶
type InstalledSkill struct {
Name string `json:"name"`
Description string `json:"description"`
Path string `json:"path"`
CanonicalPath string `json:"canonicalPath"`
Scope string `json:"scope"`
Agents []AgentType `json:"agents"`
// DirName is the actual directory name on disk. If it differs from
// SanitizeName(Name), the install path has diverged from the frontmatter name.
DirName string `json:"dirName,omitempty"`
}
InstalledSkill represents a skill installed on disk.
func ListInstalled ¶
func ListInstalled(dest *DestOptions) ([]*InstalledSkill, error)
ListInstalled lists all installed skills from canonical and agent directories. The scope can be controlled via dest.Scope (ScopeAll by default, which returns both project and global when dest.Global is false, or global-only when dest.Global is true). For explicit control, set dest.Scope to ScopeProject, ScopeGlobal, or ScopeAll.
func (*InstalledSkill) AddAgent ¶
func (is *InstalledSkill) AddAgent(t AgentType)
AddAgent adds an agent to the installed skill if not already present.
func (*InstalledSkill) NameDiverged ¶
func (is *InstalledSkill) NameDiverged() bool
NameDiverged returns true if the on-disk directory name differs from what SanitizeName would produce for the skill's frontmatter name.
type ParsedSource ¶
type ParsedSource struct {
Type SourceType
URL string // For local sources, this is the absolute path.
Subpath string
Ref string
SkillFilter string
}
ParsedSource is the result of parsing a source string.
func ParseSource ¶
func ParseSource(input string) (ParsedSource, error)
ParseSource parses a source string into a structured format. Supports: local paths, GitHub URLs/shorthand, GitLab URLs, well-known URLs, git URLs.
func ParseSourceWith ¶
func ParseSourceWith(input string, parser SourceParser) (ParsedSource, error)
ParseSourceWith parses a source string, trying a custom parser first. If parser is non-nil and recognizes the input, its result is returned. Otherwise the built-in logic is used.
func (ParsedSource) OwnerRepo ¶
func (ps ParsedSource) OwnerRepo() string
OwnerRepo extracts owner/repo from the parsed source for lockfile tracking.
type PathTraversalError ¶
type PathTraversalError struct {
Subpath string
}
PathTraversalError is returned when a subpath attempts to escape the base directory.
func (*PathTraversalError) Error ¶
func (e *PathTraversalError) Error() string
type ProjectLock ¶
type ProjectLock struct {
Version int `json:"version"`
Skills map[string]ProjectLockEntry `json:"skills"`
}
ProjectLock represents the project-scoped lock file (skills-lock.json).
func NewProjectLock ¶
func NewProjectLock() *ProjectLock
NewProjectLock creates a new empty project lock.
func ReadProjectLock ¶
func ReadProjectLock(r io.Reader) (*ProjectLock, error)
ReadProjectLock decodes a project lock from an io.Reader.
func ReadProjectLockFile ¶
func ReadProjectLockFile(path string) (*ProjectLock, error)
ReadProjectLockFile reads the project lock file from the given path.
func (*ProjectLock) ApplyResults ¶
func (l *ProjectLock) ApplyResults(results []InstallResult)
ApplyResults applies successful install results to the project lock. It does not write to disk; the caller is responsible for persistence.
func (*ProjectLock) RemoveSkill ¶
func (l *ProjectLock) RemoveSkill(name string)
RemoveSkill removes a skill entry from the project lock.
func (*ProjectLock) SetSkill ¶
func (l *ProjectLock) SetSkill(name string, entry ProjectLockEntry)
SetSkill adds or updates a skill entry in the project lock.
func (*ProjectLock) WriteFile ¶
func (l *ProjectLock) WriteFile(path string) error
WriteFile writes the project lock file to the given path.
type ProjectLockEntry ¶
type ProjectLockEntry struct {
Source string `json:"source"`
SourceType string `json:"sourceType"`
ComputedHash string `json:"computedHash,omitempty"`
}
ProjectLockEntry represents a single skill entry in the project lock file.
type Providers ¶
type Providers struct {
// Fetcher retrieves skills from remote sources (git, well-known endpoints, etc.).
// Use [MultiFetcher] to combine multiple fetchers.
Fetcher Fetcher
// HashProvider checks remote hashes for update detection.
HashProvider HashProvider
// SourceParser parses source strings into ParsedSource.
// Tried before the built-in logic.
SourceParser SourceParser
}
Providers bundles the provider interfaces needed by high-level APIs. All fields are optional; nil fields cause the corresponding functionality to be skipped or use defaults.
To combine multiple implementations, use MultiFetcher, MultiHashProvider, and MultiSourceParser.
type Skill ¶
type Skill struct {
// Name is the unique identifier for the skill (lowercase, hyphens allowed, 1-64 chars).
Name string `yaml:"name" json:"name"`
// Description is a brief explanation of the skill's functionality.
Description string `yaml:"description" json:"description"`
// Metadata contains optional fields.
Metadata SkillMetadata `yaml:"metadata,omitempty" json:"metadata,omitempty"`
// RawFrontmatter preserves all frontmatter fields (including unknown ones like
// allowed-tools, disable-model-invocation) for round-trip fidelity in Marshal().
RawFrontmatter map[string]any `yaml:"-" json:"-"`
// Body is the markdown content after the frontmatter.
Body string `yaml:"-" json:"-"`
// RawContent is the original SKILL.md content for hashing.
RawContent string `yaml:"-" json:"-"`
// Path is the directory containing the SKILL.md file (absolute on disk, or FS-relative).
// When Files is set, Path may be empty.
Path string `yaml:"-" json:"path,omitempty"`
// Files holds in-memory file contents for skills fetched from remote providers.
// When non-nil, Install writes these to disk instead of copying from Path.
// Keys are relative file paths (e.g. "SKILL.md", "helper.sh").
Files map[string]string `yaml:"-" json:"files,omitempty"`
// PluginName is the name of the plugin this skill belongs to (if any).
PluginName string `yaml:"-" json:"pluginName,omitempty"`
// SourceURL is the URL of the source (set by remote providers).
SourceURL string `yaml:"-" json:"sourceUrl,omitempty"`
// ProviderID identifies which provider fetched this skill.
ProviderID string `yaml:"-" json:"providerId,omitempty"`
// SourceIdentifier is a provider-specific identifier for the source.
SourceIdentifier string `yaml:"-" json:"sourceIdentifier,omitempty"`
}
Skill represents a parsed SKILL.md file.
func Discover ¶
func Discover(basePath string, subpath string, opts *DiscoverOptions) ([]*Skill, error)
Discover finds all SKILL.md files in the given directory.
func DiscoverFS ¶
DiscoverFS finds all SKILL.md files in the given fs.FS. Paths within the FS use forward slashes (path.Join). Skill.Path is set to the FS-relative path (e.g. "skills/my-skill").
func ParseSkill ¶
ParseSkill parses a SKILL.md file from a reader.
func ParseSkillBytes ¶
ParseSkillBytes parses a SKILL.md file from bytes.
func ParseSkillFile ¶
ParseSkillFile parses a SKILL.md file from the filesystem.
type SkillMetadata ¶
type SkillMetadata struct {
Internal bool `yaml:"internal,omitempty" json:"internal,omitempty"`
}
SkillMetadata contains optional metadata fields for a skill.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source describes where to obtain skills for installation. Create instances using SourceFrom, SourceFromFS, or SourceFromLocal.
func SourceFrom ¶
SourceFrom creates a Source from a string that will be parsed automatically. Supports GitHub shorthand ("owner/repo"), Git URLs, well-known endpoints, and local paths. The string may include subpath and skill filter (e.g. "owner/repo/path/to/skills@skill-name").
func SourceFromFS ¶
SourceFromFS creates a Source backed by an fs.FS (e.g. embed.FS).
func SourceFromLocal ¶
SourceFromLocal creates a Source from a local directory path. Unlike SourceFrom, this always treats the path as local without running it through source parsing.
type SourceParser ¶
type SourceParser func(input string) (ParsedSource, bool, error)
SourceParser is a function that attempts to parse a source string. It returns a ParsedSource and true if the input was recognized, or false if not. Custom parsers are tried before the built-in logic, allowing extension for formats like Azure DevOps, Bitbucket shorthand, etc.
func MultiSourceParser ¶
func MultiSourceParser(parsers ...SourceParser) SourceParser
MultiSourceParser combines multiple SourceParsers. Each is tried in order; the first that recognizes the input wins.
type SourceRef ¶
type SourceRef struct {
// FS is the source filesystem for reading skill files.
// When set, skill.Path is treated as an FS-relative path and files are read
// from FS instead of the OS filesystem. Writing still goes to the OS.
// If nil, skill.Path is treated as an OS absolute path (backward compat).
FS fs.FS
// Parsed is the parsed source used for this install, used to populate lock entries in InstallResult.
Parsed *ParsedSource
// FetchRoot is the root directory of the fetched source (e.g. the clone directory).
// Used to compute repo-relative skill paths for lock entries.
FetchRoot string
}
SourceRef describes where a skill comes from.
type SourceType ¶
type SourceType string
SourceType identifies how a source was parsed.
const ( SourceGitHub SourceType = "github" SourceGitLab SourceType = "gitlab" SourceGit SourceType = "git" SourceLocal SourceType = "local" SourceWellKnown SourceType = "well-known" )
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
skills
command
|
|
|
internal
|
|
|
cmd/docgen
command
Command docgen regenerates marker sections in README.md from Go source.
|
Command docgen regenerates marker sections in README.md from Go source. |
|
provider
|
|
|
git
Package git implements skills.Fetcher using the git command-line tool.
|
Package git implements skills.Fetcher using the git command-line tool. |
|
github
Package github implements skills.HashProvider using the GitHub Trees API.
|
Package github implements skills.HashProvider using the GitHub Trees API. |
|
go-git
Package gogit implements skills.Fetcher using go-git v6 (pure Go git implementation).
|
Package gogit implements skills.Fetcher using go-git v6 (pure Go git implementation). |
|
local
Package local implements skills.Fetcher for local filesystem paths and provides local disk hashing for skill folders.
|
Package local implements skills.Fetcher for local filesystem paths and provides local disk hashing for skill folders. |
|
wellknown
Package wellknown implements skills.Fetcher for RFC 8615 well-known endpoints.
|
Package wellknown implements skills.Fetcher for RFC 8615 well-known endpoints. |
|
Package sk provides high-level orchestration functions for skill management.
|
Package sk provides high-level orchestration functions for skill management. |