syntaxai/tdd.md · main · src / a31_docs_nav.ts
// c31 — model: hierarchical site-nav for the GitBook-style docs
// chrome. Pure data: combines the existing per-section registries
// (sama, guides, blog) into one structure the sidebar walks at
// render-time, plus a flat per-section list the prev/next navigator
// uses to compute neighbours.
import { ALL_SAMA, type SamaDiscipline } from "./a31_sama.ts";
import { ALL_GUIDES, type GuideEntry } from "./a31_guides.ts";
import { ALL_POSTS, type BlogEntry } from "./a31_blog.ts";
export interface DocsNavLink {
href: string;
label: string;
// GitHub raw-edit URL for the source markdown, when applicable.
// null for pages whose body is built inline in c21_app.ts.
editPath: string | null;
}
export interface DocsNavSection {
id: "sama" | "guides" | "blog";
title: string;
rootHref: string;
links: DocsNavLink[];
}
const samaLink = (d: SamaDiscipline): DocsNavLink => ({
href: `/sama/${d.slug}`,
label: `${d.letter} — ${d.title}`,
editPath: `content/sama/${d.slug}.md`,
});
const guideLink = (g: GuideEntry): DocsNavLink => ({
href: `/guides/${g.slug}`,
label: g.title,
editPath: `content/guides/${g.slug}.md`,
});
const blogLink = (p: BlogEntry): DocsNavLink => ({
href: `/blog/${p.slug}`,
label: p.title,
editPath: `content/blog/${p.slug}.md`,
});
export const SITE_NAV: DocsNavSection[] = [
{
id: "sama",
title: "SAMA",
rootHref: "/sama",
links: [
...ALL_SAMA.map(samaLink),
{ href: "/sama/skill", label: "SKILL.md (drop into your agent)", editPath: "content/sama/skill.md" },
{ href: "/sama/verify", label: "verify a public repo", editPath: null },
],
},
{
id: "guides",
title: "Guides",
rootHref: "/guides",
links: ALL_GUIDES.map(guideLink),
},
{
id: "blog",
title: "Blog",
rootHref: "/blog",
links: ALL_POSTS.map(blogLink),
},
];
// Resolve the section + position of a given path. Used by the
// docs layout to select the right sidebar section and to compute
// prev/next neighbours.
export interface ResolvedDocsLocation {
section: DocsNavSection;
index: number;
current: DocsNavLink;
prev: DocsNavLink | null;
next: DocsNavLink | null;
}
export const resolveDocsLocation = (path: string): ResolvedDocsLocation | null => {
for (const section of SITE_NAV) {
const i = section.links.findIndex((l) => l.href === path);
if (i === -1) continue;
return {
section,
index: i,
current: section.links[i]!,
prev: i > 0 ? section.links[i - 1]! : null,
next: i < section.links.length - 1 ? section.links[i + 1]! : null,
};
}
return null;
};