Documentation
¶
Overview ¶
Package skilltree owns the one canonical definition of an Agent Skill's content: which filesystem nodes belong to a skill, how they are hashed, how they are materialized, and how two divergent versions are merged.
Every skill content operation — import, local change detection, pull merge, push delta, and ordinary projection — reads trees through this package so a permissive copier can never drift from the strict import policy.
Index ¶
- Constants
- func HasManifest(tree Tree) bool
- func IsIgnoredName(name string) bool
- func Materialize(tree Tree, dir string) error
- func Merge(base, local, remote Tree, mergeText TextMerger) (Tree, []Conflict, error)
- func NormalizeName(value string) string
- func ValidateRelativePath(value string) error
- type Conflict
- type ConflictKind
- type Diff
- type FS
- type File
- type OSFS
- type SkillInfo
- type TextMerger
- type Tree
Constants ¶
const SkillManifestName = "SKILL.md"
SkillManifestName is the canonical skill manifest filename. Every source tier requires it exactly; no lowercase fallback is accepted.
Variables ¶
This section is empty.
Functions ¶
func HasManifest ¶
HasManifest reports whether a tree carries a root-level canonical SKILL.md. Wildcard selectors use it to ignore ordinary directories.
func IsIgnoredName ¶
IsIgnoredName reports whether a filesystem entry is one of the three source artifacts excluded from every canonical skill-tree read.
func Materialize ¶
Materialize writes the tree into dir, which must already exist and is expected to be an empty staging directory owned by the caller. It never writes outside dir.
func Merge ¶
func Merge(base, local, remote Tree, mergeText TextMerger) (Tree, []Conflict, error)
Merge reconciles local and remote against their common base.
A path changed on only one side applies cleanly, identical changes on both sides coalesce, compatible text changes are merged by mergeText, and every remaining divergence is reported as a conflict rather than resolved by preference. Renames are handled as the deletion plus addition they are recorded as, because a skill tree carries no rename metadata.
Merge never partially applies: when any conflict is reported the returned tree must be discarded by the caller.
func NormalizeName ¶
NormalizeName applies the same Unicode normalization used when comparing skill names across configuration, imports, and user-managed sources.
func ValidateRelativePath ¶
ValidateRelativePath rejects any tree path that could escape its skill root.
Types ¶
type Conflict ¶
type Conflict struct {
Path string
Kind ConflictKind
}
Conflict reports one unmergeable path.
type ConflictKind ¶
type ConflictKind string
ConflictKind names why a path could not be reconciled automatically.
const ( // ConflictContent means both sides changed the same text file // incompatibly. ConflictContent ConflictKind = "content" // ConflictDeleteModify means one side deleted a path the other changed. ConflictDeleteModify ConflictKind = "delete/modify" // ConflictBinary means both sides changed a non-text file differently. ConflictBinary ConflictKind = "binary" // ConflictMode means both sides changed the executable bit differently. ConflictMode ConflictKind = "mode" )
type Diff ¶
Diff reports the paths added, modified, and deleted going from base to next.
type FS ¶
type FS interface {
Lstat(name string) (os.FileInfo, error)
ReadDir(name string) ([]os.DirEntry, error)
ReadFile(name string) ([]byte, error)
}
FS is the filesystem surface a tree read needs. It is deliberately small so the sync package's injectable System and a plain OS implementation both satisfy it.
type File ¶
type File struct {
// Path is the slash-normalized path relative to the skill root.
Path string
// Data is the file's exact bytes.
Data []byte
// Executable records whether the owner execute bit is set. Git uses that
// bit to choose between blob modes 100644 and 100755.
Executable bool
}
File is one regular file in a skill tree.
type OSFS ¶
type OSFS struct{}
OSFS reads through the real filesystem.
type SkillInfo ¶
type SkillInfo struct {
// Name is the frontmatter name, which must equal the selected directory
// name and becomes the local imported directory name.
Name string
// Description is the required nonempty frontmatter description.
Description string
}
SkillInfo is the identity a validated skill tree carries.
func ValidateManifest ¶
ValidateManifest applies the same strict rules to one manifest's bytes.
Callers that already hold the manifest use it to apply the same identity and metadata rules without constructing a second tree. sourcePath names the skill root.
func ValidateSkill ¶
ValidateSkill enforces Agent Layer's strict skill rules on a tree that was selected at sourcePath.
It requires a canonical SKILL.md at the tree root, valid required metadata, a safe skill name, a name matching the selected directory, and frontmatter Agent Layer can project faithfully. sourcePath is used for error context and to derive the expected name.
type TextMerger ¶
TextMerger performs a three-way merge of text content. It returns the merged bytes and whether the merge produced conflicts. An error means the merge could not be attempted at all.
type Tree ¶
type Tree struct {
// contains filtered or unexported fields
}
Tree is a skill's complete regular-file content, sorted by path.
Directories are intentionally absent: an empty directory carries no skill content and is not representable in Git, so including it would make local and upstream hashes disagree for identical skills.
func Read ¶
Read enumerates the skill tree rooted at dir.
It walks with Lstat so a link is classified without being followed, includes every regular file (hidden files included), ignores only `.git`, `.DS_Store`, and `Thumbs.db`, and rejects every other node type. A missing root directory yields an empty tree so callers can distinguish "no content" from a read failure by checking the directory themselves.