skills

package
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Feb 20, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Overview

Package skills provides OCI artifact types, media types, local storage, and remote registry operations for ToolHive skill packages.

A skill is an OCI artifact containing MCP server configuration, prompt files, and metadata. This package defines the constants, data structures, storage layer, and registry client that the rest of the ToolHive ecosystem uses to package, push, pull, and cache skills as OCI images.

Media Types and Constants

Standard OCI media types and ToolHive-specific annotation/label keys:

// Artifact type identifies a skill manifest
skills.ArtifactTypeSkill // "dev.toolhive.skills.v1"

// Annotations carry metadata in manifests
skills.AnnotationSkillName
skills.AnnotationSkillVersion

// Labels carry metadata in OCI image configs
skills.LabelSkillName
skills.LabelSkillFiles

Registry Client

The Registry type implements RegistryClient for pushing and pulling skill artifacts to/from OCI-compliant registries (GHCR, ECR, Docker Hub, etc.). It uses ORAS for registry operations and the Docker credential store for authentication by default:

reg, err := skills.NewRegistry()
// Push an artifact
err = reg.Push(ctx, store, indexDigest, "ghcr.io/myorg/my-skill:v1.0.0")
// Pull an artifact
digest, err := reg.Pull(ctx, store, "ghcr.io/myorg/my-skill:v1.0.0")

Use functional options to customise behaviour:

reg, err := skills.NewRegistry(
    skills.WithPlainHTTP(true),           // for local dev registries
    skills.WithCredentialStore(myStore),   // custom auth
)

Stability

This package is Alpha. Breaking changes are possible between minor versions.

Index

Constants

View Source
const (
	// AnnotationSkillName is the annotation key for skill name.
	AnnotationSkillName = "dev.toolhive.skills.name"

	// AnnotationSkillDescription is the annotation key for skill description.
	AnnotationSkillDescription = "dev.toolhive.skills.description"

	// AnnotationSkillVersion is the annotation key for skill version.
	AnnotationSkillVersion = "dev.toolhive.skills.version"

	// AnnotationSkillRequires is the annotation key for skill external dependencies (JSON array of OCI references).
	AnnotationSkillRequires = "dev.toolhive.skills.requires"
)

Annotation keys for skill metadata in manifests.

View Source
const (
	// LabelSkillName is the label key for skill name.
	LabelSkillName = "dev.toolhive.skills.name"

	// LabelSkillDescription is the label key for skill description.
	LabelSkillDescription = "dev.toolhive.skills.description"

	// LabelSkillVersion is the label key for skill version.
	LabelSkillVersion = "dev.toolhive.skills.version"

	// LabelSkillAllowedTools is the label key for allowed tools (JSON array).
	LabelSkillAllowedTools = "dev.toolhive.skills.allowedTools"

	// LabelSkillLicense is the label key for skill license.
	LabelSkillLicense = "dev.toolhive.skills.license"

	// LabelSkillFiles is the label key for skill files (JSON array).
	LabelSkillFiles = "dev.toolhive.skills.files"
)

Label keys for skill metadata in OCI image config.

View Source
const (
	// ArtifactTypeSkill identifies skill artifacts in manifests.
	ArtifactTypeSkill = "dev.toolhive.skills.v1"
)

Artifact type for skill identification.

View Source
const MaxBlobSize int64 = 100 * 1024 * 1024

MaxBlobSize is the maximum size of a blob (100MB).

View Source
const MaxDecompressedSize = 100 * 1024 * 1024

MaxDecompressedSize is the maximum size of decompressed data (100MB). This prevents decompression bombs.

View Source
const MaxManifestSize int64 = 1 * 1024 * 1024

MaxManifestSize is the maximum size of a manifest (1MB).

View Source
const MaxTarFileSize = 100 * 1024 * 1024

MaxTarFileSize is the maximum size of a single file in a tar archive (100MB). This prevents decompression bombs.

Variables

View Source
var DefaultPlatforms = []ocispec.Platform{
	{OS: "linux", Architecture: "amd64"},
	{OS: "linux", Architecture: "arm64"},
}

DefaultPlatforms are the default platforms for skill artifacts. These cover most Kubernetes clusters.

Functions

func Compress

func Compress(data []byte, opts GzipOptions) ([]byte, error)

Compress creates a reproducible gzip compressed byte slice. Headers are explicitly controlled for reproducibility: - ModTime: uses opts.Epoch (defaults to Unix epoch) - Name: empty (no filename) - Comment: empty - OS: 255 (unknown) for cross-platform consistency

