squeaky-clean 0.4.18 → 0.5.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.
Files changed (63) hide show
  1. package/README.md +71 -0
  2. package/dist/cleaners/BaseCleaner.d.ts +1 -1
  3. package/dist/cleaners/BaseCleaner.d.ts.map +1 -1
  4. package/dist/cleaners/BaseCleaner.js +61 -16
  5. package/dist/cleaners/BaseCleaner.js.map +1 -1
  6. package/dist/cleaners/appCacheDiscovery.d.ts +35 -0
  7. package/dist/cleaners/appCacheDiscovery.d.ts.map +1 -0
  8. package/dist/cleaners/appCacheDiscovery.js +353 -0
  9. package/dist/cleaners/appCacheDiscovery.js.map +1 -0
  10. package/dist/cleaners/brew.d.ts.map +1 -1
  11. package/dist/cleaners/brew.js +9 -3
  12. package/dist/cleaners/brew.js.map +1 -1
  13. package/dist/cleaners/docker.d.ts.map +1 -1
  14. package/dist/cleaners/docker.js +8 -0
  15. package/dist/cleaners/docker.js.map +1 -1
  16. package/dist/cleaners/index.d.ts +2 -1
  17. package/dist/cleaners/index.d.ts.map +1 -1
  18. package/dist/cleaners/index.js +5 -3
  19. package/dist/cleaners/index.js.map +1 -1
  20. package/dist/cleaners/universalBinary.d.ts.map +1 -1
  21. package/dist/cleaners/universalBinary.js +7 -0
  22. package/dist/cleaners/universalBinary.js.map +1 -1
  23. package/dist/cleaners/vscode.d.ts.map +1 -1
  24. package/dist/cleaners/vscode.js +12 -3
  25. package/dist/cleaners/vscode.js.map +1 -1
  26. package/dist/cli.js +51 -0
  27. package/dist/cli.js.map +1 -1
  28. package/dist/commands/categories.d.ts.map +1 -1
  29. package/dist/commands/categories.js +9 -1
  30. package/dist/commands/categories.js.map +1 -1
  31. package/dist/commands/clean.d.ts +33 -1
  32. package/dist/commands/clean.d.ts.map +1 -1
  33. package/dist/commands/clean.js +264 -0
  34. package/dist/commands/clean.js.map +1 -1
  35. package/dist/commands/interactive.d.ts.map +1 -1
  36. package/dist/commands/interactive.js +24 -2
  37. package/dist/commands/interactive.js.map +1 -1
  38. package/dist/commands/profile.d.ts +7 -0
  39. package/dist/commands/profile.d.ts.map +1 -0
  40. package/dist/commands/profile.js +61 -0
  41. package/dist/commands/profile.js.map +1 -0
  42. package/dist/config/index.d.ts +2 -0
  43. package/dist/config/index.d.ts.map +1 -1
  44. package/dist/config/index.js +9 -1
  45. package/dist/config/index.js.map +1 -1
  46. package/dist/safety/index.d.ts +47 -0
  47. package/dist/safety/index.d.ts.map +1 -0
  48. package/dist/safety/index.js +115 -0
  49. package/dist/safety/index.js.map +1 -0
  50. package/dist/safety/rules.d.ts +27 -0
  51. package/dist/safety/rules.d.ts.map +1 -0
  52. package/dist/safety/rules.js +465 -0
  53. package/dist/safety/rules.js.map +1 -0
  54. package/dist/types/index.d.ts +10 -1
  55. package/dist/types/index.d.ts.map +1 -1
  56. package/dist/utils/fs.d.ts +2 -2
  57. package/dist/utils/fs.d.ts.map +1 -1
  58. package/dist/utils/fs.js +56 -22
  59. package/dist/utils/fs.js.map +1 -1
  60. package/dist/utils/which.d.ts.map +1 -1
  61. package/dist/utils/which.js +3 -0
  62. package/dist/utils/which.js.map +1 -1
  63. package/package.json +2 -1
