Help us shape the future of Go! Take the 2026 Go Developer Survey

config

package
v0.40.4 Latest Latest
Warning

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

Go to latest
Published: Sep 30, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package config loads beekeeper's machine configuration: where its state lives, which shared resources sessions lease, the GitHub budget floor, the thresholds of the machine watch and which installations' alerts it reads.

The file is $XDG_CONFIG_HOME/beekeeper/config.yaml (or --config, or $BEEKEEPER_CONFIG). Every field is optional; a missing file is the defaults. The defaults are the numbers proven on an 86 GiB workstation running a Claude Desktop scope capped at 48 GiB: tune them to the machine.

Index

Constants

View Source
const Browser = "browser"

Browser is the resource every machine has: the one Chrome the Claude in Chrome extension drives.

View Source
const ModelServer = "model-server"

ModelServer is the resource of the host's model server: a claim carries the GiB its models may hold.

Variables

View Source
var DefaultIgnore = []string{"Heartbeat", "InhibitionOutsideWorkingHours", "Watchdog"}

DefaultIgnore are the alerts that always fire or only route others.

View Source
var DefaultModels = map[string]Model{
	"claude-fable-5-1":  {Input: 10, Output: 50, CacheWrite5m: 12.5, CacheWrite1h: 20, CacheRead: 0.25, ContextWindow: 1_000_000},
	"claude-fable-5":    {Input: 10, Output: 50, CacheWrite5m: 12.5, CacheWrite1h: 20, CacheRead: 1, ContextWindow: 1_000_000},
	"claude-opus-5-5":   {Input: 4, Output: 20, CacheWrite5m: 5, CacheWrite1h: 8, CacheRead: 0.2, ContextWindow: 1_000_000},
	"claude-opus-5":     {Input: 5, Output: 25, CacheWrite5m: 6.25, CacheWrite1h: 10, CacheRead: 0.5, ContextWindow: 1_000_000},
	"claude-opus-4-8":   {Input: 5, Output: 25, CacheWrite5m: 6.25, CacheWrite1h: 10, CacheRead: 0.5, ContextWindow: 1_000_000},
	"claude-opus-4-7":   {Input: 5, Output: 25, CacheWrite5m: 6.25, CacheWrite1h: 10, CacheRead: 0.5, ContextWindow: 1_000_000},
	"claude-opus-4-6":   {Input: 5, Output: 25, CacheWrite5m: 6.25, CacheWrite1h: 10, CacheRead: 0.5, ContextWindow: 1_000_000},
	"claude-sonnet-5":   {Input: 2, Output: 10, CacheWrite5m: 2.5, CacheWrite1h: 4, CacheRead: 0.2, ContextWindow: 1_000_000},
	"claude-sonnet-4-6": {Input: 3, Output: 15, CacheWrite5m: 3.75, CacheWrite1h: 6, CacheRead: 0.3, ContextWindow: 1_000_000},
	"claude-haiku-4-5":  {Input: 1, Output: 5, CacheWrite5m: 1.25, CacheWrite1h: 2, CacheRead: 0.1, ContextWindow: 200_000},
}

DefaultModels are the Claude API list prices (platform.claude.com/docs/en/ about-claude/pricing): cache writes cost 1.25 times the input price for the 5-minute TTL and twice for the 1-hour TTL, cache reads a tenth, except where a model's own rate differs (Opus 5.5 $0.20, Fable 5.1 $0.25).

View Source
var DefaultQuiet = []alerts.Quiet{{Cluster: "t-*"}}

DefaultQuiet are the alerts of other teams' e2e test clusters.

View Source
var DefaultQuietSessions = []string{"test: *"}

DefaultQuietSessions are the sessions of beekeeper's own tests.

View Source
var OtherTeamsNotify = alerts.Quiet{Severity: "notify"}

OtherTeamsNotify are other teams' and team-less notify alerts: notify pages nobody, and the rule never quiets the team's alerts, a page or an installation in play.

Functions

func DefaultQuietFor added in v0.37.0

func DefaultQuietFor(team string) []alerts.Quiet

