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 ¶
- Variables
- func IsADKNotFound(err error) bool
- func Scaffold(suggestedName string) string
- func ValidateSkillMD(content []byte) []error
- type Loader
- func (l *Loader) DeleteSkill(name string) error
- func (l *Loader) Dir() string
- func (l *Loader) FrontmatterOf(ctx context.Context, name string) (*adkskill.Frontmatter, error)
- func (l *Loader) List() ([]string, error)
- func (l *Loader) Load(slug string) (*Skill, error)
- func (l *Loader) LoadAll() ([]*Skill, error)
- func (l *Loader) LoadResourceCloser(ctx context.Context, name, resourcePath string) (io.ReadCloser, error)
- func (l *Loader) ReadSkillMD(name string) ([]byte, error)
- func (l *Loader) Source() (adkskill.Source, error)
- func (l *Loader) WriteSkillMD(name string, content []byte) error
- type Skill
Constants ¶
This section is empty.
Variables ¶
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.
var ErrNotFound = errors.New("skill not found")
ErrNotFound is returned when a skill slug does not exist on disk.
Functions ¶
func IsADKNotFound ¶
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 ¶
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 ¶
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 ¶
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 ¶
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) FrontmatterOf ¶
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 ¶
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 ¶
Load reads and parses the skill named slug. Returns ErrNotFound when the slug does not exist or has no SKILL.md.
func (*Loader) LoadAll ¶
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 ¶
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 ¶
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 ¶
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.