congmao-cli 1.0.0

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 (180) hide show
  1. package/README.md +2 -0
  2. package/bin/index.js +20 -0
  3. package/package.json +42 -0
  4. package/src/commands/create.js +171 -0
  5. package/src/commands/mcp.js +157 -0
  6. package/src/mcp/CURSOR_SETUP.md +259 -0
  7. package/src/mcp/README.md +134 -0
  8. package/src/mcp/USAGE_EXAMPLES.md +181 -0
  9. package/src/mcp/get-cursor-config.js +58 -0
  10. package/src/mcp/package.json +23 -0
  11. package/src/mcp/pnpm-lock.yaml +2441 -0
  12. package/src/mcp/src/handlers.js +211 -0
  13. package/src/mcp/src/http-server.js +332 -0
  14. package/src/mcp/src/index.js +195 -0
  15. package/src/mcp/src/schemas.js +54 -0
  16. package/src/mcp/test-create-project.js +49 -0
  17. package/src/mcp/test-mcp.js +89 -0
  18. package/src/mcp/test-show-tree.js +66 -0
  19. package/src/template/Uni-app/README.md +19 -0
  20. package/src/template/Uni-app/babel.config.js +81 -0
  21. package/src/template/Uni-app/package.json +107 -0
  22. package/src/template/Uni-app/postcss.config.js +27 -0
  23. package/src/template/Uni-app/public/index.html +25 -0
  24. package/src/template/Uni-app/shims-uni.d.ts +11 -0
  25. package/src/template/Uni-app/shims-vue.d.ts +4 -0
  26. package/src/template/Uni-app/src/App.vue +17 -0
  27. package/src/template/Uni-app/src/main.js +12 -0
  28. package/src/template/Uni-app/src/manifest.json +75 -0
  29. package/src/template/Uni-app/src/pages/index/index.vue +49 -0
  30. package/src/template/Uni-app/src/pages.json +16 -0
  31. package/src/template/Uni-app/src/static/logo.png +0 -0
  32. package/src/template/Uni-app/src/uni.promisify.adaptor.js +13 -0
  33. package/src/template/Uni-app/src/uni.scss +76 -0
  34. package/src/template/Uni-app/yarn.lock +11466 -0
  35. package/src/template/Vue2/.editorconfig +14 -0
  36. package/src/template/Vue2/.env +2 -0
  37. package/src/template/Vue2/.env.development +2 -0
  38. package/src/template/Vue2/.env.site +2 -0
  39. package/src/template/Vue2/.prettierrc.js +39 -0
  40. package/src/template/Vue2/.stylelintignore +8 -0
  41. package/src/template/Vue2/README-zh_CN.md +115 -0
  42. package/src/template/Vue2/commitlint.config.js +1 -0
  43. package/src/template/Vue2/docs/docs-starter.png +0 -0
  44. package/src/template/Vue2/docs/docs-startup.png +0 -0
  45. package/src/template/Vue2/docs/docs-structure.png +0 -0
  46. package/src/template/Vue2/globals.d.ts +13 -0
  47. package/src/template/Vue2/index.html +27 -0
  48. package/src/template/Vue2/jsx.d.ts +13 -0
  49. package/src/template/Vue2/mock/index.ts +147 -0
  50. package/src/template/Vue2/package.json +91 -0
  51. package/src/template/Vue2/package.json.ejs +91 -0
  52. package/src/template/Vue2/public/favicon.ico +0 -0
  53. package/src/template/Vue2/shims-vue.d.ts +5 -0
  54. package/src/template/Vue2/src/App.vue +19 -0
  55. package/src/template/Vue2/src/assets/assets-login-bg-black.png +0 -0
  56. package/src/template/Vue2/src/assets/assets-login-bg-white.png +0 -0
  57. package/src/template/Vue2/src/assets/assets-logo-full.svg +39 -0
  58. package/src/template/Vue2/src/assets/assets-product-1.svg +5 -0
  59. package/src/template/Vue2/src/assets/assets-product-2.svg +5 -0
  60. package/src/template/Vue2/src/assets/assets-product-3.svg +5 -0
  61. package/src/template/Vue2/src/assets/assets-product-4.svg +5 -0
  62. package/src/template/Vue2/src/assets/assets-result-403.svg +32 -0
  63. package/src/template/Vue2/src/assets/assets-result-404.svg +36 -0
  64. package/src/template/Vue2/src/assets/assets-result-500.svg +32 -0
  65. package/src/template/Vue2/src/assets/assets-result-ie.svg +33 -0
  66. package/src/template/Vue2/src/assets/assets-result-maintenance.svg +49 -0
  67. package/src/template/Vue2/src/assets/assets-result-wifi.svg +23 -0
  68. package/src/template/Vue2/src/assets/assets-setting-auto.svg +13 -0
  69. package/src/template/Vue2/src/assets/assets-setting-dark.svg +5 -0
  70. package/src/template/Vue2/src/assets/assets-setting-light.svg +13 -0
  71. package/src/template/Vue2/src/assets/assets-t-logo.svg +41 -0
  72. package/src/template/Vue2/src/assets/assets-tencent-logo.png +0 -0
  73. package/src/template/Vue2/src/components/color/index.vue +35 -0
  74. package/src/template/Vue2/src/components/product-card/index.vue +121 -0
  75. package/src/template/Vue2/src/components/result/index.vue +118 -0
  76. package/src/template/Vue2/src/components/thumbnail/index.vue +49 -0
  77. package/src/template/Vue2/src/components/trend/index.vue +105 -0
  78. package/src/template/Vue2/src/config/color.ts +30 -0
  79. package/src/template/Vue2/src/config/global.ts +2 -0
  80. package/src/template/Vue2/src/config/host.ts +26 -0
  81. package/src/template/Vue2/src/config/style.ts +14 -0
  82. package/src/template/Vue2/src/constants/index.ts +46 -0
  83. package/src/template/Vue2/src/interface.ts +39 -0
  84. package/src/template/Vue2/src/layouts/blank.vue +12 -0
  85. package/src/template/Vue2/src/layouts/components/Breadcrumb.vue +39 -0
  86. package/src/template/Vue2/src/layouts/components/Content.vue +43 -0
  87. package/src/template/Vue2/src/layouts/components/Footer.vue +27 -0
  88. package/src/template/Vue2/src/layouts/components/Header.vue +321 -0
  89. package/src/template/Vue2/src/layouts/components/LayoutContent.vue +168 -0
  90. package/src/template/Vue2/src/layouts/components/LayoutHeader.vue +52 -0
  91. package/src/template/Vue2/src/layouts/components/LayoutSidebar.vue +51 -0
  92. package/src/template/Vue2/src/layouts/components/MenuContent.vue +108 -0
  93. package/src/template/Vue2/src/layouts/components/Notice.vue +221 -0
  94. package/src/template/Vue2/src/layouts/components/Search.vue +134 -0
  95. package/src/template/Vue2/src/layouts/components/SideNav.vue +150 -0
  96. package/src/template/Vue2/src/layouts/index.vue +100 -0
  97. package/src/template/Vue2/src/layouts/setting.vue +404 -0
  98. package/src/template/Vue2/src/main.js +9 -0
  99. package/src/template/Vue2/src/main.jsx +51 -0
  100. package/src/template/Vue2/src/pages/dashboard/base/components/MiddleChart.vue +158 -0
  101. package/src/template/Vue2/src/pages/dashboard/base/components/OutputOverview.vue +189 -0
  102. package/src/template/Vue2/src/pages/dashboard/base/components/RankList.vue +111 -0
  103. package/src/template/Vue2/src/pages/dashboard/base/components/TopPanel.vue +246 -0
  104. package/src/template/Vue2/src/pages/dashboard/base/index.ts +702 -0
  105. package/src/template/Vue2/src/pages/dashboard/base/index.vue +44 -0
  106. package/src/template/Vue2/src/pages/dashboard/detail/index.ts +267 -0
  107. package/src/template/Vue2/src/pages/dashboard/detail/index.vue +242 -0
  108. package/src/template/Vue2/src/pages/detail/advanced/components/Product.vue +167 -0
  109. package/src/template/Vue2/src/pages/detail/advanced/index.less +74 -0
  110. package/src/template/Vue2/src/pages/detail/advanced/index.vue +219 -0
  111. package/src/template/Vue2/src/pages/detail/base/index.less +105 -0
  112. package/src/template/Vue2/src/pages/detail/base/index.vue +46 -0
  113. package/src/template/Vue2/src/pages/detail/deploy/index.ts +204 -0
  114. package/src/template/Vue2/src/pages/detail/deploy/index.vue +224 -0
  115. package/src/template/Vue2/src/pages/detail/secondary/index.less +71 -0
  116. package/src/template/Vue2/src/pages/detail/secondary/index.vue +131 -0
  117. package/src/template/Vue2/src/pages/form/base/index.less +57 -0
  118. package/src/template/Vue2/src/pages/form/base/index.vue +254 -0
  119. package/src/template/Vue2/src/pages/form/step/index.less +37 -0
  120. package/src/template/Vue2/src/pages/form/step/index.vue +259 -0
  121. package/src/template/Vue2/src/pages/frame/doc/index.vue +86 -0
  122. package/src/template/Vue2/src/pages/frame/tdesign/index.vue +86 -0
  123. package/src/template/Vue2/src/pages/list/base/index.vue +267 -0
  124. package/src/template/Vue2/src/pages/list/card/index.vue +221 -0
  125. package/src/template/Vue2/src/pages/list/components/CommonTable.vue +313 -0
  126. package/src/template/Vue2/src/pages/list/filter/index.vue +15 -0
  127. package/src/template/Vue2/src/pages/list/tree/index.vue +174 -0
  128. package/src/template/Vue2/src/pages/login/components/components-header.vue +74 -0
  129. package/src/template/Vue2/src/pages/login/components/components-login.vue +154 -0
  130. package/src/template/Vue2/src/pages/login/components/components-register.vue +144 -0
  131. package/src/template/Vue2/src/pages/login/index.less +202 -0
  132. package/src/template/Vue2/src/pages/login/index.vue +53 -0
  133. package/src/template/Vue2/src/pages/nest-menu/Index.vue +10 -0
  134. package/src/template/Vue2/src/pages/result/403/index.vue +14 -0
  135. package/src/template/Vue2/src/pages/result/404/index.vue +14 -0
  136. package/src/template/Vue2/src/pages/result/500/index.vue +14 -0
  137. package/src/template/Vue2/src/pages/result/browser-incompatible/index.vue +77 -0
  138. package/src/template/Vue2/src/pages/result/fail/index.vue +57 -0
  139. package/src/template/Vue2/src/pages/result/maintenance/index.vue +14 -0
  140. package/src/template/Vue2/src/pages/result/network-error/index.vue +24 -0
  141. package/src/template/Vue2/src/pages/result/success/index.vue +59 -0
  142. package/src/template/Vue2/src/pages/user/index.less +148 -0
  143. package/src/template/Vue2/src/pages/user/index.ts +157 -0
  144. package/src/template/Vue2/src/pages/user/index.vue +204 -0
  145. package/src/template/Vue2/src/permission.js +56 -0
  146. package/src/template/Vue2/src/router/index.js +43 -0
  147. package/src/template/Vue2/src/router/modules/base.ts +29 -0
  148. package/src/template/Vue2/src/router/modules/components.ts +175 -0
  149. package/src/template/Vue2/src/router/modules/others.ts +55 -0
  150. package/src/template/Vue2/src/service/service-advance.ts +233 -0
  151. package/src/template/Vue2/src/service/service-base.ts +205 -0
  152. package/src/template/Vue2/src/service/service-detail-base.ts +84 -0
  153. package/src/template/Vue2/src/service/service-detail-deploy.ts +234 -0
  154. package/src/template/Vue2/src/service/service-detail.ts +57 -0
  155. package/src/template/Vue2/src/service/service-user.ts +64 -0
  156. package/src/template/Vue2/src/store/index.ts +22 -0
  157. package/src/template/Vue2/src/store/modules/notification.ts +90 -0
  158. package/src/template/Vue2/src/store/modules/permission.ts +66 -0
  159. package/src/template/Vue2/src/store/modules/setting.ts +122 -0
  160. package/src/template/Vue2/src/store/modules/tab-router.ts +83 -0
  161. package/src/template/Vue2/src/store/modules/user.ts +98 -0
  162. package/src/template/Vue2/src/style/font-family.less +6 -0
  163. package/src/template/Vue2/src/style/index.less +5 -0
  164. package/src/template/Vue2/src/style/layout.less +201 -0
  165. package/src/template/Vue2/src/style/reset.less +78 -0
  166. package/src/template/Vue2/src/style/variables.less +27 -0
  167. package/src/template/Vue2/src/utils/charts.ts +38 -0
  168. package/src/template/Vue2/src/utils/color.ts +118 -0
  169. package/src/template/Vue2/src/utils/date.ts +12 -0
  170. package/src/template/Vue2/src/utils/request.ts +60 -0
  171. package/src/template/Vue2/stylelint.config.js +5 -0
  172. package/src/template/Vue2/tsconfig.json +26 -0
  173. package/src/template/Vue2/vite.config.js +58 -0
  174. package/src/template/Vue3/package.json.ejs +8 -0
  175. package/src/template/Vue3/pages.json +10 -0
  176. package/src/template/Vue3/src/main.js +7 -0
  177. package/src/utils/copy.js +17 -0
  178. package/src/utils/eslint.js +205 -0
  179. package/src/utils/logo.js +18 -0
  180. package/src/utils/render.js +20 -0
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # cm-cli
2
+ cli
package/bin/index.js ADDED
@@ -0,0 +1,20 @@
1
+ #! /usr/bin/env node
2
+
3
+ import { program } from "commander";
4
+ import create from "../src/commands/create.js";
5
+ import mcp from "../src/commands/mcp.js";
6
+ import { showLogo } from "../src/utils/logo.js";
7
+
8
+ showLogo();
9
+
10
+ program.name("cm-cli").version("1.0.0");
11
+
12
+ program.command("create").description("创建初始化项目").action(create);
13
+
14
+ program
15
+ .command("mcp")
16
+ .description("启动 MCP stdio 服务器并显示配置信息(用于 Cursor)")
17
+ .option("--config-only", "仅显示配置信息,不启动服务器", false)
18
+ .action(mcp);
19
+
20
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "congmao-cli",
3
+ "version": "1.0.0",
4
+ "description": "cli",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "bin": {
8
+ "cm": "bin/index.js"
9
+ },
10
+ "files": [
11
+ "bin",
12
+ "src",
13
+ "package.json",
14
+ "README.md"
15
+ ],
16
+ "scripts": {
17
+ "test": "echo \"Error: no test specified\" && exit 1",
18
+ "prepublishOnly": "node scripts/prepublish.js",
19
+ "postinstall": "cd src/mcp && npm install --no-save || true"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/aZeroDoubleSeven/cm-cli.git"
24
+ },
25
+ "keywords": [],
26
+ "author": "",
27
+ "license": "ISC",
28
+ "bugs": {
29
+ "url": "https://github.com/aZeroDoubleSeven/cm-cli/issues"
30
+ },
31
+ "homepage": "https://github.com/aZeroDoubleSeven/cm-cli#readme",
32
+ "dependencies": {
33
+ "@clack/prompts": "^0.11.0",
34
+ "boxen": "^8.0.1",
35
+ "chalk": "^5.4.1",
36
+ "commander": "^11.0.0",
37
+ "ejs": "^3.1.9",
38
+ "gradient-string": "^3.0.0",
39
+ "inquirer": "^9.2.12",
40
+ "lerna": "^8.1.9"
41
+ }
42
+ }
@@ -0,0 +1,171 @@
1
+ import {
2
+ intro,
3
+ outro,
4
+ text,
5
+ select,
6
+ confirm,
7
+ spinner,
8
+ cancel,
9
+ isCancel,
10
+ } from '@clack/prompts';
11
+ import gradient from 'gradient-string';
12
+ import path from "node:path";
13
+ import fs from "node:fs";
14
+ import chalk from "chalk";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ import copyDir from "../utils/copy.js";
18
+ import renderTemplates from "../utils/render.js";
19
+ import setupESLint from "../utils/eslint.js";
20
+
21
+ const __filename = fileURLToPath(import.meta.url);
22
+ const __dirname = path.dirname(__filename);
23
+
24
+ /**
25
+ * 根据模板类型获取启动命令
26
+ */
27
+ function getStartCommand(templateName, needESLint) {
28
+ const commands = {
29
+ 'Uni-app': {
30
+ install: 'pnpm install',
31
+ lint: needESLint ? 'pnpm run lint' : null,
32
+ dev: 'pnpm run dev:h5'
33
+ },
34
+ 'Vue2': {
35
+ install: 'pnpm install',
36
+ lint: needESLint ? 'pnpm run lint' : null,
37
+ dev: 'pnpm run dev'
38
+ },
39
+ 'Vue3': {
40
+ install: 'pnpm install',
41
+ lint: needESLint ? 'pnpm run lint' : null,
42
+ dev: 'pnpm run dev'
43
+ }
44
+ };
45
+
46
+ return commands[templateName] || commands['Vue2'];
47
+ }
48
+
49
+ export default async function create() {
50
+ // 显示欢迎信息
51
+ intro(gradient(['#00FFFF', '#00CED1', '#00BFFF', '#00FF7F'])('欢迎使用丛茂科技 CM CLI ! 🚀'));
52
+
53
+ // 1. 选择项目类型
54
+ const projectType = await select({
55
+ message: '请选择项目类型:',
56
+ options: [
57
+ { value: 'mobile', label: '移动端', hint: '适用于移动端应用开发' },
58
+ { value: 'miniprogram', label: '小程序', hint: '适用于小程序开发' },
59
+ { value: 'admin', label: '后台管理系统', hint: '适用于后台管理系统开发' },
60
+ ],
61
+ });
62
+
63
+ if (isCancel(projectType)) {
64
+ cancel('操作已取消');
65
+ process.exit(0);
66
+ }
67
+
68
+ // 2. 根据项目类型选择具体模板
69
+ let templateName;
70
+
71
+ if (projectType === 'mobile' || projectType === 'miniprogram') {
72
+ // 移动端和小程序使用 Uni-app
73
+ templateName = 'Uni-app';
74
+ } else if (projectType === 'admin') {
75
+ // 后台管理系统选择 Vue 版本
76
+ const vueVersion = await select({
77
+ message: '请选择 Vue 版本:',
78
+ options: [
79
+ { value: 'Vue2', label: 'Vue 2', hint: '稳定版本' },
80
+ { value: 'Vue3', label: 'Vue 3', hint: '最新版本' },
81
+ ],
82
+ });
83
+
84
+ if (isCancel(vueVersion)) {
85
+ cancel('操作已取消');
86
+ process.exit(0);
87
+ }
88
+
89
+ templateName = vueVersion;
90
+ }
91
+
92
+ // 3. 获取项目名称
93
+ const projectName = await text({
94
+ message: '请输入项目名称:',
95
+ placeholder: projectType === 'admin' ? 'admin-project' : 'uni-app-project',
96
+ validate: (value) => {
97
+ if (!value) return '项目名称不能为空';
98
+ if (!/^[a-z0-9-]+$/.test(value)) {
99
+ return '只能包含小写字母、数字和连字符';
100
+ }
101
+ },
102
+ });
103
+
104
+ if (isCancel(projectName)) {
105
+ cancel('操作已取消');
106
+ process.exit(0);
107
+ }
108
+
109
+ // 4. 询问是否配置 ESLint
110
+ const needESLint = await confirm({
111
+ message: '是否配置 ESLint?',
112
+ initialValue: true,
113
+ });
114
+
115
+ if (isCancel(needESLint)) {
116
+ cancel('操作已取消');
117
+ process.exit(0);
118
+ }
119
+
120
+ // 5. 检查目录是否存在
121
+ const targetDir = path.resolve(process.cwd(), projectName);
122
+
123
+ if (fs.existsSync(targetDir)) {
124
+ cancel(chalk.red('❌ 目录已存在'));
125
+ process.exit(1);
126
+ }
127
+
128
+ // 6. 创建项目
129
+ const s = spinner();
130
+ s.start('正在创建项目...');
131
+
132
+ try {
133
+ const templateDir = path.resolve(
134
+ __dirname,
135
+ `../template/${templateName}`
136
+ );
137
+
138
+ if (!fs.existsSync(templateDir)) {
139
+ s.stop('❌ 模板不存在');
140
+ cancel(`模板目录不存在: ${templateDir}`);
141
+ process.exit(1);
142
+ }
143
+
144
+ copyDir(templateDir, targetDir);
145
+ renderTemplates(targetDir, { projectName, needESLint });
146
+
147
+ // 如果选择配置 ESLint,则进行配置
148
+ if (needESLint) {
149
+ s.message('正在配置 ESLint...');
150
+ await setupESLint(targetDir, templateName);
151
+ }
152
+
153
+ s.stop('✅ 项目创建成功!');
154
+
155
+ // 7. 显示成功信息
156
+ const startCmd = getStartCommand(templateName, needESLint);
157
+ let installCmd = ` cd ${projectName}\n ${startCmd.install}\n`;
158
+
159
+ if (startCmd.lint) {
160
+ installCmd += ` ${startCmd.lint}\n`;
161
+ }
162
+
163
+ installCmd += ` ${startCmd.dev}\n`;
164
+
165
+ outro(chalk.green(`\n🎉 项目创建成功!\n\n${installCmd}`));
166
+ } catch (error) {
167
+ s.stop('❌ 创建失败');
168
+ cancel(`创建项目时出错: ${error.message}`);
169
+ process.exit(1);
170
+ }
171
+ }
@@ -0,0 +1,157 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import path from "node:path";
3
+ import fs from "node:fs";
4
+ import chalk from "chalk";
5
+
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+
9
+ /**
10
+ * 查找包根目录(包含 package.json 的目录)
11
+ */
12
+ function findPackageRoot() {
13
+ let currentDir = __dirname;
14
+ const root = path.parse(currentDir).root;
15
+
16
+ while (currentDir !== root) {
17
+ const packageJsonPath = path.join(currentDir, "package.json");
18
+ if (fs.existsSync(packageJsonPath)) {
19
+ return currentDir;
20
+ }
21
+ currentDir = path.dirname(currentDir);
22
+ }
23
+
24
+ // 如果找不到,使用相对路径(开发环境)
25
+ return path.resolve(__dirname, "../..");
26
+ }
27
+
28
+ /**
29
+ * 获取 MCP 服务器配置信息
30
+ */
31
+ function getMCPConfig() {
32
+ // 获取包根目录
33
+ const packageRoot = findPackageRoot();
34
+
35
+ // 获取 MCP 服务器的绝对路径(用于 stdio 传输)
36
+ // 优先尝试包内的路径,如果不存在则尝试相对路径(开发环境)
37
+ const mcpServerPathInPackage = path.join(packageRoot, "src/mcp/src/index.js");
38
+ const mcpServerPathRelative = path.resolve(__dirname, "../mcp/src/index.js");
39
+
40
+ const mcpServerPath = fs.existsSync(mcpServerPathInPackage)
41
+ ? mcpServerPathInPackage
42
+ : mcpServerPathRelative;
43
+
44
+ // Cursor 使用 stdio 传输,需要 command + args 配置
45
+ const config = {
46
+ mcpServers: {
47
+ "cm-cli": {
48
+ command: "node",
49
+ args: [mcpServerPath],
50
+ },
51
+ },
52
+ };
53
+
54
+ // 检查依赖(尝试多个可能的位置)
55
+ const possibleDepsPaths = [
56
+ path.join(packageRoot, "src/mcp/node_modules/@modelcontextprotocol/sdk"),
57
+ path.join(packageRoot, "node_modules/@modelcontextprotocol/sdk"),
58
+ path.resolve(__dirname, "../mcp/node_modules/@modelcontextprotocol/sdk"),
59
+ ];
60
+
61
+ const depsInstalled = possibleDepsPaths.some(depPath => fs.existsSync(depPath));
62
+
63
+ return {
64
+ config,
65
+ mcpServerPath,
66
+ pathExists: fs.existsSync(mcpServerPath),
67
+ depsInstalled,
68
+ };
69
+ }
70
+
71
+ /**
72
+ * 打印 MCP 配置信息
73
+ */
74
+ function printConfig() {
75
+ const { config } = getMCPConfig();
76
+
77
+ console.log(chalk.yellow.bold("Cursor MCP 配置 (mcpServers) - stdio 传输:\n"));
78
+ console.log(chalk.white(JSON.stringify(config, null, 2)));
79
+ console.log("\n");
80
+ }
81
+
82
+ /**
83
+ * 启动 MCP 服务器
84
+ */
85
+ async function startMCPServer() {
86
+ const { mcpServerPath, pathExists, depsInstalled } = getMCPConfig();
87
+
88
+ if (!pathExists) {
89
+ console.error(chalk.red(`❌ MCP 服务器文件不存在: ${mcpServerPath}`));
90
+ process.exit(1);
91
+ }
92
+
93
+ if (!depsInstalled) {
94
+ console.error(chalk.red("❌ 依赖未安装,请先运行: cd src/mcp && pnpm install"));
95
+ process.exit(1);
96
+ }
97
+
98
+ try {
99
+ // 启动 stdio 服务器(用于 Cursor)
100
+ console.log(chalk.green("🚀 正在启动 MCP stdio 服务器(用于 Cursor)...\n"));
101
+
102
+ const { spawn } = await import("child_process");
103
+ const stdioProcess = spawn("node", [mcpServerPath], {
104
+ stdio: "inherit",
105
+ cwd: path.dirname(mcpServerPath),
106
+ });
107
+
108
+ stdioProcess.on("error", (error) => {
109
+ console.error(chalk.red(`❌ 启动失败: ${error.message}`));
110
+ process.exit(1);
111
+ });
112
+
113
+ console.log(chalk.green(`✅ MCP stdio 服务器已启动(用于 Cursor)`));
114
+ console.log(chalk.gray(` 按 Ctrl+C 停止服务器\n`));
115
+
116
+ // 处理退出信号
117
+ process.on("SIGINT", () => {
118
+ console.log(chalk.yellow("\n\n正在停止 MCP 服务器..."));
119
+ stdioProcess.kill();
120
+ console.log(chalk.green("✅ 服务器已停止"));
121
+ process.exit(0);
122
+ });
123
+
124
+ process.on("SIGTERM", () => {
125
+ stdioProcess.kill();
126
+ process.exit(0);
127
+ });
128
+
129
+ stdioProcess.on("exit", (code) => {
130
+ if (code !== 0 && code !== null) {
131
+ console.error(chalk.red(`❌ 服务器异常退出,代码: ${code}`));
132
+ }
133
+ process.exit(code || 0);
134
+ });
135
+ } catch (error) {
136
+ console.error(chalk.red(`❌ 启动失败: ${error.message}`));
137
+ process.exit(1);
138
+ }
139
+ }
140
+
141
+ /**
142
+ * MCP 命令主函数
143
+ */
144
+ export default async function mcp(options = {}) {
145
+ // 先打印配置信息
146
+ printConfig();
147
+
148
+ // 如果只是查看配置,不启动服务器
149
+ if (options.configOnly) {
150
+ console.log(chalk.gray("💡 提示: 使用 'cm mcp' 可以启动 MCP stdio 服务器(用于 Cursor)\n"));
151
+ return;
152
+ }
153
+
154
+ // 然后启动服务器
155
+ await startMCPServer();
156
+ }
157
+
@@ -0,0 +1,259 @@
1
+ # 在 Cursor 中使用 CM CLI MCP 服务器
2
+
3
+ 本指南将帮助你在 Cursor 中配置和使用 CM CLI MCP 服务器。
4
+
5
+ ## 🚀 快速开始
6
+
7
+ 1. **安装依赖(首次使用必需)**
8
+ ```bash
9
+ cd src/mcp
10
+ pnpm install
11
+ ```
12
+ 这会安装 MCP SDK 等必要的依赖包。
13
+
14
+ 2. **获取配置信息**
15
+ ```bash
16
+ pnpm run get-config
17
+ ```
18
+ 这会显示你需要的配置信息。
19
+
20
+ 2. **在 Cursor 中配置**
21
+ - 打开设置 (`Ctrl+,` 或 `Cmd+,`)
22
+ - 搜索 "MCP"
23
+ - 添加显示的配置
24
+
25
+ 3. **重启 Cursor**
26
+
27
+ 4. **开始使用**
28
+ 在 Cursor 的 AI 聊天中,你可以说:
29
+ - "请创建一个 Vue2 后台管理系统项目"
30
+ - "请查看当前项目的结构树"
31
+
32
+ ## 前置要求
33
+
34
+ 1. 确保已安装 Node.js (v18 或更高版本)
35
+ 2. 确保已安装 pnpm:`npm install -g pnpm`
36
+ 3. **重要**: 首次使用前必须安装项目依赖:
37
+ ```bash
38
+ cd src/mcp
39
+ pnpm install
40
+ ```
41
+ 如果遇到依赖问题,可以使用 `pnpm install --force` 强制重新安装。
42
+
43
+ ## 配置步骤
44
+
45
+ ### 方法 1: 通过 Cursor 设置配置(推荐)
46
+
47
+ 1. **打开 Cursor 设置**
48
+ - 按 `Ctrl+,` (Windows/Linux) 或 `Cmd+,` (Mac) 打开设置
49
+ - 或者点击左下角齿轮图标 → Settings
50
+
51
+ 2. **找到 MCP 设置**
52
+ - 在设置搜索框中输入 "MCP" 或 "Model Context Protocol"
53
+ - 找到 MCP 服务器配置选项
54
+
55
+ 3. **添加 MCP 服务器配置**
56
+
57
+ 运行以下命令获取配置:
58
+ ```bash
59
+ cm mcp --config-only
60
+ ```
61
+
62
+ 或者手动添加以下内容(JSON 格式):
63
+
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "cm-cli": {
68
+ "command": "node",
69
+ "args": [
70
+ "/path/to/cm-cli/src/mcp/src/index.js"
71
+ ]
72
+ }
73
+ }
74
+ }
75
+ ```
76
+
77
+ **重要**:
78
+ - Cursor 使用 **stdio 传输**,必须使用 `command` + `args` 格式
79
+ - 请将路径替换为你的实际项目路径
80
+ - 不需要指定端口,stdio 传输不依赖端口
81
+
82
+ ### 方法 2: 通过配置文件
83
+
84
+ 1. **找到 Cursor 配置文件位置**
85
+ - Windows: `%APPDATA%\Cursor\User\globalStorage\cursor.mcp\settings.json`
86
+ - macOS: `~/Library/Application Support/Cursor/User/globalStorage/cursor.mcp/settings.json`
87
+ - Linux: `~/.config/Cursor/User/globalStorage/cursor.mcp/settings.json`
88
+
89
+ 2. **编辑配置文件**
90
+
91
+ 如果文件不存在,创建它。添加以下内容:
92
+
93
+ ```json
94
+ {
95
+ "mcpServers": {
96
+ "cm-cli": {
97
+ "command": "node",
98
+ "args": [
99
+ "/absolute/path/to/cm-cli/src/mcp/src/index.js"
100
+ ]
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ 3. **重启 Cursor**
107
+
108
+ 保存配置文件后,重启 Cursor 使配置生效。
109
+
110
+ ## 验证配置
111
+
112
+ 配置完成后,你可以通过以下方式验证:
113
+
114
+ 1. **在 Cursor 中询问 AI**
115
+ - 打开 Cursor 的 AI 聊天面板
116
+ - 输入:`请使用 create-project 工具创建一个 Vue2 项目`
117
+ - 如果配置正确,AI 应该能够调用 MCP 工具
118
+
119
+ 2. **查看可用工具**
120
+ - 询问 AI:`列出可用的 MCP 工具`
121
+ - 应该能看到 `create-project` 和 `show-project-tree` 两个工具
122
+
123
+ ## 使用示例
124
+
125
+ ### 示例 1: 创建项目
126
+
127
+ 在 Cursor 的 AI 聊天中,你可以这样请求:
128
+
129
+ ```
130
+ 请使用 create-project 工具创建一个名为 "my-admin-app" 的后台管理系统项目,
131
+ 使用 Vue2,并配置 ESLint。
132
+ ```
133
+
134
+ AI 会自动调用 MCP 工具并创建项目。
135
+
136
+ ### 示例 2: 查看项目结构
137
+
138
+ ```
139
+ 请使用 show-project-tree 工具查看当前项目的结构树,最大深度为 2。
140
+ ```
141
+
142
+ ### 示例 3: 创建移动端项目
143
+
144
+ ```
145
+ 请创建一个名为 "my-mobile-app" 的移动端项目(Uni-app),不配置 ESLint。
146
+ ```
147
+
148
+ ## 路径配置说明
149
+
150
+ ### Windows 路径示例
151
+ ```json
152
+ {
153
+ "args": [
154
+ "D:\\files\\test\\cli\\cm-cli\\src\\mcp\\src\\index.js"
155
+ ]
156
+ }
157
+ ```
158
+
159
+ ### macOS/Linux 路径示例
160
+ ```json
161
+ {
162
+ "args": [
163
+ "/Users/username/projects/cm-cli/src/mcp/src/index.js"
164
+ ]
165
+ }
166
+ ```
167
+
168
+ ### 使用相对路径(如果可能)
169
+
170
+ 某些情况下,Cursor 可能支持相对路径,但建议使用绝对路径以确保可靠性。
171
+
172
+ ## 故障排除
173
+
174
+ ### 问题 1: MCP 服务器无法启动
175
+
176
+ **解决方案**:
177
+ 1. 检查 Node.js 是否正确安装:`node --version`
178
+ 2. 检查路径是否正确(使用绝对路径)
179
+ 3. 检查依赖是否已安装:`cd src/mcp && pnpm install`
180
+
181
+ ### 问题 2: AI 无法识别工具
182
+
183
+ **解决方案**:
184
+ 1. 重启 Cursor
185
+ 2. 检查配置文件格式是否正确(JSON 格式)
186
+ 3. 查看 Cursor 的开发者工具(如果有)查看错误信息
187
+
188
+ ### 问题 3: 工具执行失败
189
+
190
+ **解决方案**:
191
+ 1. 确保项目路径存在且可访问
192
+ 2. 检查文件权限
193
+ 3. 查看控制台错误信息
194
+
195
+ ## 高级配置
196
+
197
+ ### 使用环境变量
198
+
199
+ 如果需要设置环境变量,可以在配置中添加:
200
+
201
+ ```json
202
+ {
203
+ "mcpServers": {
204
+ "cm-cli": {
205
+ "command": "node",
206
+ "args": [
207
+ "/path/to/cm-cli/src/mcp/src/index.js"
208
+ ],
209
+ "env": {
210
+ "NODE_ENV": "production"
211
+ }
212
+ }
213
+ }
214
+ }
215
+ ```
216
+
217
+ ### 使用 npm/pnpm 脚本
218
+
219
+ 如果你想通过 npm 脚本运行,可以创建一个启动脚本:
220
+
221
+ 在 `src/mcp/package.json` 中添加:
222
+
223
+ ```json
224
+ {
225
+ "scripts": {
226
+ "start": "node src/index.js"
227
+ }
228
+ }
229
+ ```
230
+
231
+ 然后在 Cursor 配置中使用:
232
+
233
+ ```json
234
+ {
235
+ "mcpServers": {
236
+ "cm-cli": {
237
+ "command": "pnpm",
238
+ "args": ["--dir", "/path/to/cm-cli/src/mcp", "start"]
239
+ }
240
+ }
241
+ }
242
+ ```
243
+
244
+ ## 测试 MCP 服务器
245
+
246
+ 在配置之前,你可以先手动测试 MCP 服务器是否正常工作:
247
+
248
+ ```bash
249
+ cd src/mcp
250
+ node src/index.js
251
+ ```
252
+
253
+ 如果服务器正常启动,你应该看到类似 "CM CLI MCP 服务器已启动" 的消息。
254
+
255
+ ## 更多信息
256
+
257
+ - 查看 [README.md](./README.md) 了解工具详细说明
258
+ - 查看 [test-mcp.js](./test-mcp.js) 了解如何测试
259
+