Skip to content

feat(website): generate llms.txt and llms-full.txt#3179

Open
vpetersson wants to merge 1 commit into
masterfrom
feat/website-llms-txt
Open

feat(website): generate llms.txt and llms-full.txt#3179
vpetersson wants to merge 1 commit into
masterfrom
feat/website-llms-txt

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Issues Fixed

No associated issue. Adds LLM-discovery files to the marketing site and fixes a rendering bug on the /api page found along the way.

Description

Adds a post-build generator (website/scripts/generate-llms.ts) that produces two files served from the site root, following the llmstxt.org convention:

  • /llms.txt — a curated index: H1, a > summary, and annotated links to every page.
  • /llms-full.txt — the full text of all pages concatenated into one Markdown document, each section headed by its source URL.

It extracts clean Markdown from the rendered public/ HTML rather than the Markdown/data sources, so it also captures the marketing copy that lives in Hugo layouts (home, features, get-started) and never drifts from what visitors see. Handles headings, lists (incl. code blocks nested in list items), tables, blockquotes, code fences and links; strips nav/footer/scripts; skips Hugo redirect stubs; decodes HTML entities. Wired into bun run build and a new step in deploy-website.yaml (output ships in the existing Pages artifact). Adds node-html-parser as a build-time devDependency.

Also fixes four pre-existing sort $map calls in the /api templates. In Hugo, sort on a map collapses it to a slice, replacing the map keys with numeric indices. On the live page that made API paths, HTTP status codes, request-body content-types, and every schema field name render as 0, 1, 2… instead of /api/v2/assets, 200, asset_id, etc. Hugo already ranges maps in sorted-key order, so dropping sort fixes it.

Checklist

  • I have performed a self-review of my own code.
  • New and existing unit tests pass locally and on CI with my changes.
  • I have done an end-to-end test for Raspberry Pi devices.
  • I have tested my changes for x86 devices.
  • I added a documentation for the changes I have made (when necessary).

Website-only change (no device runtime impact). Validated end-to-end: clean bun run build, strict tsc passes, output verified on both minified (CI) and non-minified HTML, and the /api page confirmed rendering real paths/status codes/field names.

Add a post-build generator that produces llms.txt (a curated index)
and llms-full.txt (the full text of every page) for the marketing
site, following the llmstxt.org convention and served from the site
root.

The generator extracts clean Markdown from the rendered public/ HTML
rather than the Markdown/data sources, so it captures the marketing
copy that lives in Hugo layouts (home, features, get-started) and
never drifts from what visitors actually see. Wired into `bun run
build` and the deploy-website workflow.

Also fixes four pre-existing `sort $map` calls in the /api templates:
in Hugo, sorting a map collapses it to a slice, so the keys were
replaced by numeric indices — API paths, HTTP status codes, request
body content-types, and schema field names all rendered as 0, 1, 2…
on the live page. Hugo already ranges maps in sorted-key order, so
dropping `sort` fixes it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vpetersson vpetersson requested a review from a team as a code owner July 9, 2026 18:13
@vpetersson vpetersson self-assigned this Jul 9, 2026
@vpetersson vpetersson requested a review from Copilot July 9, 2026 18:13
@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

for (const tr of el.querySelectorAll('tr')) {
const cells = tr
.querySelectorAll('th,td')
.map((c) => inline(c).trim().replace(/\|/g, '\\|'))

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds automated generation of llms.txt and llms-full.txt for the marketing site (from the built public/ HTML), and fixes Hugo /api template rendering where sort on maps was collapsing keys to numeric indices.

Changes:

  • Add a Bun post-build script (website/scripts/generate-llms.ts) to extract Markdown-like text from rendered HTML and emit /llms.txt + /llms-full.txt.
  • Wire generation into bun run build and the Pages deploy workflow; add node-html-parser as a devDependency.
  • Remove incorrect sort usage on Hugo maps in /api templates so API paths/status codes/schema field names render correctly.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
website/scripts/generate-llms.ts New generator that crawls public/**/index.html, extracts cleaned Markdown, and writes llms.txt/llms-full.txt.
website/package.json Adds llms:generate and runs it as part of build; adds node-html-parser.
website/layouts/partials/api-schema.html Stops sorting schema properties map so field names don’t become numeric indices.
website/layouts/_default/api.html Stops sorting paths, responses, and request-body content maps so keys render correctly.
website/bun.lock Locks transitive deps for node-html-parser.
.github/workflows/deploy-website.yaml Runs bun run llms:generate after Hugo build so the files ship with Pages artifacts.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +161 to +165
const flush = () => {
const t = buf.trim()
if (t) out.push(t)
buf = ''
}
)
}

main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants