Documentation
¶
Overview ¶
Package skills provides types and utilities for loading, parsing, and managing PromptKit skills defined via the AgentSkills.io SKILL.md format.
Index ¶
- Constants
- Variables
- func BuildSkillActivateDescriptor() *tools.ToolDescriptor
- func BuildSkillActivateDescriptorWithIndex(index string) *tools.ToolDescriptor
- func BuildSkillDeactivateDescriptor() *tools.ToolDescriptor
- func BuildSkillReadResourceDescriptor() *tools.ToolDescriptor
- func DefaultSkillsProjectDir() (string, error)
- func DefaultSkillsUserDir() (string, error)
- func IsLocalPath(arg string) bool
- type EmbeddingProvider
- type EmbeddingSelector
- type Executor
- func (e *Executor) Activate(name string) (instructions string, addedTools []string, retErr error)
- func (e *Executor) ActiveSkills() []string
- func (e *Executor) ActiveTools() []string
- func (e *Executor) Deactivate(name string) (removedTools []string, retErr error)
- func (e *Executor) ReadResource(skillName, path string) ([]byte, error)
- func (e *Executor) SkillIndex(skillsDir string) string
- type ExecutorConfig
- type InstalledSkill
- type Installer
- func (inst *Installer) Install(ref SkillRef, projectLevel bool) (string, error)
- func (inst *Installer) InstallInto(ref SkillRef, targetDir string) (string, error)
- func (inst *Installer) InstallLocal(srcPath string, projectLevel bool) (string, error)
- func (inst *Installer) InstallLocalInto(srcPath, targetDir string) (string, error)
- func (inst *Installer) List() ([]InstalledSkill, error)
- func (inst *Installer) Remove(ref SkillRef) error
- func (inst *Installer) Resolve(ref SkillRef) (string, error)
- type ModelDrivenSelector
- type Registry
- func (r *Registry) Discover(sources []SkillSource) error
- func (r *Registry) Has(name string) bool
- func (r *Registry) List() []SkillMetadata
- func (r *Registry) ListForDir(dir string) []SkillMetadata
- func (r *Registry) Load(name string) (*Skill, error)
- func (r *Registry) PreloadedSkills() []*Skill
- func (r *Registry) ReadResource(name, resourcePath string) ([]byte, error)
- func (r *Registry) ResolveRef(ref SkillRef) (string, error)
- type Skill
- type SkillMetadata
- type SkillRef
- type SkillSelector
- type SkillSource
- type TagSelector
- type ToolExecutor
Constants ¶
const ( SkillActivateTool = "skill__activate" SkillDeactivateTool = "skill__deactivate" SkillReadResourceTool = "skill__read_resource" SkillNamespace = "skill" SkillExecutorName = "skill" )
Tool name constants for the skill__ namespace.
Variables ¶
var ErrPathTraversal = errors.New("resource path escapes skill directory")
ErrPathTraversal is returned when a resource path attempts to escape the skill directory.
Functions ¶
func BuildSkillActivateDescriptor ¶
func BuildSkillActivateDescriptor() *tools.ToolDescriptor
BuildSkillActivateDescriptor returns the tool descriptor for skill__activate.
func BuildSkillActivateDescriptorWithIndex ¶
func BuildSkillActivateDescriptorWithIndex(index string) *tools.ToolDescriptor
BuildSkillActivateDescriptorWithIndex returns a skill__activate descriptor whose Description includes the available-skills index so the LLM can discover which skills are available.
func BuildSkillDeactivateDescriptor ¶
func BuildSkillDeactivateDescriptor() *tools.ToolDescriptor
BuildSkillDeactivateDescriptor returns the tool descriptor for skill__deactivate.
func BuildSkillReadResourceDescriptor ¶
func BuildSkillReadResourceDescriptor() *tools.ToolDescriptor
BuildSkillReadResourceDescriptor returns the tool descriptor for skill__read_resource.
func DefaultSkillsProjectDir ¶
DefaultSkillsProjectDir returns the project-level skills directory.
func DefaultSkillsUserDir ¶
DefaultSkillsUserDir returns the XDG-compliant user-level skills directory.
func IsLocalPath ¶
IsLocalPath returns true if the argument looks like a local filesystem path rather than a skill reference (starts with "./", "../", or "/").
Types ¶
type EmbeddingProvider ¶
type EmbeddingProvider interface {
// Embed returns embedding vectors for the given texts.
// Each text produces one vector. All vectors must have the same dimensionality.
Embed(ctx context.Context, texts []string) ([][]float64, error)
}
EmbeddingProvider generates vector embeddings for text inputs. Implementations may wrap OpenAI, Anthropic, or local embedding models.
type EmbeddingSelector ¶
type EmbeddingSelector struct {
// contains filtered or unexported fields
}
EmbeddingSelector uses semantic similarity to select the most relevant skills for a given query. It precomputes embeddings for all skill descriptions at initialization and ranks skills by cosine similarity at selection time.
Effective for large skill sets (50+) where showing all skills in the Phase 1 index would waste context. Returns the top-k most relevant skills.
Safe for concurrent use after Build() completes.
func NewEmbeddingSelector ¶
func NewEmbeddingSelector(provider EmbeddingProvider, topK int) *EmbeddingSelector
NewEmbeddingSelector creates a new EmbeddingSelector with the given provider and top-k count. If topK <= 0, it defaults to 10.
func (*EmbeddingSelector) Build ¶
func (s *EmbeddingSelector) Build(ctx context.Context, skills []SkillMetadata) error
Build precomputes embeddings for the given skills' descriptions. Must be called before Select. Safe to call multiple times to rebuild the index.
func (*EmbeddingSelector) Select ¶
func (s *EmbeddingSelector) Select( ctx context.Context, query string, available []SkillMetadata, ) ([]string, error)
Select returns the top-k skill names most semantically similar to the query. If the embedding provider fails, it falls back to returning all skill names (equivalent to ModelDrivenSelector behavior). If available skills differ from the built index, only indexed skills that appear in available are considered.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor manages the skill activation lifecycle and provides functions that implement the skill__ namespaced tools.
func NewExecutor ¶
func NewExecutor(cfg ExecutorConfig) *Executor
NewExecutor creates a new Executor from the given configuration. If Selector is nil, a ModelDrivenSelector is used.
func (*Executor) Activate ¶
Activate loads a skill's instructions and returns them. It extends the active tool set with the skill's allowed-tools (capped by pack tools). If the skill is already active, it returns the instructions again (idempotent). Returns error if skill not found or at max active limit.
func (*Executor) ActiveSkills ¶
ActiveSkills returns the names of currently active skills, sorted.
func (*Executor) ActiveTools ¶
ActiveTools returns the aggregate set of tools added by all active skills (each capped by pack tools). The result is deduplicated and sorted.
func (*Executor) Deactivate ¶
Deactivate removes a skill from the active set. Returns the tools that should be removed from the active tool set. A tool is only removed if no other active skill also needs it.
func (*Executor) ReadResource ¶
ReadResource reads a file from within a skill's directory. Delegates to the underlying registry.
func (*Executor) SkillIndex ¶
SkillIndex returns the Phase 1 skill index string for inclusion in the skill__activate tool description. This is the list of available skills with their names and descriptions. If skillsDir is non-empty, filters to skills under that directory.
type ExecutorConfig ¶
type ExecutorConfig struct {
Registry *Registry
Selector SkillSelector // nil = ModelDrivenSelector
PackTools []string // all tools declared in the pack
MaxActive int // 0 = unlimited
}
ExecutorConfig configures the skill executor.
type InstalledSkill ¶
type InstalledSkill struct {
Org string // e.g., "anthropic"
Name string // e.g., "pdf-processing"
Location string // "user" or "project"
Path string // filesystem path to the skill directory
}
InstalledSkill describes a skill found in user-level or project-level directories.
type Installer ¶
type Installer struct {
UserDir string // ~/.config/promptkit/skills/
ProjectDir string // .promptkit/skills/
GitCloneFunc func(url, dest string) error // injectable for testing
GitCheckout func(dir, ref string) error // injectable for testing
CopyDirFunc func(src, dest string) error // injectable for testing
}
Installer manages installing, removing, listing, and resolving shared skills.
func NewInstaller ¶
NewInstaller creates an Installer with default XDG-compliant paths.
func (*Installer) Install ¶
Install clones a skill from its Git repository into the appropriate directory. If projectLevel is true, installs to .promptkit/skills/; otherwise to user-level. Returns the installation path.
func (*Installer) InstallInto ¶
InstallInto clones a skill from its Git repository directly into a target directory (e.g., a workflow stage directory like ./skills/billing/). The skill is placed at <targetDir>/<name>/. Returns the installation path.
func (*Installer) InstallLocal ¶
InstallLocal copies a skill from a local path into the appropriate directory. Returns the installation path.
func (*Installer) InstallLocalInto ¶
InstallLocalInto copies a skill from a local path directly into a target directory. Returns the installation path.
func (*Installer) List ¶
func (inst *Installer) List() ([]InstalledSkill, error)
List returns all installed skills from both user and project directories.
type ModelDrivenSelector ¶
type ModelDrivenSelector struct{}
ModelDrivenSelector is the default selector — it returns all available skills, letting the model decide which to activate via skill__activate. Effective for up to ~50 skills. Safe for concurrent use.
func NewModelDrivenSelector ¶
func NewModelDrivenSelector() *ModelDrivenSelector
NewModelDrivenSelector creates a new ModelDrivenSelector.
func (*ModelDrivenSelector) Select ¶
func (s *ModelDrivenSelector) Select( _ context.Context, _ string, available []SkillMetadata, ) ([]string, error)
Select returns all skill names from available.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds discovered skills and provides access by name and directory.
func (*Registry) Discover ¶
func (r *Registry) Discover(sources []SkillSource) error
Discover scans skill sources and registers all found skills. Sources are processed in order — later sources do NOT override earlier ones (first wins).
func (*Registry) List ¶
func (r *Registry) List() []SkillMetadata
List returns metadata for all registered skills, sorted by name.
func (*Registry) ListForDir ¶
func (r *Registry) ListForDir(dir string) []SkillMetadata
ListForDir returns metadata for skills whose path is under the given directory. If dir is empty, returns all skills. Results are sorted by name.
func (*Registry) Load ¶
Load returns the full skill by name, reading instructions from disk on demand.
func (*Registry) PreloadedSkills ¶
PreloadedSkills returns fully loaded skills marked with preload: true.
func (*Registry) ReadResource ¶
ReadResource reads a file from within a skill's directory. Returns error if the path escapes the skill directory (path traversal prevention).
type Skill ¶
type Skill struct {
SkillMetadata
Instructions string `json:"instructions"` // Markdown body from SKILL.md
Path string `json:"path"` // Filesystem path to skill directory
}
Skill holds a fully loaded skill — metadata + instructions + path. This is the Phase 2 data — loaded on activation.
func ParseSkillFile ¶
ParseSkillFile parses a SKILL.md file at the given path into a Skill. It extracts YAML frontmatter and markdown body.
type SkillMetadata ¶
type SkillMetadata struct {
Name string `yaml:"name" json:"name"`
Description string `yaml:"description" json:"description"`
License string `yaml:"license,omitempty" json:"license,omitempty"`
Compatibility string `yaml:"compatibility,omitempty" json:"compatibility,omitempty"`
Metadata map[string]string `yaml:"metadata,omitempty" json:"metadata,omitempty"`
AllowedTools []string `yaml:"allowed-tools,omitempty" json:"allowed_tools,omitempty"`
}
SkillMetadata holds the YAML frontmatter from a SKILL.md file. This is the Phase 1 data — loaded at discovery time (~50 tokens per skill).
func ParseSkillContent ¶
func ParseSkillContent(content []byte) (*SkillMetadata, string, error)
ParseSkillContent parses SKILL.md content from bytes. It returns the parsed metadata, the markdown body, and any error.
func ParseSkillMetadata ¶
func ParseSkillMetadata(path string) (*SkillMetadata, error)
ParseSkillMetadata parses only the YAML frontmatter from a SKILL.md file. Used for Phase 1 discovery — avoids loading the full body.
type SkillRef ¶
type SkillRef struct {
Org string // e.g., "anthropic"
Name string // e.g., "pdf-processing"
Version string // e.g., "v1.0.0" (empty = latest)
}
SkillRef represents a parsed skill reference like @org/skill-name@v1.0.0.
func ParseSkillRef ¶
ParseSkillRef parses "@org/name[@version]" into a SkillRef.
type SkillSelector ¶
type SkillSelector interface {
// Select returns the names of skills that should appear in the Phase 1 index.
// The query is typically the latest user message or conversation context.
// Available contains all skills that passed directory filtering for the current state.
Select(ctx context.Context, query string, available []SkillMetadata) ([]string, error)
}
SkillSelector determines which skills from the available set should be presented to the model in the Phase 1 index. Implementations can filter, rank, or transform the available skill list.
type SkillSource ¶
type SkillSource struct {
// For directory-based skills
Dir string `yaml:"dir,omitempty" json:"dir,omitempty"`
Path string `yaml:"path,omitempty" json:"path,omitempty"` // schema alias for dir
// For inline skills
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty"`
Instructions string `yaml:"instructions,omitempty" json:"instructions,omitempty"`
// Options
Preload bool `yaml:"preload,omitempty" json:"preload,omitempty"`
}
SkillSource represents a skill reference from the pack YAML.
func (*SkillSource) EffectiveDir ¶
func (s *SkillSource) EffectiveDir() string
EffectiveDir returns the directory path, preferring Dir over Path.
type TagSelector ¶
type TagSelector struct {
// contains filtered or unexported fields
}
TagSelector pre-filters skills based on metadata tags. Skills whose Metadata map contains a "tags" key with a comma-separated list are matched against the selector's required tags. A skill is included if it has at least one tag in common with the selector's required tags. If a skill has no "tags" metadata key, it is excluded. Safe for concurrent use.
func NewTagSelector ¶
func NewTagSelector(tags []string) *TagSelector
NewTagSelector creates a TagSelector that matches skills having at least one of the specified tags. Duplicate tags are deduplicated automatically.
func (*TagSelector) Select ¶
func (s *TagSelector) Select( _ context.Context, _ string, available []SkillMetadata, ) ([]string, error)
Select returns the names of skills whose metadata["tags"] contains at least one tag matching the selector's required tags.
type ToolExecutor ¶
type ToolExecutor struct {
// contains filtered or unexported fields
}
ToolExecutor handles execution of skill__ tools by delegating to the Executor.
func NewToolExecutor ¶
func NewToolExecutor(exec *Executor) *ToolExecutor
NewToolExecutor creates a new ToolExecutor wrapping the given skills Executor.
func (*ToolExecutor) Execute ¶
func (e *ToolExecutor) Execute( _ context.Context, tool *tools.ToolDescriptor, args json.RawMessage, ) (json.RawMessage, error)
Execute dispatches a skill tool call to the appropriate executor method.
func (*ToolExecutor) Name ¶
func (e *ToolExecutor) Name() string
Name returns the executor name used for mode matching.