func CompressTar

func CompressTar(files []FileEntry, tarOpts TarOptions, gzipOpts GzipOptions) ([]byte, error)

CompressTar creates a reproducible .tar.gz from the given files.

func CreateTar

func CreateTar(files []FileEntry, opts TarOptions) ([]byte, error)

CreateTar creates a reproducible tar archive from the given files. Files are sorted alphabetically and normalized headers are used to ensure deterministic output.

func Decompress

func Decompress(data []byte) ([]byte, error)

Decompress decompresses gzip data.

func DecompressWithLimit

func DecompressWithLimit(data []byte, maxSize int64) ([]byte, error)

DecompressWithLimit decompresses gzip data with a size limit.

func DefaultStoreRoot

func DefaultStoreRoot() string

DefaultStoreRoot returns the default store root directory using XDG base directory conventions.

func ParsePlatform

func ParsePlatform(s string) (ocispec.Platform, error)

ParsePlatform parses a platform string in "os/arch" or "os/arch/variant" format.

func ParseRequiresAnnotation

func ParseRequiresAnnotation(annotations map[string]string) []string

ParseRequiresAnnotation parses skill dependency references from manifest annotations. Returns nil if the annotation is missing or invalid.

func PlatformString

func PlatformString(p ocispec.Platform) string

PlatformString returns the platform in "os/arch" or "os/arch/variant" format.

func StoreRoot

func StoreRoot(dataHome string) string

StoreRoot returns the skills store root within the given data home directory. This is the injectable, testable form. For the standard XDG location, use DefaultStoreRoot.

Types

type FileEntry

type FileEntry struct {
	Path    string // Path within the archive
	Content []byte // File content
	Mode    int64  // File mode (defaults to 0644)
}

FileEntry represents a file to include in a tar archive.

func DecompressTar

func DecompressTar(data []byte) ([]FileEntry, error)

DecompressTar extracts files from a .tar.gz archive.

func ExtractTar

func ExtractTar(data []byte) ([]FileEntry, error)

ExtractTar extracts files from a tar archive.

func ExtractTarWithLimit

func ExtractTarWithLimit(data []byte, maxFileSize int64) ([]FileEntry, error)

ExtractTarWithLimit extracts files from a tar archive with a per-file size limit. It rejects symlinks, hardlinks, device entries, and paths containing traversal sequences.

type GzipOptions

type GzipOptions struct {
	// Level is the compression level (defaults to gzip.BestCompression).
	Level int

	// Epoch is the modification time to use in the gzip header.
	// If zero, uses Unix epoch (1970-01-01) for reproducibility.
	Epoch time.Time
}

GzipOptions configures reproducible gzip compression.

func DefaultGzipOptions

func DefaultGzipOptions() GzipOptions

DefaultGzipOptions returns default options for reproducible gzip compression.

type PackageOptions

type PackageOptions struct {
	// Epoch is the timestamp to use for reproducible builds.
	Epoch time.Time

	// Platforms specifies target platforms for the image index.
	// If empty, defaults to DefaultPlatforms.
	Platforms []ocispec.Platform
}

PackageOptions configures skill packaging.

func DefaultPackageOptions

func DefaultPackageOptions() PackageOptions

DefaultPackageOptions returns default packaging options. Respects SOURCE_DATE_EPOCH for reproducible builds.

type PackageResult

type PackageResult struct {
	IndexDigest    digest.Digest
	ManifestDigest digest.Digest
	ConfigDigest   digest.Digest
	LayerDigest    digest.Digest
	Config         *SkillConfig
	Platforms      []ocispec.Platform
}

PackageResult contains the result of packaging a skill.

type Packager

type Packager struct {
	// contains filtered or unexported fields
}

Packager creates reproducible OCI artifacts from skill directories.

func NewPackager

func NewPackager(store *Store) *Packager

NewPackager creates a new packager with the given store. Panics if store is nil.

func (*Packager) Package

func (p *Packager) Package(ctx context.Context, skillDir string, opts PackageOptions) (*PackageResult, error)

Package packages a skill directory into an OCI artifact in the local store.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry provides operations for pushing and pulling skills from OCI registries.

func NewRegistry

func NewRegistry(opts ...RegistryOption) (*Registry, error)

NewRegistry creates a new registry client with the given options. By default it uses the Docker credential store for authentication.

func (*Registry) Pull

func (r *Registry) Pull(ctx context.Context, store *Store, ref string) (digest.Digest, error)

