stigmergy 1.2.13 → 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 -1783
@@ -1,4 +1,20 @@
1
- // Enhanced CLI Help Analyzer with better pattern extraction
1
+ /**
2
+ * Enhanced CLI Help Analyzer with better pattern extraction
3
+ *
4
+ * 📚 参考文档:
5
+ * - 重构文档:REFACTORING_CLI_HELP_ANALYZER.md
6
+ * - 实现清单:IMPLEMENTATION_CHECKLIST_CLI_HELP_ANALYZER_REFACTOR.md
7
+ * - 设计文档:DESIGN_CLI_HELP_ANALYZER_REFACTOR.md
8
+ * - 规格说明:SPECS_CLI_HELP_ANALYZER_REFACTOR.md
9
+ *
10
+ * 🎯 重构说明(v1.4.0):
11
+ * - 统一 analyzeCLI() 入口点,支持 options 参数
12
+ * - 提取 addEnhancedInfo() 方法,实现不可变对象模式
13
+ * - 简化包装器方法(getCLIPattern, getEnhancedCLIPattern, analyzeCLIEnhanced)
14
+ * - 所有方法保持向后兼容,已添加 @deprecated 注释
15
+ *
16
+ * 🧪 测试覆盖:36/36 测试通过(23单元测试 + 13集成测试)
17
+ */
2
18
  const { spawnSync } = require('child_process');
3
19
  const fs = require('fs/promises');
4
20
  const path = require('path');
