This guide provides AI coding assistants with essential commands, patterns, and conventions for working in the Mole codebase.
Quick reference: Build/test commands β’ Safety rules β’ Architecture map β’ Code style
Before any operation:
- Use
safe_*helpers (never rawrm -rforfind -delete) - Check protection:
is_protected(),is_whitelisted() - Test first:
MO_DRY_RUN=1 ./mole clean - Validate syntax:
bash -n <file> - Run tests:
./scripts/test.sh
- Run
rm -rfor any raw deletion commands - Delete files without checking protection lists
- Modify system-critical paths (e.g.,
/System,/Library/Apple) - Remove installer flags
--prefix/--configfrominstall.sh - Commit code changes unless explicitly requested
- Run destructive operations without dry-run validation
- Use raw
gitcommands whenghCLI is available
- Use
safe_*helper functions for deletions (safe_rm,safe_find_delete) - Respect whitelist files (e.g.,
~/.config/mole/whitelist) - Check protection logic before cleanup operations
- Test with dry-run modes first
- Validate syntax before suggesting changes:
bash -n <file> - Use
ghCLI for all GitHub operations (issues, PRs, releases, etc.) - Never commit code unless explicitly requested by user
# Build Go binaries for current platform
make build
# Build release binaries (cross-platform)
make release-amd64 # macOS Intel
make release-arm64 # macOS Apple Silicon
# Clean build artifacts
make clean# Run full test suite (recommended before commits)
./scripts/test.sh
# Run specific BATS test file
bats tests/clean.bats
# Run specific test case by name
bats tests/clean.bats -f "should respect whitelist"
# Run Go tests only
go test -v ./cmd/...
# Run Go tests for specific package
go test -v ./cmd/analyze
# Shell syntax check
bash -n lib/clean/user.sh
bash -n mole
# Lint shell scripts
shellcheck --rcfile .shellcheckrc lib/**/*.sh bin/**/*.sh# Test cleanup in dry-run mode
MO_DRY_RUN=1 ./mole clean
# Enable debug logging
MO_DEBUG=1 ./mole clean
# Test Go tool directly
go run ./cmd/analyze
# Test installation locally
./install.sh --prefix /usr/local/bin --config ~/.config/molemole/ # Main CLI entrypoint (menu + routing)
βββ mo # CLI alias wrapper
βββ install.sh # Manual installer/updater (preserves --prefix/--config)
βββ bin/ # Command entry points (thin wrappers)
β βββ clean.sh # Deep cleanup orchestrator
β βββ uninstall.sh # App removal with leftover detection
β βββ optimize.sh # Cache rebuild + service refresh
β βββ purge.sh # Aggressive cleanup mode
β βββ touchid.sh # Touch ID sudo enabler
β βββ analyze.sh # Disk usage explorer wrapper
β βββ status.sh # System health dashboard wrapper
βββ lib/ # Reusable shell logic
β βββ core/ # base.sh, log.sh, sudo.sh, ui.sh
β βββ clean/ # Cleanup modules (user, apps, dev, caches, system)
β βββ ui/ # Confirmation dialogs, progress bars
βββ cmd/ # Go applications
β βββ analyze/ # Disk analysis tool
β βββ status/ # Real-time monitoring
βββ scripts/ # Build and test automation
β βββ test.sh # Main test runner (shell + go + BATS)
βββ tests/ # BATS integration tests
Decision Tree:
- User cleanup logic β
lib/clean/<module>.sh - Command entry β
bin/<command>.sh - Core utils β
lib/core/<util>.sh - Performance tool β
cmd/<tool>/*.go - Tests β
tests/<test>.bats
- Shell (Bash 3.2): Core cleanup and system operations (
lib/,bin/) - Go: Performance-critical tools (
cmd/analyze/,cmd/status/) - BATS: Integration testing (
tests/)
- Indentation: 4 spaces (configured in .editorconfig)
- Variables:
lowercase_with_underscores - Functions:
verb_nounformat (e.g.,clean_caches,get_size) - Constants:
UPPERCASE_WITH_UNDERSCORES - Quoting: Always quote variables:
"$var"not$var - Tests: Use
[[instead of[ - Command substitution: Use
$(command)not backticks - Error handling: Use
set -euo pipefailat top of files
- Formatting: Follow standard Go conventions (
gofmt,go vet) - Package docs: Add package-level documentation for exported functions
- Error handling: Never ignore errors, always handle them explicitly
- Build tags: Use
//go:build darwinfor macOS-specific code
- Language: English only
- Focus: Explain "why" not "what" (code should be self-documenting)
- Safety: Document safety boundaries explicitly
- Non-obvious logic: Explain workarounds or complex patterns
safe_rm <path>: Safe deletion with validationsafe_find_delete <base> <pattern> <days> <type>: Protected find+deleteis_protected <path>: Check if path is system-protectedis_whitelisted <name>: Check user whitelist
log_info <msg>: Informational messageslog_success <msg>: Success notificationslog_warn <msg>: Warningslog_error <msg>: Error messagesdebug <msg>: Debug output (requires MO_DEBUG=1)
confirm <prompt>: Yes/no confirmationshow_progress <current> <total> <msg>: Progress display
- Syntax Validation:
bash -n <file>- catches basic errors - Unit Tests: BATS tests for individual functions
- Integration Tests: Full command execution with BATS
- Dry-run Tests:
MO_DRY_RUN=1to validate without deletion - Go Tests:
go test -v ./cmd/...
MO_DRY_RUN=1: Preview changes without executionMO_DEBUG=1: Enable detailed debug loggingBATS_FORMATTER=pretty: Use pretty output for BATS (default)BATS_FORMATTER=tap: Use TAP output for CI
- Create
lib/clean/new_module.sh - Implement cleanup logic using
safe_*helpers - Source it in
bin/clean.sh - Add protection checks for critical paths
- Write BATS test in
tests/clean.bats - Test with
MO_DRY_RUN=1first
- Navigate to
cmd/<tool>/ - Make changes to Go files
- Test with
go run .ormake build && ./bin/<tool>-go - Run
go test -vfor unit tests - Check integration:
./mole <command>
- Enable debug mode:
MO_DEBUG=1 ./mole clean - Check logs for error messages
- Verify sudo permissions:
sudo -n trueor./mole touchid - Test individual functions in isolation
- Use
shellcheckfor shell script issues
- Tool: shellcheck with custom
.shellcheckrc - Disabled rules: SC2155, SC2034, SC2059, SC1091, SC2038
- Command:
shellcheck --rcfile .shellcheckrc lib/**/*.sh bin/**/*.sh
- Tools:
go vet,go fmt,go test - Command:
go vet ./cmd/... && go test ./cmd/...
- Triggers: Push/PR to main, dev branches
- Platforms: macOS 14, macOS 15
- Tools: bats-core, shellcheck, Go 1.24.6
- Security checks: Unsafe rm usage, app protection, secret scanning
- Entry scripts in
bin/should be thin wrappers - Reusable logic goes in
lib/ - Core utilities in
lib/core/ - Feature-specific modules in
lib/clean/,lib/ui/, etc.
- Each tool in its own
cmd/<tool>/directory - Main entry point in
main.go - Use standard Go project layout
- macOS-specific code guarded with build tags
Preferred Commands:
# Issues
gh issue view 123 # View issue details
gh issue list # List issues
gh issue comment 123 "message" # Comment on issue
# Pull Requests
gh pr view # View current PR
gh pr diff # Show diff
gh pr list # List PRs
gh pr checkout 123 # Checkout PR branch
gh pr merge # Merge current PR
# Repository operations
gh release create v1.0.0 # Create release
gh repo view # Repository info
gh api repos/owner/repo/issues # Raw API accessNEVER use raw git commands for GitHub operations when gh is available:
- β
git log --oneline origin/main..HEADβ βgh pr view - β
git remote get-url originβ βgh repo view - β Manual GitHub API curl commands β β
gh api
- Use
set -euo pipefailfor strict error handling - Check command exit codes:
if command; then ... - Provide meaningful error messages with
log_error - Use cleanup traps for temporary resources
- Never ignore errors:
if err != nil { return err } - Use structured error messages
- Handle context cancellation appropriately
- Log errors with context information
- Use built-in shell operations over external commands
- Prefer
find -deleteover-exec rm - Minimize subprocess creation
- Use appropriate timeout mechanisms
- Use concurrency for I/O-bound operations
- Implement proper caching for expensive operations
- Profile memory usage in scanning operations
- Use efficient data structures for large datasets
- Always validate user-provided paths
- Check against protection lists before operations
- Use absolute paths to prevent directory traversal
- Implement proper sandboxing for destructive operations
- Request sudo only when necessary
- Use
sudo -n trueto check sudo availability - Implement proper Touch ID integration
- Respect user whitelist configurations
- Over-engineering: Keep solutions simple. Don't add abstractions for one-time operations.
- Premature optimization: Focus on correctness first, performance second.
- Assuming paths exist: Always check before operating on files/directories.
- Ignoring protection logic: User data loss is unacceptable.
- Breaking updates: Keep
--prefix/--configflags ininstall.sh. - Platform assumptions: Code must work on all supported macOS versions (10.13+).
- Silent failures: Always log errors and provide actionable messages.
- Be concise and technical
- Explain safety implications upfront
- Show before/after for significant changes
- Provide file:line references for code locations
- Suggest testing steps for validation
- Main script:
mole(menu + routing logic) - Protection lists: Check
is_protected()implementations - User config:
~/.config/mole/ - Test directory:
tests/ - Build scripts:
scripts/ - Documentation:
README.md,CONTRIBUTING.md,SECURITY_AUDIT.md
Remember: When in doubt, err on the side of safety. It's better to clean less than to risk user data.