config

package
v0.2.1 Latest Latest
Warning

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

Go to latest
Published: Nov 8, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package config loads and merges nexss.srcpack.yml files. It owns every srcpack-specific type, default, and merge rule; file discovery and YAML decoding are delegated to github.com/nexssp/flow/config.

Index

Constants

View Source
const ConfigFileName = "nexss.srcpack.yml"

ConfigFileName is the name srcpack looks for when walking up from a project root.

View Source
const DefaultTreeDepth = 1

DefaultTreeDepth is the single source of truth for omitted tree depth.

Variables

View Source
var BuiltinProfiles = []ProfileMeta{
	{
		Name:        "arch",
		Aliases:     []string{"architecture", "architecture-map", "no-comments", "nocomments", "skeleton", "api-map", "arch-clean"},
		Description: "Architecture map: signatures only (NO bodies, NO comments)",
		Options: ConfigOptions{
			ExportedOnly:   new(true),
			RemoveBodyFunc: new(true),
			StripComments:  new(true),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
		},
	},
	{
		Name:        "api",
		Aliases:     []string{"with-comments", "withcomments", "docs", "contracts", "arch-docs"},
		Description: "Public API declarations: signatures + doc comments (NO bodies, WITH comments)",
		Options: ConfigOptions{
			ExportedOnly:   new(true),
			RemoveBodyFunc: new(true),
			StripComments:  new(false),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
		},
	},
	{
		Name:        "impl",
		Aliases:     []string{"implementation", "review", "logic"},
		Description: "Implementation logic (bodies preserved, comments stripped)",
		Options: ConfigOptions{
			ExportedOnly:   new(false),
			RemoveBodyFunc: new(false),
			StripComments:  new(true),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
		},
	},
	{
		Name:        "source",
		Aliases:     []string{"full", "src", "sources"},
		Description: "Full code context for AI (bodies & comments, no tests/deps)",
		Options: ConfigOptions{
			ExportedOnly:   new(false),
			RemoveBodyFunc: new(false),
			StripComments:  new(false),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
		},
	},
	{
		Name:        "with-tests",
		Aliases:     []string{"test", "tests", "withtests"},
		Description: "Source code plus unit tests and test helpers",
		Options: ConfigOptions{
			ExportedOnly:   new(false),
			RemoveBodyFunc: new(false),
			StripComments:  new(false),
			NoTests:        new(false),
		},
	},
	{
		Name:        "compact",
		Aliases:     []string{"min", "tiny"},
		Description: "Aggressively reduced context for small token budgets",
		Options: ConfigOptions{
			ExportedOnly:   new(true),
			RemoveBodyFunc: new(true),
			StripComments:  new(true),
			TrimBlankLines: new(true),
			TrimIndent:     new(true),
			MaxLines:       new(100),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
		},
	},
	{
		Name:        "dense",
		Aliases:     []string{"ai-dense", "idl", "ultra", "signatures"},
		Description: "Ultra-compact IDL for AI reasoning (signatures only, max token savings)",
		Options: ConfigOptions{
			ExportedOnly:   new(true),
			RemoveBodyFunc: new(true),
			StripComments:  new(true),
			NoTests:        new(true),
			NoGenerated:    new(true),
			NoDeps:         new(true),
			TrimBlankLines: new(true),
			TrimIndent:     new(true),
			Dense:          new(true),
		},
	},
}

BuiltinProfiles is the ordered list of profiles every srcpack run starts from. User profiles with the same name override fields on top; user profiles with a new name are added alongside.

View Source
var ConfigFileNames = []string{
	"nexss.srcpack.yml",
	"nexss.srcpack.yaml",
	"_nexss.yml",
	"_nexss.yaml",
}

ConfigFileNames is the ordered list of names srcpack recognizes as a configuration file when looking inside a specific directory. The first entry is the canonical name written by `srcpack init`; the rest are accepted for compatibility.