DefaultQuietFor are the default quiet rules of team: DefaultQuiet, and OtherTeamsNotify once there is a team whose alerts it leaves out.

func Path

func Path(flag string) (string, error)

Path returns the configuration file beekeeper reads.

Types

type Agents added in v0.23.0

type Agents struct {
	// RelayAt is an agent's session context, in tokens, at which the watch
	// says its hand-over due (default: supervisor.relayAt).
	RelayAt Tokens `yaml:"relayAt"`
	// NoteWait bounds how long `agents handover` waits for the agent's
	// note on what is in flight (3m).
	NoteWait Duration `yaml:"noteWait"`
}

Agents configures the hand-over of registered agents.

type Alerts added in v0.7.0

type Alerts struct {
	// Installations are read always; a held lease whose name resolves to a
	// kube context is read too.
	Installations []Installation `yaml:"installations"`
	// Ignore are alert names that never appear; setting it replaces the
	// default (Heartbeat, InhibitionOutsideWorkingHours, Watchdog).
	Ignore []string `yaml:"ignore"`
	// Team is the team whose alerts are marked in capitals and counted.
	Team string `yaml:"team"`
	// Collapse is the number of changes of one alertname in one run above
	// which they are one line with a count.
	Collapse int `yaml:"collapse"`
	// Every is the watch's reading interval.
	Every Duration `yaml:"every"`
	// Timeout bounds the reading of one installation, port-forwards included.
	Timeout Duration `yaml:"timeout"`
	// Kubectl is the kubectl binary.
	Kubectl string `yaml:"kubectl"`
	// Flap is the flap damper.
	Flap Flap `yaml:"flap"`
	// Quiet are the rules whose alerts' changes are no wake-up: the watch
	// logs them (watch.quiet) instead of printing them. A rule never
	// quiets an alert of the team, one on an installation in play (leased,
	// claimed or merged into within the last half hour, or with a merge
	// settling), or a page unless it names a cluster. Setting it replaces
	// the default, Giant Swarm's e2e test clusters ({cluster: "t-*"}) and,
	// once Team is set, every other team's and team-less notify alert
	// ({severity: notify}). An alert back after a reading that missed it,
	// with its old start, is quiet too.
	Quiet []alerts.Quiet `yaml:"quiet"`
}

Alerts configures the reading of the installations' Alertmanagers: watch reads them every Every and prints NEW and RESOLVED lines, snapshot adds the current set as a section.

type Claude

type Claude struct {
	ProjectsDir string `yaml:"projectsDir"`
	// SessionsDir holds the record every running CLI keeps of the session
	// it runs (<pid>.json), what `claude agents` lists.
	SessionsDir string `yaml:"sessionsDir"`
	DesktopDir  string `yaml:"desktopDir"`
	// DesktopLog is the desktop app's main log: its latest focus change
	// says which session the main window shows.
	DesktopLog string `yaml:"desktopLog"`
}

Claude locates what Claude Code and the desktop app keep on disk.

type Config

type Config struct {
	// StateDir holds state.json, events.jsonl and the last snapshot.
	StateDir string `yaml:"stateDir"`
	// LeaseDir holds one directory per held lease (mkdir is the lock).
	LeaseDir string `yaml:"leaseDir"`
	// Resources are the environments sessions lease besides the browser:
	// kind labs and shared installations.
	Resources []string `yaml:"resources"`
	// GrantTTL is how long a grant stays claimable once its resource is free.
	GrantTTL Duration `yaml:"grantTTL"`

	GitHub   GitHub   `yaml:"github"`
	Watch    Watch    `yaml:"watch"`
	Overlaps Overlaps `yaml:"overlaps"`
	Claude   Claude   `yaml:"claude"`
	Memcap   Memcap   `yaml:"memcap"`
	Lanes    []Lane   `yaml:"lanes"`
	Merge    Merge    `yaml:"merge"`
	Alerts   Alerts   `yaml:"alerts"`
	Notify   Notify   `yaml:"notify"`
	Metrics  Metrics  `yaml:"metrics"`
	Ollama   Ollama   `yaml:"ollama"`
	// Supervisor is what `handover --prompt` tells a successor supervisor,
	// how long a relay to it stays open and at what context it is due.
	Supervisor Supervisor `yaml:"supervisor"`
	// Guide is the role that walks the person through the decisions
	// waiting on them, never in the supervisor's session.
	Guide Guide `yaml:"guide"`
	// Agents configures how a registered agent near its context limit is
	// handed over to a fresh session.
	Agents Agents `yaml:"agents"`
	// Reporter is the one-off status reporter session the standby watch
	// starts once per interval.
	Reporter Reporter `yaml:"reporter"`
}

