summaryrefslogtreecommitdiff
path: root/internal/slashcommands
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-11 08:49:20 +0300
committerPaul Buetow <paul@buetow.org>2026-06-11 08:49:20 +0300
commita5bd7dd1eb63a2be332ecda50fbeccfe5d5de0a8 (patch)
treede9986add3f31b6af8b00c1cf99c5237416d8ed1 /internal/slashcommands
parent133ef49de26ae251c2c86417f9c673ebc7166f76 (diff)
appconfig: split FeatureConfig into cohesive per-subsystem structs
The FeatureConfig section was a grab-bag mixing five unrelated non-LLM subsystems (ignore filtering, stats, tmux popup editor, tmux action menu, MCP server). Decompose it into named per-subsystem structs (IgnoreConfig, StatsConfig, TmuxEditConfig, TmuxActionConfig, MCPConfig) embedded into FeatureConfig so the subsystem boundaries are explicit. Embedding keeps Go field promotion intact, so existing flat read access (e.g. cfg.MCPPromptsDir) and the JSON/TOML on-disk shape are unchanged; only composite literals that set these leaf fields directly were updated to the nested form. Add fine-grained, defensive-copy section accessors on App (IgnoreSection, StatsSection, TmuxEditSection, TmuxActionSection, MCPSection) so consumers can depend on a single subsystem's config instead of the whole App God-struct. Decouple slashcommands.NewSyncer to accept appconfig.MCPConfig rather than appconfig.App. All tests pass with -race; appconfig coverage 91.5%, total 86.2%. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'internal/slashcommands')
-rw-r--r--internal/slashcommands/syncer.go3
-rw-r--r--internal/slashcommands/syncer_test.go22
2 files changed, 13 insertions, 12 deletions
diff --git a/internal/slashcommands/syncer.go b/internal/slashcommands/syncer.go
index 1268e7b..674b974 100644
--- a/internal/slashcommands/syncer.go
+++ b/internal/slashcommands/syncer.go
@@ -30,7 +30,8 @@ type Syncer struct {
// NewSyncer creates a new syncer and validates the commands directory.
// Returns error if directory cannot be created or is not writable.
-func NewSyncer(cfg appconfig.App) (*Syncer, error) {
+// It depends only on the MCP subsystem config rather than the whole App.
+func NewSyncer(cfg appconfig.MCPConfig) (*Syncer, error) {
if !cfg.MCPSlashCommandSync {
return &Syncer{enabled: false}, nil
}
diff --git a/internal/slashcommands/syncer_test.go b/internal/slashcommands/syncer_test.go
index 01c6d28..b7ffe47 100644
--- a/internal/slashcommands/syncer_test.go
+++ b/internal/slashcommands/syncer_test.go
@@ -13,10 +13,10 @@ import (
func TestNewSyncer_Disabled(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{MCPSlashCommandSync: false},
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{MCPSlashCommandSync: false}},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() with disabled sync failed: %v", err)
}
@@ -28,13 +28,13 @@ func TestNewSyncer_Disabled(t *testing.T) {
func TestNewSyncer_NoDirectory(t *testing.T) {
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: "",
- },
+ }},
}
- _, err := NewSyncer(cfg)
+ _, err := NewSyncer(cfg.MCPSection())
if err == nil {
t.Error("NewSyncer() should fail when directory is not configured")
}
@@ -45,13 +45,13 @@ func TestNewSyncer_CreatesDirectory(t *testing.T) {
testDir := filepath.Join(tmpDir, "test-commands")
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: testDir,
- },
+ }},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() failed: %v", err)
}
@@ -75,13 +75,13 @@ func TestNewSyncer_ExpandsHomeDirectory(t *testing.T) {
defer os.Setenv("HOME", home)
cfg := appconfig.App{
- FeatureConfig: appconfig.FeatureConfig{
+ FeatureConfig: appconfig.FeatureConfig{MCPConfig: appconfig.MCPConfig{
MCPSlashCommandSync: true,
MCPSlashCommandDir: "~/test-commands",
- },
+ }},
}
- syncer, err := NewSyncer(cfg)
+ syncer, err := NewSyncer(cfg.MCPSection())
if err != nil {
t.Fatalf("NewSyncer() failed: %v", err)
}