View Source
var DefaultExampleFolders = []string{
	"examples", "example",
	"samples", "sample",
	"demo", "demos",
}

DefaultExampleFolders is the built-in set of directory names treated as "examples" and excluded when NoExamples is on.

Functions

func CanonicalProfileName

func CanonicalProfileName(name string) string

CanonicalProfileName resolves a case-insensitive name or alias to a built-in profile's canonical name. Unknown names are returned trimmed but otherwise unchanged, so user-defined profile names pass through.

func EmbeddedIgnore

func EmbeddedIgnore() []byte

EmbeddedIgnore returns the shipped content of nexss.srcpack.ignore. Used by `srcpack init` to seed the file when one is not present.

func FindInDir

func FindInDir(dir string) string

FindInDir returns the config file present in dir, or "" when none is found. Unlike FindRoot, this does not walk upward — it only checks the given directory.

Used by `srcpack init` to detect "a config already exists HERE", which is what decides whether --force is required. The distinction matters: init creates a config in the current directory, so a walk-up would find the parent project's config and overwrite it.

func FindRoot

func FindRoot(startDir string) (root, configPath string)

FindRoot returns the project root for startDir, plus the path of the config file found there (empty when the root was determined by .git/ only).

The project root is the first ancestor of startDir that contains either a recognized config file or a .git/ directory. When neither is found before the filesystem root, startDir is returned with an empty configPath.

This is the single source of truth for "where is the project". Both config discovery and default output placement use it, so a run from a subdirectory never produces a stray _srcpack/ under the subdirectory.

func FormatSnippet

func FormatSnippet(s string, maxLen int) string

FormatSnippet renders a short preview of multi-line text: the first few words, then an ellipsis, then the last few words.

func MergeConfigOptions

func MergeConfigOptions(dst *ConfigOptions, src ConfigOptions)

MergeConfigOptions overlays every non-nil field of src onto dst.

func MergeProfile

func MergeProfile(dst *Profile, src Profile)

MergeProfile overlays src on dst. Fields that src leaves unset are preserved. Includes are unioned; Options merge recursively.

func MergeStringSlices

func MergeStringSlices(dst, src []string) []string

MergeStringSlices appends src items to dst, skipping duplicates.

func ParseProfileRef

func ParseProfileRef(ref, currentDir string) (configPath, profileName string)

ParseProfileRef splits a selector into an optional external config file and a profile name. When ref does not name a config file, the returned path is empty and the whole ref is the profile name.

Supported forms:

"path/to/file.yml:profile"
"path/to/file.yml#profile"
"path/to/dir:profile"        (dir must contain a config file)
"path/to/dir#profile"
"path/to/dir/profile"        (dir must contain a config file)
"profile"                    (bare profile name)

func ResolveTreeDepth

func ResolveTreeDepth(depth int) int

ResolveTreeDepth preserves positive overrides and defaults unset/invalid values.

func SortedProfileNames

func SortedProfileNames(cfg Config) []string

SortedProfileNames returns every profile name in cfg.Profiles in stable order. Used for error messages and CLI listings.

func TargetHasCycle

func TargetHasCycle(start string, targets map[string]TargetGroup) bool

TargetHasCycle reports whether a target's reachable dependency graph cycles. It performs no filesystem access and leaves reporting policy to its caller.

Types

type ChangeDetector

type ChangeDetector interface {
	IsActive() bool
	IsFileChanged(absPath, relPath string, modTime time.Time) (bool, error)
}

ChangeDetector reports whether a file should be included under an incremental or git-filtered run. Implementations live in the operators package; the config layer only needs the contract.

type Config

type Config struct {
	Prompts    map[string]string       `yaml:"prompts,omitempty" json:"prompts,omitempty"`
	Editors    map[string]EditorFormat `yaml:"editors,omitempty" json:"editors,omitempty"`
	TargetsMap map[string]TargetGroup  `yaml:"targets,omitempty" json:"targets,omitempty"`
	Views      map[string][]string     `yaml:"views,omitempty"   json:"views,omitempty"`
	Profile    `yaml:",inline"`
	Profiles   map[string]Profile `yaml:"profiles,omitempty" json:"profiles,omitempty"`
}

