mta-mcp 1.9.1 → 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.
- package/README.md +140 -2
- package/bin/mta.cjs +43 -0
- package/dist/index.cjs +4784 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4769 -0
- package/dist/index.js.map +1 -0
- package/package.json +44 -16
- package/build/core/agentTemplate.d.ts +0 -33
- package/build/core/agentTemplate.d.ts.map +0 -1
- package/build/core/agentTemplate.js +0 -158
- package/build/core/agentTemplate.js.map +0 -1
- package/build/core/autoInitializer.d.ts +0 -34
- package/build/core/autoInitializer.d.ts.map +0 -1
- package/build/core/autoInitializer.js +0 -145
- package/build/core/autoInitializer.js.map +0 -1
- package/build/core/codeValidator.d.ts +0 -82
- package/build/core/codeValidator.d.ts.map +0 -1
- package/build/core/codeValidator.js +0 -287
- package/build/core/codeValidator.js.map +0 -1
- package/build/core/githubClient.d.ts +0 -26
- package/build/core/githubClient.d.ts.map +0 -1
- package/build/core/githubClient.js +0 -60
- package/build/core/githubClient.js.map +0 -1
- package/build/core/i18nDetector.d.ts +0 -47
- package/build/core/i18nDetector.d.ts.map +0 -1
- package/build/core/i18nDetector.js +0 -314
- package/build/core/i18nDetector.js.map +0 -1
- package/build/core/projectContextManager.d.ts +0 -39
- package/build/core/projectContextManager.d.ts.map +0 -1
- package/build/core/projectContextManager.js +0 -147
- package/build/core/projectContextManager.js.map +0 -1
- package/build/core/smartAgentMatcher.d.ts +0 -51
- package/build/core/smartAgentMatcher.d.ts.map +0 -1
- package/build/core/smartAgentMatcher.js +0 -493
- package/build/core/smartAgentMatcher.js.map +0 -1
- package/build/core/standardsManager.d.ts +0 -130
- package/build/core/standardsManager.d.ts.map +0 -1
- package/build/core/standardsManager.js +0 -600
- package/build/core/standardsManager.js.map +0 -1
- package/build/core/types.d.ts +0 -55
- package/build/core/types.d.ts.map +0 -1
- package/build/core/types.js +0 -21
- package/build/core/types.js.map +0 -1
- package/build/index.d.ts +0 -3
- package/build/index.d.ts.map +0 -1
- package/build/index.js +0 -463
- package/build/index.js.map +0 -1
- package/build/tools/analyzeProject.d.ts +0 -12
- package/build/tools/analyzeProject.d.ts.map +0 -1
- package/build/tools/analyzeProject.js +0 -85
- package/build/tools/analyzeProject.js.map +0 -1
- package/build/tools/autoSetup.d.ts +0 -15
- package/build/tools/autoSetup.d.ts.map +0 -1
- package/build/tools/autoSetup.js +0 -291
- package/build/tools/autoSetup.js.map +0 -1
- package/build/tools/generateConfig.d.ts +0 -16
- package/build/tools/generateConfig.d.ts.map +0 -1
- package/build/tools/generateConfig.js +0 -379
- package/build/tools/generateConfig.js.map +0 -1
- package/build/tools/generateProjectAgent.d.ts +0 -15
- package/build/tools/generateProjectAgent.d.ts.map +0 -1
- package/build/tools/generateProjectAgent.js +0 -348
- package/build/tools/generateProjectAgent.js.map +0 -1
- package/build/tools/getCompactStandards.d.ts +0 -20
- package/build/tools/getCompactStandards.d.ts.map +0 -1
- package/build/tools/getCompactStandards.js +0 -367
- package/build/tools/getCompactStandards.js.map +0 -1
- package/build/tools/getSmartStandards.d.ts +0 -17
- package/build/tools/getSmartStandards.d.ts.map +0 -1
- package/build/tools/getSmartStandards.js +0 -190
- package/build/tools/getSmartStandards.js.map +0 -1
- package/build/tools/healthCheck.d.ts +0 -14
- package/build/tools/healthCheck.d.ts.map +0 -1
- package/build/tools/healthCheck.js +0 -237
- package/build/tools/healthCheck.js.map +0 -1
- package/build/tools/listAgents.d.ts +0 -10
- package/build/tools/listAgents.d.ts.map +0 -1
- package/build/tools/listAgents.js +0 -79
- package/build/tools/listAgents.js.map +0 -1
- package/build/tools/matchAgents.d.ts +0 -14
- package/build/tools/matchAgents.d.ts.map +0 -1
- package/build/tools/matchAgents.js +0 -70
- package/build/tools/matchAgents.js.map +0 -1
- package/build/tools/usePreset.d.ts +0 -23
- package/build/tools/usePreset.d.ts.map +0 -1
- package/build/tools/usePreset.js +0 -163
- package/build/tools/usePreset.js.map +0 -1
- package/src/core/autoInitializer.ts +0 -170
- package/src/core/codeValidator.ts +0 -357
- package/src/core/githubClient.ts +0 -64
- package/src/core/i18nDetector.ts +0 -357
- package/src/core/smartAgentMatcher.ts +0 -490
- package/src/core/standardsManager.ts +0 -769
- package/src/core/types.ts +0 -72
- package/src/index.ts +0 -519
- package/src/tools/analyzeProject.ts +0 -94
- package/src/tools/autoSetup.ts +0 -312
- package/src/tools/generateConfig.ts +0 -429
- package/src/tools/getCompactStandards.ts +0 -413
- package/src/tools/getSmartStandards.ts +0 -214
- package/src/tools/healthCheck.ts +0 -261
- package/src/tools/listAgents.ts +0 -91
- package/src/tools/matchAgents.ts +0 -80
- package/src/tools/usePreset.ts +0 -180
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
|
-
import { analyzeProject } from '../tools/analyzeProject.js';
|
|
4
|
-
import { generateConfig } from '../tools/generateConfig.js';
|
|
5
|
-
import { Logger } from './types.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* 自动初始化器
|
|
9
|
-
* 在工具调用前检查项目配置,如果不存在则自动生成
|
|
10
|
-
*/
|
|
11
|
-
export class AutoInitializer {
|
|
12
|
-
private initialized: Map<string, boolean> = new Map();
|
|
13
|
-
|
|
14
|
-
constructor(private logger?: Logger) {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 检查并初始化项目配置
|
|
18
|
-
* @param workspacePath 工作区路径
|
|
19
|
-
* @returns 是否需要初始化(返回 true 表示已执行初始化)
|
|
20
|
-
*/
|
|
21
|
-
async ensureProjectConfig(workspacePath?: string): Promise<{
|
|
22
|
-
needsInit: boolean;
|
|
23
|
-
initialized: boolean;
|
|
24
|
-
message: string;
|
|
25
|
-
}> {
|
|
26
|
-
// 检测工作区路径
|
|
27
|
-
const projectPath = workspacePath || this.detectWorkspacePath();
|
|
28
|
-
|
|
29
|
-
if (!projectPath) {
|
|
30
|
-
return {
|
|
31
|
-
needsInit: false,
|
|
32
|
-
initialized: false,
|
|
33
|
-
message: '未检测到工作区路径'
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 检查是否已经初始化过(避免重复)
|
|
38
|
-
if (this.initialized.get(projectPath)) {
|
|
39
|
-
return {
|
|
40
|
-
needsInit: false,
|
|
41
|
-
initialized: true,
|
|
42
|
-
message: `项目已配置: ${path.basename(projectPath)}`
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 检查是否存在配置文件
|
|
47
|
-
const configPath = path.join(projectPath, '.github', 'copilot-instructions.md');
|
|
48
|
-
const hasConfig = fs.existsSync(configPath);
|
|
49
|
-
|
|
50
|
-
if (hasConfig) {
|
|
51
|
-
this.initialized.set(projectPath, true);
|
|
52
|
-
return {
|
|
53
|
-
needsInit: false,
|
|
54
|
-
initialized: true,
|
|
55
|
-
message: `项目已有配置: ${path.basename(projectPath)}`
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 需要初始化
|
|
60
|
-
this.log(`🔍 检测到项目未配置,开始自动分析和生成配置...`);
|
|
61
|
-
this.log(`📁 项目路径: ${projectPath}`);
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
// 1. 分析项目
|
|
65
|
-
this.log('1️⃣ 分析项目技术栈...');
|
|
66
|
-
const analysisResult = await analyzeProject({ projectPath });
|
|
67
|
-
|
|
68
|
-
if (analysisResult.content?.[0]?.text) {
|
|
69
|
-
const analysis = JSON.parse(analysisResult.content[0].text);
|
|
70
|
-
this.log(`✅ 检测到: ${analysis.frameworks?.join(', ') || '未知技术栈'}`);
|
|
71
|
-
|
|
72
|
-
// 2. 生成配置
|
|
73
|
-
this.log('2️⃣ 生成项目配置文件...');
|
|
74
|
-
await generateConfig({
|
|
75
|
-
projectPath,
|
|
76
|
-
autoMatch: true
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
this.initialized.set(projectPath, true);
|
|
80
|
-
|
|
81
|
-
return {
|
|
82
|
-
needsInit: true,
|
|
83
|
-
initialized: true,
|
|
84
|
-
message: `✅ 项目配置已自动生成\n📁 路径: ${configPath}\n🎯 技术栈: ${analysis.frameworks?.join(', ')}`
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
} catch (error) {
|
|
88
|
-
this.log(`❌ 自动初始化失败: ${error}`);
|
|
89
|
-
return {
|
|
90
|
-
needsInit: true,
|
|
91
|
-
initialized: false,
|
|
92
|
-
message: `⚠️ 自动初始化失败: ${error instanceof Error ? error.message : String(error)}`
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
needsInit: true,
|
|
98
|
-
initialized: false,
|
|
99
|
-
message: '⚠️ 无法完成自动初始化'
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* 检测工作区路径
|
|
105
|
-
*/
|
|
106
|
-
private detectWorkspacePath(): string | null {
|
|
107
|
-
// 优先级 1: 环境变量
|
|
108
|
-
if (process.env.WORKSPACE_PATH) {
|
|
109
|
-
return process.env.WORKSPACE_PATH;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// 优先级 2: 当前工作目录
|
|
113
|
-
const cwd = process.cwd();
|
|
114
|
-
if (this.isValidProject(cwd)) {
|
|
115
|
-
return cwd;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// 优先级 3: 尝试从常见位置检测
|
|
119
|
-
const possiblePaths = [
|
|
120
|
-
path.join(cwd, '..'),
|
|
121
|
-
path.join(cwd, '../..'),
|
|
122
|
-
];
|
|
123
|
-
|
|
124
|
-
for (const possiblePath of possiblePaths) {
|
|
125
|
-
if (this.isValidProject(possiblePath)) {
|
|
126
|
-
return possiblePath;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* 判断是否是有效的项目目录
|
|
135
|
-
*/
|
|
136
|
-
private isValidProject(dirPath: string): boolean {
|
|
137
|
-
if (!fs.existsSync(dirPath)) {
|
|
138
|
-
return false;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// 检查是否有项目标志文件
|
|
142
|
-
const markers = [
|
|
143
|
-
'package.json',
|
|
144
|
-
'pubspec.yaml',
|
|
145
|
-
'pom.xml',
|
|
146
|
-
'go.mod',
|
|
147
|
-
'Cargo.toml',
|
|
148
|
-
'.git'
|
|
149
|
-
];
|
|
150
|
-
|
|
151
|
-
return markers.some(marker =>
|
|
152
|
-
fs.existsSync(path.join(dirPath, marker))
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* 重置初始化状态(用于测试)
|
|
158
|
-
*/
|
|
159
|
-
reset(): void {
|
|
160
|
-
this.initialized.clear();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private log(message: string): void {
|
|
164
|
-
if (this.logger) {
|
|
165
|
-
this.logger.log(message);
|
|
166
|
-
} else {
|
|
167
|
-
console.error(`[AutoInit] ${message}`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 代码验证器 (v1.1.0)
|
|
3
|
-
* 用于检测和防止常见的代码生成错误
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { ConsoleLogger } from './types.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 验证结果接口
|
|
10
|
-
*/
|
|
11
|
-
export interface ValidationResult {
|
|
12
|
-
isValid: boolean;
|
|
13
|
-
errors: ValidationError[];
|
|
14
|
-
warnings: ValidationWarning[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 验证错误
|
|
19
|
-
*/
|
|
20
|
-
export interface ValidationError {
|
|
21
|
-
type: 'syntax' | 'completeness' | 'compatibility';
|
|
22
|
-
message: string;
|
|
23
|
-
line?: number;
|
|
24
|
-
suggestion?: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 验证警告
|
|
29
|
-
*/
|
|
30
|
-
export interface ValidationWarning {
|
|
31
|
-
type: 'best-practice' | 'performance' | 'compatibility' | 'completeness';
|
|
32
|
-
message: string;
|
|
33
|
-
suggestion?: string;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 代码验证器类
|
|
38
|
-
*/
|
|
39
|
-
export class CodeValidator {
|
|
40
|
-
private logger: ConsoleLogger;
|
|
41
|
-
|
|
42
|
-
constructor(logger?: ConsoleLogger) {
|
|
43
|
-
this.logger = logger || new ConsoleLogger();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* 验证生成的配置文件内容
|
|
48
|
-
*/
|
|
49
|
-
validateConfigContent(content: string): ValidationResult {
|
|
50
|
-
const errors: ValidationError[] = [];
|
|
51
|
-
const warnings: ValidationWarning[] = [];
|
|
52
|
-
|
|
53
|
-
// 1. 检查重复标签闭合 (如 </style></style>)
|
|
54
|
-
this.checkDuplicateTags(content, errors);
|
|
55
|
-
|
|
56
|
-
// 2. 检查括号匹配
|
|
57
|
-
this.checkBracketMatching(content, errors);
|
|
58
|
-
|
|
59
|
-
// 3. 检查 Markdown 语法
|
|
60
|
-
this.checkMarkdownSyntax(content, errors);
|
|
61
|
-
|
|
62
|
-
// 4. 检查必要章节完整性
|
|
63
|
-
this.checkRequiredSections(content, warnings);
|
|
64
|
-
|
|
65
|
-
// 5. 检查自定义内容标记
|
|
66
|
-
this.checkCustomContentMarkers(content, warnings);
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
isValid: errors.length === 0,
|
|
70
|
-
errors,
|
|
71
|
-
warnings
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 检查重复的HTML标签
|
|
77
|
-
*/
|
|
78
|
-
private checkDuplicateTags(content: string, errors: ValidationError[]): void {
|
|
79
|
-
const lines = content.split('\n');
|
|
80
|
-
const tagPattern = /<\/([\w-]+)>/g;
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i < lines.length; i++) {
|
|
83
|
-
const line = lines[i];
|
|
84
|
-
const matches = Array.from(line.matchAll(tagPattern));
|
|
85
|
-
|
|
86
|
-
if (matches.length > 0) {
|
|
87
|
-
const tags = matches.map(m => m[1]);
|
|
88
|
-
const tagCounts = new Map<string, number>();
|
|
89
|
-
|
|
90
|
-
tags.forEach(tag => {
|
|
91
|
-
tagCounts.set(tag, (tagCounts.get(tag) || 0) + 1);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
tagCounts.forEach((count, tag) => {
|
|
95
|
-
if (count > 1) {
|
|
96
|
-
errors.push({
|
|
97
|
-
type: 'syntax',
|
|
98
|
-
message: `重复的闭合标签 </${tag}> 在同一行出现 ${count} 次`,
|
|
99
|
-
line: i + 1,
|
|
100
|
-
suggestion: `检查是否有多余的闭合标签,应该只保留一个 </${tag}>`
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* 检查括号匹配
|
|
110
|
-
*/
|
|
111
|
-
private checkBracketMatching(content: string, errors: ValidationError[]): void {
|
|
112
|
-
const brackets = {
|
|
113
|
-
'(': ')',
|
|
114
|
-
'[': ']',
|
|
115
|
-
'{': '}',
|
|
116
|
-
'<': '>'
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const stack: Array<{ char: string; line: number; col: number }> = [];
|
|
120
|
-
const lines = content.split('\n');
|
|
121
|
-
|
|
122
|
-
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
123
|
-
const line = lines[lineNum];
|
|
124
|
-
|
|
125
|
-
// 跳过代码块内容
|
|
126
|
-
if (line.trim().startsWith('```')) {
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// 跳过 Markdown blockquote 行(以 > 开头)
|
|
131
|
-
if (line.trim().startsWith('>')) {
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
for (let col = 0; col < line.length; col++) {
|
|
136
|
-
const char = line[col];
|
|
137
|
-
|
|
138
|
-
// 跳过 Markdown blockquote 的 > 符号
|
|
139
|
-
if (char === '>' && (col === 0 || line[col - 1] === ' ') &&
|
|
140
|
-
(col === line.length - 1 || line[col + 1] === ' ')) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (char in brackets) {
|
|
145
|
-
stack.push({ char, line: lineNum + 1, col: col + 1 });
|
|
146
|
-
} else if (Object.values(brackets).includes(char)) {
|
|
147
|
-
if (stack.length === 0) {
|
|
148
|
-
errors.push({
|
|
149
|
-
type: 'syntax',
|
|
150
|
-
message: `未配对的闭合括号 '${char}'`,
|
|
151
|
-
line: lineNum + 1,
|
|
152
|
-
suggestion: `检查是否缺少对应的开放括号`
|
|
153
|
-
});
|
|
154
|
-
} else {
|
|
155
|
-
const last = stack.pop()!;
|
|
156
|
-
const expectedClose = brackets[last.char as keyof typeof brackets];
|
|
157
|
-
|
|
158
|
-
if (char !== expectedClose) {
|
|
159
|
-
errors.push({
|
|
160
|
-
type: 'syntax',
|
|
161
|
-
message: `括号不匹配: 期望 '${expectedClose}' 但得到 '${char}'`,
|
|
162
|
-
line: lineNum + 1,
|
|
163
|
-
suggestion: `检查第 ${last.line} 行的 '${last.char}' 对应的闭合括号`
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// 检查未闭合的括号
|
|
172
|
-
if (stack.length > 0) {
|
|
173
|
-
stack.forEach(bracket => {
|
|
174
|
-
errors.push({
|
|
175
|
-
type: 'syntax',
|
|
176
|
-
message: `未闭合的括号 '${bracket.char}'`,
|
|
177
|
-
line: bracket.line,
|
|
178
|
-
suggestion: `添加对应的闭合括号 '${brackets[bracket.char as keyof typeof brackets]}'`
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* 检查 Markdown 语法
|
|
186
|
-
*/
|
|
187
|
-
private checkMarkdownSyntax(content: string, errors: ValidationError[]): void {
|
|
188
|
-
const lines = content.split('\n');
|
|
189
|
-
let inCodeBlock = false;
|
|
190
|
-
let codeBlockStart = 0;
|
|
191
|
-
|
|
192
|
-
for (let i = 0; i < lines.length; i++) {
|
|
193
|
-
const line = lines[i];
|
|
194
|
-
|
|
195
|
-
// 检查代码块标记
|
|
196
|
-
if (line.trim().startsWith('```')) {
|
|
197
|
-
if (inCodeBlock) {
|
|
198
|
-
inCodeBlock = false;
|
|
199
|
-
} else {
|
|
200
|
-
inCodeBlock = true;
|
|
201
|
-
codeBlockStart = i + 1;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// 如果代码块未闭合
|
|
207
|
-
if (inCodeBlock) {
|
|
208
|
-
errors.push({
|
|
209
|
-
type: 'syntax',
|
|
210
|
-
message: '未闭合的代码块',
|
|
211
|
-
line: codeBlockStart,
|
|
212
|
-
suggestion: '在代码块末尾添加 ``` 闭合标记'
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* 检查必要章节完整性
|
|
219
|
-
*/
|
|
220
|
-
private checkRequiredSections(content: string, warnings: ValidationWarning[]): void {
|
|
221
|
-
const requiredSections = [
|
|
222
|
-
{ pattern: /## ⚠️ 强制工作流/i, name: '强制工作流章节' },
|
|
223
|
-
{ pattern: /## 📚 配置的 Agents/i, name: 'Agents 配置章节' }
|
|
224
|
-
];
|
|
225
|
-
|
|
226
|
-
requiredSections.forEach(section => {
|
|
227
|
-
if (!section.pattern.test(content)) {
|
|
228
|
-
warnings.push({
|
|
229
|
-
type: 'completeness',
|
|
230
|
-
message: `缺少必要章节: ${section.name}`,
|
|
231
|
-
suggestion: '确保生成的配置文件包含所有必要的章节'
|
|
232
|
-
});
|
|
233
|
-
}
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* 检查自定义内容标记
|
|
239
|
-
*/
|
|
240
|
-
private checkCustomContentMarkers(content: string, warnings: ValidationWarning[]): void {
|
|
241
|
-
const hasCustomStart = content.includes('<!-- CUSTOM_START -->');
|
|
242
|
-
const hasCustomEnd = content.includes('<!-- CUSTOM_END -->');
|
|
243
|
-
|
|
244
|
-
if (hasCustomStart !== hasCustomEnd) {
|
|
245
|
-
warnings.push({
|
|
246
|
-
type: 'completeness',
|
|
247
|
-
message: 'CUSTOM 标记不完整',
|
|
248
|
-
suggestion: '确保 CUSTOM_START 和 CUSTOM_END 成对出现'
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* 验证 Agent 内容
|
|
255
|
-
*/
|
|
256
|
-
validateAgentContent(content: string, agentId: string): ValidationResult {
|
|
257
|
-
const errors: ValidationError[] = [];
|
|
258
|
-
const warnings: ValidationWarning[] = [];
|
|
259
|
-
|
|
260
|
-
// 检查 Agent 文件的特殊要求
|
|
261
|
-
if (!content.includes('⚠️ 强制工作流') && !content.includes('## 强制工作流')) {
|
|
262
|
-
warnings.push({
|
|
263
|
-
type: 'best-practice',
|
|
264
|
-
message: `Agent ${agentId} 缺少强制工作流说明`,
|
|
265
|
-
suggestion: '建议在 Agent 中包含 MCP 工具调用的强制说明'
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// 基本语法检查
|
|
270
|
-
const syntaxValidation = this.validateConfigContent(content);
|
|
271
|
-
errors.push(...syntaxValidation.errors);
|
|
272
|
-
warnings.push(...syntaxValidation.warnings);
|
|
273
|
-
|
|
274
|
-
return {
|
|
275
|
-
isValid: errors.length === 0,
|
|
276
|
-
errors,
|
|
277
|
-
warnings
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
/**
|
|
282
|
-
* 生成验证报告
|
|
283
|
-
*/
|
|
284
|
-
generateValidationReport(result: ValidationResult): string {
|
|
285
|
-
let report = '';
|
|
286
|
-
|
|
287
|
-
if (result.isValid && result.warnings.length === 0) {
|
|
288
|
-
report = '✅ 验证通过,未发现问题\n';
|
|
289
|
-
return report;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
if (!result.isValid) {
|
|
293
|
-
report += '❌ 验证失败,发现以下错误:\n\n';
|
|
294
|
-
result.errors.forEach((error, index) => {
|
|
295
|
-
report += `${index + 1}. [${error.type}] ${error.message}\n`;
|
|
296
|
-
if (error.line) {
|
|
297
|
-
report += ` 位置: 第 ${error.line} 行\n`;
|
|
298
|
-
}
|
|
299
|
-
if (error.suggestion) {
|
|
300
|
-
report += ` 建议: ${error.suggestion}\n`;
|
|
301
|
-
}
|
|
302
|
-
report += '\n';
|
|
303
|
-
});
|
|
304
|
-
} else {
|
|
305
|
-
report += '✅ 验证通过\n\n';
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (result.warnings.length > 0) {
|
|
309
|
-
report += '⚠️ 发现以下警告:\n\n';
|
|
310
|
-
result.warnings.forEach((warning, index) => {
|
|
311
|
-
report += `${index + 1}. [${warning.type}] ${warning.message}\n`;
|
|
312
|
-
if (warning.suggestion) {
|
|
313
|
-
report += ` 建议: ${warning.suggestion}\n`;
|
|
314
|
-
}
|
|
315
|
-
report += '\n';
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
return report;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* 尝试自动修复简单的语法错误
|
|
324
|
-
*/
|
|
325
|
-
attemptAutoFix(content: string): { fixed: boolean; content: string; changes: string[] } {
|
|
326
|
-
let fixedContent = content;
|
|
327
|
-
const changes: string[] = [];
|
|
328
|
-
|
|
329
|
-
// 1. 修复重复的闭合标签
|
|
330
|
-
const tagPattern = /(<\/([\w-]+)>)\1+/g;
|
|
331
|
-
const tagMatches = content.match(tagPattern);
|
|
332
|
-
if (tagMatches) {
|
|
333
|
-
fixedContent = fixedContent.replace(tagPattern, '$1');
|
|
334
|
-
changes.push(`修复了重复的闭合标签: ${tagMatches.join(', ')}`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// 2. 修复未闭合的代码块
|
|
338
|
-
const codeBlockCount = (fixedContent.match(/```/g) || []).length;
|
|
339
|
-
if (codeBlockCount % 2 !== 0) {
|
|
340
|
-
fixedContent += '\n```\n';
|
|
341
|
-
changes.push('添加了缺失的代码块闭合标记');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
return {
|
|
345
|
-
fixed: changes.length > 0,
|
|
346
|
-
content: fixedContent,
|
|
347
|
-
changes
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* 创建默认验证器实例
|
|
354
|
-
*/
|
|
355
|
-
export function createValidator(logger?: ConsoleLogger): CodeValidator {
|
|
356
|
-
return new CodeValidator(logger);
|
|
357
|
-
}
|
package/src/core/githubClient.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
import { Logger } from './types.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* GitHub 客户端(Node.js 版本,无 VS Code 依赖)
|
|
6
|
-
*/
|
|
7
|
-
export class GitHubClient {
|
|
8
|
-
private readonly owner = 'ForLear';
|
|
9
|
-
private readonly repo = 'copilot-prompts';
|
|
10
|
-
private readonly branch = 'main';
|
|
11
|
-
private readonly baseUrl = 'https://api.github.com';
|
|
12
|
-
private readonly rawBaseUrl = 'https://raw.githubusercontent.com';
|
|
13
|
-
|
|
14
|
-
constructor(private logger?: Logger) {}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 列出目录中的文件
|
|
18
|
-
*/
|
|
19
|
-
async listDirectoryFiles(dirPath: string): Promise<Array<{ name: string; path: string; type: string }>> {
|
|
20
|
-
const url = `${this.baseUrl}/repos/${this.owner}/${this.repo}/contents/${dirPath}?ref=${this.branch}`;
|
|
21
|
-
|
|
22
|
-
try {
|
|
23
|
-
const response = await axios.get(url, {
|
|
24
|
-
headers: {
|
|
25
|
-
'Accept': 'application/vnd.github.v3+json',
|
|
26
|
-
'User-Agent': 'Copilot-Prompts-MCP-Server'
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
if (Array.isArray(response.data)) {
|
|
31
|
-
return response.data.map((item: any) => ({
|
|
32
|
-
name: item.name,
|
|
33
|
-
path: item.path,
|
|
34
|
-
type: item.type
|
|
35
|
-
}));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return [];
|
|
39
|
-
} catch (error) {
|
|
40
|
-
this.logger?.error(`获取目录失败: ${error}`);
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 获取文件内容
|
|
47
|
-
*/
|
|
48
|
-
async fetchFileContent(filePath: string): Promise<string> {
|
|
49
|
-
const url = `${this.rawBaseUrl}/${this.owner}/${this.repo}/${this.branch}/${filePath}`;
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const response = await axios.get(url, {
|
|
53
|
-
headers: {
|
|
54
|
-
'User-Agent': 'Copilot-Prompts-MCP-Server'
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
return response.data;
|
|
59
|
-
} catch (error) {
|
|
60
|
-
this.logger?.error(`获取文件失败: ${filePath}`);
|
|
61
|
-
throw error;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|