Config is the parsed configuration with the defaults applied.

func Load

func Load(path string) (*Config, error)

Load reads the file at path and applies the defaults.

func (*Config) IsLeasable

func (c *Config) IsLeasable(name string) bool

IsLeasable reports whether name is a configured resource or the browser.

func (*Config) LaneNamed added in v0.6.0

func (c *Config) LaneNamed(name string) (Lane, bool)

LaneNamed is the configured lane of that name.

func (*Config) LaneOf added in v0.6.0

func (c *Config) LaneOf(repo string) Lane

LaneOf is the lane a repository's merges queue in: the configured lane that lists it, else a lane of its own named after it.

func (*Config) Leasable

func (c *Config) Leasable() []string

Leasable returns every resource a session can lease: the configured ones, the model server when one is watched, the browser last.

type Duration

type Duration struct{ time.Duration }

Duration is a time.Duration written as "30s", "10m" in YAML.

func (*Duration) UnmarshalYAML

func (d *Duration) UnmarshalYAML(n *yaml.Node) error

UnmarshalYAML parses a Go duration string.

type Flap added in v0.12.0

type Flap struct {
	Changes int      `yaml:"changes"`
	Window  Duration `yaml:"window"`
}

Flap holds back an alert that changes too often: its Changes-th NEW or RESOLVED within Window is one FLAPPING line, and its changes print nothing until it has been stable for Window.

type GitHub

type GitHub struct {
	// Floor is the remaining core budget under which GitHub work stops.
	Floor int `yaml:"floor"`
	// ProbeRepo is the repository whose conditional GET reads the budget
	// headers; any repository the token can read.
	ProbeRepo string `yaml:"probeRepo"`
}

GitHub configures the budget reading.

type Guide added in v0.21.1

type Guide struct {
	Role `yaml:",inline"`
	// Person is the name the guide's notes are filed for (note add --for,
	// or an older note's "[for <person>]" prefix), matched without regard
	// to case. Its queue and feed show only that person's notes; empty,
	// they show every note filed --for anyone.
	Person string `yaml:"person"`
}

Guide configures the guide: its role and the person it guides.

type Installation added in v0.7.0

type Installation struct {
	Name    string `yaml:"name"`
	Context string `yaml:"context"`
	// Floor is the lowest severity printed (alerts.Severities: none, info,
	// warning, notify, critical, page); empty prints every alert.
	Floor string `yaml:"floor"`
}

Installation is an installation and, optionally, the kube context that reaches it and the lowest severity printed of its alerts; written as a name alone or as {name, context, floor}. Without a context it is teleport.giantswarm.io-<name>, else <name>, else the one ending in @<name>.

func (*Installation) UnmarshalYAML added in v0.7.0

func (i *Installation) UnmarshalYAML(n *yaml.Node) error

UnmarshalYAML accepts a plain name.

type Lane added in v0.6.0

type Lane struct {
	Name string `yaml:"name"`
	// Repositories are owner/repo; a bare name matches it under any owner.
	// A repository's name is also the chart name of its HelmReleases.
	Repositories []string `yaml:"repositories"`
	// Installation is where the lane's HelmReleases run; empty: none to wait for.
	Installation string `yaml:"installation"`
	// Context is the kubeconfig context of the installation (default: the
	// one named after it, or ending in -<installation>).
	Context string `yaml:"context"`
}

Lane is a set of repositories whose merges roll the same components of an installation: one merge at a time, the next once they rolled. A repository in no lane is a lane of its own, with no installation to wait for.

type Memcap

type Memcap struct {
	SlotDir string `yaml:"slotDir"`
	Slots   int    `yaml:"slots"`
}

