config

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: MPL-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package config owns the unified runtime configuration for codamigo.

Configuration is loaded in four layers, with later sources winning: built-in defaults → global YAML file → project YAML file → environment variables → CLI flags. Defaults provides the built-in defaults; Load reads a YAML file; LoadOrDefault returns an empty Config instead of an error when the file is absent; Config.Merge applies a second Config on top of an existing one, with non-zero fields winning.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GlobalConfigPath

func GlobalConfigPath() (string, error)

GlobalConfigPath returns the path to the user-global config file. Honours XDG_CONFIG_HOME when set; falls back to ~/.codamigo/global_settings.yml. Returns an error when the home directory cannot be determined.

func ProjectConfigPath

func ProjectConfigPath() string

ProjectConfigPath returns the path to the per-project config file.

Types

type Config

type Config struct {
	// EmbeddingProvider selects the embedding backend (e.g. "openai", "voyage").
	EmbeddingProvider string `yaml:"embedding_provider"`
	// EmbeddingModel is the model name sent to the embedding API.
	EmbeddingModel string `yaml:"embedding_model"`
	// EmbeddingAPIKey authenticates requests to the embedding provider.
	EmbeddingAPIKey string `yaml:"embedding_api_key"`
	// EmbeddingBaseURL is the base URL of the embedding API (e.g. "https://api.openai.com/v1").
	EmbeddingBaseURL string `yaml:"embedding_base_url"`
	// EmbeddingDimensions is the dimensionality of the embedding vectors.
	EmbeddingDimensions int `yaml:"embedding_dimensions"`
	// EmbeddingIndexInputType is the input_type sent when embedding documents for indexing.
	EmbeddingIndexInputType string `yaml:"embedding_index_input_type"`
	// EmbeddingQueryInputType is the input_type sent when embedding queries for search.
	EmbeddingQueryInputType string `yaml:"embedding_query_input_type"`
	// EmbeddingMaxBatchSize caps the number of texts sent per embedding API call.
	EmbeddingMaxBatchSize int `yaml:"embedding_max_batch_size"`
	// EmbeddingRateLimit is the sustained requests-per-second limit for the embedding API.
	EmbeddingRateLimit float64 `yaml:"embedding_rate_limit"`
	// EmbeddingRateBurst is the maximum burst size allowed above the sustained rate.
	EmbeddingRateBurst int `yaml:"embedding_rate_burst"`
	// EmbeddingMaxRetries is the maximum number of retries on transient embedding API errors.
	EmbeddingMaxRetries int `yaml:"embedding_max_retries"`
	// EmbeddingRetryBaseDelay is the initial backoff delay before the first retry.
	EmbeddingRetryBaseDelay time.Duration `yaml:"-"`
	// EmbeddingHTTPTimeout caps each embedding HTTP request. Default 60s.
	// Increase for slow local backends; decrease for fast cloud endpoints.
	EmbeddingHTTPTimeout time.Duration `yaml:"-"`
	// IncludePatterns limits indexing to files matching these glob patterns.
	IncludePatterns []string `yaml:"include_patterns"`
	// ExcludePatterns skips files matching these glob patterns during indexing.
	ExcludePatterns []string `yaml:"exclude_patterns"`
	// StorePath is the path to the sqlite-vec database file.
	StorePath string `yaml:"store_path"`
	// ProjectRoot is the root directory to walk for source files.
	ProjectRoot string `yaml:"project_root"`
	// WatchMode controls the filesystem watcher strategy: "auto", "fsnotify", or "poll".
	WatchMode string `yaml:"watch_mode"`
	// PollInterval is the interval between poll cycles when WatchMode is "poll".
	PollInterval time.Duration `yaml:"-"`
	// DebounceWindow groups rapid filesystem events into a single re-index pass.
	DebounceWindow time.Duration `yaml:"-"`
	// IndexConcurrency is the maximum number of files indexed concurrently.
	IndexConcurrency int `yaml:"index_concurrency"`
	// MaxFileSize is the maximum file size in bytes to index. Files larger than
	// this are skipped. 0 means no limit. The default (set by [Defaults]) is 1 MB.
	MaxFileSize int64 `yaml:"-"`
	// WriteBatchSize is the number of files per DB write transaction during
	// batch indexing. 0 means use the default (50).
	WriteBatchSize int `yaml:"write_batch_size"`
	// NonCodeLanguages lists language names excluded from the map when
	// CodeOnly is true. Defaults to ["markdown", "yaml", "json"].
	NonCodeLanguages []string `yaml:"non_code_languages"`
}

Config holds the unified runtime configuration for codamigo.

Configuration is loaded in layers with later sources winning: built-in defaults → global YAML file → project YAML file → env vars → CLI flags.

Duration fields are tagged yaml:"-" because they are parsed from human-readable strings (e.g. "500ms", "5s") via the unexported fileConfig intermediary.

func Defaults

func Defaults() *Config

Defaults returns a Config populated with built-in default values. Use as the starting point before merging file and flag configs.

Example
package main

import (
	"fmt"

	"github.com/ieshan/codamigo/config"
)

func main() {
	cfg := config.Defaults()
	fmt.Println(cfg.EmbeddingModel)
	fmt.Println(cfg.StorePath)
	fmt.Println(cfg.PollInterval)
}
Output:
text-embedding-3-small
.codamigo/store.db
5s

func Load

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

Load reads a Config from a YAML file at path. Returns an error if the file does not exist, contains unknown keys, or has malformed duration strings.

Example
package main

import (
	"fmt"
	"os"

	"github.com/ieshan/codamigo/config"
)

func main() {
	f, err := os.CreateTemp("", "example-*.yml")
	if err != nil {
		panic(err)
	}
	defer os.Remove(f.Name())
	f.WriteString("embedding_model: my-model\npoll_interval: 10s\n")
	f.Close()

	cfg, err := config.Load(f.Name())
	if err != nil {
		panic(err)
	}
	fmt.Println(cfg.EmbeddingModel)
	fmt.Println(cfg.PollInterval)
}
Output:
my-model
10s

func LoadOrDefault

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

LoadOrDefault reads a Config from path, returning a zero-value Config if the file does not exist.

Example
package main

import (
	"fmt"

	"github.com/ieshan/codamigo/config"
)

func main() {
	cfg, err := config.LoadOrDefault("/nonexistent/path.yml")
	if err != nil {
		panic(err)
	}
	fmt.Println(cfg.EmbeddingModel) // zero value, not defaults
}

func (*Config) Merge

func (c *Config) Merge(o *Config) *Config

Merge returns a new Config where non-zero fields in overlay override c. Zero-value fields in the overlay are treated as "not set" and do not override the base value. This means it is impossible to explicitly set numeric fields (like EmbeddingMaxRetries) to 0 via an overlay config. For slices, a non-nil overlay slice (even empty) overrides the base value, allowing an explicit empty list in YAML to clear inherited patterns.

Example
package main

import (
	"fmt"

	"github.com/ieshan/codamigo/config"
)

func main() {
	base := config.Defaults()
	overlay := &config.Config{
		EmbeddingModel: "voyage-code-3",
		StorePath:      "custom/store.db",
	}
	merged := base.Merge(overlay)
	fmt.Println(merged.EmbeddingModel)
	fmt.Println(merged.StorePath)
	fmt.Println(merged.EmbeddingDimensions) // unchanged from base
}
Output:
voyage-code-3
custom/store.db
1536

func (*Config) Validate

func (c *Config) Validate() error

Validate checks all config fields for invalid values and returns a joined error listing every violation found. Returns nil when the config is valid.

Jump to

Keyboard shortcuts

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