Config is the top-level structure of nexss.srcpack.yml. Profile is embedded so top-level keys such as `editor:` and `options:` bind directly to the default profile without an intermediate `profile:` wrapper.

func Load

func Load(rootDir, explicitPath string) (Config, error)

Load returns the effective Config for a run. When no user file is found under rootDir the embedded defaults plus built-in profiles are returned. When a user file is present it is overlaid on the defaults; built-in profile fields are preserved unless the user file explicitly overrides them.

explicitPath, when non-empty, bypasses discovery and loads that file instead. A missing explicit path is an error, unlike a missing discovered path.

func LoadOptional

func LoadOptional(rootDir string) (Config, error)

LoadOptional behaves like Load but treats a missing explicit path as "no file present" rather than an error. Used by callers that want the defaults-plus-discovery behavior only.

type ConfigOptions

type ConfigOptions struct {
	StripComments    *bool    `yaml:"strip_comments,omitempty"`
	RemoveBodyFunc   *bool    `yaml:"remove_body_func,omitempty"`
	MaxLines         *int     `yaml:"max_lines,omitempty"`
	MaxLinesHead     *int     `yaml:"max_lines_head,omitempty"`
	MaxLinesTail     *int     `yaml:"max_lines_tail,omitempty"`
	NoTests          *bool    `yaml:"no_tests,omitempty"`
	NoGenerated      *bool    `yaml:"no_generated,omitempty"`
	TrimBlankLines   *bool    `yaml:"trim_blank_lines,omitempty"`
	TrimIndent       *bool    `yaml:"trim_indent,omitempty"`
	NoDeps           *bool    `yaml:"no_deps,omitempty"`
	ExtFilter        *string  `yaml:"ext_filter,omitempty"`
	ExportedOnly     *bool    `yaml:"exported_only,omitempty"`
	NoHeader         *bool    `yaml:"no_header,omitempty"`
	NoPrompt         *bool    `yaml:"no_prompt,omitempty"`
	NoStart          *bool    `yaml:"no_start,omitempty"`
	NoEnd            *bool    `yaml:"no_end,omitempty"`
	Since            *string  `yaml:"since,omitempty"`
	Modified         *bool    `yaml:"modified,omitempty"`
	Staged           *bool    `yaml:"staged,omitempty"`
	Changed          *bool    `yaml:"changed,omitempty"`
	MaskSecrets      *bool    `yaml:"mask_secrets,omitempty"`
	DiffOnly         *bool    `yaml:"diff_only,omitempty"`
	Tree             *bool    `yaml:"tree,omitempty"`
	TreeOnly         *bool    `yaml:"tree_only,omitempty"`
	TreeFiles        *bool    `yaml:"tree_files,omitempty"`
	TreeDepth        *int     `yaml:"tree_depth,omitempty"`
	FullTree         *bool    `yaml:"full_tree,omitempty"`
	CostROI          *bool    `yaml:"cost,omitempty"`
	IncludeDirPrefix *bool    `yaml:"include_dir_prefix,omitempty"`
	Dense            *bool    `yaml:"dense,omitempty"`
	Examples         []string `yaml:"examples,omitempty"`
	NoExamples       *bool    `yaml:"no_examples,omitempty"`
}

ConfigOptions is the sparse, YAML-facing form of Options. A nil pointer means "not specified"; overlay skips those fields.

func (ConfigOptions) Mutator

func (c ConfigOptions) Mutator() OptionMutator

Mutator returns an OptionMutator that overlays every non-nil field of c onto the target Options.

func (ConfigOptions) ToOptions

func (c ConfigOptions) ToOptions() Options

ToOptions materializes a fresh Options with the srcpack defaults and then overlays c on top.

type ConfigRes

type ConfigRes struct {
	Profiles []ProfileInfo     `json:"profiles"`
	Targets  []TargetInfo      `json:"targets"`
	Prompts  map[string]string `json:"prompts"`
	Editors  []EditorInfo      `json:"editors"`
}

ConfigRes is the structured response for `srcpack list`.

func (ConfigRes) String

func (c ConfigRes) String() string

type ConfigStore

type ConfigStore struct {
	Path string
}

ConfigStore reads and writes nexss.srcpack.yml. Every write goes through xfs.WriteFileAtomic so a crash mid-write never leaves a partial file.

func NewConfigStore

func NewConfigStore(path string) *ConfigStore

func (*ConfigStore) LoadRaw

func (s *ConfigStore) LoadRaw() (UserConfig, error)

LoadRaw reads the user config without overlaying built-in defaults. A missing file is not an error — it returns an empty config.

func (*ConfigStore) Mutate

func (s *ConfigStore) Mutate(dryRun bool, fn func(*UserConfig) error) (string, error)

Mutate loads the raw config, applies fn, then atomically writes the result. A failed fn aborts the write. When dryRun is true the serialized YAML is returned without touching disk.

type DirEntry

type DirEntry struct {
	Path       string   `yaml:"path"                 json:"path"`
	Full       []string `yaml:"full,omitempty"       json:"full,omitempty"`
	Omit       []string `yaml:"omit,omitempty"       json:"omit,omitempty"`
	Signatures []string `yaml:"signatures,omitempty" json:"signatures,omitempty"`
}

DirEntry is one entry in a target's `dir:` list. When no per-entry rule is present it may be written as a bare string; otherwise it is an object with optional full/omit/signatures sub-lists.

func (DirEntry) MarshalYAML

func (d DirEntry) MarshalYAML() (any, error)

func (*DirEntry) UnmarshalYAML

func (d *DirEntry) UnmarshalYAML(value *yaml.Node) error

type EditorFormat

type EditorFormat struct {
	Description string `yaml:"description,omitempty" json:"description,omitempty"`
	Start       string `yaml:"start,omitempty"       json:"start,omitempty"`
	End         string `yaml:"end,omitempty"         json:"end,omitempty"`
	FileStart   string `yaml:"file_start,omitempty"  json:"file_start,omitempty"`
	FileEnd     string `yaml:"file_end,omitempty"    json:"file_end,omitempty"`
}

EditorFormat defines layout rules for one output format.

type EditorInfo

type EditorInfo struct {
	Name        string `json:"name"`
	Description string `json:"description,omitempty"`
}

type FlexibleText

type FlexibleText struct {
	Value    string
	Disabled bool
	Set      bool
}

FlexibleText accepts a string, a YAML block scalar, or the boolean false (meaning "explicitly disabled"). Set records whether the field was present at all, so overlay merge can distinguish "not specified" from "specified as disabled".

func (FlexibleText) MarshalYAML

func (f FlexibleText) MarshalYAML() (any, error)

func (*FlexibleText) UnmarshalYAML

func (f *FlexibleText) UnmarshalYAML(value *yaml.Node) error

type Guardrails

type Guardrails interface {
	CheckFile(path string, info os.FileInfo) error
}

Guardrails enforces per-scan safety limits.

type IssueSeverity

type IssueSeverity string

IssueSeverity classifies one validation finding.

const (
	SeverityOK      IssueSeverity = "OK"
	SeverityWarning IssueSeverity = "WARN"
	SeverityError   IssueSeverity = "ERROR"
)

type OptionMutator

type OptionMutator func(*Options)

OptionMutator is one step in a chain of option overlays.

type Options

