|
1 | 1 | const path = require('path'); |
2 | 2 | const fs = require('fs'); |
| 3 | +const matter = require('gray-matter'); |
| 4 | + |
| 5 | +const DOCS_URL = 'https://commandkit.dev/docs/next/guide'; |
3 | 6 |
|
4 | 7 | module.exports = function (context) { |
5 | 8 | return { |
6 | 9 | name: 'llms-txt-plugin', |
7 | 10 | loadContent: async () => { |
8 | 11 | const { siteDir } = context; |
9 | 12 | const docsDir = path.join(siteDir, 'docs'); |
| 13 | + const guideDir = path.join(docsDir, 'guide'); |
10 | 14 | const versionedDocsDir = path.join(siteDir, 'versioned_docs'); |
11 | | - const allMdx = []; |
| 15 | + const allDocs = []; |
12 | 16 |
|
13 | | - // Recursive function to get all mdx and md files (excluding API reference) |
14 | 17 | const getMdxFiles = async (dir, versionPrefix = '') => { |
15 | 18 | if (!fs.existsSync(dir)) return; |
16 | 19 |
|
| 20 | + // skip versioned docs |
| 21 | + if (dir.includes(versionedDocsDir)) return; |
| 22 | + |
17 | 23 | const entries = await fs.promises.readdir(dir, { withFileTypes: true }); |
18 | 24 |
|
19 | 25 | for (const entry of entries) { |
20 | 26 | const fullPath = path.join(dir, entry.name); |
21 | 27 | if (entry.isDirectory()) { |
22 | | - // Skip api-reference directories |
23 | | - if (entry.name === 'api-reference') { |
24 | | - continue; |
25 | | - } |
26 | 28 | await getMdxFiles(fullPath, versionPrefix); |
27 | | - } else if ( |
28 | | - entry.name.endsWith('.mdx') || |
29 | | - entry.name.endsWith('.md') |
30 | | - ) { |
31 | | - // Skip files in api-reference paths |
32 | | - if (fullPath.includes('api-reference')) { |
33 | | - continue; |
34 | | - } |
| 29 | + } else if (entry.name.endsWith('.mdx') || entry.name.endsWith('.md')) { |
35 | 30 | const content = await fs.promises.readFile(fullPath, 'utf8'); |
36 | | - allMdx.push({ |
37 | | - content, |
38 | | - path: fullPath, |
| 31 | + const { data: frontmatter } = matter(content); |
| 32 | + |
| 33 | + // Get relative path from guide directory |
| 34 | + const relativePath = path.relative(guideDir, fullPath) |
| 35 | + .replace(/\.mdx?$/, '') |
| 36 | + .replace(/\\/g, '/'); |
| 37 | + |
| 38 | + allDocs.push({ |
| 39 | + title: frontmatter.title, |
| 40 | + description: frontmatter.description, |
| 41 | + path: relativePath, |
39 | 42 | version: versionPrefix, |
40 | 43 | }); |
41 | 44 | } |
42 | 45 | } |
43 | 46 | }; |
44 | 47 |
|
45 | | - // Get current/latest docs |
46 | | - await getMdxFiles(docsDir, 'latest'); |
47 | | - |
48 | | - // Get versioned docs |
49 | | - if (fs.existsSync(versionedDocsDir)) { |
50 | | - const versionDirs = await fs.promises.readdir(versionedDocsDir, { |
51 | | - withFileTypes: true, |
52 | | - }); |
53 | | - for (const versionDir of versionDirs) { |
54 | | - if (versionDir.isDirectory()) { |
55 | | - const versionName = versionDir.name.replace('version-', ''); |
56 | | - await getMdxFiles( |
57 | | - path.join(versionedDocsDir, versionDir.name), |
58 | | - versionName, |
59 | | - ); |
60 | | - } |
61 | | - } |
| 48 | + // Only process guide directory |
| 49 | + if (fs.existsSync(guideDir)) { |
| 50 | + await getMdxFiles(guideDir, 'latest'); |
62 | 51 | } |
63 | 52 |
|
64 | | - return { allMdx }; |
| 53 | + return { allDocs }; |
65 | 54 | }, |
66 | 55 | postBuild: async ({ content, outDir }) => { |
67 | | - const { allMdx } = content; |
| 56 | + const { allDocs } = content; |
68 | 57 |
|
69 | | - // Filter out any remaining API reference content and concatenate |
70 | | - const filteredContent = allMdx |
71 | | - .filter((item) => !item.path.includes('api-reference')) |
72 | | - .map((item) => item.content) |
73 | | - .join('\n\n---\n\n'); |
| 58 | + // Generate markdown content |
| 59 | + const markdownContent = [ |
| 60 | + '# CommandKit Docs\n', |
| 61 | + ...allDocs |
| 62 | + .filter(doc => doc.title && doc.description) |
| 63 | + .map(doc => { |
| 64 | + const url = `${DOCS_URL}/${doc.path}`; |
| 65 | + return `- [${doc.title}](${url}): ${doc.description || doc.title}`; |
| 66 | + }) |
| 67 | + ].join('\n'); |
74 | 68 |
|
75 | | - // Write concatenated content as llms.txt |
| 69 | + // Write markdown content |
76 | 70 | const llmsTxtPath = path.join(outDir, 'llms.txt'); |
77 | 71 | try { |
78 | | - await fs.promises.writeFile(llmsTxtPath, filteredContent); |
| 72 | + await fs.promises.writeFile(llmsTxtPath, markdownContent); |
79 | 73 | console.log('✅ llms.txt generated successfully'); |
80 | 74 | } catch (err) { |
81 | 75 | console.error('❌ Error generating llms.txt:', err); |
|
0 commit comments