summaryrefslogtreecommitdiff
path: root/internal/appconfig
diff options
context:
space:
mode:
Diffstat (limited to 'internal/appconfig')
-rw-r--r--internal/appconfig/app_feature_sections.go7
-rw-r--r--internal/appconfig/app_feature_sections_test.go12
-rw-r--r--internal/appconfig/app_sections.go3
-rw-r--r--internal/appconfig/app_sections_test.go21
-rw-r--r--internal/appconfig/config_features_test.go102
-rw-r--r--internal/appconfig/config_load.go32
-rw-r--r--internal/appconfig/config_merge.go17
-rw-r--r--internal/appconfig/config_types.go38
-rw-r--r--internal/appconfig/feature_sections.go14
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:"-"`