stigmergy 1.2.12 → 1.3.1-beta

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 (84) hide show
  1. package/README.md +39 -3
  2. package/STIGMERGY.md +3 -0
  3. package/config/builtin-skills.json +43 -0
  4. package/config/enhanced-cli-config.json +438 -0
  5. package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
  6. package/docs/DESIGN_CLI_HELP_ANALYZER_REFACTOR.md +726 -0
  7. package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
  8. package/docs/IMPLEMENTATION_CHECKLIST_CLI_HELP_ANALYZER_REFACTOR.md +1268 -0
  9. package/docs/INSTALLER_ARCHITECTURE.md +257 -0
  10. package/docs/LESSONS_LEARNED.md +252 -0
  11. package/docs/SPECS_CLI_HELP_ANALYZER_REFACTOR.md +287 -0
  12. package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
  13. package/docs/correct-skillsio-implementation.md +368 -0
  14. package/docs/development_guidelines.md +276 -0
  15. package/docs/independent-resume-implementation.md +198 -0
  16. package/docs/resumesession-final-implementation.md +195 -0
  17. package/docs/resumesession-usage.md +87 -0
  18. package/package.json +19 -9
  19. package/scripts/analyze-router.js +168 -0
  20. package/scripts/run-comprehensive-tests.js +230 -0
  21. package/scripts/run-quick-tests.js +90 -0
  22. package/scripts/test-runner.js +344 -0
  23. package/skills/resumesession/INDEPENDENT_SKILL.md +171 -0
  24. package/skills/resumesession/SKILL.md +127 -0
  25. package/skills/resumesession/__init__.py +33 -0
  26. package/skills/resumesession/implementations/simple-resume.js +13 -0
  27. package/src/adapters/claude/install_claude_integration.js +9 -1
  28. package/src/adapters/codebuddy/install_codebuddy_integration.js +3 -1
  29. package/src/adapters/codex/install_codex_integration.js +15 -5
  30. package/src/adapters/gemini/install_gemini_integration.js +3 -1
  31. package/src/adapters/qwen/install_qwen_integration.js +3 -1
  32. package/src/cli/commands/autoinstall.js +65 -0
  33. package/src/cli/commands/errors.js +190 -0
  34. package/src/cli/commands/independent-resume.js +395 -0
  35. package/src/cli/commands/install.js +179 -0
  36. package/src/cli/commands/permissions.js +108 -0
  37. package/src/cli/commands/project.js +485 -0
  38. package/src/cli/commands/scan.js +97 -0
  39. package/src/cli/commands/simple-resume.js +377 -0
  40. package/src/cli/commands/skills.js +158 -0
  41. package/src/cli/commands/status.js +113 -0
  42. package/src/cli/commands/stigmergy-resume.js +775 -0
  43. package/src/cli/commands/system.js +301 -0
  44. package/src/cli/commands/universal-resume.js +394 -0
  45. package/src/cli/router-beta.js +471 -0
  46. package/src/cli/utils/environment.js +75 -0
  47. package/src/cli/utils/formatters.js +47 -0
  48. package/src/cli/utils/skills_cache.js +92 -0
  49. package/src/core/cache_cleaner.js +1 -0
  50. package/src/core/cli_adapters.js +345 -0
  51. package/src/core/cli_help_analyzer.js +582 -26
  52. package/src/core/cli_path_detector.js +702 -709
  53. package/src/core/cli_tools.js +515 -160
  54. package/src/core/coordination/nodejs/CLIIntegrationManager.js +18 -0
  55. package/src/core/coordination/nodejs/HookDeploymentManager.js +242 -412
  56. package/src/core/coordination/nodejs/HookDeploymentManager.refactored.js +323 -0
  57. package/src/core/coordination/nodejs/generators/CLIAdapterGenerator.js +363 -0
  58. package/src/core/coordination/nodejs/generators/ResumeSessionGenerator.js +932 -0
  59. package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1395 -0
  60. package/src/core/coordination/nodejs/generators/index.js +12 -0
  61. package/src/core/enhanced_cli_installer.js +1208 -608
  62. package/src/core/enhanced_cli_parameter_handler.js +402 -0
  63. package/src/core/execution_mode_detector.js +222 -0
  64. package/src/core/installer.js +151 -106
  65. package/src/core/local_skill_scanner.js +732 -0
  66. package/src/core/multilingual/language-pattern-manager.js +1 -1
  67. package/src/core/skills/BuiltinSkillsDeployer.js +188 -0
  68. package/src/core/skills/StigmergySkillManager.js +123 -16
  69. package/src/core/skills/embedded-openskills/SkillParser.js +7 -3
  70. package/src/core/smart_router.js +291 -2
  71. package/src/index.js +10 -4
  72. package/src/utils.js +66 -7
  73. package/test/cli-integration.test.js +304 -0
  74. package/test/direct_smart_router_test.js +88 -0
  75. package/test/enhanced-cli-agent-skill-test.js +485 -0
  76. package/test/simple_test.js +82 -0
  77. package/test/smart_router_test_runner.js +123 -0
  78. package/test/smart_routing_edge_cases.test.js +284 -0
  79. package/test/smart_routing_simple_verification.js +139 -0
  80. package/test/smart_routing_verification.test.js +346 -0
  81. package/test/specific-cli-agent-skill-analysis.js +385 -0
  82. package/test/unit/smart_router.test.js +295 -0
  83. package/test/very_simple_test.js +54 -0
  84. package/src/cli/router.js +0 -1737
