diff --git a/README.md b/README.md index aa2204c..43aaad5 100644 --- a/README.md +++ b/README.md @@ -46,16 +46,16 @@ This is an [MCP server](https://modelcontextprotocol.io/) that implements **huma ### Qt GUI Interface (Refactored Version)
- Qt GUI Main Interface - Qt GUI Settings Interface + Qt GUI Main Interface + Qt GUI Settings Interface
*Qt GUI Interface - Modular refactoring, supporting local environments* ### Web UI Interface (Refactored Version)
- Web UI Main Interface - Web UI Settings Interface + Web UI Main Interface + Web UI Settings Interface
*Web UI Interface - Brand new architecture, suitable for SSH Remote environments* @@ -189,9 +189,29 @@ A: Fixed in v2.0.3. Update to latest version: `uvx mcp-feedback-enhanced@latest` **Q: Image upload fails** A: Check file size (≤1MB) and format (PNG/JPG/GIF/BMP/WebP). -**Q: Web UI won't start** +**Q: Web UI won't start** A: Set `FORCE_WEB=true` or check firewall settings. +**Q: UV Cache taking up too much disk space** +A: Due to frequent use of `uvx` commands, cache may accumulate to tens of GB. Regular cleanup is recommended: +```bash +# Check cache size and detailed information +python scripts/cleanup_cache.py --size + +# Preview cleanup content (without actually cleaning) +python scripts/cleanup_cache.py --dry-run + +# Execute standard cleanup +python scripts/cleanup_cache.py --clean + +# Force cleanup (attempts to close related processes, solves Windows file lock issues) +python scripts/cleanup_cache.py --force + +# Or use uv command directly +uv cache clean +``` +For detailed instructions, see: [Cache Management Guide](docs/en/cache-management.md) + **Q: Gemini Pro 2.5 cannot parse images** A: Known issue. Gemini Pro 2.5 may not correctly parse uploaded image content. Testing shows Claude-4-Sonnet can properly analyze images. Recommend using Claude models for better image understanding capabilities. diff --git a/README.zh-CN.md b/README.zh-CN.md index 4b904c7..7ea8cc8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -46,16 +46,16 @@ ### Qt GUI 界面(重构版)
- Qt GUI 主界面 - Qt GUI 设置界面 + Qt GUI 主界面 + Qt GUI 设置界面
*Qt GUI 界面 - 模块化重构,支持本地环境* ### Web UI 界面(重构版)
- Web UI 主界面 - Web UI 设置界面 + Web UI 主界面 + Web UI 设置界面
*Web UI 界面 - 全新架构,适合 SSH Remote 环境* @@ -189,9 +189,29 @@ A: 已在 v2.0.3 修复。更新到最新版本:`uvx mcp-feedback-enhanced@lat **Q: 图片上传失败** A: 检查文件大小(≤1MB)和格式(PNG/JPG/GIF/BMP/WebP)。 -**Q: Web UI 无法启动** +**Q: Web UI 无法启动** A: 设置 `FORCE_WEB=true` 或检查防火墙设定。 +**Q: UV Cache 占用过多磁盘空间** +A: 由于频繁使用 `uvx` 命令,cache 可能会累积到数十 GB。建议定期清理: +```bash +# 查看 cache 大小和详细信息 +python scripts/cleanup_cache.py --size + +# 预览清理内容(不实际清理) +python scripts/cleanup_cache.py --dry-run + +# 执行标准清理 +python scripts/cleanup_cache.py --clean + +# 强制清理(会尝试关闭相关程序,解决 Windows 文件占用问题) +python scripts/cleanup_cache.py --force + +# 或直接使用 uv 命令 +uv cache clean +``` +详细说明请参考:[Cache 管理指南](docs/zh-CN/cache-management.md) + **Q: Gemini Pro 2.5 无法解析图片** A: 已知问题,Gemini Pro 2.5 可能无法正确解析上传的图片内容。实测 Claude-4-Sonnet 可以正常解析图片。建议使用 Claude 模型获得更好的图片理解能力。 diff --git a/README.zh-TW.md b/README.zh-TW.md index 1bab0d4..8b56b54 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -46,16 +46,16 @@ ### Qt GUI 介面(重構版)
- Qt GUI 主介面 - Qt GUI 設定介面 + Qt GUI 主介面 + Qt GUI 設定介面
*Qt GUI 介面 - 模組化重構,支援本地環境* ### Web UI 介面(重構版)
- Web UI 主介面 - Web UI 設定介面 + Web UI 主介面 + Web UI 設定介面
*Web UI 介面 - 全新架構,適合 SSH Remote 環境* @@ -192,9 +192,29 @@ A: 已在 v2.1.1 修復。進入「⚙️ 設定」分頁,勾選「總是在 **Q: 圖片上傳失敗** A: 檢查檔案大小(≤1MB)和格式(PNG/JPG/GIF/BMP/WebP)。 -**Q: Web UI 無法啟動** +**Q: Web UI 無法啟動** A: 設置 `FORCE_WEB=true` 或檢查防火牆設定。 +**Q: UV Cache 佔用過多磁碟空間** +A: 由於頻繁使用 `uvx` 命令,cache 可能會累積到數十 GB。建議定期清理: +```bash +# 查看 cache 大小和詳細資訊 +python scripts/cleanup_cache.py --size + +# 預覽清理內容(不實際清理) +python scripts/cleanup_cache.py --dry-run + +# 執行標準清理 +python scripts/cleanup_cache.py --clean + +# 強制清理(會嘗試關閉相關程序,解決 Windows 檔案佔用問題) +python scripts/cleanup_cache.py --force + +# 或直接使用 uv 命令 +uv cache clean +``` +詳細說明請參考:[Cache 管理指南](docs/zh-TW/cache-management.md) + **Q: AI 模型無法解析圖片** A: 各種 AI 模型(包括 Gemini Pro 2.5、Claude 等)在圖片解析上可能存在不穩定性,表現為有時能正確識別、有時無法解析上傳的圖片內容。這是 AI 視覺理解技術的已知限制。建議: 1. 確保圖片品質良好(高對比度、清晰文字) diff --git a/docs/en/cache-management.md b/docs/en/cache-management.md new file mode 100644 index 0000000..aef9112 --- /dev/null +++ b/docs/en/cache-management.md @@ -0,0 +1,142 @@ +# UV Cache Management Guide + +## 🔍 Problem Description + +Since this project uses `uvx` for execution, cache files are created in the system with each run. Over time, these caches can consume significant disk space. + +### Cache Location +- **Windows**: `%USERPROFILE%\AppData\Local\uv\cache` +- **macOS/Linux**: `~/.cache/uv` + +## 🧹 Cleanup Methods + +### Method 1: Using UV Built-in Commands (Recommended) + +```bash +# Check cache location +uv cache dir + +# Clean all cache +uv cache clean +``` + +### Method 2: Using Project-Provided Cleanup Tool + +```bash +# Check cache size +python scripts/cleanup_cache.py --size + +# Preview cleanup content +python scripts/cleanup_cache.py --dry-run + +# Execute cleanup +python scripts/cleanup_cache.py --clean + +# Force cleanup (attempts to close related processes) +python scripts/cleanup_cache.py --force +``` + +## ⚠️ Common Issues + +### Issue: "File is being used by another process" error during cleanup + +**Cause**: MCP server or other uvx processes are running + +**Solutions**: +1. **Close related processes**: + - Close Claude Desktop or other MCP-using applications + - Terminate all `uvx` related processes + +2. **Use force cleanup**: + ```bash + python scripts/cleanup_cache.py --force + ``` + +3. **Manual cleanup**: + ```bash + # Windows + taskkill /f /im uvx.exe + taskkill /f /im python.exe /fi "WINDOWTITLE eq *mcp-feedback-enhanced*" + + # Then execute cleanup + uv cache clean + ``` + +### Issue: Cache grows large again quickly after cleanup + +**Cause**: Frequent use of `uvx mcp-feedback-enhanced@latest` + +**Recommendations**: +1. **Regular cleanup**: Recommend weekly or monthly cleanup +2. **Monitor size**: Regularly check cache size +3. **Consider local installation**: For developers, consider local installation instead of uvx + +## 📊 Cache Size Monitoring + +### Check Cache Size + +```bash +# Using cleanup tool +python scripts/cleanup_cache.py --size + +# Or check directory size directly (Windows) +dir "%USERPROFILE%\AppData\Local\uv\cache" /s + +# macOS/Linux +du -sh ~/.cache/uv +``` + +### Recommended Cleanup Frequency + +| Cache Size | Recommended Action | +|-----------|-------------------| +| < 100MB | No cleanup needed | +| 100MB-500MB | Consider cleanup | +| > 500MB | Cleanup recommended | +| > 1GB | Cleanup strongly recommended | + +## 🔧 Automated Cleanup + +### Windows Scheduled Task + +```batch +@echo off +cd /d "G:\github\interactive-feedback-mcp" +python scripts/cleanup_cache.py --clean +``` + +### macOS/Linux Cron Job + +```bash +# Weekly cleanup on Sunday +0 2 * * 0 cd /path/to/interactive-feedback-mcp && python scripts/cleanup_cache.py --clean +``` + +## 💡 Best Practices + +1. **Regular monitoring**: Check cache size monthly +2. **Timely cleanup**: Clean when cache exceeds 500MB +3. **Close processes**: Ensure related MCP services are closed before cleanup +4. **Backup important data**: Ensure important projects are backed up before cleanup + +## 🆘 Troubleshooting + +### Common Causes of Cleanup Failure + +1. **Process occupation**: MCP server is running +2. **Insufficient permissions**: Administrator privileges required +3. **Disk errors**: File system errors + +### Resolution Steps + +1. Close all MCP-related processes +2. Run cleanup command as administrator +3. If still failing, restart computer and try again +4. Consider manually deleting parts of cache directory + +## 📞 Support + +If you encounter cleanup issues, please: +1. Check the troubleshooting section in this document +2. Report issues on [GitHub Issues](https://github.com/Minidoracat/mcp-feedback-enhanced/issues) +3. Provide error messages and system information diff --git a/docs/images/en/gui1.png b/docs/en/images/gui1.png similarity index 100% rename from docs/images/en/gui1.png rename to docs/en/images/gui1.png diff --git a/docs/images/en/gui2.png b/docs/en/images/gui2.png similarity index 100% rename from docs/images/en/gui2.png rename to docs/en/images/gui2.png diff --git a/docs/images/en/web1.png b/docs/en/images/web1.png similarity index 100% rename from docs/images/en/web1.png rename to docs/en/images/web1.png diff --git a/docs/images/en/web2.png b/docs/en/images/web2.png similarity index 100% rename from docs/images/en/web2.png rename to docs/en/images/web2.png diff --git a/docs/zh-CN/cache-management.md b/docs/zh-CN/cache-management.md new file mode 100644 index 0000000..c91b2f3 --- /dev/null +++ b/docs/zh-CN/cache-management.md @@ -0,0 +1,142 @@ +# UV Cache 管理指南 + +## 🔍 问题说明 + +由于本项目使用 `uvx` 执行,每次运行都会在系统中建立 cache 文件。随着时间推移,这些 cache 可能会占用大量磁盘空间。 + +### Cache 位置 +- **Windows**: `%USERPROFILE%\AppData\Local\uv\cache` +- **macOS/Linux**: `~/.cache/uv` + +## 🧹 清理方法 + +### 方法一:使用 UV 内建命令(推荐) + +```bash +# 查看 cache 位置 +uv cache dir + +# 清理所有 cache +uv cache clean +``` + +### 方法二:使用项目提供的清理工具 + +```bash +# 查看 cache 大小 +python scripts/cleanup_cache.py --size + +# 预览清理内容 +python scripts/cleanup_cache.py --dry-run + +# 执行清理 +python scripts/cleanup_cache.py --clean + +# 强制清理(会尝试关闭相关程序) +python scripts/cleanup_cache.py --force +``` + +## ⚠️ 常见问题 + +### 问题:清理时出现「文件正由另一个程序使用」错误 + +**原因**:有 MCP 服务器或其他 uvx 程序正在运行 + +**解决方案**: +1. **关闭相关程序**: + - 关闭 Claude Desktop 或其他使用 MCP 的应用 + - 结束所有 `uvx` 相关程序 + +2. **使用强制清理**: + ```bash + python scripts/cleanup_cache.py --force + ``` + +3. **手动清理**: + ```bash + # Windows + taskkill /f /im uvx.exe + taskkill /f /im python.exe /fi "WINDOWTITLE eq *mcp-feedback-enhanced*" + + # 然后执行清理 + uv cache clean + ``` + +### 问题:清理后 cache 很快又变大 + +**原因**:频繁使用 `uvx mcp-feedback-enhanced@latest` + +**建议**: +1. **定期清理**:建议每周或每月清理一次 +2. **监控大小**:定期检查 cache 大小 +3. **考虑本地安装**:如果是开发者,可考虑本地安装而非每次使用 uvx + +## 📊 Cache 大小监控 + +### 检查 Cache 大小 + +```bash +# 使用清理工具 +python scripts/cleanup_cache.py --size + +# 或直接查看目录大小(Windows) +dir "%USERPROFILE%\AppData\Local\uv\cache" /s + +# macOS/Linux +du -sh ~/.cache/uv +``` + +### 建议的清理频率 + +| Cache 大小 | 建议动作 | +|-----------|---------| +| < 100MB | 无需清理 | +| 100MB-500MB | 可考虑清理 | +| > 500MB | 建议清理 | +| > 1GB | 强烈建议清理 | + +## 🔧 自动化清理 + +### Windows 计划任务 + +```batch +@echo off +cd /d "G:\github\interactive-feedback-mcp" +python scripts/cleanup_cache.py --clean +``` + +### macOS/Linux Cron Job + +```bash +# 每周日清理一次 +0 2 * * 0 cd /path/to/interactive-feedback-mcp && python scripts/cleanup_cache.py --clean +``` + +## 💡 最佳实践 + +1. **定期监控**:每月检查一次 cache 大小 +2. **适时清理**:当 cache 超过 500MB 时进行清理 +3. **关闭程序**:清理前确保关闭相关 MCP 服务 +4. **备份重要资料**:清理前确保重要项目已备份 + +## 🆘 故障排除 + +### 清理失败的常见原因 + +1. **程序占用**:MCP 服务器正在运行 +2. **权限不足**:需要管理员权限 +3. **磁盘错误**:文件系统错误 + +### 解决步骤 + +1. 关闭所有 MCP 相关程序 +2. 以管理员身份运行清理命令 +3. 如果仍然失败,重启电脑后再试 +4. 考虑手动删除部分 cache 目录 + +## 📞 支持 + +如果遇到清理问题,请: +1. 查看本文档的故障排除部分 +2. 在 [GitHub Issues](https://github.com/Minidoracat/mcp-feedback-enhanced/issues) 报告问题 +3. 提供错误信息和系统信息 diff --git a/docs/images/zh-TW/gui1.png b/docs/zh-CN/images/gui1.png similarity index 100% rename from docs/images/zh-TW/gui1.png rename to docs/zh-CN/images/gui1.png diff --git a/docs/images/zh-TW/gui2.png b/docs/zh-CN/images/gui2.png similarity index 100% rename from docs/images/zh-TW/gui2.png rename to docs/zh-CN/images/gui2.png diff --git a/docs/images/zh-TW/web1.png b/docs/zh-CN/images/web1.png similarity index 100% rename from docs/images/zh-TW/web1.png rename to docs/zh-CN/images/web1.png diff --git a/docs/images/zh-TW/web2.png b/docs/zh-CN/images/web2.png similarity index 100% rename from docs/images/zh-TW/web2.png rename to docs/zh-CN/images/web2.png diff --git a/docs/zh-TW/cache-management.md b/docs/zh-TW/cache-management.md new file mode 100644 index 0000000..79ee85a --- /dev/null +++ b/docs/zh-TW/cache-management.md @@ -0,0 +1,142 @@ +# UV Cache 管理指南 + +## 🔍 問題說明 + +由於本專案使用 `uvx` 執行,每次運行都會在系統中建立 cache 檔案。隨著時間推移,這些 cache 可能會佔用大量磁碟空間。 + +### Cache 位置 +- **Windows**: `%USERPROFILE%\AppData\Local\uv\cache` +- **macOS/Linux**: `~/.cache/uv` + +## 🧹 清理方法 + +### 方法一:使用 UV 內建命令(推薦) + +```bash +# 查看 cache 位置 +uv cache dir + +# 清理所有 cache +uv cache clean +``` + +### 方法二:使用專案提供的清理工具 + +```bash +# 查看 cache 大小 +python scripts/cleanup_cache.py --size + +# 預覽清理內容 +python scripts/cleanup_cache.py --dry-run + +# 執行清理 +python scripts/cleanup_cache.py --clean + +# 強制清理(會嘗試關閉相關程序) +python scripts/cleanup_cache.py --force +``` + +## ⚠️ 常見問題 + +### 問題:清理時出現「檔案正由另一個程序使用」錯誤 + +**原因**:有 MCP 服務器或其他 uvx 程序正在運行 + +**解決方案**: +1. **關閉相關程序**: + - 關閉 Claude Desktop 或其他使用 MCP 的應用 + - 結束所有 `uvx` 相關程序 + +2. **使用強制清理**: + ```bash + python scripts/cleanup_cache.py --force + ``` + +3. **手動清理**: + ```bash + # Windows + taskkill /f /im uvx.exe + taskkill /f /im python.exe /fi "WINDOWTITLE eq *mcp-feedback-enhanced*" + + # 然後執行清理 + uv cache clean + ``` + +### 問題:清理後 cache 很快又變大 + +**原因**:頻繁使用 `uvx mcp-feedback-enhanced@latest` + +**建議**: +1. **定期清理**:建議每週或每月清理一次 +2. **監控大小**:定期檢查 cache 大小 +3. **考慮本地安裝**:如果是開發者,可考慮本地安裝而非每次使用 uvx + +## 📊 Cache 大小監控 + +### 檢查 Cache 大小 + +```bash +# 使用清理工具 +python scripts/cleanup_cache.py --size + +# 或直接查看目錄大小(Windows) +dir "%USERPROFILE%\AppData\Local\uv\cache" /s + +# macOS/Linux +du -sh ~/.cache/uv +``` + +### 建議的清理頻率 + +| Cache 大小 | 建議動作 | +|-----------|---------| +| < 100MB | 無需清理 | +| 100MB-500MB | 可考慮清理 | +| > 500MB | 建議清理 | +| > 1GB | 強烈建議清理 | + +## 🔧 自動化清理 + +### Windows 排程任務 + +```batch +@echo off +cd /d "G:\github\interactive-feedback-mcp" +python scripts/cleanup_cache.py --clean +``` + +### macOS/Linux Cron Job + +```bash +# 每週日清理一次 +0 2 * * 0 cd /path/to/interactive-feedback-mcp && python scripts/cleanup_cache.py --clean +``` + +## 💡 最佳實踐 + +1. **定期監控**:每月檢查一次 cache 大小 +2. **適時清理**:當 cache 超過 500MB 時進行清理 +3. **關閉程序**:清理前確保關閉相關 MCP 服務 +4. **備份重要資料**:清理前確保重要專案已備份 + +## 🆘 故障排除 + +### 清理失敗的常見原因 + +1. **程序佔用**:MCP 服務器正在運行 +2. **權限不足**:需要管理員權限 +3. **磁碟錯誤**:檔案系統錯誤 + +### 解決步驟 + +1. 關閉所有 MCP 相關程序 +2. 以管理員身份運行清理命令 +3. 如果仍然失敗,重啟電腦後再試 +4. 考慮手動刪除部分 cache 目錄 + +## 📞 支援 + +如果遇到清理問題,請: +1. 查看本文檔的故障排除部分 +2. 在 [GitHub Issues](https://github.com/Minidoracat/mcp-feedback-enhanced/issues) 回報問題 +3. 提供錯誤訊息和系統資訊 diff --git a/docs/zh-TW/images/gui1.png b/docs/zh-TW/images/gui1.png new file mode 100644 index 0000000..eadbf1a Binary files /dev/null and b/docs/zh-TW/images/gui1.png differ diff --git a/docs/zh-TW/images/gui2.png b/docs/zh-TW/images/gui2.png new file mode 100644 index 0000000..cb69fc5 Binary files /dev/null and b/docs/zh-TW/images/gui2.png differ diff --git a/docs/zh-TW/images/web1.png b/docs/zh-TW/images/web1.png new file mode 100644 index 0000000..3ff6019 Binary files /dev/null and b/docs/zh-TW/images/web1.png differ diff --git a/docs/zh-TW/images/web2.png b/docs/zh-TW/images/web2.png new file mode 100644 index 0000000..5c76078 Binary files /dev/null and b/docs/zh-TW/images/web2.png differ diff --git a/scripts/cleanup_cache.py b/scripts/cleanup_cache.py new file mode 100644 index 0000000..5ed318a --- /dev/null +++ b/scripts/cleanup_cache.py @@ -0,0 +1,284 @@ +#!/usr/bin/env python3 +""" +UV Cache 清理腳本 +================ + +定期清理 uv cache 以防止磁碟空間不斷增加 +特別針對 Windows 系統「檔案正由另一個程序使用」的問題提供解決方案 + +使用方式: + python scripts/cleanup_cache.py --size # 查看 cache 大小和詳細資訊 + python scripts/cleanup_cache.py --dry-run # 預覽將要清理的內容(不實際清理) + python scripts/cleanup_cache.py --clean # 執行標準清理 + python scripts/cleanup_cache.py --force # 強制清理(會嘗試關閉相關程序) + +功能特色: + - 智能跳過正在使用中的檔案 + - 提供強制清理模式 + - 詳細的清理統計和進度顯示 + - 支援 Windows/macOS/Linux 跨平台 +""" + +import subprocess +import sys +import argparse +import shutil +from pathlib import Path +import os + +def get_cache_dir(): + """取得 uv cache 目錄""" + # Windows 預設路徑 + if os.name == 'nt': + return Path.home() / "AppData" / "Local" / "uv" + # macOS/Linux 預設路徑 + else: + return Path.home() / ".cache" / "uv" + +def get_cache_size(cache_dir): + """計算 cache 目錄大小""" + if not cache_dir.exists(): + return 0 + + total_size = 0 + for dirpath, dirnames, filenames in os.walk(cache_dir): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + try: + total_size += os.path.getsize(filepath) + except (OSError, FileNotFoundError): + pass + return total_size + +def format_size(size_bytes): + """格式化檔案大小顯示""" + if size_bytes == 0: + return "0 B" + + for unit in ['B', 'KB', 'MB', 'GB']: + if size_bytes < 1024.0: + return f"{size_bytes:.1f} {unit}" + size_bytes /= 1024.0 + return f"{size_bytes:.1f} TB" + +def run_uv_command(command, check=True): + """執行 uv 命令""" + try: + result = subprocess.run( + ["uv"] + command, + capture_output=True, + text=True, + check=check + ) + return result + except subprocess.CalledProcessError as e: + print(f"❌ 命令執行失敗: uv {' '.join(command)}") + print(f"錯誤: {e.stderr}") + return None + except FileNotFoundError: + print("❌ 找不到 uv 命令,請確認 uv 已正確安裝") + return None + +def show_cache_info(): + """顯示 cache 資訊""" + print("🔍 UV Cache 資訊") + print("=" * 50) + + cache_dir = get_cache_dir() + print(f"Cache 目錄: {cache_dir}") + + if cache_dir.exists(): + cache_size = get_cache_size(cache_dir) + print(f"Cache 大小: {format_size(cache_size)}") + + # 顯示子目錄大小 + subdirs = [] + for subdir in cache_dir.iterdir(): + if subdir.is_dir(): + subdir_size = get_cache_size(subdir) + subdirs.append((subdir.name, subdir_size)) + + if subdirs: + print("\n📁 子目錄大小:") + subdirs.sort(key=lambda x: x[1], reverse=True) + for name, size in subdirs[:10]: # 顯示前10大 + print(f" {name}: {format_size(size)}") + else: + print("Cache 目錄不存在") + +def clean_cache_selective(cache_dir, dry_run=False): + """選擇性清理 cache,跳過正在使用的檔案""" + cleaned_count = 0 + skipped_count = 0 + total_saved = 0 + + print(f"🔍 掃描 cache 目錄: {cache_dir}") + + # 遍歷 cache 目錄 + for root, dirs, files in os.walk(cache_dir): + # 跳過一些可能正在使用的目錄 + if any(skip_dir in root for skip_dir in ['Scripts', 'Lib', 'pyvenv.cfg']): + continue + + for file in files: + file_path = Path(root) / file + try: + if dry_run: + file_size = file_path.stat().st_size + total_saved += file_size + cleaned_count += 1 + if cleaned_count <= 10: # 只顯示前10個 + print(f" 將清理: {file_path.relative_to(cache_dir)} ({format_size(file_size)})") + else: + file_size = file_path.stat().st_size + file_path.unlink() + total_saved += file_size + cleaned_count += 1 + except (OSError, PermissionError, FileNotFoundError) as e: + skipped_count += 1 + if not dry_run and skipped_count <= 5: # 只顯示前5個錯誤 + print(f" ⚠️ 跳過: {file_path.name} (正在使用中)") + + return cleaned_count, skipped_count, total_saved + +def clean_cache(dry_run=False): + """清理 cache""" + action = "預覽" if dry_run else "執行" + print(f"🧹 {action} UV Cache 清理") + print("=" * 50) + + # 顯示清理前的大小 + cache_dir = get_cache_dir() + if cache_dir.exists(): + before_size = get_cache_size(cache_dir) + print(f"清理前大小: {format_size(before_size)}") + else: + print("Cache 目錄不存在,無需清理") + return + + if dry_run: + print("\n🔍 將要清理的內容:") + # 先嘗試 uv cache clean --dry-run + result = run_uv_command(["cache", "clean", "--dry-run"], check=False) + if result and result.returncode == 0: + print(result.stdout) + else: + print(" 使用自定義掃描...") + cleaned_count, skipped_count, total_saved = clean_cache_selective(cache_dir, dry_run=True) + print(f"\n📊 預覽結果:") + print(f" 可清理檔案: {cleaned_count}") + print(f" 預計節省: {format_size(total_saved)}") + else: + print("\n🗑️ 正在清理...") + + # 先嘗試標準清理 + result = run_uv_command(["cache", "clean"], check=False) + if result and result.returncode == 0: + print("✅ 標準 Cache 清理完成") + else: + print("⚠️ 標準清理失敗,使用選擇性清理...") + cleaned_count, skipped_count, total_saved = clean_cache_selective(cache_dir, dry_run=False) + + print(f"\n📊 清理結果:") + print(f" 已清理檔案: {cleaned_count}") + print(f" 跳過檔案: {skipped_count}") + print(f" 節省空間: {format_size(total_saved)}") + + if skipped_count > 0: + print(f"\n💡 提示: {skipped_count} 個檔案正在使用中,已跳過") + print(" 建議關閉相關程序後重新執行清理") + + # 顯示清理後的大小 + if cache_dir.exists(): + after_size = get_cache_size(cache_dir) + saved_size = before_size - after_size + print(f"\n📈 總體效果:") + print(f" 清理前: {format_size(before_size)}") + print(f" 清理後: {format_size(after_size)}") + print(f" 實際節省: {format_size(saved_size)}") + else: + print(f" 節省空間: {format_size(before_size)}") + +def force_clean_cache(): + """強制清理 cache(關閉相關程序後)""" + print("🔥 強制清理模式") + print("=" * 50) + print("⚠️ 警告:此模式會嘗試關閉可能使用 cache 的程序") + + confirm = input("確定要繼續嗎?(y/N): ") + if confirm.lower() != 'y': + print("❌ 已取消") + return + + cache_dir = get_cache_dir() + if not cache_dir.exists(): + print("Cache 目錄不存在") + return + + before_size = get_cache_size(cache_dir) + print(f"清理前大小: {format_size(before_size)}") + + # 嘗試關閉可能的 uvx 程序 + print("\n🔍 檢查相關程序...") + try: + import psutil + killed_processes = [] + for proc in psutil.process_iter(['pid', 'name', 'cmdline']): + try: + if proc.info['name'] and any(name in proc.info['name'].lower() + for name in ['uvx', 'uv.exe', 'python.exe']): + cmdline = ' '.join(proc.info['cmdline'] or []) + if 'mcp-feedback-enhanced' in cmdline or 'uvx' in cmdline: + print(f" 終止程序: {proc.info['name']} (PID: {proc.info['pid']})") + proc.terminate() + killed_processes.append(proc.info['pid']) + except (psutil.NoSuchProcess, psutil.AccessDenied): + pass + + if killed_processes: + print(f" 已終止 {len(killed_processes)} 個程序") + import time + time.sleep(2) # 等待程序完全關閉 + else: + print(" 未發現相關程序") + + except ImportError: + print(" 無法檢查程序(需要 psutil),繼續清理...") + + # 再次嘗試標準清理 + print("\n🗑️ 執行清理...") + result = run_uv_command(["cache", "clean"], check=False) + if result and result.returncode == 0: + print("✅ 強制清理成功") + else: + print("⚠️ 標準清理仍然失敗,使用檔案級清理...") + cleaned_count, skipped_count, total_saved = clean_cache_selective(cache_dir, dry_run=False) + print(f" 清理檔案: {cleaned_count}, 跳過: {skipped_count}") + + # 顯示結果 + after_size = get_cache_size(cache_dir) + saved_size = before_size - after_size + print(f"\n📈 清理結果:") + print(f" 節省空間: {format_size(saved_size)}") + +def main(): + parser = argparse.ArgumentParser(description="UV Cache 清理工具") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("--size", action="store_true", help="顯示 cache 大小資訊") + group.add_argument("--dry-run", action="store_true", help="預覽清理內容(不實際清理)") + group.add_argument("--clean", action="store_true", help="執行 cache 清理") + group.add_argument("--force", action="store_true", help="強制清理(會嘗試關閉相關程序)") + + args = parser.parse_args() + + if args.size: + show_cache_info() + elif args.dry_run: + clean_cache(dry_run=True) + elif args.clean: + clean_cache(dry_run=False) + elif args.force: + force_clean_cache() + +if __name__ == "__main__": + main()