catalog

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package catalog discovers installable nib extensions (skills and plugins) from agentskills.io-compatible index sources, merges them across sources, and installs a chosen entry through the skill/plugin managers. It is GUI-free: fetch, parse, crawl, merge, and install only — no terminal or window code.

Index

Constants

View Source
const (
	// SourceIndex is a URL ending in .json, fetched verbatim.
	SourceIndex = "index"
	// SourceWellKnown is a bare host exposing /.well-known/skills/index.json.
	SourceWellKnown = "wellknown"
	// SourceGitHub is a github.com repo, resolved index-first with a crawl fallback.
	SourceGitHub = "github"
	// SourceBundled is the index compiled into the binary (not user-addable).
	SourceBundled = "bundled"
)

Source kind constants: how a source's index is obtained.

Variables

This section is empty.

Functions

func DetectSourceKind

func DetectSourceKind(url string) (kind, label string)

DetectSourceKind classifies a user-pasted source URL and derives a display label. A URL ending in .json is a verbatim index; a github.com/… or git@… URL is a GitHub source; anything else is treated as a bare host exposing a /.well-known/skills/index.json.

func RemoveSource

func RemoveSource(baseDir, label string) error

RemoveSource removes a source by label. Built-in default sources (bundled, agentskills.io, openclaw/agent-skills) are a fixed set and cannot be removed; LoadSources always re-seeds them, so a "removed" default would silently reappear. Use SetSourceEnabled to disable a built-in instead (the bundled source cannot even be disabled).

func SaveSources

func SaveSources(baseDir string, sources []Source) error

SaveSources writes the user-configurable sources to <baseDir>/sources.yaml. The bundled source is never persisted (LoadSources always re-injects it), so it cannot be edited away on disk.

func SetSourceEnabled

func SetSourceEnabled(baseDir, label string, enabled bool) error

SetSourceEnabled toggles a source by label and persists the change. The bundled source is always enabled and cannot be disabled.

Types

type Client

type Client struct {
	HTTP    *http.Client
	RawBase string // raw file host, default https://raw.githubusercontent.com
	APIBase string // GitHub API host, default https://api.github.com
	// Branches is the ordered list of default branches to try for github
	// index-first resolution and crawl.
	Branches []string
}

Client fetches and merges catalog sources over HTTP. RawBase and APIBase are fields so tests can point them at an httptest server; production uses NewClient's public GitHub endpoints.

func NewClient

func NewClient() *Client

NewClient returns a Client with production GitHub endpoints and a 30s timeout.

func (*Client) Fetch

func (c *Client) Fetch(ctx context.Context, s Source) ([]Meta, error)

Fetch resolves a single source to its metas. It never stamps provenance — that happens in Merge. A bundled source reads its embedded index; every other kind fetches over HTTP.

func (*Client) Install

func (c *Client) Install(ctx context.Context, m Meta, baseDir, nibVersion string) (string, error)

Install materializes m into a local directory and installs it through the matching manager, DISABLED. A git locator clones the repo (Ref optional) and installs the Path subdirectory; a ZipURL downloads and extracts the archive. The extension's real origin — not the throwaway extraction dir — is recorded as its registry provenance. It returns the installed extension's name.

func (*Client) Merge

func (c *Client) Merge(ctx context.Context, sources []Source) (metas []Meta, errs []SourceError)

Merge fetches every enabled source concurrently, stamps each Meta with its source label and trust, unions the results, and dedupes by (Kind, Name, Source). A per-source failure is non-fatal: it is collected into errs while the remaining sources still contribute. metas are sorted by category then name for deterministic output regardless of fetch-completion order.

type Kind

type Kind string

Kind is the kind of extension an index entry describes.

const (
	// KindSkill is a skill pack (a SKILL.md tree).
	KindSkill Kind = "skill"
	// KindPlugin is a plugin bundle (a manifested contribution set).
	KindPlugin Kind = "plugin"
)

type Meta

type Meta struct {
	Kind        Kind     `json:"kind"`
	Name        string   `json:"name"`
	Description string   `json:"description"`
	Category    string   `json:"category,omitempty"`
	Tags        []string `json:"tags,omitempty"`

	// install locator (one of):
	GitURL string `json:"gitURL,omitempty"` // clone a whole repo…
	Repo   string `json:"repo,omitempty"`   // …or owner/repo + subpath…
	Path   string `json:"path,omitempty"`
	Ref    string `json:"ref,omitempty"`
	ZipURL string `json:"zipURL,omitempty"` // …or download a zip.

	// provenance (filled by Merge, not by the index):
	Source string `json:"source,omitempty"`
	Trust  string `json:"trust,omitempty"`
}

Meta is the normalized, kind-tagged description of one installable extension, whatever its source. Only Kind, Name, and Description are required; the install locator is one of GitURL, Repo+Path, or ZipURL. Source and Trust are provenance stamped by Merge, never read from an index document.

func ParseIndex

func ParseIndex(data []byte) ([]Meta, error)

ParseIndex parses an agentskills.io index document into metas. It accepts both the object form ({"skills":[…]} and/or {"extensions":[…]}) and a bare top-level array. Each entry's Kind defaults to KindSkill when absent, matching the agentskills.io convention that an index without a kind field lists skills.

type Source

type Source struct {
	Label   string `yaml:"label" json:"label"`
	URL     string `yaml:"url" json:"url"`
	Kind    string `yaml:"kind" json:"kind"`   // index|wellknown|github|bundled
	Trust   string `yaml:"trust" json:"trust"` // official|community
	Enabled bool   `yaml:"enabled" json:"enabled"`
}

Source is a place Metas come from. Kind (auto-detected from URL for user-added sources) drives how the index is obtained. Label is the display name and the dedup/removal key.

func AddSource

func AddSource(baseDir, url string) (Source, error)

AddSource detects the kind/label of a pasted URL, appends it as an enabled community source, and persists it. It errors if a source with that label already exists.

func DefaultSources

func DefaultSources() []Source

DefaultSources returns the seeded sources every install starts with: the always-on bundled starter index, the official agentskills.io well-known catalog, and the openclaw/agent-skills community GitHub catalog.

func LoadSources

func LoadSources(baseDir string) ([]Source, error)

LoadSources returns the effective source list: the seeded defaults overlaid with any user-added or user-modified sources from <baseDir>/sources.yaml. A persisted source with the same Label as a default overrides it (so a user can disable a default), except the bundled source, which is always present and enabled and can never be overridden.

type SourceError

type SourceError struct {
	Source string
	Err    error
}

SourceError is a per-source failure from Merge. The rest of the sources still return, so a single unreachable or malformed source never aborts a browse.

func (SourceError) Error

func (e SourceError) Error() string

Error implements error.

Jump to

Keyboard shortcuts

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