Documentation
¶
Overview ¶
Package skills provides types and interfaces for managing ToolHive skills.
Index ¶
- Constants
- Variables
- func CheckFilesystem(path string) error
- func LockFileFeatureEnabled() bool
- func Remove(skillDir string) error
- func RemoveEmptyParents(dir, stopAt string)
- func ValidatePathNoSymlinks(targetDir string) error
- func ValidateProjectRoot(projectRoot string) (string, error)
- func ValidateScope(s Scope) error
- func ValidateSkillName(name string) error
- type BuildOptions
- type BuildResult
- type ContentOptions
- type Dependency
- type ExtractResult
- type FailureReason
- type InfoOptions
- type InstallOptions
- type InstallResult
- type InstallStatus
- type InstalledSkill
- type Installer
- type ListOptions
- type LocalBuild
- type ParseResult
- type PathResolver
- type ProvenanceInfo
- type PushOptions
- type Scope
- type SkillContent
- type SkillFileEntry
- type SkillFrontmatter
- type SkillIndex
- type SkillIndexEntry
- type SkillInfo
- type SkillLockService
- type SkillMetadata
- type SkillService
- type StringOrSlice
- type SyncFailure
- type SyncOptions
- type SyncResult
- type UninstallOptions
- type UpgradeOptions
- type UpgradeOutcome
- type UpgradeResult
- type UpgradeStatus
- type ValidationResult
Constants ¶
const ( // MaxTotalExtractSize is the maximum total decompressed size (500MB). MaxTotalExtractSize int64 = 500 * 1024 * 1024 // MaxFileExtractSize is the maximum size per file in the tar archive (100MB). // Matches the toolhive-core default. MaxFileExtractSize int64 = 100 * 1024 * 1024 // MaxExtractFileCount is the maximum number of files allowed in an archive. MaxExtractFileCount = 1000 // DirPermissions is the permission mode for created directories. DirPermissions os.FileMode = 0750 // FilePermissionMask strips setuid, setgid, sticky bits and caps at 0644. FilePermissionMask os.FileMode = 0644 // PluginFilePermissionMask strips setuid, setgid, sticky bits and caps at // 0755, preserving the executable bit so plugin hook scripts keep +x. // For non-executable files (mode 0644), 0644 & 0755 = 0644 — no change. PluginFilePermissionMask os.FileMode = 0755 )
const LockFileEnvVar = "TOOLHIVE_SKILLS_LOCK_ENABLED"
LockFileEnvVar gates the project-level skills lock file feature (RFC THV-0080) while it lands across multiple PRs. The feature is inert on main until every PR in the stack — lock file, sync, upgrade, and Sigstore signing/verification — has merged; this keeps each PR mergeable on its own without exposing partial, unsigned-by-default behavior in between.
This is intentionally a plain env var, not persisted config or a CLI flag: it exists only for the duration of the rollout and is expected to be removed once the feature ships, matching the existing TOOLHIVE_DEV / TOOLHIVE_REMOTE_HEALTHCHECKS precedent for staged/dev-only behavior.
const MaxCompatibilityLength = 500
MaxCompatibilityLength is the maximum allowed length for the compatibility field.
const MaxDependencies = 100
MaxDependencies is the maximum number of dependencies allowed per skill. This prevents resource exhaustion from malicious or misconfigured skills.
const MaxDescriptionLength = 1024
MaxDescriptionLength is the maximum allowed length for the description field.
const MaxFrontmatterSize = 64 * 1024 // 64KB
MaxFrontmatterSize is the maximum size of frontmatter content in bytes. This prevents YAML parsing attacks (e.g., billion laughs).
const RecommendedMaxSkillMDLines = 500
RecommendedMaxSkillMDLines is the recommended maximum number of lines in SKILL.md. Exceeding this generates a warning, not an error.
Variables ¶
var ErrInvalidFrontmatter = errors.New("invalid frontmatter")
ErrInvalidFrontmatter indicates that the SKILL.md frontmatter is malformed.
Functions ¶
func CheckFilesystem ¶ added in v0.10.0
CheckFilesystem walks the directory once, checking for symlinks and path traversal.
func LockFileFeatureEnabled ¶ added in v0.41.0
func LockFileFeatureEnabled() bool
LockFileFeatureEnabled reports whether the project-level skills lock file feature is enabled for this process.
func Remove ¶ added in v0.10.0
Remove safely removes a skill directory. Returns nil if the directory does not exist.
func RemoveEmptyParents ¶ added in v0.22.0
func RemoveEmptyParents(dir, stopAt string)
RemoveEmptyParents walks up from dir, removing each directory that is empty, stopping at stopAt (which is never removed) or when a non-empty directory is encountered. Errors are silently ignored — this is best-effort cleanup.
func ValidatePathNoSymlinks ¶ added in v0.11.3
ValidatePathNoSymlinks walks up from the target path checking each existing path component for symlinks. This prevents symlink attacks where an attacker places a symlink at a parent directory before extraction.
func ValidateProjectRoot ¶ added in v0.11.0
ValidateProjectRoot validates a project root path and returns its cleaned form. Symlinks are rejected to avoid unexpected filesystem traversal.
func ValidateScope ¶ added in v0.9.4
ValidateScope checks that a scope value is valid. An empty scope is accepted (meaning "unscoped" / "all"). Otherwise only "user" and "project" are allowed.
func ValidateSkillName ¶ added in v0.9.4
ValidateSkillName checks that a skill name conforms to the Agent Skills specification. Names must be 2-64 lowercase alphanumeric characters or hyphens, starting and ending with alphanumeric, with no consecutive hyphens. See: https://agentskills.io/specification
Types ¶
type BuildOptions ¶
type BuildOptions struct {
// Path is the local directory path containing the skill definition.
Path string `json:"path"`
// Tag is the OCI tag to use for the built artifact.
Tag string `json:"tag,omitempty"`
}
BuildOptions configures the behavior of the Build operation.
type BuildResult ¶
type BuildResult struct {
// Reference is the OCI reference of the built skill artifact.
Reference string `json:"reference"`
}
BuildResult contains the outcome of a Build operation.
type ContentOptions ¶ added in v0.21.0
type ContentOptions struct {
// Reference is an OCI reference (e.g. ghcr.io/org/skill:v1) or a local build tag.
Reference string `json:"reference"`
}
ContentOptions configures the behavior of the GetContent operation.
type Dependency ¶ added in v0.9.3
type Dependency struct {
// Name is the dependency name.
Name string `json:"name,omitempty"`
// Reference is the OCI reference for the dependency.
Reference string `json:"reference"`
// Digest is the OCI digest for upgrade detection.
Digest string `json:"digest,omitempty"`
}
Dependency represents an external skill dependency (OCI reference).
type ExtractResult ¶ added in v0.10.0
type ExtractResult struct {
// SkillDir is the absolute path where the skill was extracted.
SkillDir string
// Files is the number of files written.
Files int
}
ExtractResult contains the outcome of an Extract operation.
func Extract ¶ added in v0.10.0
func Extract(layerData []byte, targetDir string, force bool) (*ExtractResult, error)
Extract decompresses a tar.gz OCI layer and writes files to targetDir. If targetDir exists and force is false, an error is returned. If force is true, the existing directory is removed before extraction.
func ExtractPlugin ¶ added in v0.34.0
func ExtractPlugin(layerData []byte, targetDir string, force bool) (*ExtractResult, error)
ExtractPlugin is like Extract but uses PluginFilePermissionMask (0755) so executable files (hook scripts, entry points) keep their +x bit. Used by plugin adapters which install multi-component trees that may include executable hooks — unlike skills, which are single markdown files.
type FailureReason ¶ added in v0.41.0
type FailureReason string
FailureReason is a typed failure reason for sync/upgrade operations, per RFC THV-0080's exit-code and automation contract. Only reasons the current feature set can actually produce are defined; the RFC's remaining values (the Sigstore verification reasons and ref-change-blocked, which surfaces as an UpgradeStatus rather than a failure) land together with the code that emits them.
const ( // FailureReasonRegistryUnreachable means the skill's remote source — an // OCI registry or a git host — could not be reached. FailureReasonRegistryUnreachable FailureReason = "registry-unreachable" FailureReasonDigestMissing FailureReason = "digest-missing" FailureReasonValidationRejected FailureReason = "validation-rejected" FailureReasonLockWriteFailed FailureReason = "lock-write-failed" FailureReasonUnknown FailureReason = "unknown" )
Typed failure reasons for sync/upgrade operations.
type InfoOptions ¶
type InfoOptions struct {
// Name is the skill name to look up.
Name string `json:"name"`
// Scope filters the lookup by installation scope.
Scope Scope `json:"scope,omitempty"`
// ProjectRoot filters the lookup by project root path.
ProjectRoot string `json:"project_root,omitempty"`
}
InfoOptions configures the behavior of the Info operation.
type InstallOptions ¶
type InstallOptions struct {
// Name is the skill name or OCI reference to install.
Name string `json:"name"`
// Version is the specific version to install. Empty means latest.
Version string `json:"version,omitempty"`
// Scope is the installation scope.
Scope Scope `json:"scope,omitempty"`
// Clients lists target clients (e.g., "claude-code"). Empty means first skill-supporting client.
Clients []string `json:"clients,omitempty"`
// Force allows overwriting unmanaged skill directories.
Force bool `json:"force,omitempty"`
// ProjectRoot is the project root path for project-scoped installs.
ProjectRoot string `json:"project_root,omitempty"`
// Group is the group name to add the skill to after installation.
Group string `json:"group,omitempty"`
// AllowUnsigned permits installing a project-scoped skill whose artifact
// carries no Sigstore signature. Without it, unsigned artifacts are
// rejected; with it, the lock entry records the exception as
// "unsigned: true". Skill content is AI-executed instructions, so this
// is an explicit per-install trust decision, never a default.
AllowUnsigned bool `json:"allow_unsigned,omitempty"`
// LayerData is the tar.gz content from an OCI layer. Internal use only — NOT exposed via HTTP API.
LayerData []byte `json:"-"`
// Reference is the full OCI reference (e.g. ghcr.io/org/skill:v1).
Reference string `json:"-"`
// Digest is the OCI digest for upgrade detection.
Digest string `json:"-"`
// LockSource overrides the value recorded as the lock entry's Source. When
// empty, the entry's Source is Name as given by the caller before any
// internal resolution. Set by Sync/Upgrade, which pass an already-resolved
// Name that must not overwrite the entry's original Source. Internal use
// only — NOT exposed via HTTP API.
LockSource string `json:"-"`
// LockResolvedReference overrides the value recorded as the lock entry's
// ResolvedReference. When empty, the entry's ResolvedReference is
// whatever this install actually resolved to. Set by Sync when
// reinstalling at a pinned reference: without this override, a drift
// repair would overwrite ResolvedReference with the internal pinned
// form (e.g. a digest or commit hash spliced into the reference)
// instead of preserving what Source originally resolved to. Internal
// use only — NOT exposed via HTTP API.
LockResolvedReference string `json:"-"`
// RequiredByParent is set when this install is a transitively materialized
// dependency (toolhive.requires) of another skill, naming that parent.
// Empty means the user explicitly requested this install. Internal use
// only — NOT exposed via HTTP API.
RequiredByParent string `json:"-"`
// Visited tracks skill names already materialized in this dependency
// tree, preventing infinite recursion on a requires cycle. Left nil by
// external callers; Install initializes it on first entry and threads it
// through recursive dependency installs. Internal use only — NOT exposed
// via HTTP API.
Visited map[string]struct{} `json:"-"`
// SyncRestore forces re-extraction to every existing client even when
// Digest matches the currently-installed digest. Set by Sync when
// reinstalling at a pinned reference: the whole point is repairing
// on-disk drift that happened without the pinned digest changing, so the
// normal "same digest means content is already correct" fast path must
// not apply. Internal use only — NOT exposed via HTTP API.
SyncRestore bool `json:"-"`
// Provenance carries the verified signer identity established during
// install-time verification, for recording into the lock entry. Set by
// the verification step, nil when the artifact is unsigned or
// verification did not run. Internal use only — NOT exposed via HTTP API.
Provenance *ProvenanceInfo `json:"-"`
// SigstoreBundle is the serialized Sigstore bundle backing Provenance,
// persisted alongside the install record so sync can re-verify offline.
// Internal use only — NOT exposed via HTTP API.
SigstoreBundle []byte `json:"-"`
}
InstallOptions configures the behavior of the Install operation.
type InstallResult ¶
type InstallResult struct {
// Skill is the installed skill.
Skill InstalledSkill `json:"skill"`
// PreExisting is the store record as it was before this install, or nil
// when this install created the record. Rollback uses it to restore the
// previous state instead of destructively deleting a record this call
// did not create. Internal use only — NOT exposed via HTTP API.
PreExisting *InstalledSkill `json:"-"`
}
InstallResult contains the outcome of an Install operation.
type InstallStatus ¶
type InstallStatus string
InstallStatus represents the current status of a skill installation.
const ( // InstallStatusInstalled indicates a skill is fully installed and ready. InstallStatusInstalled InstallStatus = "installed" // InstallStatusPending indicates a skill installation is in progress. InstallStatusPending InstallStatus = "pending" // InstallStatusFailed indicates a skill installation has failed. InstallStatusFailed InstallStatus = "failed" )
type InstalledSkill ¶
type InstalledSkill struct {
// Metadata contains the skill's metadata.
Metadata SkillMetadata `json:"metadata"`
// Scope is the installation scope (user or project).
Scope Scope `json:"scope"`
// ProjectRoot is the project root path for project-scoped skills. Empty for user-scoped.
ProjectRoot string `json:"project_root,omitempty"`
// Reference is the full OCI reference (e.g. ghcr.io/org/skill:v1).
Reference string `json:"reference,omitempty"`
// Tag is the OCI tag (e.g. v1.0.0).
Tag string `json:"tag,omitempty"`
// Digest is the OCI digest (sha256:...) for upgrade detection.
Digest string `json:"digest,omitempty"`
// Status is the current installation status.
Status InstallStatus `json:"status"`
// InstalledAt is the timestamp when the skill was installed.
InstalledAt time.Time `json:"installed_at"`
// Clients is the list of client identifiers the skill is installed for.
// TODO: Refactor client.ClientApp to a shared package so it can be used here instead of []string.
Clients []string `json:"clients,omitempty"`
// Dependencies is the list of external skill dependencies.
Dependencies []Dependency `json:"dependencies,omitempty"`
// Managed indicates this install is tracked in the project's
// toolhive.lock.yaml. Only ever true for project-scoped installs. No
// omitempty: false is an observable state (unmanaged), not an absence.
Managed bool `json:"managed"`
// SigstoreBundle is the serialized Sigstore bundle captured at install
// time, used for offline re-verification during sync. Nil for unsigned
// installs. Never serialized to API responses.
SigstoreBundle []byte `json:"-"`
}
InstalledSkill represents a skill that has been installed locally.
type Installer ¶ added in v0.10.0
type Installer interface {
// Extract decompresses a tar.gz OCI layer and writes files to targetDir.
Extract(layerData []byte, targetDir string, force bool) (*ExtractResult, error)
// ExtractPlugin is like Extract but preserves the executable bit (cap 0755)
// so plugin hook scripts keep +x. Used by plugin adapters.
ExtractPlugin(layerData []byte, targetDir string, force bool) (*ExtractResult, error)
// Remove safely removes a skill directory.
Remove(skillDir string) error
}
Installer handles filesystem operations for skill installation and removal.
func NewInstaller ¶ added in v0.10.0
func NewInstaller() Installer
NewInstaller returns a production Installer that delegates to the package-level Extract and Remove functions.
type ListOptions ¶
type ListOptions struct {
// Scope filters results by installation scope.
Scope Scope `json:"scope,omitempty"`
// ClientApp filters results by client application.
ClientApp string `json:"client,omitempty"`
// ProjectRoot filters results by project root path.
ProjectRoot string `json:"project_root,omitempty"`
// Group filters results to only skills that belong to the specified group.
Group string `json:"group,omitempty"`
}
ListOptions configures the behavior of the List operation.
type LocalBuild ¶ added in v0.16.0
type LocalBuild struct {
// Tag is the OCI tag or name used to reference the artifact.
Tag string `json:"tag"`
// Digest is the OCI digest of the artifact (sha256:...).
Digest string `json:"digest"`
// Name is the skill name extracted from the artifact metadata, if available.
Name string `json:"name,omitempty"`
// Description is the skill description extracted from the artifact metadata, if available.
Description string `json:"description,omitempty"`
// Version is the skill version extracted from the artifact metadata, if available.
Version string `json:"version,omitempty"`
}
LocalBuild represents a locally-built OCI skill artifact in the local store.
type ParseResult ¶ added in v0.9.3
type ParseResult struct {
Name string
Description string
Version string
AllowedTools []string
License string
Compatibility string
Metadata map[string]string
Requires []Dependency
Body []byte
}
ParseResult contains the parsed contents of a SKILL.md file.
func ParseSkillMD ¶ added in v0.9.3
func ParseSkillMD(content []byte) (*ParseResult, error)
ParseSkillMD parses a SKILL.md file and extracts frontmatter and body.
type PathResolver ¶ added in v0.10.0
type PathResolver interface {
// GetSkillPath returns the filesystem path where a skill should be installed.
GetSkillPath(clientType, skillName string, scope Scope, projectRoot string) (string, error)
// ListSkillSupportingClients returns all client identifiers that support skills.
ListSkillSupportingClients() []string
}
PathResolver resolves filesystem paths for skill installations. It uses string (not client.ClientApp) to avoid importing pkg/client from pkg/skills.
type ProvenanceInfo ¶ added in v0.41.0
type ProvenanceInfo struct {
// SignerIdentity is the certificate subject identity (workflow path for
// GitHub Actions certificates, SAN verbatim otherwise).
SignerIdentity string `json:"-"`
// CertIssuer is the OIDC issuer that authenticated the signer.
CertIssuer string `json:"-"`
// RepositoryURI is the source repository from the certificate
// extensions, when present.
RepositoryURI string `json:"-"`
// SigstoreURL is the Sigstore instance the signature chains to.
SigstoreURL string `json:"-"`
}
ProvenanceInfo is the verified signer identity of an installed artifact, the in-memory mirror of the lock file's provenance block.
type PushOptions ¶
type PushOptions struct {
// Reference is the OCI reference to push.
Reference string `json:"reference"`
}
PushOptions configures the behavior of the Push operation.
type SkillContent ¶ added in v0.21.0
type SkillContent struct {
// Name is the skill name from the OCI config labels.
Name string `json:"name"`
// Description is the skill description from the OCI config labels.
Description string `json:"description"`
// Version is the skill version from the OCI config labels.
Version string `json:"version,omitempty"`
// License is the SPDX license identifier from the OCI config labels.
License string `json:"license,omitempty"`
// Body is the raw SKILL.md markdown content.
Body string `json:"body"`
// Files is the list of all files in the artifact with their sizes.
Files []SkillFileEntry `json:"files"`
}
SkillContent contains the SKILL.md body and file listing extracted from an OCI artifact.
type SkillFileEntry ¶ added in v0.21.0
type SkillFileEntry struct {
// Path is the file path within the artifact.
Path string `json:"path"`
// Size is the uncompressed file size in bytes.
Size int `json:"size"`
}
SkillFileEntry represents a single file within a skill artifact.
type SkillFrontmatter ¶ added in v0.9.3
type SkillFrontmatter struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Version string `yaml:"version,omitempty"`
AllowedTools StringOrSlice `yaml:"allowed-tools,omitempty"`
Requires StringOrSlice `yaml:"toolhive.requires,omitempty"`
License string `yaml:"license,omitempty"`
Compatibility string `yaml:"compatibility,omitempty"`
Metadata map[string]string `yaml:"metadata,omitempty"`
}
SkillFrontmatter represents the raw YAML frontmatter from a SKILL.md file.
type SkillIndex ¶
type SkillIndex struct {
// Skills is the list of available skills.
Skills []SkillIndexEntry `json:"skills"`
}
SkillIndex represents a collection of available skills from a remote index.
type SkillIndexEntry ¶
type SkillIndexEntry struct {
// Metadata contains the skill's metadata.
Metadata SkillMetadata `json:"metadata"`
// Repository is the OCI repository reference for the skill.
Repository string `json:"repository"`
// Group is the optional group this skill belongs to.
Group string `json:"group,omitempty"`
}
SkillIndexEntry represents a single skill entry in a remote skill index.
type SkillInfo ¶
type SkillInfo struct {
// Metadata contains the skill's metadata.
Metadata SkillMetadata `json:"metadata"`
// InstalledSkill contains the full installation record.
InstalledSkill *InstalledSkill `json:"installed_skill,omitempty"`
}
SkillInfo contains detailed information about an installed skill.
type SkillLockService ¶ added in v0.41.0
type SkillLockService interface {
// Sync restores the project's installed skills to match its lock file.
Sync(ctx context.Context, opts SyncOptions) (*SyncResult, error)
// Upgrade re-resolves each lock entry's source and installs newer content
// when the resolved digest has changed.
Upgrade(ctx context.Context, opts UpgradeOptions) (*UpgradeResult, error)
}
SkillLockService defines the interface for operations driven by a project's toolhive.lock.yaml. It is separate from SkillService because Sync and Upgrade operate over the whole lock file rather than a single named skill, per RFC THV-0080.
type SkillMetadata ¶
type SkillMetadata struct {
// Name is the unique name of the skill.
Name string `json:"name"`
// Version is the semantic version of the skill.
Version string `json:"version"`
// Description is a human-readable description of the skill.
Description string `json:"description"`
// Author is the skill author or maintainer.
Author string `json:"author"`
// Tags is a list of tags for categorization.
Tags []string `json:"tags,omitempty"`
}
SkillMetadata contains metadata about a skill.
type SkillService ¶
type SkillService interface {
// List returns all installed skills matching the given options.
List(ctx context.Context, opts ListOptions) ([]InstalledSkill, error)
// Install installs a skill from a remote source.
Install(ctx context.Context, opts InstallOptions) (*InstallResult, error)
// Uninstall removes an installed skill.
Uninstall(ctx context.Context, opts UninstallOptions) error
// Info returns detailed information about a skill.
Info(ctx context.Context, opts InfoOptions) (*SkillInfo, error)
// Validate checks whether a skill definition is valid.
Validate(ctx context.Context, path string) (*ValidationResult, error)
// Build builds a skill from a local directory into an OCI artifact.
Build(ctx context.Context, opts BuildOptions) (*BuildResult, error)
// Push pushes a built skill artifact to a remote registry.
Push(ctx context.Context, opts PushOptions) error
// ListBuilds returns all locally-built OCI skill artifacts in the local store.
ListBuilds(ctx context.Context) ([]LocalBuild, error)
// DeleteBuild removes a locally-built OCI skill artifact from the local store.
DeleteBuild(ctx context.Context, tag string) error
// GetContent retrieves the SKILL.md body and file listing from an OCI artifact
// without installing it. Works for both remote registry references and local build tags.
GetContent(ctx context.Context, opts ContentOptions) (*SkillContent, error)
}
SkillService defines the interface for managing skills.
type StringOrSlice ¶ added in v0.9.3
type StringOrSlice []string
StringOrSlice is a custom type that can unmarshal from either a YAML string (space-delimited per spec, or comma-delimited for compatibility) or a YAML array.
func (*StringOrSlice) UnmarshalYAML ¶ added in v0.9.3
func (s *StringOrSlice) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML implements yaml.Unmarshaler for StringOrSlice. Per the Agent Skills spec, allowed-tools is space-delimited, but we also support comma-delimited for compatibility with existing skills.
type SyncFailure ¶ added in v0.41.0
type SyncFailure struct {
// Name is the skill name that failed.
Name string `json:"name"`
// Reason is a typed failure reason for CI and automation.
Reason FailureReason `json:"reason,omitempty"`
// Error is a human-readable description of the failure.
Error string `json:"error"`
}
SyncFailure describes a single skill that failed to sync.
type SyncOptions ¶ added in v0.41.0
type SyncOptions struct {
// ProjectRoot is the project root path whose lock file should be synced.
ProjectRoot string `json:"project_root"`
// Clients lists target clients (e.g., "claude-code"). Empty means every
// skill-supporting client detected on this host.
Clients []string `json:"clients,omitempty"`
// Prune removes project-scoped skills that are installed but not present
// in the lock file. When false, such skills are only reported.
Prune bool `json:"prune,omitempty"`
// Check verifies on-disk content against contentDigest without installing
// or writing anything.
Check bool `json:"check,omitempty"`
// Adopt writes lock entries for existing unmanaged project-scope installs.
Adopt bool `json:"adopt,omitempty"`
}
SyncOptions configures the behavior of the Sync operation.
type SyncResult ¶ added in v0.41.0
type SyncResult struct {
// Installed lists skills that were installed or reinstalled to match the lock file.
Installed []string `json:"installed,omitempty"`
// Drifted lists skills whose on-disk contentDigest differed from the lock
// file. Normally these are reinstalled to match it; when Check is set,
// nothing is written and this field reports the drift only.
Drifted []string `json:"drifted,omitempty"`
// Missing lists lock entries with no corresponding install record at all
// — the fresh-clone state. Normally these are installed at their pinned
// reference; when Check is set, nothing is written and this field
// reports the gap only.
Missing []string `json:"missing,omitempty"`
// AlreadyCurrent lists skills that already matched the lock file.
AlreadyCurrent []string `json:"already_current,omitempty"`
// NeverManaged lists project-scoped skills never recorded as lock-managed.
NeverManaged []string `json:"never_managed,omitempty"`
// RemovedFromLock lists previously managed skills absent from the lock file.
RemovedFromLock []string `json:"removed_from_lock,omitempty"`
// Pruned lists removed-from-lock skills that were uninstalled because Prune was set.
Pruned []string `json:"pruned,omitempty"`
// Failed lists skills that could not be synced, with the reason for each.
// Drift alone is never reported here — see Drifted.
Failed []SyncFailure `json:"failed,omitempty"`
}
SyncResult contains the outcome of a Sync operation.
type UninstallOptions ¶
type UninstallOptions struct {
// Name is the skill name to uninstall.
Name string `json:"name"`
// Scope is the scope from which to uninstall.
Scope Scope `json:"scope,omitempty"`
// ProjectRoot is the project root path for project-scoped skills.
ProjectRoot string `json:"project_root,omitempty"`
// Visited tracks skill names already removed in this cascade-uninstall
// tree, preventing infinite recursion on a requiredBy cycle. Left nil by
// external callers; Uninstall initializes it on first entry and threads
// it through recursive cascade removals. Internal use only — NOT exposed
// via HTTP API.
Visited map[string]struct{} `json:"-"`
}
UninstallOptions configures the behavior of the Uninstall operation.
type UpgradeOptions ¶ added in v0.41.0
type UpgradeOptions struct {
// ProjectRoot is the project root path whose lock file should be upgraded.
ProjectRoot string `json:"project_root"`
// Names restricts the upgrade to specific skill names. Empty means every
// entry in the lock file.
Names []string `json:"names,omitempty"`
// Preview reports what would change without installing (still fetches
// artifacts to compare digests).
Preview bool `json:"preview,omitempty"`
// FailOnChanges exits with an error when any mutable source would upgrade.
FailOnChanges bool `json:"fail_on_changes,omitempty"`
// AllowRefChange permits resolvedReference changes during upgrade.
AllowRefChange bool `json:"allow_ref_change,omitempty"`
// Clients lists target clients (e.g., "claude-code"). Empty means every
// skill-supporting client detected on this host.
Clients []string `json:"clients,omitempty"`
}
UpgradeOptions configures the behavior of the Upgrade operation.
type UpgradeOutcome ¶ added in v0.41.0
type UpgradeOutcome struct {
// Name is the skill name.
Name string `json:"name"`
// Status is the outcome of the upgrade attempt.
Status UpgradeStatus `json:"status"`
// OldDigest is the digest pinned in the lock file before this operation.
OldDigest string `json:"old_digest,omitempty"`
// NewDigest is the digest the source currently resolves to. Equal to
// OldDigest when Status is UpgradeStatusUpToDate.
NewDigest string `json:"new_digest,omitempty"`
// NewResolvedReference is the new resolvedReference when it changed.
NewResolvedReference string `json:"new_resolved_reference,omitempty"`
// Reason is a typed failure reason when Status is UpgradeStatusFailed.
Reason FailureReason `json:"reason,omitempty"`
// Error is a human-readable description of the failure, set only when Status is UpgradeStatusFailed.
Error string `json:"error,omitempty"`
}
UpgradeOutcome describes the result of attempting to upgrade one skill.
type UpgradeResult ¶ added in v0.41.0
type UpgradeResult struct {
// Outcomes contains one entry per skill considered for upgrade.
Outcomes []UpgradeOutcome `json:"outcomes"`
}
UpgradeResult contains the outcome of an Upgrade operation.
type UpgradeStatus ¶ added in v0.41.0
type UpgradeStatus string
UpgradeStatus represents the outcome of upgrading a single skill.
const ( // UpgradeStatusUpgraded indicates the skill was installed at a new digest. UpgradeStatusUpgraded UpgradeStatus = "upgraded" // UpgradeStatusUpToDate indicates the resolved source still points at the pinned digest. UpgradeStatusUpToDate UpgradeStatus = "up-to-date" // UpgradeStatusNotUpgradable indicates the entry is pinned to an immutable // reference (an OCI digest or a full git commit hash) and cannot be upgraded. UpgradeStatusNotUpgradable UpgradeStatus = "not-upgradable" // UpgradeStatusRefChangeBlocked indicates re-resolution changed resolvedReference. UpgradeStatusRefChangeBlocked UpgradeStatus = "ref-change-blocked" // UpgradeStatusFailed indicates the upgrade attempt failed. UpgradeStatusFailed UpgradeStatus = "failed" )
type ValidationResult ¶
type ValidationResult struct {
// Valid indicates whether the skill definition is valid.
Valid bool `json:"valid"`
// Errors is a list of validation errors, if any.
Errors []string `json:"errors,omitempty"`
// Warnings is a list of non-blocking validation warnings, if any.
Warnings []string `json:"warnings,omitempty"`
}
ValidationResult contains the outcome of a Validate operation.
func ValidateSkillDir ¶ added in v0.9.3
func ValidateSkillDir(path string) (*ValidationResult, error)
ValidateSkillDir validates a skill directory at the given path. I/O errors are returned as error; validation issues are returned in ValidationResult.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package client provides an HTTP client for the ToolHive Skills API.
|
Package client provides an HTTP client for the ToolHive Skills API. |
|
Package gitresolver resolves skill installations from git repositories.
|
Package gitresolver resolves skill installations from git repositories. |
|
mocks
Package mocks is a generated GoMock package.
|
Package mocks is a generated GoMock package. |
|
Package lockfile manages the project-level skills lock file (toolhive.lock.yaml).
|
Package lockfile manages the project-level skills lock file (toolhive.lock.yaml). |
|
Package mocks is a generated GoMock package.
|
Package mocks is a generated GoMock package. |
|
Package signer signs skill OCI artifacts with Sigstore, following the cosign key-pair convention: a "simple signing" payload binding the artifact's manifest digest is signed with the user's key, attached to the registry as a cosign signature manifest (the "sha256-<hex>.sig" tag), and returned as a serialized Sigstore bundle for durable storage and offline re-verification.
|
Package signer signs skill OCI artifacts with Sigstore, following the cosign key-pair convention: a "simple signing" payload binding the artifact's manifest digest is signed with the user's key, attached to the registry as a cosign signature manifest (the "sha256-<hex>.sig" tag), and returned as a serialized Sigstore bundle for durable storage and offline re-verification. |
|
Package skillsvc provides the default implementation of skills.SkillService.
|
Package skillsvc provides the default implementation of skills.SkillService. |