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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 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 ¶
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 ¶
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 ¶
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 ¶
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.