plugin

package
v0.0.0-...-5467d48 Latest Latest
Warning

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

Go to latest
Published: Jul 14, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package plugin defines the Plugin interface, the KernelAPI that plugins are given access to, the kernel event bus, and the plugin loader.

A plugin's entire surface area is kernel registration. It gets a KernelAPI handle and installs hooks, commands, generators, and schemas through that handle. It NEVER reaches into kernel internals directly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Register

func Register(p Plugin)

Register adds a plugin to the global registry. Called from each plugin package's init() function.

func Unregister

func Unregister(name string)

Unregister removes a plugin from the global registry. Intended for use in tests only — do not call in production code.

Types

type Bus

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

Bus is the kernel event bus. Plugins subscribe to events via OnEvent.

func NewBus

func NewBus() *Bus

NewBus creates a new event bus.

func (*Bus) Emit

func (b *Bus) Emit(event Event, payload EventPayload)

Emit publishes an event to all registered handlers. Handlers run synchronously in registration order. Panics in handlers are recovered and logged.

func (*Bus) On

func (b *Bus) On(event Event, handler func(EventPayload))

On subscribes a handler to a specific event.

type CLICommand

type CLICommand struct {
	Use   string
	Short string
	Long  string
	Run   func(args []string) error
	Flags []CLIFlag
}

CLICommand represents a new command that a plugin adds to the Acthur CLI.

type CLIFlag

type CLIFlag struct {
	Name    string
	Short   string
	Default string
	Usage   string
}

CLIFlag is a flag on a plugin-registered CLI command.

type Event

type Event string

Event names published on the kernel event bus.

const (
	EventBeforeGraphBuild   Event = "kernel:graph:before_build"
	EventAfterGraphBuild    Event = "kernel:graph:after_build"
	EventBeforeNodeStart    Event = "kernel:node:before_start"
	EventAfterNodeStart     Event = "kernel:node:after_start"
	EventAfterNodeHealthy   Event = "kernel:node:after_healthy"
	EventBeforeNodeStop     Event = "kernel:node:before_stop"
	EventAfterNodeStop      Event = "kernel:node:after_stop"
	EventOnNodeFailure      Event = "kernel:node:on_failure"
	EventBeforeProxyRequest Event = "kernel:proxy:before_request"
	EventAfterProxyRequest  Event = "kernel:proxy:after_request"
	EventBeforeMigrateRun   Event = "kernel:db:before_migrate"
	EventAfterMigrateRun    Event = "kernel:db:after_migrate"
	EventBeforeSeedRun      Event = "kernel:db:before_seed"
	EventAfterSeedRun       Event = "kernel:db:after_seed"
	EventBeforeDeploy       Event = "kernel:deploy:before"
	EventAfterDeploy        Event = "kernel:deploy:after"
	EventDeployPreflight    Event = "kernel:deploy:preflight"
	EventContractRegistered Event = "kernel:contract:registered"
	EventContractViolated   Event = "kernel:contract:violated"
	EventPluginLoaded       Event = "kernel:plugin:loaded"
	EventPluginError        Event = "kernel:plugin:error"
)

type EventPayload

type EventPayload struct {
	Event     Event
	NodeID    string
	Timestamp time.Time
	Data      map[string]any
}

EventPayload carries event-specific data to handlers.

type FieldDef

type FieldDef struct {
	Type     string
	Required bool
	Default  any
}

FieldDef defines a single field in a schema.

type GeneratedFile

type GeneratedFile struct {
	Path        string
	Content     []byte
	Mode        uint32
	Overwrite   bool   // if false, skip if file already exists
	MergeMarker string // if set, merge at this marker rather than overwrite
}

GeneratedFile is a single file produced by a generator.

type Generator

type Generator interface {
	// Generate produces files for the given adapter.
	// Returns an error if the adapter is not supported.
	Generate(adapterName string, ctx GeneratorContext) ([]GeneratedFile, error)

	// SupportedAdapters returns which adapters this generator supports.
	SupportedAdapters() []string
}

Generator is a code generation unit provided by a plugin. When `acthur generate <target>` is run (or triggered internally), the kernel calls Generate() with the resolved adapter name.

type GeneratorContext

type GeneratorContext struct {
	ProjectName string
	NodeID      string
	RootDir     string
	Config      map[string]any
	Extra       map[string]any
}

GeneratorContext is passed to Generator.Generate().

type GraphReader

type GraphReader interface {
	Node(id string) *graph.Node
	Nodes() []*graph.Node
	Edges() []*graph.Edge
}

GraphReader provides read-only access to the graph for plugins.

type KernelAPI

