stigmergy 1.2.0 → 1.2.6

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 (125) hide show
  1. package/LICENSE +18 -18
  2. package/README.md +28 -223
  3. package/STIGMERGY.md +61 -61
  4. package/docs/PROJECT_CONSTITUTION.md +433 -433
  5. package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
  6. package/examples/calculator-example.js +72 -72
  7. package/examples/cline_usage_examples.md +364 -364
  8. package/examples/encryption-example.js +67 -67
  9. package/examples/json-parser-example.js +120 -120
  10. package/examples/json-validation-example.js +64 -64
  11. package/examples/rest-client-example.js +52 -52
  12. package/examples/rest_client_example.js +54 -54
  13. package/package.json +36 -15
  14. package/scripts/build.js +74 -74
  15. package/scripts/post-deployment-config.js +296 -296
  16. package/scripts/preinstall-check.js +173 -173
  17. package/scripts/publish.js +58 -268
  18. package/scripts/run-layered-tests.js +247 -0
  19. package/scripts/safe-install.js +139 -139
  20. package/scripts/simple-publish.js +57 -59
  21. package/src/adapters/claude/install_claude_integration.js +292 -0
  22. package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
  23. package/src/adapters/codex/install_codex_integration.js +395 -0
  24. package/src/adapters/copilot/install_copilot_integration.js +716 -0
  25. package/src/adapters/gemini/install_gemini_integration.js +304 -0
  26. package/src/adapters/iflow/install_iflow_integration.js +304 -0
  27. package/src/adapters/qoder/install_qoder_integration.js +1090 -0
  28. package/src/adapters/qwen/install_qwen_integration.js +285 -0
  29. package/src/auth.js +173 -173
  30. package/src/auth_command.js +208 -208
  31. package/src/calculator.js +313 -313
  32. package/src/cli/router.js +417 -38
  33. package/src/core/cache_cleaner.js +767 -744
  34. package/src/core/cli_help_analyzer.js +680 -674
  35. package/src/core/cli_parameter_handler.js +132 -127
  36. package/src/core/cli_tools.js +89 -89
  37. package/src/core/coordination/index.js +16 -16
  38. package/src/core/coordination/nodejs/AdapterManager.js +102 -89
  39. package/src/core/coordination/nodejs/CLCommunication.js +132 -124
  40. package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -236
  41. package/src/core/coordination/nodejs/HealthChecker.js +76 -77
  42. package/src/core/coordination/nodejs/HookDeploymentManager.js +263 -190
  43. package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
  44. package/src/core/coordination/nodejs/index.js +90 -72
  45. package/src/core/coordination/nodejs/utils/Logger.js +29 -29
  46. package/src/core/enhanced_installer.js +479 -456
  47. package/src/core/enhanced_uninstaller.js +638 -618
  48. package/src/core/error_handler.js +406 -406
  49. package/src/core/installer.js +815 -294
  50. package/src/core/memory_manager.js +83 -83
  51. package/src/core/rest_client.js +160 -160
  52. package/src/core/smart_router.js +249 -146
  53. package/src/core/upgrade_manager.js +76 -59
  54. package/src/data_encryption.js +143 -143
  55. package/src/data_structures.js +440 -440
  56. package/src/deploy.js +55 -55
  57. package/src/index.js +30 -30
  58. package/src/test/cli-availability-checker.js +194 -0
  59. package/src/test/test-environment.js +289 -0
  60. package/src/utils/helpers.js +35 -35
  61. package/src/utils.js +921 -915
  62. package/src/weatherProcessor.js +228 -228
  63. package/test/cache-cleaner-implemented.test.js +0 -328
  64. package/test/cache-cleaner.test.js +0 -390
  65. package/test/calculator.test.js +0 -215
  66. package/test/collision-test.js +0 -26
  67. package/test/comprehensive-enhanced-features.test.js +0 -252
  68. package/test/comprehensive-execution-test.js +0 -428
  69. package/test/conflict-prevention-test.js +0 -95
  70. package/test/cross-cli-detection-test.js +0 -33
  71. package/test/csv-processing-test.js +0 -36
  72. package/test/deploy-hooks-test.js +0 -250
  73. package/test/e2e/claude-cli-test.js +0 -128
  74. package/test/e2e/collaboration-test.js +0 -75
  75. package/test/e2e/comprehensive-test.js +0 -431
  76. package/test/e2e/error-handling-test.js +0 -90
  77. package/test/e2e/individual-tool-test.js +0 -143
  78. package/test/e2e/other-cli-test.js +0 -130
  79. package/test/e2e/qoder-cli-test.js +0 -128
  80. package/test/e2e/run-e2e-tests.js +0 -73
  81. package/test/e2e/test-data.js +0 -88
  82. package/test/e2e/test-utils.js +0 -222
  83. package/test/encryption-simple-test.js +0 -110
  84. package/test/encryption.test.js +0 -129
  85. package/test/enhanced-main-alignment.test.js +0 -298
  86. package/test/enhanced-uninstaller-implemented.test.js +0 -271
  87. package/test/enhanced-uninstaller.test.js +0 -284
  88. package/test/error-handling-test.js +0 -341
  89. package/test/fibonacci.test.js +0 -178
  90. package/test/final-deploy-test.js +0 -221
  91. package/test/final-install-test.js +0 -226
  92. package/test/hash-table-demo.js +0 -33
  93. package/test/hash-table-test.js +0 -26
  94. package/test/hash_table_test.js +0 -114
  95. package/test/hook-system-integration-test.js +0 -307
  96. package/test/iflow-integration-test.js +0 -292
  97. package/test/improved-install-test.js +0 -362
  98. package/test/install-command-test.js +0 -370
  99. package/test/json-parser-test.js +0 -161
  100. package/test/json-validation-test.js +0 -164
  101. package/test/natural-language-skills-test.js +0 -320
  102. package/test/nl-integration-test.js +0 -179
  103. package/test/parameter-parsing-test.js +0 -143
  104. package/test/plugin-deployment-test.js +0 -316
  105. package/test/postinstall-test.js +0 -269
  106. package/test/python-plugins-test.js +0 -259
  107. package/test/real-test.js +0 -435
  108. package/test/remaining-adapters-test.js +0 -256
  109. package/test/rest-client-test.js +0 -56
  110. package/test/rest_client.test.js +0 -85
  111. package/test/safe-installation-cleaner.test.js +0 -343
  112. package/test/simple-iflow-hook-test.js +0 -137
  113. package/test/stigmergy-upgrade-test.js +0 -243
  114. package/test/system-compatibility-test.js +0 -467
  115. package/test/tdd-deploy-fix-test.js +0 -324
  116. package/test/tdd-fixes-test.js +0 -211
  117. package/test/third-party-skills-test.js +0 -321
  118. package/test/tool-selection-integration-test.js +0 -158
  119. package/test/unit/calculator-full.test.js +0 -191
  120. package/test/unit/calculator-simple.test.js +0 -96
  121. package/test/unit/calculator.test.js +0 -97
  122. package/test/unit/cli-scanner.test.js +0 -291
  123. package/test/unit/cli_parameter_handler.test.js +0 -116
  124. package/test/unit/cross-cli-executor.test.js +0 -399
  125. package/test/weather-processor.test.js +0 -104
