skills

package
v0.6.6 Latest Latest
Warning

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

Go to latest
Published: Aug 6, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package skills loads file-backed skills and exposes them to a coding agent.

A skill is a directory named after the skill, containing a SKILL.md file with YAML frontmatter (name and description) and a Markdown body. Only the name and description enter the model's context up front; the body is injected on demand when the model calls the skill tool (see Registry.Tool). This keeps the initial context small while letting the model pull full instructions for the task at hand.

Skills are discovered from two roots: a user root that applies everywhere and a project root scoped to one workspace. A project skill overrides a user skill of the same name. Loading is decoupled from the agent: callers resolve the two roots and pass them to Load, then hand the resulting skills to the session.

Index

Constants

View Source
const ToolName = "skill"

ToolName is the advertised name of the skill-loading tool.

Variables

This section is empty.

Functions

func Expand

func Expand(content, skillDir, arguments string) string

Expand substitutes placeholders in a skill body:

  • $ARGUMENTS and $@ expand to the full argument string.
  • $1..$N expand to whitespace-separated fields of the argument string.
  • ${OR_SKILL_DIR} expands to skillDir.

A positional placeholder with no matching field expands to the empty string.

func IsExplicitInvocationText

func IsExplicitInvocationText(text string) bool

IsExplicitInvocationText reports whether a text block was generated by ExpandExplicitInvocation. UI/history projections omit these blocks.

func Load

func Load(opts LoadOptions) (*Registry, []Diagnostic)

Load discovers skills under the configured roots and returns a Registry. Project skills override user skills of the same name. Malformed or misnamed skills are skipped and reported as diagnostics rather than failing the load, so one bad skill does not hide the rest.

func LoadFor

func LoadFor(workspace string) (*Registry, []Diagnostic)

LoadFor discovers the skills visible to one workspace, using Roots. Diagnostics are returned for a caller that surfaces them; an agent that only needs the usable skills can ignore them.

func Roots

func Roots(workspace string) (userDir, projectDir string)

Roots returns the two roots skills are discovered from: the user-level root that applies everywhere, and the workspace root that overrides it. Either is empty when it does not apply — no home directory, or no workspace given — which Load treats as "skip that root".

The convention lives here, with the loader that consumes it, so an agent assembling its skills and a UI listing them can never disagree about where skills come from.

Types

type Delta

type Delta struct {
	Added   []Skill
	Updated []Skill
	Removed []string
}

Delta describes the semantic change between two resolved registries. Added and Updated retain full Skill values so the caller can advertise their current discovery metadata. Removed contains stable names.

func Diff

func Diff(before, after *Registry) Delta

Diff compares immutable registry snapshots in stable name order.

func (Delta) Empty

func (d Delta) Empty() bool

type Diagnostic

type Diagnostic struct {
	// Path is the SKILL.md (or directory) the problem concerns.
	Path string
	// Message explains why the skill was skipped.
	Message string
}

Diagnostic reports a skill that could not be loaded, so the caller can surface the problem without failing the whole load.

type DynamicRegistry

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

DynamicRegistry exposes one stable skill tool while atomically replacing the immutable Registry snapshot consulted by tool calls. Provider-visible tool definitions therefore stay byte-stable across skill additions, updates, and removals.

func NewDynamicRegistry

func NewDynamicRegistry(initial *Registry) *DynamicRegistry

func (*DynamicRegistry) List

func (d *DynamicRegistry) List() []Skill

func (*DynamicRegistry) Lookup

func (d *DynamicRegistry) Lookup(name string) (Skill, bool)

func (*DynamicRegistry) ModelList

func (d *DynamicRegistry) ModelList() []Skill

func (*DynamicRegistry) ModelLookup

func (d *DynamicRegistry) ModelLookup(name string) (Skill, bool)

func (*DynamicRegistry) Replace

func (d *DynamicRegistry) Replace(next *Registry)

Replace atomically publishes next. A nil registry means an empty snapshot.

func (*DynamicRegistry) Snapshot

func (d *DynamicRegistry) Snapshot() *Registry

Snapshot returns the current immutable registry.

func (*DynamicRegistry) Tool

func (d *DynamicRegistry) Tool() agent.AgentTool

