plugin

package
v0.1.561 Latest Latest
Warning

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

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Overview

Package plugin runs OpenCode's provider plugins for magpie.

A subscription a vendor may object to being used outside its own app is not built into magpie: a plugin signs in to it and makes its requests, the way OpenCode's plugins do (opencode-gemini-auth and the like), and magpie runs those same plugins. They are npm packages (or local files) written against OpenCode's plugin API (@opencode-ai/plugin, v1): their auth hook gives the sign-in methods and a loader whose fetch carries the requests, their config and provider hooks the models. magpie runs them under Bun, downloaded the first time a plugin is added, in one process (host.js) it talks to over stdin and stdout.

What magpie keeps: plugins.json, the plugins and the config handed to them (OpenCode's, its provider section: a plugin's options); the npm packages under plugins/; plugin-auth.json, the sign-ins, in OpenCode's auth.json shape (so one can be moved between the two).

Index

Constants

View Source
const BunVersion = "1.3.14"

BunVersion is the Bun magpie downloads to run plugins with, the first time one is needed.

View Source
const MarketURL = "https://raw.githubusercontent.com/magpie-community/plugins/main/registry.json"

MarketURL is where the list is kept; MAGPIE_PLUGIN_MARKET moves it, and "off" keeps to the built-in copy.

View Source
const NewAccount = "new"

NewAccount is the account a sign-in goes to when it is a new one: the provider's own id while nothing is kept there. A sign-in to an account already signed in replaces that one's instead.

Variables

View Source
var ErrFailed = errors.New("the sign-in failed")

ErrFailed is a sign-in the plugin says failed.

Functions

func AuthPath

func AuthPath() string

AuthPath is the plugins' sign-ins, OpenCode's auth.json in shape.

func Auths added in v0.1.506

func Auths(provider string) map[string]map[string]any

Auths are provider's sign-ins as plugin-auth.json keeps them, by key.

func Bun

func Bun(ctx context.Context) (string, error)

Bun is the bun to run plugins with: $MAGPIE_BUN when set, else the one magpie downloaded, downloading it now when there is none yet.

func Call

func Call(ctx context.Context, method string, params, out any) error

Call starts the host if need be and asks it method.

func Dir

func Dir() string

Dir is the folder magpie installs npm plugins into.

func Fetch

func Fetch(ctx context.Context, r FetchRequest) (*http.Response, error)

Fetch sends r through the provider's plugin — its loader's fetch, or Bun's own when it gives none — and streams back the reply.

func HasBun

func HasBun() bool

HasBun is whether a Bun is at hand without a download.

func Icon added in v0.1.497

func Icon(spec, id string) string

Icon is the icon the market gives the plugin spec, or else any listed plugin signing in to provider id; "" when none does. It never goes to the network: the list fetched last, else the cached copy, else the one built in.

func Import added in v0.1.506

func Import(ctx context.Context, provider string, auth map[string]any) (string, error)

Import keeps auth (a plugin-auth.json entry) as one more of provider's accounts — or, the same account as one kept already, in its place — and gives the account's key. The plugin's host is started for it: it alone writes the file while it runs.

func Info added in v0.1.489

func Info(ctx context.Context, names []string) map[string]NPM

Info is what npm says of each package, asked at most hourly and all at once; a package npm doesn't have has no Version.

func Installed added in v0.1.489

func Installed(spec string) string

Installed is the version of the plugin spec installed, "" for a path or one not installed.

func IsPath

func IsPath(spec string) bool

IsPath is whether spec names a file or folder rather than a package, as OpenCode tells them apart.

func ListedAt added in v0.1.552

func ListedAt() (time.Time, bool)

ListedAt is when the plugins last listed their providers and models, as a built-in's list is dated by when it was fetched.

func Name

func Name(spec string) string

Name is the package spec names, without its version: "@scope/x" of "@scope/x@1.2", or the path.

func OnChange

func OnChange(f func())

OnChange registers f to be told when a plugin sign-in or the plugins change (a sign-in saved or refreshed, a plugin added).

func OnSignIn added in v0.1.547

func OnSignIn(f func(provider, account, said string))

OnSignIn registers f to be told what a plugin said, outside an answer, its account's sign-in is: "expired", "kept" or "renewed" (a models hook's error saying it).

func PackageName added in v0.1.506

func PackageName(spec string) string

PackageName is the npm package spec is: its name, or, for a plugin added from a folder or file (a checkout of it), the name its package.json gives.

func ProviderOf added in v0.1.500

func ProviderOf(key string) string

ProviderOf is the provider an account key is one of.

func Remove

func Remove(ctx context.Context, name string) error

Remove takes a plugin off the list (and out of plugins/).