Pull pulls a skill artifact from a remote registry to the local store. Returns the digest of the pulled artifact (index or manifest).

func (*Registry) Push

func (r *Registry) Push(ctx context.Context, store *Store, artifactDigest digest.Digest, ref string) error

Push pushes a skill artifact from the local store to a remote registry. The digest can be either an index digest or a manifest digest.

type RegistryClient

type RegistryClient interface {
	// Push pushes an artifact from the local store to a remote registry.
	Push(ctx context.Context, store *Store, manifestDigest digest.Digest, ref string) error

	// Pull pulls an artifact from a remote registry into the local store.
	Pull(ctx context.Context, store *Store, ref string) (digest.Digest, error)
}

RegistryClient provides remote OCI registry operations for skills.

type RegistryOption

type RegistryOption func(*Registry)

RegistryOption configures a Registry.

func WithCredentialStore

func WithCredentialStore(store credentials.Store) RegistryOption

WithCredentialStore sets a custom credential store for registry authentication. If not provided, the default Docker credential store is used.

func WithPlainHTTP

func WithPlainHTTP(enabled bool) RegistryOption

WithPlainHTTP configures whether the registry client uses plain HTTP (insecure) connections.

type SkillConfig

type SkillConfig struct {
	Name          string            `json:"name"`
	Description   string            `json:"description"`
	Version       string            `json:"version,omitempty"`
	AllowedTools  []string          `json:"allowedTools,omitempty"`
	License       string            `json:"license,omitempty"`
	Compatibility string            `json:"compatibility,omitempty"`
	Metadata      map[string]string `json:"metadata,omitempty"`
	Files         []string          `json:"files"`
}

SkillConfig represents skill metadata extracted from OCI image config labels.

func SkillConfigFromImageConfig

func SkillConfigFromImageConfig(imgConfig *ocispec.Image) (*SkillConfig, error)

SkillConfigFromImageConfig extracts SkillConfig from OCI image config labels.

type SkillPackager

type SkillPackager interface {
	// Package packages a skill directory into an OCI artifact in the local store.
	Package(ctx context.Context, skillDir string, opts PackageOptions) (*PackageResult, error)
}

SkillPackager creates OCI artifacts from skill directories.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store provides local OCI artifact storage backed by an OCI Image Layout.

func NewStore

func NewStore(root string) (*Store, error)

NewStore creates a new local OCI store at the given root directory. The directory is initialized as an OCI Image Layout with blobs/, oci-layout, and index.json.

func (*Store) GetBlob

func (s *Store) GetBlob(ctx context.Context, d digest.Digest) ([]byte, error)

GetBlob retrieves a blob by digest.

func (*Store) GetIndex

func (s *Store) GetIndex(ctx context.Context, d digest.Digest) (*ocispec.Index, error)

GetIndex retrieves and parses an image index by digest.

func (*Store) GetManifest

func (s *Store) GetManifest(ctx context.Context, d digest.Digest) ([]byte, error)

GetManifest retrieves a manifest by digest.

func (*Store) IsIndex

func (s *Store) IsIndex(ctx context.Context, d digest.Digest) (bool, error)

IsIndex checks if the content at the given digest is an image index.

func (*Store) ListTags

func (s *Store) ListTags(ctx context.Context) ([]string, error)

ListTags returns all tags in the store.

func (*Store) PutBlob

func (s *Store) PutBlob(ctx context.Context, content []byte) (digest.Digest, error)

PutBlob stores a blob and returns its digest.

func (*Store) PutManifest

func (s *Store) PutManifest(ctx context.Context, content []byte) (digest.Digest, error)

PutManifest stores a manifest and returns its digest.

func (*Store) Resolve

func (s *Store) Resolve(ctx context.Context, tag string) (digest.Digest, error)

Resolve resolves a tag to a manifest digest.

func (*Store) Root

func (s *Store) Root() string

Root returns the store root directory.

func (*Store) Tag

func (s *Store) Tag(ctx context.Context, d digest.Digest, tag string) error

Tag associates a tag with a manifest digest.

func (*Store) Target

func (s *Store) Target() oras.Target

Target returns the underlying oras.Target for direct use by registry operations.

type TarOptions

type TarOptions struct {
	// Epoch is the timestamp to use for all files (defaults to Unix epoch).
	Epoch time.Time
}

TarOptions configures reproducible tar archive creation.

func DefaultTarOptions

func DefaultTarOptions() TarOptions

DefaultTarOptions returns default options for reproducible tar archives.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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