Documentation
¶
Overview ¶
Package plugin provides the plugin architecture for QNTX domain extensions.
A domain plugin represents a complete functional area (e.g., code, biotech, finance). Each domain provides HTTP endpoints, WebSocket handlers, and lifecycle management.
Architecture:
- All domains run as separate processes via gRPC
- All domains implement the same DomainPlugin interface
- Domains are isolated - interact only via shared database (attestations)
Example domains:
- code: Software development (git ingestion, GitHub PRs, language servers, code editor)
- biotech: Bioinformatics (sequence analysis, protein folding, genomics)
- finance: Financial analysis (market data, risk modeling, portfolio optimization)
Index ¶
- func List() []string
- func Register(plugin DomainPlugin) error
- func SetDefaultRegistry(registry *Registry)
- type Config
- type ConfigField
- type ConfigProvider
- type ConfigurablePlugin
- type DefaultServiceRegistry
- func (r *DefaultServiceRegistry) ATSStore() ats.AttestationStore
- func (r *DefaultServiceRegistry) Config(domain string) Config
- func (r *DefaultServiceRegistry) Database() *sql.DB
- func (r *DefaultServiceRegistry) Logger(domain string) *zap.SugaredLogger
- func (r *DefaultServiceRegistry) Queue() QueueService
- type DomainPlugin
- type HealthStatus
- type Metadata
- type PausablePlugin
- type PluginState
- type QueueService
- type Registry
- func (r *Registry) Get(name string) (DomainPlugin, bool)
- func (r *Registry) GetAll() map[string]DomainPlugin
- func (r *Registry) GetAllStates() map[string]PluginState
- func (r *Registry) GetState(name string) (PluginState, bool)
- func (r *Registry) HealthCheckAll(ctx context.Context) map[string]HealthStatus
- func (r *Registry) InitializeAll(ctx context.Context, services ServiceRegistry) error
- func (r *Registry) IsPausable(name string) bool
- func (r *Registry) IsReady(name string) bool
- func (r *Registry) List() []string
- func (r *Registry) ListEnabled() []string
- func (r *Registry) MarkReady(name string)
- func (r *Registry) Pause(ctx context.Context, name string) error
- func (r *Registry) PreRegister(name string)
- func (r *Registry) Register(plugin DomainPlugin) error
- func (r *Registry) Resume(ctx context.Context, name string) error
- func (r *Registry) ShutdownAll(ctx context.Context) error
- type ServiceRegistry
- type WebSocketHandler
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func List ¶
func List() []string
List returns all plugin names from the global registry (Issue #4: Thread-safe)
func Register ¶
func Register(plugin DomainPlugin) error
Register registers a plugin with the global registry (Issue #4: Thread-safe)
func SetDefaultRegistry ¶
func SetDefaultRegistry(registry *Registry)
SetDefaultRegistry sets the global registry (Issue #4: Thread-safe) Panics if called more than once. The mutex ensures thread-safe check-and-set.
Types ¶
type Config ¶
type Config interface {
// GetString retrieves a string configuration value
GetString(key string) string
// GetInt retrieves an integer configuration value
GetInt(key string) int
// GetBool retrieves a boolean configuration value
GetBool(key string) bool
// GetStringSlice retrieves a string slice configuration value
GetStringSlice(key string) []string
// Get retrieves a raw configuration value
Get(key string) interface{}
// Set sets a configuration value (for runtime overrides)
Set(key string, value interface{})
// GetKeys returns all available configuration keys (sorted)
GetKeys() []string
}
Config provides access to plugin configuration
type ConfigField ¶
type ConfigField struct {
Type string // "string", "number", "boolean", "array"
Description string // Human-readable description
DefaultValue string // Default value as string
Required bool // Whether field is required
MinValue string // For numbers: minimum value
MaxValue string // For numbers: maximum value
Pattern string // For strings: regex validation pattern
ElementType string // For arrays: element type
}
ConfigField describes a single configuration field for UI-based configuration. This maps directly to protocol.ConfigFieldSchema for gRPC serialization.
type ConfigProvider ¶
type ConfigProvider interface {
// GetPluginConfig returns configuration for a specific plugin
GetPluginConfig(domain string) Config
}
ConfigProvider provides configuration for plugins
type ConfigurablePlugin ¶
type ConfigurablePlugin interface {
DomainPlugin
// ConfigSchema returns the configuration schema for this plugin.
// The returned map keys are configuration field names (e.g., "gopls.workspace_root").
// Values describe each field's type, description, default, and validation constraints.
//
// Field types: "string", "number", "boolean", "array"
// See protocol.ConfigFieldSchema for the full schema definition.
ConfigSchema() map[string]ConfigField
}
ConfigurablePlugin is an optional interface for plugins that expose configuration schemas for UI-based configuration. Plugins implementing this interface will have their configuration schema exposed via the gRPC ConfigSchema RPC, enabling the web UI to render configuration forms.
type DefaultServiceRegistry ¶
type DefaultServiceRegistry struct {
// contains filtered or unexported fields
}
DefaultServiceRegistry is the standard implementation of ServiceRegistry
func (*DefaultServiceRegistry) ATSStore ¶
func (r *DefaultServiceRegistry) ATSStore() ats.AttestationStore
ATSStore returns the attestation storage interface
func (*DefaultServiceRegistry) Config ¶
func (r *DefaultServiceRegistry) Config(domain string) Config
Config returns plugin-specific configuration
func (*DefaultServiceRegistry) Database ¶
func (r *DefaultServiceRegistry) Database() *sql.DB
Database returns the shared QNTX database connection
func (*DefaultServiceRegistry) Logger ¶
func (r *DefaultServiceRegistry) Logger(domain string) *zap.SugaredLogger
Logger returns a logger for the specified domain with version information
func (*DefaultServiceRegistry) Queue ¶
func (r *DefaultServiceRegistry) Queue() QueueService
Queue returns the Pulse async job queue
type DomainPlugin ¶
type DomainPlugin interface {
// Metadata returns information about this domain plugin
Metadata() Metadata
// Initialize is called when the plugin is loaded
// The plugin receives a service registry to access QNTX core services
Initialize(ctx context.Context, services ServiceRegistry) error
// Shutdown is called when QNTX is shutting down
Shutdown(ctx context.Context) error
// RegisterHTTP registers HTTP handlers for this domain
// Handlers will be mounted at: /api/<domain-name>/*
RegisterHTTP(mux *http.ServeMux) error
// RegisterWebSocket registers WebSocket handlers for this domain
// Handlers will be mounted at: /<domain-name>-ws
RegisterWebSocket() (map[string]WebSocketHandler, error)
// Health returns the health status of this domain plugin
Health(ctx context.Context) HealthStatus
}
DomainPlugin defines the interface that all domain plugins must implement. All plugins implement this interface.
func Get ¶
func Get(name string) (DomainPlugin, bool)
Get retrieves a plugin from the global registry (Issue #4: Thread-safe)
type HealthStatus ¶
type HealthStatus struct {
Healthy bool
Paused bool // True if plugin is intentionally paused (not a failure)
Message string
Details map[string]interface{}
}
HealthStatus represents the health of a domain plugin
type Metadata ¶
type Metadata struct {
// Name is the domain identifier (e.g., "code", "biotech")
Name string
// Version is the plugin version (semver)
Version string
// QNTXVersion is the required QNTX version (semver constraint)
QNTXVersion string
// Description is a human-readable description
Description string
// Author is the plugin author/maintainer
Author string
// License is the plugin license (e.g., "MIT", "Apache-2.0")
License string
}
Metadata describes a domain plugin
type PausablePlugin ¶
type PausablePlugin interface {
DomainPlugin
// Pause temporarily suspends the plugin's operations.
// The plugin should stop processing new requests but maintain its state.
// HTTP endpoints may return 503 Service Unavailable while paused.
Pause(ctx context.Context) error
// Resume restores the plugin to active operation after a pause.
Resume(ctx context.Context) error
}
PausablePlugin is an optional interface for plugins that support pause/resume. Plugins that implement this interface can be paused and resumed at runtime without a full shutdown/restart cycle.
type PluginState ¶
type PluginState string
PluginState represents the current state of a plugin
const ( // StateLoading indicates the plugin is currently loading/connecting StateLoading PluginState = "loading" // StateRunning indicates the plugin is active and processing requests StateRunning PluginState = "running" // StatePaused indicates the plugin is temporarily suspended StatePaused PluginState = "paused" // StateStopped indicates the plugin has been shut down StateStopped PluginState = "stopped" // StateFailed indicates the plugin failed to initialize or encountered a fatal error StateFailed PluginState = "failed" )
type QueueService ¶
type QueueService interface {
// Enqueue adds a new job to the queue
Enqueue(job *async.Job) error
// GetJob retrieves a job by ID
GetJob(id string) (*async.Job, error)
// UpdateJob updates a job's state
UpdateJob(job *async.Job) error
// ListJobs lists jobs with optional status filter
ListJobs(status *async.JobStatus, limit int) ([]*async.Job, error)
}
QueueService defines the job queue operations available to plugins. This interface allows both local and remote queue implementations.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages all domain plugins
func GetDefaultRegistry ¶
func GetDefaultRegistry() *Registry
GetDefaultRegistry returns the global registry (Issue #4: Thread-safe read)
func NewRegistry ¶
func NewRegistry(qntxVersion string, logger *zap.SugaredLogger) *Registry
NewRegistry creates a new plugin registry
func (*Registry) Get ¶
func (r *Registry) Get(name string) (DomainPlugin, bool)
Get retrieves a domain plugin by name
func (*Registry) GetAll ¶
func (r *Registry) GetAll() map[string]DomainPlugin
GetAll returns all registered plugins
func (*Registry) GetAllStates ¶
func (r *Registry) GetAllStates() map[string]PluginState
GetAllStates returns the states of all plugins
func (*Registry) GetState ¶
func (r *Registry) GetState(name string) (PluginState, bool)
GetState returns the current state of a plugin
func (*Registry) HealthCheckAll ¶
func (r *Registry) HealthCheckAll(ctx context.Context) map[string]HealthStatus
HealthCheckAll checks health of all plugins
func (*Registry) InitializeAll ¶
func (r *Registry) InitializeAll(ctx context.Context, services ServiceRegistry) error
InitializeAll initializes all registered plugins
func (*Registry) IsPausable ¶
IsPausable checks if a plugin implements the PausablePlugin interface
func (*Registry) ListEnabled ¶
ListEnabled returns all enabled plugin names (including pre-registered ones) in sorted order This includes plugins that are still loading, not just fully loaded ones
func (*Registry) MarkReady ¶
MarkReady marks a plugin as ready (StateRunning) after successful loading Used by async plugin loading to indicate plugin is ready to handle requests
func (*Registry) PreRegister ¶
PreRegister reserves a plugin slot in loading state before async initialization This allows routes to be registered immediately while plugins load in background
func (*Registry) Register ¶
func (r *Registry) Register(plugin DomainPlugin) error
Register registers a domain plugin Returns error if plugin name conflicts or version incompatible
type ServiceRegistry ¶
type ServiceRegistry interface {
// Database returns the shared QNTX database connection
Database() *sql.DB
// Logger returns a logger for this plugin
Logger(domain string) *zap.SugaredLogger
// Config returns plugin-specific configuration
Config(domain string) Config
// ATSStore returns the attestation storage interface
ATSStore() ats.AttestationStore
// Queue returns the Pulse async job queue
Queue() QueueService
}
ServiceRegistry provides access to QNTX core services for domain plugins. Plugins use this registry to look up services they need.
func NewServiceRegistry ¶
func NewServiceRegistry(db *sql.DB, logger *zap.SugaredLogger, store ats.AttestationStore, config ConfigProvider, queue QueueService) ServiceRegistry
NewServiceRegistry creates a new service registry
type WebSocketHandler ¶
type WebSocketHandler interface {
ServeWS(w http.ResponseWriter, r *http.Request)
}
WebSocketHandler handles WebSocket connections