func Restart

func Restart()

Restart stops the host, so the next call starts one with the plugins as they are now.

func Restore added in v0.1.506

func Restore(ctx context.Context, provider, key string, auth map[string]any) error

Restore puts auth back as provider's account key.

func Running

func Running() bool

Running is whether a host is up.

func SetConfig

func SetConfig(cfg map[string]any) error

SetConfig sets the OpenCode config the plugins are handed.

func SetOff

func SetOff(name string, off bool) error

SetOff turns a plugin off or back on.

func Settle

func Settle()

Settle waits for Cached's refreshes to end, then stops the host: for tests, whose folders the host runs in go when they end.

func SignOut

func SignOut(ctx context.Context, provider, account string) error

SignOut forgets one account of the provider's, every one when account is "".

func SignedIn

func SignedIn(provider string) bool

SignedIn is whether a plugin sign-in is kept for provider.

func Take added in v0.1.506

func Take(ctx context.Context, provider string, keys []string) (map[string]map[string]any, error)

Take gives provider's accounts named by keys (every one when there are none) and signs them out in one step, so the plugin renews none of their tokens after it gave them.

func Target

func Target(spec string) string

Target is where the plugin is to load from: the installed package's folder, or the path.

func Update

func Update(ctx context.Context) error

Update installs the version of each npm plugin its spec says now (latest, for the most part).

func Upgrade added in v0.1.489

func Upgrade(ctx context.Context, name string) error

Upgrade installs the newest version of one plugin.

func UseCached added in v0.1.538

func UseCached(ps []Provider)

UseCached is for tests: Cached answers with ps, as though the plugins had just been asked, without Bun; nil forgets them.

func Validate

func Validate(ctx context.Context, provider string, method int, key, value string) (string, error)

Validate is what the method says is wrong with value as the answer to key, "" when nothing is.

func Version added in v0.1.506

func Version(spec string) string

Version is the version of the package spec installed (or checked out at its path), "" when there is none.

Types

type Account added in v0.1.500

type Account struct {
	Key       string `json:"key"`
	Type      string `json:"type"`
	AccountID string `json:"accountId"`
	// Hint tells an account with no id from another: the end of its key.
	Hint string `json:"hint,omitempty"`
	// Models are the ids of the provider's models this account has, when
	// the provider has more than one account; none, it has them all.
	Models []string `json:"models,omitempty"`
}

