Improve user experience when osascript fails to empty Trash:
- Count successfully cleaned items
- Display cleanup confirmation message
- Only show message if items were actually cleaned
- Call note_activity to record the cleanup
This ensures users get consistent feedback regardless of which
cleanup method is used (osascript vs find fallback).
Replace glob pattern with find command to properly clean dotfiles
in Trash when osascript fallback is used. The old pattern
~/.Trash/* does not match files starting with "." in bash.
This fix ensures that hidden files like .DS_Store, .hidden_file,
etc. are properly removed when cleaning the Trash.
Issue #393 reported mo clean hanging on 'Scanning sandboxed apps'
and 'Scanning orphaned app resources'.
Root cause: should_protect_data() was looping through 332 patterns
(28 SYSTEM_CRITICAL_BUNDLES_FAST + 304 DATA_PROTECTED_BUNDLES).
For 662 sandboxed containers, this resulted in 220,000+ pattern matches.
Solution: Replace loops with fast case statement for common prefixes:
- com.apple.* (system apps) - instant return
- com.microsoft.*, com.jetbrains.* (IDEs) - instant return
- Password managers, VPNs, Docker etc. - instant return
- Other apps - instant return (no protection needed)
- Only check detailed list for special wildcards (com.tencent.* etc.)
Performance: Clean command maintains 35s (same as previous optimization)
Functionality: All 9 protection tests pass
Resolved conflict in lib/core/base.sh:
- Kept local version with conditional check in stop_section_spinner
- This prevents clearing lines when no spinner is running (fixes extra blank lines)
Fixes text remnants and extra blank lines when spinner messages change.
Issues fixed:
1. Text remnants when switching from longer to shorter messages (e.g., 'Cleaning...ems...')
2. Extra blank lines appearing after section headers
Root causes:
- \033[K only clears from cursor to end of line, leaving remnants when new messages are shorter
- stop_section_spinner was clearing lines even when no spinner was running
Changes:
- lib/core/base.sh:
- Changed stop_section_spinner(), safe_clear_line(), safe_clear_lines() to use \033[2K
- Added guard in stop_section_spinner to only clear when spinner is actually running
- lib/core/ui.sh:
- Clear line once when starting spinner (before loop) to ensure clean start
- Normal spinner rotation uses \r without clearing (performance optimization)
Performance: Line clearing happens only once per spinner start, not on every loop iteration.
Fixes#390
Fixes text remnants showing when spinner messages change from longer to shorter text. Changed from \033[K (clear to end of line) to \033[2K (clear entire line) in stop_section_spinner(), safe_clear_line(), and safe_clear_lines() functions.
Fixes#390
- Replace time.After() with reusable timer to reduce GC pressure
- Use pre-compiled regex for app bundle matching (O(1) vs O(N))
- Fix Bash 3.2 compatibility (remove local -n usage)
Add unit tests for parsing functions in `cmd/status/view_test.go`:
- `parseInt`: parses integers from strings with padding/decimals
- `parseRefreshRate`: parses display refresh rates from system output
- `isNoiseInterface`: filters noise network interfaces
- `parsePMSet`: parses macOS pmset battery output
Coverage for `cmd/status` improved from 8.4% to 12.6%.
- Add get_timestamp() helper and optimize log rotation
- Create mo log viewer with search/filter capabilities
- Improve test coverage to 18.4% with better assertions
- Add security fixes for grep injection prevention
Add unit tests for additional utility functions in `cmd/status/view_test.go`:
- `humanBytes`: byte formatting with decimals and units
- `humanBytesCompact`: compact byte formatting
- `splitDisks`: separates internal/external disks
- `diskLabel`: generates numbered disk labels
Coverage for cmd/status improved from 6.9% to 8.4%.
Add unit tests for utility functions in cmd/status/view_test.go:
- formatRate: MB/s rate formatting with adaptive precision
- shorten: string truncation with ellipsis
- humanBytesShort: byte formatting with binary units
Add unit tests for heap implementations in cmd/analyze/heap_test.go:
- entryHeap: min-heap for dirEntry (basic ops, empty, single element)
- largeFileHeap: min-heap for fileEntry (basic ops, top N pattern)