import './servers/bootstrap'; import type { ServerWebSocket } from 'bun'; import { serve } from 'bun'; import { eq } from 'drizzle-orm'; import { honoServer } from './servers/hono'; import { verify } from './servers/jwt'; import { officerdb, TokenBlacklist } from 'officerdb'; import { claudeWebsocket } from './servers/api/claude/websocket'; import { opencodeWebsocket } from './servers/api/opencode/websocket'; import { terminalWebsocket, initTerminalSidecars } from './servers/api/terminal/websocket'; import officerWeb from './apps/officer-web/index.html'; const { PORT = '5000' } = process.env; type WSData = { userId: number; email: string; role: string; provider: 'claude' | 'opencode' | 'terminal'; sandboxed: boolean; sessionId?: string; }; const handlers: Record = { claude: claudeWebsocket, opencode: opencodeWebsocket, terminal: terminalWebsocket, }; async function upgradeWs(req: Request, server: any, provider: 'claude' | 'opencode' | 'terminal') { const token = new URL(req.url).searchParams.get('token'); if (!token) return new Response('Unauthorized', { status: 401 }); try { const user = await verify(token); if (!user) return new Response('Unauthorized', { status: 401 }); if (user.jti) { const blacklisted = await officerdb.query.TokenBlacklist.findFirst({ where: eq(TokenBlacklist.jti, user.jti), }); if (blacklisted) return new Response('Unauthorized', { status: 401 }); } const url = new URL(req.url); const sessionId = url.searchParams.get('sessionId') ?? undefined; const sandboxed = url.searchParams.get('sandboxed') !== 'false'; const ok = server.upgrade(req, { data: { userId: user.id, email: user.email, role: user.role, provider, sandboxed, sessionId }, }); if (!ok) return new Response('Upgrade failed', { status: 500 }); } catch { return new Response('Unauthorized', { status: 401 }); } } const server = serve({ port: Number(PORT), idleTimeout: 60, maxRequestBodySize: 1024 * 1024 * 1024 * 50, // 50 GB routes: { '/static/*': async (req) => { const path = new URL(req.url).pathname.slice('/static'.length); const file = Bun.file(`public${path}`); if (await file.exists()) return new Response(file); return new Response(null, { status: 404 }); }, '/api/harness/claudecode/ws': (req, server) => upgradeWs(req, server, 'claude'), '/api/harness/opencode/ws': (req, server) => upgradeWs(req, server, 'opencode'), '/api/terminal/ws': (req, server) => upgradeWs(req, server, 'terminal'), '/': officerWeb, '/*': officerWeb, '/api': honoServer.fetch, '/api/*': honoServer.fetch, }, websocket: { open(ws) { const { provider } = (ws as unknown as ServerWebSocket).data; handlers[provider]!.open(ws as any); }, message(ws, raw) { const { provider } = (ws as unknown as ServerWebSocket).data; handlers[provider]!.message(ws as any, raw); }, close(ws) { const { provider } = (ws as unknown as ServerWebSocket).data; handlers[provider]!.close(ws as any); }, drain() {}, }, development: process.env.NODE_ENV !== 'production' && { hmr: true, }, }); console.log(`🚀 Server running at ${server.url}`); void initTerminalSidecars();