From 2c1daf30a52c526abf1db474da15028e5307e81b Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 21 Jul 2026 17:19:48 -0500 Subject: [PATCH 1/2] feat(build): generate llms.txt via doc-kit - add the llms-txt target with a webpack-specific template - link entries to raw markdown pages and copy the .md sources into out/ - drop empty entries produced by JSX-driven pages (home, blog index) --- scripts/html/doc-kit.config.mjs | 5 +++++ scripts/html/index.mjs | 26 +++++++++++++++++++++++++- scripts/html/llms-template.txt | 8 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 scripts/html/llms-template.txt diff --git a/scripts/html/doc-kit.config.mjs b/scripts/html/doc-kit.config.mjs index 7606bb74..71924db4 100644 --- a/scripts/html/doc-kit.config.mjs +++ b/scripts/html/doc-kit.config.mjs @@ -43,6 +43,11 @@ export default { generateIndexPage: false, generateAllPage: false, }, + 'llms-txt': { + templatePath: join(ROOT, 'scripts/html/llms-template.txt'), + pageURL: `${BASE_URL.replace(/\/$/, '')}{path}.md`, + output: VERSION ? `./out/docs/api/${MAJOR_VERSION}` : './out', + }, web: { project: 'webpack', useAbsoluteURLs: true, diff --git a/scripts/html/index.mjs b/scripts/html/index.mjs index d2ff70c1..36736561 100644 --- a/scripts/html/index.mjs +++ b/scripts/html/index.mjs @@ -1,9 +1,22 @@ import { execFile } from 'node:child_process'; -import { readFile } from 'node:fs/promises'; +import { cp, readFile, writeFile } from 'node:fs/promises'; +import { statSync } from 'node:fs'; import { promisify } from 'node:util'; const execFileAsync = promisify(execFile); +// The llms-txt generator lists every page with a depth-1 heading. JSX-driven +// pages like the homepage produce entries with no title or description — drop +// them, they carry no information for LLMs. +const cleanLlmsTxt = async path => { + const content = await readFile(path, 'utf8'); + const cleaned = content + .split('\n') + .filter(line => !line.startsWith('- [](')) + .join('\n'); + await writeFile(path, cleaned); +}; + const runDocKit = version => execFileAsync( 'npx', @@ -16,6 +29,8 @@ const runDocKit = version => 'web', '-t', 'orama-db', + '-t', + 'llms-txt', '--config-file', './scripts/html/doc-kit.config.mjs', ], @@ -35,5 +50,14 @@ const versions = JSON.parse(await readFile('./versions.json')); for (const version of versions) { await runDocKit(version); + await cleanLlmsTxt(`./out/docs/api/v${version.match(/\d+/)[0]}.x/llms.txt`); } await runDocKit(); +await cleanLlmsTxt('./out/llms.txt'); + +// Publish the markdown sources next to the rendered pages so the llms.txt +// links (`{path}.md`) resolve to LLM-friendly raw markdown. +await cp('./pages', './out', { + recursive: true, + filter: source => statSync(source).isDirectory() || source.endsWith('.md'), +}); diff --git a/scripts/html/llms-template.txt b/scripts/html/llms-template.txt new file mode 100644 index 00000000..6672a249 --- /dev/null +++ b/scripts/html/llms-template.txt @@ -0,0 +1,8 @@ +# webpack Documentation + +> webpack is a static module bundler for modern JavaScript applications. It builds a dependency graph from one or more entry points and combines every module your project needs into one or more bundles, and it can transform, bundle, or package just about any resource or asset. + +Below are the sections of the webpack documentation. Look out especially towards the links that point towards guidance/introduction to the structure of this documentation. + +## Documentation + From 0736b2fb1b921a13a027511c9d99778d49946a3f Mon Sep 17 00:00:00 2001 From: Sebastian Beltran Date: Tue, 21 Jul 2026 18:37:46 -0500 Subject: [PATCH 2/2] Apply suggestion from @bjohansebas --- scripts/html/index.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/html/index.mjs b/scripts/html/index.mjs index 36736561..7bd0c835 100644 --- a/scripts/html/index.mjs +++ b/scripts/html/index.mjs @@ -5,6 +5,7 @@ import { promisify } from 'node:util'; const execFileAsync = promisify(execFile); +// TODO: Have doc-kit understand that some pages don't have meaningful information // The llms-txt generator lists every page with a depth-1 heading. JSX-driven // pages like the homepage produce entries with no title or description — drop // them, they carry no information for LLMs.