stigmergy 1.0.93 → 1.0.95

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 (51) hide show
  1. package/bin/stigmergy +26 -12
  2. package/bin/stigmergy.cmd +1 -1
  3. package/docs/HASH_TABLE.md +83 -0
  4. package/docs/WEATHER_PROCESSOR_API.md +230 -0
  5. package/docs/best_practices.md +135 -0
  6. package/docs/development_guidelines.md +392 -0
  7. package/docs/requirements_specification.md +148 -0
  8. package/docs/system_design.md +314 -0
  9. package/docs/tdd_implementation_plan.md +384 -0
  10. package/docs/test_report.md +49 -0
  11. package/examples/calculator-example.js +72 -0
  12. package/examples/json-validation-example.js +64 -0
  13. package/examples/rest-client-example.js +52 -0
  14. package/package.json +21 -17
  15. package/scripts/post-deployment-config.js +9 -2
  16. package/src/auth.js +171 -0
  17. package/src/auth_command.js +195 -0
  18. package/src/calculator.js +220 -0
  19. package/src/core/cli_help_analyzer.js +625 -562
  20. package/src/core/cli_parameter_handler.js +121 -0
  21. package/src/core/cli_tools.js +89 -0
  22. package/src/core/error_handler.js +307 -0
  23. package/src/core/memory_manager.js +76 -0
  24. package/src/core/smart_router.js +133 -0
  25. package/src/deploy.js +50 -0
  26. package/src/main_english.js +643 -720
  27. package/src/main_fixed.js +1035 -0
  28. package/src/utils.js +529 -0
  29. package/src/weatherProcessor.js +205 -0
  30. package/test/calculator.test.js +215 -0
  31. package/test/collision-test.js +26 -0
  32. package/test/csv-processing-test.js +36 -0
  33. package/test/e2e/claude-cli-test.js +128 -0
  34. package/test/e2e/collaboration-test.js +75 -0
  35. package/test/e2e/comprehensive-test.js +431 -0
  36. package/test/e2e/error-handling-test.js +90 -0
  37. package/test/e2e/individual-tool-test.js +143 -0
  38. package/test/e2e/other-cli-test.js +130 -0
  39. package/test/e2e/qoder-cli-test.js +128 -0
  40. package/test/e2e/run-e2e-tests.js +73 -0
  41. package/test/e2e/test-data.js +88 -0
  42. package/test/e2e/test-utils.js +222 -0
  43. package/test/hash-table-demo.js +33 -0
  44. package/test/hash-table-test.js +26 -0
  45. package/test/json-validation-test.js +164 -0
  46. package/test/rest-client-test.js +56 -0
  47. package/test/unit/calculator-full.test.js +191 -0
  48. package/test/unit/calculator-simple.test.js +96 -0
  49. package/test/unit/calculator.test.js +97 -0
  50. package/test/unit/cli_parameter_handler.test.js +116 -0
  51. package/test/weather-processor.test.js +104 -0
@@ -3,7 +3,7 @@
3
3
  /**
4
4
  * Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System
5
5
  * International Version - Pure English & ANSI Only
6
- * Version: 1.0.90
6
+ * Version: 1.0.94
7
7
  */
8
8
 
9
9
  console.log('[DEBUG] Stigmergy CLI script started...');
@@ -12,117 +12,16 @@ const { spawn, spawnSync } = require('child_process');
12
12
  const path = require('path');
13
13
  const fs = require('fs/promises');
14
14
  const os = require('os');
15
+ const { Command } = require('commander');
16
+ const inquirer = require('inquirer');
17
+ const chalk = require('chalk');
18
+ const yaml = require('js-yaml');
15
19
 
16
- // AI CLI Tools Configuration
17
- const CLI_TOOLS = {
18
- claude: {
19
- name: 'Claude CLI',
20
- version: 'claude --version',
21
- install: 'npm install -g @anthropic-ai/claude-cli',
22
- hooksDir: path.join(os.homedir(), '.claude', 'hooks'),
23
- config: path.join(os.homedir(), '.claude', 'config.json')
24
- },
25
- gemini: {
26
- name: 'Gemini CLI',
27
- version: 'gemini --version',
28
- install: 'npm install -g @google/generative-ai-cli',
29
- hooksDir: path.join(os.homedir(), '.gemini', 'extensions'),
30
- config: path.join(os.homedir(), '.gemini', 'config.json')
31
- },
32
- qwen: {
33
- name: 'Qwen CLI',
34
- version: 'qwen --version',
35
- install: 'npm install -g @alibaba/qwen-cli',
36
- hooksDir: path.join(os.homedir(), '.qwen', 'hooks'),
37
- config: path.join(os.homedir(), '.qwen', 'config.json')
38
- },
39
- iflow: {
40
- name: 'iFlow CLI',
41
- version: 'iflow --version',
42
- install: 'npm install -g iflow-cli',
43
- hooksDir: path.join(os.homedir(), '.iflow', 'hooks'),
44
- config: path.join(os.homedir(), '.iflow', 'config.json')
45
- },
46
- qodercli: {
47
- name: 'Qoder CLI',
48
- version: 'qodercli --version',
49
- install: 'npm install -g @qoder-ai/qodercli',
50
- hooksDir: path.join(os.homedir(), '.qoder', 'hooks'),
51
- config: path.join(os.homedir(), '.qoder', 'config.json')
52
- },
53
- codebuddy: {
54
- name: 'CodeBuddy CLI',
55
- version: 'codebuddy --version',
56
- install: 'npm install -g codebuddy-cli',
57
- hooksDir: path.join(os.homedir(), '.codebuddy', 'hooks'),
58
- config: path.join(os.homedir(), '.codebuddy', 'config.json')
59
- },
60
- copilot: {
61
- name: 'GitHub Copilot CLI',
62
- version: 'copilot --version',
63
- install: 'npm install -g @github/copilot-cli',
64
- hooksDir: path.join(os.homedir(), '.copilot', 'mcp'),
65
- config: path.join(os.homedir(), '.copilot', 'config.json')
66
- },
67
- codex: {
68
- name: 'OpenAI Codex CLI',
69
- version: 'codex --version',
70
- install: 'npm install -g openai-codex-cli',
71
- hooksDir: path.join(os.homedir(), '.config', 'codex', 'slash_commands'),
72
- config: path.join(os.homedir(), '.codex', 'config.json')
73
- }
74
- };
75
-
76
- class SmartRouter {
77
- constructor() {
78
- this.tools = CLI_TOOLS;
79
- this.routeKeywords = ['use', 'help', 'please', 'write', 'generate', 'explain', 'analyze', 'translate', 'code', 'article'];
80
- this.defaultTool = 'claude';
81
- }
82
-
83
- shouldRoute(userInput) {
84
- return this.routeKeywords.some(keyword =>
85
- userInput.toLowerCase().includes(keyword.toLowerCase())
86
- );
87
- }
88
-
89
- smartRoute(userInput) {
90
- const input = userInput.trim();
91
-
92
- // Detect tool-specific keywords
93
- for (const [toolName, toolInfo] of Object.entries(this.tools)) {
94
- for (const keyword of this.extractKeywords(toolName)) {
95
- if (input.toLowerCase().includes(keyword.toLowerCase())) {
96
- // Extract clean parameters
97
- const cleanInput = input
98
- .replace(new RegExp(`.*${keyword}\\s*`, 'gi'), '')
99
- .replace(/^(use|please|help|using|with)\s*/i, '')
100
- .trim();
101
- return { tool: toolName, prompt: cleanInput };
102
- }
103
- }
104
- }
105
-
106
- // Default routing
107
- const cleanInput = input.replace(/^(use|please|help|using|with)\s*/i, '').trim();
108
- return { tool: this.defaultTool, prompt: cleanInput };
109
- }
110
-
111
- extractKeywords(toolName) {
112
- const keywords = {
113
- claude: ['claude', 'anthropic'],
114
- gemini: ['gemini', 'google'],
115
- qwen: ['qwen', 'alibaba', 'tongyi'],
116
- iflow: ['iflow', 'workflow', 'intelligent'],
117
- qodercli: ['qoder', 'code'],
118
- codebuddy: ['codebuddy', 'buddy', 'assistant'],
119
- copilot: ['copilot', 'github', 'gh'],
120
- codex: ['codex', 'openai', 'gpt']
121
- };
122
-
123
- return keywords[toolName] || [toolName];
124
- }
125
- }
20
+ // Import our custom modules
21
+ const SmartRouter = require('./core/smart_router');
22
+ const CLIHelpAnalyzer = require('./core/cli_help_analyzer');
23
+ const { CLI_TOOLS } = require('./core/cli_tools');
24
+ const { errorHandler } = require('./core/error_handler');
126
25
 
