skills

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: May 27, 2026 License: MIT Imports: 32 Imported by: 0

Documentation

Overview

Package skills provides the core types and loading primitives for AgentSkills `SKILL.md` files.

Index

Constants

View Source
const (
	// SkillResourceKind is the canonical desired-state resource kind for skill definitions.
	SkillResourceKind resources.ResourceKind = "skill"
)

Variables

View Source
var (
	// ErrAgentNotFound reports that the requested agent is unavailable in the selected scope.
	ErrAgentNotFound = errors.New("skills: agent not found")
	// ErrAgentLocalInvalid reports an invalid AGENT.md or agent-local skills layer.
	ErrAgentLocalInvalid = errors.New("skills: invalid agent-local layer")
)
View Source
var ErrSymlinkEscape = errors.New("skills: symlink escapes skill directory")

ErrSymlinkEscape reports a skill payload symlink that resolves outside the skill directory.

Functions

func BuildCatalog

func BuildCatalog(skills []*Skill) string

BuildCatalog renders the XML-like available-skills block injected into agent system prompts.

func BuildCurrentCatalog

func BuildCurrentCatalog(skills []*Skill) string

BuildCurrentCatalog renders the authoritative per-turn skills block injected ahead of live prompts.

func BuildCurrentCatalogUnchanged added in v0.0.3

func BuildCurrentCatalogUnchanged() string

BuildCurrentCatalogUnchanged renders the compact per-turn marker used when the catalog did not change.

func ComputeDirectoryHash

func ComputeDirectoryHash(skillDir string) (string, error)

ComputeDirectoryHash returns a deterministic SHA-256 digest for a skill directory payload, excluding the provenance sidecar itself.

func ComputeHash

func ComputeHash(content []byte) string

ComputeHash returns the SHA-256 hex digest for raw SKILL.md content bytes.

func HasSidecar

func HasSidecar(skillDir string) (bool, error)

HasSidecar reports whether a skill directory contains marketplace provenance metadata.

func NewResourceCodec

func NewResourceCodec() (resources.KindCodec[SkillResourceSpec], error)

NewResourceCodec builds the canonical skill resource codec.

func ReadSkillContent

func ReadSkillContent(path string) (string, error)

ReadSkillContent reads and returns the markdown body from a SKILL.md file.

func ReadSkillResourceContent

func ReadSkillResourceContent(skillDir string, relativePath string) (string, error)

ReadSkillResourceContent reads a resource file relative to a filesystem-backed skill directory.

func SkillPrecedenceTierName

func SkillPrecedenceTierName(source SkillSource) string

SkillPrecedenceTierName returns the canonical public resolver tier label.

func SkillSourceName

func SkillSourceName(source SkillSource) string

SkillSourceName returns the canonical string label for a skill source.

func VerifyHash

func VerifyHash(skillDir string, provenance *Provenance) error

VerifyHash recomputes the installed skill payload hash for a skill directory and compares it with the stored provenance hash.

func WriteSidecar

func WriteSidecar(skillDir string, provenance Provenance) error

WriteSidecar writes marketplace provenance metadata alongside a skill's SKILL.md file.

Types

type CatalogProvider

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

CatalogProvider builds the workspace-scoped skill catalog section expected by the composed prompt assembly pipeline.

func NewCatalogProvider

func NewCatalogProvider(registry *Registry) *CatalogProvider

NewCatalogProvider constructs a CatalogProvider backed by the provided registry.

func (*CatalogProvider) PromptAgentSection

func (cp *CatalogProvider) PromptAgentSection(
	ctx context.Context,
	agent aghconfig.AgentDef,
	workspace *workspacepkg.ResolvedWorkspace,
) (string, error)

PromptStartupSection resolves the effective catalog for the concrete agent being started when the prompt assembler provides that identity.

func (*CatalogProvider) PromptSection

func (cp *CatalogProvider) PromptSection(
	ctx context.Context,
	workspace *workspacepkg.ResolvedWorkspace,
) (string, error)

PromptSection loads the workspace-scoped skills and returns their XML-like catalog representation.

type HashMismatchError

type HashMismatchError struct {
	ExpectedHash string
	ActualHash   string
}

HashMismatchError reports a provenance hash mismatch for a marketplace skill.

func (*HashMismatchError) Error

func (e *HashMismatchError) Error() string

Error implements the error interface.

type MCPResolver

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

MCPResolver collects and resolves MCP server declarations from active skills.

func NewMCPResolver

func NewMCPResolver(cfg aghconfig.SkillsConfig, logger *slog.Logger) *MCPResolver

NewMCPResolver constructs an MCPResolver from skills config and logger settings.

func (*MCPResolver) Resolve

func (mr *MCPResolver) Resolve(skills []*Skill) []aghconfig.MCPServer

