@blueking/chat-x 0.0.50 → 0.0.51-beta.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.
Files changed (147) hide show
  1. package/dist/ag-ui/types/contents.d.ts +2 -0
  2. package/dist/ag-ui/types/messages.d.ts +5 -0
  3. package/dist/common/constants.d.ts +1 -1
  4. package/dist/components/ai-buttons/file-upload-btn/file-upload-btn.vue.d.ts +0 -2
  5. package/dist/components/chat-content/file-content/file-content.vue.d.ts +5 -2
  6. package/dist/components/chat-content/file-content/upload-file-item.vue.d.ts +12 -0
  7. package/dist/components/chat-content/file-content/upload-image-item.vue.d.ts +21 -0
  8. package/dist/components/chat-input/ai-slash-editor/ai-slash-editor.vue.d.ts +1 -1
  9. package/dist/components/chat-input/build-default-placeholder.d.ts +7 -0
  10. package/dist/components/chat-input/chat-input.vue.d.ts +1 -1
  11. package/dist/components/chat-message/message-container/message-container.vue.d.ts +1 -0
  12. package/dist/components/chat-message/message-render/message-render.vue.d.ts +2 -0
  13. package/dist/components/chat-message/user-message/user-message.vue.d.ts +3 -1
  14. package/dist/components/index.d.ts +2 -1
  15. package/dist/components/message-tools/message-time/format-message-time.d.ts +8 -0
  16. package/dist/components/message-tools/message-time/message-time.vue.d.ts +8 -0
  17. package/dist/components/message-tools/message-tools.vue.d.ts +11 -1
  18. package/dist/composables/use-custom-tab.d.ts +5 -3
  19. package/dist/composables/use-global-config.d.ts +3 -0
  20. package/dist/composables/use-message-group.d.ts +150 -72
  21. package/dist/icons/execution.d.ts +6 -0
  22. package/dist/icons/tools.d.ts +3 -0
  23. package/dist/index.css +1 -1
  24. package/dist/index.js +3124 -2837
  25. package/dist/index.js.map +1 -1
  26. package/dist/lang/lang.d.ts +8 -7
  27. package/dist/mcp/generated/docs/ai-slash-input.md +2 -0
  28. package/dist/mcp/generated/docs/assistant-message.md +9 -7
  29. package/dist/mcp/generated/docs/chat-container.md +38 -32
  30. package/dist/mcp/generated/docs/chat-input.md +18 -12
  31. package/dist/mcp/generated/docs/cite-content.md +3 -3
  32. package/dist/mcp/generated/docs/desc-panel.md +32 -10
  33. package/dist/mcp/generated/docs/execution-summary.md +3 -3
  34. package/dist/mcp/generated/docs/file-artifact-panel.md +6 -4
  35. package/dist/mcp/generated/docs/file-content.md +89 -73
  36. package/dist/mcp/generated/docs/file-upload-btn.md +16 -18
  37. package/dist/mcp/generated/docs/message-container.md +3 -0
  38. package/dist/mcp/generated/docs/message-render.md +2 -1
  39. package/dist/mcp/generated/docs/message-time.md +180 -0
  40. package/dist/mcp/generated/docs/message-tools.md +47 -12
  41. package/dist/mcp/generated/docs/messages.md +9 -0
  42. package/dist/mcp/generated/docs/toolcall-render.md +82 -43
  43. package/dist/mcp/generated/docs/use-artifact-preview.md +19 -17
  44. package/dist/mcp/generated/docs/use-custom-tab.md +12 -8
  45. package/dist/mcp/generated/docs/use-global-config.md +15 -5
  46. package/dist/mcp/generated/docs/user-message.md +9 -0
  47. package/dist/mcp/generated/docs/user-question-card.md +2 -0
  48. package/dist/mcp/generated/index.json +46 -6
  49. package/dist/types/input.d.ts +6 -0
  50. package/dist/utils/file.d.ts +7 -1
  51. package/dist/utils/index.d.ts +2 -0
  52. package/dist/utils/merge-tools-by-id.d.ts +6 -0
  53. package/dist/utils/upload-file.d.ts +35 -0
  54. package/package.json +3 -2
  55. package/skills/blueking-chat-x/SKILL.md +139 -0
  56. package/skills/blueking-chat-x/references/_index.md +131 -0
  57. package/skills/blueking-chat-x/references/components/activity-layout.md +134 -0
  58. package/skills/blueking-chat-x/references/components/activity-message.md +486 -0
  59. package/skills/blueking-chat-x/references/components/ai-image.md +230 -0
  60. package/skills/blueking-chat-x/references/components/ai-loading.md +131 -0
  61. package/skills/blueking-chat-x/references/components/ai-prompt-list.md +44 -0
  62. package/skills/blueking-chat-x/references/components/ai-selection.md +439 -0
  63. package/skills/blueking-chat-x/references/components/ai-skill-list.md +73 -0
  64. package/skills/blueking-chat-x/references/components/ai-slash-editor.md +43 -0
  65. package/skills/blueking-chat-x/references/components/ai-slash-input.md +56 -0
  66. package/skills/blueking-chat-x/references/components/ai-slash-menu.md +42 -0
  67. package/skills/blueking-chat-x/references/components/animation-text.md +202 -0
  68. package/skills/blueking-chat-x/references/components/assistant-message.md +498 -0
  69. package/skills/blueking-chat-x/references/components/chat-container.md +869 -0
  70. package/skills/blueking-chat-x/references/components/chat-input.md +769 -0
  71. package/skills/blueking-chat-x/references/components/cite-content.md +142 -0
  72. package/skills/blueking-chat-x/references/components/code-content.md +211 -0
  73. package/skills/blueking-chat-x/references/components/common-error-content.md +73 -0
  74. package/skills/blueking-chat-x/references/components/content-render.md +233 -0
  75. package/skills/blueking-chat-x/references/components/delete-tool.md +191 -0
  76. package/skills/blueking-chat-x/references/components/desc-panel.md +162 -0
  77. package/skills/blueking-chat-x/references/components/detail-section.md +91 -0
  78. package/skills/blueking-chat-x/references/components/execution-summary.md +128 -0
  79. package/skills/blueking-chat-x/references/components/file-artifact-panel.md +289 -0
  80. package/skills/blueking-chat-x/references/components/file-content.md +319 -0
  81. package/skills/blueking-chat-x/references/components/file-icon.md +109 -0
  82. package/skills/blueking-chat-x/references/components/file-upload-btn.md +159 -0
  83. package/skills/blueking-chat-x/references/components/flow-agent-content.md +264 -0
  84. package/skills/blueking-chat-x/references/components/flow-agent-node-detail.md +236 -0
  85. package/skills/blueking-chat-x/references/components/highlight-keyword.md +146 -0
  86. package/skills/blueking-chat-x/references/components/image-content.md +182 -0
  87. package/skills/blueking-chat-x/references/components/image-preview-group.md +184 -0
  88. package/skills/blueking-chat-x/references/components/image-preview.md +226 -0
  89. package/skills/blueking-chat-x/references/components/info-message.md +144 -0
  90. package/skills/blueking-chat-x/references/components/input-attachment.md +49 -0
  91. package/skills/blueking-chat-x/references/components/input-info-alert.md +42 -0
  92. package/skills/blueking-chat-x/references/components/interrupt-message.md +212 -0
  93. package/skills/blueking-chat-x/references/components/key-value-content.md +128 -0
  94. package/skills/blueking-chat-x/references/components/knowledge-rag-content.md +122 -0
  95. package/skills/blueking-chat-x/references/components/latex-content.md +200 -0
  96. package/skills/blueking-chat-x/references/components/loading-message.md +192 -0
  97. package/skills/blueking-chat-x/references/components/markdown-content.md +232 -0
  98. package/skills/blueking-chat-x/references/components/mermaid-content.md +189 -0
  99. package/skills/blueking-chat-x/references/components/message-container.md +645 -0
  100. package/skills/blueking-chat-x/references/components/message-loading.md +118 -0
  101. package/skills/blueking-chat-x/references/components/message-render.md +327 -0
  102. package/skills/blueking-chat-x/references/components/message-time.md +177 -0
  103. package/skills/blueking-chat-x/references/components/message-tools.md +416 -0
  104. package/skills/blueking-chat-x/references/components/model-selector.md +155 -0
  105. package/skills/blueking-chat-x/references/components/preview-toolbar.md +42 -0
  106. package/skills/blueking-chat-x/references/components/questions-container.md +85 -0
  107. package/skills/blueking-chat-x/references/components/reasoning-message.md +232 -0
  108. package/skills/blueking-chat-x/references/components/reference-content.md +135 -0
  109. package/skills/blueking-chat-x/references/components/reference-doc-content.md +109 -0
  110. package/skills/blueking-chat-x/references/components/scroll-btn.md +159 -0
  111. package/skills/blueking-chat-x/references/components/selection-footer.md +78 -0
  112. package/skills/blueking-chat-x/references/components/selection-question.md +88 -0
  113. package/skills/blueking-chat-x/references/components/shortcut-btn.md +204 -0
  114. package/skills/blueking-chat-x/references/components/shortcut-btns.md +266 -0
  115. package/skills/blueking-chat-x/references/components/shortcut-render.md +424 -0
  116. package/skills/blueking-chat-x/references/components/simple-table.md +101 -0
  117. package/skills/blueking-chat-x/references/components/text-content.md +77 -0
  118. package/skills/blueking-chat-x/references/components/tool-approval-card.md +183 -0
  119. package/skills/blueking-chat-x/references/components/tool-btn.md +317 -0
  120. package/skills/blueking-chat-x/references/components/tool-message.md +235 -0
  121. package/skills/blueking-chat-x/references/components/toolcall-render.md +348 -0
  122. package/skills/blueking-chat-x/references/components/user-feedback.md +233 -0
  123. package/skills/blueking-chat-x/references/components/user-message.md +424 -0
  124. package/skills/blueking-chat-x/references/components/user-question-answered-card.md +104 -0
  125. package/skills/blueking-chat-x/references/components/user-question-card.md +231 -0
  126. package/skills/blueking-chat-x/references/components/user-question-choice.md +105 -0
  127. package/skills/blueking-chat-x/references/components/user-question-option.md +42 -0
  128. package/skills/blueking-chat-x/references/components/vnode-renderer.md +122 -0
  129. package/skills/blueking-chat-x/references/composables/use-animation-text.md +196 -0
  130. package/skills/blueking-chat-x/references/composables/use-artifact-preview.md +231 -0
  131. package/skills/blueking-chat-x/references/composables/use-clipboard.md +203 -0
  132. package/skills/blueking-chat-x/references/composables/use-command-selection.md +150 -0
  133. package/skills/blueking-chat-x/references/composables/use-container-scroll.md +57 -0
  134. package/skills/blueking-chat-x/references/composables/use-custom-tab.md +158 -0
  135. package/skills/blueking-chat-x/references/composables/use-flow-node-actions.md +157 -0
  136. package/skills/blueking-chat-x/references/composables/use-full-screen.md +112 -0
  137. package/skills/blueking-chat-x/references/composables/use-global-config.md +148 -0
  138. package/skills/blueking-chat-x/references/composables/use-menu-keydown.md +163 -0
  139. package/skills/blueking-chat-x/references/composables/use-message-group.md +247 -0
  140. package/skills/blueking-chat-x/references/composables/use-observer-visible-list.md +188 -0
  141. package/skills/blueking-chat-x/references/composables/use-parent-scrolling.md +46 -0
  142. package/skills/blueking-chat-x/references/theme/theme.md +431 -0
  143. package/skills/blueking-chat-x/references/types/constants.md +307 -0
  144. package/skills/blueking-chat-x/references/types/interrupt.md +379 -0
  145. package/skills/blueking-chat-x/references/types/messages.md +553 -0
  146. package/skills/blueking-chat-x/references/types/schema.md +91 -0
  147. package/skills/blueking-chat-x/scripts/generate-references.mjs +314 -0
