mta-mcp 1.9.0 → 2.2.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 (117) hide show
  1. package/README.md +140 -2
  2. package/build/core/analyzers/eslint.d.ts +51 -0
  3. package/build/core/analyzers/eslint.d.ts.map +1 -0
  4. package/build/core/analyzers/eslint.js +259 -0
  5. package/build/core/analyzers/eslint.js.map +1 -0
  6. package/build/core/analyzers/index.d.ts +9 -0
  7. package/build/core/analyzers/index.d.ts.map +1 -0
  8. package/build/core/analyzers/index.js +9 -0
  9. package/build/core/analyzers/index.js.map +1 -0
  10. package/build/core/analyzers/registry.d.ts +59 -0
  11. package/build/core/analyzers/registry.d.ts.map +1 -0
  12. package/build/core/analyzers/registry.js +241 -0
  13. package/build/core/analyzers/registry.js.map +1 -0
  14. package/build/core/analyzers/tsconfig.d.ts +45 -0
  15. package/build/core/analyzers/tsconfig.d.ts.map +1 -0
  16. package/build/core/analyzers/tsconfig.js +197 -0
  17. package/build/core/analyzers/tsconfig.js.map +1 -0
  18. package/build/core/analyzers/types.d.ts +176 -0
  19. package/build/core/analyzers/types.d.ts.map +1 -0
  20. package/build/core/analyzers/types.js +39 -0
  21. package/build/core/analyzers/types.js.map +1 -0
  22. package/build/core/analyzers/vite.d.ts +46 -0
  23. package/build/core/analyzers/vite.d.ts.map +1 -0
  24. package/build/core/analyzers/vite.js +211 -0
  25. package/build/core/analyzers/vite.js.map +1 -0
  26. package/build/core/enhancedProjectAnalyzer.d.ts +102 -0
  27. package/build/core/enhancedProjectAnalyzer.d.ts.map +1 -0
  28. package/build/core/enhancedProjectAnalyzer.js +312 -0
  29. package/build/core/enhancedProjectAnalyzer.js.map +1 -0
  30. package/build/core/errors.d.ts +84 -0
  31. package/build/core/errors.d.ts.map +1 -0
  32. package/build/core/errors.js +151 -0
  33. package/build/core/errors.js.map +1 -0
  34. package/build/core/index.d.ts +11 -0
  35. package/build/core/index.d.ts.map +1 -0
  36. package/build/core/index.js +14 -0
  37. package/build/core/index.js.map +1 -0
  38. package/build/core/logger.d.ts +91 -0
  39. package/build/core/logger.d.ts.map +1 -0
  40. package/build/core/logger.js +164 -0
  41. package/build/core/logger.js.map +1 -0
  42. package/build/core/mappings/index.d.ts +5 -0
  43. package/build/core/mappings/index.d.ts.map +1 -0
  44. package/build/core/mappings/index.js +5 -0
  45. package/build/core/mappings/index.js.map +1 -0
  46. package/build/core/mappings/scenarioMappings.d.ts +51 -0
  47. package/build/core/mappings/scenarioMappings.d.ts.map +1 -0
  48. package/build/core/mappings/scenarioMappings.js +105 -0
  49. package/build/core/mappings/scenarioMappings.js.map +1 -0
  50. package/build/core/matching/index.d.ts +8 -0
  51. package/build/core/matching/index.d.ts.map +1 -0
  52. package/build/core/matching/index.js +8 -0
  53. package/build/core/matching/index.js.map +1 -0
  54. package/build/core/matching/intentAnalyzer.d.ts +78 -0
  55. package/build/core/matching/intentAnalyzer.d.ts.map +1 -0
  56. package/build/core/matching/intentAnalyzer.js +255 -0
  57. package/build/core/matching/intentAnalyzer.js.map +1 -0
  58. package/build/core/matching/standardMatcher.d.ts +101 -0
  59. package/build/core/matching/standardMatcher.d.ts.map +1 -0
  60. package/build/core/matching/standardMatcher.js +299 -0
  61. package/build/core/matching/standardMatcher.js.map +1 -0
  62. package/build/core/matching/weights.d.ts +64 -0
  63. package/build/core/matching/weights.d.ts.map +1 -0
  64. package/build/core/matching/weights.js +334 -0
  65. package/build/core/matching/weights.js.map +1 -0
  66. package/build/core/scenarioDetector.d.ts +2 -0
  67. package/build/core/scenarioDetector.d.ts.map +1 -0
  68. package/build/core/scenarioDetector.js +2 -0
  69. package/build/core/scenarioDetector.js.map +1 -0
  70. package/build/core/templates/discovery.d.ts +41 -0
  71. package/build/core/templates/discovery.d.ts.map +1 -0
  72. package/build/core/templates/discovery.js +262 -0
  73. package/build/core/templates/discovery.js.map +1 -0
  74. package/build/core/templates/types.d.ts +80 -0
  75. package/build/core/templates/types.d.ts.map +1 -0
  76. package/build/core/templates/types.js +10 -0
  77. package/build/core/templates/types.js.map +1 -0
  78. package/build/core/types.d.ts +2 -0
  79. package/build/core/types.d.ts.map +1 -1
  80. package/build/core/types.js +4 -3
  81. package/build/core/types.js.map +1 -1
  82. package/build/index.js +136 -23
  83. package/build/index.js.map +1 -1
  84. package/build/tools/getStandardById.d.ts +42 -0
  85. package/build/tools/getStandardById.d.ts.map +1 -0
  86. package/build/tools/getStandardById.js +289 -0
  87. package/build/tools/getStandardById.js.map +1 -0
  88. package/build/tools/getTemplate.d.ts +37 -0
  89. package/build/tools/getTemplate.d.ts.map +1 -0
  90. package/build/tools/getTemplate.js +78 -0
  91. package/build/tools/getTemplate.js.map +1 -0
  92. package/build/tools/listTemplates.d.ts +41 -0
  93. package/build/tools/listTemplates.d.ts.map +1 -0
  94. package/build/tools/listTemplates.js +81 -0
  95. package/build/tools/listTemplates.js.map +1 -0
  96. package/build/tools/queryMappings.d.ts +55 -0
  97. package/build/tools/queryMappings.d.ts.map +1 -0
  98. package/build/tools/queryMappings.js +119 -0
  99. package/build/tools/queryMappings.js.map +1 -0
  100. package/package.json +25 -8
  101. package/src/core/autoInitializer.ts +0 -170
  102. package/src/core/codeValidator.ts +0 -357
  103. package/src/core/githubClient.ts +0 -64
  104. package/src/core/i18nDetector.ts +0 -357
  105. package/src/core/smartAgentMatcher.ts +0 -490
  106. package/src/core/standardsManager.ts +0 -769
  107. package/src/core/types.ts +0 -72
  108. package/src/index.ts +0 -519
  109. package/src/tools/analyzeProject.ts +0 -94
  110. package/src/tools/autoSetup.ts +0 -312
  111. package/src/tools/generateConfig.ts +0 -429
  112. package/src/tools/getCompactStandards.ts +0 -413
  113. package/src/tools/getSmartStandards.ts +0 -225
  114. package/src/tools/healthCheck.ts +0 -261
  115. package/src/tools/listAgents.ts +0 -91
  116. package/src/tools/matchAgents.ts +0 -80
  117. package/src/tools/usePreset.ts +0 -180