Resolve returns MCP servers from active skills after trust-tier filtering. When multiple declarations share the same trimmed server name, the later skill in source-precedence order replaces the earlier one ("last wins"). The caller then passes the result through aghconfig.MergeMCPServers, which keeps the first server at each final position. Combined together, skill-local duplicates are resolved last-wins before config-vs-skill merge applies its first-wins behavior.

type MCPServerDecl

type MCPServerDecl struct {
	Name      string            `yaml:"name"`
	Command   string            `yaml:"command"`
	Args      []string          `yaml:"args,omitempty"`
	Env       map[string]string `yaml:"env,omitempty"`
	SecretEnv map[string]string `yaml:"secret_env,omitempty"`
}

MCPServerDecl declares an MCP server dependency in skill frontmatter.

type Option

type Option func(*Registry)

Option customizes a Registry instance.

func WithEventSummaryStore

func WithEventSummaryStore(events store.EventSummaryStore) Option

WithEventSummaryStore injects the optional global observe-event writer used for public skill.shadowed and skills.load_failed events.

func WithLogger

func WithLogger(logger *slog.Logger) Option

WithLogger injects the logger used for registry diagnostics.

func WithNow

func WithNow(now func() time.Time) Option

WithNow injects the clock used for cache timestamps and eviction.

type Provenance

type Provenance struct {
	Hash        string    `json:"hash"`
	Registry    string    `json:"registry"`
	Slug        string    `json:"slug"`
	Version     string    `json:"version"`
	InstalledAt time.Time `json:"installed_at"`
}

Provenance stores marketplace install metadata for a skill.

func ReadSidecar

func ReadSidecar(skillDir string) (*Provenance, error)

ReadSidecar reads marketplace provenance metadata from a skill directory.

type Registry

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

Registry manages global skills loaded at boot and lazily cached workspace skills.

func NewRegistry

func NewRegistry(cfg RegistryConfig, opts ...Option) *Registry

NewRegistry constructs a Registry with the provided configuration.

func (*Registry) ApplyResourceRecords

func (r *Registry) ApplyResourceRecords(revision int64, records []resources.Record[SkillResourceSpec]) error

ApplyResourceRecords atomically replaces the runtime skill catalog with the canonical resource projection.

func (*Registry) DiscoverGlobal

func (r *Registry) DiscoverGlobal(ctx context.Context) ([]*Skill, map[string]filesnap.Snapshot, error)

DiscoverGlobal loads global skill definitions for resource publication without making the file-system scan authoritative in the registry.

func (*Registry) DiscoverWorkspace

func (r *Registry) DiscoverWorkspace(
	ctx context.Context,
	resolved *workspacepkg.ResolvedWorkspace,
) ([]*Skill, map[string]filesnap.Snapshot, error)

DiscoverWorkspace loads workspace-visible skill definitions for resource publication.

func (*Registry) ForAgent

func (r *Registry) ForAgent(
	ctx context.Context,
	resolved *workspacepkg.ResolvedWorkspace,
	agentName string,
) ([]*Skill, error)

ForAgent returns the effective skill set for one logical agent after applying the final agent-local overlay over the current global/workspace-effective set.

func (*Registry) ForWorkspace

func (r *Registry) ForWorkspace(ctx context.Context, resolved *workspacepkg.ResolvedWorkspace) ([]*Skill, error)

ForWorkspace returns the global skill set overlaid with resolver-provided workspace skills.

func (*Registry) Get

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

Get returns a cloned global skill by name when present.

func (*Registry) GlobalVersion

func (r *Registry) GlobalVersion() int64

GlobalVersion returns the current global snapshot version.

func (*Registry) List

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

List returns the current global skills sorted by skill name.

func (*Registry) LoadAll

func (r *Registry) LoadAll(ctx context.Context) error

LoadAll loads bundled and user-level skills into the global registry snapshot.

func (*Registry) LoadContent

func (r *Registry) LoadContent(ctx context.Context, skill *Skill) (string, error)

LoadContent loads the full markdown body for one resolved skill.

func (*Registry) LoadResource

func (r *Registry) LoadResource(ctx context.Context, skill *Skill, relativePath string) (string, error)

LoadResource loads a resource file relative to one resolved skill.

func (*Registry) RefreshGlobal

func (r *Registry) RefreshGlobal(ctx context.Context) error

RefreshGlobal re-scans the global skill sources and swaps them in atomically.

func (*Registry) SetEnabled

func (r *Registry) SetEnabled(name string, resolved *workspacepkg.ResolvedWorkspace, enabled bool) error

SetEnabled updates the runtime enabled state for a named skill and keeps the disabled-skills overlay in sync so future reloads preserve the change.

func (*Registry) SetEnabledForAgent

