brain-cleaner 1.2.2 → 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 CHANGED
@@ -1,95 +1,85 @@
1
1
  # Brain Cleaner
2
2
 
3
+ [![NPM Version](https://img.shields.io/npm/v/brain-cleaner.svg)](https://www.npmjs.com/package/brain-cleaner)
4
+ [![Licencia: MIT](https://img.shields.io/badge/Licencia-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
6
+
3
7
  **Language / Idioma:**
4
8
  🇪🇸 Español  |  [🇬🇧 English](https://github.com/konstantinWDK/brain-cleaner/blob/main/README.md)
5
9
 
6
- [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
7
- [![Licencia: MIT](https://img.shields.io/badge/Licencia-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
- [![Plataforma macOS](https://img.shields.io/badge/plataforma-macOS-lightgrey.svg)](https://www.apple.com/macos/)
10
+ ![Brain Cleaner Demostración de Interfaz](./assets/ui-demo.png)
9
11
 
10
12
  ---
11
13
 
12
- ### 🚀 Instalación Recomendada (Global)
13
- Instala directamente desde NPM para obtener la última versión estable:
14
-
15
- ```bash
16
- npm install -g brain-cleaner
17
- ```
14
+ ## ¿Por qué Brain Cleaner?
18
15
 
19
- #### Alternativa: Instalación desde el Código Fuente (Python)
20
- Si prefieres instalar vía Python/Pip directamente desde el repositorio:
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.
21
17
 
22
- ```bash
23
- pip install git+https://github.com/konstantinwdk/brain-cleaner
24
- ```
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.
25
19
 
26
20
  ---
27
21
 
28
- ### 🚀 Requisitos
29
- - Se requiere **Python 3.9+**.
30
- - **Node.js 14+** (si se instala por NPM).
22
+ ## 🚀 Características Principales
31
23
 
32
- ---
33
-
34
- ## Inicio Rápido (Instalación y Ejecución)
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.
35
29
 
36
- ### Instalación (Modo Consola)
30
+ ---
37
31
 
38
- Para instalar **Brain Cleaner** como un comando global en tu terminal:
32
+ ## ⚙️ Instalación
39
33
 
40
- 1. **Clonar el repositorio**:
41
- ```bash
42
- git clone https://github.com/konstantinwdk/brain-cleaner.git
43
- ```
44
- 2. **Navegar a la carpeta**:
45
- ```bash
46
- cd brain-cleaner
47
- ```
48
- 3. **Instalar el paquete**:
49
- ```bash
50
- pip install .
51
- ```
34
+ Instala globalmente a través de NPM para empezar a limpiar inmediatamente:
52
35
 
53
- ### Instalación (Modo NPM)
54
- Si prefieres usar NPM, puedes instalarlo globalmente:
55
36
  ```bash
56
37
  npm install -g brain-cleaner
57
38
  ```
58
- *Nota: Requiere tener Python 3.9+ instalado en el sistema.*
59
39
 
60
- ## Uso
40
+ ### Requisitos
41
+ - **Python 3.9+** (Requerido para el motor de escaneo).
42
+ - **Node.js 14+**.
61
43
 
62
- Una vez instalado, puedes arrancar la **Consola Interactiva (CLI)** desde cualquier directorio:
44
+ ---
45
+
46
+ ## 📖 Cómo Usar
63
47
 
48
+ ### 1. Iniciar la Interfaz
49
+ Simplemente ejecuta el comando desde cualquier terminal:
64
50
  ```bash
65
51
  brain-cleaner
66
52
  ```
67
- *Consejo: Usa el CLI para una limpieza rápida gestionada totalmente por teclado.*
68
53
 
69
- > [!TIP]
70
- > En macOS usa Python de Homebrew para evitar cierres inesperados: `brew install python@3.11`
54
+ ### 2. Elige el Alcance
55
+ Selecciona en la barra lateral entre escanear tu directorio **Home**, el **Sistema Completo** o una **Carpeta Personalizada**.
71
56
 
72
- ## Uso
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.
73
61
 
74
- 1. **Ubicación** Elige `Home`, `Full System` o `Custom Folder` en la barra lateral.
75
- 2. **Modo** Elige entre `AI Tools` o `NPM Modules` según lo que quieras escanear.
76
- 3. **Escanear** — Pulsa `START SCAN`. Los resultados aparecen en dos secciones diferenciadas.
77
- 4. **Revisar** — Haz clic en `›` para desplegar el contenido de una carpeta. Puedes marcar o desmarcar elementos individuales.
78
- 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**.
79
64
 
80
- > [!WARNING]
81
- > La eliminación es **permanente**. No hay papelera de reciclaje. Revisa bien antes de limpiar.
65
+ ---
66
+
67
+ ## 🛠 Detalles Técnicos
82
68
 
83
- ## Categorías Detectadas
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.
84
73
 
85
- | Categoría | Herramientas |
86
- |---|---|
87
- | **Gemini** | Caché de la CLI / API de Google Gemini |
88
- | **Claude** | Logs y configuración de Anthropic Claude |
89
- | **IDE Agents** | Cursor, Windsurf, Trae, Roo-Code, Claude-Dev |
90
- | **Other Tools** | Herramientas de IA no categorizadas |
91
- | **Node Modules** | Carpetas `node_modules` en proyectos Node.js |
74
+ ---
75
+
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
+ ---
92
82
 
93
- ## Licencia
83
+ ## 📄 Licencia
94
84
 
95
- MIT — *Desarrollado para mantener tu sistema libre de ruido digital.*
85
+ MIT — *Desarrollado para mantener tu sistema de desarrollo ligero y enfocado.*
package/README.md CHANGED
@@ -7,103 +7,79 @@
7
7
  **Language / Idioma:**
8
8
  🇬🇧 English  |  [🇪🇸 Español](https://github.com/konstantinWDK/brain-cleaner/blob/main/README.es.md)
9
9
 
10
+ ![Brain Cleaner UI Demo](./assets/ui-demo.png)
11
+
10
12
  ---
11
13
 
12
- **Brain Cleaner** is a professional CLI utility designed to reclaim disk space by identifying and removing digital noise:
13
- - **AI Residue Cleaner** — Finds cache, logs, and config files from Gemini, Claude, Cursor, Windsurf, and more.
14
- - **NPM Optimization** — Detects and safely deletes heavy `node_modules` folders from your development projects.
15
- - **Interactive UI** — High-performance terminal interface with granular selection and safety checks.
14
+ ## Why Brain Cleaner?
16
15
 
17
- ### ⚙️ Technical Architecture
18
- While distributed via NPM for ease of use, Brain Cleaner is a hybrid tool. The Node.js wrapper automatically:
19
- 1. Detects your local Python environment.
20
- 2. **Auto-installs missing dependencies** (`blessed`, `Pillow`) on first run.
21
- 3. Seamlessly executes the core Python cleaning engine.
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.
22
17
 
23
- ### 🚀 Recommended Installation (Global)
24
- Install directly from NPM to get the latest stable version:
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.
25
19
 
26
- ```bash
27
- npm install -g brain-cleaner
28
- ```
20
+ ---
29
21
 
30
- #### Alternative: Install from Source (Python)
31
- If you prefer to install via Python/Pip directly from the repository:
22
+ ## 🚀 Key Features
32
23
 
33
- ```bash
34
- pip install git+https://github.com/konstantinwdk/brain-cleaner
35
- ```
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).
36
29
 
37
- ### 🚀 Requirements
38
- - **Python 3.9+** is required.
39
- - **Node.js 14+** (if installing via NPM).
30
+ ---
40
31
 
41
- ## Quick Start
32
+ ## ⚙️ Installation
42
33
 
43
- ```bash
44
- cd brain-cleaner
45
- ```
46
- 3. **Install the package**:
47
- ```bash
48
- pip install .
49
- ```
34
+ Install globally via NPM to start cleaning immediately:
50
35
 
51
- ### Installation (NPM Mode)
52
- If you are coming from the Node.js ecosystem, you can install it globally via NPM:
53
36
  ```bash
54
37
  npm install -g brain-cleaner
55
38
  ```
56
- *Note: Requires Python 3.9+ installed on your system.*
57
-
58
- ## Installation
59
-
60
- To install this console interface as a global command:
61
39
 
62
- 1. Open your terminal in the root directory of the project.
63
- 2. Run:
64
- ```bash
65
- pip install .
66
- ```
40
+ ### Requirements
41
+ - **Python 3.9+** (Required for the scanning engine).
42
+ - **Node.js 14+**.
67
43
 
68
- ## Quick Start
44
+ ---
69
45
 
70
- Once installed, you can run the interactive interface from anywhere:
46
+ ## 📖 How to Use
71
47
 
48
+ ### 1. Launch the Interface
49
+ Simply run the command from any terminal:
72
50
  ```bash
73
51
  brain-cleaner
74
52
  ```
75
- *Tip: Use the CLI for fast, keyboard-driven system cleaning.*
76
53
 
77
- > [!IMPORTANT]
78
- > **macOS 26 (Tahoe) Compatibility**: Use Homebrew Python 3.11 or later to avoid "macOS 26 required" errors in GUI mode.
79
- > ```bash
80
- > brew install python@3.11 python-tk@3.11
81
- > python3.11 -m venv .venv
82
- > source .venv/bin/activate
83
- > pip install .
84
- > ```
54
+ ### 2. Choose Your Scope
55
+ Select between scanning your **Home** directory, the **Full System**, or a **Custom Folder** in the sidebar.
85
56
 
86
- ## Usage
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.
87
61
 
88
- 1. **Scope** Choose `Home`, `Full System` or `Custom Folder` in the sidebar.
89
- 2. **Mode** Choose between `AI Tools` or `NPM Modules` to set what to scan.
90
- 3. **Scan** — Click `START SCAN`. Results appear in two labeled sections.
91
- 4. **Review** — Click `›` on any row to expand its subfolders. Check/uncheck individual items.
92
- 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**.
93
64
 
94
- > [!WARNING]
95
- > Deletion is **permanent**. There is no recycle bin. Review carefully before cleaning.
65
+ ---
96
66
 
97
- ## Detected Categories
67
+ ## 🛠 Technical Details
98
68
 
99
- | Category | Tools |
100
- |---|---|
101
- | **Gemini** | Google Gemini CLI / API cache |
102
- | **Claude** | Anthropic Claude logs & config |
103
- | **IDE Agents** | Cursor, Windsurf, Trae, Roo-Code, Claude-Dev |
104
- | **Other Tools** | Uncategorized AI tools |
105
- | **Node Modules** | `node_modules` in Node.js projects |
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
+ ---
75
+
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
+ ---
106
82
 
107
- ## License
83
+ ## 📄 License
108
84
 
109
- MIT — *Developed to keep your system free of digital noise.*
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
- assets_dir = os.path.join(os.path.dirname(__file__), "assets")
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.1.0",
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=(2, 4), sticky="w")
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
- else:
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")
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.1.0"))
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
- self.scanner.categories = {k: v for k, v in self.scanner.categories.items() if k != "Node Modules"}
86
- else:
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,6 +1,6 @@
1
1
  {
2
2
  "name": "brain-cleaner",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
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": {
@@ -34,6 +34,7 @@
34
34
  "developer-tools"
35
35
  ],
36
36
  "engines": {
37
- "node": ">=14.0.0"
37
+ "node": ">=14.0.0",
38
+ "python": ">=3.9"
38
39
  }
39
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].append(item)
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