stigmergy 1.2.0 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/LICENSE +18 -18
  2. package/README.md +28 -223
  3. package/STIGMERGY.md +61 -61
  4. package/docs/PROJECT_CONSTITUTION.md +433 -433
  5. package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
  6. package/examples/calculator-example.js +72 -72
  7. package/examples/cline_usage_examples.md +364 -364
  8. package/examples/encryption-example.js +67 -67
  9. package/examples/json-parser-example.js +120 -120
  10. package/examples/json-validation-example.js +64 -64
  11. package/examples/rest-client-example.js +52 -52
  12. package/examples/rest_client_example.js +54 -54
  13. package/package.json +36 -15
  14. package/scripts/build.js +74 -74
  15. package/scripts/post-deployment-config.js +296 -296
  16. package/scripts/preinstall-check.js +173 -173
  17. package/scripts/publish.js +58 -268
  18. package/scripts/run-layered-tests.js +247 -0
  19. package/scripts/safe-install.js +139 -139
  20. package/scripts/simple-publish.js +57 -59
  21. package/src/adapters/claude/install_claude_integration.js +292 -0
  22. package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
  23. package/src/adapters/codex/install_codex_integration.js +395 -0
  24. package/src/adapters/copilot/install_copilot_integration.js +716 -0
  25. package/src/adapters/gemini/install_gemini_integration.js +304 -0
  26. package/src/adapters/iflow/install_iflow_integration.js +304 -0
  27. package/src/adapters/qoder/install_qoder_integration.js +1090 -0
  28. package/src/adapters/qwen/install_qwen_integration.js +285 -0
  29. package/src/auth.js +173 -173
  30. package/src/auth_command.js +208 -208
  31. package/src/calculator.js +313 -313
  32. package/src/cli/router.js +417 -38
  33. package/src/core/cache_cleaner.js +767 -744
  34. package/src/core/cli_help_analyzer.js +680 -674
  35. package/src/core/cli_parameter_handler.js +132 -127
  36. package/src/core/cli_tools.js +89 -89
  37. package/src/core/coordination/index.js +16 -16
  38. package/src/core/coordination/nodejs/AdapterManager.js +102 -89
  39. package/src/core/coordination/nodejs/CLCommunication.js +132 -124
  40. package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -236
  41. package/src/core/coordination/nodejs/HealthChecker.js +76 -77
  42. package/src/core/coordination/nodejs/HookDeploymentManager.js +263 -190
  43. package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
  44. package/src/core/coordination/nodejs/index.js +90 -72
  45. package/src/core/coordination/nodejs/utils/Logger.js +29 -29
  46. package/src/core/enhanced_installer.js +479 -456
  47. package/src/core/enhanced_uninstaller.js +638 -618
  48. package/src/core/error_handler.js +406 -406
  49. package/src/core/installer.js +815 -294
  50. package/src/core/memory_manager.js +83 -83
  51. package/src/core/rest_client.js +160 -160
  52. package/src/core/smart_router.js +249 -146
  53. package/src/core/upgrade_manager.js +76 -59
  54. package/src/data_encryption.js +143 -143
  55. package/src/data_structures.js +440 -440
  56. package/src/deploy.js +55 -55
  57. package/src/index.js +30 -30
  58. package/src/test/cli-availability-checker.js +194 -0
  59. package/src/test/test-environment.js +289 -0
  60. package/src/utils/helpers.js +35 -35
  61. package/src/utils.js +921 -915
  62. package/src/weatherProcessor.js +228 -228
  63. package/test/cache-cleaner-implemented.test.js +0 -328
  64. package/test/cache-cleaner.test.js +0 -390
  65. package/test/calculator.test.js +0 -215
  66. package/test/collision-test.js +0 -26
  67. package/test/comprehensive-enhanced-features.test.js +0 -252
  68. package/test/comprehensive-execution-test.js +0 -428
  69. package/test/conflict-prevention-test.js +0 -95
  70. package/test/cross-cli-detection-test.js +0 -33
  71. package/test/csv-processing-test.js +0 -36
  72. package/test/deploy-hooks-test.js +0 -250
  73. package/test/e2e/claude-cli-test.js +0 -128
  74. package/test/e2e/collaboration-test.js +0 -75
  75. package/test/e2e/comprehensive-test.js +0 -431
  76. package/test/e2e/error-handling-test.js +0 -90
  77. package/test/e2e/individual-tool-test.js +0 -143
  78. package/test/e2e/other-cli-test.js +0 -130
  79. package/test/e2e/qoder-cli-test.js +0 -128
  80. package/test/e2e/run-e2e-tests.js +0 -73
  81. package/test/e2e/test-data.js +0 -88
  82. package/test/e2e/test-utils.js +0 -222
  83. package/test/encryption-simple-test.js +0 -110
  84. package/test/encryption.test.js +0 -129
  85. package/test/enhanced-main-alignment.test.js +0 -298
  86. package/test/enhanced-uninstaller-implemented.test.js +0 -271
  87. package/test/enhanced-uninstaller.test.js +0 -284
  88. package/test/error-handling-test.js +0 -341
  89. package/test/fibonacci.test.js +0 -178
  90. package/test/final-deploy-test.js +0 -221
  91. package/test/final-install-test.js +0 -226
  92. package/test/hash-table-demo.js +0 -33
  93. package/test/hash-table-test.js +0 -26
  94. package/test/hash_table_test.js +0 -114
  95. package/test/hook-system-integration-test.js +0 -307
  96. package/test/iflow-integration-test.js +0 -292
  97. package/test/improved-install-test.js +0 -362
  98. package/test/install-command-test.js +0 -370
  99. package/test/json-parser-test.js +0 -161
  100. package/test/json-validation-test.js +0 -164
  101. package/test/natural-language-skills-test.js +0 -320
  102. package/test/nl-integration-test.js +0 -179
  103. package/test/parameter-parsing-test.js +0 -143
  104. package/test/plugin-deployment-test.js +0 -316
  105. package/test/postinstall-test.js +0 -269
  106. package/test/python-plugins-test.js +0 -259
  107. package/test/real-test.js +0 -435
  108. package/test/remaining-adapters-test.js +0 -256
  109. package/test/rest-client-test.js +0 -56
  110. package/test/rest_client.test.js +0 -85
  111. package/test/safe-installation-cleaner.test.js +0 -343
  112. package/test/simple-iflow-hook-test.js +0 -137
  113. package/test/stigmergy-upgrade-test.js +0 -243
  114. package/test/system-compatibility-test.js +0 -467
  115. package/test/tdd-deploy-fix-test.js +0 -324
  116. package/test/tdd-fixes-test.js +0 -211
  117. package/test/third-party-skills-test.js +0 -321
  118. package/test/tool-selection-integration-test.js +0 -158
  119. package/test/unit/calculator-full.test.js +0 -191
  120. package/test/unit/calculator-simple.test.js +0 -96
  121. package/test/unit/calculator.test.js +0 -97
  122. package/test/unit/cli-scanner.test.js +0 -291
  123. package/test/unit/cli_parameter_handler.test.js +0 -116
  124. package/test/unit/cross-cli-executor.test.js +0 -399
  125. package/test/weather-processor.test.js +0 -104