127
26
  class MemoryManager {
128
27
  constructor() {
@@ -139,11 +38,15 @@ class MemoryManager {
139
38
  duration: Date.now() - new Date().getTime()
140
39
  };
141
40
 
142
- // Add to global memory
143
- await this.saveGlobalMemory(interaction);
41
+ try {
42
+ // Add to global memory
43
+ await this.saveGlobalMemory(interaction);
144
44
 
145
- // Add to project memory
146
- await this.saveProjectMemory(interaction);
45
+ // Add to project memory
46
+ await this.saveProjectMemory(interaction);
47
+ } catch (error) {
48
+ await errorHandler.logError(error, 'ERROR', 'MemoryManager.addInteraction');
49
+ }
147
50
  }
148
51
 
149
52
  async saveGlobalMemory(interaction) {
@@ -155,6 +58,7 @@ class MemoryManager {
155
58
  await fs.mkdir(path.dirname(this.globalMemoryFile), { recursive: true });
156
59
  await fs.writeFile(this.globalMemoryFile, JSON.stringify(memory, null, 2));
157
60
  } catch (error) {
61
+ await errorHandler.logError(error, 'ERROR', 'MemoryManager.saveGlobalMemory');
158
62
  console.error(`[MEMORY] Failed to save global memory: ${error.message}`);
159
63
  }
160
64
  }
@@ -167,6 +71,7 @@ class MemoryManager {
167
71
 
168
72
  await fs.writeFile(this.projectMemoryFile, this.formatProjectMemory(memory));
169
73
  } catch (error) {
74
+ await errorHandler.logError(error, 'ERROR', 'MemoryManager.saveProjectMemory');
170
75
  console.error(`[MEMORY] Failed to save project memory: ${error.message}`);
171
76
  }
172
77
  }
@@ -252,61 +157,23 @@ class StigmergyInstaller {
252
157
  { args: ['-h'], expected: 0 },
253
158
  // Method 4: Try just the command (help case)
254
159
  { args: [], expected: 0 },
255
- // Method 5: Try version with alternative format
256
- { args: ['version'], expected: 0 }
257
160
  ];
258
161
 
