Skip to main content

Documentation for assistants

An assistant answering a question about pgToolBox should read the pages of the version the person runs, as plain text, and find the right section by its exact name. Three things on this site and in the console serve that.

Version​

The site documents one version: the release named in charts/pgtoolbox/Chart.yaml, built from main. The navbar links that release's notes.

llms.txt and one Markdown file per page​

The build writes the clean Markdown of each page next to its HTML (/docs/console/tour.md beside /docs/console/tour/; a section's own page is /docs/console/index.md), an llms.txt index and an llms-full.txt with every page in one file. The two files are also served at the site root (/llms.txt, /llms-full.txt).

A page file starts with front matter naming its title, version and canonical url. The body is the page's source with what only a browser needs removed: MDX imports, exports and comments, components rendered to the text they carry (a screenshot becomes its alt text), admonitions turned into a bold label, links to other pages pointing at their .md files. Code fences, Mermaid diagrams included, are kept as they are. A local plugin does this (docs/site/plugins/llms, TypeScript, no dependency, tested by npm test in docs/site).

The console's own documentation​

The console binary embeds the pages of the version it was built for and a prebuilt keyword index over them, so it can answer from the documentation that matches it. The index is BM25 over sections (a ## or ### block is one chunk); there are no embeddings: the pages are exact technical names, which keyword ranking finds better than a model would, and nothing needs a model in the cluster.

The package is internal/console/docsbundle, standard library only:

CallReturns
Search(query string, limit int) []Hitthe best sections: ChunkID, PageTitle, Section, Version, Path, Excerpt, Score. limit defaults to 10 and is capped at 50
Page(path string) (Document, bool)one page (Path, Title, Version, Markdown), by the path it is served at, with or without a trailing slash or .md
Pages() []Documentevery page, in path order
Version() stringthe documentation version, the chart version the console is built with

The tokenizer keeps identifiers findable: history.persistent, InstanceCABundleComplete and cluster-ref each match as a whole and by their parts, and a plural matches its singular. A query that writes an identifier whole weighs it double.

The console's MCP endpoint serves it through its documentation tools and docs:// resources.

make docs-bundle builds the site and writes one file, internal/console/docsbundle/data/bundle.gz: a gzip archive (standard library compress/gzip at its best compression, no file name or time in the header, the files in name order) of the pages of docs/ under pages/ (except this development section, which documents building pgToolBox rather than running it) and of the index, index.bin. It is byte-for-byte reproducible from the same pages with the same Go toolchain (mise.toml pins it). The console decompresses it once, on first use (at start when the MCP endpoint is enabled), and keeps it in memory.

Two budgets bound it, both in internal/console/docsbundle/archive.go, and the generator fails naming the one a site build breaks and by how much:

BudgetBoundsLimit
MaxEmbeddedBytesthe compressed archive: what the docs add to the console binary and image1 MiB
MaxBundleBytesthe archive decompressed: what the console holds in memory once loaded, so the docs cannot grow unchecked behind a good compression ratio4 MiB

The console itself refuses an archive that does not decompress cleanly or inflates past twice MaxBundleBytes: its docs tools are then absent, and it says why at start.

The files are generated and not committed (only data/.keep is, so that go:embed matches on a fresh clone): a committed binary index would make any two pull requests that touch the docs conflict. make docs, part of CI, runs the generator and then loads what it wrote and searches it (make test-docs-bundle), so a site build the console cannot embed fails the pull request. The console image builds the site and the bundle in its own Dockerfile stages, so every image, make images and the release workflow included, carries the documentation of its release. A console built from source without make docs-bundle starts and logs a warning; its MCP endpoint serves everything but the docs tools. The same holds for the tour's screenshots: the site build copies them from ui/e2e/__screenshots__/screens.spec.ts/.