config

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Apr 9, 2026 License: AGPL-3.0 Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StateFileName     = "state.json"
	InstancesFileName = "instances.json"
)
View Source
const (
	// DefaultLockTimeout is the default timeout for acquiring locks
	DefaultLockTimeout = 5 * time.Second
	// LockFileName is the name of the lock file
	LockFileName = "state.lock"
)
View Source
const (
	ConfigFileName = "config.json"
)
View Source
const DiscoveryConfigFileName = "discovery.json"

Variables

View Source
var (
	ErrConfigNotFound = fmt.Errorf("config file not found")
	ErrInvalidConfig  = fmt.Errorf("invalid config file")
	ErrInvalidJSON    = fmt.Errorf("invalid JSON")
)

Common errors for Claude config operations

Functions

func EnsureWorkspaceMeta

func EnsureWorkspaceMeta()

EnsureWorkspaceMeta writes workspace metadata for the current configuration directory. Should be called once at server startup. Skips test mode directories.

func GetAvailablePrograms

func GetAvailablePrograms() []string

GetAvailablePrograms returns a list of all detected CLI programs.

func GetClaudeCommand

func GetClaudeCommand() (string, error)

GetClaudeCommand attempts to find the "claude" command in the user's shell It checks in the following order: 1. Shell alias resolution (proxy-claude, then claude) 2. PATH lookup

If both fail, it returns an error.

func GetClaudeDir

func GetClaudeDir() (string, error)

GetClaudeDir returns the path to the ~/.claude directory

func GetConfigDir

func GetConfigDir() (string, error)

GetConfigDir returns the path to the application's configuration directory with hierarchical isolation for safe multi-instance and test execution.

Priority hierarchy:

  1. Test directory override via STAPLER_SQUAD_TEST_DIR (for --test-mode flag)
  2. Explicit instance ID via STAPLER_SQUAD_INSTANCE environment variable
  3. Test mode auto-detection (automatic isolation for tests/benchmarks)
  4. Workspace-based isolation (default for production, per-directory state)
  5. Global shared state (fallback, backward compatibility)

func GetPreferredWorkspaceFile

func GetPreferredWorkspaceFile(baseDir string) string

GetPreferredWorkspaceFile returns the path to the preferred workspace preference file.

func ResetCommandExecutor

func ResetCommandExecutor()

ResetCommandExecutor resets the global command executor to the default implementation Uses timeout protection by default (5 seconds)

func SaveConfig

func SaveConfig(config *Config) error

SaveConfig exports the saveConfig function for use by other packages

func SaveDiscoveryConfig

func SaveDiscoveryConfig(config *DiscoveryConfig) error

SaveDiscoveryConfig saves the discovery configuration to disk

func SaveState

func SaveState(state *State) error

SaveState saves the state to disk with locking.

func SetCommandExecutor

func SetCommandExecutor(executor CommandExecutor)

SetCommandExecutor sets the global command executor (primarily for testing)

func SetPreferredWorkspace

func SetPreferredWorkspace(baseDir, configDir string) error

SetPreferredWorkspace atomically writes the preferred workspace config dir path. Pass configDir="" to clear the preference.

Types

type AppState

type AppState interface {
	// GetHelpScreensSeen returns the bitmask of seen help screens
	GetHelpScreensSeen() uint32
	// SetHelpScreensSeen updates the bitmask of seen help screens
	SetHelpScreensSeen(seen uint32) error
}

AppState handles application-level state

type ClaudeConfigManager

type ClaudeConfigManager struct {
	// contains filtered or unexported fields
}

ClaudeConfigManager manages access to Claude configuration files located in the ~/.claude directory

func NewClaudeConfigManager

func NewClaudeConfigManager() (*ClaudeConfigManager, error)

NewClaudeConfigManager creates a new ClaudeConfigManager instance with the ~/.claude directory resolved

func (*ClaudeConfigManager) GetConfig

func (m *ClaudeConfigManager) GetConfig(filename string) (*ConfigFile, error)

GetConfig reads a specific Claude configuration file by name Common file names include "CLAUDE.md", "settings.json", "agents.md"

func (*ClaudeConfigManager) ListConfigs

func (m *ClaudeConfigManager) ListConfigs() ([]ConfigFile, error)

ListConfigs returns all configuration files in the ~/.claude directory

func (*ClaudeConfigManager) UpdateConfig

func (m *ClaudeConfigManager) UpdateConfig(filename string, content string) error