@@ -1,490 +0,0 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- import glob from 'fast-glob';
4
- import { ProjectFeatures, AgentMetadata, Logger } from './types.js';
5
-
6
- /**
7
- * 工作区文件夹接口(简化版)
8
- */
9
- interface WorkspaceFolder {
10
- uri: { fsPath: string };
11
- name: string;
12
- }
13
-
14
- /**
15
- * 智能 Agent 匹配器
16
- * 根据项目特征自动推荐和应用合适的 Agents
17
- */
18
- export class SmartAgentMatcher {
19
- constructor(private logger?: Logger) {}
20
-
21
- /**
22
- * 分析项目特征
23
- */
24
- async analyzeProject(workspaceFolder: WorkspaceFolder): Promise<ProjectFeatures> {
25
- this.log(`🔍 开始分析项目: ${workspaceFolder.name}`);
26
-
27
- const features: ProjectFeatures = {
28
- frameworks: [],
29
- languages: [],
30
- tools: [],
31
- keywords: [],
32
- projectType: 'unknown'
33
- };
34
-
35
- const rootPath = workspaceFolder.uri.fsPath;
36
-
37
- // 优先检测 Flutter 项目
38
- const pubspecPath = path.join(rootPath, 'pubspec.yaml');
39
- if (fs.existsSync(pubspecPath)) {
40
- const pubspecFeatures = this.analyzePubspecYaml(pubspecPath);
41
- this.mergeFeatures(features, pubspecFeatures);
42
- features.projectType = 'flutter';
43
- this.log(`✅ 项目分析完成: ${features.projectType}`);
44
- return features;
45
- }
46
-
47
- // 分析 package.json
48
- const packageJsonPath = path.join(rootPath, 'package.json');
49
- if (fs.existsSync(packageJsonPath)) {
50
- const packageFeatures = this.analyzePackageJson(packageJsonPath);
51
- this.mergeFeatures(features, packageFeatures);
52
- }
53
-
54
- // 分析文件结构
55
- const structureFeatures = await this.analyzeFileStructure(rootPath);
56
- this.mergeFeatures(features, structureFeatures);
57
-
58
- // 推断项目类型
59
- features.projectType = this.inferProjectType(features);
60
-
61
- this.log(`✅ 项目分析完成: ${features.projectType}`);
62
-
63
- return features;
64
- }
65
-
66
- /**
67
- * 分析 package.json
68
- */
69
- private analyzePackageJson(packageJsonPath: string): Partial<ProjectFeatures> {
70
- const features: Partial<ProjectFeatures> = {
71
- frameworks: [],
72
- languages: [],
73
- tools: [],
74
- keywords: []
75
- };
76
-
77
- try {
78
- const content = fs.readFileSync(packageJsonPath, 'utf-8');
79
- const packageJson = JSON.parse(content);
80
-
81
- const allDeps = {
82
- ...packageJson.dependencies,
83
- ...packageJson.devDependencies
84
- };
85
-
86
- // 检测前端框架
87
- if (allDeps['vue']) features.frameworks!.push('Vue 3');
88
- if (allDeps['react']) features.frameworks!.push('React');
89
- if (allDeps['@angular/core']) features.frameworks!.push('Angular');
90
- if (allDeps['next']) features.frameworks!.push('Next.js');
91
- if (allDeps['nuxt']) features.frameworks!.push('Nuxt.js');
92
- if (allDeps['svelte']) features.frameworks!.push('Svelte');
93
- if (allDeps['solid-js']) features.frameworks!.push('Solid.js');
94
- if (allDeps['preact']) features.frameworks!.push('Preact');
95
- if (allDeps['remix']) features.frameworks!.push('Remix');
96
- if (allDeps['astro']) features.frameworks!.push('Astro');
97
-
98
- // 检测后端框架
99
- if (allDeps['express']) features.frameworks!.push('Express');
100
- if (allDeps['koa']) features.frameworks!.push('Koa');
101
- if (allDeps['fastify']) features.frameworks!.push('Fastify');
102
- if (allDeps['nestjs'] || allDeps['@nestjs/core']) features.frameworks!.push('NestJS');
103
- if (allDeps['egg']) features.frameworks!.push('Egg.js');
104
- if (allDeps['midway']) features.frameworks!.push('Midway');
105
- if (allDeps['hapi']) features.frameworks!.push('Hapi');
106
-
107
- // 检测全栈框架
108
- if (allDeps['meteor']) features.frameworks!.push('Meteor');
109
- if (allDeps['blitz']) features.frameworks!.push('Blitz.js');
110
-
111
- // 检测构建工具
112
- if (allDeps['vite']) features.tools!.push('Vite');
113
- if (allDeps['webpack']) features.tools!.push('Webpack');
114
- if (allDeps['rollup']) features.tools!.push('Rollup');
115
- if (allDeps['parcel']) features.tools!.push('Parcel');
116
- if (allDeps['esbuild']) features.tools!.push('ESBuild');
117
- if (allDeps['turbopack']) features.tools!.push('Turbopack');
118
-
119
- // 检测 UI 组件库
120
- if (allDeps['element-plus']) features.tools!.push('Element Plus');
121
- if (allDeps['ant-design-vue']) features.tools!.push('Ant Design Vue');
122
- if (allDeps['antd']) features.tools!.push('Ant Design');
123
- if (allDeps['@mui/material']) features.tools!.push('Material-UI');
124
- if (allDeps['naive-ui']) features.tools!.push('Naive UI');
125
- if (allDeps['vuetify']) features.tools!.push('Vuetify');
126
- if (allDeps['quasar']) features.tools!.push('Quasar');
127
- if (allDeps['primevue']) features.tools!.push('PrimeVue');
128
- if (allDeps['chakra-ui']) features.tools!.push('Chakra UI');
129
- if (allDeps['@headlessui/react'] || allDeps['@headlessui/vue']) features.tools!.push('Headless UI');
130
- if (allDeps['daisyui']) features.tools!.push('DaisyUI');
131
- if (allDeps['shadcn-ui'] || allDeps['@shadcn/ui']) features.tools!.push('Shadcn UI');
132
-
133
- // 检测样式工具
134
- if (allDeps['tailwindcss']) features.tools!.push('Tailwind CSS');
135
- if (allDeps['sass'] || allDeps['node-sass']) features.tools!.push('Sass');
136
- if (allDeps['less']) features.tools!.push('Less');
137
- if (allDeps['postcss']) features.tools!.push('PostCSS');
138
- if (allDeps['styled-components']) features.tools!.push('Styled Components');
139
- if (allDeps['emotion']) features.tools!.push('Emotion');
140
- if (allDeps['unocss']) features.tools!.push('UnoCSS');
141
-
142
- // 检测流程图/可视化库
143
- if (allDeps['@logicflow/core']) features.tools!.push('LogicFlow');
144
- if (allDeps['echarts']) features.tools!.push('ECharts');
145
- if (allDeps['d3']) features.tools!.push('D3.js');
146
- if (allDeps['chart.js']) features.tools!.push('Chart.js');
147
- if (allDeps['antv'] || allDeps['@antv/g6']) features.tools!.push('AntV');
148
-
149
- // 检测编程语言
150
- if (allDeps['typescript']) features.languages!.push('TypeScript');
151
- if (packageJson.dependencies?.['react'] || packageJson.devDependencies?.['react']) {
152
- features.languages!.push('JavaScript');
153
- }
154
-
155
- // 检测国际化
156
- if (allDeps['vue-i18n'] || allDeps['react-i18n'] || allDeps['i18next'] || allDeps['react-intl']) {
157
- features.keywords!.push('i18n');
158
- }
159
-
160
- // 检测状态管理
161
- if (allDeps['pinia'] || allDeps['vuex'] || allDeps['redux'] || allDeps['@reduxjs/toolkit'] ||
162
- allDeps['mobx'] || allDeps['zustand'] || allDeps['recoil'] || allDeps['jotai']) {
163
- features.keywords!.push('state-management');
164
- }
165
-
166
- // 检测路由
167
- if (allDeps['vue-router'] || allDeps['react-router'] || allDeps['react-router-dom'] ||
168
- allDeps['@tanstack/react-router']) {
169
- features.keywords!.push('routing');
170
- }
171
-
172
- // 检测数据请求
173
- if (allDeps['axios'] || allDeps['@tanstack/react-query'] || allDeps['@tanstack/vue-query'] ||
174
- allDeps['swr'] || allDeps['urql']) {
175
- features.keywords!.push('data-fetching');
176
- }
177
-
178
- // 检测表单处理
179
- if (allDeps['formik'] || allDeps['react-hook-form'] || allDeps['vee-validate'] ||
180
- allDeps['@vuelidate/core']) {
181
- features.keywords!.push('forms');
182
- }
183
-
184
- // 检测测试工具
185
- if (allDeps['vitest'] || allDeps['jest'] || allDeps['@testing-library/react'] ||
186
- allDeps['@testing-library/vue'] || allDeps['cypress'] || allDeps['playwright']) {
187
- features.keywords!.push('testing');
188
- }
189
-
190
- // 检测移动端
191
- if (allDeps['vant'] || allDeps['@tarojs/taro'] || allDeps['react-native'] ||
192
- allDeps['uni-app'] || allDeps['@nutui/nutui']) {
193
- features.keywords!.push('mobile');
194
- }
195
-
196
- // 检测微信小程序
197
- if (packageJson.miniprogram || allDeps['@tarojs/taro'] || allDeps['uni-app']) {
198
- features.keywords!.push('miniprogram');
199
- features.keywords!.push('wechat');
200
- }
201
-
202
- // 检测数据库/ORM
203
- if (allDeps['prisma'] || allDeps['typeorm'] || allDeps['sequelize'] || allDeps['mongoose']) {
204
- features.keywords!.push('database');
205
- }
206
-
207
- // 检测GraphQL
208
- if (allDeps['graphql'] || allDeps['apollo-client'] || allDeps['@apollo/client']) {
209
- features.keywords!.push('graphql');
210
- }
211
-
212
- } catch (error) {
213
- this.log(`解析 package.json 失败: ${error}`);
214
- }
215
-
216
- return features;
217
- }
218
-
219
- /**
220
- * 分析 pubspec.yaml (Flutter 项目)
221
- */
222
- private analyzePubspecYaml(pubspecPath: string): Partial<ProjectFeatures> {
223
- const features: Partial<ProjectFeatures> = {
224
- frameworks: ['Flutter'],
225
- languages: ['Dart'],
226
- tools: [],
227
- keywords: []
228
- };
229
-
230
- try {
231
- const content = fs.readFileSync(pubspecPath, 'utf-8');
232
-
233
- // 检测状态管理
234
- if (content.includes('provider:')) features.keywords!.push('state-management');
235
- if (content.includes('riverpod:')) features.keywords!.push('state-management');
236
- if (content.includes('bloc:') || content.includes('flutter_bloc:')) features.keywords!.push('state-management');
237
- if (content.includes('get:') || content.includes('get_x:')) {
238
- features.keywords!.push('routing', 'state-management');
239
- }
240
-
241
- // 检测国际化
242
- if (content.includes('flutter_localizations:') || content.includes('intl:') || content.includes('easy_localization:')) {
243
- features.keywords!.push('i18n');
244
- }
245
-
246
- // 检测路由
247
- if (content.includes('go_router:') || content.includes('auto_route:')) features.keywords!.push('routing');
248
-
249
- // 检测网络请求
250
- if (content.includes('dio:') || content.includes('http:')) features.keywords!.push('data-fetching');
251
-
252
- // 检测UI库
253
- if (content.includes('flutter_screenutil:')) features.tools!.push('ScreenUtil');
254
-
255
- // 检测测试
256
- if (content.includes('flutter_test:') || content.includes('mockito:') || content.includes('integration_test:')) {
257
- features.keywords!.push('testing');
258
- }
259
-
260
- } catch (error) {
261
- this.log(`解析 pubspec.yaml 失败: ${error}`);
262
- }
263
-
264
- return features;
265
- }
266
-
267
- /**
268
- * 分析文件结构
269
- */
270
- private async analyzeFileStructure(rootPath: string): Promise<Partial<ProjectFeatures>> {
271
- const features: Partial<ProjectFeatures> = {
272
- frameworks: [],
273
- languages: [],
274
- tools: [],
275
- keywords: []
276
- };
277
-
278
- try {
279
- const patterns = [
280
- '**/*.vue', '**/*.ts', '**/*.tsx', '**/*.jsx', '**/*.js',
281
- '**/*.py', '**/*.java', '**/*.go', '**/*.rs', '**/*.cpp', '**/*.c',
282
- '**/locales/**', '**/i18n/**', '**/lang/**',
283
- '**/stores/**', '**/store/**', '**/redux/**',
284
- '**/*.test.*', '**/*.spec.*',
285
- '**/components/**', '**/pages/**', '**/views/**'
286
- ];
287
-
288
- const files = await glob(patterns, {
289
- cwd: rootPath,
290
- ignore: ['**/node_modules/**', '**/dist/**', '**/build/**', '**/.git/**'],
291
- onlyFiles: true
292
- });
293
-
294
- // 检测前端框架
295
- if (files.some(f => f.endsWith('.vue'))) features.frameworks!.push('Vue');
296
- if (files.some(f => f.endsWith('.tsx'))) features.frameworks!.push('React');
297
- if (files.some(f => f.endsWith('.svelte'))) features.frameworks!.push('Svelte');
298
-
299
- // 检测编程语言
300
- if (files.some(f => f.endsWith('.ts') || f.endsWith('.tsx'))) features.languages!.push('TypeScript');
301
- if (files.some(f => f.endsWith('.js') || f.endsWith('.jsx'))) features.languages!.push('JavaScript');
302
- if (files.some(f => f.endsWith('.py'))) features.languages!.push('Python');
303
- if (files.some(f => f.endsWith('.java'))) features.languages!.push('Java');
304
- if (files.some(f => f.endsWith('.go'))) features.languages!.push('Go');
305
- if (files.some(f => f.endsWith('.rs'))) features.languages!.push('Rust');
306
- if (files.some(f => f.match(/\.(cpp|cc|cxx|c)$/))) features.languages!.push('C/C++');
307
-
308
- // 检测国际化
309
- if (files.some(f => f.includes('/locales/') || f.includes('/i18n/') || f.includes('/lang/'))) {
310
- features.keywords!.push('i18n');
311
- }
312
-
313
- // 检测状态管理
314
- if (files.some(f => f.includes('/stores/') || f.includes('/store/') || f.includes('/redux/'))) {
315
- features.keywords!.push('state-management');
316
- }
317
-
318
- // 检测测试文件
319
- if (files.some(f => f.includes('.test.') || f.includes('.spec.'))) {
320
- features.keywords!.push('testing');
321
- }
322
-
323
- } catch (error) {
324
- this.log(`扫描文件结构失败: ${error}`);
325
- }
326
-
327
- return features;
328
- }
329
-
330
- /**
331
- * 匹配 Agents
332
- */
333
- matchAgents(features: ProjectFeatures, availableAgents: AgentMetadata[]): AgentMetadata[] {
334
- const scoredAgents = availableAgents.map(agent => {
335
- const score = this.calculateMatchScore(features, agent);
336
- return { ...agent, score };
337
- });
338
-
339
- return scoredAgents
340
- .filter(a => a.score > 0)
341
- .sort((a, b) => (b.score || 0) - (a.score || 0));
342
- }
343
-
344
- /**
345
- * 计算匹配分数
346
- */
347
- private calculateMatchScore(features: ProjectFeatures, agent: AgentMetadata): number {
348
- let score = 0;
349
-
350
- const WEIGHTS = {
351
- framework: 10,
352
- tool: 8,
353
- language: 5,
354
- keyword: 3,
355
- tag: 2
356
- };
357
-
358
- // 框架匹配
359
- features.frameworks.forEach(f => {
360
- if (agent.applicableWhen?.frameworks?.some(af => af.toLowerCase().includes(f.toLowerCase()))) {
361
- score += WEIGHTS.framework;
362
- }
363
- });
364
-
365
- // 工具匹配
366
- features.tools.forEach(t => {
367
- if (agent.applicableWhen?.tools?.some(at => at.toLowerCase().includes(t.toLowerCase()))) {
368
- score += WEIGHTS.tool;
369
- }
370
- });
371
-
372
- // 语言匹配
373
- features.languages.forEach(l => {
374
- if (agent.applicableWhen?.languages?.some(al => al.toLowerCase().includes(l.toLowerCase()))) {
375
- score += WEIGHTS.language;
376
- }
377
- });
378
-
379
- // 关键词匹配
380
- features.keywords.forEach(k => {
381
- if (agent.applicableWhen?.keywords?.some(ak => ak.toLowerCase().includes(k.toLowerCase()))) {
382
- score += WEIGHTS.keyword;
383
- }
384
- });
385
-
386
- // 标签匹配
387
- features.frameworks.concat(features.tools, features.languages, features.keywords).forEach(feature => {
388
- if (agent.tags.some(tag => tag.toLowerCase().includes(feature.toLowerCase()))) {
389
- score += WEIGHTS.tag;
390
- }
391
- });
392
-
393
- return score;
394
- }
395
-
396
- /**
397
- * 解析 Agent 元数据
398
- */
399
- parseAgentMetadata(filePath: string, content: string): AgentMetadata {
400
- const id = path.basename(filePath, '.agent.md');
401
-
402
- // 解析 YAML frontmatter
403
- let description = '';
404
- let tags: string[] = [];
405
-
406
- if (content.startsWith('---')) {
407
- const endIndex = content.indexOf('---', 3);
408
- if (endIndex > 0) {
409
- const frontmatter = content.substring(3, endIndex);
410
- const descMatch = frontmatter.match(/description:\s*['"](.+)['"]/);
411
- if (descMatch) description = descMatch[1];
412
-
413
- const tagsMatch = frontmatter.match(/tags:\s*\[(.+)\]/);
414
- if (tagsMatch) {
415
- tags = tagsMatch[1].split(',').map(t => t.trim().replace(/['"]/g, ''));
416
- }
417
- }
418
- }
419
-
420
- // 提取标题
421
- const titleMatch = content.match(/^#\s+(.+)$/m);
422
- const title = titleMatch ? titleMatch[1] : id;
423
-
424
- return {
425
- id,
426
- path: filePath,
427
- title,
428
- description,
429
- tags,
430
- applicableWhen: {
431
- frameworks: tags.filter(t =>
432
- ['vue', 'vue3', 'react', 'angular', 'next', 'nuxt', 'svelte', 'flutter',
433
- 'express', 'nestjs', 'koa', 'fastify'].includes(t.toLowerCase())
434
- ),
435
- languages: tags.filter(t =>
436
- ['typescript', 'javascript', 'python', 'java', 'go', 'rust', 'dart', 'c++'].includes(t.toLowerCase())
437
- ),
438
- tools: tags.filter(t =>
439
- ['vite', 'webpack', 'rollup', 'logicflow', 'element-plus', 'antd',
440
- 'tailwind', 'sass', 'echarts', 'prisma', 'graphql'].includes(t.toLowerCase())
441
- ),
442
- keywords: tags.filter(t =>
443
- ['i18n', 'state-management', 'routing', 'testing', 'mobile', 'miniprogram',
444
- 'database', 'forms', 'data-fetching'].includes(t.toLowerCase())
445
- )
446
- }
447
- };
448
- }
449
-
450
- private mergeFeatures(target: ProjectFeatures, source: Partial<ProjectFeatures>): void {
451
- if (source.frameworks) target.frameworks.push(...source.frameworks);
452
- if (source.languages) target.languages.push(...source.languages);
453
- if (source.tools) target.tools.push(...source.tools);
454
- if (source.keywords) target.keywords.push(...source.keywords);
455
- }
456
-
457
- private inferProjectType(features: ProjectFeatures): string {
458
- // 前端框架
459
- if (features.frameworks.some(f => f.toLowerCase().includes('vue'))) return 'vue3';
460
- if (features.frameworks.some(f => f.toLowerCase().includes('react'))) return 'react';
461
- if (features.frameworks.some(f => f.toLowerCase().includes('angular'))) return 'angular';
462
- if (features.frameworks.some(f => f.toLowerCase().includes('svelte'))) return 'svelte';
463
- if (features.frameworks.some(f => f.toLowerCase().includes('next'))) return 'nextjs';
464
- if (features.frameworks.some(f => f.toLowerCase().includes('nuxt'))) return 'nuxtjs';
465
-
466
- // 移动端/跨平台
467
- if (features.frameworks.some(f => f.toLowerCase().includes('flutter'))) return 'flutter';
468
- if (features.frameworks.some(f => f.toLowerCase().includes('react-native'))) return 'react-native';
469
- if (features.keywords.includes('miniprogram')) return 'miniprogram';
470
-
471
- // 后端框架
472
- if (features.frameworks.some(f => f.toLowerCase().includes('nest'))) return 'nestjs';
473
- if (features.frameworks.some(f => f.toLowerCase().includes('express'))) return 'express';
474
- if (features.frameworks.some(f => f.toLowerCase().includes('koa'))) return 'koa';
475
- if (features.frameworks.some(f => f.toLowerCase().includes('fastify'))) return 'fastify';
476
-
477
- // 编程语言
478
- if (features.languages.includes('TypeScript')) return 'typescript';
479
- if (features.languages.includes('Python')) return 'python';
480
- if (features.languages.includes('Java')) return 'java';
481
- if (features.languages.includes('Go')) return 'go';
482
- if (features.languages.includes('Rust')) return 'rust';
483
-
484
- return 'general';
485
- }
486
-
487
- private log(message: string): void {
488
- this.logger?.log(message);
489
- }
490
- }