feat: add optional API configuration for custom Anthropic endpoints

Add a new "API Configuration" section in settings for users who use
custom Anthropic-compatible APIs (e.g. via ai-claude-start). Users
can optionally set ANTHROPIC_AUTH_TOKEN and ANTHROPIC_BASE_URL in
CodePilot's settings UI. These are stored in SQLite and injected
into the Claude Code subprocess env only when configured.

Existing authentication methods (claude login, shell env vars) are
not affected - the API config is purely additive.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-06 23:17:49 +08:00
1 parent e4ae2154af
commit 8b27f69a6f
3 files changed
+190 -6

No files matched your search

+64
View File
@@ -0,0 +1,64 @@
import { NextRequest, NextResponse } from 'next/server';
import { getSetting, setSetting } from '@/lib/db';
/**
* CodePilot app-level settings (stored in SQLite, separate from ~/.claude/settings.json).
* Used for API configuration (ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, etc.)
*/
const ALLOWED_KEYS = [
'anthropic_auth_token',
'anthropic_base_url',
];
export async function GET() {
try {
const result: Record<string, string> = {};
for (const key of ALLOWED_KEYS) {
const value = getSetting(key);
if (value !== undefined) {
// Mask token for security (only return last 8 chars)
if (key === 'anthropic_auth_token' && value.length > 8) {
result[key] = '***' + value.slice(-8);
} else {
result[key] = value;
}
}
}
return NextResponse.json({ settings: result });
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to read app settings';
return NextResponse.json({ error: message }, { status: 500 });
}
}
export async function PUT(request: NextRequest) {
try {
const body = await request.json();
const { settings } = body;
if (!settings || typeof settings !== 'object') {
return NextResponse.json({ error: 'Invalid settings data' }, { status: 400 });
}
for (const [key, value] of Object.entries(settings)) {
if (!ALLOWED_KEYS.includes(key)) continue;
const strValue = String(value ?? '').trim();
if (strValue) {
// Don't overwrite token if user sent the masked version back
if (key === 'anthropic_auth_token' && strValue.startsWith('***')) {
continue;
}
setSetting(key, strValue);
} else {
// Empty value = remove the setting
setSetting(key, '');
}
}
return NextResponse.json({ success: true });
} catch (error) {
const message = error instanceof Error ? error.message : 'Failed to save app settings';
return NextResponse.json({ error: message }, { status: 500 });
}
}