packagepurge 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/workflows/build.md +58 -0
- package/.github/workflows/release.yml +176 -0
- package/README.md +215 -49
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +122 -132
- package/dist/cli/index.js.map +1 -1
- package/dist/core/bindings.d.ts +11 -0
- package/dist/core/bindings.d.ts.map +1 -1
- package/dist/core/bindings.js +40 -94
- package/dist/core/bindings.js.map +1 -1
- package/dist/utils/core-utils.d.ts +31 -0
- package/dist/utils/core-utils.d.ts.map +1 -0
- package/dist/utils/core-utils.js +121 -0
- package/dist/utils/core-utils.js.map +1 -0
- package/dist/utils/formatter.d.ts +63 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +295 -0
- package/dist/utils/formatter.js.map +1 -0
- package/package.json +3 -3
- package/core/src/arc_lfu.rs +0 -91
- package/core/src/cache.rs +0 -205
- package/core/src/lockfiles.rs +0 -112
- package/core/src/main.rs +0 -125
- package/core/src/ml.rs +0 -188
- package/core/src/optimization.rs +0 -314
- package/core/src/safety.rs +0 -103
- package/core/src/scanner.rs +0 -136
- package/core/src/symlink.rs +0 -223
- package/core/src/types.rs +0 -87
- package/core/src/usage_tracker.rs +0 -107
- package/src/cli/index.ts +0 -212
- package/src/core/bindings.ts +0 -157
- package/src/managers/base-manager.ts +0 -117
- package/src/managers/index.ts +0 -32
- package/src/managers/npm-manager.ts +0 -96
- package/src/managers/pnpm-manager.ts +0 -107
- package/src/managers/yarn-manager.ts +0 -112
- package/src/types/index.ts +0 -97
- package/src/utils/logger.ts +0 -50
- package/tsconfig.json +0 -22
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if running on Windows
|
|
3
|
+
*/
|
|
4
|
+
export declare function isWindows(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Check if a file exists at the given path
|
|
7
|
+
*/
|
|
8
|
+
export declare function fileExists(p: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Resolve an executable from PATH environment variable
|
|
11
|
+
*/
|
|
12
|
+
export declare function resolveFromPATH(name: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Get the path to the packagepurge-core binary
|
|
15
|
+
* Search order:
|
|
16
|
+
* 1. PACKAGEPURGE_CORE environment variable
|
|
17
|
+
* 2. Local release build (core/target/release)
|
|
18
|
+
* 3. Local debug build (core/target/debug)
|
|
19
|
+
* 4. PATH
|
|
20
|
+
*/
|
|
21
|
+
export declare function coreBinary(): string;
|
|
22
|
+
export interface CoreResult {
|
|
23
|
+
stdout: string;
|
|
24
|
+
stderr: string;
|
|
25
|
+
code: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Run the packagepurge-core binary with the given arguments
|
|
29
|
+
*/
|
|
30
|
+
export declare function runCore(args: string[]): Promise<CoreResult>;
|
|
31
|
+
//# sourceMappingURL=core-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-utils.d.ts","sourceRoot":"","sources":["../../src/utils/core-utils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAM7C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU3D;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAiBnC;AAED,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAW3D"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.isWindows = isWindows;
|
|
37
|
+
exports.fileExists = fileExists;
|
|
38
|
+
exports.resolveFromPATH = resolveFromPATH;
|
|
39
|
+
exports.coreBinary = coreBinary;
|
|
40
|
+
exports.runCore = runCore;
|
|
41
|
+
/**
|
|
42
|
+
* Core utilities for PackagePurge - shared between CLI and bindings
|
|
43
|
+
*/
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
/**
|
|
48
|
+
* Check if running on Windows
|
|
49
|
+
*/
|
|
50
|
+
function isWindows() {
|
|
51
|
+
return process.platform === 'win32';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Check if a file exists at the given path
|
|
55
|
+
*/
|
|
56
|
+
function fileExists(p) {
|
|
57
|
+
try {
|
|
58
|
+
return fs.existsSync(p);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Resolve an executable from PATH environment variable
|
|
66
|
+
*/
|
|
67
|
+
function resolveFromPATH(name) {
|
|
68
|
+
const exts = isWindows() ? ['.exe', '.cmd', ''] : [''];
|
|
69
|
+
const parts = (process.env.PATH || '').split(path.delimiter);
|
|
70
|
+
for (const dir of parts) {
|
|
71
|
+
for (const ext of exts) {
|
|
72
|
+
const candidate = path.join(dir, name + ext);
|
|
73
|
+
if (fileExists(candidate))
|
|
74
|
+
return candidate;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get the path to the packagepurge-core binary
|
|
81
|
+
* Search order:
|
|
82
|
+
* 1. PACKAGEPURGE_CORE environment variable
|
|
83
|
+
* 2. Local release build (core/target/release)
|
|
84
|
+
* 3. Local debug build (core/target/debug)
|
|
85
|
+
* 4. PATH
|
|
86
|
+
*/
|
|
87
|
+
function coreBinary() {
|
|
88
|
+
// 1) Env override
|
|
89
|
+
const envPath = process.env.PACKAGEPURGE_CORE;
|
|
90
|
+
if (envPath && fileExists(envPath))
|
|
91
|
+
return envPath;
|
|
92
|
+
// 2) Local release/debug
|
|
93
|
+
const exe = isWindows() ? 'packagepurge_core.exe' : 'packagepurge-core';
|
|
94
|
+
const rel = path.join(process.cwd(), 'core', 'target', 'release', exe);
|
|
95
|
+
if (fileExists(rel))
|
|
96
|
+
return rel;
|
|
97
|
+
const dbg = path.join(process.cwd(), 'core', 'target', 'debug', exe);
|
|
98
|
+
if (fileExists(dbg))
|
|
99
|
+
return dbg;
|
|
100
|
+
// 3) PATH
|
|
101
|
+
const fromPath = resolveFromPATH(isWindows() ? 'packagepurge_core' : 'packagepurge-core');
|
|
102
|
+
if (fromPath)
|
|
103
|
+
return fromPath;
|
|
104
|
+
throw new Error('packagepurge-core binary not found. Build with "npm run build:core" or set PACKAGEPURGE_CORE.');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Run the packagepurge-core binary with the given arguments
|
|
108
|
+
*/
|
|
109
|
+
function runCore(args) {
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
const bin = coreBinary();
|
|
112
|
+
const child = (0, child_process_1.spawn)(bin, args, { stdio: ['ignore', 'pipe', 'pipe'], env: process.env });
|
|
113
|
+
let out = '';
|
|
114
|
+
let err = '';
|
|
115
|
+
child.stdout.on('data', (d) => out += d.toString());
|
|
116
|
+
child.stderr.on('data', (d) => err += d.toString());
|
|
117
|
+
child.on('error', reject);
|
|
118
|
+
child.on('close', (code) => resolve({ stdout: out, stderr: err, code: code ?? 1 }));
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=core-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-utils.js","sourceRoot":"","sources":["../../src/utils/core-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export type OutputFormat = 'table' | 'json' | 'yaml';
|
|
2
|
+
/**
|
|
3
|
+
* Format bytes into a human-readable string
|
|
4
|
+
*/
|
|
5
|
+
export declare function formatBytes(bytes: number): string;
|
|
6
|
+
/**
|
|
7
|
+
* Truncate a path to fit within maxLen characters
|
|
8
|
+
*/
|
|
9
|
+
export declare function truncatePath(pathStr: string, maxLen: number): string;
|
|
10
|
+
export interface PlanItem {
|
|
11
|
+
target_path: string;
|
|
12
|
+
estimated_size_bytes: number;
|
|
13
|
+
reason: string;
|
|
14
|
+
}
|
|
15
|
+
export interface DryRunReport {
|
|
16
|
+
items: PlanItem[];
|
|
17
|
+
total_estimated_bytes: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ScanOutput {
|
|
20
|
+
packages: Array<{
|
|
21
|
+
name: string;
|
|
22
|
+
version: string;
|
|
23
|
+
path: string;
|
|
24
|
+
size_bytes: number;
|
|
25
|
+
}>;
|
|
26
|
+
projects: Array<{
|
|
27
|
+
path: string;
|
|
28
|
+
manager?: string;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Format scan output as a human-readable table
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatScanAsTable(data: ScanOutput): void;
|
|
35
|
+
/**
|
|
36
|
+
* Format cleanup plan as a human-readable table
|
|
37
|
+
*/
|
|
38
|
+
export declare function formatPlanAsTable(data: DryRunReport): void;
|
|
39
|
+
/**
|
|
40
|
+
* Format quarantine result
|
|
41
|
+
*/
|
|
42
|
+
export declare function formatQuarantineResult(data: any[]): void;
|
|
43
|
+
/**
|
|
44
|
+
* Format rollback result
|
|
45
|
+
*/
|
|
46
|
+
export declare function formatRollbackResult(data: any): void;
|
|
47
|
+
/**
|
|
48
|
+
* Format symlink result
|
|
49
|
+
*/
|
|
50
|
+
export declare function formatSymlinkResult(data: any): void;
|
|
51
|
+
/**
|
|
52
|
+
* Format data as JSON
|
|
53
|
+
*/
|
|
54
|
+
export declare function formatAsJSON(data: any, pretty?: boolean): string;
|
|
55
|
+
/**
|
|
56
|
+
* Format data as YAML
|
|
57
|
+
*/
|
|
58
|
+
export declare function formatAsYAML(data: any): string;
|
|
59
|
+
/**
|
|
60
|
+
* Output data in the specified format
|
|
61
|
+
*/
|
|
62
|
+
export declare function output(data: string | object, format: OutputFormat, type?: 'scan' | 'analyze' | 'optimize' | 'quarantine' | 'rollback' | 'symlink'): void;
|
|
63
|
+
//# sourceMappingURL=formatter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAErD;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMpE;AAwED,MAAM,WAAW,QAAQ;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACvB,QAAQ,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IACH,QAAQ,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC,CAAC;CACN;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAoCxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CA2C1D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAgBxD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CAQpD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,CASnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,GAAE,OAAc,GAAG,MAAM,CAEtE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,CAQ9C;AAED;;GAEG;AACH,wBAAgB,MAAM,CAClB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,MAAM,EAAE,YAAY,EACpB,IAAI,GAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,UAAU,GAAG,SAAqB,GAC1F,IAAI,CAgDN"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.formatBytes = formatBytes;
|
|
7
|
+
exports.truncatePath = truncatePath;
|
|
8
|
+
exports.formatScanAsTable = formatScanAsTable;
|
|
9
|
+
exports.formatPlanAsTable = formatPlanAsTable;
|
|
10
|
+
exports.formatQuarantineResult = formatQuarantineResult;
|
|
11
|
+
exports.formatRollbackResult = formatRollbackResult;
|
|
12
|
+
exports.formatSymlinkResult = formatSymlinkResult;
|
|
13
|
+
exports.formatAsJSON = formatAsJSON;
|
|
14
|
+
exports.formatAsYAML = formatAsYAML;
|
|
15
|
+
exports.output = output;
|
|
16
|
+
/**
|
|
17
|
+
* Output formatting utilities for PackagePurge CLI
|
|
18
|
+
* Provides human-readable, JSON, and YAML output formats
|
|
19
|
+
*/
|
|
20
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
21
|
+
const yaml_1 = __importDefault(require("yaml"));
|
|
22
|
+
/**
|
|
23
|
+
* Format bytes into a human-readable string
|
|
24
|
+
*/
|
|
25
|
+
function formatBytes(bytes) {
|
|
26
|
+
if (bytes === 0)
|
|
27
|
+
return '0 B';
|
|
28
|
+
const k = 1024;
|
|
29
|
+
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
30
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
31
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Truncate a path to fit within maxLen characters
|
|
35
|
+
*/
|
|
36
|
+
function truncatePath(pathStr, maxLen) {
|
|
37
|
+
if (pathStr.length <= maxLen)
|
|
38
|
+
return pathStr;
|
|
39
|
+
const ellipsis = '...';
|
|
40
|
+
const start = Math.floor((maxLen - ellipsis.length) / 3);
|
|
41
|
+
const end = maxLen - ellipsis.length - start;
|
|
42
|
+
return pathStr.slice(0, start) + ellipsis + pathStr.slice(-end);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get color for a cleanup reason
|
|
46
|
+
*/
|
|
47
|
+
function getReasonColor(reason) {
|
|
48
|
+
switch (reason.toLowerCase()) {
|
|
49
|
+
case 'orphaned':
|
|
50
|
+
return chalk_1.default.yellow;
|
|
51
|
+
case 'old':
|
|
52
|
+
return chalk_1.default.gray;
|
|
53
|
+
case 'duplicate':
|
|
54
|
+
case 'duplicate_symlink_candidate':
|
|
55
|
+
return chalk_1.default.blue;
|
|
56
|
+
case 'ml_predicted_unused':
|
|
57
|
+
return chalk_1.default.magenta;
|
|
58
|
+
case 'size_pressure':
|
|
59
|
+
return chalk_1.default.red;
|
|
60
|
+
default:
|
|
61
|
+
return chalk_1.default.white;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Get human-readable reason text
|
|
66
|
+
*/
|
|
67
|
+
function formatReason(reason) {
|
|
68
|
+
switch (reason.toLowerCase()) {
|
|
69
|
+
case 'orphaned':
|
|
70
|
+
return 'Orphaned';
|
|
71
|
+
case 'old':
|
|
72
|
+
return 'Outdated';
|
|
73
|
+
case 'duplicate':
|
|
74
|
+
return 'Duplicate';
|
|
75
|
+
case 'duplicate_symlink_candidate':
|
|
76
|
+
return 'Symlink Candidate';
|
|
77
|
+
case 'ml_predicted_unused':
|
|
78
|
+
return 'ML: Unused';
|
|
79
|
+
case 'size_pressure':
|
|
80
|
+
return 'Size Pressure';
|
|
81
|
+
default:
|
|
82
|
+
return reason;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Extract package name and version from a path
|
|
87
|
+
*/
|
|
88
|
+
function extractPackageInfo(targetPath) {
|
|
89
|
+
// Try to extract from path like /path/to/node_modules/package-name or /path/to/cache/package@version
|
|
90
|
+
const parts = targetPath.split(/[\/\\]/);
|
|
91
|
+
const last = parts[parts.length - 1] || 'unknown';
|
|
92
|
+
// Check for @scope/package format
|
|
93
|
+
const nodeModulesIdx = parts.findIndex(p => p === 'node_modules');
|
|
94
|
+
if (nodeModulesIdx !== -1 && nodeModulesIdx < parts.length - 1) {
|
|
95
|
+
const pkgName = parts[nodeModulesIdx + 1];
|
|
96
|
+
if (pkgName.startsWith('@') && nodeModulesIdx < parts.length - 2) {
|
|
97
|
+
return { name: `${pkgName}/${parts[nodeModulesIdx + 2]}`, version: '-' };
|
|
98
|
+
}
|
|
99
|
+
return { name: pkgName, version: '-' };
|
|
100
|
+
}
|
|
101
|
+
// Try to parse name@version format
|
|
102
|
+
const atIdx = last.lastIndexOf('@');
|
|
103
|
+
if (atIdx > 0) {
|
|
104
|
+
return { name: last.slice(0, atIdx), version: last.slice(atIdx + 1) };
|
|
105
|
+
}
|
|
106
|
+
return { name: last, version: '-' };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Format scan output as a human-readable table
|
|
110
|
+
*/
|
|
111
|
+
function formatScanAsTable(data) {
|
|
112
|
+
console.log(chalk_1.default.bold.cyan('\n📦 Packages Found\n'));
|
|
113
|
+
// Simple table without external dependency
|
|
114
|
+
const header = `${'Package'.padEnd(30)} ${'Version'.padEnd(12)} ${'Size'.padEnd(10)} Path`;
|
|
115
|
+
console.log(chalk_1.default.bold(header));
|
|
116
|
+
console.log('─'.repeat(100));
|
|
117
|
+
const sortedPackages = [...(data.packages || [])].sort((a, b) => b.size_bytes - a.size_bytes);
|
|
118
|
+
const displayLimit = 50;
|
|
119
|
+
const packagesToShow = sortedPackages.slice(0, displayLimit);
|
|
120
|
+
for (const pkg of packagesToShow) {
|
|
121
|
+
const name = (pkg.name || 'unknown').slice(0, 28).padEnd(30);
|
|
122
|
+
const version = (pkg.version || '-').slice(0, 10).padEnd(12);
|
|
123
|
+
const size = formatBytes(pkg.size_bytes).padEnd(10);
|
|
124
|
+
const path = truncatePath(pkg.path, 45);
|
|
125
|
+
console.log(`${chalk_1.default.green(name)} ${chalk_1.default.cyan(version)} ${chalk_1.default.yellow(size)} ${chalk_1.default.gray(path)}`);
|
|
126
|
+
}
|
|
127
|
+
if (sortedPackages.length > displayLimit) {
|
|
128
|
+
console.log(chalk_1.default.gray(`\n... and ${sortedPackages.length - displayLimit} more packages`));
|
|
129
|
+
}
|
|
130
|
+
const totalSize = data.packages?.reduce((sum, p) => sum + p.size_bytes, 0) || 0;
|
|
131
|
+
console.log(chalk_1.default.bold(`\n📊 Total: ${data.packages?.length || 0} packages, ${formatBytes(totalSize)}`));
|
|
132
|
+
if (data.projects?.length) {
|
|
133
|
+
console.log(chalk_1.default.bold.cyan(`\n📁 Projects Found: ${data.projects.length}`));
|
|
134
|
+
for (const proj of data.projects.slice(0, 10)) {
|
|
135
|
+
console.log(` ${chalk_1.default.gray('•')} ${proj.path}`);
|
|
136
|
+
}
|
|
137
|
+
if (data.projects.length > 10) {
|
|
138
|
+
console.log(chalk_1.default.gray(` ... and ${data.projects.length - 10} more projects`));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Format cleanup plan as a human-readable table
|
|
144
|
+
*/
|
|
145
|
+
function formatPlanAsTable(data) {
|
|
146
|
+
console.log(chalk_1.default.bold.cyan('\n🧹 Cleanup Plan\n'));
|
|
147
|
+
if (!data.items?.length) {
|
|
148
|
+
console.log(chalk_1.default.green('✓ No packages identified for cleanup!'));
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
// Group by reason
|
|
152
|
+
const byReason = new Map();
|
|
153
|
+
for (const item of data.items) {
|
|
154
|
+
const items = byReason.get(item.reason) || [];
|
|
155
|
+
items.push(item);
|
|
156
|
+
byReason.set(item.reason, items);
|
|
157
|
+
}
|
|
158
|
+
// Display by category
|
|
159
|
+
for (const [reason, items] of byReason) {
|
|
160
|
+
const colorFn = getReasonColor(reason);
|
|
161
|
+
const reasonText = formatReason(reason);
|
|
162
|
+
const categorySize = items.reduce((sum, i) => sum + i.estimated_size_bytes, 0);
|
|
163
|
+
console.log(colorFn.bold(`\n${reasonText} (${items.length} packages, ${formatBytes(categorySize)})`));
|
|
164
|
+
console.log('─'.repeat(80));
|
|
165
|
+
const sorted = [...items].sort((a, b) => b.estimated_size_bytes - a.estimated_size_bytes);
|
|
166
|
+
const toShow = sorted.slice(0, 10);
|
|
167
|
+
for (const item of toShow) {
|
|
168
|
+
const { name } = extractPackageInfo(item.target_path);
|
|
169
|
+
const size = formatBytes(item.estimated_size_bytes).padEnd(10);
|
|
170
|
+
console.log(` ${colorFn('•')} ${name.padEnd(35)} ${chalk_1.default.yellow(size)} ${chalk_1.default.gray(truncatePath(item.target_path, 30))}`);
|
|
171
|
+
}
|
|
172
|
+
if (items.length > 10) {
|
|
173
|
+
console.log(chalk_1.default.gray(` ... and ${items.length - 10} more`));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Summary
|
|
177
|
+
console.log(chalk_1.default.bold.green(`\n📊 Summary`));
|
|
178
|
+
console.log(` ${chalk_1.default.bold('Total packages:')} ${data.items.length}`);
|
|
179
|
+
console.log(` ${chalk_1.default.bold('Estimated savings:')} ${chalk_1.default.yellow.bold(formatBytes(data.total_estimated_bytes))}`);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Format quarantine result
|
|
183
|
+
*/
|
|
184
|
+
function formatQuarantineResult(data) {
|
|
185
|
+
console.log(chalk_1.default.bold.cyan('\n🗄️ Quarantine Results\n'));
|
|
186
|
+
if (!data?.length) {
|
|
187
|
+
console.log(chalk_1.default.yellow('No items were quarantined.'));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
for (const rec of data) {
|
|
191
|
+
console.log(chalk_1.default.green('✓') + ` Quarantined: ${chalk_1.default.cyan(rec.original_path || rec.id)}`);
|
|
192
|
+
console.log(` ${chalk_1.default.gray('ID:')} ${rec.id}`);
|
|
193
|
+
console.log(` ${chalk_1.default.gray('Size:')} ${formatBytes(rec.size_bytes || 0)}`);
|
|
194
|
+
}
|
|
195
|
+
const totalSize = data.reduce((sum, r) => sum + (r.size_bytes || 0), 0);
|
|
196
|
+
console.log(chalk_1.default.bold.green(`\n✓ ${data.length} items quarantined, ${formatBytes(totalSize)} recoverable space`));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Format rollback result
|
|
200
|
+
*/
|
|
201
|
+
function formatRollbackResult(data) {
|
|
202
|
+
console.log(chalk_1.default.bold.cyan('\n↩️ Rollback Result\n'));
|
|
203
|
+
if (data.status === 'ok') {
|
|
204
|
+
console.log(chalk_1.default.green('✓') + ` Successfully rolled back: ${chalk_1.default.cyan(data.id)}`);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
console.log(chalk_1.default.red('✗') + ` Rollback failed`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Format symlink result
|
|
212
|
+
*/
|
|
213
|
+
function formatSymlinkResult(data) {
|
|
214
|
+
console.log(chalk_1.default.bold.cyan('\n🔗 Symlink Results\n'));
|
|
215
|
+
if (data.status === 'ok') {
|
|
216
|
+
console.log(chalk_1.default.green('✓') + ` Successfully symlinked ${chalk_1.default.bold(data.symlinked_count)} packages`);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.log(chalk_1.default.yellow('ℹ') + ` Symlink operation completed`);
|
|
220
|
+
console.log(JSON.stringify(data, null, 2));
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Format data as JSON
|
|
225
|
+
*/
|
|
226
|
+
function formatAsJSON(data, pretty = true) {
|
|
227
|
+
return pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Format data as YAML
|
|
231
|
+
*/
|
|
232
|
+
function formatAsYAML(data) {
|
|
233
|
+
try {
|
|
234
|
+
return yaml_1.default.stringify(data);
|
|
235
|
+
}
|
|
236
|
+
catch (e) {
|
|
237
|
+
// Fallback to JSON if YAML conversion fails
|
|
238
|
+
console.error(chalk_1.default.yellow('Warning: YAML conversion failed, falling back to JSON'));
|
|
239
|
+
return JSON.stringify(data, null, 2);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Output data in the specified format
|
|
244
|
+
*/
|
|
245
|
+
function output(data, format, type = 'analyze') {
|
|
246
|
+
// Parse JSON string if needed
|
|
247
|
+
let parsed;
|
|
248
|
+
if (typeof data === 'string') {
|
|
249
|
+
try {
|
|
250
|
+
parsed = JSON.parse(data);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// If not valid JSON, just print as-is for json/yaml, or show error for table
|
|
254
|
+
if (format === 'table') {
|
|
255
|
+
console.log(data);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
parsed = data;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
parsed = data;
|
|
263
|
+
}
|
|
264
|
+
switch (format) {
|
|
265
|
+
case 'table':
|
|
266
|
+
switch (type) {
|
|
267
|
+
case 'scan':
|
|
268
|
+
formatScanAsTable(parsed);
|
|
269
|
+
break;
|
|
270
|
+
case 'analyze':
|
|
271
|
+
case 'optimize':
|
|
272
|
+
formatPlanAsTable(parsed);
|
|
273
|
+
break;
|
|
274
|
+
case 'quarantine':
|
|
275
|
+
formatQuarantineResult(parsed);
|
|
276
|
+
break;
|
|
277
|
+
case 'rollback':
|
|
278
|
+
formatRollbackResult(parsed);
|
|
279
|
+
break;
|
|
280
|
+
case 'symlink':
|
|
281
|
+
formatSymlinkResult(parsed);
|
|
282
|
+
break;
|
|
283
|
+
default:
|
|
284
|
+
console.log(formatAsJSON(parsed));
|
|
285
|
+
}
|
|
286
|
+
break;
|
|
287
|
+
case 'yaml':
|
|
288
|
+
console.log(formatAsYAML(parsed));
|
|
289
|
+
break;
|
|
290
|
+
case 'json':
|
|
291
|
+
default:
|
|
292
|
+
console.log(formatAsJSON(parsed));
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=formatter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "packagepurge",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Intelligent package manager cache cleanup service with project-aware optimization",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
+
"purge": "dist/cli/index.js",
|
|
8
9
|
"packagepurge": "dist/cli/index.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
@@ -60,5 +61,4 @@
|
|
|
60
61
|
"engines": {
|
|
61
62
|
"node": ">=16.0.0"
|
|
62
63
|
}
|
|
63
|
-
}
|
|
64
|
-
|
|
64
|
+
}
|
package/core/src/arc_lfu.rs
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
#![allow(dead_code)]
|
|
2
|
-
use std::collections::{HashMap, VecDeque};
|
|
3
|
-
|
|
4
|
-
// SLRU: probationary and protected segments, each LRU-like (front=MRU, back=LRU)
|
|
5
|
-
pub struct SlruPolicy {
|
|
6
|
-
probationary: VecDeque<String>,
|
|
7
|
-
protected: VecDeque<String>,
|
|
8
|
-
cap_probationary: usize,
|
|
9
|
-
cap_protected: usize,
|
|
10
|
-
in_probationary: HashMap<String, bool>,
|
|
11
|
-
in_protected: HashMap<String, bool>,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
impl SlruPolicy {
|
|
15
|
-
pub fn new(capacity: usize) -> Self {
|
|
16
|
-
let cap_protected = (capacity as f32 * 0.8) as usize;
|
|
17
|
-
let cap_probationary = capacity.saturating_sub(cap_protected);
|
|
18
|
-
Self {
|
|
19
|
-
probationary: VecDeque::new(),
|
|
20
|
-
protected: VecDeque::new(),
|
|
21
|
-
cap_probationary,
|
|
22
|
-
cap_protected,
|
|
23
|
-
in_probationary: HashMap::new(),
|
|
24
|
-
in_protected: HashMap::new(),
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
pub fn record_hit(&mut self, key: &str) {
|
|
29
|
-
let k = key.to_string();
|
|
30
|
-
if self.in_protected.remove(&k).is_some() {
|
|
31
|
-
self.protected.retain(|x| x != &k);
|
|
32
|
-
self.protected.push_front(k.clone());
|
|
33
|
-
self.in_protected.insert(k, true);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if self.in_probationary.remove(&k).is_some() {
|
|
37
|
-
// promote to protected
|
|
38
|
-
self.probationary.retain(|x| x != &k);
|
|
39
|
-
self.protected.push_front(k.clone());
|
|
40
|
-
self.in_protected.insert(k.clone(), true);
|
|
41
|
-
// enforce protected capacity
|
|
42
|
-
while self.protected.len() > self.cap_protected {
|
|
43
|
-
if let Some(v) = self.protected.pop_back() { self.in_protected.remove(&v); }
|
|
44
|
-
}
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
// new entry goes to probationary
|
|
48
|
-
self.probationary.push_front(k.clone());
|
|
49
|
-
self.in_probationary.insert(k.clone(), true);
|
|
50
|
-
while self.probationary.len() > self.cap_probationary {
|
|
51
|
-
if let Some(v) = self.probationary.pop_back() { self.in_probationary.remove(&v); }
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
pub fn select_victim(&mut self) -> Option<String> {
|
|
56
|
-
if let Some(v) = self.probationary.pop_back() { self.in_probationary.remove(&v); return Some(v); }
|
|
57
|
-
if let Some(v) = self.protected.pop_back() { self.in_protected.remove(&v); return Some(v); }
|
|
58
|
-
None
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Simple LFU: key->freq, and buckets freq->VecDeque keys. Evicts from lowest freq, oldest within bucket
|
|
63
|
-
pub struct SimpleLfu {
|
|
64
|
-
freq: HashMap<String, usize>,
|
|
65
|
-
buckets: HashMap<usize, VecDeque<String>>,
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
impl SimpleLfu {
|
|
69
|
-
pub fn new() -> Self { Self { freq: HashMap::new(), buckets: HashMap::new() } }
|
|
70
|
-
|
|
71
|
-
pub fn increment(&mut self, key: &str) {
|
|
72
|
-
let k = key.to_string();
|
|
73
|
-
let f = *self.freq.get(&k).unwrap_or(&0);
|
|
74
|
-
if let Some(q) = self.buckets.get_mut(&f) { q.retain(|x| x != &k); }
|
|
75
|
-
let nf = f + 1;
|
|
76
|
-
self.freq.insert(k.clone(), nf);
|
|
77
|
-
self.buckets.entry(nf).or_default().push_front(k);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
pub fn victim(&mut self) -> Option<String> {
|
|
81
|
-
if self.freq.is_empty() { return None; }
|
|
82
|
-
let minf = *self.freq.values().min().unwrap_or(&0);
|
|
83
|
-
if let Some(q) = self.buckets.get_mut(&minf) {
|
|
84
|
-
if let Some(k) = q.pop_back() {
|
|
85
|
-
self.freq.remove(&k);
|
|
86
|
-
return Some(k);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
None
|
|
90
|
-
}
|
|
91
|
-
}
|