skills

package
v0.0.310 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package skills provides Agent Skills integration for term-llm. Skills are portable, cross-tool instruction bundles using the SKILL.md format.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckAgentsMdForSkills

func CheckAgentsMdForSkills() bool

CheckAgentsMdForSkills checks if AGENTS.md contains skill system markup. If true, the caller should not inject <available_skills> to avoid duplication.

func CopySkill

func CopySkill(src *Skill, destDir, newName string) error

CopySkill copies a skill to a new location.

func CreateSkillDir

func CreateSkillDir(baseDir, name string) error

CreateSkillDir creates a skill directory with template files.

func EstimateTokens

func EstimateTokens(s string) int

EstimateTokens provides a rough token estimate (chars / 3.5). This is a placeholder until a proper tokenizer is added.

func GenerateActivationResponse

func GenerateActivationResponse(skill *Skill, prompt string) string

GenerateActivationResponse generates the tool response when a skill is activated.

func GenerateAvailableSkillsXML

func GenerateAvailableSkillsXML(skills []*Skill) string

GenerateAvailableSkillsXML generates the <available_skills> prompt injection. Returns empty string if no skills are available.

func GenerateSearchHint added in v0.0.163

func GenerateSearchHint(shown, total int) string

GenerateSearchHint returns a note to append to the system prompt when more skills are available than shown. This tells the model to use search_skills.

func GetLocalSkillsDir

func GetLocalSkillsDir() (string, error)

GetLocalSkillsDir returns the path for project-local skills.

func GetUserSkillsDir

func GetUserSkillsDir() (string, error)

GetUserSkillsDir returns the path for user-global skills.

func InjectGitHubProvenance added in v0.0.40

func InjectGitHubProvenance(content []byte, skill DiscoveredSkill) []byte

InjectGitHubProvenance adds GitHub-specific provenance metadata to SKILL.md content. It also updates the skill name to match the directory name for validation.

func IsSkillDir

func IsSkillDir(dir string) bool

IsSkillDir checks if a directory contains a SKILL.md file.

func ValidateName

func ValidateName(name string) error

ValidateName checks if a skill name is valid per the spec. Returns an error describing the issue, or nil if valid.

Types

type DiscoveredSkill added in v0.0.40

type DiscoveredSkill struct {
	Name        string        // Skill name (directory name)
	Path        string        // Full path in repo (e.g., "skills/remotion")
	Description string        // Description from SKILL.md if available
	FileCount   int           // Total file count including subdirectories
	RepoRef     GitHubRepoRef // Reference to the source repository
}

DiscoveredSkill represents a skill found in a GitHub repository.

func (*DiscoveredSkill) RawURL added in v0.0.40

func (skill *DiscoveredSkill) RawURL() string

RawURL returns the raw GitHub URL for a skill's SKILL.md file.

func (*DiscoveredSkill) RepoURL added in v0.0.40

func (skill *DiscoveredSkill) RepoURL() string

RepoURL returns the GitHub repository URL.

type GitHubClient added in v0.0.40

type GitHubClient struct {
	// contains filtered or unexported fields
}

GitHubClient handles GitHub API interactions for skill discovery and download.

func NewGitHubClient added in v0.0.40

func NewGitHubClient() *GitHubClient

NewGitHubClient creates a new GitHub client. It checks for GITHUB_TOKEN environment variable for authenticated requests.

func (*GitHubClient) DiscoverSkills added in v0.0.40

func (c *GitHubClient) DiscoverSkills(ctx context.Context, ref GitHubRepoRef) ([]DiscoveredSkill, error)

DiscoverSkills lists skill directories in a repository's skills folder.

func (*GitHubClient) DownloadSkillDir added in v0.0.40

func (c *GitHubClient) DownloadSkillDir(ctx context.Context, skill DiscoveredSkill, destDir string) error

DownloadSkillDir downloads an entire skill directory to the destination.

func (*GitHubClient) FetchSkillMD added in v0.0.40

func (c *GitHubClient) FetchSkillMD(ctx context.Context, skill DiscoveredSkill) ([]byte, error)

FetchSkillMD downloads and returns the SKILL.md content for a discovered skill.

func (*GitHubClient) HasToken added in v0.0.40

func (c *GitHubClient) HasToken() bool

HasToken returns whether the client has an API token configured.

type GitHubContent added in v0.0.40