Memcap locates the build slots of the memcap wrapper.

type Merge added in v0.6.0

type Merge struct {
	// Cap is the most devctl processes the machine runs when a merge starts.
	Cap int `yaml:"cap"`
	// QueueTTL is how long a queued merge keeps its place after its run ended,
	// and how long after it the place holds up the merges behind it.
	QueueTTL Duration `yaml:"queueTTL"`
	// SeedTTL is how long a place queued on a session's behalf is kept from
	// its seeding or the session's last arrival, and a failed run's from the
	// failure.
	SeedTTL Duration `yaml:"seedTTL"`
	// Settle is how long a lane waits after a merge whose release is unknown.
	Settle Duration `yaml:"settle"`
	// SettleTimeout is how long a lane waits for a release to roll before
	// the next merge is refused.
	SettleTimeout Duration `yaml:"settleTimeout"`
	// BudgetFresh is how old the last budget reading may be to gate on.
	BudgetFresh Duration `yaml:"budgetFresh"`
	// StallAfter is how long a lane's first arrived merge may wait behind
	// places whose merges are not in the gate before the lane is stalled.
	StallAfter Duration `yaml:"stallAfter"`
	// DevctlOwners are the owners whose repositories devctl pr merge serves
	// (its GitHub App login reaches the giantswarm organisation only); a
	// repository of any other owner takes the plain squash merge as the gh
	// login instead.
	DevctlOwners []string `yaml:"devctlOwners"`
}

Merge configures the gate on devctl pr merge.

func (Merge) DevctlServes added in v0.31.2

func (m Merge) DevctlServes(repo string) bool

DevctlServes says whether devctl pr merge serves repo's owner.

type Metrics added in v0.14.0

type Metrics struct {
	// Models maps a model id, or the prefix of one, to its price and context
	// window. A configured entry replaces the default of the same key; a
	// model no entry matches has no cost ("cost unknown").
	Models map[string]Model `yaml:"models"`
	// Runaway holds the watch's thresholds; a negative one turns its
	// figure off.
	Runaway Runaway `yaml:"runaway"`
}

Metrics prices the tokens of the sessions' transcripts and sets the thresholds at which the watch reports a runaway session.

func (Metrics) Model added in v0.14.0

func (m Metrics) Model(model string) (Model, bool)

Model returns the entry of model: its id, or its dated snapshot ("claude-haiku-4-5-20251001"). Another model of the same family is not priced like it.

type Model added in v0.14.0

type Model struct {
	Input        float64 `yaml:"input" json:"input"`
	Output       float64 `yaml:"output" json:"output"`
	CacheWrite5m float64 `yaml:"cacheWrite5m" json:"cacheWrite5m"`
	CacheWrite1h float64 `yaml:"cacheWrite1h" json:"cacheWrite1h"`
	CacheRead    float64 `yaml:"cacheRead" json:"cacheRead"`
	// Fast multiplies every price of a request in fast mode; zero (the
	// defaults): a fast request's cost is unknown.
	Fast          float64 `yaml:"fast" json:"fast,omitempty"`
	ContextWindow int     `yaml:"contextWindow" json:"contextWindow"`
}

Model is a model's price in US dollars per million tokens and its context window in tokens.

type Notify added in v0.13.0

type Notify struct {
	// Kinds are the kinds that notify (notify.Kinds, the default: due,
	// oom-line, oom-kill, budget, stale-lease, no-supervisor).
	Kinds []string `yaml:"kinds"`
	// QuietHours ("22:00-07:00", local time) hold every notification but a
	// critical one until they end.
	QuietHours string `yaml:"quietHours"`
	// Urgency is a kind's urgency (low, normal, critical); oom-line,
	// oom-kill and no-supervisor are critical, the others normal.
	Urgency map[string]string `yaml:"urgency"`
	// Repeat is how often a lasting condition (oom-line, budget,
	// no-supervisor) notifies again while it lasts.
	Repeat Duration `yaml:"repeat"`
}

Notify configures what `watch --notify` sends to the desktop.

func (Notify) Policy added in v0.13.0

func (n Notify) Policy() notify.Policy

