Documentation
¶
Overview ¶
Package plugin is the host side of the connector plugin platform: it spawns connector subprocesses on demand, hands out live gRPC clients, and reaps idle ones.
Index ¶
- func BuildModule(mod connector.Module, getConn ConnGetter) connector.Module
- func DefaultDir() string
- func ExtractArchive(archive, destBase string) (string, error)
- func InstallFromDir(srcDir, destRoot string) error
- func InstallFromURL(ctx context.Context, url, destRoot string) error
- func ResolveSource(ctx context.Context, src string) (string, func(), error)
- func RunDir() string
- type Available
- type Catalog
- type ConnGetter
- type Found
- type Lease
- type Manager
- func (m *Manager) Client(key string) (*Lease, error)
- func (m *Manager) IsPlugin(key string) bool
- func (m *Manager) KillAll()
- func (m *Manager) RemoveBinary(key string)
- func (m *Manager) ResolveIdentity(ctx context.Context, key, token string) (string, string, error)
- func (m *Manager) SetBinary(key, path string)
- func (m *Manager) WarmUp()
- type Reloader
- type StateStore
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildModule ¶
func BuildModule(mod connector.Module, getConn ConnGetter) connector.Module
BuildModule wires a parsed connector.Module's operations to gRPC closures that dispatch to the plugin subprocess. The host engine (service.Execute) calls these closures exactly like in-proc ops — same pattern as custom-MCP. The envelope parsing and verification happen in the loader before this is called.
func DefaultDir ¶
func DefaultDir() string
DefaultDir is the runtime location wick scans for installed connector plugins: <home>/.wick/plugins/connectors, overridable with WICK_PLUGINS_DIR. It matches the layout `make plugins` writes to.
func ExtractArchive ¶
ExtractArchive extracts a .tar.gz or .zip into destBase and returns the directory that holds plugin.json (the archive root or its single subdir).
func InstallFromDir ¶
InstallFromDir verifies the {binary, plugin.json} in srcDir and copies them into destRoot/<key>/. The manifest's sha256 + signature are checked against the binary BEFORE anything is written, so an unverified plugin never lands in the plugins dir.
func InstallFromURL ¶
InstallFromURL downloads an archive (zip or tar.gz) from url, extracts it, verifies the manifest, and installs into destRoot. Used by the marketplace install action and `<app> plugin install <url|name>`.
func ResolveSource ¶
ResolveSource turns a path / url / archive into a directory containing {binary, plugin.json}, returning the dir and a cleanup func. A bare existing directory is returned as-is.
Types ¶
type Available ¶
type Available struct {
Key string `json:"key"`
Name string `json:"name"`
Description string `json:"description"`
Version string `json:"version"`
// Assets maps "<goos>/<goarch>" → direct download URL of the release zip.
Assets map[string]string `json:"assets"`
}
Available is one installable connector surfaced by the catalog.
Key vs Name mirrors connector.Meta: Key is the slug (= source folder = zip name = install dir = registry key — the one identity used for matching and install); Name is the free display string shown in the UI. Older catalog entries that only have "name" are tolerated: parseCatalog backfills Key from Name when Key is absent.
type Catalog ¶
type Catalog struct {
// contains filtered or unexported fields
}
Catalog discovers connector plugins that are AVAILABLE to install from a single curated JSON file checked into the wick repo's default branch (raw.githubusercontent.com/yogasw/wick/master/plugins/plugins.json).
This is deliberately NOT the GitHub Releases API: listing is a plain raw-file fetch, so it never hits the API rate limit and needs no token. The JSON carries, per plugin, the direct release download URL for each os/arch — the binary is pulled from the GitHub Release only when the user clicks Download.
func DefaultRegistry ¶
func DefaultRegistry() *Catalog
DefaultRegistry builds a Catalog from env overrides:
WICK_PLUGIN_CATALOG full URL to plugins.json (default: wick repo master, plugins/plugins.json)
Named DefaultRegistry for call-site compatibility with the earlier API.
type ConnGetter ¶
ConnGetter returns a lease on a live plugin connection for a connector key. The manager's Client method satisfies it; tests pass a fake.
type Found ¶
type Found struct {
Key string
BinaryPath string
Manifest wickplugin.Manifest
}
Found is one discovered plugin: its key, on-disk binary, and parsed manifest envelope.
type Lease ¶
type Lease struct {
Conn wickplugin.GRPCConn
// contains filtered or unexported fields
}
Lease is a borrowed plugin connection. Release MUST be called exactly once (the adapter does so via defer) so the Manager can account for in-flight calls and free the subprocess for eviction.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns connector plugin subprocesses keyed by connector Meta.Key.
func Load ¶
Load scans dir, builds a Manager over the discovered binaries, registers each plugin module via connectors.Register (replace-by-key so a plugin overrides the compiled-in builtin of the same key), and returns the Manager (caller owns its KillAll on shutdown). Returns a nil Manager when no plugins are present. When enabled is non-nil, keys for which it returns false are excluded from the Manager (not spawnable) and not registered; a nil enabled treats all discovered plugins as enabled.
func NewManager ¶
NewManager builds a Manager and starts the idle sweeper.
func (*Manager) Client ¶
Client returns a lease on a live gRPC connection for key, spawning the subprocess on first use (lazy) and re-spawning if a previous process died. Release the lease when the call completes.
func (*Manager) KillAll ¶
func (m *Manager) KillAll()
KillAll reaps every subprocess (call on app shutdown). It is safe to call more than once: the stop channel is closed at most once.
func (*Manager) RemoveBinary ¶
RemoveBinary drops a connector key and kills its running subprocess (if any).
func (*Manager) ResolveIdentity ¶
ResolveIdentity spawns-if-needed and asks the plugin to resolve an OAuth token's owner.
type Reloader ¶
type Reloader struct {
// contains filtered or unexported fields
}
Reloader watches the plugins dir and reconciles installed plugins into the running service without a restart. It polls on a fixed interval (no fsnotify dependency).
func NewReloader ¶
func NewReloader(dir string, svc moduleSink, mgr *Manager, interval time.Duration, store enabledChecker) *Reloader
NewReloader builds a Reloader. interval <= 0 defaults to 5s.
func (*Reloader) Reload ¶
Reload triggers an immediate reconcile (for in-process callers, e.g. CLI install).
type StateStore ¶
type StateStore struct {
// contains filtered or unexported fields
}
StateStore reads and writes the plugin enable/disable overlay.
func NewStateStore ¶
func NewStateStore(db *gorm.DB) *StateStore
NewStateStore wraps db. A nil db yields a store whose Enabled defaults to true.
func (*StateStore) Enabled ¶
func (s *StateStore) Enabled(key string) bool
Enabled reports whether key may be registered/spawned. Missing row or any error -> true (default-on; never hide a plugin because of a read error).
func (*StateStore) List ¶
func (s *StateStore) List() (map[string]bool, error)
List returns key -> enabled for all overlay rows.
func (*StateStore) SetEnabled ¶
func (s *StateStore) SetEnabled(key string, enabled bool) error
SetEnabled upserts the overlay row for key. A map is used so gorm writes the literal enabled value; a struct would let the `default:true` tag override a zero-value false on insert.