skills

package
v1.3.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 4, 2026 License: Apache-2.0 Imports: 16 Imported by: 4

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

View Source
const (
	SkillActivateTool     = "skill__activate"
	SkillDeactivateTool   = "skill__deactivate"
	SkillReadResourceTool = "skill__read_resource"
	SkillNamespace        = "skill"
	SkillExecutorName     = "skill"
)

Tool name constants for the skill__ namespace.

Variables

View Source
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

func DefaultSkillsProjectDir() (string, error)

DefaultSkillsProjectDir returns the project-level skills directory.

func DefaultSkillsUserDir

func DefaultSkillsUserDir() (string, error)

DefaultSkillsUserDir returns the XDG-compliant user-level skills directory.

func IsLocalPath

func IsLocalPath(arg string) bool

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

func (e *Executor) Activate(name string) (instructions string, addedTools []string, retErr error)

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

func (e *Executor) ActiveSkills() []string

ActiveSkills returns the names of currently active skills, sorted.

func (*Executor) ActiveTools

func (e *Executor) ActiveTools() []string

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

func (e *Executor) Deactivate(name string) (removedTools []string, retErr error)

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

func (e *Executor) ReadResource(skillName, path string) ([]byte, error)

ReadResource reads a file from within a skill's directory. Delegates to the underlying registry.

func (*Executor) SkillIndex

func (e *Executor) SkillIndex(skillsDir string) string

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

func NewInstaller() (*Installer, error)

NewInstaller creates an Installer with default XDG-compliant paths.

func (*Installer) Install

func (inst *Installer) Install(ref SkillRef, projectLevel bool) (string, error)

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

func (inst *Installer) InstallInto(ref SkillRef, targetDir string) (string, error)

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

func (inst *Installer) InstallLocal(srcPath string, projectLevel bool) (string, error)

InstallLocal copies a skill from a local path into the appropriate directory. Returns the installation path.

func (*Installer) InstallLocalInto

func (inst *Installer) InstallLocalInto(srcPath, targetDir string) (string, error)

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.

func (*Installer) Remove

func (inst *Installer) Remove(ref SkillRef) error

Remove removes an installed skill. It checks project-level first, then user-level.

func (*Installer) Resolve

func (inst *Installer) Resolve(ref SkillRef) (string, error)

Resolve finds the installation path for a skill reference. Checks project-level first, then user-level.

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 NewRegistry

func NewRegistry() *Registry

NewRegistry creates a new empty skill registry.

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) Has

func (r *Registry) Has(name string) bool

Has returns true if a skill with the given name is registered.

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

func (r *Registry) Load(name string) (*Skill, error)

Load returns the full skill by name, reading instructions from disk on demand.

func (*Registry) PreloadedSkills

func (r *Registry) PreloadedSkills() []*Skill

PreloadedSkills returns fully loaded skills marked with preload: true.

func (*Registry) ReadResource

func (r *Registry) ReadResource(name, resourcePath string) ([]byte, error)

ReadResource reads a file from within a skill's directory. Returns error if the path escapes the skill directory (path traversal prevention).

func (*Registry) ResolveRef

func (r *Registry) ResolveRef(ref SkillRef) (string, error)

ResolveRef resolves an @org/name skill reference to its installed filesystem path. It delegates to the Installer's Resolve method which checks project-level first, then user-level directories.

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

func ParseSkillFile(path string) (*Skill, error)

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

func ParseSkillRef(s string) (SkillRef, error)

ParseSkillRef parses "@org/name[@version]" into a SkillRef.

func (SkillRef) FullName

func (r SkillRef) FullName() string

FullName returns "org/skill-name".

func (SkillRef) GitURL

func (r SkillRef) GitURL() string

GitURL returns the GitHub clone URL.

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

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL