Documentation
¶
Overview ¶
Package configui provides schema-driven configuration UI types and metadata.
Package configui provides schema-driven configuration UI types and metadata.
Package configui provides schema-driven configuration UI types and metadata.
Package configui provides schema-driven configuration UI types and metadata.
Index ¶
- Variables
- func CollapseAll(nodes []*ConfigNode)
- func ExpandAll(nodes []*ConfigNode)
- func FindParentIndex(flatNodes []*ConfigNode, node *ConfigNode) int
- func FormatValue(v interface{}) string
- func FormatValuePreview(v interface{}, maxWidth int) string
- func FormatValueWithType(v interface{}, fieldType FieldType) string
- func ShouldShowField(field FieldMeta, value interface{}, viewMode ViewMode, ...) bool
- func SortNodes(nodes []*ConfigNode, mode SortMode)
- func SortTree(nodes []*ConfigNode, mode SortMode)
- func ToggleNode(node *ConfigNode)
- type ConfigNode
- type ConfigPage
- type FieldMeta
- func (f FieldMeta) FullPath() string
- func (f FieldMeta) HasChildren() bool
- func (f FieldMeta) IsDeprecated() bool
- func (f FieldMeta) IsImportant() bool
- func (f FieldMeta) IsNonStable() bool
- func (f FieldMeta) IsSensitive() bool
- func (f FieldMeta) IsStable() bool
- func (f FieldMeta) Label() string
- func (f FieldMeta) StatusBadge() string
- func (f FieldMeta) StatusNotice() string
- type FieldStatus
- type FieldType
- type LayeredValue
- type MaturityFilter
- type SortMode
- type ViewMode
Constants ¶
This section is empty.
Variables ¶
var FieldsByPath = map[string]*FieldMeta{ "groves": &SchemaFields[0], "notebooks": &SchemaFields[1], "explicit_projects": &SchemaFields[2], "name": &SchemaFields[3], "workspaces": &SchemaFields[4], "build_cmd": &SchemaFields[5], "build_after": &SchemaFields[6], "tui": &SchemaFields[7], "logging": &SchemaFields[8], "gemini.api_key_command": &SchemaFields[9], "context": &SchemaFields[10], "version": &SchemaFields[11], "gemini.api_key": &SchemaFields[12], "search_paths": &SchemaFields[13], }
FieldsByPath provides O(1) lookup by full path.
var ImportantFields = []*FieldMeta{ &SchemaFields[0], &SchemaFields[1], &SchemaFields[9], &SchemaFields[12], }
ImportantFields contains only fields marked as important/key configuration options.
var SchemaFields = []FieldMeta{ { Path: []string{"groves"}, Type: FieldMap, Description: "Root directories to search for projects and ecosystems", Layer: config.SourceGlobal, Priority: 1, Important: true, }, { Path: []string{"notebooks"}, Type: FieldObject, Description: "Notebook configuration", Layer: config.SourceGlobal, Priority: 2, Important: true, RefType: "NotebooksConfig", Children: []FieldMeta{ { Path: []string{"notebooks", "definitions"}, Type: FieldMap, Description: "Map of notebook name to notebook configuration", }, { Path: []string{"notebooks", "rules"}, Type: FieldObject, Description: "Rules for notebook usage (default notebook", RefType: "NotebookRules", Children: []FieldMeta{ { Path: []string{"notebooks", "rules", "default"}, Type: FieldString, Description: "Name of the default notebook to use", Important: true, }, { Path: []string{"notebooks", "rules", "global"}, Type: FieldObject, Description: "Configuration for the system-wide global notebook", Important: true, RefType: "GlobalNotebookConfig", Children: []FieldMeta{ { Path: []string{"notebooks", "rules", "global", "root_dir"}, Type: FieldString, Description: "Absolute path to the global notebook root directory", Important: true, Required: true, }, }, }, }, }, }, }, { Path: []string{"explicit_projects"}, Type: FieldArray, Description: "Specific projects to include without discovery", Layer: config.SourceGlobal, Priority: 5, }, { Path: []string{"name"}, Type: FieldString, Description: "Name of the project or ecosystem", Layer: config.SourceEcosystem, Priority: 10, }, { Path: []string{"workspaces"}, Type: FieldArray, Description: "Glob patterns for workspace directories in this ecosystem", Layer: config.SourceEcosystem, Priority: 11, }, { Path: []string{"build_cmd"}, Type: FieldString, Description: "Custom build command (default: make build)", Layer: config.SourceProject, Priority: 20, }, { Path: []string{"build_after"}, Type: FieldArray, Description: "Projects that must be built before this one", Layer: config.SourceProject, Priority: 21, }, { Path: []string{"tui"}, Type: FieldObject, Description: "TUI appearance and behavior settings", Layer: config.SourceGlobal, Priority: 50, RefType: "TUIConfig", Children: []FieldMeta{ { Path: []string{"tui", "theme"}, Type: FieldSelect, Description: "Color theme for terminal interfaces", Options: []string{"kanagawa", "gruvbox", "terminal"}, Layer: config.SourceGlobal, Priority: 51, Important: true, }, { Path: []string{"tui", "icons"}, Type: FieldSelect, Description: "Icon set to use: nerd or ascii", Options: []string{"nerd", "ascii"}, Layer: config.SourceGlobal, Priority: 52, Important: true, }, { Path: []string{"tui", "nvim_embed"}, Type: FieldObject, Description: "Embedded Neovim configuration", Layer: config.SourceGlobal, Priority: 53, RefType: "NvimEmbedConfig", Status: StatusAlpha, StatusMessage: "Experimental Neovim embedding", StatusSince: "v0.6.0", StatusTarget: "v1.0", Children: []FieldMeta{ { Path: []string{"tui", "nvim_embed", "user_config"}, Type: FieldBool, Description: "If true", Required: true, }, }, }, }, }, { Path: []string{"logging"}, Type: FieldObject, Description: "Logging configuration", Layer: config.SourceGlobal, Priority: 60, RefType: "LoggingSchemaConfig", Children: []FieldMeta{ { Path: []string{"logging", "groups"}, Type: FieldMap, Description: "Named collections of component loggers for filtering", }, { Path: []string{"logging", "level"}, Type: FieldString, Description: "Minimum log level (debug", Required: true, }, { Path: []string{"logging", "log_startup"}, Type: FieldBool, Description: "Log 'Grove binary started' on first init", Required: true, }, { Path: []string{"logging", "report_caller"}, Type: FieldBool, Description: "Include file/line/function in output", Required: true, }, { Path: []string{"logging", "show_current_project"}, Type: FieldBool, Description: "Always show logs from current project regardless of filters", }, }, }, { Path: []string{"api_key_command"}, Type: FieldString, Description: "Shell command to retrieve API key (e.g. gcloud secrets or 1password)", Layer: config.SourceGlobal, Priority: 60, Important: true, Namespace: "gemini", }, { Path: []string{"context"}, Type: FieldObject, Description: "Configuration for the cx (context) tool", Layer: config.SourceGlobal, Priority: 80, RefType: "ContextConfig", Children: []FieldMeta{ { Path: []string{"context", "repos_dir"}, Type: FieldString, Description: "Directory where cx repo stores bare repositories (default: ~/.grove/cx)", Layer: config.SourceGlobal, Priority: 80, }, { Path: []string{"context", "default_rules_path"}, Type: FieldString, Description: "Default rules file path for context filtering", Layer: config.SourceProject, Priority: 81, }, }, }, { Path: []string{"version"}, Type: FieldString, Description: "Configuration version (e.g. 1.0)", Layer: config.SourceGlobal, Priority: 100, }, { Path: []string{"api_key"}, Type: FieldString, Description: "Direct API key for Google Gemini", Layer: config.SourceGlobal, Priority: 200, Sensitive: true, Important: true, Hint: "Consider using api_key_command to fetch from a secrets manager", Namespace: "gemini", }, { Path: []string{"search_paths"}, Type: FieldMap, Description: "DEPRECATED: Use groves instead", Layer: config.SourceGlobal, Priority: 1000, Status: StatusDeprecated, StatusMessage: "Use 'groves' for project discovery", StatusSince: "v0.5.0", StatusTarget: "v1.0.0", StatusReplacedBy: "groves", }, }
SchemaFields contains all config fields sorted by priority.
Functions ¶
func CollapseAll ¶
func CollapseAll(nodes []*ConfigNode)
CollapseAll collapses all expandable nodes in the tree including root level.
func FindParentIndex ¶
func FindParentIndex(flatNodes []*ConfigNode, node *ConfigNode) int
FindParentIndex returns the index of the parent node in a flattened list.
func FormatValue ¶
func FormatValue(v interface{}) string
FormatValue returns a human-readable string representation of a config value. It handles primitives, maps (showing key count), slices (showing item count), and structs.
func FormatValuePreview ¶
FormatValuePreview returns a value string with a preview of content, limited to maxWidth. For maps and structs, it shows key-value pairs up to the width limit.
func FormatValueWithType ¶
FormatValueWithType returns a formatted value string, taking field type into account. This allows for type-specific formatting (e.g., showing array item count for FieldArray).
func ShouldShowField ¶
func ShouldShowField(field FieldMeta, value interface{}, viewMode ViewMode, maturityFilter MaturityFilter) bool
ShouldShowField determines if a field should be visible based on current filters.
func SortNodes ¶
func SortNodes(nodes []*ConfigNode, mode SortMode)
SortNodes sorts a slice of config nodes in place based on the sort mode. Note: This only sorts the given slice, not recursively. Use SortTree for recursive sorting.
func SortTree ¶
func SortTree(nodes []*ConfigNode, mode SortMode)
SortTree recursively sorts the tree at each level, preserving parent-child relationships. This should be called on tree roots BEFORE flattening.
func ToggleNode ¶
func ToggleNode(node *ConfigNode)
ToggleNode toggles the collapsed state of a node.
Types ¶
type ConfigNode ¶
type ConfigNode struct {
Field FieldMeta
Value interface{} // Final merged value
LayerValues LayeredValue // Values at each layer
ActiveSource config.ConfigSource // Which layer provided the value
Depth int
Collapsed bool
Children []*ConfigNode
Parent *ConfigNode
// Key is used for map entries (the map key) or array indices.
// For regular schema fields, this is empty.
Key string
// IsDynamic indicates if this node was dynamically created from map keys
// rather than defined in the schema.
IsDynamic bool
}
ConfigNode represents a node in the configuration tree. It holds both schema information (via FieldMeta) and runtime value information.
func BuildTree ¶
func BuildTree(schema []FieldMeta, layered *config.LayeredConfig) []*ConfigNode
BuildTree constructs a tree of ConfigNodes from the schema and layered config.
func FilterNodes ¶
func FilterNodes(nodes []*ConfigNode, viewMode ViewMode, maturityFilter MaturityFilter) []*ConfigNode
FilterNodes returns a filtered list of nodes based on view mode and maturity filter.
func Flatten ¶
func Flatten(nodes []*ConfigNode) []*ConfigNode
Flatten returns a list of visible nodes based on collapsed state. Only visible (expanded) nodes are included in the result.
func (*ConfigNode) DisplayKey ¶
func (n *ConfigNode) DisplayKey() string
DisplayKey returns the appropriate key/label for display. For dynamic map entries, returns the Key; otherwise returns the field label.
func (*ConfigNode) HasValue ¶
func (n *ConfigNode) HasValue() bool
HasValue returns true if the node has a non-nil value.
func (*ConfigNode) IsContainer ¶
func (n *ConfigNode) IsContainer() bool
IsContainer returns true if the node can have children (Map, Object, or Array).
func (*ConfigNode) IsExpandable ¶
func (n *ConfigNode) IsExpandable() bool
IsExpandable returns true if the node has children and can be expanded/collapsed.
type ConfigPage ¶
type ConfigPage interface {
// Name returns the display name for the tab (e.g., "Global", "Ecosystem", "Project").
Name() string
// Layer returns the config layer this page represents.
Layer() config.ConfigSource
// Init initializes the page model.
Init() tea.Cmd
// Update handles messages for the page.
Update(tea.Msg) (ConfigPage, tea.Cmd)
// View renders the page's UI.
View() string
// Focus is called when the page becomes active.
Focus() tea.Cmd
// Blur is called when the page loses focus.
Blur()
// SetSize sets the dimensions for the page.
SetSize(width, height int)
// Refresh reloads the page with updated config data.
Refresh(layered *config.LayeredConfig)
}
ConfigPage defines the interface for a tabbed page in the config editor. This follows the same pattern as cx/cmd/view/Page for consistency.
type FieldMeta ¶
type FieldMeta struct {
// Path is the dot-separated path to the field (e.g., ["tui", "theme"]).
Path []string
// Type is the UI field type.
Type FieldType
// Description is the human-readable description from the schema.
Description string
// Options contains enum values for FieldSelect type fields.
Options []string
// Default is the default value if specified in the schema.
Default interface{}
// Layer is the recommended config layer for saving (from x-layer).
Layer config.ConfigSource
// Priority determines the sort order (lower = higher in list).
// 1-10 for wizard fields, 50+ for common, 100+ for advanced.
Priority int
// Sensitive indicates if the field contains sensitive data (from x-sensitive).
// If true, the UI should mask the value and suggest alternatives.
Sensitive bool
// Important indicates if the field is a key/important configuration option (from x-important).
Important bool
// Hint provides additional guidance shown in the edit dialog (from x-hint).
Hint string
// Children contains nested fields for FieldObject type.
Children []FieldMeta
// Namespace is the schema namespace (e.g., "gemini", "tmux", empty for core).
Namespace string
// Required indicates if this field is required by the schema.
Required bool
// RefType is the $ref type name if this field references a definition.
RefType string
// Unified Status Fields (alpha, beta, stable, deprecated)
Status FieldStatus `json:"status,omitempty"`
StatusMessage string `json:"status_message,omitempty"`
StatusSince string `json:"status_since,omitempty"`
StatusTarget string `json:"status_target,omitempty"`
StatusReplaces string `json:"status_replaces,omitempty"`
StatusReplacedBy string `json:"status_replaced_by,omitempty"`
}
FieldMeta contains metadata for a configuration field derived from JSON Schema.
func FilterSchema ¶
func FilterSchema(schema []FieldMeta, layer config.ConfigSource) []FieldMeta
FilterSchema returns a subset of fields belonging to the specified layer. This is used by tabbed config pages to show only fields relevant to each layer.
func (FieldMeta) HasChildren ¶
HasChildren returns true if this is a nested object with children.
func (FieldMeta) IsDeprecated ¶
IsDeprecated returns true if this field is deprecated.
func (FieldMeta) IsImportant ¶
IsImportant returns true if this field is a key/important configuration option.
func (FieldMeta) IsNonStable ¶
IsNonStable returns true for alpha, beta, or deprecated fields.
func (FieldMeta) IsSensitive ¶
IsSensitive returns true if this field contains sensitive data.
func (FieldMeta) Label ¶
Label returns a human-readable label for the field. Uses the last path component, converted to title case.
func (FieldMeta) StatusBadge ¶
StatusBadge returns the display badge for the status.
func (FieldMeta) StatusNotice ¶
StatusNotice returns a formatted status message for the UI.
type FieldStatus ¶
type FieldStatus string
FieldStatus represents the lifecycle stage of a config field.
const ( StatusAlpha FieldStatus = "alpha" StatusBeta FieldStatus = "beta" StatusStable FieldStatus = "stable" // default StatusDeprecated FieldStatus = "deprecated" )
type FieldType ¶
type FieldType int
FieldType represents the type of a configuration field for UI rendering.
const ( FieldString FieldType = iota // Plain text input FieldBool // Boolean toggle FieldInt // Integer input FieldSelect // String with enum (dropdown/select) FieldArray // Array of strings FieldObject // Nested object (collapsible in UI) FieldMap // Object with additionalProperties (key-value editor) )
type LayeredValue ¶
type LayeredValue struct {
Default interface{}
Global interface{}
GlobalOverride interface{}
EnvOverlay interface{}
Ecosystem interface{}
Project interface{}
Override interface{} // From grove.override.toml
}
LayeredValue holds the values for a node across all config layers.
type MaturityFilter ¶
type MaturityFilter string
MaturityFilter controls which maturity levels are displayed.
const ( MaturityStable MaturityFilter = "stable" // stable only MaturityExperimental MaturityFilter = "+experimental" // stable + alpha/beta MaturityDeprecated MaturityFilter = "+deprecated" // stable + deprecated MaturityAll MaturityFilter = "all" // everything )
func CycleMaturityFilter ¶
func CycleMaturityFilter(current MaturityFilter) MaturityFilter
CycleMaturityFilter returns the next filter in the rotation.
func CycleMaturityFilterReverse ¶
func CycleMaturityFilterReverse(current MaturityFilter) MaturityFilter
CycleMaturityFilterReverse returns the previous filter in the rotation.
type SortMode ¶
type SortMode string
SortMode controls the order of fields in the TUI.
func CycleSortMode ¶
CycleSortMode returns the next sort mode in the rotation.
func CycleSortModeReverse ¶
CycleSortModeReverse returns the previous sort mode in the rotation.
type ViewMode ¶
type ViewMode string
ViewMode controls whether we show all fields or only configured ones.
func CycleViewMode ¶
CycleViewMode toggles between ViewAll and ViewConfigured.