stigmergy 1.2.0 → 1.2.8

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 (130) hide show
  1. package/LICENSE +18 -18
  2. package/README.md +31 -211
  3. package/STIGMERGY.md +70 -61
  4. package/docs/MULTI_USER_WIKI_COLLABORATION_SYSTEM.md +523 -0
  5. package/docs/PROJECT_CONSTITUTION.md +433 -433
  6. package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
  7. package/docs/PROMPT_BASED_SKILLS_SYSTEM_DESIGN.md +458 -0
  8. package/docs/SKILL_IMPLEMENTATION_CONSTRAINTS_AND_ALIGNMENT.md +423 -0
  9. package/docs/TECHNICAL_FEASIBILITY_ANALYSIS.md +308 -0
  10. package/examples/calculator-example.js +72 -72
  11. package/examples/cline_usage_examples.md +364 -364
  12. package/examples/encryption-example.js +67 -67
  13. package/examples/json-parser-example.js +120 -120
  14. package/examples/json-validation-example.js +64 -64
  15. package/examples/multilingual-hook-demo.js +125 -0
  16. package/examples/rest-client-example.js +52 -52
  17. package/examples/rest_client_example.js +54 -54
  18. package/package.json +38 -20
  19. package/scripts/build.js +74 -74
  20. package/scripts/dependency-analyzer.js +101 -0
  21. package/scripts/generate-cli-docs.js +64 -0
  22. package/scripts/post-deployment-config.js +296 -296
  23. package/scripts/postuninstall.js +46 -0
  24. package/scripts/preinstall-check.js +173 -173
  25. package/scripts/preuninstall.js +75 -0
  26. package/scripts/publish.js +58 -268
  27. package/scripts/run-layered-tests.js +247 -0
  28. package/scripts/safe-install.js +139 -139
  29. package/scripts/simple-publish.js +57 -59
  30. package/src/adapters/claude/install_claude_integration.js +292 -0
  31. package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
  32. package/src/adapters/codex/install_codex_integration.js +395 -0
  33. package/src/adapters/copilot/install_copilot_integration.js +716 -0
  34. package/src/adapters/gemini/install_gemini_integration.js +304 -0
  35. package/src/adapters/iflow/install_iflow_integration.js +304 -0
  36. package/src/adapters/qoder/install_qoder_integration.js +1090 -0
  37. package/src/adapters/qwen/install_qwen_integration.js +285 -0
  38. package/src/cli/router.js +562 -39
  39. package/src/core/cache_cleaner.js +82 -59
  40. package/src/core/cli_help_analyzer.js +297 -291
  41. package/src/core/cli_parameter_handler.js +5 -0
  42. package/src/core/cli_tools.js +6 -6
  43. package/src/core/coordination/index.js +2 -2
  44. package/src/core/coordination/nodejs/AdapterManager.js +30 -17
  45. package/src/core/coordination/nodejs/CLCommunication.js +28 -20
  46. package/src/core/coordination/nodejs/CLIIntegrationManager.js +72 -36
  47. package/src/core/coordination/nodejs/HealthChecker.js +13 -14
  48. package/src/core/coordination/nodejs/HookDeploymentManager.js +325 -63
  49. package/src/core/coordination/nodejs/StatisticsCollector.js +6 -6
  50. package/src/core/coordination/nodejs/index.js +29 -11
  51. package/src/core/coordination/nodejs/utils/Logger.js +1 -1
  52. package/src/core/enhanced_installer.js +92 -69
  53. package/src/core/enhanced_uninstaller.js +73 -53
  54. package/src/core/installer.js +815 -294
  55. package/src/core/multilingual/language-pattern-manager.js +172 -0
  56. package/src/core/smart_router.js +141 -26
  57. package/src/core/upgrade_manager.js +91 -46
  58. package/src/data_structures.js +1 -1
  59. package/src/deploy.js +2 -2
  60. package/src/index.js +3 -3
  61. package/src/test/cli-availability-checker.js +194 -0
  62. package/src/test/test-environment.js +289 -0
  63. package/src/utils/helpers.js +2 -2
  64. package/src/utils.js +7 -1
  65. package/test/multilingual/hook-deployment.test.js +91 -0
  66. package/test/multilingual/language-pattern-manager.test.js +140 -0
  67. package/test/multilingual/system-test.js +85 -0
  68. package/test/cache-cleaner-implemented.test.js +0 -328
  69. package/test/cache-cleaner.test.js +0 -390
  70. package/test/calculator.test.js +0 -215
  71. package/test/collision-test.js +0 -26
  72. package/test/comprehensive-enhanced-features.test.js +0 -252
  73. package/test/comprehensive-execution-test.js +0 -428
  74. package/test/conflict-prevention-test.js +0 -95
  75. package/test/cross-cli-detection-test.js +0 -33
  76. package/test/csv-processing-test.js +0 -36
  77. package/test/deploy-hooks-test.js +0 -250
  78. package/test/e2e/claude-cli-test.js +0 -128
  79. package/test/e2e/collaboration-test.js +0 -75
  80. package/test/e2e/comprehensive-test.js +0 -431
  81. package/test/e2e/error-handling-test.js +0 -90
  82. package/test/e2e/individual-tool-test.js +0 -143
  83. package/test/e2e/other-cli-test.js +0 -130
  84. package/test/e2e/qoder-cli-test.js +0 -128
  85. package/test/e2e/run-e2e-tests.js +0 -73
  86. package/test/e2e/test-data.js +0 -88
  87. package/test/e2e/test-utils.js +0 -222
  88. package/test/encryption-simple-test.js +0 -110
  89. package/test/encryption.test.js +0 -129
  90. package/test/enhanced-main-alignment.test.js +0 -298
  91. package/test/enhanced-uninstaller-implemented.test.js +0 -271
  92. package/test/enhanced-uninstaller.test.js +0 -284
  93. package/test/error-handling-test.js +0 -341
  94. package/test/fibonacci.test.js +0 -178
  95. package/test/final-deploy-test.js +0 -221
  96. package/test/final-install-test.js +0 -226
  97. package/test/hash-table-demo.js +0 -33
  98. package/test/hash-table-test.js +0 -26
  99. package/test/hash_table_test.js +0 -114
  100. package/test/hook-system-integration-test.js +0 -307
  101. package/test/iflow-integration-test.js +0 -292
  102. package/test/improved-install-test.js +0 -362
  103. package/test/install-command-test.js +0 -370
  104. package/test/json-parser-test.js +0 -161
  105. package/test/json-validation-test.js +0 -164
  106. package/test/natural-language-skills-test.js +0 -320
  107. package/test/nl-integration-test.js +0 -179
  108. package/test/parameter-parsing-test.js +0 -143
  109. package/test/plugin-deployment-test.js +0 -316
  110. package/test/postinstall-test.js +0 -269
  111. package/test/python-plugins-test.js +0 -259
  112. package/test/real-test.js +0 -435
  113. package/test/remaining-adapters-test.js +0 -256
  114. package/test/rest-client-test.js +0 -56
  115. package/test/rest_client.test.js +0 -85
  116. package/test/safe-installation-cleaner.test.js +0 -343
  117. package/test/simple-iflow-hook-test.js +0 -137
  118. package/test/stigmergy-upgrade-test.js +0 -243
  119. package/test/system-compatibility-test.js +0 -467
  120. package/test/tdd-deploy-fix-test.js +0 -324
  121. package/test/tdd-fixes-test.js +0 -211
  122. package/test/third-party-skills-test.js +0 -321
  123. package/test/tool-selection-integration-test.js +0 -158
  124. package/test/unit/calculator-full.test.js +0 -191
  125. package/test/unit/calculator-simple.test.js +0 -96
  126. package/test/unit/calculator.test.js +0 -97
  127. package/test/unit/cli-scanner.test.js +0 -291
  128. package/test/unit/cli_parameter_handler.test.js +0 -116
  129. package/test/unit/cross-cli-executor.test.js +0 -399
  130. package/test/weather-processor.test.js +0 -104
