packages

package
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Aug 23, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const CurrentSchema = 1

CurrentSchema is the only lineage.yaml schema this build understands. schema describes how to interpret the manifest; version describes the package itself — the two change independently.

View Source
const DefaultRegistryURL = "https://agenticlineage.vercel.app"

DefaultRegistryURL is used when LINEAGE_REGISTRY_URL isn't set. It points at the Lineage website's package API (docs/decisions/ 0012-v1-distribution-contract-and-receiver-activation.md), which is itself a thin proxy in front of a private GitHub repo used as artifact storage - the registry API is the only interface this file talks to.

This is the actual deployed domain (priyam-jain-2002/lineagelanding on Vercel), not a placeholder - update it if a custom domain is ever attached in front of that deployment.

View Source
const ManifestFileName = "lineage.yaml"
View Source
const WorkflowFileName = "WORKFLOW.md"

Variables

This section is empty.

Functions

func ApplySetup added in v1.0.0

func ApplySetup(projectRoot string, plan SetupPlan) error

ApplySetup creates whatever plan says doesn't already exist: missing files get their declared template content, missing directories get created empty. Anything already present is left completely untouched - this is what makes ApplySetup safe to call more than once (#72's idempotent/resumable requirement): a second call after a first partial success only creates what's still missing, and a call against a project that already has everything does nothing at all.

func ComputeDigest

func ComputeDigest(dir string) (string, error)

ComputeDigest returns a stable "sha256:<hex>" content digest over a package's manifest and every file in its standard content directories, hashed in deterministic path order. Two packages with byte-identical content always produce the same digest; any content change changes it.

func Export

func Export(dir string, w io.Writer) error

Export writes package dir as a deterministic, reproducible tar.gz archive to w: the manifest plus every file in the package's standard content directories, in sorted path order, with normalized permissions and a fixed modification time. Two exports of byte-identical package content always produce byte-identical archive bytes.

Export refuses to run against a package that fails Validate — exporting is exactly the moment package content starts moving to another machine, so it must not ship something with an unresolved secret finding, a traversing entrypoint, or a declared-but-missing export.

func FindWorkflow

func FindWorkflow(pkgs []Package, name string) (Package, Workflow, error)

FindWorkflow looks for a workflow named name across pkgs (typically the set of currently-enabled packages) and returns the package that declares it along with the parsed workflow. It's an error if no enabled package declares the workflow, or if more than one does — workflow names aren't namespaced across packages, so an ambiguous match needs a human decision rather than a silent pick.

func Import

func Import(r io.Reader, destParent, asName string) (string, error)

Import returns the name the package was imported under.

func InitPackage

func InitPackage(dir, name string) error

InitPackage scaffolds a package directory: a lineage.yaml manifest plus the standard skills/workflows/agents/policies/references/adapters subdirectories. It is safe to call more than once against the same directory. If a manifest already exists there, InitPackage leaves it untouched rather than resetting it to defaults, so re-running `lineage package init` never silently discards a maintainer's version bump, description edit, or other manifest changes.

func Pull

func Pull(ref string, cfg RegistryConfig, destParent, asName string) (string, error)

Pull fetches a published package by ref ("<name>@<version>", or just "<name>" for the latest published version) from the registry and imports it into destParent, the same way Import does for a local archive.

The digest the registry reports for ref is untrusted the same way the archive bytes are: after import, Pull recomputes the digest from the content Import actually kept and fails closed - removing what was imported - if it doesn't match what the registry claimed, or if the registry didn't report a digest at all.

func ResolveReference

func ResolveReference(home string, workspace string, projectRoot string, ref string) (string, error)

func SafeJoin

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

SafeJoin joins rel onto root and guarantees the result stays within root, rejecting absolute paths and any ".."-escaping reference however it's disguised (e.g. "a/../../etc/passwd"). Use this for every path that comes from untrusted, package-controlled input — manifest fields like entrypoints, and archive entries during import — never for a path the user typed directly at the CLI, which is trusted first-party intent.

func SaveManifest

func SaveManifest(dir string, manifest Manifest) error

func ValidateDependencies

func ValidateDependencies(pkgs []Package) error

ValidateDependencies checks that every package's Requires.Skills is satisfied somewhere across pkgs — its own skills, or another package's. It's meant to run against the full set of packages that will be enabled together (not one package in isolation), since a required skill can legitimately be provided by a different enabled package.

func ValidateWorkflowSteps

func ValidateWorkflowSteps(pkg Package, wf Workflow) error

