// A clean, self-contained HTML page for a Ladder, in the spirit of a
// Claude Artifact: readable typography, light/dark aware, no build step
// or external resources, collapsible nesting via plain so it
// needs no JS at all.
import type { ResolvedRung } from "../../engine/ladderRender.js";
function escapeHtml(s: string): string {
return s.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """);
}
function renderNode(rung: ResolvedRung, depth: number): string {
const sources = rung.sources.length
? `
` : "";
const children = rung.children.map((c) => renderNode(c, depth + 1)).join("");
const header = `${escapeHtml(rung.kind)}${escapeHtml(rung.path)}`;
const body = `
${escapeHtml(rung.summary)}
${sources}${touches}${children ? `
${children}
` : ""}`;
if (depth === 0) {
return `${header}${body}`;
}
// by default so the page reads top-to-bottom like the
// text/JSON forms; a reader can collapse branches they don't care about.
return `${header}${body}`;
}
export function renderHtml(tree: ResolvedRung, meta: { repoSlug: string; generatedAt: string; stats: { rungs: number; notes: number } }): string {
return `
Ladder: ${escapeHtml(meta.repoSlug)}
Ladder: ${escapeHtml(meta.repoSlug)}
${meta.stats.rungs} rungs, from ${meta.stats.notes} git notes. Generated ${escapeHtml(meta.generatedAt)}.