Documentation
¶
Overview ¶
Package processctl owns the in-process lifecycle of the HTTP server and background worker: Start/Stop/IsRunning + a per-process IsManaged flag that says whether wick was launched via the system tray (and is therefore allowed to mutate its own server/worker state).
Two consumers:
- internal/systemtray — calls Start/Stop on menu clicks and subscribes to OnStateChange so tray UI redraws when state flips.
- internal/connectors/wickmanager — exposes Start/Stop/Status as MCP ops gated by IsManaged so an LLM can only manage server/ worker when wick is actually the tray-resident process. `wick server` / `wick worker` / headless modes leave IsManaged=false so the ops return "system management unavailable in this run mode".
Implementation lives in headless-build-tagged files so the headless build (no tray) compiles a stub that always reports IsManaged=false and refuses Start/Stop. Tray boot calls SetManaged(true) once.
Index ¶
- Variables
- func IsManaged() bool
- func IsServerRunning() bool
- func IsWorkerRunning() bool
- func MCPLogger() (zerolog.Logger, bool)
- func ServerPort() int
- func SetMCPLogger(l zerolog.Logger)
- func SetManaged(v bool)
- func SetPort(port int)
- func SetServerLogger(l zerolog.Logger)
- func SetServerRunner(r Runner)
- func SetWorkerLogger(l zerolog.Logger)
- func SetWorkerRunner(r Runner)
- func StartServer() error
- func StartWorker() error
- func StopAll()
- func StopServer() error
- func StopWorker() error
- func Subscribe(fn func(StateChange)) func()
- type Runner
- type RunnerFunc
- type StateChange
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyRunning = errors.New("already running")
ErrAlreadyRunning is returned by Server.Start / Worker.Start when the component is already up. Callers check via errors.Is so wickmanager can map it to a stable error string for the LLM.
var ErrNotManaged = errors.New("system management unavailable in this run mode (start wick via the tray)")
ErrNotManaged is returned by every state-mutating method when the process was not launched via the tray. wick server / wick worker / headless never satisfy IsManaged.
Functions ¶
func IsManaged ¶
func IsManaged() bool
IsManaged reports whether the current process is the tray-resident one. wickmanager's tray-only ops gate on this.
func IsServerRunning ¶
func IsServerRunning() bool
IsServerRunning reports whether the server goroutine is up.
func IsWorkerRunning ¶
func IsWorkerRunning() bool
IsWorkerRunning reports whether the worker goroutine is up.
func MCPLogger ¶
MCPLogger returns the wickmanager audit logger configured via SetMCPLogger. The bool is false when no logger was set; callers then default to log.Logger / zerolog.Ctx(ctx).
func ServerPort ¶
func ServerPort() int
ServerPort returns the configured listen port. 0 before SetPort.
func SetMCPLogger ¶
SetMCPLogger configures the destination for the wickmanager connector's audit log (~/.<appName>/logs/mcp-YYYY-MM-DD.log). Tray calls this after opening the log file; non-tray callers (wick server / headless) leave it at zero, in which case wickmanager falls back to the global zerolog logger.
func SetManaged ¶
func SetManaged(v bool)
SetManaged marks the current process as the tray-resident one. Called once from systemtray.Run before any Start/Stop is reachable. Other entry points (wick server / wick worker / headless) never call this, so IsManaged stays false there.
func SetPort ¶
func SetPort(port int)
SetPort configures the HTTP listen port StartServer will bind. Tray resolves config.Load().App.Port at boot and passes it in here.
func SetServerLogger ¶
SetServerLogger configures the zerolog.Logger threaded through every future server.Run context. Tray calls this with its server-log file writer; wickmanager-only callers (no tray) leave it at the default.
func SetServerRunner ¶
func SetServerRunner(r Runner)
SetServerRunner installs the runner StartServer launches. Tray wires this to api.NewServer with its port closed-over; non-tray callers (wick server / wick worker / headless) never call it.
func SetWorkerLogger ¶
SetWorkerLogger is the worker-side counterpart to SetServerLogger.
func SetWorkerRunner ¶
func SetWorkerRunner(r Runner)
SetWorkerRunner installs the runner StartWorker launches. Tray wires this to worker.NewServer.
func StartServer ¶
func StartServer() error
StartServer launches the HTTP server in this process. Returns ErrAlreadyRunning when one is already up, ErrNotManaged when the process is not tray-resident, or a wrapped bind error when the pre-flight listener check fails.
func StartWorker ¶
func StartWorker() error
StartWorker launches the background worker in this process. Returns ErrAlreadyRunning / ErrNotManaged the same way StartServer does.
func StopAll ¶
func StopAll()
StopAll halts both. Used by tray Quit and the updater's apply-then- restart path. Ignores ErrNotManaged so non-tray callers (which shouldn't reach here) get a no-op.
func StopServer ¶
func StopServer() error
StopServer cancels the server goroutine and waits for it to drain. No-op when nothing is running. Always reports nil — used by tray menu and wickmanager system_server_stop.
func StopWorker ¶
func StopWorker() error
StopWorker cancels the worker goroutine and waits for it to drain. No-op when nothing is running.
func Subscribe ¶
func Subscribe(fn func(StateChange)) func()
Subscribe registers a callback fired after every Start/Stop. Used by the tray to refresh its icon + menu labels — non-tray callers don't subscribe. Returned func unsubscribes.
Types ¶
type Runner ¶
Runner is the contract a server / worker must satisfy. Both internal/pkg/api.Server and internal/pkg/worker.Server already implement it via their existing Run(ctx) signatures (api.Server.Run also takes a port; the tray wraps it before plugging in here).
processctl owns the goroutine + cancel handle and never calls NewServer itself — that keeps internal/pkg/api and internal/pkg/ worker free to import processctl when they need IsManaged without dragging the whole runtime through an import cycle.
type RunnerFunc ¶
RunnerFunc adapts a closure to Runner. Tray uses it to wrap api.NewServer().Run with the configured port:
processctl.SetServerRunner(processctl.RunnerFunc(func(ctx context.Context) error {
return api.NewServer().Run(ctx, processctl.ServerPort())
}))
type StateChange ¶
StateChange is the event payload sent on every state transition. The tray subscribes to refresh its menu icon + labels; wickmanager does not subscribe (it polls IsRunning at op-call time).