From 11fd74eeca5b8d06a6961fc5adbca9bc964e5df2 Mon Sep 17 00:00:00 2001 From: abramdawson Date: Fri, 13 Feb 2026 16:12:04 -0800 Subject: [PATCH] docs: add llms.txt and llms-full.txt for LLM discoverability Add a hand-crafted llms.txt index and a build script that auto-generates llms-full.txt from all MDX pages in navigation order. The script reads _meta.json files dynamically so it stays in sync as pages are added or reordered. Co-Authored-By: Claude Opus 4.6 --- .gitignore | 3 + package.json | 2 +- public/llms.txt | 55 ++++++++++++++++ scripts/generate-llms-full.js | 116 ++++++++++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 public/llms.txt create mode 100644 scripts/generate-llms-full.js diff --git a/.gitignore b/.gitignore index 2bf874e..c9b604d 100644 --- a/.gitignore +++ b/.gitignore @@ -48,5 +48,8 @@ yarn-error.log* /artifacts /typechain +# generated at build time +public/llms-full.txt + # claude local config .claude/settings.local.json diff --git a/package.json b/package.json index 7abaec4..9d4b2e2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "dev": "next dev", "start": "next start", - "build": "next build && yarn post-build", + "build": "node scripts/generate-llms-full.js && next build && yarn post-build", "post-build": "next-sitemap" }, "engines": { diff --git a/public/llms.txt b/public/llms.txt new file mode 100644 index 0000000..a57bc13 --- /dev/null +++ b/public/llms.txt @@ -0,0 +1,55 @@ +# Splits + +> Composable, open-source, audited smart contracts for managing onchain revenue. No protocol fees. Runs forever as a hyperstructure. + +Splits makes it easy to split onchain payments among multiple recipients. Contracts are deployed on Ethereum, Optimism, Base, Zora, Polygon, Arbitrum, and more. All contracts use deterministic deployment (same addresses across chains). + +## Docs + +- [Introduction](https://docs.splits.org): Overview of Splits protocol, features, and values +- [Flow of funds](https://docs.splits.org/flow): How funds move through the system — receiving, distributing, withdrawing + +## SDK + +- [SDK Overview](https://docs.splits.org/sdk): Installation and setup for @0xsplits/splits-sdk (TypeScript) +- [SplitsV2 Client](https://docs.splits.org/sdk/splits-v2): Create, update, distribute, and withdraw from V2 splits +- [SplitsV1 Client](https://docs.splits.org/sdk/splits-v1): Legacy V1 split operations +- [Warehouse Client](https://docs.splits.org/sdk/warehouse): Interact with the SplitWarehouse contract for balance management +- [Data Client](https://docs.splits.org/sdk/data): Query split metadata, balances, and activity via GraphQL +- [Waterfall Client](https://docs.splits.org/sdk/waterfall): Create and manage waterfall payment flows +- [Swapper Client](https://docs.splits.org/sdk/swapper): Token swapping within payment flows +- [Liquid Splits Client](https://docs.splits.org/sdk/liquid): NFT-governed mutable splits +- [Vesting Client](https://docs.splits.org/sdk/vesting): Time-locked payment vesting +- [Templates Client](https://docs.splits.org/sdk/templates): Create recoup, diversifier, and other composed flows +- [Multicall](https://docs.splits.org/sdk/multicall): Batch multiple SDK calls in a single transaction +- [Utilities](https://docs.splits.org/sdk/utils): Helper functions for formatting, validation, and calculations + +## React + +- [React SDK](https://docs.splits.org/react): React hooks wrapping the core SDK (@0xsplits/splits-sdk-react) +- [SplitsKit](https://docs.splits.org/splits-kit): Pre-built React component library with Storybook + +## Contracts + +- [Core Contracts Overview](https://docs.splits.org/core): Architecture and flow of funds through the contract system +- [Warehouse](https://docs.splits.org/core/warehouse): Central balance storage contract (SplitWarehouse) +- [SplitV2](https://docs.splits.org/core/split-v2): Latest split contract — push and pull variants with deterministic deployment +- [Split (V1)](https://docs.splits.org/core/split): Original split contract via SplitMain +- [Waterfall](https://docs.splits.org/core/waterfall): Sequential payment tranches — first recipient filled before next +- [Swapper](https://docs.splits.org/core/swapper): Swap tokens on distribution using oracle-based pricing +- [Oracle](https://docs.splits.org/core/oracle): Price oracle used by Swapper for token conversions +- [Pass-Through Wallet](https://docs.splits.org/core/pass-through): Forward funds through an intermediary address +- [Vesting](https://docs.splits.org/core/vesting): Time-locked release of funds to recipients + +## Templates + +- [Templates Overview](https://docs.splits.org/templates): Composed payment flows built from core building blocks +- [Recoup](https://docs.splits.org/templates/recoup): Reimburse an initial investment before splitting remaining funds +- [Liquid Split](https://docs.splits.org/templates/liquid): Mutable split governed by NFT ownership +- [Diversifier](https://docs.splits.org/templates/diversifier): Automatically swap and diversify incoming tokens + +## Optional + +- [GitHub](https://github.com/0xSplits): Source code for all contracts and SDKs +- [Help Center](https://splits.org/help/): Non-technical user support +- [App](https://app.splits.org): Web interface for creating and managing splits diff --git a/scripts/generate-llms-full.js b/scripts/generate-llms-full.js new file mode 100644 index 0000000..01d9020 --- /dev/null +++ b/scripts/generate-llms-full.js @@ -0,0 +1,116 @@ +const fs = require("fs"); +const path = require("path"); + +const PAGES_DIR = path.join(__dirname, "..", "pages"); +const OUTPUT = path.join(__dirname, "..", "public", "llms-full.txt"); + +// Read a _meta.json and return ordered page slugs (skipping separators, external links, etc.) +function readMeta(dir) { + const metaPath = path.join(dir, "_meta.json"); + if (!fs.existsSync(metaPath)) return []; + + const meta = JSON.parse(fs.readFileSync(metaPath, "utf-8")); + const slugs = []; + + for (const [key, value] of Object.entries(meta)) { + // Skip separators, external links, and non-page entries + if (typeof value === "object" && value !== null) { + if (value.type === "separator") continue; + if (value.href) continue; // external link + } + slugs.push(key); + } + + return slugs; +} + +// Recursively collect MDX files in navigation order from _meta.json +function collectPages(dir, prefix) { + const slugs = readMeta(dir); + const pages = []; + + for (const slug of slugs) { + const mdxFile = path.join(dir, `${slug}.mdx`); + const subDir = path.join(dir, slug); + const relPath = prefix ? `${prefix}/${slug}` : slug; + + // Add the page itself if it exists + if (fs.existsSync(mdxFile)) { + pages.push({ file: mdxFile, relPath: `${relPath}.mdx` }); + } + + // Recurse into subdirectory if it has a _meta.json + if (fs.existsSync(path.join(subDir, "_meta.json"))) { + pages.push(...collectPages(subDir, relPath)); + } + } + + return pages; +} + +// Map file paths to URL paths +function fileToUrl(relPath) { + const slug = relPath.replace(/\.mdx$/, "").replace(/\/index$/, ""); + if (slug === "index") return "https://docs.splits.org"; + return `https://docs.splits.org/${slug}`; +} + +// Strip JSX/MDX artifacts and convert to clean markdown +function cleanMdx(content) { + let lines = content.split("\n"); + + // Remove import lines at the top of the file + lines = lines.filter((line) => !line.match(/^import\s+.*from\s+['"]/)); + + let text = lines.join("\n"); + + // Remove self-closing JSX tags: + text = text.replace(/<\w+[^>]*\/>/g, ""); + + // Remove opening JSX tags (Toggle, Tabs, Tab, Callout, div) + text = text.replace(/<(Toggle|Tabs|Tab|Callout|div)[^>]*>/gs, ""); + + // Remove closing JSX tags + text = text.replace(/<\/(Toggle|Tabs|Tab|Callout|div)>/g, ""); + + // Remove {/* JSX comments */} + text = text.replace(/\{\/\*[\s\S]*?\*\/\}/g, ""); + + // Collapse 3+ blank lines into 2 + text = text.replace(/\n{3,}/g, "\n\n"); + + return text.trim(); +} + +function main() { + const header = `# Splits — Full Documentation + +> Composable, open-source, audited smart contracts for managing onchain revenue. No protocol fees. Runs forever as a hyperstructure. + +This file contains the complete Splits documentation concatenated into a single document. +For a curated index, see https://docs.splits.org/llms.txt + +--- + +`; + + const pages = collectPages(PAGES_DIR, ""); + const sections = []; + + for (const { file, relPath } of pages) { + const raw = fs.readFileSync(file, "utf-8"); + const cleaned = cleanMdx(raw); + const url = fileToUrl(relPath); + + sections.push(`\n\n${cleaned}`); + } + + const output = header + sections.join("\n\n---\n\n") + "\n"; + + fs.writeFileSync(OUTPUT, output, "utf-8"); + console.log( + `Generated ${OUTPUT} (${sections.length} pages, ${output.length} bytes)` + ); +} + +main();