nuxt-ai-ready 0.1.0 → 0.1.2
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/dist/module.d.mts +6 -29
- package/dist/module.json +1 -1
- package/dist/module.mjs +41 -56
- package/package.json +2 -2
package/dist/module.d.mts
CHANGED
|
@@ -1,36 +1,8 @@
|
|
|
1
1
|
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import {
|
|
2
|
+
import { BulkChunk, ModuleOptions } from '../dist/runtime/types.js';
|
|
3
3
|
export { BulkChunk, ModuleOptions } from '../dist/runtime/types.js';
|
|
4
|
-
import { ProcessedFile } from 'mdream/llms-txt';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Hook payload for mdream:llms-txt
|
|
8
|
-
* Called after mdream has generated llms.txt, before writing to disk
|
|
9
|
-
*
|
|
10
|
-
* IMPORTANT: This uses a mutable pattern. Hooks should modify the content
|
|
11
|
-
* and fullContent properties directly rather than returning values.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* nuxt.hooks.hook('mdream:llms-txt', async (payload) => {
|
|
15
|
-
* payload.content += '\n\n## Custom Section\n\nAdded by hook!'
|
|
16
|
-
* payload.fullContent += '\n\n## Custom Section (Full)\n\nAdded by hook!'
|
|
17
|
-
* })
|
|
18
|
-
*/
|
|
19
|
-
interface LlmsTxtGeneratePayload {
|
|
20
|
-
/** Current llms.txt content - modify this directly */
|
|
21
|
-
content: string;
|
|
22
|
-
/** Current llms-full.txt content - modify this directly */
|
|
23
|
-
fullContent: string;
|
|
24
|
-
/** All routes with their metadata (read-only) */
|
|
25
|
-
pages: ProcessedFile[];
|
|
26
|
-
}
|
|
27
4
|
|
|
28
5
|
interface ModuleHooks {
|
|
29
|
-
/**
|
|
30
|
-
* Hook to modify llms.txt content before final output
|
|
31
|
-
* Other modules can append their own API endpoints here
|
|
32
|
-
*/
|
|
33
|
-
'ai-ready:llms-txt': (payload: LlmsTxtGeneratePayload) => void | Promise<void>;
|
|
34
6
|
/**
|
|
35
7
|
* Hook to add routes to the AI ready
|
|
36
8
|
* Other modules can register their own API routes
|
|
@@ -58,5 +30,10 @@ interface ModulePublicRuntimeConfig {
|
|
|
58
30
|
}
|
|
59
31
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
60
32
|
|
|
33
|
+
declare module '@nuxt/schema' {
|
|
34
|
+
interface NuxtHooks extends ModuleHooks {
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
61
38
|
export { _default as default };
|
|
62
39
|
export type { ModuleHooks, ModulePublicRuntimeConfig };
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -6,26 +6,39 @@ import { TagIdMap } from 'mdream';
|
|
|
6
6
|
import { extractionPlugin } from 'mdream/plugins';
|
|
7
7
|
import { htmlToMarkdownSplitChunksStream } from 'mdream/splitter';
|
|
8
8
|
import { useSiteConfig, installNuxtSiteConfig, withSiteUrl } from 'nuxt-site-config/kit';
|
|
9
|
+
import { isPathFile } from 'nuxt-site-config/urls';
|
|
9
10
|
import { relative, resolve, dirname } from 'pathe';
|
|
10
11
|
import { readPackageJSON } from 'pkg-types';
|
|
11
12
|
import { estimateTokenCount } from 'tokenx';
|
|
12
|
-
import {
|
|
13
|
+
import { stat } from 'node:fs/promises';
|
|
13
14
|
import { join } from 'node:path';
|
|
14
|
-
import {
|
|
15
|
-
import { normalizeLlmsTxtConfig } from '../dist/runtime/llms-txt.js';
|
|
15
|
+
import { createLlmsTxtStream } from 'mdream/llms-txt';
|
|
16
16
|
|
|
17
17
|
const logger = useLogger("nuxt-ai-ready");
|
|
18
18
|
|
|
19
19
|
function setupPrerenderHandler() {
|
|
20
20
|
const nuxt = useNuxt();
|
|
21
|
-
const pages = [];
|
|
22
21
|
nuxt.hooks.hook("nitro:init", async (nitro) => {
|
|
22
|
+
let writer = null;
|
|
23
|
+
let pageCount = 0;
|
|
24
|
+
const startTime = Date.now();
|
|
23
25
|
nitro.hooks.hook("prerender:generate", async (route) => {
|
|
24
26
|
if (!route.fileName?.endsWith(".md")) {
|
|
25
27
|
return;
|
|
26
28
|
}
|
|
29
|
+
if (!writer) {
|
|
30
|
+
const siteConfig = useSiteConfig();
|
|
31
|
+
const stream = createLlmsTxtStream({
|
|
32
|
+
siteName: siteConfig.name || siteConfig.url,
|
|
33
|
+
description: siteConfig.description,
|
|
34
|
+
origin: siteConfig.url,
|
|
35
|
+
generateFull: true,
|
|
36
|
+
outputDir: nitro.options.output.publicDir
|
|
37
|
+
});
|
|
38
|
+
writer = stream.getWriter();
|
|
39
|
+
}
|
|
27
40
|
const { markdown, title, description } = JSON.parse(route.contents || "{}");
|
|
28
|
-
|
|
41
|
+
await writer.write({
|
|
29
42
|
filePath: route.fileName,
|
|
30
43
|
url: route.route,
|
|
31
44
|
title,
|
|
@@ -34,68 +47,37 @@ function setupPrerenderHandler() {
|
|
|
34
47
|
description,
|
|
35
48
|
title
|
|
36
49
|
}
|
|
37
|
-
};
|
|
38
|
-
|
|
50
|
+
});
|
|
51
|
+
pageCount++;
|
|
39
52
|
route.contents = markdown;
|
|
40
53
|
});
|
|
41
54
|
nitro.hooks.hook("prerender:done", async () => {
|
|
42
|
-
if (
|
|
55
|
+
if (!writer) {
|
|
43
56
|
return;
|
|
44
57
|
}
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
logger.success(`Generated markdown for ${pages.length} pages`);
|
|
55
|
-
const hookPayload = {
|
|
56
|
-
content: artifacts.llmsTxt || "",
|
|
57
|
-
fullContent: artifacts.llmsFullTxt || "",
|
|
58
|
-
pages
|
|
59
|
-
};
|
|
60
|
-
const llmsTxtConfig = nuxt.options.runtimeConfig["nuxt-ai-ready"].llmsTxt;
|
|
61
|
-
const normalizedContent = normalizeLlmsTxtConfig(llmsTxtConfig);
|
|
62
|
-
if (normalizedContent) {
|
|
63
|
-
hookPayload.content = `${hookPayload.content}
|
|
64
|
-
|
|
65
|
-
${normalizedContent}
|
|
66
|
-
`;
|
|
67
|
-
}
|
|
68
|
-
await nuxt.hooks.callHook("ai-ready:llms-txt", hookPayload);
|
|
69
|
-
const finalLlmsTxt = hookPayload.content;
|
|
70
|
-
const finalLlmsFullTxt = hookPayload.fullContent;
|
|
71
|
-
const generatedFiles = [];
|
|
72
|
-
if (finalLlmsTxt) {
|
|
73
|
-
const llmsTxtPath = join(nitro.options.output.publicDir, "llms.txt");
|
|
74
|
-
await writeFile(llmsTxtPath, finalLlmsTxt, "utf-8");
|
|
75
|
-
const sizeKb = (Buffer.byteLength(finalLlmsTxt, "utf-8") / 1024).toFixed(2);
|
|
76
|
-
generatedFiles.push({ path: "llms.txt", size: `${sizeKb}kb` });
|
|
77
|
-
nitro._prerenderedRoutes.push({
|
|
58
|
+
await writer.close();
|
|
59
|
+
const llmsTxtPath = join(nitro.options.output.publicDir, "llms.txt");
|
|
60
|
+
const llmsFullTxtPath = join(nitro.options.output.publicDir, "llms-full.txt");
|
|
61
|
+
const [llmsStats, llmsFullStats] = await Promise.all([
|
|
62
|
+
stat(llmsTxtPath),
|
|
63
|
+
stat(llmsFullTxtPath)
|
|
64
|
+
]);
|
|
65
|
+
nitro._prerenderedRoutes.push(
|
|
66
|
+
{
|
|
78
67
|
route: "/llms.txt",
|
|
79
68
|
fileName: llmsTxtPath,
|
|
80
69
|
generateTimeMS: 0
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (finalLlmsFullTxt) {
|
|
84
|
-
const llmsFullTxtPath = join(nitro.options.output.publicDir, "llms-full.txt");
|
|
85
|
-
await writeFile(llmsFullTxtPath, finalLlmsFullTxt, "utf-8");
|
|
86
|
-
const sizeKb = (Buffer.byteLength(finalLlmsFullTxt, "utf-8") / 1024).toFixed(2);
|
|
87
|
-
generatedFiles.push({ path: "llms-full.txt", size: `${sizeKb}kb` });
|
|
88
|
-
nitro._prerenderedRoutes.push({
|
|
70
|
+
},
|
|
71
|
+
{
|
|
89
72
|
route: "/llms-full.txt",
|
|
90
73
|
fileName: llmsFullTxtPath,
|
|
91
74
|
generateTimeMS: 0
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
const elapsed = Date.now() - startTime;
|
|
78
|
+
const llmsKb = (llmsStats.size / 1024).toFixed(2);
|
|
79
|
+
const llmsFullKb = (llmsFullStats.size / 1024).toFixed(2);
|
|
80
|
+
logger.info(`Generated llms.txt (${llmsKb}kb) and llms-full.txt (${llmsFullKb}kb) from ${pageCount} pages in ${elapsed}ms`);
|
|
99
81
|
});
|
|
100
82
|
});
|
|
101
83
|
}
|
|
@@ -293,6 +275,9 @@ Returns JSONL (newline-delimited JSON) with all indexed content.`
|
|
|
293
275
|
if (typeof route._sitemap !== "undefined" && !route._sitemap) {
|
|
294
276
|
return;
|
|
295
277
|
}
|
|
278
|
+
if (isPathFile(route.route)) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
296
281
|
let title = "";
|
|
297
282
|
let description = "";
|
|
298
283
|
const headings = [];
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-ai-ready",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"description": "Best practice AI & LLM discoverability for Nuxt sites.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"@nuxt/kit": "4.2.1",
|
|
36
36
|
"consola": "^3.4.2",
|
|
37
37
|
"defu": "^6.1.4",
|
|
38
|
-
"mdream": "^0.
|
|
38
|
+
"mdream": "^0.15.0",
|
|
39
39
|
"minimatch": "^10.1.1",
|
|
40
40
|
"nuxt-site-config": "^3.2.11",
|
|
41
41
|
"pathe": "^2.0.3",
|