@@ -0,0 +1,314 @@
1
+ /*
2
+ * Tencent is pleased to support the open source community by making
3
+ * 蓝鲸智云PaaS平台 (BlueKing PaaS) available.
4
+ *
5
+ * Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
6
+ *
7
+ * 蓝鲸智云PaaS平台 (BlueKing PaaS) is licensed under the MIT License.
8
+ *
9
+ * License for 蓝鲸智云PaaS平台 (BlueKing PaaS):
10
+ *
11
+ * ---------------------------------------------------
12
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation
14
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
15
+ * to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16
+ *
17
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18
+ * the Software.
19
+ *
20
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21
+ * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24
+ * IN THE SOFTWARE.
25
+ */
26
+ /** biome-ignore-all lint/suspicious/noAssignInExpressions: <explanation> */
27
+
28
+ /**
29
+ * 从 wikis 生成 blueking-chat-x skill 的 references。
30
+ *
31
+ * 设计目标:把面向人类阅读的 VitePress 文档(含大量 demo 脚本/演示 HTML)清洗成
32
+ * LLM 友好的「使用方视角」精简文档——剥离演示噪音、保留完整 API 表格与示例代码。
33
+ *
34
+ * 与 mcp/scripts/build-index.ts 共享清洗思路,但本脚本:
35
+ * 1. 强化代码围栏处理:正确识别 ````vue 内嵌套 ``` 的情况,避免误删示例里的 <script setup>;
36
+ * 2. 按「使用方」需要的范围生成(组件全量 + composables/types/theme),并产出能力地图索引。
37
+ *
38
+ * 运行(在 packages/chat-x 下,依赖 glob / gray-matter 已在 devDependencies):
39
+ * node skills/blueking-chat-x/scripts/generate-references.mjs
40
+ */
41
+
42
+ import { glob } from 'glob';
43
+ import matter from 'gray-matter';
44
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
45
+ import { basename, dirname, join, relative, resolve } from 'node:path';
46
+ import { fileURLToPath } from 'node:url';
47
+
48
+ const __filename = fileURLToPath(import.meta.url);
49
+ const __dirname = dirname(__filename);
50
+
51
+ // scripts/ -> blueking-chat-x -> skills -> chat-x
52
+ const WIKIS_DIR = resolve(__dirname, '../../../wikis');
53
+ const REFERENCES_DIR = resolve(__dirname, '../references');
54
+
55
+ /** 组件能力域:以 wikis/components/<domain>/ 目录为准,避免依赖 frontmatter.domain 出现的拼写漂移。 */
56
+ const DOMAIN_LABELS = {
57
+ setup: '对话搭建',
58
+ message: '消息系统',
59
+ rendering: '内容渲染',
60
+ medias: '媒体文件',
61
+ input: '输入交互',
62
+ agent: 'Agent 能力',
63
+ feedback: '工具与反馈',
64
+ helper: '辅助能力',
65
+ };
66
+
67
+ /** 生成范围:每条对应 references 下的一个子目录与一个 wikis glob。 */
68
+ const GROUPS = [
69
+ { key: 'components', label: '组件', pattern: 'components/*/*.md', grouped: true },
70
+ { key: 'composables', label: 'Composables 组合式函数', pattern: 'composables/*.md', grouped: false },
71
+ { key: 'types', label: '类型定义', pattern: 'types/*.md', grouped: false },
72
+ { key: 'theme', label: '主题', pattern: 'theme/*.md', grouped: false },
73
+ ];
74
+
75
+ const FENCE_RE = /^(\s*)(`{3,}|~{3,})(.*)$/;
76
+
77
+ /** 生成能力地图索引:组件按能力域分组,其余按组列出。 */
78
+ function buildIndexDoc(index) {
79
+ const lines = [];
80
+ lines.push('# @blueking/chat-x 能力地图(自动生成)');
81
+ lines.push('');
82
+ lines.push('> 由 `scripts/generate-references.mjs` 从 `wikis/` 生成,请勿手改。');
83
+ lines.push('> 查某个能力时:先在本索引定位 slug,再读对应 `path` 的 reference 文档。');
84
+ lines.push('');
85
+ lines.push(`> 生成时间:${index.generatedAt}`);
86
+ lines.push('');
87
+
88
+ lines.push('## 组件(按能力域)');
89
+ lines.push('');
90
+ for (const domainKey of Object.keys(DOMAIN_LABELS)) {
91
+ const list = index.components[domainKey];
92
+ if (!list?.length) continue;
93
+ lines.push(`### ${DOMAIN_LABELS[domainKey]}`);
94
+ lines.push('');
95
+ for (const entry of list.sort((a, b) => a.slug.localeCompare(b.slug))) {
96
+ lines.push(`- **${entry.name}** — ${entry.description} → \`${entry.path}\``);
97
+ }
98
+ lines.push('');
99
+ }
100
+
101
+ for (const group of GROUPS) {
102
+ if (group.grouped) continue;
103
+ const list = index[group.key];
104
+ if (!list?.length) continue;
105
+ lines.push(`## ${group.label}`);
106
+ lines.push('');
107
+ for (const entry of list.sort((a, b) => a.slug.localeCompare(b.slug))) {
108
+ lines.push(`- **${entry.name}** — ${entry.description} → \`${entry.path}\``);
109
+ }
110
+ lines.push('');
111
+ }
112
+
113
+ return lines.join('\n');
114
+ }
115
+
116
+ /** 组装单个 reference 文档:精简元信息头 + 关联组件 + 清洗后的完整正文。 */
117
+ function buildReferenceDoc(meta, cleanedBody) {
118
+ const lines = [];
119
+ lines.push(`# ${meta.name}`);
120
+ lines.push('');
121
+
122
+ const tags = [];
123
+ if (meta.domainLabel) tags.push(`能力域:${meta.domainLabel}`);
124
+ if (meta.symbol) tags.push(`导入:\`import { ${meta.symbol} } from '@blueking/chat-x'\``);
125
+ if (meta.since) tags.push(`since ${meta.since}`);
126
+ if (tags.length) {
127
+ lines.push(`> ${tags.join(' | ')}`);
128
+ lines.push('');
129
+ }
130
+
131
+ if (meta.aiSummary) {
132
+ lines.push(meta.aiSummary.trim());
133
+ lines.push('');
134
+ }
135
+
136
+ if (meta.related.length) {
137
+ lines.push(`**关联**:${meta.related.map(r => (r.relation ? `${r.slug}(${r.relation})` : r.slug)).join('、')}`);
138
+ lines.push('');
139
+ }
140
+
141
+ lines.push('---');
142
+ lines.push('');
143
+ lines.push(cleanedBody);
144
+ lines.push('');
145
+
146
+ return lines.join('\n');
147
+ }
148
+
149
+ /**
150
+ * 清洗 wiki 正文:剥离 <script> demo 块、<div class="demo"> 演示块、内联 style,
151
+ * 并合并多余空行。代码围栏内的内容原样保留。
152
+ *
153
+ * 围栏处理采用 CommonMark 规则:记录开围栏的字符与长度,只有「同字符、长度 >= 开围栏、
154
+ * 且其后无信息串」的行才视为闭围栏。这样 ````vue 内的 ``` 会被当作内容,
155
+ * 不会误把示例里的 <script setup> 当成需剥离的 VitePress demo。
156
+ */
157
+ function cleanMarkdownBody(rawBody) {
158
+ const lines = rawBody.split('\n');
159
+ const out = [];
160
+ let fence = null; // { char, len }
161
+ let i = 0;
162
+
163
+ while (i < lines.length) {
164
+ const line = lines[i];
165
+ const fenceMatch = line.match(FENCE_RE);
166
+
167
+ if (fenceMatch) {
168
+ const marker = fenceMatch[2];
169
+ const char = marker[0];
170
+ const len = marker.length;
171
+ const rest = fenceMatch[3].trim();
172
+
173
+ if (!fence) {
174
+ fence = { char, len };
175
+ } else if (char === fence.char && len >= fence.len && rest === '') {
176
+ fence = null;
177
+ }
178
+ out.push(line);
179
+ i++;
180
+ continue;
181
+ }
182
+
183
+ if (fence) {
184
+ out.push(line);
185
+ i++;
186
+ continue;
187
+ }
188
+
189
+ // 以下分支仅在围栏外生效——剥离 VitePress 演示噪音
190
+ if (/<script\b/i.test(line)) {
191
+ if (/<\/script>/i.test(line)) {
192
+ i++;
193
+ continue;
194
+ }
195
+ i++;
196
+ while (i < lines.length && !/<\/script>/i.test(lines[i])) {
197
+ i++;
198
+ }
199
+ if (i < lines.length) i++;
200
+ continue;
201
+ }
202
+
203
+ if (/<div[^>]*\bclass="demo"[^>]*>/i.test(line)) {
204
+ let depth = 0;
205
+ const start = i;
206
+ while (i < lines.length) {
207
+ depth += countDivDelta(lines[i]);
208
+ i++;
209
+ if (depth <= 0) break;
210
+ }
211
+ if (i === start) i++;
212
+ continue;
213
+ }
214
+
215
+ out.push(stripInlineStyles(line));
216
+ i++;
217
+ }
218
+
219
+ return mergeBlankLines(out.join('\n')).trim();
220
+ }
221
+
222
+ function countDivDelta(line) {
223
+ const opens = (line.match(/<div\b/gi) ?? []).length;
224
+ const closes = (line.match(/<\/div>/gi) ?? []).length;
225
+ return opens - closes;
226
+ }
227
+
228
+ /** frontmatter.name 形如 "ChatContainer 聊天容器",首段若是合法标识符则视为导入符号。 */
229
+ function extractSymbol(name) {
230
+ const first = String(name).trim().split(/\s+/)[0] ?? '';
231
+ return /^[A-Za-z][A-Za-z0-9]*$/.test(first) ? first : '';
232
+ }
233
+
234
+ function main() {
235
+ // 全量重建,避免删除/重命名后的残留
236
+ rmSync(REFERENCES_DIR, { recursive: true, force: true });
237
+ mkdirSync(REFERENCES_DIR, { recursive: true });
238
+
239
+ const index = {
240
+ generatedAt: new Date().toISOString(),
241
+ components: {}, // domainKey -> entries[]
242
+ composables: [],
243
+ types: [],
244
+ theme: [],
245
+ };
246
+
247
+ for (const group of GROUPS) {
248
+ const files = glob.sync(join(WIKIS_DIR, group.pattern)).sort();
249
+ const outDir = join(REFERENCES_DIR, group.key);
250
+ mkdirSync(outDir, { recursive: true });
251
+
252
+ for (const file of files) {
253
+ const fileName = basename(file, '.md');
254
+ if (fileName === 'index') continue;
255
+
256
+ const rel = relative(WIKIS_DIR, file).replace(/\\/g, '/');
257
+ const parsed = matter(readFileSync(file, 'utf-8'));
258
+ const data = parsed.data ?? {};
259
+
260
+ const slug = typeof data.slug === 'string' && data.slug.trim() ? data.slug.trim() : fileName;
261
+ const name = typeof data.name === 'string' && data.name.trim() ? data.name.trim() : slug;
262
+ const description = typeof data.description === 'string' ? data.description.trim() : '';
263
+ const aiSummary =
264
+ typeof data.aiSummary === 'string' && data.aiSummary.trim() ? data.aiSummary.trim() : description;
265
+ const since = typeof data.sinceVersion === 'string' ? data.sinceVersion.trim() : '';
266
+ const related = normalizeRelated(data.relatedComponents);
267
+ const symbol = extractSymbol(name);
268
+
269
+ // 组件能力域以目录为准:components/<domain>/<slug>.md
270
+ let domainKey = '';
271
+ let domainLabel = '';
272
+ if (group.grouped) {
273
+ domainKey = rel.split('/')[1] ?? 'helper';
274
+ domainLabel = DOMAIN_LABELS[domainKey] ?? domainKey;
275
+ }
276
+
277
+ const cleanedBody = cleanMarkdownBody(parsed.content);
278
+ const doc = buildReferenceDoc({ name, domainLabel, symbol, since, aiSummary, related }, cleanedBody);
279
+ writeFileSync(join(outDir, `${slug}.md`), doc);
280
+
281
+ const entry = { name, slug, description: description || aiSummary, path: `${group.key}/${slug}.md` };
282
+ if (group.grouped) {
283
+ (index.components[domainKey] ??= []).push({ ...entry, domainLabel });
284
+ } else {
285
+ index[group.key].push(entry);
286
+ }
287
+ }
288
+ }
289
+
290
+ writeFileSync(join(REFERENCES_DIR, '_index.md'), buildIndexDoc(index));
291
+
292
+ const componentCount = Object.values(index.components).reduce((acc, list) => acc + list.length, 0);
293
+ console.log(
294
+ `生成完成:components ${componentCount}、composables ${index.composables.length}、` +
295
+ `types ${index.types.length}、theme ${index.theme.length}`,
296
+ );
297
+ }
298
+
299
+ function mergeBlankLines(text) {
300
+ return text.replace(/\n{3,}/g, '\n\n');
301
+ }
302
+
303
+ function normalizeRelated(raw) {
304
+ if (!Array.isArray(raw)) return [];
305
+ return raw
306
+ .filter(item => item && typeof item === 'object' && 'slug' in item)
307
+ .map(item => ({ slug: String(item.slug), relation: 'relation' in item ? String(item.relation) : '' }));
308
+ }
309
+
310
+ function stripInlineStyles(line) {
311
+ return line.replace(/\sstyle="[^"]*"/gi, '');
312
+ }
313
+
314
+ main();