@@ -8,7 +8,14 @@ class HookDeploymentManager {
8
8
  constructor() {
9
9
  this.deploymentDir = path.join(os.homedir(), '.stigmergy', 'hooks');
10
10
  this.supportedCLIs = [
11
- 'claude', 'gemini', 'qwen', 'iflow', 'qodercli', 'codebuddy', 'codex', 'copilot'
11
+ 'claude',
12
+ 'gemini',
13
+ 'qwen',
14
+ 'iflow',
15
+ 'qodercli',
16
+ 'codebuddy',
17
+ 'codex',
18
+ 'copilot',
12
19
  ];
13
20
  }
14
21
 
@@ -20,13 +27,15 @@ class HookDeploymentManager {
20
27
  async ensureDeploymentDirectory() {
21
28
  if (!fs.existsSync(this.deploymentDir)) {
22
29
  fs.mkdirSync(this.deploymentDir, { recursive: true });
23
- console.log(`[HOOK_DEPLOYMENT] Created deployment directory: ${this.deploymentDir}`);
30
+ console.log(
31
+ `[HOOK_DEPLOYMENT] Created deployment directory: ${this.deploymentDir}`,
32
+ );
24
33
  }
25
34
  }
26
35
 
27
36
  async deployHooksForCLI(cliName, options = {}) {
28
37
  console.log(`[HOOK_DEPLOYMENT] Deploying hooks for ${cliName}...`);
29
-
38
+
30
39
  if (!this.supportedCLIs.includes(cliName.toLowerCase())) {
31
40
  throw new Error(`Unsupported CLI: ${cliName}`);
32
41
  }
@@ -40,41 +49,48 @@ class HookDeploymentManager {
40
49
 
41
50
  // Deploy Node.js specific hooks
42
51
  await this.deployNodeJsHooks(cliName, cliHookDir, options);
43
-
44
- console.log(`[HOOK_DEPLOYMENT] Hooks deployed successfully for ${cliName}`);
52
+
53
+ console.log(
54
+ `[HOOK_DEPLOYMENT] Hooks deployed successfully for ${cliName}`,
55
+ );
45
56
  return true;
46
57
  } catch (error) {
47
- console.error(`[HOOK_DEPLOYMENT] Failed to deploy hooks for ${cliName}:`, error);
58
+ console.error(
59
+ `[HOOK_DEPLOYMENT] Failed to deploy hooks for ${cliName}:`,
60
+ error,
61
+ );
48
62
  return false;
49
63
  }
50
64
  }
51
65
 
52
66
  async deployNodeJsHooks(cliName, hookDir, options) {
53
67
  console.log(`[HOOK_DEPLOYMENT] Deploying Node.js hooks for ${cliName}...`);
54
-
68
+
55
69
  // Create a basic hook template for Node.js
56
70
  const hookTemplate = this.generateNodeJsHookTemplate(cliName);
57
71
  const hookFilePath = path.join(hookDir, `${cliName}_nodejs_hook.js`);
58
-
72
+
59
73
  fs.writeFileSync(hookFilePath, hookTemplate);
60
74
  console.log(`[HOOK_DEPLOYMENT] Created Node.js hook: ${hookFilePath}`);
61
-
75
+
62
76
  // Make the hook executable
63
77
  try {
64
78
  fs.chmodSync(hookFilePath, 0o755);
65
79
  console.log(`[HOOK_DEPLOYMENT] Made hook executable: ${hookFilePath}`);
66
80
  } catch (error) {
67
- console.warn(`[HOOK_DEPLOYMENT] Failed to make hook executable: ${error.message}`);
81
+ console.warn(
82
+ `[HOOK_DEPLOYMENT] Failed to make hook executable: ${error.message}`,
83
+ );
68
84
  }
69
-
85
+
70
86
  // Create configuration file
71
87
  const config = {
72
88
  cli: cliName,
73
89
  hookPath: hookFilePath,
74
90
  deploymentTime: new Date().toISOString(),
75
- version: '1.0.0-nodejs'
91
+ version: '1.0.0-nodejs',
76
92
  };
77
-
93
+
78
94
  const configPath = path.join(hookDir, 'config.json');
79
95
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
80
96
  console.log(`[HOOK_DEPLOYMENT] Created hook configuration: ${configPath}`);
@@ -82,64 +98,296 @@ class HookDeploymentManager {
82
98
 
83
99
  generateNodeJsHookTemplate(cliName) {
84
100
  return `#!/usr/bin/env node
85
-
86
101
  /**
87
102
  * Node.js Hook for ${cliName.toUpperCase()}
88
103
  * Auto-generated by Stigmergy CLI Hook Deployment Manager
89
104
  */
90
-
91
105
  const fs = require('fs');
92
106
  const path = require('path');
93
107
 
108
+ // Embed LanguagePatternManager directly to ensure availability in deployed hooks
109
+ class LanguagePatternManager {
110
+ constructor() {
111
+ this.supportedLanguages = {
112
+ en: { name: 'English', direction: 'ltr' },
113
+ zh: { name: 'Chinese', direction: 'ltr' },
114
+ ja: { name: 'Japanese', direction: 'ltr' },
115
+ ko: { name: 'Korean', direction: 'ltr' },
116
+ de: { name: 'German', direction: 'ltr' },
117
+ fr: { name: 'French', direction: 'ltr' },
118
+ es: { name: 'Spanish', direction: 'ltr' },
119
+ it: { name: 'Italian', direction: 'ltr' },
120
+ pt: { name: 'Portuguese', direction: 'ltr' },
121
+ ru: { name: 'Russian', direction: 'ltr' },
122
+ ar: { name: 'Arabic', direction: 'rtl' },
123
+ tr: { name: 'Turkish', direction: 'ltr' }
124
+ };
125
+
126
+ // Define language patterns directly in the hook
127
+ this.languagePatterns = {
128
+ // English patterns
129
+ en: [
130
+ { name: 'use_tool_for_task', regex: /(?:use|call|ask)\\s+(\\w+)\\s+(?:to|for)\\s+(.+)$/i },
131
+ { name: 'please_use_tool', regex: /(?:please\\s+)?(?:use|call|ask)\\s+(\\w+)\\s+(.+)$/i },
132
+ { name: 'tool_please_help', regex: /(\\w+)[,\\s]+(?:please\\s+)?(?:help\\s+me\\s+)?(.+)$/i }
133
+ ],
134
+ // Chinese patterns
135
+ zh: [
136
+ { name: 'qing_yong_gongneng_bang_wo', regex: /请用(\\w+)\\s*帮我(.+)$/i },
137
+ { name: 'diaoyong_lai', regex: /调用(\\w+)\\s*来(.+)$/i },
138
+ { name: 'yong_gongneng_bang_wo', regex: /用(\\w+)\\s*帮我(.+)$/i },
139
+ { name: 'tool_comma_task', regex: /(\\w+),(.+)$/i },
140
+ { name: 'rang_gongneng', regex: /让(\\w+)\\s*(.+)$/i }
141
+ ],
142
+ // German patterns
143
+ de: [
144
+ { name: 'benutze_tool_um', regex: /benutze\\s+(\\w+)\\s+um\\s+(.+)$/i },
145
+ { name: 'verwende_tool_fur', regex: /verwende\\s+(\\w+)\\s+für\\s+(.+)$/i },
146
+ { name: 'rufe_tool_fur_an', regex: /rufe\\s+(\\w+)\\s+für\\s+(.+)\\s+an$/i }
147
+ ],
148
+ // French patterns
149
+ fr: [
150
+ { name: 'utilise_tool_pour', regex: /utilise\\s+(\\w+)\\s+pour\\s+(.+)$/i },
151
+ { name: 'emploie_tool_avec', regex: /emploie\\s+(\\w+)\\s+avec\\s+(.+)$/i },
152
+ { name: 'appelle_tool_pour', regex: /appelle\\s+(\\w+)\\s+pour\\s+(.+)$/i }
153
+ ],
154
+ // Spanish patterns
155
+ es: [
156
+ { name: 'usa_tool_para', regex: /usa\\s+(\\w+)\\s+para\\s+(.+)$/i },
157
+ { name: 'utiliza_tool_para', regex: /utiliza\\s+(\\w+)\\s+para\\s+(.+)$/i },
158
+ { name: 'llama_tool_para', regex: /llama\\s+(\\w+)\\s+para\\s+(.+)$/i }
159
+ ],
160
+ // Italian patterns
161
+ it: [
162
+ { name: 'usa_tool_per', regex: /usa\\s+(\\w+)\\s+per\\s+(.+)$/i },
163
+ { name: 'utilizza_tool_per', regex: /utilizza\\s+(\\w+)\\s+per\\s+(.+)$/i },
164
+ { name: 'chiedi_tool_per', regex: /chiedi\\s+(\\w+)\\s+per\\s+(.+)$/i }
165
+ ],
166
+ // Portuguese patterns
167
+ pt: [
168
+ { name: 'usa_tool_para_pt', regex: /usa\\s+(\\w+)\\s+para\\s+(.+)$/i },
169
+ { name: 'utiliza_tool_para_pt', regex: /utiliza\\s+(\\w+)\\s+para\\s+(.+)$/i },
170
+ { name: 'chama_tool_para', regex: /chama\\s+(\\w+)\\s+para\\s+(.+)$/i }
171
+ ],
172
+ // Russian patterns
173
+ ru: [
174
+ { name: 'ispolzuy_tool_chtoby', regex: /используй\\s+(\\w+)\\s+чтобы\\s+(.+)$/i },
175
+ { name: 'primeni_tool_dlya', regex: /примени\\s+(\\w+)\\s+для\\s+(.+)$/i },
176
+ { name: 'vysovyi_tool_dlya', regex: /вызови\\s+(\\w+)\\s+для\\s+(.+)$/i }
177
+ ],
178
+ // Arabic patterns
179
+ ar: [
180
+ { name: 'ista5dam_tool_liktabat', regex: /استخدم\\s+(\\w+)\\s+ل(?:كتابة|عمل)\\s+(.+)$/i },
181
+ { name: 'atssil_b_tool', regex: /اتصل\\s+ب\\s+(\\w+)\\s+(.+)$/i },
182
+ { name: 'ast5raj_tool', regex: /استخرج\\s+(\\w+)\\s+(.+)$/i }
183
+ ],
184
+ // Japanese patterns
185
+ ja: [
186
+ { name: 'tool_o_tsukatte', regex: /(\\w+)\\s*を使って\\s*(.+)$/i },
187
+ { name: 'tool_wo_yatte', regex: /(\\w+)\\s*を\\s*やって\\s*(.+)$/i },
188
+ { name: 'tool_ni_onegaishimasu', regex: /(\\w+)、\\s*(.+)$/i }
189
+ ],
190
+ // Korean patterns
191
+ ko: [
192
+ { name: 'tool_sayonghae', regex: /(\\w+)\\s*를\\s*사용해\\s*(.+)$/i },
193
+ { name: 'tool_sayonghayeyo', regex: /(\\w+)\\s*를\\s*사용하여\\s*(.+)$/i },
194
+ { name: 'tool_irae', regex: /(\\w+)\\s*을\\s*이용해\\s*(.+)$/i },
195
+ { name: 'tool_ggumyeon', regex: /(\\w+)\\s*하고\\s*(.+)$/i }
196
+ ],
197
+ // Turkish patterns
198
+ tr: [
199
+ { name: 'tool_icin_kullan', regex: /(\\w+)'?u\\s*(.+)\\s+için\\s+kullan/i },
200
+ { name: 'tool_kullan_icin', regex: /(\\w+)\\s*kullan\\s+için\\s*(.+)$/i },
201
+ { name: 'tool_ile_yap', regex: /(\\w+)\\s*ile\\s*(.+)$/i }
202
+ ]
203
+ };
204
+ }
205
+
206
+ getPatterns(languageCode) {
207
+ return this.languagePatterns[languageCode] || [];
208
+ }
209
+
210
+ getAllPatterns() {
211
+ return this.languagePatterns;
212
+ }
213
+
214
+ detectLanguage() {
215
+ // Try to detect language from environment variables
216
+ const envLang = process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL || process.env.LC_MESSAGES;
217
+
218
+ if (envLang) {
219
+ // Extract language code (e.g., en_US.UTF-8 -> en)
220
+ const langCode = envLang.split('.')[0].split('_')[0].split('-')[0].toLowerCase();
221
+ if (this.supportedLanguages[langCode]) {
222
+ return langCode;
223
+ }
224
+ }
225
+
226
+ // Try to detect language using Intl API
227
+ try {
228
+ if (typeof Intl !== 'undefined' && Intl.DateTimeFormat) {
229
+ const locale = Intl.DateTimeFormat().resolvedOptions().locale;
230
+ if (locale) {
231
+ const langCode = locale.split('-')[0].toLowerCase();
232
+ if (this.supportedLanguages[langCode]) {
233
+ return langCode;
234
+ }
235
+ }
236
+ }
237
+ } catch (error) {
238
+ // Intl API not available or failed
239
+ }
240
+
241
+ // Default to English
242
+ return 'en';
243
+ }
244
+
245
+ detectCrossCLIRequest(input, preferredLanguage = null) {
246
+ // If preferred language is specified, try that first
247
+ if (preferredLanguage && this.languagePatterns[preferredLanguage]) {
248
+ const result = this.matchPatterns(input, preferredLanguage);
249
+ if (result) return result;
250
+ }
251
+
252
+ // Try user's detected language
253
+ const detectedLanguage = this.detectLanguage();
254
+ if (detectedLanguage !== preferredLanguage) {
255
+ const result = this.matchPatterns(input, detectedLanguage);
256
+ if (result) return result;
257
+ }
258
+
259
+ // Fall back to English
260
+ if (detectedLanguage !== 'en') {
261
+ const result = this.matchPatterns(input, 'en');
262
+ if (result) return result;
263
+ }
264
+
265
+ // Try all languages as last resort
266
+ for (const languageCode in this.languagePatterns) {
267
+ if (languageCode !== detectedLanguage && languageCode !== 'en') {
268
+ const result = this.matchPatterns(input, languageCode);
269
+ if (result) return result;
270
+ }
271
+ }
272
+
273
+ return null;
274
+ }
275
+
276
+ matchPatterns(input, languageCode) {
277
+ const patterns = this.languagePatterns[languageCode];
278
+ if (!patterns) return null;
279
+
280
+ for (const pattern of patterns) {
281
+ const match = input.match(pattern.regex);
282
+ if (match && match.length >= 3) {
283
+ const targetCLI = match[1].toLowerCase();
284
+ const task = match[2];
285
+
286
+ // Validate that the target CLI is supported
287
+ const supportedCLIs = [
288
+ 'claude', 'gemini', 'qwen', 'iflow', 'qodercli', 'codebuddy', 'codex', 'copilot'
289
+ ];
290
+
291
+ if (supportedCLIs.includes(targetCLI)) {
292
+ return {
293
+ targetCLI: targetCLI,
294
+ task: task,
295
+ language: languageCode,
296
+ patternName: pattern.name
297
+ };
298
+ }
299
+ }
300
+ }
301
+
302
+ return null;
303
+ }
304
+ }
305
+
306
+ // Instantiate the LanguagePatternManager
307
+ const embeddedLanguageManager = new LanguagePatternManager();
308
+
94
309
  class ${this.capitalize(cliName)}NodeJsHook {
95
310
  constructor() {
96
311
  this.cliName = '${cliName}';
97
312
  this.hookDir = __dirname;
98
313
  this.logFile = path.join(this.hookDir, '${cliName}_hook.log');
314
+ this.languageManager = embeddedLanguageManager;
99
315
  }
100
-
101
316
  async onUserPrompt(prompt, context) {
102
317
  this.log('INFO', \`User prompt received: \${prompt}\`);
103
-
104
318
  // Check for cross-CLI requests
105
319
  const crossCLIRequest = this.detectCrossCLIRequest(prompt);
106
320
  if (crossCLIRequest) {
107
321
  return await this.handleCrossCLIRequest(crossCLIRequest, context);
108
322
  }
109
-
110
323
  // Default processing
111
324
  return null;
112
325
  }
113
-
114
326
  async onToolUse(toolName, toolArgs, context) {
115
327
  this.log('INFO', \`Tool use detected: \${toolName}\`);
116
328
  return null;
117
329
  }
118
-
119
330
  async onResponseGenerated(response, context) {
120
331
  this.log('INFO', 'Response generated');
121
332
  return null;
122
333
  }
123
-
124
334
  detectCrossCLIRequest(prompt) {
125
- // Enhanced pattern matching for cross-CLI requests
335
+ // Use the embedded LanguagePatternManager for enhanced multilingual pattern matching
336
+ try {
337
+ // Verify that the languageManager has the required method
338
+ if (this.languageManager && this.languageManager.detectCrossCLIRequest) {
339
+ const result = this.languageManager.detectCrossCLIRequest(prompt);
340
+
341
+ if (result) {
342
+ return {
343
+ targetCLI: result.targetCLI,
344
+ task: result.task,
345
+ source: this.cliName,
346
+ language: result.language,
347
+ patternName: result.patternName
348
+ };
349
+ }
350
+ }
351
+ } catch (error) {
352
+ // If LanguagePatternManager fails, fall back to original pattern matching
353
+ console.warn('LanguagePatternManager failed, falling back to original patterns:', error.message);
354
+ }
355
+
356
+ // Fallback to original pattern matching for backward compatibility
126
357
  const patterns = [
127
- /(?:use|call|ask)\\\\s+(\\\\w+)\\\\s+(?:to|for)\\\\s+(.+)$/i,
128
- /(?:please\\\\s+)?(?:use|call|ask)\\\\s+(\\\\w+)\\\\s+(.+)$/i,
129
- /(\\\\w+)[,\\\\s]+(?:please\\\\s+)?(?:help\\\\s+me\\\\s+)?(.+)$/i
358
+ /(?:use|call|ask)\\s+(\\w+)\\s+(?:to|for)\\s+(.+)$/i,
359
+ /(?:please\\s+)?(?:use|call|ask)\\s+(\\w+)\\s+(.+)$/i,
360
+ /(\\w+)[,\\s]+((?:please\\s+)?(?:help\\s+me\\s+)?(?:.+))$/i,
361
+ /请用(\\w+)\\s*帮我(.+)$/i,
362
+ /调用(\\w+)\\s*来(.+)$/i,
363
+ /用(\\w+)\\s*帮我(.+)$/i,
364
+ /(\\w+),(.+)$/i,
365
+ /让(\\w+)\\s*(.+)$/i,
366
+ /(?:utiliser|appeler|demander)\\s+(\\w+)\\s+(?:pour|afin de)\\s+(.+)$/i,
367
+ /(?:usar|llamar|pedir)\\s+(\\w+)\\s+(?:para|para que)\\s+(.+)$/i,
368
+ /(?:utilizzare|chiedere)\\s+(\\w+)\\s+(?:per|per far)\\s+(.+)$/i,
369
+ /(?:verwenden|aufrufen|bitten)\\s+(\\w+)\\s+(?:für|um)\\s+(.+)$/i,
370
+ /(?:使う|呼び出す|頼む)\\s+(\\w+)\\s+(?:ために|で)\\s+(.+)$/i
130
371
  ];
131
-
372
+
132
373
  for (const pattern of patterns) {
133
374
  const match = prompt.match(pattern);
134
375
  if (match && match.length >= 3) {
135
376
  const targetCLI = match[1].toLowerCase();
136
- const task = match[2];
137
-
377
+ let task = match[2];
378
+
379
+ // For the specific pattern that includes optional prefixes in the task capture,
380
+ // no additional processing needed as it's already captured correctly
381
+ if (pattern.source.includes('(?:please\\\\s+)?(?:help\\\\s+me\\\\s+)?')) {
382
+ // This is the pattern /(\\w+)[,\\\\s]+((?:please\\\\s+)?(?:help\\\\s+me\\\\s+)?(?:.+))$/i
383
+ // The task is already captured with the prefixes if they exist
384
+ }
385
+
138
386
  // Validate that the target CLI is supported
139
387
  const supportedCLIs = [
140
388
  'claude', 'gemini', 'qwen', 'iflow', 'qodercli', 'codebuddy', 'codex', 'copilot'
141
389
  ];
142
-
390
+
143
391
  if (supportedCLIs.includes(targetCLI)) {
144
392
  return {
145
393
  targetCLI: targetCLI,
@@ -149,39 +397,47 @@ class ${this.capitalize(cliName)}NodeJsHook {
149
397
  }
150
398
  }
151
399
  }
152
-
400
+
153
401
  return null;
154
402
  }
155
-
156
403
  async handleCrossCLIRequest(request, context) {
157
404
  this.log('INFO', \`Cross-CLI request detected: \${JSON.stringify(request)}\`);
158
-
405
+
159
406
  // Validate the request
160
407
  if (!request.targetCLI || !request.task) {
161
408
  this.log('ERROR', 'Invalid cross-CLI request: missing targetCLI or task');
162
409
  return \`[CROSS-CLI] Invalid request: missing targetCLI or task\`;
163
410
  }
164
-
411
+
165
412
  // Check if the target CLI is the same as the source
166
413
  if (request.targetCLI === this.cliName) {
167
414
  this.log('WARN', 'Cross-CLI request to self ignored');
168
415
  return \`[CROSS-CLI] Cannot call self (\${request.targetCLI})\`;
169
416
  }
170
-
417
+
171
418
  // Communicate with the coordination layer to execute the cross-CLI call
172
419
  try {
173
- // Dynamically load the CLCommunication module
174
- const modulePath = path.join(__dirname, '..', '..', '..', '..', 'src', 'core', 'coordination', 'nodejs', 'CLCommunication');
175
- const CLCommunication = require(modulePath);
420
+ // Try to load the CLCommunication module
421
+ let CLCommunication;
422
+ try {
423
+ // First, try the standard installation path
424
+ const modulePath = path.join(__dirname, '..', '..', '..', 'node_modules', 'stigmergy', 'src', 'core', 'coordination', 'nodejs', 'CLCommunication');
425
+ CLCommunication = require(modulePath);
426
+ } catch (e) {
427
+ // If that fails, try alternative paths or gracefully degrade
428
+ console.warn('CLCommunication module not found, cross-CLI functionality may be limited');
429
+ return \`[CROSS-CLI] CLCommunication module not found for \${request.targetCLI}\`;
430
+ }
431
+
176
432
  const communicator = new CLCommunication();
177
-
433
+
178
434
  const result = await communicator.executeTask(
179
- request.source,
180
- request.targetCLI,
181
- request.task,
435
+ request.source,
436
+ request.targetCLI,
437
+ request.task,
182
438
  context
183
439
  );
184
-
440
+
185
441
  if (result.success) {
186
442
  return \`[CROSS-CLI] Response from \${request.targetCLI}: \${result.output}\`;
187
443
  } else {
@@ -192,18 +448,16 @@ class ${this.capitalize(cliName)}NodeJsHook {
192
448
  return \`[CROSS-CLI] Failed to execute \${request.targetCLI}: \${error.message}\`;
193
449
  }
194
450
  }
195
-
196
451
  log(level, message) {
197
452
  const timestamp = new Date().toISOString();
198
- const logEntry = \`[\${timestamp}] [\${level}] [\${this.cliName.toUpperCase()}] \${message}\\\\n\`;
199
-
453
+ const logEntry = \`[\${timestamp}] [\${level}] [\${this.cliName.toUpperCase()}] \${message}\\n\`;
454
+
200
455
  try {
201
456
  fs.appendFileSync(this.logFile, logEntry);
202
457
  } catch (error) {
203
458
  console.error('Failed to write to log file:', error);
204
459
  }
205
460
  }
206
-
207
461
  capitalize(str) {
208
462
  return str.charAt(0).toUpperCase() + str.slice(1);
209
463
  }
@@ -216,8 +470,7 @@ module.exports = ${this.capitalize(cliName)}NodeJsHook;
216
470
  if (require.main === module) {
217
471
  const hook = new ${this.capitalize(cliName)}NodeJsHook();
218
472
  console.log('${cliName.toUpperCase()} Node.js Hook initialized');
219
- }
220
- `;
473
+ }`;
221
474
  }
222
475
 
223
476
  capitalize(str) {
@@ -226,7 +479,7 @@ if (require.main === module) {
226
479
 
227
480
  async undeployHooksForCLI(cliName) {
228
481
  console.log(`[HOOK_DEPLOYMENT] Undeploying hooks for ${cliName}...`);
229
-
482
+
230
483
  const cliHookDir = path.join(this.deploymentDir, cliName);
231
484
  if (fs.existsSync(cliHookDir)) {
232
485
  try {
@@ -234,11 +487,14 @@ if (require.main === module) {
234
487
  console.log(`[HOOK_DEPLOYMENT] Removed hook directory: ${cliHookDir}`);
235
488
  return true;
236
489
  } catch (error) {
237
- console.error(`[HOOK_DEPLOYMENT] Failed to remove hook directory:`, error);
490
+ console.error(
491
+ '[HOOK_DEPLOYMENT] Failed to remove hook directory:',
492
+ error,
493
+ );
238
494
  return false;
239
495
  }
240
496
  }
241
-
497
+
242
498
  console.log(`[HOOK_DEPLOYMENT] No hooks found for ${cliName}`);
243
499
  return true;
244
500
  }
@@ -247,11 +503,12 @@ if (require.main === module) {
247
503
  if (!fs.existsSync(this.deploymentDir)) {
248
504
  return [];
249
505
  }
250
-
251
- const cliDirs = fs.readdirSync(this.deploymentDir, { withFileTypes: true })
252
- .filter(dirent => dirent.isDirectory())
253
- .map(dirent => dirent.name);
254
-
506
+
507
+ const cliDirs = fs
508
+ .readdirSync(this.deploymentDir, { withFileTypes: true })
509
+ .filter((dirent) => dirent.isDirectory())
510
+ .map((dirent) => dirent.name);
511
+
255
512
  const hooks = [];
256
513
  for (const cliName of cliDirs) {
257
514
  const configPath = path.join(this.deploymentDir, cliName, 'config.json');
@@ -260,32 +517,37 @@ if (require.main === module) {
260
517
  const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
261
518
  hooks.push(config);
262
519
  } catch (error) {
263
- console.warn(`[HOOK_DEPLOYMENT] Failed to read config for ${cliName}:`, error.message);
520
+ console.warn(
521
+ `[HOOK_DEPLOYMENT] Failed to read config for ${cliName}:`,
522
+ error.message,
523
+ );
264
524
  }
265
525
  }
266
526
  }
267
-
527
+
268
528
  return hooks;
269
529
  }
270
530
 
271
531
  async validateHookDeployment(cliName) {
272
- console.log(`[HOOK_DEPLOYMENT] Validating hook deployment for ${cliName}...`);
273
-
532
+ console.log(
533
+ `[HOOK_DEPLOYMENT] Validating hook deployment for ${cliName}...`,
534
+ );
535
+
274
536
  const cliHookDir = path.join(this.deploymentDir, cliName);
275
537
  if (!fs.existsSync(cliHookDir)) {
276
538
  return { valid: false, error: 'Hook directory not found' };
277
539
  }
278
-
540
+
279
541
  const configPath = path.join(cliHookDir, 'config.json');
280
542
  if (!fs.existsSync(configPath)) {
281
543
  return { valid: false, error: 'Configuration file not found' };
282
544
  }
283
-
545
+
284
546
  const hookPath = path.join(cliHookDir, `${cliName}_nodejs_hook.js`);
285
547
  if (!fs.existsSync(hookPath)) {
286
548
  return { valid: false, error: 'Hook script not found' };
287
549
  }
288
-
550
+
289
551
  // Try to load the hook
290
552
  try {
291
553
  require(hookPath);
@@ -16,11 +16,11 @@ class StatisticsCollector {
16
16
  cross_cli_calls: 0,
17
17
  successful_calls: 0,
18
18
  failed_calls: 0,
19
- adapter_loads: 0
19
+ adapter_loads: 0,
20
20
  };
21
21
  this.timings = {
22
22
  execution_times: [],
23
- last_reset: Date.now()
23
+ last_reset: Date.now(),
24
24
  };
25
25
  }
26
26
 
@@ -41,7 +41,7 @@ class StatisticsCollector {
41
41
  calls: this.counters.cross_cli_calls,
42
42
  successRate: this.calculateSuccessRate(),
43
43
  averageExecutionTime: this.calculateAverageExecutionTime(),
44
- uptime: Date.now() - this.startTime
44
+ uptime: Date.now() - this.startTime,
45
45
  };
46
46
  }
47
47
 
@@ -50,9 +50,9 @@ class StatisticsCollector {
50
50
  counters: this.counters,
51
51
  timings: {
52
52
  ...this.timings,
53
- averageExecutionTime: this.calculateAverageExecutionTime()
53
+ averageExecutionTime: this.calculateAverageExecutionTime(),
54
54
  },
55
- uptime: Date.now() - this.startTime
55
+ uptime: Date.now() - this.startTime,
56
56
  };
57
57
  }
58
58
 
@@ -68,4 +68,4 @@ class StatisticsCollector {
68
68
  }
69
69
  }
70
70
 
71
- module.exports = StatisticsCollector;
71
+ module.exports = StatisticsCollector;