plugin

package
v0.0.0-...-dac86b4 Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckVersion

func CheckVersion(version, constraint string) (bool, error)

CheckVersion checks if a version string satisfies a constraint string.

func SaveManifest

func SaveManifest(path string, manifest *PluginManifest) error

SaveManifest writes a manifest to a JSON file.

Types

type APIHandler

type APIHandler struct {
	// contains filtered or unexported fields
}

APIHandler serves HTTP endpoints for the plugin registry.

func NewAPIHandler

func NewAPIHandler(registry *LocalRegistry, loader *dynamic.Loader) *APIHandler

NewAPIHandler creates a new plugin API handler.

func (*APIHandler) RegisterRoutes

func (h *APIHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers the plugin API routes on the given mux.

type CompositeRegistry

type CompositeRegistry struct {
	// contains filtered or unexported fields
}

CompositeRegistry combines a local registry with a remote registry, searching both and allowing installation from the remote into local.

func NewCompositeRegistry

func NewCompositeRegistry(local *LocalRegistry, remote *RemoteRegistry) *CompositeRegistry

NewCompositeRegistry creates a composite registry from a local and remote registry.

func (*CompositeRegistry) CheckDependencies

func (c *CompositeRegistry) CheckDependencies(manifest *PluginManifest) error

CheckDependencies delegates to the local registry.

func (*CompositeRegistry) Get

func (c *CompositeRegistry) Get(name string) (*PluginEntry, bool)

Get delegates to the local registry.

func (*CompositeRegistry) Install

func (c *CompositeRegistry) Install(ctx context.Context, name, version string) error

Install downloads a plugin from the remote registry and registers it locally.

func (*CompositeRegistry) List

func (c *CompositeRegistry) List() []*PluginEntry

List delegates to the local registry.

func (*CompositeRegistry) Local

func (c *CompositeRegistry) Local() *LocalRegistry

Local returns the underlying local registry.

func (*CompositeRegistry) Register

func (c *CompositeRegistry) Register(manifest *PluginManifest, component *dynamic.DynamicComponent, sourceDir string) error

Register delegates to the local registry.

func (*CompositeRegistry) Remote

func (c *CompositeRegistry) Remote() *RemoteRegistry

Remote returns the underlying remote registry.

func (*CompositeRegistry) Search

func (c *CompositeRegistry) Search(ctx context.Context, query string) ([]*PluginManifest, error)

Search checks local first, then remote, merging results with no duplicates.

func (*CompositeRegistry) Unregister

func (c *CompositeRegistry) Unregister(name string) error

Unregister delegates to the local registry.

type Constraint

type Constraint struct {
	Op      string
	Version Semver
}

Constraint represents a semver constraint that can check version compatibility.

func ParseConstraint

func ParseConstraint(s string) (*Constraint, error)

ParseConstraint parses a constraint string like ">=1.0.0", "^2.1.0", "~1.2.0".

func (*Constraint) Check

func (c *Constraint) Check(v Semver) bool

Check returns true if the given version satisfies the constraint.

type Dependency

type Dependency struct {
	Name       string `json:"name" yaml:"name"`
	Constraint string `json:"constraint" yaml:"constraint"` // semver constraint, e.g. ">=1.0.0", "^2.1"
}

Dependency declares a versioned dependency on another plugin.

type LocalRegistry

type LocalRegistry struct {
	// contains filtered or unexported fields
}

LocalRegistry implements PluginRegistry by scanning local directories.

func NewLocalRegistry

func NewLocalRegistry() *LocalRegistry

NewLocalRegistry creates a new empty local registry.

func (*LocalRegistry) CheckDependencies

func (r *LocalRegistry) CheckDependencies(manifest *PluginManifest) error

CheckDependencies verifies that all dependencies declared in the manifest are satisfied by currently registered plugins.

func (*LocalRegistry) Get

func (r *LocalRegistry) Get(name string) (*PluginEntry, bool)

Get retrieves a plugin entry by name.

func (*LocalRegistry) List

func (r *LocalRegistry) List() []*PluginEntry

List returns all registered plugin entries.

func (*LocalRegistry) Register

func (r *LocalRegistry) Register(manifest *PluginManifest, component *dynamic.DynamicComponent, sourceDir string) error

Register adds a plugin to the registry after validating its manifest and checking version compatibility of declared dependencies.

func (*LocalRegistry) ScanDirectory

func (r *LocalRegistry) ScanDirectory(dir string, loader *dynamic.Loader) ([]*PluginEntry, error)

ScanDirectory scans a directory for plugin subdirectories. Each subdirectory should contain a plugin.json manifest and a .go source file.

func (*LocalRegistry) Unregister

func (r *LocalRegistry) Unregister(name string) error

Unregister removes a plugin from the registry.

type NativeHandler

type NativeHandler struct {
	// contains filtered or unexported fields
}

NativeHandler serves HTTP endpoints for native plugin discovery and route dispatch. It delegates all behavior to the PluginManager.

func NewNativeHandler

func NewNativeHandler(manager *PluginManager) *NativeHandler

NewNativeHandler creates a new handler backed by a PluginManager.

func (*NativeHandler) ServeHTTP

func (h *NativeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler by delegating to the PluginManager.

type NativePlugin

type NativePlugin interface {
	Name() string
	Version() string
	Description() string
	Dependencies() []PluginDependency
	UIPages() []UIPageDef
	RegisterRoutes(mux *http.ServeMux)
	OnEnable(ctx PluginContext) error
	OnDisable(ctx PluginContext) error
}

NativePlugin is a compiled-in plugin that provides HTTP handlers, UI page metadata, and lifecycle hooks with dependency declarations.

type PluginContext

type PluginContext struct {
	App     interface{} // modular.Application — use interface{} to avoid import cycle
	DB      *sql.DB
	Logger  *slog.Logger
	DataDir string
}

PluginContext provides shared resources to plugins during lifecycle events.

type PluginDependency

type PluginDependency struct {
	Name       string // required plugin name
	MinVersion string // semver constraint, empty = any version
}

PluginDependency declares a dependency on another plugin.

type PluginEntry

type PluginEntry struct {
	Manifest  *PluginManifest           `json:"manifest"`
	Component *dynamic.DynamicComponent `json:"-"`
	SourceDir string                    `json:"source_dir,omitempty"`
}

PluginEntry holds the manifest and component for a registered plugin.

type PluginInfo

type PluginInfo struct {
	Name         string             `json:"name"`
	Version      string             `json:"version"`
	Description  string             `json:"description"`
	Enabled      bool               `json:"enabled"`
	UIPages      []UIPageDef        `json:"ui_pages"`
	Dependencies []PluginDependency `json:"dependencies"`
	EnabledAt    string             `json:"enabled_at,omitempty"`
	DisabledAt   string             `json:"disabled_at,omitempty"`
}

PluginInfo is the JSON representation of a plugin for API responses.

type PluginManager

type PluginManager struct {
	// contains filtered or unexported fields
}

PluginManager handles plugin registration, dependency resolution, lifecycle management, enable/disable state persistence, and HTTP route dispatch.

func NewPluginManager

func NewPluginManager(db *sql.DB, logger *slog.Logger) *PluginManager

NewPluginManager creates a new PluginManager with SQLite-backed state persistence. It initializes the plugin_state table if it does not exist.

func (*PluginManager) AllPlugins

func (pm *PluginManager) AllPlugins() []PluginInfo

AllPlugins returns info about all registered plugins sorted by name.

func (*PluginManager) Disable

func (pm *PluginManager) Disable(name string) error

Disable disables a plugin and all plugins that depend on it (reverse dependency order). Returns an error if the plugin is not registered.

func (*PluginManager) Enable

func (pm *PluginManager) Enable(name string) error

Enable enables a plugin and all its unsatisfied dependencies (topological order). Returns an error if the plugin is not registered, if a dependency is missing, or if a circular dependency is detected.

func (*PluginManager) EnabledPlugins

func (pm *PluginManager) EnabledPlugins() []NativePlugin

EnabledPlugins returns all currently enabled plugins sorted by name.

func (*PluginManager) IsEnabled

func (pm *PluginManager) IsEnabled(name string) bool

IsEnabled returns whether a plugin is currently enabled.

func (*PluginManager) Register

func (pm *PluginManager) Register(p NativePlugin) error

Register adds a plugin to the known set. It does not enable the plugin. Returns an error if a plugin with the same name is already registered.

func (*PluginManager) RestoreState

func (pm *PluginManager) RestoreState() error

RestoreState re-enables all plugins that were previously enabled (from the plugin_state table). This is called after an engine restart or reload.

func (*PluginManager) ServeHTTP

func (pm *PluginManager) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP dispatches HTTP requests to the correct plugin's mux. Route pattern: /api/v1/admin/plugins/{name}/{path...} Returns 404 if the plugin is not found or not enabled.

func (*PluginManager) SetContext

func (pm *PluginManager) SetContext(ctx PluginContext)

SetContext sets the shared PluginContext used for OnEnable/OnDisable calls.

type PluginManifest

type PluginManifest struct {
	Name         string                 `json:"name" yaml:"name"`
	Version      string                 `json:"version" yaml:"version"`
	Author       string                 `json:"author" yaml:"author"`
	Description  string                 `json:"description" yaml:"description"`
	License      string                 `json:"license,omitempty" yaml:"license,omitempty"`
	Dependencies []Dependency           `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
	Contract     *dynamic.FieldContract `json:"contract,omitempty" yaml:"contract,omitempty"`
	Tags         []string               `json:"tags,omitempty" yaml:"tags,omitempty"`
	Repository   string                 `json:"repository,omitempty" yaml:"repository,omitempty"`
}

PluginManifest describes a plugin's metadata, dependencies, and contract.

func LoadManifest

func LoadManifest(path string) (*PluginManifest, error)

LoadManifest reads a manifest from a JSON file.

func (*PluginManifest) Validate

func (m *PluginManifest) Validate() error

Validate checks that a manifest has all required fields and valid semver.

type PluginRegistry

type PluginRegistry interface {
	Register(manifest *PluginManifest, component *dynamic.DynamicComponent, sourceDir string) error
	Unregister(name string) error
	Get(name string) (*PluginEntry, bool)
	List() []*PluginEntry
	CheckDependencies(manifest *PluginManifest) error
}

PluginRegistry manages plugin registration and lookup.

type RegistryHandler

type RegistryHandler struct {
	// contains filtered or unexported fields
}

RegistryHandler provides HTTP API handlers for plugin management.

func NewRegistryHandler

func NewRegistryHandler(registry *CompositeRegistry) *RegistryHandler

NewRegistryHandler creates a new registry handler backed by the given composite registry.

func (*RegistryHandler) RegisterRoutes

func (h *RegistryHandler) RegisterRoutes(mux *http.ServeMux)

RegisterRoutes registers plugin management HTTP routes on the given mux.

type RemoteRegistry

type RemoteRegistry struct {
	// contains filtered or unexported fields
}

RemoteRegistry discovers and downloads plugins from a remote HTTP registry.

func NewRemoteRegistry

func NewRemoteRegistry(baseURL string, opts ...RemoteRegistryOption) *RemoteRegistry

NewRemoteRegistry creates a new remote registry client.

func (*RemoteRegistry) ClearCache

func (r *RemoteRegistry) ClearCache()

ClearCache clears the in-memory manifest cache.

func (*RemoteRegistry) Download

func (r *RemoteRegistry) Download(ctx context.Context, name, version string) (io.ReadCloser, error)

Download retrieves the plugin archive for a specific version.

func (*RemoteRegistry) GetManifest

func (r *RemoteRegistry) GetManifest(ctx context.Context, name, version string) (*PluginManifest, error)

GetManifest retrieves the manifest for a specific plugin version from the remote registry.

func (*RemoteRegistry) ListVersions

func (r *RemoteRegistry) ListVersions(ctx context.Context, name string) ([]string, error)

ListVersions retrieves available versions for a plugin from the remote registry.

func (*RemoteRegistry) Search

func (r *RemoteRegistry) Search(ctx context.Context, query string) ([]*PluginManifest, error)

Search queries the remote registry for plugins matching the given query string.

type RemoteRegistryOption

type RemoteRegistryOption func(*RemoteRegistry)

RemoteRegistryOption configures a RemoteRegistry.

func WithCacheTTL

func WithCacheTTL(ttl time.Duration) RemoteRegistryOption

WithCacheTTL sets how long cached manifests remain valid.

func WithHTTPClient

func WithHTTPClient(client *http.Client) RemoteRegistryOption

WithHTTPClient sets the HTTP client used by the remote registry.

type Semver

type Semver struct {
	Major int
	Minor int
	Patch int
}

Semver represents a parsed semantic version.

func ParseSemver

func ParseSemver(v string) (Semver, error)

ParseSemver parses a version string like "1.2.3" into a Semver.

func (Semver) Compare

func (s Semver) Compare(other Semver) int

Compare returns -1, 0, or 1.

func (Semver) String

func (s Semver) String() string

type UIPageDef

type UIPageDef struct {
	ID       string `json:"id"`
	Label    string `json:"label"`
	Icon     string `json:"icon"`
	Category string `json:"category"` // "global", "workflow", "plugin"
	Order    int    `json:"order"`
}

UIPageDef describes a UI page contributed by a plugin.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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