Documentation
¶
Overview ¶
Package skills implements the Agent Skills open standard. See https://agentskills.io for the specification.
Index ¶
- Constants
- Variables
- func ApproxTokenCount(s string) int
- func DiscoverFromConfig(cfg DiscoveryConfig) (allSkills, activeSkills []*Skill, states []*SkillState)
- func DiscoverWithStates(paths []string) ([]*Skill, []*SkillState)
- func PublishStates(states []*SkillState)
- func SetLatestStates(states []*SkillState)
- func SubscribeEvents(ctx context.Context) <-chan pubsub.Event[Event]
- func ToPromptXML(skills []*Skill) string
- type CatalogEntry
- type DiscoveryConfig
- type DiscoveryState
- type Event
- type Manager
- func (m *Manager) ActiveSkills() []*Skill
- func (m *Manager) AllSkills() []*Skill
- func (m *Manager) PublishStates(states []*SkillState)
- func (m *Manager) ResolvedPaths() []string
- func (m *Manager) SetLatestStates(states []*SkillState)
- func (m *Manager) Shutdown()
- func (m *Manager) States() []*SkillState
- func (m *Manager) SubscribeEvents(ctx context.Context) <-chan pubsub.Event[Event]
- func (m *Manager) WorkingDir() string
- type ManagerOption
- type Skill
- type SkillReadResult
- type SkillState
- type SourceType
- type Tracker
Constants ¶
const ( SkillFileName = "SKILL.md" MaxNameLength = 64 MaxDescriptionLength = 1024 MaxCompatibilityLength = 500 )
Variables ¶
var ErrSkillNotFound = errors.New("skill not found")
ErrSkillNotFound is returned when a skill ID is not part of the effective visible skill set.
Functions ¶
func ApproxTokenCount ¶
ApproxTokenCount returns a rough estimate of how many tokens a string occupies when sent to an LLM. Uses the common ~4-chars-per-token heuristic that approximates GPT/Claude tokenizers well enough for diagnostic logging.
func DiscoverFromConfig ¶
func DiscoverFromConfig(cfg DiscoveryConfig) (allSkills, activeSkills []*Skill, states []*SkillState)
DiscoverFromConfig walks every path in cfg.Options.SkillsPaths (after home / env expansion), then dedups and filters by cfg.Options.DisabledSkills. It returns the three slices the rest of the system needs:
- allSkills: deduplicated, pre-filter (includes disabled).
- activeSkills: post-filter (DisabledSkills removed).
- states: per-file discovery outcome for diagnostics/UI.
func DiscoverWithStates ¶
func DiscoverWithStates(paths []string) ([]*Skill, []*SkillState)
DiscoverWithStates finds all valid skills in the given paths and also returns a per-file state slice describing parse/validation outcomes. Useful for diagnostics and UI reporting.
func PublishStates ¶
func PublishStates(states []*SkillState)
PublishStates publishes a skill discovery event with the given states.
func SetLatestStates ¶
func SetLatestStates(states []*SkillState)
SetLatestStates stores the given states in the package-level cache so that GetLatestStates can return them synchronously before the first pubsub event arrives.
func SubscribeEvents ¶
SubscribeEvents returns a channel that receives events when skill discovery state changes.
func ToPromptXML ¶
ToPromptXML generates XML for injection into the system prompt. Skills with DisableModelInvocation set to true are excluded.
Types ¶
type CatalogEntry ¶
type CatalogEntry struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Label string `json:"label"`
Source SourceType `json:"source"`
// Collection is the name of the enclosing skill repo (e.g. a cloned
// collection like "seshat-skills" or "paperasse") when the skill is
// nested under one. Empty for standalone skills placed directly under
// a registered skills path.
Collection string `json:"collection,omitempty"`
UserInvocable bool `json:"user_invocable"`
}
CatalogEntry describes an effective visible skill for frontend display.
func Catalog ¶
func Catalog(active []*Skill, skillPaths []string, workingDir string) []CatalogEntry
Catalog builds a slice of CatalogEntry values from pre-discovered skills. The skillPaths and workingDir parameters are used only for labelling (system / user / project); pass nil/empty when labels are not needed.
type DiscoveryConfig ¶
type DiscoveryConfig struct {
SkillsPaths []string
DisabledSkills []string
WorkingDir string
// Resolver expands $VAR-style references in paths. May be nil.
Resolver func(string) (string, error)
}
DiscoveryConfig contains the inputs DiscoverFromConfig needs. Using a dedicated struct (rather than importing internal/config) keeps the skills package's dependency graph small.
func (DiscoveryConfig) ResolvePaths ¶
func (c DiscoveryConfig) ResolvePaths() []string
ResolvePaths expands home-directory and $VAR references in SkillsPaths. This is the canonical path-resolution logic used by DiscoverFromConfig; callers that need the resolved list (e.g. for Catalog labels) can call this directly.
type DiscoveryState ¶
type DiscoveryState int
DiscoveryState represents the outcome of discovering a single skill file.
const ( // StateNormal indicates the skill was parsed and validated successfully. StateNormal DiscoveryState = iota // StateError indicates discovery encountered a scan/parse/validate error. StateError )
type Event ¶
type Event struct {
States []*SkillState
}
Event is published when skill discovery completes.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns per-workspace skill discovery state: the latest discovery snapshot, the full skill metadata (with Instructions) for the coordinator, and a pubsub broker for change events. There is exactly one Manager per workspace.
Package-level helpers (GetLatestStates, SetLatestStates, PublishStates, SubscribeEvents) are preserved for callers that share a process with the TUI. To bridge a Manager to those globals, construct it with WithGlobalMirror. Only do this when the process hosts a single workspace (local mode or a client process); the backend server hosts multiple workspaces concurrently and must not enable mirroring.
func NewManager ¶
func NewManager(allSkills, activeSkills []*Skill, states []*SkillState, opts ...ManagerOption) *Manager
NewManager constructs a workspace-scoped Manager with the given pre-computed discovery results. The slices are stored as-is; callers should not mutate them afterwards.
func (*Manager) ActiveSkills ¶
ActiveSkills returns the post-filter list of active skills (after removing disabled entries).
func (*Manager) PublishStates ¶
func (m *Manager) PublishStates(states []*SkillState)
PublishStates updates the manager's cached snapshot and publishes a discovery event to subscribers. Callers should not call SetLatestStates separately — PublishStates is the single mutation point, keeping Manager.States(), workspaceToProto, and (when WithGlobalMirror is set) skills.GetLatestStates consistent with what subscribers observe.
func (*Manager) ResolvedPaths ¶
ResolvedPaths returns the expanded skills directory paths stored at construction time.
func (*Manager) SetLatestStates ¶
func (m *Manager) SetLatestStates(states []*SkillState)
SetLatestStates updates the manager's cached discovery snapshot.
func (*Manager) States ¶
func (m *Manager) States() []*SkillState
States returns a clone of the latest discovery state snapshot.
func (*Manager) SubscribeEvents ¶
SubscribeEvents returns a channel of discovery events for the manager's workspace.
func (*Manager) WorkingDir ¶
WorkingDir returns the workspace working directory stored at construction time.
type ManagerOption ¶
type ManagerOption func(*Manager)
ManagerOption configures a Manager at construction time.
func WithGlobalMirror ¶
func WithGlobalMirror() ManagerOption
WithGlobalMirror causes the manager to forward SetLatestStates and PublishStates calls to the package-level cache and broker. Only safe when the process hosts at most one Manager (e.g. local mode or the client process).
func WithResolvedPaths ¶
func WithResolvedPaths(paths []string) ManagerOption
WithResolvedPaths stores the expanded skills directory paths that were used during discovery. Catalog and ReadContent use these for source labelling.
func WithWorkingDir ¶
func WithWorkingDir(dir string) ManagerOption
WithWorkingDir stores the workspace working directory. Catalog and ReadContent use it to distinguish project skills from user skills.
type Skill ¶
type Skill struct {
Name string `yaml:"name" json:"name"`
Description string `yaml:"description" json:"description"`
UserInvocable bool `yaml:"user-invocable" json:"user_invocable"`
DisableModelInvocation bool `yaml:"disable-model-invocation" json:"disable_model_invocation"`
License string `yaml:"license,omitempty" json:"license,omitempty"`
Compatibility string `yaml:"compatibility,omitempty" json:"compatibility,omitempty"`
Metadata map[string]string `yaml:"metadata,omitempty" json:"metadata,omitempty"`
Instructions string `yaml:"-" json:"instructions"`
Path string `yaml:"-" json:"path"`
SkillFilePath string `yaml:"-" json:"skill_file_path"`
Builtin bool `yaml:"-" json:"builtin"`
}
Skill represents a parsed SKILL.md file.
func Deduplicate ¶
Deduplicate removes duplicate skills by name. When duplicates exist, the last occurrence wins. This means user skills (appended after builtins) override builtin skills with the same name.
func FindEffective ¶
FindEffective returns the named skill from the given active skill set.
func ParseContent ¶
ParseContent parses a SKILL.md from raw bytes.
func (*Skill) FormatInvocation ¶
FormatInvocation generates XML for a skill when invoked as a user command.
type SkillReadResult ¶
type SkillReadResult struct {
Name string `json:"name"`
Description string `json:"description"`
Source SourceType `json:"source"`
Builtin bool `json:"builtin"`
}
SkillReadResult holds metadata about a skill returned alongside its content.
func ReadContent ¶
func ReadContent(active []*Skill, skillPaths []string, workingDir string, skillID string) ([]byte, SkillReadResult, error)
ReadContent reads the contents of a visible skill by ID and returns the raw bytes along with metadata about the skill.
type SkillState ¶
type SkillState struct {
Name string
Path string
State DiscoveryState
Err error
}
SkillState represents the latest discovery status of a skill file.
func DeduplicateStates ¶
func DeduplicateStates(all []*SkillState) []*SkillState
DeduplicateStates removes duplicate skill states by name. When duplicates exist, the last occurrence wins (consistent with Deduplicate for skills).
func GetLatestStates ¶
func GetLatestStates() []*SkillState
GetLatestStates returns the latest discovery states.
type SourceType ¶
type SourceType string
SourceType describes where a visible skill comes from.
const ( SourceSystem SourceType = "system" SourceUser SourceType = "user" SourceProject SourceType = "project" )
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
Tracker tracks which skills have been loaded (read) during a session. It is safe for concurrent use.
Note: Tracking is name-based and limited to active skills only. If a builtin skill is overridden by a user skill, only the user skill (which is active) can be marked as loaded. This prevents misattribution when reading builtin files that have been overridden.
func NewTracker ¶
NewTracker creates a new skill tracker with the given active skill names. Only skills in activeSkills can be marked as loaded.
func (*Tracker) LoadedCount ¶
LoadedCount returns the number of unique skills that have been loaded. Safe to call on a nil Tracker (returns 0).
func (*Tracker) LoadedNames ¶
LoadedNames returns the names of all skills that have been loaded, sorted alphabetically. Safe to call on a nil Tracker (returns nil).
func (*Tracker) MarkLoaded ¶
MarkLoaded marks a skill as having been loaded. Only marks as loaded if the skill is in the active set (not overridden/disabled).