type GitHubContent struct {
	Name        string `json:"name"`
	Path        string `json:"path"`
	Type        string `json:"type"` // "file" or "dir"
	Size        int    `json:"size"`
	DownloadURL string `json:"download_url"`
	URL         string `json:"url"` // API URL for this content
}

GitHubContent represents a file or directory from the GitHub Contents API.

type GitHubRepoRef added in v0.0.40

type GitHubRepoRef struct {
	Owner  string // Repository owner (user or org)
	Repo   string // Repository name
	Branch string // Branch name (default: "main", fallback: "master")
	Path   string // Path within repo to look for skills (default: "skills")
}

GitHubRepoRef represents a parsed GitHub repository reference.

func ParseRepoRef added in v0.0.40

func ParseRepoRef(ref string) (*GitHubRepoRef, error)

ParseRepoRef parses a GitHub repository reference string. Supported formats:

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry manages skill discovery and resolution.

func NewRegistry

func NewRegistry(cfg RegistryConfig) (*Registry, error)

NewRegistry creates a skill registry with the given configuration.

func (*Registry) Get

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

Get retrieves a skill by name, loading full content.

func (*Registry) HasAnySkill added in v0.0.218

func (r *Registry) HasAnySkill() (bool, error)

HasAnySkill returns true as soon as a valid skill is found in any search path. This avoids a full catalog scan during startup when callers only need to know whether the skills system should be enabled at all.

func (*Registry) IsAlwaysEnabled

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

IsAlwaysEnabled checks if a skill should always be included.

func (*Registry) IsNeverAuto

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

IsNeverAuto checks if a skill requires explicit activation.

func (*Registry) List

func (r *Registry) List() ([]*Skill, error)

List returns all available skills (metadata only). Each skill appears only once, with first-found taking precedence.

func (*Registry) ListAll

func (r *Registry) ListAll() ([]*Skill, error)

ListAll returns all skills from all paths without shadowing. Use this when you want to see every installed copy of a skill.

func (*Registry) ListBySource

func (r *Registry) ListBySource(source SkillSource) ([]*Skill, error)

ListBySource returns skills from a specific source.

func (*Registry) Reload

func (r *Registry) Reload() error

Reload clears the cache and rediscovers skills.

func (*Registry) Search added in v0.0.163

func (r *Registry) Search(query string, maxResults int) ([]*Skill, error)

Search finds skills matching a query string by fuzzy matching on name and description. Skills in the never_auto set are excluded since this is called by the model, not the user. Returns up to maxResults matches, sorted by relevance.

func (*Registry) ShadowCount

func (r *Registry) ShadowCount(name string) int

ShadowCount returns how many skills were shadowed by this name.

type RegistryConfig

type RegistryConfig struct {
	// AutoInvoke allows model-driven skill activation
	AutoInvoke bool

	// MetadataBudgetTokens limits skill metadata in system prompt
	MetadataBudgetTokens int

	// MaxVisibleSkills limits skills shown in system prompt metadata
	MaxVisibleSkills int

	// Ecosystem integration
	IncludeProjectSkills  bool // Discover from project-local paths
	IncludeEcosystemPaths bool // Include ~/.agents/skills, ~/.codex/skills, ~/.claude/skills, ~/.gemini/skills, .skills/

	// Skill lists
	AlwaysEnabled []string // Always include in metadata
	NeverAuto     []string // Must be explicit
}

RegistryConfig configures the skill registry.

func DefaultRegistryConfig

func DefaultRegistryConfig() RegistryConfig

DefaultRegistryConfig returns the default configuration.

type RemoteRegistryClient

type RemoteRegistryClient struct {
	// contains filtered or unexported fields
}

RemoteRegistryClient queries the SkillsMP API for skills.

func NewRemoteRegistryClient

func NewRemoteRegistryClient() *RemoteRegistryClient

NewRemoteRegistryClient creates a new SkillsMP registry client.

func NewRemoteRegistryClientWithKey

func NewRemoteRegistryClientWithKey(apiKey string) *RemoteRegistryClient

NewRemoteRegistryClientWithKey creates a client with an explicit API key.

func (*RemoteRegistryClient) AISearch

func (r *RemoteRegistryClient) AISearch(ctx context.Context, query string) (*RemoteSearchResult, error)

AISearch performs an AI-powered semantic search for skills.

func (*RemoteRegistryClient) DownloadSkill

func (r *RemoteRegistryClient) DownloadSkill(ctx context.Context, skill *RemoteSkill) ([]byte, error)

DownloadSkill downloads a skill's SKILL.md content from its raw URL.

