**Architecture changes:** - Renamed `.gastown/` → `.runtime/` for runtime state (gitignored) - Added `settings/` directory for rig behavioral config (git-tracked) - Added `mayor/config.json` for town-level config (MayorConfig type) - Separated RigConfig (identity) from RigSettings (behavioral) **File location changes:** - Town runtime: `~/.gastown/*` → `~/.runtime/*` - Rig runtime: `<rig>/.gastown/*` → `<rig>/.runtime/*` - Rig config: `<rig>/.gastown/config.json` → `<rig>/settings/config.json` - Namepool state: `namepool.json` → `namepool-state.json` **New types:** - MayorConfig: town-level behavioral config - RigSettings: rig behavioral config (merge_queue, theme, namepool) - RigConfig now identity-only (name, git_url, beads, created_at) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
211 lines
7.8 KiB
Go
211 lines
7.8 KiB
Go
// Package config provides configuration types and serialization for Gas Town.
|
|
package config
|
|
|
|
import "time"
|
|
|
|
// TownConfig represents the main town identity (mayor/town.json).
|
|
type TownConfig struct {
|
|
Type string `json:"type"` // "town"
|
|
Version int `json:"version"` // schema version
|
|
Name string `json:"name"` // town identifier
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// MayorConfig represents town-level behavioral configuration (mayor/config.json).
|
|
// This is separate from TownConfig (identity) to keep configuration concerns distinct.
|
|
type MayorConfig struct {
|
|
Type string `json:"type"` // "mayor-config"
|
|
Version int `json:"version"` // schema version
|
|
Theme *TownThemeConfig `json:"theme,omitempty"` // global theme settings
|
|
Daemon *DaemonConfig `json:"daemon,omitempty"` // daemon settings
|
|
Deacon *DeaconConfig `json:"deacon,omitempty"` // deacon settings
|
|
}
|
|
|
|
// DaemonConfig represents daemon process settings.
|
|
type DaemonConfig struct {
|
|
HeartbeatInterval string `json:"heartbeat_interval,omitempty"` // e.g., "30s"
|
|
PollInterval string `json:"poll_interval,omitempty"` // e.g., "10s"
|
|
}
|
|
|
|
// DeaconConfig represents deacon process settings.
|
|
type DeaconConfig struct {
|
|
PatrolInterval string `json:"patrol_interval,omitempty"` // e.g., "5m"
|
|
}
|
|
|
|
// CurrentMayorConfigVersion is the current schema version for MayorConfig.
|
|
const CurrentMayorConfigVersion = 1
|
|
|
|
// RigsConfig represents the rigs registry (mayor/rigs.json).
|
|
type RigsConfig struct {
|
|
Version int `json:"version"`
|
|
Rigs map[string]RigEntry `json:"rigs"`
|
|
}
|
|
|
|
// RigEntry represents a single rig in the registry.
|
|
type RigEntry struct {
|
|
GitURL string `json:"git_url"`
|
|
AddedAt time.Time `json:"added_at"`
|
|
BeadsConfig *BeadsConfig `json:"beads,omitempty"`
|
|
}
|
|
|
|
// BeadsConfig represents beads configuration for a rig.
|
|
type BeadsConfig struct {
|
|
Repo string `json:"repo"` // "local" | path | git-url
|
|
Prefix string `json:"prefix"` // issue prefix
|
|
}
|
|
|
|
// AgentState represents an agent's current state (*/state.json).
|
|
type AgentState struct {
|
|
Role string `json:"role"` // "mayor", "witness", etc.
|
|
LastActive time.Time `json:"last_active"`
|
|
Session string `json:"session,omitempty"`
|
|
Extra map[string]any `json:"extra,omitempty"`
|
|
}
|
|
|
|
// CurrentTownVersion is the current schema version for TownConfig.
|
|
const CurrentTownVersion = 1
|
|
|
|
// CurrentRigsVersion is the current schema version for RigsConfig.
|
|
const CurrentRigsVersion = 1
|
|
|
|
// CurrentRigConfigVersion is the current schema version for RigConfig.
|
|
const CurrentRigConfigVersion = 1
|
|
|
|
// CurrentRigSettingsVersion is the current schema version for RigSettings.
|
|
const CurrentRigSettingsVersion = 1
|
|
|
|
// RigConfig represents per-rig identity (rig/config.json).
|
|
// This contains only identity - behavioral config is in settings/config.json.
|
|
type RigConfig struct {
|
|
Type string `json:"type"` // "rig"
|
|
Version int `json:"version"` // schema version
|
|
Name string `json:"name"` // rig name
|
|
GitURL string `json:"git_url"` // git repository URL
|
|
CreatedAt time.Time `json:"created_at"` // when the rig was created
|
|
Beads *BeadsConfig `json:"beads,omitempty"`
|
|
}
|
|
|
|
// RigSettings represents per-rig behavioral configuration (settings/config.json).
|
|
type RigSettings struct {
|
|
Type string `json:"type"` // "rig-settings"
|
|
Version int `json:"version"` // schema version
|
|
MergeQueue *MergeQueueConfig `json:"merge_queue,omitempty"` // merge queue settings
|
|
Theme *ThemeConfig `json:"theme,omitempty"` // tmux theme settings
|
|
Namepool *NamepoolConfig `json:"namepool,omitempty"` // polecat name pool settings
|
|
}
|
|
|
|
// ThemeConfig represents tmux theme settings for a rig.
|
|
type ThemeConfig struct {
|
|
// Name picks from the default palette (e.g., "ocean", "forest").
|
|
// If empty, a theme is auto-assigned based on rig name.
|
|
Name string `json:"name,omitempty"`
|
|
|
|
// Custom overrides the palette with specific colors.
|
|
Custom *CustomTheme `json:"custom,omitempty"`
|
|
|
|
// RoleThemes overrides themes for specific roles in this rig.
|
|
// Keys: "witness", "refinery", "crew", "polecat"
|
|
RoleThemes map[string]string `json:"role_themes,omitempty"`
|
|
}
|
|
|
|
// CustomTheme allows specifying exact colors for the status bar.
|
|
type CustomTheme struct {
|
|
BG string `json:"bg"` // Background color (hex or tmux color name)
|
|
FG string `json:"fg"` // Foreground color (hex or tmux color name)
|
|
}
|
|
|
|
// TownThemeConfig represents global theme settings (mayor/config.json).
|
|
type TownThemeConfig struct {
|
|
// RoleDefaults sets default themes for roles across all rigs.
|
|
// Keys: "witness", "refinery", "crew", "polecat"
|
|
RoleDefaults map[string]string `json:"role_defaults,omitempty"`
|
|
}
|
|
|
|
// BuiltinRoleThemes returns the default themes for each role.
|
|
// These are used when no explicit configuration is provided.
|
|
func BuiltinRoleThemes() map[string]string {
|
|
return map[string]string{
|
|
"witness": "rust", // Red/rust - watchful, alert
|
|
"refinery": "plum", // Purple - processing, refining
|
|
// crew and polecat use rig theme by default (no override)
|
|
}
|
|
}
|
|
|
|
// MergeQueueConfig represents merge queue settings for a rig.
|
|
type MergeQueueConfig struct {
|
|
// Enabled controls whether the merge queue is active.
|
|
Enabled bool `json:"enabled"`
|
|
|
|
// TargetBranch is the default branch to merge into (usually "main").
|
|
TargetBranch string `json:"target_branch"`
|
|
|
|
// IntegrationBranches enables integration branch workflow for epics.
|
|
IntegrationBranches bool `json:"integration_branches"`
|
|
|
|
// OnConflict specifies conflict resolution strategy: "assign_back" or "auto_rebase".
|
|
OnConflict string `json:"on_conflict"`
|
|
|
|
// RunTests controls whether to run tests before merging.
|
|
RunTests bool `json:"run_tests"`
|
|
|
|
// TestCommand is the command to run for tests.
|
|
TestCommand string `json:"test_command,omitempty"`
|
|
|
|
// DeleteMergedBranches controls whether to delete branches after merging.
|
|
DeleteMergedBranches bool `json:"delete_merged_branches"`
|
|
|
|
// RetryFlakyTests is the number of times to retry flaky tests.
|
|
RetryFlakyTests int `json:"retry_flaky_tests"`
|
|
|
|
// PollInterval is how often to poll for new merge requests (e.g., "30s").
|
|
PollInterval string `json:"poll_interval"`
|
|
|
|
// MaxConcurrent is the maximum number of concurrent merges.
|
|
MaxConcurrent int `json:"max_concurrent"`
|
|
}
|
|
|
|
// OnConflict strategy constants.
|
|
const (
|
|
OnConflictAssignBack = "assign_back"
|
|
OnConflictAutoRebase = "auto_rebase"
|
|
)
|
|
|
|
// DefaultMergeQueueConfig returns a MergeQueueConfig with sensible defaults.
|
|
func DefaultMergeQueueConfig() *MergeQueueConfig {
|
|
return &MergeQueueConfig{
|
|
Enabled: true,
|
|
TargetBranch: "main",
|
|
IntegrationBranches: true,
|
|
OnConflict: OnConflictAssignBack,
|
|
RunTests: true,
|
|
TestCommand: "go test ./...",
|
|
DeleteMergedBranches: true,
|
|
RetryFlakyTests: 1,
|
|
PollInterval: "30s",
|
|
MaxConcurrent: 1,
|
|
}
|
|
}
|
|
|
|
// NamepoolConfig represents namepool settings for themed polecat names.
|
|
type NamepoolConfig struct {
|
|
// Style picks from a built-in theme (e.g., "mad-max", "minerals", "wasteland").
|
|
// If empty, defaults to "mad-max".
|
|
Style string `json:"style,omitempty"`
|
|
|
|
// Names is a custom list of names to use instead of a built-in theme.
|
|
// If provided, overrides the Style setting.
|
|
Names []string `json:"names,omitempty"`
|
|
|
|
// MaxBeforeNumbering is when to start appending numbers.
|
|
// Default is 50. After this many polecats, names become name-01, name-02, etc.
|
|
MaxBeforeNumbering int `json:"max_before_numbering,omitempty"`
|
|
}
|
|
|
|
// DefaultNamepoolConfig returns a NamepoolConfig with sensible defaults.
|
|
func DefaultNamepoolConfig() *NamepoolConfig {
|
|
return &NamepoolConfig{
|
|
Style: "mad-max",
|
|
MaxBeforeNumbering: 50,
|
|
}
|
|
}
|