diff --git a/internal/commands/cobra.go b/internal/commands/cobra.go index be79a10..988e7b9 100644 --- a/internal/commands/cobra.go +++ b/internal/commands/cobra.go @@ -2,11 +2,11 @@ package commands import ( "os/exec" + "strings" "github.com/spf13/cobra" "codes/internal/ui" - "strings" ) // InitCmd represents the init command diff --git a/internal/commands/commands.go b/internal/commands/commands.go index f2ddc82..1b31cd4 100644 --- a/internal/commands/commands.go +++ b/internal/commands/commands.go @@ -984,7 +984,7 @@ func runClaudeInDirectory(dir string) { } // Set environment variables - config.SetEnvironmentVarsWithConfig(&selectedConfig, cfg) + config.SetEnvironmentVarsWithConfig(&selectedConfig) ui.ShowInfo("Using configuration: %s", selectedConfig.Name) ui.ShowInfo("Working directory: %s", dir) @@ -1187,7 +1187,7 @@ func RunConfigSet(key, value string) { cfg.DefaultBehavior = value ui.ShowSuccess("Default behavior set to: %s", value) default: - ui.ShowError("Unknown configuration key: %s", nil) + ui.ShowError(fmt.Sprintf("Unknown configuration key: %s", key), nil) fmt.Printf("Available keys: defaultBehavior\n") return } @@ -1213,7 +1213,7 @@ func RunConfigGet(args []string) { case "defaultBehavior": fmt.Printf("%s: %s\n", key, cfg.DefaultBehavior) default: - ui.ShowError("Unknown configuration key: %s", nil) + ui.ShowError(fmt.Sprintf("Unknown configuration key: %s", key), nil) fmt.Printf("Available keys: defaultBehavior\n") return } diff --git a/internal/config/config.go b/internal/config/config.go index 178e487..0df785b 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,13 +1,12 @@ package config import ( + "bytes" "encoding/json" "fmt" - "log" "net/http" "os" "path/filepath" - "strings" "time" ) @@ -27,6 +26,43 @@ type APIConfig struct { Status string `json:"status,omitempty"` // "active", "inactive", "unknown" } +// UnmarshalJSON implements custom JSON unmarshaling for APIConfig to support +// backward compatibility with the old flat config format where ANTHROPIC_BASE_URL +// and ANTHROPIC_AUTH_TOKEN were top-level fields instead of nested under "env". +func (a *APIConfig) UnmarshalJSON(data []byte) error { + // Use an alias to avoid infinite recursion + type Alias APIConfig + aux := &struct { + *Alias + // Legacy flat fields from old config format + AnthropicBaseURL string `json:"ANTHROPIC_BASE_URL"` + AnthropicAuthToken string `json:"ANTHROPIC_AUTH_TOKEN"` + }{ + Alias: (*Alias)(a), + } + + if err := json.Unmarshal(data, aux); err != nil { + return err + } + + // Migrate legacy flat fields into the env map + if a.Env == nil { + a.Env = make(map[string]string) + } + if aux.AnthropicBaseURL != "" { + if _, exists := a.Env["ANTHROPIC_BASE_URL"]; !exists { + a.Env["ANTHROPIC_BASE_URL"] = aux.AnthropicBaseURL + } + } + if aux.AnthropicAuthToken != "" { + if _, exists := a.Env["ANTHROPIC_AUTH_TOKEN"]; !exists { + a.Env["ANTHROPIC_AUTH_TOKEN"] = aux.AnthropicAuthToken + } + } + + return nil +} + var ConfigPath string func init() { @@ -98,18 +134,27 @@ func TestAPIConfig(config APIConfig) bool { } // 构建测试请求体 - testBody := fmt.Sprintf(`{ - "model": "%s", - "max_tokens": 10, - "messages": [ - { - "role": "user", - "content": "Hello" - } - ] - }`, model) + type testMessage struct { + Role string `json:"role"` + Content string `json:"content"` + } + type testRequest struct { + Model string `json:"model"` + MaxTokens int `json:"max_tokens"` + Messages []testMessage `json:"messages"` + } + + reqBody := testRequest{ + Model: model, + MaxTokens: 10, + Messages: []testMessage{{Role: "user", Content: "Hello"}}, + } + bodyBytes, err := json.Marshal(reqBody) + if err != nil { + return false + } - req, err := http.NewRequest("POST", apiURL, strings.NewReader(testBody)) + req, err := http.NewRequest("POST", apiURL, bytes.NewReader(bodyBytes)) if err != nil { return false } @@ -310,15 +355,15 @@ func GetEnvironmentVars(apiConfig *APIConfig) map[string]string { // SetEnvironmentVars 设置环境变量到当前进程 func SetEnvironmentVars(apiConfig *APIConfig) { - SetEnvironmentVarsWithConfig(apiConfig, nil) + SetEnvironmentVarsWithConfig(apiConfig) } // SetEnvironmentVarsWithConfig 使用已加载的配置设置环境变量 -func SetEnvironmentVarsWithConfig(apiConfig *APIConfig, cfg *Config) { +func SetEnvironmentVarsWithConfig(apiConfig *APIConfig) { envVars := GetEnvironmentVars(apiConfig) for key, value := range envVars { if err := os.Setenv(key, value); err != nil { - log.Printf("Warning: Failed to set environment variable %s: %v", key, err) + fmt.Fprintf(os.Stderr, "Warning: Failed to set environment variable %s: %v\n", key, err) } } }