refactor: remove CLAUDE_CODE_OAUTH_TOKEN references and update authentication to use ANTHROPIC_API_KEY exclusively

This commit is contained in:
Cody Seibert
2025-12-15 14:33:58 -05:00
parent 54b977ee1b
commit d42857ec26
13 changed files with 21 additions and 88 deletions

View File

@@ -150,21 +150,17 @@ npm run lint
Automaker supports multiple authentication methods (in order of priority):
| Method | Environment Variable | Description |
| -------------------- | ------------------------- | --------------------------------------------------------- |
| OAuth Token (env) | `CLAUDE_CODE_OAUTH_TOKEN` | From `claude setup-token` - uses your Claude subscription |
| OAuth Token (stored) | — | Stored in app credentials file |
| API Key (stored) | — | Anthropic API key stored in app |
| API Key (env) | `ANTHROPIC_API_KEY` | Pay-per-use API key |
**Recommended:** Use `CLAUDE_CODE_OAUTH_TOKEN` if you have a Claude subscription.
| Method | Environment Variable | Description |
| ---------------- | -------------------- | ------------------------------- |
| API Key (env) | `ANTHROPIC_API_KEY` | Anthropic API key |
| API Key (stored) | — | Anthropic API key stored in app |
### Persistent Setup (Optional)
Add to your `~/.bashrc` or `~/.zshrc`:
```bash
export CLAUDE_CODE_OAUTH_TOKEN="YOUR_TOKEN_HERE"
export ANTHROPIC_API_KEY="YOUR_API_KEY_HERE"
```
Then restart your terminal or run `source ~/.bashrc`.

View File

@@ -33,25 +33,15 @@ cd automaker
npm install
```
**Step 3:** Get your Claude subscription token:
**Step 3:** Set your Anthropic API key (optional - you can also enter it in the app's setup wizard):
```bash
claude setup-token
export ANTHROPIC_API_KEY="sk-ant-..."
```
This command will authenticate you via your browser and print a token to your terminal.
Alternatively, you can enter your API key directly in the Automaker setup wizard when you launch the app.
> **⚠️ Warning:** This command will print your token to your terminal. Be careful if you're streaming or sharing your screen, as the token will be visible to anyone watching.
**Step 4:** Export the Claude Code OAuth token in your shell (optional - you can also enter it in the app's setup wizard):
```bash
export CLAUDE_CODE_OAUTH_TOKEN="your-token-here"
```
Alternatively, you can enter your token directly in the Automaker setup wizard when you launch the app.
**Step 5:** Start the development server:
**Step 4:** Start the development server:
```bash
npm run dev:electron

View File

@@ -2,9 +2,6 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "export",
env: {
CLAUDE_CODE_OAUTH_TOKEN: process.env.CLAUDE_CODE_OAUTH_TOKEN || "",
},
};
export default nextConfig;

View File

