openmatrix 0.1.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 +512 -0
- package/dist/agents/agent-runner.d.ts +152 -0
- package/dist/agents/agent-runner.js +656 -0
- package/dist/agents/base-agent.d.ts +46 -0
- package/dist/agents/base-agent.js +17 -0
- package/dist/agents/impl/coder-agent.d.ts +17 -0
- package/dist/agents/impl/coder-agent.js +96 -0
- package/dist/agents/impl/executor-agent.d.ts +32 -0
- package/dist/agents/impl/executor-agent.js +168 -0
- package/dist/agents/impl/index.d.ts +6 -0
- package/dist/agents/impl/index.js +17 -0
- package/dist/agents/impl/planner-agent.d.ts +24 -0
- package/dist/agents/impl/planner-agent.js +126 -0
- package/dist/agents/impl/researcher-agent.d.ts +17 -0
- package/dist/agents/impl/researcher-agent.js +133 -0
- package/dist/agents/impl/reviewer-agent.d.ts +17 -0
- package/dist/agents/impl/reviewer-agent.js +120 -0
- package/dist/agents/impl/tester-agent.d.ts +17 -0
- package/dist/agents/impl/tester-agent.js +110 -0
- package/dist/cli/commands/approve.d.ts +2 -0
- package/dist/cli/commands/approve.js +87 -0
- package/dist/cli/commands/meeting.d.ts +2 -0
- package/dist/cli/commands/meeting.js +245 -0
- package/dist/cli/commands/report.d.ts +2 -0
- package/dist/cli/commands/report.js +202 -0
- package/dist/cli/commands/resume.d.ts +2 -0
- package/dist/cli/commands/resume.js +104 -0
- package/dist/cli/commands/retry.d.ts +2 -0
- package/dist/cli/commands/retry.js +79 -0
- package/dist/cli/commands/start.d.ts +2 -0
- package/dist/cli/commands/start.js +252 -0
- package/dist/cli/commands/status.d.ts +2 -0
- package/dist/cli/commands/status.js +226 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +26 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -0
- package/dist/orchestrator/ai-reviewer.d.ts +50 -0
- package/dist/orchestrator/ai-reviewer.js +326 -0
- package/dist/orchestrator/approval-manager.d.ts +62 -0
- package/dist/orchestrator/approval-manager.js +160 -0
- package/dist/orchestrator/executor.d.ts +114 -0
- package/dist/orchestrator/executor.js +325 -0
- package/dist/orchestrator/full-test-runner.d.ts +122 -0
- package/dist/orchestrator/full-test-runner.js +335 -0
- package/dist/orchestrator/git-commit-manager.d.ts +75 -0
- package/dist/orchestrator/git-commit-manager.js +248 -0
- package/dist/orchestrator/interactive-question-generator.d.ts +90 -0
- package/dist/orchestrator/interactive-question-generator.js +312 -0
- package/dist/orchestrator/meeting-manager.d.ts +85 -0
- package/dist/orchestrator/meeting-manager.js +222 -0
- package/dist/orchestrator/phase-executor.d.ts +198 -0
- package/dist/orchestrator/phase-executor.js +796 -0
- package/dist/orchestrator/question-generator.d.ts +22 -0
- package/dist/orchestrator/question-generator.js +102 -0
- package/dist/orchestrator/retry-manager.d.ts +41 -0
- package/dist/orchestrator/retry-manager.js +83 -0
- package/dist/orchestrator/scheduler.d.ts +62 -0
- package/dist/orchestrator/scheduler.js +148 -0
- package/dist/orchestrator/state-machine.d.ts +53 -0
- package/dist/orchestrator/state-machine.js +124 -0
- package/dist/orchestrator/task-parser.d.ts +7 -0
- package/dist/orchestrator/task-parser.js +63 -0
- package/dist/orchestrator/task-planner.d.ts +71 -0
- package/dist/orchestrator/task-planner.js +316 -0
- package/dist/storage/file-store.d.ts +12 -0
- package/dist/storage/file-store.js +80 -0
- package/dist/storage/state-manager.d.ts +31 -0
- package/dist/storage/state-manager.js +202 -0
- package/dist/types/index.d.ts +193 -0
- package/dist/types/index.js +30 -0
- package/dist/utils/logger.d.ts +41 -0
- package/dist/utils/logger.js +166 -0
- package/dist/utils/progress-reporter.d.ts +116 -0
- package/dist/utils/progress-reporter.js +287 -0
- package/package.json +50 -0
- package/scripts/build-check.js +19 -0
- package/scripts/install-skills.js +51 -0
- package/skills/approve.md +253 -0
- package/skills/meeting.md +346 -0
- package/skills/report.md +100 -0
- package/skills/resume.md +68 -0
- package/skills/retry.md +61 -0
- package/skills/start.md +449 -0
- package/skills/status.md +46 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AgentRunner = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* AgentRunner - 使用 Subagent 执行任务
|
|
6
|
+
*
|
|
7
|
+
* 通过 Claude Code 的 Agent 工具启动子 Agent 执行任务
|
|
8
|
+
*
|
|
9
|
+
* 增强版特性:
|
|
10
|
+
* - 注入用户上下文到提示词
|
|
11
|
+
* - 注入验收标准
|
|
12
|
+
* - 注入代码上下文
|
|
13
|
+
*/
|
|
14
|
+
class AgentRunner {
|
|
15
|
+
stateManager;
|
|
16
|
+
approvalManager;
|
|
17
|
+
config;
|
|
18
|
+
runningAgents = new Map();
|
|
19
|
+
userContext = {};
|
|
20
|
+
constructor(stateManager, approvalManager, config) {
|
|
21
|
+
this.stateManager = stateManager;
|
|
22
|
+
this.approvalManager = approvalManager;
|
|
23
|
+
this.config = {
|
|
24
|
+
maxConcurrent: 3,
|
|
25
|
+
taskTimeout: 120000,
|
|
26
|
+
...config
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 设置用户上下文
|
|
31
|
+
*/
|
|
32
|
+
setUserContext(context) {
|
|
33
|
+
this.userContext = context;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 获取用户上下文
|
|
37
|
+
*/
|
|
38
|
+
getUserContext() {
|
|
39
|
+
return this.userContext;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 准备 Subagent 任务配置
|
|
43
|
+
*
|
|
44
|
+
* 返回可用于 Agent 工具调用的完整配置
|
|
45
|
+
*/
|
|
46
|
+
async prepareSubagentTask(task) {
|
|
47
|
+
const subagentType = this.mapAgentType(task.assignedAgent);
|
|
48
|
+
const prompt = this.buildExecutionPrompt(task);
|
|
49
|
+
const needsIsolation = this.needsIsolation(task);
|
|
50
|
+
console.log(`🤖 Preparing ${task.assignedAgent} subagent for task ${task.id}`);
|
|
51
|
+
return {
|
|
52
|
+
subagent_type: subagentType,
|
|
53
|
+
description: `${task.assignedAgent}: ${task.title.slice(0, 50)}`,
|
|
54
|
+
prompt,
|
|
55
|
+
isolation: needsIsolation ? 'worktree' : undefined,
|
|
56
|
+
taskId: task.id,
|
|
57
|
+
agentType: task.assignedAgent,
|
|
58
|
+
timeout: task.timeout,
|
|
59
|
+
needsApproval: false
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 批量准备 Subagent 任务
|
|
64
|
+
*/
|
|
65
|
+
async prepareSubagentTasks(tasks) {
|
|
66
|
+
const results = [];
|
|
67
|
+
for (const task of tasks) {
|
|
68
|
+
if (this.canStartNew()) {
|
|
69
|
+
const subagentTask = await this.prepareSubagentTask(task);
|
|
70
|
+
results.push(subagentTask);
|
|
71
|
+
this.runningAgents.set(task.id, subagentTask);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return results;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 映射 OpenMatrix Agent 类型到 Claude Code Subagent 类型
|
|
78
|
+
*/
|
|
79
|
+
mapAgentType(agentType) {
|
|
80
|
+
const mapping = {
|
|
81
|
+
planner: 'Plan',
|
|
82
|
+
coder: 'general-purpose',
|
|
83
|
+
tester: 'general-purpose',
|
|
84
|
+
reviewer: 'general-purpose',
|
|
85
|
+
researcher: 'Explore',
|
|
86
|
+
executor: 'general-purpose'
|
|
87
|
+
};
|
|
88
|
+
return mapping[agentType] || 'general-purpose';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 判断任务是否需要隔离执行
|
|
92
|
+
*/
|
|
93
|
+
needsIsolation(task) {
|
|
94
|
+
// Coder 和 Executor 任务可能修改文件,建议隔离
|
|
95
|
+
const isolationTypes = ['coder', 'executor'];
|
|
96
|
+
return isolationTypes.includes(task.assignedAgent);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* 构建完整的执行提示词
|
|
100
|
+
*/
|
|
101
|
+
buildExecutionPrompt(task) {
|
|
102
|
+
const agentPrompt = this.buildAgentPrompt(task);
|
|
103
|
+
const phaseContext = this.buildPhaseContext(task);
|
|
104
|
+
return `# 任务执行
|
|
105
|
+
|
|
106
|
+
## 任务信息
|
|
107
|
+
- ID: ${task.id}
|
|
108
|
+
- 标题: ${task.title}
|
|
109
|
+
- 描述: ${task.description}
|
|
110
|
+
- 优先级: ${task.priority}
|
|
111
|
+
- 超时: ${task.timeout / 1000} 秒
|
|
112
|
+
|
|
113
|
+
## 当前阶段
|
|
114
|
+
${phaseContext}
|
|
115
|
+
|
|
116
|
+
## 依赖任务
|
|
117
|
+
${task.dependencies.length > 0
|
|
118
|
+
? task.dependencies.map(d => `- ${d}`).join('\n')
|
|
119
|
+
: '无依赖'}
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
${agentPrompt.context}
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
${agentPrompt.instructions}
|
|
128
|
+
|
|
129
|
+
## 完成要求
|
|
130
|
+
|
|
131
|
+
1. 完成任务后,更新任务状态文件: \`.openmatrix/tasks/${task.id}/task.json\`
|
|
132
|
+
2. 将执行结果写入: \`.openmatrix/tasks/${task.id}/artifacts/result.md\`
|
|
133
|
+
3. 如需审批,创建审批请求: \`.openmatrix/approvals/\` 目录
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 构建阶段上下文
|
|
138
|
+
*/
|
|
139
|
+
buildPhaseContext(task) {
|
|
140
|
+
const phases = task.phases;
|
|
141
|
+
const currentPhase = this.getCurrentPhase(task);
|
|
142
|
+
return `当前阶段: **${currentPhase}**
|
|
143
|
+
- 开发阶段: ${phases.develop.status}
|
|
144
|
+
- 验证阶段: ${phases.verify.status}
|
|
145
|
+
- 验收阶段: ${phases.accept.status}`;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 获取当前阶段
|
|
149
|
+
*/
|
|
150
|
+
getCurrentPhase(task) {
|
|
151
|
+
const phases = task.phases;
|
|
152
|
+
if (phases.develop.status !== 'completed')
|
|
153
|
+
return '开发 (Develop)';
|
|
154
|
+
if (phases.verify.status !== 'completed')
|
|
155
|
+
return '验证 (Verify)';
|
|
156
|
+
if (phases.accept.status !== 'completed')
|
|
157
|
+
return '验收 (Accept)';
|
|
158
|
+
return '已完成';
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 执行任务 - 返回 Subagent 调用提示 (向后兼容)
|
|
162
|
+
* @deprecated 使用 prepareSubagentTask() 代替
|
|
163
|
+
*/
|
|
164
|
+
async runTask(task) {
|
|
165
|
+
const startTime = Date.now();
|
|
166
|
+
try {
|
|
167
|
+
// 准备 Subagent 任务
|
|
168
|
+
const subagentTask = await this.prepareSubagentTask(task);
|
|
169
|
+
// 返回结果配置
|
|
170
|
+
const result = {
|
|
171
|
+
runId: await this.generateRunId(),
|
|
172
|
+
taskId: task.id,
|
|
173
|
+
agentType: task.assignedAgent,
|
|
174
|
+
status: 'completed',
|
|
175
|
+
output: `Subagent task prepared. Use Agent tool with:\n${JSON.stringify({
|
|
176
|
+
subagent_type: subagentTask.subagent_type,
|
|
177
|
+
description: subagentTask.description,
|
|
178
|
+
prompt: subagentTask.prompt.substring(0, 200) + '...'
|
|
179
|
+
}, null, 2)}`,
|
|
180
|
+
artifacts: [],
|
|
181
|
+
needsApproval: subagentTask.needsApproval,
|
|
182
|
+
duration: 0,
|
|
183
|
+
completedAt: new Date().toISOString()
|
|
184
|
+
};
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
runId: await this.generateRunId(),
|
|
190
|
+
taskId: task.id,
|
|
191
|
+
agentType: task.assignedAgent,
|
|
192
|
+
status: 'failed',
|
|
193
|
+
output: '',
|
|
194
|
+
artifacts: [],
|
|
195
|
+
needsApproval: false,
|
|
196
|
+
error: error instanceof Error ? error.message : String(error),
|
|
197
|
+
duration: Date.now() - startTime,
|
|
198
|
+
completedAt: new Date().toISOString()
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* 构建 Agent 提示词
|
|
204
|
+
*/
|
|
205
|
+
buildAgentPrompt(task) {
|
|
206
|
+
const agentPrompts = {
|
|
207
|
+
planner: this.getPlannerPrompt(task),
|
|
208
|
+
coder: this.getCoderPrompt(task),
|
|
209
|
+
tester: this.getTesterPrompt(task),
|
|
210
|
+
reviewer: this.getReviewerPrompt(task),
|
|
211
|
+
researcher: this.getResearcherPrompt(task),
|
|
212
|
+
executor: this.getExecutorPrompt(task)
|
|
213
|
+
};
|
|
214
|
+
return {
|
|
215
|
+
task,
|
|
216
|
+
context: this.buildContext(task),
|
|
217
|
+
instructions: agentPrompts[task.assignedAgent]
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* 构建任务上下文 (增强版: 注入用户上下文)
|
|
222
|
+
*/
|
|
223
|
+
buildContext(task) {
|
|
224
|
+
const parts = [];
|
|
225
|
+
parts.push(`
|
|
226
|
+
## 任务信息
|
|
227
|
+
|
|
228
|
+
- ID: ${task.id}
|
|
229
|
+
- 标题: ${task.title}
|
|
230
|
+
- 描述: ${task.description}
|
|
231
|
+
- 优先级: ${task.priority}
|
|
232
|
+
- 超时: ${task.timeout}ms
|
|
233
|
+
|
|
234
|
+
## 依赖
|
|
235
|
+
|
|
236
|
+
${task.dependencies.length > 0
|
|
237
|
+
? task.dependencies.map(d => `- ${d}`).join('\n')
|
|
238
|
+
: '无依赖'}
|
|
239
|
+
|
|
240
|
+
## 约束
|
|
241
|
+
|
|
242
|
+
- 最大执行时间: ${task.timeout / 1000} 秒
|
|
243
|
+
- 失败重试次数: 3
|
|
244
|
+
`);
|
|
245
|
+
// 注入用户上下文
|
|
246
|
+
if (this.userContext.objective) {
|
|
247
|
+
parts.push(`
|
|
248
|
+
## 整体目标
|
|
249
|
+
|
|
250
|
+
${this.userContext.objective}
|
|
251
|
+
`);
|
|
252
|
+
}
|
|
253
|
+
if (this.userContext.techStack && this.userContext.techStack.length > 0) {
|
|
254
|
+
parts.push(`
|
|
255
|
+
## 技术栈要求
|
|
256
|
+
|
|
257
|
+
${this.userContext.techStack.map(t => `- ${t}`).join('\n')}
|
|
258
|
+
`);
|
|
259
|
+
}
|
|
260
|
+
if (this.userContext.testCoverage) {
|
|
261
|
+
parts.push(`
|
|
262
|
+
## 测试要求
|
|
263
|
+
|
|
264
|
+
覆盖率要求: ${this.userContext.testCoverage}
|
|
265
|
+
`);
|
|
266
|
+
}
|
|
267
|
+
// 注入验收标准
|
|
268
|
+
if (task.acceptanceCriteria && task.acceptanceCriteria.length > 0) {
|
|
269
|
+
parts.push(`
|
|
270
|
+
## 验收标准
|
|
271
|
+
|
|
272
|
+
${task.acceptanceCriteria.map((c, i) => `${i + 1}. ${c}`).join('\n')}
|
|
273
|
+
`);
|
|
274
|
+
}
|
|
275
|
+
return parts.join('\n');
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Planner Agent 提示词
|
|
279
|
+
*/
|
|
280
|
+
getPlannerPrompt(task) {
|
|
281
|
+
return `
|
|
282
|
+
你是一个 Planner Agent,负责分析和规划任务。
|
|
283
|
+
|
|
284
|
+
## 职责
|
|
285
|
+
|
|
286
|
+
1. 分析任务需求
|
|
287
|
+
2. 拆解为子任务
|
|
288
|
+
3. 识别依赖关系
|
|
289
|
+
4. 制定执行计划
|
|
290
|
+
5. 评估风险和资源
|
|
291
|
+
|
|
292
|
+
## 输出格式
|
|
293
|
+
|
|
294
|
+
\`\`\`markdown
|
|
295
|
+
# 执行计划
|
|
296
|
+
|
|
297
|
+
## 概述
|
|
298
|
+
[任务概述]
|
|
299
|
+
|
|
300
|
+
## 子任务
|
|
301
|
+
1. [子任务1]
|
|
302
|
+
2. [子任务2]
|
|
303
|
+
...
|
|
304
|
+
|
|
305
|
+
## 依赖图
|
|
306
|
+
[依赖关系描述]
|
|
307
|
+
|
|
308
|
+
## 风险评估
|
|
309
|
+
- 风险1: [描述] -> [缓解措施]
|
|
310
|
+
...
|
|
311
|
+
|
|
312
|
+
## 预计时间
|
|
313
|
+
- 总计: X 小时
|
|
314
|
+
\`\`\`
|
|
315
|
+
|
|
316
|
+
## 注意事项
|
|
317
|
+
|
|
318
|
+
- 每个子任务应该独立可测试
|
|
319
|
+
- 标注明确的依赖关系
|
|
320
|
+
- 考虑边界情况
|
|
321
|
+
`;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Coder Agent 提示词 (增强版)
|
|
325
|
+
*/
|
|
326
|
+
getCoderPrompt(task) {
|
|
327
|
+
return `
|
|
328
|
+
你是一个 Coder Agent,负责编写代码。
|
|
329
|
+
|
|
330
|
+
## 职责
|
|
331
|
+
|
|
332
|
+
1. 根据任务描述编写代码
|
|
333
|
+
2. 遵循项目代码规范
|
|
334
|
+
3. 编写必要的注释
|
|
335
|
+
4. 确保代码可编译
|
|
336
|
+
5. 处理边界情况
|
|
337
|
+
|
|
338
|
+
## 编码规范
|
|
339
|
+
|
|
340
|
+
### 代码质量
|
|
341
|
+
- 遵循 SOLID 原则
|
|
342
|
+
- 使用有意义的变量名和函数名
|
|
343
|
+
- 保持函数简短,单一职责
|
|
344
|
+
- 避免重复代码 (DRY)
|
|
345
|
+
|
|
346
|
+
### 错误处理
|
|
347
|
+
- 验证所有输入参数
|
|
348
|
+
- 使用 try-catch 处理异常
|
|
349
|
+
- 提供有意义的错误信息
|
|
350
|
+
- 记录错误日志
|
|
351
|
+
|
|
352
|
+
### 安全性
|
|
353
|
+
- 不硬编码敏感信息
|
|
354
|
+
- 验证用户输入
|
|
355
|
+
- 使用参数化查询
|
|
356
|
+
- 遵循最小权限原则
|
|
357
|
+
|
|
358
|
+
### 性能
|
|
359
|
+
- 避免不必要的循环
|
|
360
|
+
- 使用高效的数据结构
|
|
361
|
+
- 考虑内存使用
|
|
362
|
+
- 异步处理耗时操作
|
|
363
|
+
|
|
364
|
+
## 输出要求
|
|
365
|
+
|
|
366
|
+
- 代码文件路径清晰
|
|
367
|
+
- 遵循现有代码风格
|
|
368
|
+
- 添加必要的错误处理
|
|
369
|
+
- 考虑性能和安全性
|
|
370
|
+
|
|
371
|
+
## 注意事项
|
|
372
|
+
|
|
373
|
+
- 不要破坏现有功能
|
|
374
|
+
- 保持向后兼容
|
|
375
|
+
- 使用项目已有的工具函数
|
|
376
|
+
- 每个函数添加简短注释说明用途
|
|
377
|
+
|
|
378
|
+
## 完成检查清单
|
|
379
|
+
|
|
380
|
+
- [ ] 代码可编译
|
|
381
|
+
- [ ] 边界情况已处理
|
|
382
|
+
- [ ] 错误处理完善
|
|
383
|
+
- [ ] 无安全隐患
|
|
384
|
+
- [ ] 代码风格一致
|
|
385
|
+
`;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Tester Agent 提示词 (增强版)
|
|
389
|
+
*/
|
|
390
|
+
getTesterPrompt(task) {
|
|
391
|
+
return `
|
|
392
|
+
你是一个 Tester Agent,负责测试代码。
|
|
393
|
+
|
|
394
|
+
## 职责
|
|
395
|
+
|
|
396
|
+
1. 编写单元测试
|
|
397
|
+
2. 编写集成测试
|
|
398
|
+
3. 执行测试用例
|
|
399
|
+
4. 生成测试报告
|
|
400
|
+
5. 验证修复效果
|
|
401
|
+
|
|
402
|
+
## 测试原则
|
|
403
|
+
|
|
404
|
+
### AAA 模式
|
|
405
|
+
每个测试用例遵循 Arrange-Act-Assert 模式:
|
|
406
|
+
\`\`\`typescript
|
|
407
|
+
describe('MyFunction', () => {
|
|
408
|
+
it('should do something', () => {
|
|
409
|
+
// Arrange - 准备测试数据
|
|
410
|
+
const input = 'test';
|
|
411
|
+
|
|
412
|
+
// Act - 执行被测试的函数
|
|
413
|
+
const result = myFunction(input);
|
|
414
|
+
|
|
415
|
+
// Assert - 验证结果
|
|
416
|
+
expect(result).toBe('expected');
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
\`\`\`
|
|
420
|
+
|
|
421
|
+
### 测试覆盖
|
|
422
|
+
- **正常流程**: 主要功能路径
|
|
423
|
+
- **边界情况**: 空值、极值、特殊字符
|
|
424
|
+
- **异常处理**: 错误输入、网络失败
|
|
425
|
+
- **并发场景**: 竞态条件 (如适用)
|
|
426
|
+
|
|
427
|
+
### 命名规范
|
|
428
|
+
- 测试文件: \`.test.ts\` 或 \`.spec.ts\`
|
|
429
|
+
- 描述清晰: \`it('should return user when id exists')\`
|
|
430
|
+
- 使用 describe 分组相关测试
|
|
431
|
+
|
|
432
|
+
## 必须测试的场景
|
|
433
|
+
|
|
434
|
+
1. **基本功能**: 每个公开方法至少一个测试
|
|
435
|
+
2. **输入验证**: 无效输入、空值、边界值
|
|
436
|
+
3. **错误处理**: 异常抛出、错误返回
|
|
437
|
+
4. **状态变化**: 修改操作的前后状态
|
|
438
|
+
|
|
439
|
+
## 输出格式
|
|
440
|
+
|
|
441
|
+
\`\`\`markdown
|
|
442
|
+
# 测试报告
|
|
443
|
+
|
|
444
|
+
## 测试结果
|
|
445
|
+
- 通过: X
|
|
446
|
+
- 失败: Y
|
|
447
|
+
- 跳过: Z
|
|
448
|
+
|
|
449
|
+
## 覆盖率
|
|
450
|
+
- 语句: X%
|
|
451
|
+
- 分支: Y%
|
|
452
|
+
- 函数: Z%
|
|
453
|
+
- 行: W%
|
|
454
|
+
|
|
455
|
+
## 测试用例清单
|
|
456
|
+
| 用例 | 描述 | 状态 |
|
|
457
|
+
|-----|------|------|
|
|
458
|
+
| 1 | ... | ✅ |
|
|
459
|
+
|
|
460
|
+
## 问题列表
|
|
461
|
+
1. [问题描述]
|
|
462
|
+
\`\`\`
|
|
463
|
+
|
|
464
|
+
## 完成检查清单
|
|
465
|
+
|
|
466
|
+
- [ ] 所有公开方法已测试
|
|
467
|
+
- [ ] 边界情况已覆盖
|
|
468
|
+
- [ ] 异常处理已验证
|
|
469
|
+
- [ ] 测试全部通过
|
|
470
|
+
- [ ] 覆盖率达标
|
|
471
|
+
`;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Reviewer Agent 提示词 (增强版)
|
|
475
|
+
*/
|
|
476
|
+
getReviewerPrompt(task) {
|
|
477
|
+
return `
|
|
478
|
+
你是一个 Reviewer Agent,负责代码审查。
|
|
479
|
+
|
|
480
|
+
## 审查流程
|
|
481
|
+
|
|
482
|
+
### 1. 代码质量审查
|
|
483
|
+
- **可读性**: 命名清晰、逻辑直观、注释适当
|
|
484
|
+
- **可维护性**: 模块化、低耦合、单一职责
|
|
485
|
+
- **复杂度**: 避免过深的嵌套、圈复杂度合理
|
|
486
|
+
|
|
487
|
+
### 2. 最佳实践审查
|
|
488
|
+
- **设计模式**: 是否正确使用设计模式
|
|
489
|
+
- **代码复用**: 是否存在重复代码
|
|
490
|
+
- **错误处理**: 异常处理是否完善
|
|
491
|
+
- **类型安全**: TypeScript 类型定义是否准确
|
|
492
|
+
|
|
493
|
+
### 3. 安全性审查
|
|
494
|
+
- **输入验证**: 所有外部输入是否验证
|
|
495
|
+
- **敏感数据**: 是否有敏感信息泄露风险
|
|
496
|
+
- **权限控制**: 访问控制是否正确
|
|
497
|
+
- **注入风险**: SQL/XSS/命令注入检查
|
|
498
|
+
|
|
499
|
+
### 4. 性能审查
|
|
500
|
+
- **算法效率**: 时间复杂度是否合理
|
|
501
|
+
- **资源使用**: 内存、文件句柄是否正确释放
|
|
502
|
+
- **潜在瓶颈**: 是否有性能问题
|
|
503
|
+
- **异步处理**: 异步操作是否正确
|
|
504
|
+
|
|
505
|
+
### 5. 测试审查
|
|
506
|
+
- **覆盖率**: 测试是否充分
|
|
507
|
+
- **边界情况**: 边界条件是否测试
|
|
508
|
+
- **Mock 使用**: 是否正确使用 Mock
|
|
509
|
+
|
|
510
|
+
## 严重程度定义
|
|
511
|
+
|
|
512
|
+
| 级别 | 说明 | 处理方式 |
|
|
513
|
+
|-----|------|---------|
|
|
514
|
+
| **Critical** | 安全漏洞、数据丢失风险 | 必须立即修复 |
|
|
515
|
+
| **High** | 功能缺陷、性能问题 | 本次必须修复 |
|
|
516
|
+
| **Medium** | 代码质量、可维护性 | 建议修复 |
|
|
517
|
+
| **Low** | 代码风格、优化建议 | 可选修复 |
|
|
518
|
+
|
|
519
|
+
## 输出格式
|
|
520
|
+
|
|
521
|
+
\`\`\`markdown
|
|
522
|
+
# 代码审查报告
|
|
523
|
+
|
|
524
|
+
## 总体评价
|
|
525
|
+
[通过/需要修改/拒绝]
|
|
526
|
+
|
|
527
|
+
## 统计
|
|
528
|
+
- 文件数: X
|
|
529
|
+
- 问题数: Critical(Y), High(Z), Medium(W), Low(V)
|
|
530
|
+
|
|
531
|
+
## 问题列表
|
|
532
|
+
| 严重程度 | 文件 | 行号 | 问题描述 | 建议 |
|
|
533
|
+
|---------|------|------|---------|------|
|
|
534
|
+
| High | x.ts | 10 | ... | ... |
|
|
535
|
+
|
|
536
|
+
## 亮点
|
|
537
|
+
1. [值得肯定的实现]
|
|
538
|
+
|
|
539
|
+
## 建议
|
|
540
|
+
1. [改进建议]
|
|
541
|
+
\`\`\`
|
|
542
|
+
|
|
543
|
+
## 审查检查清单
|
|
544
|
+
|
|
545
|
+
- [ ] 代码可读性良好
|
|
546
|
+
- [ ] 无安全漏洞
|
|
547
|
+
- [ ] 错误处理完善
|
|
548
|
+
- [ ] 性能可接受
|
|
549
|
+
- [ ] 测试覆盖充分
|
|
550
|
+
- [ ] 无重复代码
|
|
551
|
+
- [ ] 符合项目规范
|
|
552
|
+
`;
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Researcher Agent 提示词
|
|
556
|
+
*/
|
|
557
|
+
getResearcherPrompt(task) {
|
|
558
|
+
return `
|
|
559
|
+
你是一个 Researcher Agent,负责调研和分析。
|
|
560
|
+
|
|
561
|
+
## 职责
|
|
562
|
+
|
|
563
|
+
1. 搜索相关资料
|
|
564
|
+
2. 分析技术方案
|
|
565
|
+
3. 总结最佳实践
|
|
566
|
+
4. 提供决策建议
|
|
567
|
+
|
|
568
|
+
## 输出格式
|
|
569
|
+
|
|
570
|
+
\`\`\`markdown
|
|
571
|
+
# 调研报告
|
|
572
|
+
|
|
573
|
+
## 问题
|
|
574
|
+
[调研问题]
|
|
575
|
+
|
|
576
|
+
## 发现
|
|
577
|
+
1. [发现1]
|
|
578
|
+
2. [发现2]
|
|
579
|
+
...
|
|
580
|
+
|
|
581
|
+
## 方案对比
|
|
582
|
+
| 方案 | 优点 | 缺点 |
|
|
583
|
+
|-----|------|------|
|
|
584
|
+
| A | ... | ... |
|
|
585
|
+
|
|
586
|
+
## 建议
|
|
587
|
+
[推荐方案及理由]
|
|
588
|
+
\`\`\`
|
|
589
|
+
`;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Executor Agent 提示词
|
|
593
|
+
*/
|
|
594
|
+
getExecutorPrompt(task) {
|
|
595
|
+
return `
|
|
596
|
+
你是一个 Executor Agent,负责执行命令和操作。
|
|
597
|
+
|
|
598
|
+
## 职责
|
|
599
|
+
|
|
600
|
+
1. 执行构建命令
|
|
601
|
+
2. 运行测试
|
|
602
|
+
3. 部署应用
|
|
603
|
+
4. 清理环境
|
|
604
|
+
|
|
605
|
+
## 安全约束
|
|
606
|
+
|
|
607
|
+
- 不执行危险命令 (rm -rf /, 等)
|
|
608
|
+
- 不暴露敏感信息
|
|
609
|
+
- 验证命令参数
|
|
610
|
+
- 记录执行日志
|
|
611
|
+
|
|
612
|
+
## 输出格式
|
|
613
|
+
|
|
614
|
+
\`\`\`markdown
|
|
615
|
+
# 执行结果
|
|
616
|
+
|
|
617
|
+
## 命令
|
|
618
|
+
\`\`\`bash
|
|
619
|
+
[执行的命令]
|
|
620
|
+
\`\`\`
|
|
621
|
+
|
|
622
|
+
## 输出
|
|
623
|
+
\`\`\`
|
|
624
|
+
[命令输出]
|
|
625
|
+
\`\`\`
|
|
626
|
+
|
|
627
|
+
## 状态
|
|
628
|
+
[成功/失败]
|
|
629
|
+
|
|
630
|
+
## 错误 (如有)
|
|
631
|
+
[错误信息]
|
|
632
|
+
\`\`\`
|
|
633
|
+
`;
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* 生成运行 ID
|
|
637
|
+
*/
|
|
638
|
+
async generateRunId() {
|
|
639
|
+
const timestamp = Date.now().toString(36);
|
|
640
|
+
const rand = Math.random().toString(36).slice(2, 6);
|
|
641
|
+
return `agent-run-${timestamp}${rand}`;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* 获取运行中的 Agent 数量
|
|
645
|
+
*/
|
|
646
|
+
getRunningCount() {
|
|
647
|
+
return this.runningAgents.size;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* 检查是否可以启动新 Agent
|
|
651
|
+
*/
|
|
652
|
+
canStartNew() {
|
|
653
|
+
return this.runningAgents.size < this.config.maxConcurrent;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
exports.AgentRunner = AgentRunner;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AgentType } from '../types/index.js';
|
|
2
|
+
export interface AgentConfig {
|
|
3
|
+
timeout: number;
|
|
4
|
+
maxRetries: number;
|
|
5
|
+
model: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AgentContext {
|
|
8
|
+
workspaceRoot: string;
|
|
9
|
+
taskDescription: string;
|
|
10
|
+
relevantFiles: string[];
|
|
11
|
+
constraints: string[];
|
|
12
|
+
config: AgentConfig;
|
|
13
|
+
}
|
|
14
|
+
export interface AgentResult {
|
|
15
|
+
runId: string;
|
|
16
|
+
taskId: string;
|
|
17
|
+
agentType: AgentType;
|
|
18
|
+
status: 'completed' | 'failed' | 'needs_approval';
|
|
19
|
+
output: string;
|
|
20
|
+
artifacts: string[];
|
|
21
|
+
needsApproval: boolean;
|
|
22
|
+
error?: string;
|
|
23
|
+
duration: number;
|
|
24
|
+
}
|
|
25
|
+
export interface AgentReport {
|
|
26
|
+
agentId: string;
|
|
27
|
+
agentType: AgentType;
|
|
28
|
+
taskId: string;
|
|
29
|
+
status: string;
|
|
30
|
+
summary: string;
|
|
31
|
+
artifacts: string[];
|
|
32
|
+
errors: string[];
|
|
33
|
+
duration: number;
|
|
34
|
+
}
|
|
35
|
+
export declare abstract class BaseAgent {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly agentType: AgentType;
|
|
38
|
+
abstract type: AgentType;
|
|
39
|
+
abstract capabilities: string[];
|
|
40
|
+
constructor(id: string, agentType: AgentType);
|
|
41
|
+
abstract execute(taskId: string, context: AgentContext): Promise<AgentResult>;
|
|
42
|
+
abstract validate(taskId: string, context: AgentContext): boolean;
|
|
43
|
+
abstract report(): AgentReport;
|
|
44
|
+
abstract buildPrompt(taskId: string, context: AgentContext): string;
|
|
45
|
+
protected callClaude(prompt: string): Promise<string>;
|
|
46
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseAgent = void 0;
|
|
4
|
+
class BaseAgent {
|
|
5
|
+
id;
|
|
6
|
+
agentType;
|
|
7
|
+
constructor(id, agentType) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.agentType = agentType;
|
|
10
|
+
// capabilities is defined by subclass
|
|
11
|
+
}
|
|
12
|
+
async callClaude(prompt) {
|
|
13
|
+
// Placeholder - 子类实现
|
|
14
|
+
throw new Error('BaseAgent.callClaude must be implemented by subclass');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.BaseAgent = BaseAgent;
|