func (*RemoteRegistryClient) FetchRawURL

func (r *RemoteRegistryClient) FetchRawURL(ctx context.Context, rawURL string) ([]byte, error)

FetchRawURL fetches content from a raw URL (for updates).

func (*RemoteRegistryClient) GetSkill

func (r *RemoteRegistryClient) GetSkill(ctx context.Context, name string) (*RemoteSkill, error)

GetSkill fetches details for a specific skill by name.

func (*RemoteRegistryClient) HasAPIKey

func (r *RemoteRegistryClient) HasAPIKey() bool

HasAPIKey returns whether an API key is configured.

func (*RemoteRegistryClient) Search

Search performs a keyword search for skills.

type RemoteSearchResult

type RemoteSearchResult struct {
	Success bool `json:"success"`
	Data    struct {
		Skills []RemoteSkill `json:"skills"`
		Total  int           `json:"total"`
		Page   int           `json:"page"`
	} `json:"data"`
	// Flattened for convenience
	Skills []RemoteSkill `json:"-"`
}

RemoteSearchResult contains the response from a skill search.

type RemoteSkill

type RemoteSkill struct {
	ID          string  `json:"id"`
	Name        string  `json:"name"`
	Description string  `json:"description"`
	Author      string  `json:"author"`
	Repository  string  `json:"githubUrl"` // GitHub URL
	Category    string  `json:"category"`
	Downloads   int     `json:"downloads"`
	Stars       int     `json:"stars"`
	URL         string  `json:"skillUrl"` // SkillsMP page URL
	RawURL      string  `json:"rawUrl"`   // Direct SKILL.md URL
	License     string  `json:"license"`
	UpdatedAt   float64 `json:"updatedAt"` // Unix timestamp
}

RemoteSkill represents a skill from the SkillsMP registry.

type Setup

type Setup struct {
	Registry    *Registry
	XML         string   // Pregenerated <available_skills> XML (populated lazily)
	Skills      []*Skill // Skills included in metadata (populated lazily)
	TotalSkills int      // Total auto-invocable skills discovered (populated lazily)
	HasOverflow bool     // True when more skills exist than are shown (populated lazily)
	// contains filtered or unexported fields
}

Setup holds the initialized skills system for a session.

func NewSetup

func NewSetup(cfg *config.SkillsConfig) (*Setup, error)

NewSetup initializes the skills system from config. Returns nil if skills are disabled or no skills are available.

func NewSetupWithOptions added in v0.0.237

func NewSetupWithOptions(cfg *config.SkillsConfig, opts SetupOptions) (*Setup, error)

NewSetupWithOptions initializes the skills system from config. Returns nil if skills are disabled or no skills are available.

func (*Setup) EnsurePromptMetadata added in v0.0.218

func (s *Setup) EnsurePromptMetadata() error

EnsurePromptMetadata loads and caches prompt-facing skill metadata on demand.

func (*Setup) HasSkillsXML

func (s *Setup) HasSkillsXML() bool

HasSkillsXML returns true if the setup has skill XML to inject.

func (*Setup) PromptMetadataSuppressed added in v0.0.237

func (s *Setup) PromptMetadataSuppressed() (suppressed bool, known bool)

PromptMetadataSuppressed reports whether the caller already supplies skill metadata and whether that decision came from a completed suppression check.

type SetupOptions added in v0.0.237

type SetupOptions struct {
	// PromptMetadataSuppressed means the caller already has <available_skills>
	// metadata from another source (for example AGENTS.md). In that case setup only
	// verifies that at least one skill exists so activate_skill/search_skills can be
	// registered, and skips the full prompt catalog preload.
	PromptMetadataSuppressed bool

	// PromptMetadataSuppressionKnown records whether PromptMetadataSuppressed came
	// from an actual check. It lets callers avoid repeating the same AGENTS.md read
	// before deciding whether to inject metadata.
	PromptMetadataSuppressionKnown bool
}

SetupOptions controls optional startup behavior for NewSetupWithOptions.

type Skill

