manifest

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package manifest reads and writes skills.toml, the committed, hand-authored declaration of a project's skills, overrides, and project configuration (spec 023). It is the intent half of the pair; skills-lock.json records what that intent resolved to.

Index

Constants

View Source
const (
	ModeSymlink = "symlink"
	ModeCopy    = "copy"
	ModeAuto    = "auto"
)

Install modes a skill may declare (data-model.md §1.1).

View Source
const FileName = "skills.toml"

FileName is the manifest's fixed name at the repository root.

Deliberately NOT "gskill.toml": that name belonged to a manifest released in v0.0.1–v0.2.0 and retired in #32 ("skills-lock.json is the only project state"), and lockonly_guard_test.go still guards against its return. A pre-v0.3.0 project may hold one on disk with an incompatible schema (schema_version, [defaults], install_mode, path), so reusing the name would either misread it or hard-fail every command in that project.

Variables

This section is empty.

Functions

func ProjectConfig added in v0.7.0

func ProjectConfig(root string) (map[string]any, error)

ProjectConfig returns the config table declared in the manifest at root, suitable for config.Sources.ProjectMap. A project with no manifest, or one declaring no configuration, yields nil — the layer simply contributes nothing rather than erroring, so a project without a manifest behaves as it always did.

A malformed manifest is reported: silently ignoring it would let a typo disable project configuration with no signal at all.

func Remove added in v0.7.0

func Remove(path, name string) error

Remove deletes a skill's block and every `[skills.<name>.*]` sub-table. A missing manifest or absent block is a no-op, so `remove` stays idempotent.

func ResolveInRepo added in v0.7.0

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

ResolveInRepo resolves a repo-relative path against root and proves the result stays inside the repository, after symlink resolution.

Validation happens *after* resolution rather than by inspecting the string: only that defeats `..` segments, absolute paths, and symlinked escapes uniformly (research R2). Every committed artifact must stay in-repo (spec 022 FR-003, extended by FR-006), so a path that escapes is refused outright.

func SetKey added in v0.7.1

func SetKey(path, skill, key, value string) error

SetKey rewrites exactly one key of one declaration in place (spec 024 data-model.md §5): the value token is replaced and everything else on the line — indentation, spacing around "=", a trailing comment — survives, as does every other line of the file. A key the block lacks is inserted right after its source line. Upsert re-renders a whole block; upgrade must not, because a comment inside the block is the user's and a rewrite that ate it would be a regression dressed as a feature.

func Upsert added in v0.7.0

func Upsert(path string, s Skill) error

Upsert writes skill's declaration into the manifest at path, replacing an existing block of the same name or appending a new one, and creating the file when absent.

Writing is surgical — the file is spliced as text rather than re-marshalled from a struct — because a TOML round-trip discards comments and key order. The manifest is hand-authored and committed, so silently eating a user's comments would be a serious regression, not a cosmetic one.

Types

type Manifest

type Manifest struct {
	Skills   map[string]Skill
	Config   map[string]any
	Warnings []string
}

Manifest is a parsed skills.toml. Warnings carry non-fatal findings (V3, V9) that the CLI surfaces without failing the run.

func Load

func Load(path string) (*Manifest, error)

Load reads the manifest at path. A missing file is not an error: a pre-023 project has none until a mutating command generates one (FR-015), so callers receive (nil, nil) and treat the project as unmanifested.

func Parse added in v0.7.0

func Parse(data []byte) (*Manifest, error)

Parse decodes and structurally validates manifest bytes: rules V1, V2, V4, V7, V8, and V9 from contracts/manifest.md. Filesystem-dependent rules (V5, V6) belong to Validate, which needs the repository root.

func (*Manifest) Validate

func (m *Manifest) Validate(root string) error

Validate applies the filesystem-dependent rules V5 and V6: every referenced path stays inside the repository and names a readable file. Both run before any network or cache access (FR-005), so a malformed manifest costs nothing.

type Override added in v0.7.0

type Override struct {
	Replace map[string]string
	Patch   []string
	Prepend []string
	Append  []string
}

Override is one `[skills.<name>.override]` declaration (data-model.md §2). Pinning is deliberately absent: it selects the input at resolve time rather than transforming bytes (FR-004).

func (*Override) Empty added in v0.7.0

func (o *Override) Empty() bool

Empty reports whether the declaration transforms nothing, in which case the entry behaves exactly as an un-overridden one (FR-008).

func (*Override) Inputs added in v0.7.0

func (o *Override) Inputs() []string

Inputs returns every repo-relative file the declaration references, in a stable order: replace sources sorted by their target, then patch, prepend, and append in declared order. The order is part of the digest, so it must never depend on map iteration (Constitution I).

type Skill

type Skill struct {
	Name   string
	Source string
	Skill  string
	// Version is a semver constraint (e.g. "^1.0.0") the skill tracks. It is
	// intent, not a resolution: `update` advances within it. Recording the tag
	// it happened to resolve to instead would silently convert a tracking
	// range into a hard pin the user never declared.
	Version  string
	Ref      string
	Commit   string
	Agents   []string
	Mode     string
	Override *Override
}

Skill is one `[skills.<name>]` declaration.

func (Skill) Pin added in v0.7.0

func (s Skill) Pin() string

Pin returns the revision this declaration selects: the exact commit when one is declared, otherwise the ref. `commit` beats `ref` (V9), because an exact revision is strictly more specific than a movable one.

Jump to

Keyboard shortcuts

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