func (r *Registry) SetEnabledForAgent(
	name string,
	resolved *workspacepkg.ResolvedWorkspace,
	agentName string,
	enabled bool,
) error

SetEnabledForAgent persists an agent-scoped logical tombstone in the winning AGENT.md.

func (*Registry) SetEventSummaryStore

func (r *Registry) SetEventSummaryStore(events store.EventSummaryStore)

SetEventSummaryStore updates the optional global observe-event writer after registry construction.

func (*Registry) SkillDiagnostics

func (r *Registry) SkillDiagnostics(
	ctx context.Context,
	resolved *workspacepkg.ResolvedWorkspace,
	agentName string,
) ([]SkillDiagnostic, error)

SkillDiagnostics returns diagnostics for the same resolution scope used by List, ForWorkspace, and ForAgent. It does not change resolution semantics.

type RegistryConfig

type RegistryConfig struct {
	BundledFS      fs.FS
	UserSkillsDir  string
	UserAgentsDir  string
	DisabledSkills []string
}

RegistryConfig controls how the registry discovers global skills.

type ShadowEntry

type ShadowEntry struct {
	Path             string
	Tier             string
	ResolvedToWinner bool
	DetectedAt       time.Time
}

ShadowEntry is the public read model for one declaration participating in skill resolution. The winner and every shadowed declaration come from the same resolver snapshot.

type Skill

type Skill struct {
	Meta                   SkillMeta
	Source                 SkillSource
	Dir                    string
	FilePath               string
	Enabled                bool
	MCPServers             []MCPServerDecl
	Hooks                  []hookspkg.HookDecl
	Provenance             *Provenance
	InstalledFrom          string
	InstalledFromBundle    string
	InstalledFromExtension string
	Diagnostics            SkillDiagnostics
}

Skill is the metadata-first in-memory representation of a parsed skill file.

func ParseSkillFile

func ParseSkillFile(path string) (*Skill, error)

ParseSkillFile reads and parses a SKILL.md file from disk.

The loader fills parsed metadata plus canonical file locations. The skill body is intentionally not retained on the returned Skill; callers must use ReadSkillContent when they need the full instructions.

func ParseSkillFileWithSource

func ParseSkillFileWithSource(path string, source SkillSource) (*Skill, error)

ParseSkillFileWithSource reads and parses a skill file from disk while preserving the caller-selected source tier for downstream precedence and hook metadata handling.

func SkillFromResourceSpec

func SkillFromResourceSpec(spec SkillResourceSpec) (*Skill, error)

SkillFromResourceSpec converts a canonical resource spec into the runtime skill shape.

type SkillDefinitionRef

type SkillDefinitionRef struct {
	Source     string
	Path       string
	DetectedAt time.Time
}

SkillDefinitionRef identifies a skill definition involved in resolution diagnostics.

type SkillDiagnostic

type SkillDiagnostic struct {
	Name               string
	State              SkillDiagnosticState
	Source             string
	Path               string
	WinningSource      string
	WinningPath        string
	VerificationStatus SkillVerificationStatus
	Warnings           []Warning
	Failure            *SkillVerificationFailure
}

SkillDiagnostic is the public read model for one effective, shadowed, or rejected definition.

func DiagnosticsForSkill

func DiagnosticsForSkill(skill *Skill) []SkillDiagnostic

DiagnosticsForSkill returns the diagnostics visible for one effective skill.

type SkillDiagnosticState

type SkillDiagnosticState string

SkillDiagnosticState describes how one discovered skill definition resolved.

const (
	// SkillDiagnosticStateValid reports a loaded definition that participates in the effective skill set.
	SkillDiagnosticStateValid SkillDiagnosticState = "valid"
	// SkillDiagnosticStateShadowed reports a definition superseded by a higher-precedence definition.
	SkillDiagnosticStateShadowed SkillDiagnosticState = "shadowed"
	// SkillDiagnosticStateVerificationFailed reports a definition rejected by provenance or content verification.
	SkillDiagnosticStateVerificationFailed SkillDiagnosticState = "verification_failed"
)

type SkillDiagnostics

type SkillDiagnostics struct {
	VerificationStatus  SkillVerificationStatus
	Warnings            []Warning
	ShadowedDefinitions []SkillDefinitionRef
}

SkillDiagnostics stores verifier and resolution diagnostics on an effective skill.

type SkillMeta

type SkillMeta struct {
	Name        string         `yaml:"name"`
	Description string         `yaml:"description"`
	Version     string         `yaml:"version,omitempty"`
	Metadata    map[string]any `yaml:"metadata,omitempty"`
}

SkillMeta maps YAML frontmatter fields per the AgentSkills spec.

type SkillResourceSpec

