Documentation
¶
Overview ¶
Package skills provides Agent Skills integration for term-llm. Skills are portable, cross-tool instruction bundles using the SKILL.md format.
Index ¶
- func CheckAgentsMdForSkills() bool
- func CopySkill(src *Skill, destDir, newName string) error
- func CreateSkillDir(baseDir, name string) error
- func EstimateTokens(s string) int
- func GenerateActivationResponse(skill *Skill, prompt string) string
- func GenerateAvailableSkillsXML(skills []*Skill) string
- func GenerateSearchHint(shown, total int) string
- func GetLocalSkillsDir() (string, error)
- func GetUserSkillsDir() (string, error)
- func InjectGitHubProvenance(content []byte, skill DiscoveredSkill) []byte
- func IsSkillDir(dir string) bool
- func ValidateName(name string) error
- type DiscoveredSkill
- type GitHubClient
- func (c *GitHubClient) DiscoverSkills(ctx context.Context, ref GitHubRepoRef) ([]DiscoveredSkill, error)
- func (c *GitHubClient) DownloadSkillDir(ctx context.Context, skill DiscoveredSkill, destDir string) error
- func (c *GitHubClient) FetchSkillMD(ctx context.Context, skill DiscoveredSkill) ([]byte, error)
- func (c *GitHubClient) HasToken() bool
- type GitHubContent
- type GitHubRepoRef
- type Registry
- func (r *Registry) Get(name string) (*Skill, error)
- func (r *Registry) HasAnySkill() (bool, error)
- func (r *Registry) IsAlwaysEnabled(name string) bool
- func (r *Registry) IsNeverAuto(name string) bool
- func (r *Registry) List() ([]*Skill, error)
- func (r *Registry) ListAll() ([]*Skill, error)
- func (r *Registry) ListBySource(source SkillSource) ([]*Skill, error)
- func (r *Registry) Reload() error
- func (r *Registry) Search(query string, maxResults int) ([]*Skill, error)
- func (r *Registry) ShadowCount(name string) int
- type RegistryConfig
- type RemoteRegistryClient
- func (r *RemoteRegistryClient) AISearch(ctx context.Context, query string) (*RemoteSearchResult, error)
- func (r *RemoteRegistryClient) DownloadSkill(ctx context.Context, skill *RemoteSkill) ([]byte, error)
- func (r *RemoteRegistryClient) FetchRawURL(ctx context.Context, rawURL string) ([]byte, error)
- func (r *RemoteRegistryClient) GetSkill(ctx context.Context, name string) (*RemoteSkill, error)
- func (r *RemoteRegistryClient) HasAPIKey() bool
- func (r *RemoteRegistryClient) Search(ctx context.Context, query string) (*RemoteSearchResult, error)
- type RemoteSearchResult
- type RemoteSkill
- type Setup
- type SetupOptions
- type Skill
- func LoadFromDir(dir string, source SkillSource, loadBody bool) (*Skill, error)
- func ParseSkillMD(path string, loadBody bool) (*Skill, error)
- func ParseSkillMDContent(content string, loadBody bool) (*Skill, error)
- func TruncateSkillsToTokenBudget(skills []*Skill, alwaysEnabled []string, budgetTokens, maxSkills int) []*Skill
- type SkillSource
- type SkillToolDef
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 CreateSkillDir ¶
CreateSkillDir creates a skill directory with template files.
func EstimateTokens ¶
EstimateTokens provides a rough token estimate (chars / 3.5). This is a placeholder until a proper tokenizer is added.
func GenerateActivationResponse ¶
GenerateActivationResponse generates the tool response when a skill is activated.
func GenerateAvailableSkillsXML ¶
GenerateAvailableSkillsXML generates the <available_skills> prompt injection. Returns empty string if no skills are available.
func GenerateSearchHint ¶ added in v0.0.163
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 ¶
GetLocalSkillsDir returns the path for project-local skills.
func GetUserSkillsDir ¶
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 ¶
IsSkillDir checks if a directory contains a SKILL.md file.
func ValidateName ¶
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:
- owner/repo
- owner/repo@branch
- https://github.com/owner/repo
- https://github.com/owner/repo/tree/branch
- https://github.com/owner/repo/tree/branch/path
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) HasAnySkill ¶ added in v0.0.218
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 ¶
IsAlwaysEnabled checks if a skill should always be included.
func (*Registry) IsNeverAuto ¶
IsNeverAuto checks if a skill requires explicit activation.
func (*Registry) List ¶
List returns all available skills (metadata only). Each skill appears only once, with first-found taking precedence.
func (*Registry) ListAll ¶
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) Search ¶ added in v0.0.163
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 ¶
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 ¶
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 ¶
func (r *RemoteRegistryClient) Search(ctx context.Context, query string) (*RemoteSearchResult, error)
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
EnsurePromptMetadata loads and caches prompt-facing skill metadata on demand.
func (*Setup) HasSkillsXML ¶
HasSkillsXML returns true if the setup has skill XML to inject.
func (*Setup) PromptMetadataSuppressed ¶ added in v0.0.237
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 ¶
ParseSkillMD parses a SKILL.md file and returns a Skill. The loadBody parameter controls whether to load the full Markdown body.
func ParseSkillMDContent ¶
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 ¶
HasResources returns true if the skill has bundled resources.
func (*Skill) HasTools ¶ added in v0.0.90
HasTools returns true if the skill declares any script-backed tools.
func (*Skill) ResourceTree ¶
ResourceTree returns a formatted string of bundled resources.
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).