@szc-ft/mcp-szcd-client 0.12.4 → 0.13.1
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/agents/qwen-extension/agents/szcd-component-expert.md +47 -21
- package/agents/src/szcd-component-expert.md +72 -31
- package/agents/src/tools.json +34 -74
- package/agents/szcd-component-expert.md +47 -21
- package/agents/szcd-component-expert.qoder.md +72 -31
- package/agents/szcd-component-expert.trae.md +58 -9
- package/mcp-proxy.js +20 -0
- package/package.json +1 -1
- package/qwen-extension/agents/szcd-component-expert.md +47 -21
- package/qwen-extension/qwen-extension.json +1 -1
- package/scripts/lib/claude-code.js +5 -0
- package/scripts/lib/common.js +33 -0
- package/scripts/lib/qoder.js +7 -0
- package/scripts/lib/qwen-code.js +43 -1
- package/scripts/lib/trae-cli.js +25 -3
- package/scripts/lib/trae-ide.js +15 -2
- package/scripts/postinstall.js +1 -0
|
@@ -78,27 +78,15 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
78
78
|
|
|
79
79
|
**这一步是核心,必须实际调用 MCP 工具查询,禁止凭记忆猜测 API。**
|
|
80
80
|
|
|
81
|
-
使用 MCP 工具获取组件信息和 API
|
|
82
|
-
|
|
83
|
-
- `
|
|
84
|
-
- `
|
|
85
|
-
- `
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
- `read_file` —
|
|
89
|
-
|
|
90
|
-
**映射规则**:
|
|
91
|
-
- 页面布局 → `TemplateMode`
|
|
92
|
-
- 查询表单 → `Query`(通过 config 配置字段)
|
|
93
|
-
- 数据表格 → `TableOrList`
|
|
94
|
-
- 左侧树 → `LeftTree`
|
|
95
|
-
- 弹窗/抽屉 → `ModelOrDrawer`
|
|
96
|
-
- 返回标题 → `TitleAndBack`
|
|
97
|
-
- 按钮 → Cover 层 `Button`
|
|
98
|
-
- 输入框 → Cover 层 `Input` 或 Query 的 valueType: 'input'
|
|
99
|
-
- 下拉选择 → Cover 层 `Select` 或 Query 的 valueType: 'select'
|
|
100
|
-
- 日期选择 → Cover 层 `DatePicker` 或 Query 的 valueType: 'datePicker'
|
|
101
|
-
- 树选择 → Query 的 valueType: 'treeSelect'
|
|
81
|
+
使用 MCP 工具获取组件信息和 API,**优先使用 Repowiki 语义搜索工具**:
|
|
82
|
+
|
|
83
|
+
- `search_components_semantic` — 基于 Repowiki 知识库的语义搜索,用自然语言描述匹配最适合的组件(**优先使用**)
|
|
84
|
+
- `get_component_full_profile` — 一站式获取组件全景画像。`name` 支持逗号分隔批量查询(如 `"Query,TableOrList"`),`depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入,**返回值是紧凑 Markdown 格式**(**推荐首选,一次调用替代多次查询**)
|
|
85
|
+
- `get_component_dependencies` — 查询组件依赖关系图,确认 hooks 和插槽关系
|
|
86
|
+
- `get_best_practices` — 获取组件使用最佳实践,指定 scenario 可获取组合最佳实践(如"左树右表页面")
|
|
87
|
+
- `get_style_injection_guide` — 查询组件样式注入方法,获取 CSS 覆盖路径和分配策略
|
|
88
|
+
- `read_file` — 读取组件源码(deep 模式信息不足时)
|
|
89
|
+
- `api_tool` — 拉取 API 文档(自动识别 YApi/Swagger)或联调测试接口
|
|
102
90
|
|
|
103
91
|
|
|
104
92
|
### 步骤5:匹配组件并确认方案(必做)
|
|
@@ -126,6 +114,44 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
126
114
|
- "是否需要补充表单校验规则?"
|
|
127
115
|
- "是否需要添加批量操作功能?"
|
|
128
116
|
|
|
117
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
118
|
+
|
|
119
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
120
|
+
|
|
121
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
122
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
123
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
124
|
+
4. **调用 `submit_feedback` 提交反馈**:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
参数示例:
|
|
128
|
+
{
|
|
129
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
130
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
131
|
+
"userQuery": "<用户的原始需求描述>",
|
|
132
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
133
|
+
"accuracyRating": <1-5>,
|
|
134
|
+
"adopted": <true/false>,
|
|
135
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
136
|
+
"contextSnapshot": {
|
|
137
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
138
|
+
"layoutType": "LeftRight",
|
|
139
|
+
"queryFields": ["name", "status", "date"]
|
|
140
|
+
},
|
|
141
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**toolType 映射规则**:
|
|
146
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
147
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
148
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
149
|
+
- Qoder CLI → `"qoder"`
|
|
150
|
+
- Cursor → `"cursor"`
|
|
151
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
152
|
+
- 其他 → `"generic"`
|
|
153
|
+
|
|
154
|
+
|
|
129
155
|
## 典型页面模式
|
|
130
156
|
|
|
131
157
|
### 模式1: 左右布局 + 查询 + 表格(最常见)
|
|
@@ -75,8 +75,8 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
75
75
|
|
|
76
76
|
| 任务类型 | 判断条件 | 流程 |
|
|
77
77
|
|---------|---------|------|
|
|
78
|
-
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6) |
|
|
79
|
-
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6) |
|
|
78
|
+
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6→7) |
|
|
79
|
+
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6→7) |
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
<!-- /INCLUDE:enhanced -->
|
|
@@ -159,44 +159,41 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
159
159
|
**这一步是核心,必须实际调用 MCP 工具查询,禁止凭记忆猜测 API。**
|
|
160
160
|
|
|
161
161
|
<!-- EXCLUDE:enhanced -->
|
|
162
|
-
使用 MCP 工具获取组件信息和 API
|
|
163
|
-
|
|
164
|
-
- `{{TOOL:
|
|
165
|
-
- `{{TOOL:
|
|
166
|
-
- `{{TOOL:
|
|
167
|
-
- `{{TOOL:
|
|
168
|
-
- `{{TOOL:
|
|
169
|
-
- `{{TOOL:read_file}}` —
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
- 页面布局 → `TemplateMode`
|
|
173
|
-
- 查询表单 → `Query`(通过 config 配置字段)
|
|
174
|
-
- 数据表格 → `TableOrList`
|
|
175
|
-
- 左侧树 → `LeftTree`
|
|
176
|
-
- 弹窗/抽屉 → `ModelOrDrawer`
|
|
177
|
-
- 返回标题 → `TitleAndBack`
|
|
178
|
-
- 按钮 → Cover 层 `Button`
|
|
179
|
-
- 输入框 → Cover 层 `Input` 或 Query 的 valueType: 'input'
|
|
180
|
-
- 下拉选择 → Cover 层 `Select` 或 Query 的 valueType: 'select'
|
|
181
|
-
- 日期选择 → Cover 层 `DatePicker` 或 Query 的 valueType: 'datePicker'
|
|
182
|
-
- 树选择 → Query 的 valueType: 'treeSelect'
|
|
162
|
+
使用 MCP 工具获取组件信息和 API,**优先使用 Repowiki 语义搜索工具**:
|
|
163
|
+
|
|
164
|
+
- `{{TOOL:search_components_semantic}}` — 基于 Repowiki 知识库的语义搜索,用自然语言描述匹配最适合的组件(**优先使用**)
|
|
165
|
+
- `{{TOOL:get_component_full_profile}}` — 一站式获取组件全景画像。`name` 支持逗号分隔批量查询(如 `"Query,TableOrList"`),`depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入,**返回值是紧凑 Markdown 格式**(**推荐首选,一次调用替代多次查询**)
|
|
166
|
+
- `{{TOOL:get_component_dependencies}}` — 查询组件依赖关系图,确认 hooks 和插槽关系
|
|
167
|
+
- `{{TOOL:get_best_practices}}` — 获取组件使用最佳实践,指定 scenario 可获取组合最佳实践(如"左树右表页面")
|
|
168
|
+
- `{{TOOL:get_style_injection_guide}}` — 查询组件样式注入方法,获取 CSS 覆盖路径和分配策略
|
|
169
|
+
- `{{TOOL:read_file}}` — 读取组件源码(deep 模式信息不足时)
|
|
170
|
+
- `{{TOOL:api_tool}}` — 拉取 API 文档(自动识别 YApi/Swagger)或联调测试接口
|
|
171
|
+
|
|
183
172
|
<!-- /EXCLUDE:enhanced -->
|
|
184
173
|
|
|
185
174
|
<!-- INCLUDE:enhanced -->
|
|
186
175
|
按以下顺序查询:
|
|
187
176
|
|
|
188
|
-
1.
|
|
177
|
+
1. **语义搜索匹配**:调用 `{{TOOL:search_components_semantic}}` 用自然语言描述搜索最匹配的组件(**优先使用**)
|
|
178
|
+
|
|
179
|
+
2. **批量获取全景画像**:调用 `{{TOOL:get_component_full_profile}}` 获取组件全景画像。关键用法:
|
|
180
|
+
- `name` 支持逗号分隔批量查询(如 `"Query,TableOrList,LeftTree"`),一次调用替代多次查询
|
|
181
|
+
- `depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入信息
|
|
182
|
+
- `depth="standard"` 获取完整 Props 表格 + 依赖 + 示例
|
|
183
|
+
- **返回值是紧凑 Markdown 格式**,直接阅读即可
|
|
184
|
+
|
|
185
|
+
3. **确认组合关系**:调用 `{{TOOL:get_component_dependencies}}` 获取核心组件的依赖图,确认:
|
|
189
186
|
- 必选组件和 hooks(如 TreeQueryTable 需要 LeftTree + Query + TableOrList + useLeftTree + useTable)
|
|
190
187
|
- 插槽组件(如 CustomOption 是 LeftTree 的插槽)
|
|
191
188
|
- 检查 `llmMappingHints` 是否有针对当前组件的常见错误修正
|
|
192
189
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
190
|
+
4. **组合最佳实践**(可选):调用 `{{TOOL:get_best_practices}}`(scenario="页面场景描述")获取页面级组件组合最佳实践
|
|
191
|
+
|
|
192
|
+
5. **样式注入**(可选):调用 `{{TOOL:get_style_injection_guide}}` 获取样式覆盖方式和 CSS 穿透路径
|
|
196
193
|
|
|
197
|
-
|
|
194
|
+
6. **读取源码**(仅在 deep 模式信息不足时):调用 `{{TOOL:read_file}}` 读取具体源码文件确认行为
|
|
198
195
|
|
|
199
|
-
|
|
196
|
+
7. **API 联调**(如需要后端接口):调用 `{{TOOL:api_tool}}`(action="fetch" 拉取文档,action="test" 联调测试)
|
|
200
197
|
<!-- /INCLUDE:enhanced -->
|
|
201
198
|
|
|
202
199
|
<!-- INCLUDE:full -->
|
|
@@ -238,7 +235,7 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
238
235
|
<!-- /INCLUDE:enhanced -->
|
|
239
236
|
|
|
240
237
|
<!-- INCLUDE:full -->
|
|
241
|
-
|
|
238
|
+
**交互节点**:向用户确认:
|
|
242
239
|
- "以上组件方案是否合适?是否需要调整?"
|
|
243
240
|
- 提供选项:同意方案 / 需要调整 / 换一个方案
|
|
244
241
|
<!-- /INCLUDE:full -->
|
|
@@ -270,7 +267,50 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
270
267
|
- "代码已生成,是否需要调整样式或交互细节?"
|
|
271
268
|
- "是否需要补充表单校验规则?"
|
|
272
269
|
- "是否需要添加批量操作功能?"
|
|
270
|
+
<!-- /EXCLUDE:enhanced -->
|
|
271
|
+
|
|
272
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
273
|
+
|
|
274
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
275
|
+
|
|
276
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
277
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
278
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
279
|
+
4. **调用 `{{TOOL:submit_feedback}}` 提交反馈**:
|
|
273
280
|
|
|
281
|
+
```
|
|
282
|
+
参数示例:
|
|
283
|
+
{
|
|
284
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
285
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
286
|
+
"userQuery": "<用户的原始需求描述>",
|
|
287
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
288
|
+
"accuracyRating": <1-5>,
|
|
289
|
+
"adopted": <true/false>,
|
|
290
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
291
|
+
"contextSnapshot": {
|
|
292
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
293
|
+
"layoutType": "LeftRight",
|
|
294
|
+
"queryFields": ["name", "status", "date"]
|
|
295
|
+
},
|
|
296
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**toolType 映射规则**:
|
|
301
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
302
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
303
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
304
|
+
- Qoder CLI → `"qoder"`
|
|
305
|
+
- Cursor → `"cursor"`
|
|
306
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
307
|
+
- 其他 → `"generic"`
|
|
308
|
+
|
|
309
|
+
<!-- INCLUDE:enhanced -->
|
|
310
|
+
**注意**:此步骤不阻塞用户后续操作,即使反馈提交失败也不影响已生成的代码。
|
|
311
|
+
<!-- /INCLUDE:enhanced -->
|
|
312
|
+
|
|
313
|
+
<!-- EXCLUDE:enhanced -->
|
|
274
314
|
## 典型页面模式
|
|
275
315
|
|
|
276
316
|
### 模式1: 左右布局 + 查询 + 表格(最常见)
|
|
@@ -318,10 +358,11 @@ ProForm / ProFormWrapper
|
|
|
318
358
|
|
|
319
359
|
## 快速流程(简单查询类任务)
|
|
320
360
|
|
|
321
|
-
仅执行步骤1→4→6,跳过需求分析和方案确认:
|
|
361
|
+
仅执行步骤1→4→6→7,跳过需求分析和方案确认:
|
|
322
362
|
1. **架构认知 + 自检** — 同步骤1
|
|
323
363
|
2. **查询组件** — 按需查询目标组件(含依赖验证)
|
|
324
364
|
3. **输出结果** — 直接返回组件信息/API/示例
|
|
365
|
+
4. **收集反馈** — 同步骤7(如生成了代码则收集反馈)
|
|
325
366
|
|
|
326
367
|
---
|
|
327
368
|
|
package/agents/src/tools.json
CHANGED
|
@@ -5,108 +5,68 @@
|
|
|
5
5
|
"whenToUse": "步骤1:架构认知"
|
|
6
6
|
},
|
|
7
7
|
{
|
|
8
|
-
"name": "
|
|
9
|
-
"description": "
|
|
10
|
-
"whenToUse": "步骤4
|
|
11
|
-
},
|
|
12
|
-
{
|
|
13
|
-
"name": "get_other_component",
|
|
14
|
-
"description": "获取复合组件详情(路径、Props、透传目标、示例)",
|
|
15
|
-
"whenToUse": "步骤4:获取组件详情"
|
|
8
|
+
"name": "search_components_semantic",
|
|
9
|
+
"description": "基于Repowiki知识库的语义搜索,用自然语言描述匹配最适合的组件",
|
|
10
|
+
"whenToUse": "步骤4:语义搜索匹配"
|
|
16
11
|
},
|
|
17
12
|
{
|
|
18
|
-
"name": "
|
|
19
|
-
"description": "获取
|
|
20
|
-
"whenToUse": "步骤4
|
|
13
|
+
"name": "get_component_full_profile",
|
|
14
|
+
"description": "一站式获取组件全景画像。name支持逗号分隔批量查询,depth=deep获取Props链+源码摘要+样式注入,返回值是紧凑Markdown格式",
|
|
15
|
+
"whenToUse": "步骤4:批量获取全景画像"
|
|
21
16
|
},
|
|
22
17
|
{
|
|
23
|
-
"name": "
|
|
24
|
-
"description": "
|
|
25
|
-
"whenToUse": "步骤4
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"name": "search_component_examples",
|
|
29
|
-
"description": "搜索组件使用示例",
|
|
30
|
-
"whenToUse": "步骤4:查找示例"
|
|
18
|
+
"name": "get_component_dependencies",
|
|
19
|
+
"description": "查询组件依赖关系图(依赖谁/被谁依赖/hooks依赖)",
|
|
20
|
+
"whenToUse": "步骤4:确认组合关系"
|
|
31
21
|
},
|
|
32
22
|
{
|
|
33
|
-
"name": "
|
|
34
|
-
"description": "
|
|
35
|
-
"whenToUse": "
|
|
23
|
+
"name": "get_best_practices",
|
|
24
|
+
"description": "获取组件使用最佳实践和常见错误修正,指定scenario可获取组合最佳实践",
|
|
25
|
+
"whenToUse": "步骤4:组合最佳实践"
|
|
36
26
|
},
|
|
37
27
|
{
|
|
38
|
-
"name": "
|
|
39
|
-
"description": "
|
|
40
|
-
"whenToUse": "
|
|
28
|
+
"name": "get_style_injection_guide",
|
|
29
|
+
"description": "查询组件样式注入方法、CSS穿透路径、优先级和反模式",
|
|
30
|
+
"whenToUse": "步骤5:样式注入"
|
|
41
31
|
},
|
|
42
32
|
{
|
|
43
33
|
"name": "read_file",
|
|
44
|
-
"description": "
|
|
45
|
-
"whenToUse": "
|
|
34
|
+
"description": "读取仓库内文件(组件源码/文档),组件源码无长度限制",
|
|
35
|
+
"whenToUse": "步骤6:读取源码确认"
|
|
46
36
|
},
|
|
47
37
|
{
|
|
48
38
|
"name": "analyze_design_image",
|
|
49
|
-
"description": "
|
|
39
|
+
"description": "分析UI设计稿,提取Token配置、CSS覆盖样式、视觉细节,支持pixel_perfect模式",
|
|
50
40
|
"whenToUse": "步骤3:分析设计稿"
|
|
51
41
|
},
|
|
52
42
|
{
|
|
53
|
-
"name": "
|
|
54
|
-
"description": "
|
|
55
|
-
"whenToUse": "
|
|
43
|
+
"name": "api_tool",
|
|
44
|
+
"description": "统一API工具:自动识别YApi/Swagger拉取API文档、联调测试、配置管理",
|
|
45
|
+
"whenToUse": "API联调"
|
|
56
46
|
},
|
|
57
47
|
{
|
|
58
|
-
"name": "
|
|
59
|
-
"description": "
|
|
60
|
-
"whenToUse": "
|
|
48
|
+
"name": "coding_fetch_issue",
|
|
49
|
+
"description": "获取CODING Issue(缺陷/需求)详情,支持URL自动解析",
|
|
50
|
+
"whenToUse": "获取需求详情"
|
|
61
51
|
},
|
|
62
52
|
{
|
|
63
|
-
"name": "
|
|
64
|
-
"description": "
|
|
65
|
-
"whenToUse": "
|
|
53
|
+
"name": "coding_config",
|
|
54
|
+
"description": "查看或设置CODING默认配置(baseUrl/projectId/账号/Cookie)",
|
|
55
|
+
"whenToUse": "配置CODING连接"
|
|
66
56
|
},
|
|
67
57
|
{
|
|
68
58
|
"name": "get_antd_component",
|
|
69
|
-
"description": "获取
|
|
70
|
-
"whenToUse": "需要底层
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
"name": "list_pro_components",
|
|
74
|
-
"description": "列出 ProComponents 组件分类概览",
|
|
75
|
-
"whenToUse": "需要了解 Pro 组件分类时"
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"name": "list_pro_components_by_category",
|
|
79
|
-
"description": "按分类列出 ProComponents 组件",
|
|
80
|
-
"whenToUse": "按分类查找 Pro 组件时"
|
|
59
|
+
"description": "获取Ant Design组件详细信息(中文名、描述、API文档、Props列表)",
|
|
60
|
+
"whenToUse": "需要底层antd组件时"
|
|
81
61
|
},
|
|
82
62
|
{
|
|
83
63
|
"name": "get_pro_component",
|
|
84
|
-
"description": "获取
|
|
85
|
-
"whenToUse": "需要
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
"name": "swagger_fetch_apis",
|
|
89
|
-
"description": "获取 Swagger API 列表",
|
|
90
|
-
"whenToUse": "需要 API 联调时"
|
|
91
|
-
},
|
|
92
|
-
{
|
|
93
|
-
"name": "swagger_test_api",
|
|
94
|
-
"description": "测试 Swagger API 接口",
|
|
95
|
-
"whenToUse": "需要测试 API 接口时"
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
"name": "coding_fetch_issue",
|
|
99
|
-
"description": "获取 CODING Issue(缺陷/需求)详情",
|
|
100
|
-
"whenToUse": "需要获取需求详情时"
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
"name": "coding_config",
|
|
104
|
-
"description": "查看或设置 CODING 默认配置",
|
|
105
|
-
"whenToUse": "配置 CODING 连接时"
|
|
64
|
+
"description": "获取ProComponents组件详细信息(特性说明、API文档、Props列表)",
|
|
65
|
+
"whenToUse": "需要Pro组件详情时"
|
|
106
66
|
},
|
|
107
67
|
{
|
|
108
|
-
"name": "
|
|
109
|
-
"description": "
|
|
110
|
-
"whenToUse": "
|
|
68
|
+
"name": "submit_feedback",
|
|
69
|
+
"description": "提交用户对AI生成结果的反馈(准确率评分、是否采纳、拒绝原因、上下文快照)",
|
|
70
|
+
"whenToUse": "步骤7:收集用户反馈"
|
|
111
71
|
}
|
|
112
72
|
]
|
|
@@ -82,27 +82,15 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
82
82
|
|
|
83
83
|
**这一步是核心,必须实际调用 MCP 工具查询,禁止凭记忆猜测 API。**
|
|
84
84
|
|
|
85
|
-
使用 MCP 工具获取组件信息和 API
|
|
86
|
-
|
|
87
|
-
- `
|
|
88
|
-
- `
|
|
89
|
-
- `
|
|
90
|
-
- `
|
|
91
|
-
- `
|
|
92
|
-
- `read_file` —
|
|
93
|
-
|
|
94
|
-
**映射规则**:
|
|
95
|
-
- 页面布局 → `TemplateMode`
|
|
96
|
-
- 查询表单 → `Query`(通过 config 配置字段)
|
|
97
|
-
- 数据表格 → `TableOrList`
|
|
98
|
-
- 左侧树 → `LeftTree`
|
|
99
|
-
- 弹窗/抽屉 → `ModelOrDrawer`
|
|
100
|
-
- 返回标题 → `TitleAndBack`
|
|
101
|
-
- 按钮 → Cover 层 `Button`
|
|
102
|
-
- 输入框 → Cover 层 `Input` 或 Query 的 valueType: 'input'
|
|
103
|
-
- 下拉选择 → Cover 层 `Select` 或 Query 的 valueType: 'select'
|
|
104
|
-
- 日期选择 → Cover 层 `DatePicker` 或 Query 的 valueType: 'datePicker'
|
|
105
|
-
- 树选择 → Query 的 valueType: 'treeSelect'
|
|
85
|
+
使用 MCP 工具获取组件信息和 API,**优先使用 Repowiki 语义搜索工具**:
|
|
86
|
+
|
|
87
|
+
- `search_components_semantic` — 基于 Repowiki 知识库的语义搜索,用自然语言描述匹配最适合的组件(**优先使用**)
|
|
88
|
+
- `get_component_full_profile` — 一站式获取组件全景画像。`name` 支持逗号分隔批量查询(如 `"Query,TableOrList"`),`depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入,**返回值是紧凑 Markdown 格式**(**推荐首选,一次调用替代多次查询**)
|
|
89
|
+
- `get_component_dependencies` — 查询组件依赖关系图,确认 hooks 和插槽关系
|
|
90
|
+
- `get_best_practices` — 获取组件使用最佳实践,指定 scenario 可获取组合最佳实践(如"左树右表页面")
|
|
91
|
+
- `get_style_injection_guide` — 查询组件样式注入方法,获取 CSS 覆盖路径和分配策略
|
|
92
|
+
- `read_file` — 读取组件源码(deep 模式信息不足时)
|
|
93
|
+
- `api_tool` — 拉取 API 文档(自动识别 YApi/Swagger)或联调测试接口
|
|
106
94
|
|
|
107
95
|
|
|
108
96
|
### 步骤5:匹配组件并确认方案(必做)
|
|
@@ -130,6 +118,44 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
130
118
|
- "是否需要补充表单校验规则?"
|
|
131
119
|
- "是否需要添加批量操作功能?"
|
|
132
120
|
|
|
121
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
122
|
+
|
|
123
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
124
|
+
|
|
125
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
126
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
127
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
128
|
+
4. **调用 `submit_feedback` 提交反馈**:
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
参数示例:
|
|
132
|
+
{
|
|
133
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
134
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
135
|
+
"userQuery": "<用户的原始需求描述>",
|
|
136
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
137
|
+
"accuracyRating": <1-5>,
|
|
138
|
+
"adopted": <true/false>,
|
|
139
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
140
|
+
"contextSnapshot": {
|
|
141
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
142
|
+
"layoutType": "LeftRight",
|
|
143
|
+
"queryFields": ["name", "status", "date"]
|
|
144
|
+
},
|
|
145
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**toolType 映射规则**:
|
|
150
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
151
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
152
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
153
|
+
- Qoder CLI → `"qoder"`
|
|
154
|
+
- Cursor → `"cursor"`
|
|
155
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
156
|
+
- 其他 → `"generic"`
|
|
157
|
+
|
|
158
|
+
|
|
133
159
|
## 典型页面模式
|
|
134
160
|
|
|
135
161
|
### 模式1: 左右布局 + 查询 + 表格(最常见)
|
|
@@ -45,27 +45,19 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
45
45
|
| 工具名 | 功能 | 何时使用 |
|
|
46
46
|
|--------|------|---------|
|
|
47
47
|
| `get_architecture_overview` | 获取7层架构图、模板组合模式、LLM映射错误提示 | 步骤1:架构认知 |
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `list_pro_components` | 列出 ProComponents 组件分类概览 | 需要了解 Pro 组件分类时 |
|
|
62
|
-
| `list_pro_components_by_category` | 按分类列出 ProComponents 组件 | 按分类查找 Pro 组件时 |
|
|
63
|
-
| `get_pro_component` | 获取 ProComponents 组件详细信息 | 需要 Pro 组件详情时 |
|
|
64
|
-
| `swagger_fetch_apis` | 获取 Swagger API 列表 | 需要 API 联调时 |
|
|
65
|
-
| `swagger_test_api` | 测试 Swagger API 接口 | 需要测试 API 接口时 |
|
|
66
|
-
| `coding_fetch_issue` | 获取 CODING Issue(缺陷/需求)详情 | 需要获取需求详情时 |
|
|
67
|
-
| `coding_config` | 查看或设置 CODING 默认配置 | 配置 CODING 连接时 |
|
|
68
|
-
| `refresh_component_docs` | 刷新组件文档缓存 | 缓存过期时 |
|
|
48
|
+
| `search_components_semantic` | 基于Repowiki知识库的语义搜索,用自然语言描述匹配最适合的组件 | 步骤4:语义搜索匹配 |
|
|
49
|
+
| `get_component_full_profile` | 一站式获取组件全景画像。name支持逗号分隔批量查询,depth=deep获取Props链+源码摘要+样式注入,返回值是紧凑Markdown格式 | 步骤4:批量获取全景画像 |
|
|
50
|
+
| `get_component_dependencies` | 查询组件依赖关系图(依赖谁/被谁依赖/hooks依赖) | 步骤4:确认组合关系 |
|
|
51
|
+
| `get_best_practices` | 获取组件使用最佳实践和常见错误修正,指定scenario可获取组合最佳实践 | 步骤4:组合最佳实践 |
|
|
52
|
+
| `get_style_injection_guide` | 查询组件样式注入方法、CSS穿透路径、优先级和反模式 | 步骤5:样式注入 |
|
|
53
|
+
| `read_file` | 读取仓库内文件(组件源码/文档),组件源码无长度限制 | 步骤6:读取源码确认 |
|
|
54
|
+
| `analyze_design_image` | 分析UI设计稿,提取Token配置、CSS覆盖样式、视觉细节,支持pixel_perfect模式 | 步骤3:分析设计稿 |
|
|
55
|
+
| `api_tool` | 统一API工具:自动识别YApi/Swagger拉取API文档、联调测试、配置管理 | API联调 |
|
|
56
|
+
| `coding_fetch_issue` | 获取CODING Issue(缺陷/需求)详情,支持URL自动解析 | 获取需求详情 |
|
|
57
|
+
| `coding_config` | 查看或设置CODING默认配置(baseUrl/projectId/账号/Cookie) | 配置CODING连接 |
|
|
58
|
+
| `get_antd_component` | 获取Ant Design组件详细信息(中文名、描述、API文档、Props列表) | 需要底层antd组件时 |
|
|
59
|
+
| `get_pro_component` | 获取ProComponents组件详细信息(特性说明、API文档、Props列表) | 需要Pro组件详情时 |
|
|
60
|
+
| `submit_feedback` | 提交用户对AI生成结果的反馈(准确率评分、是否采纳、拒绝原因、上下文快照) | 步骤7:收集用户反馈 |
|
|
69
61
|
|
|
70
62
|
## 流程分支:先判断任务类型
|
|
71
63
|
|
|
@@ -73,8 +65,8 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
73
65
|
|
|
74
66
|
| 任务类型 | 判断条件 | 流程 |
|
|
75
67
|
|---------|---------|------|
|
|
76
|
-
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6) |
|
|
77
|
-
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6) |
|
|
68
|
+
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6→7) |
|
|
69
|
+
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6→7) |
|
|
78
70
|
|
|
79
71
|
---
|
|
80
72
|
|
|
@@ -134,18 +126,26 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
134
126
|
|
|
135
127
|
按以下顺序查询:
|
|
136
128
|
|
|
137
|
-
1.
|
|
129
|
+
1. **语义搜索匹配**:调用 `search_components_semantic` 用自然语言描述搜索最匹配的组件(**优先使用**)
|
|
130
|
+
|
|
131
|
+
2. **批量获取全景画像**:调用 `get_component_full_profile` 获取组件全景画像。关键用法:
|
|
132
|
+
- `name` 支持逗号分隔批量查询(如 `"Query,TableOrList,LeftTree"`),一次调用替代多次查询
|
|
133
|
+
- `depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入信息
|
|
134
|
+
- `depth="standard"` 获取完整 Props 表格 + 依赖 + 示例
|
|
135
|
+
- **返回值是紧凑 Markdown 格式**,直接阅读即可
|
|
136
|
+
|
|
137
|
+
3. **确认组合关系**:调用 `get_component_dependencies` 获取核心组件的依赖图,确认:
|
|
138
138
|
- 必选组件和 hooks(如 TreeQueryTable 需要 LeftTree + Query + TableOrList + useLeftTree + useTable)
|
|
139
139
|
- 插槽组件(如 CustomOption 是 LeftTree 的插槽)
|
|
140
140
|
- 检查 `llmMappingHints` 是否有针对当前组件的常见错误修正
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
4. **组合最佳实践**(可选):调用 `get_best_practices`(scenario="页面场景描述")获取页面级组件组合最佳实践
|
|
143
|
+
|
|
144
|
+
5. **样式注入**(可选):调用 `get_style_injection_guide` 获取样式覆盖方式和 CSS 穿透路径
|
|
145
145
|
|
|
146
|
-
|
|
146
|
+
6. **读取源码**(仅在 deep 模式信息不足时):调用 `read_file` 读取具体源码文件确认行为
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
7. **API 联调**(如需要后端接口):调用 `api_tool`(action="fetch" 拉取文档,action="test" 联调测试)
|
|
149
149
|
|
|
150
150
|
**输出**:每个选用组件的 API 详情、Props 列表、依赖关系、使用示例
|
|
151
151
|
|
|
@@ -174,7 +174,7 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
174
174
|
[说明]
|
|
175
175
|
```
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
**交互节点**:向用户确认:
|
|
178
178
|
- "以上组件方案是否合适?是否需要调整?"
|
|
179
179
|
- 提供选项:同意方案 / 需要调整 / 换一个方案
|
|
180
180
|
|
|
@@ -195,16 +195,57 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
195
195
|
- Hooks 按依赖关系正确引入(如 useLeftTree、useTable)
|
|
196
196
|
|
|
197
197
|
|
|
198
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
199
|
+
|
|
200
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
201
|
+
|
|
202
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
203
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
204
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
205
|
+
4. **调用 `submit_feedback` 提交反馈**:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
参数示例:
|
|
209
|
+
{
|
|
210
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
211
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
212
|
+
"userQuery": "<用户的原始需求描述>",
|
|
213
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
214
|
+
"accuracyRating": <1-5>,
|
|
215
|
+
"adopted": <true/false>,
|
|
216
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
217
|
+
"contextSnapshot": {
|
|
218
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
219
|
+
"layoutType": "LeftRight",
|
|
220
|
+
"queryFields": ["name", "status", "date"]
|
|
221
|
+
},
|
|
222
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**toolType 映射规则**:
|
|
227
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
228
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
229
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
230
|
+
- Qoder CLI → `"qoder"`
|
|
231
|
+
- Cursor → `"cursor"`
|
|
232
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
233
|
+
- 其他 → `"generic"`
|
|
234
|
+
|
|
235
|
+
**注意**:此步骤不阻塞用户后续操作,即使反馈提交失败也不影响已生成的代码。
|
|
236
|
+
|
|
237
|
+
|
|
198
238
|
**输出**:完整代码文件 + 组件映射说明表 + 关键实现要点
|
|
199
239
|
|
|
200
240
|
---
|
|
201
241
|
|
|
202
242
|
## 快速流程(简单查询类任务)
|
|
203
243
|
|
|
204
|
-
仅执行步骤1→4→6,跳过需求分析和方案确认:
|
|
244
|
+
仅执行步骤1→4→6→7,跳过需求分析和方案确认:
|
|
205
245
|
1. **架构认知 + 自检** — 同步骤1
|
|
206
246
|
2. **查询组件** — 按需查询目标组件(含依赖验证)
|
|
207
247
|
3. **输出结果** — 直接返回组件信息/API/示例
|
|
248
|
+
4. **收集反馈** — 同步骤7(如生成了代码则收集反馈)
|
|
208
249
|
|
|
209
250
|
---
|
|
210
251
|
|
|
@@ -45,8 +45,8 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
45
45
|
|
|
46
46
|
| 任务类型 | 判断条件 | 流程 |
|
|
47
47
|
|---------|---------|------|
|
|
48
|
-
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6) |
|
|
49
|
-
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6) |
|
|
48
|
+
| **简单查询** | 只查组件信息/API/示例,不涉及代码生成 | 快速流程(步骤1→4→6→7) |
|
|
49
|
+
| **页面生成** | 需要根据需求/设计稿生成页面代码 | 完整流程(步骤1→2→3→4→5→6→7) |
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -98,18 +98,26 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
98
98
|
|
|
99
99
|
按以下顺序查询:
|
|
100
100
|
|
|
101
|
-
1.
|
|
101
|
+
1. **语义搜索匹配**:调用 `mcp__szcd-component-helper__search_components_semantic` 用自然语言描述搜索最匹配的组件(**优先使用**)
|
|
102
|
+
|
|
103
|
+
2. **批量获取全景画像**:调用 `mcp__szcd-component-helper__get_component_full_profile` 获取组件全景画像。关键用法:
|
|
104
|
+
- `name` 支持逗号分隔批量查询(如 `"Query,TableOrList,LeftTree"`),一次调用替代多次查询
|
|
105
|
+
- `depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入信息
|
|
106
|
+
- `depth="standard"` 获取完整 Props 表格 + 依赖 + 示例
|
|
107
|
+
- **返回值是紧凑 Markdown 格式**,直接阅读即可
|
|
108
|
+
|
|
109
|
+
3. **确认组合关系**:调用 `mcp__szcd-component-helper__get_component_dependencies` 获取核心组件的依赖图,确认:
|
|
102
110
|
- 必选组件和 hooks(如 TreeQueryTable 需要 LeftTree + Query + TableOrList + useLeftTree + useTable)
|
|
103
111
|
- 插槽组件(如 CustomOption 是 LeftTree 的插槽)
|
|
104
112
|
- 检查 `llmMappingHints` 是否有针对当前组件的常见错误修正
|
|
105
113
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
114
|
+
4. **组合最佳实践**(可选):调用 `mcp__szcd-component-helper__get_best_practices`(scenario="页面场景描述")获取页面级组件组合最佳实践
|
|
115
|
+
|
|
116
|
+
5. **样式注入**(可选):调用 `mcp__szcd-component-helper__get_style_injection_guide` 获取样式覆盖方式和 CSS 穿透路径
|
|
109
117
|
|
|
110
|
-
|
|
118
|
+
6. **读取源码**(仅在 deep 模式信息不足时):调用 `mcp__szcd-component-helper__read_file` 读取具体源码文件确认行为
|
|
111
119
|
|
|
112
|
-
|
|
120
|
+
7. **API 联调**(如需要后端接口):调用 `mcp__szcd-component-helper__api_tool`(action="fetch" 拉取文档,action="test" 联调测试)
|
|
113
121
|
|
|
114
122
|
|
|
115
123
|
### 步骤5:匹配组件并确认方案(必做)
|
|
@@ -154,14 +162,55 @@ Ant Design → ProComponents → Cover 层 → Wrapper 层 → ProPackages →
|
|
|
154
162
|
- Hooks 按依赖关系正确引入(如 useLeftTree、useTable)
|
|
155
163
|
|
|
156
164
|
|
|
165
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
166
|
+
|
|
167
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
168
|
+
|
|
169
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
170
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
171
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
172
|
+
4. **调用 `mcp__szcd-component-helper__submit_feedback` 提交反馈**:
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
参数示例:
|
|
176
|
+
{
|
|
177
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
178
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
179
|
+
"userQuery": "<用户的原始需求描述>",
|
|
180
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
181
|
+
"accuracyRating": <1-5>,
|
|
182
|
+
"adopted": <true/false>,
|
|
183
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
184
|
+
"contextSnapshot": {
|
|
185
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
186
|
+
"layoutType": "LeftRight",
|
|
187
|
+
"queryFields": ["name", "status", "date"]
|
|
188
|
+
},
|
|
189
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**toolType 映射规则**:
|
|
194
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
195
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
196
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
197
|
+
- Qoder CLI → `"qoder"`
|
|
198
|
+
- Cursor → `"cursor"`
|
|
199
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
200
|
+
- 其他 → `"generic"`
|
|
201
|
+
|
|
202
|
+
**注意**:此步骤不阻塞用户后续操作,即使反馈提交失败也不影响已生成的代码。
|
|
203
|
+
|
|
204
|
+
|
|
157
205
|
---
|
|
158
206
|
|
|
159
207
|
## 快速流程(简单查询类任务)
|
|
160
208
|
|
|
161
|
-
仅执行步骤1→4→6,跳过需求分析和方案确认:
|
|
209
|
+
仅执行步骤1→4→6→7,跳过需求分析和方案确认:
|
|
162
210
|
1. **架构认知 + 自检** — 同步骤1
|
|
163
211
|
2. **查询组件** — 按需查询目标组件(含依赖验证)
|
|
164
212
|
3. **输出结果** — 直接返回组件信息/API/示例
|
|
213
|
+
4. **收集反馈** — 同步骤7(如生成了代码则收集反馈)
|
|
165
214
|
|
|
166
215
|
---
|
|
167
216
|
|
package/mcp-proxy.js
CHANGED
|
@@ -54,6 +54,14 @@ const SERVER_URL = process.env.MCP_SERVER_URL || fileConfig.MCP_SERVER_URL || "h
|
|
|
54
54
|
const SERVER_TIMEOUT = parseInt(process.env.MCP_TIMEOUT || fileConfig.MCP_TIMEOUT || "120000", 10);
|
|
55
55
|
const SERVER_API_KEY = process.env.MCP_API_KEY || fileConfig.MCP_API_KEY || "";
|
|
56
56
|
|
|
57
|
+
// 提取用户本地 CODING 配置,通过 Header 透传给服务器(服务器优先使用客户端配置)
|
|
58
|
+
const CLIENT_CODING_CONFIG = {};
|
|
59
|
+
if (fileConfig.CODING_BASE_URL) CLIENT_CODING_CONFIG.CODING_BASE_URL = fileConfig.CODING_BASE_URL;
|
|
60
|
+
if (fileConfig.CODING_DEFAULT_PROJECT_ID) CLIENT_CODING_CONFIG.CODING_DEFAULT_PROJECT_ID = fileConfig.CODING_DEFAULT_PROJECT_ID;
|
|
61
|
+
if (fileConfig.CODING_ACCOUNT) CLIENT_CODING_CONFIG.CODING_ACCOUNT = fileConfig.CODING_ACCOUNT;
|
|
62
|
+
if (fileConfig.CODING_COOKIES) CLIENT_CODING_CONFIG.CODING_COOKIES = fileConfig.CODING_COOKIES;
|
|
63
|
+
if (fileConfig.CODING_PASSWORD) CLIENT_CODING_CONFIG.CODING_PASSWORD = fileConfig.CODING_PASSWORD;
|
|
64
|
+
|
|
57
65
|
// ==================== 日志 ====================
|
|
58
66
|
|
|
59
67
|
function log(msg) {
|
|
@@ -138,6 +146,10 @@ function forwardToStreamableHttp(msg) {
|
|
|
138
146
|
if (httpSessionId) {
|
|
139
147
|
headers["Mcp-Session-Id"] = httpSessionId;
|
|
140
148
|
}
|
|
149
|
+
// 透传用户本地 CODING 配置给服务器
|
|
150
|
+
if (Object.keys(CLIENT_CODING_CONFIG).length > 0) {
|
|
151
|
+
headers["X-Client-Config"] = Buffer.from(JSON.stringify(CLIENT_CODING_CONFIG)).toString("base64");
|
|
152
|
+
}
|
|
141
153
|
|
|
142
154
|
const postData = JSON.stringify(msg);
|
|
143
155
|
|
|
@@ -262,6 +274,10 @@ function connectSSE() {
|
|
|
262
274
|
headers["X-API-Key"] = SERVER_API_KEY;
|
|
263
275
|
headers["Authorization"] = `Bearer ${SERVER_API_KEY}`;
|
|
264
276
|
}
|
|
277
|
+
// 透传用户本地 CODING 配置给服务器
|
|
278
|
+
if (Object.keys(CLIENT_CODING_CONFIG).length > 0) {
|
|
279
|
+
headers["X-Client-Config"] = Buffer.from(JSON.stringify(CLIENT_CODING_CONFIG)).toString("base64");
|
|
280
|
+
}
|
|
265
281
|
|
|
266
282
|
log(`Connecting to SSE endpoint: ${url.toString()}, headers: ${JSON.stringify(headers)}`);
|
|
267
283
|
|
|
@@ -334,6 +350,10 @@ function forwardToSSEMessageEndpoint(msg) {
|
|
|
334
350
|
headers["X-API-Key"] = SERVER_API_KEY;
|
|
335
351
|
headers["Authorization"] = `Bearer ${SERVER_API_KEY}`;
|
|
336
352
|
}
|
|
353
|
+
// 透传用户本地 CODING 配置给服务器
|
|
354
|
+
if (Object.keys(CLIENT_CODING_CONFIG).length > 0) {
|
|
355
|
+
headers["X-Client-Config"] = Buffer.from(JSON.stringify(CLIENT_CODING_CONFIG)).toString("base64");
|
|
356
|
+
}
|
|
337
357
|
|
|
338
358
|
const postData = JSON.stringify(msg);
|
|
339
359
|
|
package/package.json
CHANGED
|
@@ -78,27 +78,15 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
78
78
|
|
|
79
79
|
**这一步是核心,必须实际调用 MCP 工具查询,禁止凭记忆猜测 API。**
|
|
80
80
|
|
|
81
|
-
使用 MCP 工具获取组件信息和 API
|
|
82
|
-
|
|
83
|
-
- `
|
|
84
|
-
- `
|
|
85
|
-
- `
|
|
86
|
-
- `
|
|
87
|
-
- `
|
|
88
|
-
- `read_file` —
|
|
89
|
-
|
|
90
|
-
**映射规则**:
|
|
91
|
-
- 页面布局 → `TemplateMode`
|
|
92
|
-
- 查询表单 → `Query`(通过 config 配置字段)
|
|
93
|
-
- 数据表格 → `TableOrList`
|
|
94
|
-
- 左侧树 → `LeftTree`
|
|
95
|
-
- 弹窗/抽屉 → `ModelOrDrawer`
|
|
96
|
-
- 返回标题 → `TitleAndBack`
|
|
97
|
-
- 按钮 → Cover 层 `Button`
|
|
98
|
-
- 输入框 → Cover 层 `Input` 或 Query 的 valueType: 'input'
|
|
99
|
-
- 下拉选择 → Cover 层 `Select` 或 Query 的 valueType: 'select'
|
|
100
|
-
- 日期选择 → Cover 层 `DatePicker` 或 Query 的 valueType: 'datePicker'
|
|
101
|
-
- 树选择 → Query 的 valueType: 'treeSelect'
|
|
81
|
+
使用 MCP 工具获取组件信息和 API,**优先使用 Repowiki 语义搜索工具**:
|
|
82
|
+
|
|
83
|
+
- `search_components_semantic` — 基于 Repowiki 知识库的语义搜索,用自然语言描述匹配最适合的组件(**优先使用**)
|
|
84
|
+
- `get_component_full_profile` — 一站式获取组件全景画像。`name` 支持逗号分隔批量查询(如 `"Query,TableOrList"`),`depth="deep"` 获取 Props 链 + 源码摘要 + 样式注入,**返回值是紧凑 Markdown 格式**(**推荐首选,一次调用替代多次查询**)
|
|
85
|
+
- `get_component_dependencies` — 查询组件依赖关系图,确认 hooks 和插槽关系
|
|
86
|
+
- `get_best_practices` — 获取组件使用最佳实践,指定 scenario 可获取组合最佳实践(如"左树右表页面")
|
|
87
|
+
- `get_style_injection_guide` — 查询组件样式注入方法,获取 CSS 覆盖路径和分配策略
|
|
88
|
+
- `read_file` — 读取组件源码(deep 模式信息不足时)
|
|
89
|
+
- `api_tool` — 拉取 API 文档(自动识别 YApi/Swagger)或联调测试接口
|
|
102
90
|
|
|
103
91
|
|
|
104
92
|
### 步骤5:匹配组件并确认方案(必做)
|
|
@@ -126,6 +114,44 @@ szcd 是基于 Ant Design 5.27 封装的企业级 React 组件库,采用分层
|
|
|
126
114
|
- "是否需要补充表单校验规则?"
|
|
127
115
|
- "是否需要添加批量操作功能?"
|
|
128
116
|
|
|
117
|
+
### 步骤7:收集用户反馈(必做,质量闭环)
|
|
118
|
+
|
|
119
|
+
代码生成完成后,**必须**向用户收集反馈,用于优化 MCP 工具行为:
|
|
120
|
+
|
|
121
|
+
1. **询问准确率评分**:"请对本次生成的代码准确性评分(1-5 分,5 分最准确)?"
|
|
122
|
+
2. **询问是否采纳**:"您是否计划采纳本次生成的代码?"
|
|
123
|
+
3. **如拒绝,询问原因**:"未采纳的原因是什么?(如:组件不匹配、API 错误、缺少功能、不符合设计稿等)"
|
|
124
|
+
4. **调用 `submit_feedback` 提交反馈**:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
参数示例:
|
|
128
|
+
{
|
|
129
|
+
"sessionId": "<当前会话ID或时间戳>",
|
|
130
|
+
"toolsUsed": ["search_components_semantic", "get_component_full_profile", ...],
|
|
131
|
+
"userQuery": "<用户的原始需求描述>",
|
|
132
|
+
"generatedCodeSummary": "<生成代码的摘要或关键组件列表>",
|
|
133
|
+
"accuracyRating": <1-5>,
|
|
134
|
+
"adopted": <true/false>,
|
|
135
|
+
"rejectionReason": "<拒绝原因,如采纳则为空>",
|
|
136
|
+
"contextSnapshot": {
|
|
137
|
+
"matchedComponents": ["Query", "TableOrList", "TemplateMode"],
|
|
138
|
+
"layoutType": "LeftRight",
|
|
139
|
+
"queryFields": ["name", "status", "date"]
|
|
140
|
+
},
|
|
141
|
+
"toolType": "<trae|claude|qwen|qoder|cursor|vscode>"
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**toolType 映射规则**:
|
|
146
|
+
- Trae CLI / Trae IDE → `"trae"`
|
|
147
|
+
- Claude Code / Claude Desktop → `"claude"`
|
|
148
|
+
- Qwen Code / 通义灵码 → `"qwen"`
|
|
149
|
+
- Qoder CLI → `"qoder"`
|
|
150
|
+
- Cursor → `"cursor"`
|
|
151
|
+
- VS Code + Cline / Continue → `"vscode"`
|
|
152
|
+
- 其他 → `"generic"`
|
|
153
|
+
|
|
154
|
+
|
|
129
155
|
## 典型页面模式
|
|
130
156
|
|
|
131
157
|
### 模式1: 左右布局 + 查询 + 表格(最常见)
|
|
@@ -9,6 +9,7 @@ import fs from "node:fs";
|
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import os from "node:os";
|
|
11
11
|
import { execSync } from "node:child_process";
|
|
12
|
+
import { getClientConfigHeader as getClientConfigHeaderDirect } from "./common.js";
|
|
12
13
|
|
|
13
14
|
// ==================== 路径工具 ====================
|
|
14
15
|
|
|
@@ -59,9 +60,11 @@ function syncClaudeCodeConfig(deps) {
|
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
|
|
63
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
62
64
|
config.mcpServers[serverName] = {
|
|
63
65
|
type: "http",
|
|
64
66
|
url: mcpUrl,
|
|
67
|
+
...(clientConfigHeader ? { headers: { "X-Client-Config": clientConfigHeader } } : {}),
|
|
65
68
|
};
|
|
66
69
|
|
|
67
70
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
@@ -314,9 +317,11 @@ function syncClaudeCodeConfigDirect(targetUrl, serverName) {
|
|
|
314
317
|
return;
|
|
315
318
|
}
|
|
316
319
|
|
|
320
|
+
const clientConfigHeader = getClientConfigHeaderDirect();
|
|
317
321
|
config.mcpServers[serverName] = {
|
|
318
322
|
type: "http",
|
|
319
323
|
url: mcpUrl,
|
|
324
|
+
...(clientConfigHeader ? { headers: { "X-Client-Config": clientConfigHeader } } : {}),
|
|
320
325
|
};
|
|
321
326
|
|
|
322
327
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
package/scripts/lib/common.js
CHANGED
|
@@ -159,3 +159,36 @@ export function getMcpServerName() {
|
|
|
159
159
|
const config = loadExistingConfig();
|
|
160
160
|
return config.MCP_SERVER_NAME || DEFAULT_MCP_SERVER_NAME;
|
|
161
161
|
}
|
|
162
|
+
|
|
163
|
+
// ==================== 客户端 CODING 配置透传 ====================
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* 读取用户本地 ~/.szcd-mcp-config.json 中的 CODING 配置
|
|
167
|
+
* 用于通过 HTTP Header (X-Client-Config) 透传给 MCP 服务器
|
|
168
|
+
*/
|
|
169
|
+
export function loadClientCodingConfig() {
|
|
170
|
+
const config = loadExistingConfig();
|
|
171
|
+
const codingConfig = {};
|
|
172
|
+
if (config.CODING_BASE_URL) codingConfig.CODING_BASE_URL = config.CODING_BASE_URL;
|
|
173
|
+
if (config.CODING_DEFAULT_PROJECT_ID) codingConfig.CODING_DEFAULT_PROJECT_ID = config.CODING_DEFAULT_PROJECT_ID;
|
|
174
|
+
if (config.CODING_ACCOUNT) codingConfig.CODING_ACCOUNT = config.CODING_ACCOUNT;
|
|
175
|
+
if (config.CODING_COOKIES) codingConfig.CODING_COOKIES = config.CODING_COOKIES;
|
|
176
|
+
if (config.CODING_PASSWORD) codingConfig.CODING_PASSWORD = config.CODING_PASSWORD;
|
|
177
|
+
return Object.keys(codingConfig).length > 0 ? codingConfig : null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* 将 CODING 配置编码为 Base64,用于 X-Client-Config Header
|
|
182
|
+
*/
|
|
183
|
+
export function encodeClientConfig(config) {
|
|
184
|
+
if (!config) return null;
|
|
185
|
+
return Buffer.from(JSON.stringify(config)).toString("base64");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* 获取 X-Client-Config Header 值(便捷函数)
|
|
190
|
+
* 返回 Base64 编码的字符串,或 null(无 CODING 配置时)
|
|
191
|
+
*/
|
|
192
|
+
export function getClientConfigHeader() {
|
|
193
|
+
return encodeClientConfig(loadClientCodingConfig());
|
|
194
|
+
}
|
package/scripts/lib/qoder.js
CHANGED
|
@@ -29,6 +29,7 @@ import fs from "node:fs";
|
|
|
29
29
|
import path from "node:path";
|
|
30
30
|
import os from "node:os";
|
|
31
31
|
import { execSync } from "node:child_process";
|
|
32
|
+
import { getClientConfigHeader as _getClientConfigHeader } from "./common.js";
|
|
32
33
|
|
|
33
34
|
// ==================== 路径工具 ====================
|
|
34
35
|
|
|
@@ -148,9 +149,11 @@ function syncQoderSettings(deps) {
|
|
|
148
149
|
|
|
149
150
|
if (!settings.mcpServers) settings.mcpServers = {};
|
|
150
151
|
|
|
152
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
151
153
|
const desiredConfig = {
|
|
152
154
|
type: "http",
|
|
153
155
|
url: mcpUrl,
|
|
156
|
+
...(clientConfigHeader ? { headers: { "X-Client-Config": clientConfigHeader } } : {}),
|
|
154
157
|
};
|
|
155
158
|
|
|
156
159
|
const current = settings.mcpServers[serverName];
|
|
@@ -358,9 +361,11 @@ function setupQoderProjectConfig(deps) {
|
|
|
358
361
|
let settings = readJsonFile(projectSettingsPath);
|
|
359
362
|
if (!settings.mcpServers) settings.mcpServers = {};
|
|
360
363
|
|
|
364
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
361
365
|
settings.mcpServers[serverName] = {
|
|
362
366
|
type: "http",
|
|
363
367
|
url: mcpUrl,
|
|
368
|
+
...(clientConfigHeader ? { headers: { "X-Client-Config": clientConfigHeader } } : {}),
|
|
364
369
|
};
|
|
365
370
|
|
|
366
371
|
writeJsonFile(projectSettingsPath, settings);
|
|
@@ -440,9 +445,11 @@ function syncQoderSettingsDirect(targetUrl, serverName) {
|
|
|
440
445
|
return;
|
|
441
446
|
}
|
|
442
447
|
|
|
448
|
+
const clientConfigHeader = _getClientConfigHeader();
|
|
443
449
|
settings.mcpServers[serverName] = {
|
|
444
450
|
type: "http",
|
|
445
451
|
url: mcpUrl,
|
|
452
|
+
...(clientConfigHeader ? { headers: { "X-Client-Config": clientConfigHeader } } : {}),
|
|
446
453
|
};
|
|
447
454
|
|
|
448
455
|
writeJsonFile(settingsPath, settings);
|
package/scripts/lib/qwen-code.js
CHANGED
|
@@ -23,6 +23,7 @@ import fs from "node:fs";
|
|
|
23
23
|
import path from "node:path";
|
|
24
24
|
import os from "node:os";
|
|
25
25
|
import { execSync } from "node:child_process";
|
|
26
|
+
import { getClientConfigHeader as getClientConfigHeaderDirect } from "./common.js";
|
|
26
27
|
|
|
27
28
|
// ==================== 路径工具 ====================
|
|
28
29
|
|
|
@@ -299,6 +300,29 @@ function cleanupSettingsMcpEntry(serverName) {
|
|
|
299
300
|
console.log(`✓ Cleaned up mcpServers in ~/.qwen/settings.json (extension mode)`);
|
|
300
301
|
}
|
|
301
302
|
|
|
303
|
+
/**
|
|
304
|
+
* 向已安装扩展的 qwen-extension.json 注入 X-Client-Config Header
|
|
305
|
+
* 仅在 postinstall 时调用(setupQwenCode),syncMcpUrl 路径由 syncExtensionConfig 处理
|
|
306
|
+
*/
|
|
307
|
+
function injectClientConfigHeader(serverName, clientConfigHeader) {
|
|
308
|
+
const extDir = path.join(getQwenCodeExtensionsDirectory(), serverName);
|
|
309
|
+
const manifestPath = path.join(extDir, "qwen-extension.json");
|
|
310
|
+
|
|
311
|
+
if (!fs.existsSync(manifestPath)) return;
|
|
312
|
+
|
|
313
|
+
const manifest = readJsonFile(manifestPath);
|
|
314
|
+
if (!manifest.mcpServers || !manifest.mcpServers[serverName]) return;
|
|
315
|
+
|
|
316
|
+
const entry = manifest.mcpServers[serverName];
|
|
317
|
+
if (entry.headers && entry.headers["X-Client-Config"] === clientConfigHeader) {
|
|
318
|
+
return; // 已是最新
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
entry.headers = { "X-Client-Config": clientConfigHeader };
|
|
322
|
+
writeJsonFile(manifestPath, manifest);
|
|
323
|
+
console.log(`✓ Injected X-Client-Config header into extension qwen-extension.json`);
|
|
324
|
+
}
|
|
325
|
+
|
|
302
326
|
/**
|
|
303
327
|
* 更新已安装扩展目录中的 qwen-extension.json
|
|
304
328
|
*/
|
|
@@ -318,8 +342,12 @@ function syncExtensionConfig(targetUrl, serverName) {
|
|
|
318
342
|
}
|
|
319
343
|
|
|
320
344
|
const mcpUrl = `${targetUrl}/mcp`;
|
|
345
|
+
const clientConfigHeader = getClientConfigHeaderDirect();
|
|
321
346
|
const entry = manifest.mcpServers[serverName];
|
|
322
|
-
|
|
347
|
+
const headersUnchanged = clientConfigHeader
|
|
348
|
+
? entry.headers && entry.headers["X-Client-Config"] === clientConfigHeader
|
|
349
|
+
: !entry.headers;
|
|
350
|
+
if (entry.type === "http" && entry.httpUrl === mcpUrl && headersUnchanged) {
|
|
323
351
|
console.log(`⏭️ Extension qwen-extension.json already up-to-date: ${mcpUrl}`);
|
|
324
352
|
return;
|
|
325
353
|
}
|
|
@@ -328,6 +356,12 @@ function syncExtensionConfig(targetUrl, serverName) {
|
|
|
328
356
|
entry.httpUrl = mcpUrl;
|
|
329
357
|
// 清理旧字段,避免冲突
|
|
330
358
|
delete entry.url;
|
|
359
|
+
// 透传用户本地 CODING 配置
|
|
360
|
+
if (clientConfigHeader) {
|
|
361
|
+
entry.headers = { "X-Client-Config": clientConfigHeader };
|
|
362
|
+
} else {
|
|
363
|
+
delete entry.headers;
|
|
364
|
+
}
|
|
331
365
|
writeJsonFile(manifestPath, manifest);
|
|
332
366
|
console.log(`✓ Updated extension qwen-extension.json: ${mcpUrl}`);
|
|
333
367
|
}
|
|
@@ -362,6 +396,14 @@ export function setupQwenCode(deps) {
|
|
|
362
396
|
extensionInstalled = installExtensionViaCopy(deps);
|
|
363
397
|
}
|
|
364
398
|
|
|
399
|
+
// ---- 注入 X-Client-Config Header ----
|
|
400
|
+
if (extensionInstalled) {
|
|
401
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
402
|
+
if (clientConfigHeader) {
|
|
403
|
+
injectClientConfigHeader(deps.getMcpServerName(), clientConfigHeader);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
365
407
|
// ---- 结果 ----
|
|
366
408
|
if (extensionInstalled) {
|
|
367
409
|
console.log(`\n✅ Qwen Code extension installed successfully!`);
|
package/scripts/lib/trae-cli.js
CHANGED
|
@@ -14,6 +14,7 @@ import fs from "node:fs";
|
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import os from "node:os";
|
|
16
16
|
import { execSync } from "node:child_process";
|
|
17
|
+
import { loadClientCodingConfig, encodeClientConfig } from "./common.js";
|
|
17
18
|
|
|
18
19
|
// ==================== 路径工具 ====================
|
|
19
20
|
|
|
@@ -73,6 +74,12 @@ function parseYamlMcpServers(content) {
|
|
|
73
74
|
return { servers, lines };
|
|
74
75
|
}
|
|
75
76
|
|
|
77
|
+
// ==================== 客户端 CODING 配置(使用 common.js 公共函数)====================
|
|
78
|
+
|
|
79
|
+
// loadClientCodingConfig / encodeClientConfig 已在 common.js 中定义,
|
|
80
|
+
// 通过 deps 参数传入(deps.getClientConfigHeader())
|
|
81
|
+
// 此处仅保留兼容旧代码的本地引用
|
|
82
|
+
|
|
76
83
|
// ==================== YAML 文件同步 ====================
|
|
77
84
|
|
|
78
85
|
export function syncTraeCliYaml(deps) {
|
|
@@ -80,10 +87,16 @@ export function syncTraeCliYaml(deps) {
|
|
|
80
87
|
const mcpUrl = `${deps.getMcpServerUrl()}/mcp`;
|
|
81
88
|
const serverName = deps.getMcpServerName();
|
|
82
89
|
|
|
90
|
+
// 读取用户本地 CODING 配置,生成 X-Client-Config Header
|
|
91
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
92
|
+
const headersBlock = clientConfigHeader
|
|
93
|
+
? `\n headers:\n X-Client-Config: ${clientConfigHeader}`
|
|
94
|
+
: "";
|
|
95
|
+
|
|
83
96
|
if (!fs.existsSync(yamlPath)) {
|
|
84
97
|
const dir = path.dirname(yamlPath);
|
|
85
98
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
86
|
-
const content = `mcp_servers:\n - name: ${serverName}\n url: ${mcpUrl}\n type: http\n`;
|
|
99
|
+
const content = `mcp_servers:\n - name: ${serverName}\n url: ${mcpUrl}\n type: http${headersBlock}\n`;
|
|
87
100
|
fs.writeFileSync(yamlPath, content);
|
|
88
101
|
console.log(`✓ Created Trae CLI YAML: ${yamlPath}`);
|
|
89
102
|
return;
|
|
@@ -108,7 +121,7 @@ export function syncTraeCliYaml(deps) {
|
|
|
108
121
|
content = content.replace(oldBlock, newBlock);
|
|
109
122
|
console.log(`✓ Updated Trae CLI YAML: ${existing.url} → ${mcpUrl}, type → http`);
|
|
110
123
|
} else {
|
|
111
|
-
const entry = ` - name: ${serverName}\n url: ${mcpUrl}\n type: http\n`;
|
|
124
|
+
const entry = ` - name: ${serverName}\n url: ${mcpUrl}\n type: http${headersBlock}\n`;
|
|
112
125
|
if (/^mcp_servers\s*:\s*\[\]\s*$/m.test(content)) {
|
|
113
126
|
content = content.replace(/^mcp_servers\s*:\s*\[\]\s*$/m, `mcp_servers:\n${entry}`);
|
|
114
127
|
} else if (/^mcp_servers\s*:\s*$/m.test(content)) {
|
|
@@ -130,7 +143,16 @@ export function createTraeCliConfig(deps) {
|
|
|
130
143
|
if (deps.isCommandAvailable("trae-cli")) {
|
|
131
144
|
const mcpUrl = `${deps.getMcpServerUrl()}/mcp`;
|
|
132
145
|
const serverName = deps.getMcpServerName();
|
|
133
|
-
|
|
146
|
+
|
|
147
|
+
// 读取用户本地 CODING 配置,生成 X-Client-Config Header
|
|
148
|
+
const codingConfig = loadClientCodingConfig();
|
|
149
|
+
const clientConfigHeader = encodeClientConfig(codingConfig);
|
|
150
|
+
const jsonConfigObj = { type: "http", url: mcpUrl };
|
|
151
|
+
if (clientConfigHeader) {
|
|
152
|
+
jsonConfigObj.headers = { "X-Client-Config": clientConfigHeader };
|
|
153
|
+
}
|
|
154
|
+
const jsonConfig = JSON.stringify(jsonConfigObj);
|
|
155
|
+
|
|
134
156
|
deps.safeExecSync(`trae-cli mcp remove ${serverName} 2>/dev/null`);
|
|
135
157
|
const result = deps.safeExecSync(`trae-cli mcp add-json ${serverName} '${jsonConfig}'`);
|
|
136
158
|
if (result === true || result === "already_exists") {
|
package/scripts/lib/trae-ide.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import fs from "node:fs";
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
import os from "node:os";
|
|
16
|
+
import { getClientConfigHeader } from "./common.js";
|
|
16
17
|
|
|
17
18
|
// ==================== 路径工具 ====================
|
|
18
19
|
|
|
@@ -78,10 +79,16 @@ export function syncTraeCnMcpJson(deps) {
|
|
|
78
79
|
return;
|
|
79
80
|
}
|
|
80
81
|
|
|
81
|
-
|
|
82
|
+
const clientConfigHeader = deps.getClientConfigHeader ? deps.getClientConfigHeader() : null;
|
|
83
|
+
const serverConfig = {
|
|
82
84
|
type: "http",
|
|
83
85
|
url: mcpUrl,
|
|
84
86
|
};
|
|
87
|
+
if (clientConfigHeader) {
|
|
88
|
+
serverConfig.headers = { "X-Client-Config": clientConfigHeader };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
config.mcpServers[serverName] = serverConfig;
|
|
85
92
|
|
|
86
93
|
const dir = path.dirname(mcpJsonPath);
|
|
87
94
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
@@ -119,10 +126,16 @@ export function syncMcpUrl(targetUrl, serverName) {
|
|
|
119
126
|
return;
|
|
120
127
|
}
|
|
121
128
|
|
|
122
|
-
|
|
129
|
+
const clientConfigHeader = getClientConfigHeader();
|
|
130
|
+
const serverConfig = {
|
|
123
131
|
type: "http",
|
|
124
132
|
url: mcpUrl,
|
|
125
133
|
};
|
|
134
|
+
if (clientConfigHeader) {
|
|
135
|
+
serverConfig.headers = { "X-Client-Config": clientConfigHeader };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
config.mcpServers[serverName] = serverConfig;
|
|
126
139
|
|
|
127
140
|
const dir = path.dirname(mcpJsonPath);
|
|
128
141
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
package/scripts/postinstall.js
CHANGED
|
@@ -33,6 +33,7 @@ const IS_QUICK = process.argv.includes("--quick");
|
|
|
33
33
|
const deps = {
|
|
34
34
|
getMcpServerUrl: common.getMcpServerUrl,
|
|
35
35
|
getMcpServerName: common.getMcpServerName,
|
|
36
|
+
getClientConfigHeader: common.getClientConfigHeader,
|
|
36
37
|
safeExecSync: common.safeExecSync,
|
|
37
38
|
isCommandAvailable: common.isCommandAvailable,
|
|
38
39
|
ensureDirectory: common.ensureDirectory,
|