import "server-only"; import { authenticateRunner, type RunnerIdentity } from "./runners"; /* * The HTTP API that runners (public/vectrum-runner.mjs) talk to. Every request carries the runner's * token as `Authorization: Bearer vrn_…`. * * POST /api/runner/claim { hostname, os, arch, version } → 200 { job } or 204 after waiting a while * POST /api/runner/jobs/:id { steps?, logs?, status? } → { cancelled } */ export const json = (body: unknown, status = 200) => Response.json(body, { status, headers: { "Cache-Control": "no-store" } }); export async function runnerFromRequest(request: Request): Promise { const header = request.headers.get("authorization") ?? ""; const runner = header.startsWith("Bearer ") ? await authenticateRunner(header.slice(7).trim()) : null; if (!runner) return json({ error: "Unknown or expired runner token. Register the runner again in Settings → Runners." }, 401); return runner; } export async function readBody(request: Request) { try { const body: unknown = await request.json(); return typeof body === "object" && body !== null ? (body as Record) : {}; } catch { return {}; } }