Documentation
¶
Overview ¶
Package registry is the discovery half of TaskYou's plugin story.
Installing a plugin used to require knowing that github.com/taskyou/plugins existed and typing its URL. A registry fixes that: it is a small JSON catalog of installable plugins, so every surface can offer *search* ("what can I install that posts to Slack?") before it offers *install*.
Three layers, most-trusted-last:
- A snapshot bundled into the binary (catalog.json, embedded). Discovery therefore works on a fresh install, offline, with zero configuration.
- The on-disk cache of each remote catalog, refreshed in the background.
- A live fetch of each remote catalog when the cache is older than the TTL.
Later layers overlay earlier ones by entry ID, so a published catalog can correct or extend what a shipped binary knows without a release. A failed fetch is never fatal — it degrades to the cache, then to the bundle.
Index ¶
Constants ¶
const BundledOrigin = "bundled"
BundledOrigin is the Origin.URL value for the embedded snapshot.
const CatalogEnv = "TY_PLUGIN_REGISTRY"
CatalogEnv overrides the remote catalog list with a comma-separated set of URLs. Set it to "" (explicitly empty) to use only the bundled snapshot — which is what the tests and air-gapped installs want.
const DefaultCatalogURL = "https://taskyou.dev/registry.json"
DefaultCatalogURL is the community catalog published from the TaskYou docs site (docs/registry.json in the main repo). It is the same document embedded in the binary, so the fetch only ever brings news.
const DefaultTTL = 6 * time.Hour
DefaultTTL is how long a cached catalog is served before it is re-fetched.
const SchemaVersion = 1
SchemaVersion is the catalog format this build reads and writes. Readers accept anything at or below it; a newer catalog is still parsed (unknown fields are ignored) so an old binary keeps working against a new catalog.
Variables ¶
This section is empty.
Functions ¶
func Categories ¶
Categories returns the distinct categories present, sorted.
func ConfiguredURLs ¶
func ConfiguredURLs() []string
ConfiguredURLs returns the remote catalogs to consult. TY_PLUGIN_REGISTRY replaces the default list; setting it to an empty string disables remote catalogs entirely (bundled snapshot only).
func DefaultCacheDir ¶
func DefaultCacheDir() string
DefaultCacheDir returns where fetched catalogs are cached.
Types ¶
type Catalog ¶
type Catalog struct {
SchemaVersion int `json:"schema_version"`
Name string `json:"name,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Plugins []Entry `json:"plugins"`
}
Catalog is a published set of installable plugins.
type Entry ¶
type Entry struct {
// ID is the stable, unique handle users type: `ty plugins add slack`.
ID string `json:"id"`
// Name is the human-facing title.
Name string `json:"name"`
// Description is one or two sentences on what the plugin does.
Description string `json:"description"`
// Author is a display name or GitHub handle.
Author string `json:"author,omitempty"`
// Source is the git URL to clone.
Source string `json:"source"`
// Subdir is the plugin's path inside Source, for collection repos that hold
// many plugins. Empty means the repo root is the plugin.
Subdir string `json:"subdir,omitempty"`
// Homepage is a URL to read more (README, docs page).
Homepage string `json:"homepage,omitempty"`
// Category groups entries in the browser ("workflows", "notifications", …).
Category string `json:"category,omitempty"`
// Tags are free-form search keywords.
Tags []string `json:"tags,omitempty"`
// Provides lists the plugin's capability kinds ("workflow", "hook",
// "action", "service", "routine") so a browser can say what you get.
Provides []string `json:"provides,omitempty"`
// Requires lists external prerequisites in plain words ("jq", "an ARC API
// key") — the things that make an install fail confusingly if missing.
Requires []string `json:"requires,omitempty"`
}
Entry is one installable plugin in a catalog.
It is deliberately *not* a plugin manifest: a manifest describes a plugin that is already on disk, an entry describes how to get one and why you would want it. Only ID, Name, Description and Source are required.
func Search ¶
Search ranks entries against a free-text query.
The query is split on whitespace and every term must hit *something* (AND), so "slack notify" doesn't return every plugin that merely mentions Slack. Within a term the strongest field wins — an ID match outranks a description mention — and scores are summed across terms. An empty query returns everything in catalog order, which is what a browser wants when the search box is empty.
func (Entry) DisplayName ¶
DisplayName returns Name, falling back to the ID.
type Loader ¶
type Loader struct {
// URLs are the remote catalogs to overlay onto the bundled snapshot, in
// increasing precedence order.
URLs []string
// CacheDir is where fetched catalogs are cached.
CacheDir string
// TTL is how long a cached copy is served before re-fetching.
TTL time.Duration
// HTTP is the client used for fetches.
HTTP *http.Client
// Now is the clock, injectable for tests.
Now func() time.Time
}
Loader loads and caches catalogs. The zero value is not usable; call NewLoader (or Default) instead.
func Default ¶
func Default() *Loader
Default returns the loader every surface uses: the configured remote catalogs (TY_PLUGIN_REGISTRY, else the community catalog) over the bundled snapshot, cached under the user cache dir.
type Match ¶
Match is one search hit: the entry plus why it ranked where it did.
func SearchRanked ¶
SearchRanked is Search, keeping the scores.
type Origin ¶
type Origin struct {
// URL is the remote catalog, or "bundled" for the embedded snapshot.
URL string
// From is "bundled", "cache", or "network".
From string
// Entries is how many entries this layer contributed (before overlay).
Entries int
// Age is how old the served copy is; zero for a fresh fetch.
Age time.Duration
// Err is why a remote fetch was not used, if it failed.
Err error
}
Origin records where one layer of the loaded catalog came from, so a UI can say "3 sources, one stale" instead of silently serving month-old data.