UpdateConfig updates a Claude configuration file atomically with backup It creates a .bak file before writing, and uses a temporary file for atomicity. JSON files are validated before writing to prevent corrupt settings files.

func (*ClaudeConfigManager) UpdateConfigWithValidation

func (m *ClaudeConfigManager) UpdateConfigWithValidation(filename string, content string) error

UpdateConfigWithValidation updates a config file with JSON validation This is a convenience method that combines validation and update

func (*ClaudeConfigManager) ValidateJSON

func (m *ClaudeConfigManager) ValidateJSON(filename string, content string) error

ValidateJSON validates a JSON configuration file against a schema Returns nil if valid, error with details if invalid

type CommandExecutor

type CommandExecutor interface {
	Command(name string, args ...string) *exec.Cmd
	Output(cmd *exec.Cmd) ([]byte, error)
	LookPath(file string) (string, error)
}

CommandExecutor defines the interface for executing external commands

type Config

type Config struct {
	// ListenAddress is the address the HTTP server listens on.
	// Default: "localhost:8543". Set to "0.0.0.0:8543" for remote access.
	ListenAddress string `json:"listen_address"`
	// PasskeyRPID is the WebAuthn Relying Party ID (effective domain, no scheme/port).
	// Example: "192.168.1.42" or "myhost.local". Must match the hostname clients use.
	// Required when remote access is enabled.
	PasskeyRPID string `json:"passkey_rp_id"`
	// PasskeyEnabled controls whether passkey authentication is enforced.
	// Automatically set to true when non-localhost listen address is used.
	PasskeyEnabled bool `json:"passkey_enabled"`
	// DefaultProgram is the default program to run in new instances
	DefaultProgram string `json:"default_program"`
	// AutoYes is a flag to automatically accept all prompts.
	AutoYes bool `json:"auto_yes"`
	// DaemonPollInterval is the interval (ms) at which the daemon polls sessions for autoyes mode.
	DaemonPollInterval int `json:"daemon_poll_interval"`
	// BranchPrefix is the prefix used for git branches created by the application.
	BranchPrefix string `json:"branch_prefix"`
	// DetectNewSessions is a flag to enable detection of new sessions from other windows
	DetectNewSessions bool `json:"detect_new_sessions"`
	// SessionDetectionInterval is the interval (ms) at which the daemon checks for new sessions
	SessionDetectionInterval int `json:"session_detection_interval"`
	// StateRefreshInterval is the interval (ms) at which the state is refreshed from disk
	StateRefreshInterval int `json:"state_refresh_interval"`
	// LogsEnabled is a flag to enable logging to files
	LogsEnabled bool `json:"logs_enabled"`
	// LogsDir is the directory where logs are stored (defaults to ~/.stapler-squad/logs)
	LogsDir string `json:"logs_dir"`
	// LogMaxSize is the maximum size of a log file in megabytes before it gets rotated
	LogMaxSize int `json:"log_max_size"`
	// LogMaxFiles is the maximum number of rotated log files to keep (not including the current log file)
	LogMaxFiles int `json:"log_max_files"`
	// LogMaxAge is the maximum number of days to keep rotated log files
	LogMaxAge int `json:"log_max_age"`
	// LogCompress is a flag to enable compression of rotated log files
	LogCompress bool `json:"log_compress"`
	// UseSessionLogs is a flag to enable per-session log files
	UseSessionLogs bool `json:"use_session_logs"`
	// TmuxSessionPrefix allows customizing the tmux session prefix for process isolation
	TmuxSessionPrefix string `json:"tmux_session_prefix"`
	// PerformBackgroundHealthChecks enables non-blocking health checks for session maintenance
	PerformBackgroundHealthChecks bool `json:"perform_background_health_checks"`
	// KeyCategories defines custom category mappings for key bindings in help system
	KeyCategories map[string]string `json:"key_categories"`
	// TerminalStreamingMode controls how terminal output is streamed to the client
	// Options: "raw" (direct PTY streaming), "state" (MOSH-style state sync), "hybrid" (both)
	TerminalStreamingMode string `json:"terminal_streaming_mode"`
	// VCSPreference controls which version control system to prefer when both are available
	// Options: "auto" (prefer JJ if available), "jj" (always use JJ), "git" (always use Git)
	VCSPreference string `json:"vcs_preference"`
	// AvailablePrograms is a list of detected CLI programs
	AvailablePrograms []string `json:"available_programs"`
}

Config represents the application configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns the default configuration

func LoadConfig

func LoadConfig() *Config