Tool returns a stable tool whose execution reads the registry snapshot that is current at call time.

type LoadOptions

type LoadOptions struct {
	// UserDir is the user-level skills root, applied to every workspace.
	UserDir string
	// ProjectDir is the workspace-scoped skills root. A skill here overrides a
	// user skill of the same name.
	ProjectDir string
}

LoadOptions names the two roots skills are discovered from. Either may be empty to skip that root. Both should be absolute paths to a skills directory, e.g. ~/.or/skills and <workspace>/.or/skills.

type Registry

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

Registry is an immutable, name-indexed set of loaded skills. It is built by Load and read concurrently; it is never mutated after construction.

func NewRegistry

func NewRegistry(skills []Skill) *Registry

NewRegistry builds a Registry from an explicit set of skills, for callers that assemble or filter skills themselves rather than loading from disk. On a name collision the last skill wins.

func (*Registry) DisplayExplicitInvocation added in v0.6.4

func (r *Registry) DisplayExplicitInvocation(text string) string

DisplayExplicitInvocation converts an explicit invocation into a durable Markdown reference to its SKILL.md file. The UI can render the reference as a rich token while copying it remains useful plain text.

func (*Registry) ExpandExplicitInvocation

func (r *Registry) ExpandExplicitInvocation(text string) (expanded string, matched bool, err error)

ExpandExplicitInvocation recognizes a leading /skill:name command and resolves it against the complete registry, including manual-only skills. The returned block is product-generated context intended to follow the original user text in the same message.

func (*Registry) Len

func (r *Registry) Len() int

Len reports how many skills are registered.

func (*Registry) List

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

List returns the skills in stable name order.

func (*Registry) Lookup

func (r *Registry) Lookup(name string) (Skill, bool)

Lookup returns the skill registered under name.

func (*Registry) ModelList

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

ModelList returns only skills the model may discover and invoke.

func (*Registry) ModelLookup

func (r *Registry) ModelLookup(name string) (Skill, bool)

ModelLookup returns a skill only when model invocation is allowed.

func (*Registry) ModelRegistry

func (r *Registry) ModelRegistry() *Registry

ModelRegistry returns an immutable registry containing only model-invocable skills. It is primarily useful when computing model-visible deltas.

func (*Registry) ModelRevision

func (r *Registry) ModelRevision() string

ModelRevision fingerprints only the skills visible to the model. Changes to manual-only skills do not create a model-context update.

func (*Registry) Revision

func (r *Registry) Revision() string

Revision fingerprints the complete resolved registry, including skill bodies and source paths. A body-only edit therefore advances the revision even when its model-visible name and description do not change.

func (*Registry) Tool

func (r *Registry) Tool() agent.AgentTool

Tool returns the agent tool that loads a skill's body on demand. The returned tool only reads registered skills; it makes no workspace changes, so callers should advertise it as read-only. On an unknown name it returns an error naming the valid skills, so the model corrects rather than guesses.

type Skill

type Skill struct {
	// Name is the stable identifier, equal to the skill's directory name. It is
	// used for lookup and in the model-visible listing.
	Name string
	// Description is the model-visible note on when to use the skill. Required.
	Description string
	// DisableModelInvocation keeps the skill out of the model-visible listing
	// and prevents the skill tool from loading it. The product may still list
	// and explicitly invoke the skill on behalf of the user.
	DisableModelInvocation bool
	// Content is the SKILL.md body, injected verbatim (after placeholder
	// expansion) when the skill is invoked. It is not part of the initial context.
	Content string
	// Dir is the absolute path to the skill's directory, exposed to Content via
	// the ${OR_SKILL_DIR} placeholder so bundled scripts and references resolve.
	Dir string
	// Path is the absolute path to the SKILL.md file, for diagnostics.
	Path string
	// Source records which root the skill came from.
	Source Source
}

Skill is one loaded skill: the metadata advertised to the model plus the body injected when the skill is invoked.

type Source

type Source string

Source identifies where a skill was loaded from.

const (
	// SourceUser is the user-level root that applies to every workspace.
	SourceUser Source = "user"
	// SourceProject is the workspace-scoped root, which overrides user skills of
	// the same name.
	SourceProject Source = "project"
)

Jump to

Keyboard shortcuts

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