brain-cleaner 1.2.1 → 1.2.3
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/README.es.md +54 -50
- package/README.md +52 -64
- package/app.py +59 -7
- package/assets/icon.ico +0 -0
- package/assets/ui-demo.png +1 -0
- package/console/brain_cleaner_cli.py +13 -3
- package/package.json +20 -9
- package/scanner.py +21 -2
package/README.es.md
CHANGED
|
@@ -1,81 +1,85 @@
|
|
|
1
1
|
# Brain Cleaner
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/brain-cleaner)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
3
7
|
**Language / Idioma:**
|
|
4
|
-
[🇬🇧 English](https://github.com/konstantinWDK/brain-cleaner/blob/main/README.md)
|
|
8
|
+
🇪🇸 Español | [🇬🇧 English](https://github.com/konstantinWDK/brain-cleaner/blob/main/README.md)
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
[](https://opensource.org/licenses/MIT)
|
|
8
|
-
[](https://www.apple.com/macos/)
|
|
10
|
+

|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
## ¿Por qué Brain Cleaner?
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
En la era del desarrollo moderno, nuestros sistemas se llenan constantemente de "ruido digital". Cada interacción con asistentes de IA (Gemini, Claude, Cursor), cada proyecto NPM y cada experimento en Python dejan un rastro de registros, caché y entornos virtuales pesados que rápidamente consumen cientos de gigabytes de espacio en disco.
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
- Revisor de NPM — Libera espacio en disco detectando y eliminando carpetas `node_modules` de proyectos web.
|
|
18
|
-
- Selección Granular — Árbol de archivos interactivo para revisar y excluir dependencias individuales antes de borrar.
|
|
18
|
+
**Brain Cleaner nació para solucionar esto.** Ofrece una interfaz profesional de alto rendimiento para recuperar espacio en disco, atacando precisamente esos residuos de desarrollo que los limpiadores estándar pasan por alto.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
---
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
## 🚀 Características Principales
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
- **Limpiador de Residuos de IA** — Escaneo profundo de caché, logs y configuraciones de Gemini, Claude, Cursor, Windsurf, Trae y más.
|
|
25
|
+
- **Optimización NPM** — Encuentra y elimina de forma segura carpetas `node_modules` pesadas de proyectos olvidados.
|
|
26
|
+
- **Gestión de Entornos Python** — Detecta entornos virtuales obsoletos (`venv`, `.venv`) que no se han tocado en más de 90 días.
|
|
27
|
+
- **Potencia Híbrida** — La facilidad de una instalación global de NPM con el motor de escaneo de alto rendimiento de Python.
|
|
28
|
+
- **Interfaz Interactiva** — Elige entre una elegante GUI de escritorio o una interfaz de línea de comandos (CLI) profesional.
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
cd brain-cleaner
|
|
33
|
-
```
|
|
34
|
-
3. **Instalar el paquete**:
|
|
35
|
-
```bash
|
|
36
|
-
pip install .
|
|
37
|
-
```
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## ⚙️ Instalación
|
|
33
|
+
|
|
34
|
+
Instala globalmente a través de NPM para empezar a limpiar inmediatamente:
|
|
38
35
|
|
|
39
|
-
### Instalación (Modo NPM)
|
|
40
|
-
Si prefieres usar NPM, puedes instalarlo globalmente:
|
|
41
36
|
```bash
|
|
42
37
|
npm install -g brain-cleaner
|
|
43
38
|
```
|
|
44
|
-
*Nota: Requiere tener Python 3.9+ instalado en el sistema.*
|
|
45
39
|
|
|
46
|
-
|
|
40
|
+
### Requisitos
|
|
41
|
+
- **Python 3.9+** (Requerido para el motor de escaneo).
|
|
42
|
+
- **Node.js 14+**.
|
|
43
|
+
|
|
44
|
+
---
|
|
47
45
|
|
|
48
|
-
|
|
46
|
+
## 📖 Cómo Usar
|
|
49
47
|
|
|
48
|
+
### 1. Iniciar la Interfaz
|
|
49
|
+
Simplemente ejecuta el comando desde cualquier terminal:
|
|
50
50
|
```bash
|
|
51
51
|
brain-cleaner
|
|
52
52
|
```
|
|
53
|
-
*Consejo: Usa el CLI para una limpieza rápida gestionada totalmente por teclado.*
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
### 2. Elige el Alcance
|
|
55
|
+
Selecciona en la barra lateral entre escanear tu directorio **Home**, el **Sistema Completo** o una **Carpeta Personalizada**.
|
|
57
56
|
|
|
58
|
-
|
|
57
|
+
### 3. Selecciona Modo y Escanea
|
|
58
|
+
- **AI Tools**: Para logs y caché de asistentes de IA.
|
|
59
|
+
- **NPM Modules**: Para carpetas `node_modules` pesadas.
|
|
60
|
+
- **Python Envs**: Para identificar entornos virtuales abandonados.
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
3. **Escanear** — Pulsa `START SCAN`. Los resultados aparecen en dos secciones diferenciadas.
|
|
63
|
-
4. **Revisar** — Haz clic en `›` para desplegar el contenido de una carpeta. Puedes marcar o desmarcar elementos individuales.
|
|
64
|
-
5. **Limpiar** — Usa `Clean Selected` para los elementos marcados o `Clean All (Visible)` para todo lo visible en el filtro activo.
|
|
62
|
+
### 4. Revisa y Limpia
|
|
63
|
+
Despliega las entradas para revisar las subcarpetas, marca elementos individuales y haz clic en **Clean Selected** o **Clean All**.
|
|
65
64
|
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🛠 Detalles Técnicos
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
Aunque se distribuye a través de NPM, Brain Cleaner es una herramienta híbrida. El wrapper de Node.js automáticamente:
|
|
70
|
+
1. Detecta tu entorno local de Python.
|
|
71
|
+
2. Auto-instala las dependencias principales (`customtkinter`, `blessed`, `Pillow`) en la primera ejecución.
|
|
72
|
+
3. Ejecuta de forma segura el motor de limpieza multiplataforma.
|
|
73
|
+
|
|
74
|
+
---
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
| **Node Modules** | Carpetas `node_modules` en proyectos Node.js |
|
|
76
|
+
## ⚠️ Seguridad Primero
|
|
77
|
+
|
|
78
|
+
> [!WARNING]
|
|
79
|
+
> La eliminación es **permanente**. Brain Cleaner no mueve archivos a la papelera; los elimina para recuperar espacio inmediatamente. Siempre revisa los resultados del escaneo antes de confirmar la limpieza.
|
|
80
|
+
|
|
81
|
+
---
|
|
78
82
|
|
|
79
|
-
## Licencia
|
|
83
|
+
## 📄 Licencia
|
|
80
84
|
|
|
81
|
-
MIT — *Desarrollado para mantener tu sistema
|
|
85
|
+
MIT — *Desarrollado para mantener tu sistema de desarrollo ligero y enfocado.*
|
package/README.md
CHANGED
|
@@ -1,97 +1,85 @@
|
|
|
1
1
|
# Brain Cleaner
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/brain-cleaner)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
3
7
|
**Language / Idioma:**
|
|
4
8
|
🇬🇧 English | [🇪🇸 Español](https://github.com/konstantinWDK/brain-cleaner/blob/main/README.es.md)
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
[](https://opensource.org/licenses/MIT)
|
|
8
|
-
[](https://www.apple.com/macos/)
|
|
10
|
+

|
|
9
11
|
|
|
10
12
|
---
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
## Why Brain Cleaner?
|
|
15
|
+
|
|
16
|
+
In the modern development era, our systems are constantly cluttered with "digital noise." Every interaction with AI assistants (Gemini, Claude, Cursor), every NPM project, and every Python experiment leaves behind a trail of logs, cache, and heavy virtual environments that quickly eat up hundreds of gigabytes of disk space.
|
|
17
|
+
|
|
18
|
+
**Brain Cleaner was built to solve this.** It provides a professional, high-performance interface to reclaim your disk space by targeting precisely those development residues that standard cleaners miss.
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
---
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
- NPM Cleaner — Reclaims disk space by detecting and removing heavy `node_modules` folders.
|
|
18
|
-
- Granular Selection — Interactive file tree to review and exclude individual files from deletion.
|
|
22
|
+
## 🚀 Key Features
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
- **AI Residue Cleaner** — Deep scan for cache, logs, and configs from Gemini, Claude, Cursor, Windsurf, Trae, and more.
|
|
25
|
+
- **NPM Optimization** — Instantly find and safely delete heavy `node_modules` folders from forgotten projects.
|
|
26
|
+
- **Python Env Manager** — Detect obsolete virtual environments (`venv`, `.venv`) that haven't been touched in over 90 days.
|
|
27
|
+
- **Hybrid Power** — The ease of an NPM global install with the high-performance scanning engine of Python.
|
|
28
|
+
- **Interactive UI** — Choice between a sleek Desktop GUI or a professional Command Line Interface (CLI).
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
---
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
## ⚙️ Installation
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
git clone https://github.com/konstantinwdk/brain-cleaner.git
|
|
29
|
-
```
|
|
30
|
-
2. **Navigate to the folder**:
|
|
31
|
-
```bash
|
|
32
|
-
cd brain-cleaner
|
|
33
|
-
```
|
|
34
|
-
3. **Install the package**:
|
|
35
|
-
```bash
|
|
36
|
-
pip install .
|
|
37
|
-
```
|
|
34
|
+
Install globally via NPM to start cleaning immediately:
|
|
38
35
|
|
|
39
|
-
### Installation (NPM Mode)
|
|
40
|
-
If you are coming from the Node.js ecosystem, you can install it globally via NPM:
|
|
41
36
|
```bash
|
|
42
37
|
npm install -g brain-cleaner
|
|
43
38
|
```
|
|
44
|
-
*Note: Requires Python 3.9+ installed on your system.*
|
|
45
|
-
|
|
46
|
-
## Installation
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
### Requirements
|
|
41
|
+
- **Python 3.9+** (Required for the scanning engine).
|
|
42
|
+
- **Node.js 14+**.
|
|
49
43
|
|
|
50
|
-
|
|
51
|
-
2. Run:
|
|
52
|
-
```bash
|
|
53
|
-
pip install .
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Quick Start
|
|
44
|
+
---
|
|
57
45
|
|
|
58
|
-
|
|
46
|
+
## 📖 How to Use
|
|
59
47
|
|
|
48
|
+
### 1. Launch the Interface
|
|
49
|
+
Simply run the command from any terminal:
|
|
60
50
|
```bash
|
|
61
51
|
brain-cleaner
|
|
62
52
|
```
|
|
63
|
-
*Tip: Use the CLI for fast, keyboard-driven system cleaning.*
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
> ```bash
|
|
68
|
-
> brew install python@3.11 python-tk@3.11
|
|
69
|
-
> python3.11 -m venv .venv
|
|
70
|
-
> source .venv/bin/activate
|
|
71
|
-
> pip install .
|
|
72
|
-
> ```
|
|
54
|
+
### 2. Choose Your Scope
|
|
55
|
+
Select between scanning your **Home** directory, the **Full System**, or a **Custom Folder** in the sidebar.
|
|
73
56
|
|
|
74
|
-
|
|
57
|
+
### 3. Select Mode & Scan
|
|
58
|
+
- **AI Tools**: For logs and cache from AI assistants.
|
|
59
|
+
- **NPM Modules**: For heavy `node_modules`.
|
|
60
|
+
- **Python Envs**: For identifying abandoned virtual environments.
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
3. **Scan** — Click `START SCAN`. Results appear in two labeled sections.
|
|
79
|
-
4. **Review** — Click `›` on any row to expand its subfolders. Check/uncheck individual items.
|
|
80
|
-
5. **Clean** — Use `Clean Selected` for marked items or `Clean All (Visible)` for everything in the active filter.
|
|
62
|
+
### 4. Review & Clean
|
|
63
|
+
Expand entries to review subfolders, check individual items, and click **Clean Selected** or **Clean All**.
|
|
81
64
|
|
|
82
|
-
|
|
83
|
-
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 🛠 Technical Details
|
|
84
68
|
|
|
85
|
-
|
|
69
|
+
While distributed via NPM, Brain Cleaner is a hybrid tool. The Node.js wrapper automatically:
|
|
70
|
+
1. Detects your local Python environment.
|
|
71
|
+
2. Auto-installs core dependencies (`customtkinter`, `blessed`, `Pillow`) on the first run.
|
|
72
|
+
3. Securely executes the cross-platform cleaning engine.
|
|
73
|
+
|
|
74
|
+
---
|
|
86
75
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
| **Node Modules** | `node_modules` in Node.js projects |
|
|
76
|
+
## ⚠️ Safety First
|
|
77
|
+
|
|
78
|
+
> [!WARNING]
|
|
79
|
+
> Deletion is **permanent**. Brain Cleaner does not move files to the trash; it deletes them to reclaim space immediately. Always review the scan results before confirming cleanup.
|
|
80
|
+
|
|
81
|
+
---
|
|
94
82
|
|
|
95
|
-
## License
|
|
83
|
+
## 📄 License
|
|
96
84
|
|
|
97
|
-
MIT — *Developed to keep your system
|
|
85
|
+
MIT — *Developed to keep your development system lean and focused.*
|
package/app.py
CHANGED
|
@@ -9,6 +9,17 @@ import subprocess
|
|
|
9
9
|
from scanner import BrainScanner
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from PIL import Image
|
|
12
|
+
import webbrowser
|
|
13
|
+
|
|
14
|
+
def resource_path(relative_path):
|
|
15
|
+
""" Get absolute path to resource, works for dev and for PyInstaller """
|
|
16
|
+
try:
|
|
17
|
+
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
18
|
+
base_path = sys._MEIPASS
|
|
19
|
+
except Exception:
|
|
20
|
+
base_path = os.path.abspath(".")
|
|
21
|
+
|
|
22
|
+
return os.path.join(base_path, relative_path)
|
|
12
23
|
|
|
13
24
|
ctk.set_appearance_mode("Dark")
|
|
14
25
|
ctk.set_default_color_theme("blue")
|
|
@@ -29,8 +40,7 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
29
40
|
self.current_loc_type = "Home"
|
|
30
41
|
|
|
31
42
|
# Load Icon
|
|
32
|
-
|
|
33
|
-
icon_ui_path = os.path.join(assets_dir, "icon_ui.png")
|
|
43
|
+
icon_ui_path = resource_path(os.path.join("assets", "icon_ui.png"))
|
|
34
44
|
self.logo_image = None
|
|
35
45
|
if os.path.exists(icon_ui_path):
|
|
36
46
|
try:
|
|
@@ -42,6 +52,7 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
42
52
|
# Category definitions
|
|
43
53
|
self.AI_CATS = ["Gemini", "Claude", "IDE Agents", "Other Tools"]
|
|
44
54
|
self.NPM_CATS = ["Node Modules"]
|
|
55
|
+
self.PY_CATS = ["Python Envs", "Python Envs (Obsolete)"]
|
|
45
56
|
|
|
46
57
|
# Info slider data
|
|
47
58
|
self.info_states = [
|
|
@@ -79,7 +90,7 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
79
90
|
ctk.CTkLabel(title_f, text="Brain Cleaner",
|
|
80
91
|
font=ctk.CTkFont(size=19, weight="bold")
|
|
81
92
|
).pack(pady=(0, 2))
|
|
82
|
-
ctk.CTkLabel(title_f, text="v1.
|
|
93
|
+
ctk.CTkLabel(title_f, text="v1.2.3",
|
|
83
94
|
font=ctk.CTkFont(size=11, slant="italic"), text_color="#a1a1a1"
|
|
84
95
|
).pack()
|
|
85
96
|
|
|
@@ -124,7 +135,14 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
124
135
|
font=ctk.CTkFont(size=12), border_color="#2e7d32",
|
|
125
136
|
hover_color="#2e7d32", fg_color="#2e7d32",
|
|
126
137
|
command=self._update_mode_ui
|
|
127
|
-
).grid(row=7, column=0, padx=24, pady=
|
|
138
|
+
).grid(row=7, column=0, padx=24, pady=2, sticky="w")
|
|
139
|
+
|
|
140
|
+
ctk.CTkRadioButton(self.sidebar, text="Python Envs",
|
|
141
|
+
variable=self.scan_mode_var, value="python",
|
|
142
|
+
font=ctk.CTkFont(size=12), border_color="#3776ab",
|
|
143
|
+
hover_color="#3776ab", fg_color="#3776ab",
|
|
144
|
+
command=self._update_mode_ui
|
|
145
|
+
).grid(row=8, column=0, padx=24, pady=(2, 4), sticky="w")
|
|
128
146
|
|
|
129
147
|
# ── Bottom Sidebar Controls ───────────────────────────────
|
|
130
148
|
bottom = ctk.CTkFrame(self.sidebar, fg_color="transparent")
|
|
@@ -294,6 +312,25 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
294
312
|
font=ctk.CTkFont(size=11))
|
|
295
313
|
self.status_label.pack(side="right", padx=10)
|
|
296
314
|
|
|
315
|
+
# Project Links
|
|
316
|
+
links_f = ctk.CTkFrame(footer, fg_color="transparent")
|
|
317
|
+
links_f.pack(side="left", padx=20)
|
|
318
|
+
|
|
319
|
+
ctk.CTkButton(links_f, text="braincleaner.dev",
|
|
320
|
+
font=ctk.CTkFont(size=10, underline=True),
|
|
321
|
+
fg_color="transparent", text_color=("#1f538d", "#5da7e6"),
|
|
322
|
+
hover_color=("#e0e0e0", "#3a3a3a"),
|
|
323
|
+
width=80, height=20,
|
|
324
|
+
command=lambda: webbrowser.open("https://braincleaner.dev")
|
|
325
|
+
).pack(side="left", padx=2)
|
|
326
|
+
|
|
327
|
+
ctk.CTkButton(links_f, text="⭐ Star on GitHub",
|
|
328
|
+
font=ctk.CTkFont(size=10, weight="bold"),
|
|
329
|
+
fg_color=("#24292e", "#333333"), hover_color=("#2c3137", "#444444"),
|
|
330
|
+
text_color="white", width=100, height=22, corner_radius=6,
|
|
331
|
+
command=lambda: webbrowser.open("https://github.com/konstantinwdk/brain-cleaner")
|
|
332
|
+
).pack(side="left", padx=5)
|
|
333
|
+
|
|
297
334
|
# Log Area
|
|
298
335
|
self.log_textbox = ctk.CTkTextbox(main, height=80, font=ctk.CTkFont(size=10))
|
|
299
336
|
self.log_textbox.grid(row=6, column=0, padx=10, pady=(0, 8), sticky="nsew")
|
|
@@ -312,10 +349,14 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
312
349
|
self.scan_header_frame.configure(fg_color="#1f538d")
|
|
313
350
|
self.scan_header_title.configure(text="AI Tools Cleanup")
|
|
314
351
|
self.scan_header_desc.configure(text="Identify and remove cache, logs, and configs left by AI assistants (Gemini, Claude, Cursor...).")
|
|
315
|
-
|
|
352
|
+
elif mode == "npm":
|
|
316
353
|
self.scan_header_frame.configure(fg_color="#2e7d32")
|
|
317
354
|
self.scan_header_title.configure(text="NPM Modules Cleanup")
|
|
318
355
|
self.scan_header_desc.configure(text="Free up space by removing heavy node_modules directories from web projects.")
|
|
356
|
+
elif mode == "python":
|
|
357
|
+
self.scan_header_frame.configure(fg_color="#3776ab")
|
|
358
|
+
self.scan_header_title.configure(text="Python Envs Cleanup")
|
|
359
|
+
self.scan_header_desc.configure(text="Remove obsolete virtual environments (venv, .venv) from your local projects.")
|
|
319
360
|
self.scan_header_count.configure(text="")
|
|
320
361
|
|
|
321
362
|
# ── Helpers ───────────────────────────────────────────────────
|
|
@@ -338,7 +379,9 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
338
379
|
"Claude": "#d97757",
|
|
339
380
|
"IDE Agents": "#7c4dff",
|
|
340
381
|
"Other Tools": "#546e7a",
|
|
341
|
-
"Node Modules": "#2e7d32"
|
|
382
|
+
"Node Modules": "#2e7d32",
|
|
383
|
+
"Python Envs": "#3776ab",
|
|
384
|
+
"Python Envs (Obsolete)": "#d32f2f"
|
|
342
385
|
}.get(cat, "#757575")
|
|
343
386
|
|
|
344
387
|
# ── Info Slider ───────────────────────────────────────────────
|
|
@@ -440,6 +483,10 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
440
483
|
for c in self.NPM_CATS:
|
|
441
484
|
results[c] = raw.get(c, [])
|
|
442
485
|
results["All"] += results[c]
|
|
486
|
+
elif mode == "python":
|
|
487
|
+
for c in self.PY_CATS:
|
|
488
|
+
results[c] = raw.get(c, [])
|
|
489
|
+
results["All"] += results[c]
|
|
443
490
|
self.scanning_active = False
|
|
444
491
|
self.after(0, lambda: self._finish_scan(results, mode))
|
|
445
492
|
|
|
@@ -462,7 +509,7 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
462
509
|
self.status_label.configure(text=f"Found {total} items — {total_str}")
|
|
463
510
|
self.log(f"Scan complete. {total} items found ({total_str}).")
|
|
464
511
|
|
|
465
|
-
found_cats = [c for c in (self.AI_CATS + self.NPM_CATS) if results.get(c)]
|
|
512
|
+
found_cats = [c for c in (self.AI_CATS + self.NPM_CATS + self.PY_CATS) if results.get(c)]
|
|
466
513
|
self.create_filter_bubbles(["All"] + found_cats)
|
|
467
514
|
|
|
468
515
|
count = 0
|
|
@@ -476,6 +523,11 @@ class BrainCleanerApp(ctk.CTk):
|
|
|
476
523
|
count = sum(len(results[c]) for c in section_cats)
|
|
477
524
|
for cat in section_cats:
|
|
478
525
|
self._render_rows(results[cat], cat)
|
|
526
|
+
elif mode == "python":
|
|
527
|
+
section_cats = [c for c in self.PY_CATS if results.get(c)]
|
|
528
|
+
count = sum(len(results[c]) for c in section_cats)
|
|
529
|
+
for cat in section_cats:
|
|
530
|
+
self._render_rows(results[cat], cat)
|
|
479
531
|
|
|
480
532
|
if count > 0:
|
|
481
533
|
self.scan_header_count.configure(text=f"{count} items")
|
package/assets/icon.ico
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
IMAGE_DATA_ATTACHED
|
|
@@ -50,11 +50,12 @@ class BrainCleanerCLI:
|
|
|
50
50
|
def draw_splash(self):
|
|
51
51
|
content = []
|
|
52
52
|
content.append(self.term.cyan(ASCII_ART))
|
|
53
|
-
content.append(self.term.bold("\n Welcome to Brain Cleaner CLI v1.
|
|
53
|
+
content.append(self.term.bold("\n Welcome to Brain Cleaner CLI v1.2.3"))
|
|
54
54
|
content.append(" " + "-" * 40)
|
|
55
55
|
content.append("\n Select Mode to begin:")
|
|
56
56
|
content.append(self.term.blue(" [1] AI Tools Cleanup"))
|
|
57
57
|
content.append(self.term.green(" [2] NPM Modules Cleanup"))
|
|
58
|
+
content.append(self.term.yellow(" [3] Python Envs Cleanup"))
|
|
58
59
|
content.append("\n Press 'q' to exit")
|
|
59
60
|
|
|
60
61
|
output = self.term.home + self.term.clear + "\n".join(content)
|
|
@@ -82,9 +83,15 @@ class BrainCleanerCLI:
|
|
|
82
83
|
|
|
83
84
|
# Mutual exclusivity like GUI
|
|
84
85
|
if mode == 'ai':
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
# AI Categories only
|
|
87
|
+
ai_cats = ["Gemini", "Claude", "IDE Agents", "Other Tools"]
|
|
88
|
+
self.scanner.categories = {k: v for k, v in self.scanner.categories.items() if k in ai_cats}
|
|
89
|
+
elif mode == 'npm':
|
|
87
90
|
self.scanner.categories = {k: v for k, v in self.scanner.categories.items() if k == "Node Modules"}
|
|
91
|
+
elif mode == 'python':
|
|
92
|
+
# Both Python Envs and Python Envs (Obsolete) are captured by the scanner.py logic
|
|
93
|
+
self.scanner.categories = {k: v for k, v in self.scanner.categories.items() if k == "Python Envs"}
|
|
94
|
+
|
|
88
95
|
self.scanner.all_patterns = [p for patterns in self.scanner.categories.values() for p in patterns]
|
|
89
96
|
|
|
90
97
|
self.status_msg = f"Scanning {mode.upper()} residues in {scan_root}..."
|
|
@@ -270,6 +277,9 @@ class BrainCleanerCLI:
|
|
|
270
277
|
elif val == '2':
|
|
271
278
|
self.mode = 'npm'
|
|
272
279
|
state = "SELECT_PATH"
|
|
280
|
+
elif val == '3':
|
|
281
|
+
self.mode = 'python'
|
|
282
|
+
state = "SELECT_PATH"
|
|
273
283
|
elif val.lower() == 'q':
|
|
274
284
|
return
|
|
275
285
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brain-cleaner",
|
|
3
|
-
"version": "1.2.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.2.3",
|
|
4
|
+
"description": "Professional CLI utility to reclaim disk space by removing residues from AI tools (Gemini, Claude, Cursor) and heavy node_modules folders. Optimized for system performance and digital decluttering.",
|
|
5
5
|
"main": "bin/brain-cleaner.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"brain-cleaner": "bin/brain-cleaner.js"
|
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/konstantinwdk/brain-cleaner.git"
|
|
15
|
+
},
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/konstantinwdk/brain-cleaner/issues"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/konstantinwdk/brain-cleaner#readme",
|
|
12
20
|
"author": "Konstantin <info@webdesignerk.com>",
|
|
13
21
|
"license": "MIT",
|
|
14
22
|
"keywords": [
|
|
@@ -17,13 +25,16 @@
|
|
|
17
25
|
"system",
|
|
18
26
|
"npm",
|
|
19
27
|
"node_modules",
|
|
20
|
-
"disk-space"
|
|
28
|
+
"disk-space",
|
|
29
|
+
"ai-tools-cleaner",
|
|
30
|
+
"gemini",
|
|
31
|
+
"claude",
|
|
32
|
+
"cursor-cleaner",
|
|
33
|
+
"cleanup-utility",
|
|
34
|
+
"developer-tools"
|
|
21
35
|
],
|
|
22
36
|
"engines": {
|
|
23
|
-
"node": ">=14.0.0"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"url": "https://github.com/konstantinwdk/brain-cleaner/issues"
|
|
27
|
-
},
|
|
28
|
-
"homepage": "https://github.com/konstantinwdk/brain-cleaner#readme"
|
|
37
|
+
"node": ">=14.0.0",
|
|
38
|
+
"python": ">=3.9"
|
|
39
|
+
}
|
|
29
40
|
}
|
package/scanner.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import shutil
|
|
3
|
+
import time
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
|
|
5
6
|
class BrainScanner:
|
|
@@ -28,6 +29,7 @@ class BrainScanner:
|
|
|
28
29
|
".github-copilot",
|
|
29
30
|
"brain-recordings"
|
|
30
31
|
],
|
|
32
|
+
"Python Envs": ["venv", ".venv", "env", ".env", "virtualenv", "pyenv"],
|
|
31
33
|
"Node Modules": ["node_modules"]
|
|
32
34
|
}
|
|
33
35
|
# Flattened list for the walker
|
|
@@ -78,8 +80,9 @@ class BrainScanner:
|
|
|
78
80
|
|
|
79
81
|
for cat, path, size_str, size_bytes in self.scan_stream(start_path, interrupt_event):
|
|
80
82
|
item = (path, size_str, size_bytes)
|
|
81
|
-
if cat in found:
|
|
82
|
-
found[cat]
|
|
83
|
+
if cat not in found:
|
|
84
|
+
found[cat] = []
|
|
85
|
+
found[cat].append(item)
|
|
83
86
|
found["All"].append(item)
|
|
84
87
|
|
|
85
88
|
# Sort by path
|
|
@@ -107,6 +110,22 @@ class BrainScanner:
|
|
|
107
110
|
for cat, patterns in self.categories.items():
|
|
108
111
|
if d in patterns or any(d.startswith(p) for p in patterns):
|
|
109
112
|
full_path = os.path.join(root, d)
|
|
113
|
+
|
|
114
|
+
# Verify if it's a real Python Virtual Env
|
|
115
|
+
if cat == "Python Envs":
|
|
116
|
+
cfg_path = os.path.join(full_path, "pyvenv.cfg")
|
|
117
|
+
if not os.path.exists(cfg_path):
|
|
118
|
+
continue
|
|
119
|
+
|
|
120
|
+
# Check obsolescence (90 days)
|
|
121
|
+
try:
|
|
122
|
+
mtime = os.path.getmtime(cfg_path)
|
|
123
|
+
days_old = (time.time() - mtime) / (24 * 3600)
|
|
124
|
+
if days_old > 90:
|
|
125
|
+
cat = "Python Envs (Obsolete)"
|
|
126
|
+
except Exception:
|
|
127
|
+
pass
|
|
128
|
+
|
|
110
129
|
size_bytes = self.get_dir_size(full_path)
|
|
111
130
|
size_str = self.format_size(size_bytes)
|
|
112
131
|
|