Files
platform/src/servers/api/server-settings/opencode.ts
T
2026-02-16 19:34:35 +00:00

77 lines
2.8 KiB
TypeScript

import { createRouter } from '../../create-router';
export const opencodeRouter = createRouter();
const GLOBAL_DIRS = ['/usr/local/bin', '/usr/bin'];
const getPaths = async () => {
try {
const proc = Bun.spawn(['which', '-a', 'opencode'], { 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 };
}
};
opencodeRouter.post('/auth/login', async (ctx) => {
try {
Bun.spawn(['opencode', 'auth', 'login'], { stdout: 'ignore', stderr: 'ignore' });
return ctx.json({ started: true });
} catch {
return ctx.json({ started: false, error: 'Failed to start login' }, 500);
}
});
opencodeRouter.get('/auth', async (ctx) => {
try {
const authPath = `${process.env.HOME}/.local/share/opencode/auth.json`;
const file = Bun.file(authPath);
if (!(await file.exists())) return ctx.json({ authenticated: false, providers: [] });
const auth = await file.json();
const providers = Object.keys(auth);
return ctx.json({ authenticated: providers.length > 0, providers });
} catch {
return ctx.json({ authenticated: false, providers: [] });
}
});
opencodeRouter.post('/install', async (ctx) => {
try {
const proc = Bun.spawn(['bash', '-c', 'curl -fsSL https://opencode.ai/install | 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(['opencode', '--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);
}
});
opencodeRouter.get('/version', async (ctx) => {
try {
const proc = Bun.spawn(['opencode', '--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 });
}
});