@movk/nuxt-docs 1.16.0 → 1.16.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/README.md CHANGED
@@ -1,3 +1,4 @@
1
+ [![Movk Nuxt Docs OG](https://docs.mhaibaraai.cn/_og/s/c_Docs,title_~546w5Luj5YyWIE51eHQg5paH5qGj5Li76aKY,description_~5Z-65LqOIE51eHQgNCDnmoTnjrDku6PmlofmoaPkuLvpopjvvIzpm4bmiJDnu4Tku7boh6rliqjljJbmlofmoaPjgIFBSSDogYrlpKnliqnmiYvjgIFNQ1AgU2VydmVyIOWSjOWujOaVtOeahOW8gOWPkeiAheS9k-mqjOS8mOWMluOAgg.png)](https://docs.mhaibaraai.cn/)
1
2
  [![Movk Nuxt Docs](https://docs.mhaibaraai.cn/og-image.png)](https://docs.mhaibaraai.cn/)
2
3
 
3
4
  > 基于 Nuxt 4 的现代文档主题,集成组件自动化文档、AI 聊天助手、MCP Server 和完整的开发者体验优化
@@ -21,7 +22,7 @@
21
22
  ### 🤖 AI 增强体验
22
23
 
23
24
  <div style="padding: 40px 0; display: flex; justify-content: center;">
24
- <img src="https://docs.mhaibaraai.cn/ai/AiChat.png" alt="AiChat" width="400">
25
+ <img src="https://docs.mhaibaraai.cn/ai/AiChat.png" alt="AiChat" width="400">
25
26
  </div>
26
27
 
27
28
  - **AI 聊天助手** - 内置智能文档助手,基于 Vercel AI SDK 支持多种 LLM 模型
@@ -201,11 +202,11 @@ export default defineNuxtConfig({
201
202
  ````md [md]
202
203
  ```mermaid
203
204
  graph TD
204
- A[开始] --> B{是否有效?}
205
- B -->|是| C[处理数据]
206
- B -->|否| D[显示错误]
207
- C --> E[完成]
208
- D --> E
205
+ A[开始] --> B{是否有效?}
206
+ B -->|是| C[处理数据]
207
+ B -->|否| D[显示错误]
208
+ C --> E[完成]
209
+ D --> E
209
210
  ```
210
211
  ````
211
212
 
@@ -218,9 +219,9 @@ graph TD
218
219
 
219
220
  **支持的图表类型:**
220
221
  - **流程图**(`flowchart`/`graph`):用于展示流程和决策
221
- ![Mermaid 流程图示例](https://docs.mhaibaraai.cn/mermaid/mermaid-flowchart.png)
222
+ ![Mermaid 流程图示例](https://docs.mhaibaraai.cn/mermaid/mermaid-flowchart.png)
222
223
  - **时序图**(`sequenceDiagram`):用于展示交互时序
223
- ![Mermaid 时序图示例](https://docs.mhaibaraai.cn/mermaid/mermaid-sequence.png)
224
+ ![Mermaid 时序图示例](https://docs.mhaibaraai.cn/mermaid/mermaid-sequence.png)
224
225
  - **类图**(`classDiagram`):用于展示类关系
225
226
  - **状态图**(`stateDiagram`):用于展示状态转换
226
227
  - **甘特图**(`gantt`):用于展示项目时间线
package/app/app.config.ts CHANGED
@@ -22,7 +22,6 @@ export default defineAppConfig({
22
22
  },
23
23
  header: {
24
24
  avatar: 'https://docs.mhaibaraai.cn/avatar.png',
25
- title: 'Movk Nuxt Docs',
26
25
  to: '/',
27
26
  search: true,
28
27
  colorMode: true,
@@ -98,8 +98,11 @@ function getToolIcon(part: ToolPart): string {
98
98
  const { toolIcon } = useToolCall(part.state, toolName, part.input || {} as any)
99
99
 
100
100
  const iconMap: Record<string, string> = {
101
- 'get-page': 'i-lucide-file-text',
102
- 'get-example': 'i-lucide-file-text',
101
+ 'get-page': 'i-lucide-book-open',
102
+ 'get-example': 'i-lucide-codepen',
103
+ 'list-examples': 'i-lucide-codesandbox',
104
+ 'list-getting-started-guides': 'i-lucide-square-play',
105
+ 'list-pages': 'i-lucide-book-minus',
103
106
  ...toolIcon
104
107
  }
105
108
 
package/modules/module.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { addComponentsDir, createResolver, defineNuxtModule, logger } from '@nuxt/kit'
2
2
  import type { ModuleDependencies } from 'nuxt/schema'
3
+ import { defu } from 'defu'
4
+ import { getGitBranch, getGitEnv, getLocalGitInfo } from '../utils/git'
5
+ import { getPackageJsonMetadata, inferSiteURL } from '../utils/meta'
6
+ import { createComponentMetaExcludeFilters } from '../utils/component-meta'
7
+ import { startCase, kebabCase } from '@movk/core'
8
+ import { updateSiteConfig } from 'nuxt-site-config/kit'
3
9
 
4
10
  export interface ModuleOptions {
5
11
  /**
@@ -29,17 +35,23 @@ export default defineNuxtModule<ModuleOptions>({
29
35
  },
30
36
  moduleDependencies(nuxt): ModuleDependencies {
31
37
  const userOptions = nuxt.options.movkNuxtDocs || {}
38
+
32
39
  return {
33
40
  ...userOptions.a11y !== false && {
34
41
  '@nuxt/a11y': {
35
- version: '^1.0.0-alpha.1'
42
+ version: '^1.0.0-alpha.1',
43
+ defaults: {
44
+ logIssues: false
45
+ }
36
46
  }
37
47
  }
38
48
  }
39
49
  },
40
- setup(options, nuxt) {
50
+ async setup(options, nuxt) {
41
51
  const { resolve } = createResolver(import.meta.url)
42
52
 
53
+ nuxt.options.alias['#ai-chat'] = resolve('./ai-chat/runtime')
54
+
43
55
  if (options.mermaid) {
44
56
  let mermaidAvailable = true
45
57
  try {
@@ -93,6 +105,74 @@ export default defineNuxtModule<ModuleOptions>({
93
105
  log.info('mermaid diagram support enabled')
94
106
  }
95
107
  }
108
+
109
+ const dir = nuxt.options.rootDir
110
+ const url = inferSiteURL()
111
+ const meta = await getPackageJsonMetadata(dir)
112
+ const gitInfo = await getLocalGitInfo(dir) || getGitEnv()
113
+
114
+ const site = defu(nuxt.options.site, {
115
+ url,
116
+ name: kebabCase(meta.name || gitInfo?.name || ''),
117
+ debug: false
118
+ })
119
+ updateSiteConfig(site)
120
+
121
+ const siteName = (typeof nuxt.options.site === 'object' && nuxt.options.site?.name) || meta.name || gitInfo?.name || ''
122
+
123
+ nuxt.options.llms = defu(nuxt.options.llms, {
124
+ domain: url || 'https://example.com',
125
+ title: siteName,
126
+ description: meta.description || '',
127
+ full: {
128
+ title: siteName,
129
+ description: meta.description || ''
130
+ }
131
+ })
132
+
133
+ nuxt.options.appConfig.header = defu(nuxt.options.appConfig.header, {
134
+ title: startCase(siteName)
135
+ })
136
+
137
+ nuxt.options.appConfig.seo = defu(nuxt.options.appConfig.seo, {
138
+ titleTemplate: `%s - ${siteName}`,
139
+ title: siteName,
140
+ description: meta.description || ''
141
+ })
142
+
143
+ nuxt.options.appConfig.github = defu(nuxt.options.appConfig.github, {
144
+ owner: gitInfo?.owner,
145
+ name: gitInfo?.name,
146
+ url: gitInfo?.url,
147
+ commitPath: 'src',
148
+ suffix: 'vue',
149
+ since: '2025-01-31T04:00:00Z',
150
+ branch: getGitBranch(),
151
+ per_page: 100,
152
+ until: new Date().toISOString()
153
+ })
154
+
155
+ const layerPath = resolve('..')
156
+
157
+ // @ts-ignore - component-meta is not typed
158
+ nuxt.hook('component-meta:extend', (options: any) => {
159
+ const userInclude = (nuxt.options.componentMeta && typeof nuxt.options.componentMeta === 'object')
160
+ ? nuxt.options.componentMeta.include || []
161
+ : []
162
+
163
+ options.exclude = [
164
+ ...(options.exclude || []),
165
+ ...createComponentMetaExcludeFilters(resolve, dir, layerPath, userInclude)
166
+ ]
167
+ })
168
+
169
+ nuxt.hook('nitro:config', (nitroConfig) => {
170
+ nitroConfig.publicAssets ||= []
171
+ nitroConfig.publicAssets.push({
172
+ dir: resolve('./runtime/public'),
173
+ maxAge: 60 * 60 * 24 * 30
174
+ })
175
+ })
96
176
  }
97
177
  })
98
178
 
package/nuxt.config.ts CHANGED
@@ -145,10 +145,6 @@ export default defineNuxtConfig({
145
145
  }
146
146
  },
147
147
 
148
- a11y: {
149
- logIssues: false
150
- },
151
-
152
148
  componentMeta: {
153
149
  metaFields: {
154
150
  type: false,
@@ -172,7 +168,7 @@ export default defineNuxtConfig({
172
168
 
173
169
  fonts: {
174
170
  families: [
175
- { name: 'Public Sans', global: true, provider: 'bunny' },
171
+ { name: 'Public Sans', global: true },
176
172
  { name: 'Noto Sans SC', global: true, provider: 'local' }
177
173
  ]
178
174
  },
@@ -194,5 +190,19 @@ export default defineNuxtConfig({
194
190
  // Must be defined before @nuxt/content setup,
195
191
  // otherwise Content LLMS module will overwrite it in modules:done.
196
192
  contentRawMarkdown: false
193
+ },
194
+
195
+ ogImage: {
196
+ zeroRuntime: true
197
+ },
198
+
199
+ robots: {
200
+ groups: [
201
+ {
202
+ userAgent: '*',
203
+ allow: '/'
204
+ }
205
+ ],
206
+ sitemap: '/sitemap.xml'
197
207
  }
198
208
  })
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@movk/nuxt-docs",
3
3
  "type": "module",
4
- "version": "1.16.0",
4
+ "version": "1.16.2",
5
5
  "private": false,
6
6
  "description": "Modern Nuxt 4 documentation theme with auto-generated component docs, AI chat assistant, MCP server, and complete developer experience optimization.",
7
7
  "author": "YiXuan <mhaibaraai@gmail.com>",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@ai-sdk/gateway": "^3.0.83",
43
43
  "@ai-sdk/mcp": "^1.0.30",
44
- "@ai-sdk/vue": "^3.0.140",
44
+ "@ai-sdk/vue": "^3.0.141",
45
45
  "@iconify-json/lucide": "^1.2.100",
46
46
  "@iconify-json/simple-icons": "^1.2.75",
47
47
  "@iconify-json/vscode-icons": "^1.2.45",
@@ -70,7 +70,8 @@
70
70
  "motion-v": "^2.2.0",
71
71
  "nuxt-component-meta": "^0.17.2",
72
72
  "nuxt-llms": "^0.2.0",
73
- "nuxt-og-image": "^6.2.6",
73
+ "nuxt-og-image": "^6.3.0",
74
+ "nuxt-site-config": "^4.0.7",
74
75
  "ohash": "^2.0.11",
75
76
  "pathe": "^2.0.3",
76
77
  "pkg-types": "^2.3.0",
@@ -13,7 +13,7 @@ export default defineMcpTool({
13
13
  content: [{ type: 'text' as const, text: result.code }]
14
14
  }
15
15
  } catch {
16
- return errorResult(`示例 '${exampleName}' 未找到。使用 list_examples 工具查看所有可用示例。`)
16
+ throw createError({ statusCode: 404, message: `示例 '${exampleName}' 未找到。使用 list_examples 工具查看所有可用示例。` })
17
17
  }
18
18
  }
19
19
  })
@@ -22,7 +22,7 @@ export default defineMcpTool({
22
22
  content: [{ type: 'text', text: JSON.stringify(content, null, 2) }]
23
23
  }
24
24
  } catch (error) {
25
- return errorResult(`获取页面失败: ${error}`)
25
+ throw createError({ statusCode: 500, message: `获取页面失败: ${error}` })
26
26
  }
27
27
  }
28
28
  })
@@ -5,6 +5,6 @@ export default defineMcpTool({
5
5
  description: '列出所有可用的示例和代码演示',
6
6
  cache: '1h',
7
7
  async handler() {
8
- return jsonResult(await listComponentExamples())
8
+ return await listComponentExamples()
9
9
  }
10
10
  })
@@ -22,6 +22,6 @@ export default defineMcpTool({
22
22
  navigation: page.navigation
23
23
  })).sort((a, b) => a.path.localeCompare(b.path))
24
24
 
25
- return jsonResult(result)
25
+ return result
26
26
  }
27
27
  })
@@ -8,10 +8,10 @@ export default defineMcpTool({
8
8
 
9
9
  const pages = await queryCollection(event, 'docs').all()
10
10
 
11
- return jsonResult(pages.map(doc => ({
11
+ return pages.map(doc => ({
12
12
  title: doc.title,
13
13
  description: doc.description,
14
14
  path: doc.path
15
- })))
15
+ }))
16
16
  }
17
17
  })
package/modules/config.ts DELETED
@@ -1,84 +0,0 @@
1
- import { createResolver, defineNuxtModule } from '@nuxt/kit'
2
- import { defu } from 'defu'
3
- import { getGitBranch, getGitEnv, getLocalGitInfo } from '../utils/git'
4
- import { getPackageJsonMetadata, inferSiteURL } from '../utils/meta'
5
- import { createComponentMetaExcludeFilters } from '../utils/component-meta'
6
-
7
- export default defineNuxtModule({
8
- meta: {
9
- name: 'config'
10
- },
11
- async setup(_options, nuxt) {
12
- const { resolve } = createResolver(import.meta.url)
13
-
14
- nuxt.options.alias['#ai-chat'] = resolve('./ai-chat/runtime')
15
-
16
- const dir = nuxt.options.rootDir
17
- const url = inferSiteURL()
18
- const meta = await getPackageJsonMetadata(dir)
19
- const gitInfo = await getLocalGitInfo(dir) || getGitEnv()
20
-
21
- const site = nuxt.options.site
22
- const siteName = (site && site.name) || meta.name || gitInfo?.name || ''
23
-
24
- nuxt.options.site = defu(nuxt.options.site, {
25
- url,
26
- name: siteName,
27
- debug: false
28
- })
29
-
30
- nuxt.options.llms = defu(nuxt.options.llms, {
31
- domain: url || 'https://example.com',
32
- title: siteName,
33
- description: meta.description || '',
34
- full: {
35
- title: siteName,
36
- description: meta.description || ''
37
- }
38
- })
39
-
40
- nuxt.options.appConfig.header = defu(nuxt.options.appConfig.header, {
41
- title: siteName
42
- })
43
-
44
- nuxt.options.appConfig.seo = defu(nuxt.options.appConfig.seo, {
45
- titleTemplate: `%s - ${siteName}`,
46
- title: siteName,
47
- description: meta.description || ''
48
- })
49
-
50
- nuxt.options.appConfig.github = defu(nuxt.options.appConfig.github, {
51
- owner: gitInfo?.owner,
52
- name: gitInfo?.name,
53
- url: gitInfo?.url,
54
- commitPath: 'src',
55
- suffix: 'vue',
56
- since: '2025-01-31T04:00:00Z',
57
- branch: getGitBranch(),
58
- per_page: 100,
59
- until: new Date().toISOString()
60
- })
61
-
62
- const layerPath = resolve('..')
63
-
64
- // @ts-ignore - component-meta is not typed
65
- nuxt.hook('component-meta:extend', (options: any) => {
66
- const userInclude = (nuxt.options.componentMeta && typeof nuxt.options.componentMeta === 'object')
67
- ? nuxt.options.componentMeta.include || []
68
- : []
69
-
70
- options.exclude = [
71
- ...(options.exclude || []),
72
- ...createComponentMetaExcludeFilters(resolve, dir, layerPath, userInclude)
73
- ]
74
- })
75
-
76
- nuxt.hook('nitro:config', (nitroConfig) => {
77
- nitroConfig.publicAssets ||= []
78
- nitroConfig.publicAssets.push({
79
- dir: resolve('./runtime/public'),
80
- maxAge: 60 * 60 * 24 * 30
81
- })
82
- })
83
- }
84
- })