type SkillResourceSpec struct {
	Name                   string              `json:"name"`
	Description            string              `json:"description"`
	Version                string              `json:"version,omitempty"`
	Metadata               map[string]any      `json:"metadata,omitempty"`
	Source                 string              `json:"source"`
	Dir                    string              `json:"dir,omitempty"`
	FilePath               string              `json:"file_path,omitempty"`
	Enabled                bool                `json:"enabled"`
	MCPServers             []MCPServerDecl     `json:"mcp_servers,omitempty"`
	Hooks                  []hookspkg.HookDecl `json:"hooks,omitempty"`
	Provenance             *Provenance         `json:"provenance,omitempty"`
	InstalledFrom          string              `json:"installed_from,omitempty"`
	InstalledFromBundle    string              `json:"installed_from_bundle,omitempty"`
	InstalledFromExtension string              `json:"installed_from_extension,omitempty"`
}

SkillResourceSpec is the resource-backed metadata index for one parsed skill.

The full SKILL.md body intentionally remains outside the resource record and is loaded through the skills package when callers need content.

func SkillToResourceSpec

func SkillToResourceSpec(skill *Skill) SkillResourceSpec

SkillToResourceSpec converts a parsed skill into its canonical resource spec.

type SkillShadows

type SkillShadows struct {
	Name    string
	Winner  ShadowEntry
	Shadows []ShadowEntry
}

SkillShadows describes every declaration for one skill name with the resolver winner called out explicitly.

func ShadowsForSkill

func ShadowsForSkill(skill *Skill, fallbackDetectedAt time.Time) (SkillShadows, bool)

ShadowsForSkill returns the resolver winner and every known shadowed definition for one effective skill. It does not perform resolution itself.

func ShadowsForSkillList

func ShadowsForSkillList(skills []*Skill, name string, fallbackDetectedAt time.Time) (SkillShadows, bool)

ShadowsForSkillList returns shadow evidence for a named winner in a resolved skill list.

type SkillSource

type SkillSource int

SkillSource identifies where a skill was loaded from.

const (
	// SourceBundled is the lowest-precedence source backed by go:embed files.
	SourceBundled SkillSource = iota
	// SourceMarketplace identifies skills installed from a marketplace registry.
	SourceMarketplace
	// SourceUser identifies skills loaded from the user-level skill directories.
	SourceUser
	// SourceAdditional identifies skills loaded from additional workspace roots.
	SourceAdditional
	// SourceWorkspace is the highest-precedence source from `<workspace>/.agh/skills/`.
	SourceWorkspace
	// SourceAgentLocal is the final overlay from `<root>/.agh/agents/<name>/skills/`.
	SourceAgentLocal
)

type SkillVerificationFailure

type SkillVerificationFailure struct {
	Code         string
	Message      string
	ExpectedHash string
	ActualHash   string
}

SkillVerificationFailure captures an actionable verification rejection.

type SkillVerificationStatus

type SkillVerificationStatus string

SkillVerificationStatus describes the verifier outcome for one skill definition.

const (
	// SkillVerificationStatusPassed means no verifier warning or error is attached.
	SkillVerificationStatusPassed SkillVerificationStatus = "passed"
	// SkillVerificationStatusWarning means non-blocking verifier warnings were found.
	SkillVerificationStatusWarning SkillVerificationStatus = "warning"
	// SkillVerificationStatusFailed means the definition was rejected by verification.
	SkillVerificationStatusFailed SkillVerificationStatus = "failed"
)

type Warning

type Warning struct {
	Severity WarningSeverity
	Message  string
	Pattern  string
}

Warning captures a verification or loading concern associated with a skill.

func VerifyContent

func VerifyContent(content string) []Warning

VerifyContent scans skill content for prompt-injection and abuse patterns.

type WarningSeverity

type WarningSeverity int

WarningSeverity describes the impact of a loader or verifier warning.

const (
	SeverityInfo WarningSeverity = iota
	SeverityWarning
	SeverityCritical
)

type Watcher

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

Watcher polls global skill directories and refreshes the registry when their SKILL.md snapshots change.

func NewWatcher

func NewWatcher(registry *Registry, interval time.Duration) *Watcher

NewWatcher constructs a watcher that polls the registry's global skill directories. A non-positive interval falls back to the default poll interval.

func (*Watcher) SetAfterRefresh

func (w *Watcher) SetAfterRefresh(callback func(context.Context) error)

SetAfterRefresh installs an optional callback that runs after a successful registry refresh and before watcher snapshots are committed.

func (*Watcher) SetRootsProvider

func (w *Watcher) SetRootsProvider(provider func(context.Context) ([]string, error))

SetRootsProvider installs an optional callback that contributes additional directories to watch on each poll, such as workspace-local skill roots.

func (*Watcher) Start

func (w *Watcher) Start(ctx context.Context)

Start runs the polling loop until the provided context is canceled.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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