@@ -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;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Direct test of SmartRouter functionality without Jest
3
+ */
4
+
5
+ // Since we can't use Jest in this environment, we'll create a simple test
6
+ const SmartRouter = require('../src/core/smart_router');
7
+
8
+ async function directSmartRouterTest() {
9
+ console.log('Direct SmartRouter functionality test...\n');
10
+
11
+ try {
12
+ // Create router instance
13
+ const router = new SmartRouter();
14
+
15
+ // Initialize - this might fail without full CLI tools, but let's see
16
+ try {
17
+ await router.initialize();
18
+ console.log('✓ SmartRouter initialized successfully\n');
19
+ } catch (initError) {
20
+ console.log('? SmartRouter initialization had issues (expected in test environment):', initError.message);
21
+ console.log('Continuing with basic functionality test...\n');
22
+ }
23
+
24
+ // Test the shouldRoute method directly
25
+ console.log('Testing shouldRoute method:');
26
+
27
+ const shouldRouteCases = [
28
+ { input: 'use claude to analyze', expected: true },
29
+ { input: 'please help with code', expected: true },
30
+ { input: 'write with qwen', expected: true },
31
+ { input: 'hello world', expected: false },
32
+ { input: 'test input', expected: false }
33
+ ];
34
+
35
+ let shouldRoutePassed = 0;
36
+ for (const testCase of shouldRouteCases) {
37
+ const result = router.shouldRoute(testCase.input);
38
+ const passed = result === testCase.expected;
39
+ console.log(` shouldRoute("${testCase.input}") = ${result} ${passed ? '✓' : '✗'}`);
40
+ if (passed) shouldRoutePassed++;
41
+ }
42
+ console.log(`shouldRoute tests: ${shouldRoutePassed}/${shouldRouteCases.length} passed\n`);
43
+
44
+ // Test the extractKeywords method
45
+ console.log('Testing extractKeywords method:');
46
+
47
+ const tools = ['claude', 'qwen', 'gemini', 'iflow', 'codebuddy', 'copilot', 'codex', 'qodercli', 'kode'];
48
+ let extractKeywordsPassed = 0;
49
+
50
+ for (const tool of tools) {
51
+ const keywords = router.extractKeywords(tool, null);
52
+ const hasToolName = keywords.includes(tool);
53
+ console.log(` extractKeywords("${tool}") includes "${tool}": ${hasToolName} ${hasToolName ? '✓' : '✗'}`);
54
+ if (hasToolName) extractKeywordsPassed++;
55
+ }
56
+ console.log(`extractKeywords tests: ${extractKeywordsPassed}/${tools.length} passed\n`);
57
+
58
+ // Test basic routing logic without full initialization
59
+ console.log('Testing basic routing logic:');
60
+
61
+ // Manually test the routing patterns
62
+ const testInputs = [
63
+ 'use claude to analyze this',
64
+ 'using qwen for documentation',
65
+ 'help me with gemini',
66
+ 'with codebuddy',
67
+ 'analyze with copilot'
68
+ ];
69
+
70
+ for (const input of testInputs) {
71
+ const shouldRoute = router.shouldRoute(input);
72
+ console.log(` Input: "${input}" -> shouldRoute: ${shouldRoute}`);
73
+ }
74
+
75
+ console.log('\nDirect SmartRouter test completed.');
76
+ console.log('\nNote: This test verifies the core logic of the SmartRouter class.');
77
+ console.log('The comprehensive test suite is available in test/smart_routing_verification.test.js');
78
+ console.log('This file contains extensive unit tests for all SmartRouter functionality');
79
+ console.log('including edge cases, error handling, and performance tests.');
80
+
81
+ } catch (error) {
82
+ console.error('Error in direct SmartRouter test:', error);
83
+ console.error('Stack:', error.stack);
84
+ }
85
+ }
86
+
87
+ // Run the test
88
+ directSmartRouterTest();