daemon

package
v0.22.3 Latest Latest
Warning

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

Go to latest
Published: Apr 28, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package daemon manages a single persistent `clawtool serve --listen --mcp-http` process the operator's hosts (Codex / OpenCode / Gemini / Claude Code) all fan into. Per ADR-014 (recursive) and the operator's design call: every host that registers clawtool as an MCP server should connect to the SAME backend so BIAM identity, task store, and notify channels are shared. Stdio-spawning a child per host would create N independent identities and N independent BIAM stores — cross-host notify cannot work that way.

State lives at $XDG_CONFIG_HOME/clawtool/daemon.json (LF-delimited, 0600). Token file (bearer) lives at $XDG_CONFIG_HOME/clawtool/ listener-token. Ensure starts the daemon if missing, returns the existing state otherwise; Stop SIGTERMs and cleans up.

This package is the only place that knows the daemon's process lifecycle. Adapters (mcp_host.go) and CLI (`clawtool daemon …`) drive it through Ensure / Stop / Status — they don't touch the state file directly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FormatStatus

func FormatStatus(s *State) string

FormatStatus renders the daemon state as a multi-line human string for `clawtool daemon status`. Used by the CLI; tests assert on substrings not whole layout.

func IsRunning

func IsRunning(s *State) bool

IsRunning returns true when the recorded PID is alive AND the port still answers /v1/health within a short timeout. Both checks matter: a stale state file from a crashed daemon must not look healthy, and a port that no longer belongs to us (recycled by some other process) must not look ours.

func LogPath

func LogPath() string

LogPath returns the daemon's combined-output log path.

func PortFromEnv

func PortFromEnv() (int, bool)

PortFromEnv lets tests override the port pick (used in adapter integration tests where we don't actually want to spawn).

func ReadToken

func ReadToken() (string, error)

ReadToken returns the bearer token contents (whitespace-trimmed). Empty string + nil error if the file is missing — Ensure ensures the file exists before exposing the token to callers.

func StatePath

func StatePath() string

StatePath returns the file Ensure / Stop persist to. Honors $XDG_CONFIG_HOME, else ~/.config/clawtool/daemon.json.

func Stop

func Stop() error

Stop sends SIGTERM, waits up to 5s, escalates to SIGKILL, then removes the state file. No-op if no daemon is recorded.

func TokenPath

func TokenPath() string

TokenPath returns the bearer-token file the daemon and adapters share. Same XDG conventions as StatePath.

Types

type State

type State struct {
	Version   int       `json:"version"`
	PID       int       `json:"pid"`
	Port      int       `json:"port"`
	StartedAt time.Time `json:"started_at"`
	TokenFile string    `json:"token_file"`
	LogFile   string    `json:"log_file"`
}

State is the persisted snapshot of a running daemon.

func Ensure

func Ensure(ctx context.Context) (*State, error)

Ensure starts the daemon if it isn't already running and returns the live State. Idempotent: if the daemon is already healthy, the existing state is returned without spawning.

Spawn flow: pick a free port, ensure the bearer token, fork the detached process, write state, poll /v1/health for up to 5s.

func ReadState

func ReadState() (*State, error)

ReadState returns the persisted state, or (nil, nil) if no daemon has been started yet. Parse errors are returned verbatim so callers can decide whether to wipe + retry.

func (*State) HealthURL

func (s *State) HealthURL() string

HealthURL is the unauthenticated probe URL the daemon exposes for readiness checks.

func (*State) URL

func (s *State) URL() string

URL is the MCP-over-HTTP endpoint hosts dial.

Jump to

Keyboard shortcuts

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