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,744 +1,767 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Comprehensive Cache Cleaner for Stigmergy
|
|
3
|
-
*
|
|
4
|
-
* Intelligent cache cleaning with selective removal, performance optimization,
|
|
5
|
-
* and error recovery capabilities.
|
|
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 CacheCleaner {
|
|
14
|
-
constructor(options = {}) {
|
|
15
|
-
this.options = {
|
|
16
|
-
dryRun: options.dryRun || false,
|
|
17
|
-
force: options.force || false,
|
|
18
|
-
verbose: options.verbose || false,
|
|
19
|
-
preserveRecent: options.preserveRecent || 24 * 60 * 60 * 1000, // 24 hours
|
|
20
|
-
batchSize: options.batchSize || 50,
|
|
21
|
-
parallel: options.parallel || true,
|
|
22
|
-
...options
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
this.homeDir = os.homedir();
|
|
26
|
-
this.results = {
|
|
27
|
-
filesRemoved: 0,
|
|
28
|
-
directoriesRemoved: 0,
|
|
29
|
-
bytesFreed: 0,
|
|
30
|
-
errors: [],
|
|
31
|
-
skipped: []
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Clean all caches comprehensively
|
|
37
|
-
*/
|
|
38
|
-
async cleanAllCaches(options = {}) {
|
|
39
|
-
const config = {
|
|
40
|
-
cleanStigmergy: true,
|
|
41
|
-
cleanNPX: true,
|
|
42
|
-
cleanNPM: true,
|
|
43
|
-
cleanCLI: true,
|
|
44
|
-
cleanTemp: true,
|
|
45
|
-
...options
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
console.log('š§¹ Starting Comprehensive Cache Cleaning...\n');
|
|
49
|
-
|
|
50
|
-
if (this.options.dryRun) {
|
|
51
|
-
console.log('š DRY RUN MODE - No files will be deleted\n');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
try {
|
|
55
|
-
// 1. Clean Stigmergy cache
|
|
56
|
-
if (config.cleanStigmergy) {
|
|
57
|
-
await this.cleanStigmergyCache();
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// 2. Clean NPX cache
|
|
61
|
-
if (config.cleanNPX) {
|
|
62
|
-
await this.cleanNPXCache();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// 3. Clean NPM cache
|
|
66
|
-
if (config.cleanNPM) {
|
|
67
|
-
await this.cleanNPMCache();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// 4. Clean CLI configurations
|
|
71
|
-
if (config.cleanCLI) {
|
|
72
|
-
await this.cleanCLIConfigurations();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 5. Clean temporary files
|
|
76
|
-
if (config.cleanTemp) {
|
|
77
|
-
await this.cleanTemporaryFiles();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// 6. Print summary
|
|
81
|
-
this.printSummary();
|
|
82
|
-
|
|
83
|
-
return this.results;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.results
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
path.join(stigmergyDir, '
|
|
114
|
-
path.join(stigmergyDir, '
|
|
115
|
-
path.join(stigmergyDir, '
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
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
|
-
|
|
300
|
-
|
|
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
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const
|
|
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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
if (
|
|
482
|
-
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
if (
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
return false;
|
|
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
|
-
return
|
|
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
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
try {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
console.log(
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive Cache Cleaner for Stigmergy
|
|
3
|
+
*
|
|
4
|
+
* Intelligent cache cleaning with selective removal, performance optimization,
|
|
5
|
+
* and error recovery capabilities.
|
|
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 CacheCleaner {
|
|
14
|
+
constructor(options = {}) {
|
|
15
|
+
this.options = {
|
|
16
|
+
dryRun: options.dryRun || false,
|
|
17
|
+
force: options.force || false,
|
|
18
|
+
verbose: options.verbose || false,
|
|
19
|
+
preserveRecent: options.preserveRecent || 24 * 60 * 60 * 1000, // 24 hours
|
|
20
|
+
batchSize: options.batchSize || 50,
|
|
21
|
+
parallel: options.parallel || true,
|
|
22
|
+
...options,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
this.homeDir = os.homedir();
|
|
26
|
+
this.results = {
|
|
27
|
+
filesRemoved: 0,
|
|
28
|
+
directoriesRemoved: 0,
|
|
29
|
+
bytesFreed: 0,
|
|
30
|
+
errors: [],
|
|
31
|
+
skipped: [],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Clean all caches comprehensively
|
|
37
|
+
*/
|
|
38
|
+
async cleanAllCaches(options = {}) {
|
|
39
|
+
const config = {
|
|
40
|
+
cleanStigmergy: true,
|
|
41
|
+
cleanNPX: true,
|
|
42
|
+
cleanNPM: true,
|
|
43
|
+
cleanCLI: true,
|
|
44
|
+
cleanTemp: true,
|
|
45
|
+
...options,
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
console.log('š§¹ Starting Comprehensive Cache Cleaning...\n');
|
|
49
|
+
|
|
50
|
+
if (this.options.dryRun) {
|
|
51
|
+
console.log('š DRY RUN MODE - No files will be deleted\n');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
try {
|
|
55
|
+
// 1. Clean Stigmergy cache
|
|
56
|
+
if (config.cleanStigmergy) {
|
|
57
|
+
await this.cleanStigmergyCache();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2. Clean NPX cache
|
|
61
|
+
if (config.cleanNPX) {
|
|
62
|
+
await this.cleanNPXCache();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 3. Clean NPM cache
|
|
66
|
+
if (config.cleanNPM) {
|
|
67
|
+
await this.cleanNPMCache();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// 4. Clean CLI configurations
|
|
71
|
+
if (config.cleanCLI) {
|
|
72
|
+
await this.cleanCLIConfigurations();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 5. Clean temporary files
|
|
76
|
+
if (config.cleanTemp) {
|
|
77
|
+
await this.cleanTemporaryFiles();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 6. Print summary
|
|
81
|
+
this.printSummary();
|
|
82
|
+
|
|
83
|
+
return this.results;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error('ļæ½?Cache cleaning failed:', error.message);
|
|
86
|
+
this.results.errors.push(error.message);
|
|
87
|
+
return this.results;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Clean Stigmergy cache and temporary files
|
|
93
|
+
*/
|
|
94
|
+
async cleanStigmergyCache() {
|
|
95
|
+
console.log('š Cleaning Stigmergy cache...');
|
|
96
|
+
|
|
97
|
+
const stigmergyDir = path.join(this.homeDir, '.stigmergy');
|
|
98
|
+
const testDir = path.join(this.homeDir, '.stigmergy-test');
|
|
99
|
+
|
|
100
|
+
// Clean main cache directory
|
|
101
|
+
if (fs.existsSync(stigmergyDir)) {
|
|
102
|
+
await this.cleanStigmergyDirectory(stigmergyDir, 'main');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Clean test directory
|
|
106
|
+
if (fs.existsSync(testDir)) {
|
|
107
|
+
await this.cleanStigmergyDirectory(testDir, 'test');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Clean cache subdirectories specifically
|
|
111
|
+
const cachePaths = [
|
|
112
|
+
path.join(stigmergyDir, 'cache'),
|
|
113
|
+
path.join(stigmergyDir, 'logs'),
|
|
114
|
+
path.join(stigmergyDir, 'temp'),
|
|
115
|
+
path.join(stigmergyDir, '.tmp'),
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
for (const cachePath of cachePaths) {
|
|
119
|
+
if (fs.existsSync(cachePath)) {
|
|
120
|
+
await this.cleanDirectory(cachePath);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
console.log('ļæ½?Stigmergy cache cleaning completed');
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Clean a specific Stigmergy directory
|
|
129
|
+
*/
|
|
130
|
+
async cleanStigmergyDirectory(dirPath, type) {
|
|
131
|
+
console.log(` š Cleaning ${type} directory...`);
|
|
132
|
+
|
|
133
|
+
const files = await this.scanDirectory(dirPath);
|
|
134
|
+
const recentFiles = this.filterRecentFiles(files);
|
|
135
|
+
|
|
136
|
+
if (recentFiles.length === 0) {
|
|
137
|
+
console.log(` ā¹ļø No recent files to clean in ${type} directory`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log(` š Found ${recentFiles.length} files to clean`);
|
|
142
|
+
|
|
143
|
+
if (this.options.dryRun) {
|
|
144
|
+
this.logFiles(recentFiles, ' š ');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const removed = await this.batchRemoveFiles(recentFiles);
|
|
149
|
+
console.log(` ļæ½?Removed ${removed} files from ${type} directory`);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Clean NPX cache of Stigmergy entries
|
|
154
|
+
*/
|
|
155
|
+
async cleanNPXCache() {
|
|
156
|
+
console.log('š¦ Cleaning NPX cache...');
|
|
157
|
+
|
|
158
|
+
const npxCacheDirs = await this.findNPXCacheDirectories();
|
|
159
|
+
|
|
160
|
+
if (npxCacheDirs.length === 0) {
|
|
161
|
+
console.log(' ā¹ļø No Stigmergy entries in NPX cache');
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log(` š¦ Found ${npxCacheDirs.length} Stigmergy cache entries`);
|
|
166
|
+
|
|
167
|
+
if (this.options.dryRun) {
|
|
168
|
+
this.logFiles(npxCacheDirs, ' š ');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let removed = 0;
|
|
173
|
+
const failed = [];
|
|
174
|
+
|
|
175
|
+
for (const cacheDir of npxCacheDirs) {
|
|
176
|
+
try {
|
|
177
|
+
const size = await this.getDirectorySize(cacheDir);
|
|
178
|
+
await this.removeDirectory(cacheDir);
|
|
179
|
+
this.results.bytesFreed += size;
|
|
180
|
+
removed++;
|
|
181
|
+
} catch (error) {
|
|
182
|
+
failed.push(cacheDir);
|
|
183
|
+
this.results.errors.push(`NPX cache ${cacheDir}: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
console.log(` ļæ½?Removed ${removed} NPX cache entries`);
|
|
188
|
+
if (failed.length > 0) {
|
|
189
|
+
console.log(` ā ļø Failed to remove ${failed.length} entries`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Clean NPM cache
|
|
195
|
+
*/
|
|
196
|
+
async cleanNPMCache() {
|
|
197
|
+
console.log('š¦ Cleaning NPM cache...');
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
// Use npm cache clean command
|
|
201
|
+
if (this.options.dryRun) {
|
|
202
|
+
console.log(' š Would run: npm cache clean --force');
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const result = spawnSync('npm', ['cache', 'clean', '--force'], {
|
|
207
|
+
encoding: 'utf8',
|
|
208
|
+
shell: true,
|
|
209
|
+
stdio: this.options.verbose ? 'inherit' : 'pipe',
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
if (result.status === 0) {
|
|
213
|
+
console.log(' ļæ½?NPM cache cleaned successfully');
|
|
214
|
+
} else {
|
|
215
|
+
console.log(' ā ļø NPM cache clean failed, trying manual cleanup');
|
|
216
|
+
await this.manualNPMCacheClean();
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error(` ļæ½?Failed to clean NPM cache: ${error.message}`);
|
|
220
|
+
this.results.errors.push(`NPM cache: ${error.message}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Manual NPM cache cleaning fallback
|
|
226
|
+
*/
|
|
227
|
+
async manualNPMCacheClean() {
|
|
228
|
+
const npmCacheDirs = [
|
|
229
|
+
path.join(this.homeDir, '.npm', '_cacache'),
|
|
230
|
+
path.join(this.homeDir, 'AppData', 'Local', 'npm-cache', '_cacache'),
|
|
231
|
+
];
|
|
232
|
+
|
|
233
|
+
for (const cacheDir of npmCacheDirs) {
|
|
234
|
+
if (fs.existsSync(cacheDir)) {
|
|
235
|
+
console.log(` š§¹ Manual cleanup of ${cacheDir}`);
|
|
236
|
+
await this.cleanDirectory(cacheDir);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Clean CLI configurations
|
|
243
|
+
*/
|
|
244
|
+
async cleanCLIConfigurations() {
|
|
245
|
+
console.log('āļø Cleaning CLI configurations...');
|
|
246
|
+
|
|
247
|
+
const supportedCLIs = [
|
|
248
|
+
'claude',
|
|
249
|
+
'gemini',
|
|
250
|
+
'qwen',
|
|
251
|
+
'iflow',
|
|
252
|
+
'qodercli',
|
|
253
|
+
'codebuddy',
|
|
254
|
+
'codex',
|
|
255
|
+
'copilot',
|
|
256
|
+
'qwencode',
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
let totalCleaned = 0;
|
|
260
|
+
|
|
261
|
+
for (const cli of supportedCLIs) {
|
|
262
|
+
const cliConfig = path.join(this.homeDir, `.${cli}`);
|
|
263
|
+
|
|
264
|
+
if (!fs.existsSync(cliConfig)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
const stigmergyFiles = await this.findStigmergyFiles(cliConfig);
|
|
269
|
+
|
|
270
|
+
if (stigmergyFiles.length === 0) {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
console.log(` š ${cli}: ${stigmergyFiles.length} Stigmergy files`);
|
|
275
|
+
|
|
276
|
+
if (this.options.dryRun) {
|
|
277
|
+
this.logFiles(stigmergyFiles, ' š ');
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const removed = await this.batchRemoveFiles(stigmergyFiles);
|
|
282
|
+
totalCleaned += removed;
|
|
283
|
+
|
|
284
|
+
if (removed > 0) {
|
|
285
|
+
console.log(` ļæ½?Cleaned ${removed} files from ${cli}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (totalCleaned > 0) {
|
|
290
|
+
console.log(` ļæ½?Cleaned ${totalCleaned} CLI configuration files`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Clean temporary files
|
|
296
|
+
*/
|
|
297
|
+
async cleanTemporaryFiles() {
|
|
298
|
+
console.log('šļæ½? Cleaning temporary files...');
|
|
299
|
+
|
|
300
|
+
const tempDirs = [
|
|
301
|
+
os.tmpdir(),
|
|
302
|
+
path.join(this.homeDir, 'AppData', 'Local', 'Temp'),
|
|
303
|
+
path.join(this.homeDir, 'AppData', 'Local', 'npm-cache', '_tmp'),
|
|
304
|
+
];
|
|
305
|
+
|
|
306
|
+
let totalRemoved = 0;
|
|
307
|
+
|
|
308
|
+
for (const tempDir of tempDirs) {
|
|
309
|
+
if (!fs.existsSync(tempDir)) {
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const tempFiles = await this.findStigmergyTempFiles(tempDir);
|
|
314
|
+
|
|
315
|
+
if (tempFiles.length === 0) {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
console.log(
|
|
320
|
+
` š ${path.basename(tempDir)}: ${tempFiles.length} temporary files`,
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
if (this.options.dryRun) {
|
|
324
|
+
this.logFiles(tempFiles.slice(0, 5), ' š ');
|
|
325
|
+
if (tempFiles.length > 5) {
|
|
326
|
+
console.log(` ... and ${tempFiles.length - 5} more`);
|
|
327
|
+
}
|
|
328
|
+
continue;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
const removed = await this.batchRemoveFiles(tempFiles);
|
|
332
|
+
totalRemoved += removed;
|
|
333
|
+
|
|
334
|
+
if (removed > 0) {
|
|
335
|
+
console.log(
|
|
336
|
+
` ļæ½?Removed ${removed} files from ${path.basename(tempDir)}`,
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (totalRemoved > 0) {
|
|
342
|
+
console.log(` ļæ½?Removed ${totalRemoved} temporary files`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Selective cleaning with patterns
|
|
348
|
+
*/
|
|
349
|
+
async selectiveClean(targetDirectory, options = {}) {
|
|
350
|
+
const {
|
|
351
|
+
preservePatterns = [],
|
|
352
|
+
removePatterns = [],
|
|
353
|
+
preserveRecent = this.options.preserveRecent,
|
|
354
|
+
} = options;
|
|
355
|
+
|
|
356
|
+
console.log(`šÆ Selective cleaning: ${targetDirectory}`);
|
|
357
|
+
|
|
358
|
+
if (!fs.existsSync(targetDirectory)) {
|
|
359
|
+
console.log(' ā¹ļø Directory not found');
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const allFiles = await this.scanDirectory(targetDirectory);
|
|
364
|
+
const filesToRemove = [];
|
|
365
|
+
|
|
366
|
+
for (const file of allFiles) {
|
|
367
|
+
// Check preserve patterns
|
|
368
|
+
const shouldPreserve =
|
|
369
|
+
preservePatterns.some((pattern) => this.matchPattern(file, pattern)) ||
|
|
370
|
+
this.isRecentFile(file, preserveRecent);
|
|
371
|
+
|
|
372
|
+
// Check remove patterns
|
|
373
|
+
const shouldRemove = removePatterns.some((pattern) =>
|
|
374
|
+
this.matchPattern(file, pattern),
|
|
375
|
+
);
|
|
376
|
+
|
|
377
|
+
if (shouldRemove && !shouldPreserve) {
|
|
378
|
+
filesToRemove.push(file);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
console.log(` š Found ${filesToRemove.length} files to remove`);
|
|
383
|
+
|
|
384
|
+
if (this.options.dryRun) {
|
|
385
|
+
this.logFiles(filesToRemove, ' š ');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const removed = await this.batchRemoveFiles(filesToRemove);
|
|
390
|
+
console.log(` ļæ½?Selectively removed ${removed} files`);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Performance-optimized cleaning
|
|
395
|
+
*/
|
|
396
|
+
async cleanWithPerformance(targetDirectory, options = {}) {
|
|
397
|
+
const {
|
|
398
|
+
batchSize = this.options.batchSize,
|
|
399
|
+
parallel = this.options.parallel,
|
|
400
|
+
maxConcurrency = 4,
|
|
401
|
+
} = options;
|
|
402
|
+
|
|
403
|
+
console.log(`ļæ½?Performance cleaning: ${targetDirectory}`);
|
|
404
|
+
|
|
405
|
+
const files = await this.scanDirectory(targetDirectory);
|
|
406
|
+
const recentFiles = this.filterRecentFiles(files);
|
|
407
|
+
|
|
408
|
+
console.log(
|
|
409
|
+
` š Processing ${recentFiles.length} files in batches of ${batchSize}`,
|
|
410
|
+
);
|
|
411
|
+
|
|
412
|
+
if (this.options.dryRun) {
|
|
413
|
+
console.log(
|
|
414
|
+
` š Would process in ${Math.ceil(recentFiles.length / batchSize)} batches`,
|
|
415
|
+
);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
let removed = 0;
|
|
420
|
+
const batches = this.createBatches(recentFiles, batchSize);
|
|
421
|
+
|
|
422
|
+
if (parallel && batches.length > 1) {
|
|
423
|
+
removed = await this.parallelRemoveBatches(batches, maxConcurrency);
|
|
424
|
+
} else {
|
|
425
|
+
for (const batch of batches) {
|
|
426
|
+
const batchRemoved = await this.batchRemoveFiles(batch);
|
|
427
|
+
removed += batchRemoved;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
console.log(` ļæ½?Performance cleaned ${removed} files`);
|
|
432
|
+
return removed;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Helper methods
|
|
437
|
+
*/
|
|
438
|
+
async scanDirectory(dirPath, files = []) {
|
|
439
|
+
try {
|
|
440
|
+
const items = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
441
|
+
|
|
442
|
+
for (const item of items) {
|
|
443
|
+
const fullPath = path.join(dirPath, item.name);
|
|
444
|
+
|
|
445
|
+
if (item.isDirectory()) {
|
|
446
|
+
await this.scanDirectory(fullPath, files);
|
|
447
|
+
files.push(fullPath);
|
|
448
|
+
} else {
|
|
449
|
+
files.push(fullPath);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
} catch (error) {
|
|
453
|
+
this.results.errors.push(`Scan error ${dirPath}: ${error.message}`);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
return files;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
async batchRemoveFiles(files) {
|
|
460
|
+
let removed = 0;
|
|
461
|
+
|
|
462
|
+
for (const file of files) {
|
|
463
|
+
try {
|
|
464
|
+
const stat = fs.statSync(file);
|
|
465
|
+
|
|
466
|
+
if (this.removeFile(file)) {
|
|
467
|
+
removed++;
|
|
468
|
+
this.results.bytesFreed += stat.size;
|
|
469
|
+
}
|
|
470
|
+
} catch (error) {
|
|
471
|
+
this.results.errors.push(`Remove error ${file}: ${error.message}`);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
this.results.filesRemoved += removed;
|
|
476
|
+
return removed;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
removeFile(filePath) {
|
|
480
|
+
try {
|
|
481
|
+
if (!fs.existsSync(filePath)) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const stat = fs.statSync(filePath);
|
|
486
|
+
|
|
487
|
+
if (stat.isDirectory()) {
|
|
488
|
+
fs.rmSync(filePath, { recursive: true, force: true });
|
|
489
|
+
this.results.directoriesRemoved++;
|
|
490
|
+
} else {
|
|
491
|
+
fs.unlinkSync(filePath);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (this.options.verbose) {
|
|
495
|
+
console.log(` Removed: ${path.basename(filePath)}`);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return true;
|
|
499
|
+
} catch (error) {
|
|
500
|
+
if (!this.options.force) {
|
|
501
|
+
throw error;
|
|
502
|
+
}
|
|
503
|
+
this.results.skipped.push(`${filePath}: ${error.message}`);
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
async removeDirectory(dirPath) {
|
|
509
|
+
try {
|
|
510
|
+
if (fs.existsSync(dirPath)) {
|
|
511
|
+
const size = await this.getDirectorySize(dirPath);
|
|
512
|
+
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
513
|
+
this.results.bytesFreed += size;
|
|
514
|
+
this.results.directoriesRemoved++;
|
|
515
|
+
return true;
|
|
516
|
+
}
|
|
517
|
+
return false;
|
|
518
|
+
} catch (error) {
|
|
519
|
+
if (!this.options.force) {
|
|
520
|
+
throw error;
|
|
521
|
+
}
|
|
522
|
+
this.results.skipped.push(`Directory: ${dirPath} (${error.message})`);
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
async getDirectorySize(dirPath) {
|
|
528
|
+
let totalSize = 0;
|
|
529
|
+
|
|
530
|
+
try {
|
|
531
|
+
const files = await this.scanDirectory(dirPath);
|
|
532
|
+
|
|
533
|
+
for (const file of files) {
|
|
534
|
+
try {
|
|
535
|
+
const stat = fs.statSync(file);
|
|
536
|
+
totalSize += stat.size;
|
|
537
|
+
} catch (error) {
|
|
538
|
+
// Skip files we can't stat
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (error) {
|
|
542
|
+
// Return 0 for directories we can't scan
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return totalSize;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
filterRecentFiles(files) {
|
|
549
|
+
return files.filter(
|
|
550
|
+
(file) => !this.isRecentFile(file, this.options.preserveRecent),
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
isRecentFile(filePath, maxAge) {
|
|
555
|
+
try {
|
|
556
|
+
const stat = fs.statSync(filePath);
|
|
557
|
+
const age = Date.now() - stat.mtime.getTime();
|
|
558
|
+
return age < maxAge;
|
|
559
|
+
} catch (error) {
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async findStigmergyFiles(dirPath) {
|
|
565
|
+
const stigmergyFiles = [];
|
|
566
|
+
|
|
567
|
+
try {
|
|
568
|
+
const files = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
569
|
+
|
|
570
|
+
for (const file of files) {
|
|
571
|
+
const fullPath = path.join(dirPath, file.name);
|
|
572
|
+
|
|
573
|
+
if (file.isDirectory()) {
|
|
574
|
+
stigmergyFiles.push(...(await this.findStigmergyFiles(fullPath)));
|
|
575
|
+
} else if (this.isStigmergyFile(file.name)) {
|
|
576
|
+
stigmergyFiles.push(fullPath);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
} catch (error) {
|
|
580
|
+
// Skip directories we can't read
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return stigmergyFiles;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
isStigmergyFile(fileName) {
|
|
587
|
+
const stigmergyPatterns = [
|
|
588
|
+
'stigmergy',
|
|
589
|
+
'cross-cli',
|
|
590
|
+
'hook',
|
|
591
|
+
'integration',
|
|
592
|
+
'cache',
|
|
593
|
+
'.tmp',
|
|
594
|
+
'temp',
|
|
595
|
+
];
|
|
596
|
+
|
|
597
|
+
const lowerFileName = fileName.toLowerCase();
|
|
598
|
+
return stigmergyPatterns.some((pattern) =>
|
|
599
|
+
lowerFileName.includes(pattern.toLowerCase()),
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
async findNPXCacheDirectories() {
|
|
604
|
+
const cacheDirs = [];
|
|
605
|
+
const possibleNPXBases = [
|
|
606
|
+
path.join(this.homeDir, 'AppData', 'Local', 'npm-cache', '_npx'),
|
|
607
|
+
path.join(this.homeDir, '.npm', '_npx'),
|
|
608
|
+
path.join(os.tmpdir(), 'npm-cache', '_npx'),
|
|
609
|
+
];
|
|
610
|
+
|
|
611
|
+
for (const npxCacheBase of possibleNPXBases) {
|
|
612
|
+
if (!fs.existsSync(npxCacheBase)) {
|
|
613
|
+
continue;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
try {
|
|
617
|
+
const entries = fs.readdirSync(npxCacheBase);
|
|
618
|
+
|
|
619
|
+
for (const entry of entries) {
|
|
620
|
+
const entryPath = path.join(npxCacheBase, entry);
|
|
621
|
+
const stigmergyPath = path.join(
|
|
622
|
+
entryPath,
|
|
623
|
+
'node_modules',
|
|
624
|
+
'stigmergy',
|
|
625
|
+
);
|
|
626
|
+
|
|
627
|
+
if (fs.existsSync(stigmergyPath)) {
|
|
628
|
+
cacheDirs.push(entryPath);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
} catch (error) {
|
|
632
|
+
this.results.errors.push(`NPX scan error: ${error.message}`);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
return cacheDirs;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async findStigmergyTempFiles(tempDir) {
|
|
640
|
+
const tempFiles = [];
|
|
641
|
+
|
|
642
|
+
try {
|
|
643
|
+
const files = fs.readdirSync(tempDir, { withFileTypes: true });
|
|
644
|
+
|
|
645
|
+
for (const file of files) {
|
|
646
|
+
if (
|
|
647
|
+
this.isStigmergyFile(file.name) ||
|
|
648
|
+
file.name.startsWith('stigmergy-') ||
|
|
649
|
+
file.name.includes('stigmergy')
|
|
650
|
+
) {
|
|
651
|
+
const fullPath = path.join(tempDir, file.name);
|
|
652
|
+
tempFiles.push(fullPath);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
} catch (error) {
|
|
656
|
+
// Skip temp directories we can't read
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
return tempFiles;
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
async cleanDirectory(dirPath) {
|
|
663
|
+
try {
|
|
664
|
+
if (!fs.existsSync(dirPath)) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
const files = await this.scanDirectory(dirPath);
|
|
669
|
+
const removed = await this.batchRemoveFiles(files);
|
|
670
|
+
|
|
671
|
+
console.log(
|
|
672
|
+
` š§¹ Cleaned ${removed} files from ${path.basename(dirPath)}`,
|
|
673
|
+
);
|
|
674
|
+
} catch (error) {
|
|
675
|
+
console.error(` ļæ½?Failed to clean ${dirPath}: ${error.message}`);
|
|
676
|
+
this.results.errors.push(`Clean error ${dirPath}: ${error.message}`);
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
matchPattern(filePath, pattern) {
|
|
681
|
+
const fileName = path.basename(filePath);
|
|
682
|
+
|
|
683
|
+
// Simple glob pattern matching
|
|
684
|
+
const regexPattern = pattern.replace(/\*/g, '.*').replace(/\?/g, '.');
|
|
685
|
+
|
|
686
|
+
const regex = new RegExp(regexPattern, 'i');
|
|
687
|
+
return regex.test(fileName);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
createBatches(items, batchSize) {
|
|
691
|
+
const batches = [];
|
|
692
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
693
|
+
batches.push(items.slice(i, i + batchSize));
|
|
694
|
+
}
|
|
695
|
+
return batches;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
async parallelRemoveBatches(batches, maxConcurrency) {
|
|
699
|
+
let totalRemoved = 0;
|
|
700
|
+
const executing = [];
|
|
701
|
+
|
|
702
|
+
for (const batch of batches) {
|
|
703
|
+
const promise = this.batchRemoveFiles(batch);
|
|
704
|
+
executing.push(promise);
|
|
705
|
+
|
|
706
|
+
if (executing.length >= maxConcurrency) {
|
|
707
|
+
await Promise.race(executing);
|
|
708
|
+
executing.splice(0, 1);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
await Promise.all(executing);
|
|
713
|
+
return totalRemoved;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
formatBytes(bytes) {
|
|
717
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
718
|
+
if (bytes === 0) return '0 Bytes';
|
|
719
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
720
|
+
return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i];
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
logFiles(files, prefix = '') {
|
|
724
|
+
files.slice(0, 10).forEach((file) => {
|
|
725
|
+
console.log(`${prefix}${path.basename(file)}`);
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
if (files.length > 10) {
|
|
729
|
+
console.log(`${prefix}... and ${files.length - 10} more`);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
printSummary() {
|
|
734
|
+
console.log('\nš CACHE CLEANING SUMMARY:');
|
|
735
|
+
console.log('='.repeat(50));
|
|
736
|
+
|
|
737
|
+
if (this.options.dryRun) {
|
|
738
|
+
console.log('š DRY RUN MODE - No files were actually deleted');
|
|
739
|
+
} else {
|
|
740
|
+
console.log(`š Directories removed: ${this.results.directoriesRemoved}`);
|
|
741
|
+
console.log(`š Files removed: ${this.results.filesRemoved}`);
|
|
742
|
+
console.log(
|
|
743
|
+
`š¾ Space freed: ${this.formatBytes(this.results.bytesFreed)}`,
|
|
744
|
+
);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
if (this.results.skipped.length > 0) {
|
|
748
|
+
console.log(`āļø Items skipped: ${this.results.skipped.length}`);
|
|
749
|
+
if (this.options.verbose) {
|
|
750
|
+
this.results.skipped.forEach((item) => {
|
|
751
|
+
console.log(` ${item}`);
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
if (this.results.errors.length > 0) {
|
|
757
|
+
console.log(`ļæ½?Errors: ${this.results.errors.length}`);
|
|
758
|
+
this.results.errors.forEach((error) => {
|
|
759
|
+
console.log(` ${error}`);
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
console.log('\nļæ½?Cache cleaning completed!');
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
module.exports = CacheCleaner;
|