@@ -11,7 +11,7 @@ export async function POST(request: NextRequest) {
const { apiKey } = await request.json();
// Use provided API key or fall back to environment variable
const effectiveApiKey = apiKey || process.env.ANTHROPIC_API_KEY || process.env.CLAUDE_CODE_OAUTH_TOKEN;
const effectiveApiKey = apiKey || process.env.ANTHROPIC_API_KEY;
if (!effectiveApiKey) {
return NextResponse.json(

View File

@@ -55,9 +55,7 @@ export function AuthenticationStatusDisplay({
<div className="flex items-center gap-2 text-muted-foreground">
<Info className="w-3 h-3 shrink-0" />
<span>
{claudeAuthStatus.method === "oauth_token_env"
? "Using CLAUDE_CODE_OAUTH_TOKEN"
: claudeAuthStatus.method === "oauth_token"
{claudeAuthStatus.method === "oauth_token"
? "Using stored OAuth token (subscription)"
: claudeAuthStatus.method === "api_key_env"
? "Using ANTHROPIC_API_KEY"

View File

@@ -50,30 +50,21 @@ const DATA_DIR = process.env.DATA_DIR || "./data";
const ENABLE_REQUEST_LOGGING = process.env.ENABLE_REQUEST_LOGGING !== "false"; // Default to true
// Check for required environment variables
// Claude Agent SDK supports EITHER OAuth token (subscription) OR API key (pay-per-use)
const hasAnthropicKey = !!process.env.ANTHROPIC_API_KEY;
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
if (!hasAnthropicKey && !hasOAuthToken) {
if (!hasAnthropicKey) {
console.warn(`
╔═══════════════════════════════════════════════════════════════════════╗
║ ⚠️ WARNING: No Claude authentication configured ║
║ ║
║ The Claude Agent SDK requires authentication to function. ║
║ ║
Option 1 - Subscription (OAuth Token):
║ export CLAUDE_CODE_OAUTH_TOKEN="your-oauth-token" ║
║ ║
║ Option 2 - Pay-per-use (API Key): ║
Set your Anthropic API key:
║ export ANTHROPIC_API_KEY="sk-ant-..." ║
║ ║
║ Or use the setup wizard in Settings to configure authentication. ║
╚═══════════════════════════════════════════════════════════════════════╝
`);
} else if (hasOAuthToken) {
console.log(
"[Server] ✓ CLAUDE_CODE_OAUTH_TOKEN detected (subscription auth)"
);
} else {
console.log("[Server] ✓ ANTHROPIC_API_KEY detected (API key auth)");
}

View File

@@ -112,9 +112,7 @@ export class ClaudeProvider extends BaseProvider {
*/
async detectInstallation(): Promise<InstallationStatus> {
// Claude SDK is always available since it's a dependency
const hasAnthropicKey = !!process.env.ANTHROPIC_API_KEY;
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
const hasApiKey = hasAnthropicKey || hasOAuthToken;
const hasApiKey = !!process.env.ANTHROPIC_API_KEY;
const status: InstallationStatus = {
installed: true,

View File

@@ -35,19 +35,9 @@ export function setRunningState(
* Helper to log authentication status
*/
export function logAuthStatus(context: string): void {
const hasOAuthToken = !!process.env.CLAUDE_CODE_OAUTH_TOKEN;
const hasApiKey = !!process.env.ANTHROPIC_API_KEY;
logger.info(`${context} - Auth Status:`);
logger.info(
` CLAUDE_CODE_OAUTH_TOKEN: ${
hasOAuthToken
? "SET (" +
process.env.CLAUDE_CODE_OAUTH_TOKEN?.substring(0, 20) +
"...)"
: "NOT SET"
}`
);
logger.info(
` ANTHROPIC_API_KEY: ${
hasApiKey
@@ -56,7 +46,7 @@ export function logAuthStatus(context: string): void {
}`
);
if (!hasOAuthToken && !hasApiKey) {
if (!hasApiKey) {
logger.warn("⚠️ WARNING: No authentication configured! SDK will fail.");
}
}

View File

@@ -15,9 +15,7 @@ export function createProvidersHandler() {
const providers: Record<string, any> = {
anthropic: {
available: statuses.claude?.installed || false,
hasApiKey:
!!process.env.ANTHROPIC_API_KEY ||
!!process.env.CLAUDE_CODE_OAUTH_TOKEN,
hasApiKey: !!process.env.ANTHROPIC_API_KEY,
},
google: {
available: !!process.env.GOOGLE_API_KEY,

View File

@@ -74,7 +74,6 @@ export async function getClaudeStatus() {
hasStoredOAuthToken: !!getApiKey("anthropic_oauth_token"),
hasStoredApiKey: !!getApiKey("anthropic"),
hasEnvApiKey: !!process.env.ANTHROPIC_API_KEY,
hasEnvOAuthToken: !!process.env.CLAUDE_CODE_OAUTH_TOKEN,
// Additional fields for detailed status
oauthTokenValid: false,
apiKeyValid: false,
@@ -148,11 +147,7 @@ export async function getClaudeStatus() {
}
// Environment variables override stored credentials (higher priority)
if (auth.hasEnvOAuthToken) {
auth.authenticated = true;
auth.oauthTokenValid = true;
auth.method = "oauth_token_env";
} else if (auth.hasEnvApiKey) {
if (auth.hasEnvApiKey) {
auth.authenticated = true;
auth.apiKeyValid = true;
auth.method = "api_key_env"; // API key from ANTHROPIC_API_KEY env var

View File

@@ -31,16 +31,8 @@ export function createStoreApiKeyHandler() {
setApiKey(provider, apiKey);
// Also set as environment variable and persist to .env
// IMPORTANT: OAuth tokens and API keys must be stored separately
// - OAuth tokens (subscription auth) -> CLAUDE_CODE_OAUTH_TOKEN
// - API keys (pay-per-use) -> ANTHROPIC_API_KEY
if (provider === "anthropic_oauth_token") {
// OAuth token from claude setup-token (subscription-based auth)
process.env.CLAUDE_CODE_OAUTH_TOKEN = apiKey;
await persistApiKeyToEnv("CLAUDE_CODE_OAUTH_TOKEN", apiKey);
logger.info("[Setup] Stored OAuth token as CLAUDE_CODE_OAUTH_TOKEN");
} else if (provider === "anthropic") {
// Direct API key (pay-per-use)
if (provider === "anthropic" || provider === "anthropic_oauth_token") {
// Both API key and OAuth token use ANTHROPIC_API_KEY
process.env.ANTHROPIC_API_KEY = apiKey;
await persistApiKeyToEnv("ANTHROPIC_API_KEY", apiKey);
logger.info("[Setup] Stored API key as ANTHROPIC_API_KEY");

View File

@@ -12,7 +12,6 @@ describe("claude-provider.ts", () => {
vi.clearAllMocks();
provider = new ClaudeProvider();
delete process.env.ANTHROPIC_API_KEY;
delete process.env.CLAUDE_CODE_OAUTH_TOKEN;
});
describe("getName", () => {
@@ -254,15 +253,6 @@ describe("claude-provider.ts", () => {
expect(result.authenticated).toBe(true);
});
it("should detect CLAUDE_CODE_OAUTH_TOKEN", async () => {
process.env.CLAUDE_CODE_OAUTH_TOKEN = "oauth-token";
const result = await provider.detectInstallation();
expect(result.hasApiKey).toBe(true);
expect(result.authenticated).toBe(true);
});
it("should return hasApiKey false when no keys present", async () => {
const result = await provider.detectInstallation();

View File

@@ -179,9 +179,8 @@ Routes models that:
#### Authentication
Requires one of:
Requires:
- `ANTHROPIC_API_KEY` environment variable
- `CLAUDE_CODE_OAUTH_TOKEN` environment variable
#### Example Usage
@@ -704,9 +703,8 @@ describe("Provider Integration", () => {
### Claude Provider
```bash
# Required (one of):
# Required:
ANTHROPIC_API_KEY=sk-ant-...
CLAUDE_CODE_OAUTH_TOKEN=...
```
### Codex Provider