func (*Config) GetKeyCategoryForKey

func (c *Config) GetKeyCategoryForKey(key string) string

GetKeyCategoryForKey returns the category for a specific key, or empty string if not found

func (*Config) RemoveKeyCategory

func (c *Config) RemoveKeyCategory(key string)

RemoveKeyCategory removes the category mapping for a specific key

func (*Config) SetKeyCategory

func (c *Config) SetKeyCategory(key, category string)

SetKeyCategory updates the category for a specific key

type ConfigFile

type ConfigFile struct {
	// Name is the filename (e.g., "CLAUDE.md", "settings.json", "agents.md")
	Name string
	// Path is the absolute path to the file
	Path string
	// Content is the file contents
	Content string
	// ModTime is the last modification timestamp
	ModTime time.Time
}

ConfigFile represents a single Claude configuration file

type DiscoveryConfig

type DiscoveryConfig struct {
	// Mode determines which types of instances to discover
	Mode DiscoveryMode `json:"mode"`

	// AllowExternalAttach controls whether users can attach to external instances
	AllowExternalAttach bool `json:"allow_external_attach"`

	// ConfirmExternalOperations requires confirmation before operations on external instances
	ConfirmExternalOperations bool `json:"confirm_external_operations"`

	// SocketPaths defines custom socket paths for discovery (optional)
	// Empty means use system defaults (/tmp/tmux-*/default)
	SocketPaths []string `json:"socket_paths"`

	// ExcludedSocketPaths defines socket paths to skip during discovery
	ExcludedSocketPaths []string `json:"excluded_socket_paths"`

	// DiscoverInterval is the interval (ms) at which external instances are scanned
	DiscoverInterval int `json:"discover_interval"`

	// AutoRefreshExternal enables automatic refresh of external instance metadata
	AutoRefreshExternal bool `json:"auto_refresh_external"`
}

DiscoveryConfig controls instance discovery behavior and safety settings

func DefaultDiscoveryConfig

func DefaultDiscoveryConfig() *DiscoveryConfig

DefaultDiscoveryConfig returns the default discovery configuration By default, only managed instances are shown for safety

func LoadDiscoveryConfig

func LoadDiscoveryConfig() *DiscoveryConfig

LoadDiscoveryConfig loads the discovery configuration from disk

func (*DiscoveryConfig) CanAttachToExternal

func (c *DiscoveryConfig) CanAttachToExternal() bool

CanAttachToExternal returns true if attaching to external instances is allowed

func (*DiscoveryConfig) IsExternalDiscoveryEnabled

func (c *DiscoveryConfig) IsExternalDiscoveryEnabled() bool

IsExternalDiscoveryEnabled returns true if external instance discovery is enabled

func (*DiscoveryConfig) IsManagedDiscoveryEnabled

func (c *DiscoveryConfig) IsManagedDiscoveryEnabled() bool

IsManagedDiscoveryEnabled returns true if managed instance discovery is enabled

func (*DiscoveryConfig) ShouldConfirmOperation

func (c *DiscoveryConfig) ShouldConfirmOperation(isExternal bool) bool

ShouldConfirmOperation returns true if the operation requires user confirmation

func (*DiscoveryConfig) ShouldShowExternalInstances

func (c *DiscoveryConfig) ShouldShowExternalInstances() bool

ShouldShowExternalInstances returns true if external instances should be displayed

type DiscoveryMode

type DiscoveryMode string

DiscoveryMode defines how the application discovers Claude instances

const (
	// DiscoveryManagedOnly discovers only instances created by stapler-squad
	DiscoveryManagedOnly DiscoveryMode = "managed-only"

	// DiscoveryExternalOnly discovers only external Claude instances
	DiscoveryExternalOnly DiscoveryMode = "external-only"

	// DiscoveryAll discovers both managed and external instances
	DiscoveryAll DiscoveryMode = "all"
)

type State

type State struct {
	// HelpScreensSeen is a bitmask tracking which help screens have been shown
	HelpScreensSeen uint32 `json:"help_screens_seen"`
	// UI stores the UI preferences and state
	UI UIState `json:"ui"`
	// contains filtered or unexported fields
}

State represents the application state that persists between sessions

func DefaultState

func DefaultState() *State

DefaultState returns the default state

func LoadState

func LoadState() *State

LoadState loads the state from disk with locking. If it cannot be done, we return the default state.

func NewTestState

func NewTestState(testDir string) *State

