@fjyueke/bify-mcp 1.0.2 → 1.0.5

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 (3) hide show
  1. package/README.md +68 -5
  2. package/dist/index.js +278 -86
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -9,26 +9,89 @@
9
9
 
10
10
  Bify 是基于 Taroify 的移动端组件库,基于 Vant 视觉规范,提供一致的 API 接口,助力开发者快速搭建小程序应用。
11
11
 
12
- Bify MCP 是一项独立的 MCP(模型上下文协议)服务,旨在将 Bify 与大模型连接起来。它使大模型能够直接从文档中检索组件、API数据。
12
+ Bify MCP 是一项独立的 MCP(模型上下文协议)服务,旨在将 Bify 与大模型连接起来。它使大模型能够直接从文档中检索组件、API 数据,并支持 Arco Mobile → Bify 代码转换。
13
13
 
14
14
  - 直接使用 npx 运行
15
15
  - 无需外部依赖,只需要 Node 环境
16
+ - 支持 68+ 个组件文档查询
17
+ - 支持 Arco Mobile 代码转换
16
18
 
17
- ## Cursor 用法
19
+ ## 配置方式
18
20
 
19
- Cursor Mcp 使用指南参考:<https://docs.cursor.com/context/model-context-protocol#using-mcp-tools-in-agent>
21
+ ### Cursor
20
22
 
21
- ``` json
23
+ ```json
22
24
  {
23
25
  "mcpServers": {
24
26
  "@fjyueke/bify-mcp": {
25
27
  "command": "npx",
26
28
  "args": [
27
29
  "-y",
28
- "@fjyueke/bify-mcp",
30
+ "@fjyueke/bify-mcp"
29
31
  ],
30
32
  "env": {}
31
33
  }
32
34
  }
33
35
  }