Policy is the notify package's view of the section.

type Ollama added in v0.38.0

type Ollama struct {
	// URL is its API; a machine without one answers nothing and shows none.
	URL string `yaml:"url"`
	// Unit is its systemd unit, whose journal names the client that
	// loaded a model.
	Unit string `yaml:"unit"`
	// BudgetGiB is what a model-server claim may load without --gib;
	// MaxBudgetGiB the most a claim may ask for.
	BudgetGiB    int `yaml:"budgetGiB"`
	MaxBudgetGiB int `yaml:"maxBudgetGiB"`
	// NameOnly keeps the watch from unloading a model no lease covers: it
	// only names it.
	NameOnly bool `yaml:"nameOnly"`
	// LabTests are the agentlab subcommands that run turns on the host's
	// models; the hook refuses them outside the model-server lease.
	LabTests []string `yaml:"labTests"`
}

Ollama is the host's ollama server, whose loaded models live in the iGPU's GTT.

type Overlaps

type Overlaps struct {
	// Ignore lists repositories whose issues and name form no overlap:
	// issue trackers and notebooks every session writes to.
	Ignore []string `yaml:"ignore"`
	// ActiveWithin leaves out sessions idle for longer.
	ActiveWithin Duration `yaml:"activeWithin"`
}

Overlaps tunes which sessions count as working on the same thing.

type Reporter added in v0.26.0

type Reporter struct {
	// Every is the interval; the reports start on its multiples (on the
	// hour for 1h). Unset, no reporter runs.
	Every Duration `yaml:"every"`
	// Brief is the reporter's brief file (~/ allowed): what to report and
	// where to post it.
	Brief string `yaml:"brief"`
	// Model is the session's model (default: Claude Code's).
	Model string `yaml:"model"`
	// Person is who the report is for (default: guide.person).
	Person string `yaml:"person"`
	// Dir is the session's working directory (~/ allowed; default: home).
	Dir string `yaml:"dir"`
	// Timeout is how long a reporter may run without posting before it is
	// stopped (20m).
	Timeout Duration `yaml:"timeout"`
}

Reporter configures the scheduled status reporter: once per Every the standby watch starts one headless session with Brief, which posts one report to Person and ends; beekeeper then takes it off the roster.

func (Reporter) Enabled added in v0.26.0

func (r Reporter) Enabled() bool

Enabled reports whether a reporter is scheduled.

type Role added in v0.20.0

type Role struct {
	// Skill is the name of the skill the successor runs (supervise, guide).
	Skill string `yaml:"skill"`
	// Instructions is a file (~/ allowed) whose content opens the prompt
	// instead.
	Instructions string `yaml:"instructions"`
	// RelayAt is the role's session context, in tokens, at which the watch
	// reports the relay due ("400k").
	RelayAt Tokens `yaml:"relayAt"`
	// RelayTTL is how long a relay stays open for the successor's start.
	RelayTTL Duration `yaml:"relayTTL"`
	// RestartGrace is how long beekeeper waits after it first saw the
	// role's CLI gone: a CLI back under the same session within it is a
	// restart and keeps the role; past it, the watch says the supervisor
	// is gone and notifies. The grant rule holds throughout.
	RestartGrace Duration `yaml:"restartGrace"`
}

Role configures a relayed role, the supervisor's or the guide's: the successor's session prompt (the instructions it follows, a skill or a file, not both) and the relay.

type Runaway added in v0.14.0

type Runaway struct {
	// GitHubCallsPerHour: gh and devctl commands and GitHub MCP tool calls
	// in the last hour.
	GitHubCallsPerHour int `yaml:"githubCallsPerHour"`
	// SameErrorRepeats: the same failing tool call in the last hour.
	SameErrorRepeats int `yaml:"sameErrorRepeats"`
	// ContextFill: the last request's context over the model's window.
	ContextFill float64 `yaml:"contextFill"`
}

Runaway are the per-session figures over which the watch prints one line.

type Supervisor added in v0.9.0