Account is one account a provider is signed in to: Key is where plugin-auth.json keeps it (the provider's id, else id#slot).

type Authorization

type Authorization struct {
	Session      string `json:"session"`
	URL          string `json:"url"`
	Instructions string `json:"instructions"`
	Method       string `json:"method"`
}

Authorization is an OAuth sign-in begun: the page to open, and whether the plugin waits for it itself ("auto") or needs the code the page shows pasted back ("code").

func Authorize

func Authorize(ctx context.Context, provider string, method int, inputs map[string]string, account string) (Authorization, error)

Authorize begins an OAuth sign-in to account (a key, or NewAccount).

type Checked added in v0.1.552

type Checked struct {
	Models  []string `json:"models"`
	Usage   *Usage   `json:"usage"`
	Refused string   `json:"refused"`
}

Checked is what trying an account gave: the model ids the plugin lists for it, its usage read (nil when the plugin tells none), and why its models hook said the vendor refused the sign-in, if it did.

func Check added in v0.1.506

func Check(ctx context.Context, provider, account string) (Checked, error)

Check tries one of provider's accounts as a request would — its auth loader, then its models as the plugin lists them for it — and reads its usage, which asks the vendor of the account itself. It fails when the plugin reached none of the places it asked (the vendor offline): a models hook falling back to a list it keeps proves nothing.

type Entry

type Entry struct {
	// Spec is how it was added: an npm package (name, name@version) or a
	// path to a file or folder.
	Spec string `json:"spec"`
	// Off is set on a plugin the user turned off.
	Off bool `json:"off,omitempty"`
	// Options are handed to the plugin as its second argument, as
	// OpenCode's ["name", {options}] does.
	Options map[string]any `json:"options,omitempty"`
}

Entry is one plugin the user added.

func Add

func Add(ctx context.Context, spec string) (Entry, error)

Add installs a plugin and adds it to the list, in place of one of the same package. A package is installed with its scripts left unrun.

type FetchRequest

type FetchRequest struct {
	Provider string            `json:"provider"`
	Account  string            `json:"account,omitempty"` // the provider's first when ""
	Model    string            `json:"model"`
	NPM      string            `json:"npm"`
	URL      string            `json:"url"`
	Method   string            `json:"method"`
	Headers  map[string]string `json:"headers"`
	Body     []byte            `json:"-"`
	Session  string            `json:"session,omitempty"`
	// Proxy is the provider's or the account's own proxy (netproxy.With):
	// "direct", or its URL; "" follows magpie's. Fetch takes it from ctx
	// when it isn't set.
	Proxy string `json:"proxy,omitempty"`
}

FetchRequest is a request a provider's plugin makes.

type Hit added in v0.1.489

type Hit struct {
	Package string `json:"package"`
	NPM
}

Hit is a package npm's search found.

func Search(ctx context.Context, q string) ([]Hit, error)

Search asks npm for OpenCode plugins matching q.

type List

type List struct {
	Plugins []Entry `json:"plugins"`
	// Config is OpenCode's config the plugins are handed: its provider
	// section says what a plugin reads of it
	// (provider.google.options.projectId).
	Config map[string]any `json:"config,omitempty"`
}

List is plugins.json.

func Load

func Load() List

Load reads plugins.json.

type Listing added in v0.1.489

type Listing struct {
	Package   string            `json:"package"`
	Name      string            `json:"name"`
	Icon      string            `json:"icon,omitempty"`
	Providers []string          `json:"providers,omitempty"` // OpenCode's ids of those it signs in to
	Community bool              `json:"community,omitempty"` // written by magpie's community
	Replaces  string            `json:"replaces,omitempty"`  // the built-in subscription it does the work of
	Summary   map[string]string `json:"summary,omitempty"`   // by language: en, zh
}

Listing is a plugin the market suggests.

func Market added in v0.1.489

func Market(ctx context.Context) []Listing

Market is the list of plugins magpie suggests: fetched at most every six hours, else the copy fetched last, else the one built in.

type Loaded

type Loaded struct {
	Spec  string `json:"spec"`
	Error string `json:"error,omitempty"`
}

Loaded is how a plugin fared when the host loaded it.

func Plugins

func Plugins(ctx context.Context) ([]Loaded, error)

Plugins is how each plugin fared when the host loaded it, starting the host if need be.

type Method

type Method struct {
	Type  string `json:"type"`
	Label string `json:"label"`
	// Placeholder is the hint an "api" method gives in its key's field
	// (magpie's own field: OpenCode's says "API key")
	Placeholder string `json:"placeholder,omitempty"`
}

Method is a way a plugin signs in: "oauth" (a browser, then a code pasted back or not) or "api" (a key).

func (Method) KeyTitle added in v0.1.553

func (m Method) KeyTitle(name string) string

KeyTitle is what an "api" method's key is asked as: its label, as OpenCode's dialog titles it, unless that only says "API key" (or nothing), when it is name's API key.

type Model

type Model struct {
	ID        string   `json:"id"`
	Name      string   `json:"name"`
	NPM       string   `json:"npm"` // the AI SDK package it is spoken to with
	URL       string   `json:"url"`
	APIID     string   `json:"apiId"`
	Context   int      `json:"context"`
	Input     int      `json:"input"`
	Output    int      `json:"output"`
	Reasoning bool     `json:"reasoning"`
	Image     bool     `json:"image"`
	Released  string   `json:"released"`
	Variants  []string `json:"variants"`
	// Free is set by the plugin on a model the plan serves at no cost to
	// its allowance (WorkBuddy's "credits": "x0.00")
	Free bool `json:"free"`
	Cost *struct {
		Input  float64 `json:"input"`
		Output float64 `json:"output"`
	} `json:"cost"`
	// ImageSaid is whether the plugin (or models.dev) said if it takes
	// images: Image false without it is not known
	ImageSaid bool `json:"imageSaid"`
}

Model is a model a plugin's provider serves, as OpenCode lists it.

type NPM added in v0.1.489

type NPM struct {
	Version     string `json:"version,omitempty"` // latest; none when npm has no such package
	Description string `json:"description,omitempty"`
	Publisher   string `json:"publisher,omitempty"`
	License     string `json:"license,omitempty"`
	Homepage    string `json:"homepage,omitempty"`
	Repository  string `json:"repository,omitempty"`
	Weekly      int    `json:"weekly"` // downloads last week
}

NPM is what npm says of a package now.

type Options

type Options struct {
	BaseURL string            `json:"baseURL"`
	APIKey  string            `json:"apiKey"`
	Headers map[string]string `json:"headers"`
	Fetch   bool              `json:"fetch"`
}

Options is what the provider's auth loader gave: where its requests go, the key the AI SDK would send, and whether it carries them itself.

func LoaderOptions

func LoaderOptions(ctx context.Context, provider, account string) (Options, error)

LoaderOptions runs the provider's auth loader for account (once per sign-in and host) and gives what it returned; account "" is the provider's first.

type Page added in v0.1.489

type Page struct {
	Readme  string    `json:"readme"`
	Updated time.Time `json:"updated"`
}

Page is a package's page: its README and when it last changed.

func Readme added in v0.1.489

func Readme(ctx context.Context, name string) (Page, error)

Readme is the package's README, as npm has it.

type Prompt

type Prompt struct {
	Type        string `json:"type"` // text, select
	Key         string `json:"key"`
	Message     string `json:"message"`
	Placeholder string `json:"placeholder,omitempty"`
	Options     []struct {
		Label string `json:"label"`
		Value string `json:"value"`
		Hint  string `json:"hint,omitempty"`
	} `json:"options,omitempty"`
}

Prompt is a question a sign-in method asks before it starts.

func NextPrompt

func NextPrompt(ctx context.Context, provider string, method int, inputs map[string]string) (*Prompt, error)

NextPrompt is the method's next question given the answers so far; nil when it has asked them all.

type Provider

type Provider struct {
	ID      string   `json:"id"`   // OpenCode's: google, github-copilot
	Spec    string   `json:"spec"` // the plugin
	Name    string   `json:"name"`
	NPM     string   `json:"npm"`
	API     string   `json:"api"`
	Methods []Method `json:"methods"`
	// Icon is the picture the plugin gives the provider, as it said it:
	// an https URL or a data:image URI (internal/provider keeps it)
	Icon string `json:"icon,omitempty"`
	// Usage says the plugin tells each account's allowance (auth.usage)
	Usage     bool    `json:"usage"`
	SignedIn  bool    `json:"signedIn"`
	AuthType  string  `json:"authType"`
	AccountID string  `json:"accountId"`
	Models    []Model `json:"models"`
	// Accounts are the accounts signed in to it, the one kept under its
	// own id first; SignedIn, AuthType and AccountID are that one's.
	Accounts []Account `json:"accounts"`
}

Provider is a provider a plugin signs in to.

func Cached

func Cached() []Provider

Cached is the plugins' providers as last asked, without starting the host: what is known of them when magpie has only just started. A provider's sign-in is read afresh from plugin-auth.json.

func Providers

func Providers(ctx context.Context) ([]Provider, error)

Providers asks the plugins for their providers, starting the host if need be, and keeps the answer for Cached.

type Saved added in v0.1.500

type Saved struct {
	Provider string `json:"provider"`
	Account  string `json:"account"`
}

Saved is where a sign-in was kept: the provider (a plugin may sign in to another than asked) and the account's key.

func APIKey

func APIKey(ctx context.Context, provider string, method int, inputs map[string]string, key, account string) (Saved, error)

APIKey signs in to account (a key, or NewAccount) with a key, as an "api" method does.

func Finish

func Finish(ctx context.Context, session, code string) (Saved, error)

Finish waits for an OAuth sign-in to finish: an "auto" one on its own, a "code" one with the code pasted back. It gives where the sign-in was saved.

type Usage added in v0.1.514

type Usage struct {
	Plan    string        `json:"plan"`
	Until   string        `json:"until"` // RFC 3339, "" when not told
	Renew   string        `json:"renew"`
	Balance string        `json:"balance"`
	Error   string        `json:"error"`
	User    string        `json:"user"`
	SignIn  string        `json:"signIn"` // "expired", "kept", "renewed" or ""
	Windows []UsageWindow `json:"windows"`
	Resets  *UsageResets  `json:"resets"`
}

Usage is how much of its allowance one account has used, as the plugin's auth.usage tells it (host.js has the shape).

func AccountUsage added in v0.1.514

func AccountUsage(ctx context.Context, provider, account string) (Usage, error)

AccountUsage asks the plugin for account's usage of provider.

type UsageResets added in v0.1.514

type UsageResets struct {
	Count    int    `json:"count"`
	Until    string `json:"until"`
	ByWindow bool   `json:"byWindow"`
	FiveHour int    `json:"fiveHour"`
	Weekly   int    `json:"weekly"`
}

UsageResets are the rate-limit resets an account may spend.

type UsageWindow added in v0.1.514

type UsageWindow struct {
	Name      string   `json:"name"`
	Used      float64  `json:"used"`     // percent
	ResetsAt  string   `json:"resetsAt"` // RFC 3339
	ResetSecs int64    `json:"resetSecs"`
	Display   string   `json:"display"`
	Span      float64  `json:"span"` // seconds
	Model     string   `json:"model"`
	Models    []string `json:"models"`
	NotModels []string `json:"notModels"`
	Aside     bool     `json:"aside"`
}

Jump to

Keyboard shortcuts

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