259
162
  for (const check of checks) {
260
163
  try {
261
164
  const result = spawnSync(toolName, check.args, {
262
165
  encoding: 'utf8',
263
- timeout: 8000,
264
- stdio: 'pipe'
166
+ timeout: 5000,
167
+ shell: true
265
168
  });
266
169
 
267
- // Check if command exists and runs (exit 0 or shows help)
268
- if (result.status === 0 || result.stdout.includes(toolName) || result.stderr.includes(toolName)) {
269
- return true;
270
- }
271
-
272
- // Also check if command exists but returns non-zero (some CLIs do this)
273
- if (result.error === undefined && (result.stdout.length > 0 || result.stderr.length > 0)) {
274
- const output = (result.stdout + result.stderr).toLowerCase();
275
- if (output.includes(toolName) || output.includes('cli') || output.includes('ai') || output.includes('help')) {
276
- return true;
277
- }
278
- }
279
- } catch (error) {
280
- // Command not found, continue to next check
281
- continue;
282
- }
283
- }
284
-
285
- // Method 6: Check if command exists in PATH using `which`/`where` (platform specific)
286
- try {
287
- const whichCmd = process.platform === 'win32' ? 'where' : 'which';
288
- const result = spawnSync(whichCmd, [toolName], {
289
- encoding: 'utf8',
290
- timeout: 5000
291
- });
292
-
293
- if (result.status === 0 && result.stdout.trim().length > 0) {
294
- // Found in PATH
295
- return true;
296
- }
297
- } catch (error) {
298
- // Continue
299
- }
300
-
301
- // Method 7: Check common installation paths
302
- const commonPaths = this.getCommonCLIPaths(toolName);
303
- for (const cliPath of commonPaths) {
304
- try {
305
- if (await this.fileExists(cliPath)) {
306
- // Found at specific path
170
+ // Check if command executed successfully or at least didn't fail with "command not found"
171
+ if (result.status === check.expected ||
172
+ (result.status !== 127 && result.status !== 9009)) { // 127 = command not found on Unix, 9009 = command not found on Windows
307
173
  return true;
308
174
  }
309
175
  } catch (error) {
176
+ // Continue to next check method
310
177
  continue;
311
178
  }
312
179
  }
@@ -314,223 +181,51 @@ class StigmergyInstaller {
314
181
  return false;
315
182
  }
316
183
 
317
- getCommonCLIPaths(toolName) {
318
- const homeDir = os.homedir();
319
- const paths = [];
320
-
321
- // Add platform-specific paths
322
- if (process.platform === 'win32') {
323
- // Local and global npm paths
324
- paths.push(
325
- path.join(homeDir, 'AppData', 'Roaming', 'npm', `${toolName}.cmd`),
326
- path.join(homeDir, 'AppData', 'Roaming', 'npm', `${toolName}.ps1`),
327
- path.join(homeDir, 'AppData', 'Local', 'npm', `${toolName}.cmd`),
328
- path.join(homeDir, 'AppData', 'Local', 'npm', `${toolName}.ps1`),
329
- // Program Files
330
- path.join(process.env.ProgramFiles || 'C:\\Program Files', `${toolName}`, `${toolName}.exe`),
331
- path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', `${toolName}`, `${toolName}.exe`),
332
- // Node.js global packages
333
- path.join(homeDir, '.npm', `${toolName}.cmd`),
334
- path.join(homeDir, '.npm', `${toolName}.js`),
335
- // User directories
336
- path.join(homeDir, `${toolName}.cmd`),
337
- path.join(homeDir, `${toolName}.exe`),
338
- // Custom test directories
339
- path.join(homeDir, '.stigmergy-test', `${toolName}.cmd`),
340
- path.join(homeDir, '.stigmergy-test', `${toolName}.js`)
341
- );
342
- } else {
343
- paths.push(
344
- // Global npm paths
345
- path.join(homeDir, '.npm', 'global', 'bin', toolName),
346
- path.join(homeDir, '.npm', 'global', 'bin', `${toolName}.js`),
347
- // Local npm paths
348
- path.join(homeDir, '.npm', 'bin', toolName),
349
- path.join(homeDir, '.local', 'bin', toolName),
350
- path.join(homeDir, '.local', 'bin', `${toolName}.js`),
351
- // System paths
352
- path.join('/usr', 'local', 'bin', toolName),
353
- path.join('/usr', 'local', 'bin', `${toolName}.js`),
354
- path.join('/usr', 'bin', toolName),
355
- path.join('/usr', 'bin', `${toolName}.js`),
356
- // User home
357
- path.join(homeDir, '.local', 'bin', toolName),
358
- path.join(homeDir, '.local', 'bin', `${toolName}.js`),
359
- // Custom test directories
360
- path.join(homeDir, '.stigmergy-test', toolName),
361
- path.join(homeDir, '.stigmergy-test', `${toolName}.js`)
362
- );
363
- }
364
-
365
- // Add NPM global bin directory
366
- try {
367
- const { spawnSync } = require('child_process');
368
- const npmRoot = spawnSync('npm', ['root', '-g'], { encoding: 'utf8' }).stdout.trim();
369
- if (npmRoot) {
370
- paths.push(path.join(npmRoot, 'bin', toolName));
371
- paths.push(path.join(npmRoot, `${toolName}.js`));
372
- paths.push(path.join(npmRoot, `${toolName}.cmd`));
373
- }
374
- } catch (error) {
375
- // Continue
376
- }
377
-
378
- return paths;
379
- }
380
-
381
- async fileExists(filePath) {
382
- try {
383
- await fs.access(filePath);
384
- return true;
385
- } catch {
386
- return false;
387
- }
388
- }
389
-
390
184
  async scanCLI() {
391
- console.log('[SCAN] Scanning for AI CLI tools on your system...');
392
- console.log('='.repeat(60));
393
-
185
+ console.log('[SCAN] Scanning for AI CLI tools...');
394
186
  const available = {};
395
187
  const missing = {};
396
188
 
397
189
  for (const [toolName, toolInfo] of Object.entries(this.router.tools)) {
398
- const isAvailable = await this.checkCLI(toolName);
399
-
400
- if (isAvailable) {
401
- available[toolName] = toolInfo;
402
- console.log(`[OK] ${toolInfo.name}: Available`);
403
- } else {
190
+ try {
191
+ console.log(`[SCAN] Checking ${toolInfo.name}...`);
192
+ const isAvailable = await this.checkCLI(toolName);
193
+
194
+ if (isAvailable) {
195
+ console.log(`[OK] ${toolInfo.name} is available`);
196
+ available[toolName] = toolInfo;
197
+ } else {
198
+ console.log(`[MISSING] ${toolInfo.name} is not installed`);
199
+ missing[toolName] = toolInfo;
200
+ }
201
+ } catch (error) {
202
+ await errorHandler.logError(error, 'WARN', `StigmergyInstaller.scanCLI.${toolName}`);
203
+ console.log(`[ERROR] Failed to check ${toolInfo.name}: ${error.message}`);
404
204
  missing[toolName] = toolInfo;
405
- console.log(`[X] ${toolInfo.name}: Not Available`);
406
205
  }
407
206
  }
408
207
 
409
- console.log('='.repeat(60));
410
- console.log(`[SUMMARY] ${Object.keys(available).length}/${Object.keys(this.router.tools).length} tools available`);
411
-
412
208
  return { available, missing };
413
209
  }
414
210
 
415
- async showInstallOptions(missing, isNonInteractive = false) {
416
- if (Object.keys(missing).length === 0) {
417
- console.log('[INFO] All AI CLI tools are already installed!');
418
- return [];
419
- }
420
-
421
- console.log('\n[INSTALL] The following AI CLI tools can be automatically installed:\n');
422
-
423
- const options = [];
424
- let index = 1;
425
-
426
- for (const [toolName, toolInfo] of Object.entries(missing)) {
427
- console.log(` ${index}. ${toolInfo.name}`);
428
- console.log(` Install: ${toolInfo.install}`);
429
- options.push({ index, toolName, toolInfo });
430
- index++;
431
- }
432
-
433
- if (isNonInteractive) {
434
- console.log('\n[INFO] Non-interactive mode detected. Skipping automatic installation.');
435
- console.log('[INFO] To install these tools manually, run: stigmergy install');
436
- return [];
437
- }
438
-
439
- console.log('\n[OPTIONS] Installation Options:');
440
- console.log('- Enter numbers separated by spaces (e.g: 1 3 5)');
441
- console.log('- Enter "all" to install all missing tools');
442
- console.log('- Enter "skip" to skip CLI installation');
443
-
444
- return options;
445
- }
446
-
447
- async getUserSelection(options, missing) {
448
- if (options.length === 0) {
449
- return [];
450
- }
211
+ async installTools(selectedTools, missingTools) {
212
+ console.log(`\n[INSTALL] Installing ${selectedTools.length} AI CLI tools...`);
451
213
 
452
- try {
453
- const inquirer = require('inquirer');
454
-
455
- const choices = options.map(opt => ({
456
- name: `${opt.toolInfo.name} - ${opt.toolInfo.install}`,
457
- value: opt.toolName
458
- }));
459
-
460
- choices.push(new inquirer.Separator(' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ='),
461
- { name: 'All missing tools', value: 'all' },
462
- { name: 'Skip installation', value: 'skip' });
463
-
464
- const answers = await inquirer.prompt([
465
- {
466
- type: 'checkbox',
467
- name: 'selectedTools',
468
- message: 'Select tools to install (Space to select, Enter to confirm):',
469
- choices: choices,
470
- validate: function (answer) {
471
- if (answer.length < 1) {
472
- return 'You must choose at least one option.';
473
- }
474
- return true;
475
- }
476
- }
477
- ]);
478
-
479
- if (answers.selectedTools.includes('skip')) {
480
- console.log('[INFO] Skipping CLI tool installation');
481
- return [];
482
- } else {
483
- let toolsToInstall;
484
- if (answers.selectedTools.includes('all')) {
485
- toolsToInstall = options;
486
- } else {
487
- toolsToInstall = options.filter(opt => answers.selectedTools.includes(opt.toolName));
488
- }
489
- return toolsToInstall;
214
+ for (const toolName of selectedTools) {
215
+ const toolInfo = missingTools[toolName];
216
+ if (!toolInfo) {
217
+ console.log(`[SKIP] Tool ${toolName} not found in missing tools list`);
218
+ continue;
490
219
  }
491
- } catch (error) {
492
- console.log('[ERROR] Interactive selection failed:', error.message);
493
- console.log('[INFO] Skipping CLI tool installation due to input error');
494
- console.log('[INFO] To install tools manually, run: stigmergy install');
495
- return [];
496
- }
497
- }
498
-
499
- async installTools(selectedTools, missing) {
500
- if (!selectedTools || selectedTools.length === 0) {
501
- console.log('[INFO] Skipping CLI tool installation');
502
- return true;
503
- }
504
-
505
- console.log('\n[INSTALL] Installing selected AI CLI tools...');
506
-
507
- for (const selection of selectedTools) {
508
- const { toolName, toolInfo } = selection;
509
- console.log(`\n[INSTALLING] ${toolInfo.name}...`);
510
220
 
511
221
  try {
512
- const installCmd = toolInfo.install.split(' ');
513
- console.log(`[DEBUG] Installing ${toolInfo.name} with command: ${toolInfo.install}`);
514
-
515
- // Try with shell=true first (works better on Windows)
516
- let result = spawnSync(installCmd[0], installCmd.slice(1), {
517
- encoding: 'utf8',
518
- timeout: 300000, // Increased to 5 minutes for CLI tools that download binaries
519
- stdio: 'inherit',
520
- env: process.env,
521
- shell: true
522
- });
222
+ console.log(`\n[INSTALL] Installing ${toolInfo.name}...`);
223
+ console.log(`[CMD] ${toolInfo.install}`);
523
224
 
524
- // If shell=true fails, try without shell
525
- if (result.status !== 0 && result.status !== null) {
526
- console.log(`[DEBUG] Shell execution failed, trying without shell...`);
527
- result = spawnSync(installCmd[0], installCmd.slice(1), {
528
- encoding: 'utf8',
529
- timeout: 300000,
530
- stdio: 'inherit',
531
- env: process.env
532
- });
533
- }
225
+ const result = spawnSync(toolInfo.install, {
226
+ shell: true,
227
+ stdio: 'inherit'
228
+ });
534
229
 
535
230
  if (result.status === 0) {
536
231
  console.log(`[OK] ${toolInfo.name} installed successfully`);
@@ -542,6 +237,7 @@ class StigmergyInstaller {
542
237
  console.log(`[INFO] Please run manually: ${toolInfo.install}`);
543
238
  }
544
239
  } catch (error) {
240
+ await errorHandler.logError(error, 'ERROR', `StigmergyInstaller.installTools.${toolName}`);
545
241
  console.log(`[ERROR] Failed to install ${toolInfo.name}: ${error.message}`);
546
242
  console.log(`[INFO] Please run manually: ${toolInfo.install}`);
547
243
  }
@@ -585,168 +281,174 @@ class StigmergyInstaller {
585
281
  if (await this.fileExists(adaptersDir)) {
586
282
  await fs.mkdir(localAdaptersDir, { recursive: true });
587
283
 
588
- // Copy adapter files recursively
589
- await this.copyDirectory(adaptersDir, localAdaptersDir);
590
- console.log(`[OK] Copied CLI adapters to ${localAdaptersDir}`);
284
+ // Copy all adapter directories
285
+ const adapterDirs = await fs.readdir(adaptersDir);
286
+ for (const dir of adapterDirs) {
287
+ // Skip non-directory items
288
+ const dirPath = path.join(adaptersDir, dir);
289
+ const stat = await fs.stat(dirPath);
290
+ if (!stat.isDirectory()) continue;
291
+
292
+ // Skip __pycache__ directories
293
+ if (dir === '__pycache__') continue;
294
+
295
+ const dstPath = path.join(localAdaptersDir, dir);
296
+ await this.copyDirectory(dirPath, dstPath);
297
+ console.log(`[OK] Copied adapter: ${dir}`);
298
+ }
591
299
  }
592
300
 
593
- console.log('[OK] Required assets downloaded successfully');
301
+ console.log('[OK] All required assets downloaded successfully');
594
302
  return true;
303
+
595
304
  } catch (error) {
596
- console.log(`[ERROR] Failed to download assets: ${error.message}`);
305
+ await errorHandler.logError(error, 'ERROR', 'StigmergyInstaller.downloadRequiredAssets');
306
+ console.log(`[ERROR] Failed to download required assets: ${error.message}`);
597
307
  return false;
598
308
  }
599
309
  }
600
-
601
- // Safety check to prevent conflicts with other CLI tools
310
+
602
311
  async safetyCheck() {
603
- console.log('[SAFETY] Running conflict prevention check...');
312
+ console.log('\n[SAFETY] Performing safety check for conflicting packages...');
604
313
 
314
+ // List of potentially conflicting packages
315
+ const conflictingPackages = [
316
+ '@aws-amplify/cli',
317
+ 'firebase-tools',
318
+ 'heroku',
319
+ 'netlify-cli',
320
+ 'vercel',
321
+ 'surge',
322
+ 'now'
323
+ ];
324
+
325
+ // Check for globally installed conflicting packages
605
326
  try {
606
- // Check for problematic node package
607
- const npmNodeModules = path.join(os.homedir(), 'AppData', 'Roaming', 'npm', 'node_modules');
608
- const nodePackageDir = path.join(npmNodeModules, 'node');
609
-
610
- try {
611
- await fs.access(nodePackageDir);
612
- console.warn('[WARNING] Conflicting "node" package detected!');
613
- console.warn('[WARNING] This may interfere with other CLI tools.');
614
- console.warn('[WARNING] Consider running: npm uninstall -g node');
615
- } catch (error) {
616
- // Package doesn't exist, that's good
617
- }
618
-
619
- // Check for broken node executable
620
- const npmDir = path.join(os.homedir(), 'AppData', 'Roaming', 'npm');
621
- const nodeExecutable = path.join(npmDir, 'node');
327
+ const result = spawnSync('npm', ['list', '-g', '--depth=0'], {
328
+ encoding: 'utf8',
329
+ timeout: 10000
330
+ });
622
331
 
623
- try {
624
- await fs.access(nodeExecutable);
625
- const content = await fs.readFile(nodeExecutable, 'utf8');
626
- if (content.includes('intentionally left blank') ||
627
- content.includes('node_modules/node/bin/node')) {
628
- console.warn('[WARNING] Broken node executable detected!');
629
- console.warn('[WARNING] This will break other CLI tools.');
630
- console.warn('[WARNING] Consider running: npm run fix-node-conflict');
332
+ if (result.status === 0) {
333
+ const installedPackages = result.stdout;
334
+ const conflicts = [];
335
+
336
+ for (const pkg of conflictingPackages) {
337
+ if (installedPackages.includes(pkg)) {
338
+ conflicts.push(pkg);
339
+ }
340
+ }
341
+
342
+ if (conflicts.length > 0) {
343
+ console.log(`[WARN] Potential conflicting packages detected: ${conflicts.join(', ')}`);
344
+ console.log('[INFO] These packages may interfere with Stigmergy CLI functionality');
345
+ } else {
346
+ console.log('[OK] No conflicting packages detected');
631
347
  }
632
- } catch (error) {
633
- // File doesn't exist, that's fine
634
348
  }
635
-
636
- console.log('[SAFETY] Check completed.');
637
349
  } catch (error) {
638
- console.log('[SAFETY] Could not complete safety check:', error.message);
350
+ console.log(`[WARN] Unable to perform safety check: ${error.message}`);
639
351
  }
640
352
  }
641
353
 
642
- async copyDirectory(src, dst) {
643
- await fs.mkdir(dst, { recursive: true });
644
- const entries = await fs.readdir(src, { withFileTypes: true });
354
+ async copyDirectory(src, dest) {
355
+ try {
356
+ await fs.mkdir(dest, { recursive: true });
357
+ const entries = await fs.readdir(src, { withFileTypes: true });
645
358
 
646
- for (const entry of entries) {
647
- const srcPath = path.join(src, entry.name);
648
- const dstPath = path.join(dst, entry.name);
359
+ for (const entry of entries) {
360
+ const srcPath = path.join(src, entry.name);
361
+ const destPath = path.join(dest, entry.name);
649
362
 
650
- if (entry.isDirectory()) {
651
- await this.copyDirectory(srcPath, dstPath);
652
- } else {
653
- await fs.copyFile(srcPath, dstPath);
363
+ if (entry.isDirectory()) {
364
+ // Skip __pycache__ directories
365
+ if (entry.name === '__pycache__') continue;
366
+ await this.copyDirectory(srcPath, destPath);
367
+ } else {
368
+ await fs.copyFile(srcPath, destPath);
369
+ }
654
370
  }
371
+ } catch (error) {
372
+ await errorHandler.logError(error, 'WARN', 'StigmergyInstaller.copyDirectory');
373
+ console.log(`[WARN] Failed to copy directory ${src} to ${dest}: ${error.message}`);
655
374
  }
656
375
  }
657
376
 
658
- async deployProjectDocumentation() {
659
- console.log('\n[DEPLOY] Deploying project documentation...');
660
-
377
+ async fileExists(filePath) {
661
378
  try {
662
- const projectDir = process.cwd();
663
- const assetsTemplatesDir = path.join(os.homedir(), '.stigmergy', 'assets', 'templates');
664
-
665
- if (!(await this.fileExists(assetsTemplatesDir))) {
666
- console.log('[SKIP] No template files found');
667
- return true;
668
- }
669
-
670
- const templateFiles = await fs.readdir(assetsTemplatesDir);
671
- let deployedCount = 0;
672
-
673
- for (const templateFile of templateFiles) {
674
- if (templateFile.endsWith('.j2')) {
675
- const dstFileName = templateFile.replace('.j2', '');
676
- const dstPath = path.join(projectDir, dstFileName);
677
-
678
- // Read template and substitute variables
679
- const templateContent = await fs.readFile(path.join(assetsTemplatesDir, templateFile), 'utf8');
680
- const processedContent = this.substituteTemplateVariables(templateContent);
681
-
682
- await fs.writeFile(dstPath, processedContent);
683
- console.log(`[OK] Deployed project doc: ${dstFileName}`);
684
- deployedCount++;
685
- }
686
- }
687
-
688
- console.log(`[RESULT] ${deployedCount} project documentation files deployed`);
379
+ await fs.access(filePath);
689
380
  return true;
690
- } catch (error) {
691
- console.log(`[ERROR] Failed to deploy project documentation: ${error.message}`);
381
+ } catch {
692
382
  return false;
693
383
  }
694
384
  }
695
385
 
696
- substituteTemplateVariables(content) {
697
- const now = new Date();
698
- const projectName = path.basename(process.cwd());
699
-
700
- const variables = {
701
- '{{PROJECT_NAME}}': projectName,
702
- '{{PROJECT_TYPE}}': 'Node.js Project',
703
- '{{TECH_STACK}}': 'Node.js, JavaScript, TypeScript',
704
- '{{CREATED_DATE}}': now.toISOString(),
705
- '{{LAST_UPDATED}}': now.toISOString(),
706
- '{{GENERATION_TIME}}': now.toLocaleString(),
707
- '{{CODE_STYLE}}': 'ESLint + Prettier',
708
- '{{TEST_FRAMEWORK}}': 'Jest',
709
- '{{BUILD_TOOL}}': 'npm',
710
- '{{DEPLOY_METHOD}}': 'npm publish',
711
- '{{PRIMARY_LANGUAGE}}': 'English',
712
- '{{TARGET_LANGUAGES}}': 'Chinese, Japanese, Spanish',
713
- '{{DOC_STYLE}}': 'Markdown',
714
- '{{OUTPUT_FORMAT}}': 'Markdown',
715
- '{{RECENT_CHANGES}}': 'No recent changes recorded',
716
- '{{KNOWN_ISSUES}}': 'No known issues',
717
- '{{TODO_ITEMS}}': 'No todo items',
718
- '{{TEAM_PREFERENCES}}': 'Standard development practices',
719
- '{{TRANSLATION_PREFERENCES}}': 'Technical accuracy first',
720
- '{{DOC_STANDARDS}}': 'Markdown with code examples',
721
- '{{ANALYSIS_TEMPLATES}}': 'Standard analysis templates',
722
- '{{COMMON_LANGUAGES}}': 'English, Chinese, Japanese',
723
- '{{CHINESE_TERMINOLOGY}}': 'Standard Chinese technical terms',
724
- '{{LOCALIZATION_STANDARDS}}': 'Chinese localization standards',
725
- '{{USER_HABITS}}': 'Chinese user preferences',
726
- '{{COMPLIANCE_REQUIREMENTS}}': 'Local regulations compliance',
727
- '{{CHINESE_DOC_STYLE}}': '简体中文技术文档',
728
- '{{ENCODING_STANDARD}}': 'UTF-8',
729
- '{{TECHNICAL_DOMAIN}}': 'Software Development',
730
- '{{WORKFLOW_ENGINE}}': 'iFlow CLI',
731
- '{{EXECUTION_ENVIRONMENT}}': 'Node.js',
732
- '{{DATA_SOURCES}}': 'Local files, APIs',
733
- '{{OUTPUT_TARGETS}}': 'Files, databases, APIs',
734
- '{{AGENT_COMMUNICATION_PROTOCOL}}': 'JSON-based messaging',
735
- '{{COLLABORATION_MODE}}': 'Sequential and Parallel',
736
- '{{DECISION_MECHANISM}}': 'Consensus-based',
737
- '{{CONFLICT_RESOLUTION}}': 'Expert arbitration',
738
- '{{AGENT_PROFILES}}': 'Default agent configurations',
739
- '{{COLLABORATION_HISTORY}}': 'No history yet',
740
- '{{DECISION_RECORDS}}': 'No decisions recorded yet',
741
- '{{PERFORMANCE_METRICS}}': 'To be collected'
742
- };
743
-
744
- let processedContent = content;
745
- for (const [placeholder, value] of Object.entries(variables)) {
746
- processedContent = processedContent.replace(new RegExp(placeholder.replace(/[{}]/g, '\\$&'), 'g'), value);
386
+ async showInstallOptions(missingTools) {
387
+ if (Object.keys(missingTools).length === 0) {
388
+ console.log('[INFO] All required AI CLI tools are already installed!');
389
+ return [];
747
390
  }
748
-
749
- return processedContent;
391
+
392
+ console.log('\n[INSTALL] Missing AI CLI tools detected:');
393
+ const choices = [];
394
+
395
+ for (const [toolName, toolInfo] of Object.entries(missingTools)) {
396
+ choices.push({
397
+ name: `${toolInfo.name} (${toolName}) - ${toolInfo.install}`,
398
+ value: toolName,
399
+ checked: true
400
+ });
401
+ }
402
+
403
+ const answers = await inquirer.prompt([
404
+ {
405
+ type: 'checkbox',
406
+ name: 'tools',
407
+ message: 'Select which tools to install (Space to select, Enter to confirm):',
408
+ choices: choices,
409
+ pageSize: 10
410
+ }
411
+ ]);
412
+
413
+ return answers.tools;
414
+ }
415
+
416
+ async getUserSelection(options, missingTools) {
417
+ if (options.length === 0) {
418
+ return [];
419
+ }
420
+
421
+ const answers = await inquirer.prompt([
422
+ {
423
+ type: 'confirm',
424
+ name: 'proceed',
425
+ message: `Install ${options.length} missing AI CLI tools?`,
426
+ default: true
427
+ }
428
+ ]);
429
+
430
+ if (answers.proceed) {
431
+ return options;
432
+ }
433
+
434
+ // If user doesn't want to install all, let them choose individually
435
+ const individualChoices = options.map(toolName => ({
436
+ name: missingTools[toolName].name,
437
+ value: toolName,
438
+ checked: true
439
+ }));
440
+
441
+ const individualAnswers = await inquirer.prompt([
442
+ {
443
+ type: 'checkbox',
444
+ name: 'selectedTools',
445
+ message: 'Select which tools to install:',
446
+ choices: individualChoices,
447
+ pageSize: 10
448
+ }
449
+ ]);
450
+
451
+ return individualAnswers.selectedTools;
750
452
  }
751
453
 
752
454
  async deployHooks(available) {
@@ -782,87 +484,144 @@ class StigmergyInstaller {
782
484
  console.log(`[OK] Copied adapter files for ${toolInfo.name}`);
783
485
  }
784
486
 
785
- // NEW: Execute the installation script to complete configuration
786
- console.log(`[CONFIG] Running installation script for ${toolInfo.name}...`);
787
- const installResult = await configurer.configureTool(toolName);
788
- if (installResult.runSuccess) {
789
- console.log(`[OK] ${toolInfo.name} configured successfully`);
487
+ // Execute post-deployment configuration
488
+ try {
489
+ await configurer.configureTool(toolName);
490
+ console.log(`[OK] Post-deployment configuration completed for ${toolInfo.name}`);
790
491
  successCount++;
791
- } else {
792
- console.log(`[WARN] ${toolInfo.name} configuration failed: ${installResult.error || 'Unknown error'}`);
793
- console.log(`[INFO] You can manually configure ${toolInfo.name} later by running the installation script`);
492
+ } catch (configError) {
493
+ await errorHandler.logError(configError, 'WARN', `StigmergyInstaller.deployHooks.${toolName}.config`);
494
+ console.log(`[WARN] Post-deployment configuration failed for ${toolInfo.name}: ${configError.message}`);
495
+ // Continue with other tools even if one fails
794
496
  }
795
497
 
796
- console.log(`[OK] Created directories for ${toolInfo.name}`);
797
- console.log(`[INFO] Hooks directory: ${toolInfo.hooksDir}`);
798
- console.log(`[INFO] Config directory: ${configDir}`);
799
498
  } catch (error) {
499
+ await errorHandler.logError(error, 'ERROR', `StigmergyInstaller.deployHooks.${toolName}`);
800
500
  console.log(`[ERROR] Failed to deploy hooks for ${toolInfo.name}: ${error.message}`);
801
- console.log(`[INFO] You can manually deploy hooks for ${toolInfo.name} later by running: stigmergy deploy`);
501
+ console.log('[INFO] Continuing with other tools...');
802
502
  }
803
503
  }
804
504
 
805
- console.log(`\n[SUMMARY] Hook deployment completed: ${successCount}/${totalCount} tools configured successfully`);
806
-
807
- if (successCount < totalCount) {
808
- console.log(`[INFO] ${totalCount - successCount} tools failed to configure. See warnings above for details.`);
809
- console.log(`[INFO] Run 'stigmergy deploy' to retry configuration for failed tools.`);
505
+ console.log(`\n[SUMMARY] Hook deployment completed: ${successCount}/${totalCount} tools successful`);
506
+ }
507
+
508
+ async deployProjectDocumentation() {
509
+ console.log('\n[DEPLOY] Deploying project documentation...');
510
+
511
+ try {
512
+ // Create standard project documentation files
513
+ const docs = {
514
+ 'STIGMERGY.md': this.generateProjectMemoryTemplate(),
515
+ 'README.md': this.generateProjectReadme()
516
+ };
517
+
518
+ for (const [filename, content] of Object.entries(docs)) {
519
+ const filepath = path.join(process.cwd(), filename);
520
+ if (!(await this.fileExists(filepath))) {
521
+ await fs.writeFile(filepath, content);
522
+ console.log(`[OK] Created ${filename}`);
523
+ }
524
+ }
525
+
526
+ console.log('[OK] Project documentation deployed successfully');
527
+ } catch (error) {
528
+ console.log(`[ERROR] Failed to deploy project documentation: ${error.message}`);
810
529
  }
811
-
812
- return successCount > 0; // Return true if at least one tool was configured successfully
530
+ }
531
+
532
+ generateProjectMemoryTemplate() {
533
+ return `# Stigmergy Project Memory
534
+
535
+ ## Project Information
536
+ - **Project Name**: ${path.basename(process.cwd())}
537
+ - **Created**: ${new Date().toISOString()}
538
+ - **Stigmergy Version**: 1.0.94
539
+
540
+ ## Usage Instructions
541
+ This file automatically tracks all interactions with AI CLI tools through the Stigmergy system.
542
+
543
+ ## Recent Interactions
544
+ No interactions recorded yet.
545
+
546
+ ## Collaboration History
547
+ No collaboration history yet.
548
+
549
+ ---
550
+ *This file is automatically managed by Stigmergy CLI*
551
+ *Last updated: ${new Date().toISOString()}*
552
+ `;
553
+ }
554
+
555
+ generateProjectReadme() {
556
+ return `# ${path.basename(process.cwd())}
557
+
558
+ This project uses Stigmergy CLI for AI-assisted development.
559
+
560
+ ## Getting Started
561
+ 1. Install Stigmergy CLI: \`npm install -g stigmergy\`
562
+ 2. Run \`stigmergy setup\` to configure the environment
563
+ 3. Use \`stigmergy call "<your prompt>"\` to interact with AI tools
564
+
565
+ ## Available AI Tools
566
+ - Claude (Anthropic)
567
+ - Qwen (Alibaba)
568
+ - Gemini (Google)
569
+ - And others configured in your environment
570
+
571
+ ## Project Memory
572
+ See [STIGMERGY.md](STIGMERGY.md) for interaction history and collaboration records.
573
+
574
+ ---
575
+ *Generated by Stigmergy CLI*
576
+ `;
813
577
  }
814
578
 
815
579
  async initializeConfig() {
816
580
  console.log('\n[CONFIG] Initializing Stigmergy configuration...');
817
581
 
818
582
  try {
819
- await fs.mkdir(this.configDir, { recursive: true });
583
+ // Create config directory
584
+ const configDir = path.join(os.homedir(), '.stigmergy');
585
+ await fs.mkdir(configDir, { recursive: true });
820
586
 
821
- const configFile = path.join(this.configDir, 'config.json');
587
+ // Create initial configuration
822
588
  const config = {
823
- version: '1.0.93',
589
+ version: '1.0.94',
824
590
  initialized: true,
825
591
  createdAt: new Date().toISOString(),
826
592
  lastUpdated: new Date().toISOString(),
827
593
  defaultCLI: 'claude',
828
594
  enableCrossCLI: true,
829
- enableMemory: true
595
+ enableMemory: true,
596
+ tools: {}
830
597
  };
831
598
 
832
- await fs.writeFile(configFile, JSON.stringify(config, null, 2));
833
- console.log('[OK] Configuration initialized');
834
- console.log(`[INFO] Config file: ${configFile}`);
599
+ // Save configuration
600
+ const configPath = path.join(configDir, 'config.json');
601
+ await fs.writeFile(configPath, JSON.stringify(config, null, 2));
835
602
 
836
- return true;
603
+ console.log('[OK] Configuration initialized successfully');
837
604
  } catch (error) {
838
605
  console.log(`[ERROR] Failed to initialize configuration: ${error.message}`);
839
- return false;
840
606
  }
841
607
  }
842
608
 
843
609
  showUsageInstructions() {
844
- console.log('\n[USAGE] Stigmergy CLI Usage Instructions:');
610
+ console.log('\n' + '='.repeat(60));
611
+ console.log('🎉 Stigmergy CLI Setup Complete!');
845
612
  console.log('='.repeat(60));
846
613
  console.log('');
847
- console.log('1. Check System Status:');
848
- console.log(' stigmergy status');
849
- console.log('');
850
- console.log('2. Check Available Tools:');
851
- console.log(' stigmergy scan');
852
- console.log('');
853
- console.log('3. Start Using AI CLI Collaboration:');
854
- console.log(' stigmergy call claude "help me debug this code"');
855
- console.log(' stigmergy call gemini "generate documentation"');
856
- console.log(' stigmergy call qwen "translate to English"');
614
+ console.log('Next steps:');
615
+ console.log(' 1. Run "stigmergy install" to scan and install AI CLI tools');
616
+ console.log(' 2. Run "stigmergy deploy" to set up cross-CLI integration');
617
+ console.log(' 3. Use "stigmergy call \\"<your prompt>\\"" to start collaborating');
857
618
  console.log('');
858
- console.log('4. Initialize New Projects:');
859
- console.log(' stigmergy init --primary claude');
860
- console.log('');
861
- console.log('[INFO] Documentation:');
862
- console.log(' - Global Config: ~/.stigmergy/config.json');
863
- console.log(' - Project Docs: ./STIGMERGY.md');
864
- console.log(' - GitHub: https://github.com/ptreezh/stigmergy-CLI-Multi-Agents');
619
+ console.log('Example usage:');
620
+ console.log(' stigmergy call "用claude分析项目架构"');
621
+ console.log(' stigmergy call "用qwen写一个hello world程序"');
622
+ console.log(' stigmergy call "用gemini设计数据库表结构"');
865
623
  console.log('');
624
+ console.log('For more information, visit: https://github.com/ptreezh/stigmergy-CLI-Multi-Agents');
866
625
  console.log('[END] Happy collaborating with multiple AI CLI tools!');
867
626
  }
868
627
  }
@@ -870,229 +629,393 @@ class StigmergyInstaller {
870
629
  // Main CLI functionality
871
630
  async function main() {
872
631
  console.log('[DEBUG] Main function called with args:', process.argv);
873
-
874
632
  const args = process.argv.slice(2);
875
633
  const installer = new StigmergyInstaller();
634
+
635
+ try {
636
+ // Handle case when no arguments are provided
637
+ if (args.length === 0) {
638
+ console.log('Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System');
639
+ console.log('Version: 1.0.94');
640
+ console.log('');
641
+ console.log('[SYSTEM] Automated Installation and Deployment System');
642
+ console.log('');
643
+ console.log('Usage: stigmergy [command] [options]');
644
+ console.log('');
645
+ console.log('Commands:');
646
+ console.log(' help, --help Show this help message');
647
+ console.log(' version, --version Show version information');
648
+ console.log(' status Check CLI tools status');
649
+ console.log(' scan Scan for available AI CLI tools');
650
+ console.log(' install Auto-install missing CLI tools');
651
+ console.log(' deploy Deploy hooks and integration to installed tools');
652
+ console.log(' setup Complete setup and configuration');
653
+ console.log(' call "<prompt>" Execute prompt with auto-routed AI CLI');
654
+ console.log('');
655
+ console.log('[WORKFLOW] Automated Workflow:');
656
+ console.log(' 1. npm install -g stigmergy # Install Stigmergy');
657
+ console.log(' 2. stigmergy install # Auto-scan & install CLI tools');
658
+ console.log(' 3. stigmergy setup # Deploy hooks & config');
659
+ console.log(' 4. stigmergy call "<prompt>" # Start collaborating');
660
+ console.log('');
661
+ console.log('[INFO] For first-time setup, run: stigmergy setup');
662
+ console.log('[INFO] To scan and install AI tools, run: stigmergy install');
663
+ console.log('');
664
+ console.log('For more information, visit: https://github.com/ptreezh/stigmergy-CLI-Multi-Agents');
665
+ return;
666
+ }
667
+
668
+ // Handle help commands
669
+ if (args.includes('--help') || args.includes('-h')) {
670
+ console.log('Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System');
671
+ console.log('Version: 1.0.94');
672
+ console.log('');
673
+ console.log('[SYSTEM] Automated Installation and Deployment System');
674
+ console.log('');
675
+ console.log('Usage: stigmergy [command] [options]');
676
+ console.log('');
677
+ console.log('Commands:');
678
+ console.log(' help, --help Show this help message');
679
+ console.log(' version, --version Show version information');
680
+ console.log(' status Check CLI tools status');
681
+ console.log(' scan Scan for available AI CLI tools');
682
+ console.log(' install Auto-install missing CLI tools');
683
+ console.log(' deploy Deploy hooks and integration to installed tools');
684
+ console.log(' setup Complete setup and configuration');
685
+ console.log(' call "<prompt>" Execute prompt with auto-routed AI CLI');
686
+ console.log('');
687
+ console.log('[WORKFLOW] Automated Workflow:');
688
+ console.log(' 1. npm install -g stigmergy # Install Stigmergy');
689
+ console.log(' 2. stigmergy install # Auto-scan & install CLI tools');
690
+ console.log(' 3. stigmergy setup # Deploy hooks & config');
691
+ console.log(' 4. stigmergy call "<prompt>" # Start collaborating');
692
+ console.log('');
693
+ console.log('For more information, visit: https://github.com/ptreezh/stigmergy-CLI-Multi-Agents');
694
+ return;
695
+ }
696
+
697
+ const command = args[0];
698
+ switch (command) {
699
+ case 'version':
700
+ case '--version':
701
+ // Use the version from configuration instead of hardcoding
702
+ const config = {
703
+ version: '1.0.94',
704
+ initialized: true,
705
+ createdAt: new Date().toISOString(),
706
+ lastUpdated: new Date().toISOString(),
707
+ defaultCLI: 'claude',
708
+ enableCrossCLI: true,
709
+ enableMemory: true
710
+ };
711
+ console.log(`Stigmergy CLI v${config.version}`);
712
+ break;
876
713
 
877
- if (args.length === 0 || args.includes('--help') || args.includes('-h')) {
878
- console.log('Stigmergy CLI - Multi-Agents Cross-AI CLI Tools Collaboration System');
879
- console.log('Version: 1.0.90');
880
- console.log('');
881
- console.log('[SYSTEM] Automated Installation and Deployment System');
882
- console.log('');
883
- console.log('Usage: stigmergy [command] [options]');
884
- console.log('');
885
- console.log('Commands:');
886
- console.log(' help, --help Show this help message');
887
- console.log(' version, --version Show version information');
888
- console.log(' status Check CLI tools status');
889
- console.log(' scan Scan for available AI CLI tools');
890
- console.log(' install Auto-install missing CLI tools');
891
- console.log(' deploy Deploy hooks and integration to installed tools');
892
- console.log(' setup Complete setup and configuration');
893
- console.log(' call <tool> Execute prompt with specified or auto-routed AI CLI');
894
- console.log('');
895
- console.log('[WORKFLOW] Automated Workflow:');
896
- console.log(' 1. npm install -g stigmergy # Install Stigmergy');
897
- console.log(' 2. stigmergy install # Auto-scan & install CLI tools');
898
- console.log(' 3. stigmergy setup # Deploy hooks & config');
899
- console.log(' 4. stigmergy call <ai> <prompt> # Start collaborating');
900
- console.log('');
901
- console.log('For more information, visit: https://github.com/ptreezh/stigmergy-CLI-Multi-Agents');
902
- return;
903
- }
904
-
905
- const command = args[0];
906
-
907
- switch (command) {
908
- case 'version':
909
- case '--version':
910
- console.log('Stigmergy CLI v1.0.89');
911
- break;
912
-
913
- case 'status':
914
- const { available, missing } = await installer.scanCLI();
915
- console.log('\n[STATUS] System Status:');
916
- console.log(`Available: ${Object.keys(available).length} tools`);
917
- console.log(`Missing: ${Object.keys(missing).length} tools`);
918
- break;
919
-
920
- case 'scan':
921
- await installer.scanCLI();
922
- break;
923
-
924
- case 'install':
925
- const { missing: missingTools } = await installer.scanCLI();
926
- const options = await installer.showInstallOptions(missingTools);
927
-
928
- if (options.length > 0) {
929
- const selectedTools = await installer.getUserSelection(options, missingTools);
930
- if (selectedTools.length > 0) {
931
- console.log('\n[INFO] Installing selected tools (this may take several minutes for tools that download binaries)...');
932
- await installer.installTools(selectedTools, missingTools);
933
- }
934
- } else {
935
- console.log('\n[INFO] All required tools are already installed!');
936
- }
937
- break;
938
-
939
- case 'deploy':
940
- const { available: deployedTools } = await installer.scanCLI();
941
- await installer.deployHooks(deployedTools);
942
- break;
943
-
944
- case 'setup':
945
- console.log('[SETUP] Starting complete Stigmergy setup...\n');
946
-
947
- // Step 1: Download required assets
948
- await installer.downloadRequiredAssets();
949
-
950
- // Step 2: Scan for CLI tools
951
- const { available: setupAvailable, missing: setupMissing } = await installer.scanCLI();
952
- const setupOptions = await installer.showInstallOptions(setupMissing);
953
-
954
- // Step 3: Install missing CLI tools if user chooses
955
- if (setupOptions.length > 0) {
956
- const selectedTools = await installer.getUserSelection(setupOptions, setupMissing);
957
- if (selectedTools.length > 0) {
958
- console.log('\n[INFO] Installing selected tools (this may take several minutes for tools that download binaries)...');
959
- await installer.installTools(selectedTools, setupMissing);
960
- }
961
- } else {
962
- console.log('\n[INFO] All required tools are already installed!');
963
- }
964
-
965
- // Step 4: Deploy hooks to available CLI tools
966
- await installer.deployHooks(setupAvailable);
967
-
968
- // Step 5: Deploy project documentation
969
- await installer.deployProjectDocumentation();
970
-
971
- // Step 6: Initialize configuration
972
- await installer.initializeConfig();
973
-
974
- // Step 7: Show usage instructions
975
- installer.showUsageInstructions();
976
- break;
977
-
978
- case 'call':
979
- if (args.length < 2) {
980
- console.log('[ERROR] Usage: stigmergy call <tool> "<prompt>"');
981
- process.exit(1);
982
- }
983
-
984
- const targetTool = args[1];
985
- const prompt = args.slice(2).join(' ');
986
-
987
- // Handle call command logic
988
- console.log(`[CALL] Executing with ${targetTool}: ${prompt}`);
989
- // Implementation would go here
990
- break;
991
-
992
- case 'auto-install':
993
- // Auto-install mode for npm postinstall - NON-INTERACTIVE
994
- console.log('[AUTO-INSTALL] Stigmergy CLI automated setup');
995
- console.log('='.repeat(60));
996
-
997
- try {
998
- // Step 1: Download required assets
714
+ case 'status':
999
715
  try {
1000
- console.log('[STEP] Downloading required assets...');
1001
- await installer.downloadRequiredAssets();
1002
- console.log('[OK] Assets downloaded successfully');
716
+ const { available, missing } = await installer.scanCLI();
717
+ console.log('\n[STATUS] AI CLI Tools Status Report');
718
+ console.log('=====================================');
719
+
720
+ if (Object.keys(available).length > 0) {
721
+ console.log('\n✅ Available Tools:');
722
+ for (const [toolName, toolInfo] of Object.entries(available)) {
723
+ console.log(` - ${toolInfo.name} (${toolName})`);
724
+ }
725
+ }
726
+
727
+ if (Object.keys(missing).length > 0) {
728
+ console.log('\n❌ Missing Tools:');
729
+ for (const [toolName, toolInfo] of Object.entries(missing)) {
730
+ console.log(` - ${toolInfo.name} (${toolName})`);
731
+ console.log(` Install command: ${toolInfo.install}`);
732
+ }
733
+ }
734
+
735
+ console.log(`\n[SUMMARY] ${Object.keys(available).length} available, ${Object.keys(missing).length} missing`);
1003
736
  } catch (error) {
1004
- console.log(`[WARN] Failed to download assets: ${error.message}`);
1005
- console.log('[INFO] Continuing with installation...');
737
+ await errorHandler.logError(error, 'ERROR', 'main.status');
738
+ console.log(`[ERROR] Failed to get status: ${error.message}`);
739
+ process.exit(1);
1006
740
  }
741
+ break;
1007
742
 
1008
- // Step 2: Scan for CLI tools
1009
- let autoAvailable = {}, autoMissing = {};
743
+ case 'scan':
1010
744
  try {
1011
- console.log('[STEP] Scanning for CLI tools...');
1012
- const scanResult = await installer.scanCLI();
1013
- autoAvailable = scanResult.available;
1014
- autoMissing = scanResult.missing;
1015
- console.log('[OK] CLI tools scanned successfully');
745
+ await installer.scanCLI();
1016
746
  } catch (error) {
1017
- console.log(`[WARN] Failed to scan CLI tools: ${error.message}`);
1018
- console.log('[INFO] Continuing with installation...');
747
+ await errorHandler.logError(error, 'ERROR', 'main.scan');
748
+ console.log(`[ERROR] Failed to scan CLI tools: ${error.message}`);
749
+ process.exit(1);
1019
750
  }
751
+ break;
1020
752
 
1021
- // Step 3: Show summary to user after installation
753
+ case 'install':
1022
754
  try {
1023
- if (Object.keys(autoMissing).length > 0) {
1024
- console.log('\n[INFO] Found ' + Object.keys(autoMissing).length + ' missing AI CLI tools:');
1025
- for (const [toolName, toolInfo] of Object.entries(autoMissing)) {
1026
- console.log(` - ${toolInfo.name} (${toolName})`);
755
+ console.log('[INSTALL] Starting AI CLI tools installation...');
756
+ const { missing: missingTools } = await installer.scanCLI();
757
+ const options = await installer.showInstallOptions(missingTools);
758
+
759
+ if (options.length > 0) {
760
+ const selectedTools = await installer.getUserSelection(options, missingTools);
761
+ if (selectedTools.length > 0) {
762
+ console.log('\n[INFO] Installing selected tools (this may take several minutes for tools that download binaries)...');
763
+ await installer.installTools(selectedTools, missingTools);
1027
764
  }
1028
- console.log('\n[INFO] Auto-install mode detected. Skipping automatic installation of missing tools.');
1029
- console.log('[INFO] For full functionality, please run "stigmergy install" after installation completes.');
1030
765
  } else {
1031
- console.log('\n[INFO] All AI CLI tools are already installed! No additional tools required.');
766
+ console.log('\n[INFO] All required tools are already installed!');
1032
767
  }
1033
768
  } catch (error) {
1034
- console.log(`[WARN] Failed to show tool summary: ${error.message}`);
769
+ await errorHandler.logError(error, 'ERROR', 'main.install');
770
+ console.log(`[ERROR] Installation failed: ${error.message}`);
771
+ process.exit(1);
1035
772
  }
773
+ break;
1036
774
 
1037
- // Step 4: Deploy hooks to available CLI tools
775
+ case 'deploy':
1038
776
  try {
1039
- console.log('[STEP] Deploying hooks to available CLI tools...');
1040
- await installer.deployHooks(autoAvailable);
1041
- console.log('[OK] Hooks deployed successfully');
777
+ const { available: deployedTools } = await installer.scanCLI();
778
+ await installer.deployHooks(deployedTools);
1042
779
  } catch (error) {
1043
- console.log(`[ERROR] Failed to deploy hooks: ${error.message}`);
1044
- console.log('[INFO] You can manually deploy hooks later by running: stigmergy deploy');
780
+ await errorHandler.logError(error, 'ERROR', 'main.deploy');
781
+ console.log(`[ERROR] Deployment failed: ${error.message}`);
782
+ process.exit(1);
1045
783
  }
784
+ break;
1046
785
 
1047
- // Step 5: Deploy project documentation
786
+ case 'setup':
1048
787
  try {
1049
- console.log('[STEP] Deploying project documentation...');
788
+ console.log('[SETUP] Starting complete Stigmergy setup...\n');
789
+
790
+ // Step 1: Download required assets
791
+ await installer.downloadRequiredAssets();
792
+
793
+ // Step 2: Scan for CLI tools
794
+ const { available: setupAvailable, missing: setupMissing } = await installer.scanCLI();
795
+ const setupOptions = await installer.showInstallOptions(setupMissing);
796
+
797
+ // Step 3: Install missing CLI tools if user chooses
798
+ if (setupOptions.length > 0) {
799
+ const selectedTools = await installer.getUserSelection(setupOptions, setupMissing);
800
+ if (selectedTools.length > 0) {
801
+ console.log('\n[INFO] Installing selected tools (this may take several minutes for tools that download binaries)...');
802
+ await installer.installTools(selectedTools, setupMissing);
803
+ }
804
+ } else {
805
+ console.log('\n[INFO] All required tools are already installed!');
806
+ }
807
+
808
+ // Step 4: Deploy hooks to available CLI tools
809
+ await installer.deployHooks(setupAvailable);
810
+
811
+ // Step 5: Deploy project documentation
1050
812
  await installer.deployProjectDocumentation();
1051
- console.log('[OK] Documentation deployed successfully');
813
+
814
+ // Step 6: Initialize configuration
815
+ await installer.initializeConfig();
816
+
817
+ // Step 7: Show usage instructions
818
+ installer.showUsageInstructions();
1052
819
  } catch (error) {
1053
- console.log(`[WARN] Failed to deploy documentation: ${error.message}`);
1054
- console.log('[INFO] Continuing with installation...');
820
+ await errorHandler.logError(error, 'ERROR', 'main.setup');
821
+ console.log(`[ERROR] Setup failed: ${error.message}`);
822
+ console.log('\n[TROUBLESHOOTING] To manually complete setup:');
823
+ console.log('1. Run: stigmergy deploy # Deploy hooks manually');
824
+ console.log('2. Run: stigmergy setup # Try setup again');
825
+ process.exit(1);
1055
826
  }
827
+ break;
1056
828
 
1057
- // Step 6: Initialize configuration
829
+ case 'call':
830
+ if (args.length < 2) {
831
+ console.log('[ERROR] Usage: stigmergy call "<prompt>"');
832
+ process.exit(1);
833
+ }
834
+
835
+ // Get the prompt (everything after the command)
836
+ const prompt = args.slice(1).join(' ');
837
+
838
+ // Use smart router to determine which tool to use
839
+ const router = new SmartRouter();
840
+ await router.initialize(); // Initialize the router first
841
+ const route = await router.smartRoute(prompt);
842
+
843
+ console.log(`[CALL] Routing to ${route.tool}: ${route.prompt}`);
844
+
845
+ // Execute the routed command
1058
846
  try {
1059
- console.log('[STEP] Initializing configuration...');
1060
- await installer.initializeConfig();
1061
- console.log('[OK] Configuration initialized successfully');
847
+ // Get the actual executable path for the tool
848
+ const toolPath = route.tool;
849
+ console.log(`[DEBUG] Tool path: ${toolPath}, Prompt: ${route.prompt}`);
850
+
851
+ // For different tools, we need to pass the prompt differently
852
+ // Use unified parameter handler for better parameter handling
853
+ let toolArgs = [];
854
+
855
+ try {
856
+ // Get CLI pattern for this tool
857
+ const cliPattern = await router.analyzer.getCLIPattern(route.tool);
858
+
859
+ // Use the unified CLI parameter handler
860
+ const CLIParameterHandler = require('./core/cli_parameter_handler');
861
+ toolArgs = CLIParameterHandler.generateArguments(route.tool, route.prompt, cliPattern);
862
+ } catch (patternError) {
863
+ // Fallback to original logic if pattern analysis fails
864
+ if (route.tool === 'claude') {
865
+ // Claude CLI expects the prompt with -p flag for non-interactive mode
866
+ toolArgs = ['-p', `"${route.prompt}"`];
867
+ } else if (route.tool === 'qodercli' || route.tool === 'iflow') {
868
+ // Qoder CLI and iFlow expect the prompt with -p flag
869
+ toolArgs = ['-p', `"${route.prompt}"`];
870
+ } else if (route.tool === 'codex') {
871
+ // Codex CLI needs 'exec' subcommand for non-interactive mode
872
+ toolArgs = ['exec', '-p', `"${route.prompt}"`];
873
+ } else {
874
+ // For other tools, pass the prompt with -p flag
875
+ toolArgs = ['-p', `"${route.prompt}"`];
876
+ }
877
+ }
878
+
879
+ // Use the correct way to spawn the process
880
+ const child = spawn(toolPath, toolArgs, {
881
+ stdio: 'inherit',
882
+ shell: true
883
+ });
884
+
885
+ child.on('close', (code) => {
886
+ if (code !== 0) {
887
+ console.log(`[WARN] ${route.tool} exited with code ${code}`);
888
+ }
889
+ process.exit(code);
890
+ });
891
+
892
+ child.on('error', async (error) => {
893
+ const cliError = await errorHandler.handleCLIError(route.tool, error, toolArgs.join(' '));
894
+ console.log(`[ERROR] Failed to execute ${route.tool}:`, cliError.message);
895
+ process.exit(1);
896
+ });
1062
897
  } catch (error) {
1063
- console.log(`[ERROR] Failed to initialize configuration: ${error.message}`);
1064
- console.log('[INFO] You can manually initialize configuration later by running: stigmergy setup');
898
+ const cliError = await errorHandler.handleCLIError(route.tool, error, prompt);
899
+ console.log(`[ERROR] Failed to execute ${route.tool}:`, cliError.message);
900
+ process.exit(1);
1065
901
  }
902
+ break;
1066
903
 
1067
- // Step 7: Show final message to guide users
1068
- console.log('\n[SUCCESS] Stigmergy CLI installed successfully!');
1069
- console.log('[USAGE] Run "stigmergy setup" to complete full configuration and install missing AI CLI tools.');
1070
- console.log('[USAGE] Run "stigmergy install" to install only missing AI CLI tools.');
1071
- console.log('[USAGE] Run "stigmergy --help" to see all available commands.');
1072
- } catch (fatalError) {
1073
- console.error('[FATAL] Auto-install process failed:', fatalError.message);
1074
- console.log('\n[TROUBLESHOOTING] To manually complete installation:');
1075
- console.log('1. Run: stigmergy setup # Complete setup');
1076
- console.log('2. Run: stigmergy install # Install missing tools');
1077
- console.log('3. Run: stigmergy deploy # Deploy hooks manually');
1078
- process.exit(1);
1079
- }
1080
- break;
904
+ case 'auto-install':
905
+ // Auto-install mode for npm postinstall - NON-INTERACTIVE
906
+ console.log('[AUTO-INSTALL] Stigmergy CLI automated setup');
907
+ console.log('='.repeat(60));
1081
908
 
1082
- default:
1083
- console.log(`[ERROR] Unknown command: ${command}`);
1084
- console.log('[INFO] Run "stigmergy --help" for usage information');
1085
- process.exit(1);
909
+ try {
910
+ // Step 1: Download required assets
911
+ try {
912
+ console.log('[STEP] Downloading required assets...');
913
+ await installer.downloadRequiredAssets();
914
+ console.log('[OK] Assets downloaded successfully');
915
+ } catch (error) {
916
+ console.log(`[WARN] Failed to download assets: ${error.message}`);
917
+ console.log('[INFO] Continuing with installation...');
918
+ }
919
+
920
+ // Step 2: Scan for CLI tools
921
+ let autoAvailable = {}, autoMissing = {};
922
+ try {
923
+ console.log('[STEP] Scanning for CLI tools...');
924
+ const scanResult = await installer.scanCLI();
925
+ autoAvailable = scanResult.available;
926
+ autoMissing = scanResult.missing;
927
+ console.log('[OK] CLI tools scanned successfully');
928
+ } catch (error) {
929
+ console.log(`[WARN] Failed to scan CLI tools: ${error.message}`);
930
+ console.log('[INFO] Continuing with installation...');
931
+ }
932
+
933
+ // Step 3: Show summary to user after installation
934
+ try {
935
+ if (Object.keys(autoMissing).length > 0) {
936
+ console.log('\n[INFO] Found ' + Object.keys(autoMissing).length + ' missing AI CLI tools:');
937
+ for (const [toolName, toolInfo] of Object.entries(autoMissing)) {
938
+ console.log(` - ${toolInfo.name} (${toolName})`);
939
+ }
940
+ console.log('\n[INFO] Auto-install mode detected. Skipping automatic installation of missing tools.');
941
+ console.log('[INFO] For full functionality, please run "stigmergy install" after installation completes.');
942
+ } else {
943
+ console.log('\n[INFO] All AI CLI tools are already installed! No additional tools required.');
944
+ }
945
+ } catch (error) {
946
+ console.log(`[WARN] Failed to show tool summary: ${error.message}`);
947
+ }
948
+
949
+ // Step 4: Deploy hooks to available CLI tools
950
+ try {
951
+ console.log('[STEP] Deploying hooks to available CLI tools...');
952
+ await installer.deployHooks(autoAvailable);
953
+ console.log('[OK] Hooks deployed successfully');
954
+ } catch (error) {
955
+ console.log(`[ERROR] Failed to deploy hooks: ${error.message}`);
956
+ console.log('[INFO] You can manually deploy hooks later by running: stigmergy deploy');
957
+ }
958
+
959
+ // Step 5: Deploy project documentation
960
+ try {
961
+ console.log('[STEP] Deploying project documentation...');
962
+ await installer.deployProjectDocumentation();
963
+ console.log('[OK] Documentation deployed successfully');
964
+ } catch (error) {
965
+ console.log(`[WARN] Failed to deploy documentation: ${error.message}`);
966
+ console.log('[INFO] Continuing with installation...');
967
+ }
968
+
969
+ // Step 6: Initialize configuration
970
+ try {
971
+ console.log('[STEP] Initializing configuration...');
972
+ await installer.initializeConfig();
973
+ console.log('[OK] Configuration initialized successfully');
974
+ } catch (error) {
975
+ console.log(`[ERROR] Failed to initialize configuration: ${error.message}`);
976
+ console.log('[INFO] You can manually initialize configuration later by running: stigmergy setup');
977
+ }
978
+
979
+ // Step 7: Show final message to guide users
980
+ console.log('\n[SUCCESS] Stigmergy CLI installed successfully!');
981
+ console.log('[USAGE] Run "stigmergy setup" to complete full configuration and install missing AI CLI tools.');
982
+ console.log('[USAGE] Run "stigmergy install" to install only missing AI CLI tools.');
983
+ console.log('[USAGE] Run "stigmergy --help" to see all available commands.');
984
+ } catch (fatalError) {
985
+ await errorHandler.logError(fatalError, 'ERROR', 'main.auto-install');
986
+ console.error('[FATAL] Auto-install process failed:', fatalError.message);
987
+ console.log('\n[TROUBLESHOOTING] To manually complete installation:');
988
+ console.log('1. Run: stigmergy setup # Complete setup');
989
+ console.log('2. Run: stigmergy install # Install missing tools');
990
+ console.log('3. Run: stigmergy deploy # Deploy hooks manually');
991
+ process.exit(1);
992
+ }
993
+ break;
994
+
995
+ default:
996
+ console.log(`[ERROR] Unknown command: ${command}`);
997
+ console.log('[INFO] Run "stigmergy --help" for usage information');
998
+ process.exit(1);
999
+ }
1000
+ } catch (error) {
1001
+ await errorHandler.logError(error, 'ERROR', 'main');
1002
+ console.error('[FATAL] Stigmergy CLI encountered an error:', error.message);
1003
+ process.exit(1);
1086
1004
  }
1087
1005
  }
1088
1006
 
1007
+ // Function to find maximum of two numbers
1008
+ function maxOfTwo(a, b) {
1009
+ return a > b ? a : b;
1010
+ }
1011
+
1089
1012
  // Export for testing
1090
- module.exports = { StigmergyInstaller, SmartRouter, MemoryManager, CLI_TOOLS };
1013
+ module.exports = { StigmergyInstaller, SmartRouter, MemoryManager, CLI_TOOLS, maxOfTwo };
1091
1014
 
1092
1015
  // Run main function
1093
1016
  if (require.main === module) {
1094
1017
  main().catch(error => {
1095
- console.error('[FATAL] Stigmergy CLI encountered an error:', error);
1018
+ console.error('[FATAL] Stigmergy CLI encountered an unhandled error:', error);
1096
1019
  process.exit(1);
1097
1020
  });
1098
1021
  }