diff options
Diffstat (limited to 'internal/appconfig')
| -rw-r--r-- | internal/appconfig/app_feature_sections.go | 7 | ||||
| -rw-r--r-- | internal/appconfig/app_feature_sections_test.go | 12 | ||||
| -rw-r--r-- | internal/appconfig/app_sections.go | 3 | ||||
| -rw-r--r-- | internal/appconfig/app_sections_test.go | 21 | ||||
| -rw-r--r-- | internal/appconfig/config_features_test.go | 102 | ||||
| -rw-r--r-- | internal/appconfig/config_load.go | 32 | ||||
| -rw-r--r-- | internal/appconfig/config_merge.go | 17 | ||||
| -rw-r--r-- | internal/appconfig/config_types.go | 38 | ||||
| -rw-r--r-- | internal/appconfig/feature_sections.go | 14 |
9 files changed, 4 insertions, 242 deletions
diff --git a/internal/appconfig/app_feature_sections.go b/internal/appconfig/app_feature_sections.go index 2513946..da944d3 100644 --- a/internal/appconfig/app_feature_sections.go +++ b/internal/appconfig/app_feature_sections.go @@ -20,13 +20,6 @@ func (a *App) StatsSection() StatsConfig { return a.StatsConfig } -// TmuxEditSection returns a copy of the tmux popup editor settings. -func (a *App) TmuxEditSection() TmuxEditConfig { - c := a.TmuxEditConfig - c.TmuxEditAgents = append([]TmuxEditAgentCfg{}, a.TmuxEditAgents...) - return c -} - // TmuxActionSection returns a copy of the tmux action menu settings. func (a *App) TmuxActionSection() TmuxActionConfig { c := a.TmuxActionConfig diff --git a/internal/appconfig/app_feature_sections_test.go b/internal/appconfig/app_feature_sections_test.go index 1f9ac2d..b217146 100644 --- a/internal/appconfig/app_feature_sections_test.go +++ b/internal/appconfig/app_feature_sections_test.go @@ -33,18 +33,6 @@ func TestStatsSectionReads(t *testing.T) { } } -func TestTmuxEditSectionCopies(t *testing.T) { - cfg := buildFeatureApp() - got := cfg.TmuxEditSection() - if got.TmuxEditDefaultAgent != "codex" || len(got.TmuxEditAgents) != 1 { - t.Fatalf("unexpected tmux edit section: %+v", got) - } - got.TmuxEditAgents[0].Name = "mutated" - if cfg.TmuxEditAgents[0].Name == "mutated" { - t.Fatal("TmuxEditSection did not return a defensive copy") - } -} - func TestTmuxActionSectionCopies(t *testing.T) { cfg := App{} cfg.TmuxActionMenu = []TmuxActionMenuEntry{{Kind: "rewrite"}} diff --git a/internal/appconfig/app_sections.go b/internal/appconfig/app_sections.go index 5919db1..afa7bf0 100644 --- a/internal/appconfig/app_sections.go +++ b/internal/appconfig/app_sections.go @@ -111,7 +111,6 @@ type PromptConfig struct { type FeatureConfig struct { StatsConfig // usage statistics window IgnoreConfig // gitignore-aware file filtering for LSP - TmuxEditConfig // popup editor settings for hexai-tmux-edit TmuxActionConfig // configurable main menu for hexai-tmux-action MCPConfig // Model Context Protocol server settings } @@ -200,7 +199,6 @@ func (a *App) ApplyPromptSection(prompts PromptConfig) { func (a *App) FeatureSection() FeatureConfig { f := a.FeatureConfig f.IgnoreExtraPatterns = slices.Clone(a.IgnoreExtraPatterns) - f.TmuxEditAgents = append([]TmuxEditAgentCfg{}, a.TmuxEditAgents...) f.TmuxActionMenu = append([]TmuxActionMenuEntry{}, a.TmuxActionMenu...) return f } @@ -210,6 +208,5 @@ func (a *App) FeatureSection() FeatureConfig { func (a *App) ApplyFeatureSection(features FeatureConfig) { a.FeatureConfig = features a.IgnoreExtraPatterns = slices.Clone(features.IgnoreExtraPatterns) - a.TmuxEditAgents = append([]TmuxEditAgentCfg{}, features.TmuxEditAgents...) a.TmuxActionMenu = append([]TmuxActionMenuEntry{}, features.TmuxActionMenu...) } diff --git a/internal/appconfig/app_sections_test.go b/internal/appconfig/app_sections_test.go index bcd1cbe..2ff002d 100644 --- a/internal/appconfig/app_sections_test.go +++ b/internal/appconfig/app_sections_test.go @@ -28,7 +28,6 @@ func TestSectionsDefensiveCopies(t *testing.T) { sections.Providers.CLIConfigs[0].Model = "mutated" sections.Prompts.CustomActions[0].Title = "mutated" sections.Features.IgnoreExtraPatterns[0] = "mutated" - sections.Features.TmuxEditAgents[0].Name = "mutated" assertNotEqual(t, cfg.TriggerCharacters[0], "mutated", "trigger characters") assertNotEqual(t, cfg.ChatPrefixes[0], "mutated", "chat prefixes") @@ -36,7 +35,6 @@ func TestSectionsDefensiveCopies(t *testing.T) { assertNotEqual(t, cfg.CLIConfigs[0].Model, "mutated", "cli configs") assertNotEqual(t, cfg.CustomActions[0].Title, "mutated", "custom actions") assertNotEqual(t, cfg.IgnoreExtraPatterns[0], "mutated", "ignore patterns") - assertNotEqual(t, cfg.TmuxEditAgents[0].Name, "mutated", "tmux agents") out := cfg.Sections() out.Core.TriggerCharacters[0] = "mutated" @@ -45,7 +43,6 @@ func TestSectionsDefensiveCopies(t *testing.T) { out.Providers.CLIConfigs[0].Model = "mutated" out.Prompts.CustomActions[0].Title = "mutated" out.Features.IgnoreExtraPatterns[0] = "mutated" - out.Features.TmuxEditAgents[0].Name = "mutated" assertNotEqual(t, cfg.TriggerCharacters[0], "mutated", "sections trigger characters") assertNotEqual(t, cfg.ChatPrefixes[0], "mutated", "sections chat prefixes") @@ -53,7 +50,6 @@ func TestSectionsDefensiveCopies(t *testing.T) { assertNotEqual(t, cfg.CLIConfigs[0].Model, "mutated", "sections cli configs") assertNotEqual(t, cfg.CustomActions[0].Title, "mutated", "sections custom actions") assertNotEqual(t, cfg.IgnoreExtraPatterns[0], "mutated", "sections ignore patterns") - assertNotEqual(t, cfg.TmuxEditAgents[0].Name, "mutated", "sections tmux agents") } func assertNotEqual(t *testing.T, got, want, field string) { @@ -175,23 +171,6 @@ func testFeatureConfig() FeatureConfig { IgnoreExtraPatterns: []string{"vendor/**", "tmp/**"}, IgnoreLSPNotify: sectionBoolPtr(false), }, - TmuxEditConfig: TmuxEditConfig{ - TmuxEditPopupWidth: "80%", - TmuxEditPopupHeight: "75%", - TmuxEditDefaultAgent: "codex", - TmuxEditAgents: []TmuxEditAgentCfg{{ - Name: "codex", - DisplayName: "Codex", - DetectPattern: "(?i)codex", - SectionPattern: "section", - PromptPattern: "prompt", - StripPatterns: []string{"x", "y"}, - ClearFirst: sectionBoolPtr(true), - ClearKeys: "C-u", - NewlineKeys: "S-Enter", - SubmitKeys: "Enter", - }}, - }, MCPConfig: MCPConfig{ MCPPromptsDir: ".hexai/prompts", MCPSlashCommandSync: true, diff --git a/internal/appconfig/config_features_test.go b/internal/appconfig/config_features_test.go index 2b8c769..3d94c77 100644 --- a/internal/appconfig/config_features_test.go +++ b/internal/appconfig/config_features_test.go @@ -1,4 +1,4 @@ -// Tests for ignore config, tmux-edit config, and low-level parsing helpers +// Tests for ignore config and low-level parsing helpers // (temperature, model entries, surface entries, resolved model). package appconfig @@ -119,106 +119,6 @@ gitignore = false } } -func TestTmuxEditConfig_FromFile(t *testing.T) { - clearHexaiEnv(t) - dir := t.TempDir() - cfgPath := filepath.Join(dir, "config.toml") - writeFile(t, cfgPath, ` -[tmux_edit] -popup_width = "90%" -popup_height = "85%" -default_agent = "claude" - -[[tmux_edit.agents]] -name = "claude" -display_name = "Claude Code" -detect_pattern = "(?i)(claude|anthropic)" -prompt_pattern = '(?s)>\s*(.+?)$' -clear_first = true -clear_keys = "C-u" -newline_keys = "S-Enter" -submit_keys = "Enter" - -[[tmux_edit.agents]] -name = "cursor" -display_name = "Cursor" -detect_pattern = "(?i)cursor" -prompt_pattern = '(?s)│\s*(.+?)$' -strip_patterns = ["INSERT", "Add a follow-up"] -clear_first = true -clear_keys = "C-u" -newline_keys = "S-Enter" -submit_keys = "Enter" -`) - cfg := LoadWithOptions(context.Background(), newLogger(), LoadOptions{ConfigPath: cfgPath, ProjectRoot: dir}) - if cfg.TmuxEditPopupWidth != "90%" { - t.Errorf("PopupWidth = %q, want 90%%", cfg.TmuxEditPopupWidth) - } - if cfg.TmuxEditPopupHeight != "85%" { - t.Errorf("PopupHeight = %q, want 85%%", cfg.TmuxEditPopupHeight) - } - if cfg.TmuxEditDefaultAgent != "claude" { - t.Errorf("DefaultAgent = %q, want claude", cfg.TmuxEditDefaultAgent) - } - if len(cfg.TmuxEditAgents) != 2 { - t.Fatalf("got %d agents, want 2", len(cfg.TmuxEditAgents)) - } - a := cfg.TmuxEditAgents[0] - if a.Name != "claude" || a.DisplayName != "Claude Code" { - t.Errorf("agent[0] = %q/%q, want claude/Claude Code", a.Name, a.DisplayName) - } - if a.ClearFirst == nil || !*a.ClearFirst { - t.Error("expected ClearFirst = true for claude agent") - } - b := cfg.TmuxEditAgents[1] - if b.Name != "cursor" { - t.Errorf("agent[1].Name = %q, want cursor", b.Name) - } - if len(b.StripPatterns) != 2 { - t.Errorf("agent[1].StripPatterns = %v, want 2 entries", b.StripPatterns) - } -} - -func TestTmuxEditConfig_Merge(t *testing.T) { - clearHexaiEnv(t) - a := newDefaultConfig() - b := App{ - FeatureConfig: FeatureConfig{TmuxEditConfig: TmuxEditConfig{ - TmuxEditPopupWidth: "70%", - TmuxEditDefaultAgent: "amp", - TmuxEditAgents: []TmuxEditAgentCfg{ - {Name: "amp", DisplayName: "Amp"}, - }, - }}, - } - a.mergeWith(&b) - if a.TmuxEditPopupWidth != "70%" { - t.Errorf("PopupWidth = %q, want 70%%", a.TmuxEditPopupWidth) - } - if a.TmuxEditDefaultAgent != "amp" { - t.Errorf("DefaultAgent = %q, want amp", a.TmuxEditDefaultAgent) - } - if len(a.TmuxEditAgents) != 1 || a.TmuxEditAgents[0].Name != "amp" { - t.Errorf("Agents = %v, want single amp", a.TmuxEditAgents) - } -} - -func TestTmuxEditConfig_SkipsEmptyName(t *testing.T) { - clearHexaiEnv(t) - dir := t.TempDir() - cfgPath := filepath.Join(dir, "config.toml") - writeFile(t, cfgPath, ` -[tmux_edit] -[[tmux_edit.agents]] -name = "" -display_name = "Empty" -`) - cfg := LoadWithOptions(context.Background(), newLogger(), LoadOptions{ConfigPath: cfgPath, ProjectRoot: dir}) - if len(cfg.TmuxEditAgents) != 0 { - t.Errorf("got %d agents, want 0 (empty name should be skipped)", len(cfg.TmuxEditAgents)) - } -} - // --- Config Parsing Tests --- func TestParseTemperatureValue(t *testing.T) { diff --git a/internal/appconfig/config_load.go b/internal/appconfig/config_load.go index ccbf49f..052050b 100644 --- a/internal/appconfig/config_load.go +++ b/internal/appconfig/config_load.go @@ -296,7 +296,6 @@ func applyPromptSections(fc *fileConfig, out *App) { func applyFeatureSections(fc *fileConfig, out *App) { applyTmuxSection(fc, out) applyStatsSection(fc, out) - fc.applyTmuxEdit(out) applyMCPSection(fc, out) applyTmuxActionSection(fc, out) } @@ -564,37 +563,6 @@ func setIfNotBlank(dst *string, value string) { } } -// applyTmuxEdit converts the [tmux_edit] section into App fields. -func (fc *fileConfig) applyTmuxEdit(out *App) { - te := fc.TmuxEdit - if strings.TrimSpace(te.PopupWidth) != "" { - out.TmuxEditPopupWidth = strings.TrimSpace(te.PopupWidth) - } - if strings.TrimSpace(te.PopupHeight) != "" { - out.TmuxEditPopupHeight = strings.TrimSpace(te.PopupHeight) - } - if strings.TrimSpace(te.DefaultAgent) != "" { - out.TmuxEditDefaultAgent = strings.TrimSpace(te.DefaultAgent) - } - for _, a := range te.Agents { - if strings.TrimSpace(a.Name) == "" { - continue - } - out.TmuxEditAgents = append(out.TmuxEditAgents, TmuxEditAgentCfg{ - Name: strings.TrimSpace(a.Name), - DisplayName: strings.TrimSpace(a.DisplayName), - DetectPattern: strings.TrimSpace(a.DetectPattern), - SectionPattern: strings.TrimSpace(a.SectionPattern), - PromptPattern: strings.TrimSpace(a.PromptPattern), - StripPatterns: a.StripPatterns, - ClearFirst: a.ClearFirst, - ClearKeys: strings.TrimSpace(a.ClearKeys), - NewlineKeys: strings.TrimSpace(a.NewlineKeys), - SubmitKeys: strings.TrimSpace(a.SubmitKeys), - }) - } -} - func parseSurfaceModels(raw map[string]any, logger *log.Logger) *App { modelsRaw, ok := raw["models"] if !ok { diff --git a/internal/appconfig/config_merge.go b/internal/appconfig/config_merge.go index f3557c1..e5ad6a5 100644 --- a/internal/appconfig/config_merge.go +++ b/internal/appconfig/config_merge.go @@ -10,7 +10,6 @@ func (a *App) mergeWith(other *App) { a.mergeProviderFields(other) a.mergeSurfaceModels(other) a.mergePrompts(other) - a.mergeTmuxEdit(other) a.mergeTmuxAction(other) } @@ -237,19 +236,3 @@ func (a *App) mergeTmuxAction(other *App) { a.TmuxActionMenu = append([]TmuxActionMenuEntry{}, other.TmuxActionMenu...) } } - -// mergeTmuxEdit copies non-empty tmux edit settings from other. -func (a *App) mergeTmuxEdit(other *App) { - if s := strings.TrimSpace(other.TmuxEditPopupWidth); s != "" { - a.TmuxEditPopupWidth = s - } - if s := strings.TrimSpace(other.TmuxEditPopupHeight); s != "" { - a.TmuxEditPopupHeight = s - } - if s := strings.TrimSpace(other.TmuxEditDefaultAgent); s != "" { - a.TmuxEditDefaultAgent = s - } - if len(other.TmuxEditAgents) > 0 { - a.TmuxEditAgents = append([]TmuxEditAgentCfg{}, other.TmuxEditAgents...) - } -} diff --git a/internal/appconfig/config_types.go b/internal/appconfig/config_types.go index 7069b21..8b046e6 100644 --- a/internal/appconfig/config_types.go +++ b/internal/appconfig/config_types.go @@ -48,21 +48,6 @@ type TmuxActionMenuEntry struct { Hotkey string // optional single-character hotkey override } -// TmuxEditAgentCfg describes an AI agent's detection and interaction patterns -// for the tmux popup editor (hexai-tmux-edit). -type TmuxEditAgentCfg struct { - Name string - DisplayName string - DetectPattern string - SectionPattern string - PromptPattern string - StripPatterns []string - ClearFirst *bool - ClearKeys string - NewlineKeys string - SubmitKeys string -} - // LoadOptions tune how configuration is loaded at runtime. type LoadOptions struct { // IgnoreEnv skips applying environment overrides when true. @@ -170,7 +155,6 @@ type fileConfig struct { Tmux sectionTmux `toml:"tmux"` Stats sectionStats `toml:"stats"` Ignore sectionIgnore `toml:"ignore"` - TmuxEdit sectionTmuxEdit `toml:"tmux_edit"` TmuxAction sectionTmuxAction `toml:"tmux_action"` MCP sectionMCP `toml:"mcp"` } @@ -225,28 +209,6 @@ type sectionIgnore struct { LSPNotifyIgnored *bool `toml:"lsp_notify_ignored"` } -// sectionTmuxEdit configures the tmux popup editor feature (hexai-tmux-edit). -type sectionTmuxEdit struct { - PopupWidth string `toml:"popup_width"` - PopupHeight string `toml:"popup_height"` - DefaultAgent string `toml:"default_agent"` - Agents []sectionTmuxEditAgent `toml:"agents"` -} - -// sectionTmuxEditAgent defines detection and interaction patterns for one AI agent. -type sectionTmuxEditAgent struct { - Name string `toml:"name"` - DisplayName string `toml:"display_name"` - DetectPattern string `toml:"detect_pattern"` - SectionPattern string `toml:"section_pattern"` - PromptPattern string `toml:"prompt_pattern"` - StripPatterns []string `toml:"strip_patterns"` - ClearFirst *bool `toml:"clear_first"` - ClearKeys string `toml:"clear_keys"` - NewlineKeys string `toml:"newline_keys"` - SubmitKeys string `toml:"submit_keys"` -} - // sectionMCP configures the MCP server settings. type sectionMCP struct { PromptsDir string `toml:"prompts_dir"` diff --git a/internal/appconfig/feature_sections.go b/internal/appconfig/feature_sections.go index 9216400..b4010b8 100644 --- a/internal/appconfig/feature_sections.go +++ b/internal/appconfig/feature_sections.go @@ -1,9 +1,9 @@ package appconfig // This file defines the cohesive per-subsystem config structs that make up -// FeatureConfig. The old FeatureConfig was a grab-bag that mixed five unrelated -// non-LLM subsystems (ignore filtering, stats, tmux popup editor, tmux action -// menu, MCP server). Splitting them into named structs documents the seams +// FeatureConfig. The old FeatureConfig was a grab-bag that mixed four unrelated +// non-LLM subsystems (ignore filtering, stats, tmux action menu, MCP server). +// Splitting them into named structs documents the seams // between subsystems and lets consumers depend on a single subsystem's config // (via the *Section accessors on App) instead of the whole App God-struct. // @@ -29,14 +29,6 @@ type StatsConfig struct { StatsWindowMinutes int `json:"-"` } -// TmuxEditConfig configures the tmux popup editor feature (hexai-tmux-edit). -type TmuxEditConfig struct { - TmuxEditPopupWidth string `json:"-"` - TmuxEditPopupHeight string `json:"-"` - TmuxEditDefaultAgent string `json:"-"` - TmuxEditAgents []TmuxEditAgentCfg `json:"-"` -} - // TmuxActionConfig configures the main menu for hexai-tmux-action. type TmuxActionConfig struct { TmuxActionMenu []TmuxActionMenuEntry `json:"-"` |