type Options struct {
	StripComments    bool
	RemoveBodyFunc   bool
	MaxLines         int
	MaxLinesHead     int
	MaxLinesTail     int
	NoTests          bool
	NoGenerated      bool
	TrimBlankLines   bool
	TrimIndent       bool
	ExtFilter        string
	NoDeps           bool
	OutputFile       string
	ExportedOnly     bool
	NoHeader         bool
	NoPrompt         bool
	NoStart          bool
	NoEnd            bool
	Since            string
	Modified         bool
	Staged           bool
	Changed          bool
	MaskSecrets      bool
	DiffOnly         bool
	Tree             bool
	TreeOnly         bool
	TreeFiles        bool
	TreeDepth        int
	FullTree         bool
	CostROI          bool
	IncludeDirPrefix bool
	Dense            bool
	Examples         []string
	NoExamples       bool
	Detector         ChangeDetector
	Guardrails       Guardrails
}

Options is the fully resolved configuration for one pipeline run. Every field is concrete; overlay of ConfigOptions on top of it happens once, before scanning starts.

func ResolveOptions

func ResolveOptions(base Options, chain []Profile) Options

ResolveOptions applies every profile's option overlay to base in chain order — earliest first, latest last — and returns the result. Callers pass cfg.Options.ToOptions() as base.

func (*Options) Apply

func (o *Options) Apply(mutators ...OptionMutator) *Options

Apply runs every non-nil mutator in order and returns the receiver for chaining.

type Profile

type Profile struct {
	Name             string        `yaml:"-"                          json:"name,omitempty"`
	BaseDir          string        `yaml:"-"                          json:"base_dir,omitempty"`
	Description      string        `yaml:"description,omitempty"      json:"description,omitempty"`
	Example          string        `yaml:"example,omitempty"          json:"example,omitempty"`
	Prompt           FlexibleText  `yaml:"prompt,omitempty"            json:"prompt,omitzero"`
	Start            FlexibleText  `yaml:"start,omitempty"             json:"start,omitzero"`
	End              FlexibleText  `yaml:"end,omitempty"               json:"end,omitzero"`
	FileStart        string        `yaml:"file_start,omitempty"       json:"file_start,omitempty"`
	FileEnd          string        `yaml:"file_end,omitempty"         json:"file_end,omitempty"`
	Editor           string        `yaml:"editor,omitempty"           json:"editor,omitempty"`
	Output           string        `yaml:"output,omitempty"           json:"output,omitempty"`
	OutputFile       string        `yaml:"output_file,omitempty"      json:"output_file,omitempty"`
	Options          ConfigOptions `yaml:"options,omitempty"           json:"options,omitzero"`
	Dir              []DirEntry    `yaml:"dir,omitempty"              json:"dir,omitempty"`
	Files            []string      `yaml:"files,omitempty"            json:"files,omitempty"`
	Includes         []string      `yaml:"includes,omitempty"         json:"includes,omitempty"`
	IncludeProfiles  []string      `yaml:"include_profiles,omitempty" json:"include_profiles,omitempty"`
	IncludeProfile   string        `yaml:"include_profile,omitempty"  json:"include_profile,omitempty"`
	IncludedProfiles []string      `yaml:"-"                          json:"included_profiles,omitempty"`
}

Profile defines transformation rules, prompt bindings, and file or directory scopes for a named content mode.

func ResolveProfileChain

func ResolveProfileChain(ref string, cfg Config, currentDir string) ([]Profile, error)

ResolveProfileChain resolves ref to a list of profiles whose option overlays are applied in order — earliest first, latest last — to produce the effective options for a run. The last profile in the chain is the target profile; profiles before it are its transitive includes.

ref may be a bare profile name, "path:profile", "path#profile", or "path/to/dir/profile" when the directory contains a config file. When ref names an external config, that file is loaded and its profiles are used; otherwise cfg is used.

Cycles in the include graph are reported as xerr.Conflict. Missing profiles are reported as xerr.NotFound with the available names.

func (Profile) GetIncludeProfiles

func (p Profile) GetIncludeProfiles() []string