34
36
  ```
37
+
38
+ ### Trae
39
+
40
+ 在 `.trae/skills/` 目录下创建配置文件,或在 Trae 设置中添加 MCP 服务。
41
+
42
+ ### 其他支持 MCP 的 IDE
43
+
44
+ 参考对应 IDE 的 MCP 配置文档,使用上述配置格式。
45
+
46
+ ## 可用工具
47
+
48
+ | 工具名 | 功能 |
49
+ |--------|------|
50
+ | `list-components` | 列出所有可用的 Bify 组件 |
51
+ | `get-component-docs` | 获取指定组件的详细文档 |
52
+ | `get-component-props` | 获取指定组件的属性和 API 文档 |
53
+ | `list-component-example` | 获取指定组件的所有示例代码 |
54
+ | `convert-arco-to-bify` | 将 Arco Mobile React 代码转换为 Bify 代码 |
55
+ | `get-arco-conversion-help` | 获取 Arco Mobile → Bify 转换帮助信息 |
56
+
57
+ ## 使用示例
58
+
59
+ ### 查询组件文档
60
+
61
+ ```bash
62
+ # 列出所有组件
63
+ list-components
64
+
65
+ # 获取 Cell 组件文档
66
+ get-component-docs Cell
67
+
68
+ # 获取 Cell 组件属性
69
+ get-component-props Cell
70
+
71
+ # 获取 Cell 组件示例
72
+ list-component-example Cell
73
+ ```
74
+
75
+ ### Arco Mobile 代码转换
76
+
77
+ ```bash
78
+ # 获取转换帮助
79
+ get-arco-conversion-help
80
+
81
+ # 转换代码
82
+ convert-arco-to-bify "<Cell label='标题' desc='描述' showArrow>内容</Cell>"
83
+ ```
84
+
85
+ ## 版本历史
86
+
87
+ | 版本 | 日期 | 说明 |
88
+ |------|------|------|
89
+ | 1.0.3 | 2026-07-13 | 优化代码转换工具,增加 40+ 组件映射、值映射、布尔属性转换 |
90
+ | 1.0.2 | 2026-07-13 | 添加 Arco Mobile → Bify 代码转换功能 |
91
+ | 1.0.1 | 2026-07-13 | 更正包名为 bify-mcp |
92
+ | 1.0.0 | 2026-07-13 | 初始版本,支持 68+ 组件文档查询 |
93
+
94
+ ## 相关链接
95
+
96
+ - npm 包地址:https://www.npmjs.com/package/@fjyueke/bify-mcp
97
+ - Bify 组件库:https://github.com/fjyueke/bify
package/dist/index.js CHANGED
@@ -172,9 +172,11 @@ var componentMappings = [
172
172
  { arcoProp: "label", bifyProp: "title" },
173
173
  { arcoProp: "desc", bifyProp: "brief" },
174
174
  { arcoProp: "text", bifyProp: "children" },
175
- { arcoProp: "showArrow", bifyProp: "clickable" },
175
+ { arcoProp: "showArrow", bifyProp: "clickable", transform: () => "true" },
176
+ { arcoProp: "arrow", bifyProp: "rightIcon" },
176
177
  { arcoProp: "bordered", bifyProp: "bordered" },
177
- { arcoProp: "icon", bifyProp: "icon" }
178
+ { arcoProp: "icon", bifyProp: "icon" },
179
+ { arcoProp: "onClick", bifyProp: "onClick" }
178
180
  ]
179
181
  },
180
182
  {
@@ -182,7 +184,10 @@ var componentMappings = [
182
184
  bifyName: "CellGroup",
183
185
  arcoImport: "@arco-design/mobile-react",
184
186
  bifyImport: "@fjyueke/bify-core",
185
- propMappings: []
187
+ propMappings: [
188
+ { arcoProp: "bordered", bifyProp: "bordered" },
189
+ { arcoProp: "onClick", bifyProp: "onClick" }
190
+ ]
186
191
  },
187
192
  {
188
193
  arcoName: "Button",
@@ -194,16 +199,25 @@ var componentMappings = [
194
199
  { arcoProp: "size", bifyProp: "size" },
195
200
  { arcoProp: "disabled", bifyProp: "disabled" },
196
201
  { arcoProp: "loading", bifyProp: "loading" },
197
- { arcoProp: "block", bifyProp: "block" },
198
- { arcoProp: "ghost", bifyProp: "plain" }
199
- ]
200
- },
201
- {
202
- arcoName: "Icon",
203
- bifyName: "",
204
- arcoImport: "@arco-design/mobile-react",
205
- bifyImport: "@fjyueke/bify-icons",
206
- propMappings: []
202
+ { arcoProp: "icon", bifyProp: "icon" },
203
+ { arcoProp: "onClick", bifyProp: "onClick" },
204
+ { arcoProp: "className", bifyProp: "className" },
205
+ { arcoProp: "style", bifyProp: "style" }
206
+ ],
207
+ valueMappings: {
208
+ type: {
209
+ ghost: "outlined",
210
+ default: "default",
211
+ primary: "primary"
212
+ },
213
+ size: {
214
+ mini: "mini",
215
+ small: "small",
216
+ medium: "medium",
217
+ large: "large",
218
+ huge: "large"
219
+ }
220
+ }
207
221
  },
208
222
  {
209
223
  arcoName: "Avatar",
@@ -235,8 +249,18 @@ var componentMappings = [
235
249
  propMappings: [
236
250
  { arcoProp: "type", bifyProp: "type" },
237
251
  { arcoProp: "size", bifyProp: "size" },
238
- { arcoProp: "closable", bifyProp: "closable" }
239
- ]
252
+ { arcoProp: "closable", bifyProp: "closable" },
253
+ { arcoProp: "onClose", bifyProp: "onClose" }
254
+ ],
255
+ valueMappings: {
256
+ type: {
257
+ default: "default",
258
+ primary: "primary",
259
+ success: "success",
260
+ warning: "warning",
261
+ danger: "danger"
262
+ }
263
+ }
240
264
  },
241
265
  {
242
266
  arcoName: "Switch",
@@ -257,6 +281,17 @@ var componentMappings = [
257
281
  propMappings: [
258
282
  { arcoProp: "checked", bifyProp: "checked" },
259
283
  { arcoProp: "disabled", bifyProp: "disabled" },
284
+ { arcoProp: "onChange", bifyProp: "onChange" },
285
+ { arcoProp: "label", bifyProp: "children" }
286
+ ]
287
+ },
288
+ {
289
+ arcoName: "CheckboxGroup",
290
+ bifyName: "Checkbox.Group",
291
+ arcoImport: "@arco-design/mobile-react",
292
+ bifyImport: "@fjyueke/bify-core",
293
+ propMappings: [
294
+ { arcoProp: "value", bifyProp: "modelValue" },
260
295
  { arcoProp: "onChange", bifyProp: "onChange" }
261
296
  ]
262
297
  },
@@ -268,6 +303,17 @@ var componentMappings = [
268
303
  propMappings: [
269
304
  { arcoProp: "checked", bifyProp: "checked" },
270
305
  { arcoProp: "disabled", bifyProp: "disabled" },
306
+ { arcoProp: "onChange", bifyProp: "onChange" },
307
+ { arcoProp: "label", bifyProp: "children" }
308
+ ]
309
+ },
310
+ {
311
+ arcoName: "RadioGroup",
312
+ bifyName: "Radio.Group",
313
+ arcoImport: "@arco-design/mobile-react",
314
+ bifyImport: "@fjyueke/bify-core",
315
+ propMappings: [
316
+ { arcoProp: "value", bifyProp: "modelValue" },
271
317
  { arcoProp: "onChange", bifyProp: "onChange" }
272
318
  ]
273
319
  },
@@ -332,13 +378,6 @@ var componentMappings = [
332
378
  { arcoProp: "onClose", bifyProp: "onClose" }
333
379
  ]
334
380
  },
335
- {
336
- arcoName: "PickerView",
337
- bifyName: "Picker",
338
- arcoImport: "@arco-design/mobile-react",
339
- bifyImport: "@fjyueke/bify-core",
340
- propMappings: []
341
- },
342
381
  {
343
382
  arcoName: "DatePicker",
344
383
  bifyName: "DatePicker",
@@ -505,6 +544,16 @@ var componentMappings = [
505
544
  { arcoProp: "activeKey", bifyProp: "activeNames" }
506
545
  ]
507
546
  },
547
+ {
548
+ arcoName: "CollapseItem",
549
+ bifyName: "Collapse.Item",
550
+ arcoImport: "@arco-design/mobile-react",
551
+ bifyImport: "@fjyueke/bify-core",
552
+ propMappings: [
553
+ { arcoProp: "title", bifyProp: "title" },
554
+ { arcoProp: "name", bifyProp: "name" }
555
+ ]
556
+ },
508
557
  {
509
558
  arcoName: "PullRefresh",
510
559
  bifyName: "PullRefresh",
@@ -533,6 +582,29 @@ var componentMappings = [
533
582
  propMappings: [
534
583
  { arcoProp: "endTime", bifyProp: "endTime" }
535
584
  ]
585
+ },
586
+ {
587
+ arcoName: "List",
588
+ bifyName: "List",
589
+ arcoImport: "@arco-design/mobile-react",
590
+ bifyImport: "@fjyueke/bify-core",
591
+ propMappings: []
592
+ },
593
+ {
594
+ arcoName: "RefreshControl",
595
+ bifyName: "PullRefresh",
596
+ arcoImport: "@arco-design/mobile-react",
597
+ bifyImport: "@fjyueke/bify-core",
598
+ propMappings: [
599
+ { arcoProp: "onRefresh", bifyProp: "onRefresh" }
600
+ ]
601
+ },
602
+ {
603
+ arcoName: "PickerView",
604
+ bifyName: "PickerView",
605
+ arcoImport: "@arco-design/mobile-react",
606
+ bifyImport: "@fjyueke/bify-core",
607
+ propMappings: []
536
608
  }
537
609
  ];
538
610
  function findMappingByArcoName(arcoName) {
@@ -544,19 +616,36 @@ function findAllArcoComponents() {
544
616
 
545
617
  // src/services/arco-converter.ts
546
618
  async function convertArcoToBify(arcoCode) {
619
+ const warnings = [];
620
+ const suggestions = [];
621
+ const usedMappings = [];
547
622
  let result = arcoCode;
548
- result = convertImports(result);
549
- result = convertComponents(result);
623
+ const importsResult = convertImports(result, warnings);
624
+ result = importsResult.code;
625
+ usedMappings.push(...importsResult.mappings);
626
+ const componentsResult = convertComponents(result, warnings, suggestions);
627
+ result = componentsResult.code;
628
+ usedMappings.push(...componentsResult.mappings);
550
629
  result = convertIconImports(result);
551
- return result;
630
+ result = fixCodeFormat(result);
631
+ const uniqueMappings = usedMappings.filter(
632
+ (m, index, self) => self.findIndex((t) => t.arcoName === m.arcoName) === index
633
+ );
634
+ return {
635
+ code: result,
636
+ mappings: uniqueMappings,
637
+ warnings,
638
+ suggestions
639
+ };
552
640
  }
553
- function convertImports(code) {
641
+ function convertImports(code, warnings) {
554
642
  let result = code;
643
+ const usedMappings = [];
555
644
  const arcoImportRegex = /import\s+([\s\S]*?)\s+from\s+['"]@arco-design\/mobile-react['"]/g;
556
645
  const matches = [...code.matchAll(arcoImportRegex)];
557
646
  const bifyCoreComponents = [];
558
647
  const bifyIconComponents = [];
559
- const remainingComponents = [];
648
+ const unsupportedComponents = [];
560
649
  for (const match of matches) {
561
650
  const importContent = match[1].trim();
562
651
  const namedImportRegex = /\{([\s\S]*?)\}/;
@@ -566,62 +655,56 @@ function convertImports(code) {
566
655
  for (const component of components) {
567
656
  const mapping = findMappingByArcoName(component);
568
657
  if (mapping) {
658
+ usedMappings.push(mapping);
569
659
  if (mapping.bifyImport === "@fjyueke/bify-icons") {
570
660
  bifyIconComponents.push(component);
571
661
  } else {
572
662
  bifyCoreComponents.push(mapping.bifyName || component);
573
663
  }
574
664
  } else {
575
- remainingComponents.push(component);
665
+ unsupportedComponents.push(component);
576
666
  }
577
667
  }
578
- } else {
579
- remainingComponents.push(importContent);
580
668
  }
581
669
  result = result.replace(match[0], "");
582
670
  }
583
671
  result = result.trim();
584
672
  if (bifyCoreComponents.length > 0) {
585
- const coreImport = `import { ${bifyCoreComponents.join(", ")} } from "@fjyueke/bify-core"
673
+ const uniqueCoreComponents = [...new Set(bifyCoreComponents)];
674
+ const coreImport = `import { ${uniqueCoreComponents.join(", ")} } from "@fjyueke/bify-core"
586
675
  `;