NewTestState creates a test state with isolated storage in the given directory This prevents tests from loading or interfering with production data

func (*State) Close

func (s *State) Close() error

Close releases any locks held by this state

func (*State) GetCategoryExpanded

func (s *State) GetCategoryExpanded(category string) bool

GetCategoryExpanded returns whether a category is expanded (defaults to true for new categories)

func (*State) GetHelpScreensSeen

func (s *State) GetHelpScreensSeen() uint32

GetHelpScreensSeen returns the bitmask of seen help screens

func (*State) GetSearchState

func (s *State) GetSearchState() (bool, string)

GetSearchState returns the current search mode and query

func (*State) GetSelectedIndex

func (s *State) GetSelectedIndex() int

GetSelectedIndex returns the last selected session index

func (*State) GetUIState

func (s *State) GetUIState() UIState

GetUIState returns a copy of the current UI state

func (*State) RefreshState

func (s *State) RefreshState() error

RefreshState reloads state from disk with locking

func (*State) SetCategoryExpanded

func (s *State) SetCategoryExpanded(category string, expanded bool) error

SetCategoryExpanded updates the expanded state for a category

func (*State) SetHelpScreensSeen

func (s *State) SetHelpScreensSeen(seen uint32) error

SetHelpScreensSeen updates the bitmask of seen help screens

func (*State) SetHidePaused

func (s *State) SetHidePaused(hidePaused bool) error

SetHidePaused updates the hide paused filter state

func (*State) SetSearchMode

func (s *State) SetSearchMode(searchMode bool, query string) error

SetSearchMode updates the search mode state

func (*State) SetSelectedIndex

func (s *State) SetSelectedIndex(index int) error

SetSelectedIndex updates the selected session index

type StateManager

type StateManager interface {
	AppState
	UIStateAccess

	// RefreshState reloads state from disk to detect changes made by other processes
	RefreshState() error

	// Close releases any resources held by the state manager
	Close() error
}

StateManager combines app state and UI state management

type UIState

type UIState struct {
	// HidePaused controls whether paused sessions are filtered out
	HidePaused bool `json:"hide_paused"`
	// CategoryExpanded maps category names to their expanded state
	CategoryExpanded map[string]bool `json:"category_expanded"`
	// SearchMode tracks if search mode was active
	SearchMode bool `json:"search_mode"`
	// SearchQuery holds the last search query
	SearchQuery string `json:"search_query"`
	// SelectedIdx tracks the last selected session index
	SelectedIdx int `json:"selected_idx"`
}

UIState represents UI preferences that persist between sessions

type UIStateAccess

type UIStateAccess interface {
	// GetUIState returns a copy of the current UI state
	GetUIState() UIState
	// SetHidePaused updates the hide paused filter state
	SetHidePaused(hidePaused bool) error
	// SetCategoryExpanded updates the expanded state for a category
	SetCategoryExpanded(category string, expanded bool) error
	// GetCategoryExpanded returns whether a category is expanded
	GetCategoryExpanded(category string) bool
	// SetSearchMode updates the search mode state
	SetSearchMode(searchMode bool, query string) error
	// GetSearchState returns the current search mode and query
	GetSearchState() (bool, string)
	// SetSelectedIndex updates the selected session index
	SetSelectedIndex(index int) error
	// GetSelectedIndex returns the last selected session index
	GetSelectedIndex() int
}

UIStateAccess provides methods for accessing and modifying UI state

type WorkspaceMeta

type WorkspaceMeta struct {
	WorkspaceID string    `json:"workspace_id"` // dir name (hash or instance name)
	Type        string    `json:"type"`         // "workspace", "instance", "shared"
	CWD         string    `json:"cwd"`
	Name        string    `json:"name"`       // last path component of CWD, or "Default"
	ConfigDir   string    `json:"config_dir"` // absolute path to this workspace dir
	LastUsed    time.Time `json:"last_used"`
}

WorkspaceMeta stores display information about a workspace/database. Written to each workspace directory at startup to enable workspace discovery.

func ListAvailableWorkspaces

func ListAvailableWorkspaces(baseDir string) ([]WorkspaceMeta, error)

ListAvailableWorkspaces discovers all known workspaces by scanning workspace and instance subdirs. Skips test directories. Returns an empty slice (not an error) if none are found.

func ReadWorkspaceMeta

func ReadWorkspaceMeta(configDir string) (WorkspaceMeta, error)

ReadWorkspaceMeta reads workspace metadata from the given config directory.

Jump to

Keyboard shortcuts

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