Documentation
¶
Overview ¶
Package host finds, starts and supervises plugins, and connects them to the engine.
Index ¶
- Constants
- Variables
- func CacheDir() string
- func ConfigDir() string
- func GC() ([]string, error)
- func HostSupports(c string) bool
- func Keygen() (pub, secret string, err error)
- func LogFile(name string) string
- func Platform() string
- func Sandbox(args []string) error
- func Sandboxed() bool
- func Sign(secret, file string, data []byte) (string, error)
- func StateDir() string
- func StoreDir() string
- func TraceFile(name string) string
- func Trust(dir string) error
- func Trusted(dir string) bool
- type ActionDecl
- type Artifact
- type Command
- type Detect
- type Host
- func (h *Host) Close()
- func (h *Host) Get(name string) *Plugin
- func (h *Host) Import(ctx context.Context, name string, files []string) (*protocol.ImportResult, error)
- func (h *Host) Plugins() []*Plugin
- func (h *Host) Query(ctx context.Context, name string, args protocol.Args) (*protocol.Frame, error)
- func (h *Host) Run(ctx context.Context, name string, args protocol.Args, dryRun bool) (*protocol.RunResult, error)
- func (h *Host) Skills() []Skill
- func (h *Host) Stream(ctx context.Context, name string, args protocol.Args) (<-chan protocol.StreamBatch, error)
- func (h *Host) View(ctx context.Context, name string, args protocol.Args) (*protocol.Node, error)
- func (h *Host) Widget(ctx context.Context, name string, params protocol.WidgetRenderParams) ([]string, error)
- type ImporterDecl
- type Index
- type IndexEntry
- type IndexVersion
- type Installer
- func (in *Installer) Add(ctx context.Context, srcs []string) error
- func (in *Installer) Ensure(ctx context.Context) (changed bool, err error)
- func (in *Installer) Remove(names []string) error
- func (in *Installer) Up(ctx context.Context, names []string, major bool) error
- func (in *Installer) Vendor() ([]string, error)
- type Lacking
- type Lock
- type Locked
- type Manifest
- func (m *Manifest) Kind() string
- func (m *Manifest) Missing(needsOnly bool) []Lacking
- func (m *Manifest) MissingText(needsOnly bool) string
- func (m *Manifest) Path(p string) string
- func (m *Manifest) Relevant(dir string, cfg map[string]*spec.Plugin) bool
- func (m *Manifest) ShowsTab(dir string, cfg map[string]*spec.Plugin) bool
- type Options
- type Permissions
- type Plugin
- type Registry
- type Server
- type Skill
- type SourceDecl
Constants ¶
const DefaultIndex = "https://raw.githubusercontent.com/goxang/rig-plugins/main/registry/index.json"
const DevStamp = "plugin-dev"
DevStamp, under .rig, names the plugin rig plugin dev just built; a running TUI reloads when it changes.
const LockFile = "rig.lock"
const ManifestFile = "rig-plugin.yaml"
Variables ¶
var ErrUntrusted = errors.New("this project's plugins need workspace trust: run rig trust (or pass --yes, or set RIG_TRUST=project)")
ErrUntrusted stops a run nobody can answer the workspace trust question for.
var OfficialKey = "RWSO4FXV354ZdKG69JB39vUGx5l3XooSJoWp0c8T/bWN548qByjgecLr"
OfficialKey is the minisign public key goxang's artifacts are signed with.
var SandboxExe string
SandboxExe is the rig binary that runs `rig __sandbox`; empty starts plugins directly.
var Version = "dev"
Version is the rig version plugins see at initialize.
Functions ¶
func HostSupports ¶
HostSupports says whether this rig satisfies a manifest's rig: constraint; dev builds take anything.
func Keygen ¶
Keygen makes a minisign key pair: the public key as minisign writes it, the secret as a base64 key id and ed25519 seed (not minisign's encrypted format), for Sign.
func Sandbox ¶
Sandbox is `rig __sandbox [--ro dir] [--rw dir] [--port n] -- command...`: it confines itself, then becomes the command.
Types ¶
type ActionDecl ¶
type Artifact ¶
type Artifact struct {
URL string `json:"url"`
SHA256 string `json:"sha256"`
// Sig is the minisign signature file's text.
Sig string `json:"sig,omitempty"`
// Files are gzipped files the archive leaves out because several plugins share them (rig-std),
// by their path in the plugin; each is downloaded once.
Files map[string]Artifact `json:"files,omitempty"`
}
type Host ¶
Host runs the project's plugins.
func (*Host) Import ¶
func (h *Host) Import(ctx context.Context, name string, files []string) (*protocol.ImportResult, error)
Import runs a plugin importer, returning its rig.yaml fragment.
func (*Host) Run ¶
func (h *Host) Run(ctx context.Context, name string, args protocol.Args, dryRun bool) (*protocol.RunResult, error)
Run runs or plans an action; progress goes to the job in ctx.
func (*Host) Skills ¶
Skills are the skills of every plugin, from the skills: directories their manifests list.
func (*Host) Stream ¶
func (h *Host) Stream(ctx context.Context, name string, args protocol.Args) (<-chan protocol.StreamBatch, error)
Stream opens a server plugin's stream; batches arrive until Done, an error, or ctx ends.
type ImporterDecl ¶
type Index ¶
type Index struct {
Plugins map[string]*IndexEntry `json:"plugins"`
}
type IndexEntry ¶
type IndexEntry struct {
Description string `json:"description,omitempty"`
Publisher string `json:"publisher,omitempty"`
Repo string `json:"repo,omitempty"`
// Key is the publisher's minisign public key; goxang's is built in.
Key string `json:"key,omitempty"`
Detect *Detect `json:"detect,omitempty"`
Provides map[string]any `json:"provides,omitempty"`
Packs []string `json:"packs,omitempty"`
Versions map[string]*IndexVersion `json:"versions"`
}
func (*IndexEntry) Latest ¶
func (e *IndexEntry) Latest() string
Latest is the highest published version, pre-releases only when nothing else exists.
type IndexVersion ¶
type Installer ¶
type Installer struct {
Dir string
Registry *Registry
// Yes approves workspace trust and permissions without asking (--yes).
Yes bool
// Ask asks the person at the terminal; nil means nobody is there.
Ask func(question string) bool
Out io.Writer
// contains filtered or unexported fields
}
Installer adds, upgrades and restores a project's plugins, pinned in rig.lock.
func (*Installer) Add ¶
Add installs plugins from their sources and pins them in rig.lock, with their packs' plugins.
func (*Installer) Ensure ¶
Ensure installs what rig.lock pins and this machine lacks, after workspace trust; changed says the project's plugins differ from before, so a loaded project is stale.
func (*Installer) Remove ¶
Remove unpins plugins, and the plugins a removed pack brought that nothing else needs.
type Lacking ¶
type Lacking struct{ Bin, Fix string }
Lacking is a program a plugin needs that is not on PATH, and what to do about it.
type Locked ¶
type Locked struct {
Version string `yaml:"version"`
// Source is registry, a git repo (host/owner/repo[/sub]@ref), a tarball URL or a local path.
Source string `yaml:"source"`
Commit string `yaml:"commit,omitempty"`
// SHA256 is per os/arch, or "any" for a platform-independent artifact.
SHA256 map[string]string `yaml:"sha256,omitempty"`
// Files are the shared files' sha256, per os/arch and then by path in the plugin.
Files map[string]map[string]string `yaml:"files,omitempty"`
// Permissions is the hash of the permissions granted; a plugin asking for more needs approval again.
Permissions string `yaml:"permissions"`
// Pack names the pack that brought it in, if any.
Pack string `yaml:"pack,omitempty"`
}
Locked pins one plugin: where it came from and what it was, so every machine gets the same bytes.
type Manifest ¶
type Manifest struct {
Name string `yaml:"name"`
Version string `yaml:"version"`
Rig string `yaml:"rig,omitempty"`
Description string `yaml:"description,omitempty"`
Publisher string `yaml:"publisher,omitempty"`
Requires map[string]string `yaml:"requires,omitempty"`
// Needs are programs on the machine the plugin's scripts run, each with how to install it
// (needs: {jq: "apt install jq"}); permissions.exec ones are checked too.
Needs map[string]string `yaml:"needs,omitempty"`
Implements []string `yaml:"implements,omitempty"`
Detect *Detect `yaml:"detect,omitempty"`
Server *Server `yaml:"server,omitempty"`
MCP *Server `yaml:"mcp,omitempty"`
Permissions Permissions `yaml:"permissions,omitempty"`
// Config is the JSON Schema of plugins.<name>: in rig.yaml, as properties.
Config map[string]map[string]any `yaml:"config,omitempty"`
Types map[string]yaml.Node `yaml:"types,omitempty"`
Schemes []string `yaml:"schemes,omitempty"`
Sources map[string]SourceDecl `yaml:"sources,omitempty"`
Actions map[string]ActionDecl `yaml:"actions,omitempty"`
Importers map[string]ImporterDecl `yaml:"importers,omitempty"`
Views map[string]yaml.Node `yaml:"views,omitempty"`
Widgets map[string]yaml.Node `yaml:"widgets,omitempty"`
On map[string]yaml.Node `yaml:"on,omitempty"`
Events []string `yaml:"events,omitempty"`
Skills []string `yaml:"skills,omitempty"`
Search bool `yaml:"search,omitempty"`
Complete []string `yaml:"complete,omitempty"`
Doctor bool `yaml:"doctor,omitempty"`
Docs string `yaml:"docs,omitempty"`
// Build runs in the plugin's directory after a git or path install, such as go build -o bin/x .
Build Command `yaml:"build,omitempty"`
// Dir is where the manifest lives; Fragment the rig.yaml keys it contributes.
Dir string `yaml:"-"`
Fragment *config.Doc `yaml:"-"`
Warnings []string `yaml:"-"`
}
func Discover ¶
Discover finds the project's plugins. A later scope replaces an earlier one of the same name: what rig.lock pins, then what the user's own lock pins (rig plugin add --user), then user plugins, then project plugins (under workspace trust), then plugins.<name>.path.
func LoadManifest ¶
LoadManifest reads dir/rig-plugin.yaml. Unknown keys are warnings, so an older rig loads a newer plugin. Callers share the result and must not change it.
func (*Manifest) Missing ¶
Missing lists the programs the plugin needs (needs:, and unless needsOnly permissions.exec) that are not on PATH.
func (*Manifest) MissingText ¶
MissingText is Missing as one sentence, "" when nothing is missing.
func (*Manifest) Relevant ¶
Relevant reports whether m belongs on dir's screens. Project plugins always do; a user-wide one does when rig.yaml configures it, its detect matches, or it has neither detect nor config.
type Options ¶
type Options struct {
// Dir is the project, File its rig.yaml; Env the environment calls run in.
Dir string
File string
Env string
// StateDir keeps host/state values, per plugin: the project's .rig/<env>.
StateDir string
// Engine serves host/query and host/run.
Engine api.Engine
Ask func(context.Context, protocol.AskParams) (protocol.AskResult, error)
AI func(context.Context, protocol.AIParams) (string, error)
// Secret looks up a declared secret; nil reads the process environment.
Secret func(name string) (string, bool)
Emit func(protocol.Event)
// Components are the project's components a plugin serves (type: <plugin>), by name; nil is none.
Components func(plugin string) map[string]protocol.Args
// Idle stops a plugin process after this long unused; zero is 10 minutes.
Idle time.Duration
}
type Permissions ¶
type Permissions struct {
// Net lists hosts or URLs a plugin connects to; on Landlock ABI 4+ their ports are enforced.
Net []string `yaml:"net,omitempty" json:"net,omitempty"`
// Secrets are the names host/secret answers.
Secrets []string `yaml:"secrets,omitempty" json:"secrets,omitempty"`
// Exec lists programs the plugin runs (advisory; PATH stays).
Exec []string `yaml:"exec,omitempty" json:"exec,omitempty"`
// Uses are globs of other plugins' sources and actions it may call through the host.
Uses []string `yaml:"uses,omitempty" json:"uses,omitempty"`
// FS lists paths beyond the project, its own directory and temp it reads (ro:) or writes.
FS []string `yaml:"fs,omitempty" json:"fs,omitempty"`
// Env lists environment variables it gets besides PATH, HOME and LANG.
Env []string `yaml:"env,omitempty" json:"env,omitempty"`
// AI lets it call host/ai.
AI bool `yaml:"ai,omitempty" json:"ai,omitempty"`
}
func (Permissions) Hash ¶
func (p Permissions) Hash() string
Hash identifies a set of permissions, so an update that widens them asks again.
func (Permissions) String ¶
func (p Permissions) String() string
type Plugin ¶
type Plugin struct {
*Manifest
// Config is plugins.<name> from rig.yaml over the manifest's config defaults.
Config map[string]any
// contains filtered or unexported fields
}
Plugin is one discovered plugin and, once called, its process.
type Registry ¶
type Registry struct {
// Mirror replaces every download: <mirror>/index.json and <mirror>/<name>/<version>/<file>.
Mirror string
Client *http.Client
}
Registry reads the plugin index, from a mirror when one is set.
func UserRegistry ¶
func UserRegistry() *Registry
UserRegistry is the registry the user config, or $RIG_REGISTRY, points at.
type Server ¶
type Server struct {
Command Command `yaml:"command"`
Env map[string]string `yaml:"env,omitempty"`
}
Server is how a plugin runs: a JSON-RPC process, or an MCP server under mcp:.
type Skill ¶
type Skill struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Plugin string `yaml:"-"`
Body string `yaml:"-"`
}
Skill is a SKILL.md: its front matter's name and description, always shown to the AI, and the body, loaded only when asked for.
func ParseSkill ¶
ParseSkill reads a SKILL.md; fallback names it when its front matter does not.
type SourceDecl ¶
type SourceDecl struct {
Help string `yaml:"help,omitempty"`
Args map[string]any `yaml:"args,omitempty"`
Cache string `yaml:"cache,omitempty"`
Stream bool `yaml:"stream,omitempty"`
// Run makes it a script source; Format overrides output detection.
Run Command `yaml:"run,omitempty"`
Format string `yaml:"format,omitempty"`
}