GetIncludeProfiles returns IncludeProfile followed by IncludeProfiles, with empty entries dropped.

func (Profile) GetOutputFile

func (p Profile) GetOutputFile() string

GetOutputFile returns OutputFile, falling back to the legacy Output key.

type ProfileInfo

type ProfileInfo struct {
	Name        string   `json:"name"`
	Description string   `json:"description,omitempty"`
	Prompt      string   `json:"prompt,omitempty"`
	Includes    []string `json:"includes,omitempty"`
}

type ProfileMeta

type ProfileMeta struct {
	Name        string
	Aliases     []string
	Description string
	PromptKey   string
	Options     ConfigOptions
}

ProfileMeta describes one shipped built-in profile. The Options field carries the profile's default overlay; a user override in nexss.srcpack.yml merges on top of it.

func FindBuiltinProfile

func FindBuiltinProfile(name string) (ProfileMeta, bool)

FindBuiltinProfile returns the built-in profile matching name or one of its aliases.

type TargetGroup

type TargetGroup struct {
	Name        string        `yaml:"-"                    json:"name,omitempty"`
	Description string        `yaml:"description,omitempty" json:"description,omitempty"`
	Paths       []string      `yaml:"paths,omitempty"       json:"paths,omitempty"`
	Dir         []DirEntry    `yaml:"dir,omitempty"         json:"dir,omitempty"`
	Files       []string      `yaml:"files,omitempty"       json:"files,omitempty"`
	Targets     []string      `yaml:"targets,omitempty"     json:"targets,omitempty"`
	Prompt      FlexibleText  `yaml:"prompt,omitempty"       json:"prompt,omitzero"`
	Header      FlexibleText  `yaml:"header,omitempty"       json:"header,omitzero"`
	Options     ConfigOptions `yaml:"options,omitempty"      json:"options,omitzero"`
}

TargetGroup specifies a named subsystem of directories and explicit files.

type TargetInfo

type TargetInfo struct {
	Name    string   `json:"name"`
	Paths   []string `json:"paths,omitempty"`
	Dir     []string `json:"dir,omitempty"`
	Files   []string `json:"files,omitempty"`
	Targets []string `json:"targets,omitempty"`
	Prompt  string   `json:"prompt,omitempty"`
}

type UserConfig

type UserConfig struct {
	Prompts  map[string]string       `yaml:"prompts,omitempty"`
	Prompt   *FlexibleText           `yaml:"prompt,omitempty"`
	Options  *ConfigOptions          `yaml:"options,omitempty"`
	Editor   string                  `yaml:"editor,omitempty"`
	Dir      []DirEntry              `yaml:"dir,omitempty"`
	Targets  map[string]TargetGroup  `yaml:"targets,omitempty"`
	Profiles map[string]Profile      `yaml:"profiles,omitempty"`
	Editors  map[string]EditorFormat `yaml:"editors,omitempty"`
	Views    map[string][]string     `yaml:"views,omitempty"`
}

UserConfig is the raw YAML structure of nexss.srcpack.yml as written by a user. It contains only fields the user actually wrote — no defaults, no built-in profiles. Used exclusively for read-modify- write operations; runtime consumers use Config.

type ValidationIssue

type ValidationIssue struct {
	Severity IssueSeverity
	Category string
	Message  string
}

ValidationIssue is one finding from Validate.

type ValidationReport

type ValidationReport struct {
	ConfigFile string
	Issues     []ValidationIssue
	Passed     bool
}

ValidationReport is the structured result of a config audit.

func Validate

func Validate(cwd, configPath string) ValidationReport

Validate audits a workspace configuration: missing target paths, cycles in target sub-targets, references into _srcpack, and profile prompts that name an undefined prompt. It never fails — problems are reported in the returned report with Passed=false.

func (ValidationReport) String

func (r ValidationReport) String() string

Jump to

Keyboard shortcuts

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