stigmergy 1.2.12 → 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.
- package/README.md +39 -3
- package/STIGMERGY.md +3 -0
- package/config/enhanced-cli-config.json +438 -0
- package/docs/CLI_TOOLS_AGENT_SKILL_ANALYSIS.md +463 -0
- package/docs/ENHANCED_CLI_AGENT_SKILL_CONFIG.md +285 -0
- package/docs/INSTALLER_ARCHITECTURE.md +257 -0
- package/docs/SUDO_PROBLEM_AND_SOLUTION.md +529 -0
- package/package.json +14 -5
- package/scripts/analyze-router.js +168 -0
- package/scripts/test-runner.js +344 -0
- package/src/cli/commands/autoinstall.js +158 -0
- package/src/cli/commands/errors.js +190 -0
- package/src/cli/commands/install.js +142 -0
- package/src/cli/commands/permissions.js +108 -0
- package/src/cli/commands/project.js +449 -0
- package/src/cli/commands/resume.js +136 -0
- package/src/cli/commands/scan.js +97 -0
- package/src/cli/commands/skills.js +158 -0
- package/src/cli/commands/status.js +106 -0
- package/src/cli/commands/system.js +301 -0
- package/src/cli/router-beta.js +477 -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 +473 -1
- package/src/core/cli_path_detector.js +2 -1
- package/src/core/cli_tools.js +107 -0
- package/src/core/coordination/nodejs/HookDeploymentManager.js +185 -422
- 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 +701 -0
- package/src/core/coordination/nodejs/generators/SkillsIntegrationGenerator.js +1210 -0
- package/src/core/coordination/nodejs/generators/index.js +12 -0
- package/src/core/enhanced_cli_installer.js +220 -30
- package/src/core/enhanced_cli_parameter_handler.js +395 -0
- package/src/core/execution_mode_detector.js +222 -0
- package/src/core/installer.js +51 -70
- package/src/core/local_skill_scanner.js +732 -0
- package/src/core/multilingual/language-pattern-manager.js +1 -1
- package/src/core/skills/StigmergySkillManager.js +26 -8
- package/src/core/smart_router.js +279 -2
- package/src/index.js +10 -4
- package/test/cli-integration.test.js +304 -0
- package/test/enhanced-cli-agent-skill-test.js +485 -0
- package/test/specific-cli-agent-skill-analysis.js +385 -0
- package/src/cli/router.js +0 -1737
|
@@ -13,6 +13,180 @@ class CLIHelpAnalyzer {
|
|
|
13
13
|
this.lastAnalysisFile = path.join(this.configDir, 'last-analysis.json');
|
|
14
14
|
this.cliTools = CLI_TOOLS;
|
|
15
15
|
|
|
16
|
+
// Enhanced CLI Agent and Skill Patterns Configuration
|
|
17
|
+
this.enhancedPatterns = {
|
|
18
|
+
'claude': {
|
|
19
|
+
commandFormat: 'claude -p "{prompt}"',
|
|
20
|
+
agentDetection: true,
|
|
21
|
+
skillDetection: true,
|
|
22
|
+
naturalLanguageSupport: true,
|
|
23
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
24
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
|
|
25
|
+
examples: [
|
|
26
|
+
'claude -p "请使用异化分析技能分析程序员异化现象"',
|
|
27
|
+
'claude -p "请使用数字马克思智能体进行阶级分析"'
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
'iflow': {
|
|
31
|
+
commandFormat: 'iflow -p "{prompt}"',
|
|
32
|
+
agentDetection: true,
|
|
33
|
+
skillDetection: true,
|
|
34
|
+
naturalLanguageSupport: true,
|
|
35
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
36
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
|
|
37
|
+
examples: [
|
|
38
|
+
'iflow -p "请使用异化分析技能分析程序员异化现象"',
|
|
39
|
+
'iflow -p "请使用数字马克思智能体进行异化分析"'
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
'qwen': {
|
|
43
|
+
commandFormat: 'qwen "{prompt}"',
|
|
44
|
+
agentDetection: true,
|
|
45
|
+
skillDetection: true,
|
|
46
|
+
naturalLanguageSupport: true,
|
|
47
|
+
positionalArgs: true,
|
|
48
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
49
|
+
skillKeywords: ['智能体', '分析技能', '马克思', '异化', '阶级'],
|
|
50
|
+
examples: [
|
|
51
|
+
'qwen "使用数字马克思智能体进行异化分析,分析程序员的技术异化现象"',
|
|
52
|
+
'qwen "使用异化分析技能分析程序员在AI开发中的异化现象"'
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
'codebuddy': {
|
|
56
|
+
commandFormat: 'codebuddy -y -p "{prompt}"',
|
|
57
|
+
agentDetection: false,
|
|
58
|
+
skillDetection: true,
|
|
59
|
+
skillPrefixRequired: true,
|
|
60
|
+
agentTypes: ['skill'],
|
|
61
|
+
skillKeywords: ['skill:', '技能', '分析'],
|
|
62
|
+
examples: [
|
|
63
|
+
'codebuddy -y -p "skill:alienation-analysis 分析程序员异化现象"',
|
|
64
|
+
'codebuddy -y -p "skill:marxist-analysis 分析技术异化"'
|
|
65
|
+
]
|
|
66
|
+
},
|
|
67
|
+
'qodercli': {
|
|
68
|
+
commandFormat: 'qodercli -p "{prompt}"',
|
|
69
|
+
agentDetection: false,
|
|
70
|
+
skillDetection: false,
|
|
71
|
+
basicAISupport: true,
|
|
72
|
+
agentTypes: ['basic'],
|
|
73
|
+
skillKeywords: ['分析', '理解'],
|
|
74
|
+
examples: [
|
|
75
|
+
'qodercli -p "分析程序员在AI开发中的异化现象"',
|
|
76
|
+
'qodercli -p "进行技术异化的基础分析"'
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
'gemini': {
|
|
80
|
+
commandFormat: 'gemini -p "{prompt}"',
|
|
81
|
+
agentDetection: true,
|
|
82
|
+
skillDetection: true,
|
|
83
|
+
naturalLanguageSupport: true,
|
|
84
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
85
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
|
|
86
|
+
examples: [
|
|
87
|
+
'gemini -p "请使用分析技能分析程序员异化现象"',
|
|
88
|
+
'gemini -p "使用智能体进行技术分析"'
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
'copilot': {
|
|
92
|
+
commandFormat: 'copilot "{prompt}"',
|
|
93
|
+
agentDetection: true,
|
|
94
|
+
skillDetection: true,
|
|
95
|
+
naturalLanguageSupport: true,
|
|
96
|
+
positionalArgs: true,
|
|
97
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
98
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法'],
|
|
99
|
+
examples: [
|
|
100
|
+
'copilot "请使用分析技能分析程序员异化现象"',
|
|
101
|
+
'copilot "使用智能体进行技术分析"'
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
'codex': {
|
|
105
|
+
commandFormat: 'codex -m gpt-5 "{prompt}"',
|
|
106
|
+
agentDetection: true,
|
|
107
|
+
skillDetection: true,
|
|
108
|
+
naturalLanguageSupport: true,
|
|
109
|
+
positionalArgs: true,
|
|
110
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
111
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法', '代码', '审查'],
|
|
112
|
+
examples: [
|
|
113
|
+
'codex "请使用异化分析技能分析程序员异化现象"',
|
|
114
|
+
'codex exec "使用数字马克思智能体分析代码库"',
|
|
115
|
+
'codex review "分析这段代码的异化现象"'
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
'kode': {
|
|
119
|
+
commandFormat: 'kode -p "{prompt}"',
|
|
120
|
+
agentDetection: true,
|
|
121
|
+
skillDetection: true,
|
|
122
|
+
naturalLanguageSupport: true,
|
|
123
|
+
positionalArgs: true,
|
|
124
|
+
agentTypes: ['expert', 'skill', 'analysis', 'agent'],
|
|
125
|
+
skillKeywords: ['技能', '智能体', '分析', '工具', '方法', '多模型', '协作'],
|
|
126
|
+
examples: [
|
|
127
|
+
'kode -p "请使用异化分析技能分析程序员异化现象"',
|
|
128
|
+
'kode -p "使用数字马克思智能体进行异化分析"',
|
|
129
|
+
'kode -p "@ask-claude-sonnet-4 分析这个问题"'
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Agent and Skill Recognition Patterns
|
|
135
|
+
this.agentSkillPatterns = {
|
|
136
|
+
// Agent type detection patterns
|
|
137
|
+
agentTypes: {
|
|
138
|
+
'expert': ['专家', 'expert', 'specialist', '马克思', 'marxist', '数字马克思'],
|
|
139
|
+
'skill': ['技能', 'skill', '能力', '方法', '工具'],
|
|
140
|
+
'analysis': ['分析', 'analysis', '解析', '评估'],
|
|
141
|
+
'agent': ['智能体', 'agent', '助手', '助手'],
|
|
142
|
+
'basic': ['基础', 'basic', '简单', '初步']
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
// Skill name patterns for different CLIs
|
|
146
|
+
skillMapping: {
|
|
147
|
+
'异化分析': {
|
|
148
|
+
'claude': '异化分析技能',
|
|
149
|
+
'iflow': '异化分析技能',
|
|
150
|
+
'qwen': '异化分析技能',
|
|
151
|
+
'codebuddy': 'alienation-analysis',
|
|
152
|
+
'gemini': '异化分析技能',
|
|
153
|
+
'copilot': '异化分析技能',
|
|
154
|
+
'codex': 'alienation-analysis',
|
|
155
|
+
'kode': '异化分析技能'
|
|
156
|
+
},
|
|
157
|
+
'马克思分析': {
|
|
158
|
+
'claude': '数字马克思智能体',
|
|
159
|
+
'iflow': '数字马克思智能体',
|
|
160
|
+
'qwen': '数字马克思智能体',
|
|
161
|
+
'codebuddy': 'marxist-analysis',
|
|
162
|
+
'gemini': '马克思分析技能',
|
|
163
|
+
'copilot': '马克思分析智能体',
|
|
164
|
+
'codex': 'marxist-analysis',
|
|
165
|
+
'kode': '数字马克思智能体'
|
|
166
|
+
},
|
|
167
|
+
'技术分析': {
|
|
168
|
+
'claude': '技术分析技能',
|
|
169
|
+
'iflow': '技术分析技能',
|
|
170
|
+
'qwen': '技术分析技能',
|
|
171
|
+
'codebuddy': 'tech-analysis',
|
|
172
|
+
'gemini': '技术分析技能',
|
|
173
|
+
'copilot': '技术分析技能',
|
|
174
|
+
'codex': 'tech-analysis',
|
|
175
|
+
'kode': '技术分析技能'
|
|
176
|
+
},
|
|
177
|
+
'阶级分析': {
|
|
178
|
+
'claude': '阶级分析技能',
|
|
179
|
+
'iflow': '阶级分析技能',
|
|
180
|
+
'qwen': '阶级分析技能',
|
|
181
|
+
'codebuddy': 'class-analysis',
|
|
182
|
+
'gemini': '阶级分析技能',
|
|
183
|
+
'copilot': '阶级分析技能',
|
|
184
|
+
'codex': 'class-analysis',
|
|
185
|
+
'kode': '阶级分析技能'
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
16
190
|
// Pattern recognition rules for different CLI types
|
|
17
191
|
this.patternRules = {
|
|
18
192
|
// OpenAI style CLI (codex, chatgpt)
|
|
@@ -403,7 +577,10 @@ class CLIHelpAnalyzer {
|
|
|
403
577
|
option.includes('non-interactive') ||
|
|
404
578
|
option.includes('batch') ||
|
|
405
579
|
option.includes('no-input') ||
|
|
406
|
-
option.includes('stdin')
|
|
580
|
+
option.includes('stdin') ||
|
|
581
|
+
option.includes('print') || // For CLI tools like kode with --print flag
|
|
582
|
+
option.includes('pipe') || // Pipes mentioned in description
|
|
583
|
+
option.includes('exit'), // Exit after execution
|
|
407
584
|
);
|
|
408
585
|
patterns.nonInteractiveFlag =
|
|
409
586
|
nonInteractiveFlags.length > 0 ? nonInteractiveFlags[0] : null;
|
|
@@ -675,6 +852,301 @@ class CLIHelpAnalyzer {
|
|
|
675
852
|
setCLITools(tools) {
|
|
676
853
|
this.cliTools = tools;
|
|
677
854
|
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Enhanced analysis with agent and skill detection
|
|
858
|
+
*/
|
|
859
|
+
async analyzeCLIEnhanced(cliName) {
|
|
860
|
+
const basicAnalysis = await this.analyzeCLI(cliName);
|
|
861
|
+
|
|
862
|
+
if (!basicAnalysis.success) {
|
|
863
|
+
return basicAnalysis;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// Add enhanced agent and skill information
|
|
867
|
+
const enhancedPatterns = this.enhancedPatterns[cliName] || {};
|
|
868
|
+
|
|
869
|
+
basicAnalysis.agentSkillSupport = {
|
|
870
|
+
supportsAgents: enhancedPatterns.agentDetection || false,
|
|
871
|
+
supportsSkills: enhancedPatterns.skillDetection || false,
|
|
872
|
+
naturalLanguageSupport: enhancedPatterns.naturalLanguageSupport || false,
|
|
873
|
+
skillPrefixRequired: enhancedPatterns.skillPrefixRequired || false,
|
|
874
|
+
positionalArgs: enhancedPatterns.positionalArgs || false,
|
|
875
|
+
agentTypes: enhancedPatterns.agentTypes || [],
|
|
876
|
+
skillKeywords: enhancedPatterns.skillKeywords || [],
|
|
877
|
+
commandFormat: enhancedPatterns.commandFormat || '',
|
|
878
|
+
examples: enhancedPatterns.examples || []
|
|
879
|
+
};
|
|
880
|
+
|
|
881
|
+
return basicAnalysis;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Detect agent and skill mentions in user input
|
|
886
|
+
*/
|
|
887
|
+
detectAgentSkillMentions(input, cliName) {
|
|
888
|
+
const enhancedPattern = this.enhancedPatterns[cliName];
|
|
889
|
+
if (!enhancedPattern) {
|
|
890
|
+
return { hasAgent: false, hasSkill: false, confidence: 0 };
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
const inputLower = input.toLowerCase();
|
|
894
|
+
let hasAgent = false;
|
|
895
|
+
let hasSkill = false;
|
|
896
|
+
let confidence = 0;
|
|
897
|
+
|
|
898
|
+
// Check for agent keywords
|
|
899
|
+
if (enhancedPattern.agentDetection) {
|
|
900
|
+
const agentKeywords = [
|
|
901
|
+
...this.agentSkillPatterns.agentTypes['expert'],
|
|
902
|
+
...this.agentSkillPatterns.agentTypes['agent'],
|
|
903
|
+
...enhancedPattern.skillKeywords
|
|
904
|
+
];
|
|
905
|
+
|
|
906
|
+
for (const keyword of agentKeywords) {
|
|
907
|
+
if (inputLower.includes(keyword.toLowerCase())) {
|
|
908
|
+
hasAgent = true;
|
|
909
|
+
confidence += 0.3;
|
|
910
|
+
break;
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
// Check for skill keywords
|
|
916
|
+
if (enhancedPattern.skillDetection) {
|
|
917
|
+
const skillKeywords = enhancedPattern.skillKeywords;
|
|
918
|
+
|
|
919
|
+
for (const keyword of skillKeywords) {
|
|
920
|
+
if (inputLower.includes(keyword.toLowerCase())) {
|
|
921
|
+
hasSkill = true;
|
|
922
|
+
confidence += 0.4;
|
|
923
|
+
break;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// Special check for skill: prefix (codebuddy)
|
|
928
|
+
if (enhancedPattern.skillPrefixRequired && inputLower.includes('skill:')) {
|
|
929
|
+
hasSkill = true;
|
|
930
|
+
confidence += 0.6;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Boost confidence based on CLI-specific patterns
|
|
935
|
+
if (cliName === 'qwen' && enhancedPattern.positionalArgs) {
|
|
936
|
+
// Qwen CLI has higher confidence for natural language
|
|
937
|
+
confidence *= 1.2;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
return { hasAgent, hasSkill, confidence: Math.min(confidence, 1.0) };
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* Optimize prompt for specific CLI tool
|
|
945
|
+
*/
|
|
946
|
+
optimizePromptForCLI(prompt, cliName, detectedMentions) {
|
|
947
|
+
const enhancedPattern = this.enhancedPatterns[cliName];
|
|
948
|
+
if (!enhancedPattern) {
|
|
949
|
+
return prompt;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
let optimizedPrompt = prompt;
|
|
953
|
+
|
|
954
|
+
// Apply skill mapping if applicable
|
|
955
|
+
for (const [chineseSkill, mapping] of Object.entries(this.agentSkillPatterns.skillMapping)) {
|
|
956
|
+
if (prompt.includes(chineseSkill) && mapping[cliName]) {
|
|
957
|
+
if (enhancedPattern.skillPrefixRequired && !prompt.includes('skill:')) {
|
|
958
|
+
// For codebuddy, add skill: prefix
|
|
959
|
+
optimizedPrompt = prompt.replace(
|
|
960
|
+
chineseSkill,
|
|
961
|
+
`skill:${mapping[cliName]}`
|
|
962
|
+
);
|
|
963
|
+
} else if (enhancedPattern.naturalLanguageSupport) {
|
|
964
|
+
// For CLIs that support natural language, use the mapped term
|
|
965
|
+
optimizedPrompt = prompt.replace(
|
|
966
|
+
chineseSkill,
|
|
967
|
+
mapping[cliName]
|
|
968
|
+
);
|
|
969
|
+
}
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
return optimizedPrompt;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Get enhanced CLI pattern with agent/skill support
|
|
979
|
+
*/
|
|
980
|
+
async getEnhancedCLIPattern(cliName) {
|
|
981
|
+
const cached = await this.getCachedAnalysis(cliName);
|
|
982
|
+
|
|
983
|
+
if (cached && cached.timestamp && !this.isCacheExpired(cached.timestamp)) {
|
|
984
|
+
// Enhance cached data with agent/skill information
|
|
985
|
+
const enhancedPatterns = this.enhancedPatterns[cliName];
|
|
986
|
+
if (enhancedPatterns) {
|
|
987
|
+
cached.agentSkillSupport = {
|
|
988
|
+
supportsAgents: enhancedPatterns.agentDetection || false,
|
|
989
|
+
supportsSkills: enhancedPatterns.skillDetection || false,
|
|
990
|
+
naturalLanguageSupport: enhancedPatterns.naturalLanguageSupport || false,
|
|
991
|
+
skillPrefixRequired: enhancedPatterns.skillPrefixRequired || false,
|
|
992
|
+
positionalArgs: enhancedPatterns.positionalArgs || false,
|
|
993
|
+
agentTypes: enhancedPatterns.agentTypes || [],
|
|
994
|
+
skillKeywords: enhancedPatterns.skillKeywords || [],
|
|
995
|
+
commandFormat: enhancedPatterns.commandFormat || '',
|
|
996
|
+
examples: enhancedPatterns.examples || []
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
return cached;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Perform enhanced analysis
|
|
1003
|
+
return await this.analyzeCLIEnhanced(cliName);
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/**
|
|
1007
|
+
* Analyze call success and update patterns accordingly
|
|
1008
|
+
*/
|
|
1009
|
+
async updatePatternOnAgentSkillFailure(cliName, error, attemptedCommand, userPrompt) {
|
|
1010
|
+
if (process.env.DEBUG === 'true') {
|
|
1011
|
+
console.log(`Updating agent/skill pattern for ${cliName} due to failure:`, error.message);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
try {
|
|
1015
|
+
// Re-analyze with enhanced capabilities
|
|
1016
|
+
const newAnalysis = await this.analyzeCLIEnhanced(cliName);
|
|
1017
|
+
|
|
1018
|
+
// Add failure context with agent/skill information
|
|
1019
|
+
const detectedMentions = this.detectAgentSkillMentions(userPrompt, cliName);
|
|
1020
|
+
newAnalysis.lastFailure = {
|
|
1021
|
+
error: error.message,
|
|
1022
|
+
attemptedCommand,
|
|
1023
|
+
userPrompt,
|
|
1024
|
+
agentSkillDetected: detectedMentions,
|
|
1025
|
+
timestamp: new Date().toISOString(),
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
// Update the cached analysis
|
|
1029
|
+
await this.cacheAnalysis(cliName, newAnalysis);
|
|
1030
|
+
return newAnalysis;
|
|
1031
|
+
} catch (analysisError) {
|
|
1032
|
+
if (process.env.DEBUG === 'true') {
|
|
1033
|
+
console.error(`Failed to re-analyze ${cliName}:`, analysisError.message);
|
|
1034
|
+
}
|
|
1035
|
+
return null;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Get agent/skill compatibility score for CLI tool
|
|
1041
|
+
*/
|
|
1042
|
+
getAgentSkillCompatibilityScore(cliName, prompt) {
|
|
1043
|
+
const enhancedPattern = this.enhancedPatterns[cliName];
|
|
1044
|
+
if (!enhancedPattern) {
|
|
1045
|
+
return { score: 0, reasons: ['CLI not supported'] };
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
const detectedMentions = this.detectAgentSkillMentions(prompt, cliName);
|
|
1049
|
+
let score = 0.5; // Base score
|
|
1050
|
+
const reasons = [];
|
|
1051
|
+
|
|
1052
|
+
// Base compatibility
|
|
1053
|
+
if (enhancedPattern.agentDetection) {
|
|
1054
|
+
score += 0.2;
|
|
1055
|
+
reasons.push('支持智能体检测');
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
if (enhancedPattern.skillDetection) {
|
|
1059
|
+
score += 0.2;
|
|
1060
|
+
reasons.push('支持技能检测');
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
// Detection results
|
|
1064
|
+
if (detectedMentions.hasAgent) {
|
|
1065
|
+
score += 0.1;
|
|
1066
|
+
reasons.push('检测到智能体提及');
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
if (detectedMentions.hasSkill) {
|
|
1070
|
+
score += 0.1;
|
|
1071
|
+
reasons.push('检测到技能提及');
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// CLI-specific advantages
|
|
1075
|
+
if (cliName === 'qwen' && enhancedPattern.positionalArgs) {
|
|
1076
|
+
score += 0.1;
|
|
1077
|
+
reasons.push('位置参数支持,自然语言理解优秀');
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
if (cliName === 'codebuddy' && enhancedPattern.skillPrefixRequired) {
|
|
1081
|
+
score += 0.1;
|
|
1082
|
+
reasons.push('明确的技能语法支持');
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
// Penalty for mismatches
|
|
1086
|
+
if (enhancedPattern.skillPrefixRequired && !detectedMentions.hasSkill) {
|
|
1087
|
+
score -= 0.2;
|
|
1088
|
+
reasons.push('需要技能语法但未检测到技能');
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
return {
|
|
1092
|
+
score: Math.max(0, Math.min(1, score)),
|
|
1093
|
+
reasons,
|
|
1094
|
+
detected: detectedMentions
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* Generate optimized call command for CLI tool
|
|
1100
|
+
*/
|
|
1101
|
+
generateOptimizedCall(cliName, userPrompt) {
|
|
1102
|
+
const enhancedPattern = this.enhancedPatterns[cliName];
|
|
1103
|
+
if (!enhancedPattern) {
|
|
1104
|
+
return null;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
// Optimize the prompt
|
|
1108
|
+
const detectedMentions = this.detectAgentSkillMentions(userPrompt, cliName);
|
|
1109
|
+
const optimizedPrompt = this.optimizePromptForCLI(userPrompt, cliName, detectedMentions);
|
|
1110
|
+
|
|
1111
|
+
// Generate command based on CLI format
|
|
1112
|
+
let command;
|
|
1113
|
+
let args;
|
|
1114
|
+
|
|
1115
|
+
switch (cliName) {
|
|
1116
|
+
case 'qwen':
|
|
1117
|
+
// Qwen uses positional arguments
|
|
1118
|
+
command = 'qwen';
|
|
1119
|
+
args = [optimizedPrompt];
|
|
1120
|
+
break;
|
|
1121
|
+
|
|
1122
|
+
case 'codebuddy':
|
|
1123
|
+
// Codebuddy requires -y flag and skill prefix
|
|
1124
|
+
command = 'codebuddy';
|
|
1125
|
+
args = ['-y', '-p', optimizedPrompt];
|
|
1126
|
+
break;
|
|
1127
|
+
|
|
1128
|
+
case 'claude':
|
|
1129
|
+
case 'iflow':
|
|
1130
|
+
case 'qodercli':
|
|
1131
|
+
// These use -p flag
|
|
1132
|
+
command = cliName;
|
|
1133
|
+
args = ['-p', optimizedPrompt];
|
|
1134
|
+
break;
|
|
1135
|
+
|
|
1136
|
+
default:
|
|
1137
|
+
command = cliName;
|
|
1138
|
+
args = ['-p', optimizedPrompt];
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
return {
|
|
1142
|
+
command,
|
|
1143
|
+
args,
|
|
1144
|
+
fullCommand: `${command} ${args.join(' ')}`,
|
|
1145
|
+
optimizedPrompt,
|
|
1146
|
+
detectedMentions,
|
|
1147
|
+
compatibilityScore: this.getAgentSkillCompatibilityScore(cliName, userPrompt)
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
678
1150
|
}
|
|
679
1151
|
|
|
680
1152
|
module.exports = CLIHelpAnalyzer;
|
package/src/core/cli_tools.js
CHANGED
|
@@ -61,6 +61,20 @@ const CLI_TOOLS = {
|
|
|
61
61
|
hooksDir: path.join(os.homedir(), '.config', 'codex', 'slash_commands'),
|
|
62
62
|
config: path.join(os.homedir(), '.codex', 'config.json'),
|
|
63
63
|
},
|
|
64
|
+
kode: {
|
|
65
|
+
name: 'Kode CLI',
|
|
66
|
+
version: 'kode --version',
|
|
67
|
+
install: 'npm install -g @shareai-lab/kode',
|
|
68
|
+
hooksDir: path.join(os.homedir(), '.kode', 'agents'),
|
|
69
|
+
config: path.join(os.homedir(), '.kode', 'config.json'),
|
|
70
|
+
},
|
|
71
|
+
resumesession: {
|
|
72
|
+
name: 'ResumeSession CLI',
|
|
73
|
+
version: 'resumesession --version',
|
|
74
|
+
install: 'npm install -g resumesession',
|
|
75
|
+
hooksDir: path.join(os.homedir(), '.resumesession', 'hooks'),
|
|
76
|
+
config: path.join(os.homedir(), '.resumesession', 'config.json'),
|
|
77
|
+
},
|
|
64
78
|
};
|
|
65
79
|
|
|
66
80
|
/**
|
|
@@ -150,6 +164,99 @@ async function setupCLIPaths() {
|
|
|
150
164
|
};
|
|
151
165
|
}
|
|
152
166
|
|
|
167
|
+
/**
|
|
168
|
+
* Scan for available CLI tools
|
|
169
|
+
* @param {Object} options - Scan options
|
|
170
|
+
* @param {boolean} options.deep - Deep scan
|
|
171
|
+
* @param {boolean} options.verbose - Verbose output
|
|
172
|
+
* @returns {Promise<Object>} Scan results
|
|
173
|
+
*/
|
|
174
|
+
async function scanForTools(options = {}) {
|
|
175
|
+
const detector = getPathDetector();
|
|
176
|
+
|
|
177
|
+
// Load cached paths first
|
|
178
|
+
await detector.loadDetectedPaths();
|
|
179
|
+
|
|
180
|
+
// Detect all CLI paths
|
|
181
|
+
const detectedPaths = await detector.detectAllCLIPaths();
|
|
182
|
+
|
|
183
|
+
const found = [];
|
|
184
|
+
const missing = [];
|
|
185
|
+
|
|
186
|
+
for (const [toolName, toolPath] of Object.entries(detectedPaths)) {
|
|
187
|
+
if (toolPath) {
|
|
188
|
+
found.push({
|
|
189
|
+
name: toolName,
|
|
190
|
+
path: toolPath,
|
|
191
|
+
type: 'cli',
|
|
192
|
+
status: 'installed',
|
|
193
|
+
description: CLI_TOOLS[toolName]?.name || toolName
|
|
194
|
+
});
|
|
195
|
+
} else {
|
|
196
|
+
missing.push(toolName);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
return {
|
|
201
|
+
found,
|
|
202
|
+
missing,
|
|
203
|
+
total: Object.keys(CLI_TOOLS).length
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Check installation status of a specific CLI tool
|
|
209
|
+
* @param {string} toolName - Name of the tool
|
|
210
|
+
* @returns {Promise<Object>} Installation status
|
|
211
|
+
*/
|
|
212
|
+
async function checkInstallation(toolName) {
|
|
213
|
+
validateCLITool(toolName);
|
|
214
|
+
|
|
215
|
+
const detector = getPathDetector();
|
|
216
|
+
await detector.loadDetectedPaths();
|
|
217
|
+
|
|
218
|
+
let toolPath = detector.getDetectedPath(toolName);
|
|
219
|
+
|
|
220
|
+
// If not cached, detect it
|
|
221
|
+
if (!toolPath) {
|
|
222
|
+
toolPath = await detector.detectCLIPath(toolName);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const installed = !!toolPath;
|
|
226
|
+
|
|
227
|
+
let version = null;
|
|
228
|
+
if (installed) {
|
|
229
|
+
try {
|
|
230
|
+
const { spawnSync } = require('child_process');
|
|
231
|
+
const toolConfig = CLI_TOOLS[toolName];
|
|
232
|
+
const versionCmd = toolConfig.version || `${toolName} --version`;
|
|
233
|
+
|
|
234
|
+
const result = spawnSync(versionCmd.split(' ')[0], versionCmd.split(' ').slice(1), {
|
|
235
|
+
encoding: 'utf8',
|
|
236
|
+
shell: true,
|
|
237
|
+
timeout: 5000
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
if (result.status === 0) {
|
|
241
|
+
version = result.stdout.trim() || result.stderr.trim();
|
|
242
|
+
}
|
|
243
|
+
} catch (error) {
|
|
244
|
+
// Version check failed, but tool is still installed
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return {
|
|
249
|
+
installed,
|
|
250
|
+
path: toolPath,
|
|
251
|
+
version,
|
|
252
|
+
lastChecked: new Date().toISOString()
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Attach methods to CLI_TOOLS object for backward compatibility
|
|
257
|
+
CLI_TOOLS.scanForTools = scanForTools;
|
|
258
|
+
CLI_TOOLS.checkInstallation = checkInstallation;
|
|
259
|
+
|
|
153
260
|
module.exports = {
|
|
154
261
|
CLI_TOOLS,
|
|
155
262
|
validateCLITool,
|