app

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2026 License: MIT Imports: 28 Imported by: 0

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

View Source
const (
	ManifestName = "gskill.toml"
	LockName     = "gskill.lock"
)

Project file and directory names.

Variables

This section is empty.

Functions

This section is empty.

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)
}

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 AgentStatus added in v0.1.0

type AgentStatus struct {
	ID     string `json:"id"`
	Mode   string `json:"mode"`
	Health string `json:"health"`
}

AgentStatus reports one agent target's 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 New

func New(opts Options) *App

New builds an App from opts, filling in defaults for any nil dependency.

func (*App) Add

func (a *App) Add(ctx context.Context, req AddRequest) (AddResult, error)

Add resolves, installs, and records a new skill, updating the manifest and lockfile. 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) Agents

func (a *App) Agents() *agent.Registry

Agents returns the agent registry.

func (*App) Check

func (a *App) Check(_ context.Context, root string, failOnDrift bool) (CheckReport, error)

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) Config

func (a *App) Config() *config.Config

Config returns the resolved configuration.

func (*App) Diff

func (a *App) Diff(_ context.Context, root string) ([]DiffEntry, error)

Diff reports manifest/lock/disk differences per skill.

func (*App) Doctor

func (a *App) Doctor(ctx context.Context, root string) (DoctorReport, error)

Doctor checks the environment (git, detected agents) and reports declared requirements, warning on any that are unmet (FR-032). It never installs.

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) Info

func (a *App) Info(_ context.Context, root, name string) (SkillInfo, error)

Info returns the full detail for one locked skill.

func (*App) Init

func (a *App) Init(_ context.Context, root string) (InitResult, error)

Init scaffolds the project: a gskill.toml manifest, a .gskill state dir, and a .gitignore hint (FR-001). It is idempotent.

func (*App) Install

func (a *App) Install(ctx context.Context, req InstallRequest) (InstallResult, error)

Install materializes every declared skill, additively and idempotently, updating the lockfile only when resolved content changes (FR-022).

func (*App) List

func (a *App) List(_ context.Context, root string) ([]ListedSkill, error)

List returns every declared/locked skill with its drift status.

func (*App) Lock

func (a *App) Lock(ctx context.Context, root string) (InstallResult, error)

Lock recomputes the lockfile from the manifest, honoring existing pins without bumping skills whose declaration is unchanged.

func (*App) Logger

func (a *App) Logger() *slog.Logger

Logger returns the structured logger.

func (*App) Outdated

func (a *App) Outdated(ctx context.Context, root string) (OutdatedReport, error)

Outdated reports available updates per locked skill (FR-009).

func (*App) Remove

func (a *App) Remove(ctx context.Context, root string, names []string) (RemoveResult, error)

Remove uninstalls the named skills from the manifest, lockfile, and every agent directory, then garbage-collects unreferenced store entries.

func (*App) Repair

func (a *App) Repair(ctx context.Context, root string) (RepairResult, error)

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) SkillMarkdown

func (a *App) SkillMarkdown(_ context.Context, root, name string) (string, error)

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) Status added in v0.1.0

func (a *App) Status(_ context.Context, root string) (StatusReport, error)

Status reports the installed skills, their target agents, install modes, and per-target health (FR-021). It is read-only and always succeeds on a readable project (exit 0), so it composes in scripts; use `check` for a non-zero exit on drift. An unreadable manifest is a hard error (exit 3).

func (*App) Sync

func (a *App) Sync(ctx context.Context, req SyncRequest) (SyncResult, error)

Sync reconciles the filesystem to the manifest's desired state across the three layers (store → active → agent). It installs declared-but-missing skills, creates declared-but-missing agent targets, 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 agent targets and active entries the manifest no longer declares; without Prune it reports such orphans instead of deleting them (FR-013).

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 manifest entry are retained unless prune is set, in which case the skill is removed entirely and unreferenced store content is GC'd.

func (*App) Update

func (a *App) Update(ctx context.Context, root string, names []string) (InstallResult, error)

Update re-resolves the named skills (or all when names is empty) to the newest version within their constraints and rewrites the lockfile (FR-009).

func (*App) Verify

func (a *App) Verify(_ context.Context, root string) (VerifyReport, error)

Verify re-hashes every installed skill against the lockfile, failing closed on the first mismatch (exit 6, FR-015).

type CheckReport

type CheckReport struct {
	Skills   []SkillCheck
	HasDrift bool
}

CheckReport aggregates a check run.

type DiffEntry

type DiffEntry struct {
	Name       string
	InManifest bool
	InLock     bool
	Status     string
}

DiffEntry reports how a skill differs across manifest, lock, and disk.

type DoctorReport

type DoctorReport struct {
	GitAvailable   bool
	DetectedAgents []string
	Requirements   []RequirementCheck
	Warnings       []string
}

DoctorReport is the result of `gskill doctor`.

type FindScope added in v0.1.0

type FindScope struct {
	Source string
	Owner  string
	Root   string
}

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

type InitResult struct {
	ManifestPath string
	Created      []string
}

InitResult reports what Init created.

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 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
}

ListedSkill is one row of `gskill list`.

type Options

type Options struct {
	Config *config.Config
	Logger *slog.Logger
	Agents *agent.Registry
	Git    git.Runner
	Repos  RepoLister
}

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

type OutdatedSkill struct {
	Name      string
	Current   string
	Latest    string
	Available bool
}

OutdatedSkill reports one skill's update availability.

type RemoveResult

type RemoveResult struct {
	Removed    []string
	StoreGCed  int
	NotPresent []string
}

RemoveResult reports a remove run.

type RepairResult

type RepairResult struct {
	Repaired       []string
	StagingCleaned int
}

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

type ScanOptions struct {
	Ref      string
	MaxDepth int
	Include  []string
	Exclude  []string
}

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

type SkillChange struct {
	Name        string
	ContentHash string
	Changed     bool
	// ManifestChanged is set when an always-present field (agent set or version
	// pin) was backfilled into the manifest entry this run, so the caller knows
	// to persist gskill.toml (008 FR-008/FR-009). In-memory only.
	ManifestChanged bool
}

SkillChange records the per-skill outcome of an install.

type SkillCheck

type SkillCheck struct {
	Name   string
	Status string
}

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    lockfile.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 SkillStatus added in v0.1.0

type SkillStatus struct {
	Name        string        `json:"name"`
	Source      string        `json:"source"`
	Commit      string        `json:"commit"`
	ContentHash string        `json:"content_hash"`
	Active      string        `json:"active"`
	Agents      []AgentStatus `json:"agents"`
}

SkillStatus reports one skill's source, resolved identity, and per-agent health across the active layer and agent targets.

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 StatusReport added in v0.1.0

type StatusReport struct {
	Skills []SkillStatus
}

StatusReport aggregates a status run.

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

type SyncRequest struct {
	Root    string
	Prune   bool
	Offline bool
}

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.

Jump to

Keyboard shortcuts

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