stigmergy 1.2.13 → 1.3.2-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +39 -3
  2. package/STIGMERGY.md +3 -0
  3. package/config/enhanced-cli-config.json +438 -0
  4. package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
  5. package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
  6. package/docs/INSTALLER_ARCHITECTURE.md +257 -0
  7. package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
  8. package/package.json +14 -5
  9. package/scripts/analyze-router.js +168 -0
  10. package/scripts/test-runner.js +344 -0
  11. package/src/cli/commands/autoinstall.js +158 -0
  12. package/src/cli/commands/errors.js +190 -0
  13. package/src/cli/commands/install.js +142 -0
  14. package/src/cli/commands/permissions.js +108 -0
  15. package/src/cli/commands/project.js +449 -0
  16. package/src/cli/commands/resume.js +136 -0
  17. package/src/cli/commands/scan.js +97 -0
  18. package/src/cli/commands/skills.js +158 -0
  19. package/src/cli/commands/status.js +106 -0
  20. package/src/cli/commands/system.js +301 -0
  21. package/src/cli/router-beta.js +477 -0
  22. package/src/cli/utils/environment.js +75 -0
  23. package/src/cli/utils/formatters.js +47 -0
  24. package/src/cli/utils/skills_cache.js +92 -0
  25. package/src/core/cache_cleaner.js +1 -0
  26. package/src/core/cli_adapters.js +345 -0
  27. package/src/core/cli_help_analyzer.js +473 -1
  28. package/src/core/cli_path_detector.js +2 -1
  29. package/src/core/cli_tools.js +107 -0
  30. package/src/core/coordination/nodejs/HookDeploymentManager.js +185 -422
  31. package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
  32. package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
  33. package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +701 -0
  34. package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1210 -0
  35. package/src/core/coordination/nodejs/generators/index.js +12 -0
  36. package/src/core/enhanced_cli_installer.js +220 -30
  37. package/src/core/enhanced_cli_parameter_handler.js +395 -0
  38. package/src/core/execution_mode_detector.js +222 -0
  39. package/src/core/installer.js +51 -70
  40. package/src/core/local_skill_scanner.js +732 -0
  41. package/src/core/multilingual/language-pattern-manager.js +1 -1
  42. package/src/core/skills/StigmergySkillManager.js +26 -8
  43. package/src/core/smart_router.js +279 -2
  44. package/src/index.js +10 -4
  45. package/test/cli-integration.test.js +304 -0
  46. package/test/enhanced-cli-agent-skill-test.js +485 -0
  47. package/test/specific-cli-agent-skill-analysis.js +385 -0
  48. package/src/cli/router.js +0 -1783
