task logs: migrate from filesystem to postgresql; refactor sidecars into submodules

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 11:49:39 +00:00
co-authored by Claude Opus 4.6
parent 5129f7827f
commit d88fe3cac7
22 changed files with 621 additions and 545 deletions
+104
View File
@@ -0,0 +1,104 @@
import { join } from 'node:path';
import { homedir } from 'node:os';
import { getState, updateState } from './state';
const PROXY_PORT = Number(process.env.ANTHROPIC_PROXY_PORT ?? '5051');
const ANTHROPIC_API_BASE = 'https://api.anthropic.com';
const CREDENTIALS_PATH = join(homedir(), '.claude', '.credentials.json');
type CredentialsFile = {
claudeAiOauth?: {
accessToken?: string;
};
};
async function readOAuthToken(): Promise<string | null> {
try {
const file = Bun.file(CREDENTIALS_PATH);
if (!(await file.exists())) return null;
const data = (await file.json()) as CredentialsFile;
return data.claudeAiOauth?.accessToken?.trim() || null;
} catch {
return null;
}
}
export function getProxySecret(): string {
return getState().proxySecret;
}
export function ensureProxySecret(): string {
const state = getState();
if (state.proxySecret) return state.proxySecret;
// Generate once, persist forever
const secret = `sk-ant-api03-${crypto.randomUUID()}`;
updateState({ proxySecret: secret });
return secret;
}
export function startAnthropicProxy() {
const secret = ensureProxySecret();
Bun.serve({
port: PROXY_PORT,
hostname: '127.0.0.1',
idleTimeout: 0,
async fetch(req) {
const url = new URL(req.url);
// Validate proxy secret
const incomingKey = req.headers.get('x-api-key');
if (incomingKey !== secret) {
return new Response(JSON.stringify({ error: 'Unauthorized' }), {
status: 401,
headers: { 'Content-Type': 'application/json' },
});
}
// Read fresh OAuth token
const token = await readOAuthToken();
if (!token) {
return new Response(JSON.stringify({ error: 'No OAuth token available' }), {
status: 502,
headers: { 'Content-Type': 'application/json' },
});
}
// Build upstream URL
const upstream = `${ANTHROPIC_API_BASE}${url.pathname}${url.search}`;
// Clone headers, replace proxy secret with real OAuth token
const headers = new Headers(req.headers);
headers.set('x-api-key', token);
headers.delete('host');
// Read request body fully before forwarding
const body = req.body ? await req.arrayBuffer() : null;
// Forward request
const upstreamRes = await fetch(upstream, {
method: req.method,
headers,
body,
});
// Build clean response headers
const resHeaders = new Headers();
for (const [key, value] of upstreamRes.headers) {
const lower = key.toLowerCase();
if (lower === 'content-encoding' || lower === 'content-length' || lower === 'transfer-encoding') continue;
resHeaders.set(key, value);
}
return new Response(upstreamRes.body, {
status: upstreamRes.status,
statusText: upstreamRes.statusText,
headers: resHeaders,
});
},
});
console.log(`[claude:proxy] listening on 127.0.0.1:${PROXY_PORT}`);
}