ValidateWorkflowSteps checks that every step in wf references a skill pkg actually has. Returns an error naming the first missing step.

Types

type Capabilities

type Capabilities struct {
	Filesystem FilesystemCapabilities `yaml:"filesystem" json:"filesystem"`
	Network    []string               `yaml:"network" json:"network"`
}

Capabilities is a purely declarative statement of what a package wants access to — printed by lineage package validate and the enable-time plan so a receiver can see it before enabling, not enforced by this build.

type Entrypoints

type Entrypoints struct {
	Claude string `yaml:"claude" json:"claude"`
	Codex  string `yaml:"codex" json:"codex"`
}

Entrypoints and Capabilities carry both yaml and json tags: yaml for the manifest file itself, json because Publish (#90) sends both verbatim to the registry so a receiver can see provider compatibility and safety notes before ever pulling the package, not just after enabling it.

func (Entrypoints) Providers added in v1.0.0

func (e Entrypoints) Providers() []string

Providers returns which of claude/codex e declares a non-empty entrypoint for - the "provider compatibility" a receiver sees before enabling. Computed once here so every consumer (structured CLI output, the registry's own listing) agrees on what "declared" means: a non-empty entrypoint string, not just the field being present.

type ErrAlreadyImported added in v1.0.0

type ErrAlreadyImported struct {
	Name   string
	Dest   string
	Digest string
}

Import extracts an archive produced by Export into a new directory under destParent, named after the package's manifest (or asName, if given, to import under a different name than the one it was exported with).

The archive is untrusted input the same way a manifest is: every entry path is checked with SafeJoin before anything is written, and the fully extracted content is run through Validate before it's kept — an archive that fails validation (a secret finding, a traversing entrypoint, a declared-but-missing export) is discarded, not imported. Import never overwrites an existing package directory; it fails rather than silently clobbering one.

ErrAlreadyImported is returned by Import when destParent already has a package directory under the name Import resolved (asName, or the manifest's own name). Digest is the digest of the content Import was just asked to import, computed before it discovered the conflict - a caller that wants idempotent-reuse semantics (re-running the same import is a no-op, not a failure) can compare Digest against the existing directory's own digest instead of re-deriving either value.

func (*ErrAlreadyImported) Error added in v1.0.0

func (e *ErrAlreadyImported) Error() string

type Exports

type Exports struct {
	Agents    []string `yaml:"agents"`
	Workflows []string `yaml:"workflows"`
}

type FilesystemCapabilities

type FilesystemCapabilities struct {
	Read []string `yaml:"read" json:"read"`
}

type Manifest

type Manifest struct {
	Schema       int          `yaml:"schema"`
	Name         string       `yaml:"name"`
	Version      string       `yaml:"version"`
	Description  string       `yaml:"description"`
	Exports      Exports      `yaml:"exports"`
	Requires     Requires     `yaml:"requires"`
	Entrypoints  Entrypoints  `yaml:"entrypoints"`
	Capabilities Capabilities `yaml:"capabilities"`
	Setup        Setup        `yaml:"setup"`
}

func DefaultManifest

func DefaultManifest(name string) Manifest

func LoadManifest

func LoadManifest(dir string) (Manifest, error)

type Package

type Package struct {
	Path      string
	Manifest  Manifest
	Skills    []string
	Workflows []string
	Agents    []string
	Policies  []string
	// Digest is a sha256 content digest over the manifest and every file in
	// the package's standard content directories, in deterministic order.
	// Identical package content always produces the same digest.
	Digest string
}

func Discover

func Discover(dir string) (Package, error)

func ResolveEnabled

func ResolveEnabled(home string, workspace string, projectRoot string, enabled []string) ([]Package, error)

type PublishResult

type PublishResult struct {
	Name             string
	Version          string
	Digest           string
	AlreadyPublished bool
}

func Publish

func Publish(dir string, cfg RegistryConfig) (PublishResult, error)

Publish validates dir the same way Export does, then uploads the resulting archive to the registry. It refuses to run against a package that fails Validate for the same reason Export does: publish is exactly the moment package content starts moving to other machines.

type RegistryConfig

type RegistryConfig struct {
	URL   string
	Token string
}

RegistryConfig is read from the environment by CLI commands, not stored in .lineage/config.yaml: a publish token is a per-invocation secret, not committed project state.

type Requires

type Requires struct {
	Skills []string `yaml:"skills"`
}

type SecretFinding

type SecretFinding struct {
	Path   string // relative to the package root, forward-slashed
	Reason string
}

SecretFinding is one file that a secret scan flagged, and why.

func ScanForSecrets

func ScanForSecrets(dir string) ([]SecretFinding, error)

ScanForSecrets walks a package directory and flags files that look like they contain secrets or credentials, by filename pattern or by high-confidence content pattern. It never returns the matched content itself — only the path and a human-readable reason — so a caller can safely print findings without risking a secret ending up in command output.

type Setup added in v1.0.0

type Setup struct {
	Files       []SetupFile      `yaml:"files"`
	Directories []SetupDirectory `yaml:"directories"`
}

Setup declares local resources a package's workflow expects to exist - tracker files and directories - so a receiver sees and approves exactly what will be created before anything is, instead of a workflow silently assuming files exist or creating them itself without asking (#72).

type SetupDirectory added in v1.0.0

type SetupDirectory struct {
	Path        string `yaml:"path"`
	Description string `yaml:"description"`
}

SetupDirectory is a single local directory a package wants to exist, relative to the project root (e.g. an output or notes directory).

type SetupDirectoryAction added in v1.0.0

type SetupDirectoryAction struct {
	Path        string // relative to the project root
	Description string
	Exists      bool
}

type SetupFile added in v1.0.0

type SetupFile struct {
	Path        string `yaml:"path"`
	Description string `yaml:"description"`
	Template    string `yaml:"template"`
}

SetupFile is a single local file a package wants to exist, relative to the project root. Template is its initial content if the file doesn't already exist; a file already present at Path is never overwritten.

type SetupFileAction added in v1.0.0

type SetupFileAction struct {
	Path        string // relative to the project root
	Description string
	Template    string
	Exists      bool
}

type SetupPlan added in v1.0.0

type SetupPlan struct {
	Files       []SetupFileAction
	Directories []SetupDirectoryAction
}

SetupPlan is what applying a package's Setup declarations against a project root would do: every declared file/directory, and whether it already exists (a no-op) or would be created. Computing this separately from ApplySetup is what lets a caller show "here's what will happen" and get permission before anything is written (#72).

func PlanSetup added in v1.0.0

func PlanSetup(projectRoot string, setup Setup) (SetupPlan, error)

PlanSetup resolves every path setup declares against projectRoot and checks what's already there, without creating anything. A setup path is publisher-declared, untrusted input like every other package-controlled path in this project, so it goes through SafeJoin the same way archive entries and manifest-declared entrypoints do.

func (SetupPlan) NeedsAction added in v1.0.0

func (p SetupPlan) NeedsAction() bool

NeedsAction reports whether applying plan would actually create anything. A plan where every declared file and directory already exists doesn't need a permission prompt - there's nothing new to approve.

type ValidateReport

type ValidateReport struct {
	Manifest Manifest
	Digest   string
	// Errors block Passed(): a declared-but-missing export, a traversing
	// entrypoint, or a secret-scan finding.
	Errors []string
	// Notes are informational only, e.g. a required skill this package
	// doesn't itself provide (it may be provided by another package at
	// enable time - Validate only sees this one package in isolation).
	Notes []string
}

ValidateReport is the result of Validate: every problem found, plus the informational facts (digest, declared capabilities) a receiver would want before enabling a package. Unlike Discover, which fails fast on the first problem so callers that actually resolve/materialize a package never proceed with a broken one, Validate collects every problem it finds so a package author sees the whole picture in one run.

func Validate

func Validate(dir string) (ValidateReport, error)

Validate runs every Phase 2 format and safety check against a package directory without enabling it or writing anything to disk: manifest schema, export authority, entrypoint path safety, a secret scan, and the content digest. It fails outright only if the manifest itself can't be loaded (schema mismatch, missing name) or a check can't run at all (I/O error) - anything else becomes an Errors entry so the report is complete.

func (ValidateReport) Passed

func (r ValidateReport) Passed() bool

Passed reports whether the package validated cleanly.

type Workflow

type Workflow struct {
	Name  string
	Steps []string
}

Workflow is an ordered sequence of skill names, declared in a WORKFLOW.md's YAML frontmatter (the same `---`-delimited convention SKILL.md already uses). A workflow with no frontmatter, or frontmatter with no `steps`, has an empty Steps list — WORKFLOW.md remains valid plain documentation on its own, same as before this existed.

func LoadWorkflow

func LoadWorkflow(pkgDir, name string) (Workflow, error)

LoadWorkflow reads and parses the WORKFLOW.md frontmatter for the named workflow inside pkgDir.

Jump to

Keyboard shortcuts

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