skills

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 26, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package skills loads skill packages from .baifo/skills/{slug}/SKILL.md.

Same model as Magec's decision #29: SKILL.md is markdown with a YAML frontmatter that declares at least `name` and `description`. The optional subdirectories references/, assets/ and scripts/ are exposed to the agent through the skill toolset's filesystem whitelist (built by the agent layer, not here).

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidSkillName    = adkskill.ErrInvalidSkillName
	ErrInvalidFrontmatter  = adkskill.ErrInvalidFrontmatter
	ErrSkillNotFound       = adkskill.ErrSkillNotFound
	ErrDuplicateSkill      = adkskill.ErrDuplicateSkill
	ErrInvalidResourcePath = adkskill.ErrInvalidResourcePath
	ErrResourceNotFound    = adkskill.ErrResourceNotFound
)

Forward sentinel errors from ADK so callers can use errors.Is against them without importing the ADK package directly.

View Source
var ErrNotFound = errors.New("skill not found")

ErrNotFound is returned when a skill slug does not exist on disk.

Functions

func IsADKNotFound

func IsADKNotFound(err error) bool

IsADKNotFound reports whether err signals a missing skill on the ADK side. Useful for the Facade which has its own ErrNotFound but needs to bridge both.

func Scaffold

func Scaffold(suggestedName string) string

Scaffold returns the SKILL.md content baifo drops into the editor for /skill add. The body is short on purpose: enough to remind the user where to put what, no padding. Validation is the same one ADK applies on save, so the scaffold is guaranteed to pass through untouched if the user just types Ctrl+S.

func ValidateSkillMD

func ValidateSkillMD(content []byte) []error

ValidateSkillMD parses content as a SKILL.md document and returns the validation errors gathered by ADK. Returns an empty slice on success. The editor uses this as its Ctrl+S validator so users see schema errors before the file ever touches disk.

Types

type Loader

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

Loader reads skills on demand from a base directory. There is no caching layer: every Load and List call goes to disk. This matches the spec in ARCHITECTURE.md and keeps hot-reload trivial — edit a SKILL.md and the next agent build picks the change up.

func NewLoader

func NewLoader(configDir string) *Loader

NewLoader returns a Loader rooted at <configDir>/skills. The directory does not need to exist yet; it is created lazily when a skill is installed.

func (*Loader) DeleteSkill

func (l *Loader) DeleteSkill(name string) error

DeleteSkill removes <skillsDir>/<name> recursively. Refuses to touch anything outside skillsDir so a maliciously-named slug cannot escape the sandbox. Returns ErrNotFound when the directory is absent.

func (*Loader) Dir

func (l *Loader) Dir() string

Dir returns the absolute path of the skills directory.

func (*Loader) FrontmatterOf

func (l *Loader) FrontmatterOf(ctx context.Context, name string) (*adkskill.Frontmatter, error)

FrontmatterOf reads the named skill's SKILL.md and returns the parsed ADK frontmatter struct. Returns an error wrapping skill.ErrSkillNotFound when the directory or its SKILL.md is missing. Used by the Facade methods that surface skill metadata to the TUI (Settings overlay, /skill list rich rendering).

func (*Loader) List

func (l *Loader) List() ([]string, error)

List enumerates the slugs of every skill package under the loader's directory. The result is sorted lexicographically. Missing directory returns an empty slice and no error so callers do not need to special-case fresh installations.

func (*Loader) Load

func (l *Loader) Load(slug string) (*Skill, error)

Load reads and parses the skill named slug. Returns ErrNotFound when the slug does not exist or has no SKILL.md.

func (*Loader) LoadAll

func (l *Loader) LoadAll() ([]*Skill, error)

LoadAll loads every skill found by List. Useful for the /skills tab. Errors on individual skills are returned as a multi-line error.

func (*Loader) LoadResourceCloser

func (l *Loader) LoadResourceCloser(ctx context.Context, name, resourcePath string) (io.ReadCloser, error)

LoadResourceCloser is a tiny convenience for callers (notably the future "show resource" path in the TUI) that need to read a file inside a skill via the Source interface.

func (*Loader) ReadSkillMD

func (l *Loader) ReadSkillMD(name string) ([]byte, error)

ReadSkillMD returns the raw bytes of <skillsDir>/<name>/SKILL.md. Used by the Facade to seed the embedded editor with the on-disk content, comments and whitespace included. Returns os.IsNotExist for absent files so callers can render their own error message.

func (*Loader) Source

func (l *Loader) Source() (adkskill.Source, error)

Source returns the ADK skill.Source bound to the loader's skills directory. Created lazily on the first call; the underlying implementation is the fs.FS-backed variant ADK ships, which gives us conformance with the agentskills.io spec for free (frontmatter validation, name rules, etc).

The Source is the thing baifo hands to skilltoolset.New so the root agent can list, load and read skill resources at runtime. Callers that only need to enumerate slugs from the TUI keep using Loader.List for backwards compatibility.

Note: the directory may not exist yet on a fresh install. We create it lazily here so the Source's fs.FS has something to walk.

func (*Loader) WriteSkillMD

func (l *Loader) WriteSkillMD(name string, content []byte) error

WriteSkillMD writes content to <skillsDir>/<name>/SKILL.md, creating the directory if needed. Atomic via tmp + rename to avoid leaving a half-written file on a crash. Callers are expected to have validated content via skill.ParseBytes first.

type Skill

type Skill struct {
	// Slug is the directory name under .baifo/skills/, used as the
	// canonical identifier (kebab-case).
	Slug string

	// Name is the human-readable name from the frontmatter. Required.
	Name string

	// Description is the natural-language description from the
	// frontmatter, used as input to the LLM when deciding whether to
	// activate the skill. Required.
	Description string

	// Extra holds any frontmatter key that is not Name or Description.
	// Values are preserved verbatim so future loaders can opt in to
	// fields like version, author, tags, etc. without forcing a schema
	// migration here.
	Extra map[string]string

	// Body is the markdown content of SKILL.md, with the frontmatter
	// block stripped. Loaded fresh from disk on every call to Load.
	Body string

	// Root is the absolute path of the skill directory. Tools and
	// helpers that need to resolve references/, assets/ or scripts/
	// should use this as their base.
	Root string
}

Skill is the in-memory representation of a SKILL.md package.

Directories

Path Synopsis
Package installer downloads and extracts skill packages distributed as .zip or .tar.gz archives.
Package installer downloads and extracts skill packages distributed as .zip or .tar.gz archives.

Jump to

Keyboard shortcuts

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