From 328ea9c3d694c2dc180806b75aaed7350d64f993 Mon Sep 17 00:00:00 2001 From: EM Date: Wed, 23 Sep 2026 19:27:59 +0800 Subject: [PATCH 1/2] feat: publish agent-friendly documentation surfaces --- docs/api/README.mdx | 1 + docusaurus.config.ts | 21 ++++++++++++++ package.json | 5 +++- pnpm-lock.yaml | 31 +++++++++++++++++++++ scripts/check-agent-docs.mjs | 54 ++++++++++++++++++++++++++++++++++++ src/pages/index.tsx | 4 +++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 scripts/check-agent-docs.mjs diff --git a/docs/api/README.mdx b/docs/api/README.mdx index 66b7c8f..e5eab21 100644 --- a/docs/api/README.mdx +++ b/docs/api/README.mdx @@ -26,6 +26,7 @@ export const SpecLinks = () => { - New to the API? **[Quickstart](./quickstart)** — mint a key, make your first call, round-trip a resource. ~10 minutes. - Already know the shape? **[Interactive reference](/api)** — every endpoint, rendered from the OpenAPI spec that ships with each release. - Generating a client? Point your generator at . The same URLs feed the [API client guide](./postman) (Postman, Insomnia, Bruno, Hoppscotch). +- Static fallback for Markdown consumers: production specs are `https://app.trakrf.id/api/openapi.json` and `https://app.trakrf.id/api/openapi.yaml`; preview deployments use the matching `app.preview.trakrf.id` host. ## Concept guides diff --git a/docusaurus.config.ts b/docusaurus.config.ts index d2ad0b3..8ac6bab 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -62,6 +62,27 @@ const config: Config = { ], }, ], + [ + "docusaurus-plugin-llms", + { + generateLLMsTxt: true, + generateLLMsFullTxt: true, + generateMarkdownFiles: true, + preserveDirectoryStructure: true, + addMdExtension: true, + excludeImports: true, + removeDuplicateHeadings: true, + customLLMFiles: [ + { + filename: "llms-api.txt", + includePatterns: ["api/**/*.md", "api/**/*.mdx"], + fullContent: true, + title: "TrakRF API Documentation", + description: "Integrator-focused API reference and conventions", + }, + ], + }, + ], ], presets: [ diff --git a/package.json b/package.json index 53a343f..08aae1e 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "swizzle": "docusaurus swizzle", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "check:contributing": "node scripts/check-contributing.mjs" + "check:contributing": "node scripts/check-contributing.mjs", + "check:agent-docs": "node scripts/check-agent-docs.mjs" }, "dependencies": { "@docusaurus/core": "3.9.2", @@ -32,6 +33,8 @@ "@docusaurus/module-type-aliases": "3.9.2", "@docusaurus/tsconfig": "3.9.2", "@docusaurus/types": "3.9.2", + "docusaurus-plugin-llms": "0.6.0", + "docusaurus-plugin-llms": "0.6.0", "prettier": "^3.0.0", "typescript": "~5.6.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7600c8f..4f6f2ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: '@docusaurus/types': specifier: 3.9.2 version: 3.9.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + docusaurus-plugin-llms: + specifier: 0.6.0 + version: 0.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.6.3)) prettier: specifier: ^3.0.0 version: 3.8.1 @@ -2522,6 +2525,12 @@ packages: resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} engines: {node: '>=6'} + docusaurus-plugin-llms@0.6.0: + resolution: {integrity: sha512-v9I6QEJLujkmtKjfWZ/SniWu7oOGZd0JUkyxO5MaFU09+qZHjQuraYuJZ+2AoZdesrrcktgDmZtqPL/sJtHe6A==} + engines: {node: '>=18.0'} + peerDependencies: + '@docusaurus/core': ^3.0.0 + docusaurus-plugin-redoc@2.5.0: resolution: {integrity: sha512-44sDhuXvItHnUuPdKswF3cRhiN5UW3YZxmMBsQLSfCYKcYr9tgWF2qvDfQoZO9i1DwpaYbIZ/RKMrSgny/iWYA==} engines: {node: '>=18'} @@ -3716,6 +3725,10 @@ packages: resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -5442,6 +5455,11 @@ packages: resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} engines: {node: '>= 6'} + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} @@ -9012,6 +9030,13 @@ snapshots: dependencies: '@leichtgewicht/ip-codec': 2.0.5 + docusaurus-plugin-llms@0.6.0(@docusaurus/core@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.6.3)): + dependencies: + '@docusaurus/core': 3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.14)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.6.3) + gray-matter: 4.0.3 + minimatch: 9.0.3 + yaml: 2.8.1 + docusaurus-plugin-redoc@2.5.0(@docusaurus/utils@3.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(core-js@3.48.0)(mobx@6.15.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(styled-components@6.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)): dependencies: '@docusaurus/utils': 3.10.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -10581,6 +10606,10 @@ snapshots: dependencies: brace-expansion: 2.1.0 + minimatch@9.0.3: + dependencies: + brace-expansion: 2.1.0 + minimist@1.2.8: {} mobx-react-lite@4.1.1(mobx@6.15.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -12553,6 +12582,8 @@ snapshots: yaml@1.10.3: {} + yaml@2.8.1: {} + yargs-parser@21.1.1: {} yargs@17.7.2: diff --git a/scripts/check-agent-docs.mjs b/scripts/check-agent-docs.mjs new file mode 100644 index 0000000..75abcae --- /dev/null +++ b/scripts/check-agent-docs.mjs @@ -0,0 +1,54 @@ +import { readFile } from "node:fs/promises"; +import { resolve } from "node:path"; + +const buildDir = resolve("build"); +const requiredFiles = ["llms.txt", "llms-full.txt", "llms-api.txt"]; +const markdownFiles = [ + "docs/api/authentication.md", + "docs/api/errors.md", + "docs/api/design-notes.md", + "docs/api/quickstart.md", +]; + +async function readBuildFile(file) { + try { + return await readFile(resolve(buildDir, file), "utf8"); + } catch (error) { + throw new Error(`Missing build/${file}: ${error.message}`); + } +} + +function assert(condition, message) { + if (!condition) throw new Error(message); +} + +const files = new Map( + await Promise.all( + [...requiredFiles, ...markdownFiles].map(async (file) => [ + file, + await readBuildFile(file), + ]), + ), +); + +const llms = files.get("llms.txt"); +const api = files.get("llms-api.txt"); + +assert( + /\[[^\]]+\]\([^\s)]+\.md\)/.test(llms), + "llms.txt does not link to Markdown mirrors", +); +assert(api.includes("TrakRF API"), "llms-api.txt does not contain API content"); +assert( + !/\/docs\/(?:user-guide|app-tour)\//.test(api), + "llms-api.txt includes user-guide or app-tour content", +); + +for (const file of markdownFiles) { + assert( + !/^\s*

{siteConfig.tagline}

+

+ Coding with an agent? Browse our machine-readable documentation at{" "} + /llms.txt. +

Date: Wed, 23 Sep 2026 19:51:58 +0800 Subject: [PATCH 2/2] fix: remove duplicate llms plugin dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 08aae1e..740b74a 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "@docusaurus/tsconfig": "3.9.2", "@docusaurus/types": "3.9.2", "docusaurus-plugin-llms": "0.6.0", - "docusaurus-plugin-llms": "0.6.0", "prettier": "^3.0.0", "typescript": "~5.6.2" },