@docsector/docsector-reader 0.9.1 β 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -1
- package/bin/docsector.js +1 -1
- package/package.json +1 -1
- package/src/components/DPageBar.vue +25 -6
- package/src/i18n/helpers.js +4 -0
- package/src/index.js +1 -0
- package/src/quasar.factory.js +57 -0
package/README.md
CHANGED
|
@@ -27,6 +27,7 @@ Transform Markdown content into beautiful, navigable documentation sites β wit
|
|
|
27
27
|
- πΊοΈ **Sitemap Generation** β Automatic `sitemap.xml` generation at build time with all page URLs (requires `siteUrl` in config)
|
|
28
28
|
- π€ **AI-Friendly robots.txt** β Scaffold includes a `robots.txt` explicitly allowing 23 AI crawlers (GPTBot, ClaudeBot, PerplexityBot, GrokBot, etc.)
|
|
29
29
|
- π **MCP Server** β Auto-generated [MCP](https://modelcontextprotocol.io) server at `/mcp` for AI assistant integration (Claude Desktop, VS Code, etc.)
|
|
30
|
+
- π **llms.txt / llms-full.txt** β Auto-generated [llms.txt](https://llmstxt.org) index and full-content file for LLM discovery (requires `siteUrl` in config)
|
|
30
31
|
|
|
31
32
|
---
|
|
32
33
|
|
|
@@ -128,7 +129,31 @@ curl -X POST http://localhost:8788/mcp \
|
|
|
128
129
|
|
|
129
130
|
---
|
|
130
131
|
|
|
131
|
-
##
|
|
132
|
+
## οΏ½ llms.txt (LLM Discovery)
|
|
133
|
+
|
|
134
|
+
Docsector Reader automatically generates [llms.txt](https://llmstxt.org) files at build time when `siteUrl` is configured (same requirement as sitemap.xml).
|
|
135
|
+
|
|
136
|
+
| File | Purpose |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `/llms.txt` | Markdown index of all pages with links to `.md` versions, grouped by type |
|
|
139
|
+
| `/llms-full.txt` | Full documentation content concatenated in a single file for LLM context |
|
|
140
|
+
|
|
141
|
+
Optionally add a `description` to your branding for a richer `llms.txt` blockquote:
|
|
142
|
+
|
|
143
|
+
```javascript
|
|
144
|
+
export default {
|
|
145
|
+
branding: {
|
|
146
|
+
name: 'My Project',
|
|
147
|
+
version: 'v1.0.0',
|
|
148
|
+
description: 'A framework for building awesome things'
|
|
149
|
+
},
|
|
150
|
+
siteUrl: 'https://my-docs.example.com'
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## οΏ½π Quick Start
|
|
132
157
|
|
|
133
158
|
### π¦ Install
|
|
134
159
|
|
package/bin/docsector.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@docsector/docsector-reader",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "A documentation rendering engine built with Vue 3, Quasar v2 and Vite. Transform Markdown into beautiful, navigable documentation sites.",
|
|
5
5
|
"productName": "Docsector Reader",
|
|
6
6
|
"author": "Rodrigo de Araujo Vieira",
|
|
@@ -93,16 +93,15 @@ const MCP_PATHS = [
|
|
|
93
93
|
'M14.485 4.703a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a4.115 4.115 0 000 5.9 4.314 4.314 0 006.016 0l7.12-6.982a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a2.588 2.588 0 01-3.61 0 2.47 2.47 0 010-3.54l7.12-6.982z'
|
|
94
94
|
]
|
|
95
95
|
const VSCODE_PATH = 'M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z'
|
|
96
|
-
const CODEX_PATH = 'M15.672 11.249a.75.75 0 00-.006-1.5 3.504 3.504 0 01-3.26-2.26.75.75 0 00-1.392 0 3.504 3.504 0 01-3.26 2.26.75.75 0 000 1.5 3.504 3.504 0 013.258 2.252.75.75 0 001.396-.004A3.504 3.504 0 0115.672 11.249zM21.665 7.317a.75.75 0 000-1.5 5.253 5.253 0 01-4.887-3.386.75.75 0 00-1.392 0A5.253 5.253 0 0110.5 5.817a.75.75 0 000 1.5 5.253 5.253 0 014.886 3.386.75.75 0 001.392 0 5.253 5.253 0 014.887-3.386z'
|
|
97
|
-
|
|
98
96
|
const mcpIcon = computed(() => buildIconURI(MCP_PATHS, 'evenodd'))
|
|
99
97
|
|
|
100
|
-
function buildVSCodeIconURI () {
|
|
101
|
-
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill-rule="evenodd" clip-rule="evenodd" d="${VSCODE_PATH}" fill="%
|
|
98
|
+
function buildVSCodeIconURI (color) {
|
|
99
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill-rule="evenodd" clip-rule="evenodd" d="${VSCODE_PATH}" fill="%23${color}"/></svg>`
|
|
102
100
|
return `img:data:image/svg+xml,${svg}`
|
|
103
101
|
}
|
|
104
|
-
const vscodeIcon = computed(() => buildVSCodeIconURI())
|
|
105
|
-
const
|
|
102
|
+
const vscodeIcon = computed(() => buildVSCodeIconURI('007ACC'))
|
|
103
|
+
const vscodeInsidersIcon = computed(() => buildVSCodeIconURI('24bfa5'))
|
|
104
|
+
const codexIcon = computed(() => buildIconURI(OPENAI_PATH))
|
|
106
105
|
|
|
107
106
|
const mcpURL = computed(() => {
|
|
108
107
|
if (!docsectorConfig.mcp) return null
|
|
@@ -116,6 +115,13 @@ const vscodeMcpURL = computed(() => {
|
|
|
116
115
|
return `vscode:mcp/install?${encodeURIComponent(JSON.stringify({ name, url }))}`
|
|
117
116
|
})
|
|
118
117
|
|
|
118
|
+
const vscodeInsidersMcpURL = computed(() => {
|
|
119
|
+
if (!docsectorConfig.mcp) return null
|
|
120
|
+
const name = docsectorConfig.mcp.serverName
|
|
121
|
+
const url = `${window.location.origin}/mcp`
|
|
122
|
+
return `vscode-insiders:mcp/install?${encodeURIComponent(JSON.stringify({ name, url }))}`
|
|
123
|
+
})
|
|
124
|
+
|
|
119
125
|
const claudeCodeCommand = computed(() => {
|
|
120
126
|
if (!docsectorConfig.mcp) return null
|
|
121
127
|
const name = docsectorConfig.mcp.serverName
|
|
@@ -246,6 +252,19 @@ const copyPage = () => {
|
|
|
246
252
|
</q-item-section>
|
|
247
253
|
</q-item>
|
|
248
254
|
|
|
255
|
+
<q-item clickable v-close-popup :href="vscodeInsidersMcpURL" class="q-py-sm">
|
|
256
|
+
<q-item-section avatar>
|
|
257
|
+
<q-icon :name="vscodeInsidersIcon" size="xs" />
|
|
258
|
+
</q-item-section>
|
|
259
|
+
<q-item-section>
|
|
260
|
+
<q-item-label>{{ t('page.connectVSCodeInsiders') }}</q-item-label>
|
|
261
|
+
<q-item-label caption>{{ t('page.connectVSCodeInsidersCaption') }}</q-item-label>
|
|
262
|
+
</q-item-section>
|
|
263
|
+
<q-item-section side>
|
|
264
|
+
<q-icon name="open_in_new" size="xs" />
|
|
265
|
+
</q-item-section>
|
|
266
|
+
</q-item>
|
|
267
|
+
|
|
249
268
|
<q-item clickable v-close-popup @click="copyMcpCommand(claudeCodeCommand, 'claude')" class="q-py-sm">
|
|
250
269
|
<q-item-section avatar>
|
|
251
270
|
<q-icon :name="claudeIcon" size="xs" />
|
package/src/i18n/helpers.js
CHANGED
|
@@ -38,6 +38,8 @@ const engineDefaults = {
|
|
|
38
38
|
mcpServerCaption: 'Connect AI assistants via MCP',
|
|
39
39
|
connectVSCode: 'Connect to VSCode',
|
|
40
40
|
connectVSCodeCaption: 'Use this MCP in VSCode',
|
|
41
|
+
connectVSCodeInsiders: 'Connect to VSCode Insiders',
|
|
42
|
+
connectVSCodeInsidersCaption: 'Use this MCP in VSCode Insiders',
|
|
41
43
|
connectClaudeCode: 'Connect to Claude Code',
|
|
42
44
|
connectClaudeCodeCaption: 'Use this MCP in Claude Code',
|
|
43
45
|
connectCodex: 'Connect to Codex',
|
|
@@ -60,6 +62,8 @@ const engineDefaults = {
|
|
|
60
62
|
mcpServerCaption: 'Conecte assistentes de IA via MCP',
|
|
61
63
|
connectVSCode: 'Conectar ao VSCode',
|
|
62
64
|
connectVSCodeCaption: 'Use este MCP no VSCode',
|
|
65
|
+
connectVSCodeInsiders: 'Conectar ao VSCode Insiders',
|
|
66
|
+
connectVSCodeInsidersCaption: 'Use este MCP no VSCode Insiders',
|
|
63
67
|
connectClaudeCode: 'Conectar ao Claude Code',
|
|
64
68
|
connectClaudeCodeCaption: 'Use este MCP no Claude Code',
|
|
65
69
|
connectCodex: 'Conectar ao Codex',
|
package/src/index.js
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
* @param {string} config.branding.logo - Logo image path (relative to public/)
|
|
27
27
|
* @param {string} config.branding.name - Project name displayed in sidebar
|
|
28
28
|
* @param {string} config.branding.version - Version label
|
|
29
|
+
* @param {string} [config.branding.description] - Project description (used in llms.txt)
|
|
29
30
|
* @param {string[]} [config.branding.versions] - Available versions for dropdown
|
|
30
31
|
* @param {Object} config.links - External links
|
|
31
32
|
* @param {string} [config.links.github] - GitHub repository URL
|
package/src/quasar.factory.js
CHANGED
|
@@ -467,6 +467,63 @@ function createMarkdownBuildPlugin (projectRoot) {
|
|
|
467
467
|
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}</urlset>\n`
|
|
468
468
|
writeFileSync(resolve(distDir, 'sitemap.xml'), sitemap)
|
|
469
469
|
console.log(`\x1b[36m[docsector]\x1b[0m Generated sitemap.xml`)
|
|
470
|
+
|
|
471
|
+
// Generate llms.txt and llms-full.txt (LLM-friendly page index and full content)
|
|
472
|
+
const brandingName = config.branding?.name || 'Documentation'
|
|
473
|
+
const brandingVersion = config.branding?.version || ''
|
|
474
|
+
const brandingDesc = config.branding?.description || `${brandingName} documentation`
|
|
475
|
+
|
|
476
|
+
let llmsIndex = `# ${brandingName}${brandingVersion ? ' ' + brandingVersion : ''}\n\n> ${brandingDesc}\n\n`
|
|
477
|
+
let llmsFull = `# ${brandingName}${brandingVersion ? ' ' + brandingVersion : ''}\n\n> ${brandingDesc}\n\n---\n\n`
|
|
478
|
+
|
|
479
|
+
const llmsSections = {}
|
|
480
|
+
|
|
481
|
+
for (const [pagePath, page] of Object.entries(pages)) {
|
|
482
|
+
if (page.config === null) continue
|
|
483
|
+
if (page.config.status === 'empty') continue
|
|
484
|
+
|
|
485
|
+
const type = page.config.type ?? 'manual'
|
|
486
|
+
const title = page.data?.['*']?.title
|
|
487
|
+
|| page.data?.[defaultLang]?.title
|
|
488
|
+
|| page.data?.['en-US']?.title
|
|
489
|
+
|| pagePath.split('/').pop()
|
|
490
|
+
|| pagePath
|
|
491
|
+
|
|
492
|
+
const subpages = ['overview']
|
|
493
|
+
if (page.config.subpages?.showcase) subpages.push('showcase')
|
|
494
|
+
if (page.config.subpages?.vs) subpages.push('vs')
|
|
495
|
+
|
|
496
|
+
for (const subpage of subpages) {
|
|
497
|
+
const srcFile = resolve(pagesDir, `${type}${pagePath}.${subpage}.${defaultLang}.md`)
|
|
498
|
+
if (!existsSync(srcFile)) continue
|
|
499
|
+
|
|
500
|
+
const routePath = `${type}${pagePath}/${subpage}`
|
|
501
|
+
const mdUrl = `${siteUrl}/${routePath}.md`
|
|
502
|
+
const pageUrl = `${siteUrl}/${routePath}`
|
|
503
|
+
|
|
504
|
+
const desc = page.config.meta?.description
|
|
505
|
+
const descText = typeof desc === 'object' ? (desc[defaultLang] || desc['en-US'] || '') : (desc || '')
|
|
506
|
+
|
|
507
|
+
if (!llmsSections[type]) llmsSections[type] = []
|
|
508
|
+
llmsSections[type].push(
|
|
509
|
+
descText
|
|
510
|
+
? `- [${title}](${mdUrl}): ${descText}`
|
|
511
|
+
: `- [${title}](${mdUrl})`
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
const content = readFileSync(srcFile, 'utf-8')
|
|
515
|
+
llmsFull += `## ${title}\n\nSource: ${pageUrl}\n\n${content}\n\n---\n\n`
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
for (const [section, entries] of Object.entries(llmsSections)) {
|
|
520
|
+
const sectionName = section.charAt(0).toUpperCase() + section.slice(1)
|
|
521
|
+
llmsIndex += `## ${sectionName}\n\n${entries.join('\n')}\n\n`
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
writeFileSync(resolve(distDir, 'llms.txt'), llmsIndex.trimEnd() + '\n')
|
|
525
|
+
writeFileSync(resolve(distDir, 'llms-full.txt'), llmsFull.trimEnd() + '\n')
|
|
526
|
+
console.log(`\x1b[36m[docsector]\x1b[0m Generated llms.txt and llms-full.txt`)
|
|
470
527
|
}
|
|
471
528
|
|
|
472
529
|
// Generate _headers file for Cloudflare Pages (append if exists)
|