type Skill struct {
	// Required fields
	Name        string `yaml:"name"`
	Description string `yaml:"description"`

	// Optional standard fields
	License       string            `yaml:"license,omitempty"`
	Compatibility string            `yaml:"compatibility,omitempty"`
	AllowedTools  []string          `yaml:"-"` // Parsed from allowed-tools
	Metadata      map[string]string `yaml:"metadata,omitempty"`

	// Tools declares script-backed tools that are registered when this skill is activated.
	Tools []SkillToolDef `yaml:"-"`

	// Extras stores vendor-specific/unknown frontmatter fields
	Extras map[string]any `yaml:"-"`

	// Body is the Markdown content after frontmatter
	Body string `yaml:"-"`

	// Resource discovery
	References []string `yaml:"-"` // Files in references/
	Scripts    []string `yaml:"-"` // Files in scripts/
	Assets     []string `yaml:"-"` // Files in assets/

	// Source tracking
	Source     SkillSource `yaml:"-"`
	SourcePath string      `yaml:"-"` // Directory path
	// contains filtered or unexported fields
}

Skill represents a skill loaded from a SKILL.md file.

func LoadFromDir

func LoadFromDir(dir string, source SkillSource, loadBody bool) (*Skill, error)

LoadFromDir loads a skill from a directory containing SKILL.md. If loadBody is false, only metadata is loaded (for discovery).

func ParseSkillMD

func ParseSkillMD(path string, loadBody bool) (*Skill, error)

ParseSkillMD parses a SKILL.md file and returns a Skill. The loadBody parameter controls whether to load the full Markdown body.

func ParseSkillMDContent

func ParseSkillMDContent(content string, loadBody bool) (*Skill, error)

ParseSkillMDContent parses SKILL.md content from a string.

func TruncateSkillsToTokenBudget

func TruncateSkillsToTokenBudget(skills []*Skill, alwaysEnabled []string, budgetTokens, maxSkills int) []*Skill

TruncateSkillsToTokenBudget returns skills that fit within the token budget. Always includes always_enabled skills, then fills with remaining skills.

func (*Skill) HasResources

func (s *Skill) HasResources() bool

HasResources returns true if the skill has bundled resources.

func (*Skill) HasTools added in v0.0.90

func (s *Skill) HasTools() bool

HasTools returns true if the skill declares any script-backed tools.

func (*Skill) IsLoaded

func (s *Skill) IsLoaded() bool

IsLoaded returns true if the skill body has been loaded.

func (*Skill) ResourceTree

func (s *Skill) ResourceTree() string

ResourceTree returns a formatted string of bundled resources.

func (*Skill) String

func (s *Skill) String() string

String returns a brief description of the skill.

func (*Skill) Validate

func (s *Skill) Validate() error

Validate checks that the skill meets the spec requirements.

type SkillSource

type SkillSource int

SkillSource indicates where a skill was loaded from.

const (
	SourceLocal   SkillSource = iota // Project-local (.skills/, .claude/skills/, etc.)
	SourceUser                       // User-global (~/.config/term-llm/skills/, etc.)
	SourceBuiltin                    // Embedded built-in
	SourceClaude                     // Claude Code ecosystem (~/.claude/skills/)
	SourceCodex                      // Codex ecosystem (~/.codex/skills/)
	SourceGemini                     // Gemini CLI ecosystem (~/.gemini/skills/)
	SourceCursor                     // Cursor ecosystem (~/.cursor/skills/)
)

func (SkillSource) SourceName

func (s SkillSource) SourceName() string

SourceName returns a human-readable name for the skill source.

type SkillToolDef added in v0.0.90

type SkillToolDef struct {
	// Name is the tool name shown to the LLM. Must match ^[a-z][a-z0-9_]*$
	Name string `yaml:"name"`

	// Description is the tool description passed to the LLM.
	Description string `yaml:"description"`

	// Script is the path to the script, relative to the skill directory.
	// Subdirectories are allowed (e.g. "scripts/travel-time.sh").
	Script string `yaml:"script"`

	// Input is a JSON Schema (type: object) for the tool's input parameters.
	// If omitted, the tool accepts no parameters.
	Input map[string]interface{} `yaml:"input,omitempty"`

	// TimeoutSeconds is the execution timeout. Default 30, max 300.
	TimeoutSeconds int `yaml:"timeout_seconds,omitempty"`

	// Env is a map of additional environment variables to set when running the script.
	Env map[string]string `yaml:"env,omitempty"`

	// Call controls how arguments are passed to the script.
	//   ""       / "args"       — named flags: --key value (default)
	//   "positional"            — positional args in schema property order
	//   "json"                  — JSON object on stdin
	Call string `yaml:"call,omitempty"`
}

SkillToolDef defines a script-backed tool declared in a skill's SKILL.md frontmatter. When the skill is activated, these tools are dynamically registered with the engine. Scripts are resolved relative to the skill directory (SourcePath).

Jump to

Keyboard shortcuts

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