Repository navigation
Releases
Releases · ohing504/devclean
v0.3.1
devclean v0.3.1
Install:
go install github.com/ohing504/devclean/cmd/devclean@v0.3.1Or download a pre-built binary from the assets below and put it on your PATH.
0.3.1 (2026-10-29)
Changed
Fixed
v0.3.0
devclean v0.3.0
Install:
go install github.com/ohing504/devclean/cmd/devclean@v0.3.0Or download a pre-built binary from the assets below and put it on your PATH.
0.3.0 (2026-10-19)
Added
- add a Claude Code plugin whose skill scans and cleans approved artifacts with devclean (#67) (dcc9e6e)
- add clean --item to clean only the named artifacts without the interactive selector (#59) (3d42e47)
Fixed
- count hard-linked blocks once in ecosystem, project and sub-package sizes and their collapsed lines (#51) (0b6808f), closes #40
- order scan projects and -n by --sort, make --asc ascending, count -n by project root in table and --json, and reject unknown --sort (#54) (39ec13c)
- print equal-size projects in the same order on every run and keep ecosystems sorted with --top (#52) (6542822)
- say how many trashed artifacts start with a dot and how to show them in Finder (#69) (b1ca3b7), closes #65
- show each group by its path and keep each project's largest artifact visible (#70) (ea3c4aa), closes #64
- size browser code-sign copies and pnpm node_modules by the space deleting them frees on macOS (#55) (67cc2f8), closes #30
- size Hugging Face models by their shared blobs and delete those blobs with the model (#66) (dab9430), closes #61
- stop offering installed packages' dist, pycache and vendor outside projects as safe to delete (#60) (6dd43b4)
- stop printing spinner codes into piped output and fail clean without a terminal unless --yes is given (#58) (5f88dc5)
v0.2.0
devclean v0.2.0
Install:
go install github.com/ohing504/devclean/cmd/devclean@v0.2.0Or download a pre-built binary from the assets below and put it on your PATH.
0.2.0 (2026-10-02)
Added
Ecosystem scanners
- Global Caches scanner (
global) covering 27 shared caches at fixed home paths: package managers (npm, pnpm store & cache, Yarn, bun, pip, Homebrew, CocoaPods, Gradle caches & wrapper dists, cargo registry, Go build & module caches), dev tools (Playwright, Electron, node-gyp, TypeScript), and Android SDK (AVD, NDK, system images). macOS paths with Linux~/.cachefallbacks. Shared caches whose deletion forces re-downloads are markedcautionwith a consequence note. - Global Caches catalog expanded from 27 to 56 entries: uv (XDG
~/.cache/uv+ macOS~/Library/Caches/uv), AI tools (Claude Code, Codex, Gemini, Cursor — only Cursor's cache subdirs, never its settings), Puppeteer, Cypress, Deno, Poetry, pipx, Maven repository, rustup toolchains, cargo git cache, nvm/pyenv/rbenv runtimes, RubyGems, CocoaPods spec repos, and Android SDK build-tools. Entries that delete installed runtimes/tools or session history arecautionwith consequence notes. - Global Caches: Browser Temp detection (macOS) — zombie Chromium-family code-sign clones under
/private/var/folders/*/*/X/*.code_sign_cloneleft behind by force-killed browsers (headless automation like lighthouse/puppeteer), labeled with browser name and copy count.safewhen the browser is not running;cautionwhile it runs (newest copy may be in use) or for unrecognized bundle IDs. - LLM Model Stores scanner (
llm) covering local model weights at fixed home paths: LM Studio (~/.lmstudio/models, per model) and Hugging Face hub (~/.cache/huggingface/hub, per model,models--org--namedecoded toorg/name), plus the Ollama (~/.ollama/models) and llamafile (~/.llamafile) stores as a whole. Allsafewith re-download notes; the Ollama note points toollama rm <model>for removing individual models. Results carry a newlast_used_atJSON field (model directory mtime; omitted when unknown), shown in the table as a dim "last used …" hint. - Node.js: a pnpm-installed
node_moduleswhose pnpm store (thestoreDirinnode_modules/.modules.yaml) is on the same volume is annotated that its files are likely shared with the store, so deleting it frees space only afterpnpm store prune. The note appears in both the scan table and thecleanselector. - Flutter/Dart scanner (
flutter): a project'sbuild/and.dart_tool/(whatflutter cleanremoves), plus the shared~/.pub-cacheascaution. The Flutter SDK checkout itself is never scanned, so committed engine source is not offered for deletion. - Android/Gradle scanner (
android): each module'sbuild/and.gradle/in projects withbuild.gradle(.kts); every module is its own project root. - Docker scanner (
docker): reports the Docker Desktop disk image (Docker.raw) with its real on-disk size. It is protected and never deleted by path, since all images, containers and volumes live in that one file. - Xcode: each DerivedData folder shows the workspace it was built from, or notes that the source project no longer exists and the folder is safe to remove.
Cleaning
clean --vendor-cleanupalso runs each installed package manager's own cache prune (npm/yarn cache clean,pnpm store prune,pip/uv cache prune); managers not onPATHare skipped.
Sizing
- Sparse-aware sizing: a sparse artifact shows its real on-disk size next to the size it reports —
8.6 GB (appears as 494.4 GB)for aDocker.rawimage. JSON gains anapparent_sizefield alongside the disk-basedsize.
Changed
- Project scanners (Node, Rust, Ruby, Python, Go) are now declarative rule tables executed by a single shared filesystem walk instead of five independent traversals — one pass over the scan root regardless of how many project ecosystems are active. Stat-based scanners (xcode, global, llm) are unchanged.
- The scan spinner shows a single "Scanning projects..." stage for all project scanners (previously "Scanning node...", "Scanning rust...", … in sequence). Stat scanners still report under their own names.
- Artifact sizing runs in-process (
scanner.Measure) instead of forkingduper artifact, collecting disk (allocated blocks) and apparent (logical) size in one pass. Disk stays the primary figure for sorting, filtering and totals. - Totals count hard-linked blocks shared across artifacts once (e.g. a pnpm store blob linked into
node_modules), sototal_sizeno longer double-counts them. Per-artifact sizes are unchanged. cleancounts hard-linked blocks once in the selector footer, the confirm prompt, and the final summary, matching the scan total. The summary saysmoved to Trashinstead offreedwhen items went to the Trash, since that space is reclaimed only once the Trash is emptied.- The walk engine now reads each directory once and reuses those entries for both project-marker detection and recursion, instead of reading every directory twice (a
filepath.WalkDirread plus a secondos.ReadDir). Directory traversal — the dominant cost of scanning a large tree — is roughly 1.8× faster (~29% faster end-to-end on a workspace with tens of thousands of directories); scan results are unchanged. - Git classification now forks
gitacross a bounded worker pool (min(NumCPU, 8)) instead of one repo at a time — root resolution,status/log, andcheck-ignoreall run concurrently across repos. On a workspace spanning dozens of repos this cut the classify phase roughly in half (~1.24s → ~0.54s warm cache, ~19% faster end-to-end); protection and activity results are unchanged. - The status-badge, safety-icon, and relative-time display formatters, previously duplicated between the table output and the interactive tree selector, are now single shared functions in
internal/ui(StatusBadge,SafetyIcon,RelativeTime). Table and selector rendering are unchanged; the formatters gained direct unit tests. - Test coverage: the interactive tree selector's toggle, parent/child selection propagation, cursor movement, quick-select keys, and
Updatekey routing are now tested (internal/ui35% → 57%); the scan→classify integration workspace gained Python and Ruby project fixtures plus a Global-scanner (fixed-home) pipeline test; andDirSizenow has a test that pins the sizing arithmetic (the golden test zeroes sizes out for portability). - Global caches of installed tools are
caution, soclean --yesskips them. - Homebrew is reclaimed by
brew cleanupas a scan item sized by its dry-run (was: deleting~/Library/Caches/Homebrew; removed from--vendor-cleanup). - The walk engine's no-follow symlink policy is now explicit: it skips any symlink entry (
os.ModeSymlink) rather than relying onos.ReadDir's incidentalIsDir()==false, so a future refactor can't silently start following links. Behavior is unchanged — a symlink is never descended into or matched as an artifact (even a symlinkednode_modulesfrom pnpm/monorepos), which avoids double-counting the target's disk space and never reclaims a shared target; symlink cycles remain unwalkable. Documented indocs/decisions/symlink-no-follow.md. - The scan table and the
cleanselector show an item's name, size, last-used time and deletion note the same way.
Fixed
--pathwith a relative path ending in.or..(e.g.--path .), or naming a directory that starts with., reported "No items found" because the scan root was skipped as a hidden directory. The root is now always scanned, and relative paths are resolved to absolute ones, so results show absolute paths.- Browser Temp: when the
pgreprun-state check fails (not installed or erroring), a known browser's code-sign clones are nowcautioninstead ofsafe, soclean --yesno longer deletes a copy a running browser may be using. - Directories listed by several ecosystems (e.g.
coverage/in a project with bothpackage.jsonandGemfile) were reported once per ecosystem, double-counting their size. They are now reported once, attributed to the first ecosystem in scanner order (node → rust → ruby → python → go) among those active in the scan — a full scan attributes a sharedcoverage/to node, while--eco rubyattributes it to ruby. - Scanners no longer walk into another ecosystem's matched artifact:
__pycache__directories insidenode_moduleswere previously reported separately by the Python scanner, andnode_modulesitself was fully traversed by four other scanners. - Tree selector:
a(select all) no longer selects artifacts under protected projects, matching the other bulk-select keys and the ✗ rendering (deletion was already blocked by the cleaner guard). clean --vendor-cleanupwithout--ecoran vendor commands for every registered ecosystem (e.g.xcrun simctl delete unavailablewhen nothing Xcode-related was cleaned); it is now scoped to the targeted ecosystems.- Ctrl-C / SIGTERM now cancels an in-progress scan instead of being ignored until the walk finishes.
- Config roots and irreplaceable user state are no longer offered for deletion. A home dotfile is now treated as config unless it is unambiguously a package/build cache. Previously listed as
caution/safeand thus removable byclean --yes, now excluded: the whole~/.claudetree (session transcripts, project memory, agents, skills, plugins),~/.codex,~/.gemini, Claude Code's~/Library/Caches/claude-cli-nodejs,~/.cursor(extensions & settings),~/.gem(holds the RubyGems credential + installed gems), and~/.android/avd(emulator user data). Deleting any of it was unrecoverable data or credential loss, not reclaimed space. Only genuine caches under those trees or dedicated cache dirs remain eligib...
v0.1.0
devclean v0.1.0
Install:
go install github.com/ohing504/devclean/cmd/devclean@v0.1.0Or download a pre-built binary from the assets below and put it on your PATH.
Changelog
Features
- badbea0: feat: add --min-size filter to scan and clean (Youngsup Oh ohing504@gmail.com)
- 3a9da56: feat: add Go ecosystem scanner (per-project) (Youngsup Oh ohing504@gmail.com)
- 155d05e: feat: add Python ecosystem scanner (Youngsup Oh ohing504@gmail.com)
- 5da2878: feat: add Ruby ecosystem scanner (Youngsup Oh ohing504@gmail.com)
- 3278b76: feat: add Rust ecosystem scanner (Youngsup Oh ohing504@gmail.com)
- 2b317f3: feat: add Xcode/iOS ecosystem scanner (Youngsup Oh ohing504@gmail.com)
- b2ad6fc: feat: core implementation with Node.js ecosystem support (Youngsup Oh ohing504@gmail.com)
- 50b28c6: feat: detect React Native projects in node scanner (Youngsup Oh ohing504@gmail.com)
- de9c582: feat: enrich Xcode scan results with labels and recommendations (Youngsup Oh ohing504@gmail.com)
- b03446c: feat: interactive tree selector for clean command (Youngsup Oh ohing504@gmail.com)
- 9c9144a: feat: support ecosystem-native vendor cleanup commands (Youngsup Oh ohing504@gmail.com)
Bug fixes
- cf5f203: fix: align HumanSize with --min-size by switching to decimal SI (Youngsup Oh ohing504@gmail.com)
Other
- 1084494: docs(.github): add issue and PR templates (Youngsup Oh ohing504@gmail.com)
- 6d5b54f: docs(changelog): cut [0.1.0] section dated 2026-05-04 (Youngsup Oh ohing504@gmail.com)
- 0405e1d: docs(readme): drop unimplemented
brew installinstruction (Youngsup Oh ohing504@gmail.com) - a3708e4: initial commit (Youngsup Oh ohing504@gmail.com)
Full Changelog: ...v0.1.0