@@ -13,6 +29,180 @@ class CLIHelpAnalyzer {
13
29
  this.lastAnalysisFile = path.join(this.configDir, 'last-analysis.json');
14
30
  this.cliTools = CLI_TOOLS;
15
31
 
32
+ // Enhanced CLI Agent and Skill Patterns Configuration
33
+ this.enhancedPatterns = {
34
+ 'claude': {
35
+ commandFormat: 'claude -p "{prompt}"',
36
+ agentDetection: true,
37
+ skillDetection: true,
38
+ naturalLanguageSupport: true,
39
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
40
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
41
+ examples: [
42
+ 'claude -p "请使用异化分析技能分析程序员异化现象"',
43
+ 'claude -p "请使用数字马克思智能体进行阶级分析"'
44
+ ]
45
+ },
46
+ 'iflow': {
47
+ commandFormat: 'iflow -p "{prompt}"',
48
+ agentDetection: true,
49
+ skillDetection: true,
50
+ naturalLanguageSupport: true,
51
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
52
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
53
+ examples: [
54
+ 'iflow -p "请使用异化分析技能分析程序员异化现象"',
55
+ 'iflow -p "请使用数字马克思智能体进行异化分析"'
56
+ ]
57
+ },
58
+ 'qwen': {
59
+ commandFormat: 'qwen "{prompt}"',
60
+ agentDetection: true,
61
+ skillDetection: true,
62
+ naturalLanguageSupport: true,
63
+ positionalArgs: true,
64
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
65
+ skillKeywords: ['智能体', '分析技能', '马克思', '异化', '阶级'],
66
+ examples: [
67
+ 'qwen "使用数字马克思智能体进行异化分析,分析程序员的技术异化现象"',
68
+ 'qwen "使用异化分析技能分析程序员在AI开发中的异化现象"'
69
+ ]
70
+ },
71
+ 'codebuddy': {
72
+ commandFormat: 'codebuddy -y -p "{prompt}"',
73
+ agentDetection: false,
74
+ skillDetection: true,
75
+ skillPrefixRequired: true,
76
+ agentTypes: ['skill'],
77
+ skillKeywords: ['skill:', '技能', '分析'],
78
+ examples: [
79
+ 'codebuddy -y -p "skill:alienation-analysis 分析程序员异化现象"',
80
+ 'codebuddy -y -p "skill:marxist-analysis 分析技术异化"'
81
+ ]
82
+ },
83
+ 'qodercli': {
84
+ commandFormat: 'qodercli -p "{prompt}"',
85
+ agentDetection: false,
86
+ skillDetection: false,
87
+ basicAISupport: true,
88
+ agentTypes: ['basic'],
89
+ skillKeywords: ['分析', '理解'],
90
+ examples: [
91
+ 'qodercli -p "分析程序员在AI开发中的异化现象"',
92
+ 'qodercli -p "进行技术异化的基础分析"'
93
+ ]
94
+ },
95
+ 'gemini': {
96
+ commandFormat: 'gemini -p "{prompt}"',
97
+ agentDetection: true,
98
+ skillDetection: true,
99
+ naturalLanguageSupport: true,
100
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
101
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
102
+ examples: [
103
+ 'gemini -p "请使用分析技能分析程序员异化现象"',
104
+ 'gemini -p "使用智能体进行技术分析"'
105
+ ]
106
+ },
107
+ 'copilot': {
108
+ commandFormat: 'copilot "{prompt}"',
109
+ agentDetection: true,
110
+ skillDetection: true,
111
+ naturalLanguageSupport: true,
112
+ positionalArgs: true,
113
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
114
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
115
+ examples: [
116
+ 'copilot "请使用分析技能分析程序员异化现象"',
117
+ 'copilot "使用智能体进行技术分析"'
118
+ ]
119
+ },
120
+ 'codex': {
121
+ commandFormat: 'codex -m gpt-5 "{prompt}"',
122
+ agentDetection: true,
123
+ skillDetection: true,
124
+ naturalLanguageSupport: true,
125
+ positionalArgs: true,
126
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
127
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法', '代码', '审查'],
128
+ examples: [
129
+ 'codex "请使用异化分析技能分析程序员异化现象"',
130
+ 'codex exec "使用数字马克思智能体分析代码库"',
131
+ 'codex review "分析这段代码的异化现象"'
132
+ ]
133
+ },
134
+ 'kode': {
135
+ commandFormat: 'kode -p "{prompt}"',
136
+ agentDetection: true,
137
+ skillDetection: true,
138
+ naturalLanguageSupport: true,
139
+ positionalArgs: true,
140
+ agentTypes: ['expert', 'skill', 'analysis', 'agent'],
141
+ skillKeywords: ['技能', '智能体', '分析', '工具', '方法', '多模型', '协作'],
142
+ examples: [
143
+ 'kode -p "请使用异化分析技能分析程序员异化现象"',
144
+ 'kode -p "使用数字马克思智能体进行异化分析"',
145
+ 'kode -p "@ask-claude-sonnet-4 分析这个问题"'
146
+ ]
147
+ }
148
+ };
149
+
150
+ // Agent and Skill Recognition Patterns
151
+ this.agentSkillPatterns = {
152
+ // Agent type detection patterns
153
+ agentTypes: {
154
+ 'expert': ['专家', 'expert', 'specialist', '马克思', 'marxist', '数字马克思'],
155
+ 'skill': ['技能', 'skill', '能力', '方法', '工具'],
156
+ 'analysis': ['分析', 'analysis', '解析', '评估'],
157
+ 'agent': ['智能体', 'agent', '助手', '助手'],
158
+ 'basic': ['基础', 'basic', '简单', '初步']
159
+ },
160
+
161
+ // Skill name patterns for different CLIs
162
+ skillMapping: {
163
+ '异化分析': {
164
+ 'claude': '异化分析技能',
165
+ 'iflow': '异化分析技能',
166
+ 'qwen': '异化分析技能',
167
+ 'codebuddy': 'alienation-analysis',
168
+ 'gemini': '异化分析技能',
169
+ 'copilot': '异化分析技能',
170
+ 'codex': 'alienation-analysis',
171
+ 'kode': '异化分析技能'
172
+ },
173
+ '马克思分析': {
174
+ 'claude': '数字马克思智能体',
175
+ 'iflow': '数字马克思智能体',
176
+ 'qwen': '数字马克思智能体',
177
+ 'codebuddy': 'marxist-analysis',
178
+ 'gemini': '马克思分析技能',
179
+ 'copilot': '马克思分析智能体',
180
+ 'codex': 'marxist-analysis',
181
+ 'kode': '数字马克思智能体'
182
+ },
183
+ '技术分析': {
184
+ 'claude': '技术分析技能',
185
+ 'iflow': '技术分析技能',
186
+ 'qwen': '技术分析技能',
187
+ 'codebuddy': 'tech-analysis',
188
+ 'gemini': '技术分析技能',
189
+ 'copilot': '技术分析技能',
190
+ 'codex': 'tech-analysis',
191
+ 'kode': '技术分析技能'
192
+ },
193
+ '阶级分析': {
194
+ 'claude': '阶级分析技能',
195
+ 'iflow': '阶级分析技能',
196
+ 'qwen': '阶级分析技能',
197
+ 'codebuddy': 'class-analysis',
198
+ 'gemini': '阶级分析技能',
199
+ 'copilot': '阶级分析技能',
200
+ 'codex': 'class-analysis',
201
+ 'kode': '阶级分析技能'
202
+ }
203
+ }
204
+ };
205
+
16
206
  // Pattern recognition rules for different CLI types
17
207
  this.patternRules = {
18
208
  // OpenAI style CLI (codex, chatgpt)
@@ -95,16 +285,28 @@ class CLIHelpAnalyzer {
95
285
  }
96
286
 
97
287
  /**
98
- * Analyze all configured CLI tools with optimized error handling
288
+ * 分析所有配置的CLI工具
289
+ * @param {Object} options - 分析选项
290
+ * @param {boolean} options.enhanced - 是否返回增强信息
291
+ * @param {boolean} options.forceRefresh - 是否强制刷新缓存
292
+ * @returns {Promise<Object>} 所有CLI的分析结果
99
293
  */
100
- async analyzeAllCLI() {
294
+ async analyzeAllCLI(options = {}) {
101
295
  const results = {};
102
- for (const [cliName, _] of Object.entries(this.cliTools)) {
296
+ const cliNames = Object.keys(this.cliTools);
297
+
298
+ // 优化:并行分析所有 CLI,添加超时保护
299
+ const analysisPromises = cliNames.map(async (cliName) => {
103
300
  try {
104
301
  if (process.env.DEBUG === 'true') {
105
302
  console.log(`Analyzing ${cliName}...`);
106
303
  }
107
- results[cliName] = await this.analyzeCLI(cliName);
304
+ // 添加超时保护,单个 CLI 分析最多 60 秒(因为需要尝试多个 help 方法)
305
+ const timeoutPromise = new Promise((_, reject) =>
306
+ setTimeout(() => reject(new Error('Analysis timeout')), 60000)
307
+ );
308
+ const result = await Promise.race([this.analyzeCLI(cliName, options), timeoutPromise]);
309
+ return { cliName, result };
108
310
  } catch (error) {
109
311
  // Only log important errors, suppress expected file not found errors
110
312
  if (
@@ -112,7 +314,8 @@ class CLIHelpAnalyzer {
112
314
  !error.message.includes('no such file or directory') &&
113
315
  !error.message.includes(
114
316
  'not recognized as an internal or external command',
115
- )
317
+ ) &&
318
+ !error.message.includes('Analysis timeout')
116
319
  ) {
117
320
  await errorHandler.logError(
118
321
  error,
@@ -120,21 +323,64 @@ class CLIHelpAnalyzer {
120
323
  `CLIHelpAnalyzer.analyzeAllCLI.${cliName}`,
121
324
  );
122
325
  }
123
- results[cliName] = { success: false, error: error.message };
326
+ return { cliName, result: { success: false, error: error.message } };
124
327
  }
328
+ });
329
+
330
+ // 等待所有分析完成,添加整体超时保护
331
+ const overallTimeoutPromise = new Promise((_, reject) =>
332
+ setTimeout(() => reject(new Error('Overall analysis timeout')), 120000)
333
+ );
334
+ const analysisResults = await Promise.race([Promise.all(analysisPromises), overallTimeoutPromise]);
335
+
336
+ // 整理结果
337
+ for (const { cliName, result } of analysisResults) {
338
+ results[cliName] = result;
125
339
  }
340
+
126
341
  return results;
127
342
  }
128
343
 
129
344
  /**
130
- * Analyze specific CLI tool
345
+ * 分析CLI工具
346
+ * @param {string} cliName - CLI工具名称
347
+ * @param {Object} options - 分析选项
348
+ * @param {boolean} options.enhanced - 是否返回增强信息
349
+ * @param {boolean} options.forceRefresh - 是否强制刷新缓存
350
+ * @returns {Promise<Object>} 分析结果
131
351
  */
132
- async analyzeCLI(cliName) {
352
+ async analyzeCLI(cliName, options = {}) {
353
+ const { enhanced = false, forceRefresh = false } = options;
133
354
  const cliConfig = this.cliTools[cliName];
134
355
  if (!cliConfig) {
135
356
  throw new Error(`CLI tool ${cliName} not found in configuration`);
136
357
  }
137
358
  try {
359
+ // 检查是否强制刷新
360
+ if (!forceRefresh) {
361
+ // 优化:检查缓存版本,只在版本变化时重新分析
362
+ const cachedAnalysis = await this.getCachedAnalysis(cliName);
363
+ if (cachedAnalysis && cachedAnalysis.success) {
364
+ // 获取当前版本
365
+ const currentVersion = await this.getCurrentVersion(cliName, cliConfig);
366
+ // 如果版本未变化,使用缓存
367
+ if (currentVersion === cachedAnalysis.version && !this.isCacheExpired(cachedAnalysis.timestamp)) {
368
+ if (process.env.DEBUG === 'true') {
369
+ console.log(`[DEBUG] ${cliName}: 使用缓存的分析结果 (版本: ${cachedAnalysis.version})`);
370
+ }
371
+ // 添加增强信息
372
+ if (enhanced) {
373
+ return this.addEnhancedInfo(cachedAnalysis, cliName);
374
+ }
375
+ return cachedAnalysis;
376
+ } else {
377
+ if (process.env.DEBUG === 'true') {
378
+ console.log(`[DEBUG] ${cliName}: 版本变化 (${cachedAnalysis.version} -> ${currentVersion}) 或缓存过期,重新分析`);
379
+ }
380
+ }
381
+ }
382
+ }
383
+
138
384
  // Get help information
139
385
  const helpInfo = await this.getHelpInfo(cliName, cliConfig);
140
386
  // Detect CLI type
@@ -161,6 +407,10 @@ class CLIHelpAnalyzer {
161
407
  };
162
408
  // Cache the analysis
163
409
  await this.cacheAnalysis(cliName, analysis);
410
+ // 添加增强信息
411
+ if (enhanced) {
412
+ return this.addEnhancedInfo(analysis, cliName);
413
+ }
164
414
  return analysis;
165
415
  } catch (error) {
166
416
  // Record failed attempt but suppress error if it's an expected issue
@@ -184,6 +434,33 @@ class CLIHelpAnalyzer {
184
434
  }
185
435
  }
186
436
 
437
+ /**
438
+ * 添加增强信息
439
+ * @param {Object} analysis - 基础分析结果
440
+ * @param {string} cliName - CLI工具名称
441
+ * @returns {Object} 增强分析结果
442
+ * @重要说明:必须返回新对象,不能修改原对象
443
+ */
444
+ addEnhancedInfo(analysis, cliName) {
445
+ const enhancedPatterns = this.enhancedPatterns[cliName] || {};
446
+
447
+ // 使用展开运算符创建新对象,不修改原对象
448
+ return {
449
+ ...analysis,
450
+ agentSkillSupport: {
451
+ supportsAgents: enhancedPatterns.agentDetection || false,
452
+ supportsSkills: enhancedPatterns.skillDetection || false,
453
+ naturalLanguageSupport: enhancedPatterns.naturalLanguageSupport || false,
454
+ skillPrefixRequired: enhancedPatterns.skillPrefixRequired || false,
455
+ positionalArgs: enhancedPatterns.positionalArgs || false,
456
+ agentTypes: enhancedPatterns.agentTypes || [],
457
+ skillKeywords: enhancedPatterns.skillKeywords || [],
458
+ commandFormat: enhancedPatterns.commandFormat || "",
459
+ examples: enhancedPatterns.examples || []
460
+ }
461
+ };
462
+ }
463
+
187
464
  /**
188
465
  * Get help information using multiple methods
189
466
  */
@@ -194,14 +471,8 @@ class CLIHelpAnalyzer {
194
471
  }
195
472
 
196
473
  const helpMethods = [
197
- ['--help'],
198
- ['-h'],
199
- ['help'],
200
- ['--usage'],
201
- [''],
202
- ['version'],
203
- ['--version'],
204
- ['-v'],
474
+ ['--help'], // 最常用
475
+ ['-h'], // 常用
205
476
  ];
206
477
  let rawHelp = '';
207
478
  let version = 'unknown';
@@ -211,7 +482,7 @@ class CLIHelpAnalyzer {
211
482
  try {
212
483
  const result = spawnSync(cliName, helpArgs, {
213
484
  encoding: 'utf8',
214
- timeout: 15000,
485
+ timeout: 5000,
215
486
  shell: true,
216
487
  });
217
488
  if (result.status === 0 && result.stdout) {
@@ -233,11 +504,10 @@ class CLIHelpAnalyzer {
233
504
  try {
234
505
  const versionCmd = cliConfig.version.split(' ');
235
506
  const versionResult = spawnSync(versionCmd[0], versionCmd.slice(1), {
236
- encoding: 'utf8',
237
- timeout: 10000,
238
- shell: true,
239
- });
240
- if (versionResult.status === 0) {
507
+ encoding: 'utf8',
508
+ timeout: 3000, // 优化:减少超时时间从 10 秒到 3 秒
509
+ shell: true,
510
+ }); if (versionResult.status === 0) {
241
511
  version = versionResult.stdout.trim() || versionResult.stderr.trim();
242
512
  }
243
513
  } catch (error) {
@@ -403,7 +673,10 @@ class CLIHelpAnalyzer {
403
673
  option.includes('non-interactive') ||
404
674
  option.includes('batch') ||
405
675
  option.includes('no-input') ||
406
- option.includes('stdin'),
676
+ option.includes('stdin') ||
677
+ option.includes('print') || // For CLI tools like kode with --print flag
678
+ option.includes('pipe') || // Pipes mentioned in description
679
+ option.includes('exit'), // Exit after execution
407
680
  );
408
681
  patterns.nonInteractiveFlag =
409
682
  nonInteractiveFlags.length > 0 ? nonInteractiveFlags[0] : null;
@@ -540,10 +813,13 @@ class CLIHelpAnalyzer {
540
813
  }
541
814
 
542
815
  /**
543
- * Get CLI pattern (wrapper for getCachedAnalysis)
816
+ * 获取CLI模式(包装器方法)
817
+ * @deprecated 此方法已弃用,请使用 analyzeCLI(cliName, { enhanced: false }) 代替
818
+ * @param {string} cliName - CLI工具名称
819
+ * @returns {Promise<Object>} 分析结果
544
820
  */
545
821
  async getCLIPattern(cliName) {
546
- return await this.getCachedAnalysis(cliName);
822
+ return await this.analyzeCLI(cliName, { enhanced: false });
547
823
  }
548
824
 
549
825
  /**
@@ -598,6 +874,28 @@ class CLIHelpAnalyzer {
598
874
  }
599
875
  }
600
876
 
877
+ /**
878
+ * Get current CLI version
879
+ */
880
+ async getCurrentVersion(cliName, cliConfig) {
881
+ try {
882
+ const versionCmd = cliConfig.version || `${cliName} --version`;
883
+ const result = spawnSync(versionCmd.split(' ')[0], versionCmd.split(' ').slice(1), {
884
+ encoding: 'utf8',
885
+ shell: true,
886
+ timeout: 3000,
887
+ stdio: ['ignore', 'pipe', 'pipe']
888
+ });
889
+
890
+ if (result.status === 0) {
891
+ return (result.stdout.trim() || result.stderr.trim()).split('\n')[0];
892
+ }
893
+ return 'unknown';
894
+ } catch (error) {
895
+ return 'unknown';
896
+ }
897
+ }
898
+
601
899
  /**
602
900
  * Record failed attempt
603
901
  */
@@ -675,6 +973,264 @@ class CLIHelpAnalyzer {
675
973
  setCLITools(tools) {
676
974
  this.cliTools = tools;
677
975
  }
976
+
977
+ /**
978
+ * 增强分析,包含智能体和技能检测(包装器方法)
979
+ * @deprecated 此方法已弃用,请使用 analyzeCLI(cliName, { enhanced: true }) 代替
980
+ * @param {string} cliName - CLI工具名称
981
+ * @returns {Promise<Object>} 增强分析结果
982
+ */
983
+ async analyzeCLIEnhanced(cliName) {
984
+ return await this.analyzeCLI(cliName, { enhanced: true });
985
+ }
986
+
987
+ /**
988
+ * Detect agent and skill mentions in user input
989
+ */
990
+ detectAgentSkillMentions(input, cliName) {
991
+ const enhancedPattern = this.enhancedPatterns[cliName];
992
+ if (!enhancedPattern) {
993
+ return { hasAgent: false, hasSkill: false, confidence: 0 };
994
+ }
995
+
996
+ const inputLower = input.toLowerCase();
997
+ let hasAgent = false;
998
+ let hasSkill = false;
999
+ let confidence = 0;
1000
+
1001
+ // Check for agent keywords
1002
+ if (enhancedPattern.agentDetection) {
1003
+ const agentKeywords = [
1004
+ ...this.agentSkillPatterns.agentTypes['expert'],
1005
+ ...this.agentSkillPatterns.agentTypes['agent'],
1006
+ ...enhancedPattern.skillKeywords
1007
+ ];
1008
+
1009
+ for (const keyword of agentKeywords) {
1010
+ if (inputLower.includes(keyword.toLowerCase())) {
1011
+ hasAgent = true;
1012
+ confidence += 0.3;
1013
+ break;
1014
+ }
1015
+ }
1016
+ }
1017
+
1018
+ // Check for skill keywords
1019
+ if (enhancedPattern.skillDetection) {
1020
+ const skillKeywords = enhancedPattern.skillKeywords;
1021
+
1022
+ for (const keyword of skillKeywords) {
1023
+ if (inputLower.includes(keyword.toLowerCase())) {
1024
+ hasSkill = true;
1025
+ confidence += 0.4;
1026
+ break;
1027
+ }
1028
+ }
1029
+
1030
+ // Special check for skill: prefix (codebuddy)
1031
+ if (enhancedPattern.skillPrefixRequired && inputLower.includes('skill:')) {
1032
+ hasSkill = true;
1033
+ confidence += 0.6;
1034
+ }
1035
+ }
1036
+
1037
+ // Boost confidence based on CLI-specific patterns
1038
+ if (cliName === 'qwen' && enhancedPattern.positionalArgs) {
1039
+ // Qwen CLI has higher confidence for natural language
1040
+ confidence *= 1.2;
1041
+ }
1042
+
1043
+ return { hasAgent, hasSkill, confidence: Math.min(confidence, 1.0) };
1044
+ }
1045
+
1046
+ /**
1047
+ * Optimize prompt for specific CLI tool
1048
+ */
1049
+ optimizePromptForCLI(prompt, cliName, detectedMentions) {
1050
+ const enhancedPattern = this.enhancedPatterns[cliName];
1051
+ if (!enhancedPattern) {
1052
+ return prompt;
1053
+ }
1054
+
1055
+ let optimizedPrompt = prompt;
1056
+
1057
+ // Apply skill mapping if applicable
1058
+ for (const [chineseSkill, mapping] of Object.entries(this.agentSkillPatterns.skillMapping)) {
1059
+ if (prompt.includes(chineseSkill) && mapping[cliName]) {
1060
+ if (enhancedPattern.skillPrefixRequired && !prompt.includes('skill:')) {
1061
+ // For codebuddy, add skill: prefix
1062
+ optimizedPrompt = prompt.replace(
1063
+ chineseSkill,
1064
+ `skill:${mapping[cliName]}`
1065
+ );
1066
+ } else if (enhancedPattern.naturalLanguageSupport) {
1067
+ // For CLIs that support natural language, use the mapped term
1068
+ optimizedPrompt = prompt.replace(
1069
+ chineseSkill,
1070
+ mapping[cliName]
1071
+ );
1072
+ }
1073
+ break;
1074
+ }
1075
+ }
1076
+
1077
+ return optimizedPrompt;
1078
+ }
1079
+
1080
+ /**
1081
+ * 获取增强CLI模式,包含智能体/技能支持(包装器方法)
1082
+ * @deprecated 此方法已弃用,请使用 analyzeCLI(cliName, { enhanced: true }) 代替
1083
+ * @param {string} cliName - CLI工具名称
1084
+ * @returns {Promise<Object>} 增强分析结果
1085
+ */
1086
+ async getEnhancedCLIPattern(cliName) {
1087
+ return await this.analyzeCLI(cliName, { enhanced: true });
1088
+ }
1089
+
1090
+ /**
1091
+ * Analyze call success and update patterns accordingly
1092
+ */
1093
+ async updatePatternOnAgentSkillFailure(cliName, error, attemptedCommand, userPrompt) {
1094
+ if (process.env.DEBUG === 'true') {
1095
+ console.log(`Updating agent/skill pattern for ${cliName} due to failure:`, error.message);
1096
+ }
1097
+
1098
+ try {
1099
+ // Re-analyze with enhanced capabilities
1100
+ const newAnalysis = await this.analyzeCLIEnhanced(cliName);
1101
+
1102
+ // Add failure context with agent/skill information
1103
+ const detectedMentions = this.detectAgentSkillMentions(userPrompt, cliName);
1104
+ newAnalysis.lastFailure = {
1105
+ error: error.message,
1106
+ attemptedCommand,
1107
+ userPrompt,
1108
+ agentSkillDetected: detectedMentions,
1109
+ timestamp: new Date().toISOString(),
1110
+ };
1111
+
1112
+ // Update the cached analysis
1113
+ await this.cacheAnalysis(cliName, newAnalysis);
1114
+ return newAnalysis;
1115
+ } catch (analysisError) {
1116
+ if (process.env.DEBUG === 'true') {
1117
+ console.error(`Failed to re-analyze ${cliName}:`, analysisError.message);
1118
+ }
1119
+ return null;
1120
+ }
1121
+ }
1122
+
1123
+ /**
1124
+ * Get agent/skill compatibility score for CLI tool
1125
+ */
1126
+ getAgentSkillCompatibilityScore(cliName, prompt) {
1127
+ const enhancedPattern = this.enhancedPatterns[cliName];
1128
+ if (!enhancedPattern) {
1129
+ return { score: 0, reasons: ['CLI not supported'] };
1130
+ }
1131
+
1132
+ const detectedMentions = this.detectAgentSkillMentions(prompt, cliName);
1133
+ let score = 0.5; // Base score
1134
+ const reasons = [];
1135
+
1136
+ // Base compatibility
1137
+ if (enhancedPattern.agentDetection) {
1138
+ score += 0.2;
1139
+ reasons.push('支持智能体检测');
1140
+ }
1141
+
1142
+ if (enhancedPattern.skillDetection) {
1143
+ score += 0.2;
1144
+ reasons.push('支持技能检测');
1145
+ }
1146
+
1147
+ // Detection results
1148
+ if (detectedMentions.hasAgent) {
1149
+ score += 0.1;
1150
+ reasons.push('检测到智能体提及');
1151
+ }
1152
+
1153
+ if (detectedMentions.hasSkill) {
1154
+ score += 0.1;
1155
+ reasons.push('检测到技能提及');
1156
+ }
1157
+
1158
+ // CLI-specific advantages
1159
+ if (cliName === 'qwen' && enhancedPattern.positionalArgs) {
1160
+ score += 0.1;
1161
+ reasons.push('位置参数支持,自然语言理解优秀');
1162
+ }
1163
+
1164
+ if (cliName === 'codebuddy' && enhancedPattern.skillPrefixRequired) {
1165
+ score += 0.1;
1166
+ reasons.push('明确的技能语法支持');
1167
+ }
1168
+
1169
+ // Penalty for mismatches
1170
+ if (enhancedPattern.skillPrefixRequired && !detectedMentions.hasSkill) {
1171
+ score -= 0.2;
1172
+ reasons.push('需要技能语法但未检测到技能');
1173
+ }
1174
+
1175
+ return {
1176
+ score: Math.max(0, Math.min(1, score)),
1177
+ reasons,
1178
+ detected: detectedMentions
1179
+ };
1180
+ }
1181
+
1182
+ /**
1183
+ * Generate optimized call command for CLI tool
1184
+ */
1185
+ generateOptimizedCall(cliName, userPrompt) {
1186
+ const enhancedPattern = this.enhancedPatterns[cliName];
1187
+ if (!enhancedPattern) {
1188
+ return null;
1189
+ }
1190
+
1191
+ // Optimize the prompt
1192
+ const detectedMentions = this.detectAgentSkillMentions(userPrompt, cliName);
1193
+ const optimizedPrompt = this.optimizePromptForCLI(userPrompt, cliName, detectedMentions);
1194
+
1195
+ // Generate command based on CLI format
1196
+ let command;
1197
+ let args;
1198
+
1199
+ switch (cliName) {
1200
+ case 'qwen':
1201
+ // Qwen uses positional arguments
1202
+ command = 'qwen';
1203
+ args = [optimizedPrompt];
1204
+ break;
1205
+
1206
+ case 'codebuddy':
1207
+ // Codebuddy requires -y flag and skill prefix
1208
+ command = 'codebuddy';
1209
+ args = ['-y', '-p', optimizedPrompt];
1210
+ break;
1211
+
1212
+ case 'claude':
1213
+ case 'iflow':
1214
+ case 'qodercli':
1215
+ // These use -p flag
1216
+ command = cliName;
1217
+ args = ['-p', optimizedPrompt];
1218
+ break;
1219
+
1220
+ default:
1221
+ command = cliName;
1222
+ args = ['-p', optimizedPrompt];
1223
+ }
1224
+
1225
+ return {
1226
+ command,
1227
+ args,
1228
+ fullCommand: `${command} ${args.join(' ')}`,
1229
+ optimizedPrompt,
1230
+ detectedMentions,
1231
+ compatibilityScore: this.getAgentSkillCompatibilityScore(cliName, userPrompt)
1232
+ };
1233
+ }
678
1234
  }
679
1235
 
680
1236
  module.exports = CLIHelpAnalyzer;