@@ -0,0 +1,47 @@
1
+ import { CacheCategory, SafetyTier } from "../types";
2
+ /**
3
+ * Safety tiers ordered from least to most restricted. Used to compare and
4
+ * filter categories against a cleaning profile.
5
+ */
6
+ export declare const SAFETY_TIER_ORDER: SafetyTier[];
7
+ export declare function isSafetyTier(value: string): value is SafetyTier;
8
+ /**
9
+ * Display metadata per tier. Colors reference chalk method names so UI code
10
+ * can apply them without this module depending on chalk.
11
+ */
12
+ export declare const SAFETY_TIER_INFO: Record<SafetyTier, {
13
+ label: string;
14
+ color: "green" | "cyan" | "yellow" | "red";
15
+ summary: string;
16
+ }>;
17
+ /**
18
+ * Effective safety tier for a category. Categories that predate the safety
19
+ * field derive a tier from their priority: critical (active in the last day)
20
+ * maps to caution, low (untouched for 30+ days) maps to safe, everything
21
+ * else is probably-safe. "manual" is never derived - cleaners must opt in
22
+ * explicitly.
23
+ */
24
+ export declare function effectiveSafety(category: CacheCategory): SafetyTier;
25
+ /**
26
+ * Cleaning profiles: named presets mapping to the set of tiers cleaned
27
+ * without per-item confirmation. The "manual" tier is intentionally part of
28
+ * no profile - manual categories always need explicit consent.
29
+ */
30
+ export type CleaningProfileName = "conservative" | "balanced" | "aggressive";
31
+ export declare const CLEANING_PROFILES: Record<CleaningProfileName, {
32
+ tiers: SafetyTier[];
33
+ description: string;
34
+ }>;
35
+ export declare const DEFAULT_PROFILE: CleaningProfileName;
36
+ export declare function isCleaningProfileName(value: string): value is CleaningProfileName;
37
+ /**
38
+ * Resolve the allowed tiers for a profile name; unknown names fall back to
39
+ * the default profile.
40
+ */
41
+ export declare function tiersForProfile(profile?: string): SafetyTier[];
42
+ /**
43
+ * Parse a user-supplied comma-separated tier list (e.g. "safe,caution").
44
+ * Returns null when any entry is invalid so callers can report it.
45
+ */
46
+ export declare function parseSafetyTiers(input: string): SafetyTier[] | null;
47
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/safety/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,UAAU,EAKzC,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CACnC,UAAU,EACV;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAwB/E,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,CAWnE;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAE7E,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,mBAAmB,EACnB;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAgB7C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,mBAAgC,CAAC;AAE/D,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GACZ,KAAK,IAAI,mBAAmB,CAE9B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,EAAE,CAK9D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,IAAI,CAanE"}
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_PROFILE = exports.CLEANING_PROFILES = exports.SAFETY_TIER_INFO = exports.SAFETY_TIER_ORDER = void 0;
4
+ exports.isSafetyTier = isSafetyTier;
5
+ exports.effectiveSafety = effectiveSafety;
6
+ exports.isCleaningProfileName = isCleaningProfileName;
7
+ exports.tiersForProfile = tiersForProfile;
8
+ exports.parseSafetyTiers = parseSafetyTiers;
9
+ /**
10
+ * Safety tiers ordered from least to most restricted. Used to compare and
11
+ * filter categories against a cleaning profile.
12
+ */
13
+ exports.SAFETY_TIER_ORDER = [
14
+ "safe",
15
+ "probably-safe",
16
+ "caution",
17
+ "manual",
18
+ ];
19
+ function isSafetyTier(value) {
20
+ return exports.SAFETY_TIER_ORDER.includes(value);
21
+ }
22
+ /**
23
+ * Display metadata per tier. Colors reference chalk method names so UI code
24
+ * can apply them without this module depending on chalk.
25
+ */
26
+ exports.SAFETY_TIER_INFO = {
27
+ safe: {
28
+ label: "SAFE",
29
+ color: "green",
30
+ summary: "Regenerated transparently; no observable downside to cleaning",
31
+ },
32
+ "probably-safe": {
33
+ label: "PROBABLY SAFE",
34
+ color: "cyan",
35
+ summary: "Regenerable; apps may start slower or re-download data once",
36
+ },
37
+ caution: {
38
+ label: "CAUTION",
39
+ color: "yellow",
40
+ summary: "May lose useful state (offline content, large re-downloads) or upset running apps",
41
+ },
42
+ manual: {
43
+ label: "MANUAL",
44
+ color: "red",
45
+ summary: "User-data adjacent; requires explicit per-item confirmation, never cleaned implicitly",
46
+ },
47
+ };
48
+ /**
49
+ * Effective safety tier for a category. Categories that predate the safety
50
+ * field derive a tier from their priority: critical (active in the last day)
51
+ * maps to caution, low (untouched for 30+ days) maps to safe, everything
52
+ * else is probably-safe. "manual" is never derived - cleaners must opt in
53
+ * explicitly.
54
+ */
55
+ function effectiveSafety(category) {
56
+ if (category.safety)
57
+ return category.safety;
58
+ switch (category.priority) {
59
+ case "critical":
60
+ return "caution";
61
+ case "low":
62
+ return "safe";
63
+ default:
64
+ return "probably-safe";
65
+ }
66
+ }
67
+ exports.CLEANING_PROFILES = {
68
+ conservative: {
69
+ tiers: ["safe"],
70
+ description: "Only caches that are definitely safe to clean",
71
+ },
72
+ balanced: {
73
+ tiers: ["safe", "probably-safe"],
74
+ description: "Safe caches plus regenerable ones that may cost a slower next launch (default)",
75
+ },
76
+ aggressive: {
77
+ tiers: ["safe", "probably-safe", "caution"],
78
+ description: "Everything except manual-confirmation items; includes caches with re-download or running-app risks",
79
+ },
80
+ };
81
+ exports.DEFAULT_PROFILE = "balanced";
82
+ function isCleaningProfileName(value) {
83
+ return value in exports.CLEANING_PROFILES;
84
+ }
85
+ /**
86
+ * Resolve the allowed tiers for a profile name; unknown names fall back to
87
+ * the default profile.
88
+ */
89
+ function tiersForProfile(profile) {
90
+ if (profile && isCleaningProfileName(profile)) {
91
+ return exports.CLEANING_PROFILES[profile].tiers;
92
+ }
93
+ return exports.CLEANING_PROFILES[exports.DEFAULT_PROFILE].tiers;
94
+ }
95
+ /**
96
+ * Parse a user-supplied comma-separated tier list (e.g. "safe,caution").
97
+ * Returns null when any entry is invalid so callers can report it.
98
+ */
99
+ function parseSafetyTiers(input) {
100
+ const parts = input
101
+ .split(",")
102
+ .map((p) => p.trim().toLowerCase())
103
+ .filter(Boolean);
104
+ if (parts.length === 0)
105
+ return null;
106
+ const tiers = [];
107
+ for (const part of parts) {
108
+ if (!isSafetyTier(part))
109
+ return null;
110
+ if (!tiers.includes(part))
111
+ tiers.push(part);
112
+ }
113
+ return tiers;
114
+ }
115
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/safety/index.ts"],"names":[],"mappings":";;;AAaA,oCAEC;AAyCD,0CAWC;AA+BD,sDAIC;AAMD,0CAKC;AAMD,4CAaC;AAlID;;;GAGG;AACU,QAAA,iBAAiB,GAAiB;IAC7C,MAAM;IACN,eAAe;IACf,SAAS;IACT,QAAQ;CACT,CAAC;AAEF,SAAgB,YAAY,CAAC,KAAa;IACxC,OAAQ,yBAA8B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACzD,CAAC;AAED;;;GAGG;AACU,QAAA,gBAAgB,GAGzB;IACF,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM;QACb,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,+DAA+D;KACzE;IACD,eAAe,EAAE;QACf,KAAK,EAAE,eAAe;QACtB,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,6DAA6D;KACvE;IACD,OAAO,EAAE;QACP,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,QAAQ;QACf,OAAO,EACL,mFAAmF;KACtF;IACD,MAAM,EAAE;QACN,KAAK,EAAE,QAAQ;QACf,KAAK,EAAE,KAAK;QACZ,OAAO,EACL,uFAAuF;KAC1F;CACF,CAAC;AAEF;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,QAAuB;IACrD,IAAI,QAAQ,CAAC,MAAM;QAAE,OAAO,QAAQ,CAAC,MAAM,CAAC;IAE5C,QAAQ,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAC1B,KAAK,UAAU;YACb,OAAO,SAAS,CAAC;QACnB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB;YACE,OAAO,eAAe,CAAC;IAC3B,CAAC;AACH,CAAC;AASY,QAAA,iBAAiB,GAG1B;IACF,YAAY,EAAE;QACZ,KAAK,EAAE,CAAC,MAAM,CAAC;QACf,WAAW,EAAE,+CAA+C;KAC7D;IACD,QAAQ,EAAE;QACR,KAAK,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC;QAChC,WAAW,EACT,gFAAgF;KACnF;IACD,UAAU,EAAE;QACV,KAAK,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,CAAC;QAC3C,WAAW,EACT,oGAAoG;KACvG;CACF,CAAC;AAEW,QAAA,eAAe,GAAwB,UAAU,CAAC;AAE/D,SAAgB,qBAAqB,CACnC,KAAa;IAEb,OAAO,KAAK,IAAI,yBAAiB,CAAC;AACpC,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,OAAgB;IAC9C,IAAI,OAAO,IAAI,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;QAC9C,OAAO,yBAAiB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC;IAC1C,CAAC;IACD,OAAO,yBAAiB,CAAC,uBAAe,CAAC,CAAC,KAAK,CAAC;AAClD,CAAC;AAED;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,KAAa;IAC5C,MAAM,KAAK,GAAG,KAAK;SAChB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;SAClC,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { SafetyTier } from "../types";
2
+ /**
3
+ * Verdict for a discovered cache path. Beyond the four user-facing safety
4
+ * tiers, the rule engine can also exclude paths entirely:
5
+ * - "never": not a cache (or user-data adjacent enough that deleting it can
6
+ * destroy data). Never shown, never cleaned.
7
+ * - "claimed": already covered by a dedicated cleaner module; excluded from
8
+ * discovery to avoid double-counting and double-cleaning.
9
+ */
10
+ export type RuleVerdict = SafetyTier | "never" | "claimed";
11
+ export interface RuleMatch {
12
+ verdict: RuleVerdict;
13
+ reason: string;
14
+ }
15
+ /**
16
+ * Classify a discovered cache directory. First-match-wins over the ordered
17
+ * rule list; unmatched paths default to "probably-safe" because every
18
+ * discovery root is a platform cache/log location whose contents apps must
19
+ * tolerate losing (Apple's Caches API contract, XDG cache spec).
20
+ */
21
+ export declare function classifyCachePath(absolutePath: string): RuleMatch;
22
+ /**
23
+ * Top-level discovery roots for the current platform. Computed at call time
24
+ * so os.homedir()/env mocks and changes are respected.
25
+ */
26
+ export declare function getDiscoveryRoots(): string[];
27
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/safety/rules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AA+YD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CA+BjE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CA6B5C"}
@@ -0,0 +1,465 @@
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.classifyCachePath = classifyCachePath;
37
+ exports.getDiscoveryRoots = getDiscoveryRoots;
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ /** Predicate factory: basename matches. */
41
+ const base = (re) => (ctx) => re.test(ctx.base);
42
+ /** Predicate factory: normalized full path matches. */
43
+ const full = (re) => (ctx) => re.test(ctx.full);
44
+ /**
45
+ * Ordered, first-match-wins classification rules. Priority:
46
+ * never > claimed > manual > caution > safe; anything unmatched falls
47
+ * through to the "probably-safe" default in classifyCachePath().
48
+ */
49
+ const RULES = [
50
+ // ---------------------------------------------------------------- never
51
+ {
52
+ test: /^com\.apple\.bird$/i,
53
+ verdict: "never",
54
+ reason: "iCloud Drive daemon state; deleting can corrupt iCloud sync",
55
+ },
56
+ {
57
+ test: /^cloudkit$/i,
58
+ verdict: "never",
59
+ reason: "CloudKit sync state; deleting can corrupt iCloud sync",
60
+ },
61
+ {
62
+ test: /^com\.apple\.cloudkit/i,
63
+ verdict: "never",
64
+ reason: "CloudKit daemon state; deleting can corrupt iCloud sync",
65
+ },
66
+ {
67
+ test: /^com\.apple\.mail/i,
68
+ verdict: "never",
69
+ reason: "Mail attachments and message index; user-data adjacent",
70
+ },
71
+ {
72
+ test: /^com\.apple\.mobilesync/i,
73
+ verdict: "never",
74
+ reason: "Device backups (MobileSync); deleting destroys backups",
75
+ },
76
+ {
77
+ test: /^com\.docker\.docker$/i,
78
+ verdict: "never",
79
+ reason: "Docker VM disk image; not a cache",
80
+ },
81
+ {
82
+ test: /^com\.apple\.photolibraryd/i,
83
+ verdict: "never",
84
+ reason: "Photos library daemon state; user-data adjacent",
85
+ },
86
+ {
87
+ test: /^com\.apple\.photos/i,
88
+ verdict: "never",
89
+ reason: "Photos app state; user-data adjacent",
90
+ },
91
+ {
92
+ test: full(/\.photoslibrary(\/|$)/i),
93
+ verdict: "never",
94
+ reason: "Inside a Photos library bundle; user data",
95
+ },
96
+ {
97
+ test: /1password/i,
98
+ verdict: "never",
99
+ reason: "Password manager data; never touched",
100
+ },
101
+ {
102
+ test: /bitwarden/i,
103
+ verdict: "never",
104
+ reason: "Password manager data; never touched",
105
+ },
106
+ {
107
+ test: /keepass/i,
108
+ verdict: "never",
109
+ reason: "Password manager data; never touched",
110
+ },
111
+ {
112
+ test: /^keychains$/i,
113
+ verdict: "never",
114
+ reason: "Keychain storage; never touched",
115
+ },
116
+ {
117
+ test: /^signal$/i,
118
+ verdict: "never",
119
+ reason: "Signal messenger data; messages are user data",
120
+ },
121
+ {
122
+ test: /^com\.apple\.security/i,
123
+ verdict: "never",
124
+ reason: "Security daemon state; never touched",
125
+ },
126
+ {
127
+ test: /^clouddocs$/i,
128
+ verdict: "never",
129
+ reason: "iCloud Documents sync state; deleting can corrupt sync",
130
+ },
131
+ // -------------------------------------------------------------- claimed
132
+ {
133
+ test: /^homebrew$/i,
134
+ verdict: "claimed",
135
+ reason: "Covered by the brew cleaner",
136
+ },
137
+ {
138
+ test: /^portable-ruby$/i,
139
+ verdict: "claimed",
140
+ reason: "Covered by the brew cleaner",
141
+ },
142
+ {
143
+ test: /^cask$/i,
144
+ verdict: "claimed",
145
+ reason: "Covered by the brew cleaner",
146
+ },
147
+ {
148
+ test: /^\.?npm$/i,
149
+ verdict: "claimed",
150
+ reason: "Covered by the npm cleaner",
151
+ },
152
+ {
153
+ test: /^\.?yarn$/i,
154
+ verdict: "claimed",
155
+ reason: "Covered by the yarn cleaner",
156
+ },
157
+ {
158
+ test: /^\.?bun$/i,
159
+ verdict: "claimed",
160
+ reason: "Covered by the bun cleaner",
161
+ },
162
+ {
163
+ test: /^pip$/i,
164
+ verdict: "claimed",
165
+ reason: "Covered by the pip cleaner",
166
+ },
167
+ {
168
+ test: /^pip-tools$/i,
169
+ verdict: "claimed",
170
+ reason: "Covered by the pip cleaner",
171
+ },
172
+ {
173
+ test: /^pipenv$/i,
174
+ verdict: "claimed",
175
+ reason: "Covered by the pipenv cleaner",
176
+ },
177
+ {
178
+ test: /^node-gyp$/i,
179
+ verdict: "claimed",
180
+ reason: "Covered by the node-gyp cleaner",
181
+ },
182
+ {
183
+ test: /^go-build$/i,
184
+ verdict: "claimed",
185
+ reason: "Covered by the go-build cleaner",
186
+ },
187
+ {
188
+ test: /^org\.swift\.swiftpm$/i,
189
+ verdict: "claimed",
190
+ reason: "Covered by the swiftpm cleaner",
191
+ },
192
+ {
193
+ test: /^cocoapods$/i,
194
+ verdict: "claimed",
195
+ reason: "Covered by the cocoapods cleaner",
196
+ },
197
+ {
198
+ test: /^turborepo$/i,
199
+ verdict: "claimed",
200
+ reason: "Covered by the turbo cleaner",
201
+ },
202
+ {
203
+ test: /^ms-playwright/i,
204
+ verdict: "claimed",
205
+ reason: "Covered by the playwright cleaner",
206
+ },
207
+ {
208
+ test: full(/\/google\/chrome(\/|$)/i),
209
+ verdict: "claimed",
210
+ reason: "Covered by the chrome cleaner",
211
+ },
212
+ {
213
+ test: full(/\/mozilla\/firefox(\/|$)/i),
214
+ verdict: "claimed",
215
+ reason: "Covered by the firefox cleaner",
216
+ },
217
+ {
218
+ test: /^firefox$/i,
219
+ verdict: "claimed",
220
+ reason: "Covered by the firefox cleaner",
221
+ },
222
+ {
223
+ test: /^com\.microsoft\.vscode/i,
224
+ verdict: "claimed",
225
+ reason: "Covered by the vscode cleaner",
226
+ },
227
+ {
228
+ test: /^com\.vscodium/i,
229
+ verdict: "claimed",
230
+ reason: "Covered by the vscode cleaner",
231
+ },
232
+ {
233
+ test: /^com\.todesktop\./i,
234
+ verdict: "claimed",
235
+ reason: "Covered by the cursor cleaner",
236
+ },
237
+ {
238
+ test: /^com\.exafunction\.windsurf/i,
239
+ verdict: "claimed",
240
+ reason: "Covered by the windsurf cleaner",
241
+ },
242
+ {
243
+ test: /^com\.google\.antigravity/i,
244
+ verdict: "claimed",
245
+ reason: "Covered by an existing IDE cleaner",
246
+ },
247
+ {
248
+ test: /^dev\.zed\.zed/i,
249
+ verdict: "claimed",
250
+ reason: "Covered by the zed cleaner",
251
+ },
252
+ {
253
+ test: /^jetbrains$/i,
254
+ verdict: "claimed",
255
+ reason: "Covered by the jetbrains cleaner",
256
+ },
257
+ {
258
+ test: /^androidstudio/i,
259
+ verdict: "claimed",
260
+ reason: "Covered by the androidstudio cleaner",
261
+ },
262
+ {
263
+ test: /^com\.apple\.dt\./i,
264
+ verdict: "claimed",
265
+ reason: "Covered by the xcode cleaner",
266
+ },
267
+ {
268
+ test: /\.shipit$/i,
269
+ verdict: "claimed",
270
+ reason: "Covered by the shipit cleaner",
271
+ },
272
+ {
273
+ test: /keystone/i,
274
+ verdict: "claimed",
275
+ reason: "Covered by the shipit cleaner (Google Keystone)",
276
+ },
277
+ // --------------------------------------------------------------- manual
278
+ {
279
+ test: /^huggingface$/i,
280
+ verdict: "manual",
281
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
282
+ },
283
+ {
284
+ test: /^torch$/i,
285
+ verdict: "manual",
286
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
287
+ },
288
+ {
289
+ test: /^whisper$/i,
290
+ verdict: "manual",
291
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
292
+ },
293
+ {
294
+ test: /^suno$/i,
295
+ verdict: "manual",
296
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
297
+ },
298
+ {
299
+ test: /^modelscope$/i,
300
+ verdict: "manual",
301
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
302
+ },
303
+ {
304
+ test: /^ollama$/i,
305
+ verdict: "manual",
306
+ reason: "ML model store; regenerable but re-downloads can exceed 100GB",
307
+ },
308
+ {
309
+ // Exact segment match: "spotify-ui-widgets" or "my-spotify-backup"
310
+ // must NOT be pulled into the manual tier.
311
+ test: (ctx) => ctx.segments.some((s) => s === "spotify" || s === "com.spotify.client") &&
312
+ ctx.segments.some((s) => s === "persistentcache"),
313
+ verdict: "manual",
314
+ reason: "Spotify PersistentCache; offline downloads may live here",
315
+ },
316
+ // -------------------------------------------------------------- caution
317
+ {
318
+ test: /^com\.apple\./i,
319
+ verdict: "caution",
320
+ reason: "Apple system daemon cache; long-running daemons may misbehave",
321
+ },
322
+ {
323
+ test: /^arc$/i,
324
+ verdict: "caution",
325
+ reason: "Browser cache; risky while the browser is running",
326
+ },
327
+ {
328
+ test: /^company\.thebrowser\./i,
329
+ verdict: "caution",
330
+ reason: "Browser cache; risky while the browser is running",
331
+ },
332
+ {
333
+ test: /^dia$/i,
334
+ verdict: "caution",
335
+ reason: "Browser cache; risky while the browser is running",
336
+ },
337
+ {
338
+ test: /^slack$/i,
339
+ verdict: "caution",
340
+ reason: "Chat/meeting app cache; risky while the app is running",
341
+ },
342
+ {
343
+ test: /^discord$/i,
344
+ verdict: "caution",
345
+ reason: "Chat/meeting app cache; risky while the app is running",
346
+ },
347
+ {
348
+ test: /^microsoft teams$/i,
349
+ verdict: "caution",
350
+ reason: "Chat/meeting app cache; risky while the app is running",
351
+ },
352
+ {
353
+ test: /^teams$/i,
354
+ verdict: "caution",
355
+ reason: "Chat/meeting app cache; risky while the app is running",
356
+ },
357
+ {
358
+ test: /^skype$/i,
359
+ verdict: "caution",
360
+ reason: "Chat/meeting app cache; risky while the app is running",
361
+ },
362
+ {
363
+ test: /^zoom\.us$/i,
364
+ verdict: "caution",
365
+ reason: "Chat/meeting app cache; risky while the app is running",
366
+ },
367
+ {
368
+ test: /^uv$/i,
369
+ verdict: "caution",
370
+ reason: "uv package cache; 80GB-class re-downloads, prefer `uv cache clean`",
371
+ },
372
+ // ----------------------------------------------------------------- safe
373
+ {
374
+ test: base(/^(gpucache|code cache|shadercache|grshadercache|dawncache|dawngraphitecache|cacheddata)$/i),
375
+ verdict: "safe",
376
+ reason: "GPU/shader/code cache; regenerated transparently",
377
+ },
378
+ {
379
+ test: (ctx) => ctx.full.includes("/application support/caches/") &&
380
+ /(-updater|\.update)$/i.test(ctx.base),
381
+ verdict: "safe",
382
+ reason: "Electron updater staging directory; regenerated transparently",
383
+ },
384
+ {
385
+ test: base(/^\.?thumbnails$/i),
386
+ verdict: "safe",
387
+ reason: "Thumbnail cache; regenerated transparently",
388
+ },
389
+ {
390
+ test: base(/^fontconfig$/i),
391
+ verdict: "safe",
392
+ reason: "Font cache; regenerated transparently",
393
+ },
394
+ {
395
+ test: base(/^mesa_shader_cache$/i),
396
+ verdict: "safe",
397
+ reason: "Shader cache; regenerated transparently",
398
+ },
399
+ ];
400
+ /**
401
+ * Classify a discovered cache directory. First-match-wins over the ordered
402
+ * rule list; unmatched paths default to "probably-safe" because every
403
+ * discovery root is a platform cache/log location whose contents apps must
404
+ * tolerate losing (Apple's Caches API contract, XDG cache spec).
405
+ */
406
+ function classifyCachePath(absolutePath) {
407
+ const normalized = absolutePath.replace(/\\/g, "/").toLowerCase();
408
+ const segments = normalized.split("/").filter(Boolean);
409
+ const ctx = {
410
+ full: normalized,
411
+ segments,
412
+ base: segments[segments.length - 1] ?? "",
413
+ };
414
+ for (const rule of RULES) {
415
+ const test = rule.test;
416
+ const matched = test instanceof RegExp
417
+ ? segments.some((segment) => test.test(segment))
418
+ : test(ctx);
419
+ if (matched) {
420
+ return { verdict: rule.verdict, reason: rule.reason };
421
+ }
422
+ }
423
+ if (ctx.full.includes("/library/logs/")) {
424
+ return {
425
+ verdict: "probably-safe",
426
+ reason: "Log directory; regenerable, apps recreate logs as needed",
427
+ };
428
+ }
429
+ return {
430
+ verdict: "probably-safe",
431
+ reason: "App cache; apps must tolerate cache deletion, next launch may rebuild",
432
+ };
433
+ }
434
+ /**
435
+ * Top-level discovery roots for the current platform. Computed at call time
436
+ * so os.homedir()/env mocks and changes are respected.
437
+ */
438
+ function getDiscoveryRoots() {
439
+ const home = os.homedir();
440
+ let roots;
441
+ switch (os.platform()) {
442
+ case "darwin":
443
+ roots = [
444
+ path.join(home, "Library", "Caches"),
445
+ path.join(home, "Library", "Application Support", "Caches"),
446
+ path.join(home, "Library", "Application Support"),
447
+ path.join(home, "Library", "Logs"),
448
+ path.join(home, ".cache"),
449
+ ];
450
+ break;
451
+ case "win32": {
452
+ const local = process.env.LOCALAPPDATA || path.join(home, "AppData", "Local");
453
+ const roaming = process.env.APPDATA || path.join(home, "AppData", "Roaming");
454
+ roots = [local, roaming];
455
+ break;
456
+ }
457
+ default:
458
+ roots = [process.env.XDG_CACHE_HOME || path.join(home, ".cache")];
459
+ }
460
+ // Drop any relative root. An empty os.homedir() (stripped env in some CI or
461
+ // service accounts) would otherwise yield paths like "Library/Caches" that
462
+ // resolve against the current working directory.
463
+ return roots.filter((root) => path.isAbsolute(root));
464
+ }
465
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/safety/rules.ts"],"names":[],"mappings":"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"}