@roomi-fields/notebooklm-mcp 1.1.2
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 +22 -0
- package/README.md +548 -0
- package/dist/auth/auth-manager.d.ts +139 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.js +981 -0
- package/dist/auth/auth-manager.js.map +1 -0
- package/dist/config.d.ts +89 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +216 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +41 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-wrapper.d.ts +8 -0
- package/dist/http-wrapper.d.ts.map +1 -0
- package/dist/http-wrapper.js +221 -0
- package/dist/http-wrapper.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +499 -0
- package/dist/index.js.map +1 -0
- package/dist/library/notebook-library.d.ts +81 -0
- package/dist/library/notebook-library.d.ts.map +1 -0
- package/dist/library/notebook-library.js +362 -0
- package/dist/library/notebook-library.js.map +1 -0
- package/dist/library/types.d.ts +67 -0
- package/dist/library/types.d.ts.map +1 -0
- package/dist/library/types.js +8 -0
- package/dist/library/types.js.map +1 -0
- package/dist/session/browser-session.d.ts +108 -0
- package/dist/session/browser-session.d.ts.map +1 -0
- package/dist/session/browser-session.js +630 -0
- package/dist/session/browser-session.js.map +1 -0
- package/dist/session/session-manager.d.ts +76 -0
- package/dist/session/session-manager.d.ts.map +1 -0
- package/dist/session/session-manager.js +273 -0
- package/dist/session/session-manager.js.map +1 -0
- package/dist/session/shared-context-manager.d.ts +107 -0
- package/dist/session/shared-context-manager.d.ts.map +1 -0
- package/dist/session/shared-context-manager.js +447 -0
- package/dist/session/shared-context-manager.js.map +1 -0
- package/dist/tools/index.d.ts +225 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1396 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types.d.ts +82 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +133 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +673 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/logger.d.ts +61 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +92 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/page-utils.d.ts +54 -0
- package/dist/utils/page-utils.d.ts.map +1 -0
- package/dist/utils/page-utils.js +422 -0
- package/dist/utils/page-utils.js.map +1 -0
- package/dist/utils/stealth-utils.d.ts +135 -0
- package/dist/utils/stealth-utils.d.ts.map +1 -0
- package/dist/utils/stealth-utils.js +398 -0
- package/dist/utils/stealth-utils.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup Manager for NotebookLM MCP Server
|
|
3
|
+
*
|
|
4
|
+
* ULTRATHINK EDITION - Complete cleanup across all platforms!
|
|
5
|
+
*
|
|
6
|
+
* Handles safe removal of:
|
|
7
|
+
* - Legacy data from notebooklm-mcp-nodejs
|
|
8
|
+
* - Current installation data
|
|
9
|
+
* - Browser profiles and session data
|
|
10
|
+
* - NPM/NPX cache
|
|
11
|
+
* - Claude CLI MCP logs
|
|
12
|
+
* - Claude Projects cache
|
|
13
|
+
* - Temporary backups
|
|
14
|
+
* - Editor logs (Cursor, VSCode)
|
|
15
|
+
* - Trash files (optional)
|
|
16
|
+
*
|
|
17
|
+
* Platform support: Linux, Windows, macOS
|
|
18
|
+
*/
|
|
19
|
+
import fs from "fs/promises";
|
|
20
|
+
import path from "path";
|
|
21
|
+
import { globby } from "globby";
|
|
22
|
+
import envPaths from "env-paths";
|
|
23
|
+
import os from "os";
|
|
24
|
+
import { log } from "./logger.js";
|
|
25
|
+
export class CleanupManager {
|
|
26
|
+
legacyPaths;
|
|
27
|
+
currentPaths;
|
|
28
|
+
homeDir;
|
|
29
|
+
tempDir;
|
|
30
|
+
constructor() {
|
|
31
|
+
// envPaths() does NOT create directories - it just returns path strings
|
|
32
|
+
// IMPORTANT: envPaths() has a default suffix 'nodejs', so we must explicitly disable it!
|
|
33
|
+
// Legacy paths with -nodejs suffix (using default suffix behavior)
|
|
34
|
+
this.legacyPaths = envPaths("notebooklm-mcp"); // This becomes notebooklm-mcp-nodejs by default
|
|
35
|
+
// Current paths without suffix (disable the default suffix with empty string)
|
|
36
|
+
this.currentPaths = envPaths("notebooklm-mcp", { suffix: "" });
|
|
37
|
+
// Platform-agnostic paths
|
|
38
|
+
this.homeDir = os.homedir();
|
|
39
|
+
this.tempDir = os.tmpdir();
|
|
40
|
+
}
|
|
41
|
+
// ============================================================================
|
|
42
|
+
// Platform-Specific Path Resolution
|
|
43
|
+
// ============================================================================
|
|
44
|
+
/**
|
|
45
|
+
* Get NPM cache directory (platform-specific)
|
|
46
|
+
*/
|
|
47
|
+
getNpmCachePath() {
|
|
48
|
+
return path.join(this.homeDir, ".npm");
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get Claude CLI cache directory (platform-specific)
|
|
52
|
+
*/
|
|
53
|
+
getClaudeCliCachePath() {
|
|
54
|
+
const platform = process.platform;
|
|
55
|
+
if (platform === "win32") {
|
|
56
|
+
const localAppData = process.env.LOCALAPPDATA || path.join(this.homeDir, "AppData", "Local");
|
|
57
|
+
return path.join(localAppData, "claude-cli-nodejs");
|
|
58
|
+
}
|
|
59
|
+
else if (platform === "darwin") {
|
|
60
|
+
return path.join(this.homeDir, "Library", "Caches", "claude-cli-nodejs");
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Linux and others
|
|
64
|
+
return path.join(this.homeDir, ".cache", "claude-cli-nodejs");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get Claude projects directory (platform-specific)
|
|
69
|
+
*/
|
|
70
|
+
getClaudeProjectsPath() {
|
|
71
|
+
const platform = process.platform;
|
|
72
|
+
if (platform === "win32") {
|
|
73
|
+
const appData = process.env.APPDATA || path.join(this.homeDir, "AppData", "Roaming");
|
|
74
|
+
return path.join(appData, ".claude", "projects");
|
|
75
|
+
}
|
|
76
|
+
else if (platform === "darwin") {
|
|
77
|
+
return path.join(this.homeDir, "Library", "Application Support", "claude", "projects");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Linux and others
|
|
81
|
+
return path.join(this.homeDir, ".claude", "projects");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get editor config paths (Cursor, VSCode)
|
|
86
|
+
*/
|
|
87
|
+
getEditorConfigPaths() {
|
|
88
|
+
const platform = process.platform;
|
|
89
|
+
const paths = [];
|
|
90
|
+
if (platform === "win32") {
|
|
91
|
+
const appData = process.env.APPDATA || path.join(this.homeDir, "AppData", "Roaming");
|
|
92
|
+
paths.push(path.join(appData, "Cursor", "logs"), path.join(appData, "Code", "logs"));
|
|
93
|
+
}
|
|
94
|
+
else if (platform === "darwin") {
|
|
95
|
+
paths.push(path.join(this.homeDir, "Library", "Application Support", "Cursor", "logs"), path.join(this.homeDir, "Library", "Application Support", "Code", "logs"));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// Linux
|
|
99
|
+
paths.push(path.join(this.homeDir, ".config", "Cursor", "logs"), path.join(this.homeDir, ".config", "Code", "logs"));
|
|
100
|
+
}
|
|
101
|
+
return paths;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get trash directory (platform-specific)
|
|
105
|
+
*/
|
|
106
|
+
getTrashPath() {
|
|
107
|
+
const platform = process.platform;
|
|
108
|
+
if (platform === "darwin") {
|
|
109
|
+
return path.join(this.homeDir, ".Trash");
|
|
110
|
+
}
|
|
111
|
+
else if (platform === "linux") {
|
|
112
|
+
return path.join(this.homeDir, ".local", "share", "Trash");
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
// Windows Recycle Bin is complex, skip for now
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get manual legacy config paths that might not be caught by envPaths
|
|
121
|
+
* This ensures we catch ALL legacy installations including old config.json files
|
|
122
|
+
*/
|
|
123
|
+
getManualLegacyPaths() {
|
|
124
|
+
const paths = [];
|
|
125
|
+
const platform = process.platform;
|
|
126
|
+
if (platform === "linux") {
|
|
127
|
+
// Linux-specific paths
|
|
128
|
+
paths.push(path.join(this.homeDir, ".config", "notebooklm-mcp"), path.join(this.homeDir, ".config", "notebooklm-mcp-nodejs"), path.join(this.homeDir, ".local", "share", "notebooklm-mcp"), path.join(this.homeDir, ".local", "share", "notebooklm-mcp-nodejs"), path.join(this.homeDir, ".cache", "notebooklm-mcp"), path.join(this.homeDir, ".cache", "notebooklm-mcp-nodejs"), path.join(this.homeDir, ".local", "state", "notebooklm-mcp"), path.join(this.homeDir, ".local", "state", "notebooklm-mcp-nodejs"));
|
|
129
|
+
}
|
|
130
|
+
else if (platform === "darwin") {
|
|
131
|
+
// macOS-specific paths
|
|
132
|
+
paths.push(path.join(this.homeDir, "Library", "Application Support", "notebooklm-mcp"), path.join(this.homeDir, "Library", "Application Support", "notebooklm-mcp-nodejs"), path.join(this.homeDir, "Library", "Preferences", "notebooklm-mcp"), path.join(this.homeDir, "Library", "Preferences", "notebooklm-mcp-nodejs"), path.join(this.homeDir, "Library", "Caches", "notebooklm-mcp"), path.join(this.homeDir, "Library", "Caches", "notebooklm-mcp-nodejs"), path.join(this.homeDir, "Library", "Logs", "notebooklm-mcp"), path.join(this.homeDir, "Library", "Logs", "notebooklm-mcp-nodejs"));
|
|
133
|
+
}
|
|
134
|
+
else if (platform === "win32") {
|
|
135
|
+
// Windows-specific paths
|
|
136
|
+
const localAppData = process.env.LOCALAPPDATA || path.join(this.homeDir, "AppData", "Local");
|
|
137
|
+
const appData = process.env.APPDATA || path.join(this.homeDir, "AppData", "Roaming");
|
|
138
|
+
paths.push(path.join(localAppData, "notebooklm-mcp"), path.join(localAppData, "notebooklm-mcp-nodejs"), path.join(appData, "notebooklm-mcp"), path.join(appData, "notebooklm-mcp-nodejs"));
|
|
139
|
+
}
|
|
140
|
+
return paths;
|
|
141
|
+
}
|
|
142
|
+
// ============================================================================
|
|
143
|
+
// Search Methods for Different File Types
|
|
144
|
+
// ============================================================================
|
|
145
|
+
/**
|
|
146
|
+
* Find NPM/NPX cache files
|
|
147
|
+
*/
|
|
148
|
+
async findNpmCache() {
|
|
149
|
+
const found = [];
|
|
150
|
+
try {
|
|
151
|
+
const npmCachePath = this.getNpmCachePath();
|
|
152
|
+
const npxPath = path.join(npmCachePath, "_npx");
|
|
153
|
+
if (!(await this.pathExists(npxPath))) {
|
|
154
|
+
return found;
|
|
155
|
+
}
|
|
156
|
+
// Search for notebooklm-mcp in npx cache
|
|
157
|
+
const pattern = path.join(npxPath, "*/node_modules/notebooklm-mcp");
|
|
158
|
+
const matches = await globby(pattern, { onlyDirectories: true, absolute: true });
|
|
159
|
+
found.push(...matches);
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
log.warning(`โ ๏ธ Error searching NPM cache: ${error}`);
|
|
163
|
+
}
|
|
164
|
+
return found;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Find Claude CLI MCP logs
|
|
168
|
+
*/
|
|
169
|
+
async findClaudeCliLogs() {
|
|
170
|
+
const found = [];
|
|
171
|
+
try {
|
|
172
|
+
const claudeCliPath = this.getClaudeCliCachePath();
|
|
173
|
+
if (!(await this.pathExists(claudeCliPath))) {
|
|
174
|
+
return found;
|
|
175
|
+
}
|
|
176
|
+
// Search for notebooklm MCP logs
|
|
177
|
+
const patterns = [
|
|
178
|
+
path.join(claudeCliPath, "*/mcp-logs-notebooklm"),
|
|
179
|
+
path.join(claudeCliPath, "*notebooklm-mcp*"),
|
|
180
|
+
];
|
|
181
|
+
for (const pattern of patterns) {
|
|
182
|
+
const matches = await globby(pattern, { onlyDirectories: true, absolute: true });
|
|
183
|
+
found.push(...matches);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
log.warning(`โ ๏ธ Error searching Claude CLI cache: ${error}`);
|
|
188
|
+
}
|
|
189
|
+
return found;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Find Claude projects cache
|
|
193
|
+
*/
|
|
194
|
+
async findClaudeProjects() {
|
|
195
|
+
const found = [];
|
|
196
|
+
try {
|
|
197
|
+
const projectsPath = this.getClaudeProjectsPath();
|
|
198
|
+
if (!(await this.pathExists(projectsPath))) {
|
|
199
|
+
return found;
|
|
200
|
+
}
|
|
201
|
+
// Search for notebooklm-mcp projects
|
|
202
|
+
const pattern = path.join(projectsPath, "*notebooklm-mcp*");
|
|
203
|
+
const matches = await globby(pattern, { onlyDirectories: true, absolute: true });
|
|
204
|
+
found.push(...matches);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
log.warning(`โ ๏ธ Error searching Claude projects: ${error}`);
|
|
208
|
+
}
|
|
209
|
+
return found;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Find temporary backups
|
|
213
|
+
*/
|
|
214
|
+
async findTemporaryBackups() {
|
|
215
|
+
const found = [];
|
|
216
|
+
try {
|
|
217
|
+
// Search for notebooklm backup directories in temp
|
|
218
|
+
const pattern = path.join(this.tempDir, "notebooklm-backup-*");
|
|
219
|
+
const matches = await globby(pattern, { onlyDirectories: true, absolute: true });
|
|
220
|
+
found.push(...matches);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
log.warning(`โ ๏ธ Error searching temp backups: ${error}`);
|
|
224
|
+
}
|
|
225
|
+
return found;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Find editor logs (Cursor, VSCode)
|
|
229
|
+
*/
|
|
230
|
+
async findEditorLogs() {
|
|
231
|
+
const found = [];
|
|
232
|
+
try {
|
|
233
|
+
const editorPaths = this.getEditorConfigPaths();
|
|
234
|
+
for (const editorPath of editorPaths) {
|
|
235
|
+
if (!(await this.pathExists(editorPath))) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
// Search for MCP notebooklm logs
|
|
239
|
+
const pattern = path.join(editorPath, "**/exthost/**/*notebooklm*.log");
|
|
240
|
+
const matches = await globby(pattern, { onlyFiles: true, absolute: true });
|
|
241
|
+
found.push(...matches);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
log.warning(`โ ๏ธ Error searching editor logs: ${error}`);
|
|
246
|
+
}
|
|
247
|
+
return found;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Find trash files
|
|
251
|
+
*/
|
|
252
|
+
async findTrashFiles() {
|
|
253
|
+
const found = [];
|
|
254
|
+
try {
|
|
255
|
+
const trashPath = this.getTrashPath();
|
|
256
|
+
if (!trashPath || !(await this.pathExists(trashPath))) {
|
|
257
|
+
return found;
|
|
258
|
+
}
|
|
259
|
+
// Search for notebooklm files in trash
|
|
260
|
+
const patterns = [
|
|
261
|
+
path.join(trashPath, "**/*notebooklm*"),
|
|
262
|
+
];
|
|
263
|
+
for (const pattern of patterns) {
|
|
264
|
+
const matches = await globby(pattern, { absolute: true });
|
|
265
|
+
found.push(...matches);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (error) {
|
|
269
|
+
log.warning(`โ ๏ธ Error searching trash: ${error}`);
|
|
270
|
+
}
|
|
271
|
+
return found;
|
|
272
|
+
}
|
|
273
|
+
// ============================================================================
|
|
274
|
+
// Main Cleanup Methods
|
|
275
|
+
// ============================================================================
|
|
276
|
+
/**
|
|
277
|
+
* Get all paths that would be deleted for a given mode (with categorization)
|
|
278
|
+
*/
|
|
279
|
+
async getCleanupPaths(mode, preserveLibrary = false) {
|
|
280
|
+
const categories = [];
|
|
281
|
+
const allPaths = new Set();
|
|
282
|
+
let totalSizeBytes = 0;
|
|
283
|
+
// Category 1: Legacy Paths (notebooklm-mcp-nodejs & manual legacy paths)
|
|
284
|
+
if (mode === "legacy" || mode === "all" || mode === "deep") {
|
|
285
|
+
const legacyPaths = [];
|
|
286
|
+
let legacyBytes = 0;
|
|
287
|
+
// Check envPaths-based legacy directories
|
|
288
|
+
const legacyDirs = [
|
|
289
|
+
this.legacyPaths.data,
|
|
290
|
+
this.legacyPaths.config,
|
|
291
|
+
this.legacyPaths.cache,
|
|
292
|
+
this.legacyPaths.log,
|
|
293
|
+
this.legacyPaths.temp,
|
|
294
|
+
];
|
|
295
|
+
for (const dir of legacyDirs) {
|
|
296
|
+
if (await this.pathExists(dir)) {
|
|
297
|
+
const size = await this.getDirectorySize(dir);
|
|
298
|
+
legacyPaths.push(dir);
|
|
299
|
+
legacyBytes += size;
|
|
300
|
+
allPaths.add(dir);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// CRITICAL: Also check manual legacy paths to catch old config.json files
|
|
304
|
+
// and any paths that envPaths might miss
|
|
305
|
+
const manualLegacyPaths = this.getManualLegacyPaths();
|
|
306
|
+
for (const dir of manualLegacyPaths) {
|
|
307
|
+
if (await this.pathExists(dir) && !allPaths.has(dir)) {
|
|
308
|
+
const size = await this.getDirectorySize(dir);
|
|
309
|
+
legacyPaths.push(dir);
|
|
310
|
+
legacyBytes += size;
|
|
311
|
+
allPaths.add(dir);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (legacyPaths.length > 0) {
|
|
315
|
+
categories.push({
|
|
316
|
+
name: "Legacy Installation (notebooklm-mcp-nodejs)",
|
|
317
|
+
description: "Old installation data with -nodejs suffix and legacy config files",
|
|
318
|
+
paths: legacyPaths,
|
|
319
|
+
totalBytes: legacyBytes,
|
|
320
|
+
optional: false,
|
|
321
|
+
});
|
|
322
|
+
totalSizeBytes += legacyBytes;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
// Category 2: Current Installation
|
|
326
|
+
if (mode === "all" || mode === "deep") {
|
|
327
|
+
const currentPaths = [];
|
|
328
|
+
let currentBytes = 0;
|
|
329
|
+
// If preserveLibrary is true, don't delete the data directory itself
|
|
330
|
+
// Instead, only delete subdirectories
|
|
331
|
+
const currentDirs = preserveLibrary
|
|
332
|
+
? [
|
|
333
|
+
// Don't include data directory to preserve library.json
|
|
334
|
+
this.currentPaths.config,
|
|
335
|
+
this.currentPaths.cache,
|
|
336
|
+
this.currentPaths.log,
|
|
337
|
+
this.currentPaths.temp,
|
|
338
|
+
// Only delete subdirectories, not the parent
|
|
339
|
+
path.join(this.currentPaths.data, "browser_state"),
|
|
340
|
+
path.join(this.currentPaths.data, "chrome_profile"),
|
|
341
|
+
path.join(this.currentPaths.data, "chrome_profile_instances"),
|
|
342
|
+
]
|
|
343
|
+
: [
|
|
344
|
+
// Delete everything including data directory
|
|
345
|
+
this.currentPaths.data,
|
|
346
|
+
this.currentPaths.config,
|
|
347
|
+
this.currentPaths.cache,
|
|
348
|
+
this.currentPaths.log,
|
|
349
|
+
this.currentPaths.temp,
|
|
350
|
+
// Specific subdirectories (only if parent doesn't exist)
|
|
351
|
+
path.join(this.currentPaths.data, "browser_state"),
|
|
352
|
+
path.join(this.currentPaths.data, "chrome_profile"),
|
|
353
|
+
path.join(this.currentPaths.data, "chrome_profile_instances"),
|
|
354
|
+
];
|
|
355
|
+
for (const dir of currentDirs) {
|
|
356
|
+
if (await this.pathExists(dir) && !allPaths.has(dir)) {
|
|
357
|
+
const size = await this.getDirectorySize(dir);
|
|
358
|
+
currentPaths.push(dir);
|
|
359
|
+
currentBytes += size;
|
|
360
|
+
allPaths.add(dir);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (currentPaths.length > 0) {
|
|
364
|
+
const description = preserveLibrary
|
|
365
|
+
? "Active installation data and browser profiles (library.json will be preserved)"
|
|
366
|
+
: "Active installation data and browser profiles";
|
|
367
|
+
categories.push({
|
|
368
|
+
name: "Current Installation (notebooklm-mcp)",
|
|
369
|
+
description,
|
|
370
|
+
paths: currentPaths,
|
|
371
|
+
totalBytes: currentBytes,
|
|
372
|
+
optional: false,
|
|
373
|
+
});
|
|
374
|
+
totalSizeBytes += currentBytes;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Category 3: NPM Cache
|
|
378
|
+
if (mode === "all" || mode === "deep") {
|
|
379
|
+
const npmPaths = await this.findNpmCache();
|
|
380
|
+
if (npmPaths.length > 0) {
|
|
381
|
+
let npmBytes = 0;
|
|
382
|
+
for (const p of npmPaths) {
|
|
383
|
+
if (!allPaths.has(p)) {
|
|
384
|
+
npmBytes += await this.getDirectorySize(p);
|
|
385
|
+
allPaths.add(p);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (npmBytes > 0) {
|
|
389
|
+
categories.push({
|
|
390
|
+
name: "NPM/NPX Cache",
|
|
391
|
+
description: "NPX cached installations of notebooklm-mcp",
|
|
392
|
+
paths: npmPaths,
|
|
393
|
+
totalBytes: npmBytes,
|
|
394
|
+
optional: false,
|
|
395
|
+
});
|
|
396
|
+
totalSizeBytes += npmBytes;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
// Category 4: Claude CLI Logs
|
|
401
|
+
if (mode === "all" || mode === "deep") {
|
|
402
|
+
const claudeCliPaths = await this.findClaudeCliLogs();
|
|
403
|
+
if (claudeCliPaths.length > 0) {
|
|
404
|
+
let claudeCliBytes = 0;
|
|
405
|
+
for (const p of claudeCliPaths) {
|
|
406
|
+
if (!allPaths.has(p)) {
|
|
407
|
+
claudeCliBytes += await this.getDirectorySize(p);
|
|
408
|
+
allPaths.add(p);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (claudeCliBytes > 0) {
|
|
412
|
+
categories.push({
|
|
413
|
+
name: "Claude CLI MCP Logs",
|
|
414
|
+
description: "MCP server logs from Claude CLI",
|
|
415
|
+
paths: claudeCliPaths,
|
|
416
|
+
totalBytes: claudeCliBytes,
|
|
417
|
+
optional: false,
|
|
418
|
+
});
|
|
419
|
+
totalSizeBytes += claudeCliBytes;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// Category 5: Temporary Backups
|
|
424
|
+
if (mode === "all" || mode === "deep") {
|
|
425
|
+
const backupPaths = await this.findTemporaryBackups();
|
|
426
|
+
if (backupPaths.length > 0) {
|
|
427
|
+
let backupBytes = 0;
|
|
428
|
+
for (const p of backupPaths) {
|
|
429
|
+
if (!allPaths.has(p)) {
|
|
430
|
+
backupBytes += await this.getDirectorySize(p);
|
|
431
|
+
allPaths.add(p);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (backupBytes > 0) {
|
|
435
|
+
categories.push({
|
|
436
|
+
name: "Temporary Backups",
|
|
437
|
+
description: "Temporary backup directories in system temp",
|
|
438
|
+
paths: backupPaths,
|
|
439
|
+
totalBytes: backupBytes,
|
|
440
|
+
optional: false,
|
|
441
|
+
});
|
|
442
|
+
totalSizeBytes += backupBytes;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Category 6: Claude Projects (deep mode only)
|
|
447
|
+
if (mode === "deep") {
|
|
448
|
+
const projectPaths = await this.findClaudeProjects();
|
|
449
|
+
if (projectPaths.length > 0) {
|
|
450
|
+
let projectBytes = 0;
|
|
451
|
+
for (const p of projectPaths) {
|
|
452
|
+
if (!allPaths.has(p)) {
|
|
453
|
+
projectBytes += await this.getDirectorySize(p);
|
|
454
|
+
allPaths.add(p);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
if (projectBytes > 0) {
|
|
458
|
+
categories.push({
|
|
459
|
+
name: "Claude Projects Cache",
|
|
460
|
+
description: "Project-specific cache in Claude config",
|
|
461
|
+
paths: projectPaths,
|
|
462
|
+
totalBytes: projectBytes,
|
|
463
|
+
optional: true,
|
|
464
|
+
});
|
|
465
|
+
totalSizeBytes += projectBytes;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
// Category 7: Editor Logs (deep mode only)
|
|
470
|
+
if (mode === "deep") {
|
|
471
|
+
const editorPaths = await this.findEditorLogs();
|
|
472
|
+
if (editorPaths.length > 0) {
|
|
473
|
+
let editorBytes = 0;
|
|
474
|
+
for (const p of editorPaths) {
|
|
475
|
+
if (!allPaths.has(p)) {
|
|
476
|
+
editorBytes += await this.getFileSize(p);
|
|
477
|
+
allPaths.add(p);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (editorBytes > 0) {
|
|
481
|
+
categories.push({
|
|
482
|
+
name: "Editor Logs (Cursor/VSCode)",
|
|
483
|
+
description: "MCP logs from code editors",
|
|
484
|
+
paths: editorPaths,
|
|
485
|
+
totalBytes: editorBytes,
|
|
486
|
+
optional: true,
|
|
487
|
+
});
|
|
488
|
+
totalSizeBytes += editorBytes;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Category 8: Trash Files (deep mode only)
|
|
493
|
+
if (mode === "deep") {
|
|
494
|
+
const trashPaths = await this.findTrashFiles();
|
|
495
|
+
if (trashPaths.length > 0) {
|
|
496
|
+
let trashBytes = 0;
|
|
497
|
+
for (const p of trashPaths) {
|
|
498
|
+
if (!allPaths.has(p)) {
|
|
499
|
+
trashBytes += await this.getFileSize(p);
|
|
500
|
+
allPaths.add(p);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (trashBytes > 0) {
|
|
504
|
+
categories.push({
|
|
505
|
+
name: "Trash Files",
|
|
506
|
+
description: "Deleted notebooklm files in system trash",
|
|
507
|
+
paths: trashPaths,
|
|
508
|
+
totalBytes: trashBytes,
|
|
509
|
+
optional: true,
|
|
510
|
+
});
|
|
511
|
+
totalSizeBytes += trashBytes;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
categories,
|
|
517
|
+
totalPaths: Array.from(allPaths),
|
|
518
|
+
totalSizeBytes,
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Perform cleanup with safety checks and detailed reporting
|
|
523
|
+
*/
|
|
524
|
+
async performCleanup(mode, preserveLibrary = false) {
|
|
525
|
+
log.info(`๐งน Starting cleanup in "${mode}" mode...`);
|
|
526
|
+
if (preserveLibrary) {
|
|
527
|
+
log.info(`๐ Library preservation enabled - library.json will be kept!`);
|
|
528
|
+
}
|
|
529
|
+
const { categories, totalSizeBytes } = await this.getCleanupPaths(mode, preserveLibrary);
|
|
530
|
+
const deletedPaths = [];
|
|
531
|
+
const failedPaths = [];
|
|
532
|
+
const categorySummary = {};
|
|
533
|
+
// Delete by category
|
|
534
|
+
for (const category of categories) {
|
|
535
|
+
log.info(`\n๐ฆ ${category.name} (${category.paths.length} items, ${this.formatBytes(category.totalBytes)})`);
|
|
536
|
+
if (category.optional) {
|
|
537
|
+
log.warning(` โ ๏ธ Optional category - ${category.description}`);
|
|
538
|
+
}
|
|
539
|
+
let categoryDeleted = 0;
|
|
540
|
+
let categoryBytes = 0;
|
|
541
|
+
for (const itemPath of category.paths) {
|
|
542
|
+
try {
|
|
543
|
+
if (await this.pathExists(itemPath)) {
|
|
544
|
+
const size = await this.getDirectorySize(itemPath);
|
|
545
|
+
log.info(` ๐๏ธ Deleting: ${itemPath}`);
|
|
546
|
+
await fs.rm(itemPath, { recursive: true, force: true });
|
|
547
|
+
deletedPaths.push(itemPath);
|
|
548
|
+
categoryDeleted++;
|
|
549
|
+
categoryBytes += size;
|
|
550
|
+
log.success(` โ
Deleted: ${itemPath} (${this.formatBytes(size)})`);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
catch (error) {
|
|
554
|
+
log.error(` โ Failed to delete: ${itemPath} - ${error}`);
|
|
555
|
+
failedPaths.push(itemPath);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
categorySummary[category.name] = {
|
|
559
|
+
count: categoryDeleted,
|
|
560
|
+
bytes: categoryBytes,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
const success = failedPaths.length === 0;
|
|
564
|
+
if (success) {
|
|
565
|
+
log.success(`\nโ
Cleanup complete! Deleted ${deletedPaths.length} items (${this.formatBytes(totalSizeBytes)})`);
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
log.warning(`\nโ ๏ธ Cleanup completed with ${failedPaths.length} errors`);
|
|
569
|
+
log.success(` Deleted: ${deletedPaths.length} items`);
|
|
570
|
+
log.error(` Failed: ${failedPaths.length} items`);
|
|
571
|
+
}
|
|
572
|
+
return {
|
|
573
|
+
success,
|
|
574
|
+
mode,
|
|
575
|
+
deletedPaths,
|
|
576
|
+
failedPaths,
|
|
577
|
+
totalSizeBytes,
|
|
578
|
+
categorySummary,
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
// ============================================================================
|
|
582
|
+
// Helper Methods
|
|
583
|
+
// ============================================================================
|
|
584
|
+
/**
|
|
585
|
+
* Check if a path exists
|
|
586
|
+
*/
|
|
587
|
+
async pathExists(dirPath) {
|
|
588
|
+
try {
|
|
589
|
+
await fs.access(dirPath);
|
|
590
|
+
return true;
|
|
591
|
+
}
|
|
592
|
+
catch {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Get the size of a single file
|
|
598
|
+
*/
|
|
599
|
+
async getFileSize(filePath) {
|
|
600
|
+
try {
|
|
601
|
+
const stats = await fs.stat(filePath);
|
|
602
|
+
return stats.size;
|
|
603
|
+
}
|
|
604
|
+
catch {
|
|
605
|
+
return 0;
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Get the total size of a directory (recursive)
|
|
610
|
+
*/
|
|
611
|
+
async getDirectorySize(dirPath) {
|
|
612
|
+
try {
|
|
613
|
+
const stats = await fs.stat(dirPath);
|
|
614
|
+
if (!stats.isDirectory()) {
|
|
615
|
+
return stats.size;
|
|
616
|
+
}
|
|
617
|
+
let totalSize = 0;
|
|
618
|
+
const files = await fs.readdir(dirPath);
|
|
619
|
+
for (const file of files) {
|
|
620
|
+
const filePath = path.join(dirPath, file);
|
|
621
|
+
const fileStats = await fs.stat(filePath);
|
|
622
|
+
if (fileStats.isDirectory()) {
|
|
623
|
+
totalSize += await this.getDirectorySize(filePath);
|
|
624
|
+
}
|
|
625
|
+
else {
|
|
626
|
+
totalSize += fileStats.size;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return totalSize;
|
|
630
|
+
}
|
|
631
|
+
catch {
|
|
632
|
+
return 0;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Format bytes to human-readable string
|
|
637
|
+
*/
|
|
638
|
+
formatBytes(bytes) {
|
|
639
|
+
if (bytes === 0)
|
|
640
|
+
return "0 Bytes";
|
|
641
|
+
const k = 1024;
|
|
642
|
+
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
643
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
644
|
+
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Get platform-specific path info
|
|
648
|
+
*/
|
|
649
|
+
getPlatformInfo() {
|
|
650
|
+
const platform = process.platform;
|
|
651
|
+
let platformName = "Unknown";
|
|
652
|
+
switch (platform) {
|
|
653
|
+
case "win32":
|
|
654
|
+
platformName = "Windows";
|
|
655
|
+
break;
|
|
656
|
+
case "darwin":
|
|
657
|
+
platformName = "macOS";
|
|
658
|
+
break;
|
|
659
|
+
case "linux":
|
|
660
|
+
platformName = "Linux";
|
|
661
|
+
break;
|
|
662
|
+
}
|
|
663
|
+
return {
|
|
664
|
+
platform: platformName,
|
|
665
|
+
legacyBasePath: this.legacyPaths.data,
|
|
666
|
+
currentBasePath: this.currentPaths.data,
|
|
667
|
+
npmCachePath: this.getNpmCachePath(),
|
|
668
|
+
claudeCliCachePath: this.getClaudeCliCachePath(),
|
|
669
|
+
claudeProjectsPath: this.getClaudeProjectsPath(),
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
//# sourceMappingURL=cleanup-manager.js.map
|