Documentation
¶
Index ¶
- Constants
- Variables
- func EnsureWorkspaceMeta()
- func GetAvailablePrograms() []string
- func GetClaudeCommand() (string, error)
- func GetClaudeDir() (string, error)
- func GetConfigDir() (string, error)
- func GetPreferredWorkspaceFile(baseDir string) string
- func ResetCommandExecutor()
- func SaveConfig(config *Config) error
- func SaveDiscoveryConfig(config *DiscoveryConfig) error
- func SaveState(state *State) error
- func SetCommandExecutor(executor CommandExecutor)
- func SetPreferredWorkspace(baseDir, configDir string) error
- type AppState
- type ClaudeConfigManager
- func (m *ClaudeConfigManager) GetConfig(filename string) (*ConfigFile, error)
- func (m *ClaudeConfigManager) ListConfigs() ([]ConfigFile, error)
- func (m *ClaudeConfigManager) UpdateConfig(filename string, content string) error
- func (m *ClaudeConfigManager) UpdateConfigWithValidation(filename string, content string) error
- func (m *ClaudeConfigManager) ValidateJSON(filename string, content string) error
- type CommandExecutor
- type Config
- type ConfigFile
- type DiscoveryConfig
- func (c *DiscoveryConfig) CanAttachToExternal() bool
- func (c *DiscoveryConfig) IsExternalDiscoveryEnabled() bool
- func (c *DiscoveryConfig) IsManagedDiscoveryEnabled() bool
- func (c *DiscoveryConfig) ShouldConfirmOperation(isExternal bool) bool
- func (c *DiscoveryConfig) ShouldShowExternalInstances() bool
- type DiscoveryMode
- type State
- func (s *State) Close() error
- func (s *State) GetCategoryExpanded(category string) bool
- func (s *State) GetHelpScreensSeen() uint32
- func (s *State) GetSearchState() (bool, string)
- func (s *State) GetSelectedIndex() int
- func (s *State) GetUIState() UIState
- func (s *State) RefreshState() error
- func (s *State) SetCategoryExpanded(category string, expanded bool) error
- func (s *State) SetHelpScreensSeen(seen uint32) error
- func (s *State) SetHidePaused(hidePaused bool) error
- func (s *State) SetSearchMode(searchMode bool, query string) error
- func (s *State) SetSelectedIndex(index int) error
- type StateManager
- type UIState
- type UIStateAccess
- type WorkspaceMeta
Constants ¶
const ( StateFileName = "state.json" InstancesFileName = "instances.json" )
const ( // DefaultLockTimeout is the default timeout for acquiring locks DefaultLockTimeout = 5 * time.Second // LockFileName is the name of the lock file LockFileName = "state.lock" )
const (
ConfigFileName = "config.json"
)
const DiscoveryConfigFileName = "discovery.json"
Variables ¶
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 ¶
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 ¶
GetClaudeDir returns the path to the ~/.claude directory
func GetConfigDir ¶
GetConfigDir returns the path to the application's configuration directory with hierarchical isolation for safe multi-instance and test execution.
Priority hierarchy:
- Test directory override via STAPLER_SQUAD_TEST_DIR (for --test-mode flag)
- Explicit instance ID via STAPLER_SQUAD_INSTANCE environment variable
- Test mode auto-detection (automatic isolation for tests/benchmarks)
- Workspace-based isolation (default for production, per-directory state)
- Global shared state (fallback, backward compatibility)
func GetPreferredWorkspaceFile ¶
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 ¶
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 SetCommandExecutor ¶
func SetCommandExecutor(executor CommandExecutor)
SetCommandExecutor sets the global command executor (primarily for testing)
func SetPreferredWorkspace ¶
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 LoadConfig ¶
func LoadConfig() *Config
func (*Config) GetKeyCategoryForKey ¶
GetKeyCategoryForKey returns the category for a specific key, or empty string if not found
func (*Config) RemoveKeyCategory ¶
RemoveKeyCategory removes the category mapping for a specific key
func (*Config) SetKeyCategory ¶
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 LoadState ¶
func LoadState() *State
LoadState loads the state from disk with locking. If it cannot be done, we return the default state.
func NewTestState ¶
NewTestState creates a test state with isolated storage in the given directory This prevents tests from loading or interfering with production data
func (*State) GetCategoryExpanded ¶
GetCategoryExpanded returns whether a category is expanded (defaults to true for new categories)
func (*State) GetHelpScreensSeen ¶
GetHelpScreensSeen returns the bitmask of seen help screens
func (*State) GetSearchState ¶
GetSearchState returns the current search mode and query
func (*State) GetSelectedIndex ¶
GetSelectedIndex returns the last selected session index
func (*State) GetUIState ¶
GetUIState returns a copy of the current UI state
func (*State) RefreshState ¶
RefreshState reloads state from disk with locking
func (*State) SetCategoryExpanded ¶
SetCategoryExpanded updates the expanded state for a category
func (*State) SetHelpScreensSeen ¶
SetHelpScreensSeen updates the bitmask of seen help screens
func (*State) SetHidePaused ¶
SetHidePaused updates the hide paused filter state
func (*State) SetSearchMode ¶
SetSearchMode updates the search mode state
func (*State) SetSelectedIndex ¶
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.