skills

package
v0.85.1 Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package skills provides skill loading, parsing, and system prompt composition.

Skills are markdown instruction files with optional YAML frontmatter that provide domain-specific context, instructions, and workflows to the agent. They follow the cross-client agentskills.io discovery convention plus a Kit-native location:

~/.agents/skills/               user-level cross-client skills
~/.config/kit/skills/           user-level Kit skills ($XDG_CONFIG_HOME aware)
<project>/.agents/skills/       project-local cross-client skills
<project>/.kit/skills/          project-local Kit skills

Skills can be single .md/.txt files or subdirectories containing a SKILL.md file. Project-level skills take precedence over user-level skills when two skills share the same name.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatForPrompt

func FormatForPrompt(skills []*Skill) string

FormatForPrompt formats skills as metadata-only XML for inclusion in a system prompt. Only the name, description, and file location are included; the agent reads the full skill file on demand using the read tool. Skill fields are XML-escaped so that descriptions containing <, >, & or quotes produce valid markup. Skills with DisableModelInvocation set are omitted from the catalog (they remain available via the /skill: slash command).

func FormatResources added in v0.80.0

func FormatResources(resources []string) string

FormatResources renders a skill's bundled resources as a <skill_resources> block, or returns the empty string when the skill bundles no resources. It is used when a skill is explicitly activated so the model knows which files it can read without enumerating them itself.

Types

type Diagnostic added in v0.80.0

type Diagnostic struct {
	// Severity is "error" or "warning".
	Severity string `json:"severity"`
	// Field names the frontmatter field the diagnostic relates to, if any.
	Field string `json:"field,omitempty"`
	// Message is a human-readable description of the problem.
	Message string `json:"message"`
}

Diagnostic describes a validation problem with a skill. Severity is either "error" (the skill cannot be used) or "warning" (the skill is usable but non-compliant).

type PromptBuilder

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

PromptBuilder composes a system prompt from a base prompt, skills, and arbitrary named sections.

func NewPromptBuilder

func NewPromptBuilder(basePrompt string) *PromptBuilder

NewPromptBuilder creates a PromptBuilder with the given base system prompt. The base prompt is always emitted first.

func (*PromptBuilder) Build

func (pb *PromptBuilder) Build() string

Build assembles the final system prompt. The base prompt comes first, followed by each section separated by double newlines.

func (*PromptBuilder) WithSection

func (pb *PromptBuilder) WithSection(name, content string) *PromptBuilder

WithSection appends a named section. Duplicate names are allowed (both will appear). Returns the builder for chaining.

func (*PromptBuilder) WithSkills

func (pb *PromptBuilder) WithSkills(skills []*Skill) *PromptBuilder

WithSkills appends a formatted skills section. If skills is empty, no section is added. The section has no header because FormatForPrompt includes its own preamble text. Returns the builder for chaining.

type PromptTemplate

type PromptTemplate struct {
	// Name is the human-readable identifier for this template.
	Name string
	// Content is the raw template text with {{variable}} placeholders.
	Content string
	// Variables lists the placeholder names discovered in Content.
	Variables []string
}

PromptTemplate is a named text template with {{variable}} placeholders.

func LoadPromptTemplate

func LoadPromptTemplate(path string) (*PromptTemplate, error)

LoadPromptTemplate reads a template from a file. The template name is derived from the filename (without extension).

func NewPromptTemplate

func NewPromptTemplate(name, content string) *PromptTemplate

NewPromptTemplate creates a PromptTemplate, automatically extracting variable names from {{...}} placeholders in content.

func (*PromptTemplate) Expand

func (t *PromptTemplate) Expand(values map[string]string) string

Expand replaces all {{variable}} placeholders with values from the provided map. Missing variables are left as-is (no error).

func (*PromptTemplate) ExpandStrict

func (t *PromptTemplate) ExpandStrict(values map[string]string) (string, error)

ExpandStrict replaces all {{variable}} placeholders and returns an error if any variable in the template has no corresponding value.

type Skill

