Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

65 linesCodeBlameRaw
1import type { APIRoute, GetStaticPaths } from "astro";
2import { getCollection } from "astro:content";
3
4import { AGENTS, AGENTS_WITH_TOKEN, type AgentSetup } from "../data/agents";
5import { DIAGRAMS } from "../diagrams";
6import { toMarkdown } from "../diagrams/engine";
7
8/** A diagram, as the text it is drawn from. */
9function diagramMarkdown(name: string): string {
10 const spec = DIAGRAMS[name];
11 if (!spec) throw new Error(`No diagram named "${name}".`);
12 return toMarkdown(spec);
13}
14
15/** The agent toggle, as plain Markdown: each agent's snippet under its name. */
16function agentsMarkdown(agents: AgentSetup[]): string {
17 return agents
18 .map((agent) => {
19 const where = agent.file ? ` (in \`${agent.file}\`)` : "";
20 const then = agent.then ? `\n\n${agent.then}` : "";
21 const fence = "```";
22 return `**${agent.label}**${where}:\n\n${fence}${agent.lang}\n${agent.code}\n${fence}${then}`;
23 })
24 .join("\n\n");
25}
26
27/**
28 * Every page as Markdown, at its path plus `.md`, for "Copy page" and for
29 * agents that read the docs: the title, what it is about, then the page.
30 */
31export const getStaticPaths: GetStaticPaths = async () => {
32 const pages = await getCollection("docs");
33 return pages.map((page) => ({
34 params: { slug: page.id === "" ? "index" : page.id },
35 props: { page },
36 }));
37};
38
39export const GET: APIRoute = ({ props }) => {
40 const { page } = props as { page: Awaited<ReturnType<typeof getCollection<"docs">>>[number] };
41 const { title, description } = page.data;
42 // MDX pages keep their markup; strip imports and leave the rest readable.
43 const body = (page.body ?? "")
44 .replace(/^import .*$/gm, "")
45 // Tabs read as each tab's content under its label in bold.
46 .replace(/^[ \t]*<\/?Tabs[^>]*>[ \t]*\n?/gm, "")
47 .replace(/^[ \t]*<\/TabItem>[ \t]*$/gm, "")
48 .replace(/^([ \t]*)<TabItem label="([^"]+)"[^>]*>[ \t]*$/gm, "$1**$2**\n")
49 .replace(/^([ \t]*)<AgentSetup( variant="token")? \/>$/gm, (_match, indent: string, token?: string) =>
50 agentsMarkdown(token ? AGENTS_WITH_TOKEN : AGENTS)
51 .split("\n")
52 .map((line) => (line ? indent + line : line))
53 .join("\n"),
54 )
55 // A diagram reads as its boxes and arrows, or its numbered steps.
56 .replace(/^([ \t]*)<Diagram name="([^"]+)" \/>$/gm, (_match, indent: string, name: string) =>
57 diagramMarkdown(name)
58 .split("\n")
59 .map((line) => (line ? indent + line : line))
60 .join("\n"),
61 )
62 .trim();
63 const text = `# ${title}\n\n${description ? `> ${description}\n\n` : ""}${body}\n`;
64 return new Response(text, { headers: { "content-type": "text/markdown; charset=utf-8" } });
65};