type Supervisor struct {
	Role `yaml:",inline"`
	// Scope says what the supervisor watches, in a sentence or two; empty,
	// the prompt names the resources, lanes and installations configured.
	Scope string `yaml:"scope"`
	// KeepAwake is how long the recorded spare may sit idle before the
	// standby watch sends it a keep-awake message (25m): under the desktop
	// app's 30-minute idle timeout for an off-screen CLI, so a command-line
	// message still reaches it. The supervisor's restartGrace defaults to
	// 30s: past it the standby watch hands the role to the spare.
	KeepAwake Duration `yaml:"keepAwake"`
}

Supervisor configures the supervisor: its role and the scope it supervises.

type Tokens added in v0.16.0

type Tokens int64

Tokens is a token count written as "400k", "1m" or "400000" in YAML.

func ParseTokens added in v0.16.0

func ParseTokens(s string) (Tokens, error)

ParseTokens parses "400k", "1m" or "400000" (case-insensitive).

func (*Tokens) UnmarshalYAML added in v0.16.0

func (t *Tokens) UnmarshalYAML(n *yaml.Node) error

UnmarshalYAML parses a count with an optional k or m suffix.

type Watch

type Watch struct {
	Interval Duration `yaml:"interval"`
	// Repeat paces how often a lasting condition is handed to the
	// notifier (which sends it again after notify.repeat); the watch
	// prints it once when it starts and once when it ends.
	Repeat      Duration `yaml:"repeat"`
	BudgetEvery Duration `yaml:"budgetEvery"`
	AvailMinMiB int      `yaml:"availMinMiB"`
	SwapMaxMiB  int      `yaml:"swapMaxMiB"`
	// OOMDHeadroomMinMiB and OOMDWithin decide when systemd-oomd's swap
	// kill is imminent, the one memory condition that notifies a person
	// (oom-line): less swap growth left before its SwapUsedLimit than
	// OOMDHeadroomMinMiB, or the trigger reached within OOMDWithin at the
	// last hour's growth rate. Every other memory threshold is a watch
	// line for the supervisor only.
	OOMDHeadroomMinMiB int      `yaml:"oomdHeadroomMinMiB"`
	OOMDWithin         Duration `yaml:"oomdWithin"`
	ScopeAnonMaxMiB    int      `yaml:"scopeAnonMaxMiB"`
	// GTTMaxMiB is the iGPU GTT (system RAM the GPU driver pins, which no
	// cgroup counts) above which the watch prints IGPU GTT and names it
	// with the host ollama's models as the cause of LOW RAM and OOMD
	// IMMINENT.
	GTTMaxMiB int `yaml:"gttMaxMiB"`
	// LoadMax is the 1-minute load average over which the watch says HIGH
	// LOAD; unset (0), it is LoadPerCoreMax × the machine's cores
	// (LoadLimit).
	LoadMax        float64 `yaml:"loadMax"`
	LoadPerCoreMax float64 `yaml:"loadPerCoreMax"`
	PSIMax         float64 `yaml:"psiMax"`
	// CPUPSIMax is the CPU pressure ("some avg10" of /proc/pressure/cpu,
	// in percent) over which the watch says CPU PRESSURE once two samples
	// in a row read it, and over which, like over LoadLimit, the machine is
	// strained: the installation reads (upgrades, alerts, lane settling)
	// then run four times less often and at nice 10 (READS SLOWED).
	CPUPSIMax  float64 `yaml:"cpuPSIMax"`
	TmpMaxMiB  int     `yaml:"tmpMaxMiB"`
	DiskMinMiB int     `yaml:"diskMinMiB"`
	// QuietSessions are globs (* matches any run) of the names of
	// short-lived sessions whose start, end and restart are no wake-up:
	// the watch logs them (watch.quiet) instead of printing them. Setting
	// it replaces the default, beekeeper's own tests ("test: *").
	QuietSessions []string `yaml:"quietSessions"`
}

Watch holds the thresholds of `beekeeper watch` (MiB unless noted).

func (Watch) LoadLimit added in v0.39.0

func (w Watch) LoadLimit(cores int) float64

LoadLimit is the HIGH LOAD threshold on a machine of cores: LoadMax when set, LoadPerCoreMax × cores otherwise.

Jump to

Keyboard shortcuts

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