mta-mcp 2.2.0 → 2.3.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/bin/mta.cjs +43 -0
  2. package/dist/index.cjs +4784 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +1 -0
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.js +4769 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +21 -10
  9. package/build/core/agentTemplate.d.ts +0 -33
  10. package/build/core/agentTemplate.d.ts.map +0 -1
  11. package/build/core/agentTemplate.js +0 -158
  12. package/build/core/agentTemplate.js.map +0 -1
  13. package/build/core/analyzers/eslint.d.ts +0 -51
  14. package/build/core/analyzers/eslint.d.ts.map +0 -1
  15. package/build/core/analyzers/eslint.js +0 -259
  16. package/build/core/analyzers/eslint.js.map +0 -1
  17. package/build/core/analyzers/index.d.ts +0 -9
  18. package/build/core/analyzers/index.d.ts.map +0 -1
  19. package/build/core/analyzers/index.js +0 -9
  20. package/build/core/analyzers/index.js.map +0 -1
  21. package/build/core/analyzers/registry.d.ts +0 -59
  22. package/build/core/analyzers/registry.d.ts.map +0 -1
  23. package/build/core/analyzers/registry.js +0 -241
  24. package/build/core/analyzers/registry.js.map +0 -1
  25. package/build/core/analyzers/tsconfig.d.ts +0 -45
  26. package/build/core/analyzers/tsconfig.d.ts.map +0 -1
  27. package/build/core/analyzers/tsconfig.js +0 -197
  28. package/build/core/analyzers/tsconfig.js.map +0 -1
  29. package/build/core/analyzers/types.d.ts +0 -176
  30. package/build/core/analyzers/types.d.ts.map +0 -1
  31. package/build/core/analyzers/types.js +0 -39
  32. package/build/core/analyzers/types.js.map +0 -1
  33. package/build/core/analyzers/vite.d.ts +0 -46
  34. package/build/core/analyzers/vite.d.ts.map +0 -1
  35. package/build/core/analyzers/vite.js +0 -211
  36. package/build/core/analyzers/vite.js.map +0 -1
  37. package/build/core/autoInitializer.d.ts +0 -34
  38. package/build/core/autoInitializer.d.ts.map +0 -1
  39. package/build/core/autoInitializer.js +0 -145
  40. package/build/core/autoInitializer.js.map +0 -1
  41. package/build/core/codeValidator.d.ts +0 -82
  42. package/build/core/codeValidator.d.ts.map +0 -1
  43. package/build/core/codeValidator.js +0 -287
  44. package/build/core/codeValidator.js.map +0 -1
  45. package/build/core/enhancedProjectAnalyzer.d.ts +0 -102
  46. package/build/core/enhancedProjectAnalyzer.d.ts.map +0 -1
  47. package/build/core/enhancedProjectAnalyzer.js +0 -312
  48. package/build/core/enhancedProjectAnalyzer.js.map +0 -1
  49. package/build/core/errors.d.ts +0 -84
  50. package/build/core/errors.d.ts.map +0 -1
  51. package/build/core/errors.js +0 -151
  52. package/build/core/errors.js.map +0 -1
  53. package/build/core/githubClient.d.ts +0 -26
  54. package/build/core/githubClient.d.ts.map +0 -1
  55. package/build/core/githubClient.js +0 -60
  56. package/build/core/githubClient.js.map +0 -1
  57. package/build/core/i18nDetector.d.ts +0 -47
  58. package/build/core/i18nDetector.d.ts.map +0 -1
  59. package/build/core/i18nDetector.js +0 -314
  60. package/build/core/i18nDetector.js.map +0 -1
  61. package/build/core/index.d.ts +0 -11
  62. package/build/core/index.d.ts.map +0 -1
  63. package/build/core/index.js +0 -14
  64. package/build/core/index.js.map +0 -1
  65. package/build/core/logger.d.ts +0 -91
  66. package/build/core/logger.d.ts.map +0 -1
  67. package/build/core/logger.js +0 -164
  68. package/build/core/logger.js.map +0 -1
  69. package/build/core/mappings/index.d.ts +0 -5
  70. package/build/core/mappings/index.d.ts.map +0 -1
  71. package/build/core/mappings/index.js +0 -5
  72. package/build/core/mappings/index.js.map +0 -1
  73. package/build/core/mappings/scenarioMappings.d.ts +0 -51
  74. package/build/core/mappings/scenarioMappings.d.ts.map +0 -1
  75. package/build/core/mappings/scenarioMappings.js +0 -105
  76. package/build/core/mappings/scenarioMappings.js.map +0 -1
  77. package/build/core/matching/index.d.ts +0 -8
  78. package/build/core/matching/index.d.ts.map +0 -1
  79. package/build/core/matching/index.js +0 -8
  80. package/build/core/matching/index.js.map +0 -1
  81. package/build/core/matching/intentAnalyzer.d.ts +0 -78
  82. package/build/core/matching/intentAnalyzer.d.ts.map +0 -1
  83. package/build/core/matching/intentAnalyzer.js +0 -255
  84. package/build/core/matching/intentAnalyzer.js.map +0 -1
  85. package/build/core/matching/standardMatcher.d.ts +0 -101
  86. package/build/core/matching/standardMatcher.d.ts.map +0 -1
  87. package/build/core/matching/standardMatcher.js +0 -299
  88. package/build/core/matching/standardMatcher.js.map +0 -1
  89. package/build/core/matching/weights.d.ts +0 -64
  90. package/build/core/matching/weights.d.ts.map +0 -1
  91. package/build/core/matching/weights.js +0 -334
  92. package/build/core/matching/weights.js.map +0 -1
  93. package/build/core/projectContextManager.d.ts +0 -39
  94. package/build/core/projectContextManager.d.ts.map +0 -1
  95. package/build/core/projectContextManager.js +0 -147
  96. package/build/core/projectContextManager.js.map +0 -1
  97. package/build/core/scenarioDetector.d.ts +0 -2
  98. package/build/core/scenarioDetector.d.ts.map +0 -1
  99. package/build/core/scenarioDetector.js +0 -2
  100. package/build/core/scenarioDetector.js.map +0 -1
  101. package/build/core/smartAgentMatcher.d.ts +0 -51
  102. package/build/core/smartAgentMatcher.d.ts.map +0 -1
  103. package/build/core/smartAgentMatcher.js +0 -493
  104. package/build/core/smartAgentMatcher.js.map +0 -1
  105. package/build/core/standardsManager.d.ts +0 -130
  106. package/build/core/standardsManager.d.ts.map +0 -1
  107. package/build/core/standardsManager.js +0 -600
  108. package/build/core/standardsManager.js.map +0 -1
  109. package/build/core/templates/discovery.d.ts +0 -41
  110. package/build/core/templates/discovery.d.ts.map +0 -1
  111. package/build/core/templates/discovery.js +0 -262
  112. package/build/core/templates/discovery.js.map +0 -1
  113. package/build/core/templates/types.d.ts +0 -80
  114. package/build/core/templates/types.d.ts.map +0 -1
  115. package/build/core/templates/types.js +0 -10
  116. package/build/core/templates/types.js.map +0 -1
  117. package/build/core/types.d.ts +0 -57
  118. package/build/core/types.d.ts.map +0 -1
  119. package/build/core/types.js +0 -22
  120. package/build/core/types.js.map +0 -1
  121. package/build/index.d.ts +0 -3
  122. package/build/index.d.ts.map +0 -1
  123. package/build/index.js +0 -576
  124. package/build/index.js.map +0 -1
  125. package/build/tools/analyzeProject.d.ts +0 -12
  126. package/build/tools/analyzeProject.d.ts.map +0 -1
  127. package/build/tools/analyzeProject.js +0 -85
  128. package/build/tools/analyzeProject.js.map +0 -1
  129. package/build/tools/autoSetup.d.ts +0 -15
  130. package/build/tools/autoSetup.d.ts.map +0 -1
  131. package/build/tools/autoSetup.js +0 -291
  132. package/build/tools/autoSetup.js.map +0 -1
  133. package/build/tools/generateConfig.d.ts +0 -16
  134. package/build/tools/generateConfig.d.ts.map +0 -1
  135. package/build/tools/generateConfig.js +0 -379
  136. package/build/tools/generateConfig.js.map +0 -1
  137. package/build/tools/generateProjectAgent.d.ts +0 -15
  138. package/build/tools/generateProjectAgent.d.ts.map +0 -1
  139. package/build/tools/generateProjectAgent.js +0 -348
  140. package/build/tools/generateProjectAgent.js.map +0 -1
  141. package/build/tools/getCompactStandards.d.ts +0 -20
  142. package/build/tools/getCompactStandards.d.ts.map +0 -1
  143. package/build/tools/getCompactStandards.js +0 -367
  144. package/build/tools/getCompactStandards.js.map +0 -1
  145. package/build/tools/getSmartStandards.d.ts +0 -15
  146. package/build/tools/getSmartStandards.d.ts.map +0 -1
  147. package/build/tools/getSmartStandards.js +0 -201
  148. package/build/tools/getSmartStandards.js.map +0 -1
  149. package/build/tools/getStandardById.d.ts +0 -42
  150. package/build/tools/getStandardById.d.ts.map +0 -1
  151. package/build/tools/getStandardById.js +0 -289
  152. package/build/tools/getStandardById.js.map +0 -1
  153. package/build/tools/getTemplate.d.ts +0 -37
  154. package/build/tools/getTemplate.d.ts.map +0 -1
  155. package/build/tools/getTemplate.js +0 -78
  156. package/build/tools/getTemplate.js.map +0 -1
  157. package/build/tools/healthCheck.d.ts +0 -14
  158. package/build/tools/healthCheck.d.ts.map +0 -1
  159. package/build/tools/healthCheck.js +0 -237
  160. package/build/tools/healthCheck.js.map +0 -1
  161. package/build/tools/listAgents.d.ts +0 -10
  162. package/build/tools/listAgents.d.ts.map +0 -1
  163. package/build/tools/listAgents.js +0 -79
  164. package/build/tools/listAgents.js.map +0 -1
  165. package/build/tools/listTemplates.d.ts +0 -41
  166. package/build/tools/listTemplates.d.ts.map +0 -1
  167. package/build/tools/listTemplates.js +0 -81
  168. package/build/tools/listTemplates.js.map +0 -1
  169. package/build/tools/matchAgents.d.ts +0 -14
  170. package/build/tools/matchAgents.d.ts.map +0 -1
  171. package/build/tools/matchAgents.js +0 -70
  172. package/build/tools/matchAgents.js.map +0 -1
  173. package/build/tools/queryMappings.d.ts +0 -55
  174. package/build/tools/queryMappings.d.ts.map +0 -1
  175. package/build/tools/queryMappings.js +0 -119
  176. package/build/tools/queryMappings.js.map +0 -1
  177. package/build/tools/usePreset.d.ts +0 -23
  178. package/build/tools/usePreset.d.ts.map +0 -1
  179. package/build/tools/usePreset.js +0 -163
  180. package/build/tools/usePreset.js.map +0 -1