587
676
  result = coreImport + result;
588
677
  }
589
678
  if (bifyIconComponents.length > 0) {
590
- const iconImport = `import { ${bifyIconComponents.join(", ")} } from "@fjyueke/bify-icons"
679
+ const uniqueIconComponents = [...new Set(bifyIconComponents)];
680
+ const iconImport = `import { ${uniqueIconComponents.join(", ")} } from "@fjyueke/bify-icons"
591
681
  `;
592
682
  result = iconImport + result;
593
683
  }
594
- return result;
684
+ if (unsupportedComponents.length > 0) {
685
+ warnings.push(`\u4EE5\u4E0B\u7EC4\u4EF6\u6682\u4E0D\u652F\u6301\u81EA\u52A8\u8F6C\u6362\uFF1A${unsupportedComponents.join(", ")}`);
686
+ }
687
+ return { code: result, mappings: usedMappings };
595
688
  }
596
- function convertComponents(code) {
689
+ function convertComponents(code, warnings, suggestions) {
597
690
  let result = code;
691
+ const usedMappings = [];
598
692
  const arcoComponents = findAllArcoComponents();
599
693
  for (const arcoComponent of arcoComponents) {
600
694
  const mapping = findMappingByArcoName(arcoComponent);
601
695
  if (!mapping || !mapping.bifyName) continue;
696
+ const componentPattern = new RegExp(`<${arcoComponent}`, "g");
697
+ if (!componentPattern.test(code)) continue;
698
+ usedMappings.push(mapping);
602
699
  const bifyComponent = mapping.bifyName;
603
- const componentRegex = new RegExp(
700
+ const selfClosingRegex = new RegExp(
604
701
  `<${arcoComponent}([^>]*)\\/?>`,
605
702
  "g"
606
703
  );
607
- result = result.replace(componentRegex, (match, props) => {
704
+ result = result.replace(selfClosingRegex, (match, props) => {
608
705
  let newProps = props;
609
- for (const propMapping of mapping.propMappings) {
610
- const propRegex = new RegExp(
611
- `${propMapping.arcoProp}=(["'])(.*?)\\1`,
612
- "g"
613
- );
614
- newProps = newProps.replace(propRegex, `${propMapping.bifyProp}=$1$2$1`);
615
- }
616
- if (arcoComponent === "Dialog" || arcoComponent === "Popup") {
617
- newProps = newProps.replace(/visible=/g, "open=");
618
- }
619
- if (arcoComponent === "SearchBar" || arcoComponent === "Field" || arcoComponent === "Textarea") {
620
- newProps = newProps.replace(/value=/g, "modelValue=");
621
- }
622
- if (arcoComponent === "Cell") {
623
- newProps = newProps.replace(/showArrow/g, "clickable");
624
- }
706
+ newProps = applyPropMappings(newProps, mapping, warnings);
707
+ newProps = applyValueMappings(newProps, mapping);
625
708
  return `<${bifyComponent}${newProps}/>`;
626
709
  });