type Skill struct {
	// Name is the human-readable identifier for this skill. Required.
	Name string `yaml:"name" json:"name"`
	// Description summarises what this skill provides and when to use it.
	// Required by the spec — it is the sole basis on which the model decides
	// whether a skill is relevant, so a skill without one is omitted from the
	// catalog.
	Description string `yaml:"description" json:"description"`
	// Content is the full markdown body (after frontmatter).
	Content string `yaml:"-" json:"content"`
	// Path is the absolute filesystem path the skill was loaded from.
	Path string `yaml:"-" json:"path"`

	// License is an optional SPDX license identifier (spec field).
	License string `yaml:"license,omitempty" json:"license,omitempty"`
	// Compatibility is an optional free-form note describing the environments
	// or clients the skill targets (spec field). The model can use it to adapt
	// execution.
	Compatibility string `yaml:"compatibility,omitempty" json:"compatibility,omitempty"`
	// Metadata is an optional bag of arbitrary string key/value pairs (spec
	// field) for client-specific annotations.
	Metadata map[string]string `yaml:"metadata,omitempty" json:"metadata,omitempty"`
	// AllowedTools optionally restricts which tools the skill may use. This is
	// an experimental spec field carried for portability; Kit does not yet
	// enforce it.
	AllowedTools string `yaml:"allowed-tools,omitempty" json:"allowed_tools,omitempty"`
	// DisableModelInvocation, when true, hides the skill from the
	// model-facing catalog (spec field). The skill can still be activated
	// explicitly via the /skill: slash command.
	DisableModelInvocation bool `yaml:"disable-model-invocation,omitempty" json:"disable_model_invocation,omitempty"`

	// Tags are optional labels for categorisation. Kit extension.
	Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`
	// When controls automatic inclusion: "always", "on-demand", or a
	// file-glob like "file:*.go". Empty defaults to "on-demand". Kit extension.
	When string `yaml:"when,omitempty" json:"when,omitempty"`
	// contains filtered or unexported fields
}

Skill represents a markdown-based instruction file that provides domain-specific context and workflows to the agent.

The Name and Description fields are required by the agentskills.io specification. License, Compatibility, Metadata, and AllowedTools are optional spec fields. Tags and When are Kit-specific extensions that other clients ignore.

func Combine added in v0.80.0

func Combine(user, project []*Skill) []*Skill

Combine validates and deduplicates the union of user-level and project-level skills. Skills missing a required description are skipped with a logged warning; when two skills share a Name the project-level one wins (also logged). User skills are considered before project skills so first-seen ordering is stable.

func LoadProjectSkills added in v0.80.0

func LoadProjectSkills(cwd string) []*Skill

LoadProjectSkills discovers skills from the project-local scopes only:

  1. <cwd>/.agents/skills/ (cross-client convention)
  2. <cwd>/.kit/skills/ (Kit-specific)

Because project-local skills are injected into the system prompt, callers may wish to gate this on a trust check before including the result. The returned skills are not yet validated or deduplicated; pass them through Combine.

func LoadSkill

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

LoadSkill reads a single skill file (markdown with optional YAML frontmatter). If no frontmatter is present the skill name is derived from the filename.

func LoadSkills

func LoadSkills(cwd string) ([]*Skill, error)

LoadSkills auto-discovers skills from the standard agentskills.io scopes:

  1. User-level: ~/.agents/skills/ (cross-client convention)
  2. User-level: $XDG_CONFIG_HOME/kit/skills/ (default ~/.config/kit/skills/)
  3. Project-local: <cwd>/.agents/skills/ (cross-client convention)
  4. Project-local: <cwd>/.kit/skills/ (Kit-specific)

When two skills share the same Name, the project-level skill takes precedence over a user-level one and a warning is logged. cwd is the working directory for project-local discovery; if empty the current working directory is used.

func LoadSkillsFromDir

func LoadSkillsFromDir(dir string) ([]*Skill, error)

LoadSkillsFromDir loads all skills from a single directory. It looks for:

  • *.md and *.txt files directly in dir
  • SKILL.md (case-insensitive) in immediate subdirectories

Files that fail to parse are skipped with a warning logged via the returned error list.

func LoadSkillsFromFS added in v0.80.0

func LoadSkillsFromFS(fsys fs.FS, root string) ([]*Skill, error)

LoadSkillsFromFS is the fs.FS-typed counterpart of LoadSkillsFromDir. It walks fsys starting at root (which may be "." or a subdirectory), finds *.md and *.txt files plus SKILL.md files in subdirectories, parses YAML frontmatter + markdown body, and returns the loaded skills.

Because fs.FS has no notion of an absolute on-disk path, each loaded skill's Path is set to its slash-separated path within fsys. Files that fail to parse are skipped and reported via the returned error.

func LoadUserSkills added in v0.80.0

func LoadUserSkills() []*Skill

LoadUserSkills discovers skills from the user-level scopes only:

  1. ~/.agents/skills/ (cross-client convention)
  2. $XDG_CONFIG_HOME/kit/skills/ (default ~/.config/kit/skills/)

The returned skills are not yet validated or deduplicated; pass them through Combine together with project skills to produce the final catalog set.

func (*Skill) BaseDir added in v0.80.0

func (s *Skill) BaseDir() string

BaseDir returns the directory the skill was loaded from. Relative resources referenced by a skill (scripts/, references/, assets/) resolve against this directory.

func (*Skill) Resources added in v0.80.0

func (s *Skill) Resources() []string

Resources walks one level into the skill's scripts/, references/, and assets/ subdirectories and returns the relative paths of any files found (slash-separated, relative to BaseDir). The result is capped at 50 entries. It returns nil when the skill has no bundled resources or its Path is not a real on-disk file.

func (*Skill) Validate added in v0.80.0

func (s *Skill) Validate() []Diagnostic

Validate checks the skill against the agentskills.io specification and returns a list of diagnostics. An empty slice means the skill is fully compliant. A missing description is reported as an error because the spec makes it required for discovery.

Jump to

Keyboard shortcuts

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