nuxt-ai-ready 0.5.1 → 0.5.3

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.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "nuxt": ">=4.0.0"
5
5
  },
6
6
  "configKey": "aiReady",
7
- "version": "0.5.1",
7
+ "version": "0.5.3",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
package/dist/module.mjs CHANGED
@@ -573,6 +573,8 @@ export {}
573
573
  const prerenderCacheDir = join(nuxt.options.rootDir, "node_modules/.cache/nuxt-seo/ai-ready/routes");
574
574
  const pageDataPath = join(nuxt.options.buildDir, ".data/ai-ready/page-data.jsonl");
575
575
  nuxt.hooks.hook("nitro:config", (nitroConfig) => {
576
+ nitroConfig.experimental = nitroConfig.experimental || {};
577
+ nitroConfig.experimental.asyncContext = true;
576
578
  nitroConfig.virtual = nitroConfig.virtual || {};
577
579
  nitroConfig.virtual["#ai-ready-virtual/read-page-data.mjs"] = `
578
580
  import { readFile } from 'node:fs/promises'
@@ -0,0 +1,32 @@
1
+ export declare const tools: readonly [{
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {};
5
+ cache: "1h";
6
+ handler(): Promise<{
7
+ content: {
8
+ type: "text";
9
+ text: string;
10
+ }[];
11
+ }>;
12
+ }, import("@nuxtjs/mcp-toolkit").McpToolDefinition<Readonly<{
13
+ [k: string]: import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>;
14
+ }>, Readonly<{
15
+ [k: string]: import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>;
16
+ }>>];
17
+ export declare const resources: readonly [{
18
+ uri: string;
19
+ name: string;
20
+ description: string;
21
+ metadata: {
22
+ mimeType: string;
23
+ };
24
+ cache: "1h";
25
+ handler(uri: URL): Promise<{
26
+ contents: {
27
+ uri: string;
28
+ mimeType: string;
29
+ text: string;
30
+ }[];
31
+ }>;
32
+ }];
@@ -0,0 +1,5 @@
1
+ import pages from "./server/mcp/resources/pages.js";
2
+ import listPages from "./server/mcp/tools/list-pages.js";
3
+ import searchPagesFuzzy from "./server/mcp/tools/search-pages-fuzzy.js";
4
+ export const tools = [listPages, searchPagesFuzzy];
5
+ export const resources = [pages];
@@ -19,9 +19,9 @@ export default eventHandler(async (event) => {
19
19
  } else {
20
20
  mode = "production";
21
21
  }
22
- const pages = await getPages();
23
- const pagesList = await getPagesList();
24
- const errorRoutes = await getErrorRoutes();
22
+ const pages = await getPages(event);
23
+ const pagesList = await getPagesList(event);
24
+ const errorRoutes = await getErrorRoutes(event);
25
25
  let source;
26
26
  if (isDev) {
27
27
  source = "empty (dev mode returns empty Map)";
@@ -51,13 +51,28 @@ export default eventHandler(async (event) => {
51
51
  } catch {
52
52
  readPageDataModuleInfo = { available: false, note: "Module not available" };
53
53
  }
54
- const publicData = await globalThis.$fetch("/__ai-ready/pages.json", {
55
- baseURL: "/"
56
- }).catch(() => null);
54
+ let publicData = null;
55
+ let jsonFileSource = "fetch('/__ai-ready/pages.json')";
56
+ const cfEnv = event.context?.cloudflare?.env;
57
+ if (cfEnv?.ASSETS?.fetch) {
58
+ try {
59
+ const response = await cfEnv.ASSETS.fetch(new Request("https://assets.local/__ai-ready/pages.json"));
60
+ if (response.ok) {
61
+ publicData = await response.json();
62
+ jsonFileSource = "env.ASSETS.fetch('/__ai-ready/pages.json')";
63
+ }
64
+ } catch {
65
+ }
66
+ }
67
+ if (!publicData) {
68
+ publicData = await globalThis.$fetch("/__ai-ready/pages.json", {
69
+ baseURL: "/"
70
+ }).catch(() => null);
71
+ }
57
72
  const jsonFileStatus = {
58
73
  available: !!publicData,
59
74
  pageCount: publicData?.pages?.length ?? 0,
60
- source: "fetch('/__ai-ready/pages.json')"
75
+ source: jsonFileSource
61
76
  };
62
77
  const issues = [];
63
78
  const suggestions = [];
@@ -1,3 +1,4 @@
1
+ import type { H3Event } from 'h3';
1
2
  /** Page entry from virtual module */
2
3
  export interface PageEntry {
3
4
  route: string;
@@ -18,8 +19,8 @@ export interface PageListItem {
18
19
  headings?: string;
19
20
  }
20
21
  /** Read page data - returns page data indexed by route */
21
- export declare function getPages(): Promise<Map<string, PageEntry>>;
22
+ export declare function getPages(event?: H3Event): Promise<Map<string, PageEntry>>;
22
23
  /** Get error routes detected during prerender */
23
- export declare function getErrorRoutes(): Promise<Set<string>>;
24
+ export declare function getErrorRoutes(event?: H3Event): Promise<Set<string>>;
24
25
  /** Get pages as flat list for MCP consumption */
25
- export declare function getPagesList(): Promise<PageListItem[]>;
26
+ export declare function getPagesList(event?: H3Event): Promise<PageListItem[]>;
@@ -1,19 +1,29 @@
1
- export async function getPages() {
1
+ import { useEvent } from "nitropack/runtime";
2
+ function getEventFromContext(providedEvent) {
3
+ if (providedEvent)
4
+ return providedEvent;
5
+ try {
6
+ return useEvent();
7
+ } catch {
8
+ return void 0;
9
+ }
10
+ }
11
+ export async function getPages(event) {
2
12
  if (import.meta.dev)
3
13
  return /* @__PURE__ */ new Map();
4
14
  if (import.meta.prerender)
5
15
  return (await readPrerenderedData()).pages;
6
- return (await readServerAssets()).pages;
16
+ return (await readServerAssets(getEventFromContext(event))).pages;
7
17
  }
8
- export async function getErrorRoutes() {
18
+ export async function getErrorRoutes(event) {
9
19
  if (import.meta.dev)
10
20
  return /* @__PURE__ */ new Set();
11
21
  if (import.meta.prerender)
12
22
  return (await readPrerenderedData()).errorRoutes;
13
- return (await readServerAssets()).errorRoutes;
23
+ return (await readServerAssets(getEventFromContext(event))).errorRoutes;
14
24
  }
15
- export async function getPagesList() {
16
- const pages = await getPages();
25
+ export async function getPagesList(event) {
26
+ const pages = await getPages(event);
17
27
  return Array.from(pages.values()).map((p) => ({
18
28
  route: p.route,
19
29
  title: p.title || p.route,
@@ -21,10 +31,23 @@ export async function getPagesList() {
21
31
  headings: p.headings || void 0
22
32
  }));
23
33
  }
24
- async function readServerAssets() {
25
- const data = await globalThis.$fetch("/__ai-ready/pages.json", {
26
- baseURL: "/"
27
- }).catch(() => null);
34
+ async function readServerAssets(event) {
35
+ let data = null;
36
+ const cfEnv = event?.context?.cloudflare?.env;
37
+ if (cfEnv?.ASSETS?.fetch) {
38
+ try {
39
+ const response = await cfEnv.ASSETS.fetch(new Request("https://assets.local/__ai-ready/pages.json"));
40
+ if (response.ok) {
41
+ data = await response.json();
42
+ }
43
+ } catch {
44
+ }
45
+ }
46
+ if (!data) {
47
+ data = await globalThis.$fetch("/__ai-ready/pages.json", {
48
+ baseURL: "/"
49
+ }).catch(() => null);
50
+ }
28
51
  if (!data)
29
52
  return { pages: /* @__PURE__ */ new Map(), errorRoutes: /* @__PURE__ */ new Set() };
30
53
  return {
package/mcp.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { McpResourceDefinition, McpToolDefinition } from '@nuxtjs/mcp-toolkit'
2
+
3
+ export declare const tools: readonly [McpToolDefinition, McpToolDefinition]
4
+ export declare const resources: readonly [McpResourceDefinition]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-ai-ready",
3
3
  "type": "module",
4
- "version": "0.5.1",
4
+ "version": "0.5.3",
5
5
  "description": "Best practice AI & LLM discoverability for Nuxt sites.",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -25,14 +25,19 @@
25
25
  ".": {
26
26
  "types": "./dist/types.d.mts",
27
27
  "import": "./dist/module.mjs"
28
+ },
29
+ "./mcp": {
30
+ "types": "./mcp.d.ts",
31
+ "import": "./dist/runtime/mcp.js"
28
32
  }
29
33
  },
30
34
  "main": "./dist/module.mjs",
31
35
  "files": [
32
- "dist"
36
+ "dist",
37
+ "mcp.d.ts"
33
38
  ],
34
39
  "peerDependencies": {
35
- "@nuxtjs/sitemap": "^7.5.0"
40
+ "@nuxtjs/sitemap": "^7.5.2"
36
41
  },
37
42
  "dependencies": {
38
43
  "@clack/prompts": "^0.11.0",
@@ -41,12 +46,12 @@
41
46
  "defu": "^6.1.4",
42
47
  "fuse.js": "^7.1.0",
43
48
  "mdream": "^0.15.3",
44
- "nuxt-site-config": "3.2.14",
49
+ "nuxt-site-config": "^3.2.16",
45
50
  "ofetch": "^1.5.1",
46
51
  "pathe": "^2.0.3",
47
52
  "pkg-types": "^2.3.0",
48
53
  "std-env": "3.10.0",
49
- "ufo": "^1.6.1",
54
+ "ufo": "^1.6.2",
50
55
  "unstorage": "^1.17.3"
51
56
  },
52
57
  "devDependencies": {
@@ -56,32 +61,33 @@
56
61
  "@nuxt/content": "^3.10.0",
57
62
  "@nuxt/devtools-ui-kit": "^3.1.1",
58
63
  "@nuxt/module-builder": "^1.0.2",
59
- "@nuxt/test-utils": "^3.21.0",
64
+ "@nuxt/test-utils": "^3.23.0",
60
65
  "@nuxtjs/color-mode": "^4.0.0",
61
66
  "@nuxtjs/eslint-config-typescript": "^12.1.0",
62
67
  "@nuxtjs/i18n": "^10.2.1",
63
- "@nuxtjs/mcp-toolkit": "^0.6.0",
68
+ "@nuxtjs/mcp-toolkit": "^0.6.1",
64
69
  "@nuxtjs/robots": "^5.6.7",
65
- "@nuxtjs/sitemap": "7.5.0",
70
+ "@nuxtjs/sitemap": "^7.5.2",
66
71
  "@vitest/coverage-v8": "^4.0.16",
67
72
  "@vueuse/nuxt": "^14.1.0",
68
- "agents": "^0.3.0",
73
+ "agents": "^0.3.3",
74
+ "ai": "^6.0.14",
69
75
  "better-sqlite3": "^12.5.0",
70
76
  "bumpp": "^10.3.2",
71
77
  "eslint": "^9.39.2",
72
78
  "execa": "^9.6.1",
73
79
  "happy-dom": "^20.0.11",
74
80
  "nuxt": "^4.2.2",
75
- "nuxt-site-config": "3.2.14",
81
+ "nuxt-site-config": "^3.2.16",
76
82
  "playwright": "^1.57.0",
77
83
  "playwright-core": "^1.57.0",
78
- "postgres": "^3.4.7",
84
+ "postgres": "^3.4.8",
79
85
  "typescript": "^5.9.3",
80
86
  "vitest": "^4.0.16",
81
87
  "vue": "^3.5.26",
82
88
  "vue-router": "^4.6.4",
83
- "vue-tsc": "^3.2.1",
84
- "zod": "^4.2.1"
89
+ "vue-tsc": "^3.2.2",
90
+ "zod": "^4.3.5"
85
91
  },
86
92
  "resolutions": {
87
93
  "nuxt-ai-ready": "workspace:*"