627
710
  const closingComponentRegex = new RegExp(
@@ -630,23 +713,58 @@ function convertComponents(code) {
630
713
  );
631
714
  result = result.replace(closingComponentRegex, (match, props, children) => {
632
715
  let newProps = props;
633
- for (const propMapping of mapping.propMappings) {
634
- const propRegex = new RegExp(
635
- `${propMapping.arcoProp}=(["'])(.*?)\\1`,
636
- "g"
637
- );
638
- newProps = newProps.replace(propRegex, `${propMapping.bifyProp}=$1$2$1`);
639
- }
640
- if (arcoComponent === "Dialog" || arcoComponent === "Popup") {
641
- newProps = newProps.replace(/visible=/g, "open=");
642
- }
643
- if (arcoComponent === "SearchBar" || arcoComponent === "Field" || arcoComponent === "Textarea") {
644
- newProps = newProps.replace(/value=/g, "modelValue=");
716
+ newProps = applyPropMappings(newProps, mapping, warnings);
717
+ newProps = applyValueMappings(newProps, mapping);
718
+ return `<${bifyComponent}${newProps}>${children}</${bifyComponent}>`;
719
+ });
720
+ addSuggestions(mapping, suggestions);
721
+ }
722
+ return { code: result, mappings: usedMappings };
723
+ }
724
+ function applyPropMappings(props, mapping, warnings) {
725
+ let result = props;
726
+ const arcoProps = props.match(/\b(\w+)=/g)?.map((p) => p.slice(0, -1)) || [];
727
+ const mappedProps = mapping.propMappings.map((m) => m.arcoProp);
728
+ for (const arcoProp of arcoProps) {
729
+ if (!mappedProps.includes(arcoProp) && !["className", "style", "children"].includes(arcoProp)) {
730
+ warnings.push(`\u7EC4\u4EF6 ${mapping.arcoName} \u7684\u5C5E\u6027 ${arcoProp} \u672A\u627E\u5230\u6620\u5C04\uFF0C\u5DF2\u4FDD\u7559\u539F\u6837`);
731
+ }
732
+ }
733
+ for (const propMapping of mapping.propMappings) {
734
+ const propRegex = new RegExp(
735
+ `${propMapping.arcoProp}=(["'])(.*?)\\1`,
736
+ "g"
737
+ );
738
+ result = result.replace(propRegex, (match, quote, value) => {
739
+ if (propMapping.transform) {
740
+ const transformedValue = propMapping.transform(value);
741
+ return `${propMapping.bifyProp}=${quote}${transformedValue}${quote}`;
645
742
  }
646
- if (arcoComponent === "Cell") {
647
- newProps = newProps.replace(/showArrow/g, "clickable");
743
+ return `${propMapping.bifyProp}=${quote}${value}${quote}`;
744
+ });
745
+ const booleanPropRegex = new RegExp(`\\b${propMapping.arcoProp}\\b`, "g");
746
+ if (propMapping.transform) {
747
+ result = result.replace(booleanPropRegex, `${propMapping.bifyProp}=${propMapping.transform("")}`);
748
+ } else {
749
+ result = result.replace(booleanPropRegex, propMapping.bifyProp);
750
+ }
751
+ }
752
+ return result;
753
+ }
754
+ function applyValueMappings(props, mapping) {
755
+ if (!mapping.valueMappings) return props;
756
+ let result = props;
757
+ for (const [propName, valueMap] of Object.entries(mapping.valueMappings)) {
758
+ const propRegex = new RegExp(
759
+ `${propName}=(["'])(.*?)\\1`,
760
+ "g"
761
+ );
762
+ result = result.replace(propRegex, (match, quote, value) => {
763
+ const mappedValue = valueMap[value] || value;
764
+ if (mappedValue !== value) {
765
+ return `${propName}=${quote}${mappedValue}${quote}`;
648
766
  }
649
- return `<${bifyComponent}${newProps}>${children}</${bifyComponent}>`;
767
+ return match;
650
768
  });
651
769
  }
652
770
  return result;
@@ -655,16 +773,51 @@ function convertIconImports(code) {
655
773
  let result = code;
656
774
  const arcoIconRegex = /import\s+Icon(\w+)\s+from\s+['"]@arco-design\/mobile-react\/es\/icon\/Icon(\w+)['"]/g;
657
775
  result = result.replace(arcoIconRegex, 'import { Icon$1 } from "@fjyueke/bify-icons"');
776
+ const arcoIconsImportRegex = /import\s+\{([^}]+)\}\s+from\s+['"]@arco-design\/mobile-react\/es\/icon['"]/g;
777
+ result = result.replace(arcoIconsImportRegex, 'import { $1 } from "@fjyueke/bify-icons"');
658
778
  return result;
659
779
  }
780
+ function fixCodeFormat(code) {
781
+ let result = code;
782
+ result = result.replace(/\n{3,}/g, "\n\n");
783
+ result = result.replace(/import\s+\{\s*\}\s+from/g, "");
784
+ const lines = result.split("\n");
785
+ const nonEmptyLines = lines.filter((line) => line.trim() !== "");
786
+ result = nonEmptyLines.join("\n");
787
+ return result.trim();
788
+ }
789
+ function addSuggestions(mapping, suggestions) {
790
+ const suggestionMap = {
791
+ Cell: "Bify \u7684 Cell \u7EC4\u4EF6\u652F\u6301\u66F4\u591A\u5E03\u5C40\u5C5E\u6027\uFF0C\u5EFA\u8BAE\u67E5\u770B\u6587\u6863\u4E86\u89E3 align\u3001size \u7B49\u5C5E\u6027",
792
+ Button: "Bify \u7684 Button \u7EC4\u4EF6\u652F\u6301\u66F4\u591A\u6837\u5F0F\u53D8\u4F53\uFF0C\u5EFA\u8BAE\u67E5\u770B variant \u5C5E\u6027",
793
+ Dialog: "Bify \u7684 Dialog \u7EC4\u4EF6\u652F\u6301\u66F4\u591A\u4EA4\u4E92\u9009\u9879\uFF0C\u5EFA\u8BAE\u67E5\u770B closeOnClickOverlay \u7B49\u5C5E\u6027",
794
+ Tabs: "Bify \u7684 Tabs \u7EC4\u4EF6\u652F\u6301\u6ED1\u52A8\u5207\u6362\uFF0C\u5EFA\u8BAE\u67E5\u770B swipeable \u5C5E\u6027",
795
+ Field: "Bify \u7684 Field \u7EC4\u4EF6\u652F\u6301\u66F4\u591A\u9A8C\u8BC1\u5C5E\u6027\uFF0C\u5EFA\u8BAE\u67E5\u770B rules \u5C5E\u6027"
796
+ };
797
+ if (suggestionMap[mapping.arcoName]) {
798
+ suggestions.push(suggestionMap[mapping.arcoName]);
799
+ }
800
+ }
660
801
  async function getArcoConversionHelp() {
661
802
  const availableComponents = componentMappings.filter((m) => m.bifyName).map((m) => `- ${m.arcoName} \u2192 ${m.bifyName}`).join("\n");
803
+ const valueMappingExamples = componentMappings.filter((m) => m.valueMappings).map((m) => {
804
+ const mappings = Object.entries(m.valueMappings).map(([prop, values]) => {
805
+ const valuePairs = Object.entries(values).map(([from, to]) => `${from} \u2192 ${to}`).join(", ");
806
+ return ` - ${prop}: ${valuePairs}`;
807
+ }).join("\n");
808
+ return `**${m.arcoName}**
809
+ ${mappings}`;
810
+ }).join("\n\n");
662
811
  return `## Arco Mobile \u2192 Bify \u4EE3\u7801\u8F6C\u6362
663
812
 
664
- ### \u652F\u6301\u7684\u7EC4\u4EF6
813
+ ### \u652F\u6301\u7684\u7EC4\u4EF6 (${componentMappings.length} \u4E2A)
665
814
 
666
815
  ${availableComponents}
667
816
 
817
+ ### \u503C\u6620\u5C04\u793A\u4F8B
818
+
819
+ ${valueMappingExamples || "\u6682\u65E0"}
820
+
668
821
  ### \u4F7F\u7528\u65B9\u5F0F
669
822
 
670
823
  \`\`\`tsx
@@ -674,7 +827,7 @@ import { Cell, CellGroup, Button } from '@arco-design/mobile-react';
674
827
  <CellGroup>
675
828
  <Cell label="\u6807\u9898" desc="\u63CF\u8FF0" showArrow>\u5185\u5BB9</Cell>
676
829
  </CellGroup>
677
- <Button type="primary">\u6309\u94AE</Button>
830
+ <Button type="primary" ghost>\u6309\u94AE</Button>
678
831
 
679
832
  // \u8F6C\u6362\u4E3A Bify \u4EE3\u7801
680
833
  import { Cell, CellGroup, Button } from '@fjyueke/bify-core';
@@ -682,23 +835,31 @@ import { Cell, CellGroup, Button } from '@fjyueke/bify-core';
682
835
  <CellGroup>
683
836
  <Cell title="\u6807\u9898" brief="\u63CF\u8FF0" clickable>\u5185\u5BB9</Cell>
684
837
  </CellGroup>
685
- <Button type="primary">\u6309\u94AE</Button>
838
+ <Button type="primary" outlined>\u6309\u94AE</Button>
686
839
  \`\`\`
687
840
 
688
841
  ### \u5C5E\u6027\u6620\u5C04\u793A\u4F8B
689
842
 
690
- | Arco \u5C5E\u6027 | Bify \u5C5E\u6027 |
691
- |-----------|-----------|
692
- | \`label\` | \`title\` |
693
- | \`desc\` | \`brief\` |
694
- | \`showArrow\` | \`clickable\` |
695
- | \`visible\` | \`open\` |
696
- | \`value\` | \`modelValue\` |
697
- | \`ghost\` | \`plain\` |
843
+ | Arco \u5C5E\u6027 | Bify \u5C5E\u6027 | \u8BF4\u660E |
844
+ |-----------|-----------|------|
845
+ | \`label\` | \`title\` | \u5355\u5143\u683C\u6807\u9898 |
846
+ | \`desc\` | \`brief\` | \u5355\u5143\u683C\u63CF\u8FF0 |
847
+ | \`showArrow\` | \`clickable\` | \u662F\u5426\u663E\u793A\u7BAD\u5934 |
848
+ | \`visible\` | \`open\` | \u5F39\u7A97\u663E\u793A\u72B6\u6001 |
849
+ | \`value\` | \`modelValue\` | \u8868\u5355\u503C\u7ED1\u5B9A |
850
+ | \`ghost\` | \`outlined\` | \u9542\u7A7A\u6309\u94AE\u6837\u5F0F |
851
+ | \`max\` | \`count\` | Rate \u6700\u5927\u6570\u91CF |
852
+ | \`percent\` | \`percentage\` | Progress \u767E\u5206\u6BD4 |
853
+
854
+ ### \u6700\u4F73\u5B9E\u8DF5
855
+
856
+ 1. **\u4F7F\u7528 AI \u8F85\u52A9\u8F6C\u6362**\uFF1A\u540C\u65F6\u914D\u7F6E Arco Mobile MCP \u548C Bify MCP\uFF0C\u8BA9 AI \u67E5\u8BE2\u53CC\u65B9\u6587\u6863\u540E\u518D\u8FDB\u884C\u8F6C\u6362
857
+ 2. **\u624B\u52A8\u68C0\u67E5**\uFF1A\u8F6C\u6362\u540E\u8BF7\u68C0\u67E5\u8B66\u544A\u4FE1\u606F\uFF0C\u5904\u7406\u672A\u6620\u5C04\u7684\u5C5E\u6027
858
+ 3. **\u53C2\u8003\u6587\u6863**\uFF1A\u4F7F\u7528 \`get-component-docs\` \u548C \`get-component-props\` \u67E5\u770B Bify \u7EC4\u4EF6\u7684\u8BE6\u7EC6\u7528\u6CD5
698
859
 
699
860
  ### \u8C03\u7528\u65B9\u5F0F
700
861
 
701
- \u4F7F\u7528 \`convert-arco-to-bify\` \u5DE5\u5177\uFF0C\u4F20\u5165 Arco Mobile \u4EE3\u7801\u5373\u53EF\u83B7\u5F97\u8F6C\u6362\u540E\u7684 Bify \u4EE3\u7801\u3002`;
862
+ \u4F7F\u7528 \`convert-arco-to-bify\` \u5DE5\u5177\uFF0C\u4F20\u5165 Arco Mobile \u4EE3\u7801\u5373\u53EF\u83B7\u5F97\u8F6C\u6362\u540E\u7684 Bify \u4EE3\u7801\u53CA\u8BE6\u7EC6\u62A5\u544A\u3002`;
702
863
  }
703
864
 
704
865
  // src/tools/components.ts
@@ -770,19 +931,50 @@ function registerTifyTools(server) {
770
931
  );
771
932
  server.tool(
772
933
  "convert-arco-to-bify",
773
- "Converts Arco Mobile React code to Bify code",
934
+ "Converts Arco Mobile React code to Bify code with detailed report including warnings and suggestions",
774
935
  { arcoCode: z.string() },
775
936
  async (args) => {
776
- const convertedCode = await convertArcoToBify(args.arcoCode);
937
+ const result = await convertArcoToBify(args.arcoCode);
938
+ let report = `## \u8F6C\u6362\u7ED3\u679C
939
+
940
+ ### \u8F6C\u6362\u540E\u7684\u4EE3\u7801
941
+
942
+ \`\`\`tsx
943
+ ${result.code}
944
+ \`\`\``;
945
+ if (result.mappings.length > 0) {
946
+ report += `
947
+
948
+ ### \u4F7F\u7528\u7684\u6620\u5C04
949
+
950
+ | Arco \u7EC4\u4EF6 | Bify \u7EC4\u4EF6 |
951
+ |-----------|-----------|
952
+ ${result.mappings.map((m) => `| ${m.arcoName} | ${m.bifyName} |`).join("\n")}`;
953
+ }
954
+ if (result.warnings.length > 0) {
955
+ report += `
956
+
957
+ ### \u26A0\uFE0F \u8B66\u544A
958
+
959
+ - ${result.warnings.join("\n- ")}`;
960
+ }
961
+ if (result.suggestions.length > 0) {
962
+ report += `
963
+
964
+ ### \u{1F4A1} \u5EFA\u8BAE
965
+
966
+ - ${result.suggestions.join("\n- ")}`;
967
+ }
968
+ report += `
969
+
970
+ ### \u8F6C\u6362\u8BF4\u660E
971
+
972
+ \u5982\u9700\u66F4\u7CBE\u786E\u7684\u8F6C\u6362\uFF0C\u5EFA\u8BAE\u540C\u65F6\u4F7F\u7528 Arco Mobile MCP \u548C Bify MCP \u67E5\u8BE2\u53CC\u65B9\u7EC4\u4EF6\u6587\u6863\u540E\u8FDB\u884C\u624B\u52A8\u8C03\u6574\u3002`;
777
973
  return {
778
974
  content: [
779
975
  {
780
976
  type: "text",
781
- text: `## \u8F6C\u6362\u7ED3\u679C
782
-
783
- \`\`\`tsx
784
- ${convertedCode}
785
- \`\`\``
977
+ text: report
786
978
  }
787
979
  ]
788
980
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjyueke/bify-mcp",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "type": "module",
5
5
  "description": "MCP UI builder by Bify",
6
6
  "license": "MIT",