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.
- package/LICENSE +18 -18
- package/README.md +28 -223
- package/STIGMERGY.md +61 -61
- package/docs/PROJECT_CONSTITUTION.md +433 -433
- package/docs/PROJECT_STRUCTURE_CURRENT.md +80 -80
- package/examples/calculator-example.js +72 -72
- package/examples/cline_usage_examples.md +364 -364
- package/examples/encryption-example.js +67 -67
- package/examples/json-parser-example.js +120 -120
- package/examples/json-validation-example.js +64 -64
- package/examples/rest-client-example.js +52 -52
- package/examples/rest_client_example.js +54 -54
- package/package.json +36 -15
- package/scripts/build.js +74 -74
- package/scripts/post-deployment-config.js +296 -296
- package/scripts/preinstall-check.js +173 -173
- package/scripts/publish.js +58 -268
- package/scripts/run-layered-tests.js +247 -0
- package/scripts/safe-install.js +139 -139
- package/scripts/simple-publish.js +57 -59
- package/src/adapters/claude/install_claude_integration.js +292 -0
- package/src/adapters/codebuddy/install_codebuddy_integration.js +349 -0
- package/src/adapters/codex/install_codex_integration.js +395 -0
- package/src/adapters/copilot/install_copilot_integration.js +716 -0
- package/src/adapters/gemini/install_gemini_integration.js +304 -0
- package/src/adapters/iflow/install_iflow_integration.js +304 -0
- package/src/adapters/qoder/install_qoder_integration.js +1090 -0
- package/src/adapters/qwen/install_qwen_integration.js +285 -0
- package/src/auth.js +173 -173
- package/src/auth_command.js +208 -208
- package/src/calculator.js +313 -313
- package/src/cli/router.js +417 -38
- package/src/core/cache_cleaner.js +767 -744
- package/src/core/cli_help_analyzer.js +680 -674
- package/src/core/cli_parameter_handler.js +132 -127
- package/src/core/cli_tools.js +89 -89
- package/src/core/coordination/index.js +16 -16
- package/src/core/coordination/nodejs/AdapterManager.js +102 -89
- package/src/core/coordination/nodejs/CLCommunication.js +132 -124
- package/src/core/coordination/nodejs/CLIIntegrationManager.js +272 -236
- package/src/core/coordination/nodejs/HealthChecker.js +76 -77
- package/src/core/coordination/nodejs/HookDeploymentManager.js +263 -190
- package/src/core/coordination/nodejs/StatisticsCollector.js +71 -71
- package/src/core/coordination/nodejs/index.js +90 -72
- package/src/core/coordination/nodejs/utils/Logger.js +29 -29
- package/src/core/enhanced_installer.js +479 -456
- package/src/core/enhanced_uninstaller.js +638 -618
- package/src/core/error_handler.js +406 -406
- package/src/core/installer.js +815 -294
- package/src/core/memory_manager.js +83 -83
- package/src/core/rest_client.js +160 -160
- package/src/core/smart_router.js +249 -146
- package/src/core/upgrade_manager.js +76 -59
- package/src/data_encryption.js +143 -143
- package/src/data_structures.js +440 -440
- package/src/deploy.js +55 -55
- package/src/index.js +30 -30
- package/src/test/cli-availability-checker.js +194 -0
- package/src/test/test-environment.js +289 -0
- package/src/utils/helpers.js +35 -35
- package/src/utils.js +921 -915
- package/src/weatherProcessor.js +228 -228
- package/test/cache-cleaner-implemented.test.js +0 -328
- package/test/cache-cleaner.test.js +0 -390
- package/test/calculator.test.js +0 -215
- package/test/collision-test.js +0 -26
- package/test/comprehensive-enhanced-features.test.js +0 -252
- package/test/comprehensive-execution-test.js +0 -428
- package/test/conflict-prevention-test.js +0 -95
- package/test/cross-cli-detection-test.js +0 -33
- package/test/csv-processing-test.js +0 -36
- package/test/deploy-hooks-test.js +0 -250
- package/test/e2e/claude-cli-test.js +0 -128
- package/test/e2e/collaboration-test.js +0 -75
- package/test/e2e/comprehensive-test.js +0 -431
- package/test/e2e/error-handling-test.js +0 -90
- package/test/e2e/individual-tool-test.js +0 -143
- package/test/e2e/other-cli-test.js +0 -130
- package/test/e2e/qoder-cli-test.js +0 -128
- package/test/e2e/run-e2e-tests.js +0 -73
- package/test/e2e/test-data.js +0 -88
- package/test/e2e/test-utils.js +0 -222
- package/test/encryption-simple-test.js +0 -110
- package/test/encryption.test.js +0 -129
- package/test/enhanced-main-alignment.test.js +0 -298
- package/test/enhanced-uninstaller-implemented.test.js +0 -271
- package/test/enhanced-uninstaller.test.js +0 -284
- package/test/error-handling-test.js +0 -341
- package/test/fibonacci.test.js +0 -178
- package/test/final-deploy-test.js +0 -221
- package/test/final-install-test.js +0 -226
- package/test/hash-table-demo.js +0 -33
- package/test/hash-table-test.js +0 -26
- package/test/hash_table_test.js +0 -114
- package/test/hook-system-integration-test.js +0 -307
- package/test/iflow-integration-test.js +0 -292
- package/test/improved-install-test.js +0 -362
- package/test/install-command-test.js +0 -370
- package/test/json-parser-test.js +0 -161
- package/test/json-validation-test.js +0 -164
- package/test/natural-language-skills-test.js +0 -320
- package/test/nl-integration-test.js +0 -179
- package/test/parameter-parsing-test.js +0 -143
- package/test/plugin-deployment-test.js +0 -316
- package/test/postinstall-test.js +0 -269
- package/test/python-plugins-test.js +0 -259
- package/test/real-test.js +0 -435
- package/test/remaining-adapters-test.js +0 -256
- package/test/rest-client-test.js +0 -56
- package/test/rest_client.test.js +0 -85
- package/test/safe-installation-cleaner.test.js +0 -343
- package/test/simple-iflow-hook-test.js +0 -137
- package/test/stigmergy-upgrade-test.js +0 -243
- package/test/system-compatibility-test.js +0 -467
- package/test/tdd-deploy-fix-test.js +0 -324
- package/test/tdd-fixes-test.js +0 -211
- package/test/third-party-skills-test.js +0 -321
- package/test/tool-selection-integration-test.js +0 -158
- package/test/unit/calculator-full.test.js +0 -191
- package/test/unit/calculator-simple.test.js +0 -96
- package/test/unit/calculator.test.js +0 -97
- package/test/unit/cli-scanner.test.js +0 -291
- package/test/unit/cli_parameter_handler.test.js +0 -116
- package/test/unit/cross-cli-executor.test.js +0 -399
- package/test/weather-processor.test.js +0 -104
|
@@ -1,618 +1,638 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Stigmergy Uninstaller
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive uninstallation with complete cleanup of all Stigmergy-related files,
|
|
5
|
-
* configurations, caches, and integrations across all supported CLI tools.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
const os = require('os');
|
|
11
|
-
const { spawnSync } = require('child_process');
|
|
12
|
-
|
|
13
|
-
class EnhancedUninstaller {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
this.options = {
|
|
16
|
-
dryRun: options.dryRun || false,
|
|
17
|
-
force: options.force || false,
|
|
18
|
-
verbose: options.verbose || false,
|
|
19
|
-
preserveUserConfigs: options.preserveUserConfigs || false,
|
|
20
|
-
...options
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
this.homeDir = os.homedir();
|
|
24
|
-
this.stigmergyDir = path.join(this.homeDir, '.stigmergy');
|
|
25
|
-
this.stigmergyTestDir = path.join(this.homeDir, '.stigmergy-test');
|
|
26
|
-
|
|
27
|
-
this.supportedCLIs = [
|
|
28
|
-
'claude',
|
|
29
|
-
'
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
this.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
if (
|
|
300
|
-
console.log(`
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
fs.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
fs.
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
'
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Stigmergy Uninstaller
|
|
3
|
+
*
|
|
4
|
+
* Comprehensive uninstallation with complete cleanup of all Stigmergy-related files,
|
|
5
|
+
* configurations, caches, and integrations across all supported CLI tools.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const os = require('os');
|
|
11
|
+
const { spawnSync } = require('child_process');
|
|
12
|
+
|
|
13
|
+
class EnhancedUninstaller {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = {
|
|
16
|
+
dryRun: options.dryRun || false,
|
|
17
|
+
force: options.force || false,
|
|
18
|
+
verbose: options.verbose || false,
|
|
19
|
+
preserveUserConfigs: options.preserveUserConfigs || false,
|
|
20
|
+
...options,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
this.homeDir = os.homedir();
|
|
24
|
+
this.stigmergyDir = path.join(this.homeDir, '.stigmergy');
|
|
25
|
+
this.stigmergyTestDir = path.join(this.homeDir, '.stigmergy-test');
|
|
26
|
+
|
|
27
|
+
this.supportedCLIs = [
|
|
28
|
+
'claude',
|
|
29
|
+
'gemini',
|
|
30
|
+
'qwen',
|
|
31
|
+
'iflow',
|
|
32
|
+
'qodercli',
|
|
33
|
+
'codebuddy',
|
|
34
|
+
'codex',
|
|
35
|
+
'copilot',
|
|
36
|
+
'qwencode',
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
this.results = {
|
|
40
|
+
filesRemoved: 0,
|
|
41
|
+
directoriesRemoved: 0,
|
|
42
|
+
errors: [],
|
|
43
|
+
skipped: [],
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Perform complete uninstallation
|
|
49
|
+
*/
|
|
50
|
+
async completeUninstall() {
|
|
51
|
+
console.log('šļæ½? Starting Enhanced Stigmergy Uninstall...\n');
|
|
52
|
+
|
|
53
|
+
if (this.options.dryRun) {
|
|
54
|
+
console.log('š DRY RUN MODE - No files will be deleted\n');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// 1. Clean Stigmergy main directory
|
|
59
|
+
await this.cleanStigmergyDirectory();
|
|
60
|
+
|
|
61
|
+
// 2. Clean test directory
|
|
62
|
+
await this.cleanTestDirectory();
|
|
63
|
+
|
|
64
|
+
// 3. Clean CLI configurations
|
|
65
|
+
await this.cleanCLIConfigurations();
|
|
66
|
+
|
|
67
|
+
// 4. Clean NPX cache
|
|
68
|
+
await this.cleanNPXCache();
|
|
69
|
+
|
|
70
|
+
// 5. Clean temporary files
|
|
71
|
+
await this.cleanTemporaryFiles();
|
|
72
|
+
|
|
73
|
+
// 6. Uninstall global packages (if requested)
|
|
74
|
+
if (this.options.uninstallGlobal) {
|
|
75
|
+
await this.uninstallGlobalPackages();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 7. Print summary
|
|
79
|
+
this.printSummary();
|
|
80
|
+
|
|
81
|
+
return this.results;
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('ļæ½?Uninstall failed:', error.message);
|
|
84
|
+
this.results.errors.push(error.message);
|
|
85
|
+
return this.results;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Create uninstall plan without executing
|
|
91
|
+
*/
|
|
92
|
+
async createUninstallPlan() {
|
|
93
|
+
console.log('š Creating Uninstall Plan...\n');
|
|
94
|
+
|
|
95
|
+
const plan = {
|
|
96
|
+
directories: [],
|
|
97
|
+
files: [],
|
|
98
|
+
globalPackages: [],
|
|
99
|
+
cliConfigurations: [],
|
|
100
|
+
estimatedSize: 0,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// Scan Stigmergy directory
|
|
104
|
+
if (fs.existsSync(this.stigmergyDir)) {
|
|
105
|
+
await this.scanDirectory(this.stigmergyDir, plan);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Scan test directory
|
|
109
|
+
if (fs.existsSync(this.stigmergyTestDir)) {
|
|
110
|
+
await this.scanDirectory(this.stigmergyTestDir, plan);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Scan CLI configurations
|
|
114
|
+
for (const cli of this.supportedCLIs) {
|
|
115
|
+
const cliConfig = path.join(this.homeDir, `.${cli}`);
|
|
116
|
+
if (fs.existsSync(cliConfig)) {
|
|
117
|
+
const stigmergyFiles = await this.findStigmergyFiles(cliConfig);
|
|
118
|
+
plan.cliConfigurations.push({
|
|
119
|
+
cli,
|
|
120
|
+
files: stigmergyFiles,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Calculate estimated size
|
|
126
|
+
plan.estimatedSize = await this.calculateDirectorySize([
|
|
127
|
+
this.stigmergyDir,
|
|
128
|
+
this.stigmergyTestDir,
|
|
129
|
+
...plan.cliConfigurations.flatMap((c) => c.files),
|
|
130
|
+
]);
|
|
131
|
+
|
|
132
|
+
return plan;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Clean Stigmergy main directory
|
|
137
|
+
*/
|
|
138
|
+
async cleanStigmergyDirectory() {
|
|
139
|
+
console.log('š Cleaning Stigmergy directory...');
|
|
140
|
+
|
|
141
|
+
if (!fs.existsSync(this.stigmergyDir)) {
|
|
142
|
+
console.log(' ā¹ļø Stigmergy directory not found');
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const files = await this.getAllFiles(this.stigmergyDir);
|
|
147
|
+
|
|
148
|
+
if (this.options.dryRun) {
|
|
149
|
+
console.log(` š Would remove ${files.length} files and directories`);
|
|
150
|
+
this.logFiles(files, ' ');
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
await this.removeDirectory(this.stigmergyDir);
|
|
156
|
+
console.log(` ļæ½?Removed ${files.length} files and directories`);
|
|
157
|
+
this.results.filesRemoved += files.length;
|
|
158
|
+
this.results.directoriesRemoved++;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
console.error(
|
|
161
|
+
` ļæ½?Failed to remove Stigmergy directory: ${error.message}`,
|
|
162
|
+
);
|
|
163
|
+
this.results.errors.push(`Stigmergy directory: ${error.message}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Clean test directory
|
|
169
|
+
*/
|
|
170
|
+
async cleanTestDirectory() {
|
|
171
|
+
console.log('š§Ŗ Cleaning test directory...');
|
|
172
|
+
|
|
173
|
+
if (!fs.existsSync(this.stigmergyTestDir)) {
|
|
174
|
+
console.log(' ā¹ļø Test directory not found');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (this.options.dryRun) {
|
|
179
|
+
console.log(' š Would remove test directory');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
await this.removeDirectory(this.stigmergyTestDir);
|
|
185
|
+
console.log(' ļæ½?Removed test directory');
|
|
186
|
+
this.results.directoriesRemoved++;
|
|
187
|
+
} catch (error) {
|
|
188
|
+
console.error(` ļæ½?Failed to remove test directory: ${error.message}`);
|
|
189
|
+
this.results.errors.push(`Test directory: ${error.message}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Clean CLI configurations
|
|
195
|
+
*/
|
|
196
|
+
async cleanCLIConfigurations() {
|
|
197
|
+
console.log('āļø Cleaning CLI configurations...');
|
|
198
|
+
|
|
199
|
+
let totalCleaned = 0;
|
|
200
|
+
|
|
201
|
+
for (const cli of this.supportedCLIs) {
|
|
202
|
+
const cliConfig = path.join(this.homeDir, `.${cli}`);
|
|
203
|
+
|
|
204
|
+
if (!fs.existsSync(cliConfig)) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const stigmergyFiles = await this.findStigmergyFiles(cliConfig);
|
|
209
|
+
|
|
210
|
+
if (stigmergyFiles.length === 0) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
console.log(` š ${cli}: ${stigmergyFiles.length} Stigmergy files`);
|
|
215
|
+
|
|
216
|
+
if (this.options.dryRun) {
|
|
217
|
+
this.logFiles(stigmergyFiles, ' š ');
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
for (const file of stigmergyFiles) {
|
|
223
|
+
await this.removeFile(file);
|
|
224
|
+
totalCleaned++;
|
|
225
|
+
}
|
|
226
|
+
console.log(` ļæ½?Cleaned ${stigmergyFiles.length} files`);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.error(` ļæ½?Failed to clean ${cli}: ${error.message}`);
|
|
229
|
+
this.results.errors.push(`${cli} config: ${error.message}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (!this.options.dryRun && totalCleaned > 0) {
|
|
234
|
+
console.log(` ļæ½?Cleaned ${totalCleaned} CLI configuration files`);
|
|
235
|
+
this.results.filesRemoved += totalCleaned;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Clean NPX cache
|
|
241
|
+
*/
|
|
242
|
+
async cleanNPXCache() {
|
|
243
|
+
console.log('š¦ Cleaning NPX cache...');
|
|
244
|
+
|
|
245
|
+
const npxCacheDirs = await this.findNPXCacheDirectories();
|
|
246
|
+
|
|
247
|
+
if (npxCacheDirs.length === 0) {
|
|
248
|
+
console.log(' ā¹ļø No Stigmergy entries in NPX cache');
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
console.log(
|
|
253
|
+
` š¦ Found ${npxCacheDirs.length} Stigmergy entries in NPX cache`,
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
if (this.options.dryRun) {
|
|
257
|
+
this.logFiles(npxCacheDirs, ' š ');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let removed = 0;
|
|
262
|
+
for (const cacheDir of npxCacheDirs) {
|
|
263
|
+
try {
|
|
264
|
+
await this.removeDirectory(cacheDir);
|
|
265
|
+
removed++;
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.error(` ļæ½?Failed to remove ${cacheDir}: ${error.message}`);
|
|
268
|
+
this.results.errors.push(`NPX cache: ${error.message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (removed > 0) {
|
|
273
|
+
console.log(` ļæ½?Removed ${removed} NPX cache entries`);
|
|
274
|
+
this.results.directoriesRemoved += removed;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Clean temporary files
|
|
280
|
+
*/
|
|
281
|
+
async cleanTemporaryFiles() {
|
|
282
|
+
console.log('šļæ½? Cleaning temporary files...');
|
|
283
|
+
|
|
284
|
+
const tempDirs = [
|
|
285
|
+
path.join(os.tmpdir()),
|
|
286
|
+
path.join(this.homeDir, 'AppData', 'Local', 'Temp'),
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
let totalRemoved = 0;
|
|
290
|
+
|
|
291
|
+
for (const tempDir of tempDirs) {
|
|
292
|
+
if (!fs.existsSync(tempDir)) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
try {
|
|
297
|
+
const tempFiles = await this.findStigmergyTempFiles(tempDir);
|
|
298
|
+
|
|
299
|
+
if (this.options.dryRun) {
|
|
300
|
+
console.log(` š ${tempDir}: ${tempFiles.length} temporary files`);
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
for (const file of tempFiles) {
|
|
305
|
+
await this.removeFile(file);
|
|
306
|
+
totalRemoved++;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (tempFiles.length > 0) {
|
|
310
|
+
console.log(
|
|
311
|
+
` ļæ½?${path.basename(tempDir)}: removed ${tempFiles.length} files`,
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
} catch (error) {
|
|
315
|
+
console.error(` ļæ½?Failed to clean ${tempDir}: ${error.message}`);
|
|
316
|
+
this.results.errors.push(`Temp files: ${error.message}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (!this.options.dryRun && totalRemoved > 0) {
|
|
321
|
+
console.log(` ļæ½?Removed ${totalRemoved} temporary files`);
|
|
322
|
+
this.results.filesRemoved += totalRemoved;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* Uninstall global packages
|
|
328
|
+
*/
|
|
329
|
+
async uninstallGlobalPackages() {
|
|
330
|
+
console.log('š Uninstalling global packages...');
|
|
331
|
+
|
|
332
|
+
const globalPackages = ['stigmergy-cli', 'stigmergy'];
|
|
333
|
+
|
|
334
|
+
for (const pkg of globalPackages) {
|
|
335
|
+
try {
|
|
336
|
+
const result = spawnSync('npm', ['list', '-g', pkg], {
|
|
337
|
+
encoding: 'utf8',
|
|
338
|
+
shell: true,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
if (result.status === 0 && result.stdout.includes(pkg)) {
|
|
342
|
+
console.log(` š¦ Found global package: ${pkg}`);
|
|
343
|
+
|
|
344
|
+
if (this.options.dryRun) {
|
|
345
|
+
console.log(` š Would uninstall: ${pkg}`);
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
const uninstallResult = spawnSync('npm', ['uninstall', '-g', pkg], {
|
|
350
|
+
encoding: 'utf8',
|
|
351
|
+
shell: true,
|
|
352
|
+
stdio: 'inherit',
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
if (uninstallResult.status === 0) {
|
|
356
|
+
console.log(` ļæ½?Uninstalled: ${pkg}`);
|
|
357
|
+
} else {
|
|
358
|
+
console.log(` ā ļø Failed to uninstall: ${pkg}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
} catch (error) {
|
|
362
|
+
console.error(` ļæ½?Error checking ${pkg}: ${error.message}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Helper methods
|
|
369
|
+
*/
|
|
370
|
+
async removeDirectory(dirPath) {
|
|
371
|
+
try {
|
|
372
|
+
if (!fs.existsSync(dirPath)) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
if (this.options.verbose) {
|
|
377
|
+
console.log(` Removing directory: ${dirPath}`);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
fs.rmSync(dirPath, { recursive: true, force: true, maxRetries: 3 });
|
|
381
|
+
return true;
|
|
382
|
+
} catch (error) {
|
|
383
|
+
if (!this.options.force) {
|
|
384
|
+
throw error;
|
|
385
|
+
}
|
|
386
|
+
this.results.skipped.push(`Directory: ${dirPath} (${error.message})`);
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
async removeFile(filePath) {
|
|
392
|
+
try {
|
|
393
|
+
if (!fs.existsSync(filePath)) {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
if (this.options.verbose) {
|
|
398
|
+
console.log(` Removing file: ${filePath}`);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
fs.unlinkSync(filePath);
|
|
402
|
+
return true;
|
|
403
|
+
} catch (error) {
|
|
404
|
+
if (!this.options.force) {
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
this.results.skipped.push(`File: ${filePath} (${error.message})`);
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async getAllFiles(dirPath) {
|
|
413
|
+
const files = [];
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
const items = fs.readdirSync(dirPath);
|
|
417
|
+
|
|
418
|
+
for (const item of items) {
|
|
419
|
+
const fullPath = path.join(dirPath, item);
|
|
420
|
+
const stat = fs.statSync(fullPath);
|
|
421
|
+
|
|
422
|
+
if (stat.isDirectory()) {
|
|
423
|
+
files.push(...(await this.getAllFiles(fullPath)));
|
|
424
|
+
files.push(fullPath);
|
|
425
|
+
} else {
|
|
426
|
+
files.push(fullPath);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
files.push(dirPath);
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.warn(`Warning: Could not read ${dirPath}: ${error.message}`);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return files;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async findStigmergyFiles(dirPath) {
|
|
439
|
+
const stigmergyFiles = [];
|
|
440
|
+
|
|
441
|
+
try {
|
|
442
|
+
const files = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
443
|
+
|
|
444
|
+
for (const file of files) {
|
|
445
|
+
const fullPath = path.join(dirPath, file.name);
|
|
446
|
+
|
|
447
|
+
if (file.isDirectory()) {
|
|
448
|
+
stigmergyFiles.push(...(await this.findStigmergyFiles(fullPath)));
|
|
449
|
+
} else if (this.isStigmergyFile(file.name)) {
|
|
450
|
+
stigmergyFiles.push(fullPath);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
} catch (error) {
|
|
454
|
+
// Skip directories we can't read
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return stigmergyFiles;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
isStigmergyFile(fileName) {
|
|
461
|
+
const stigmergyPatterns = [
|
|
462
|
+
'stigmergy',
|
|
463
|
+
'cross-cli',
|
|
464
|
+
'hook',
|
|
465
|
+
'integration',
|
|
466
|
+
'.stigmergy',
|
|
467
|
+
];
|
|
468
|
+
|
|
469
|
+
const lowerFileName = fileName.toLowerCase();
|
|
470
|
+
return stigmergyPatterns.some((pattern) =>
|
|
471
|
+
lowerFileName.includes(pattern.toLowerCase()),
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
async findNPXCacheDirectories() {
|
|
476
|
+
const cacheDirs = [];
|
|
477
|
+
const npxCacheBase = path.join(
|
|
478
|
+
this.homeDir,
|
|
479
|
+
'AppData',
|
|
480
|
+
'Local',
|
|
481
|
+
'npm-cache',
|
|
482
|
+
'_npx',
|
|
483
|
+
);
|
|
484
|
+
|
|
485
|
+
if (!fs.existsSync(npxCacheBase)) {
|
|
486
|
+
// Try alternative locations
|
|
487
|
+
const alternatives = [
|
|
488
|
+
path.join(this.homeDir, '.npm', '_npx'),
|
|
489
|
+
path.join(os.tmpdir(), 'npm-cache', '_npx'),
|
|
490
|
+
];
|
|
491
|
+
|
|
492
|
+
for (const alt of alternatives) {
|
|
493
|
+
if (fs.existsSync(alt)) {
|
|
494
|
+
npxCacheBase = alt;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (fs.existsSync(npxCacheBase)) {
|
|
501
|
+
try {
|
|
502
|
+
const entries = fs.readdirSync(npxCacheBase);
|
|
503
|
+
|
|
504
|
+
for (const entry of entries) {
|
|
505
|
+
const entryPath = path.join(npxCacheBase, entry);
|
|
506
|
+
const stigmergyPath = path.join(
|
|
507
|
+
entryPath,
|
|
508
|
+
'node_modules',
|
|
509
|
+
'stigmergy',
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
if (fs.existsSync(stigmergyPath)) {
|
|
513
|
+
cacheDirs.push(entryPath);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
} catch (error) {
|
|
517
|
+
console.warn(`Warning: Could not scan NPX cache: ${error.message}`);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return cacheDirs;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
async findStigmergyTempFiles(tempDir) {
|
|
525
|
+
const tempFiles = [];
|
|
526
|
+
|
|
527
|
+
try {
|
|
528
|
+
const files = fs.readdirSync(tempDir, { withFileTypes: true });
|
|
529
|
+
|
|
530
|
+
for (const file of files) {
|
|
531
|
+
if (
|
|
532
|
+
this.isStigmergyFile(file.name) ||
|
|
533
|
+
file.name.startsWith('stigmergy-') ||
|
|
534
|
+
file.name.includes('stigmergy')
|
|
535
|
+
) {
|
|
536
|
+
const fullPath = path.join(tempDir, file.name);
|
|
537
|
+
|
|
538
|
+
if (file.isDirectory()) {
|
|
539
|
+
tempFiles.push(fullPath);
|
|
540
|
+
} else {
|
|
541
|
+
tempFiles.push(fullPath);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
} catch (error) {
|
|
546
|
+
// Skip temp directories we can't read
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
return tempFiles;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
async scanDirectory(dirPath, plan) {
|
|
553
|
+
try {
|
|
554
|
+
const stat = fs.statSync(dirPath);
|
|
555
|
+
|
|
556
|
+
if (stat.isDirectory()) {
|
|
557
|
+
const files = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
558
|
+
|
|
559
|
+
for (const file of files) {
|
|
560
|
+
const fullPath = path.join(dirPath, file.name);
|
|
561
|
+
|
|
562
|
+
if (file.isDirectory()) {
|
|
563
|
+
plan.directories.push(fullPath);
|
|
564
|
+
await this.scanDirectory(fullPath, plan);
|
|
565
|
+
} else {
|
|
566
|
+
plan.files.push(fullPath);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
plan.files.push(dirPath);
|
|
571
|
+
}
|
|
572
|
+
} catch (error) {
|
|
573
|
+
console.warn(`Warning: Could not scan ${dirPath}: ${error.message}`);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
async calculateDirectorySize(paths) {
|
|
578
|
+
let totalSize = 0;
|
|
579
|
+
|
|
580
|
+
for (const filePath of paths) {
|
|
581
|
+
try {
|
|
582
|
+
if (fs.existsSync(filePath)) {
|
|
583
|
+
const stat = fs.statSync(filePath);
|
|
584
|
+
totalSize += stat.size;
|
|
585
|
+
}
|
|
586
|
+
} catch (error) {
|
|
587
|
+
// Skip files we can't stat
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
return totalSize;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
formatBytes(bytes) {
|
|
595
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
596
|
+
if (bytes === 0) return '0 Bytes';
|
|
597
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
598
|
+
return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i];
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
logFiles(files, prefix = '') {
|
|
602
|
+
files.forEach((file) => {
|
|
603
|
+
console.log(`${prefix}${path.basename(file)}`);
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
printSummary() {
|
|
608
|
+
console.log('\nš UNINSTALL SUMMARY:');
|
|
609
|
+
console.log('='.repeat(50));
|
|
610
|
+
|
|
611
|
+
if (this.options.dryRun) {
|
|
612
|
+
console.log('š DRY RUN MODE - No files were actually deleted');
|
|
613
|
+
} else {
|
|
614
|
+
console.log(`š Directories removed: ${this.results.directoriesRemoved}`);
|
|
615
|
+
console.log(`š Files removed: ${this.results.filesRemoved}`);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (this.results.skipped.length > 0) {
|
|
619
|
+
console.log(`āļø Items skipped: ${this.results.skipped.length}`);
|
|
620
|
+
if (this.options.verbose) {
|
|
621
|
+
this.results.skipped.forEach((item) => {
|
|
622
|
+
console.log(` ${item}`);
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (this.results.errors.length > 0) {
|
|
628
|
+
console.log(`ļæ½?Errors: ${this.results.errors.length}`);
|
|
629
|
+
this.results.errors.forEach((error) => {
|
|
630
|
+
console.log(` ${error}`);
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
console.log('\nļæ½?Enhanced uninstall completed!');
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
module.exports = EnhancedUninstaller;
|