Wiki Bundle & Pages
- Site
- VersionInfo
- VerificationSummary
- Graph
- Writer
- Page
- Citation
- internal/wiki/html.go
Relevant source files · 3
The internal/wiki package is where astrolabe's work becomes a deliverable. After the agent has written pages, the checker has verified them, and the harness has produced a report, this package turns that content into a bundle: a fully self-contained directory of static files that can be dropped on any web host or consumed directly by an AI agent. The package doc in page.go spells out the layout — index.html, pages/<slug>.md and .html, a src/ source snapshot that citation links resolve against, llms.txt, index.json, verification.json, and assets/style.css. Citations are deliberately plain markdown links of the form [Label](src/<path>#L<start>) or #L<start>-L<end>, so they work on any static host without JavaScript.
How it works
The page model. Everything starts with Page: a title, a type (overview, reference, or guide), a scope, a symbol list, and a markdown body that must contain at least one citation. Page::Normalize fills in derived fields — the slug, derived from the title via Slugify — and validates the frontmatter: non-empty title, a known type, and a markdown heading in the body. Page::Markdown serializes the page back out with YAML frontmatter, and ParsePage parses such a document back in, which is how the checker and writer reload pages from disk.
Citations and links. The citation grammar lives in Citation and the citationRe regex at citationRe. CitationLink renders a citation, and ExtractCitations parses all of them out of a body — the writer uses this both for the manifest's citation count and to decide which files belong in the src/ snapshot. Inter-page links get the same treatment: WikiLink renders a bare <slug>.md link and ExtractWikiLinks parses them back out, while ExtractAllLinks returns every markdown link destination so the verification checker can reject anything it doesn't recognize. SortPages imposes the canonical output order: overview first, then by scope.
The site and the writer. Site is the aggregate the writer emits: the sorted pages, a VersionInfo stamping every page with the commit/tag/branch the bundle was generated from, per-page verification outcomes (VerificationSummary), and an optional Graph — the machine-readable symbol graph serialized to graph.json for the theme's interactive explorer. The Writer carries the output directory, the repo root (for the source snapshot), and an optional SourceURLTemplate that swaps the snapshot for forge links.
Writer::Write is the whole pipeline in one method. It copies and sorts the pages, rejects duplicate slugs, and resolves the source template via sourceTemplate — a template using {commit} without a known commit is a hard error, since it would emit links with an empty ref. Then, for each page, it writes pages/<slug>.md (optionally with rewriteSourceLinks rewriting src/... destinations to forge URLs, and always with a versionFooterMD provenance footer appended by the writer, never the model) and the rendered HTML. When no forge template is set, the writer builds the src/ snapshot by copying every cited file from the repo root, tolerating missing files so one broken page can't fail the whole bundle. Finally it emits the static assets, index.html, and the manifests.
Two details worth noting on link rewriting: CanonicalSourceLinks is the inverse operation — it turns forge URLs matching an expanded template back into canonical src/<path>#L<line> citations, used when reading pages written with a template. And commitURL expands {commit}/{tag} in the footer's link template.
Manifests. Writer::writeManifests produces the machine-readable artifacts: index.json (an indexManifest with one pageEntry per page — slug, type, scope, symbols, citation count, verification status, plus the source_url template when the bundle links to a forge instead of shipping a snapshot), version.json, llms.txt following the llms.txt convention, verification.json verbatim, and graph.json. Verification status per slug comes from statusOf, defaulting to "unknown".
HTML rendering. internal/wiki/html.go renders the human-facing pages with Go's html/template, using the Astrolabe design system's markup so the pages work without JavaScript and are progressively enhanced by the theme's JS bundle. Markdown is converted by a goldmark instance (gm, GFM extensions plus auto heading IDs); mermaid fences are rendered as diagram source with a caption pointing to the Astro theme, which is the only renderer that draws them. Inter-page .md destinations become .html in HTML output via rewriteWikiLinksForHTML. The page shell (newShell) assembles the numbered site nav from navGroups — overviews stand alone, references and guides become numbered groups like "2.1" — plus an "On this page" TOC built from headings, a version menu, and prev/next pager links. Each page also gets a "Sources" listing built by pageSources, which merges a page's citation ranges per file and links into the snapshot or the forge. renderIndexHTML builds the landing page grouped by page type, with citation counts and verification badges per row.
Relationships
graph LR
Agent["internal/agent.Agent"] -- pages --> Site["Site"]
Verify["internal/verify.Checker / Report"] -- verification --> Site["Site"]
GraphProvider["internal/graph.Provider"] -- symbol graph --> Graph["Graph"]
Site --> Writer["Writer::Write"]
Page["Page"] -- Markdown/ExtractCitations --> Writer
Writer -- writes --> Bundle["bundle: index.html, pages/, src/, index.json, llms.txt, graph.json"]
Writer -- renders via --> HTML["internal/wiki/html.go"]
Bundle -- loaded by --> Theme["theme/src/lib/bundle.ts (Astro theme)"]
Bundle -- indexed by --> Search["internal/wiki/search"]
indexManifest -- consumed by --> WebMCP["internal/wiki/webmcp"]The bundle is the contract between the pipeline and every consumer: the Astro Theme & Site Rendering reads it via the bundle loader, Wiki Search indexes its pages, and WebMCP Integration uses index.json and the source_url template to answer agent queries against the shipped site. The Agent Core produces the Page values, and Verification (Checker & Review) supplies the per-page status shown throughout. The design-system markup it emits is documented in Wiki Design System (JS Bundle).
Reference
| Symbol | Kind | What it does | Location |
|---|---|---|---|
Site |
struct | Aggregate of pages, version, verification, and graph for one bundle | internal/wiki/bundle.go#L15-L36 |
VersionInfo |
struct | Source revision (repo/commit/tag/branch) stamped into the bundle | internal/wiki/bundle.go#L39-L45 |
VerificationSummary |
struct | Per-page harness outcome (passed/failed) for index.json |
internal/wiki/bundle.go#L48-L51 |
Graph / GraphNode / GraphEdge |
struct | Machine-readable symbol graph serialized to graph.json | internal/wiki/bundle.go#L55-L76 |
Writer |
struct | Emits the bundle directory (pages, snapshot, HTML, manifests) | internal/wiki/bundle.go#L103-L111 |
Writer::Write |
method | The whole emit pipeline in one call | internal/wiki/bundle.go#L127-L213 |
Writer::writeManifests |
method | Writes index.json, version.json, llms.txt, verification.json, graph.json | internal/wiki/bundle.go#L329-L407 |
rewriteSourceLinks / CanonicalSourceLinks |
function | Forge-URL rewriting of citations, and its inverse | internal/wiki/bundle.go#L232-L269 |
versionFooterMD |
function | Writer-appended per-page provenance footer | internal/wiki/bundle.go#L290-L315 |
Page |
struct | One wiki page: frontmatter fields plus markdown body and slug | internal/wiki/page.go#L42-L54 |
Page::Normalize |
method | Fills slug, validates title/type/body heading | internal/wiki/page.go#L66-L89 |
Page::Markdown / ParsePage |
function | Serialize to / parse from frontmatter markdown | internal/wiki/page.go#L100-L130 |
Citation |
struct | A source reference: label, repo-relative path, 1-based line range | internal/wiki/page.go#L133-L141 |
ExtractCitations |
function | Parses all citation links from a body | internal/wiki/page.go#L154-L170 |
WikiLink / ExtractWikiLinks / ExtractAllLinks |
function | Inter-page links and full link extraction for the checker | internal/wiki/page.go#L176-L200 |
SortPages |
function | Canonical page order: overview first, then by scope | internal/wiki/page.go#L203-L218 |
internal/wiki/html.go |
file | HTML rendering: goldmark, design-system shell, nav, TOC, index page | internal/wiki/html.go#L1-L468 |
Generated by astrolabe from commit ecc180b3 (tag 0.4.0).