package/dist/index.js ADDED
@@ -0,0 +1,4769 @@
1
+ #!/usr/bin/env node
2
+
3
+ // node_modules/tsup/assets/esm_shims.js
4
+ import path from "path";
5
+ import { fileURLToPath } from "url";
6
+ var getFilename = () => fileURLToPath(import.meta.url);
7
+ var getDirname = () => path.dirname(getFilename());
8
+ var __dirname = /* @__PURE__ */ getDirname();
9
+
10
+ // src/index.ts
11
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
12
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
+ import {
14
+ CallToolRequestSchema,
15
+ ListToolsRequestSchema,
16
+ ListResourcesRequestSchema,
17
+ ReadResourceRequestSchema
18
+ } from "@modelcontextprotocol/sdk/types.js";
19
+
20
+ // src/tools/analyzeProject.ts
21
+ import * as fs3 from "fs";
22
+ import * as path4 from "path";
23
+
24
+ // src/core/smartAgentMatcher.ts
25
+ import * as fs from "fs";
26
+ import * as path2 from "path";
27
+ import glob from "fast-glob";
28
+ var SmartAgentMatcher = class {
29
+ constructor(logger3) {
30
+ this.logger = logger3;
31
+ }
32
+ /**
33
+ * 分析项目特征
34
+ */
35
+ async analyzeProject(workspaceFolder) {
36
+ this.log(`\u{1F50D} \u5F00\u59CB\u5206\u6790\u9879\u76EE: ${workspaceFolder.name}`);
37
+ const features = {
38
+ frameworks: [],
39
+ languages: [],
40
+ tools: [],
41
+ keywords: [],
42
+ projectType: "unknown"
43
+ };
44
+ const rootPath = workspaceFolder.uri.fsPath;
45
+ const pubspecPath = path2.join(rootPath, "pubspec.yaml");
46
+ if (fs.existsSync(pubspecPath)) {
47
+ const pubspecFeatures = this.analyzePubspecYaml(pubspecPath);
48
+ this.mergeFeatures(features, pubspecFeatures);
49
+ features.projectType = "flutter";
50
+ this.log(`\u2705 \u9879\u76EE\u5206\u6790\u5B8C\u6210: ${features.projectType}`);
51
+ return features;
52
+ }
53
+ const packageJsonPath = path2.join(rootPath, "package.json");
54
+ if (fs.existsSync(packageJsonPath)) {
55
+ const packageFeatures = this.analyzePackageJson(packageJsonPath);
56
+ this.mergeFeatures(features, packageFeatures);
57
+ }
58
+ const structureFeatures = await this.analyzeFileStructure(rootPath);
59
+ this.mergeFeatures(features, structureFeatures);
60
+ features.projectType = this.inferProjectType(features);
61
+ this.log(`\u2705 \u9879\u76EE\u5206\u6790\u5B8C\u6210: ${features.projectType}`);
62
+ return features;
63
+ }
64
+ /**
65
+ * 分析 package.json
66
+ */
67
+ analyzePackageJson(packageJsonPath) {
68
+ var _a, _b;
69
+ const features = {
70
+ frameworks: [],
71
+ languages: [],
72
+ tools: [],
73
+ keywords: []
74
+ };
75
+ try {
76
+ const content = fs.readFileSync(packageJsonPath, "utf-8");
77
+ const packageJson = JSON.parse(content);
78
+ const allDeps = {
79
+ ...packageJson.dependencies,
80
+ ...packageJson.devDependencies
81
+ };
82
+ if (allDeps["vue"]) features.frameworks.push("Vue 3");
83
+ if (allDeps["react"]) features.frameworks.push("React");
84
+ if (allDeps["@angular/core"]) features.frameworks.push("Angular");
85
+ if (allDeps["next"]) features.frameworks.push("Next.js");
86
+ if (allDeps["nuxt"]) features.frameworks.push("Nuxt.js");
87
+ if (allDeps["svelte"]) features.frameworks.push("Svelte");
88
+ if (allDeps["solid-js"]) features.frameworks.push("Solid.js");
89
+ if (allDeps["preact"]) features.frameworks.push("Preact");
90
+ if (allDeps["remix"]) features.frameworks.push("Remix");
91
+ if (allDeps["astro"]) features.frameworks.push("Astro");
92
+ if (allDeps["express"]) features.frameworks.push("Express");
93
+ if (allDeps["koa"]) features.frameworks.push("Koa");
94
+ if (allDeps["fastify"]) features.frameworks.push("Fastify");
95
+ if (allDeps["nestjs"] || allDeps["@nestjs/core"]) features.frameworks.push("NestJS");
96
+ if (allDeps["egg"]) features.frameworks.push("Egg.js");
97
+ if (allDeps["midway"]) features.frameworks.push("Midway");
98
+ if (allDeps["hapi"]) features.frameworks.push("Hapi");
99
+ if (allDeps["meteor"]) features.frameworks.push("Meteor");
100
+ if (allDeps["blitz"]) features.frameworks.push("Blitz.js");
101
+ if (allDeps["vite"]) features.tools.push("Vite");
102
+ if (allDeps["webpack"]) features.tools.push("Webpack");
103
+ if (allDeps["rollup"]) features.tools.push("Rollup");
104
+ if (allDeps["parcel"]) features.tools.push("Parcel");
105
+ if (allDeps["esbuild"]) features.tools.push("ESBuild");
106
+ if (allDeps["turbopack"]) features.tools.push("Turbopack");
107
+ if (allDeps["element-plus"]) features.tools.push("Element Plus");
108
+ if (allDeps["ant-design-vue"]) features.tools.push("Ant Design Vue");
109
+ if (allDeps["antd"]) features.tools.push("Ant Design");
110
+ if (allDeps["@mui/material"]) features.tools.push("Material-UI");
111
+ if (allDeps["naive-ui"]) features.tools.push("Naive UI");
112
+ if (allDeps["vuetify"]) features.tools.push("Vuetify");
113
+ if (allDeps["quasar"]) features.tools.push("Quasar");
114
+ if (allDeps["primevue"]) features.tools.push("PrimeVue");
115
+ if (allDeps["chakra-ui"]) features.tools.push("Chakra UI");
116
+ if (allDeps["@headlessui/react"] || allDeps["@headlessui/vue"]) features.tools.push("Headless UI");
117
+ if (allDeps["daisyui"]) features.tools.push("DaisyUI");
118
+ if (allDeps["shadcn-ui"] || allDeps["@shadcn/ui"]) features.tools.push("Shadcn UI");
119
+ if (allDeps["tailwindcss"]) features.tools.push("Tailwind CSS");
120
+ if (allDeps["sass"] || allDeps["node-sass"]) features.tools.push("Sass");
121
+ if (allDeps["less"]) features.tools.push("Less");
122
+ if (allDeps["postcss"]) features.tools.push("PostCSS");
123
+ if (allDeps["styled-components"]) features.tools.push("Styled Components");
124
+ if (allDeps["emotion"]) features.tools.push("Emotion");
125
+ if (allDeps["unocss"]) features.tools.push("UnoCSS");
126
+ if (allDeps["@logicflow/core"]) features.tools.push("LogicFlow");
127
+ if (allDeps["echarts"]) features.tools.push("ECharts");
128
+ if (allDeps["d3"]) features.tools.push("D3.js");
129
+ if (allDeps["chart.js"]) features.tools.push("Chart.js");
130
+ if (allDeps["antv"] || allDeps["@antv/g6"]) features.tools.push("AntV");
131
+ if (allDeps["typescript"]) features.languages.push("TypeScript");
132
+ if (((_a = packageJson.dependencies) == null ? void 0 : _a["react"]) || ((_b = packageJson.devDependencies) == null ? void 0 : _b["react"])) {
133
+ features.languages.push("JavaScript");
134
+ }
135
+ if (allDeps["vue-i18n"] || allDeps["react-i18n"] || allDeps["i18next"] || allDeps["react-intl"]) {
136
+ features.keywords.push("i18n");
137
+ }
138
+ if (allDeps["pinia"] || allDeps["vuex"] || allDeps["redux"] || allDeps["@reduxjs/toolkit"] || allDeps["mobx"] || allDeps["zustand"] || allDeps["recoil"] || allDeps["jotai"]) {
139
+ features.keywords.push("state-management");
140
+ }
141
+ if (allDeps["vue-router"] || allDeps["react-router"] || allDeps["react-router-dom"] || allDeps["@tanstack/react-router"]) {
142
+ features.keywords.push("routing");
143
+ }
144
+ if (allDeps["axios"] || allDeps["@tanstack/react-query"] || allDeps["@tanstack/vue-query"] || allDeps["swr"] || allDeps["urql"]) {
145
+ features.keywords.push("data-fetching");
146
+ }
147
+ if (allDeps["formik"] || allDeps["react-hook-form"] || allDeps["vee-validate"] || allDeps["@vuelidate/core"]) {
148
+ features.keywords.push("forms");
149
+ }
150
+ if (allDeps["vitest"] || allDeps["jest"] || allDeps["@testing-library/react"] || allDeps["@testing-library/vue"] || allDeps["cypress"] || allDeps["playwright"]) {
151
+ features.keywords.push("testing");
152
+ }
153
+ if (allDeps["vant"] || allDeps["@tarojs/taro"] || allDeps["react-native"] || allDeps["uni-app"] || allDeps["@nutui/nutui"]) {
154
+ features.keywords.push("mobile");
155
+ }
156
+ if (packageJson.miniprogram || allDeps["@tarojs/taro"] || allDeps["uni-app"]) {
157
+ features.keywords.push("miniprogram");
158
+ features.keywords.push("wechat");
159
+ }
160
+ if (allDeps["prisma"] || allDeps["typeorm"] || allDeps["sequelize"] || allDeps["mongoose"]) {
161
+ features.keywords.push("database");
162
+ }
163
+ if (allDeps["graphql"] || allDeps["apollo-client"] || allDeps["@apollo/client"]) {
164
+ features.keywords.push("graphql");
165
+ }
166
+ } catch (error) {
167
+ this.log(`\u89E3\u6790 package.json \u5931\u8D25: ${error}`);
168
+ }
169
+ return features;
170
+ }
171
+ /**
172
+ * 分析 pubspec.yaml (Flutter 项目)
173
+ */
174
+ analyzePubspecYaml(pubspecPath) {
175
+ const features = {
176
+ frameworks: ["Flutter"],
177
+ languages: ["Dart"],
178
+ tools: [],
179
+ keywords: []
180
+ };
181
+ try {
182
+ const content = fs.readFileSync(pubspecPath, "utf-8");
183
+ if (content.includes("provider:")) features.keywords.push("state-management");
184
+ if (content.includes("riverpod:")) features.keywords.push("state-management");
185
+ if (content.includes("bloc:") || content.includes("flutter_bloc:")) features.keywords.push("state-management");
186
+ if (content.includes("get:") || content.includes("get_x:")) {
187
+ features.keywords.push("routing", "state-management");
188
+ }
189
+ if (content.includes("flutter_localizations:") || content.includes("intl:") || content.includes("easy_localization:")) {
190
+ features.keywords.push("i18n");
191
+ }
192
+ if (content.includes("go_router:") || content.includes("auto_route:")) features.keywords.push("routing");
193
+ if (content.includes("dio:") || content.includes("http:")) features.keywords.push("data-fetching");
194
+ if (content.includes("flutter_screenutil:")) features.tools.push("ScreenUtil");
195
+ if (content.includes("flutter_test:") || content.includes("mockito:") || content.includes("integration_test:")) {
196
+ features.keywords.push("testing");
197
+ }
198
+ } catch (error) {
199
+ this.log(`\u89E3\u6790 pubspec.yaml \u5931\u8D25: ${error}`);
200
+ }
201
+ return features;
202
+ }
203
+ /**
204
+ * 分析文件结构
205
+ */
206
+ async analyzeFileStructure(rootPath) {
207
+ const features = {
208
+ frameworks: [],
209
+ languages: [],
210
+ tools: [],
211
+ keywords: []
212
+ };
213
+ try {
214
+ const patterns = [
215
+ "**/*.vue",
216
+ "**/*.ts",
217
+ "**/*.tsx",
218
+ "**/*.jsx",
219
+ "**/*.js",
220
+ "**/*.py",
221
+ "**/*.java",
222
+ "**/*.go",
223
+ "**/*.rs",
224
+ "**/*.cpp",
225
+ "**/*.c",
226
+ "**/locales/**",
227
+ "**/i18n/**",
228
+ "**/lang/**",
229
+ "**/stores/**",
230
+ "**/store/**",
231
+ "**/redux/**",
232
+ "**/*.test.*",
233
+ "**/*.spec.*",
234
+ "**/components/**",
235
+ "**/pages/**",
236
+ "**/views/**"
237
+ ];
238
+ const files = await glob(patterns, {
239
+ cwd: rootPath,
240
+ ignore: ["**/node_modules/**", "**/dist/**", "**/build/**", "**/.git/**"],
241
+ onlyFiles: true
242
+ });
243
+ if (files.some((f) => f.endsWith(".vue"))) features.frameworks.push("Vue");
244
+ if (files.some((f) => f.endsWith(".tsx"))) features.frameworks.push("React");
245
+ if (files.some((f) => f.endsWith(".svelte"))) features.frameworks.push("Svelte");
246
+ if (files.some((f) => f.endsWith(".ts") || f.endsWith(".tsx"))) features.languages.push("TypeScript");
247
+ if (files.some((f) => f.endsWith(".js") || f.endsWith(".jsx"))) features.languages.push("JavaScript");
248
+ if (files.some((f) => f.endsWith(".py"))) features.languages.push("Python");
249
+ if (files.some((f) => f.endsWith(".java"))) features.languages.push("Java");
250
+ if (files.some((f) => f.endsWith(".go"))) features.languages.push("Go");
251
+ if (files.some((f) => f.endsWith(".rs"))) features.languages.push("Rust");
252
+ if (files.some((f) => f.match(/\.(cpp|cc|cxx|c)$/))) features.languages.push("C/C++");
253
+ if (files.some((f) => f.includes("/locales/") || f.includes("/i18n/") || f.includes("/lang/"))) {
254
+ features.keywords.push("i18n");
255
+ }
256
+ if (files.some((f) => f.includes("/stores/") || f.includes("/store/") || f.includes("/redux/"))) {
257
+ features.keywords.push("state-management");
258
+ }
259
+ if (files.some((f) => f.includes(".test.") || f.includes(".spec."))) {
260
+ features.keywords.push("testing");
261
+ }
262
+ } catch (error) {
263
+ this.log(`\u626B\u63CF\u6587\u4EF6\u7ED3\u6784\u5931\u8D25: ${error}`);
264
+ }
265
+ return features;
266
+ }
267
+ /**
268
+ * 匹配 Agents
269
+ */
270
+ matchAgents(features, availableAgents) {
271
+ const scoredAgents = availableAgents.map((agent) => {
272
+ const score = this.calculateMatchScore(features, agent);
273
+ return { ...agent, score };
274
+ });
275
+ return scoredAgents.filter((a) => a.score > 0).sort((a, b) => (b.score || 0) - (a.score || 0));
276
+ }
277
+ /**
278
+ * 计算匹配分数
279
+ */
280
+ calculateMatchScore(features, agent) {
281
+ let score = 0;
282
+ const WEIGHTS = {
283
+ framework: 10,
284
+ tool: 8,
285
+ language: 5,
286
+ keyword: 3,
287
+ tag: 2
288
+ };
289
+ features.frameworks.forEach((f) => {
290
+ var _a, _b;
291
+ if ((_b = (_a = agent.applicableWhen) == null ? void 0 : _a.frameworks) == null ? void 0 : _b.some((af) => af.toLowerCase().includes(f.toLowerCase()))) {
292
+ score += WEIGHTS.framework;
293
+ }
294
+ });
295
+ features.tools.forEach((t) => {
296
+ var _a, _b;
297
+ if ((_b = (_a = agent.applicableWhen) == null ? void 0 : _a.tools) == null ? void 0 : _b.some((at) => at.toLowerCase().includes(t.toLowerCase()))) {
298
+ score += WEIGHTS.tool;
299
+ }
300
+ });
301
+ features.languages.forEach((l) => {
302
+ var _a, _b;
303
+ if ((_b = (_a = agent.applicableWhen) == null ? void 0 : _a.languages) == null ? void 0 : _b.some((al) => al.toLowerCase().includes(l.toLowerCase()))) {
304
+ score += WEIGHTS.language;
305
+ }
306
+ });
307
+ features.keywords.forEach((k) => {
308
+ var _a, _b;
309
+ if ((_b = (_a = agent.applicableWhen) == null ? void 0 : _a.keywords) == null ? void 0 : _b.some((ak) => ak.toLowerCase().includes(k.toLowerCase()))) {
310
+ score += WEIGHTS.keyword;
311
+ }
312
+ });
313
+ features.frameworks.concat(features.tools, features.languages, features.keywords).forEach((feature) => {
314
+ if (agent.tags.some((tag) => tag.toLowerCase().includes(feature.toLowerCase()))) {
315
+ score += WEIGHTS.tag;
316
+ }
317
+ });
318
+ return score;
319
+ }
320
+ /**
321
+ * 解析 Agent 元数据
322
+ */
323
+ parseAgentMetadata(filePath, content) {
324
+ const id = path2.basename(filePath, ".agent.md");
325
+ let description = "";
326
+ let tags = [];
327
+ if (content.startsWith("---")) {
328
+ const endIndex = content.indexOf("---", 3);
329
+ if (endIndex > 0) {
330
+ const frontmatter = content.substring(3, endIndex);
331
+ const descMatch = frontmatter.match(/description:\s*['"](.+)['"]/);
332
+ if (descMatch) description = descMatch[1];
333
+ const tagsMatch = frontmatter.match(/tags:\s*\[(.+)\]/);
334
+ if (tagsMatch) {
335
+ tags = tagsMatch[1].split(",").map((t) => t.trim().replace(/['"]/g, ""));
336
+ }
337
+ }
338
+ }
339
+ const titleMatch = content.match(/^#\s+(.+)$/m);
340
+ const title = titleMatch ? titleMatch[1] : id;
341
+ return {
342
+ id,
343
+ path: filePath,
344
+ title,
345
+ description,
346
+ tags,
347
+ applicableWhen: {
348
+ frameworks: tags.filter(
349
+ (t) => [
350
+ "vue",
351
+ "vue3",
352
+ "react",
353
+ "angular",
354
+ "next",
355
+ "nuxt",
356
+ "svelte",
357
+ "flutter",
358
+ "express",
359
+ "nestjs",
360
+ "koa",
361
+ "fastify"
362
+ ].includes(t.toLowerCase())
363
+ ),
364
+ languages: tags.filter(
365
+ (t) => ["typescript", "javascript", "python", "java", "go", "rust", "dart", "c++"].includes(t.toLowerCase())
366
+ ),
367
+ tools: tags.filter(
368
+ (t) => [
369
+ "vite",
370
+ "webpack",
371
+ "rollup",
372
+ "logicflow",
373
+ "element-plus",
374
+ "antd",
375
+ "tailwind",
376
+ "sass",
377
+ "echarts",
378
+ "prisma",
379
+ "graphql"
380
+ ].includes(t.toLowerCase())
381
+ ),
382
+ keywords: tags.filter(
383
+ (t) => [
384
+ "i18n",
385
+ "state-management",
386
+ "routing",
387
+ "testing",
388
+ "mobile",
389
+ "miniprogram",
390
+ "database",
391
+ "forms",
392
+ "data-fetching"
393
+ ].includes(t.toLowerCase())
394
+ )
395
+ }
396
+ };
397
+ }
398
+ mergeFeatures(target, source) {
399
+ if (source.frameworks) target.frameworks.push(...source.frameworks);
400
+ if (source.languages) target.languages.push(...source.languages);
401
+ if (source.tools) target.tools.push(...source.tools);
402
+ if (source.keywords) target.keywords.push(...source.keywords);
403
+ }
404
+ inferProjectType(features) {
405
+ if (features.frameworks.some((f) => f.toLowerCase().includes("vue"))) return "vue3";
406
+ if (features.frameworks.some((f) => f.toLowerCase().includes("react"))) return "react";
407
+ if (features.frameworks.some((f) => f.toLowerCase().includes("angular"))) return "angular";
408
+ if (features.frameworks.some((f) => f.toLowerCase().includes("svelte"))) return "svelte";
409
+ if (features.frameworks.some((f) => f.toLowerCase().includes("next"))) return "nextjs";
410
+ if (features.frameworks.some((f) => f.toLowerCase().includes("nuxt"))) return "nuxtjs";
411
+ if (features.frameworks.some((f) => f.toLowerCase().includes("flutter"))) return "flutter";
412
+ if (features.frameworks.some((f) => f.toLowerCase().includes("react-native"))) return "react-native";
413
+ if (features.keywords.includes("miniprogram")) return "miniprogram";
414
+ if (features.frameworks.some((f) => f.toLowerCase().includes("nest"))) return "nestjs";
415
+ if (features.frameworks.some((f) => f.toLowerCase().includes("express"))) return "express";
416
+ if (features.frameworks.some((f) => f.toLowerCase().includes("koa"))) return "koa";
417
+ if (features.frameworks.some((f) => f.toLowerCase().includes("fastify"))) return "fastify";
418
+ if (features.languages.includes("TypeScript")) return "typescript";
419
+ if (features.languages.includes("Python")) return "python";
420
+ if (features.languages.includes("Java")) return "java";
421
+ if (features.languages.includes("Go")) return "go";
422
+ if (features.languages.includes("Rust")) return "rust";
423
+ return "general";
424
+ }
425
+ log(message) {
426
+ var _a;
427
+ (_a = this.logger) == null ? void 0 : _a.log(message);
428
+ }
429
+ };
430
+
431
+ // src/core/i18nDetector.ts
432
+ import * as fs2 from "fs";
433
+ import * as path3 from "path";
434
+ import glob2 from "fast-glob";
435
+ var I18nDetector = class {
436
+ /**
437
+ * 检测项目的国际化配置
438
+ */
439
+ static async detect(projectPath) {
440
+ const packageJsonPath = path3.join(projectPath, "package.json");
441
+ if (fs2.existsSync(packageJsonPath)) {
442
+ return this.detectFrontendI18n(projectPath, packageJsonPath);
443
+ }
444
+ const pubspecPath = path3.join(projectPath, "pubspec.yaml");
445
+ if (fs2.existsSync(pubspecPath)) {
446
+ return this.detectFlutterI18n(projectPath, pubspecPath);
447
+ }
448
+ return {
449
+ enabled: false,
450
+ type: "none",
451
+ configFiles: [],
452
+ messageFiles: [],
453
+ method: "",
454
+ example: "",
455
+ tips: ["\u9879\u76EE\u672A\u914D\u7F6E\u56FD\u9645\u5316\uFF0C\u5EFA\u8BAE\u6DFB\u52A0\u4E2D\u82F1\u53CC\u8BED\u652F\u6301"]
456
+ };
457
+ }
458
+ /**
459
+ * 检测前端项目的国际化配置(Vue/React)
460
+ */
461
+ static detectFrontendI18n(projectPath, packageJsonPath) {
462
+ const content = fs2.readFileSync(packageJsonPath, "utf-8");
463
+ const packageJson = JSON.parse(content);
464
+ const allDeps = {
465
+ ...packageJson.dependencies,
466
+ ...packageJson.devDependencies
467
+ };
468
+ if (allDeps["vue-i18n"]) {
469
+ return this.detectVueI18n(projectPath);
470
+ }
471
+ if (allDeps["react-i18next"] || allDeps["i18next"]) {
472
+ return this.detectReactI18n(projectPath);
473
+ }
474
+ if (allDeps["react-intl"]) {
475
+ return this.detectReactIntl(projectPath);
476
+ }
477
+ return this.detectCustomI18n(projectPath);
478
+ }
479
+ /**
480
+ * 检测 vue-i18n 配置
481
+ */
482
+ static detectVueI18n(projectPath) {
483
+ const configFiles = [];
484
+ const messageFiles = [];
485
+ const possibleConfigPaths = [
486
+ "src/i18n/index.ts",
487
+ "src/i18n/index.js",
488
+ "src/locales/index.ts",
489
+ "src/locales/index.js",
490
+ "i18n.config.ts",
491
+ "i18n.config.js"
492
+ ];
493
+ for (const configPath of possibleConfigPaths) {
494
+ const fullPath = path3.join(projectPath, configPath);
495
+ if (fs2.existsSync(fullPath)) {
496
+ configFiles.push(configPath);
497
+ }
498
+ }
499
+ const possibleMessageDirs = ["src/i18n", "src/locales", "src/lang"];
500
+ for (const dir of possibleMessageDirs) {
501
+ const fullDir = path3.join(projectPath, dir);
502
+ if (fs2.existsSync(fullDir)) {
503
+ const files = fs2.readdirSync(fullDir);
504
+ for (const file of files) {
505
+ if (/^(zh|en|ja|ko|fr|de|es).*\.(ts|js|json)$/.test(file)) {
506
+ messageFiles.push(path3.join(dir, file));
507
+ }
508
+ }
509
+ }
510
+ }
511
+ return {
512
+ enabled: true,
513
+ type: "vue-i18n",
514
+ configFiles,
515
+ messageFiles,
516
+ method: "$t()",
517
+ example: `{{ $t('common.save') }} \u6216 :label="$t('user.username')"`,
518
+ tips: [
519
+ '\u4F7F\u7528\u547D\u540D\u7A7A\u95F4\u683C\u5F0F\uFF1A$t("common.save")',
520
+ "\u6240\u6709\u6309\u94AE\u3001\u6807\u7B7E\u3001\u63D0\u793A\u6587\u5B57\u5FC5\u987B\u4F7F\u7528 $t()",
521
+ "\u8868\u5355\u9A8C\u8BC1\u89C4\u5219\u7684 message \u4E5F\u9700\u8981\u56FD\u9645\u5316",
522
+ "\u786E\u4FDD zh-CN.ts \u548C en-US.ts \u4E2D\u7684\u952E\u540D\u5B8C\u5168\u4E00\u81F4"
523
+ ]
524
+ };
525
+ }
526
+ /**
527
+ * 检测 react-i18next 配置
528
+ */
529
+ static detectReactI18n(projectPath) {
530
+ const configFiles = [];
531
+ const messageFiles = [];
532
+ const possibleConfigPaths = [
533
+ "src/i18n.ts",
534
+ "src/i18n.js",
535
+ "src/i18n/config.ts",
536
+ "src/i18n/config.js"
537
+ ];
538
+ for (const configPath of possibleConfigPaths) {
539
+ const fullPath = path3.join(projectPath, configPath);
540
+ if (fs2.existsSync(fullPath)) {
541
+ configFiles.push(configPath);
542
+ }
543
+ }
544
+ const possibleMessageDirs = ["public/locales", "src/locales", "src/i18n"];
545
+ for (const dir of possibleMessageDirs) {
546
+ const fullDir = path3.join(projectPath, dir);
547
+ if (fs2.existsSync(fullDir)) {
548
+ const pattern = path3.join(fullDir, "**/*.json");
549
+ try {
550
+ const files = glob2.sync(pattern);
551
+ messageFiles.push(...files.map((f) => path3.relative(projectPath, f)));
552
+ } catch (e) {
553
+ }
554
+ }
555
+ }
556
+ return {
557
+ enabled: true,
558
+ type: "react-i18n",
559
+ configFiles,
560
+ messageFiles,
561
+ method: "t() \u6216 useTranslation()",
562
+ example: `{t('common.save')} \u6216 const { t } = useTranslation()`,
563
+ tips: [
564
+ "\u4F7F\u7528 useTranslation() hook \u83B7\u53D6 t \u51FD\u6570",
565
+ '\u547D\u540D\u7A7A\u95F4\u683C\u5F0F\uFF1At("common.save")',
566
+ "\u6240\u6709\u6587\u6848\u5FC5\u987B\u901A\u8FC7 t() \u51FD\u6570\u5305\u88F9",
567
+ "\u786E\u4FDD\u6240\u6709\u8BED\u8A00\u7684\u7FFB\u8BD1\u6587\u4EF6\u540C\u6B65\u66F4\u65B0"
568
+ ]
569
+ };
570
+ }
571
+ /**
572
+ * 检测 react-intl 配置
573
+ */
574
+ static detectReactIntl(projectPath) {
575
+ return {
576
+ enabled: true,
577
+ type: "react-i18n",
578
+ configFiles: [],
579
+ messageFiles: [],
580
+ method: "formatMessage() \u6216 FormattedMessage",
581
+ example: `<FormattedMessage id="common.save" /> \u6216 intl.formatMessage({ id: 'common.save' })`,
582
+ tips: [
583
+ "\u4F7F\u7528 FormattedMessage \u7EC4\u4EF6\u6216 formatMessage \u65B9\u6CD5",
584
+ "\u6D88\u606F ID \u683C\u5F0F\uFF1Acommon.save",
585
+ "\u6240\u6709\u6587\u6848\u5FC5\u987B\u5B9A\u4E49\u5728\u6D88\u606F\u6587\u4EF6\u4E2D",
586
+ "\u786E\u4FDD\u591A\u8BED\u8A00\u6587\u4EF6\u7684\u6D88\u606F ID \u4FDD\u6301\u4E00\u81F4"
587
+ ]
588
+ };
589
+ }
590
+ /**
591
+ * 检测自定义国际化方案
592
+ */
593
+ static detectCustomI18n(projectPath) {
594
+ const messageFiles = [];
595
+ const possibleDirs = ["src/locales", "src/i18n", "src/lang"];
596
+ for (const dir of possibleDirs) {
597
+ const fullDir = path3.join(projectPath, dir);
598
+ if (fs2.existsSync(fullDir)) {
599
+ const files = fs2.readdirSync(fullDir);
600
+ for (const file of files) {
601
+ if (/messages?\.(ts|js)$/i.test(file)) {
602
+ messageFiles.push(path3.join(dir, file));
603
+ const content = fs2.readFileSync(path3.join(fullDir, file), "utf-8");
604
+ if (content.includes("[") && content.includes("],")) {
605
+ return {
606
+ enabled: true,
607
+ type: "custom",
608
+ configFiles: [],
609
+ messageFiles,
610
+ method: "$t()",
611
+ example: `{{ $t('\u4FDD\u5B58') }} \u6216 :label="$t('\u7528\u6237\u540D')"`,
612
+ tips: [
613
+ '\u4F7F\u7528\u76F4\u63A5\u952E\u540D\u683C\u5F0F\uFF1A$t("\u4FDD\u5B58")',
614
+ "\u6240\u6709\u6309\u94AE\u3001\u6807\u7B7E\u3001\u63D0\u793A\u6587\u5B57\u5FC5\u987B\u4F7F\u7528 $t()",
615
+ "\u8868\u5355\u9A8C\u8BC1\u89C4\u5219\u7684 message \u4E5F\u9700\u8981\u56FD\u9645\u5316",
616
+ "\u65B0\u589E\u6587\u6848\u65F6\u9700\u8981\u540C\u65F6\u6DFB\u52A0\u4E2D\u82F1\u6587\u7FFB\u8BD1"
617
+ ]
618
+ };
619
+ }
620
+ }
621
+ }
622
+ }
623
+ }
624
+ if (messageFiles.length > 0) {
625
+ return {
626
+ enabled: true,
627
+ type: "custom",
628
+ configFiles: [],
629
+ messageFiles,
630
+ method: "$t()",
631
+ example: "\u8BF7\u67E5\u770B\u9879\u76EE\u4E2D\u73B0\u6709\u9875\u9762\u7684\u4F7F\u7528\u65B9\u5F0F",
632
+ tips: [
633
+ "\u68C0\u6D4B\u5230\u56FD\u9645\u5316\u6587\u4EF6\uFF0C\u4F46\u683C\u5F0F\u672A\u77E5",
634
+ "\u8BF7\u67E5\u770B\u73B0\u6709\u9875\u9762\u786E\u8BA4\u4F7F\u7528\u65B9\u5F0F",
635
+ "\u786E\u4FDD\u6240\u6709\u65B0\u589E\u6587\u6848\u90FD\u9075\u5FAA\u9879\u76EE\u89C4\u8303"
636
+ ]
637
+ };
638
+ }
639
+ return {
640
+ enabled: false,
641
+ type: "none",
642
+ configFiles: [],
643
+ messageFiles: [],
644
+ method: "",
645
+ example: "",
646
+ tips: [
647
+ "\u26A0\uFE0F \u9879\u76EE\u672A\u914D\u7F6E\u56FD\u9645\u5316",
648
+ "\u5EFA\u8BAE\u6DFB\u52A0\u4E2D\u82F1\u53CC\u8BED\u652F\u6301",
649
+ "\u63A8\u8350\u4F7F\u7528 vue-i18n\uFF08Vue\uFF09\u6216 react-i18next\uFF08React\uFF09"
650
+ ]
651
+ };
652
+ }
653
+ /**
654
+ * 检测 Flutter 项目的国际化配置
655
+ */
656
+ static detectFlutterI18n(projectPath, pubspecPath) {
657
+ const content = fs2.readFileSync(pubspecPath, "utf-8");
658
+ if (content.includes("flutter_localizations")) {
659
+ const messageFiles = [];
660
+ const l10nDir = path3.join(projectPath, "lib", "l10n");
661
+ if (fs2.existsSync(l10nDir)) {
662
+ const files = fs2.readdirSync(l10nDir);
663
+ for (const file of files) {
664
+ if (file.endsWith(".arb")) {
665
+ messageFiles.push(`lib/l10n/${file}`);
666
+ }
667
+ }
668
+ }
669
+ const l10nConfigPath = path3.join(projectPath, "l10n.yaml");
670
+ const configFiles = fs2.existsSync(l10nConfigPath) ? ["l10n.yaml"] : [];
671
+ return {
672
+ enabled: true,
673
+ type: "flutter-intl",
674
+ configFiles,
675
+ messageFiles,
676
+ method: "AppLocalizations",
677
+ example: `AppLocalizations.of(context)!.save \u6216 S.of(context).save`,
678
+ tips: [
679
+ "\u4F7F\u7528 AppLocalizations.of(context)!.key",
680
+ "\u6240\u6709\u6587\u672C\u5FC5\u987B\u5728 .arb \u6587\u4EF6\u4E2D\u5B9A\u4E49",
681
+ "\u786E\u4FDD app_en.arb \u548C app_zh.arb \u7684\u952E\u540D\u5B8C\u5168\u4E00\u81F4",
682
+ "\u8FD0\u884C flutter gen-l10n \u751F\u6210\u4EE3\u7801"
683
+ ]
684
+ };
685
+ }
686
+ if (content.includes("easy_localization")) {
687
+ return {
688
+ enabled: true,
689
+ type: "flutter-intl",
690
+ configFiles: [],
691
+ messageFiles: [],
692
+ method: "tr()",
693
+ example: `'save'.tr() \u6216 Text('save'.tr())`,
694
+ tips: [
695
+ "\u4F7F\u7528 .tr() \u6269\u5C55\u65B9\u6CD5",
696
+ "\u7FFB\u8BD1\u6587\u4EF6\u901A\u5E38\u5728 assets/translations/",
697
+ "\u786E\u4FDD\u6240\u6709\u8BED\u8A00\u6587\u4EF6\u7684\u952E\u540D\u4E00\u81F4"
698
+ ]
699
+ };
700
+ }
701
+ return {
702
+ enabled: false,
703
+ type: "none",
704
+ configFiles: [],
705
+ messageFiles: [],
706
+ method: "",
707
+ example: "",
708
+ tips: [
709
+ "\u26A0\uFE0F Flutter \u9879\u76EE\u672A\u914D\u7F6E\u56FD\u9645\u5316",
710
+ "\u5EFA\u8BAE\u6DFB\u52A0 flutter_localizations",
711
+ "\u5728 pubspec.yaml \u4E2D\u6DFB\u52A0\uFF1A",
712
+ " flutter_localizations:",
713
+ " sdk: flutter",
714
+ " intl: any"
715
+ ]
716
+ };
717
+ }
718
+ };
719
+
720
+ // src/core/types.ts
721
+ var ConsoleLogger = class {
722
+ constructor(enableDebug = false) {
723
+ this.enableDebug = enableDebug;
724
+ }
725
+ log(message) {
726
+ console.error(`[MCP] [INFO] ${message}`);
727
+ }
728
+ error(message) {
729
+ console.error(`[MCP] [ERROR] ${message}`);
730
+ }
731
+ debug(message) {
732
+ if (this.enableDebug) {
733
+ console.error(`[MCP] [DEBUG] ${message}`);
734
+ }
735
+ }
736
+ };
737
+
738
+ // src/tools/analyzeProject.ts
739
+ async function analyzeProject(args) {
740
+ const logger3 = new ConsoleLogger();
741
+ try {
742
+ let projectPath = args.projectPath;
743
+ if (!projectPath) {
744
+ projectPath = process.cwd();
745
+ logger3.log(`\u{1F4CD} \u672A\u6307\u5B9A\u8DEF\u5F84\uFF0C\u4F7F\u7528\u5F53\u524D\u76EE\u5F55: ${projectPath}`);
746
+ }
747
+ if (!fs3.existsSync(projectPath)) {
748
+ return {
749
+ content: [{
750
+ type: "text",
751
+ text: JSON.stringify({
752
+ error: `\u9879\u76EE\u8DEF\u5F84\u4E0D\u5B58\u5728: ${projectPath}`
753
+ }, null, 2)
754
+ }]
755
+ };
756
+ }
757
+ const matcher = new SmartAgentMatcher(logger3);
758
+ const workspaceFolder = {
759
+ uri: { fsPath: projectPath },
760
+ name: path4.basename(projectPath),
761
+ index: 0
762
+ };
763
+ const features = await matcher.analyzeProject(workspaceFolder);
764
+ logger3.log(`\u{1F30D} \u68C0\u6D4B\u56FD\u9645\u5316\u914D\u7F6E...`);
765
+ const i18nConfig = await I18nDetector.detect(projectPath);
766
+ return {
767
+ content: [{
768
+ type: "text",
769
+ text: JSON.stringify({
770
+ success: true,
771
+ projectPath,
772
+ projectName: path4.basename(projectPath),
773
+ autoDetected: !args.projectPath,
774
+ features: {
775
+ projectType: features.projectType,
776
+ frameworks: features.frameworks,
777
+ languages: features.languages,
778
+ tools: features.tools,
779
+ keywords: features.keywords
780
+ },
781
+ i18n: {
782
+ enabled: i18nConfig.enabled,
783
+ type: i18nConfig.type,
784
+ configFiles: i18nConfig.configFiles,
785
+ messageFiles: i18nConfig.messageFiles,
786
+ method: i18nConfig.method,
787
+ example: i18nConfig.example,
788
+ tips: i18nConfig.tips
789
+ },
790
+ summary: `\u68C0\u6D4B\u5230 ${features.projectType} \u9879\u76EE\uFF0C\u4F7F\u7528 ${features.frameworks.join(", ")} \u6846\u67B6\u3002\u56FD\u9645\u5316\uFF1A${i18nConfig.enabled ? `\u5DF2\u914D\u7F6E (${i18nConfig.type})` : "\u672A\u914D\u7F6E"}`
791
+ }, null, 2)
792
+ }]
793
+ };
794
+ } catch (error) {
795
+ logger3.error(`\u5206\u6790\u9879\u76EE\u5931\u8D25: ${error}`);
796
+ return {
797
+ content: [{
798
+ type: "text",
799
+ text: JSON.stringify({
800
+ error: error instanceof Error ? error.message : String(error)
801
+ }, null, 2)
802
+ }]
803
+ };
804
+ }
805
+ }
806
+
807
+ // src/core/githubClient.ts
808
+ import axios from "axios";
809
+ var GitHubClient = class {
810
+ constructor(logger3) {
811
+ this.logger = logger3;
812
+ this.owner = "ForLear";
813
+ this.repo = "copilot-prompts";
814
+ this.branch = "main";
815
+ this.baseUrl = "https://api.github.com";
816
+ this.rawBaseUrl = "https://raw.githubusercontent.com";
817
+ }
818
+ /**
819
+ * 列出目录中的文件
820
+ */
821
+ async listDirectoryFiles(dirPath) {
822
+ var _a;
823
+ const url = `${this.baseUrl}/repos/${this.owner}/${this.repo}/contents/${dirPath}?ref=${this.branch}`;
824
+ try {
825
+ const response = await axios.get(url, {
826
+ headers: {
827
+ "Accept": "application/vnd.github.v3+json",
828
+ "User-Agent": "Copilot-Prompts-MCP-Server"
829
+ }
830
+ });
831
+ if (Array.isArray(response.data)) {
832
+ return response.data.map((item) => ({
833
+ name: item.name,
834
+ path: item.path,
835
+ type: item.type
836
+ }));
837
+ }
838
+ return [];
839
+ } catch (error) {
840
+ (_a = this.logger) == null ? void 0 : _a.error(`\u83B7\u53D6\u76EE\u5F55\u5931\u8D25: ${error}`);
841
+ return [];
842
+ }
843
+ }
844
+ /**
845
+ * 获取文件内容
846
+ */
847
+ async fetchFileContent(filePath) {
848
+ var _a;
849
+ const url = `${this.rawBaseUrl}/${this.owner}/${this.repo}/${this.branch}/${filePath}`;
850
+ try {
851
+ const response = await axios.get(url, {
852
+ headers: {
853
+ "User-Agent": "Copilot-Prompts-MCP-Server"
854
+ }
855
+ });
856
+ return response.data;
857
+ } catch (error) {
858
+ (_a = this.logger) == null ? void 0 : _a.error(`\u83B7\u53D6\u6587\u4EF6\u5931\u8D25: ${filePath}`);
859
+ throw error;
860
+ }
861
+ }
862
+ };
863
+
864
+ // src/tools/matchAgents.ts
865
+ async function matchAgents(args) {
866
+ const logger3 = new ConsoleLogger();
867
+ try {
868
+ const matcher = new SmartAgentMatcher(logger3);
869
+ const githubClient = new GitHubClient(logger3);
870
+ logger3.log("\u6B63\u5728\u4ECE GitHub \u83B7\u53D6\u53EF\u7528 Agents...");
871
+ const availableAgents = [];
872
+ try {
873
+ const agentFiles = await githubClient.listDirectoryFiles("agents");
874
+ for (const file of agentFiles) {
875
+ if (file.name.endsWith(".agent.md")) {
876
+ try {
877
+ const content = await githubClient.fetchFileContent(file.path);
878
+ const metadata = matcher.parseAgentMetadata(file.path, content);
879
+ availableAgents.push(metadata);
880
+ } catch (error) {
881
+ logger3.error(`\u89E3\u6790 ${file.name} \u5931\u8D25: ${error}`);
882
+ }
883
+ }
884
+ }
885
+ } catch (error) {
886
+ logger3.error(`\u83B7\u53D6 Agents \u5931\u8D25: ${error}`);
887
+ }
888
+ const matchedAgents = matcher.matchAgents(args.projectFeatures, availableAgents);
889
+ const limit = args.limit || 10;
890
+ const topAgents = matchedAgents.slice(0, limit);
891
+ return {
892
+ content: [{
893
+ type: "text",
894
+ text: JSON.stringify({
895
+ success: true,
896
+ totalAvailable: availableAgents.length,
897
+ matched: topAgents.length,
898
+ agents: topAgents.map((agent) => ({
899
+ id: agent.id,
900
+ title: agent.title,
901
+ description: agent.description,
902
+ score: agent.score,
903
+ tags: agent.tags,
904
+ path: agent.path
905
+ })),
906
+ recommendations: topAgents.slice(0, 5).map((a) => a.title)
907
+ }, null, 2)
908
+ }]
909
+ };
910
+ } catch (error) {
911
+ logger3.error(`\u5339\u914D Agents \u5931\u8D25: ${error}`);
912
+ return {
913
+ content: [{
914
+ type: "text",
915
+ text: JSON.stringify({
916
+ error: error instanceof Error ? error.message : String(error)
917
+ }, null, 2)
918
+ }]
919
+ };
920
+ }
921
+ }
922
+
923
+ // src/tools/listAgents.ts
924
+ async function listAvailableAgents() {
925
+ const logger3 = new ConsoleLogger();
926
+ try {
927
+ const githubClient = new GitHubClient(logger3);
928
+ logger3.log("\u6B63\u5728\u4ECE GitHub \u83B7\u53D6 Agents \u5217\u8868...");
929
+ const agentFiles = await githubClient.listDirectoryFiles("agents");
930
+ const agents = agentFiles.filter((f) => f.name.endsWith(".agent.md"));
931
+ const agentList = await Promise.all(
932
+ agents.map(async (file) => {
933
+ try {
934
+ const content = await githubClient.fetchFileContent(file.path);
935
+ const lines = content.split("\n");
936
+ let title = file.name.replace(".agent.md", "");
937
+ let description = "";
938
+ if (lines[0] === "---") {
939
+ const endIndex = lines.slice(1).findIndex((l) => l === "---");
940
+ if (endIndex > 0) {
941
+ const frontmatter = lines.slice(1, endIndex + 1).join("\n");
942
+ const descMatch = frontmatter.match(/description:\s*['"](.+)['"]/);
943
+ if (descMatch) {
944
+ description = descMatch[1];
945
+ }
946
+ }
947
+ }
948
+ const titleLine = lines.find((l) => l.startsWith("# "));
949
+ if (titleLine) {
950
+ title = titleLine.replace("# ", "").trim();
951
+ }
952
+ return {
953
+ id: file.name.replace(".agent.md", ""),
954
+ name: file.name,
955
+ title,
956
+ description: description || "\u6682\u65E0\u63CF\u8FF0",
957
+ path: file.path
958
+ };
959
+ } catch (error) {
960
+ logger3.error(`\u89E3\u6790 ${file.name} \u5931\u8D25: ${error}`);
961
+ return null;
962
+ }
963
+ })
964
+ );
965
+ const validAgents = agentList.filter((a) => a !== null);
966
+ return {
967
+ content: [{
968
+ type: "text",
969
+ text: JSON.stringify({
970
+ success: true,
971
+ total: validAgents.length,
972
+ agents: validAgents,
973
+ categories: {
974
+ general: validAgents.filter((a) => a.path.includes("common/")).length,
975
+ frameworks: validAgents.filter((a) => a.path.includes("vue/") || a.path.includes("react/")).length,
976
+ agents: validAgents.filter((a) => a.path.includes("agents/")).length
977
+ }
978
+ }, null, 2)
979
+ }]
980
+ };
981
+ } catch (error) {
982
+ logger3.error(`\u83B7\u53D6 Agents \u5217\u8868\u5931\u8D25: ${error}`);
983
+ return {
984
+ content: [{
985
+ type: "text",
986
+ text: JSON.stringify({
987
+ error: error instanceof Error ? error.message : String(error)
988
+ }, null, 2)
989
+ }]
990
+ };
991
+ }
992
+ }
993
+
994
+ // src/tools/generateConfig.ts
995
+ import * as fs4 from "fs";
996
+ import * as path5 from "path";
997
+ import { fileURLToPath as fileURLToPath2 } from "url";
998
+
999
+ // src/core/codeValidator.ts
1000
+ var CodeValidator = class {
1001
+ constructor(logger3) {
1002
+ this.logger = logger3 || new ConsoleLogger();
1003
+ }
1004
+ /**
1005
+ * 验证生成的配置文件内容
1006
+ */
1007
+ validateConfigContent(content) {
1008
+ const errors = [];
1009
+ const warnings = [];
1010
+ this.checkDuplicateTags(content, errors);
1011
+ this.checkBracketMatching(content, errors);
1012
+ this.checkMarkdownSyntax(content, errors);
1013
+ this.checkRequiredSections(content, warnings);
1014
+ this.checkCustomContentMarkers(content, warnings);
1015
+ return {
1016
+ isValid: errors.length === 0,
1017
+ errors,
1018
+ warnings
1019
+ };
1020
+ }
1021
+ /**
1022
+ * 检查重复的HTML标签
1023
+ */
1024
+ checkDuplicateTags(content, errors) {
1025
+ const lines = content.split("\n");
1026
+ const tagPattern = /<\/([\w-]+)>/g;
1027
+ for (let i = 0; i < lines.length; i++) {
1028
+ const line = lines[i];
1029
+ const matches = Array.from(line.matchAll(tagPattern));
1030
+ if (matches.length > 0) {
1031
+ const tags = matches.map((m) => m[1]);
1032
+ const tagCounts = /* @__PURE__ */ new Map();
1033
+ tags.forEach((tag) => {
1034
+ tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
1035
+ });
1036
+ tagCounts.forEach((count, tag) => {
1037
+ if (count > 1) {
1038
+ errors.push({
1039
+ type: "syntax",
1040
+ message: `\u91CD\u590D\u7684\u95ED\u5408\u6807\u7B7E </${tag}> \u5728\u540C\u4E00\u884C\u51FA\u73B0 ${count} \u6B21`,
1041
+ line: i + 1,
1042
+ suggestion: `\u68C0\u67E5\u662F\u5426\u6709\u591A\u4F59\u7684\u95ED\u5408\u6807\u7B7E\uFF0C\u5E94\u8BE5\u53EA\u4FDD\u7559\u4E00\u4E2A </${tag}>`
1043
+ });
1044
+ }
1045
+ });
1046
+ }
1047
+ }
1048
+ }
1049
+ /**
1050
+ * 检查括号匹配
1051
+ */
1052
+ checkBracketMatching(content, errors) {
1053
+ const brackets = {
1054
+ "(": ")",
1055
+ "[": "]",
1056
+ "{": "}",
1057
+ "<": ">"
1058
+ };
1059
+ const stack = [];
1060
+ const lines = content.split("\n");
1061
+ for (let lineNum = 0; lineNum < lines.length; lineNum++) {
1062
+ const line = lines[lineNum];
1063
+ if (line.trim().startsWith("```")) {
1064
+ continue;
1065
+ }
1066
+ if (line.trim().startsWith(">")) {
1067
+ continue;
1068
+ }
1069
+ for (let col = 0; col < line.length; col++) {
1070
+ const char = line[col];
1071
+ if (char === ">" && (col === 0 || line[col - 1] === " ") && (col === line.length - 1 || line[col + 1] === " ")) {
1072
+ continue;
1073
+ }
1074
+ if (char in brackets) {
1075
+ stack.push({ char, line: lineNum + 1, col: col + 1 });
1076
+ } else if (Object.values(brackets).includes(char)) {
1077
+ if (stack.length === 0) {
1078
+ errors.push({
1079
+ type: "syntax",
1080
+ message: `\u672A\u914D\u5BF9\u7684\u95ED\u5408\u62EC\u53F7 '${char}'`,
1081
+ line: lineNum + 1,
1082
+ suggestion: `\u68C0\u67E5\u662F\u5426\u7F3A\u5C11\u5BF9\u5E94\u7684\u5F00\u653E\u62EC\u53F7`
1083
+ });
1084
+ } else {
1085
+ const last = stack.pop();
1086
+ const expectedClose = brackets[last.char];
1087
+ if (char !== expectedClose) {
1088
+ errors.push({
1089
+ type: "syntax",
1090
+ message: `\u62EC\u53F7\u4E0D\u5339\u914D: \u671F\u671B '${expectedClose}' \u4F46\u5F97\u5230 '${char}'`,
1091
+ line: lineNum + 1,
1092
+ suggestion: `\u68C0\u67E5\u7B2C ${last.line} \u884C\u7684 '${last.char}' \u5BF9\u5E94\u7684\u95ED\u5408\u62EC\u53F7`
1093
+ });
1094
+ }
1095
+ }
1096
+ }
1097
+ }
1098
+ }
1099
+ if (stack.length > 0) {
1100
+ stack.forEach((bracket) => {
1101
+ errors.push({
1102
+ type: "syntax",
1103
+ message: `\u672A\u95ED\u5408\u7684\u62EC\u53F7 '${bracket.char}'`,
1104
+ line: bracket.line,
1105
+ suggestion: `\u6DFB\u52A0\u5BF9\u5E94\u7684\u95ED\u5408\u62EC\u53F7 '${brackets[bracket.char]}'`
1106
+ });
1107
+ });
1108
+ }
1109
+ }
1110
+ /**
1111
+ * 检查 Markdown 语法
1112
+ */
1113
+ checkMarkdownSyntax(content, errors) {
1114
+ const lines = content.split("\n");
1115
+ let inCodeBlock = false;
1116
+ let codeBlockStart = 0;
1117
+ for (let i = 0; i < lines.length; i++) {
1118
+ const line = lines[i];
1119
+ if (line.trim().startsWith("```")) {
1120
+ if (inCodeBlock) {
1121
+ inCodeBlock = false;
1122
+ } else {
1123
+ inCodeBlock = true;
1124
+ codeBlockStart = i + 1;
1125
+ }
1126
+ }
1127
+ }
1128
+ if (inCodeBlock) {
1129
+ errors.push({
1130
+ type: "syntax",
1131
+ message: "\u672A\u95ED\u5408\u7684\u4EE3\u7801\u5757",
1132
+ line: codeBlockStart,
1133
+ suggestion: "\u5728\u4EE3\u7801\u5757\u672B\u5C3E\u6DFB\u52A0 ``` \u95ED\u5408\u6807\u8BB0"
1134
+ });
1135
+ }
1136
+ }
1137
+ /**
1138
+ * 检查必要章节完整性
1139
+ */
1140
+ checkRequiredSections(content, warnings) {
1141
+ const requiredSections = [
1142
+ { pattern: /## ⚠️ 强制工作流/i, name: "\u5F3A\u5236\u5DE5\u4F5C\u6D41\u7AE0\u8282" },
1143
+ { pattern: /## 📚 配置的 Agents/i, name: "Agents \u914D\u7F6E\u7AE0\u8282" }
1144
+ ];
1145
+ requiredSections.forEach((section) => {
1146
+ if (!section.pattern.test(content)) {
1147
+ warnings.push({
1148
+ type: "completeness",
1149
+ message: `\u7F3A\u5C11\u5FC5\u8981\u7AE0\u8282: ${section.name}`,
1150
+ suggestion: "\u786E\u4FDD\u751F\u6210\u7684\u914D\u7F6E\u6587\u4EF6\u5305\u542B\u6240\u6709\u5FC5\u8981\u7684\u7AE0\u8282"
1151
+ });
1152
+ }
1153
+ });
1154
+ }
1155
+ /**
1156
+ * 检查自定义内容标记
1157
+ */
1158
+ checkCustomContentMarkers(content, warnings) {
1159
+ const hasCustomStart = content.includes("<!-- CUSTOM_START -->");
1160
+ const hasCustomEnd = content.includes("<!-- CUSTOM_END -->");
1161
+ if (hasCustomStart !== hasCustomEnd) {
1162
+ warnings.push({
1163
+ type: "completeness",
1164
+ message: "CUSTOM \u6807\u8BB0\u4E0D\u5B8C\u6574",
1165
+ suggestion: "\u786E\u4FDD CUSTOM_START \u548C CUSTOM_END \u6210\u5BF9\u51FA\u73B0"
1166
+ });
1167
+ }
1168
+ }
1169
+ /**
1170
+ * 验证 Agent 内容
1171
+ */
1172
+ validateAgentContent(content, agentId) {
1173
+ const errors = [];
1174
+ const warnings = [];
1175
+ if (!content.includes("\u26A0\uFE0F \u5F3A\u5236\u5DE5\u4F5C\u6D41") && !content.includes("## \u5F3A\u5236\u5DE5\u4F5C\u6D41")) {
1176
+ warnings.push({
1177
+ type: "best-practice",
1178
+ message: `Agent ${agentId} \u7F3A\u5C11\u5F3A\u5236\u5DE5\u4F5C\u6D41\u8BF4\u660E`,
1179
+ suggestion: "\u5EFA\u8BAE\u5728 Agent \u4E2D\u5305\u542B MCP \u5DE5\u5177\u8C03\u7528\u7684\u5F3A\u5236\u8BF4\u660E"
1180
+ });
1181
+ }
1182
+ const syntaxValidation = this.validateConfigContent(content);
1183
+ errors.push(...syntaxValidation.errors);
1184
+ warnings.push(...syntaxValidation.warnings);
1185
+ return {
1186
+ isValid: errors.length === 0,
1187
+ errors,
1188
+ warnings
1189
+ };
1190
+ }
1191
+ /**
1192
+ * 生成验证报告
1193
+ */
1194
+ generateValidationReport(result) {
1195
+ let report = "";
1196
+ if (result.isValid && result.warnings.length === 0) {
1197
+ report = "\u2705 \u9A8C\u8BC1\u901A\u8FC7\uFF0C\u672A\u53D1\u73B0\u95EE\u9898\n";
1198
+ return report;
1199
+ }
1200
+ if (!result.isValid) {
1201
+ report += "\u274C \u9A8C\u8BC1\u5931\u8D25\uFF0C\u53D1\u73B0\u4EE5\u4E0B\u9519\u8BEF\uFF1A\n\n";
1202
+ result.errors.forEach((error, index) => {
1203
+ report += `${index + 1}. [${error.type}] ${error.message}
1204
+ `;
1205
+ if (error.line) {
1206
+ report += ` \u4F4D\u7F6E: \u7B2C ${error.line} \u884C
1207
+ `;
1208
+ }
1209
+ if (error.suggestion) {
1210
+ report += ` \u5EFA\u8BAE: ${error.suggestion}
1211
+ `;
1212
+ }
1213
+ report += "\n";
1214
+ });
1215
+ } else {
1216
+ report += "\u2705 \u9A8C\u8BC1\u901A\u8FC7\n\n";
1217
+ }
1218
+ if (result.warnings.length > 0) {
1219
+ report += "\u26A0\uFE0F \u53D1\u73B0\u4EE5\u4E0B\u8B66\u544A\uFF1A\n\n";
1220
+ result.warnings.forEach((warning, index) => {
1221
+ report += `${index + 1}. [${warning.type}] ${warning.message}
1222
+ `;
1223
+ if (warning.suggestion) {
1224
+ report += ` \u5EFA\u8BAE: ${warning.suggestion}
1225
+ `;
1226
+ }
1227
+ report += "\n";
1228
+ });
1229
+ }
1230
+ return report;
1231
+ }
1232
+ /**
1233
+ * 尝试自动修复简单的语法错误
1234
+ */
1235
+ attemptAutoFix(content) {
1236
+ let fixedContent = content;
1237
+ const changes = [];
1238
+ const tagPattern = /(<\/([\w-]+)>)\1+/g;
1239
+ const tagMatches = content.match(tagPattern);
1240
+ if (tagMatches) {
1241
+ fixedContent = fixedContent.replace(tagPattern, "$1");
1242
+ changes.push(`\u4FEE\u590D\u4E86\u91CD\u590D\u7684\u95ED\u5408\u6807\u7B7E: ${tagMatches.join(", ")}`);
1243
+ }
1244
+ const codeBlockCount = (fixedContent.match(/```/g) || []).length;
1245
+ if (codeBlockCount % 2 !== 0) {
1246
+ fixedContent += "\n```\n";
1247
+ changes.push("\u6DFB\u52A0\u4E86\u7F3A\u5931\u7684\u4EE3\u7801\u5757\u95ED\u5408\u6807\u8BB0");
1248
+ }
1249
+ return {
1250
+ fixed: changes.length > 0,
1251
+ content: fixedContent,
1252
+ changes
1253
+ };
1254
+ }
1255
+ };
1256
+
1257
+ // src/tools/generateConfig.ts
1258
+ var __filename2 = fileURLToPath2(import.meta.url);
1259
+ var __dirname2 = path5.dirname(__filename2);
1260
+ async function generateConfig(args) {
1261
+ const logger3 = new ConsoleLogger();
1262
+ try {
1263
+ if (!fs4.existsSync(args.projectPath)) {
1264
+ return {
1265
+ content: [{
1266
+ type: "text",
1267
+ text: JSON.stringify({
1268
+ error: `\u9879\u76EE\u8DEF\u5F84\u4E0D\u5B58\u5728: ${args.projectPath}`
1269
+ }, null, 2)
1270
+ }]
1271
+ };
1272
+ }
1273
+ const matcher = new SmartAgentMatcher(logger3);
1274
+ const githubClient = new GitHubClient(logger3);
1275
+ let selectedAgents = [];
1276
+ if (args.autoMatch !== false) {
1277
+ logger3.log("\u6B63\u5728\u5206\u6790\u9879\u76EE\u7279\u5F81...");
1278
+ const workspaceFolder = {
1279
+ uri: { fsPath: args.projectPath },
1280
+ name: path5.basename(args.projectPath),
1281
+ index: 0
1282
+ };
1283
+ const features = await matcher.analyzeProject(workspaceFolder);
1284
+ logger3.log("\u6B63\u5728\u5339\u914D Agents...");
1285
+ const availableAgents = [];
1286
+ try {
1287
+ logger3.log("\u{1F4E1} \u4ECE GitHub \u83B7\u53D6 Agents...");
1288
+ const agentFiles = await githubClient.listDirectoryFiles("agents");
1289
+ for (const file of agentFiles) {
1290
+ if (file.name.endsWith(".agent.md")) {
1291
+ try {
1292
+ const content2 = await githubClient.fetchFileContent(file.path);
1293
+ const metadata = matcher.parseAgentMetadata(file.path, content2);
1294
+ availableAgents.push(metadata);
1295
+ logger3.log(`\u2705 \u52A0\u8F7D Agent: ${metadata.title}`);
1296
+ } catch (error) {
1297
+ logger3.error(`\u89E3\u6790 ${file.name} \u5931\u8D25`);
1298
+ }
1299
+ }
1300
+ }
1301
+ logger3.log(`\u2705 \u4ECE GitHub \u6210\u529F\u52A0\u8F7D ${availableAgents.length} \u4E2A Agents`);
1302
+ } catch (githubError) {
1303
+ logger3.log("\u26A0\uFE0F GitHub \u83B7\u53D6\u5931\u8D25\uFF0C\u5C1D\u8BD5\u4ECE\u672C\u5730\u52A0\u8F7D...");
1304
+ const agentsDir = path5.join(__dirname2, "../../../agents");
1305
+ if (fs4.existsSync(agentsDir)) {
1306
+ const agentFiles = fs4.readdirSync(agentsDir);
1307
+ logger3.log(`\u627E\u5230 ${agentFiles.length} \u4E2A\u672C\u5730\u6587\u4EF6`);
1308
+ for (const file of agentFiles) {
1309
+ if (file.endsWith(".agent.md")) {
1310
+ try {
1311
+ const filePath = path5.join(agentsDir, file);
1312
+ const content2 = fs4.readFileSync(filePath, "utf-8");
1313
+ const metadata = matcher.parseAgentMetadata(`agents/${file}`, content2);
1314
+ availableAgents.push(metadata);
1315
+ logger3.log(`\u2705 \u52A0\u8F7D Agent: ${metadata.title}`);
1316
+ } catch (error) {
1317
+ logger3.error(`\u89E3\u6790 ${file} \u5931\u8D25`);
1318
+ }
1319
+ }
1320
+ }
1321
+ logger3.log(`\u2705 \u4ECE\u672C\u5730\u6210\u529F\u52A0\u8F7D ${availableAgents.length} \u4E2A Agents`);
1322
+ } else {
1323
+ throw new Error("\u65E0\u6CD5\u4ECE GitHub \u6216\u672C\u5730\u83B7\u53D6 Agents");
1324
+ }
1325
+ }
1326
+ logger3.log(`\u6210\u529F\u52A0\u8F7D ${availableAgents.length} \u4E2A Agents`);
1327
+ selectedAgents = matcher.matchAgents(features, availableAgents);
1328
+ logger3.log(`\u5339\u914D\u5230 ${selectedAgents.length} \u4E2A Agents`);
1329
+ selectedAgents = selectedAgents.slice(0, 5);
1330
+ }
1331
+ if (args.agentIds && args.agentIds.length > 0) {
1332
+ logger3.log(`\u4F7F\u7528\u6307\u5B9A\u7684 Agents: ${args.agentIds.join(", ")}`);
1333
+ selectedAgents = [];
1334
+ for (const id of args.agentIds) {
1335
+ try {
1336
+ let content2;
1337
+ const agentPath = `agents/${id}.agent.md`;
1338
+ try {
1339
+ logger3.log(`\u4ECE GitHub \u83B7\u53D6 Agent: ${id}`);
1340
+ content2 = await githubClient.fetchFileContent(agentPath);
1341
+ logger3.log(`\u2705 \u4ECE GitHub \u52A0\u8F7D\u6210\u529F: ${id}`);
1342
+ } catch (githubError) {
1343
+ logger3.log(`GitHub \u83B7\u53D6\u5931\u8D25\uFF0C\u5C1D\u8BD5\u672C\u5730: ${id}`);
1344
+ const agentsDir = path5.join(__dirname2, "../../../agents");
1345
+ const localPath = path5.join(agentsDir, `${id}.agent.md`);
1346
+ if (fs4.existsSync(localPath)) {
1347
+ content2 = fs4.readFileSync(localPath, "utf-8");
1348
+ logger3.log(`\u2705 \u4ECE\u672C\u5730\u52A0\u8F7D\u6210\u529F: ${id}`);
1349
+ } else {
1350
+ throw new Error(`Agent ${id} \u4E0D\u5B58\u5728\uFF08GitHub \u548C\u672C\u5730\u90FD\u672A\u627E\u5230\uFF09`);
1351
+ }
1352
+ }
1353
+ const metadata = matcher.parseAgentMetadata(`agents/${id}.agent.md`, content2);
1354
+ selectedAgents.push(metadata);
1355
+ } catch (error) {
1356
+ logger3.error(`\u83B7\u53D6 Agent ${id} \u5931\u8D25: ${error}`);
1357
+ }
1358
+ }
1359
+ }
1360
+ if (selectedAgents.length === 0) {
1361
+ return {
1362
+ content: [{
1363
+ type: "text",
1364
+ text: JSON.stringify({
1365
+ error: "\u672A\u627E\u5230\u5408\u9002\u7684 Agents"
1366
+ }, null, 2)
1367
+ }]
1368
+ };
1369
+ }
1370
+ logger3.log("\u6B63\u5728\u751F\u6210\u914D\u7F6E\u6587\u4EF6...");
1371
+ const githubDir = path5.join(args.projectPath, ".github");
1372
+ const configPath = path5.join(githubDir, "copilot-instructions.md");
1373
+ let existingCustomContent = "";
1374
+ let existingConfig = "";
1375
+ if (fs4.existsSync(configPath)) {
1376
+ existingConfig = fs4.readFileSync(configPath, "utf-8");
1377
+ const customMatch = existingConfig.match(/<!-- CUSTOM_START -->([\s\S]*?)<!-- CUSTOM_END -->/g);
1378
+ if (customMatch) {
1379
+ existingCustomContent = customMatch.join("\n\n");
1380
+ }
1381
+ }
1382
+ if (!fs4.existsSync(githubDir)) {
1383
+ fs4.mkdirSync(githubDir, { recursive: true });
1384
+ }
1385
+ const updateMode = args.updateMode || "merge";
1386
+ let content = "";
1387
+ if (updateMode === "merge") {
1388
+ content += `<!-- \u26A0\uFE0F \u6B64\u6587\u4EF6\u7531 Copilot Prompts MCP Server \u751F\u6210 -->
1389
+ `;
1390
+ content += `<!-- \u2139\uFE0F \u4F60\u53EF\u4EE5\u6DFB\u52A0\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF0C\u4F7F\u7528 CUSTOM_START/CUSTOM_END \u6807\u8BB0\u4FDD\u62A4 -->
1391
+ `;
1392
+ content += `<!-- \u793A\u4F8B: -->
1393
+ `;
1394
+ content += `<!-- CUSTOM_START -->
1395
+ `;
1396
+ content += `<!-- \u4F60\u7684\u81EA\u5B9A\u4E49\u89C4\u8303 -->
1397
+ `;
1398
+ content += `<!-- CUSTOM_END -->
1399
+
1400
+ `;
1401
+ } else {
1402
+ content += `<!-- \u26A0\uFE0F \u6B64\u6587\u4EF6\u7531 Copilot Prompts MCP Server \u81EA\u52A8\u751F\u6210 -->
1403
+ `;
1404
+ content += `<!-- \u26A0\uFE0F \u4F7F\u7528 --update-mode merge \u53EF\u4FDD\u62A4\u81EA\u5B9A\u4E49\u5185\u5BB9 -->
1405
+
1406
+ `;
1407
+ }
1408
+ const projectName = path5.basename(args.projectPath);
1409
+ const projectPath = args.projectPath;
1410
+ content += `<!-- \u{1F3AF} \u4F5C\u7528\u57DF\uFF1A\u6B64\u914D\u7F6E\u4EC5\u9002\u7528\u4E8E\u5F53\u524D\u9879\u76EE -->
1411
+ `;
1412
+ content += `<!-- \u9879\u76EE\u540D\u79F0: ${projectName} -->
1413
+ `;
1414
+ content += `<!-- \u9879\u76EE\u8DEF\u5F84: ${projectPath} -->
1415
+
1416
+ `;
1417
+ content += `# \u9879\u76EE\u5F00\u53D1\u89C4\u8303 - Copilot \u6307\u4EE4
1418
+
1419
+ `;
1420
+ content += `## \u26A0\uFE0F \u5F3A\u5236\u6267\u884C\u68C0\u67E5\u70B9
1421
+
1422
+ `;
1423
+ content += `> **\u6B64\u68C0\u67E5\u70B9\u7684\u4F18\u5148\u7EA7\u9AD8\u4E8E\u672C\u6587\u4EF6\u7684\u6240\u6709\u5176\u4ED6\u5185\u5BB9**
1424
+
1425
+ `;
1426
+ content += `\u5728\u6267\u884C**\u4EFB\u4F55**\u4EE5\u4E0B\u64CD\u4F5C\u524D\uFF0C\u5FC5\u987B\u5148\u5B8C\u6210\u89C4\u8303\u52A0\u8F7D\u9A8C\u8BC1\uFF1A
1427
+
1428
+ `;
1429
+ content += `### \u53D7\u9650\u64CD\u4F5C\u6E05\u5355
1430
+
1431
+ `;
1432
+ content += `- \u274C \u521B\u5EFA\u4EFB\u4F55\u4EE3\u7801\u6587\u4EF6\uFF08.vue\u3001.ts\u3001.tsx\u3001.js \u7B49\uFF09
1433
+ `;
1434
+ content += `- \u274C \u4FEE\u6539\u4EFB\u4F55\u4EE3\u7801\u6587\u4EF6
1435
+ `;
1436
+ content += `- \u274C \u4F7F\u7528 \`replace_string_in_file\` \u6216 \`multi_replace_string_in_file\`
1437
+ `;
1438
+ content += `- \u274C \u751F\u6210\u4EFB\u4F55\u4EE3\u7801\u7247\u6BB5
1439
+
1440
+ `;
1441
+ content += `### \u5F3A\u5236\u9A8C\u8BC1\u6D41\u7A0B
1442
+
1443
+ `;
1444
+ content += `1. **\u68C0\u67E5\u9879\u76EE\u4F5C\u7528\u57DF** - \u786E\u8BA4\u5F53\u524D\u64CD\u4F5C\u7684\u6587\u4EF6\u8DEF\u5F84\u5305\u542B \`/${projectName}/\`
1445
+ `;
1446
+ content += `2. **\u52A0\u8F7D\u76F8\u5173\u89C4\u8303** - \u6839\u636E\u6587\u4EF6\u7C7B\u578B\u8C03\u7528\u5BF9\u5E94\u7684 MCP \u5DE5\u5177\uFF1A
1447
+ `;
1448
+ content += ` - Vue \u6587\u4EF6 \u2192 \`get_smart_standards\` \u6216 \`use_preset\`
1449
+ `;
1450
+ content += ` - TypeScript \u6587\u4EF6 \u2192 \`get_smart_standards\` \u6216 \`use_preset\`
1451
+ `;
1452
+ content += ` - \u5176\u4ED6\u6587\u4EF6 \u2192 \u6839\u636E\u5B9E\u9645\u60C5\u51B5\u9009\u62E9
1453
+ `;
1454
+ content += `3. **\u9A8C\u8BC1\u52A0\u8F7D\u6210\u529F** - \u786E\u8BA4\u5DE5\u5177\u8FD4\u56DE\u4E86\u89C4\u8303\u5185\u5BB9
1455
+ `;
1456
+ content += `4. **\u58F0\u660E\u5DF2\u52A0\u8F7D** - \u5728\u54CD\u5E94\u4E2D\u660E\u786E\u8BF4\u660E\uFF1A\`\u2705 \u5DF2\u52A0\u8F7D\u89C4\u8303: [\u5DE5\u5177\u540D\u79F0]\`
1457
+
1458
+ `;
1459
+ content += `### \u8FDD\u89C4\u5904\u7406
1460
+
1461
+ `;
1462
+ content += `- \u5982\u679C\u672A\u52A0\u8F7D\u89C4\u8303\u5C31\u751F\u6210\u4EE3\u7801 \u2192 **\u6B64\u64CD\u4F5C\u65E0\u6548\uFF0C\u5FC5\u987B\u91CD\u65B0\u6267\u884C**
1463
+ `;
1464
+ content += `- \u5982\u679C\u51FA\u73B0\u8BED\u6CD5\u9519\u8BEF \u2192 **\u6DF1\u523B\u53CD\u601D\uFF0C\u68C0\u67E5\u662F\u5426\u9075\u5FAA\u4E86\u89C4\u8303**
1465
+ `;
1466
+ content += `- \u5982\u679C\u51FA\u73B0\u4F4E\u7EA7\u9519\u8BEF \u2192 **\u505C\u6B62\u64CD\u4F5C\uFF0C\u91CD\u65B0\u52A0\u8F7D\u89C4\u8303\u540E\u518D\u7EE7\u7EED**
1467
+
1468
+ `;
1469
+ content += `---
1470
+
1471
+ `;
1472
+ content += `## \u{1F3AF} \u4F5C\u7528\u57DF\u9650\u5236
1473
+
1474
+ `;
1475
+ content += `**\u26A0\uFE0F \u6B64\u914D\u7F6E\u4EC5\u5728\u4EE5\u4E0B\u60C5\u51B5\u751F\u6548\uFF1A**
1476
+
1477
+ `;
1478
+ content += `1. \u5F53\u524D\u7F16\u8F91\u7684\u6587\u4EF6\u8DEF\u5F84\u5305\u542B: \`/${projectName}/\`
1479
+ `;
1480
+ content += `2. \u6216\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\u4E3A: \`${projectPath}\`
1481
+
1482
+ `;
1483
+ content += `**\u5982\u679C\u4F60\u5728\u5176\u4ED6\u9879\u76EE\u5DE5\u4F5C\uFF08\u5982 ${projectName} \u4E4B\u5916\u7684\u9879\u76EE\uFF09\uFF0C\u8BF7\u5B8C\u5168\u5FFD\u7565\u6B64\u914D\u7F6E\u6587\u4EF6\u4E2D\u7684\u6240\u6709\u89C4\u8303\u548C\u6307\u4EE4\u3002**
1484
+
1485
+ `;
1486
+ content += `---
1487
+
1488
+ `;
1489
+ content += `> \u{1F4CC} **\u81EA\u52A8\u914D\u7F6E\u4FE1\u606F**
1490
+ `;
1491
+ content += `> - \u751F\u6210\u65F6\u95F4: ${(/* @__PURE__ */ new Date()).toLocaleString("zh-CN")}
1492
+ `;
1493
+ content += `> - \u5339\u914D\u7684 Agents: ${selectedAgents.length} \u4E2A
1494
+
1495
+ `;
1496
+ content += `---
1497
+
1498
+ `;
1499
+ if (args.configId) {
1500
+ try {
1501
+ const configFilePath = path5.join(__dirname2, "../../../configs", `element-plus-${args.configId}.json`);
1502
+ if (fs4.existsSync(configFilePath)) {
1503
+ const configData = JSON.parse(fs4.readFileSync(configFilePath, "utf-8"));
1504
+ content += `## \u{1F4E6} \u914D\u7F6E\u65B9\u6848
1505
+
1506
+ `;
1507
+ content += `**\u65B9\u6848ID**: ${configData.configId}
1508
+ `;
1509
+ content += `**\u540D\u79F0**: ${configData.name}
1510
+ `;
1511
+ content += `**\u63CF\u8FF0**: ${configData.description}
1512
+ `;
1513
+ content += `**\u7EF4\u62A4\u8005**: ${configData.maintainer}
1514
+
1515
+ `;
1516
+ if (configData.rules && configData.rules.table) {
1517
+ content += `### \u8868\u683C\u7EC4\u4EF6\u89C4\u8303
1518
+
1519
+ `;
1520
+ const tableRules = configData.rules.table;
1521
+ if (tableRules.border) content += `- \u2705 **\u5FC5\u987B\u6DFB\u52A0 border**
1522
+ `;
1523
+ if (tableRules["highlight-current-row"]) content += `- \u2705 **\u5FC5\u987B\u9AD8\u4EAE\u5F53\u524D\u884C**
1524
+ `;
1525
+ if (tableRules["v-loading"]) content += `- \u2705 **\u52A0\u8F7D\u72B6\u6001\u53D8\u91CF**: \`${tableRules["v-loading"].variable}\`
1526
+ `;
1527
+ content += `
1528
+ `;
1529
+ }
1530
+ content += `> \u8BE6\u7EC6\u89C4\u5219\u8BF7\u53C2\u8003: \`configs/element-plus-${args.configId}.json\`
1531
+
1532
+ `;
1533
+ content += `---
1534
+
1535
+ `;
1536
+ logger3.log(`\u2705 \u5DF2\u52A0\u8F7D\u914D\u7F6E\u65B9\u6848: ${configData.name}`);
1537
+ }
1538
+ } catch (error) {
1539
+ logger3.error(`\u52A0\u8F7D\u914D\u7F6E\u65B9\u6848\u5931\u8D25: ${error}`);
1540
+ }
1541
+ }
1542
+ content += `## \u26A0\uFE0F \u5F3A\u5236\u5DE5\u4F5C\u6D41
1543
+
1544
+ `;
1545
+ content += `**\u5728\u8FDB\u884C\u4EFB\u4F55\u4EE3\u7801\u751F\u6210\u6216\u4FEE\u6539\u4E4B\u524D\uFF0C\u5FC5\u987B\u5148\u8C03\u7528 MCP \u5DE5\u5177\u52A0\u8F7D\u76F8\u5173\u89C4\u8303\uFF01**
1546
+
1547
+ `;
1548
+ content += `\u6839\u636E\u6587\u4EF6\u7C7B\u578B\u548C\u573A\u666F\uFF0C\u8C03\u7528\u76F8\u5E94\u7684 MCP \u5DE5\u5177\uFF1A
1549
+
1550
+ `;
1551
+ content += `1. **Vue \u6587\u4EF6** \u2192 \`get_relevant_standards({ fileType: "vue" })\`
1552
+ `;
1553
+ content += `2. **TypeScript \u6587\u4EF6** \u2192 \`get_relevant_standards({ fileType: "ts" })\`
1554
+ `;
1555
+ content += `3. **React \u7EC4\u4EF6** \u2192 \`get_relevant_standards({ fileType: "tsx" })\`
1556
+ `;
1557
+ content += `4. **\u4F7F\u7528\u7279\u5B9A\u5E93\u65F6**\uFF1A
1558
+ `;
1559
+ content += ` - Element Plus: \`get_relevant_standards({ imports: ["element-plus"] })\`
1560
+ `;
1561
+ content += ` - Pinia: \`get_relevant_standards({ imports: ["pinia"] })\`
1562
+ `;
1563
+ content += ` - Vue Router: \`get_relevant_standards({ imports: ["vue-router"] })\`
1564
+ `;
1565
+ content += ` - LogicFlow: \`get_relevant_standards({ imports: ["@logicflow/core"] })\`
1566
+ `;
1567
+ content += `5. **\u7279\u5B9A\u573A\u666F**\uFF1A
1568
+ `;
1569
+ content += ` - API \u8C03\u7528: \`get_relevant_standards({ scenario: "API \u8C03\u7528" })\`
1570
+ `;
1571
+ content += ` - \u56FD\u9645\u5316: \`get_relevant_standards({ scenario: "\u56FD\u9645\u5316" })\`
1572
+
1573
+ `;
1574
+ content += `### \u6807\u51C6\u6D41\u7A0B
1575
+
1576
+ `;
1577
+ content += `1. \u2705 **\u5F3A\u5236**: \u52A0\u8F7D\u89C4\u8303 \u2192 2. \u7406\u89E3\u9700\u6C42 \u2192 3. \u7F16\u5199\u4EE3\u7801 \u2192 4. \u9A8C\u8BC1\u89C4\u8303
1578
+
1579
+ `;
1580
+ content += `---
1581
+
1582
+ `;
1583
+ content += `## \u{1F4DA} \u914D\u7F6E\u7684 Agents
1584
+
1585
+ `;
1586
+ content += `\u672C\u9879\u76EE\u4F7F\u7528\u4EE5\u4E0B Agents\uFF08\u89C4\u8303\u5185\u5BB9\u7531 Copilot \u901A\u8FC7 MCP \u5DE5\u5177\u5B9E\u65F6\u52A0\u8F7D\uFF09\uFF1A
1587
+
1588
+ `;
1589
+ for (const agent of selectedAgents) {
1590
+ content += `### ${agent.title}
1591
+
1592
+ `;
1593
+ content += `- **Agent ID**: \`${agent.id}\`
1594
+ `;
1595
+ content += `- **\u63CF\u8FF0**: ${agent.description || "\u6682\u65E0\u63CF\u8FF0"}
1596
+ `;
1597
+ content += `- **\u6765\u6E90**: \`${agent.path}\`
1598
+ `;
1599
+ if (agent.tags && agent.tags.length > 0) {
1600
+ content += `- **\u6807\u7B7E**: ${agent.tags.join(", ")}
1601
+ `;
1602
+ }
1603
+ content += `
1604
+ > \u{1F4A1} **\u4F7F\u7528\u65B9\u5F0F**: \u5728\u5F00\u53D1\u65F6\uFF0CCopilot \u4F1A\u81EA\u52A8\u901A\u8FC7 MCP \u5DE5\u5177\u52A0\u8F7D\u6B64 Agent \u7684\u5B8C\u6574\u89C4\u8303\u3002
1605
+
1606
+ `;
1607
+ }
1608
+ content += `---
1609
+
1610
+ `;
1611
+ if (updateMode === "merge" && existingCustomContent) {
1612
+ content += `
1613
+
1614
+ ## \u{1F4DD} \u81EA\u5B9A\u4E49\u89C4\u8303
1615
+
1616
+ `;
1617
+ content += existingCustomContent;
1618
+ logger3.log("\u2705 \u5DF2\u4FDD\u7559\u81EA\u5B9A\u4E49\u5185\u5BB9");
1619
+ }
1620
+ const validator = new CodeValidator(logger3);
1621
+ const validation = validator.validateConfigContent(content);
1622
+ if (!validation.isValid) {
1623
+ logger3.error("\u26A0\uFE0F \u914D\u7F6E\u5185\u5BB9\u9A8C\u8BC1\u5931\u8D25\uFF0C\u5C1D\u8BD5\u81EA\u52A8\u4FEE\u590D...");
1624
+ const fixResult = validator.attemptAutoFix(content);
1625
+ if (fixResult.fixed) {
1626
+ content = fixResult.content;
1627
+ logger3.log(`\u2705 \u5DF2\u81EA\u52A8\u4FEE\u590D ${fixResult.changes.length} \u4E2A\u95EE\u9898:`);
1628
+ fixResult.changes.forEach((change) => logger3.log(` - ${change}`));
1629
+ const revalidation = validator.validateConfigContent(content);
1630
+ if (!revalidation.isValid) {
1631
+ const report = validator.generateValidationReport(revalidation);
1632
+ logger3.error("\u274C \u81EA\u52A8\u4FEE\u590D\u540E\u4ECD\u5B58\u5728\u95EE\u9898:");
1633
+ logger3.error(report);
1634
+ return {
1635
+ content: [{
1636
+ type: "text",
1637
+ text: JSON.stringify({
1638
+ error: "\u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u5931\u8D25",
1639
+ validationReport: report,
1640
+ message: "\u751F\u6210\u7684\u914D\u7F6E\u6587\u4EF6\u5B58\u5728\u8BED\u6CD5\u9519\u8BEF\uFF0C\u8BF7\u68C0\u67E5\u5E76\u624B\u52A8\u4FEE\u590D"
1641
+ }, null, 2)
1642
+ }]
1643
+ };
1644
+ }
1645
+ } else {
1646
+ const report = validator.generateValidationReport(validation);
1647
+ logger3.error(report);
1648
+ return {
1649
+ content: [{
1650
+ type: "text",
1651
+ text: JSON.stringify({
1652
+ error: "\u914D\u7F6E\u6587\u4EF6\u9A8C\u8BC1\u5931\u8D25",
1653
+ validationReport: report,
1654
+ message: "\u751F\u6210\u7684\u914D\u7F6E\u6587\u4EF6\u5B58\u5728\u8BED\u6CD5\u9519\u8BEF\u4E14\u65E0\u6CD5\u81EA\u52A8\u4FEE\u590D"
1655
+ }, null, 2)
1656
+ }]
1657
+ };
1658
+ }
1659
+ } else if (validation.warnings.length > 0) {
1660
+ logger3.log("\u26A0\uFE0F \u914D\u7F6E\u5185\u5BB9\u9A8C\u8BC1\u901A\u8FC7\uFF0C\u4F46\u6709\u4EE5\u4E0B\u8B66\u544A:");
1661
+ validation.warnings.forEach((warning) => {
1662
+ logger3.log(` - [${warning.type}] ${warning.message}`);
1663
+ });
1664
+ } else {
1665
+ logger3.log("\u2705 \u914D\u7F6E\u5185\u5BB9\u9A8C\u8BC1\u901A\u8FC7");
1666
+ }
1667
+ fs4.writeFileSync(configPath, content, "utf-8");
1668
+ const gitignorePath = path5.join(args.projectPath, ".gitignore");
1669
+ if (fs4.existsSync(gitignorePath)) {
1670
+ let gitignoreContent = fs4.readFileSync(gitignorePath, "utf-8");
1671
+ if (!gitignoreContent.includes(".github/copilot-instructions.md")) {
1672
+ gitignoreContent += "\n# Copilot Prompts (auto-generated)\n.github/copilot-instructions.md\n";
1673
+ fs4.writeFileSync(gitignorePath, gitignoreContent, "utf-8");
1674
+ }
1675
+ }
1676
+ logger3.log(`\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u751F\u6210: ${configPath}`);
1677
+ return {
1678
+ content: [{
1679
+ type: "text",
1680
+ text: JSON.stringify({
1681
+ success: true,
1682
+ configPath,
1683
+ agents: selectedAgents.map((a) => ({
1684
+ id: a.id,
1685
+ title: a.title,
1686
+ score: a.score
1687
+ })),
1688
+ message: `\u5DF2\u6210\u529F\u751F\u6210\u914D\u7F6E\u6587\u4EF6\uFF0C\u5E94\u7528\u4E86 ${selectedAgents.length} \u4E2A Agents`
1689
+ }, null, 2)
1690
+ }]
1691
+ };
1692
+ } catch (error) {
1693
+ logger3.error(`\u751F\u6210\u914D\u7F6E\u5931\u8D25: ${error}`);
1694
+ return {
1695
+ content: [{
1696
+ type: "text",
1697
+ text: JSON.stringify({
1698
+ error: error instanceof Error ? error.message : String(error)
1699
+ }, null, 2)
1700
+ }]
1701
+ };
1702
+ }
1703
+ }
1704
+
1705
+ // src/tools/autoSetup.ts
1706
+ import * as fs5 from "fs";
1707
+ import * as path6 from "path";
1708
+ async function autoSetup(args) {
1709
+ var _a, _b, _c, _d, _e, _f, _g;
1710
+ const logger3 = new ConsoleLogger();
1711
+ try {
1712
+ const workspacePath = args.workspacePath || process.cwd();
1713
+ if (!fs5.existsSync(workspacePath)) {
1714
+ return {
1715
+ content: [{
1716
+ type: "text",
1717
+ text: JSON.stringify({
1718
+ error: `\u5DE5\u4F5C\u533A\u8DEF\u5F84\u4E0D\u5B58\u5728: ${workspacePath}`
1719
+ }, null, 2)
1720
+ }]
1721
+ };
1722
+ }
1723
+ const results = {
1724
+ workspacePath,
1725
+ steps: [],
1726
+ warnings: []
1727
+ };
1728
+ logger3.log("\u{1F680} \u5F00\u59CB\u81EA\u52A8\u914D\u7F6E MCP \u670D\u52A1\u5668...");
1729
+ const vscodeDir = path6.join(workspacePath, ".vscode");
1730
+ if (!fs5.existsSync(vscodeDir)) {
1731
+ fs5.mkdirSync(vscodeDir, { recursive: true });
1732
+ results.steps.push({ step: "\u521B\u5EFA .vscode \u76EE\u5F55", status: "success" });
1733
+ } else {
1734
+ results.steps.push({ step: "\u68C0\u6D4B\u5230\u5DF2\u6709 .vscode \u76EE\u5F55", status: "skip" });
1735
+ }
1736
+ let mcpServerPath = "";
1737
+ const possiblePaths = [
1738
+ path6.join(workspacePath, "mcp-server/build/index.js"),
1739
+ path6.join(workspacePath, "../copilot-prompts/mcp-server/build/index.js"),
1740
+ path6.join(workspacePath, "copilot-prompts/mcp-server/build/index.js")
1741
+ ];
1742
+ for (const p of possiblePaths) {
1743
+ if (fs5.existsSync(p)) {
1744
+ mcpServerPath = p;
1745
+ break;
1746
+ }
1747
+ }
1748
+ if (!mcpServerPath) {
1749
+ const srcPath = path6.join(workspacePath, "mcp-server/src/index.ts");
1750
+ if (fs5.existsSync(srcPath)) {
1751
+ results.warnings.push("\u68C0\u6D4B\u5230\u5F00\u53D1\u6A21\u5F0F\uFF0C\u8BF7\u5148\u8FD0\u884C npm run build \u7F16\u8BD1\u670D\u52A1\u5668");
1752
+ mcpServerPath = "${workspaceFolder}/mcp-server/build/index.js";
1753
+ } else {
1754
+ return {
1755
+ content: [{
1756
+ type: "text",
1757
+ text: JSON.stringify({
1758
+ error: "MCP \u670D\u52A1\u5668\u672A\u627E\u5230",
1759
+ hint: "\u8BF7\u786E\u4FDD mcp-server/build/index.js \u5B58\u5728\uFF0C\u6216\u8FD0\u884C npm run build"
1760
+ }, null, 2)
1761
+ }]
1762
+ };
1763
+ }
1764
+ }
1765
+ const relativePath = mcpServerPath.startsWith(workspacePath) ? "${workspaceFolder}/" + path6.relative(workspacePath, mcpServerPath) : mcpServerPath;
1766
+ results.steps.push({
1767
+ step: "\u68C0\u6D4B MCP \u670D\u52A1\u5668\u8DEF\u5F84",
1768
+ status: "success",
1769
+ detail: relativePath
1770
+ });
1771
+ const mcpJsonPath = path6.join(vscodeDir, "mcp.json");
1772
+ const mcpConfig = {
1773
+ servers: {
1774
+ "copilot-prompts": {
1775
+ command: "node",
1776
+ args: [relativePath],
1777
+ env: {},
1778
+ autoStart: true
1779
+ }
1780
+ }
1781
+ };
1782
+ if (fs5.existsSync(mcpJsonPath)) {
1783
+ try {
1784
+ const existingConfig = JSON.parse(fs5.readFileSync(mcpJsonPath, "utf-8"));
1785
+ if (existingConfig.mcpServers && !existingConfig.servers) {
1786
+ results.warnings.push("\u68C0\u6D4B\u5230\u65E7\u7248\u914D\u7F6E\u683C\u5F0F(mcpServers)\uFF0C\u5DF2\u81EA\u52A8\u5347\u7EA7\u4E3A\u65B0\u683C\u5F0F(servers)");
1787
+ existingConfig.servers = existingConfig.mcpServers;
1788
+ delete existingConfig.mcpServers;
1789
+ }
1790
+ if ((_a = existingConfig.servers) == null ? void 0 : _a["copilot-prompts"]) {
1791
+ existingConfig.servers["copilot-prompts"] = {
1792
+ ...mcpConfig.servers["copilot-prompts"],
1793
+ ...existingConfig.servers["copilot-prompts"]
1794
+ };
1795
+ fs5.writeFileSync(mcpJsonPath, JSON.stringify(existingConfig, null, 2));
1796
+ results.steps.push({ step: "\u66F4\u65B0 mcp.json", status: "success" });
1797
+ } else {
1798
+ existingConfig.servers = {
1799
+ ...existingConfig.servers,
1800
+ ...mcpConfig.servers
1801
+ };
1802
+ fs5.writeFileSync(mcpJsonPath, JSON.stringify(existingConfig, null, 2));
1803
+ results.steps.push({ step: "\u5408\u5E76\u914D\u7F6E\u5230 mcp.json", status: "success" });
1804
+ }
1805
+ } catch (err) {
1806
+ fs5.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
1807
+ results.steps.push({ step: "\u91CD\u65B0\u521B\u5EFA mcp.json", status: "success" });
1808
+ results.warnings.push(`\u539F\u914D\u7F6E\u6587\u4EF6\u89E3\u6790\u5931\u8D25: ${err}`);
1809
+ }
1810
+ } else {
1811
+ fs5.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2));
1812
+ results.steps.push({ step: "\u521B\u5EFA mcp.json", status: "success" });
1813
+ }
1814
+ const settingsJsonPath = path6.join(vscodeDir, "settings.json");
1815
+ const mcpSettings = {
1816
+ "github.copilot.chat.mcp.enabled": true,
1817
+ "github.copilot.chat.mcp.configFile": "${workspaceFolder}/.vscode/mcp.json",
1818
+ "github.copilot.chat.mcp.autoStart": true
1819
+ };
1820
+ if (fs5.existsSync(settingsJsonPath)) {
1821
+ try {
1822
+ const existingSettings = JSON.parse(fs5.readFileSync(settingsJsonPath, "utf-8"));
1823
+ const updated = { ...existingSettings, ...mcpSettings };
1824
+ fs5.writeFileSync(settingsJsonPath, JSON.stringify(updated, null, 2) + "\n");
1825
+ results.steps.push({ step: "\u66F4\u65B0 settings.json", status: "success" });
1826
+ } catch {
1827
+ fs5.writeFileSync(settingsJsonPath, JSON.stringify(mcpSettings, null, 2) + "\n");
1828
+ results.steps.push({ step: "\u91CD\u65B0\u521B\u5EFA settings.json", status: "success" });
1829
+ }
1830
+ } else {
1831
+ fs5.writeFileSync(settingsJsonPath, JSON.stringify(mcpSettings, null, 2) + "\n");
1832
+ results.steps.push({ step: "\u521B\u5EFA settings.json", status: "success" });
1833
+ }
1834
+ const extensionsJsonPath = path6.join(vscodeDir, "extensions.json");
1835
+ const recommendedExtensions = {
1836
+ recommendations: [
1837
+ "github.copilot",
1838
+ "github.copilot-chat"
1839
+ ]
1840
+ };
1841
+ if (!fs5.existsSync(extensionsJsonPath)) {
1842
+ fs5.writeFileSync(extensionsJsonPath, JSON.stringify(recommendedExtensions, null, 2));
1843
+ results.steps.push({ step: "\u521B\u5EFA extensions.json", status: "success" });
1844
+ } else {
1845
+ results.steps.push({ step: "extensions.json \u5DF2\u5B58\u5728", status: "skip" });
1846
+ }
1847
+ const gitignorePath = path6.join(workspacePath, ".gitignore");
1848
+ if (fs5.existsSync(gitignorePath)) {
1849
+ const gitignoreContent = fs5.readFileSync(gitignorePath, "utf-8");
1850
+ if (!gitignoreContent.includes(".vscode/mcp.json")) {
1851
+ const updatedContent = gitignoreContent + "\n# MCP \u914D\u7F6E\uFF08\u672C\u5730\uFF09\n.vscode/mcp.json\n";
1852
+ fs5.writeFileSync(gitignorePath, updatedContent);
1853
+ results.steps.push({ step: "\u6DFB\u52A0\u5230 .gitignore", status: "success" });
1854
+ } else {
1855
+ results.steps.push({ step: ".gitignore \u5DF2\u5305\u542B\u914D\u7F6E", status: "skip" });
1856
+ }
1857
+ } else {
1858
+ results.warnings.push("\u672A\u68C0\u6D4B\u5230 .gitignore\uFF0C\u5EFA\u8BAE\u624B\u52A8\u6DFB\u52A0 .vscode/mcp.json");
1859
+ }
1860
+ const generateInstructions = args.generateInstructions !== false;
1861
+ if (generateInstructions) {
1862
+ logger3.log("\u{1F50D} \u5206\u6790\u9879\u76EE\u5E76\u751F\u6210 copilot-instructions.md...");
1863
+ try {
1864
+ const analysisResult = await analyzeProject({ projectPath: workspacePath });
1865
+ const analysisContent = analysisResult.content[0];
1866
+ if (analysisContent.type === "text") {
1867
+ const analysisData = JSON.parse(analysisContent.text);
1868
+ if (analysisData.success && analysisData.features) {
1869
+ const agentIds = [];
1870
+ const features = analysisData.features;
1871
+ if (((_b = features.frameworks) == null ? void 0 : _b.includes("Vue 3")) || ((_c = features.frameworks) == null ? void 0 : _c.includes("Vue"))) {
1872
+ agentIds.push("vue3");
1873
+ }
1874
+ if ((_d = features.tools) == null ? void 0 : _d.includes("LogicFlow")) {
1875
+ agentIds.push("logicflow");
1876
+ }
1877
+ if (((_e = features.keywords) == null ? void 0 : _e.includes("i18n")) || ((_f = features.keywords) == null ? void 0 : _f.includes("\u56FD\u9645\u5316"))) {
1878
+ agentIds.push("i18n");
1879
+ }
1880
+ if (features.projectType === "flutter") {
1881
+ agentIds.push("flutter");
1882
+ }
1883
+ if (features.projectType === "wechat-miniprogram") {
1884
+ agentIds.push("wechat-miniprogram");
1885
+ }
1886
+ if (agentIds.length > 0) {
1887
+ const configResult = await generateConfig({
1888
+ projectPath: workspacePath,
1889
+ agentIds,
1890
+ autoMatch: false,
1891
+ updateMode: "merge"
1892
+ });
1893
+ const configContent = configResult.content[0];
1894
+ if (configContent.type === "text") {
1895
+ const configData = JSON.parse(configContent.text);
1896
+ if (configData.success) {
1897
+ results.steps.push({
1898
+ step: "\u751F\u6210 copilot-instructions.md",
1899
+ status: "success",
1900
+ detail: `\u5E94\u7528\u4E86 ${((_g = configData.agents) == null ? void 0 : _g.length) || 0} \u4E2A Agents: ${agentIds.join(", ")}`
1901
+ });
1902
+ } else {
1903
+ results.warnings.push(`\u914D\u7F6E\u751F\u6210\u5931\u8D25: ${configData.error || "\u672A\u77E5\u9519\u8BEF"}`);
1904
+ }
1905
+ }
1906
+ } else {
1907
+ results.warnings.push("\u672A\u627E\u5230\u5339\u914D\u7684 Agents\uFF0C\u8DF3\u8FC7\u914D\u7F6E\u751F\u6210");
1908
+ results.warnings.push("\u4F60\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u8FD0\u884C generate_config \u5DE5\u5177\u5E76\u6307\u5B9A agentIds");
1909
+ }
1910
+ } else {
1911
+ results.warnings.push(`\u9879\u76EE\u5206\u6790\u5931\u8D25: ${analysisData.error || "\u672A\u77E5\u9519\u8BEF"}`);
1912
+ }
1913
+ }
1914
+ } catch (error) {
1915
+ results.warnings.push(`\u81EA\u52A8\u751F\u6210\u914D\u7F6E\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
1916
+ results.warnings.push("\u4F60\u53EF\u4EE5\u7A0D\u540E\u624B\u52A8\u8FD0\u884C generate_config \u5DE5\u5177\u751F\u6210\u914D\u7F6E");
1917
+ }
1918
+ } else {
1919
+ results.steps.push({ step: "\u8DF3\u8FC7 copilot-instructions.md \u751F\u6210", status: "skip" });
1920
+ }
1921
+ logger3.log("\u2705 \u81EA\u52A8\u914D\u7F6E\u5B8C\u6210\uFF01");
1922
+ return {
1923
+ content: [{
1924
+ type: "text",
1925
+ text: JSON.stringify({
1926
+ success: true,
1927
+ message: "\u{1F389} MCP \u670D\u52A1\u5668\u5DF2\u81EA\u52A8\u914D\u7F6E\u5230\u5DE5\u4F5C\u533A",
1928
+ ...results,
1929
+ nextSteps: [
1930
+ "1. \u91CD\u65B0\u52A0\u8F7D VS Code \u7A97\u53E3 (Cmd+Shift+P \u2192 Reload Window)",
1931
+ "2. \u6253\u5F00 GitHub Copilot Chat",
1932
+ "3. \u5F00\u59CB\u4F7F\u7528\uFF1ACopilot \u4F1A\u81EA\u52A8\u5E94\u7528\u9879\u76EE\u89C4\u8303",
1933
+ '4. \u9AD8\u7EA7\u7528\u6CD5\uFF1A\u5C1D\u8BD5\u8BF4"\u83B7\u53D6 Vue 3 \u76F8\u5173\u89C4\u8303"'
1934
+ ]
1935
+ }, null, 2)
1936
+ }]
1937
+ };
1938
+ } catch (error) {
1939
+ logger3.error(`\u81EA\u52A8\u914D\u7F6E\u5931\u8D25: ${error}`);
1940
+ return {
1941
+ content: [{
1942
+ type: "text",
1943
+ text: JSON.stringify({
1944
+ error: error instanceof Error ? error.message : String(error)
1945
+ }, null, 2)
1946
+ }]
1947
+ };
1948
+ }
1949
+ }
1950
+
1951
+ // src/tools/getSmartStandards.ts
1952
+ import * as fs8 from "fs";
1953
+
1954
+ // src/core/standardsManager.ts
1955
+ import * as fs6 from "fs";
1956
+ import * as path7 from "path";
1957
+ import { fileURLToPath as fileURLToPath3 } from "url";
1958
+ var __filename3 = fileURLToPath3(import.meta.url);
1959
+ var __dirname3 = path7.dirname(__filename3);
1960
+ var StandardsManager = class {
1961
+ constructor() {
1962
+ // v1.2.0: 底层必须加载的核心规范
1963
+ this.MANDATORY_CORE_STANDARDS = [
1964
+ "standards://core/code-style",
1965
+ // 代码风格规范(命名、格式等)
1966
+ "standards://core/typescript-base",
1967
+ // TypeScript基础规范
1968
+ "standards://core/code-generation"
1969
+ // 代码生成规范(注释、文档等)
1970
+ ];
1971
+ // Phase 3: 缓存系统
1972
+ this.contentCache = /* @__PURE__ */ new Map();
1973
+ this.CACHE_DURATION = 30 * 60 * 1e3;
1974
+ // 30分钟
1975
+ this.MAX_CACHE_SIZE = 50;
1976
+ // 最多缓存50个条目
1977
+ // Phase 3: 使用统计
1978
+ this.stats = {
1979
+ standardCombinations: /* @__PURE__ */ new Map(),
1980
+ individualStandards: /* @__PURE__ */ new Map(),
1981
+ averageTokens: 0,
1982
+ totalCalls: 0
1983
+ };
1984
+ // Phase 3: 性能指标
1985
+ this.metrics = {
1986
+ totalCalls: 0,
1987
+ cacheHits: 0,
1988
+ cacheMisses: 0,
1989
+ averageResponseTime: 0,
1990
+ totalTokensSaved: 0
1991
+ };
1992
+ const devPath = path7.resolve(__dirname3, "../../../standards");
1993
+ const npmPath = path7.resolve(__dirname3, "../../standards");
1994
+ this.standardsPath = fs6.existsSync(npmPath) ? npmPath : devPath;
1995
+ }
1996
+ /**
1997
+ * 获取所有可用的规范资源
1998
+ */
1999
+ getAvailableStandards() {
2000
+ const standards = [];
2001
+ const categories = [
2002
+ { dir: "core", name: "\u6838\u5FC3\u89C4\u8303" },
2003
+ { dir: "frameworks", name: "\u6846\u67B6\u89C4\u8303" },
2004
+ { dir: "libraries", name: "\u5E93\u89C4\u8303" },
2005
+ { dir: "patterns", name: "\u8BBE\u8BA1\u6A21\u5F0F" }
2006
+ ];
2007
+ categories.forEach(({ dir, name: categoryName }) => {
2008
+ const categoryPath = path7.join(this.standardsPath, dir);
2009
+ if (!fs6.existsSync(categoryPath)) {
2010
+ return;
2011
+ }
2012
+ const files = fs6.readdirSync(categoryPath).filter((file) => file.endsWith(".md"));
2013
+ files.forEach((file) => {
2014
+ const standardId = file.replace(".md", "");
2015
+ standards.push({
2016
+ uri: `standards://${dir}/${standardId}`,
2017
+ name: this.getStandardName(dir, standardId),
2018
+ description: `${categoryName} - ${this.getStandardDescription(dir, standardId)}`,
2019
+ category: dir
2020
+ });
2021
+ });
2022
+ });
2023
+ return standards;
2024
+ }
2025
+ /**
2026
+ * 读取特定规范内容(Phase 3: 带缓存)
2027
+ */
2028
+ readStandard(uri) {
2029
+ const startTime = Date.now();
2030
+ const cached = this.contentCache.get(uri);
2031
+ if (cached && Date.now() - cached.timestamp < this.CACHE_DURATION) {
2032
+ cached.accessCount++;
2033
+ this.metrics.cacheHits++;
2034
+ return cached.content;
2035
+ }
2036
+ this.metrics.cacheMisses++;
2037
+ const match = uri.match(/^standards:\/\/([^/]+)\/(.+)$/);
2038
+ if (!match) {
2039
+ throw new Error(`Invalid standards URI: ${uri}`);
2040
+ }
2041
+ const [, category, standardId] = match;
2042
+ const filePath = path7.join(this.standardsPath, category, `${standardId}.md`);
2043
+ if (!fs6.existsSync(filePath)) {
2044
+ throw new Error(`Standard not found: ${uri}`);
2045
+ }
2046
+ const content = fs6.readFileSync(filePath, "utf-8");
2047
+ this.updateCache(uri, content);
2048
+ this.stats.individualStandards.set(
2049
+ uri,
2050
+ (this.stats.individualStandards.get(uri) || 0) + 1
2051
+ );
2052
+ const responseTime = Date.now() - startTime;
2053
+ this.updateAverageResponseTime(responseTime);
2054
+ return content;
2055
+ }
2056
+ /**
2057
+ * 更新缓存
2058
+ */
2059
+ updateCache(uri, content) {
2060
+ if (this.contentCache.size >= this.MAX_CACHE_SIZE) {
2061
+ let minAccessCount = Infinity;
2062
+ let lruKey = null;
2063
+ this.contentCache.forEach((entry, key) => {
2064
+ if (entry.accessCount < minAccessCount) {
2065
+ minAccessCount = entry.accessCount;
2066
+ lruKey = key;
2067
+ }
2068
+ });
2069
+ if (lruKey) {
2070
+ this.contentCache.delete(lruKey);
2071
+ }
2072
+ }
2073
+ this.contentCache.set(uri, {
2074
+ content,
2075
+ timestamp: Date.now(),
2076
+ accessCount: 1
2077
+ });
2078
+ }
2079
+ /**
2080
+ * 根据技术栈获取相关规范(增强版 - Phase 2)
2081
+ */
2082
+ getRelevantStandards(context) {
2083
+ const standardScores = /* @__PURE__ */ new Map();
2084
+ const WEIGHTS = {
2085
+ CORE: 100,
2086
+ // 核心规范始终包含
2087
+ FILE_TYPE: 50,
2088
+ // 文件类型匹配
2089
+ IMPORT_DIRECT: 40,
2090
+ // 直接导入匹配
2091
+ IMPORT_RELATED: 20,
2092
+ // 相关导入匹配
2093
+ SCENARIO: 30,
2094
+ // 场景匹配
2095
+ CONTENT: 15,
2096
+ // 内容关键词匹配
2097
+ THRESHOLD: 10
2098
+ // 最低阈值
2099
+ };
2100
+ this.MANDATORY_CORE_STANDARDS.forEach((standard) => {
2101
+ standardScores.set(standard, WEIGHTS.CORE);
2102
+ });
2103
+ let detectedImports = context.imports || [];
2104
+ if (context.fileContent && !context.imports) {
2105
+ detectedImports = this.detectImports(context.fileContent);
2106
+ }
2107
+ if (context.fileType) {
2108
+ this.scoreByFileType(context.fileType, standardScores, WEIGHTS);
2109
+ }
2110
+ if (detectedImports.length > 0) {
2111
+ this.scoreByImports(detectedImports, standardScores, WEIGHTS);
2112
+ }
2113
+ if (context.scenario) {
2114
+ this.scoreByScenario(context.scenario, standardScores, WEIGHTS);
2115
+ }
2116
+ if (context.fileContent) {
2117
+ this.scoreByContent(context.fileContent, standardScores, WEIGHTS);
2118
+ }
2119
+ const sortedStandards = Array.from(standardScores.entries()).filter(([_, score]) => score >= WEIGHTS.THRESHOLD).sort((a, b) => b[1] - a[1]).map(([uri]) => uri);
2120
+ this.stats.totalCalls++;
2121
+ const combinationKey = sortedStandards.join("|");
2122
+ this.stats.standardCombinations.set(
2123
+ combinationKey,
2124
+ (this.stats.standardCombinations.get(combinationKey) || 0) + 1
2125
+ );
2126
+ return sortedStandards;
2127
+ }
2128
+ /**
2129
+ * 自动检测文件中的导入语句
2130
+ */
2131
+ detectImports(content) {
2132
+ const imports = [];
2133
+ const importRegex = /import\s+(?:(?:{[^}]*}|\*\s+as\s+\w+|\w+)\s+from\s+)?['"]([^'"]+)['"]/g;
2134
+ let match;
2135
+ while ((match = importRegex.exec(content)) !== null) {
2136
+ imports.push(match[1]);
2137
+ }
2138
+ const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
2139
+ while ((match = requireRegex.exec(content)) !== null) {
2140
+ imports.push(match[1]);
2141
+ }
2142
+ return imports;
2143
+ }
2144
+ /**
2145
+ * 根据文件类型评分
2146
+ */
2147
+ scoreByFileType(fileType, scores, weights) {
2148
+ const type = fileType.toLowerCase();
2149
+ if (type === "vue" || type.endsWith(".vue")) {
2150
+ this.addScore(scores, "standards://frameworks/vue3-composition", weights.FILE_TYPE);
2151
+ this.addScore(scores, "standards://patterns/component-design", weights.FILE_TYPE * 0.6);
2152
+ }
2153
+ if (type === "wxml" || type.endsWith(".wxml") || type === "wxss" || type.endsWith(".wxss") || type === "wxs" || type.endsWith(".wxs")) {
2154
+ this.addScore(scores, "standards://frameworks/wechat-miniprogram", weights.FILE_TYPE);
2155
+ }
2156
+ if (type === "ts" || type === "typescript" || type.endsWith(".ts")) {
2157
+ this.addScore(scores, "standards://core/typescript-base", weights.FILE_TYPE * 0.3);
2158
+ }
2159
+ if (type === "dart" || type.endsWith(".dart")) {
2160
+ this.addScore(scores, "standards://frameworks/flutter", weights.FILE_TYPE);
2161
+ this.addScore(scores, "standards://frameworks/flutter-ui-system", weights.FILE_TYPE);
2162
+ this.addScore(scores, "standards://core/dart-base", weights.FILE_TYPE * 0.5);
2163
+ }
2164
+ }
2165
+ /**
2166
+ * 根据导入评分
2167
+ */
2168
+ scoreByImports(imports, scores, weights) {
2169
+ imports.forEach((imp) => {
2170
+ const normalized = imp.toLowerCase();
2171
+ if (normalized === "vue" || normalized.startsWith("vue/")) {
2172
+ this.addScore(scores, "standards://frameworks/vue3-composition", weights.IMPORT_DIRECT);
2173
+ } else if (normalized.includes("vue")) {
2174
+ this.addScore(scores, "standards://frameworks/vue3-composition", weights.IMPORT_RELATED);
2175
+ }
2176
+ if (normalized === "pinia" || normalized.startsWith("pinia/")) {
2177
+ this.addScore(scores, "standards://frameworks/pinia", weights.IMPORT_DIRECT);
2178
+ }
2179
+ if (normalized === "element-plus" || normalized.startsWith("element-plus/")) {
2180
+ this.addScore(scores, "standards://libraries/element-plus", weights.IMPORT_DIRECT);
2181
+ } else if (normalized.includes("element")) {
2182
+ this.addScore(scores, "standards://libraries/element-plus", weights.IMPORT_RELATED);
2183
+ }
2184
+ if (normalized === "vue-i18n" || normalized.includes("i18n")) {
2185
+ this.addScore(scores, "standards://libraries/i18n", weights.IMPORT_DIRECT);
2186
+ }
2187
+ if (normalized === "wx" || normalized.includes("weixin") || normalized.includes("miniprogram")) {
2188
+ this.addScore(scores, "standards://frameworks/wechat-miniprogram", weights.IMPORT_DIRECT);
2189
+ }
2190
+ if (normalized === "axios" || normalized.includes("axios")) {
2191
+ this.addScore(scores, "standards://patterns/api-layer", weights.IMPORT_DIRECT);
2192
+ }
2193
+ if (normalized.includes("component") || normalized.startsWith("./components/")) {
2194
+ this.addScore(scores, "standards://patterns/component-design", weights.IMPORT_RELATED);
2195
+ }
2196
+ if (normalized === "flutter" || normalized.startsWith("flutter/") || normalized.startsWith("package:flutter")) {
2197
+ this.addScore(scores, "standards://frameworks/flutter", weights.IMPORT_DIRECT);
2198
+ this.addScore(scores, "standards://frameworks/flutter-ui-system", weights.IMPORT_DIRECT);
2199
+ }
2200
+ if (normalized === "get" || normalized.startsWith("get/") || normalized.startsWith("package:get")) {
2201
+ this.addScore(scores, "standards://frameworks/flutter", weights.IMPORT_DIRECT);
2202
+ }
2203
+ });
2204
+ }
2205
+ /**
2206
+ * 根据场景评分
2207
+ */
2208
+ scoreByScenario(scenario, scores, weights) {
2209
+ const normalized = scenario.toLowerCase();
2210
+ if (normalized.includes("api") || normalized.includes("request") || normalized.includes("fetch") || normalized.includes("axios")) {
2211
+ this.addScore(scores, "standards://patterns/api-layer", weights.SCENARIO);
2212
+ }
2213
+ if (normalized.includes("component") || normalized.includes("\u7EC4\u4EF6") || normalized.includes("widget") || normalized.includes("\u5C01\u88C5")) {
2214
+ this.addScore(scores, "standards://patterns/component-design", weights.SCENARIO);
2215
+ }
2216
+ if (normalized.includes("form") || normalized.includes("\u8868\u5355") || normalized.includes("input") || normalized.includes("validation")) {
2217
+ this.addScore(scores, "standards://libraries/element-plus", weights.SCENARIO);
2218
+ this.addScore(scores, "standards://patterns/component-design", weights.SCENARIO * 0.5);
2219
+ }
2220
+ if (normalized.includes("store") || normalized.includes("state") || normalized.includes("\u72B6\u6001") || normalized.includes("pinia")) {
2221
+ this.addScore(scores, "standards://frameworks/pinia", weights.SCENARIO);
2222
+ }
2223
+ if (normalized.includes("i18n") || normalized.includes("translate") || normalized.includes("\u56FD\u9645\u5316") || normalized.includes("\u7FFB\u8BD1") || normalized.includes("locale") || normalized.includes("\u591A\u8BED\u8A00") || normalized.includes("messages.ts") || normalized.includes("$t(")) {
2224
+ this.addScore(scores, "standards://libraries/i18n", weights.SCENARIO);
2225
+ }
2226
+ if (normalized.includes("css") || normalized.includes("\u6837\u5F0F") || normalized.includes("style") || normalized.includes("scoped") || normalized.includes("\u5D4C\u5957") || normalized.includes("nesting") || normalized.includes("\u5185\u8054") || normalized.includes("inline") || normalized.includes("\u5DE5\u5177\u7C7B") || normalized.includes("utilities") || normalized.includes(".ml_") || normalized.includes(".mr_") || normalized.includes(".mt_") || normalized.includes(".mb_") || normalized.includes(".w_") || normalized.includes(":deep(")) {
2227
+ this.addScore(scores, "standards://patterns/vue-css-nesting", weights.SCENARIO);
2228
+ }
2229
+ if (normalized.includes("\u5C0F\u7A0B\u5E8F") || normalized.includes("miniprogram") || normalized.includes("wechat") || normalized.includes("\u5FAE\u4FE1") || normalized.includes("wx.") || normalized.includes("page(") || normalized.includes("component(") || normalized.includes("\u4E91\u5F00\u53D1") || normalized.includes("\u4E91\u51FD\u6570") || normalized.includes("\u4E91\u6570\u636E\u5E93") || normalized.includes("\u4E91\u5B58\u50A8")) {
2230
+ this.addScore(scores, "standards://frameworks/wechat-miniprogram", weights.SCENARIO);
2231
+ }
2232
+ if (normalized.includes("flutter") || normalized.includes("dart") || normalized.includes("widget") || normalized.includes("ui\u7CFB\u7EDF") || normalized.includes("ui \u7CFB\u7EDF") || normalized.includes("flutter ui") || normalized.includes("design token") || normalized.includes("token") || normalized.includes("\u4E3B\u9898") || normalized.includes("theme")) {
2233
+ this.addScore(scores, "standards://frameworks/flutter", weights.SCENARIO);
2234
+ this.addScore(scores, "standards://frameworks/flutter-ui-system", weights.SCENARIO);
2235
+ }
2236
+ if (normalized.includes("flexbutton") || normalized.includes("flexcard") || normalized.includes("flexinput") || normalized.includes("flex\u7EC4\u4EF6") || normalized.includes("$c") || normalized.includes("$s") || normalized.includes("$t") || normalized.includes("$r")) {
2237
+ this.addScore(scores, "standards://frameworks/flutter-ui-system", weights.SCENARIO * 1.5);
2238
+ }
2239
+ }
2240
+ /**
2241
+ * 根据文件内容关键词评分
2242
+ */
2243
+ scoreByContent(content, scores, weights) {
2244
+ const normalized = content.toLowerCase();
2245
+ if (normalized.includes("defineprops") || normalized.includes("defineemits") || normalized.includes("ref(") || normalized.includes("computed(") || normalized.includes("watch(") || normalized.includes("onmounted")) {
2246
+ this.addScore(scores, "standards://frameworks/vue3-composition", weights.CONTENT);
2247
+ }
2248
+ if (normalized.includes("definestore") || normalized.includes("usestore") || normalized.includes("$patch") || normalized.includes("$subscribe")) {
2249
+ this.addScore(scores, "standards://frameworks/pinia", weights.CONTENT);
2250
+ }
2251
+ if (normalized.includes("el-form") || normalized.includes("el-table") || normalized.includes("el-dialog") || normalized.includes("elmessage")) {
2252
+ this.addScore(scores, "standards://libraries/element-plus", weights.CONTENT);
2253
+ }
2254
+ if (normalized.includes("$t(") || normalized.includes("t('") || normalized.includes("usei18n") || normalized.includes("locale") || normalized.includes("messages.ts") || normalized.includes("localestore") || normalized.includes("setlocale") || normalized.includes("togglelocale")) {
2255
+ this.addScore(scores, "standards://libraries/i18n", weights.CONTENT);
2256
+ }
2257
+ if (normalized.includes("<style scoped>") || normalized.includes("&:hover") || normalized.includes("&.active") || normalized.includes("&::before") || normalized.includes(":deep(") || normalized.includes(":global(") || normalized.includes('style="') || normalized.includes('class="ml_') || normalized.includes('class="mr_') || normalized.includes('class="mt_') || normalized.includes('class="w_')) {
2258
+ this.addScore(scores, "standards://patterns/vue-css-nesting", weights.CONTENT);
2259
+ }
2260
+ if (normalized.includes("wx.") || normalized.includes("page({") || normalized.includes("component({") || normalized.includes("setdata") || normalized.includes("onload") || normalized.includes("onshow") || normalized.includes("wx:for") || normalized.includes("wx:if") || normalized.includes("wx.cloud") || normalized.includes("cloudfunctions") || normalized.includes("callfunction") || normalized.includes("wx-server-sdk") || normalized.includes("cloud.init") || normalized.includes("exports.main")) {
2261
+ this.addScore(scores, "standards://frameworks/wechat-miniprogram", weights.CONTENT);
2262
+ }
2263
+ if (normalized.includes("axios.") || normalized.includes(".get(") || normalized.includes(".post(") || normalized.includes("interceptor")) {
2264
+ this.addScore(scores, "standards://patterns/api-layer", weights.CONTENT);
2265
+ }
2266
+ if (normalized.includes("statelesswidget") || normalized.includes("statefulwidget") || normalized.includes("buildcontext") || normalized.includes("@override") || normalized.includes("widget build(") || normalized.includes("getx") || normalized.includes("get.find") || normalized.includes("obx(")) {
2267
+ this.addScore(scores, "standards://frameworks/flutter", weights.CONTENT);
2268
+ }
2269
+ if (normalized.includes("$c.") || normalized.includes("$s.") || normalized.includes("$t.") || normalized.includes("$r.") || normalized.includes("$shadow.") || normalized.includes("$b.") || normalized.includes("flexbutton") || normalized.includes("flexcard") || normalized.includes("flexinput") || normalized.includes("flexbox") || normalized.includes("tokenmanager") || normalized.includes("designtokens") || normalized.includes("thememanager") || normalized.includes("gap(")) {
2270
+ this.addScore(scores, "standards://frameworks/flutter-ui-system", weights.CONTENT * 2);
2271
+ }
2272
+ }
2273
+ /**
2274
+ * 添加分数(累加)
2275
+ */
2276
+ addScore(scores, uri, points) {
2277
+ const current = scores.get(uri) || 0;
2278
+ scores.set(uri, current + points);
2279
+ }
2280
+ /**
2281
+ * 组合多个规范内容(Phase 3: 优化去重与顺序)
2282
+ */
2283
+ combineStandards(uris) {
2284
+ const startTime = Date.now();
2285
+ const uniqueUris = Array.from(new Set(uris));
2286
+ const coreUris = uniqueUris.filter((uri) => uri.startsWith("standards://core/"));
2287
+ const otherUris = uniqueUris.filter((uri) => !uri.startsWith("standards://core/"));
2288
+ const sortedUris = [...coreUris, ...otherUris];
2289
+ const contents = [];
2290
+ let totalSize = 0;
2291
+ sortedUris.forEach((uri) => {
2292
+ try {
2293
+ const content = this.readStandard(uri);
2294
+ const standardName = this.extractStandardName(uri);
2295
+ const section = `
2296
+ ## \u{1F4DA} ${standardName}
2297
+
2298
+ ${content}
2299
+ `;
2300
+ contents.push(section);
2301
+ totalSize += section.length;
2302
+ } catch (error) {
2303
+ console.error(`Failed to read standard ${uri}:`, error);
2304
+ }
2305
+ });
2306
+ const combined = contents.join("\n---\n");
2307
+ const estimatedTokens = Math.ceil(combined.length / 4);
2308
+ const baselineTokens = 1e4;
2309
+ const tokensSaved = baselineTokens - estimatedTokens;
2310
+ this.metrics.totalTokensSaved += Math.max(0, tokensSaved);
2311
+ const processingTime = Date.now() - startTime;
2312
+ console.log(`[StandardsManager] Combined ${sortedUris.length} standards in ${processingTime}ms, ~${estimatedTokens} tokens (saved ${tokensSaved})`);
2313
+ return combined;
2314
+ }
2315
+ /**
2316
+ * 提取规范名称
2317
+ */
2318
+ extractStandardName(uri) {
2319
+ const match = uri.match(/^standards:\/\/([^/]+)\/(.+)$/);
2320
+ if (match) {
2321
+ const [, category, standardId] = match;
2322
+ return this.getStandardName(category, standardId);
2323
+ }
2324
+ return uri;
2325
+ }
2326
+ /**
2327
+ * 获取规范显示名称
2328
+ */
2329
+ getStandardName(category, standardId) {
2330
+ var _a;
2331
+ const nameMap = {
2332
+ core: {
2333
+ "code-style": "\u4EE3\u7801\u98CE\u683C\u89C4\u8303",
2334
+ "typescript-base": "TypeScript \u57FA\u7840",
2335
+ "dart-base": "Dart \u57FA\u7840"
2336
+ },
2337
+ frameworks: {
2338
+ "vue3-composition": "Vue 3 Composition API",
2339
+ "pinia": "Pinia \u72B6\u6001\u7BA1\u7406",
2340
+ "flutter": "Flutter \u5F00\u53D1\u89C4\u8303",
2341
+ "flutter-ui-system": "Flutter UI \u7CFB\u7EDF\u89C4\u8303",
2342
+ "wechat-miniprogram": "\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F\u5F00\u53D1"
2343
+ },
2344
+ libraries: {
2345
+ "element-plus": "Element Plus \u7EC4\u4EF6\u5E93",
2346
+ "i18n": "\u56FD\u9645\u5316 (i18n)"
2347
+ },
2348
+ patterns: {
2349
+ "api-layer": "API \u5C42\u8BBE\u8BA1",
2350
+ "component-design": "\u7EC4\u4EF6\u8BBE\u8BA1\u6A21\u5F0F",
2351
+ "vue-css-nesting": "Vue CSS \u5D4C\u5957\u5199\u6CD5",
2352
+ "vue-api-mock-layer": "Vue API Mock \u5C42"
2353
+ }
2354
+ };
2355
+ return ((_a = nameMap[category]) == null ? void 0 : _a[standardId]) || standardId;
2356
+ }
2357
+ /**
2358
+ * 获取规范描述
2359
+ */
2360
+ getStandardDescription(category, standardId) {
2361
+ var _a;
2362
+ const descMap = {
2363
+ core: {
2364
+ "code-style": "\u547D\u540D\u89C4\u8303\u3001\u4EE3\u7801\u7EC4\u7EC7\u3001\u6CE8\u91CA\u89C4\u8303",
2365
+ "typescript-base": "\u57FA\u7840\u7C7B\u578B\u3001\u51FD\u6570\u3001\u6CDB\u578B\u4F7F\u7528",
2366
+ "dart-base": "\u7A7A\u5B89\u5168\u3001\u5F02\u6B65\u7F16\u7A0B\u3001\u7C7B\u548C\u5BF9\u8C61"
2367
+ },
2368
+ frameworks: {
2369
+ "vue3-composition": "Props\u3001Emits\u3001\u751F\u547D\u5468\u671F\u3001Composables",
2370
+ "pinia": "Store \u5B9A\u4E49\u3001\u72B6\u6001\u7BA1\u7406\u3001\u6301\u4E45\u5316",
2371
+ "flutter": "Widget \u8BBE\u8BA1\u3001\u72B6\u6001\u7BA1\u7406\u3001\u6027\u80FD\u4F18\u5316",
2372
+ "flutter-ui-system": "Design Token\u3001Flex\u7EC4\u4EF6\u3001\u4E3B\u9898\u7CFB\u7EDF\u3001$\u5FEB\u6377\u65B9\u5F0F",
2373
+ "wechat-miniprogram": "Page/Component\u3001\u7F51\u7EDC\u8BF7\u6C42\u3001\u6027\u80FD\u4F18\u5316"
2374
+ },
2375
+ libraries: {
2376
+ "element-plus": "\u8868\u5355\u3001\u8868\u683C\u3001\u5BF9\u8BDD\u6846\u3001\u6D88\u606F\u63D0\u793A",
2377
+ "i18n": "\u7FFB\u8BD1\u6587\u4EF6\u3001\u7EC4\u4EF6\u4F7F\u7528\u3001\u53C2\u6570\u5316"
2378
+ },
2379
+ patterns: {
2380
+ "api-layer": "Axios \u914D\u7F6E\u3001API \u6A21\u5757\u5316\u3001\u9519\u8BEF\u5904\u7406",
2381
+ "component-design": "\u7EC4\u4EF6\u901A\u4FE1\u3001Props \u9A8C\u8BC1\u3001\u6027\u80FD\u4F18\u5316",
2382
+ "vue-css-nesting": "\u539F\u751F\u5D4C\u5957\u8BED\u6CD5\u3001\u4F2A\u7C7B\u4F2A\u5143\u7D20\u3001\u6DF1\u5EA6\u9009\u62E9\u5668",
2383
+ "vue-api-mock-layer": "Axios\u5C01\u88C5\u3001Mock\u6570\u636E\u3001\u6A21\u5757\u5316API"
2384
+ }
2385
+ };
2386
+ return ((_a = descMap[category]) == null ? void 0 : _a[standardId]) || "";
2387
+ }
2388
+ /**
2389
+ * 更新平均响应时间
2390
+ */
2391
+ updateAverageResponseTime(responseTime) {
2392
+ const { totalCalls, averageResponseTime } = this.metrics;
2393
+ this.metrics.totalCalls++;
2394
+ this.metrics.averageResponseTime = (averageResponseTime * totalCalls + responseTime) / this.metrics.totalCalls;
2395
+ }
2396
+ /**
2397
+ * 获取性能指标
2398
+ */
2399
+ getPerformanceMetrics() {
2400
+ return {
2401
+ ...this.metrics,
2402
+ cacheHitRate: this.metrics.totalCalls > 0 ? (this.metrics.cacheHits / this.metrics.totalCalls * 100).toFixed(2) + "%" : "0%"
2403
+ };
2404
+ }
2405
+ /**
2406
+ * 获取使用统计
2407
+ */
2408
+ getUsageStats() {
2409
+ const topCombinations = Array.from(this.stats.standardCombinations.entries()).sort((a, b) => b[1] - a[1]).slice(0, 5).map(([combination, count]) => ({ combination, count }));
2410
+ const topStandards = Array.from(this.stats.individualStandards.entries()).sort((a, b) => b[1] - a[1]).slice(0, 5).map(([standard, count]) => ({ standard, count }));
2411
+ return {
2412
+ topCombinations,
2413
+ topStandards,
2414
+ totalCalls: this.stats.totalCalls
2415
+ };
2416
+ }
2417
+ /**
2418
+ * 清除缓存
2419
+ */
2420
+ clearCache() {
2421
+ this.contentCache.clear();
2422
+ console.log("[StandardsManager] Cache cleared");
2423
+ }
2424
+ /**
2425
+ * 获取缓存统计
2426
+ */
2427
+ getCacheStats() {
2428
+ const entries = Array.from(this.contentCache.entries()).map(([uri, entry]) => ({
2429
+ uri,
2430
+ accessCount: entry.accessCount,
2431
+ age: Math.floor((Date.now() - entry.timestamp) / 1e3)
2432
+ // 秒
2433
+ })).sort((a, b) => b.accessCount - a.accessCount);
2434
+ return {
2435
+ size: this.contentCache.size,
2436
+ maxSize: this.MAX_CACHE_SIZE,
2437
+ entries
2438
+ };
2439
+ }
2440
+ };
2441
+
2442
+ // src/core/autoInitializer.ts
2443
+ import * as fs7 from "fs";
2444
+ import * as path8 from "path";
2445
+ var AutoInitializer = class {
2446
+ constructor(logger3) {
2447
+ this.logger = logger3;
2448
+ this.initialized = /* @__PURE__ */ new Map();
2449
+ }
2450
+ /**
2451
+ * 检查并初始化项目配置
2452
+ * @param workspacePath 工作区路径
2453
+ * @returns 是否需要初始化(返回 true 表示已执行初始化)
2454
+ */
2455
+ async ensureProjectConfig(workspacePath) {
2456
+ var _a, _b, _c, _d;
2457
+ const projectPath = workspacePath || this.detectWorkspacePath();
2458
+ if (!projectPath) {
2459
+ return {
2460
+ needsInit: false,
2461
+ initialized: false,
2462
+ message: "\u672A\u68C0\u6D4B\u5230\u5DE5\u4F5C\u533A\u8DEF\u5F84"
2463
+ };
2464
+ }
2465
+ if (this.initialized.get(projectPath)) {
2466
+ return {
2467
+ needsInit: false,
2468
+ initialized: true,
2469
+ message: `\u9879\u76EE\u5DF2\u914D\u7F6E: ${path8.basename(projectPath)}`
2470
+ };
2471
+ }
2472
+ const configPath = path8.join(projectPath, ".github", "copilot-instructions.md");
2473
+ const hasConfig = fs7.existsSync(configPath);
2474
+ if (hasConfig) {
2475
+ this.initialized.set(projectPath, true);
2476
+ return {
2477
+ needsInit: false,
2478
+ initialized: true,
2479
+ message: `\u9879\u76EE\u5DF2\u6709\u914D\u7F6E: ${path8.basename(projectPath)}`
2480
+ };
2481
+ }
2482
+ this.log(`\u{1F50D} \u68C0\u6D4B\u5230\u9879\u76EE\u672A\u914D\u7F6E\uFF0C\u5F00\u59CB\u81EA\u52A8\u5206\u6790\u548C\u751F\u6210\u914D\u7F6E...`);
2483
+ this.log(`\u{1F4C1} \u9879\u76EE\u8DEF\u5F84: ${projectPath}`);
2484
+ try {
2485
+ this.log("1\uFE0F\u20E3 \u5206\u6790\u9879\u76EE\u6280\u672F\u6808...");
2486
+ const analysisResult = await analyzeProject({ projectPath });
2487
+ if ((_b = (_a = analysisResult.content) == null ? void 0 : _a[0]) == null ? void 0 : _b.text) {
2488
+ const analysis = JSON.parse(analysisResult.content[0].text);
2489
+ this.log(`\u2705 \u68C0\u6D4B\u5230: ${((_c = analysis.frameworks) == null ? void 0 : _c.join(", ")) || "\u672A\u77E5\u6280\u672F\u6808"}`);
2490
+ this.log("2\uFE0F\u20E3 \u751F\u6210\u9879\u76EE\u914D\u7F6E\u6587\u4EF6...");
2491
+ await generateConfig({
2492
+ projectPath,
2493
+ autoMatch: true
2494
+ });
2495
+ this.initialized.set(projectPath, true);
2496
+ return {
2497
+ needsInit: true,
2498
+ initialized: true,
2499
+ message: `\u2705 \u9879\u76EE\u914D\u7F6E\u5DF2\u81EA\u52A8\u751F\u6210
2500
+ \u{1F4C1} \u8DEF\u5F84: ${configPath}
2501
+ \u{1F3AF} \u6280\u672F\u6808: ${(_d = analysis.frameworks) == null ? void 0 : _d.join(", ")}`
2502
+ };
2503
+ }
2504
+ } catch (error) {
2505
+ this.log(`\u274C \u81EA\u52A8\u521D\u59CB\u5316\u5931\u8D25: ${error}`);
2506
+ return {
2507
+ needsInit: true,
2508
+ initialized: false,
2509
+ message: `\u26A0\uFE0F \u81EA\u52A8\u521D\u59CB\u5316\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`
2510
+ };
2511
+ }
2512
+ return {
2513
+ needsInit: true,
2514
+ initialized: false,
2515
+ message: "\u26A0\uFE0F \u65E0\u6CD5\u5B8C\u6210\u81EA\u52A8\u521D\u59CB\u5316"
2516
+ };
2517
+ }
2518
+ /**
2519
+ * 检测工作区路径
2520
+ */
2521
+ detectWorkspacePath() {
2522
+ if (process.env.WORKSPACE_PATH) {
2523
+ return process.env.WORKSPACE_PATH;
2524
+ }
2525
+ const cwd = process.cwd();
2526
+ if (this.isValidProject(cwd)) {
2527
+ return cwd;
2528
+ }
2529
+ const possiblePaths = [
2530
+ path8.join(cwd, ".."),
2531
+ path8.join(cwd, "../..")
2532
+ ];
2533
+ for (const possiblePath of possiblePaths) {
2534
+ if (this.isValidProject(possiblePath)) {
2535
+ return possiblePath;
2536
+ }
2537
+ }
2538
+ return null;
2539
+ }
2540
+ /**
2541
+ * 判断是否是有效的项目目录
2542
+ */
2543
+ isValidProject(dirPath) {
2544
+ if (!fs7.existsSync(dirPath)) {
2545
+ return false;
2546
+ }
2547
+ const markers = [
2548
+ "package.json",
2549
+ "pubspec.yaml",
2550
+ "pom.xml",
2551
+ "go.mod",
2552
+ "Cargo.toml",
2553
+ ".git"
2554
+ ];
2555
+ return markers.some(
2556
+ (marker) => fs7.existsSync(path8.join(dirPath, marker))
2557
+ );
2558
+ }
2559
+ /**
2560
+ * 重置初始化状态(用于测试)
2561
+ */
2562
+ reset() {
2563
+ this.initialized.clear();
2564
+ }
2565
+ log(message) {
2566
+ if (this.logger) {
2567
+ this.logger.log(message);
2568
+ } else {
2569
+ console.error(`[AutoInit] ${message}`);
2570
+ }
2571
+ }
2572
+ };
2573
+
2574
+ // src/tools/getSmartStandards.ts
2575
+ async function getSmartStandards(args) {
2576
+ var _a;
2577
+ const logger3 = new ConsoleLogger();
2578
+ const manager = new StandardsManager();
2579
+ const autoInit = new AutoInitializer(logger3);
2580
+ try {
2581
+ const initResult = await autoInit.ensureProjectConfig();
2582
+ if (initResult.needsInit) {
2583
+ logger3.log("\u{1F4CB} " + initResult.message);
2584
+ if (initResult.initialized) {
2585
+ return {
2586
+ content: [{
2587
+ type: "text",
2588
+ text: `\u{1F389} **\u9996\u6B21\u4F7F\u7528\u81EA\u52A8\u914D\u7F6E\u5B8C\u6210**
2589
+
2590
+ ${initResult.message}
2591
+
2592
+ \u73B0\u5728\u53EF\u4EE5\u7EE7\u7EED\u4F7F\u7528 @mta \u8FDB\u884C\u5F00\u53D1\u4E86\uFF01
2593
+
2594
+ \u{1F4A1} \u63D0\u793A\uFF1A\u9879\u76EE\u914D\u7F6E\u6587\u4EF6\u5DF2\u751F\u6210\u5728 .github/copilot-instructions.md`
2595
+ }]
2596
+ };
2597
+ }
2598
+ }
2599
+ let detectedFileType = "unknown";
2600
+ let detectedImports = [];
2601
+ let detectedScenario = "";
2602
+ let analysisSource = "none";
2603
+ if (args.currentFile && fs8.existsSync(args.currentFile)) {
2604
+ analysisSource = "file-path";
2605
+ const ext = ((_a = args.currentFile.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
2606
+ const extMap = {
2607
+ "vue": "vue",
2608
+ "ts": "ts",
2609
+ "tsx": "tsx",
2610
+ "js": "js",
2611
+ "jsx": "jsx"
2612
+ };
2613
+ detectedFileType = extMap[ext] || "unknown";
2614
+ try {
2615
+ const content = fs8.readFileSync(args.currentFile, "utf-8");
2616
+ const imports = extractImports(content);
2617
+ detectedImports = imports;
2618
+ detectedScenario = inferScenario(content, detectedFileType);
2619
+ } catch {
2620
+ logger3.log("\u65E0\u6CD5\u8BFB\u53D6\u6587\u4EF6\u5185\u5BB9\uFF0C\u4EC5\u4F7F\u7528\u6587\u4EF6\u7C7B\u578B");
2621
+ }
2622
+ }
2623
+ if (args.fileContent) {
2624
+ analysisSource = "file-content";
2625
+ const imports = extractImports(args.fileContent);
2626
+ detectedImports = [...detectedImports, ...imports];
2627
+ if (detectedFileType === "unknown") {
2628
+ if (args.fileContent.includes("<template>")) {
2629
+ detectedFileType = "vue";
2630
+ } else if (args.fileContent.includes("interface ") || args.fileContent.includes("type ")) {
2631
+ detectedFileType = "ts";
2632
+ }
2633
+ }
2634
+ const scenario = inferScenario(args.fileContent, detectedFileType);
2635
+ if (scenario) detectedScenario = scenario;
2636
+ }
2637
+ if (detectedFileType === "unknown") {
2638
+ analysisSource = "environment";
2639
+ const cwd = process.cwd();
2640
+ const packageJsonPath = `${cwd}/package.json`;
2641
+ if (fs8.existsSync(packageJsonPath)) {
2642
+ try {
2643
+ const pkg = JSON.parse(fs8.readFileSync(packageJsonPath, "utf-8"));
2644
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
2645
+ if (deps["vue"]) {
2646
+ detectedFileType = "vue";
2647
+ detectedImports.push("vue");
2648
+ }
2649
+ if (deps["react"]) {
2650
+ detectedFileType = "tsx";
2651
+ detectedImports.push("react");
2652
+ }
2653
+ if (deps["element-plus"]) detectedImports.push("element-plus");
2654
+ if (deps["pinia"]) detectedImports.push("pinia");
2655
+ if (deps["vue-i18n"]) detectedImports.push("vue-i18n");
2656
+ } catch {
2657
+ logger3.log("\u65E0\u6CD5\u89E3\u6790 package.json");
2658
+ }
2659
+ }
2660
+ }
2661
+ detectedImports = [...new Set(detectedImports)];
2662
+ logger3.log(`\u{1F50D} \u667A\u80FD\u68C0\u6D4B\u7ED3\u679C: fileType=${detectedFileType}, imports=${detectedImports.join(",")}, scenario=${detectedScenario}`);
2663
+ const standards = manager.getRelevantStandards({
2664
+ fileType: detectedFileType !== "unknown" ? detectedFileType : void 0,
2665
+ imports: detectedImports.length > 0 ? detectedImports : void 0,
2666
+ scenario: detectedScenario || void 0
2667
+ });
2668
+ const combinedContent = manager.combineStandards(standards);
2669
+ return {
2670
+ content: [{
2671
+ type: "text",
2672
+ text: JSON.stringify({
2673
+ success: true,
2674
+ analysis: {
2675
+ source: analysisSource,
2676
+ fileType: detectedFileType,
2677
+ imports: detectedImports,
2678
+ scenario: detectedScenario
2679
+ },
2680
+ standards,
2681
+ content: combinedContent,
2682
+ stats: {
2683
+ standardsCount: standards.length,
2684
+ contentLength: combinedContent.length,
2685
+ estimatedTokens: Math.ceil(combinedContent.length / 4)
2686
+ }
2687
+ }, null, 2)
2688
+ }]
2689
+ };
2690
+ } catch (error) {
2691
+ logger3.error(`\u667A\u80FD\u89C4\u8303\u63A8\u8350\u5931\u8D25: ${error}`);
2692
+ return {
2693
+ content: [{
2694
+ type: "text",
2695
+ text: JSON.stringify({
2696
+ error: error instanceof Error ? error.message : String(error)
2697
+ }, null, 2)
2698
+ }]
2699
+ };
2700
+ }
2701
+ }
2702
+ function extractImports(content) {
2703
+ const imports = [];
2704
+ const es6Regex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
2705
+ let match;
2706
+ while ((match = es6Regex.exec(content)) !== null) {
2707
+ const pkg = match[1];
2708
+ if (!pkg.startsWith(".") && !pkg.startsWith("/")) {
2709
+ imports.push(pkg.split("/")[0]);
2710
+ }
2711
+ }
2712
+ const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
2713
+ while ((match = requireRegex.exec(content)) !== null) {
2714
+ const pkg = match[1];
2715
+ if (!pkg.startsWith(".") && !pkg.startsWith("/")) {
2716
+ imports.push(pkg.split("/")[0]);
2717
+ }
2718
+ }
2719
+ return [...new Set(imports)];
2720
+ }
2721
+ function inferScenario(content, fileType) {
2722
+ const scenarios = [];
2723
+ if (fileType === "vue") {
2724
+ if (content.includes("ElForm") || content.includes("<el-form")) {
2725
+ scenarios.push("\u8868\u5355\u7EC4\u4EF6");
2726
+ }
2727
+ if (content.includes("ElTable") || content.includes("<el-table")) {
2728
+ scenarios.push("\u8868\u683C\u7EC4\u4EF6");
2729
+ }
2730
+ if (content.includes("defineStore")) {
2731
+ scenarios.push("\u72B6\u6001\u7BA1\u7406");
2732
+ }
2733
+ if (content.includes("useI18n") || content.includes("$t(")) {
2734
+ scenarios.push("\u56FD\u9645\u5316");
2735
+ }
2736
+ }
2737
+ if (content.includes("fetch(") || content.includes("axios.")) {
2738
+ scenarios.push("API \u8C03\u7528");
2739
+ }
2740
+ if (content.includes("interface ") || content.includes("type ")) {
2741
+ scenarios.push("\u7C7B\u578B\u5B9A\u4E49");
2742
+ }
2743
+ return scenarios.join("\u3001");
2744
+ }
2745
+
2746
+ // src/tools/usePreset.ts
2747
+ var PRESETS = {
2748
+ "vue3-component": {
2749
+ name: "Vue 3 \u7EC4\u4EF6\u5F00\u53D1",
2750
+ fileType: "vue",
2751
+ imports: ["vue", "element-plus"],
2752
+ scenario: "\u7EC4\u4EF6\u5F00\u53D1",
2753
+ description: "\u5F00\u53D1 Vue 3 \u5355\u6587\u4EF6\u7EC4\u4EF6\uFF0C\u5305\u542B Composition API \u548C Element Plus"
2754
+ },
2755
+ "vue3-form": {
2756
+ name: "Vue 3 \u8868\u5355\u5F00\u53D1",
2757
+ fileType: "vue",
2758
+ imports: ["vue", "element-plus"],
2759
+ scenario: "\u8868\u5355\u7EC4\u4EF6",
2760
+ description: "Element Plus \u8868\u5355\u7EC4\u4EF6\u5F00\u53D1\uFF0C\u5305\u542B\u9A8C\u8BC1\u548C\u56FD\u9645\u5316"
2761
+ },
2762
+ "vue3-table": {
2763
+ name: "Vue 3 \u8868\u683C\u5F00\u53D1",
2764
+ fileType: "vue",
2765
+ imports: ["vue", "element-plus"],
2766
+ scenario: "\u8868\u683C\u7EC4\u4EF6",
2767
+ description: "Element Plus \u8868\u683C\u7EC4\u4EF6\u5F00\u53D1\uFF0C\u5305\u542B\u5206\u9875\u548C\u64CD\u4F5C"
2768
+ },
2769
+ "pinia-store": {
2770
+ name: "Pinia \u72B6\u6001\u7BA1\u7406",
2771
+ fileType: "ts",
2772
+ imports: ["vue", "pinia"],
2773
+ scenario: "\u72B6\u6001\u7BA1\u7406",
2774
+ description: "Pinia store \u5B9A\u4E49\uFF0C\u5305\u542B actions\u3001getters \u548C\u6301\u4E45\u5316"
2775
+ },
2776
+ "api-call": {
2777
+ name: "API \u8C03\u7528\u5C42",
2778
+ fileType: "ts",
2779
+ imports: ["axios"],
2780
+ scenario: "API \u8C03\u7528",
2781
+ description: "RESTful API \u8C03\u7528\u5C01\u88C5\uFF0C\u5305\u542B\u9519\u8BEF\u5904\u7406\u548C\u7C7B\u578B\u5B9A\u4E49"
2782
+ },
2783
+ "typescript-strict": {
2784
+ name: "TypeScript \u4E25\u683C\u6A21\u5F0F",
2785
+ fileType: "ts",
2786
+ imports: [],
2787
+ scenario: "\u7C7B\u578B\u5B9A\u4E49",
2788
+ description: "TypeScript \u4E25\u683C\u7C7B\u578B\u5B9A\u4E49\u548C\u7C7B\u578B\u5B88\u536B"
2789
+ },
2790
+ "i18n": {
2791
+ name: "\u56FD\u9645\u5316\u5F00\u53D1",
2792
+ fileType: "vue",
2793
+ imports: ["vue", "vue-i18n"],
2794
+ scenario: "\u56FD\u9645\u5316",
2795
+ description: "Vue I18n \u591A\u8BED\u8A00\u652F\u6301\uFF0C\u5305\u542B\u7FFB\u8BD1\u6587\u4EF6\u7BA1\u7406"
2796
+ },
2797
+ "composable": {
2798
+ name: "Vue 3 Composable",
2799
+ fileType: "ts",
2800
+ imports: ["vue"],
2801
+ scenario: "\u53EF\u7EC4\u5408\u51FD\u6570",
2802
+ description: "Vue 3 \u7EC4\u5408\u5F0F\u51FD\u6570\u5F00\u53D1\uFF0C\u590D\u7528\u903B\u8F91"
2803
+ }
2804
+ };
2805
+ async function usePreset(args) {
2806
+ const logger3 = new ConsoleLogger();
2807
+ const manager = new StandardsManager();
2808
+ try {
2809
+ if (!(args.preset in PRESETS)) {
2810
+ return {
2811
+ content: [{
2812
+ type: "text",
2813
+ text: JSON.stringify({
2814
+ error: `\u672A\u77E5\u7684\u9884\u8BBE: ${args.preset}`,
2815
+ availablePresets: Object.keys(PRESETS).map((id) => ({
2816
+ id,
2817
+ name: PRESETS[id].name,
2818
+ description: PRESETS[id].description
2819
+ }))
2820
+ }, null, 2)
2821
+ }]
2822
+ };
2823
+ }
2824
+ const preset = PRESETS[args.preset];
2825
+ logger3.log(`\u{1F3AF} \u4F7F\u7528\u9884\u8BBE: ${preset.name}`);
2826
+ const imports = args.customImports ? [...preset.imports, ...args.customImports] : [...preset.imports];
2827
+ const standards = manager.getRelevantStandards({
2828
+ fileType: preset.fileType,
2829
+ imports: imports.length > 0 ? imports : void 0,
2830
+ scenario: preset.scenario
2831
+ });
2832
+ const combinedContent = manager.combineStandards(standards);
2833
+ return {
2834
+ content: [{
2835
+ type: "text",
2836
+ text: JSON.stringify({
2837
+ success: true,
2838
+ preset: {
2839
+ id: args.preset,
2840
+ name: preset.name,
2841
+ description: preset.description
2842
+ },
2843
+ applied: {
2844
+ fileType: preset.fileType,
2845
+ imports,
2846
+ scenario: preset.scenario
2847
+ },
2848
+ standards,
2849
+ content: combinedContent,
2850
+ stats: {
2851
+ standardsCount: standards.length,
2852
+ contentLength: combinedContent.length,
2853
+ estimatedTokens: Math.ceil(combinedContent.length / 4)
2854
+ }
2855
+ }, null, 2)
2856
+ }]
2857
+ };
2858
+ } catch (error) {
2859
+ logger3.error(`\u4F7F\u7528\u9884\u8BBE\u5931\u8D25: ${error}`);
2860
+ return {
2861
+ content: [{
2862
+ type: "text",
2863
+ text: JSON.stringify({
2864
+ error: error instanceof Error ? error.message : String(error)
2865
+ }, null, 2)
2866
+ }]
2867
+ };
2868
+ }
2869
+ }
2870
+ async function listPresets() {
2871
+ const presetList = Object.entries(PRESETS).map(([id, preset]) => ({
2872
+ id,
2873
+ name: preset.name,
2874
+ description: preset.description,
2875
+ fileType: preset.fileType,
2876
+ imports: preset.imports,
2877
+ scenario: preset.scenario
2878
+ }));
2879
+ return {
2880
+ content: [{
2881
+ type: "text",
2882
+ text: JSON.stringify({
2883
+ success: true,
2884
+ total: presetList.length,
2885
+ presets: presetList,
2886
+ usage: "\u4F7F\u7528\u65B9\u5F0F: \u8C03\u7528 use_preset \u5DE5\u5177\u5E76\u6307\u5B9A preset \u53C2\u6570"
2887
+ }, null, 2)
2888
+ }]
2889
+ };
2890
+ }
2891
+
2892
+ // src/tools/healthCheck.ts
2893
+ import * as fs9 from "fs";
2894
+ import * as path9 from "path";
2895
+ import { fileURLToPath as fileURLToPath4 } from "url";
2896
+ var __filename4 = fileURLToPath4(import.meta.url);
2897
+ var __dirname4 = path9.dirname(__filename4);
2898
+ async function healthCheck(args) {
2899
+ var _a, _b, _c, _d, _e, _f, _g;
2900
+ const logger3 = new ConsoleLogger();
2901
+ const verbose = (_a = args.verbose) != null ? _a : false;
2902
+ try {
2903
+ const checks = {
2904
+ server: { status: "unknown", details: [] },
2905
+ configuration: { status: "unknown", details: [] },
2906
+ dependencies: { status: "unknown", details: [] },
2907
+ standards: { status: "unknown", details: [] },
2908
+ workspace: { status: "unknown", details: [] }
2909
+ };
2910
+ logger3.log("\u{1F50D} \u68C0\u67E5\u670D\u52A1\u5668\u72B6\u6001...");
2911
+ try {
2912
+ checks.server.status = "healthy";
2913
+ checks.server.details.push("\u2705 MCP \u670D\u52A1\u5668\u6B63\u5728\u8FD0\u884C");
2914
+ checks.server.details.push(`\u{1F4CD} \u8FDB\u7A0B PID: ${process.pid}`);
2915
+ checks.server.details.push(`\u{1F550} \u8FD0\u884C\u65F6\u95F4: ${Math.floor(process.uptime())}\u79D2`);
2916
+ } catch {
2917
+ checks.server.status = "error";
2918
+ checks.server.details.push("\u274C \u670D\u52A1\u5668\u672A\u54CD\u5E94");
2919
+ }
2920
+ logger3.log("\u{1F50D} \u68C0\u67E5\u914D\u7F6E\u6587\u4EF6...");
2921
+ const workspacePath = args.workspacePath || process.cwd();
2922
+ const vscodeDir = path9.join(workspacePath, ".vscode");
2923
+ if (fs9.existsSync(vscodeDir)) {
2924
+ checks.workspace.status = "healthy";
2925
+ checks.workspace.details.push(`\u2705 \u5DE5\u4F5C\u533A\u8DEF\u5F84: ${workspacePath}`);
2926
+ const mcpJsonPath = path9.join(vscodeDir, "mcp.json");
2927
+ if (fs9.existsSync(mcpJsonPath)) {
2928
+ try {
2929
+ const config = JSON.parse(fs9.readFileSync(mcpJsonPath, "utf-8"));
2930
+ const hasNewFormat = (_b = config.servers) == null ? void 0 : _b["copilot-prompts"];
2931
+ const hasOldFormat = (_c = config.mcpServers) == null ? void 0 : _c["copilot-prompts"];
2932
+ if (hasNewFormat) {
2933
+ checks.configuration.status = "healthy";
2934
+ checks.configuration.details.push("\u2705 mcp.json \u914D\u7F6E\u6B63\u786E (\u4F7F\u7528\u65B0\u683C\u5F0F)");
2935
+ const serverConfig = config.servers["copilot-prompts"];
2936
+ if (verbose) {
2937
+ checks.configuration.details.push(` Command: ${serverConfig.command}`);
2938
+ checks.configuration.details.push(` Args: ${(_d = serverConfig.args) == null ? void 0 : _d.join(" ")}`);
2939
+ checks.configuration.details.push(` AutoStart: ${(_e = serverConfig.autoStart) != null ? _e : "undefined"}`);
2940
+ checks.configuration.details.push(` Env: ${JSON.stringify((_f = serverConfig.env) != null ? _f : {})}`);
2941
+ }
2942
+ if (!serverConfig.env) {
2943
+ checks.configuration.details.push('\u{1F4A1} \u5EFA\u8BAE: \u6DFB\u52A0 "env": {} \u5B57\u6BB5');
2944
+ }
2945
+ if (!serverConfig.autoStart) {
2946
+ checks.configuration.details.push('\u{1F4A1} \u5EFA\u8BAE: \u6DFB\u52A0 "autoStart": true \u5B57\u6BB5');
2947
+ }
2948
+ } else if (hasOldFormat) {
2949
+ checks.configuration.status = "warning";
2950
+ checks.configuration.details.push("\u26A0\uFE0F mcp.json \u4F7F\u7528\u65E7\u683C\u5F0F (mcpServers)");
2951
+ checks.configuration.details.push("\u{1F4A1} \u5EFA\u8BAE: \u8FD0\u884C auto_setup \u5DE5\u5177\u5347\u7EA7\u5230\u65B0\u683C\u5F0F (servers)");
2952
+ if (verbose) {
2953
+ const serverConfig = config.mcpServers["copilot-prompts"];
2954
+ checks.configuration.details.push(` Command: ${serverConfig.command}`);
2955
+ checks.configuration.details.push(` Args: ${(_g = serverConfig.args) == null ? void 0 : _g.join(" ")}`);
2956
+ }
2957
+ } else {
2958
+ checks.configuration.status = "warning";
2959
+ checks.configuration.details.push("\u26A0\uFE0F mcp.json \u7F3A\u5C11 copilot-prompts \u914D\u7F6E");
2960
+ checks.configuration.details.push("\u{1F4A1} \u5EFA\u8BAE: \u8FD0\u884C auto_setup \u5DE5\u5177\u6DFB\u52A0\u914D\u7F6E");
2961
+ }
2962
+ } catch (error) {
2963
+ checks.configuration.status = "error";
2964
+ checks.configuration.details.push(`\u274C mcp.json \u683C\u5F0F\u9519\u8BEF: ${error}`);
2965
+ checks.configuration.details.push("\u{1F4A1} \u4FEE\u590D: \u8FD0\u884C auto_setup \u5DE5\u5177\u91CD\u65B0\u751F\u6210\u914D\u7F6E");
2966
+ }
2967
+ } else {
2968
+ checks.configuration.status = "warning";
2969
+ checks.configuration.details.push("\u26A0\uFE0F mcp.json \u4E0D\u5B58\u5728");
2970
+ checks.configuration.details.push("\u{1F4A1} \u5EFA\u8BAE: \u8FD0\u884C auto_setup \u5DE5\u5177\u81EA\u52A8\u914D\u7F6E");
2971
+ }
2972
+ const settingsPath = path9.join(vscodeDir, "settings.json");
2973
+ if (fs9.existsSync(settingsPath)) {
2974
+ try {
2975
+ const settings = JSON.parse(fs9.readFileSync(settingsPath, "utf-8"));
2976
+ if (settings["github.copilot.chat.mcp.enabled"] === true) {
2977
+ checks.configuration.details.push("\u2705 VS Code MCP \u5DF2\u542F\u7528");
2978
+ } else {
2979
+ checks.configuration.details.push("\u26A0\uFE0F VS Code MCP \u672A\u542F\u7528");
2980
+ }
2981
+ } catch {
2982
+ checks.configuration.details.push("\u26A0\uFE0F settings.json \u683C\u5F0F\u9519\u8BEF");
2983
+ }
2984
+ }
2985
+ } else {
2986
+ checks.workspace.status = "error";
2987
+ checks.workspace.details.push("\u274C .vscode \u76EE\u5F55\u4E0D\u5B58\u5728");
2988
+ }
2989
+ logger3.log("\u{1F50D} \u68C0\u67E5\u4F9D\u8D56...");
2990
+ const serverRoot = path9.resolve(__dirname4, "../..");
2991
+ const packageJsonPath = path9.join(serverRoot, "package.json");
2992
+ if (fs9.existsSync(packageJsonPath)) {
2993
+ try {
2994
+ const pkg = JSON.parse(fs9.readFileSync(packageJsonPath, "utf-8"));
2995
+ checks.dependencies.status = "healthy";
2996
+ checks.dependencies.details.push(`\u2705 \u670D\u52A1\u5668\u7248\u672C: ${pkg.version}`);
2997
+ if (verbose && pkg.dependencies) {
2998
+ const deps = Object.entries(pkg.dependencies).slice(0, 3);
2999
+ deps.forEach(([name, version]) => {
3000
+ checks.dependencies.details.push(` ${name}: ${version}`);
3001
+ });
3002
+ }
3003
+ const requiredDeps = ["@modelcontextprotocol/sdk"];
3004
+ const missing = requiredDeps.filter((dep) => {
3005
+ var _a2;
3006
+ return !((_a2 = pkg.dependencies) == null ? void 0 : _a2[dep]);
3007
+ });
3008
+ if (missing.length > 0) {
3009
+ checks.dependencies.status = "error";
3010
+ checks.dependencies.details.push(`\u274C \u7F3A\u5C11\u4F9D\u8D56: ${missing.join(", ")}`);
3011
+ }
3012
+ } catch {
3013
+ checks.dependencies.status = "error";
3014
+ checks.dependencies.details.push("\u274C \u65E0\u6CD5\u8BFB\u53D6 package.json");
3015
+ }
3016
+ }
3017
+ logger3.log("\u{1F50D} \u68C0\u67E5\u89C4\u8303\u6587\u4EF6...");
3018
+ const standardsDir = path9.join(serverRoot, "standards");
3019
+ if (fs9.existsSync(standardsDir)) {
3020
+ const categories = ["core", "frameworks", "libraries", "patterns"];
3021
+ const foundStandards = [];
3022
+ for (const category of categories) {
3023
+ const categoryPath = path9.join(standardsDir, category);
3024
+ if (fs9.existsSync(categoryPath)) {
3025
+ const files = fs9.readdirSync(categoryPath).filter((f) => f.endsWith(".md"));
3026
+ foundStandards.push(...files.map((f) => `${category}/${f}`));
3027
+ }
3028
+ }
3029
+ if (foundStandards.length > 0) {
3030
+ checks.standards.status = "healthy";
3031
+ checks.standards.details.push(`\u2705 \u627E\u5230 ${foundStandards.length} \u4E2A\u89C4\u8303\u6587\u4EF6`);
3032
+ if (verbose) {
3033
+ foundStandards.slice(0, 5).forEach((s) => {
3034
+ checks.standards.details.push(` \u{1F4C4} ${s}`);
3035
+ });
3036
+ if (foundStandards.length > 5) {
3037
+ checks.standards.details.push(` ... \u8FD8\u6709 ${foundStandards.length - 5} \u4E2A\u6587\u4EF6`);
3038
+ }
3039
+ }
3040
+ } else {
3041
+ checks.standards.status = "warning";
3042
+ checks.standards.details.push("\u26A0\uFE0F \u672A\u627E\u5230\u89C4\u8303\u6587\u4EF6");
3043
+ }
3044
+ } else {
3045
+ checks.standards.status = "error";
3046
+ checks.standards.details.push("\u274C standards \u76EE\u5F55\u4E0D\u5B58\u5728");
3047
+ }
3048
+ const allStatuses = Object.values(checks).map((c) => c.status);
3049
+ const overallStatus = allStatuses.includes("error") ? "error" : allStatuses.includes("warning") ? "warning" : "healthy";
3050
+ const statusEmoji = {
3051
+ healthy: "\u2705",
3052
+ warning: "\u26A0\uFE0F",
3053
+ error: "\u274C",
3054
+ unknown: "\u2753"
3055
+ };
3056
+ logger3.log(`${statusEmoji[overallStatus]} \u5065\u5EB7\u68C0\u67E5\u5B8C\u6210`);
3057
+ return {
3058
+ content: [{
3059
+ type: "text",
3060
+ text: JSON.stringify({
3061
+ success: true,
3062
+ overallStatus,
3063
+ summary: `${statusEmoji[overallStatus]} MCP \u670D\u52A1\u5668\u72B6\u6001: ${overallStatus}`,
3064
+ checks,
3065
+ recommendations: generateRecommendations(checks)
3066
+ }, null, 2)
3067
+ }]
3068
+ };
3069
+ } catch (error) {
3070
+ logger3.error(`\u5065\u5EB7\u68C0\u67E5\u5931\u8D25: ${error}`);
3071
+ return {
3072
+ content: [{
3073
+ type: "text",
3074
+ text: JSON.stringify({
3075
+ error: error instanceof Error ? error.message : String(error)
3076
+ }, null, 2)
3077
+ }]
3078
+ };
3079
+ }
3080
+ }
3081
+ function generateRecommendations(checks) {
3082
+ const recommendations = [];
3083
+ if (checks.configuration.status !== "healthy") {
3084
+ recommendations.push("\u{1F527} \u8FD0\u884C auto_setup \u5DE5\u5177\u81EA\u52A8\u914D\u7F6E MCP \u670D\u52A1\u5668");
3085
+ }
3086
+ if (checks.workspace.status === "error") {
3087
+ recommendations.push("\u{1F4C1} \u786E\u4FDD\u5728\u6B63\u786E\u7684\u5DE5\u4F5C\u533A\u76EE\u5F55\u4E2D\u8FD0\u884C");
3088
+ }
3089
+ if (checks.dependencies.status === "error") {
3090
+ recommendations.push("\u{1F4E6} \u8FD0\u884C npm install \u5B89\u88C5\u4F9D\u8D56");
3091
+ }
3092
+ if (checks.standards.status !== "healthy") {
3093
+ recommendations.push("\u{1F4DA} \u68C0\u67E5 standards \u76EE\u5F55\u662F\u5426\u5B58\u5728\u89C4\u8303\u6587\u4EF6");
3094
+ }
3095
+ if (recommendations.length === 0) {
3096
+ recommendations.push("\u{1F389} \u4E00\u5207\u6B63\u5E38\uFF01\u60A8\u53EF\u4EE5\u5F00\u59CB\u4F7F\u7528 MCP \u670D\u52A1\u5668\u4E86");
3097
+ }
3098
+ return recommendations;
3099
+ }
3100
+
3101
+ // src/tools/getCompactStandards.ts
3102
+ import * as fs10 from "fs";
3103
+ async function getCompactStandards(args) {
3104
+ const logger3 = new ConsoleLogger();
3105
+ const manager = new StandardsManager();
3106
+ const mode = args.mode || "key-rules";
3107
+ try {
3108
+ const context = detectContext(args, logger3);
3109
+ const standardUris = manager.getRelevantStandards({
3110
+ fileType: context.fileType,
3111
+ imports: context.imports,
3112
+ scenario: args.scenario || context.scenario
3113
+ });
3114
+ let responseContent;
3115
+ switch (mode) {
3116
+ case "summary":
3117
+ responseContent = buildSummaryResponse(standardUris, manager);
3118
+ break;
3119
+ case "key-rules":
3120
+ responseContent = buildKeyRulesResponse(standardUris, context, manager);
3121
+ break;
3122
+ case "full":
3123
+ responseContent = buildFullResponse(standardUris, manager);
3124
+ break;
3125
+ }
3126
+ return {
3127
+ content: [{
3128
+ type: "text",
3129
+ text: JSON.stringify(responseContent, null, 2)
3130
+ }]
3131
+ };
3132
+ } catch (error) {
3133
+ logger3.error(`\u89C4\u8303\u83B7\u53D6\u5931\u8D25: ${error}`);
3134
+ return {
3135
+ content: [{
3136
+ type: "text",
3137
+ text: JSON.stringify({
3138
+ error: error instanceof Error ? error.message : String(error)
3139
+ }, null, 2)
3140
+ }]
3141
+ };
3142
+ }
3143
+ }
3144
+ function detectContext(args, logger3) {
3145
+ var _a;
3146
+ let fileType = "unknown";
3147
+ let imports = [];
3148
+ let scenario = "";
3149
+ if (args.currentFile && fs10.existsSync(args.currentFile)) {
3150
+ const ext = ((_a = args.currentFile.split(".").pop()) == null ? void 0 : _a.toLowerCase()) || "";
3151
+ const extMap = {
3152
+ "vue": "vue",
3153
+ "ts": "ts",
3154
+ "tsx": "tsx",
3155
+ "js": "js",
3156
+ "jsx": "jsx",
3157
+ "dart": "dart"
3158
+ };
3159
+ fileType = extMap[ext] || "unknown";
3160
+ try {
3161
+ const content = fs10.readFileSync(args.currentFile, "utf-8");
3162
+ imports = extractImports2(content);
3163
+ scenario = inferScenario2(content, fileType);
3164
+ } catch {
3165
+ }
3166
+ }
3167
+ if (args.fileContent) {
3168
+ imports = [...imports, ...extractImports2(args.fileContent)];
3169
+ if (fileType === "unknown") {
3170
+ if (args.fileContent.includes("<template>")) fileType = "vue";
3171
+ else if (args.fileContent.includes("interface ")) fileType = "ts";
3172
+ }
3173
+ scenario = scenario || inferScenario2(args.fileContent, fileType);
3174
+ }
3175
+ return { fileType, imports: [...new Set(imports)], scenario };
3176
+ }
3177
+ function buildSummaryResponse(uris, manager) {
3178
+ const standards = manager.getAvailableStandards();
3179
+ const matched = uris.map((uri) => {
3180
+ const std = standards.find((s) => s.uri === uri);
3181
+ return {
3182
+ uri,
3183
+ name: (std == null ? void 0 : std.name) || uri,
3184
+ description: (std == null ? void 0 : std.description) || ""
3185
+ };
3186
+ });
3187
+ return {
3188
+ success: true,
3189
+ mode: "summary",
3190
+ message: '\u5DF2\u8BC6\u522B\u76F8\u5173\u89C4\u8303\uFF0C\u5982\u9700\u8BE6\u7EC6\u5185\u5BB9\u8BF7\u4F7F\u7528 mode: "key-rules" \u6216 "full"',
3191
+ standards: matched,
3192
+ stats: {
3193
+ count: matched.length,
3194
+ estimatedTokens: 500
3195
+ }
3196
+ };
3197
+ }
3198
+ function buildKeyRulesResponse(uris, context, manager) {
3199
+ const keyRules = [];
3200
+ if (context.fileType === "vue") {
3201
+ keyRules.push(...getVueKeyRules(context.imports));
3202
+ } else if (context.fileType === "dart") {
3203
+ keyRules.push(...getFlutterKeyRules());
3204
+ } else if (context.fileType === "ts" || context.fileType === "tsx") {
3205
+ keyRules.push(...getTypeScriptKeyRules());
3206
+ }
3207
+ if (context.imports.includes("element-plus")) {
3208
+ keyRules.push(...getElementPlusKeyRules());
3209
+ }
3210
+ if (context.imports.some((i) => i.includes("i18n") || i.includes("locale"))) {
3211
+ keyRules.push(...getI18nKeyRules());
3212
+ }
3213
+ if (context.imports.includes("pinia")) {
3214
+ keyRules.push(...getPiniaKeyRules());
3215
+ }
3216
+ return {
3217
+ success: true,
3218
+ mode: "key-rules",
3219
+ context: {
3220
+ fileType: context.fileType,
3221
+ detectedImports: context.imports,
3222
+ scenario: context.scenario
3223
+ },
3224
+ keyRules: keyRules.join("\n\n"),
3225
+ standardUris: uris,
3226
+ // 提供完整 URI 供按需加载
3227
+ stats: {
3228
+ rulesCount: keyRules.length,
3229
+ estimatedTokens: Math.ceil(keyRules.join("").length / 4)
3230
+ }
3231
+ };
3232
+ }
3233
+ function buildFullResponse(uris, manager) {
3234
+ const content = manager.combineStandards(uris);
3235
+ return {
3236
+ success: true,
3237
+ mode: "full",
3238
+ standards: uris,
3239
+ content,
3240
+ stats: {
3241
+ standardsCount: uris.length,
3242
+ contentLength: content.length,
3243
+ estimatedTokens: Math.ceil(content.length / 4)
3244
+ }
3245
+ };
3246
+ }
3247
+ function getVueKeyRules(imports) {
3248
+ return [
3249
+ `## Vue 3 \u5173\u952E\u89C4\u5219
3250
+
3251
+ 1. **\u4F7F\u7528 \`<script setup lang="ts">\`** - \u5FC5\u987B\u4F7F\u7528 Composition API
3252
+ 2. **Props/Emits \u7C7B\u578B\u5B9A\u4E49** - \u5FC5\u987B\u4F7F\u7528 interface \u5B9A\u4E49\u7C7B\u578B
3253
+ 3. **\u7981\u6B62\u5185\u8054\u6837\u5F0F** - \u4F7F\u7528 scoped CSS \u6216 class
3254
+ 4. **\u6A21\u677F\u7B80\u6D01** - \u590D\u6742\u903B\u8F91\u63D0\u53D6\u5230 computed \u6216\u65B9\u6CD5
3255
+ 5. **\u54CD\u5E94\u5F0F** - \u57FA\u672C\u7C7B\u578B\u7528 ref\uFF0C\u5BF9\u8C61\u7528 reactive\uFF08\u4E0D\u91CD\u65B0\u8D4B\u503C\uFF09`,
3256
+ `## \u7EC4\u4EF6\u7ED3\u6784\u987A\u5E8F
3257
+ \`\`\`vue
3258
+ <script setup lang="ts">
3259
+ // 1. \u7C7B\u578B\u5BFC\u5165
3260
+ // 2. Props/Emits \u5B9A\u4E49
3261
+ // 3. \u54CD\u5E94\u5F0F\u72B6\u6001
3262
+ // 4. \u8BA1\u7B97\u5C5E\u6027
3263
+ // 5. \u65B9\u6CD5
3264
+ // 6. \u751F\u547D\u5468\u671F
3265
+ </script>
3266
+ \`\`\``
3267
+ ];
3268
+ }
3269
+ function getElementPlusKeyRules() {
3270
+ return [
3271
+ `## Element Plus \u5173\u952E\u89C4\u5219
3272
+
3273
+ ### \u8868\u683C\u89C4\u8303
3274
+ - **\u5FC5\u987B** \`border\` + \`highlight-current-row\`
3275
+ - \u64CD\u4F5C\u5217 \`fixed="right"\`\uFF0C\u5BBD\u5EA6\uFF1A2\u6309\u94AE160px/3\u6309\u94AE240px/4\u6309\u94AE280px
3276
+ - \u4F7F\u7528 \`v-loading\` \u663E\u793A\u52A0\u8F7D\u72B6\u6001
3277
+
3278
+ ### \u8868\u5355\u89C4\u8303
3279
+ - \u4F7F\u7528 \`label-position="top"\` \u6216 \`label-width="120px"\`
3280
+ - \u9A8C\u8BC1\u89C4\u5219\u4F7F\u7528 \`FormRules<T>\` \u7C7B\u578B
3281
+ - \u9A8C\u8BC1\u6D88\u606F\u5FC5\u987B\u56FD\u9645\u5316
3282
+
3283
+ ### \u5F39\u7A97\u89C4\u8303
3284
+ - \u4F7F\u7528 \`destroy-on-close\` \u91CD\u7F6E\u72B6\u6001
3285
+ - \u5BBD\u5EA6\uFF1A\u7B80\u5355500px/\u6807\u51C6700px/\u590D\u6742900px
3286
+
3287
+ ### \u6D88\u606F\u63D0\u793A
3288
+ \`\`\`typescript
3289
+ ElMessage.success($t('\u4FDD\u5B58\u6210\u529F'))
3290
+ ElMessageBox.confirm($t('\u786E\u8BA4\u5220\u9664\uFF1F'), $t('\u8B66\u544A'), { type: 'warning' })
3291
+ \`\`\``,
3292
+ `## \u8868\u683C\u793A\u4F8B
3293
+ \`\`\`vue
3294
+ <el-table v-loading="listLoading" :data="list" border highlight-current-row>
3295
+ <el-table-column type="index" :label="$t('\u5E8F\u53F7')" width="70" />
3296
+ <el-table-column prop="name" :label="$t('\u540D\u79F0')" min-width="120" />
3297
+ <el-table-column fixed="right" :label="$t('\u64CD\u4F5C')" width="240">
3298
+ <template #default="{ row }">
3299
+ <el-button link type="primary" @click="handleEdit(row)">{{ $t('\u7F16\u8F91') }}</el-button>
3300
+ <el-button link type="danger" @click="handleDelete(row)">{{ $t('\u5220\u9664') }}</el-button>
3301
+ </template>
3302
+ </el-table-column>
3303
+ </el-table>
3304
+ \`\`\``
3305
+ ];
3306
+ }
3307
+ function getI18nKeyRules() {
3308
+ return [
3309
+ `## \u56FD\u9645\u5316\u5173\u952E\u89C4\u5219
3310
+
3311
+ ### \u5FC5\u987B\u56FD\u9645\u5316\u7684\u5185\u5BB9
3312
+ - \u6240\u6709\u6309\u94AE\u6587\u5B57\uFF1A\`{{ $t('\u4FDD\u5B58') }}\`
3313
+ - \u8868\u5355\u6807\u7B7E\uFF1A\`:label="$t('\u5BA2\u6237\u540D\u79F0')"\`
3314
+ - \u5360\u4F4D\u7B26\uFF1A\`:placeholder="$t('\u8BF7\u8F93\u5165')"\`
3315
+ - \u8868\u683C\u5217\u6807\u9898\uFF1A\`:label="$t('\u8BA2\u5355\u7F16\u53F7')"\`
3316
+ - \u5F39\u7A97\u6807\u9898\uFF1A\`:title="$t('\u65B0\u589E\u5BA2\u6237')"\`
3317
+ - \u63D0\u793A\u6D88\u606F\uFF1A\`ElMessage.success($t('\u4FDD\u5B58\u6210\u529F'))\`
3318
+ - \u9A8C\u8BC1\u89C4\u5219\uFF1A\`message: $t('\u8BF7\u8F93\u5165\u7528\u6237\u540D')\`
3319
+
3320
+ ### \u7981\u6B62
3321
+ - \u274C \`<el-button>\u65B0\u589E</el-button>\` (\u786C\u7F16\u7801)
3322
+ - \u274C \`label="\u5BA2\u6237\u540D\u79F0"\` (\u786C\u7F16\u7801)
3323
+ - \u274C \`ElMessage.success('\u4FDD\u5B58\u6210\u529F')\` (\u786C\u7F16\u7801)`
3324
+ ];
3325
+ }
3326
+ function getPiniaKeyRules() {
3327
+ return [
3328
+ `## Pinia \u5173\u952E\u89C4\u5219
3329
+
3330
+ ### Setup Store \u8BED\u6CD5\uFF08\u63A8\u8350\uFF09
3331
+ \`\`\`typescript
3332
+ export const useUserStore = defineStore('user', () => {
3333
+ const user = ref<User | null>(null)
3334
+ const isLoggedIn = computed(() => !!user.value)
3335
+
3336
+ async function login(credentials: Credentials) {
3337
+ user.value = await authApi.login(credentials)
3338
+ }
3339
+
3340
+ return { user, isLoggedIn, login }
3341
+ })
3342
+ \`\`\`
3343
+
3344
+ ### \u89C4\u8303\u8981\u6C42
3345
+ - Store ID \u4F7F\u7528\u5C0F\u5199\u77ED\u6A2A\u7EBF\u547D\u540D
3346
+ - \u4F7F\u7528 Setup Store \u8BED\u6CD5\u800C\u975E Options Store
3347
+ - \u5F02\u6B65\u64CD\u4F5C\u76F4\u63A5\u7528 async/await
3348
+ - \u590D\u6742\u72B6\u6001\u64CD\u4F5C\u4F7F\u7528 $patch`
3349
+ ];
3350
+ }
3351
+ function getTypeScriptKeyRules() {
3352
+ return [
3353
+ `## TypeScript \u5173\u952E\u89C4\u5219
3354
+
3355
+ ### \u7C7B\u578B\u5B9A\u4E49
3356
+ - \u5FC5\u987B\u5B9A\u4E49\u51FD\u6570\u53C2\u6570\u548C\u8FD4\u56DE\u7C7B\u578B
3357
+ - \u4F7F\u7528 interface \u5B9A\u4E49\u5BF9\u8C61\u7C7B\u578B
3358
+ - \u907F\u514D\u4F7F\u7528 any\uFF0C\u4F7F\u7528 unknown \u66FF\u4EE3
3359
+
3360
+ ### \u547D\u540D\u89C4\u8303
3361
+ - \u53D8\u91CF/\u51FD\u6570\uFF1AcamelCase
3362
+ - \u7C7B/\u63A5\u53E3/\u7C7B\u578B\uFF1APascalCase
3363
+ - \u5E38\u91CF\uFF1AUPPER_SNAKE_CASE
3364
+
3365
+ ### \u793A\u4F8B
3366
+ \`\`\`typescript
3367
+ interface User {
3368
+ id: number
3369
+ name: string
3370
+ email?: string
3371
+ }
3372
+
3373
+ async function fetchUser(id: number): Promise<User | null> {
3374
+ // ...
3375
+ }
3376
+ \`\`\``
3377
+ ];
3378
+ }
3379
+ function getFlutterKeyRules() {
3380
+ return [
3381
+ `## Flutter UI \u7CFB\u7EDF\u5173\u952E\u89C4\u5219
3382
+
3383
+ ### Design Token \u5FEB\u6377\u65B9\u5F0F\uFF08\u5FC5\u987B\u4F7F\u7528\uFF09
3384
+ | \u5FEB\u6377\u65B9\u5F0F | \u7528\u9014 | \u793A\u4F8B |
3385
+ |---------|------|------|
3386
+ | \`$c\` | \u989C\u8272 | \`$c.primary\`, \`$c.text.primary\` |
3387
+ | \`$s\` | \u95F4\u8DDD | \`$s.sm\`, \`$s.md\`, \`$s.px(14)\` |
3388
+ | \`$t\` | \u6392\u7248 | \`$t.displayLarge\`, \`$t.bodyMedium\` |
3389
+ | \`$r\` | \u5706\u89D2 | \`$r.sm\`, \`$r.md\`, \`$r.full\` |
3390
+
3391
+ ### Flex \u7EC4\u4EF6\u5E93\uFF08\u5FC5\u987B\u4F7F\u7528\uFF09
3392
+ - \`FlexButton\` \u66FF\u4EE3 ElevatedButton/TextButton
3393
+ - \`FlexCard\` \u66FF\u4EE3 Card/Container
3394
+ - \`FlexInput\` \u66FF\u4EE3 TextField
3395
+ - \`Gap\` \u66FF\u4EE3 SizedBox\uFF08\u95F4\u9694\uFF09
3396
+
3397
+ ### \u7981\u6B62
3398
+ - \u274C \`Color(0xFF3B82F6)\` \u786C\u7F16\u7801\u989C\u8272
3399
+ - \u274C \`EdgeInsets.all(16)\` \u786C\u7F16\u7801\u95F4\u8DDD
3400
+ - \u274C \`Colors.blue\` Material \u989C\u8272\u5E38\u91CF`
3401
+ ];
3402
+ }
3403
+ function extractImports2(content) {
3404
+ const imports = [];
3405
+ const esImportRegex = /import\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+)?['"]([^'"]+)['"]/g;
3406
+ let match;
3407
+ while ((match = esImportRegex.exec(content)) !== null) {
3408
+ imports.push(match[1]);
3409
+ }
3410
+ const requireRegex = /require\(['"]([^'"]+)['"]\)/g;
3411
+ while ((match = requireRegex.exec(content)) !== null) {
3412
+ imports.push(match[1]);
3413
+ }
3414
+ return imports;
3415
+ }
3416
+ function inferScenario2(content, fileType) {
3417
+ const scenarios = [];
3418
+ const lower = content.toLowerCase();
3419
+ if (lower.includes("el-table") || lower.includes("el-form")) {
3420
+ scenarios.push("\u8868\u683C\u7EC4\u4EF6", "\u8868\u5355\u7EC4\u4EF6");
3421
+ }
3422
+ if (lower.includes("$t(") || lower.includes("i18n")) {
3423
+ scenarios.push("\u56FD\u9645\u5316");
3424
+ }
3425
+ if (lower.includes("interface ") || lower.includes("type ")) {
3426
+ scenarios.push("\u7C7B\u578B\u5B9A\u4E49");
3427
+ }
3428
+ return scenarios.join("\u3001");
3429
+ }
3430
+
3431
+ // src/tools/getStandardById.ts
3432
+ import * as fs11 from "fs";
3433
+ import * as path10 from "path";
3434
+ var STANDARD_DIRS = [
3435
+ "standards/core",
3436
+ "standards/frameworks",
3437
+ "standards/libraries",
3438
+ "standards/patterns",
3439
+ "standards/workflows"
3440
+ ];
3441
+ var standardsCache = null;
3442
+ async function getStandardById(args) {
3443
+ const logger3 = new ConsoleLogger();
3444
+ const mode = args.mode || "key-rules";
3445
+ try {
3446
+ const idsToLoad = args.ids || (args.id ? [args.id] : []);
3447
+ if (idsToLoad.length === 0) {
3448
+ return {
3449
+ content: [{
3450
+ type: "text",
3451
+ text: JSON.stringify({
3452
+ error: "\u8BF7\u63D0\u4F9B id \u6216 ids \u53C2\u6570",
3453
+ availableIds: listAvailableStandards()
3454
+ }, null, 2)
3455
+ }]
3456
+ };
3457
+ }
3458
+ ensureCache();
3459
+ const results = [];
3460
+ for (const id of idsToLoad) {
3461
+ const filePath = standardsCache.get(id);
3462
+ if (!filePath) {
3463
+ results.push({
3464
+ id,
3465
+ found: false,
3466
+ error: `\u89C4\u8303 "${id}" \u4E0D\u5B58\u5728`
3467
+ });
3468
+ continue;
3469
+ }
3470
+ try {
3471
+ const fullContent = fs11.readFileSync(filePath, "utf-8");
3472
+ const content = formatContent(fullContent, mode);
3473
+ results.push({
3474
+ id,
3475
+ found: true,
3476
+ content
3477
+ });
3478
+ } catch (error) {
3479
+ results.push({
3480
+ id,
3481
+ found: false,
3482
+ error: `\u8BFB\u53D6\u5931\u8D25: ${error}`
3483
+ });
3484
+ }
3485
+ }
3486
+ const successCount = results.filter((r) => r.found).length;
3487
+ const totalLength = results.reduce((sum, r) => {
3488
+ var _a;
3489
+ return sum + (((_a = r.content) == null ? void 0 : _a.length) || 0);
3490
+ }, 0);
3491
+ return {
3492
+ content: [{
3493
+ type: "text",
3494
+ text: JSON.stringify({
3495
+ success: true,
3496
+ mode,
3497
+ stats: {
3498
+ requested: idsToLoad.length,
3499
+ found: successCount,
3500
+ totalChars: totalLength,
3501
+ estimatedTokens: Math.ceil(totalLength / 4)
3502
+ },
3503
+ standards: results
3504
+ }, null, 2)
3505
+ }]
3506
+ };
3507
+ } catch (error) {
3508
+ logger3.error(`\u83B7\u53D6\u89C4\u8303\u5931\u8D25: ${error}`);
3509
+ return {
3510
+ content: [{
3511
+ type: "text",
3512
+ text: JSON.stringify({
3513
+ error: error instanceof Error ? error.message : String(error)
3514
+ }, null, 2)
3515
+ }]
3516
+ };
3517
+ }
3518
+ }
3519
+ function listAvailableStandards() {
3520
+ ensureCache();
3521
+ return Array.from(standardsCache.keys());
3522
+ }
3523
+ function ensureCache() {
3524
+ if (standardsCache) return;
3525
+ standardsCache = /* @__PURE__ */ new Map();
3526
+ const baseDir = findBaseDir();
3527
+ for (const dir of STANDARD_DIRS) {
3528
+ const fullDir = path10.join(baseDir, dir);
3529
+ if (!fs11.existsSync(fullDir)) continue;
3530
+ scanDirectory(fullDir, standardsCache);
3531
+ }
3532
+ }
3533
+ function findBaseDir() {
3534
+ const possiblePaths = [
3535
+ process.cwd(),
3536
+ path10.join(process.cwd(), ".."),
3537
+ path10.join(__dirname, "..", "..", "..")
3538
+ ];
3539
+ for (const p of possiblePaths) {
3540
+ if (fs11.existsSync(path10.join(p, "standards"))) {
3541
+ return p;
3542
+ }
3543
+ }
3544
+ return process.cwd();
3545
+ }
3546
+ function scanDirectory(dir, cache) {
3547
+ const items = fs11.readdirSync(dir);
3548
+ for (const item of items) {
3549
+ const fullPath = path10.join(dir, item);
3550
+ const stat = fs11.statSync(fullPath);
3551
+ if (stat.isDirectory()) {
3552
+ scanDirectory(fullPath, cache);
3553
+ } else if (item.endsWith(".md")) {
3554
+ const id = path10.basename(item, ".md");
3555
+ cache.set(id, fullPath);
3556
+ }
3557
+ }
3558
+ }
3559
+ function formatContent(content, mode) {
3560
+ switch (mode) {
3561
+ case "summary":
3562
+ return extractSummary(content);
3563
+ case "key-rules":
3564
+ return extractKeyRules(content);
3565
+ case "full":
3566
+ return content;
3567
+ default:
3568
+ return content;
3569
+ }
3570
+ }
3571
+ function extractSummary(content) {
3572
+ const lines = content.split("\n");
3573
+ const summaryLines = [];
3574
+ const titleMatch = content.match(/^#\s+(.+)$/m);
3575
+ if (titleMatch) {
3576
+ summaryLines.push(`# ${titleMatch[1]}`);
3577
+ }
3578
+ let foundDescription = false;
3579
+ for (const line of lines) {
3580
+ if (line.startsWith("#") || line.trim() === "") continue;
3581
+ if (line.startsWith(">")) {
3582
+ summaryLines.push(line);
3583
+ foundDescription = true;
3584
+ break;
3585
+ }
3586
+ if (line.startsWith("-") || line.startsWith("*")) continue;
3587
+ summaryLines.push(line);
3588
+ foundDescription = true;
3589
+ break;
3590
+ }
3591
+ const sectionHeaders = lines.filter((l) => l.match(/^##\s+/)).slice(0, 5);
3592
+ if (sectionHeaders.length > 0) {
3593
+ summaryLines.push("\n**\u4E3B\u8981\u7AE0\u8282**:");
3594
+ summaryLines.push(...sectionHeaders.map((h) => `- ${h.replace(/^##\s+/, "")}`));
3595
+ }
3596
+ return summaryLines.join("\n");
3597
+ }
3598
+ function extractKeyRules(content) {
3599
+ const lines = content.split("\n");
3600
+ const keyRulesLines = [];
3601
+ const titleMatch = content.match(/^#\s+(.+)$/m);
3602
+ if (titleMatch) {
3603
+ keyRulesLines.push(`# ${titleMatch[1]}`);
3604
+ }
3605
+ const keyPatterns = [
3606
+ /强制|必须|禁止|规则|核心|关键|重要/,
3607
+ /MUST|REQUIRED|SHOULD|必选|核心原则/,
3608
+ /✅|❌|⚠️/
3609
+ ];
3610
+ let inKeySection = false;
3611
+ let sectionDepth = 0;
3612
+ let lineCount = 0;
3613
+ const maxLines = 80;
3614
+ for (const line of lines) {
3615
+ const headerMatch = line.match(/^(#{2,3})\s+(.+)$/);
3616
+ if (headerMatch) {
3617
+ const depth = headerMatch[1].length;
3618
+ const title = headerMatch[2];
3619
+ inKeySection = keyPatterns.some((p) => p.test(title));
3620
+ sectionDepth = depth;
3621
+ if (inKeySection) {
3622
+ keyRulesLines.push("");
3623
+ keyRulesLines.push(line);
3624
+ lineCount++;
3625
+ }
3626
+ continue;
3627
+ }
3628
+ if (inKeySection && lineCount < maxLines) {
3629
+ if (line.match(/^#{2}\s+/) && sectionDepth >= 2) {
3630
+ inKeySection = false;
3631
+ continue;
3632
+ }
3633
+ keyRulesLines.push(line);
3634
+ lineCount++;
3635
+ }
3636
+ if (!inKeySection && lineCount < maxLines) {
3637
+ if (line.includes("\u2705") || line.includes("\u274C") || line.includes("\u26A0\uFE0F")) {
3638
+ keyRulesLines.push(line);
3639
+ lineCount++;
3640
+ }
3641
+ }
3642
+ }
3643
+ if (keyRulesLines.length < 20) {
3644
+ const codeBlockMatch = content.match(/```[\s\S]{50,500}?```/);
3645
+ if (codeBlockMatch) {
3646
+ keyRulesLines.push("\n**\u793A\u4F8B**:");
3647
+ keyRulesLines.push(codeBlockMatch[0]);
3648
+ }
3649
+ }
3650
+ return keyRulesLines.join("\n").trim() || extractSummary(content);
3651
+ }
3652
+
3653
+ // src/core/mappings/scenarioMappings.ts
3654
+ var SCENARIO_STANDARDS = {
3655
+ // ========== Vue 相关场景 ==========
3656
+ "vue3-component": ["vue3-composition", "typescript-strict"],
3657
+ "vue3-form": ["vue3-composition", "element-plus", "form-validation"],
3658
+ "vue3-table": ["vue3-composition", "element-plus", "pagination"],
3659
+ "pinia-store": ["pinia-store", "typescript-strict"],
3660
+ "composable": ["vue3-composition", "composable-patterns"],
3661
+ // ========== API 相关 ==========
3662
+ "api-call": ["axios-interceptor", "error-handling", "typescript-strict"],
3663
+ "api-design": ["api-design", "restful-patterns"],
3664
+ // ========== 国际化 ==========
3665
+ "i18n": ["i18n", "vue-i18n"],
3666
+ // ========== 测试 ==========
3667
+ "unit-test": ["vitest-guide", "testing-patterns"],
3668
+ // ========== 特殊场景 ==========
3669
+ "logicflow": ["logicflow", "vue3-composition"],
3670
+ "permission": ["permission-design", "route-guard"],
3671
+ "performance": ["performance-optimization", "lazy-loading"]
3672
+ };
3673
+ var FILETYPE_STANDARDS = {
3674
+ "vue": ["vue3-composition"],
3675
+ "ts": ["typescript-strict"],
3676
+ "tsx": ["react-hooks", "typescript-strict"],
3677
+ "dart": ["dart-style", "flutter-bloc"]
3678
+ };
3679
+ var IMPORT_STANDARDS = {
3680
+ "vue": ["vue3-composition"],
3681
+ "element-plus": ["element-plus"],
3682
+ "pinia": ["pinia-store"],
3683
+ "axios": ["axios-interceptor"],
3684
+ "vue-i18n": ["i18n"],
3685
+ "@logicflow/core": ["logicflow"],
3686
+ "vitest": ["vitest-guide"]
3687
+ };
3688
+ function getStandardsForScenario(scenario) {
3689
+ return SCENARIO_STANDARDS[scenario] || [];
3690
+ }
3691
+ function getStandardsForFileType(fileType) {
3692
+ return FILETYPE_STANDARDS[fileType] || [];
3693
+ }
3694
+ function getStandardsForImport(importName) {
3695
+ const normalizedImport = importName.startsWith("@") ? importName.split("/").slice(0, 2).join("/") : importName.split("/")[0];
3696
+ return IMPORT_STANDARDS[normalizedImport] || [];
3697
+ }
3698
+ function listAvailableScenarios() {
3699
+ return Object.keys(SCENARIO_STANDARDS);
3700
+ }
3701
+ function suggestStandards(options) {
3702
+ const suggestions = [];
3703
+ if (options.scenario) {
3704
+ suggestions.push(...getStandardsForScenario(options.scenario));
3705
+ }
3706
+ if (options.fileType) {
3707
+ suggestions.push(...getStandardsForFileType(options.fileType));
3708
+ }
3709
+ if (options.imports) {
3710
+ for (const imp of options.imports) {
3711
+ suggestions.push(...getStandardsForImport(imp));
3712
+ }
3713
+ }
3714
+ return [...new Set(suggestions)];
3715
+ }
3716
+
3717
+ // src/tools/queryMappings.ts
3718
+ async function queryMappings(args) {
3719
+ const logger3 = new ConsoleLogger();
3720
+ try {
3721
+ if (args.listAll) {
3722
+ return {
3723
+ content: [{
3724
+ type: "text",
3725
+ text: JSON.stringify({
3726
+ success: true,
3727
+ description: "\u573A\u666F-\u89C4\u8303\u6620\u5C04\u8868\uFF0CAI \u53EF\u53C2\u8003\u8FD9\u4E9B\u6620\u5C04\u81EA\u884C\u51B3\u5B9A\u4F7F\u7528\u54EA\u4E9B\u89C4\u8303",
3728
+ mappings: {
3729
+ scenarios: SCENARIO_STANDARDS,
3730
+ fileTypes: FILETYPE_STANDARDS,
3731
+ imports: IMPORT_STANDARDS
3732
+ },
3733
+ availableScenarios: listAvailableScenarios()
3734
+ }, null, 2)
3735
+ }]
3736
+ };
3737
+ }
3738
+ const result = {
3739
+ success: true,
3740
+ query: {},
3741
+ suggestions: []
3742
+ };
3743
+ if (args.scenario) {
3744
+ result.query.scenario = args.scenario;
3745
+ result.scenarioStandards = SCENARIO_STANDARDS[args.scenario] || [];
3746
+ }
3747
+ if (args.fileType) {
3748
+ result.query.fileType = args.fileType;
3749
+ result.fileTypeStandards = FILETYPE_STANDARDS[args.fileType] || [];
3750
+ }
3751
+ if (args.imports && args.imports.length > 0) {
3752
+ result.query.imports = args.imports;
3753
+ result.importStandards = {};
3754
+ for (const imp of args.imports) {
3755
+ const normalizedImport = imp.startsWith("@") ? imp.split("/").slice(0, 2).join("/") : imp.split("/")[0];
3756
+ result.importStandards[imp] = IMPORT_STANDARDS[normalizedImport] || [];
3757
+ }
3758
+ }
3759
+ result.suggestions = suggestStandards({
3760
+ scenario: args.scenario,
3761
+ fileType: args.fileType,
3762
+ imports: args.imports
3763
+ });
3764
+ result.note = "AI \u53EF\u6839\u636E\u5177\u4F53\u60C5\u51B5\u9009\u62E9\u4F7F\u7528\u54EA\u4E9B\u89C4\u8303\uFF0C\u8FD9\u53EA\u662F\u5EFA\u8BAE\u5217\u8868";
3765
+ return {
3766
+ content: [{
3767
+ type: "text",
3768
+ text: JSON.stringify(result, null, 2)
3769
+ }]
3770
+ };
3771
+ } catch (error) {
3772
+ logger3.error(`\u67E5\u8BE2\u6620\u5C04\u5931\u8D25: ${error}`);
3773
+ return {
3774
+ content: [{
3775
+ type: "text",
3776
+ text: JSON.stringify({
3777
+ error: error instanceof Error ? error.message : String(error)
3778
+ }, null, 2)
3779
+ }]
3780
+ };
3781
+ }
3782
+ }
3783
+ async function listScenarios() {
3784
+ return {
3785
+ content: [{
3786
+ type: "text",
3787
+ text: JSON.stringify({
3788
+ success: true,
3789
+ scenarios: listAvailableScenarios(),
3790
+ description: "AI \u53EF\u4F7F\u7528\u8FD9\u4E9B\u573A\u666F\u540D\u79F0\u8C03\u7528 use_preset \u6216 query_mappings"
3791
+ }, null, 2)
3792
+ }]
3793
+ };
3794
+ }
3795
+
3796
+ // src/core/templates/discovery.ts
3797
+ import * as fs12 from "fs";
3798
+ import * as path11 from "path";
3799
+ var TEMPLATES_DIR = path11.resolve(
3800
+ path11.dirname(new URL(import.meta.url).pathname),
3801
+ "../../../../templates"
3802
+ );
3803
+ var templatesCache = null;
3804
+ function ensureCache2() {
3805
+ if (templatesCache) return;
3806
+ templatesCache = /* @__PURE__ */ new Map();
3807
+ scanTemplates(TEMPLATES_DIR, "");
3808
+ }
3809
+ function scanTemplates(dir, prefix) {
3810
+ if (!fs12.existsSync(dir)) return;
3811
+ const entries = fs12.readdirSync(dir, { withFileTypes: true });
3812
+ for (const entry of entries) {
3813
+ if (!entry.isDirectory()) continue;
3814
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
3815
+ const fullPath = path11.join(dir, entry.name);
3816
+ const templateId = prefix ? `${prefix}/${entry.name}` : entry.name;
3817
+ const configPath = path11.join(fullPath, "_CONFIG.md");
3818
+ if (fs12.existsSync(configPath)) {
3819
+ const metadata = parseConfigMd(configPath, templateId, fullPath);
3820
+ if (metadata) {
3821
+ templatesCache.set(templateId, metadata);
3822
+ }
3823
+ }
3824
+ scanTemplates(fullPath, templateId);
3825
+ }
3826
+ }
3827
+ function parseConfigMd(configPath, templateId, templateDir) {
3828
+ try {
3829
+ const content = fs12.readFileSync(configPath, "utf-8");
3830
+ const titleMatch = content.match(/^#\s+(.+)$/m);
3831
+ const name = titleMatch ? titleMatch[1].trim() : templateId;
3832
+ const descMatch = content.match(/^>\s*(.+)$/m);
3833
+ const description = descMatch ? descMatch[1].trim() : "";
3834
+ const frameworkMatch = content.match(/\*\*适用框架\*\*:\s*(.+)/i);
3835
+ const frameworks = frameworkMatch ? frameworkMatch[1].split(/[,\/+]/).map((f) => f.trim()) : [];
3836
+ const type = inferTemplateType(templateId, name);
3837
+ const files = getTemplateFiles(templateDir);
3838
+ const dependencies = extractDependencies(content);
3839
+ const pathMatch = content.match(/复制到.*?`([^`]+)`/i);
3840
+ const suggestedPath = pathMatch ? pathMatch[1] : void 0;
3841
+ return {
3842
+ id: templateId,
3843
+ name,
3844
+ description,
3845
+ frameworks,
3846
+ type,
3847
+ files,
3848
+ dependencies,
3849
+ configFile: "_CONFIG.md",
3850
+ suggestedPath,
3851
+ keywords: extractKeywords(name, description, frameworks)
3852
+ };
3853
+ } catch (error) {
3854
+ console.error(`\u89E3\u6790\u6A21\u677F\u914D\u7F6E\u5931\u8D25: ${configPath}`, error);
3855
+ return null;
3856
+ }
3857
+ }
3858
+ function inferTemplateType(templateId, name) {
3859
+ const lower = (templateId + name).toLowerCase();
3860
+ if (lower.includes("api") || lower.includes("request") || lower.includes("axios")) {
3861
+ return "api-layer";
3862
+ }
3863
+ if (lower.includes("component")) return "component";
3864
+ if (lower.includes("store") || lower.includes("pinia")) return "store";
3865
+ if (lower.includes("composable") || lower.includes("hook")) return "composable";
3866
+ if (lower.includes("config")) return "config";
3867
+ if (lower.includes("type")) return "types";
3868
+ return "other";
3869
+ }
3870
+ function getTemplateFiles(dir, prefix = "") {
3871
+ const files = [];
3872
+ const entries = fs12.readdirSync(dir, { withFileTypes: true });
3873
+ for (const entry of entries) {
3874
+ const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
3875
+ if (entry.name === "_CONFIG.md" || entry.name === "_template.json") {
3876
+ continue;
3877
+ }
3878
+ if (entry.isDirectory()) {
3879
+ files.push(...getTemplateFiles(path11.join(dir, entry.name), relativePath));
3880
+ } else {
3881
+ files.push(relativePath);
3882
+ }
3883
+ }
3884
+ return files;
3885
+ }
3886
+ function extractDependencies(content) {
3887
+ const depsMatch = content.match(/"dependencies":\s*\{([^}]+)\}/);
3888
+ if (!depsMatch) return void 0;
3889
+ const deps = {};
3890
+ const pairs = depsMatch[1].matchAll(/"([^"]+)":\s*"([^"]+)"/g);
3891
+ for (const match of pairs) {
3892
+ deps[match[1]] = match[2];
3893
+ }
3894
+ return Object.keys(deps).length > 0 ? deps : void 0;
3895
+ }
3896
+ function extractKeywords(name, description, frameworks) {
3897
+ const text = `${name} ${description}`.toLowerCase();
3898
+ const keywords = new Set(frameworks.map((f) => f.toLowerCase()));
3899
+ const commonKeywords = ["axios", "api", "mock", "request", "http", "fetch", "store", "pinia", "vuex"];
3900
+ for (const kw of commonKeywords) {
3901
+ if (text.includes(kw)) keywords.add(kw);
3902
+ }
3903
+ return Array.from(keywords);
3904
+ }
3905
+ function listAllTemplates() {
3906
+ ensureCache2();
3907
+ const result = [];
3908
+ for (const [id, metadata] of templatesCache) {
3909
+ result.push({
3910
+ id,
3911
+ name: metadata.name,
3912
+ description: metadata.description,
3913
+ frameworks: metadata.frameworks,
3914
+ type: metadata.type,
3915
+ fileCount: metadata.files.length,
3916
+ suggestedPath: metadata.suggestedPath
3917
+ });
3918
+ }
3919
+ return result;
3920
+ }
3921
+ function listTemplatesByType(type) {
3922
+ return listAllTemplates().filter((t) => t.type === type);
3923
+ }
3924
+ function listTemplatesByFramework(framework) {
3925
+ const lower = framework.toLowerCase();
3926
+ return listAllTemplates().filter(
3927
+ (t) => t.frameworks.some((f) => f.toLowerCase().includes(lower))
3928
+ );
3929
+ }
3930
+ function getTemplateById(templateId, includeFiles = false) {
3931
+ ensureCache2();
3932
+ const metadata = templatesCache.get(templateId);
3933
+ if (!metadata) return null;
3934
+ const templateDir = path11.join(TEMPLATES_DIR, templateId);
3935
+ const configPath = path11.join(templateDir, "_CONFIG.md");
3936
+ const configGuide = fs12.existsSync(configPath) ? fs12.readFileSync(configPath, "utf-8") : "";
3937
+ const result = {
3938
+ metadata,
3939
+ configGuide
3940
+ };
3941
+ if (includeFiles) {
3942
+ result.files = [];
3943
+ for (const filePath of metadata.files) {
3944
+ const fullPath = path11.join(templateDir, filePath);
3945
+ if (fs12.existsSync(fullPath)) {
3946
+ result.files.push({
3947
+ path: filePath,
3948
+ content: fs12.readFileSync(fullPath, "utf-8"),
3949
+ isConfig: filePath.startsWith("_")
3950
+ });
3951
+ }
3952
+ }
3953
+ }
3954
+ return result;
3955
+ }
3956
+ function getTemplateDir(templateId) {
3957
+ ensureCache2();
3958
+ if (!templatesCache.has(templateId)) return null;
3959
+ return path11.join(TEMPLATES_DIR, templateId);
3960
+ }
3961
+ function searchTemplates(query) {
3962
+ const lower = query.toLowerCase();
3963
+ return listAllTemplates().filter(
3964
+ (t) => t.id.toLowerCase().includes(lower) || t.name.toLowerCase().includes(lower) || t.description.toLowerCase().includes(lower) || t.frameworks.some((f) => f.toLowerCase().includes(lower))
3965
+ );
3966
+ }
3967
+
3968
+ // src/tools/listTemplates.ts
3969
+ async function listTemplates(args) {
3970
+ const logger3 = new ConsoleLogger();
3971
+ try {
3972
+ let templates;
3973
+ if (args.search) {
3974
+ templates = searchTemplates(args.search);
3975
+ } else if (args.type) {
3976
+ templates = listTemplatesByType(args.type);
3977
+ } else if (args.framework) {
3978
+ templates = listTemplatesByFramework(args.framework);
3979
+ } else {
3980
+ templates = listAllTemplates();
3981
+ }
3982
+ const grouped = {};
3983
+ for (const t of templates) {
3984
+ if (!grouped[t.type]) grouped[t.type] = [];
3985
+ grouped[t.type].push(t);
3986
+ }
3987
+ return {
3988
+ content: [{
3989
+ type: "text",
3990
+ text: JSON.stringify({
3991
+ success: true,
3992
+ total: templates.length,
3993
+ templates,
3994
+ byType: grouped,
3995
+ usage: {
3996
+ getDetails: 'get_template({ id: "\u6A21\u677FID" })',
3997
+ getWithFiles: 'get_template({ id: "\u6A21\u677FID", includeFiles: true })',
3998
+ note: "AI \u53EF\u76F4\u63A5\u8BFB\u53D6\u6A21\u677F\u6587\u4EF6\u5E76\u590D\u5236\u5230\u76EE\u6807\u9879\u76EE"
3999
+ }
4000
+ }, null, 2)
4001
+ }]
4002
+ };
4003
+ } catch (error) {
4004
+ logger3.error(`\u5217\u51FA\u6A21\u677F\u5931\u8D25: ${error}`);
4005
+ return {
4006
+ content: [{
4007
+ type: "text",
4008
+ text: JSON.stringify({
4009
+ error: error instanceof Error ? error.message : String(error)
4010
+ }, null, 2)
4011
+ }]
4012
+ };
4013
+ }
4014
+ }
4015
+
4016
+ // src/tools/getTemplate.ts
4017
+ async function getTemplate(args) {
4018
+ var _a;
4019
+ const logger3 = new ConsoleLogger();
4020
+ try {
4021
+ const result = getTemplateById(args.id, (_a = args.includeFiles) != null ? _a : false);
4022
+ if (!result) {
4023
+ return {
4024
+ content: [{
4025
+ type: "text",
4026
+ text: JSON.stringify({
4027
+ error: `\u6A21\u677F "${args.id}" \u4E0D\u5B58\u5728`,
4028
+ hint: "\u4F7F\u7528 list_templates \u67E5\u770B\u53EF\u7528\u6A21\u677F"
4029
+ }, null, 2)
4030
+ }]
4031
+ };
4032
+ }
4033
+ if (args.files && result.files) {
4034
+ result.files = result.files.filter(
4035
+ (f) => args.files.some(
4036
+ (requested) => f.path === requested || f.path.endsWith(requested)
4037
+ )
4038
+ );
4039
+ }
4040
+ const templateDir = getTemplateDir(args.id);
4041
+ return {
4042
+ content: [{
4043
+ type: "text",
4044
+ text: JSON.stringify({
4045
+ success: true,
4046
+ template: {
4047
+ ...result,
4048
+ absolutePath: templateDir
4049
+ },
4050
+ aiGuidance: {
4051
+ step1: "\u9605\u8BFB configGuide \u4E86\u89E3\u914D\u7F6E\u8981\u6C42",
4052
+ step2: "\u6839\u636E\u76EE\u6807\u9879\u76EE\u60C5\u51B5\u51B3\u5B9A\u5982\u4F55\u4FEE\u6539\u6A21\u677F",
4053
+ step3: "\u5C06\u6587\u4EF6\u590D\u5236\u5230\u76EE\u6807\u9879\u76EE\u5E76\u9002\u914D",
4054
+ note: "\u6A21\u677F\u6587\u4EF6\u53EF\u80FD\u9700\u8981\u6839\u636E\u9879\u76EE\u5B9E\u9645\u60C5\u51B5\u8C03\u6574\uFF08\u5982 UI \u6846\u67B6\u3001\u540E\u7AEF\u54CD\u5E94\u683C\u5F0F\u7B49\uFF09"
4055
+ }
4056
+ }, null, 2)
4057
+ }]
4058
+ };
4059
+ } catch (error) {
4060
+ logger3.error(`\u83B7\u53D6\u6A21\u677F\u5931\u8D25: ${error}`);
4061
+ return {
4062
+ content: [{
4063
+ type: "text",
4064
+ text: JSON.stringify({
4065
+ error: error instanceof Error ? error.message : String(error)
4066
+ }, null, 2)
4067
+ }]
4068
+ };
4069
+ }
4070
+ }
4071
+
4072
+ // src/core/errors.ts
4073
+ var ERROR_MESSAGES = {
4074
+ [1e3 /* UNKNOWN */]: "\u672A\u77E5\u9519\u8BEF",
4075
+ [1001 /* INVALID_PARAMETER */]: "\u53C2\u6570\u65E0\u6548",
4076
+ [1002 /* NOT_FOUND */]: "\u8D44\u6E90\u672A\u627E\u5230",
4077
+ [1003 /* PERMISSION_DENIED */]: "\u6743\u9650\u4E0D\u8DB3",
4078
+ [2001 /* PROJECT_NOT_FOUND */]: "\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728",
4079
+ [2002 /* PROJECT_PARSE_ERROR */]: "\u9879\u76EE\u89E3\u6790\u5931\u8D25",
4080
+ [2003 /* CONFIG_READ_ERROR */]: "\u914D\u7F6E\u6587\u4EF6\u8BFB\u53D6\u5931\u8D25",
4081
+ [3001 /* STANDARD_NOT_FOUND */]: "\u89C4\u8303\u672A\u627E\u5230",
4082
+ [3002 /* STANDARD_LOAD_ERROR */]: "\u89C4\u8303\u52A0\u8F7D\u5931\u8D25",
4083
+ [3003 /* PRESET_NOT_FOUND */]: "\u9884\u8BBE\u672A\u627E\u5230",
4084
+ [4001 /* TEMPLATE_NOT_FOUND */]: "\u6A21\u677F\u672A\u627E\u5230",
4085
+ [4002 /* TEMPLATE_PARSE_ERROR */]: "\u6A21\u677F\u89E3\u6790\u5931\u8D25",
4086
+ [5001 /* AGENT_NOT_FOUND */]: "Agent \u672A\u627E\u5230",
4087
+ [5002 /* AGENT_LOAD_ERROR */]: "Agent \u52A0\u8F7D\u5931\u8D25",
4088
+ [6001 /* CONFIG_GENERATE_ERROR */]: "\u914D\u7F6E\u751F\u6210\u5931\u8D25",
4089
+ [6002 /* FILE_WRITE_ERROR */]: "\u6587\u4EF6\u5199\u5165\u5931\u8D25"
4090
+ };
4091
+ var MCPError = class _MCPError extends Error {
4092
+ constructor(code, message, options) {
4093
+ const defaultMessage = ERROR_MESSAGES[code] || "\u672A\u77E5\u9519\u8BEF";
4094
+ super(message || defaultMessage);
4095
+ this.name = "MCPError";
4096
+ this.code = code;
4097
+ this.cause = options == null ? void 0 : options.cause;
4098
+ this.context = options == null ? void 0 : options.context;
4099
+ Object.setPrototypeOf(this, _MCPError.prototype);
4100
+ }
4101
+ /**
4102
+ * 转换为 JSON 格式(用于 MCP 响应)
4103
+ */
4104
+ toJSON() {
4105
+ return {
4106
+ error: true,
4107
+ code: this.code,
4108
+ message: this.message,
4109
+ ...this.context && { context: this.context }
4110
+ };
4111
+ }
4112
+ /**
4113
+ * 转换为 MCP 响应格式
4114
+ */
4115
+ toResponse() {
4116
+ return {
4117
+ content: [{
4118
+ type: "text",
4119
+ text: JSON.stringify(this.toJSON(), null, 2)
4120
+ }]
4121
+ };
4122
+ }
4123
+ };
4124
+ function errorResponse(error) {
4125
+ if (error instanceof MCPError) {
4126
+ return error.toResponse();
4127
+ }
4128
+ const message = error instanceof Error ? error.message : String(error);
4129
+ return {
4130
+ content: [{
4131
+ type: "text",
4132
+ text: JSON.stringify({
4133
+ error: true,
4134
+ code: 1e3 /* UNKNOWN */,
4135
+ message
4136
+ }, null, 2)
4137
+ }]
4138
+ };
4139
+ }
4140
+
4141
+ // src/core/logger.ts
4142
+ var LOG_LEVEL_NAMES = {
4143
+ [0 /* DEBUG */]: "DEBUG",
4144
+ [1 /* INFO */]: "INFO",
4145
+ [2 /* WARN */]: "WARN",
4146
+ [3 /* ERROR */]: "ERROR",
4147
+ [4 /* SILENT */]: "SILENT"
4148
+ };
4149
+ var globalConfig = {
4150
+ level: process.env.DEBUG ? 0 /* DEBUG */ : 1 /* INFO */,
4151
+ timestamp: false,
4152
+ prefix: "[MCP]"
4153
+ };
4154
+ var Logger = class _Logger {
4155
+ constructor(name, config) {
4156
+ this.name = name || "";
4157
+ this.config = { ...globalConfig, ...config };
4158
+ }
4159
+ /**
4160
+ * 格式化日志消息
4161
+ */
4162
+ format(level, message, ...args) {
4163
+ const parts = [];
4164
+ if (this.config.timestamp) {
4165
+ parts.push((/* @__PURE__ */ new Date()).toISOString());
4166
+ }
4167
+ parts.push(this.config.prefix);
4168
+ if (this.name) {
4169
+ parts.push(`[${this.name}]`);
4170
+ }
4171
+ parts.push(`[${LOG_LEVEL_NAMES[level]}]`);
4172
+ parts.push(message);
4173
+ if (args.length > 0) {
4174
+ const formatted = args.map((arg) => {
4175
+ if (typeof arg === "object") {
4176
+ try {
4177
+ return JSON.stringify(arg, null, 2);
4178
+ } catch {
4179
+ return String(arg);
4180
+ }
4181
+ }
4182
+ return String(arg);
4183
+ });
4184
+ parts.push(...formatted);
4185
+ }
4186
+ return parts.join(" ");
4187
+ }
4188
+ /**
4189
+ * 检查日志级别是否应该输出
4190
+ */
4191
+ shouldLog(level) {
4192
+ return level >= this.config.level;
4193
+ }
4194
+ /**
4195
+ * 调试日志
4196
+ */
4197
+ debug(message, ...args) {
4198
+ if (this.shouldLog(0 /* DEBUG */)) {
4199
+ console.error(this.format(0 /* DEBUG */, message, ...args));
4200
+ }
4201
+ }
4202
+ /**
4203
+ * 信息日志
4204
+ */
4205
+ info(message, ...args) {
4206
+ if (this.shouldLog(1 /* INFO */)) {
4207
+ console.error(this.format(1 /* INFO */, message, ...args));
4208
+ }
4209
+ }
4210
+ /**
4211
+ * 简化的 log 方法(等同于 info)
4212
+ */
4213
+ log(message, ...args) {
4214
+ this.info(message, ...args);
4215
+ }
4216
+ /**
4217
+ * 警告日志
4218
+ */
4219
+ warn(message, ...args) {
4220
+ if (this.shouldLog(2 /* WARN */)) {
4221
+ console.error(this.format(2 /* WARN */, message, ...args));
4222
+ }
4223
+ }
4224
+ /**
4225
+ * 错误日志
4226
+ */
4227
+ error(message, ...args) {
4228
+ if (this.shouldLog(3 /* ERROR */)) {
4229
+ console.error(this.format(3 /* ERROR */, message, ...args));
4230
+ }
4231
+ }
4232
+ /**
4233
+ * 创建子 Logger
4234
+ */
4235
+ child(name) {
4236
+ const childName = this.name ? `${this.name}:${name}` : name;
4237
+ return new _Logger(childName, this.config);
4238
+ }
4239
+ };
4240
+ var logger = new Logger();
4241
+ function createLogger(name) {
4242
+ return new Logger(name);
4243
+ }
4244
+
4245
+ // src/index.ts
4246
+ var SERVER_VERSION = "2.2.0";
4247
+ var logger2 = createLogger("Server");
4248
+ var CopilotPromptsMCPServer = class {
4249
+ constructor() {
4250
+ this.standardsManager = new StandardsManager();
4251
+ this.codeValidator = new CodeValidator();
4252
+ this.server = new Server(
4253
+ {
4254
+ name: "mta",
4255
+ version: SERVER_VERSION
4256
+ },
4257
+ {
4258
+ capabilities: {
4259
+ tools: {},
4260
+ resources: {}
4261
+ }
4262
+ }
4263
+ );
4264
+ this.setupToolHandlers();
4265
+ this.setupResourceHandlers();
4266
+ this.setupErrorHandlers();
4267
+ }
4268
+ /**
4269
+ * 设置错误处理器
4270
+ */
4271
+ setupErrorHandlers() {
4272
+ this.server.onerror = (error) => {
4273
+ logger2.error("MCP \u670D\u52A1\u5668\u9519\u8BEF", error);
4274
+ };
4275
+ process.on("SIGINT", async () => {
4276
+ logger2.info("\u6536\u5230\u5173\u95ED\u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...");
4277
+ await this.server.close();
4278
+ process.exit(0);
4279
+ });
4280
+ process.on("SIGTERM", async () => {
4281
+ logger2.info("\u6536\u5230\u7EC8\u6B62\u4FE1\u53F7\uFF0C\u6B63\u5728\u5173\u95ED\u670D\u52A1\u5668...");
4282
+ await this.server.close();
4283
+ process.exit(0);
4284
+ });
4285
+ process.on("uncaughtException", (error) => {
4286
+ logger2.error("\u672A\u6355\u83B7\u7684\u5F02\u5E38:", error);
4287
+ process.exit(1);
4288
+ });
4289
+ process.on("unhandledRejection", (reason, promise) => {
4290
+ logger2.error("\u672A\u5904\u7406\u7684 Promise \u62D2\u7EDD:", reason);
4291
+ process.exit(1);
4292
+ });
4293
+ }
4294
+ setupToolHandlers() {
4295
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
4296
+ tools: [
4297
+ {
4298
+ name: "analyze_project",
4299
+ description: "\u5206\u6790\u9879\u76EE\u7684\u6280\u672F\u6808\u3001\u6846\u67B6\u3001\u5DE5\u5177\u548C\u7279\u5F81\u3002\u81EA\u52A8\u68C0\u6D4B Vue\u3001React\u3001TypeScript \u7B49\u6280\u672F\u3002\u8DEF\u5F84\u53EF\u9009\uFF0C\u4E0D\u586B\u5219\u81EA\u52A8\u68C0\u6D4B\u5F53\u524D\u5DE5\u4F5C\u533A\u3002",
4300
+ inputSchema: {
4301
+ type: "object",
4302
+ properties: {
4303
+ projectPath: {
4304
+ type: "string",
4305
+ description: "\u9879\u76EE\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u4E0D\u586B\u5219\u4F7F\u7528\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55\uFF09\uFF0C\u4F8B\u5982: /Users/username/projects/my-app"
4306
+ }
4307
+ }
4308
+ }
4309
+ },
4310
+ {
4311
+ name: "auto_setup",
4312
+ description: "\u{1F3AF} \u4E00\u952E\u81EA\u52A8\u914D\u7F6E MCP \u670D\u52A1\u5668\u548C\u9879\u76EE\u89C4\u8303\u3002\u81EA\u52A8\u521B\u5EFA .vscode/mcp.json\u3001settings.json\u3001extensions.json\uFF0C\u5E76\u5206\u6790\u9879\u76EE\u751F\u6210 .github/copilot-instructions.md \u914D\u7F6E\u6587\u4EF6\u3002",
4313
+ inputSchema: {
4314
+ type: "object",
4315
+ properties: {
4316
+ workspacePath: {
4317
+ type: "string",
4318
+ description: "\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF0C\u4E0D\u586B\u5219\u4F7F\u7528\u5F53\u524D\u76EE\u5F55\uFF09"
4319
+ },
4320
+ generateInstructions: {
4321
+ type: "boolean",
4322
+ description: "\u662F\u5426\u81EA\u52A8\u751F\u6210 copilot-instructions.md\uFF08\u9ED8\u8BA4 true\uFF09",
4323
+ default: true
4324
+ }
4325
+ }
4326
+ }
4327
+ },
4328
+ {
4329
+ name: "health_check",
4330
+ description: "\u{1F3E5} \u68C0\u67E5 MCP \u670D\u52A1\u5668\u5065\u5EB7\u72B6\u6001\uFF0C\u8BCA\u65AD\u914D\u7F6E\u95EE\u9898\u3002\u8FD4\u56DE\u8BE6\u7EC6\u7684\u5065\u5EB7\u62A5\u544A\u548C\u4FEE\u590D\u5EFA\u8BAE\u3002",
4331
+ inputSchema: {
4332
+ type: "object",
4333
+ properties: {
4334
+ workspacePath: {
4335
+ type: "string",
4336
+ description: "\u5DE5\u4F5C\u533A\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09"
4337
+ },
4338
+ verbose: {
4339
+ type: "boolean",
4340
+ description: "\u662F\u5426\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F\uFF08\u9ED8\u8BA4 false\uFF09"
4341
+ }
4342
+ }
4343
+ }
4344
+ },
4345
+ {
4346
+ name: "get_smart_standards",
4347
+ description: "\u{1F9E0} \u96F6\u53C2\u6570\u667A\u80FD\u89C4\u8303\u63A8\u8350\u3002\u81EA\u52A8\u68C0\u6D4B\u5F53\u524D\u6587\u4EF6\u7C7B\u578B\u3001\u5BFC\u5165\u3001\u573A\u666F\uFF0C\u63A8\u8350\u6700\u76F8\u5173\u7684\u7F16\u7801\u89C4\u8303\u3002\u6BD4\u624B\u52A8\u6307\u5B9A\u53C2\u6570\u66F4\u7B80\u5355\u3002",
4348
+ inputSchema: {
4349
+ type: "object",
4350
+ properties: {
4351
+ currentFile: {
4352
+ type: "string",
4353
+ description: "\u5F53\u524D\u7F16\u8F91\u7684\u6587\u4EF6\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09"
4354
+ },
4355
+ fileContent: {
4356
+ type: "string",
4357
+ description: "\u6587\u4EF6\u5185\u5BB9\uFF08\u53EF\u9009\uFF0C\u7528\u4E8E\u5206\u6790\u5BFC\u5165\u548C\u573A\u666F\uFF09"
4358
+ }
4359
+ }
4360
+ }
4361
+ },
4362
+ {
4363
+ name: "use_preset",
4364
+ description: "\u26A1 \u4F7F\u7528\u9884\u8BBE\u573A\u666F\u5FEB\u6377\u83B7\u53D6\u89C4\u8303\u3002\u652F\u6301 vue3-component\u3001vue3-form\u3001pinia-store\u3001api-call \u7B49\u5E38\u89C1\u573A\u666F\uFF0C\u4E00\u952E\u83B7\u53D6\u3002",
4365
+ inputSchema: {
4366
+ type: "object",
4367
+ properties: {
4368
+ preset: {
4369
+ type: "string",
4370
+ enum: ["vue3-component", "vue3-form", "vue3-table", "pinia-store", "api-call", "typescript-strict", "i18n", "composable"],
4371
+ description: "\u9884\u8BBE\u573A\u666F ID"
4372
+ },
4373
+ customImports: {
4374
+ type: "array",
4375
+ items: { type: "string" },
4376
+ description: "\u989D\u5916\u7684\u5BFC\u5165\uFF08\u53EF\u9009\uFF09"
4377
+ }
4378
+ },
4379
+ required: ["preset"]
4380
+ }
4381
+ },
4382
+ {
4383
+ name: "list_presets",
4384
+ description: "\u{1F4CB} \u5217\u51FA\u6240\u6709\u53EF\u7528\u7684\u9884\u8BBE\u573A\u666F\u53CA\u5176\u8BF4\u660E\u3002",
4385
+ inputSchema: {
4386
+ type: "object",
4387
+ properties: {}
4388
+ }
4389
+ },
4390
+ {
4391
+ name: "match_agents",
4392
+ description: "\u6839\u636E\u9879\u76EE\u7279\u5F81\u667A\u80FD\u5339\u914D\u6700\u5408\u9002\u7684 Copilot Agents\u3002\u4F7F\u7528\u52A0\u6743\u8BC4\u5206\u7B97\u6CD5\u3002",
4393
+ inputSchema: {
4394
+ type: "object",
4395
+ properties: {
4396
+ projectFeatures: {
4397
+ type: "object",
4398
+ description: "\u9879\u76EE\u7279\u5F81\u5BF9\u8C61\uFF08\u4ECE analyze_project \u83B7\u53D6\uFF09",
4399
+ properties: {
4400
+ frameworks: { type: "array", items: { type: "string" } },
4401
+ languages: { type: "array", items: { type: "string" } },
4402
+ tools: { type: "array", items: { type: "string" } },
4403
+ keywords: { type: "array", items: { type: "string" } },
4404
+ projectType: { type: "string" }
4405
+ },
4406
+ required: ["frameworks", "languages", "tools", "keywords", "projectType"]
4407
+ },
4408
+ limit: {
4409
+ type: "number",
4410
+ description: "\u8FD4\u56DE\u7684\u6700\u5927 Agent \u6570\u91CF\uFF08\u9ED8\u8BA4 10\uFF09",
4411
+ default: 10
4412
+ }
4413
+ },
4414
+ required: ["projectFeatures"]
4415
+ }
4416
+ },
4417
+ {
4418
+ name: "list_available_agents",
4419
+ description: "\u83B7\u53D6\u6240\u6709\u53EF\u7528\u7684 Copilot Agents \u5217\u8868\uFF0C\u5305\u62EC\u540D\u79F0\u3001\u63CF\u8FF0\u3001\u8DEF\u5F84\u7B49\u4FE1\u606F\u3002",
4420
+ inputSchema: {
4421
+ type: "object",
4422
+ properties: {}
4423
+ }
4424
+ },
4425
+ {
4426
+ name: "generate_config",
4427
+ description: "\u4E3A\u9879\u76EE\u751F\u6210 Copilot \u914D\u7F6E\u6587\u4EF6\uFF08.github/copilot-instructions.md\uFF09\u3002\u53EF\u4EE5\u81EA\u52A8\u5339\u914D\u6216\u624B\u52A8\u6307\u5B9A Agents\u3002",
4428
+ inputSchema: {
4429
+ type: "object",
4430
+ properties: {
4431
+ projectPath: {
4432
+ type: "string",
4433
+ description: "\u9879\u76EE\u7684\u7EDD\u5BF9\u8DEF\u5F84"
4434
+ },
4435
+ agentIds: {
4436
+ type: "array",
4437
+ items: { type: "string" },
4438
+ description: "\u8981\u5E94\u7528\u7684 Agent ID \u5217\u8868\uFF08\u53EF\u9009\uFF0C\u5982\u4E0D\u63D0\u4F9B\u5219\u81EA\u52A8\u5339\u914D\uFF09"
4439
+ },
4440
+ autoMatch: {
4441
+ type: "boolean",
4442
+ description: "\u662F\u5426\u81EA\u52A8\u5339\u914D Agents\uFF08\u9ED8\u8BA4 true\uFF09",
4443
+ default: true
4444
+ },
4445
+ updateMode: {
4446
+ type: "string",
4447
+ enum: ["merge", "overwrite"],
4448
+ description: "\u66F4\u65B0\u6A21\u5F0F\uFF1Amerge-\u4FDD\u7559\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF08\u9ED8\u8BA4\uFF09\uFF0Coverwrite-\u5B8C\u5168\u8986\u76D6",
4449
+ default: "merge"
4450
+ },
4451
+ configId: {
4452
+ type: "string",
4453
+ description: "\u914D\u7F6E\u65B9\u6848ID\uFF08\u5982 strict\uFF09\uFF0C\u4F1A\u52A0\u8F7D\u5BF9\u5E94\u7684\u8BE6\u7EC6\u89C4\u5219"
4454
+ }
4455
+ },
4456
+ required: ["projectPath"]
4457
+ }
4458
+ },
4459
+ {
4460
+ name: "get_compact_standards",
4461
+ description: "\u{1F680} Token \u4F18\u5316\u7248\u89C4\u8303\u83B7\u53D6\u3002\u652F\u6301\u4E09\u79CD\u6A21\u5F0F\uFF1Asummary(~500 tokens)\u4EC5\u8FD4\u56DE\u89C4\u8303\u5217\u8868\u3001key-rules(~2000 tokens)\u8FD4\u56DE\u5173\u952E\u89C4\u5219\u6458\u8981\u3001full(\u5B8C\u6574\u5185\u5BB9)\u3002\u9ED8\u8BA4 key-rules \u6A21\u5F0F\uFF0C\u6BD4\u5B8C\u6574\u52A0\u8F7D\u8282\u7701 80%+ token\u3002",
4462
+ inputSchema: {
4463
+ type: "object",
4464
+ properties: {
4465
+ currentFile: {
4466
+ type: "string",
4467
+ description: "\u5F53\u524D\u6587\u4EF6\u8DEF\u5F84\uFF08\u53EF\u9009\uFF09"
4468
+ },
4469
+ fileContent: {
4470
+ type: "string",
4471
+ description: "\u6587\u4EF6\u5185\u5BB9\uFF08\u53EF\u9009\uFF0C\u7528\u4E8E\u5206\u6790\uFF09"
4472
+ },
4473
+ scenario: {
4474
+ type: "string",
4475
+ description: "\u5F00\u53D1\u573A\u666F\uFF08\u53EF\u9009\uFF09"
4476
+ },
4477
+ mode: {
4478
+ type: "string",
4479
+ enum: ["summary", "key-rules", "full"],
4480
+ description: "\u8FD4\u56DE\u6A21\u5F0F\uFF1Asummary(~500 tokens)\u3001key-rules(~2000 tokens\uFF0C\u9ED8\u8BA4)\u3001full(\u5B8C\u6574\u5185\u5BB9)",
4481
+ default: "key-rules"
4482
+ }
4483
+ }
4484
+ }
4485
+ },
4486
+ {
4487
+ name: "get_relevant_standards",
4488
+ description: "\u6839\u636E\u5F53\u524D\u5F00\u53D1\u4E0A\u4E0B\u6587\uFF0C\u83B7\u53D6\u76F8\u5173\u7684\u7F16\u7801\u89C4\u8303\uFF08\u5B8C\u6574\u5185\u5BB9\uFF09\u3002\u5982\u9700\u8282\u7701 token\uFF0C\u8BF7\u4F7F\u7528 get_compact_standards\u3002",
4489
+ inputSchema: {
4490
+ type: "object",
4491
+ properties: {
4492
+ fileType: {
4493
+ type: "string",
4494
+ description: "\u6587\u4EF6\u7C7B\u578B\uFF08\u5982 vue, ts, tsx, js\uFF09"
4495
+ },
4496
+ imports: {
4497
+ type: "array",
4498
+ items: { type: "string" },
4499
+ description: '\u6587\u4EF6\u4E2D\u7684 import \u8BED\u53E5\uFF08\u5982 ["vue", "pinia", "element-plus"]\uFF09\u3002\u5982\u679C\u672A\u63D0\u4F9B\u4E14\u63D0\u4F9B\u4E86 fileContent\uFF0C\u5C06\u81EA\u52A8\u68C0\u6D4B\u3002'
4500
+ },
4501
+ scenario: {
4502
+ type: "string",
4503
+ description: '\u5F00\u53D1\u573A\u666F\u63CF\u8FF0\uFF08\u5982 "\u521B\u5EFA\u8868\u5355\u7EC4\u4EF6", "API \u8C03\u7528", "\u72B6\u6001\u7BA1\u7406"\uFF09'
4504
+ },
4505
+ fileContent: {
4506
+ type: "string",
4507
+ description: "\u6587\u4EF6\u5185\u5BB9\uFF08\u53EF\u9009\uFF09\u3002\u63D0\u4F9B\u540E\u53EF\u81EA\u52A8\u68C0\u6D4B imports \u5E76\u6839\u636E\u5173\u952E\u8BCD\u667A\u80FD\u5339\u914D\u89C4\u8303\u3002"
4508
+ }
4509
+ }
4510
+ }
4511
+ },
4512
+ {
4513
+ name: "get_standards_stats",
4514
+ description: "\u83B7\u53D6\u89C4\u8303\u7CFB\u7EDF\u7684\u4F7F\u7528\u7EDF\u8BA1\u548C\u6027\u80FD\u6307\u6807\u3002\u7528\u4E8E\u4E86\u89E3\u6700\u5E38\u7528\u7684\u89C4\u8303\u7EC4\u5408\u3001\u7F13\u5B58\u547D\u4E2D\u7387\u3001Token \u8282\u7701\u60C5\u51B5\u7B49\u3002",
4515
+ inputSchema: {
4516
+ type: "object",
4517
+ properties: {
4518
+ includeCache: {
4519
+ type: "boolean",
4520
+ description: "\u662F\u5426\u5305\u542B\u7F13\u5B58\u8BE6\u7EC6\u4FE1\u606F\uFF08\u9ED8\u8BA4 false\uFF09"
4521
+ }
4522
+ }
4523
+ }
4524
+ },
4525
+ {
4526
+ name: "get_standard_by_id",
4527
+ description: "\u{1F4D6} \u6309 ID \u76F4\u63A5\u83B7\u53D6\u89C4\u8303\u3002AI \u77E5\u9053\u9700\u8981\u4EC0\u4E48\u89C4\u8303\u65F6\uFF0C\u76F4\u63A5\u6309 ID \u83B7\u53D6\uFF0C\u6700\u7B80\u6D01\u9AD8\u6548\u3002\u652F\u6301\u4E09\u79CD\u6A21\u5F0F\uFF1Asummary(\u6458\u8981)\u3001key-rules(\u5173\u952E\u89C4\u5219\uFF0C\u9ED8\u8BA4)\u3001full(\u5B8C\u6574\u5185\u5BB9)\u3002",
4528
+ inputSchema: {
4529
+ type: "object",
4530
+ properties: {
4531
+ id: {
4532
+ type: "string",
4533
+ description: "\u89C4\u8303 ID\uFF08\u5982 vue3-composition, element-plus, pinia\uFF09"
4534
+ },
4535
+ ids: {
4536
+ type: "array",
4537
+ items: { type: "string" },
4538
+ description: "\u591A\u4E2A\u89C4\u8303 ID\uFF0C\u6279\u91CF\u83B7\u53D6"
4539
+ },
4540
+ mode: {
4541
+ type: "string",
4542
+ enum: ["summary", "key-rules", "full"],
4543
+ description: "\u52A0\u8F7D\u6A21\u5F0F\uFF1Asummary(\u6458\u8981)\u3001key-rules(\u5173\u952E\u89C4\u5219\uFF0C\u9ED8\u8BA4)\u3001full(\u5B8C\u6574\u5185\u5BB9)",
4544
+ default: "key-rules"
4545
+ }
4546
+ }
4547
+ }
4548
+ },
4549
+ {
4550
+ name: "query_mappings",
4551
+ description: '\u{1F5FA}\uFE0F \u67E5\u8BE2\u573A\u666F-\u89C4\u8303\u6620\u5C04\u5173\u7CFB\u3002\u63D0\u4F9B\u6620\u5C04\u4FE1\u606F\u7ED9 AI \u53C2\u8003\uFF0CAI \u81EA\u5DF1\u51B3\u5B9A\u4F7F\u7528\u54EA\u4E9B\u89C4\u8303\u3002\u4E0D\u505A"\u667A\u80FD\u63A8\u8350"\uFF0C\u53EA\u63D0\u4F9B\u6570\u636E\u67E5\u8BE2\u3002',
4552
+ inputSchema: {
4553
+ type: "object",
4554
+ properties: {
4555
+ scenario: {
4556
+ type: "string",
4557
+ description: "\u573A\u666F\u540D\u79F0\uFF08\u5982 vue3-form, api-call, pinia-store\uFF09"
4558
+ },
4559
+ fileType: {
4560
+ type: "string",
4561
+ description: "\u6587\u4EF6\u7C7B\u578B\uFF08\u5982 vue, ts, tsx\uFF09"
4562
+ },
4563
+ imports: {
4564
+ type: "array",
4565
+ items: { type: "string" },
4566
+ description: "\u5BFC\u5165\u7684\u5305\uFF08\u5982 element-plus, pinia\uFF09"
4567
+ },
4568
+ listAll: {
4569
+ type: "boolean",
4570
+ description: "\u5217\u51FA\u6240\u6709\u6620\u5C04\u5173\u7CFB"
4571
+ }
4572
+ }
4573
+ }
4574
+ },
4575
+ {
4576
+ name: "list_scenarios",
4577
+ description: "\u{1F4CB} \u5217\u51FA\u6240\u6709\u53EF\u7528\u7684\u573A\u666F\u540D\u79F0\u3002AI \u53EF\u4F7F\u7528\u8FD9\u4E9B\u573A\u666F\u540D\u79F0\u8C03\u7528 use_preset \u6216 query_mappings\u3002",
4578
+ inputSchema: {
4579
+ type: "object",
4580
+ properties: {}
4581
+ }
4582
+ },
4583
+ {
4584
+ name: "list_templates",
4585
+ description: "\u{1F4E6} \u5217\u51FA\u53EF\u7528\u7684\u4EE3\u7801\u6A21\u677F\u3002\u6A21\u677F\u662F\u53EF\u590D\u7528\u7684\u4EE3\u7801\u7247\u6BB5\uFF0CAI \u53EF\u6839\u636E\u9700\u8981\u9009\u62E9\u5E76\u5E94\u7528\u5230\u76EE\u6807\u9879\u76EE\u3002",
4586
+ inputSchema: {
4587
+ type: "object",
4588
+ properties: {
4589
+ type: {
4590
+ type: "string",
4591
+ enum: ["api-layer", "component", "store", "composable", "config", "types", "other"],
4592
+ description: "\u6309\u7C7B\u578B\u7B5B\u9009"
4593
+ },
4594
+ framework: {
4595
+ type: "string",
4596
+ description: "\u6309\u6846\u67B6\u7B5B\u9009\uFF08\u5982 vue, react\uFF09"
4597
+ },
4598
+ search: {
4599
+ type: "string",
4600
+ description: "\u641C\u7D22\u5173\u952E\u8BCD"
4601
+ }
4602
+ }
4603
+ }
4604
+ },
4605
+ {
4606
+ name: "get_template",
4607
+ description: "\u{1F4C4} \u83B7\u53D6\u6A21\u677F\u8BE6\u60C5\u548C\u6587\u4EF6\u5185\u5BB9\u3002AI \u53EF\u6839\u636E\u914D\u7F6E\u8BF4\u660E\u81EA\u884C\u4FEE\u6539\u5E76\u5E94\u7528\u6A21\u677F\u3002",
4608
+ inputSchema: {
4609
+ type: "object",
4610
+ properties: {
4611
+ id: {
4612
+ type: "string",
4613
+ description: "\u6A21\u677F ID\uFF08\u5982 vue/api-layer\uFF09"
4614
+ },
4615
+ includeFiles: {
4616
+ type: "boolean",
4617
+ description: "\u662F\u5426\u5305\u542B\u6587\u4EF6\u5185\u5BB9\uFF08\u9ED8\u8BA4 false\uFF0C\u53EA\u8FD4\u56DE\u914D\u7F6E\u8BF4\u660E\uFF09",
4618
+ default: false
4619
+ },
4620
+ files: {
4621
+ type: "array",
4622
+ items: { type: "string" },
4623
+ description: "\u6307\u5B9A\u8981\u83B7\u53D6\u7684\u6587\u4EF6\u5217\u8868\uFF08\u53EF\u9009\uFF09"
4624
+ }
4625
+ },
4626
+ required: ["id"]
4627
+ }
4628
+ }
4629
+ ]
4630
+ }));
4631
+ this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
4632
+ try {
4633
+ const { name, arguments: args } = request.params;
4634
+ logger2.debug(`\u8C03\u7528\u5DE5\u5177: ${name}`);
4635
+ logger2.debug(`\u53C2\u6570:`, args);
4636
+ switch (name) {
4637
+ case "analyze_project":
4638
+ return await analyzeProject(args);
4639
+ case "auto_setup":
4640
+ return await autoSetup(args);
4641
+ case "health_check":
4642
+ return await healthCheck(args);
4643
+ case "get_smart_standards":
4644
+ return await getSmartStandards(args);
4645
+ case "use_preset":
4646
+ return await usePreset(args);
4647
+ case "list_presets":
4648
+ return await listPresets();
4649
+ case "match_agents":
4650
+ return await matchAgents(args);
4651
+ case "list_available_agents":
4652
+ return await listAvailableAgents();
4653
+ case "generate_config":
4654
+ return await generateConfig(args);
4655
+ case "get_compact_standards":
4656
+ return await getCompactStandards(args);
4657
+ case "get_relevant_standards":
4658
+ return this.getRelevantStandards(args);
4659
+ case "get_standards_stats":
4660
+ return this.getStandardsStats(args);
4661
+ case "get_standard_by_id":
4662
+ return await getStandardById(args);
4663
+ case "query_mappings":
4664
+ return await queryMappings(args);
4665
+ case "list_scenarios":
4666
+ return await listScenarios();
4667
+ case "list_templates":
4668
+ return await listTemplates(args);
4669
+ case "get_template":
4670
+ return await getTemplate(args);
4671
+ default:
4672
+ throw new Error(`\u672A\u77E5\u5DE5\u5177: ${name}`);
4673
+ }
4674
+ } catch (error) {
4675
+ logger2.error(`\u5DE5\u5177\u6267\u884C\u5931\u8D25:`, error);
4676
+ return errorResponse(error);
4677
+ }
4678
+ });
4679
+ }
4680
+ /**
4681
+ * 设置资源处理器
4682
+ */
4683
+ setupResourceHandlers() {
4684
+ this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
4685
+ const standards = this.standardsManager.getAvailableStandards();
4686
+ return {
4687
+ resources: standards.map((std) => ({
4688
+ uri: std.uri,
4689
+ name: std.name,
4690
+ description: std.description,
4691
+ mimeType: "text/markdown"
4692
+ }))
4693
+ };
4694
+ });
4695
+ this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
4696
+ const { uri } = request.params;
4697
+ try {
4698
+ const content = this.standardsManager.readStandard(uri);
4699
+ return {
4700
+ contents: [{
4701
+ uri,
4702
+ mimeType: "text/markdown",
4703
+ text: content
4704
+ }]
4705
+ };
4706
+ } catch (error) {
4707
+ throw new Error(`\u65E0\u6CD5\u8BFB\u53D6\u89C4\u8303 ${uri}: ${error}`);
4708
+ }
4709
+ });
4710
+ }
4711
+ /**
4712
+ * 获取相关编码规范
4713
+ */
4714
+ getRelevantStandards(args) {
4715
+ const standardUris = this.standardsManager.getRelevantStandards(args);
4716
+ const content = this.standardsManager.combineStandards(standardUris);
4717
+ return {
4718
+ content: [{
4719
+ type: "text",
4720
+ text: JSON.stringify({
4721
+ success: true,
4722
+ standards: standardUris,
4723
+ content,
4724
+ tokenEstimate: Math.ceil(content.length / 4),
4725
+ // 粗略估算 token 数
4726
+ message: `\u5DF2\u52A0\u8F7D ${standardUris.length} \u4E2A\u76F8\u5173\u89C4\u8303`
4727
+ }, null, 2)
4728
+ }]
4729
+ };
4730
+ }
4731
+ /**
4732
+ * 获取规范系统统计信息(Phase 3)
4733
+ */
4734
+ getStandardsStats(args) {
4735
+ const usageStats = this.standardsManager.getUsageStats();
4736
+ const performanceMetrics = this.standardsManager.getPerformanceMetrics();
4737
+ const result = {
4738
+ success: true,
4739
+ usage: usageStats,
4740
+ performance: performanceMetrics,
4741
+ summary: {
4742
+ totalCalls: usageStats.totalCalls,
4743
+ cacheHitRate: performanceMetrics.cacheHitRate,
4744
+ totalTokensSaved: performanceMetrics.totalTokensSaved,
4745
+ averageResponseTime: `${performanceMetrics.averageResponseTime.toFixed(2)}ms`
4746
+ }
4747
+ };
4748
+ if (args.includeCache) {
4749
+ result.cache = this.standardsManager.getCacheStats();
4750
+ }
4751
+ return {
4752
+ content: [{
4753
+ type: "text",
4754
+ text: JSON.stringify(result, null, 2)
4755
+ }]
4756
+ };
4757
+ }
4758
+ async run() {
4759
+ const transport = new StdioServerTransport();
4760
+ await this.server.connect(transport);
4761
+ logger2.info(`Copilot Prompts MCP Server v${SERVER_VERSION} \u5DF2\u542F\u52A8`);
4762
+ }
4763
+ };
4764
+ var server = new CopilotPromptsMCPServer();
4765
+ server.run().catch((error) => {
4766
+ logger2.error("\u670D\u52A1\u5668\u542F\u52A8\u5931\u8D25:", error);
4767
+ process.exit(1);
4768
+ });
4769
+ //# sourceMappingURL=index.js.map