import { createRouter } from '../../create-router'; export const claudeCodeRouter = createRouter(); const GLOBAL_DIRS = ['/usr/local/bin', '/usr/bin']; const getPaths = async () => { try { const proc = Bun.spawn(['which', '-a', 'claude'], { stdout: 'pipe', stderr: 'pipe' }); const output = await new Response(proc.stdout).text(); await proc.exited; if (proc.exitCode !== 0) return { path: null, globalPath: null }; const paths = [...new Set(output.trim().split('\n'))]; const path = paths[0] ?? null; const globalPath = paths.find((p) => GLOBAL_DIRS.some((dir) => p.startsWith(dir))) ?? null; return { path, globalPath }; } catch { return { path: null, globalPath: null }; } }; claudeCodeRouter.post('/install', async (ctx) => { try { const proc = Bun.spawn(['bash', '-c', 'curl -fsSL https://claude.ai/install.sh | bash'], { stdout: 'pipe', stderr: 'pipe', }); await proc.exited; if (proc.exitCode !== 0) { const stderr = await new Response(proc.stderr).text(); return ctx.json({ version: null, path: null, globalPath: null, error: stderr.trim() }, 500); } const versionProc = Bun.spawn(['claude', '--version'], { stdout: 'pipe', stderr: 'pipe' }); const output = await new Response(versionProc.stdout).text(); await versionProc.exited; const { path, globalPath } = await getPaths(); return ctx.json({ version: output.trim(), path, globalPath }); } catch { return ctx.json({ version: null, path: null, globalPath: null, error: 'Installation failed' }, 500); } }); claudeCodeRouter.post('/auth/login', async (ctx) => { try { const env = { ...process.env }; delete env.CLAUDECODE; Bun.spawn(['claude', 'auth', 'login'], { stdout: 'ignore', stderr: 'ignore', env }); return ctx.json({ started: true }); } catch { return ctx.json({ started: false, error: 'Failed to start login' }, 500); } }); claudeCodeRouter.get('/auth', async (ctx) => { try { const proc = Bun.spawn(['claude', 'auth', 'status'], { stdout: 'pipe', stderr: 'pipe' }); const output = await new Response(proc.stdout).text(); await proc.exited; if (proc.exitCode !== 0) return ctx.json({ authenticated: false }); const status = JSON.parse(output.trim()); return ctx.json({ authenticated: status.loggedIn ?? false, ...status }); } catch { return ctx.json({ authenticated: false }); } }); claudeCodeRouter.get('/version', async (ctx) => { try { const proc = Bun.spawn(['claude', '--version'], { stdout: 'pipe', stderr: 'pipe' }); const output = await new Response(proc.stdout).text(); await proc.exited; if (proc.exitCode !== 0) return ctx.json({ version: null, path: null, globalPath: null }); const { path, globalPath } = await getPaths(); return ctx.json({ version: output.trim(), path, globalPath }); } catch { return ctx.json({ version: null, path: null, globalPath: null }); } });