Maintaining These Docs
How to keep this site current — conventions, the auto-sync pipelines (plans + tool catalog), the doc-freshness discipline, and the build/deploy rules. Read this before editing pages.
This page is for whoever is editing this site — most often a Leif session Wayne has asked to update a page, sometimes a human with a clone. It exists so the docs keep their shape and don’t rot: the conventions to follow, the parts that are auto-generated (don’t hand-edit those), and the discipline that keeps facts trustworthy.
The golden rules
mainis production. A commit tomaintriggers a Cloudflare Pages build and goes live in a minute or two. Push to a branch for a preview.- Don’t hand-edit generated content. The plans pages and the tool catalog are produced by jobs — edit the source, not the output.
- Date what you touch. When you change an infrastructure page, update its freshness footer (below).
- Verify before you assert. Most facts here are confirmable with a Leif tool. Prefer a quick check over a guess; mark unknowns rather than inventing.
- Don’t bump pinned dependencies casually — see build & deploy.
Repo structure
Content is Markdown/MDX under src/content/docs/, grouped by section folder.
The folder is the URL prefix and the sidebar group:
| Folder | Section | URL |
|---|---|---|
overview/ | Overview | /overview/... |
infrastructure/ | Infrastructure | /infrastructure/... |
patterns/ | Patterns | /patterns/... |
runbooks/ | Runbooks | /runbooks/... |
tools/ | Tools | /tools/... |
plans/ | Plans (auto-synced) | /plans/... |
The sidebar is generated from these folders by
src/layouts/BaseLayout.astro — section order and labels live in the
sectionOrder / sectionLabels arrays there. Adding a new top-level section
means adding it to those arrays, or it lands in a catch-all group at the
bottom.
Writing a page
Every page is Markdown with frontmatter:
---
title: Short Title
description: One sentence — used for the <meta> description and link previews.
order: 3 # position within the section sidebar (index pages sort first)
---
Conventions to match:
- Voice. Dry, concise, direct. Lead with the answer. Surface the gotcha early. Don’t pad. (It’s the house style — read any existing page.)
- Callouts. Use a
:::callout…:::block for the one thing a reader must not miss. This renders as a styled aside viaremark-directive(wired inastro.config.mjs+src/remark-callout.mjs). The literal:::calloutspelling matters — a space (::: callout) will not render. - Cross-link. End with a
## Related pageslist. Link liberally between tools ⇄ patterns ⇄ runbooks ⇄ infrastructure — the cross-links are most of what makes the site usable. - Tables and code. Tables for param/field references; fenced code for tool
calls and signatures. Escape literal
|inside tables.
New-page checklist
- File in the right section folder, with
title/description/order - Voice and structure match the neighbouring pages
-
:::calloutfor the key caveat (correct spelling) -
## Related pageswith at least a couple of links, and inbound links added from related pages so it’s discoverable -
npm run buildpasses, no broken internal links - Committed to
main(or a preview branch) with a clear message
Auto-synced & generated content
Two parts of the site are produced by jobs. Editing the output directly is pointless — it gets overwritten.
Plans (auto-synced)
The Plans pages mirror superhitech/leif:docs/plans/. A scheduled
Leif job, leif-docs-plans-sync (daily ~06
.md files,
adds the standard frontmatter, and commits changes here. Edit a plan in the
Leif repo, not on this site — a manual edit to a synced plan page is
transient. (list_scheduled_jobs() shows the job.)
The tool catalog (generated)
/tools/catalog/ is generated from the live FastMCP tool
schemas. The pipeline:
- Introspection (Leif side). A job introspects the running FastMCP server
and writes
scripts/tools-catalog.json(the JSON contract is documented at the top ofscripts/generate-tool-catalog.mjs). - Generation (this repo).
npm run gen:toolsreads that JSON and writessrc/content/docs/tools/catalog.md. Aprebuildhook runs it automatically, so Cloudflare regenerates on every deploy.
When a tool is added, renamed, or its signature changes:
- The generated catalog updates itself once
scripts/tools-catalog.jsonis refreshed (by the introspection job, or by hand for a quick fix). - The curated namespace page (e.g.
/tools/cwa/) is hand-written prose and must be updated by hand — that’s where the gotchas and examples live. Keep its signatures in step with the server.
Doc freshness
Infrastructure facts drift. Each infrastructure page carries a dated footer so staleness is visible:
---
*Last verified against live systems: YYYY-MM-DD — see [doc freshness](/infrastructure/#doc-freshness).*
- “reviewed” = read through and looked correct on that date.
- “verified” = the values were re-checked against the live source.
When you touch one of these pages, update the date. Better, verify and use the verified wording — most facts are one tool call away:
| To confirm… | Use |
|---|---|
| Proxmox node / guests / storage | pve_node_status, pve_lxc_list, pve_vm_list, pve_storage_list |
| A container’s IP | pve_lxc_exec(node="pve", vmid=N, command="hostname -I") |
| UniFi fleet | unifi_status |
| DNS / zones / SSL | cf_list_zones, cf_list_dns_records, cf_get_ssl_mode |
| Anything on a host | the host’s shell tool (local_* / remote_* / shtops_* / pve_lxc_exec) |
| RS customer IDs / records | repairshopr_get |
Build & deploy
- Local:
npm installthennpm run dev(→http://localhost:4321). - Build:
npm run build. Theprebuildhook regenerates the tool catalog first. Always build before pushing — a bad page fails the Cloudflare build and blocks the deploy (see Docs site deploy failure). - Deploy: commit to
main→ Cloudflare Pages builds and publishes. No manual step. - Dependencies are pinned on purpose (Astro 5.18 / Zod v4 / Starlight 0.30 incompatibility). Don’t bump without a local build passing first.
Editing through Leif
Most edits happen via Leif’s github_* tools rather than a clone:
github_get_file/github_search_codeto read and findgithub_create_or_update_fileto write (commit message required) — writing tobranch="main"deploysgithub_batch_move_filesto reorganize in one commit
See github and Cloudflare Pages Deploys.
Related pages
- Getting Started — the first-session runbook
- Cloudflare Pages Deploys — the build/deploy pipeline in depth
- Docs site deploy failure — when a build breaks
- Tools — the catalog and the generator pipeline
- Plans — the auto-synced section