import { Hono } from "hono"; import { rolledUpStats } from "./migrations.js"; import type { Migration } from "./types.js"; export function buildApp(migrations: Migration[]): Hono { const app = new Hono(); app.get("/", (c) => c.html(renderDashboardHtml(migrations))); app.get("/dashboard", (c) => c.html(renderDashboardHtml(migrations))); app.get("/migrations", (c) => c.json({ stats: rolledUpStats(migrations), migrations: migrations.map((m) => ({ id: m.id, repo: m.repo, state: m.state, sourceRuntime: m.sourceRuntime, targetRuntime: m.targetRuntime, turns: m.turns, spentUsd: m.spentUsd, })), }), ); app.get("/migrations/:id", (c) => { const id = c.req.param("id"); const m = migrations.find((x) => x.id === id); if (!m) return c.json({ error: "not_found", id }, 404); return c.json(m); }); return app; } export function renderDashboardHtml(migrations: Migration[]): string { const stats = rolledUpStats(migrations); const rows = migrations .map((m) => { const passedFiles = m.files.filter((f) => f.status === "passed").length; const pct = m.files.length === 0 ? 0 : Math.round((passedFiles / m.files.length) * 100); return [ "
| repo | migration | state | progress | turns | cost | ", "
|---|
Auto-refreshes every 2s. Endpoints: /migrations, /migrations/:id.
", "", "", ].join("\n"); }