type KernelAPI interface {
	// Hook into kernel lifecycle events
	OnEvent(event Event, handler func(EventPayload))

	// Register a new CLI command (appears under `acthur` root)
	RegisterCommand(cmd CLICommand)

	// Register a code generator for a specific target name
	// Adapter support for generator targets will be modeled as a capability
	// when the generator engine lands.
	RegisterGenerator(target string, gen Generator)

	// Register a type schema (added to contract type registry)
	RegisterSchema(name string, schema SchemaDefinition)

	// Register HTTP middleware to inject at the proxy layer
	RegisterMiddleware(m Middleware)

	// Mutate the live graph (add nodes or edges)
	// Used by plugins that need to inject infrastructure nodes (e.g. a mailer
	// plugin that adds a mailpit infra node in dev)
	AddNode(node *graph.Node)
	AddEdge(edge *graph.Edge)

	// Read-only access to the graph
	Graph() GraphReader

	// Log using the kernel's output system
	Log(level LogLevel, format string, args ...any)
}

KernelAPI is the restricted interface provided to plugins. This is the ONLY way plugins can interact with the kernel. Plugins cannot access any kernel internals not exposed here.

type KernelAPIImpl

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

KernelAPIImpl is the kernel's real, concrete KernelAPI implementation. It is constructed once at CLI assembly (ADR 0005 resolver-injection pattern) and handed to every plugin's Register method during Load.

Graph mutation (AddNode/AddEdge) is only valid pre-seal — see ADR 0003. The underlying *graph.Graph enforces this itself: it panics if a structural mutation is attempted after Freeze(). KernelAPIImpl does not duplicate that check; it simply forwards to the graph.

func NewKernelAPI

func NewKernelAPI(bus *Bus, g *graph.Graph, addCommand func(CLICommand), logFunc func(level LogLevel, format string, args ...any)) *KernelAPIImpl

NewKernelAPI constructs a KernelAPIImpl.

  • bus: the kernel event bus plugins subscribe to via OnEvent.
  • g: the live graph, mutable pre-seal only (ADR 0003).
  • addCommand: called for every plugin.RegisterCommand — the CLI assembly wires this to cobra Root.AddCommand via a small adapter.

logFunc may be nil, in which case Log falls back to fmt.Printf so the implementation stays usable in tests without pulling in internal/output.

func (*KernelAPIImpl) AddEdge

func (k *KernelAPIImpl) AddEdge(edge *graph.Edge)

AddEdge forwards to the live graph. Valid pre-seal only — the graph itself panics if called after Freeze() (ADR 0003).

func (*KernelAPIImpl) AddNode

func (k *KernelAPIImpl) AddNode(node *graph.Node)

AddNode forwards to the live graph. Valid pre-seal only — the graph itself panics if called after Freeze() (ADR 0003).

func (*KernelAPIImpl) Generator

func (k *KernelAPIImpl) Generator(target string) (Generator, bool)

Generator returns the generator registered under target, if any.

func (*KernelAPIImpl) Generators

func (k *KernelAPIImpl) Generators() map[string]Generator

Generators returns every registered target name, sorted for stable output.

func (*KernelAPIImpl) Graph

func (k *KernelAPIImpl) Graph() GraphReader

Graph returns a read-only view of the live graph. *graph.Graph already satisfies GraphReader (Node/Nodes/Edges), so no adapter type is needed.

func (*KernelAPIImpl) Log

func (k *KernelAPIImpl) Log(level LogLevel, format string, args ...any)

Log routes through the kernel's output system when logFunc is provided, otherwise falls back to fmt.Printf (keeps this type usable standalone).

func (*KernelAPIImpl) Middlewares

func (k *KernelAPIImpl) Middlewares() []Middleware

Middlewares returns every registered middleware, in registration order.

func (*KernelAPIImpl) OnEvent

func (k *KernelAPIImpl) OnEvent(event Event, handler func(EventPayload))

OnEvent subscribes handler to event on the kernel bus.

func (*KernelAPIImpl) RegisterCommand

func (k *KernelAPIImpl) RegisterCommand(cmd CLICommand)

RegisterCommand hands cmd to the CLI assembly's addCommand callback.

func (*KernelAPIImpl) RegisterGenerator

func (k *KernelAPIImpl) RegisterGenerator(target string, gen Generator)

RegisterGenerator stores gen under target in the kernel's generator registry. Consumed by the generator engine (Phase 7).

func (*KernelAPIImpl) RegisterMiddleware

func (k *KernelAPIImpl) RegisterMiddleware(m Middleware)

RegisterMiddleware appends m to the kernel's proxy middleware chain. Consumed by the dev proxy once it grows a middleware chain.

func (*KernelAPIImpl) RegisterSchema

func (k *KernelAPIImpl) RegisterSchema(name string, schema SchemaDefinition)

RegisterSchema stores schema under name in the kernel's contract type registry. Consumed by the contract engine.

func (*KernelAPIImpl) Schema

func (k *KernelAPIImpl) Schema(name string) (SchemaDefinition, bool)

Schema returns the schema registered under name, if any.

func (*KernelAPIImpl) Schemas

func (k *KernelAPIImpl) Schemas() map[string]SchemaDefinition

Schemas returns every registered schema, keyed by name.

type LoadedPlugin

type LoadedPlugin struct {
	Plugin   Plugin
	LoadedAt time.Time
}

LoadedPlugin wraps a Plugin with its runtime state.

func Load

func Load(names []string, bus *Bus, k KernelAPI) ([]*LoadedPlugin, error)

