diff --git a/Makefile b/Makefile index 9d5e30d..0811dee 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,7 @@ endif all: build -build: $(GATEWAY_BIN) - -$(GATEWAY_BIN): +build: go build -o $(GATEWAY_BIN) ./cmd/gateway test: diff --git a/internal/config/config.go b/internal/config/config.go index c7fb9b2..613ee9f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -174,8 +174,13 @@ func (c *Config) normalize() { case TargetClaude, TargetCodex: default: // Providers created before targets existed belong to the - // Claude page. - c.Providers[i].Target = TargetClaude + // Claude page, unless they were only ever activated for + // Codex. + if c.Providers[i].EnabledForCodex && !c.Providers[i].EnabledForClaude { + c.Providers[i].Target = TargetCodex + } else { + c.Providers[i].Target = TargetClaude + } } } switch c.Gateway.PortMode { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 5da803d..4ee6d88 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1,6 +1,8 @@ package config import ( + "os" + "path/filepath" "strings" "testing" ) @@ -221,6 +223,42 @@ func TestUpdateProviderKeepsEnabledFlags(t *testing.T) { } } +func TestProviderTargetMigration(t *testing.T) { + home := t.TempDir() + t.Setenv("CROSSRELAY_HOME", home) + legacy := `{ + "version": 1, + "relay_token": "crl_legacy", + "providers": [ + {"id":"p_1","name":"claude-side","base_url":"https://a.example.com/v1","api_key":"sk","models":{"default":"m"},"enabled_for_claude":true,"created_at":"2026-10-01T00:00:00Z"}, + {"id":"p_2","name":"codex-side","base_url":"https://b.example.com/v1","api_key":"sk","models":{"default":"m"},"enabled_for_codex":true,"created_at":"2026-10-01T00:00:00Z"}, + {"id":"p_3","name":"never-active","base_url":"https://c.example.com/v1","api_key":"sk","models":{"default":"m"},"created_at":"2026-10-01T00:00:00Z"} + ], + "gateway": {"port_mode": "auto"}, + "language": "zh-CN" +}` + if err := os.WriteFile(filepath.Join(home, "config.json"), []byte(legacy), 0o600); err != nil { + t.Fatalf("write legacy config: %v", err) + } + store, err := Load() + if err != nil { + t.Fatalf("Load: %v", err) + } + targets := map[string]string{} + for _, p := range store.Config().Providers { + targets[p.Name] = p.Target + } + if targets["claude-side"] != TargetClaude { + t.Errorf("claude-side target = %q, want claude", targets["claude-side"]) + } + if targets["codex-side"] != TargetCodex { + t.Errorf("codex-side target = %q, want codex", targets["codex-side"]) + } + if targets["never-active"] != TargetClaude { + t.Errorf("never-active target = %q, want claude", targets["never-active"]) + } +} + func TestProviderTargetDefaultsAndValidation(t *testing.T) { t.Setenv("CROSSRELAY_HOME", t.TempDir()) store, err := Load()