skills

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package skills is the catalogue of agent skills that ship inside the seamark binary. It reads the embedded skills/ tree, parses the SKILL.md frontmatter, and owns the marker that tells the installer which directories seamark may refresh. init, doctor, and status all go through this package, so the marker rule exists once.

Index

Constants

View Source
const (
	ModeAuto   = "auto"
	ModeClaude = "claude"
	ModeCodex  = "codex"
	ModeAll    = "all"
)

Install modes for Targets. Auto is what a bare --skills means: Claude Code always, Codex only when the repository already has an .agents/ directory, which is the place Codex and other Agent Skills clients read. .codex/ is not consulted.

View Source
const (
	ClaudeDir = ".claude/skills"
	AgentsDir = ".agents/skills"
)

Client skill directories, repository-relative with forward slashes.

View Source
const (
	MarkerKey   = "seamark"
	MarkerValue = "managed"
)

Ownership marker. A SKILL.md whose metadata carries MarkerKey set to MarkerValue belongs to seamark: init refreshes such a directory and never touches any other. This mirrors how hooks are recognized by their argument tail, with the marker read from frontmatter instead.

View Source
const Root = "skills"

Root is the embedded directory that holds one subdirectory per skill.

View Source
const SkillFile = "SKILL.md"

SkillFile is the file every skill directory carries. Its YAML frontmatter is the skill's metadata; the Markdown body is the skill.

Variables

Modes lists the accepted install modes for help and error text.

Functions

func Apply

func Apply(w io.Writer, root string, entries []Entry, printOnly bool) error

Apply executes a plan with one narrated line per skill directory, in init's vocabulary: wrote, updated, kept, and the would- forms under preview. An absent directory gets every shipped file; a stale managed copy gets the shipped files rewritten and keeps any extra file the user added; current and foreign directories are left alone. A write failure returns with the path in the error, and a re-run completes the set because the plan is recomputed from disk.

func Details

func Details(states []ClientState) string

Details renders every client's Describe on one line, for example "claude 3/3 current · codex not installed". doctor prints it as the detail of its own verdict; Summary adds the corrective command.

func Files

func Files(name string) (map[string][]byte, error)

Files returns every file of one skill keyed by its path relative to the skill directory, for example "SKILL.md" and "references/interpreting-seamark.md". The map is unordered; a caller that writes the files sorts the keys for stable output.

func Install

func Install(w io.Writer, root string, targets []Target, printOnly bool) error

Install plans and applies in one call for callers that need no gap between the two, such as tests and doctor fixtures.

func IsManaged

func IsManaged(fm Frontmatter) bool

IsManaged reports whether the frontmatter carries the ownership marker.

func Names

func Names() ([]string, error)

Names lists the embedded skills in sorted order. A skill is a directory under Root that contains SkillFile; other entries, such as the tree's README, are not skills.

func Summary

func Summary(states []ClientState) string

Summary renders the one-line view init and status print. A stale or missing managed copy names the corrective command once at the end.

func SymlinkIn

func SymlinkIn(root, rel string) (string, error)

SymlinkIn walks rel down from root one component at a time and returns the first component that is a symbolic link, or "" when none is. The walk stops at the first missing component, because nothing below it exists yet. Every path seamark reads or writes under a client directory passes this check, so a link committed in a cloned repository can never redirect a refresh outside the tree.

Types

type ClientState

type ClientState struct {
	Client  string `json:"client"`
	Dir     string `json:"dir"`
	Current int    `json:"current"`
	Stale   int    `json:"stale"`
	Missing int    `json:"missing"`
	Foreign int    `json:"foreign"`
	Err     string `json:"error,omitempty"`
}

ClientState summarizes one client's skill directory for init, doctor, and status. Counts are over the shipped skills; Foreign counts directories that carry a shipped skill's name but not seamark's marker.

func Inspect

func Inspect(root string) []ClientState

Inspect reports both clients regardless of detection, so a stale copy in a directory auto would skip stays visible. A read error is recorded on the client instead of failing the call: status must never fail because one directory is unreadable.

func (ClientState) Describe

func (c ClientState) Describe() string

Describe renders one client in a few words, for example "claude 3/3 current, 1 stale" or "codex not installed". init, status, and doctor all print it, so the three never phrase a state differently.

func (ClientState) Installed

func (c ClientState) Installed() bool

Installed reports whether the client holds any managed skill.

func (ClientState) NeedsRefresh

func (c ClientState) NeedsRefresh() bool

NeedsRefresh reports whether a managed copy is stale or missing, the two states `seamark init --skills` repairs.

func (ClientState) Notable

func (c ClientState) Notable() bool

Notable reports whether the client is worth a line when nobody asked for skills: it holds managed skills, a directory seamark does not own, or an unreadable one. init and status print the summary only then, so a plain run never claims "not installed" over any of the three.

type Entry

type Entry struct {
	Name string
	// Rel is the repository-relative directory, slash-separated.
	Rel   string
	State State
	// Reason explains a Foreign classification; empty otherwise.
	Reason string
}

Entry is one skill directory in an install plan.

func Plan

func Plan(root string, targets []Target) ([]Entry, error)

Plan inspects every target skill directory before any write, so a directory that cannot be read aborts the install while the tree is still untouched. The same rule protects init's settings merge.

type Frontmatter

type Frontmatter struct {
	Name          string            `yaml:"name"`
	Description   string            `yaml:"description"`
	License       string            `yaml:"license"`
	Compatibility string            `yaml:"compatibility"`
	Metadata      map[string]string `yaml:"metadata"`
	AllowedTools  string            `yaml:"allowed-tools"`
}

Frontmatter is the YAML header of a SKILL.md. The fields are the Agent Skills core set plus allowed-tools. Unknown fields are ignored, so a user's own skill still parses when init inspects it for the marker.

func ParseFrontmatter

func ParseFrontmatter(skillMD []byte) (Frontmatter, string, error)

ParseFrontmatter splits a SKILL.md into its frontmatter and body. The file must open with a "---" line and close the header with another; the body is everything after the closing fence. YAML syntax errors are reported rather than loaded as an empty header, so a malformed shipped skill fails the tests instead of failing silently in a client.

type State

type State int

State classifies one skill directory on disk.

const (
	Absent  State = iota // nothing at the path
	Current              // managed and byte-equal to the shipped files
	Stale                // managed, but a shipped file differs or is missing
	Foreign              // present without seamark's marker
)

The four states Plan reports. Only Absent and Stale lead to a write. Foreign is never touched: the directory is the user's, not seamark's.

func (State) String

func (s State) String() string

String names a state for narration and test output.

type Target

type Target struct {
	// Client names the client in narration: "claude" or "codex".
	Client string
	// Dir is the repository-relative skill directory, slash-separated.
	Dir string
}

Target is one client skill directory an install addresses.

func Targets

func Targets(root, mode string) ([]Target, error)

Targets returns the client directories one install mode addresses.

Jump to

Keyboard shortcuts

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