@@ -1,456 +1,479 @@
1
- /**
2
- * Enhanced Stigmergy Installer
3
- *
4
- * Automatic cache cleaning before installation with comprehensive error handling
5
- * and progress reporting.
6
- */
7
-
8
- const fs = require('fs');
9
- const path = require('path');
10
- const os = require('os');
11
- const CacheCleaner = require('./cache_cleaner');
12
- const StigmergyInstaller = require('./installer');
13
-
14
- class EnhancedInstaller {
15
- constructor(options = {}) {
16
- this.options = {
17
- cleanBeforeInstall: options.cleanBeforeInstall !== false, // Default true
18
- cleanNPXCache: options.cleanNPXCache !== false,
19
- cleanTempFiles: options.cleanTempFiles !== false,
20
- cleanOldVersions: options.cleanOldVersions !== false,
21
- dryRun: options.dryRun || false,
22
- force: options.force || false,
23
- verbose: options.verbose || false,
24
- ...options
25
- };
26
-
27
- this.baseInstaller = new StigmergyInstaller();
28
- this.cacheCleaner = new CacheCleaner({
29
- dryRun: this.options.dryRun,
30
- force: this.options.force,
31
- verbose: this.options.verbose
32
- });
33
-
34
- this.results = {
35
- cacheCleaning: {},
36
- installation: {},
37
- errors: []
38
- };
39
- }
40
-
41
- /**
42
- * Perform enhanced installation with automatic cache cleaning
43
- */
44
- async enhancedInstall(options = {}) {
45
- const config = {
46
- cleanStigmergy: true,
47
- cleanNPX: this.options.cleanNPXCache,
48
- cleanNPM: this.options.cleanOldVersions,
49
- cleanCLI: false,
50
- cleanTemp: this.options.cleanTempFiles,
51
- ...options
52
- };
53
-
54
- console.log('🚀 Starting Enhanced Stigmergy Installation...\n');
55
-
56
- if (this.options.dryRun) {
57
- console.log('🔍 DRY RUN MODE - No actual changes will be made\n');
58
- }
59
-
60
- try {
61
- // Step 1: Pre-installation cache cleaning
62
- if (this.options.cleanBeforeInstall) {
63
- await this.preInstallCacheClean(config);
64
- }
65
-
66
- // Step 2: Scan and prepare for installation
67
- await this.scanAndPrepare();
68
-
69
- // Step 3: Perform installation
70
- if (!this.options.dryRun) {
71
- await this.performInstallation();
72
- }
73
-
74
- // Step 4: Post-installation verification
75
- await this.verifyInstallation();
76
-
77
- // Step 5: Print summary
78
- this.printSummary();
79
-
80
- return this.results;
81
-
82
- } catch (error) {
83
- console.error('❌ Enhanced installation failed:', error.message);
84
- this.results.errors.push(error.message);
85
- return this.results;
86
- }
87
- }
88
-
89
- /**
90
- * Pre-installation cache cleaning
91
- */
92
- async preInstallCacheClean(config) {
93
- console.log('🧹 Pre-installation Cache Cleaning...\n');
94
-
95
- const startTime = Date.now();
96
-
97
- try {
98
- // Clean caches before installation
99
- const cacheResults = await this.cacheCleaner.cleanAllCaches(config);
100
-
101
- const endTime = Date.now();
102
- const duration = endTime - startTime;
103
-
104
- this.results.cacheCleaning = {
105
- success: true,
106
- duration,
107
- filesRemoved: cacheResults.filesRemoved,
108
- directoriesRemoved: cacheResults.directoriesRemoved,
109
- bytesFreed: cacheResults.bytesFreed,
110
- errors: cacheResults.errors.length
111
- };
112
-
113
- console.log(`✅ Cache cleaning completed in ${duration}ms`);
114
- console.log(`📊 Removed ${cacheResults.filesRemoved} files, freed ${this.formatBytes(cacheResults.bytesFreed)}\n`);
115
-
116
- } catch (error) {
117
- console.error('Cache cleaning failed:', error.message);
118
- this.results.cacheCleaning = {
119
- success: false,
120
- error: error.message
121
- };
122
-
123
- if (!this.options.force) {
124
- throw new Error(`Cache cleaning failed: ${error.message}`);
125
- }
126
-
127
- console.log('⚠️ Continuing installation despite cache cleaning errors...\n');
128
- }
129
- }
130
-
131
- /**
132
- * Scan system and prepare for installation
133
- */
134
- async scanAndPrepare() {
135
- console.log('🔍 Scanning System for Installation...\n');
136
-
137
- try {
138
- // Check system requirements
139
- await this.checkSystemRequirements();
140
-
141
- // Scan for existing CLI tools
142
- const scanResult = await this.baseInstaller.scanCLI();
143
-
144
- console.log(`✅ System scan completed`);
145
- console.log(`📊 Found ${Object.keys(scanResult.available).length} available CLI tools`);
146
- console.log(`📊 Missing ${Object.keys(scanResult.missing).length} CLI tools\n`);
147
-
148
- this.results.scan = scanResult;
149
-
150
- } catch (error) {
151
- console.error('❌ System scan failed:', error.message);
152
- throw error;
153
- }
154
- }
155
-
156
- /**
157
- * Perform the actual installation
158
- */
159
- async performInstallation() {
160
- console.log('📦 Performing Installation...\n');
161
-
162
- try {
163
- // Interactive tool selection would go here
164
- // For now, we'll use a simple approach
165
- const missingTools = Object.keys(this.results.scan.missing);
166
-
167
- if (missingTools.length === 0) {
168
- console.log('ℹ️ All CLI tools are already installed');
169
- this.results.installation = {
170
- success: true,
171
- installed: [],
172
- message: 'No tools needed installation'
173
- };
174
- return;
175
- }
176
-
177
- console.log(`📦 Installing ${missingTools.length} CLI tools...`);
178
-
179
- // Install missing tools
180
- const installResult = await this.baseInstaller.installTools(
181
- missingTools,
182
- this.results.scan.missing
183
- );
184
-
185
- this.results.installation = {
186
- success: true,
187
- installed: missingTools,
188
- result: installResult
189
- };
190
-
191
- console.log(`✅ Installation completed`);
192
-
193
- } catch (error) {
194
- console.error('❌ Installation failed:', error.message);
195
- this.results.installation = {
196
- success: false,
197
- error: error.message
198
- };
199
- throw error;
200
- }
201
- }
202
-
203
- /**
204
- * Post-installation verification
205
- */
206
- async verifyInstallation() {
207
- console.log('\n✅ Post-installation Verification...');
208
-
209
- try {
210
- // Verify installation was successful
211
- const postScan = await this.baseInstaller.scanCLI();
212
-
213
- const verificationResults = {
214
- beforeCount: Object.keys(this.results.scan.available).length,
215
- afterCount: Object.keys(postScan.available).length,
216
- newlyInstalled: []
217
- };
218
-
219
- // Find newly installed tools
220
- for (const tool of Object.keys(postScan.available)) {
221
- if (!this.results.scan.available[tool]) {
222
- verificationResults.newlyInstalled.push(tool);
223
- }
224
- }
225
-
226
- this.results.verification = verificationResults;
227
-
228
- console.log(`📊 CLI tools before: ${verificationResults.beforeCount}`);
229
- console.log(`📊 CLI tools after: ${verificationResults.afterCount}`);
230
- console.log(`📊 Newly installed: ${verificationResults.newlyInstalled.length}`);
231
-
232
- if (verificationResults.newlyInstalled.length > 0) {
233
- console.log(`✅ Successfully installed: ${verificationResults.newlyInstalled.join(', ')}`);
234
- }
235
-
236
- console.log('✅ Installation verification completed\n');
237
-
238
- } catch (error) {
239
- console.error('❌ Verification failed:', error.message);
240
- this.results.errors.push(`Verification: ${error.message}`);
241
- }
242
- }
243
-
244
- /**
245
- * Check system requirements
246
- */
247
- async checkSystemRequirements() {
248
- console.log('🔧 Checking System Requirements...');
249
-
250
- // Check Node.js version
251
- const nodeVersion = process.version;
252
- const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0]);
253
-
254
- if (majorVersion < 14) {
255
- throw new Error(`Node.js version ${nodeVersion} is not supported. Please use Node.js 14 or higher.`);
256
- }
257
-
258
- console.log(` ✅ Node.js: ${nodeVersion}`);
259
-
260
- // Check npm availability
261
- try {
262
- const { spawnSync } = require('child_process');
263
- const npmResult = spawnSync('npm', ['--version'], {
264
- encoding: 'utf8',
265
- shell: true
266
- });
267
-
268
- if (npmResult.status === 0) {
269
- console.log(` ✅ npm: ${npmResult.stdout.trim()}`);
270
- } else {
271
- throw new Error('npm is not available');
272
- }
273
- } catch (error) {
274
- throw new Error('npm is required but not found');
275
- }
276
-
277
- // Check available disk space (basic check)
278
- const homeDir = os.homedir();
279
- try {
280
- const stats = fs.statSync(homeDir);
281
- console.log(` ✅ Home directory accessible: ${homeDir}`);
282
- } catch (error) {
283
- throw new Error(`Cannot access home directory: ${homeDir}`);
284
- }
285
-
286
- console.log('✅ System requirements check passed\n');
287
- }
288
-
289
- /**
290
- * Create installation plan without executing
291
- */
292
- async createInstallationPlan() {
293
- console.log('📋 Creating Installation Plan...\n');
294
-
295
- const plan = {
296
- cacheCleaning: {},
297
- installation: {},
298
- estimatedTime: 0,
299
- estimatedSpace: 0
300
- };
301
-
302
- try {
303
- // Check what would be cleaned
304
- const stigmergyDir = path.join(os.homedir(), '.stigmergy');
305
- if (fs.existsSync(stigmergyDir)) {
306
- const cacheSize = await this.calculateDirectorySize(stigmergyDir);
307
- plan.cacheCleaning.stigmergyCache = {
308
- path: stigmergyDir,
309
- size: cacheSize,
310
- wouldClean: this.options.cleanBeforeInstall
311
- };
312
- plan.estimatedSpace += cacheSize;
313
- }
314
-
315
- // Scan for missing CLI tools
316
- const scanResult = await this.baseInstaller.scanCLI();
317
- const missingTools = Object.keys(scanResult.missing);
318
-
319
- plan.installation = {
320
- missingTools: missingTools,
321
- toolCount: missingTools.length,
322
- tools: missingTools.map(tool => ({
323
- name: scanResult.missing[tool].name,
324
- installCommand: scanResult.missing[tool].install
325
- }))
326
- };
327
-
328
- // Estimate time (very rough estimate)
329
- plan.estimatedTime = missingTools.length * 30000; // 30 seconds per tool
330
-
331
- console.log(`📊 Installation Plan Summary:`);
332
- console.log(` 🧹 Cache cleaning: ${this.options.cleanBeforeInstall ? 'Yes' : 'No'}`);
333
- console.log(` 📦 Tools to install: ${missingTools.length}`);
334
- console.log(` ⏱️ Estimated time: ${Math.ceil(plan.estimatedTime / 1000)} seconds`);
335
- console.log(` 💾 Estimated space: ${this.formatBytes(plan.estimatedSpace)}`);
336
-
337
- return plan;
338
-
339
- } catch (error) {
340
- console.error(' Failed to create installation plan:', error.message);
341
- throw error;
342
- }
343
- }
344
-
345
- /**
346
- * Quick cache clean only
347
- */
348
- async quickCacheClean() {
349
- console.log('⚡ Quick Cache Clean Only...\n');
350
-
351
- try {
352
- const results = await this.cacheCleaner.cleanAllCaches({
353
- cleanStigmergy: false, // Don't clean main config
354
- cleanNPX: true,
355
- cleanNPM: false,
356
- cleanCLI: false,
357
- cleanTemp: true
358
- });
359
-
360
- console.log(`✅ Quick cache clean completed`);
361
- console.log(`📊 Removed ${results.filesRemoved} files, freed ${this.formatBytes(results.bytesFreed)}`);
362
-
363
- return results;
364
-
365
- } catch (error) {
366
- console.error('❌ Quick cache clean failed:', error.message);
367
- throw error;
368
- }
369
- }
370
-
371
- /**
372
- * Helper methods
373
- */
374
- async calculateDirectorySize(dirPath) {
375
- let totalSize = 0;
376
-
377
- try {
378
- const items = fs.readdirSync(dirPath, { withFileTypes: true });
379
-
380
- for (const item of items) {
381
- const fullPath = path.join(dirPath, item.name);
382
-
383
- if (item.isDirectory()) {
384
- totalSize += await this.calculateDirectorySize(fullPath);
385
- } else {
386
- try {
387
- const stat = fs.statSync(fullPath);
388
- totalSize += stat.size;
389
- } catch (error) {
390
- // Skip files we can't stat
391
- }
392
- }
393
- }
394
- } catch (error) {
395
- // Return 0 for directories we can't read
396
- }
397
-
398
- return totalSize;
399
- }
400
-
401
- formatBytes(bytes) {
402
- const sizes = ['Bytes', 'KB', 'MB', 'GB'];
403
- if (bytes === 0) return '0 Bytes';
404
- const i = Math.floor(Math.log(bytes) / Math.log(1024));
405
- return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
406
- }
407
-
408
- printSummary() {
409
- console.log('\n📊 ENHANCED INSTALLATION SUMMARY:');
410
- console.log('=' .repeat(50));
411
-
412
- if (this.options.dryRun) {
413
- console.log('🔍 DRY RUN MODE - No actual changes were made');
414
- }
415
-
416
- // Cache cleaning summary
417
- if (this.results.cacheCleaning.success) {
418
- console.log(`🧹 Cache Cleaning: ✅`);
419
- console.log(` Duration: ${this.results.cacheCleaning.duration}ms`);
420
- console.log(` Files removed: ${this.results.cacheCleaning.filesRemoved}`);
421
- console.log(` Space freed: ${this.formatBytes(this.results.cacheCleaning.bytesFreed)}`);
422
- } else if (this.results.cacheCleaning.error) {
423
- console.log(`🧹 Cache Cleaning: ❌ ${this.results.cacheCleaning.error}`);
424
- }
425
-
426
- // Installation summary
427
- if (this.results.installation.success) {
428
- console.log(`📦 Installation: ✅`);
429
- if (this.results.installation.installed.length > 0) {
430
- console.log(` Installed: ${this.results.installation.installed.join(', ')}`);
431
- } else {
432
- console.log(` Message: ${this.results.installation.message}`);
433
- }
434
- } else if (this.results.installation.error) {
435
- console.log(`📦 Installation: ❌ ${this.results.installation.error}`);
436
- }
437
-
438
- // Verification summary
439
- if (this.results.verification) {
440
- console.log(`✅ Verification: ✅`);
441
- console.log(` Newly installed: ${this.results.verification.newlyInstalled.length} tools`);
442
- }
443
-
444
- // Errors
445
- if (this.results.errors.length > 0) {
446
- console.log(`\n❌ Errors encountered: ${this.results.errors.length}`);
447
- this.results.errors.forEach(error => {
448
- console.log(` - ${error}`);
449
- });
450
- }
451
-
452
- console.log('\n🎉 Enhanced installation completed!');
453
- }
454
- }
455
-
456
- module.exports = EnhancedInstaller;
1
+ /**
2
+ * Enhanced Stigmergy Installer
3
+ *
4
+ * Automatic cache cleaning before installation with comprehensive error handling
5
+ * and progress reporting.
6
+ */
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+ const os = require('os');
11
+ const CacheCleaner = require('./cache_cleaner');
12
+ const StigmergyInstaller = require('./installer');
13
+
14
+ class EnhancedInstaller {
15
+ constructor(options = {}) {
16
+ this.options = {
17
+ cleanBeforeInstall: options.cleanBeforeInstall !== false, // Default true
18
+ cleanNPXCache: options.cleanNPXCache !== false,
19
+ cleanTempFiles: options.cleanTempFiles !== false,
20
+ cleanOldVersions: options.cleanOldVersions !== false,
21
+ dryRun: options.dryRun || false,
22
+ force: options.force || false,
23
+ verbose: options.verbose || false,
24
+ ...options,
25
+ };
26
+
27
+ this.baseInstaller = new StigmergyInstaller();
28
+ this.cacheCleaner = new CacheCleaner({
29
+ dryRun: this.options.dryRun,
30
+ force: this.options.force,
31
+ verbose: this.options.verbose,
32
+ });
33
+
34
+ this.results = {
35
+ cacheCleaning: {},
36
+ installation: {},
37
+ errors: [],
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Perform enhanced installation with automatic cache cleaning
43
+ */
44
+ async enhancedInstall(options = {}) {
45
+ const config = {
46
+ cleanStigmergy: true,
47
+ cleanNPX: this.options.cleanNPXCache,
48
+ cleanNPM: this.options.cleanOldVersions,
49
+ cleanCLI: false,
50
+ cleanTemp: this.options.cleanTempFiles,
51
+ ...options,
52
+ };
53
+
54
+ console.log('🚀 Starting Enhanced Stigmergy Installation...\n');
55
+
56
+ if (this.options.dryRun) {
57
+ console.log('🔍 DRY RUN MODE - No actual changes will be made\n');
58
+ }
59
+
60
+ try {
61
+ // Step 1: Pre-installation cache cleaning
62
+ if (this.options.cleanBeforeInstall) {
63
+ await this.preInstallCacheClean(config);
64
+ }
65
+
66
+ // Step 2: Scan and prepare for installation
67
+ await this.scanAndPrepare();
68
+
69
+ // Step 3: Perform installation
70
+ if (!this.options.dryRun) {
71
+ await this.performInstallation();
72
+ }
73
+
74
+ // Step 4: Post-installation verification
75
+ await this.verifyInstallation();
76
+
77
+ // Step 5: Print summary
78
+ this.printSummary();
79
+
80
+ return this.results;
81
+ } catch (error) {
82
+ console.error('�?Enhanced installation failed:', error.message);
83
+ this.results.errors.push(error.message);
84
+ return this.results;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Pre-installation cache cleaning
90
+ */
91
+ async preInstallCacheClean(config) {
92
+ console.log('🧹 Pre-installation Cache Cleaning...\n');
93
+
94
+ const startTime = Date.now();
95
+
96
+ try {
97
+ // Clean caches before installation
98
+ const cacheResults = await this.cacheCleaner.cleanAllCaches(config);
99
+
100
+ const endTime = Date.now();
101
+ const duration = endTime - startTime;
102
+
103
+ this.results.cacheCleaning = {
104
+ success: true,
105
+ duration,
106
+ filesRemoved: cacheResults.filesRemoved,
107
+ directoriesRemoved: cacheResults.directoriesRemoved,
108
+ bytesFreed: cacheResults.bytesFreed,
109
+ errors: cacheResults.errors.length,
110
+ };
111
+
112
+ console.log(`�?Cache cleaning completed in ${duration}ms`);
113
+ console.log(
114
+ `📊 Removed ${cacheResults.filesRemoved} files, freed ${this.formatBytes(cacheResults.bytesFreed)}\n`,
115
+ );
116
+ } catch (error) {
117
+ console.error('�?Cache cleaning failed:', error.message);
118
+ this.results.cacheCleaning = {
119
+ success: false,
120
+ error: error.message,
121
+ };
122
+
123
+ if (!this.options.force) {
124
+ throw new Error(`Cache cleaning failed: ${error.message}`);
125
+ }
126
+
127
+ console.log(
128
+ '⚠️ Continuing installation despite cache cleaning errors...\n',
129
+ );
130
+ }
131
+ }
132
+
133
+ /**
134
+ * Scan system and prepare for installation
135
+ */
136
+ async scanAndPrepare() {
137
+ console.log('🔍 Scanning System for Installation...\n');
138
+
139
+ try {
140
+ // Check system requirements
141
+ await this.checkSystemRequirements();
142
+
143
+ // Scan for existing CLI tools
144
+ const scanResult = await this.baseInstaller.scanCLI();
145
+
146
+ console.log('�?System scan completed');
147
+ console.log(
148
+ `📊 Found ${Object.keys(scanResult.available).length} available CLI tools`,
149
+ );
150
+ console.log(
151
+ `📊 Missing ${Object.keys(scanResult.missing).length} CLI tools\n`,
152
+ );
153
+
154
+ this.results.scan = scanResult;
155
+ } catch (error) {
156
+ console.error('�?System scan failed:', error.message);
157
+ throw error;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Perform the actual installation
163
+ */
164
+ async performInstallation() {
165
+ console.log('📦 Performing Installation...\n');
166
+
167
+ try {
168
+ // Interactive tool selection would go here
169
+ // For now, we'll use a simple approach
170
+ const missingTools = Object.keys(this.results.scan.missing);
171
+
172
+ if (missingTools.length === 0) {
173
+ console.log('ℹ️ All CLI tools are already installed');
174
+ this.results.installation = {
175
+ success: true,
176
+ installed: [],
177
+ message: 'No tools needed installation',
178
+ };
179
+ return;
180
+ }
181
+
182
+ console.log(`📦 Installing ${missingTools.length} CLI tools...`);
183
+
184
+ // Install missing tools
185
+ const installResult = await this.baseInstaller.installTools(
186
+ missingTools,
187
+ this.results.scan.missing,
188
+ );
189
+
190
+ this.results.installation = {
191
+ success: true,
192
+ installed: missingTools,
193
+ result: installResult,
194
+ };
195
+
196
+ console.log('�?Installation completed');
197
+ } catch (error) {
198
+ console.error('�?Installation failed:', error.message);
199
+ this.results.installation = {
200
+ success: false,
201
+ error: error.message,
202
+ };
203
+ throw error;
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Post-installation verification
209
+ */
210
+ async verifyInstallation() {
211
+ console.log('\n�?Post-installation Verification...');
212
+
213
+ try {
214
+ // Verify installation was successful
215
+ const postScan = await this.baseInstaller.scanCLI();
216
+
217
+ const verificationResults = {
218
+ beforeCount: Object.keys(this.results.scan.available).length,
219
+ afterCount: Object.keys(postScan.available).length,
220
+ newlyInstalled: [],
221
+ };
222
+
223
+ // Find newly installed tools
224
+ for (const tool of Object.keys(postScan.available)) {
225
+ if (!this.results.scan.available[tool]) {
226
+ verificationResults.newlyInstalled.push(tool);
227
+ }
228
+ }
229
+
230
+ this.results.verification = verificationResults;
231
+
232
+ console.log(`📊 CLI tools before: ${verificationResults.beforeCount}`);
233
+ console.log(`📊 CLI tools after: ${verificationResults.afterCount}`);
234
+ console.log(
235
+ `📊 Newly installed: ${verificationResults.newlyInstalled.length}`,
236
+ );
237
+
238
+ if (verificationResults.newlyInstalled.length > 0) {
239
+ console.log(
240
+ `�?Successfully installed: ${verificationResults.newlyInstalled.join(', ')}`,
241
+ );
242
+ }
243
+
244
+ console.log('�?Installation verification completed\n');
245
+ } catch (error) {
246
+ console.error('�?Verification failed:', error.message);
247
+ this.results.errors.push(`Verification: ${error.message}`);
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Check system requirements
253
+ */
254
+ async checkSystemRequirements() {
255
+ console.log('🔧 Checking System Requirements...');
256
+
257
+ // Check Node.js version
258
+ const nodeVersion = process.version;
259
+ const majorVersion = parseInt(nodeVersion.slice(1).split('.')[0]);
260
+
261
+ if (majorVersion < 14) {
262
+ throw new Error(
263
+ `Node.js version ${nodeVersion} is not supported. Please use Node.js 14 or higher.`,
264
+ );
265
+ }
266
+
267
+ console.log(` �?Node.js: ${nodeVersion}`);
268
+
269
+ // Check npm availability
270
+ try {
271
+ const { spawnSync } = require('child_process');
272
+ const npmResult = spawnSync('npm', ['--version'], {
273
+ encoding: 'utf8',
274
+ shell: true,
275
+ });
276
+
277
+ if (npmResult.status === 0) {
278
+ console.log(` �?npm: ${npmResult.stdout.trim()}`);
279
+ } else {
280
+ throw new Error('npm is not available');
281
+ }
282
+ } catch (error) {
283
+ throw new Error('npm is required but not found');
284
+ }
285
+
286
+ // Check available disk space (basic check)
287
+ const homeDir = os.homedir();
288
+ try {
289
+ const stats = fs.statSync(homeDir);
290
+ console.log(` �?Home directory accessible: ${homeDir}`);
291
+ } catch (error) {
292
+ throw new Error(`Cannot access home directory: ${homeDir}`);
293
+ }
294
+
295
+ console.log('�?System requirements check passed\n');
296
+ }
297
+
298
+ /**
299
+ * Create installation plan without executing
300
+ */
301
+ async createInstallationPlan() {
302
+ console.log('📋 Creating Installation Plan...\n');
303
+
304
+ const plan = {
305
+ cacheCleaning: {},
306
+ installation: {},
307
+ estimatedTime: 0,
308
+ estimatedSpace: 0,
309
+ };
310
+
311
+ try {
312
+ // Check what would be cleaned
313
+ const stigmergyDir = path.join(os.homedir(), '.stigmergy');
314
+ if (fs.existsSync(stigmergyDir)) {
315
+ const cacheSize = await this.calculateDirectorySize(stigmergyDir);
316
+ plan.cacheCleaning.stigmergyCache = {
317
+ path: stigmergyDir,
318
+ size: cacheSize,
319
+ wouldClean: this.options.cleanBeforeInstall,
320
+ };
321
+ plan.estimatedSpace += cacheSize;
322
+ }
323
+
324
+ // Scan for missing CLI tools
325
+ const scanResult = await this.baseInstaller.scanCLI();
326
+ const missingTools = Object.keys(scanResult.missing);
327
+
328
+ plan.installation = {
329
+ missingTools: missingTools,
330
+ toolCount: missingTools.length,
331
+ tools: missingTools.map((tool) => ({
332
+ name: scanResult.missing[tool].name,
333
+ installCommand: scanResult.missing[tool].install,
334
+ })),
335
+ };
336
+
337
+ // Estimate time (very rough estimate)
338
+ plan.estimatedTime = missingTools.length * 30000; // 30 seconds per tool
339
+
340
+ console.log('📊 Installation Plan Summary:');
341
+ console.log(
342
+ ` 🧹 Cache cleaning: ${this.options.cleanBeforeInstall ? 'Yes' : 'No'}`,
343
+ );
344
+ console.log(` 📦 Tools to install: ${missingTools.length}`);
345
+ console.log(
346
+ ` ⏱️ Estimated time: ${Math.ceil(plan.estimatedTime / 1000)} seconds`,
347
+ );
348
+ console.log(
349
+ ` 💾 Estimated space: ${this.formatBytes(plan.estimatedSpace)}`,
350
+ );
351
+
352
+ return plan;
353
+ } catch (error) {
354
+ console.error('�?Failed to create installation plan:', error.message);
355
+ throw error;
356
+ }
357
+ }
358
+
359
+ /**
360
+ * Quick cache clean only
361
+ */
362
+ async quickCacheClean() {
363
+ console.log('�?Quick Cache Clean Only...\n');
364
+
365
+ try {
366
+ const results = await this.cacheCleaner.cleanAllCaches({
367
+ cleanStigmergy: false, // Don't clean main config
368
+ cleanNPX: true,
369
+ cleanNPM: false,
370
+ cleanCLI: false,
371
+ cleanTemp: true,
372
+ });
373
+
374
+ console.log('�?Quick cache clean completed');
375
+ console.log(
376
+ `📊 Removed ${results.filesRemoved} files, freed ${this.formatBytes(results.bytesFreed)}`,
377
+ );
378
+
379
+ return results;
380
+ } catch (error) {
381
+ console.error('�?Quick cache clean failed:', error.message);
382
+ throw error;
383
+ }
384
+ }
385
+
386
+ /**
387
+ * Helper methods
388
+ */
389
+ async calculateDirectorySize(dirPath) {
390
+ let totalSize = 0;
391
+
392
+ try {
393
+ const items = fs.readdirSync(dirPath, { withFileTypes: true });
394
+
395
+ for (const item of items) {
396
+ const fullPath = path.join(dirPath, item.name);
397
+
398
+ if (item.isDirectory()) {
399
+ totalSize += await this.calculateDirectorySize(fullPath);
400
+ } else {
401
+ try {
402
+ const stat = fs.statSync(fullPath);
403
+ totalSize += stat.size;
404
+ } catch (error) {
405
+ // Skip files we can't stat
406
+ }
407
+ }
408
+ }
409
+ } catch (error) {
410
+ // Return 0 for directories we can't read
411
+ }
412
+
413
+ return totalSize;
414
+ }
415
+
416
+ formatBytes(bytes) {
417
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
418
+ if (bytes === 0) return '0 Bytes';
419
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
420
+ return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i];
421
+ }
422
+
423
+ printSummary() {
424
+ console.log('\n📊 ENHANCED INSTALLATION SUMMARY:');
425
+ console.log('='.repeat(50));
426
+
427
+ if (this.options.dryRun) {
428
+ console.log('🔍 DRY RUN MODE - No actual changes were made');
429
+ }
430
+
431
+ // Cache cleaning summary
432
+ if (this.results.cacheCleaning.success) {
433
+ console.log('🧹 Cache Cleaning: �?);
434
+ console.log(` Duration: ${this.results.cacheCleaning.duration}ms`);
435
+ console.log(
436
+ ` Files removed: ${this.results.cacheCleaning.filesRemoved}`,
437
+ );
438
+ console.log(
439
+ ` Space freed: ${this.formatBytes(this.results.cacheCleaning.bytesFreed)}`,
440
+ );
441
+ } else if (this.results.cacheCleaning.error) {
442
+ console.log(`🧹 Cache Cleaning: �?${this.results.cacheCleaning.error}`);
443
+ }
444
+
445
+ // Installation summary
446
+ if (this.results.installation.success) {
447
+ console.log('📦 Installation: �?);
448
+ if (this.results.installation.installed.length > 0) {
449
+ console.log(
450
+ ` Installed: ${this.results.installation.installed.join(', ')}`,
451
+ );
452
+ } else {
453
+ console.log(` Message: ${this.results.installation.message}`);
454
+ }
455
+ } else if (this.results.installation.error) {
456
+ console.log(`📦 Installation: �?${this.results.installation.error}`);
457
+ }
458
+
459
+ // Verification summary
460
+ if (this.results.verification) {
461
+ console.log('�?Verification: �?);
462
+ console.log(
463
+ ` Newly installed: ${this.results.verification.newlyInstalled.length} tools`,
464
+ );
465
+ }
466
+
467
+ // Errors
468
+ if (this.results.errors.length > 0) {
469
+ console.log(`\n�?Errors encountered: ${this.results.errors.length}`);
470
+ this.results.errors.forEach((error) => {
471
+ console.log(` - ${error}`);
472
+ });
473
+ }
474
+
475
+ console.log('\n🎉 Enhanced installation completed!');
476
+ }
477
+ }
478
+
479
+ module.exports = EnhancedInstaller;