Load resolves and loads plugins in topological dependency order. Returns the ordered list of loaded plugins, or an error if any dependency is missing or a cycle is detected.

func LoadDelta

func LoadDelta(names, satisfied []string, bus *Bus, k KernelAPI) ([]*LoadedPlugin, error)

LoadDelta loads names like Load, but treats the plugins in satisfied as already loaded in this process: a DependsOn pointing at one of them is met without re-loading it. Used when plugins are added to a process that has already loaded the project's plugin list (e.g. `acthur add` after CLI bootstrap) — re-loading an existing plugin would double-register its hooks and commands.

type LogLevel

type LogLevel string

LogLevel mirrors the output package levels.

const (
	LogInfo  LogLevel = "info"
	LogWarn  LogLevel = "warn"
	LogError LogLevel = "error"
	LogDebug LogLevel = "debug"
)

type Middleware

type Middleware struct {
	Name     string
	Priority int // lower number runs first; 0=first, 100=last
	Handler  func(req Request, next func(Request) Response) Response
}

Middleware is an HTTP middleware injected at the proxy layer.

type Plugin

type Plugin interface {
	// Name returns the plugin's unique identifier (e.g. "auth", "migrations").
	Name() string

	// Version returns the plugin's semantic version string.
	Version() string

	// DependsOn returns names of other plugins that must be loaded first.
	// The loader resolves these into a topological load order.
	DependsOn() []string

	// Register is called once during kernel boot.
	// The plugin receives a KernelAPI handle and must install everything
	// through it. After Register returns, the plugin is active.
	Register(k KernelAPI) error
}

Plugin is the interface every Acthur plugin must implement. Three methods to implement. One method called by the kernel (Register).

func All

func All() []Plugin

All returns all registered plugins.

func Resolve

func Resolve(name string) (Plugin, error)

Resolve returns the plugin registered under the given name.

type Request

type Request struct {
	Method  string
	Path    string
	Headers map[string]string
	Body    []byte
}

Request and Response are minimal representations for proxy middleware. (Full implementations use net/http internally.)

type Response

type Response struct {
	Status  int
	Headers map[string]string
	Body    []byte
}

type SchemaDefinition

type SchemaDefinition struct {
	Name   string
	Fields map[string]FieldDef
}

SchemaDefinition defines a type that plugins contribute to the contract registry.

Directories

Path Synopsis
builtin
admin
Package admin is the built-in "admin" plugin (Phase 9, tracker #65).
Package admin is the built-in "admin" plugin (Phase 9, tracker #65).
auth
Package auth is Acthur's built-in "auth" plugin (Phase 6 Slice 2).
Package auth is Acthur's built-in "auth" plugin (Phase 6 Slice 2).
featureflags
Package featureflags is the built-in "feature-flags" plugin (Phase 9, tracker #65).
Package featureflags is the built-in "feature-flags" plugin (Phase 9, tracker #65).
https
Package https is the built-in "https" plugin (Phase 9, tracker #65).
Package https is the built-in "https" plugin (Phase 9, tracker #65).
migrations
Package migrations is the built-in "migrations" plugin: it registers a generator that scaffolds a project's migrations/ directory with an initial golang-migrate-compatible pair, and exposes the database-command logic consumed by `acthur db migrate|rollback|status|create` (wired in cmd/acthur, since the plugin KernelAPI's CLICommand model registers only flat top-level commands — it has no notion of a command group, and `acthur db` already exists as a real cobra group in cmd/acthur/commands.go).
Package migrations is the built-in "migrations" plugin: it registers a generator that scaffolds a project's migrations/ directory with an initial golang-migrate-compatible pair, and exposes the database-command logic consumed by `acthur db migrate|rollback|status|create` (wired in cmd/acthur, since the plugin KernelAPI's CLICommand model registers only flat top-level commands — it has no notion of a command group, and `acthur db` already exists as a real cobra group in cmd/acthur/commands.go).
multitenancy
Package multitenancy is the built-in "multitenancy" plugin (Phase 6, Slice 4): schema-per-tenant multitenancy for go:fiber projects backed by Postgres.
Package multitenancy is the built-in "multitenancy" plugin (Phase 6, Slice 4): schema-per-tenant multitenancy for go:fiber projects backed by Postgres.
observability
Package observability is the built-in "observability" plugin (Phase 9, tracker #65).
Package observability is the built-in "observability" plugin (Phase 9, tracker #65).
rbac
Package rbac is the built-in "rbac" plugin: role-based access control for The go:fiber projects.
Package rbac is the built-in "rbac" plugin: role-based access control for The go:fiber projects.
security
Package security is the built-in "security" plugin (Phase 9, tracker #65).
Package security is the built-in "security" plugin (Phase 9, tracker #65).
testplugin
Package testplugin is the built-in "test" plugin: Phase 5's proof that a plugin's hook, command, and generator registrations all fire at the correct lifecycle points under the real kernel.
Package testplugin is the built-in "test" plugin: Phase 5's proof that a plugin's hook, command, and generator registrations all fire at the correct lifecycle points under the real kernel.

Jump to

Keyboard shortcuts

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