@@ -1,146 +1,249 @@
1
- const CLIHelpAnalyzer = require('./cli_help_analyzer');
2
- const { CLI_TOOLS, validateCLITool } = require('./cli_tools');
3
- const { errorHandler } = require('./error_handler');
4
-
5
- class SmartRouter {
6
- constructor() {
7
- this.tools = CLI_TOOLS;
8
- try {
9
- this.analyzer = new CLIHelpAnalyzer();
10
- this.analyzer.setCLITools(this.tools);
11
- } catch (error) {
12
- errorHandler.logError(error, 'ERROR', 'SmartRouter.constructor');
13
- throw error;
14
- }
15
- this.routeKeywords = [
16
- 'use',
17
- 'help',
18
- 'please',
19
- 'write',
20
- 'generate',
21
- 'explain',
22
- 'analyze',
23
- 'translate',
24
- 'code',
25
- 'article',
26
- ];
27
- this.defaultTool = 'claude';
28
- }
29
-
30
- /**
31
- * Initialize the smart router
32
- */
33
- async initialize() {
34
- await this.analyzer.initialize();
35
- }
36
-
37
- /**
38
- * Check if input should be routed to a specific CLI tool
39
- */
40
- shouldRoute(userInput) {
41
- return this.routeKeywords.some((keyword) =>
42
- userInput.toLowerCase().includes(keyword.toLowerCase()),
43
- );
44
- }
45
-
46
- /**
47
- * Perform smart routing based on user input and CLI patterns
48
- */
49
- async smartRoute(userInput) {
50
- const input = userInput.trim();
51
-
52
- // First try to detect tool-specific keywords
53
- for (const [toolName, _] of Object.entries(this.tools)) {
54
- try {
55
- // Validate tool configuration
56
- validateCLITool(toolName);
57
-
58
- // Get CLI pattern for this tool
59
- let cliPattern = await this.analyzer.getCLIPattern(toolName);
60
-
61
- // If we don't have a pattern, try to analyze the CLI
62
- if (!cliPattern) {
63
- try {
64
- cliPattern = await this.analyzer.analyzeCLI(toolName);
65
- } catch (error) {
66
- console.warn(`Failed to analyze ${toolName}:`, error.message);
67
- // Continue with next tool
68
- continue;
69
- }
70
- }
71
-
72
- // Check if input contains any of the tool's keywords or subcommands
73
- const keywords = this.extractKeywords(toolName, cliPattern);
74
- for (const keyword of keywords) {
75
- if (input.toLowerCase().includes(keyword.toLowerCase())) {
76
- // Extract clean parameters
77
- const cleanInput = input
78
- .replace(new RegExp(`.*${keyword}\\s*`, 'gi'), '')
79
- .replace(/^(use|please|help|using|with)\s*/i, '')
80
- .trim();
81
- return { tool: toolName, prompt: cleanInput };
82
- }
83
- }
84
- } catch (error) {
85
- await errorHandler.logError(
86
- error,
87
- 'WARN',
88
- `SmartRouter.smartRoute.${toolName}`,
89
- );
90
- // Continue with next tool
91
- continue;
92
- }
93
- }
94
-
95
- // Default routing
96
- const cleanInput = input
97
- .replace(/^(use|please|help|using|with)\s*/i, '')
98
- .trim();
99
- return { tool: this.defaultTool, prompt: cleanInput };
100
- }
101
-
102
- /**
103
- * Extract keywords for a tool from its CLI patterns
104
- */
105
- extractKeywords(toolName, cliPattern) {
106
- const keywords = [toolName];
107
-
108
- // Add tool-specific keywords
109
- const toolSpecificKeywords = {
110
- claude: ['claude', 'anthropic'],
111
- gemini: ['gemini', 'google'],
112
- qwen: ['qwen', 'alibaba', 'tongyi'],
113
- iflow: ['iflow', 'workflow', 'intelligent'],
114
- qodercli: ['qoder', 'code'],
115
- codebuddy: ['codebuddy', 'buddy', 'assistant'],
116
- copilot: ['copilot', 'github', 'gh'],
117
- codex: ['codex', 'openai', 'gpt'],
118
- };
119
-
120
- if (toolSpecificKeywords[toolName]) {
121
- keywords.push(...toolSpecificKeywords[toolName]);
122
- }
123
-
124
- // Add subcommands from CLI pattern if available
125
- if (cliPattern && cliPattern.patterns && cliPattern.patterns.subcommands) {
126
- cliPattern.patterns.subcommands.forEach((subcommand) => {
127
- if (subcommand.name) {
128
- keywords.push(subcommand.name);
129
- }
130
- });
131
- }
132
-
133
- // Add commands from CLI pattern if available
134
- if (cliPattern && cliPattern.patterns && cliPattern.patterns.commands) {
135
- cliPattern.patterns.commands.forEach((command) => {
136
- if (command.name && command.name !== toolName) {
137
- keywords.push(command.name);
138
- }
139
- });
140
- }
141
-
142
- return [...new Set(keywords)]; // Remove duplicates
143
- }
144
- }
145
-
146
- module.exports = SmartRouter;
1
+ const CLIHelpAnalyzer = require('./cli_help_analyzer');
2
+ const { CLI_TOOLS, validateCLITool } = require('./cli_tools');
3
+ const { errorHandler } = require('./error_handler');
4
+
5
+ class SmartRouter {
6
+ constructor() {
7
+ this.tools = CLI_TOOLS;
8
+ try {
9
+ this.analyzer = new CLIHelpAnalyzer();
10
+ this.analyzer.setCLITools(this.tools);
11
+ } catch (error) {
12
+ errorHandler.logError(error, 'ERROR', 'SmartRouter.constructor');
13
+ throw error;
14
+ }
15
+ this.routeKeywords = [
16
+ 'use',
17
+ 'help',
18
+ 'please',
19
+ 'write',
20
+ 'generate',
21
+ 'explain',
22
+ 'analyze',
23
+ 'translate',
24
+ 'article',
25
+ ];
26
+ this.defaultTool = 'claude';
27
+ // Track recently failed tools to avoid repeated analysis attempts
28
+ this.recentFailures = new Map();
29
+ }
30
+
31
+ /**
32
+ * Initialize the smart router
33
+ */
34
+ async initialize() {
35
+ await this.analyzer.initialize();
36
+ }
37
+
38
+ /**
39
+ * Check if input should be routed to a specific CLI tool
40
+ */
41
+ shouldRoute(userInput) {
42
+ return this.routeKeywords.some((keyword) =>
43
+ userInput.toLowerCase().includes(keyword.toLowerCase()),
44
+ );
45
+ }
46
+
47
+ /**
48
+ * Perform smart routing based on user input and CLI patterns
49
+ * Optimized to reduce unnecessary error messages and improve performance
50
+ * Prioritizes exact tool name matches over keyword matches
51
+ */
52
+ async smartRoute(userInput) {
53
+ const input = userInput.trim();
54
+ const inputLower = input.toLowerCase();
55
+
56
+ // First, check for exact tool name matches (higher priority)
57
+ for (const [toolName, _] of Object.entries(this.tools)) {
58
+ try {
59
+ // Validate tool configuration
60
+ validateCLITool(toolName);
61
+
62
+ if (inputLower.includes(toolName)) {
63
+ // Extract clean parameters when the tool name itself is mentioned
64
+ const cleanInput = input
65
+ .replace(new RegExp(`.*${toolName}\\s*`, 'gi'), '')
66
+ .replace(/^(use|please|help|using|with)\s*/i, '')
67
+ .trim();
68
+ return { tool: toolName, prompt: cleanInput };
69
+ }
70
+ } catch (error) {
71
+ // Only log error if it's a real issue, not just a missing pattern
72
+ if (
73
+ error.message &&
74
+ !error.message.includes('no such file or directory')
75
+ ) {
76
+ await errorHandler.logError(
77
+ error,
78
+ 'WARN',
79
+ `SmartRouter.smartRoute.${toolName}`,
80
+ );
81
+ }
82
+ // Continue with next tool
83
+ continue;
84
+ }
85
+ }
86
+
87
+ // Then check for keyword matches (lower priority)
88
+ // Only analyze tools that are likely to match to reduce overhead
89
+ const potentialMatches = [];
90
+ for (const [toolName, _] of Object.entries(this.tools)) {
91
+ // Quick check: if the input is very short, only analyze a few key tools
92
+ if (input.length < 20) {
93
+ // For short inputs, only analyze commonly used tools
94
+ const commonTools = ['claude', 'gemini', 'qwen'];
95
+ if (!commonTools.includes(toolName)) {
96
+ continue;
97
+ }
98
+ }
99
+
100
+ // Add tool to potential matches for detailed analysis
101
+ potentialMatches.push(toolName);
102
+ }
103
+
104
+ // Analyze potential matches
105
+ for (const toolName of potentialMatches) {
106
+ try {
107
+ // Validate tool configuration
108
+ validateCLITool(toolName);
109
+
110
+ // Get CLI pattern for this tool - with optimized caching
111
+ let cliPattern = await this.getOptimizedCLIPattern(toolName);
112
+
113
+ // Check if input contains any of the tool's keywords or subcommands
114
+ const keywords = this.extractKeywords(toolName, cliPattern);
115
+ for (const keyword of keywords) {
116
+ // Skip the tool name itself since we already checked for exact matches
117
+ if (
118
+ keyword.toLowerCase() !== toolName.toLowerCase() &&
119
+ inputLower.includes(keyword.toLowerCase())
120
+ ) {
121
+ // Extract clean parameters
122
+ const cleanInput = input
123
+ .replace(new RegExp(`.*${keyword}\\s*`, 'gi'), '')
124
+ .replace(/^(use|please|help|using|with)\s*/i, '')
125
+ .trim();
126
+ return { tool: toolName, prompt: cleanInput };
127
+ }
128
+ }
129
+ } catch (error) {
130
+ // Only log error if it's a real issue, not just a missing pattern
131
+ if (
132
+ error.message &&
133
+ !error.message.includes('no such file or directory')
134
+ ) {
135
+ await errorHandler.logError(
136
+ error,
137
+ 'WARN',
138
+ `SmartRouter.smartRoute.${toolName}`,
139
+ );
140
+ }
141
+ // Continue with next tool
142
+ continue;
143
+ }
144
+ }
145
+
146
+ // Default routing
147
+ const cleanInput = input
148
+ .replace(/^(use|please|help|using|with)\s*/i, '')
149
+ .trim();
150
+ return { tool: this.defaultTool, prompt: cleanInput };
151
+ }
152
+
153
+ /**
154
+ * Get CLI pattern with optimized error handling to reduce noise
155
+ */
156
+ async getOptimizedCLIPattern(toolName) {
157
+ try {
158
+ // Quick check for missing tools to avoid unnecessary analysis
159
+ const config = await this.analyzer.loadPersistentConfig();
160
+ const failedAttempt = config.failedAttempts[toolName];
161
+
162
+ // If there was a recent failure (less than 1 hour ago), skip analysis entirely
163
+ if (failedAttempt && this.isRecentFailure(failedAttempt.timestamp)) {
164
+ if (process.env.DEBUG === 'true') {
165
+ console.log(
166
+ `[INFO] Skipping analysis for ${toolName} due to recent failure`,
167
+ );
168
+ }
169
+ // Return cached analysis if available, otherwise null
170
+ const cached = await this.analyzer.getCachedAnalysis(toolName);
171
+ return cached || null;
172
+ }
173
+
174
+ const cached = await this.analyzer.getCachedAnalysis(toolName);
175
+
176
+ if (cached && !this.analyzer.isCacheExpired(cached.timestamp)) {
177
+ return cached;
178
+ }
179
+
180
+ // Analyze CLI if no cache or failure is old
181
+ return await this.analyzer.analyzeCLI(toolName);
182
+ } catch (error) {
183
+ // Only log serious errors, suppress file not found errors
184
+ if (
185
+ error.message &&
186
+ !error.message.includes('ENOENT') &&
187
+ !error.message.includes('no such file or directory')
188
+ ) {
189
+ console.warn(`[WARN] Unable to get help information for ${toolName}`);
190
+ }
191
+ return null;
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Check if failure timestamp is recent (less than 1 hour)
197
+ */
198
+ isRecentFailure(timestamp) {
199
+ const failureTime = new Date(timestamp);
200
+ const now = new Date();
201
+ const hoursDiff = (now - failureTime) / (1000 * 60 * 60);
202
+ return hoursDiff < 1; // Recent if less than 1 hour
203
+ }
204
+
205
+ /**
206
+ * Extract keywords for a tool from its CLI patterns
207
+ */
208
+ extractKeywords(toolName, cliPattern) {
209
+ const keywords = [toolName];
210
+
211
+ // Add tool-specific keywords
212
+ const toolSpecificKeywords = {
213
+ claude: ['claude', 'anthropic'],
214
+ gemini: ['gemini', 'google'],
215
+ qwen: ['qwen', 'alibaba', 'tongyi'],
216
+ iflow: ['iflow', 'workflow', 'intelligent'],
217
+ qodercli: ['qoder', 'code'], // 'code' is specifically for qodercli only
218
+ codebuddy: ['codebuddy', 'buddy', 'assistant'],
219
+ copilot: ['copilot', 'github', 'gh'],
220
+ codex: ['codex', 'openai', 'gpt'], // Remove 'code' from here to avoid conflicts
221
+ };
222
+
223
+ if (toolSpecificKeywords[toolName]) {
224
+ keywords.push(...toolSpecificKeywords[toolName]);
225
+ }
226
+
227
+ // Add subcommands from CLI pattern if available
228
+ if (cliPattern && cliPattern.patterns && cliPattern.patterns.subcommands) {
229
+ cliPattern.patterns.subcommands.forEach((subcommand) => {
230
+ if (subcommand.name) {
231
+ keywords.push(subcommand.name);
232
+ }
233
+ });
234
+ }
235
+
236
+ // Add commands from CLI pattern if available
237
+ if (cliPattern && cliPattern.patterns && cliPattern.patterns.commands) {
238
+ cliPattern.patterns.commands.forEach((command) => {
239
+ if (command.name && command.name !== toolName) {
240
+ keywords.push(command.name);
241
+ }
242
+ });
243
+ }
244
+
245
+ return [...new Set(keywords)]; // Remove duplicates
246
+ }
247
+ }
248
+
249
+ module.exports = SmartRouter;