veslx 0.1.23 → 0.1.24
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/index.html +17 -3
- package/package.json +1 -1
- package/plugin/src/plugin.ts +65 -0
- package/plugin/src/types.ts +3 -0
- package/src/index.css +5 -0
package/index.html
CHANGED
|
@@ -9,14 +9,28 @@
|
|
|
9
9
|
<script>
|
|
10
10
|
(function() {
|
|
11
11
|
var theme = localStorage.getItem('theme');
|
|
12
|
-
var
|
|
12
|
+
var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
13
|
+
var isDark = theme === 'dark' || (theme !== 'light' && prefersDark);
|
|
13
14
|
if (isDark) document.documentElement.classList.add('dark');
|
|
14
15
|
document.documentElement.style.colorScheme = isDark ? 'dark' : 'light';
|
|
15
16
|
})();
|
|
16
17
|
</script>
|
|
17
18
|
<style>
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
/* Critical theme variables to prevent FOUC */
|
|
20
|
+
:root {
|
|
21
|
+
--background: 0 0% 100%;
|
|
22
|
+
--foreground: 240 10% 10%;
|
|
23
|
+
}
|
|
24
|
+
.dark {
|
|
25
|
+
--background: 0 0% 7%;
|
|
26
|
+
--foreground: 0 0% 93%;
|
|
27
|
+
}
|
|
28
|
+
html, body {
|
|
29
|
+
background-color: hsl(var(--background));
|
|
30
|
+
color: hsl(var(--foreground));
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
body { visibility: hidden; }
|
|
20
34
|
</style>
|
|
21
35
|
<!-- Google Fonts: DM Sans + DM Mono -->
|
|
22
36
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
package/package.json
CHANGED
package/plugin/src/plugin.ts
CHANGED
|
@@ -117,7 +117,67 @@ export default function contentPlugin(contentDir: string, config?: VeslxConfig,
|
|
|
117
117
|
|
|
118
118
|
urlToDir.set('/raw', dir)
|
|
119
119
|
|
|
120
|
+
// Generate llms.txt content dynamically
|
|
121
|
+
function generateLlmsTxt(): string {
|
|
122
|
+
const frontmatters = extractFrontmatters(dir)
|
|
123
|
+
const entries: { path: string; title?: string; description?: string; date?: string; isSlides: boolean }[] = []
|
|
124
|
+
|
|
125
|
+
for (const [key, fm] of Object.entries(frontmatters)) {
|
|
126
|
+
const relativePath = key.replace('@content/', '')
|
|
127
|
+
const isSlides = relativePath.endsWith('SLIDES.mdx') || relativePath.endsWith('.slides.mdx')
|
|
128
|
+
entries.push({
|
|
129
|
+
path: relativePath,
|
|
130
|
+
title: fm.title,
|
|
131
|
+
description: fm.description,
|
|
132
|
+
date: fm.date,
|
|
133
|
+
isSlides,
|
|
134
|
+
})
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
entries.sort((a, b) => {
|
|
138
|
+
if (a.date && b.date) return b.date.localeCompare(a.date)
|
|
139
|
+
if (a.date) return -1
|
|
140
|
+
if (b.date) return 1
|
|
141
|
+
return a.path.localeCompare(b.path)
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
const lines: string[] = [`# ${siteConfig.name}`]
|
|
145
|
+
if (siteConfig.description) {
|
|
146
|
+
lines.push(siteConfig.description)
|
|
147
|
+
}
|
|
148
|
+
lines.push('')
|
|
149
|
+
|
|
150
|
+
// Links section
|
|
151
|
+
if (siteConfig.homepage) {
|
|
152
|
+
lines.push(`Homepage: ${siteConfig.homepage}`)
|
|
153
|
+
}
|
|
154
|
+
if (siteConfig.github) {
|
|
155
|
+
lines.push(`GitHub: https://github.com/${siteConfig.github}`)
|
|
156
|
+
}
|
|
157
|
+
lines.push('Install: bun install -g veslx')
|
|
158
|
+
lines.push('')
|
|
159
|
+
|
|
160
|
+
lines.push('Content is served as raw MDX files at /raw/{path}.')
|
|
161
|
+
lines.push('')
|
|
162
|
+
|
|
163
|
+
for (const entry of entries) {
|
|
164
|
+
const type = entry.isSlides ? '[slides]' : entry.date ? '[post]' : '[doc]'
|
|
165
|
+
const title = entry.title || entry.path.replace(/\.mdx?$/, '').split('/').pop()
|
|
166
|
+
const desc = entry.description ? ` - ${entry.description}` : ''
|
|
167
|
+
lines.push(`${type} ${title}: /raw/${entry.path}${desc}`)
|
|
168
|
+
}
|
|
169
|
+
lines.push('')
|
|
170
|
+
return lines.join('\n')
|
|
171
|
+
}
|
|
172
|
+
|
|
120
173
|
const middleware: Connect.NextHandleFunction = (req: IncomingMessage, res: ServerResponse, next: Connect.NextFunction) => {
|
|
174
|
+
// Serve llms.txt dynamically
|
|
175
|
+
if (req.url === '/llms.txt') {
|
|
176
|
+
res.setHeader('Content-Type', 'text/plain')
|
|
177
|
+
res.end(generateLlmsTxt())
|
|
178
|
+
return
|
|
179
|
+
}
|
|
180
|
+
|
|
121
181
|
// Check if URL matches any registered content directory
|
|
122
182
|
for (const [urlBase, contentDir] of urlToDir.entries()) {
|
|
123
183
|
if (req.url?.startsWith(urlBase + '/')) {
|
|
@@ -269,6 +329,11 @@ export const modules = import.meta.glob('@content/**/*.mdx');
|
|
|
269
329
|
if (fs.existsSync(dir)) {
|
|
270
330
|
copyDirSync(dir, destDir)
|
|
271
331
|
console.log(`Content copied successfully`)
|
|
332
|
+
|
|
333
|
+
// Generate llms.txt for CLI tools and LLMs
|
|
334
|
+
const llmsTxtPath = path.join(outDir, 'llms.txt')
|
|
335
|
+
fs.writeFileSync(llmsTxtPath, generateLlmsTxt())
|
|
336
|
+
console.log(`Generated llms.txt`)
|
|
272
337
|
} else {
|
|
273
338
|
console.warn(`Content directory not found: ${dir}`)
|
|
274
339
|
}
|
package/plugin/src/types.ts
CHANGED
|
@@ -4,6 +4,7 @@ export interface SiteConfig {
|
|
|
4
4
|
name?: string;
|
|
5
5
|
description?: string;
|
|
6
6
|
github?: string;
|
|
7
|
+
homepage?: string;
|
|
7
8
|
defaultView?: ContentView;
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -16,6 +17,7 @@ export interface ResolvedSiteConfig {
|
|
|
16
17
|
name: string;
|
|
17
18
|
description: string;
|
|
18
19
|
github: string;
|
|
20
|
+
homepage: string;
|
|
19
21
|
defaultView: ContentView;
|
|
20
22
|
}
|
|
21
23
|
|
|
@@ -23,5 +25,6 @@ export const DEFAULT_SITE_CONFIG: ResolvedSiteConfig = {
|
|
|
23
25
|
name: 'veslx',
|
|
24
26
|
description: '',
|
|
25
27
|
github: '',
|
|
28
|
+
homepage: '',
|
|
26
29
|
defaultView: 'all',
|
|
27
30
|
};
|