// Package module defines the four-phase contract every installable unit // implements, along with the value types exchanged with the engine. package module import "context" // Meta is static, declarative information about a module. type Meta struct { ID string // stable machine identifier, e.g. "packages" Name string // human label, e.g. "Base packages" Description string // one-line summary for TUI Deps []string // IDs of modules that must complete before this one } // State is an opaque, module-defined snapshot of current system state. // The engine never inspects it; it is threaded from Detect → Plan. type State any // ActionKind categorizes what an Action does, for UI grouping only. type ActionKind int const ( ActionUnknown ActionKind = iota ActionPackageInstall ActionFileWrite ActionSymlink ActionCommand ActionGitClone ActionGroupAdd ) // Action is a single planned change with a human-readable description. type Action struct { Description string Kind ActionKind Exec func(ctx context.Context) error } // Plan is an ordered list of actions returned by Module.Plan. type Plan struct { Actions []Action } // IsEmpty reports whether the plan would make no changes. func (p Plan) IsEmpty() bool { return len(p.Actions) == 0 } // Module is the four-phase contract. type Module interface { Meta() Meta Detect(ctx context.Context) (State, error) Plan(ctx context.Context, current State) (Plan, error) // PlanForce returns a plan that reapplies the module unconditionally, // ignoring current detected state. Used by `archduino install --force`. // Implementations should produce a plan equivalent to a from-scratch // install — reinstall packages without pacman's --needed guard and // rewrite managed config files. PlanForce(ctx context.Context) (Plan, error) Apply(ctx context.Context, plan Plan, r Reporter) error Verify(ctx context.Context) error } // Reporter is how modules stream progress events. Defined here as an // interface to avoid an import cycle with the engine package. type Reporter interface { Progress(moduleID string, current, total int, message string) Log(moduleID, line string) }