@@ -0,0 +1,304 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * 严格的CLI集成测试框架
5
+ * 在真实shell环境下测试每个CLI的stigmergy-resume命令
6
+ */
7
+
8
+ const { spawn, spawnSync } = require('child_process');
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ class CLIIntegrationTester {
13
+ constructor() {
14
+ this.testResults = [];
15
+ this.cliPaths = this.discoverCLIPaths();
16
+ }
17
+
18
+ // 发现各CLI的实际安装路径
19
+ discoverCLIPaths() {
20
+ const paths = {};
21
+
22
+ // Claude CLI
23
+ try {
24
+ const claudeResult = spawnSync('where', ['claude'], { encoding: 'utf8' });
25
+ if (claudeResult.status === 0) {
26
+ paths.claude = claudeResult.stdout.trim().split('\n')[0];
27
+ }
28
+ } catch (e) {}
29
+
30
+ // Gemini CLI
31
+ try {
32
+ const geminiResult = spawnSync('where', ['gemini'], { encoding: 'utf8' });
33
+ if (geminiResult.status === 0) {
34
+ paths.gemini = geminiResult.stdout.trim().split('\n')[0];
35
+ }
36
+ } catch (e) {}
37
+
38
+ // Qwen CLI
39
+ try {
40
+ const qwenResult = spawnSync('where', ['qwen'], { encoding: 'utf8' });
41
+ if (qwenResult.status === 0) {
42
+ paths.qwen = qwenResult.stdout.trim().split('\n')[0];
43
+ }
44
+ } catch (e) {}
45
+
46
+ // 其他CLI...
47
+
48
+ console.log('🔍 发现的CLI路径:');
49
+ Object.entries(paths).forEach(([cli, path]) => {
50
+ console.log(` ${cli}: ${path}`);
51
+ });
52
+
53
+ return paths;
54
+ }
55
+
56
+ // 执行CLI命令并返回结果
57
+ async executeCommand(cliName, command, timeout = 15000) {
58
+ return new Promise((resolve) => {
59
+ console.log(`\n🔧 执行: ${cliName} ${command}`);
60
+
61
+ const startTime = Date.now();
62
+ let stdout = '';
63
+ let stderr = '';
64
+
65
+ let child;
66
+
67
+ try {
68
+ if (this.cliPaths[cliName]) {
69
+ child = spawn(this.cliPaths[cliName], [command], {
70
+ stdio: ['pipe', 'pipe', 'pipe'],
71
+ encoding: 'utf8'
72
+ });
73
+ } else {
74
+ // 如果找不到CLI,尝试直接调用
75
+ child = spawn(cliName.toLowerCase(), [command], {
76
+ stdio: ['pipe', 'pipe', 'pipe'],
77
+ encoding: 'utf8'
78
+ });
79
+ }
80
+ } catch (error) {
81
+ resolve({
82
+ success: false,
83
+ error: error.message,
84
+ command: `${cliName} ${command}`,
85
+ duration: Date.now() - startTime,
86
+ stdout: '',
87
+ stderr: ''
88
+ });
89
+ return;
90
+ }
91
+
92
+ const timeoutId = setTimeout(() => {
93
+ child.kill('SIGTERM');
94
+ resolve({
95
+ success: false,
96
+ error: 'Command timeout',
97
+ command: `${cliName} ${command}`,
98
+ duration: Date.now() - startTime,
99
+ stdout,
100
+ stderr
101
+ });
102
+ }, timeout);
103
+
104
+ child.stdout.on('data', (data) => {
105
+ stdout += data;
106
+ });
107
+
108
+ child.stderr.on('data', (data) => {
109
+ stderr += data;
110
+ });
111
+
112
+ child.on('close', (code) => {
113
+ clearTimeout(timeoutId);
114
+
115
+ resolve({
116
+ success: code === 0,
117
+ exitCode: code,
118
+ command: `${cliName} ${command}`,
119
+ duration: Date.now() - startTime,
120
+ stdout,
121
+ stderr
122
+ });
123
+ });
124
+
125
+ child.on('error', (error) => {
126
+ clearTimeout(timeoutId);
127
+ resolve({
128
+ success: false,
129
+ error: error.message,
130
+ command: `${cliName} ${command}`,
131
+ duration: Date.now() - startTime,
132
+ stdout,
133
+ stderr
134
+ });
135
+ });
136
+ });
137
+ }
138
+
139
+ // 测试单个CLI
140
+ async testCLI(cliName, config) {
141
+ console.log(`\n🎯 测试 ${cliName} CLI (${config.expectedFormat})`);
142
+ console.log('='.repeat(60));
143
+
144
+ const results = {
145
+ cliName,
146
+ expectedFormat: config.expectedFormat,
147
+ tests: [],
148
+ overallSuccess: false
149
+ };
150
+
151
+ // 测试主要命令格式
152
+ for (const testCommand of config.testCommands) {
153
+ const result = await this.executeCommand(cliName, testCommand);
154
+
155
+ results.tests.push({
156
+ command: testCommand,
157
+ ...result,
158
+ expectedFormat: config.expectedFormat
159
+ });
160
+
161
+ // 分析结果
162
+ if (result.success || this.containsStigmergyResponse(result.stdout, result.stderr)) {
163
+ console.log(`✅ ${testCommand} - 成功`);
164
+ } else if (result.error.includes('ENOENT')) {
165
+ console.log(`❌ ${testCommand} - CLI未找到`);
166
+ } else {
167
+ console.log(`⚠️ ${testCommand} - 部分成功/需要调试`);
168
+ if (result.stderr) console.log(` 错误: ${result.stderr.substring(0, 100)}...`);
169
+ }
170
+ }
171
+
172
+ results.overallSuccess = results.tests.some(t => t.success || this.containsStigmergyResponse(t.stdout, t.stderr));
173
+ this.testResults.push(results);
174
+
175
+ return results;
176
+ }
177
+
178
+ // 检查响应是否包含stigmergy相关内容
179
+ containsStigmergyResponse(stdout, stderr) {
180
+ const output = (stdout + stderr).toLowerCase();
181
+ const stigmergyKeywords = [
182
+ 'stigmergy',
183
+ 'history',
184
+ 'session',
185
+ 'cross-cli',
186
+ 'resume',
187
+ '会话',
188
+ '历史'
189
+ ];
190
+ return stigmergyKeywords.some(keyword => output.includes(keyword));
191
+ }
192
+
193
+ // 生成测试报告
194
+ generateReport() {
195
+ console.log('\n📊 集成测试报告');
196
+ console.log('='.repeat(80));
197
+
198
+ const successful = this.testResults.filter(r => r.overallSuccess);
199
+ const failed = this.testResults.filter(r => !r.overallSuccess);
200
+
201
+ console.log(`✅ 成功的CLI: ${successful.length}`);
202
+ successful.forEach(r => {
203
+ console.log(` - ${r.cliName} (${r.expectedFormat})`);
204
+ });
205
+
206
+ console.log(`\n❌ 失败的CLI: ${failed.length}`);
207
+ failed.forEach(r => {
208
+ console.log(` - ${r.cliName} (${r.expectedFormat})`);
209
+ const workingTests = r.tests.filter(t => t.success || this.containsStigmergyResponse(t.stdout, t.stderr));
210
+ if (workingTests.length > 0) {
211
+ console.log(` 部分工作的命令: ${workingTests.map(t => t.command).join(', ')}`);
212
+ }
213
+ });
214
+
215
+ // 详细结果
216
+ console.log('\n🔍 详细测试结果:');
217
+ this.testResults.forEach(result => {
218
+ console.log(`\n${result.cliName}:`);
219
+ result.tests.forEach(test => {
220
+ const status = test.success ? '✅' :
221
+ this.containsStigmergyResponse(test.stdout, test.stderr) ? '⚠️' : '❌';
222
+ console.log(` ${status} ${test.command} (${test.duration}ms)`);
223
+ if (test.error) {
224
+ console.log(` 错误: ${test.error}`);
225
+ }
226
+ });
227
+ });
228
+ }
229
+ }
230
+
231
+ // 测试配置
232
+ const testConfigs = [
233
+ {
234
+ cliName: 'Claude',
235
+ expectedFormat: '需要斜杠前缀: /stigmergy-resume',
236
+ testCommands: [
237
+ '/stigmergy-resume --help',
238
+ '/stigmergy-resume --limit 1',
239
+ '/stigmergy-resume --cli claude'
240
+ ]
241
+ },
242
+ {
243
+ cliName: 'Gemini',
244
+ expectedFormat: '不需要斜杠前缀: stigmergy-resume',
245
+ testCommands: [
246
+ 'stigmergy-resume --help',
247
+ 'stigmergy-resume --limit 1',
248
+ 'stigmergy-resume --cli gemini'
249
+ ]
250
+ },
251
+ {
252
+ cliName: 'Qwen',
253
+ expectedFormat: '不需要斜杠前缀: stigmergy-resume',
254
+ testCommands: [
255
+ 'stigmergy-resume --help',
256
+ 'stigmergy-resume --limit 1',
257
+ 'stigmergy-resume --cli qwen'
258
+ ]
259
+ },
260
+ {
261
+ cliName: 'CodeBuddy',
262
+ expectedFormat: '需要斜杠前缀: /stigmergy-resume',
263
+ testCommands: [
264
+ '/stigmergy-resume --help',
265
+ '/stigmergy-resume --limit 1',
266
+ '/stigmergy-resume --cli codebuddy'
267
+ ]
268
+ },
269
+ {
270
+ cliName: 'Codex',
271
+ expectedFormat: '不需要斜杠前缀: stigmergy-resume',
272
+ testCommands: [
273
+ 'stigmergy-resume --help',
274
+ 'stigmergy-resume --limit 1',
275
+ 'stigmergy-resume --cli codex'
276
+ ]
277
+ }
278
+ ];
279
+
280
+ // 运行测试
281
+ async function runIntegrationTests() {
282
+ console.log('🚀 开始严格的CLI集成测试...\n');
283
+
284
+ const tester = new CLIIntegrationTester();
285
+
286
+ for (const config of testConfigs) {
287
+ await tester.testCLI(config.cliName, config);
288
+ }
289
+
290
+ tester.generateReport();
291
+
292
+ console.log('\n💡 调试建议:');
293
+ console.log('1. 检查CLI是否正确安装并在PATH中');
294
+ console.log('2. 验证hooks/extensions文件是否正确部署');
295
+ console.log('3. 确认每个CLI的插件系统是否正常工作');
296
+ console.log('4. 查看各CLI的调试日志获取更多信息');
297
+ }
298
+
299
+ // 执行测试
300
+ if (require.main === module) {
301
+ runIntegrationTests().catch(console.error);
302
+ }
303
+
304
+ module.exports = CLIIntegrationTester;