Documentation
¶
Overview ¶
Package app is gskill's orchestration layer. It exposes use-case methods that the cli and tui views call, and is the only layer that drives the domain packages (resolver, installer, store, and the rest). Views never import the domain packages directly.
Index ¶
- Constants
- func IntersectStrings(a, b []string) []string
- func RevisionLabel(rev resolver.Revision) string
- func ShortCommit(sha string) string
- func Subtract(a, b []string) []string
- type AddRequest
- type AddResult
- type AgentChoice
- type AgentHealthEntry
- type App
- func (a *App) Add(ctx context.Context, req AddRequest) (AddResult, error)
- func (a *App) AgentChoices(ctx context.Context, root string) ([]AgentChoice, error)
- func (a *App) Agents() *agent.Registry
- func (a *App) Check(_ context.Context, root string, failOnDrift bool) (CheckReport, error)
- func (a *App) Config() *config.Config
- func (a *App) Diff(_ context.Context, root string) ([]DiffEntry, error)
- func (a *App) DiscoverSource(ctx context.Context, req DiscoverRequest) (DiscoverResult, error)
- func (a *App) Doctor(ctx context.Context, root string) (DoctorReport, error)
- func (a *App) ExecutePlan(ctx context.Context, plan InstallPlan, progress func(InstallProgressEvent)) (AddResult, error)
- func (a *App) Find(ctx context.Context, query string, scope FindScope) ([]SearchHit, []string, error)
- func (a *App) GskillHome() string
- func (a *App) Info(_ context.Context, root, name string) (SkillInfo, error)
- func (a *App) Init(_ context.Context, root string, withLock bool) (InitResult, error)
- func (a *App) InstallFromLock(ctx context.Context, req InstallFromLockRequest) (InstallFromLockResult, error)
- func (a *App) List(_ context.Context, root string) ([]ListedSkill, error)
- func (a *App) ListVersions(ctx context.Context, root, src string, offline bool) (VersionList, error)
- func (a *App) Logger() *slog.Logger
- func (a *App) MigrateGlobalStore(ctx context.Context, root string, dryRun bool) (MigrateReport, error)
- func (a *App) Outdated(ctx context.Context, root string) (OutdatedReport, error)
- func (a *App) PlanInstall(ctx context.Context, req PlanRequest) (InstallPlan, error)
- func (a *App) PreviewLock(root string) (LockPreview, bool, error)
- func (a *App) ProjectsInspect(_ context.Context, projectID string) (projreg.Entry, error)
- func (a *App) ProjectsList(_ context.Context) ([]ProjectInfo, error)
- func (a *App) ProjectsPrune(ctx context.Context) ([]string, error)
- func (a *App) ProjectsRefresh(ctx context.Context) (refreshed []string, err error)
- func (a *App) QualifiesLocalAgentAdd(_ context.Context, root string, req AddRequest) bool
- func (a *App) Remove(ctx context.Context, root string, names []string) (RemoveResult, error)
- func (a *App) Repair(ctx context.Context, root string) (RepairResult, error)
- func (a *App) SelectByFlags(disc DiscoverResult, selectors []string, all bool, path string) ([]discovery.DiscoveredSkill, error)
- func (a *App) SkillMarkdown(_ context.Context, root, name string) (string, error)
- func (a *App) SourceCheck(ctx context.Context, sourceArg string, opts ScanOptions) (SourceCheckReport, error)
- func (a *App) SourceInspect(ctx context.Context, sourceArg, selector, root string, opts ScanOptions) (SkillInspection, error)
- func (a *App) SourceList(ctx context.Context, sourceArg string, opts ScanOptions) (discovery.Result, error)
- func (a *App) StoreGC(ctx context.Context, apply bool, olderThan time.Duration) (StoreGCReport, error)
- func (a *App) StoreInspect(_ context.Context, key string) (StoreInspectReport, error)
- func (a *App) StoreList(_ context.Context) ([]StoreListItem, error)
- func (a *App) StorePin(_ context.Context, key string) error
- func (a *App) StorePins(_ context.Context) ([]string, error)
- func (a *App) StoreRepair(ctx context.Context, key string) error
- func (a *App) StoreStatus(ctx context.Context) (StoreStatusReport, error)
- func (a *App) StoreUnpin(_ context.Context, key string) error
- func (a *App) StoreVerify(_ context.Context) (StoreVerifyResult, error)
- func (a *App) Sync(ctx context.Context, req SyncRequest) (SyncResult, error)
- func (a *App) Unlink(ctx context.Context, root, skill, agentID string, prune bool) (UnlinkResult, error)
- func (a *App) Update(ctx context.Context, root string, names []string) (InstallResult, error)
- func (a *App) Verify(_ context.Context, root string) (VerifyReport, error)
- type CheckReport
- type ConflictError
- type DiffEntry
- type DiscoverRequest
- type DiscoverResult
- type DoctorReport
- type FailureCategory
- type FindScope
- type InitResult
- type InstallFailure
- type InstallFromLockRequest
- type InstallFromLockResult
- type InstallOutcome
- type InstallPhase
- type InstallPlan
- type InstallProgressEvent
- type InstallRequest
- type InstallResult
- type InstallStatus
- type InstallSummary
- type InstalledSkill
- type ListedSkill
- type LockPreview
- type LockPreviewSkill
- type LockSkillResult
- type MigrateReport
- type Options
- type OutdatedReport
- type OutdatedSkill
- type PlanConflict
- type PlanLine
- type PlanRequest
- type PlannedAction
- type PlannedFileOp
- type ProjectInfo
- type RemoveResult
- type RepairResult
- type RepoLister
- type RequirementCheck
- type ScanOptions
- type SearchHit
- type SkillChange
- type SkillCheck
- type SkillHealth
- type SkillInfo
- type SkillInspection
- type SkillVerify
- type SourceCheckReport
- type StoreGCReport
- type StoreInspectReport
- type StoreListItem
- type StoreStatusReport
- type StoreVerifyResult
- type SyncChange
- type SyncRequest
- type SyncResult
- type TargetState
- type UnlinkResult
- type VerifyReport
- type VersionCandidate
- type VersionList
Constants ¶
const ( LockSkillInstalled = "installed" LockSkillUpToDate = "up-to-date" LockSkillRepaired = "repaired" LockSkillFailed = "failed" LockSkillPlanned = "planned" // dry-run only )
Lock-install per-skill statuses (contracts/cli-install-migrate.md).
const ( PlannedWouldInstall = "would-install" PlannedWouldRepair = "would-repair" PlannedWouldRemoveTarget = "would-remove-target" PlannedWouldUpdateLock = "would-update-lock" PlannedBlocked = "blocked" )
Planned actions distinguish what a dry-run entry would do (spec 014 FR-026).
const ( VersionLatest = "latest" VersionRelease = "release" VersionBranch = "branch" VersionCommit = "commit" )
Version candidate kinds offered by the wizard's version step (US3).
const ( ConflictCrossSource = "cross_source_collision" ConflictNoopReadd = "noop_readd" ConflictFileOverwrite = "file_overwrite" )
Plan-time conflict kinds (spec 011 data-model.md). Detection semantics are exactly planAdd's, so guided and non-guided adds fail on the same conflicts.
const ( PlanLineMeta = "meta" // source / version / agents header PlanLineInit = "init" // project scaffolding notice (FR-023) PlanLineAgent = "agent" // per-agent group header ("claude:") PlanLineAction = "action" // "skill → destination" PlanLineFileOp = "fileop" // "create|update path" PlanLineWarning = "warning" // resolution/install warnings PlanLineConflict = "conflict" // blocking conflict detail )
PlanLine kinds, in emission order.
Variables ¶
This section is empty.
Functions ¶
func IntersectStrings ¶ added in v0.3.0
IntersectStrings returns the values present in both a and b, in a's order.
func RevisionLabel ¶ added in v0.3.0
RevisionLabel names a resolved revision for display and error messages — the single label shared by the wizard preview, dry-run output, and plan errors, so the surfaces cannot disagree on the same revision.
func ShortCommit ¶ added in v0.3.0
ShortCommit abbreviates a commit SHA to the display width every human surface uses (plan/dry-run labels, version metadata, progress lines), so the same commit never renders at two different lengths in one run.
Types ¶
type AddRequest ¶
type AddRequest struct {
Root string
Source string
Version string
Ref string
Commit string
Agents []string
Force bool
Scope string
Mode string
// Selection (US2). Selectors are raw --skill values (incl. "*"); All maps
// --all; Path is the --path disambiguator; ListOnly maps --list.
Selectors []string
All bool
Path string
ListOnly bool
Interactive bool
// Discovery filters (FR-012).
MaxDepth int
Include []string
Exclude []string
// Chooser, when set and Interactive, picks among multiple discovered skills.
// It receives every in-scope skill (invalid ones shown but not selectable)
// and returns the chosen subset. The CLI wires this to the TUI picker; the
// app stays independent of the view layer (FR-021).
Chooser func([]discovery.DiscoveredSkill) ([]discovery.DiscoveredSkill, error)
// Progress, when non-nil, receives install lifecycle events (spec 014,
// contracts/install-progress-events.md); nil keeps the run unobserved.
Progress func(InstallProgressEvent)
}
AddRequest describes an `add` invocation.
type AddResult ¶
type AddResult struct {
Installed []InstalledSkill
Listed []discovery.DiscoveredSkill // populated for --list (no install)
Warnings []string
}
AddResult reports the outcome of an add (one or more skills).
type AgentChoice ¶ added in v0.3.0
AgentChoice is one row of the wizard's agent step (US2, FR-014).
type AgentHealthEntry ¶ added in v0.3.0
type AgentHealthEntry struct {
ID string `json:"id"`
Mode string `json:"mode"`
Health string `json:"health"`
}
AgentHealthEntry is one agent's install mode and health for a skill.
type App ¶
type App struct {
// contains filtered or unexported fields
}
App holds the injected dependencies shared by every use-case. Business logic is added by sibling files (install.go, inspect.go, lifecycle.go, ...).
func (*App) Add ¶
Add resolves, installs, and records a new skill, updating the shared lock. It errors on an already-declared key unless Force is set (FR-047), and writes nothing when no target agent is available (FR-029).
func (*App) AgentChoices ¶ added in v0.3.0
AgentChoices returns the wizard's agent step data: every registered agent, which ones are detected for this project, and — preselected — the exact set a non-guided add would target (explicit-free resolution: lock-declared agents, then detection, then the default agent), per FR-014.
func (*App) Check ¶
Check produces a drift report over the three-hop chain (store → active → agent). With failOnDrift, any drift returns exit 7 (FR-016). A present-but- corrupt store fails closed with exit 6 regardless of the flag (FR-018).
func (*App) DiscoverSource ¶ added in v0.3.0
func (a *App) DiscoverSource(ctx context.Context, req DiscoverRequest) (DiscoverResult, error)
DiscoverSource resolves the source to a revision and discovers every skill in it. It writes only to the content cache/store (same as `add --list`), never to the manifest, lockfile, or agent directories.
func (*App) Doctor ¶
Doctor checks the environment (git, detected agents) and reports declared requirements, warning on any that are unmet (FR-032). It never installs.
func (*App) ExecutePlan ¶ added in v0.3.0
func (a *App) ExecutePlan(ctx context.Context, plan InstallPlan, progress func(InstallProgressEvent)) (AddResult, error)
ExecutePlan performs a previously computed InstallPlan: optional project initialization (FR-023), then the staged, checksum-verified, rollback-on- failure install and the atomic lock commit — the exact pipeline non-guided adds use. It refuses a conflicted plan outright (defense in depth; the wizard's approval step already blocks on conflicts, FR-016/FR-017). progress, when non-nil, receives per-skill events.
func (*App) Find ¶ added in v0.1.0
func (a *App) Find(ctx context.Context, query string, scope FindScope) ([]SearchHit, []string, error)
Find searches for skills matching query within a source, across a GitHub owner, or across the configured repositories — always including locally installed skills. Unreachable repositories are reported as warnings rather than aborting the search (FR-036..FR-041). It returns hits and warnings.
func (*App) GskillHome ¶ added in v0.4.0
GskillHome returns the App-level home override ("" when the environment resolution applies). Tests use it to locate their private store.
func (*App) Init ¶
Init prepares local gskill runtime state: the .gskill state dir, the canonical .agents/skills layer, and .gitignore hints. It never creates a manifest; an empty skills-lock.json is written only when withLock is set. It is idempotent.
func (*App) InstallFromLock ¶ added in v0.3.0
func (a *App) InstallFromLock(ctx context.Context, req InstallFromLockRequest) (InstallFromLockResult, error)
InstallFromLock implements the install pipeline: locate and validate skills-lock.json, auto-initialize local state (FR-019/FR-020), then per entry resolve, verify the npx-compatible computedHash before activation, install for the entry's target agents (the entry's declared set, or the exact explicit --agent override when one is given — spec 013), and record the namespaced gskill metadata (FR-016). Failures are isolated per skill: verified successes stay installed and recorded (FR-016a).
func (*App) List ¶
List returns every locked skill with its drift status, active-layer health, and per-agent health — the union of what `list` and `status` used to report separately (spec 013 FR-001). Health is evaluated with the same non-hash-verifying call `status` used, so this adds no new I/O-heavy work.
func (*App) ListVersions ¶ added in v0.3.0
func (a *App) ListVersions(ctx context.Context, root, src string, offline bool) (VersionList, error)
ListVersions lists the selectable versions of a source for the wizard's version step: a synthetic "latest" first, then releases (semver descending), other tags, and branch heads. Listing problems never fail the flow: offline mode, network errors, and rate limits all return a Degraded listing with a reason while "latest" stays selectable and a typed exact ref is still accepted downstream (FR-012).
func (*App) MigrateGlobalStore ¶ added in v0.4.0
func (a *App) MigrateGlobalStore(ctx context.Context, root string, dryRun bool) (MigrateReport, error)
MigrateGlobalStore converts a project from the legacy project-local store to the user-level global store (spec 015 US5). Dry-run reports the plan and changes nothing; a real run verifies, dedupes/copies, relinks, updates machine-local state, and removes the legacy store only after complete success — any earlier failure leaves the project fully usable (FR-038).
func (*App) PlanInstall ¶ added in v0.3.0
func (a *App) PlanInstall(ctx context.Context, req PlanRequest) (InstallPlan, error)
PlanInstall derives the installation plan for the selected skills: per skill × agent destinations, merge-vs-fresh decisions, and conflicts. It is pure computation over the manifest, lockfile, and discovery result — it acquires no lock and writes nothing (SC-002 is structural: only ExecutePlan writes).
func (*App) PreviewLock ¶ added in v0.3.0
func (a *App) PreviewLock(root string) (LockPreview, bool, error)
PreviewLock loads and validates the shared lock for display. found=false (with a nil error) means the project has no skills-lock.json.
func (*App) ProjectsInspect ¶ added in v0.4.0
ProjectsInspect returns one registry entry.
func (*App) ProjectsList ¶ added in v0.4.0
func (a *App) ProjectsList(_ context.Context) ([]ProjectInfo, error)
ProjectsList lists the advisory registry (FR-028).
func (*App) ProjectsPrune ¶ added in v0.4.0
ProjectsPrune removes registry entries whose project no longer exists. It removes registry files only — never repository content (FR-028).
func (*App) ProjectsRefresh ¶ added in v0.4.0
ProjectsRefresh re-derives every registered entry from its project's current lockfile, dropping entries per the privacy mode (FR-028/029).
func (*App) QualifiesLocalAgentAdd ¶ added in v0.3.0
QualifiesLocalAgentAdd reports whether an add request is a pure agent-add — adding agents to already-locked skills from the same source — which App.Add serves entirely from the lockfile and store with no resolver or network call. The guided wizard has no equivalent shortcut, so such requests should take the direct path (review finding: offline interactive agent-adds). The check is read-only.
func (*App) Remove ¶
Remove uninstalls the named skills from the lock and every agent directory, then garbage-collects unreferenced store entries.
func (*App) Repair ¶
Repair re-materializes broken or modified installs from the store/cache without changing the lockfile, and cleans up orphaned staging left by an interrupted install (FR-024, SC-007).
func (*App) SelectByFlags ¶ added in v0.3.0
func (a *App) SelectByFlags(disc DiscoverResult, selectors []string, all bool, path string) ([]discovery.DiscoveredSkill, error)
SelectByFlags resolves explicit --skill/--all selectors against a discovered source, exactly as the non-guided add does, so a flag-preselected wizard session and a scripted add choose identically (FR-004).
func (*App) SkillMarkdown ¶
SkillMarkdown returns the installed SKILL.md content for a skill, read from its first available agent target (for the TUI preview).
func (*App) SourceCheck ¶ added in v0.1.0
func (a *App) SourceCheck(ctx context.Context, sourceArg string, opts ScanOptions) (SourceCheckReport, error)
SourceCheck scans a source and reports its invalid and duplicate skills (FR-034). It is read-only; the caller maps HasProblems to a non-zero exit.
func (*App) SourceInspect ¶ added in v0.1.0
func (a *App) SourceInspect(ctx context.Context, sourceArg, selector, root string, opts ScanOptions) (SkillInspection, error)
SourceInspect scans a source and returns the detailed view of one selected skill (FR-033). The selector is a name or name@path; invalid skills can be inspected so their diagnostics are visible.
func (*App) SourceList ¶ added in v0.1.0
func (a *App) SourceList(ctx context.Context, sourceArg string, opts ScanOptions) (discovery.Result, error)
SourceList scans a source and returns every discovered skill, read-only (FR-032). It never writes to a manifest, lockfile, or agent directory.
func (*App) StoreGC ¶ added in v0.4.0
func (a *App) StoreGC(ctx context.Context, apply bool, olderThan time.Duration) (StoreGCReport, error)
StoreGC runs garbage collection: dry-run by default, deleting only with apply (FR-025). olderThan overrides the configured grace period when > 0.
func (*App) StoreInspect ¶ added in v0.4.0
StoreInspect verifies (full re-hash) and describes one object.
func (*App) StoreList ¶ added in v0.4.0
func (a *App) StoreList(_ context.Context) ([]StoreListItem, error)
StoreList lists every object with its origin-derived display facts and the count of known referencing projects.
func (*App) StoreRepair ¶ added in v0.4.0
StoreRepair restores one corrupted object from its recorded exact origin (FR-023). It fails without touching the object when the exact source cannot be reproduced.
func (*App) StoreStatus ¶ added in v0.4.0
func (a *App) StoreStatus(ctx context.Context) (StoreStatusReport, error)
StoreStatus reports store-wide counts and sizes.
func (*App) StoreUnpin ¶ added in v0.4.0
StoreUnpin removes a GC exemption.
func (*App) StoreVerify ¶ added in v0.4.0
func (a *App) StoreVerify(_ context.Context) (StoreVerifyResult, error)
StoreVerify scans every global store object: full content re-hash, metadata validation, layout, permissions, and stray staging (FR-022).
func (*App) Sync ¶
func (a *App) Sync(ctx context.Context, req SyncRequest) (SyncResult, error)
Sync reconciles the filesystem to the lock's declared state across the three layers (store → active → agent). It restores declared-but-missing installs and skips skills whose store, active entry, and agent targets already match — never re-resolving or re-downloading unchanged content (FR-010..FR-015). With Prune it removes managed agent targets and active entries the lock no longer declares; without Prune it reports such orphans instead of deleting them (FR-013).
func (*App) Unlink ¶ added in v0.1.0
func (a *App) Unlink(ctx context.Context, root, skill, agentID string, prune bool) (UnlinkResult, error)
Unlink removes a single agent's access to a skill without affecting other agents (FR-020, SC-008). When the last agent is unlinked, the active entry, store content, and lock entry are retained unless prune is set, in which case the skill is removed entirely and unreferenced store content is GC'd.
type CheckReport ¶
type CheckReport struct {
Skills []SkillCheck
HasDrift bool
}
CheckReport aggregates a check run.
type ConflictError ¶ added in v0.3.0
ConflictError is a plan-time conflict as an error. It wraps the same errs-coded error the non-guided add path returns, so message text, exit code, and errors.Is behavior are identical in both flows.
func (*ConflictError) Error ¶ added in v0.3.0
func (e *ConflictError) Error() string
Error implements the error interface.
func (*ConflictError) Unwrap ¶ added in v0.3.0
func (e *ConflictError) Unwrap() error
Unwrap returns the underlying coded error.
type DiscoverRequest ¶ added in v0.3.0
type DiscoverRequest struct {
Root string
Source string
Version string
Ref string
Commit string
Scope string
Mode string
// Discovery filters (FR-012 of spec 006).
MaxDepth int
Include []string
Exclude []string
}
DiscoverRequest describes phase 1: resolve a source and discover its skills. It works without a project manifest, so the wizard runs on fresh directories too (FR-023).
type DiscoverResult ¶ added in v0.3.0
type DiscoverResult struct {
Ref source.Ref
Revision resolver.Revision
Scan discovery.Result
Skills []discovery.DiscoveredSkill
Warnings []string
}
DiscoverResult carries the resolved source and its skill catalog. Scan is the full discovery result (needed by selection); Skills is the catalog scoped to the source's explicit in-repo path, in display order.
type DoctorReport ¶
type DoctorReport struct {
GitAvailable bool
DetectedAgents []string
Requirements []RequirementCheck
Warnings []string
}
DoctorReport is the result of `gskill doctor`.
type FailureCategory ¶ added in v0.3.2
type FailureCategory string
FailureCategory is a normalized install-failure classification. Values are wire values in the --json document (contracts/install-result-json.md). Categories are derived from the typed errs sentinels via errors.Is/As — never by parsing error strings (spec 014 FR-013).
const ( FailureAuthentication FailureCategory = "authentication" FailureResolution FailureCategory = "resolution" FailureInvalidMetadata FailureCategory = "invalid-metadata" FailureUnsupportedSource FailureCategory = "unsupported-source" FailureUnsupportedAgent FailureCategory = "unsupported-agent" FailureIntegrity FailureCategory = "integrity" FailureStore FailureCategory = "store" FailureFilesystem FailureCategory = "filesystem" FailurePermission FailureCategory = "permission" FailureForeignContent FailureCategory = "foreign-content" FailureLink FailureCategory = "link" FailureLockfile FailureCategory = "lockfile" FailureCancelled FailureCategory = "cancelled" FailureUnknown FailureCategory = "unknown" )
Failure categories (data-model.md classification table).
type FindScope ¶ added in v0.1.0
FindScope selects where a search looks. Exactly one of Source/Owner may be set; when both are empty the configured repositories are searched. Local installed skills are always included.
type InitResult ¶
InitResult reports what Init created.
type InstallFailure ¶ added in v0.3.2
type InstallFailure struct {
Category FailureCategory
Phase InstallPhase
Message string
Hint string
Expected string // optional: recorded value (integrity mismatches)
Actual string // optional: observed value (integrity mismatches)
Cause error // not serialized; kept for errors.Is/As in tests
}
InstallFailure is the structured explanation of one skill's failure: what category of problem, in which phase, the complete message, and — when the error chain carries one — an actionable remediation hint. Message may contain untrusted remote text; renderers must sanitize it.
type InstallFromLockRequest ¶ added in v0.3.0
type InstallFromLockRequest struct {
Root string
// Agents distinguishes "no explicit selection" (nil — FR-002a: use each
// entry's recorded gskill.agents unchanged) from "explicit selection"
// (non-nil, including a non-nil empty slice — FR-001/FR-002/FR-012: the
// exact target set for every processed entry, replacing what's recorded).
// This nil-vs-empty distinction is load-bearing; do not normalize it away
// with a len()==0 check (research.md Decision 6).
Agents []string
InstallMode string // auto | symlink | copy ("" = per-entry gskill.installMode)
NoInit bool // refuse instead of auto-initializing
Force bool // accept changed upstream content, rewrite computedHash
DryRun bool // report the plan, write nothing
Offline bool // restore from local store/cache only
Frozen bool // never modify the lock file; fail closed on drift
Prune bool // afterwards, remove managed installs the lock no longer declares
// Progress, when non-nil, receives install lifecycle events synchronously
// and strictly sequentially (contracts/install-progress-events.md). A nil
// Progress makes the run behaviorally identical to an unobserved one.
Progress func(InstallProgressEvent)
}
InstallFromLockRequest describes an install (spec 012 US1/US2, spec 013): restore every skill declared in skills-lock.json for its declared agents. An explicit --agent selection (spec 013) is the exact, authoritative target set for the run, replacing each entry's declared set outright.
type InstallFromLockResult ¶ added in v0.3.0
type InstallFromLockResult struct {
Initialized bool
Agents []string
Skills []LockSkillResult
Pruned []string
Changed bool
}
InstallFromLockResult is the run summary.
type InstallOutcome ¶ added in v0.3.2
type InstallOutcome string
InstallOutcome is a run's overall result classification, serialized as the --json document's top-level status (contracts/install-result-json.md).
const ( InstallOutcomeSuccess InstallOutcome = "success" InstallOutcomePartial InstallOutcome = "partial" InstallOutcomeFailure InstallOutcome = "failure" InstallOutcomeCancelled InstallOutcome = "cancelled" InstallOutcomePlanned InstallOutcome = "planned" )
Run outcomes. Cancellation dominates: a user-interrupted run reports cancelled (exit 130) even when some entries had already failed.
type InstallPhase ¶ added in v0.3.2
type InstallPhase string
InstallPhase identifies the pipeline step a skill is in. Not every install emits every phase (the up-to-date fast path skips the fetch phases), but within one skill phases only ever advance (see Rank).
const ( // InstallPhasePrefetching is a run-scoped phase (SkillName empty): the // pre-flight warming of source resolutions and the commit cache before // per-skill processing starts. InstallPhasePrefetching InstallPhase = "prefetching" InstallPhaseResolving InstallPhase = "resolving" InstallPhaseFetching InstallPhase = "fetching" InstallPhaseReadingMetadata InstallPhase = "reading-metadata" InstallPhaseHashing InstallPhase = "hashing" InstallPhaseVerifying InstallPhase = "verifying" InstallPhaseStoring InstallPhase = "storing" InstallPhaseLinking InstallPhase = "linking" InstallPhaseLocking InstallPhase = "locking" InstallPhaseCleaning InstallPhase = "cleaning" InstallPhaseComplete InstallPhase = "complete" )
Install pipeline phases, in execution order.
func (InstallPhase) Rank ¶ added in v0.3.2
func (p InstallPhase) Rank() int
Rank returns the phase's pipeline position for monotonicity checks, or -1 for an unknown (including zero-value) phase.
type InstallPlan ¶ added in v0.3.0
type InstallPlan struct {
Root string `json:"-"`
Source string `json:"source"`
// Requested pins (manifest intent).
Version string `json:"version,omitempty"`
RequestedRef string `json:"ref,omitempty"`
RequestedCommit string `json:"commit,omitempty"`
SourceRef source.Ref `json:"-"`
Revision resolver.Revision `json:"resolved"`
Scope string `json:"scope,omitempty"`
Mode string `json:"mode,omitempty"`
Force bool `json:"force,omitempty"`
// InitProject marks that no manifest exists yet: ExecutePlan scaffolds the
// project first, and the preview lists the manifest as created (FR-023).
InitProject bool `json:"init_project,omitempty"`
Selected []discovery.DiscoveredSkill `json:"-"`
// ExplicitAgents is the raw agent selection (manifest intent); AgentIDs is
// the resolved target set.
ExplicitAgents []string `json:"-"`
AgentIDs []string `json:"agents"`
Actions []PlannedAction `json:"actions"`
Conflicts []PlanConflict `json:"conflicts,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
InstallPlan is the read-only output of PlanInstall: exactly what ExecutePlan will do, rendered by the wizard's preview and by `add --dry-run` (FR-015, FR-024). Computing it writes nothing.
func (InstallPlan) Lines ¶ added in v0.3.0
func (p InstallPlan) Lines(versionLabel string) []PlanLine
Lines flattens the plan into renderable lines. versionLabel overrides the version text (the wizard prefers the user's chosen label); "" derives it from the resolved revision.
type InstallProgressEvent ¶ added in v0.3.2
type InstallProgressEvent struct {
SkillIndex int // 1-based position in the run
SkillTotal int // total skills in the run
SkillName string
Source string
SourceType string
Version string // resolved version when known
Ref string // requested ref when known
Commit string // resolved commit when known
Phase InstallPhase
Status InstallStatus
Message string
Err error // set only on failed/cancelled terminal events
}
InstallProgressEvent is one observation of an install run. Events are emitted synchronously and strictly sequentially: at most one skill is in a non-terminal state at any time, and each skill emits exactly one terminal event (contracts/install-progress-events.md). SkillName, Source, Version, Ref, and Message may originate from remote content and are untrusted: renderers must sanitize them.
type InstallRequest ¶
type InstallRequest struct {
Root string
Scope string
Mode string
Frozen bool
Offline bool
NoCache bool
UpdateLockfile bool
}
InstallRequest describes an `install` invocation over the existing manifest.
type InstallResult ¶
type InstallResult struct {
Skills []SkillChange
Changed bool
}
InstallResult reports an install run.
type InstallStatus ¶ added in v0.3.2
type InstallStatus string
InstallStatus is a skill's state within an install run. The terminal values reuse the existing lock-install status strings (LockSkillInstalled etc.) so legacy result consumers keep working unchanged.
const ( InstallStatusPending InstallStatus = "pending" InstallStatusRunning InstallStatus = "running" InstallStatusInstalled InstallStatus = InstallStatus(LockSkillInstalled) InstallStatusUpToDate InstallStatus = InstallStatus(LockSkillUpToDate) InstallStatusRepaired InstallStatus = InstallStatus(LockSkillRepaired) InstallStatusSkipped InstallStatus = "skipped" InstallStatusFailed InstallStatus = InstallStatus(LockSkillFailed) InstallStatusCancelled InstallStatus = "cancelled" InstallStatusNotAttempted InstallStatus = "not-attempted" InstallStatusPlanned InstallStatus = InstallStatus(LockSkillPlanned) )
Install statuses. pending and running are event-only; the rest are terminal.
func (InstallStatus) IsTerminal ¶ added in v0.3.2
func (s InstallStatus) IsTerminal() bool
IsTerminal reports whether the status is a final per-skill outcome.
type InstallSummary ¶ added in v0.3.2
type InstallSummary struct {
Total int
Installed int
Repaired int
UpToDate int
Skipped int
Failed int
Cancelled int
NotAttempted int
Planned int
Outcome InstallOutcome
}
InstallSummary aggregates a run's per-skill results into the counters every renderer shares. The invariant Total == sum of all per-status counters (FR-015) holds by construction: Aggregate counts each entry exactly once.
func Aggregate ¶ added in v0.3.2
func Aggregate(skills []LockSkillResult) InstallSummary
Aggregate computes the summary for a run's results. Unknown status strings count toward Total (never silently dropped) and force the failed counter so a miscounted entry can never inflate the success story.
type InstalledSkill ¶ added in v0.1.0
type InstalledSkill struct {
Name string `json:"name"`
Path string `json:"path"`
ContentHash string `json:"content_hash"`
Targets map[string]string `json:"targets"`
}
InstalledSkill reports one installed skill in a (possibly multi-skill) add.
type ListedSkill ¶
type ListedSkill struct {
Name string
Source string
Version string
Status string
Agents []string
Commit string
ContentHash string
Active string
AgentHealth []AgentHealthEntry
}
ListedSkill is one row of `gskill list`. It carries every field `gskill status` used to carry (Commit, ContentHash, Active, AgentHealth) alongside list's own drift Status, so the two commands' data are now one shape (spec 013).
type LockPreview ¶ added in v0.3.0
type LockPreview struct {
Path string
Skills []LockPreviewSkill
}
LockPreview describes the shared lock for the interactive install flow.
type LockPreviewSkill ¶ added in v0.3.0
type LockPreviewSkill struct {
Name string
Source string
// Agents is the entry's currently recorded gskill.agents (nil for a raw,
// unmanaged entry) — used by the TUI to compute the kept/added/removed
// plan before the user confirms an agent selection (spec 013 FR-006).
Agents []string
}
LockPreviewSkill is one entry's display line.
type LockSkillResult ¶ added in v0.3.0
type LockSkillResult struct {
Name string
Source string
Status string
ComputedHash string
// AgentsKept, AgentsAdded, AgentsRemoved are populated only when the run
// had an explicit agent selection (req.Agents != nil) — never based on
// whether the resulting slice happens to be non-empty (spec 013 FR-014).
AgentsKept []string
AgentsAdded []string
AgentsRemoved []string
Err error
// Provenance and failure detail (spec 014): populated for successes and
// failures alike whenever known; empty strings render as "—", never as
// fabricated data (FR-014). Failure is non-nil exactly when the entry
// failed (or was cancelled with a cause).
SourceType string
SkillPath string
RequestedRef string
ResolvedVersion string
ResolvedRef string
Commit string
Agents []string
InstallMode string
Phase InstallPhase
PlannedAction string // dry-run only: would-install|would-repair|would-remove-target|would-update-lock|blocked
Failure *InstallFailure
// StoreReuse reports whether the content store satisfied this skill
// ("reused") or its source was fetched ("downloaded") — spec 015 FR-007.
// Empty when the entry never reached the store (failures, plans).
StoreReuse string
// StoreScope names the physical store that served the skill: "global" or
// "project".
StoreScope string
}
LockSkillResult is one skill's outcome in an InstallFromLock run.
type MigrateReport ¶ added in v0.4.0
type MigrateReport struct {
DryRun bool
// NothingToDo reports an already-migrated project (no legacy store).
NothingToDo bool
Plan migrate.Plan
Result migrate.Result
}
MigrateReport is the outcome of `gskill migrate global-store` (FR-037).
type Options ¶
type Options struct {
Config *config.Config
Logger *slog.Logger
Agents *agent.Registry
Git git.Runner
Repos RepoLister
// GskillHome overrides the resolved gskill home directory (default:
// GSKILL_HOME env, else ~/.gskill). Tests use it for isolated stores.
GskillHome string
}
Options configures New. Nil dependencies are replaced with safe defaults.
type OutdatedReport ¶
type OutdatedReport struct {
Skills []OutdatedSkill
AnyAvailable bool
}
OutdatedReport aggregates an outdated run.
type OutdatedSkill ¶
OutdatedSkill reports one skill's update availability.
type PlanConflict ¶ added in v0.3.0
type PlanConflict struct {
Skill string `json:"skill"`
Kind string `json:"kind"`
Detail string `json:"detail"`
Err error `json:"-"`
}
PlanConflict is one conflict the preview shows. A non-empty conflict list blocks approval (FR-016) and makes ExecutePlan refuse the plan.
type PlanLine ¶ added in v0.3.0
PlanLine is one renderable line of an InstallPlan. The wizard preview and `add --dry-run` both render from this single sequence, so the two surfaces describe the same plan by construction (FR-015/FR-024); renderers add their own styling and prefixes per kind.
type PlanRequest ¶ added in v0.3.0
type PlanRequest struct {
Root string
Source string
Version string
Ref string
Commit string
Discover DiscoverResult
Selected []discovery.DiscoveredSkill
// AgentIDs is the explicit agent selection ([] = resolve via manifest
// defaults, then detection, then the default agent — same as --agent).
AgentIDs []string
Scope string
Mode string
Force bool
// Discovery filters, mirrored from the original DiscoverRequest so a
// version re-pin re-discovers under the SAME constraints the user set
// (review finding: dropping them could remap onto an excluded skill).
MaxDepth int
Include []string
Exclude []string
}
PlanRequest describes phase 3: derive an installation plan from the wizard session (or flag-derived answers). Version/Ref/Commit are the *requested* pins recorded as manifest intent; the resolved revision rides in Discover.
type PlannedAction ¶ added in v0.3.0
type PlannedAction struct {
Skill string `json:"skill"`
AgentID string `json:"agent"`
Destination string `json:"destination"`
MergeInto bool `json:"merge_into,omitempty"` // agent-add into an existing install
FileOps []PlannedFileOp `json:"file_ops,omitempty"`
}
PlannedAction is one skill × agent placement the plan will perform.
type PlannedFileOp ¶ added in v0.3.0
type PlannedFileOp struct {
Path string `json:"path"`
Op string `json:"op"` // "create" or "update"
}
PlannedFileOp is one file the install will create or update (US4).
type ProjectInfo ¶ added in v0.4.0
type ProjectInfo struct {
ProjectID string
Root string
Skills int
LastSeen time.Time
// Missing reports a recorded root that no longer exists on disk.
Missing bool
}
ProjectInfo is one registered project's listing row (contracts §3).
type RemoveResult ¶
RemoveResult reports a remove run.
type RepairResult ¶
RepairResult reports a repair run.
type RepoLister ¶ added in v0.1.0
type RepoLister interface {
ListOwnerRepos(ctx context.Context, owner string) ([]registry.RepoRef, error)
}
RepoLister lists a GitHub owner's repositories, so `find --owner` can fan out across them. The default implementation calls the GitHub REST API; tests inject a fake.
type RequirementCheck ¶
type RequirementCheck struct {
Skill string
Kind string // command | environment | skill | mcp
Name string
Satisfied bool
Checked bool // false for kinds gskill cannot verify (e.g. mcp)
}
RequirementCheck is one declared requirement and whether the environment satisfies it. Requirements are recorded and surfaced only — gskill never resolves them transitively or auto-installs anything (FR-032).
type ScanOptions ¶ added in v0.1.0
ScanOptions configures a read-only source scan.
type SearchHit ¶ added in v0.1.0
type SearchHit struct {
ID string `json:"id"`
DisplayName string `json:"display_name"`
Description string `json:"description"`
Source string `json:"source"`
RepoPath string `json:"repo_path"`
Installed bool `json:"installed"`
Score int `json:"score"`
}
SearchHit is one search result, attributed to its source and in-repo path.
type SkillChange ¶
SkillChange records the per-skill outcome of an install.
type SkillCheck ¶
SkillCheck is one skill's fast drift status.
type SkillHealth ¶ added in v0.1.0
type SkillHealth struct {
Name string
Scope string
StorePresent bool
Hashed bool // whether store/copy content was hash-verified this evaluation
StoreHashOK bool // only meaningful when Hashed
StorePath string
ActiveState active.Health
ActivePath string // project-relative active entry
Agents map[string]TargetState
Modes map[string]string
}
SkillHealth is the evaluated three-hop state for one locked skill.
func (SkillHealth) Faults ¶ added in v0.1.0
func (h SkillHealth) Faults() []string
Faults returns human-readable descriptions of every non-OK rung.
func (SkillHealth) Healthy ¶ added in v0.1.0
func (h SkillHealth) Healthy() bool
Healthy reports whether every rung of the chain is in a good state. When the store was hash-verified, a content mismatch is unhealthy (fail closed).
func (SkillHealth) IntegrityFault ¶ added in v0.1.0
func (h SkillHealth) IntegrityFault() bool
IntegrityFault reports whether any fault is a content-integrity failure — a hash-verified store mismatch or a corrupt copy target — which maps to a fail-closed exit code.
type SkillInfo ¶
type SkillInfo struct {
Name string
Source string
Version string
Commit string
ContentHash string
Description string
License string
Requires skillslock.Requires
Agents []string
Targets map[string]string
}
SkillInfo is the detail shown by `gskill info`.
type SkillInspection ¶ added in v0.1.0
type SkillInspection struct {
Skill discovery.DiscoveredSkill
Source string // source identity (host/owner/repo or local path)
Agents []string // agents the skill would install into at the given root
}
SkillInspection is the detailed view of one discovered skill (FR-033).
type SkillVerify ¶
type SkillVerify struct {
Name string
OK bool
Expected string
Actual string
Issue string // ok | missing | mismatch
}
SkillVerify is one skill's integrity-verification outcome.
type SourceCheckReport ¶ added in v0.1.0
type SourceCheckReport struct {
Invalid []discovery.DiscoveredSkill
Duplicates []discovery.DuplicateConflict
}
SourceCheckReport summarizes a source's defects (FR-034).
func (SourceCheckReport) HasProblems ¶ added in v0.1.0
func (r SourceCheckReport) HasProblems() bool
HasProblems reports whether the source has any invalid or duplicate skills.
type StoreGCReport ¶ added in v0.4.0
type StoreGCReport struct {
Applied bool
globalstore.GCReport
}
StoreGCReport is the outcome of a GC run (contracts §2).
type StoreInspectReport ¶ added in v0.4.0
type StoreInspectReport struct {
Key string
Integrity string // "verified" | the failure detail
SizeBytes int64
Origins []globalstore.Origin
UsedBy []string
Pinned bool
}
StoreInspectReport is one object's detail view (contracts §2).
type StoreListItem ¶ added in v0.4.0
StoreListItem is one object's listing row (contracts §2).
type StoreStatusReport ¶ added in v0.4.0
type StoreStatusReport struct {
Path string
Objects int
SizeBytes int64
Projects int
Unused int
Corrupted int
}
StoreStatusReport summarizes the global store (contracts §2).
type StoreVerifyResult ¶ added in v0.4.0
type StoreVerifyResult struct {
Path string
Checked int
Healthy int
Findings []globalstore.ScanFinding
}
StoreVerifyResult is the outcome of a store-wide verification (FR-022).
func (StoreVerifyResult) Failed ¶ added in v0.4.0
func (r StoreVerifyResult) Failed() bool
Failed reports whether the scan found any problem.
type SyncChange ¶ added in v0.1.0
type SyncChange struct {
Name string `json:"name"`
ContentHash string `json:"content_hash"`
Changed bool `json:"changed"`
AgentsAdded []string `json:"agents_added,omitempty"`
}
SyncChange reports one skill's reconcile outcome.
type SyncRequest ¶
SyncRequest describes a `sync` invocation.
type SyncResult ¶
type SyncResult struct {
Reconciled []SyncChange
Pruned []string
Orphans []string
UpToDate bool
}
SyncResult reports a sync run.
type TargetState ¶ added in v0.1.0
type TargetState string
TargetState classifies one agent target's health relative to the locked state.
const ( TargetOKSymlink TargetState = "ok-symlink" // symlink into the active entry TargetOKCopy TargetState = "ok-copy" // a copy whose content is present TargetMissing TargetState = "missing" // no target on disk TargetBroken TargetState = "broken-link" // symlink whose target is gone TargetForeign TargetState = "foreign" // present but not gskill-managed TargetModeMismatch TargetState = "mode-mismatch" // recorded mode differs from on disk TargetLegacyStore TargetState = "legacy-store" // symlink directly into the store (pre-active-layer) TargetCorrupt TargetState = "corrupt" // a copy whose content no longer matches the lock )
Agent-target health states.
type UnlinkResult ¶ added in v0.1.0
type UnlinkResult struct {
Skill string
UnlinkedAgent string
RemainingAgents []string
Pruned bool
Unreferenced bool
}
UnlinkResult reports the outcome of an unlink.
type VerifyReport ¶
type VerifyReport struct {
Skills []SkillVerify
OK bool
}
VerifyReport aggregates a verify run.
type VersionCandidate ¶ added in v0.3.0
type VersionCandidate struct {
Kind string // VersionLatest | VersionRelease | VersionBranch | VersionCommit
Label string // display text, e.g. "v1.4.0", "main", "latest → v1.4.0"
Version string // bare semver for releases, when parseable
Ref string // tag or branch name to request
Commit string // exact SHA for commit candidates
Metadata string // optional annotation shown next to the label
}
VersionCandidate is one selectable version of a source.
type VersionList ¶ added in v0.3.0
type VersionList struct {
Candidates []VersionCandidate
Degraded bool
DegradedReason string
}
VersionList is the version step's data. Listing problems are never fatal: Degraded marks that browsing is unavailable and why (FR-012).