config

package
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Aug 3, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package config provides layered configuration loading.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ApplyOverrides

func ApplyOverrides(cfg *Config, o FlagOverrides)

ApplyOverrides applies non-empty flag overrides to cfg. Exported so root.go can re-apply after profile overlay.

func GlobalConfigDir

func GlobalConfigDir() string

GlobalConfigDir returns the global config directory path.

func IsHTTPURL added in v0.8.0

func IsHTTPURL(rawURL string) bool

IsHTTPURL reports whether rawURL is an absolute http(s) URL with a host. Used to reject non-web schemes (file://, etc.) and hostless forms (e.g. "https:example.com", which url.Parse accepts with an empty Host) for llm_endpoint, since those would later be concatenated into a request URL and produce confusing/invalid requests.

func LoadFromEnv

func LoadFromEnv(cfg *Config) error

LoadFromEnv loads configuration from environment variables. Exported so root.go can re-apply after profile overlay.

Values are stored as-is, malformed or not — mirroring the trusted-file path in loadFromFile. Validation happens at use-time in summarize.ValidateEndpoint (the TUI's LLM path, the only consumer of llm_endpoint), which fails closed for providers that send llm_api_key to the endpoint. Other commands never consume the value, so `basecamp config unset llm_endpoint` (or unsetting the env var) can always repair a bad value. Erroring here would block every command — including the repair path — for all providers, even ones that never consume the endpoint.

Always returns nil today; the error return is kept so validation can be reintroduced for a specific variable without churning every caller.

func NonInteractiveEnv added in v0.8.0

func NonInteractiveEnv() bool

NonInteractiveEnv reports whether BASECAMP_NONINTERACTIVE is set to a truthy value. When true, the CLI must not show interactive prompts regardless of TTY detection. This is an escape hatch for agents and harnesses that run the CLI under an allocated PTY (where stdout looks like a terminal) and want to avoid a selection prompt wedging the session — without forcing a machine output format the way --agent does.

func NormalizeBaseURL

func NormalizeBaseURL(url string) string

NormalizeBaseURL ensures consistent URL format (no trailing slash).

func RepoConfigPath added in v0.2.2

func RepoConfigPath() string

RepoConfigPath walks up from CWD to find .basecamp/config.json at the git repo root. Returns empty string if not found or outside $HOME.

func ShellQuote added in v0.2.2

func ShellQuote(s string) string

ShellQuote returns a POSIX single-quoted string safe for copy-paste into a shell. Single quotes inside the value are escaped as '\” (end quote, escaped literal quote, resume quote).

Types

type Config

type Config struct {
	// API settings
	BaseURL    string `json:"base_url"`
	AccountID  string `json:"account_id"`
	ProjectID  string `json:"project_id"`
	TodolistID string `json:"todolist_id"`

	// Profile settings (named identity+environment bundles)
	Profiles       map[string]*ProfileConfig `json:"profiles,omitempty"`
	DefaultProfile string                    `json:"default_profile,omitempty"`
	ActiveProfile  string                    `json:"-"` // Set at runtime, not persisted

	// Auth settings
	Scope string `json:"scope"`

	// Cache settings
	CacheDir     string `json:"cache_dir"`
	CacheEnabled bool   `json:"cache_enabled"`

	// Output settings
	Format string `json:"format"`

	// Behavior preferences (persisted via config set, overridable by flags)
	Hints     *bool `json:"hints,omitempty"`
	Stats     *bool `json:"stats,omitempty"`
	Verbose   *int  `json:"verbose,omitempty"`
	Onboarded *bool `json:"onboarded,omitempty"`

	// LLM settings (for TUI smart zoom summarization)
	LLMProvider      string `json:"llm_provider,omitempty"`
	LLMModel         string `json:"llm_model,omitempty"`
	LLMAPIKey        string `json:"llm_api_key,omitempty"`
	LLMEndpoint      string `json:"llm_endpoint,omitempty"`
	LLMMaxConcurrent int    `json:"llm_max_concurrent,omitempty"`
	LLMTokenBudget   int    `json:"llm_token_budget,omitempty"`

	// Experimental feature flags (opt-in via "config set experimental.X true --global").
	Experimental map[string]bool `json:"experimental,omitempty"`

	// Sources tracks where each value came from (for debugging).
	Sources map[string]string `json:"-"`
}

Config holds the resolved configuration.

func Default

func Default() *Config

Default returns the default configuration.

func Load

func Load(overrides FlagOverrides) (*Config, error)

Load loads configuration from all sources with proper precedence. Precedence: flags > env > local > repo > global > system > defaults

func (*Config) ApplyProfile

func (c *Config) ApplyProfile(name string) error

ApplyProfile overlays profile values onto the config.

This is the first pass of a two-pass precedence system:

Pass 1 (this method): Profile values unconditionally overwrite config fields.
Pass 2 (caller):      LoadFromEnv + ApplyOverrides re-apply env vars and CLI
                       flags, which take final precedence over profile values.

The caller in root.go MUST call LoadFromEnv and ApplyOverrides after this method to maintain the precedence chain: flags > env > profile > file > defaults.

func (*Config) IsExperimental added in v0.3.0

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

IsExperimental returns true if the named experimental feature is enabled.

type FlagOverrides

type FlagOverrides struct {
	Account  string
	Project  string
	Todolist string
	Profile  string
	CacheDir string
	Format   string
}

FlagOverrides holds command-line flag values.

type ProfileConfig

type ProfileConfig struct {
	BaseURL    string `json:"base_url"`
	AccountID  string `json:"account_id,omitempty"`
	ProjectID  string `json:"project_id,omitempty"`
	TodolistID string `json:"todolist_id,omitempty"`
	Scope      string `json:"scope,omitempty"`
	ClientID   string `json:"client_id,omitempty"`
}

ProfileConfig holds configuration for a named profile.

type Source

type Source string

Source indicates where a config value came from.

const (
	SourceDefault Source = "default"
	SourceSystem  Source = "system"
	SourceGlobal  Source = "global"
	SourceRepo    Source = "repo"
	SourceLocal   Source = "local"
	SourceEnv     Source = "env"
	SourceFlag    Source = "flag"
	SourcePrompt  Source = "prompt"
)

type TrustEntry added in v0.2.2

type TrustEntry struct {
	Path      string `json:"path"`
	TrustedAt string `json:"trusted_at"`
}

TrustEntry records a single trusted config path and when it was trusted.

type TrustStore added in v0.2.2

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

TrustStore manages the set of trusted local/repo config file paths. Trusted configs are allowed to set authority keys (base_url, profiles, default_profile) that are normally rejected from local/repo sources.

func LoadTrustStore added in v0.2.2

func LoadTrustStore(configDir string) *TrustStore

LoadTrustStore is a convenience that creates a TrustStore and verifies the backing directory exists. A missing file is fine (empty store); a missing directory is a no-op (returns nil store, no error).

func NewTrustStore added in v0.2.2

func NewTrustStore(configDir string) *TrustStore

NewTrustStore returns a TrustStore backed by trusted-configs.json in configDir.

func (*TrustStore) IsTrusted added in v0.2.2

func (ts *TrustStore) IsTrusted(path string) bool

IsTrusted reports whether path (after canonicalization) is in the trust store.

func (*TrustStore) List added in v0.2.2

func (ts *TrustStore) List() []TrustEntry

List returns all trusted entries.

func (*TrustStore) Trust added in v0.2.2

func (ts *TrustStore) Trust(path string) error

Trust adds path to the trust store (idempotent — re-trusting updates the timestamp).

func (*TrustStore) Untrust added in v0.2.2

func (ts *TrustStore) Untrust(path string) (bool, error)

Untrust removes path from the trust store. Returns true if it was present.

Jump to

Keyboard shortcuts

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