stigmergy 1.2.13 → 1.3.1
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 +39 -3
- package/STIGMERGY.md +3 -0
- package/config/builtin-skills.json +43 -0
- package/config/enhanced-cli-config.json +438 -0
- package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
- package/docs/DESIGN_CLI_HELP_ANALYZER_REFACTOR.md +726 -0
- package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
- package/docs/IMPLEMENTATION_CHECKLIST_CLI_HELP_ANALYZER_REFACTOR.md +1268 -0
- package/docs/INSTALLER_ARCHITECTURE.md +257 -0
- package/docs/LESSONS_LEARNED.md +252 -0
- package/docs/SPECS_CLI_HELP_ANALYZER_REFACTOR.md +287 -0
- package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
- package/docs/correct-skillsio-implementation.md +368 -0
- package/docs/development_guidelines.md +276 -0
- package/docs/independent-resume-implementation.md +198 -0
- package/docs/resumesession-final-implementation.md +195 -0
- package/docs/resumesession-usage.md +87 -0
- package/package.json +146 -136
- package/scripts/analyze-router.js +168 -0
- package/scripts/run-comprehensive-tests.js +230 -0
- package/scripts/run-quick-tests.js +90 -0
- package/scripts/test-runner.js +344 -0
- package/skills/resumesession/INDEPENDENT_SKILL.md +403 -0
- package/skills/resumesession/README.md +381 -0
- package/skills/resumesession/SKILL.md +211 -0
- package/skills/resumesession/__init__.py +33 -0
- package/skills/resumesession/implementations/simple-resume.js +13 -0
- package/skills/resumesession/independent-resume.js +750 -0
- package/skills/resumesession/package.json +1 -0
- package/skills/resumesession/skill.json +1 -0
- package/src/adapters/claude/install_claude_integration.js +9 -1
- package/src/adapters/codebuddy/install_codebuddy_integration.js +3 -1
- package/src/adapters/codex/install_codex_integration.js +15 -5
- package/src/adapters/gemini/install_gemini_integration.js +3 -1
- package/src/adapters/qwen/install_qwen_integration.js +3 -1
- package/src/cli/commands/autoinstall.js +65 -0
- package/src/cli/commands/errors.js +190 -0
- package/src/cli/commands/independent-resume.js +395 -0
- package/src/cli/commands/install.js +179 -0
- package/src/cli/commands/permissions.js +108 -0
- package/src/cli/commands/project.js +485 -0
- package/src/cli/commands/scan.js +97 -0
- package/src/cli/commands/simple-resume.js +377 -0
- package/src/cli/commands/skills.js +158 -0
- package/src/cli/commands/status.js +113 -0
- package/src/cli/commands/stigmergy-resume.js +775 -0
- package/src/cli/commands/system.js +301 -0
- package/src/cli/commands/universal-resume.js +394 -0
- package/src/cli/router-beta.js +471 -0
- package/src/cli/utils/environment.js +75 -0
- package/src/cli/utils/formatters.js +47 -0
- package/src/cli/utils/skills_cache.js +92 -0
- package/src/core/cache_cleaner.js +1 -0
- package/src/core/cli_adapters.js +345 -0
- package/src/core/cli_help_analyzer.js +1236 -680
- package/src/core/cli_path_detector.js +702 -709
- package/src/core/cli_tools.js +515 -160
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +18 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +242 -412
- package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
- package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
- package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +932 -0
- package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1395 -0
- package/src/core/coordination/nodejs/generators/index.js +12 -0
- package/src/core/enhanced_cli_installer.js +1208 -608
- package/src/core/enhanced_cli_parameter_handler.js +402 -0
- package/src/core/execution_mode_detector.js +222 -0
- package/src/core/installer.js +151 -106
- package/src/core/local_skill_scanner.js +732 -0
- package/src/core/multilingual/language-pattern-manager.js +1 -1
- package/src/core/skills/BuiltinSkillsDeployer.js +188 -0
- package/src/core/skills/StigmergySkillManager.js +123 -16
- package/src/core/skills/embedded-openskills/SkillParser.js +7 -3
- package/src/core/smart_router.js +550 -261
- package/src/index.js +10 -4
- package/src/utils.js +66 -7
- package/test/cli-integration.test.js +304 -0
- package/test/direct_smart_router_test.js +88 -0
- package/test/enhanced-cli-agent-skill-test.js +485 -0
- package/test/simple_test.js +82 -0
- package/test/smart_router_test_runner.js +123 -0
- package/test/smart_routing_edge_cases.test.js +284 -0
- package/test/smart_routing_simple_verification.js +139 -0
- package/test/smart_routing_verification.test.js +346 -0
- package/test/specific-cli-agent-skill-analysis.js +385 -0
- package/test/unit/smart_router.test.js +295 -0
- package/test/very_simple_test.js +54 -0
- package/src/cli/router.js +0 -1783
|
@@ -0,0 +1,1268 @@
|
|
|
1
|
+
# CLI Help Analyzer 重构 - 实施清单 (IMPLEMENTATION CHECKLIST)
|
|
2
|
+
|
|
3
|
+
## 阶段0:准备工作
|
|
4
|
+
|
|
5
|
+
### 0.1 环境准备
|
|
6
|
+
- [ ] 确认当前代码已提交并推送到远程
|
|
7
|
+
- [ ] 创建重构分支 `refactor/cli-help-analyzer`
|
|
8
|
+
- [ ] 切换到重构分支
|
|
9
|
+
- [ ] 确认所有测试通过
|
|
10
|
+
|
|
11
|
+
### 0.2 基准测试
|
|
12
|
+
- [ ] 运行现有测试套件,记录通过率
|
|
13
|
+
- [ ] 运行性能测试,记录基准数据
|
|
14
|
+
- [ ] 记录当前代码行数和复杂度
|
|
15
|
+
- [ ] 备份当前实现(git tag)
|
|
16
|
+
|
|
17
|
+
### 0.3 文档确认
|
|
18
|
+
- [ ] 确认规范需求文档已审核
|
|
19
|
+
- [ ] 确认设计文档已审核
|
|
20
|
+
- [ ] 确认实施清单已审核
|
|
21
|
+
- [ ] 所有相关方已确认理解重构方案
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 阶段1:重构核心方法
|
|
26
|
+
|
|
27
|
+
### 1.1 修改 analyzeCLI() 方法签名
|
|
28
|
+
|
|
29
|
+
#### 1.1.1 添加参数验证和边界条件处理(FR-008)
|
|
30
|
+
- [ ] 修改方法签名为 `async analyzeCLI(cliName, options = {})`
|
|
31
|
+
- [ ] 添加 cliName 参数验证(非空、非null、存在于配置中)
|
|
32
|
+
- [ ] 添加 options 参数验证(类型检查)
|
|
33
|
+
- [ ] 添加 JSDoc 注释
|
|
34
|
+
|
|
35
|
+
**验收标准**:
|
|
36
|
+
```javascript
|
|
37
|
+
// 参数验证正确
|
|
38
|
+
if (!cliName || cliName.trim() === '') {
|
|
39
|
+
throw new Error('cliName cannot be empty or null');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!this.cliTools[cliName]) {
|
|
43
|
+
throw new Error(`CLI tool ${cliName} not found`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (options !== null && typeof options !== 'object') {
|
|
47
|
+
throw new Error('options must be an object');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// JSDoc 完整
|
|
51
|
+
/**
|
|
52
|
+
* 分析CLI工具
|
|
53
|
+
* @param {string} cliName - CLI工具名称
|
|
54
|
+
* @param {Object} options - 分析选项
|
|
55
|
+
* @param {boolean} options.enhanced - 是否返回增强信息
|
|
56
|
+
* @param {boolean} options.forceRefresh - 是否强制刷新缓存
|
|
57
|
+
* @returns {Promise<Object>} 分析结果
|
|
58
|
+
*/
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**验收标准**:
|
|
62
|
+
```javascript
|
|
63
|
+
// 方法签名正确
|
|
64
|
+
async analyzeCLI(cliName, options = {})
|
|
65
|
+
|
|
66
|
+
// 参数验证正确
|
|
67
|
+
if (!this.cliTools[cliName]) {
|
|
68
|
+
throw new Error(`CLI tool ${cliName} not found`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// JSDoc 完整
|
|
72
|
+
/**
|
|
73
|
+
* 分析CLI工具
|
|
74
|
+
* @param {string} cliName - CLI工具名称
|
|
75
|
+
* @param {Object} options - 分析选项
|
|
76
|
+
* @param {boolean} options.enhanced - 是否返回增强信息
|
|
77
|
+
* @param {boolean} options.forceRefresh - 是否强制刷新缓存
|
|
78
|
+
* @returns {Promise<Object>} 分析结果
|
|
79
|
+
*/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
#### 1.1.2 解构 options 参数
|
|
83
|
+
- [ ] 添加 `const { enhanced = false, forceRefresh = false } = options;`
|
|
84
|
+
- [ ] 添加参数类型检查(可选)
|
|
85
|
+
|
|
86
|
+
**验收标准**:
|
|
87
|
+
```javascript
|
|
88
|
+
const { enhanced = false, forceRefresh = false } = options;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
#### 1.1.3 修改缓存检查逻辑
|
|
92
|
+
- [ ] 添加 `forceRefresh` 检查
|
|
93
|
+
- [ ] 保持版本检测逻辑
|
|
94
|
+
- [ ] 保持缓存过期逻辑
|
|
95
|
+
|
|
96
|
+
**验收标准**:
|
|
97
|
+
```javascript
|
|
98
|
+
if (!forceRefresh) {
|
|
99
|
+
const cachedAnalysis = await this.getCachedAnalysis(cliName);
|
|
100
|
+
if (cachedAnalysis && cachedAnalysis.success) {
|
|
101
|
+
const currentVersion = await this.getCurrentVersion(cliName);
|
|
102
|
+
if (currentVersion === cachedAnalysis.version &&
|
|
103
|
+
!this.isCacheExpired(cachedAnalysis.timestamp)) {
|
|
104
|
+
if (enhanced) {
|
|
105
|
+
return this.addEnhancedInfo(cachedAnalysis, cliName);
|
|
106
|
+
}
|
|
107
|
+
return cachedAnalysis;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### 1.1.4 添加增强信息处理
|
|
114
|
+
- [ ] 在返回结果前检查 `enhanced` 参数
|
|
115
|
+
- [ ] 调用 `addEnhancedInfo()` 方法(待实现)
|
|
116
|
+
|
|
117
|
+
**验收标准**:
|
|
118
|
+
```javascript
|
|
119
|
+
// 执行分析
|
|
120
|
+
const analysis = await this.performAnalysis(cliName);
|
|
121
|
+
|
|
122
|
+
// 添加增强信息
|
|
123
|
+
if (enhanced) {
|
|
124
|
+
return this.addEnhancedInfo(analysis, cliName);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 保存缓存
|
|
128
|
+
await this.cacheAnalysis(cliName, analysis);
|
|
129
|
+
|
|
130
|
+
return analysis;
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 1.2 提取 addEnhancedInfo() 方法
|
|
134
|
+
|
|
135
|
+
#### 1.2.1 创建方法
|
|
136
|
+
- [ ] 在类中添加 `addEnhancedInfo(analysis, cliName)` 方法
|
|
137
|
+
- [ ] 添加 JSDoc 注释
|
|
138
|
+
|
|
139
|
+
**验收标准**:
|
|
140
|
+
```javascript
|
|
141
|
+
/**
|
|
142
|
+
* 添加增强信息
|
|
143
|
+
* @param {Object} analysis - 基础分析结果
|
|
144
|
+
* @param {string} cliName - CLI工具名称
|
|
145
|
+
* @returns {Object} 增强分析结果
|
|
146
|
+
*/
|
|
147
|
+
addEnhancedInfo(analysis, cliName) {
|
|
148
|
+
// 实现
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
#### 1.2.2 实现增强信息添加逻辑
|
|
153
|
+
- [ ] 从 `this.enhancedPatterns` 读取配置
|
|
154
|
+
- [ ] 创建 `agentSkillSupport` 对象
|
|
155
|
+
- [ ] 合并到分析结果中
|
|
156
|
+
- [ ] 返回新对象(不修改原对象)
|
|
157
|
+
|
|
158
|
+
**验收标准**:
|
|
159
|
+
```javascript
|
|
160
|
+
addEnhancedInfo(analysis, cliName) {
|
|
161
|
+
const enhancedPatterns = this.enhancedPatterns[cliName] || {};
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
...analysis,
|
|
165
|
+
agentSkillSupport: {
|
|
166
|
+
supportsAgents: enhancedPatterns.agentDetection || false,
|
|
167
|
+
supportsSkills: enhancedPatterns.skillDetection || false,
|
|
168
|
+
naturalLanguageSupport: enhancedPatterns.naturalLanguageSupport || false,
|
|
169
|
+
skillPrefixRequired: enhancedPatterns.skillPrefixRequired || false,
|
|
170
|
+
positionalArgs: enhancedPatterns.positionalArgs || false,
|
|
171
|
+
agentTypes: enhancedPatterns.agentTypes || [],
|
|
172
|
+
skillKeywords: enhancedPatterns.skillKeywords || [],
|
|
173
|
+
commandFormat: enhancedPatterns.commandFormat || '',
|
|
174
|
+
examples: enhancedPatterns.examples || []
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 1.3 更新内部调用
|
|
181
|
+
|
|
182
|
+
#### 1.3.1 更新 analyzeAllCLI() 方法
|
|
183
|
+
- [ ] 修改调用 `analyzeCLI(cliName)` 为 `analyzeCLI(cliName, options)`
|
|
184
|
+
- [ ] 传递 `options` 参数
|
|
185
|
+
|
|
186
|
+
**验收标准**:
|
|
187
|
+
```javascript
|
|
188
|
+
async analyzeAllCLI(options = {}) {
|
|
189
|
+
const cliNames = Object.keys(this.cliTools);
|
|
190
|
+
const results = {};
|
|
191
|
+
|
|
192
|
+
const promises = cliNames.map(async (cliName) => {
|
|
193
|
+
try {
|
|
194
|
+
const result = await this.analyzeCLI(cliName, options);
|
|
195
|
+
return { cliName, result };
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return { cliName, result: { success: false, error: error.message } };
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const analysisResults = await Promise.all(promises);
|
|
202
|
+
for (const { cliName, result } of analysisResults) {
|
|
203
|
+
results[cliName] = result;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return results;
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### 1.3.2 更新其他内部调用
|
|
211
|
+
- [ ] 检查所有内部调用 `analyzeCLI()` 的地方
|
|
212
|
+
- [ ] 确保传递正确的参数
|
|
213
|
+
|
|
214
|
+
**验收标准**:
|
|
215
|
+
- 所有内部调用都已更新
|
|
216
|
+
- 无遗漏的调用点
|
|
217
|
+
|
|
218
|
+
### 1.4 实施错误处理(FR-007)
|
|
219
|
+
|
|
220
|
+
#### 1.4.1 实现失败尝试记录
|
|
221
|
+
- [ ] 在 `analyzeCLI()` 中添加失败记录逻辑
|
|
222
|
+
- [ ] 调用 `recordFailedAttempt()` 方法
|
|
223
|
+
- [ ] 记录到配置文件
|
|
224
|
+
|
|
225
|
+
**验收标准**:
|
|
226
|
+
```javascript
|
|
227
|
+
try {
|
|
228
|
+
const analysis = await this.performAnalysis(cliName);
|
|
229
|
+
// 成功后清除失败记录
|
|
230
|
+
this.clearFailedAttempts(cliName);
|
|
231
|
+
return analysis;
|
|
232
|
+
} catch (error) {
|
|
233
|
+
// 记录失败尝试
|
|
234
|
+
await this.recordFailedAttempt(cliName, error);
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### 1.4.2 实现错误日志记录
|
|
240
|
+
- [ ] 在所有 catch 块中添加错误日志
|
|
241
|
+
- [ ] 调用错误处理器记录错误
|
|
242
|
+
- [ ] 确保错误信息完整
|
|
243
|
+
|
|
244
|
+
**验收标准**:
|
|
245
|
+
```javascript
|
|
246
|
+
catch (error) {
|
|
247
|
+
this.errorHandler.logError('analyzeCLI', {
|
|
248
|
+
cliName,
|
|
249
|
+
error: error.message,
|
|
250
|
+
stack: error.stack,
|
|
251
|
+
timestamp: new Date().toISOString()
|
|
252
|
+
});
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
#### 1.4.3 实现缓存失败处理
|
|
258
|
+
- [ ] 缓存读取失败时使用内存配置
|
|
259
|
+
- [ ] 不阻塞主流程
|
|
260
|
+
- [ ] 记录警告日志
|
|
261
|
+
|
|
262
|
+
**验收标准**:
|
|
263
|
+
```javascript
|
|
264
|
+
async getCachedAnalysis(cliName) {
|
|
265
|
+
try {
|
|
266
|
+
const cachedData = await this.configManager.readCache(cliName);
|
|
267
|
+
return cachedData;
|
|
268
|
+
} catch (error) {
|
|
269
|
+
this.logger.warn(`Cache read failed for ${cliName}, using in-memory config`);
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
#### 1.4.4 实现配置文件写入失败处理
|
|
276
|
+
- [ ] 配置文件写入失败时不抛出异常
|
|
277
|
+
- [ ] 使用内存配置作为回退
|
|
278
|
+
- [ ] 记录错误日志
|
|
279
|
+
|
|
280
|
+
**验收标准**:
|
|
281
|
+
```javascript
|
|
282
|
+
async cacheAnalysis(cliName, analysis) {
|
|
283
|
+
try {
|
|
284
|
+
await this.configManager.writeCache(cliName, analysis);
|
|
285
|
+
} catch (error) {
|
|
286
|
+
this.logger.error(`Cache write failed for ${cliName}, using in-memory cache`);
|
|
287
|
+
// 不阻塞主流程,继续返回结果
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
#### 1.4.5 实现工具不存在处理
|
|
293
|
+
- [ ] 工具不存在时返回失败结果而非抛出异常
|
|
294
|
+
- [ ] 记录错误信息
|
|
295
|
+
|
|
296
|
+
**验收标准**:
|
|
297
|
+
```javascript
|
|
298
|
+
async analyzeCLI(cliName, options = {}) {
|
|
299
|
+
if (!this.cliTools[cliName]) {
|
|
300
|
+
return {
|
|
301
|
+
success: false,
|
|
302
|
+
cliName,
|
|
303
|
+
error: `CLI tool ${cliName} not found`,
|
|
304
|
+
timestamp: new Date().toISOString()
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
// 继续处理...
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 1.5 实施边界条件处理(FR-008)
|
|
312
|
+
|
|
313
|
+
#### 1.5.1 添加配置文件处理
|
|
314
|
+
- [ ] 配置文件不存在时创建默认配置
|
|
315
|
+
- [ ] 配置文件损坏时恢复默认配置
|
|
316
|
+
- [ ] 版本检测失败时使用 'unknown' 标记
|
|
317
|
+
|
|
318
|
+
**验收标准**:
|
|
319
|
+
```javascript
|
|
320
|
+
async getCurrentVersion(cliName) {
|
|
321
|
+
try {
|
|
322
|
+
const version = await this.executeCommand(`${cliName} --version`);
|
|
323
|
+
return version.trim();
|
|
324
|
+
} catch (error) {
|
|
325
|
+
this.logger.warn(`Version detection failed for ${cliName}`);
|
|
326
|
+
return 'unknown';
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async loadConfiguration() {
|
|
331
|
+
try {
|
|
332
|
+
return await this.configManager.readConfig();
|
|
333
|
+
} catch (error) {
|
|
334
|
+
this.logger.warn('Configuration file corrupted, using defaults');
|
|
335
|
+
return this.getDefaultConfiguration();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
#### 1.5.2 添加帮助信息获取失败处理
|
|
341
|
+
- [ ] 帮助信息获取失败时返回失败结果
|
|
342
|
+
- [ ] 记录错误到日志
|
|
343
|
+
|
|
344
|
+
**验收标准**:
|
|
345
|
+
```javascript
|
|
346
|
+
async getHelpInfo(cliName) {
|
|
347
|
+
try {
|
|
348
|
+
const helpText = await this.executeCommand(`${cliName} --help`);
|
|
349
|
+
return helpText;
|
|
350
|
+
} catch (error) {
|
|
351
|
+
this.logger.error(`Help info retrieval failed for ${cliName}: ${error.message}`);
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
#### 1.5.3 添加 CLI 命令执行超时处理
|
|
358
|
+
- [ ] CLI 命令执行超时时返回失败结果
|
|
359
|
+
- [ ] 记录超时错误到日志
|
|
360
|
+
|
|
361
|
+
**验收标准**:
|
|
362
|
+
```javascript
|
|
363
|
+
async executeCommand(command, timeout = 10000) {
|
|
364
|
+
return new Promise((resolve, reject) => {
|
|
365
|
+
const timer = setTimeout(() => {
|
|
366
|
+
reject(new Error(`Command timeout: ${command}`));
|
|
367
|
+
}, timeout);
|
|
368
|
+
|
|
369
|
+
exec(command, (error, stdout, stderr) => {
|
|
370
|
+
clearTimeout(timer);
|
|
371
|
+
if (error) {
|
|
372
|
+
reject(error);
|
|
373
|
+
} else {
|
|
374
|
+
resolve(stdout);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 1.6 单元测试 - 核心方法
|
|
382
|
+
|
|
383
|
+
#### 1.4.1 测试 analyzeCLI() 基础功能
|
|
384
|
+
- [ ] 测试 `enhanced=false` 返回基础分析
|
|
385
|
+
- [ ] 测试 `enhanced=true` 返回增强分析
|
|
386
|
+
- [ ] 测试 `forceRefresh=true` 强制刷新
|
|
387
|
+
|
|
388
|
+
**测试用例**:
|
|
389
|
+
```javascript
|
|
390
|
+
describe('analyzeCLI()', () => {
|
|
391
|
+
test('should return basic analysis when enhanced=false', async () => {
|
|
392
|
+
const result = await analyzer.analyzeCLI('claude', { enhanced: false });
|
|
393
|
+
expect(result.success).toBe(true);
|
|
394
|
+
expect(result.agentSkillSupport).toBeUndefined();
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
test('should return enhanced analysis when enhanced=true', async () => {
|
|
398
|
+
const result = await analyzer.analyzeCLI('claude', { enhanced: true });
|
|
399
|
+
expect(result.success).toBe(true);
|
|
400
|
+
expect(result.agentSkillSupport).toBeDefined();
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test('should force refresh when forceRefresh=true', async () => {
|
|
404
|
+
const result1 = await analyzer.analyzeCLI('claude');
|
|
405
|
+
const result2 = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
406
|
+
expect(result2.timestamp).not.toEqual(result1.timestamp);
|
|
407
|
+
});
|
|
408
|
+
});
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
#### 1.4.2 测试 addEnhancedInfo() 方法
|
|
412
|
+
- [ ] 测试添加增强信息
|
|
413
|
+
- [ ] 测试不修改原对象
|
|
414
|
+
|
|
415
|
+
**测试用例**:
|
|
416
|
+
```javascript
|
|
417
|
+
describe('addEnhancedInfo()', () => {
|
|
418
|
+
test('should add agentSkillSupport to analysis', () => {
|
|
419
|
+
const basicAnalysis = { cliName: 'claude', version: '2.1.4' };
|
|
420
|
+
const enhancedAnalysis = analyzer.addEnhancedInfo(basicAnalysis, 'claude');
|
|
421
|
+
|
|
422
|
+
expect(enhancedAnalysis.agentSkillSupport).toBeDefined();
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('should not modify original analysis', () => {
|
|
426
|
+
const basicAnalysis = { cliName: 'claude', version: '2.1.4' };
|
|
427
|
+
const enhancedAnalysis = analyzer.addEnhancedInfo(basicAnalysis, 'claude');
|
|
428
|
+
|
|
429
|
+
expect(basicAnalysis.agentSkillSupport).toBeUndefined();
|
|
430
|
+
});
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### 1.4.3 运行测试
|
|
435
|
+
- [ ] 运行单元测试
|
|
436
|
+
- [ ] 确保所有测试通过
|
|
437
|
+
- [ ] 修复失败的测试
|
|
438
|
+
|
|
439
|
+
**验收标准**:
|
|
440
|
+
- 所有单元测试通过
|
|
441
|
+
- 测试覆盖率 ≥ 80%
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
## 阶段2:简化包装器方法
|
|
446
|
+
|
|
447
|
+
### 2.1 简化 getCLIPattern() 方法
|
|
448
|
+
|
|
449
|
+
#### 2.1.1 重构为包装器
|
|
450
|
+
- [ ] 删除原有实现
|
|
451
|
+
- [ ] 改为调用 `analyzeCLI(cliName, { enhanced: false })`
|
|
452
|
+
|
|
453
|
+
**验收标准**:
|
|
454
|
+
```javascript
|
|
455
|
+
async getCLIPattern(cliName) {
|
|
456
|
+
return await this.analyzeCLI(cliName, { enhanced: false });
|
|
457
|
+
}
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
#### 2.1.2 添加 JSDoc 注释
|
|
461
|
+
- [ ] 添加方法说明
|
|
462
|
+
- [ ] 标注为向后兼容方法
|
|
463
|
+
|
|
464
|
+
**验收标准**:
|
|
465
|
+
```javascript
|
|
466
|
+
/**
|
|
467
|
+
* 获取CLI模式(向后兼容)
|
|
468
|
+
* @deprecated 建议使用 analyzeCLI(cliName, { enhanced: false })
|
|
469
|
+
* @param {string} cliName - CLI工具名称
|
|
470
|
+
* @returns {Promise<Object>} 分析结果
|
|
471
|
+
*/
|
|
472
|
+
async getCLIPattern(cliName) {
|
|
473
|
+
return await this.analyzeCLI(cliName, { enhanced: false });
|
|
474
|
+
}
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### 2.2 简化 getEnhancedCLIPattern() 方法
|
|
478
|
+
|
|
479
|
+
#### 2.2.1 重构为包装器
|
|
480
|
+
- [ ] 删除原有实现
|
|
481
|
+
- [ ] 改为调用 `analyzeCLI(cliName, { enhanced: true })`
|
|
482
|
+
|
|
483
|
+
**验收标准**:
|
|
484
|
+
```javascript
|
|
485
|
+
async getEnhancedCLIPattern(cliName) {
|
|
486
|
+
return await this.analyzeCLI(cliName, { enhanced: true });
|
|
487
|
+
}
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
#### 2.2.2 添加 JSDoc 注释
|
|
491
|
+
- [ ] 添加方法说明
|
|
492
|
+
- [ ] 标注为向后兼容方法
|
|
493
|
+
|
|
494
|
+
**验收标准**:
|
|
495
|
+
```javascript
|
|
496
|
+
/**
|
|
497
|
+
* 获取增强CLI模式(向后兼容)
|
|
498
|
+
* @deprecated 建议使用 analyzeCLI(cliName, { enhanced: true })
|
|
499
|
+
* @param {string} cliName - CLI工具名称
|
|
500
|
+
* @returns {Promise<Object>} 增强分析结果
|
|
501
|
+
*/
|
|
502
|
+
async getEnhancedCLIPattern(cliName) {
|
|
503
|
+
return await this.analyzeCLI(cliName, { enhanced: true });
|
|
504
|
+
}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 2.3 简化 analyzeCLIEnhanced() 方法
|
|
508
|
+
|
|
509
|
+
#### 2.3.1 重构为包装器
|
|
510
|
+
- [ ] 删除原有实现
|
|
511
|
+
- [ ] 改为调用 `analyzeCLI(cliName, { enhanced: true })`
|
|
512
|
+
|
|
513
|
+
**验收标准**:
|
|
514
|
+
```javascript
|
|
515
|
+
async analyzeCLIEnhanced(cliName) {
|
|
516
|
+
return await this.analyzeCLI(cliName, { enhanced: true });
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
#### 2.3.2 添加 JSDoc 注释
|
|
521
|
+
- [ ] 添加方法说明
|
|
522
|
+
- [ ] 标注为向后兼容方法
|
|
523
|
+
|
|
524
|
+
**验收标准**:
|
|
525
|
+
```javascript
|
|
526
|
+
/**
|
|
527
|
+
* 增强分析(向后兼容)
|
|
528
|
+
* @deprecated 建议使用 analyzeCLI(cliName, { enhanced: true })
|
|
529
|
+
* @param {string} cliName - CLI工具名称
|
|
530
|
+
* @returns {Promise<Object>} 增强分析结果
|
|
531
|
+
*/
|
|
532
|
+
async analyzeCLIEnhanced(cliName) {
|
|
533
|
+
return await this.analyzeCLI(cliName, { enhanced: true });
|
|
534
|
+
}
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### 2.4 单元测试 - 包装器方法
|
|
538
|
+
|
|
539
|
+
#### 2.4.1 测试包装器方法调用
|
|
540
|
+
- [ ] 测试 `getCLIPattern()` 调用 `analyzeCLI()`
|
|
541
|
+
- [ ] 测试 `getEnhancedCLIPattern()` 调用 `analyzeCLI()`
|
|
542
|
+
- [ ] 测试 `analyzeCLIEnhanced()` 调用 `analyzeCLI()`
|
|
543
|
+
|
|
544
|
+
**测试用例**:
|
|
545
|
+
```javascript
|
|
546
|
+
describe('wrapper methods', () => {
|
|
547
|
+
test('getCLIPattern() should call analyzeCLI with enhanced=false', async () => {
|
|
548
|
+
const spy = jest.spyOn(analyzer, 'analyzeCLI');
|
|
549
|
+
await analyzer.getCLIPattern('claude');
|
|
550
|
+
|
|
551
|
+
expect(spy).toHaveBeenCalledWith('claude', { enhanced: false });
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
test('getEnhancedCLIPattern() should call analyzeCLI with enhanced=true', async () => {
|
|
555
|
+
const spy = jest.spyOn(analyzer, 'analyzeCLI');
|
|
556
|
+
await analyzer.getEnhancedCLIPattern('claude');
|
|
557
|
+
|
|
558
|
+
expect(spy).toHaveBeenCalledWith('claude', { enhanced: true });
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
test('analyzeCLIEnhanced() should call analyzeCLI with enhanced=true', async () => {
|
|
562
|
+
const spy = jest.spyOn(analyzer, 'analyzeCLI');
|
|
563
|
+
await analyzer.analyzeCLIEnhanced('claude');
|
|
564
|
+
|
|
565
|
+
expect(spy).toHaveBeenCalledWith('claude', { enhanced: true });
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
#### 2.4.2 运行测试
|
|
571
|
+
- [ ] 运行单元测试
|
|
572
|
+
- [ ] 确保所有测试通过
|
|
573
|
+
- [ ] 修复失败的测试
|
|
574
|
+
|
|
575
|
+
**验收标准**:
|
|
576
|
+
- 所有单元测试通过
|
|
577
|
+
- 测试覆盖率 ≥ 80%
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 阶段3:集成测试
|
|
582
|
+
|
|
583
|
+
### 3.1 测试现有功能
|
|
584
|
+
|
|
585
|
+
#### 3.1.1 测试 smart_router.js 集成
|
|
586
|
+
- [ ] 测试 `smart_router.js` 调用 `getEnhancedCLIPattern()`
|
|
587
|
+
- [ ] 测试 `smart_router.js` 调用 `analyzeCLI()`
|
|
588
|
+
- [ ] 确保功能正常
|
|
589
|
+
|
|
590
|
+
**验收标准**:
|
|
591
|
+
```javascript
|
|
592
|
+
describe('smart_router integration', () => {
|
|
593
|
+
test('should work with getEnhancedCLIPattern()', async () => {
|
|
594
|
+
const router = new SmartRouter();
|
|
595
|
+
const pattern = await router.getEnhancedCLIPattern('claude');
|
|
596
|
+
|
|
597
|
+
expect(pattern.success).toBe(true);
|
|
598
|
+
expect(pattern.agentSkillSupport).toBeDefined();
|
|
599
|
+
});
|
|
600
|
+
});
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
#### 3.1.2 测试 enhanced_cli_parameter_handler.js 集成
|
|
604
|
+
- [ ] 测试 `enhanced_cli_parameter_handler.js` 调用 `getCLIPattern()`
|
|
605
|
+
- [ ] 确保功能正常
|
|
606
|
+
|
|
607
|
+
**验收标准**:
|
|
608
|
+
```javascript
|
|
609
|
+
describe('enhanced_cli_parameter_handler integration', () => {
|
|
610
|
+
test('should work with getCLIPattern()', async () => {
|
|
611
|
+
const handler = new EnhancedCLIParameterHandler();
|
|
612
|
+
const pattern = await handler.getCLIPattern('claude');
|
|
613
|
+
|
|
614
|
+
expect(pattern.success).toBe(true);
|
|
615
|
+
});
|
|
616
|
+
});
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
### 3.2 测试新功能
|
|
620
|
+
|
|
621
|
+
#### 3.2.1 测试 analyzeCLI() 新参数
|
|
622
|
+
- [ ] 测试 `enhanced` 参数
|
|
623
|
+
- [ ] 测试 `forceRefresh` 参数
|
|
624
|
+
- [ ] 测试组合使用
|
|
625
|
+
|
|
626
|
+
**验收标准**:
|
|
627
|
+
```javascript
|
|
628
|
+
describe('analyzeCLI() new features', () => {
|
|
629
|
+
test('should support enhanced option', async () => {
|
|
630
|
+
const result = await analyzer.analyzeCLI('claude', { enhanced: true });
|
|
631
|
+
expect(result.agentSkillSupport).toBeDefined();
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test('should support forceRefresh option', async () => {
|
|
635
|
+
const result1 = await analyzer.analyzeCLI('claude');
|
|
636
|
+
const result2 = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
637
|
+
expect(result2.timestamp).not.toEqual(result1.timestamp);
|
|
638
|
+
});
|
|
639
|
+
});
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### 3.3 运行所有测试
|
|
643
|
+
- [ ] 运行单元测试
|
|
644
|
+
- [ ] 运行集成测试
|
|
645
|
+
- [ ] 确保所有测试通过
|
|
646
|
+
|
|
647
|
+
**验收标准**:
|
|
648
|
+
- 所有测试通过
|
|
649
|
+
- 测试覆盖率 ≥ 80%
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
## 阶段4:性能测试
|
|
654
|
+
|
|
655
|
+
### 4.1 基准性能测试
|
|
656
|
+
|
|
657
|
+
#### 4.1.1 测试缓存命中性能
|
|
658
|
+
- [ ] 测试缓存命中时间
|
|
659
|
+
- [ ] 确保不超过 3 秒
|
|
660
|
+
|
|
661
|
+
**验收标准**:
|
|
662
|
+
```javascript
|
|
663
|
+
describe('Performance - cache hit', () => {
|
|
664
|
+
test('cache hit should be fast (< 3s)', async () => {
|
|
665
|
+
await analyzer.analyzeCLI('claude'); // 预热缓存
|
|
666
|
+
const start = Date.now();
|
|
667
|
+
await analyzer.analyzeCLI('claude');
|
|
668
|
+
const elapsed = Date.now() - start;
|
|
669
|
+
|
|
670
|
+
expect(elapsed).toBeLessThan(3000);
|
|
671
|
+
});
|
|
672
|
+
});
|
|
673
|
+
```
|
|
674
|
+
|
|
675
|
+
#### 4.1.2 测试首次分析性能
|
|
676
|
+
- [ ] 测试首次分析时间
|
|
677
|
+
- [ ] 确保不超过 10 秒
|
|
678
|
+
|
|
679
|
+
**验收标准**:
|
|
680
|
+
```javascript
|
|
681
|
+
describe('Performance - first analysis', () => {
|
|
682
|
+
test('first analysis should be reasonable (< 10s)', async () => {
|
|
683
|
+
const start = Date.now();
|
|
684
|
+
await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
685
|
+
const elapsed = Date.now() - start;
|
|
686
|
+
|
|
687
|
+
expect(elapsed).toBeLessThan(10000);
|
|
688
|
+
});
|
|
689
|
+
});
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
#### 4.1.3 测试并行分析性能
|
|
693
|
+
- [ ] 测试并行分析所有 CLI
|
|
694
|
+
- [ ] 确保不超过 35 秒
|
|
695
|
+
|
|
696
|
+
**验收标准**:
|
|
697
|
+
```javascript
|
|
698
|
+
describe('Performance - parallel analysis', () => {
|
|
699
|
+
test('analyze all CLI should be fast (< 35s)', async () => {
|
|
700
|
+
const start = Date.now();
|
|
701
|
+
await analyzer.analyzeAllCLI({ forceRefresh: true });
|
|
702
|
+
const elapsed = Date.now() - start;
|
|
703
|
+
|
|
704
|
+
expect(elapsed).toBeLessThan(35000);
|
|
705
|
+
});
|
|
706
|
+
});
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### 4.2 性能对比
|
|
710
|
+
|
|
711
|
+
#### 4.2.1 对比重构前后性能
|
|
712
|
+
- [ ] 运行重构前基准测试
|
|
713
|
+
- [ ] 运行重构后基准测试
|
|
714
|
+
- [ ] 对比性能数据
|
|
715
|
+
|
|
716
|
+
**验收标准**:
|
|
717
|
+
- 性能不低于重构前
|
|
718
|
+
- 性能下降 ≤ 10%
|
|
719
|
+
|
|
720
|
+
### 4.3 性能报告
|
|
721
|
+
- [ ] 生成性能测试报告
|
|
722
|
+
- [ ] 记录所有性能指标
|
|
723
|
+
- [ ] 确认性能达标
|
|
724
|
+
|
|
725
|
+
**验收标准**:
|
|
726
|
+
- 性能报告完整
|
|
727
|
+
- 所有指标达标
|
|
728
|
+
|
|
729
|
+
---
|
|
730
|
+
|
|
731
|
+
## 阶段5:代码质量检查
|
|
732
|
+
|
|
733
|
+
### 5.1 代码审查
|
|
734
|
+
|
|
735
|
+
#### 5.1.1 自我审查
|
|
736
|
+
- [ ] 检查代码风格
|
|
737
|
+
- [ ] 检查命名规范
|
|
738
|
+
- [ ] 检查注释完整性
|
|
739
|
+
- [ ] 检查代码复杂度
|
|
740
|
+
|
|
741
|
+
**验收标准**:
|
|
742
|
+
- 代码风格统一
|
|
743
|
+
- 命名规范一致
|
|
744
|
+
- 注释清晰完整
|
|
745
|
+
- 方法复杂度 ≤ 10
|
|
746
|
+
|
|
747
|
+
#### 5.1.2 ESLint 检查
|
|
748
|
+
- [ ] 运行 ESLint
|
|
749
|
+
- [ ] 修复所有警告和错误
|
|
750
|
+
|
|
751
|
+
**验收标准**:
|
|
752
|
+
```bash
|
|
753
|
+
npm run lint
|
|
754
|
+
```
|
|
755
|
+
- 无 ESLint 错误
|
|
756
|
+
- 无 ESLint 警告
|
|
757
|
+
|
|
758
|
+
### 5.2 文档更新
|
|
759
|
+
|
|
760
|
+
#### 5.2.1 更新 JSDoc
|
|
761
|
+
- [ ] 确保所有方法有 JSDoc
|
|
762
|
+
- [ ] 确保所有参数有说明
|
|
763
|
+
- [ ] 确保所有返回值有说明
|
|
764
|
+
|
|
765
|
+
**验收标准**:
|
|
766
|
+
- 所有公共方法有 JSDoc
|
|
767
|
+
- 所有参数有说明
|
|
768
|
+
- 所有返回值有说明
|
|
769
|
+
|
|
770
|
+
#### 5.2.2 更新 README(如有需要)
|
|
771
|
+
- [ ] 更新 API 文档
|
|
772
|
+
- [ ] 更新使用示例
|
|
773
|
+
- [ ] 更新迁移指南
|
|
774
|
+
|
|
775
|
+
**验收标准**:
|
|
776
|
+
- API 文档完整
|
|
777
|
+
- 使用示例清晰
|
|
778
|
+
- 迁移指南详细
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
## 阶段6:提交和合并
|
|
783
|
+
|
|
784
|
+
### 6.1 提交代码
|
|
785
|
+
|
|
786
|
+
#### 6.1.1 提交重构代码
|
|
787
|
+
- [ ] 添加所有修改的文件
|
|
788
|
+
- [ ] 提交代码
|
|
789
|
+
- [ ] 使用清晰的提交信息
|
|
790
|
+
|
|
791
|
+
**验收标准**:
|
|
792
|
+
```bash
|
|
793
|
+
git add .
|
|
794
|
+
git commit -m "refactor(cli-help-analyzer): 统一分析入口,简化方法调用链
|
|
795
|
+
|
|
796
|
+
- 修改 analyzeCLI() 支持 options 参数
|
|
797
|
+
- 提取 addEnhancedInfo() 方法
|
|
798
|
+
- 简化包装器方法为统一调用
|
|
799
|
+
- 保持向后兼容性
|
|
800
|
+
- 添加单元测试和集成测试"
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
#### 6.1.2 推送到远程
|
|
804
|
+
- [ ] 推送重构分支到远程
|
|
805
|
+
- [ ] 创建 Pull Request
|
|
806
|
+
|
|
807
|
+
**验收标准**:
|
|
808
|
+
```bash
|
|
809
|
+
git push origin refactor/cli-help-analyzer
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### 6.2 代码审查
|
|
813
|
+
|
|
814
|
+
#### 6.2.1 请求代码审查
|
|
815
|
+
- [ ] 创建 Pull Request
|
|
816
|
+
- [ ] 添加审查者
|
|
817
|
+
- [ ] 等待审查反馈
|
|
818
|
+
|
|
819
|
+
**验收标准**:
|
|
820
|
+
- Pull Request 创建成功
|
|
821
|
+
- 审查者已添加
|
|
822
|
+
|
|
823
|
+
#### 6.2.2 处理审查反馈
|
|
824
|
+
- [ ] 处理所有审查意见
|
|
825
|
+
- [ ] 修改代码(如有需要)
|
|
826
|
+
- [ ] 更新测试(如有需要)
|
|
827
|
+
|
|
828
|
+
**验收标准**:
|
|
829
|
+
- 所有审查意见已处理
|
|
830
|
+
- 代码已更新
|
|
831
|
+
|
|
832
|
+
### 6.3 合并代码
|
|
833
|
+
|
|
834
|
+
#### 6.3.1 合并到主分支
|
|
835
|
+
- [ ] 确认所有测试通过
|
|
836
|
+
- [ ] 确认代码审查通过
|
|
837
|
+
- [ ] 合并到主分支
|
|
838
|
+
|
|
839
|
+
**验收标准**:
|
|
840
|
+
```bash
|
|
841
|
+
git checkout main
|
|
842
|
+
git merge refactor/cli-help-analyzer
|
|
843
|
+
git push origin main
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
#### 6.3.2 删除重构分支
|
|
847
|
+
- [ ] 删除本地重构分支
|
|
848
|
+
- [ ] 删除远程重构分支
|
|
849
|
+
|
|
850
|
+
**验收标准**:
|
|
851
|
+
```bash
|
|
852
|
+
git branch -d refactor/cli-help-analyzer
|
|
853
|
+
git push origin --delete refactor/cli-help-analyzer
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
---
|
|
857
|
+
|
|
858
|
+
## 阶段7:发布和验证
|
|
859
|
+
|
|
860
|
+
### 7.1 发布新版本
|
|
861
|
+
|
|
862
|
+
#### 7.1.1 更新版本号
|
|
863
|
+
- [ ] 更新 package.json 版本号
|
|
864
|
+
- [ ] 提交版本更新
|
|
865
|
+
|
|
866
|
+
**验收标准**:
|
|
867
|
+
```bash
|
|
868
|
+
npm version 1.3.31-beta.0
|
|
869
|
+
git push
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
#### 7.1.2 发布到 npm
|
|
873
|
+
- [ ] 运行 npm publish
|
|
874
|
+
- [ ] 验证发布成功
|
|
875
|
+
|
|
876
|
+
**验收标准**:
|
|
877
|
+
```bash
|
|
878
|
+
npm publish
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### 7.2 验证发布
|
|
882
|
+
|
|
883
|
+
#### 7.2.1 安装新版本
|
|
884
|
+
- [ ] 全局安装新版本
|
|
885
|
+
- [ ] 验证安装成功
|
|
886
|
+
|
|
887
|
+
**验收标准**:
|
|
888
|
+
```bash
|
|
889
|
+
npm install -g stigmergy@1.3.31-beta.0
|
|
890
|
+
stigmergy --version
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
#### 7.2.2 功能验证
|
|
894
|
+
- [ ] 测试所有核心功能
|
|
895
|
+
- [ ] 测试所有外部调用
|
|
896
|
+
- [ ] 确认功能正常
|
|
897
|
+
|
|
898
|
+
**验收标准**:
|
|
899
|
+
- 所有功能正常
|
|
900
|
+
- 无回归问题
|
|
901
|
+
|
|
902
|
+
---
|
|
903
|
+
|
|
904
|
+
## 阶段8:文档和总结
|
|
905
|
+
|
|
906
|
+
### 8.1 更新文档
|
|
907
|
+
|
|
908
|
+
#### 8.1.1 更新 CHANGELOG
|
|
909
|
+
- [ ] 添加重构说明
|
|
910
|
+
- [ ] 记录重大变更
|
|
911
|
+
- [ ] 标注向后兼容性
|
|
912
|
+
|
|
913
|
+
**验收标准**:
|
|
914
|
+
```markdown
|
|
915
|
+
## [1.3.31-beta.0] - 2026-01-11
|
|
916
|
+
|
|
917
|
+
### Changed
|
|
918
|
+
- 重构 CLI Help Analyzer,统一分析入口
|
|
919
|
+
- 简化方法调用链,减少代码冗余
|
|
920
|
+
|
|
921
|
+
### Added
|
|
922
|
+
- analyzeCLI() 支持 options 参数
|
|
923
|
+
- addEnhancedInfo() 方法
|
|
924
|
+
|
|
925
|
+
### Deprecated
|
|
926
|
+
- getCLIPattern() (建议使用 analyzeCLI())
|
|
927
|
+
- getEnhancedCLIPattern() (建议使用 analyzeCLI({ enhanced: true }))
|
|
928
|
+
- analyzeCLIEnhanced() (建议使用 analyzeCLI({ enhanced: true }))
|
|
929
|
+
|
|
930
|
+
### Notes
|
|
931
|
+
- 保持向后兼容性
|
|
932
|
+
- 所有现有功能正常工作
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
#### 8.1.2 更新 API 文档
|
|
936
|
+
- [ ] 更新 API 使用示例
|
|
937
|
+
- [ ] 添加迁移指南
|
|
938
|
+
- [ ] 更新最佳实践
|
|
939
|
+
|
|
940
|
+
**验收标准**:
|
|
941
|
+
- API 文档完整
|
|
942
|
+
- 使用示例清晰
|
|
943
|
+
- 迁移指南详细
|
|
944
|
+
|
|
945
|
+
### 8.1.5 清理临时文件和存档
|
|
946
|
+
|
|
947
|
+
#### 8.1.5.1 清理临时测试文件
|
|
948
|
+
- [ ] 删除临时测试文件(如有)
|
|
949
|
+
- [ ] 删除调试日志文件(如有)
|
|
950
|
+
- [ ] 删除临时缓存文件
|
|
951
|
+
- [ ] 清理 node_modules/.cache(如有)
|
|
952
|
+
|
|
953
|
+
**验收标准**:
|
|
954
|
+
- 无临时测试文件残留
|
|
955
|
+
- 无调试日志文件残留
|
|
956
|
+
- 临时缓存已清理
|
|
957
|
+
|
|
958
|
+
#### 8.1.5.2 存档过时实现
|
|
959
|
+
- [ ] 创建 archive/ 目录(如不存在)
|
|
960
|
+
- [ ] 将重构前的实现备份到 archive/cli_help_analyzer.backup.js
|
|
961
|
+
- [ ] 创建 README.md 说明备份内容
|
|
962
|
+
- [ ] 记录备份日期和版本
|
|
963
|
+
|
|
964
|
+
**验收标准**:
|
|
965
|
+
```bash
|
|
966
|
+
# 创建备份
|
|
967
|
+
mkdir -p archive
|
|
968
|
+
cp src/core/cli_help_analyzer.js archive/cli_help_analyzer.backup.js
|
|
969
|
+
echo "# CLI Help Analyzer 备份\n\n备份日期: 2026-01-11\n备份版本: 1.3.30-beta.0\n\n此文件是重构前的实现备份,保留用于参考和回滚。" > archive/README.md
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
#### 8.1.5.3 清理文档冗余
|
|
973
|
+
- [ ] 删除过时的设计文档草稿(如有)
|
|
974
|
+
- [ ] 删除重复的文档(如有)
|
|
975
|
+
- [ ] 整理文档目录结构
|
|
976
|
+
- [ ] 确保文档版本一致
|
|
977
|
+
|
|
978
|
+
**验收标准**:
|
|
979
|
+
- 文档目录结构清晰
|
|
980
|
+
- 无过时文档
|
|
981
|
+
- 无重复文档
|
|
982
|
+
|
|
983
|
+
### 8.2 设计决策追溯
|
|
984
|
+
|
|
985
|
+
#### 8.2.1 DDR-001: 保留包装器方法
|
|
986
|
+
**决策描述**:保留 getCLIPattern()、getEnhancedCLIPattern()、analyzeCLIEnhanced() 作为包装器方法
|
|
987
|
+
|
|
988
|
+
**实施状态**:
|
|
989
|
+
- [ ] 已实现:getCLIPattern() 调用 analyzeCLI(cliName, { enhanced: false })
|
|
990
|
+
- [ ] 已实现:getEnhancedCLIPattern() 调用 analyzeCLI(cliName, { enhanced: true })
|
|
991
|
+
- [ ] 已实现:analyzeCLIEnhanced() 调用 analyzeCLI(cliName, { enhanced: true })
|
|
992
|
+
- [ ] 已标注:@deprecated 注释添加到所有包装器方法
|
|
993
|
+
- [ ] 已测试:包装器方法测试通过(阶段2.4)
|
|
994
|
+
|
|
995
|
+
**验证方法**:
|
|
996
|
+
```javascript
|
|
997
|
+
// 验证 getCLIPattern() 正确调用
|
|
998
|
+
const spy = jest.spyOn(analyzer, 'analyzeCLI');
|
|
999
|
+
await analyzer.getCLIPattern('claude');
|
|
1000
|
+
expect(spy).toHaveBeenCalledWith('claude', { enhanced: false });
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
#### 8.2.2 DDR-002: 使用 options 对象
|
|
1004
|
+
**决策描述**:使用 options 对象控制 analyzeCLI() 行为,而不是多个方法
|
|
1005
|
+
|
|
1006
|
+
**实施状态**:
|
|
1007
|
+
- [ ] 已实现:analyzeCLI(cliName, options) 方法签名
|
|
1008
|
+
- [ ] 已实现:enhanced 参数支持(默认 false)
|
|
1009
|
+
- [ ] 已实现:forceRefresh 参数支持(默认 false)
|
|
1010
|
+
- [ ] 已测试:enhanced 参数测试通过(阶段1.6.1)
|
|
1011
|
+
- [ ] 已测试:forceRefresh 参数测试通过(阶段1.6.1)
|
|
1012
|
+
- [ ] 已文档:JSDoc 注释完整
|
|
1013
|
+
|
|
1014
|
+
**验证方法**:
|
|
1015
|
+
```javascript
|
|
1016
|
+
// 验证 enhanced 参数
|
|
1017
|
+
const result = await analyzer.analyzeCLI('claude', { enhanced: true });
|
|
1018
|
+
expect(result.agentSkillSupport).toBeDefined();
|
|
1019
|
+
|
|
1020
|
+
// 验证 forceRefresh 参数
|
|
1021
|
+
const result1 = await analyzer.analyzeCLI('claude');
|
|
1022
|
+
const result2 = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
1023
|
+
expect(result2.timestamp).not.toEqual(result1.timestamp);
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
#### 8.2.3 DDR-003: addEnhancedInfo() 不修改原对象
|
|
1027
|
+
**决策描述**:addEnhancedInfo() 方法返回新对象,不修改原始分析结果
|
|
1028
|
+
|
|
1029
|
+
**实施状态**:
|
|
1030
|
+
- [ ] 已实现:使用展开运算符返回新对象
|
|
1031
|
+
- [ ] 已测试:不修改原对象测试通过(阶段1.6.2)
|
|
1032
|
+
- [ ] 已文档:代码注释说明
|
|
1033
|
+
|
|
1034
|
+
**验证方法**:
|
|
1035
|
+
```javascript
|
|
1036
|
+
// 验证不修改原对象
|
|
1037
|
+
const basicAnalysis = { cliName: 'claude', version: '2.1.4' };
|
|
1038
|
+
const enhancedAnalysis = analyzer.addEnhancedInfo(basicAnalysis, 'claude');
|
|
1039
|
+
expect(basicAnalysis.agentSkillSupport).toBeUndefined();
|
|
1040
|
+
expect(enhancedAnalysis.agentSkillSupport).toBeDefined();
|
|
1041
|
+
```
|
|
1042
|
+
|
|
1043
|
+
#### 8.2.4 DDR-004: 错误处理策略
|
|
1044
|
+
**决策描述**:错误时返回失败结果而非抛出异常,确保系统稳定性
|
|
1045
|
+
|
|
1046
|
+
**实施状态**:
|
|
1047
|
+
- [ ] 已实现:工具不存在时返回失败结果(阶段1.4.5)
|
|
1048
|
+
- [ ] 已实现:缓存失败时使用内存配置(阶段1.4.3)
|
|
1049
|
+
- [ ] 已实现:配置文件写入失败时不阻塞(阶段1.4.4)
|
|
1050
|
+
- [ ] 已测试:错误处理测试通过(阶段1.6.4)
|
|
1051
|
+
|
|
1052
|
+
**验证方法**:
|
|
1053
|
+
```javascript
|
|
1054
|
+
// 验证错误处理
|
|
1055
|
+
const result = await analyzer.analyzeCLI('nonexistent-cli');
|
|
1056
|
+
expect(result.success).toBe(false);
|
|
1057
|
+
expect(result.error).toContain('not found');
|
|
1058
|
+
```
|
|
1059
|
+
|
|
1060
|
+
#### 8.2.5 DDR-005: 边界条件处理
|
|
1061
|
+
**决策描述**:明确处理各种边界条件和异常输入,提高健壮性
|
|
1062
|
+
|
|
1063
|
+
**实施状态**:
|
|
1064
|
+
- [ ] 已实现:cliName 参数验证(阶段1.1.1)
|
|
1065
|
+
- [ ] 已实现:options 参数验证(阶段1.1.1)
|
|
1066
|
+
- [ ] 已实现:版本检测失败处理(阶段1.5.1)
|
|
1067
|
+
- [ ] 已实现:命令超时处理(阶段1.5.3)
|
|
1068
|
+
- [ ] 已测试:边界条件测试通过(阶段1.6.5)
|
|
1069
|
+
|
|
1070
|
+
**验证方法**:
|
|
1071
|
+
```javascript
|
|
1072
|
+
// 验证参数验证
|
|
1073
|
+
await expect(analyzer.analyzeCLI(null)).rejects.toThrow('cliName cannot be empty or null');
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
### 8.3 项目总结
|
|
1077
|
+
|
|
1078
|
+
#### 8.2.1 编写总结报告
|
|
1079
|
+
- [ ] 记录重构过程
|
|
1080
|
+
- [ ] 记录遇到的问题
|
|
1081
|
+
- [ ] 记录解决方案
|
|
1082
|
+
- [ ] 记录经验教训
|
|
1083
|
+
|
|
1084
|
+
**验收标准**:
|
|
1085
|
+
- 总结报告完整
|
|
1086
|
+
- 经验教训清晰
|
|
1087
|
+
- 建议和意见明确
|
|
1088
|
+
|
|
1089
|
+
#### 8.2.2 分享经验
|
|
1090
|
+
- [ ] 团队分享重构经验
|
|
1091
|
+
- [ ] 讨论改进建议
|
|
1092
|
+
- [ ] 规划下一步优化
|
|
1093
|
+
|
|
1094
|
+
**验收标准**:
|
|
1095
|
+
- 团队分享完成
|
|
1096
|
+
- 改进建议明确
|
|
1097
|
+
- 下一步计划清晰
|
|
1098
|
+
|
|
1099
|
+
---
|
|
1100
|
+
|
|
1101
|
+
## 附录
|
|
1102
|
+
|
|
1103
|
+
### A. 测试用例清单
|
|
1104
|
+
|
|
1105
|
+
#### A.1 单元测试用例
|
|
1106
|
+
- [ ] analyzeCLI() - enhanced=false
|
|
1107
|
+
- [ ] analyzeCLI() - enhanced=true
|
|
1108
|
+
- [ ] analyzeCLI() - forceRefresh=true
|
|
1109
|
+
- [ ] analyzeCLI() - enhanced=true + forceRefresh=true
|
|
1110
|
+
- [ ] analyzeCLI() - 版本检测
|
|
1111
|
+
- [ ] analyzeCLI() - 缓存过期
|
|
1112
|
+
- [ ] addEnhancedInfo() - 添加增强信息
|
|
1113
|
+
- [ ] addEnhancedInfo() - 不修改原对象
|
|
1114
|
+
- [ ] getCLIPattern() - 调用 analyzeCLI()
|
|
1115
|
+
- [ ] getEnhancedCLIPattern() - 调用 analyzeCLI()
|
|
1116
|
+
- [ ] analyzeCLIEnhanced() - 调用 analyzeCLI()
|
|
1117
|
+
- [ ] analyzeAllCLI() - 并行分析
|
|
1118
|
+
- [ ] analyzeAllCLI() - enhanced=true
|
|
1119
|
+
- [ ] analyzeAllCLI() - forceRefresh=true
|
|
1120
|
+
|
|
1121
|
+
#### A.2 集成测试用例
|
|
1122
|
+
- [ ] smart_router.js - getEnhancedCLIPattern()
|
|
1123
|
+
- [ ] smart_router.js - analyzeCLI()
|
|
1124
|
+
- [ ] enhanced_cli_parameter_handler.js - getCLIPattern()
|
|
1125
|
+
- [ ] 完整流程测试
|
|
1126
|
+
|
|
1127
|
+
#### A.3 性能测试用例
|
|
1128
|
+
- [ ] 缓存命中性能 (< 3s)
|
|
1129
|
+
- [ ] 首次分析性能 (< 10s)
|
|
1130
|
+
- [ ] 并行分析性能 (< 35s)
|
|
1131
|
+
- [ ] 内存使用检查
|
|
1132
|
+
|
|
1133
|
+
#### A.4 错误处理测试用例(FR-007)
|
|
1134
|
+
- [ ] analyzeCLI() - cliName不存在返回失败结果
|
|
1135
|
+
- [ ] analyzeCLI() - 配置文件损坏时恢复默认配置
|
|
1136
|
+
- [ ] analyzeCLI() - 缓存读取失败时使用内存配置
|
|
1137
|
+
- [ ] analyzeCLI() - 配置文件写入失败时不阻塞主流程
|
|
1138
|
+
- [ ] analyzeCLI() - 失败后能够重新分析
|
|
1139
|
+
- [ ] analyzeCLI() - 错误日志正确记录
|
|
1140
|
+
|
|
1141
|
+
**测试用例示例**:
|
|
1142
|
+
```javascript
|
|
1143
|
+
describe('Error Handling (FR-007)', () => {
|
|
1144
|
+
test('should return failure result when cliName not found', async () => {
|
|
1145
|
+
const result = await analyzer.analyzeCLI('nonexistent-cli');
|
|
1146
|
+
expect(result.success).toBe(false);
|
|
1147
|
+
expect(result.error).toContain('not found');
|
|
1148
|
+
});
|
|
1149
|
+
|
|
1150
|
+
test('should handle cache read failure gracefully', async () => {
|
|
1151
|
+
// Mock cache read failure
|
|
1152
|
+
jest.spyOn(analyzer.configManager, 'readCache').mockRejectedValue(new Error('Cache read failed'));
|
|
1153
|
+
const result = await analyzer.analyzeCLI('claude');
|
|
1154
|
+
expect(result.success).toBe(true); // Should still work with in-memory config
|
|
1155
|
+
});
|
|
1156
|
+
|
|
1157
|
+
test('should not block main flow when cache write fails', async () => {
|
|
1158
|
+
// Mock cache write failure
|
|
1159
|
+
jest.spyOn(analyzer.configManager, 'writeCache').mockRejectedValue(new Error('Cache write failed'));
|
|
1160
|
+
const result = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
1161
|
+
expect(result.success).toBe(true); // Should still return result
|
|
1162
|
+
});
|
|
1163
|
+
});
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
#### A.5 边界条件测试用例(FR-008)
|
|
1167
|
+
- [ ] analyzeCLI() - cliName为null抛出明确错误
|
|
1168
|
+
- [ ] analyzeCLI() - cliName为空字符串抛出明确错误
|
|
1169
|
+
- [ ] analyzeCLI() - options参数为null使用默认值
|
|
1170
|
+
- [ ] analyzeCLI() - options参数类型错误抛出明确错误
|
|
1171
|
+
- [ ] analyzeCLI() - 版本检测失败使用'unknown'标记
|
|
1172
|
+
- [ ] analyzeCLI() - 帮助信息获取失败返回失败结果
|
|
1173
|
+
- [ ] analyzeCLI() - CLI命令执行超时返回失败结果
|
|
1174
|
+
- [ ] analyzeCLI() - 配置文件不存在时创建默认配置
|
|
1175
|
+
|
|
1176
|
+
**测试用例示例**:
|
|
1177
|
+
```javascript
|
|
1178
|
+
describe('Boundary Conditions (FR-008)', () => {
|
|
1179
|
+
test('should throw error when cliName is null', async () => {
|
|
1180
|
+
await expect(analyzer.analyzeCLI(null)).rejects.toThrow('cliName cannot be empty or null');
|
|
1181
|
+
});
|
|
1182
|
+
|
|
1183
|
+
test('should throw error when cliName is empty string', async () => {
|
|
1184
|
+
await expect(analyzer.analyzeCLI('')).rejects.toThrow('cliName cannot be empty or null');
|
|
1185
|
+
});
|
|
1186
|
+
|
|
1187
|
+
test('should use default options when options is null', async () => {
|
|
1188
|
+
const result = await analyzer.analyzeCLI('claude', null);
|
|
1189
|
+
expect(result.success).toBe(true);
|
|
1190
|
+
});
|
|
1191
|
+
|
|
1192
|
+
test('should throw error when options type is wrong', async () => {
|
|
1193
|
+
await expect(analyzer.analyzeCLI('claude', 'invalid')).rejects.toThrow('options must be an object');
|
|
1194
|
+
});
|
|
1195
|
+
|
|
1196
|
+
test('should use unknown marker when version detection fails', async () => {
|
|
1197
|
+
// Mock version detection failure
|
|
1198
|
+
jest.spyOn(analyzer, 'executeCommand').mockRejectedValue(new Error('Version command failed'));
|
|
1199
|
+
const result = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
1200
|
+
expect(result.version).toBe('unknown');
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
test('should handle command timeout', async () => {
|
|
1204
|
+
// Mock command timeout
|
|
1205
|
+
jest.spyOn(analyzer, 'executeCommand').mockRejectedValue(new Error('Command timeout'));
|
|
1206
|
+
const result = await analyzer.analyzeCLI('claude', { forceRefresh: true });
|
|
1207
|
+
expect(result.success).toBe(false);
|
|
1208
|
+
});
|
|
1209
|
+
});
|
|
1210
|
+
```
|
|
1211
|
+
|
|
1212
|
+
### B. 验收标准清单
|
|
1213
|
+
|
|
1214
|
+
#### B.1 功能验收
|
|
1215
|
+
- [ ] 所有功能需求满足
|
|
1216
|
+
- [ ] 所有现有测试通过
|
|
1217
|
+
- [ ] 所有新增测试通过
|
|
1218
|
+
|
|
1219
|
+
#### B.2 性能验收
|
|
1220
|
+
- [ ] 所有性能需求满足
|
|
1221
|
+
- [ ] 性能不低于重构前
|
|
1222
|
+
- [ ] 性能测试报告通过
|
|
1223
|
+
|
|
1224
|
+
#### B.3 质量验收
|
|
1225
|
+
- [ ] 代码审查通过
|
|
1226
|
+
- [ ] 测试覆盖率 ≥ 80%
|
|
1227
|
+
- [ ] 无严重 bug
|
|
1228
|
+
|
|
1229
|
+
#### B.4 文档验收
|
|
1230
|
+
- [ ] API 文档完整
|
|
1231
|
+
- [ ] 使用示例清晰
|
|
1232
|
+
- [ ] 迁移指南详细
|
|
1233
|
+
- [ ] CHANGELOG 更新
|
|
1234
|
+
|
|
1235
|
+
### C. 风险检查清单
|
|
1236
|
+
|
|
1237
|
+
#### C.1 技术风险
|
|
1238
|
+
- [ ] 无破坏现有功能
|
|
1239
|
+
- [ ] 无性能下降
|
|
1240
|
+
- [ ] 无缓存逻辑错误
|
|
1241
|
+
|
|
1242
|
+
#### C.2 业务风险
|
|
1243
|
+
- [ ] 无用户升级问题
|
|
1244
|
+
- [ ] 无维护成本增加
|
|
1245
|
+
|
|
1246
|
+
### D. 回滚计划
|
|
1247
|
+
|
|
1248
|
+
#### D.1 回滚触发条件
|
|
1249
|
+
- [ ] 严重 bug 无法修复
|
|
1250
|
+
- [ ] 性能严重下降
|
|
1251
|
+
- [ ] 破坏向后兼容性
|
|
1252
|
+
|
|
1253
|
+
#### D.2 回滚步骤
|
|
1254
|
+
- [ ] 回退到重构前的提交
|
|
1255
|
+
- [ ] 重新发布版本
|
|
1256
|
+
- [ ] 通知用户
|
|
1257
|
+
|
|
1258
|
+
**验收标准**:
|
|
1259
|
+
- 回滚步骤清晰
|
|
1260
|
+
- 回滚时间 < 1 小时
|
|
1261
|
+
|
|
1262
|
+
---
|
|
1263
|
+
|
|
1264
|
+
## 变更历史
|
|
1265
|
+
|
|
1266
|
+
| 版本 | 日期 | 作者 | 变更说明 |
|
|
1267
|
+
|------|------|------|----------|
|
|
1268
|
+
| 1.0 | 2026-01-11 | iFlow | 初始版本 |
|