diff --git a/cmd/heygen/auth.go b/cmd/heygen/auth.go index bce500d..9fdae8b 100644 --- a/cmd/heygen/auth.go +++ b/cmd/heygen/auth.go @@ -1,10 +1,14 @@ package main -import "github.com/spf13/cobra" +import ( + "github.com/spf13/cobra" + + clierrors "github.com/heygen-com/heygen-cli/internal/errors" +) // authGuidance is the single source of truth for how to set up CLI auth. // Referenced by auth_login.go, auth_status.go, and the auth group help below. -const authGuidance = `Three ways to provide your API key: +var authGuidance = `Three ways to provide your API key: 1. Environment variable (current shell only): export HEYGEN_API_KEY= 2. Pipe to auth login (saves to ~/.heygen/credentials): @@ -14,7 +18,7 @@ const authGuidance = `Three ways to provide your API key: When both env var and stored credential are set, the env var takes priority. -Get a key: https://app.heygen.com/settings/api` +Get a key: ` + clierrors.APIKeySettingsURL func newAuthCmd(ctx *cmdContext) *cobra.Command { cmd := newCommandGroup("auth", "Manage authentication") diff --git a/cmd/heygen/auth_status_test.go b/cmd/heygen/auth_status_test.go index a63c4fa..6a4d688 100644 --- a/cmd/heygen/auth_status_test.go +++ b/cmd/heygen/auth_status_test.go @@ -82,7 +82,7 @@ func TestAuthStatus_AuthError_AddsHint(t *testing.T) { if !strings.Contains(res.Stderr, "HEYGEN_API_KEY environment variable") { t.Fatalf("stderr should mention env var source:\n%s", res.Stderr) } - if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") { + if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") { t.Fatalf("stderr should contain key generation URL:\n%s", res.Stderr) } } @@ -124,7 +124,7 @@ func TestAuthStatus_NoKey(t *testing.T) { if !strings.Contains(res.Stderr, "Three ways to provide your API key") { t.Fatalf("stderr = %s, want auth guidance", res.Stderr) } - if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") { + if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") { t.Fatalf("stderr = %s, want key URL in hint", res.Stderr) } } diff --git a/cmd/heygen/context.go b/cmd/heygen/context.go index d7dbe74..8c016eb 100644 --- a/cmd/heygen/context.go +++ b/cmd/heygen/context.go @@ -79,9 +79,9 @@ func enrichAuthHint(cliErr *clierrors.CLIError, source auth.CredentialSource) { credPath := filepath.Join(paths.ConfigDir(), "credentials") switch source { case auth.SourceEnv: - cliErr.Hint = "The HEYGEN_API_KEY environment variable contains an invalid or expired key.\nGenerate a new key: https://app.heygen.com/settings/api" + cliErr.Hint = "The HEYGEN_API_KEY environment variable contains an invalid or expired key.\nGenerate a new key: " + clierrors.APIKeySettingsURL case auth.SourceFile: - cliErr.Hint = fmt.Sprintf("The stored API key (%s) is invalid or expired.\nReplace it: heygen auth login\nGenerate a new key: https://app.heygen.com/settings/api", credPath) + cliErr.Hint = fmt.Sprintf("The stored API key (%s) is invalid or expired.\nReplace it: heygen auth login\nGenerate a new key: %s", credPath, clierrors.APIKeySettingsURL) } } diff --git a/cmd/heygen/context_test.go b/cmd/heygen/context_test.go index ae027b8..31932db 100644 --- a/cmd/heygen/context_test.go +++ b/cmd/heygen/context_test.go @@ -27,7 +27,7 @@ func TestEnrichAuthHint_EnvSource_401(t *testing.T) { if !strings.Contains(res.Stderr, "HEYGEN_API_KEY environment variable") { t.Fatalf("stderr should mention env var source:\n%s", res.Stderr) } - if !strings.Contains(res.Stderr, "app.heygen.com/settings/api") { + if !strings.Contains(res.Stderr, "app.heygen.com/settings?nav=API") { t.Fatalf("stderr should contain key generation URL:\n%s", res.Stderr) } } diff --git a/internal/errors/errors.go b/internal/errors/errors.go index 1c75d5b..e93892f 100644 --- a/internal/errors/errors.go +++ b/internal/errors/errors.go @@ -12,6 +12,8 @@ const ( ExitTimeout = 4 ) +const APIKeySettingsURL = "https://app.heygen.com/settings?nav=API" + // CLIError is the canonical error type for all CLI operations. type CLIError struct { Code string // machine-readable: "auth_error", "not_found", "network_error" @@ -131,7 +133,7 @@ func hintForAPICode(code string) string { case "voice_not_found": return "This voice does not exist. Retrying the same ID is unlikely to help. List voices: heygen voice list" case "insufficient_credit": - return "Check your credit balance: heygen user me get. Purchase API credits: https://app.heygen.com/settings?nav=API" + return "Check your credit balance: heygen user me get. Purchase API credits: " + APIKeySettingsURL case "invalid_parameter": return "Use --request-schema on the command to see expected fields" case "rate_limited":