stigmergy 1.1.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/cli/router.js CHANGED
@@ -16,12 +16,21 @@ const { executeCommand, executeJSFile } = require('../utils');
16
16
  const { UserAuthenticator } = require('../auth');
17
17
  const MemoryManager = require('../core/memory_manager');
18
18
  const StigmergyInstaller = require('../core/installer');
19
+ const UpgradeManager = require('../core/upgrade_manager');
19
20
  const { maxOfTwo, isAuthenticated } = require('../utils/helpers');
20
21
 
21
22
  // Set up global error handlers using our error handler module
22
23
  const { setupGlobalErrorHandlers } = require('../core/error_handler');
23
24
  setupGlobalErrorHandlers();
24
25
 
26
+ // Helper function to format bytes
27
+ function formatBytes(bytes) {
28
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
29
+ if (bytes === 0) return '0 Bytes';
30
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
31
+ return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
32
+ }
33
+
25
34
  async function main() {
26
35
  const args = process.argv.slice(2);
27
36
 
@@ -53,6 +62,7 @@ async function main() {
53
62
  console.log(' status Check CLI tools status');
54
63
  console.log(' scan Scan for available AI CLI tools');
55
64
  console.log(' install Auto-install missing CLI tools');
65
+ console.log(' upgrade Upgrade all CLI tools to latest versions');
56
66
  console.log(
57
67
  ' deploy Deploy hooks and integration to installed tools',
58
68
  );
@@ -60,17 +70,18 @@ async function main() {
60
70
  console.log(
61
71
  ' init Initialize Stigmergy configuration (alias for setup)',
62
72
  );
73
+ console.log(' clean (c) Clean temporary files and caches');
74
+ console.log(' diagnostic (d) Show system diagnostic information');
63
75
 
64
76
  console.log(' fibonacci <n> Calculate the nth Fibonacci number');
65
77
  console.log(' fibonacci seq <n> Generate the first n Fibonacci numbers');
66
78
  console.log(' errors Display error report and statistics');
67
79
  console.log('');
68
- console.log('[WORKFLOW] Automated Workflow:');
69
- console.log(' 1. npm install -g stigmergy # Install Stigmergy');
70
- console.log(
71
- ' 2. stigmergy install # Auto-scan & install CLI tools',
72
- );
73
- console.log(' 3. stigmergy setup # Deploy hooks & config');
80
+ console.log('[QUICK START] Getting Started:');
81
+ console.log(' 1. npm install -g stigmergy # Install Stigmergy (auto-cleans cache)');
82
+ console.log(' 2. stigmergy d # System diagnostic');
83
+ console.log(' 3. stigmergy inst # Install missing AI CLI tools');
84
+ console.log(' 4. stigmergy deploy # Deploy hooks for CLI integration');
74
85
 
75
86
  console.log('');
76
87
  console.log(
@@ -198,7 +209,157 @@ async function main() {
198
209
  }
199
210
  break;
200
211
 
212
+ case 'upgrade': {
213
+ try {
214
+ console.log('[UPGRADE] Starting CLI tools upgrade process...');
215
+ const upgrader = new UpgradeManager();
216
+ await upgrader.initialize();
217
+
218
+ // 解析命令行选项
219
+ const upgradeArgs = args.slice(1);
220
+ const options = {
221
+ dryRun: upgradeArgs.includes('--dry-run'),
222
+ force: upgradeArgs.includes('--force'),
223
+ verbose: upgradeArgs.includes('--verbose'),
224
+ diagnose: upgradeArgs.includes('--diagnose'),
225
+ suggest: upgradeArgs.includes('--suggest')
226
+ };
227
+
228
+ if (options.diagnose) {
229
+ console.log('\n🔍 DIAGNOSTIC MODE - Checking for issues...\n');
230
+ const deprecations = await upgrader.checkDeprecations();
231
+
232
+ if (deprecations.length === 0) {
233
+ console.log('✅ No issues detected.');
234
+ } else {
235
+ console.log('❌ Issues found:');
236
+ deprecations.forEach((dep, index) => {
237
+ console.log(`\n${index + 1}. ${dep.type || 'Unknown'}`);
238
+ if (dep.dependency) console.log(` Dependency: ${dep.dependency}`);
239
+ console.log(` Issues: ${dep.issues.join(', ')}`);
240
+ });
241
+ }
242
+ break;
243
+ }
244
+
245
+ if (options.suggest) {
246
+ console.log('\n💡 SUGGESTION MODE - Generating recommendations...\n');
247
+ const plan = await upgrader.generateUpgradePlan(options);
248
+
249
+ console.log('📋 Recommendations:');
250
+ if (plan.upgrades.length > 0) {
251
+ console.log('\n🔺 Available Upgrades:');
252
+ plan.upgrades.forEach(upgrade => {
253
+ console.log(` • ${upgrade.tool}: ${upgrade.from} → ${upgrade.to}`);
254
+ });
255
+ }
256
+
257
+ if (plan.fixes.length > 0) {
258
+ console.log('\n🔧 Recommended Fixes:');
259
+ plan.fixes.forEach(fix => {
260
+ console.log(` • ${fix.type}: ${fix.description}`);
261
+ });
262
+ }
263
+
264
+ if (plan.upgrades.length === 0 && plan.fixes.length === 0) {
265
+ console.log('✅ Everything is up to date!');
266
+ }
267
+ break;
268
+ }
269
+
270
+ // 生成升级计划
271
+ console.log('\n📋 Generating upgrade plan...\n');
272
+ const plan = await upgrader.generateUpgradePlan(options);
273
+
274
+ // 显示计划
275
+ console.log('📊 UPGRADE PLAN');
276
+ console.log('='.repeat(50));
277
+
278
+ if (plan.upgrades.length > 0) {
279
+ console.log('\n🔺 CLI Tool Upgrades:');
280
+ plan.upgrades.forEach(upgrade => {
281
+ console.log(` • ${upgrade.tool.padEnd(12)} ${upgrade.from} → ${upgrade.to}`);
282
+ });
283
+ } else {
284
+ console.log('\n✅ All CLI tools are up to date');
285
+ }
286
+
287
+ if (plan.fixes.length > 0) {
288
+ console.log('\n🔧 Issues to Fix:');
289
+ plan.fixes.forEach(fix => {
290
+ console.log(` • ${fix.type}: ${fix.description}`);
291
+ });
292
+ }
293
+
294
+ if (plan.warnings.length > 0) {
295
+ console.log('\n⚠️ Warnings:');
296
+ plan.warnings.forEach(warning => {
297
+ console.log(` • ${warning.tool || 'Unknown'}: ${warning.error}`);
298
+ });
299
+ }
300
+
301
+ if (options.dryRun) {
302
+ console.log('\n🔍 DRY RUN MODE - No changes will be made');
303
+ console.log(' Use --force to execute the upgrade plan');
304
+ break;
305
+ }
306
+
307
+ // 确认执行
308
+ if (!options.force) {
309
+ const { confirm } = await inquirer.prompt([{
310
+ type: 'confirm',
311
+ name: 'confirm',
312
+ message: 'Do you want to proceed with this upgrade plan?',
313
+ default: false
314
+ }]);
315
+
316
+ if (!confirm) {
317
+ console.log('\n❌ Upgrade cancelled by user');
318
+ break;
319
+ }
320
+ }
321
+
322
+ // 执行升级
323
+ console.log('\n🚀 Executing upgrade plan...\n');
324
+ const results = await upgrader.executeUpgrade(plan, options);
325
+
326
+ // 显示结果
327
+ console.log('\n📊 UPGRADE RESULTS');
328
+ console.log('='.repeat(50));
329
+
330
+ if (results.successful.length > 0) {
331
+ console.log(`\n✅ Successful (${results.successful.length}):`);
332
+ results.successful.forEach(result => {
333
+ const name = result.tool || result.type;
334
+ console.log(` • ${name}`);
335
+ });
336
+ }
337
+
338
+ if (results.failed.length > 0) {
339
+ console.log(`\n❌ Failed (${results.failed.length}):`);
340
+ results.failed.forEach(result => {
341
+ const name = result.tool || result.type;
342
+ console.log(` • ${name}: ${result.error}`);
343
+ });
344
+ }
345
+
346
+ // 记录日志
347
+ await upgrader.logUpgrade(plan, results);
348
+
349
+ console.log('\n🎉 Upgrade process completed!');
350
+
351
+ } catch (error) {
352
+ console.error('[ERROR] Upgrade failed:', error.message);
353
+ if (options.verbose) {
354
+ console.error(error.stack);
355
+ }
356
+ process.exit(1);
357
+ }
358
+ break;
359
+ }
360
+
201
361
  case 'install':
362
+ case 'inst':
202
363
  try {
203
364
  console.log('[INSTALL] Starting AI CLI tools installation...');
204
365
  const { missing: missingTools } = await installer.scanCLI();
@@ -285,18 +446,35 @@ async function main() {
285
446
 
286
447
  case 'auto-install':
287
448
  // Auto-install mode for npm postinstall - NON-INTERACTIVE
449
+ // Force immediate output visibility during npm install
288
450
  console.log('[AUTO-INSTALL] Stigmergy CLI automated setup');
289
451
  console.log('='.repeat(60));
290
452
 
453
+ // Force stdout flush to ensure visibility during npm install
454
+ if (process.stdout && process.stdout.write) {
455
+ process.stdout.write('');
456
+ if (process.stdout.flush) {
457
+ process.stdout.flush();
458
+ }
459
+ }
460
+
461
+ // Add a small delay to ensure output is visible
462
+ await new Promise(resolve => setTimeout(resolve, 100));
463
+
291
464
  try {
292
465
  // Step 1: Download required assets
293
466
  try {
294
467
  console.log('[STEP] Downloading required assets...');
468
+ // Force flush to ensure visibility
469
+ if (process.stdout.flush) process.stdout.flush();
470
+
295
471
  await installer.downloadRequiredAssets();
296
472
  console.log('[OK] Assets downloaded successfully');
473
+ if (process.stdout.flush) process.stdout.flush();
297
474
  } catch (error) {
298
475
  console.log(`[WARN] Failed to download assets: ${error.message}`);
299
476
  console.log('[INFO] Continuing with installation...');
477
+ if (process.stdout.flush) process.stdout.flush();
300
478
  }
301
479
 
302
480
  // Step 2: Scan for CLI tools
@@ -304,70 +482,116 @@ async function main() {
304
482
  autoMissing = {};
305
483
  try {
306
484
  console.log('[STEP] Scanning for CLI tools...');
485
+ if (process.stdout.flush) process.stdout.flush();
486
+
307
487
  const scanResult = await installer.scanCLI();
308
488
  autoAvailable = scanResult.available;
309
489
  autoMissing = scanResult.missing;
310
490
  console.log('[OK] CLI tools scanned successfully');
491
+ if (process.stdout.flush) process.stdout.flush();
311
492
  } catch (error) {
312
493
  console.log(`[WARN] Failed to scan CLI tools: ${error.message}`);
313
494
  console.log('[INFO] Continuing with installation...');
495
+ if (process.stdout.flush) process.stdout.flush();
314
496
  }
315
497
 
316
- // Step 3: Show summary to user after installation
498
+ // Step 4: Show usage instructions using existing scan results
317
499
  try {
500
+ console.log('\n' + '='.repeat(60));
501
+ console.log('[SUCCESS] Stigmergy CLI installation completed!');
502
+ console.log('='.repeat(60));
503
+
504
+ console.log(`\n[SCAN RESULT] Found ${Object.keys(autoAvailable).length} available AI CLI tools:`);
505
+
506
+ if (Object.keys(autoAvailable).length > 0) {
507
+ for (const [toolName, toolInfo] of Object.entries(autoAvailable)) {
508
+ const status = toolInfo.installed ? '✓ Installed' : '✗ Not Installed';
509
+ console.log(` ✓ ${toolInfo.name} (${toolName}) - ${status}`);
510
+ if (toolInfo.path) {
511
+ console.log(` Path: ${toolInfo.path}`);
512
+ }
513
+ if (toolInfo.version) {
514
+ console.log(` Version: ${toolInfo.version}`);
515
+ }
516
+ }
517
+ } else {
518
+ console.log(' [INFO] No AI CLI tools found on your system');
519
+ }
520
+
318
521
  if (Object.keys(autoMissing).length > 0) {
319
- console.log(
320
- '\n[INFO] Found ' +
321
- Object.keys(autoMissing).length +
322
- ' missing AI CLI tools:',
323
- );
522
+ console.log(`\n[MISSING] ${Object.keys(autoMissing).length} tools not found:`);
324
523
  for (const [toolName, toolInfo] of Object.entries(autoMissing)) {
325
- console.log(` - ${toolInfo.name} (${toolName})`);
524
+ console.log(` ${toolInfo.name} (${toolName})`);
525
+ console.log(` Install with: ${toolInfo.installCommand}`);
326
526
  }
327
- console.log(
328
- '\n[INFO] Auto-install mode detected. Skipping automatic installation of missing tools.',
329
- );
330
- console.log(
331
- '[INFO] For full functionality, please run "stigmergy install" after installation completes.',
332
- );
333
- } else {
334
- console.log(
335
- '\n[INFO] All AI CLI tools are already installed! No additional tools required.',
336
- );
527
+ console.log('\n[INFO] You can install missing tools with: stigmergy install');
337
528
  }
529
+
530
+ console.log('\n[USAGE] Get started with these commands:');
531
+ console.log(' stigmergy d - System diagnostic (recommended first)');
532
+ console.log(' stigmergy inst - Install missing CLI tools');
533
+ console.log(' stigmergy deploy - Deploy hooks for CLI integration');
534
+ console.log(' stigmergy c - Clean caches if needed');
535
+ console.log('\n[INFO] Stigmergy CLI enables collaboration between multiple AI CLI tools!');
536
+ console.log('[INFO] Try "stigmergy" to see all available commands and abbreviations.');
537
+
338
538
  } catch (error) {
339
- console.log(`[WARN] Failed to show tool summary: ${error.message}`);
539
+ console.log(`[WARN] Failed to show usage instructions: ${error.message}`);
540
+ if (process.stdout.flush) process.stdout.flush();
340
541
  }
341
542
 
342
- // Step 4: Deploy hooks to available CLI tools
543
+ // Step 4: Deploy hooks to available CLI tools (with Linux-specific error handling)
343
544
  try {
344
545
  console.log('[STEP] Deploying hooks to available CLI tools...');
546
+ if (process.stdout.flush) process.stdout.flush();
547
+
345
548
  await installer.deployHooks(autoAvailable);
346
549
  console.log('[OK] Hooks deployed successfully');
550
+ if (process.stdout.flush) process.stdout.flush();
347
551
  } catch (error) {
348
- console.log(`[ERROR] Failed to deploy hooks: ${error.message}`);
349
- console.log(
350
- '[INFO] You can manually deploy hooks later by running: stigmergy deploy',
351
- );
552
+ // Linux-specific error handling
553
+ const errorMessage = error.message || error.toString();
554
+ console.log(`[ERROR] Failed to deploy hooks: ${errorMessage}`);
555
+
556
+ if (process.platform === 'linux') {
557
+ if (errorMessage.includes('EACCES') || errorMessage.includes('permission')) {
558
+ console.log('[LINUX-INFO] Permission denied. This may be normal if hooks are being placed in system directories.');
559
+ console.log('[LINUX-INFO] You can try running with sudo or check directory permissions.');
560
+ } else if (errorMessage.includes('ENOENT') || errorMessage.includes('no such file')) {
561
+ console.log('[LINUX-INFO] Some directories do not exist. This is normal for tools that are not installed.');
562
+ } else if (errorMessage.includes('EPERM')) {
563
+ console.log('[LINUX-INFO] Operation not permitted. This may be due to filesystem permissions.');
564
+ }
565
+ }
566
+
567
+ console.log('[INFO] You can manually deploy hooks later by running: stigmergy deploy');
568
+ if (process.stdout.flush) process.stdout.flush();
352
569
  }
353
570
 
354
571
  // Step 5: Deploy project documentation
355
572
  try {
356
573
  console.log('[STEP] Deploying project documentation...');
574
+ if (process.stdout.flush) process.stdout.flush();
575
+
357
576
  await installer.deployProjectDocumentation();
358
577
  console.log('[OK] Documentation deployed successfully');
578
+ if (process.stdout.flush) process.stdout.flush();
359
579
  } catch (error) {
360
580
  console.log(
361
581
  `[WARN] Failed to deploy documentation: ${error.message}`,
362
582
  );
363
583
  console.log('[INFO] Continuing with installation...');
584
+ if (process.stdout.flush) process.stdout.flush();
364
585
  }
365
586
 
366
587
  // Step 6: Initialize configuration
367
588
  try {
368
589
  console.log('[STEP] Initializing configuration...');
590
+ if (process.stdout.flush) process.stdout.flush();
591
+
369
592
  await installer.initializeConfig();
370
593
  console.log('[OK] Configuration initialized successfully');
594
+ if (process.stdout.flush) process.stdout.flush();
371
595
  } catch (error) {
372
596
  console.log(
373
597
  `[ERROR] Failed to initialize configuration: ${error.message}`,
@@ -375,6 +599,7 @@ async function main() {
375
599
  console.log(
376
600
  '[INFO] You can manually initialize configuration later by running: stigmergy setup',
377
601
  );
602
+ if (process.stdout.flush) process.stdout.flush();
378
603
  }
379
604
 
380
605
  // Step 7: Show final message to guide users
@@ -388,6 +613,10 @@ async function main() {
388
613
  console.log(
389
614
  '[USAGE] Run "stigmergy --help" to see all available commands.',
390
615
  );
616
+
617
+ // Force final flush to ensure all output is visible
618
+ if (process.stdout.flush) process.stdout.flush();
619
+ if (process.stderr.flush) process.stderr.flush();
391
620
  } catch (fatalError) {
392
621
  await errorHandler.logError(fatalError, 'ERROR', 'main.auto-install');
393
622
  console.error(
@@ -402,6 +631,123 @@ async function main() {
402
631
  }
403
632
  break;
404
633
 
634
+ case 'clean':
635
+ case 'c': {
636
+ try {
637
+ console.log('[CLEAN] Starting intelligent cache cleaning...\n');
638
+
639
+ // Import our enhanced cache cleaner
640
+ const CacheCleaner = require('../core/cache_cleaner');
641
+ const cleaner = new CacheCleaner({
642
+ dryRun: false,
643
+ force: true,
644
+ verbose: true,
645
+ preserveRecent: 60 * 60 * 1000 // Preserve files from last hour
646
+ });
647
+
648
+ // Show options if arguments provided
649
+ if (args.includes('--dry-run')) {
650
+ console.log('[DRY RUN] Preview mode - no files will be deleted\n');
651
+ await cleaner.cleanAllCaches({
652
+ cleanStigmergy: args.includes('--stigmergy') || args.includes('--all'),
653
+ cleanNPX: args.includes('--npx') || args.includes('--all'),
654
+ cleanNPM: args.includes('--npm') || args.includes('--all'),
655
+ cleanCLI: args.includes('--cli') || args.includes('--all'),
656
+ cleanTemp: true // Always clean temp files
657
+ });
658
+ break;
659
+ }
660
+
661
+ // Default clean: safe options
662
+ console.log('[OPTIONS] Running safe cache cleaning...');
663
+ console.log('[INFO] This will remove temporary files and NPX cache only\n');
664
+
665
+ const results = await cleaner.cleanAllCaches({
666
+ cleanStigmergy: false, // Don't clean main config
667
+ cleanNPX: true, // Clean NPX cache (safe)
668
+ cleanNPM: false, // Don't clean NPM cache during normal run
669
+ cleanCLI: false, // Don't clean CLI configs during normal run
670
+ cleanTemp: true // Clean temporary files (always safe)
671
+ });
672
+
673
+ console.log('\n[SUMMARY] Cache cleaning completed:');
674
+ console.log(` 📄 Files removed: ${results.filesRemoved}`);
675
+ console.log(` 📁 Directories removed: ${results.directoriesRemoved}`);
676
+ console.log(` 💾 Space freed: ${formatBytes(results.bytesFreed)}`);
677
+
678
+ if (results.errors.length > 0) {
679
+ console.log(`\n⚠️ Warnings: ${results.errors.length} files couldn't be removed`);
680
+ }
681
+
682
+ } catch (error) {
683
+ console.error('[ERROR] Cache cleaning failed:', error.message);
684
+ process.exit(1);
685
+ }
686
+ break;
687
+ }
688
+
689
+ case 'diagnostic':
690
+ case 'diag':
691
+ case 'd': {
692
+ try {
693
+ console.log('[DIAGNOSTIC] Stigmergy CLI System Diagnostic...\n');
694
+
695
+ // System information
696
+ const packageJson = require('../../package.json');
697
+ console.log(`📦 Stigmergy CLI v${packageJson.version}`);
698
+ console.log(`🔧 Node.js: ${process.version}`);
699
+ console.log(`💻 Platform: ${process.platform} (${process.arch})\n`);
700
+
701
+ // Check cache cleaner availability
702
+ try {
703
+ const CacheCleaner = require('../core/cache_cleaner');
704
+ const cleaner = new CacheCleaner({ dryRun: true });
705
+
706
+ const plan = await cleaner.createInstallationPlan();
707
+ console.log('🧹 Cache Analysis:');
708
+ console.log(` 📊 Estimated space to clean: ${formatBytes(plan.estimatedSize)}`);
709
+ console.log(` 🗂️ Temporary files detected: ${plan.files.length}`);
710
+ } catch (error) {
711
+ console.log('⚠️ Cache cleaner not available');
712
+ }
713
+
714
+ // CLI tools status
715
+ try {
716
+ const { available, missing } = await installer.scanCLI();
717
+ console.log('\n🔧 CLI Tools Status:');
718
+ console.log(` ✅ Available: ${Object.keys(available).length}`);
719
+ console.log(` ❌ Missing: ${Object.keys(missing).length}`);
720
+
721
+ if (Object.keys(missing).length > 0) {
722
+ console.log('\nMissing Tools:');
723
+ for (const [toolName, toolInfo] of Object.entries(missing)) {
724
+ console.log(` - ${toolInfo.name}`);
725
+ }
726
+ }
727
+ } catch (error) {
728
+ console.log('⚠️ CLI scan failed');
729
+ }
730
+
731
+ // Installation suggestions
732
+ console.log('\n💡 Recommendations:');
733
+ console.log(' • Run "stigmergy install" to install missing CLI tools');
734
+ console.log(' • Run "stigmergy clean" to free up disk space');
735
+ console.log(' • Run "stigmergy setup" for complete configuration');
736
+
737
+ if (args.includes('--verbose')) {
738
+ console.log('\n📋 Advanced Options:');
739
+ console.log(' • stigmergy clean --all - Clean all caches');
740
+ console.log(' • stigmergy clean --dry-run - Preview cleaning');
741
+ console.log(' • npm run uninstall - Uninstall Stigmergy completely');
742
+ }
743
+
744
+ } catch (error) {
745
+ console.error('[ERROR] Diagnostic failed:', error.message);
746
+ process.exit(1);
747
+ }
748
+ break;
749
+ }
750
+
405
751
  default:
406
752
  console.log(`[ERROR] Unknown command: ${command}`);
407
753
  console.log('[INFO] Run "stigmergy --help" for usage information');