# How Mole's Shell Scripts Are Structured: A Layered Architecture Guide

> Explore Mole's shell script structure, a layered architecture from bin to libcore and libmanage. Understand its convention-over-configuration design and organize your own projects effectively.

- Repository: [Tw93/Mole](https://github.com/tw93/Mole)
- Tags: architecture
- Published: 2026-03-20

---

**Mole's shell scripts follow a convention-over-configuration architecture organized into nine distinct layers, from user-facing binaries in `bin/` to core utilities in `lib/core/` and specialized management modules in `lib/manage/`.**

Mole is an open-source macOS optimization tool maintained by tw93 that is built almost entirely from Bash scripts. Understanding how Mole's shell scripts are structured reveals a modular, maintainable architecture that separates entry points, core libraries, and UI components into a clear directory hierarchy designed for easy navigation and testing.

## The Nine-Layer Directory Architecture

Mole organizes its shell scripts into a logical hierarchy where each directory serves a specific architectural purpose. This separation ensures that low-level utilities never depend on high-level business logic.

### Entry Points (`bin/`)

The `bin/` directory contains user-facing commands that are executed directly from the terminal. Each script corresponds to a high-level action such as installation, uninstallation, or system optimization.

Representative files include [`bin/installer.sh`](https://github.com/tw93/Mole/blob/main/bin/installer.sh) for the main installation flow, [`bin/uninstall.sh`](https://github.com/tw93/Mole/blob/main/bin/uninstall.sh) for removal operations, and [`bin/optimize.sh`](https://github.com/tw93/Mole/blob/main/bin/optimize.sh) for running maintenance tasks.

### Convenience Helpers (`scripts/`)

The `scripts/` directory houses small wrappers used by CI pipelines or developers for tasks like testing or environment setup. These are not intended for end-users but support development workflows.

Key files include [`scripts/test.sh`](https://github.com/tw93/Mole/blob/main/scripts/test.sh) for running the test suite and [`scripts/setup-quick-launchers.sh`](https://github.com/tw93/Mole/blob/main/scripts/setup-quick-launchers.sh) for configuring development shortcuts.

### Core Library (`lib/core/`)

The `lib/core/` directory contains low-level utilities that the rest of the codebase depends on. These scripts provide foundational functionality including logging, argument parsing, timeout handling, privilege escalation, and file operations.

Essential files include [`lib/core/log.sh`](https://github.com/tw93/Mole/blob/main/lib/core/log.sh) for unified logging functions, [`lib/core/commands.sh`](https://github.com/tw93/Mole/blob/main/lib/core/commands.sh) for command execution wrappers, [`lib/core/file_ops.sh`](https://github.com/tw93/Mole/blob/main/lib/core/file_ops.sh) for safe file manipulation, and [`lib/core/base.sh`](https://github.com/tw93/Mole/blob/main/lib/core/base.sh) which serves as the main entry point for sourcing other core modules.

### UI Components (`lib/ui/`)

The `lib/ui/` directory contains small interactive helpers that render menus or selectors in the terminal. These components are deliberately decoupled from core logic so they can be swapped or modified without affecting business rules.

Notable files include [`lib/ui/menu_simple.sh`](https://github.com/tw93/Mole/blob/main/lib/ui/menu_simple.sh) for basic selection menus, [`lib/ui/menu_paginated.sh`](https://github.com/tw93/Mole/blob/main/lib/ui/menu_paginated.sh) for handling long lists, and [`lib/ui/app_selector.sh`](https://github.com/tw93/Mole/blob/main/lib/ui/app_selector.sh) for interactive application selection.

### Management Functions (`lib/manage/`)

The `lib/manage/` directory implements higher-level actions like updating, purging paths, whitelisting, or fixing system state. These scripts orchestrate core utilities and UI helpers to complete complex workflows.

Key files include [`lib/manage/update.sh`](https://github.com/tw93/Mole/blob/main/lib/manage/update.sh) for self-update logic, [`lib/manage/purge_paths.sh`](https://github.com/tw93/Mole/blob/main/lib/manage/purge_paths.sh) for removing specific paths, and [`lib/manage/autofix.sh`](https://github.com/tw93/Mole/blob/main/lib/manage/autofix.sh) for automated system repairs.

### Cleaning Utilities (`lib/clean/`)

The `lib/clean/` directory contains dedicated scripts for removing caches, brew data, Maven artifacts, and other temporary files. These keep the system tidy after installations or repairs.

Representative files include [`lib/clean/caches.sh`](https://github.com/tw93/Mole/blob/main/lib/clean/caches.sh) for general cache removal, [`lib/clean/brew.sh`](https://github.com/tw93/Mole/blob/main/lib/clean/brew.sh) for Homebrew cleanup, and [`lib/clean/maven.sh`](https://github.com/tw93/Mole/blob/main/lib/clean/maven.sh) for Maven artifact purging.

### Health-Check and Diagnostics (`lib/check/`)

The `lib/check/` directory gathers system health information used by the `mole check` command. These scripts generate JSON reports and overall status summaries.

Key files include [`lib/check/health_json.sh`](https://github.com/tw93/Mole/blob/main/lib/check/health_json.sh) for generating JSON health reports and [`lib/check/all.sh`](https://github.com/tw93/Mole/blob/main/lib/check/all.sh) for comprehensive system diagnostics.

### Uninstall Helpers (`lib/uninstall/`)

The `lib/uninstall/` directory contains logic for clean removal of components installed by Mole, ensuring services are stopped and caches are cleared.

Essential files include [`lib/uninstall/brew.sh`](https://github.com/tw93/Mole/blob/main/lib/uninstall/brew.sh) for removing Homebrew dependencies and [`lib/uninstall/batch.sh`](https://github.com/tw93/Mole/blob/main/lib/uninstall/batch.sh) for batch uninstallation operations.

### Testing Suite (`tests/`)

The `tests/` directory contains standalone test scripts that validate diagnostics, uninstall flow, and other behaviors without requiring the full toolchain.

A representative file is [`tests/test_diagnostic_reports_standalone.sh`](https://github.com/tw93/Mole/blob/main/tests/test_diagnostic_reports_standalone.sh), which tests health report generation in isolation.

## How the Layers Interact

Mole's shell script architecture follows a strict dependency flow that prevents circular references and maintains clear separation of concerns.

When a user executes a command, the interaction flow follows these steps:

1. **User runs a binary script** in `bin/` (e.g., [`./bin/installer.sh`](https://github.com/tw93/Mole/blob/main/./bin/installer.sh)).

2. The binary script sources **core utilities** (`lib/core/*.sh`) for logging, argument parsing, and permission handling.

3. For any interactive prompt, it calls **UI helpers** (`lib/ui/*.sh`) to render menus.

4. Business-logic actions (install, update, purge) are delegated to **management scripts** in `lib/manage/`.

5. Those management scripts may invoke **cleaning** or **check** modules to ensure a consistent system state.

6. When the user asks to **uninstall**, the binary script routes the request to `lib/uninstall/*` which safely removes files, services, and caches.

This modular hierarchy keeps each script focused on a single responsibility, simplifies testing, and makes the overall codebase easy to navigate.

## Code Examples

### Running Top-Level Commands

The `bin/` directory contains executable entry points that users invoke directly:

```bash

# Install Mole (high-level entry point)

./bin/installer.sh

# Check system health

./bin/check.sh

# Optimize system (runs cleanup & maintenance tasks)

./bin/optimize.sh

```

Each of these scripts begins with a standard header that sources the core library:

```bash
#!/usr/bin/env bash

# shellcheck source=../lib/core/base.sh

source "$(dirname "$0")/../lib/core/base.sh"

```

### Management Scripts Calling Core Utilities

The following excerpt from [`lib/manage/update.sh`](https://github.com/tw93/Mole/blob/main/lib/manage/update.sh) demonstrates how higher-level scripts leverage core utilities:

```bash
#!/usr/bin/env bash
source "$(dirname "$0")/../core/log.sh"
source "$(dirname "$0")/../core/file_ops.sh"

log_info "Starting Mole update..."
if ! file_exists "/usr/local/bin/mole"; then
  log_error "Mole is not installed."
  exit 1
fi

# Pull latest version from GitHub

git -C "/usr/local/Cellar/mole" pull origin main
log_success "Mole updated successfully."

```

The script uses `log_*` functions from [`lib/core/log.sh`](https://github.com/tw93/Mole/blob/main/lib/core/log.sh) and `file_exists` from [`lib/core/file_ops.sh`](https://github.com/tw93/Mole/blob/main/lib/core/file_ops.sh), demonstrating cross-layer reuse.

### Interactive UI Components

The [`lib/ui/menu_simple.sh`](https://github.com/tw93/Mole/blob/main/lib/ui/menu_simple.sh) script provides reusable interactive elements:

```bash

# Inside lib/ui/menu_simple.sh

menu_simple() {
  local options=("$@")
  PS3="Select an option: "
  select opt in "${options[@]}" "Cancel"; do
    case "$REPLY" in
      [0-9]*) echo "$opt"; return;;
      *) echo "Invalid choice.";;
    esac
  done
}

```

A management script can invoke it like:

```bash
choice=$(menu_simple "Clean caches" "Update Mole" "Quit")
case "$choice" in
  "Clean caches") lib/clean/caches.sh ;;
  "Update Mole") lib/manage/update.sh ;;
  "Quit") exit 0 ;;
esac

```

## Key Files

| File | Role | Location |
|------|------|----------|
| [`bin/installer.sh`](https://github.com/tw93/Mole/blob/main/bin/installer.sh) | Main installer entry point | [bin/installer.sh](https://github.com/tw93/Mole/blob/main/bin/installer.sh) |
| [`bin/uninstall.sh`](https://github.com/tw93/Mole/blob/main/bin/uninstall.sh) | Uninstall entry point | [bin/uninstall.sh](https://github.com/tw93/Mole/blob/main/bin/uninstall.sh) |
| [`bin/optimize.sh`](https://github.com/tw93/Mole/blob/main/bin/optimize.sh) | Runs cleaning + maintenance | [bin/optimize.sh](https://github.com/tw93/Mole/blob/main/bin/optimize.sh) |
| [`lib/core/base.sh`](https://github.com/tw93/Mole/blob/main/lib/core/base.sh) | Sets up environment, loads other core modules | [lib/core/base.sh](https://github.com/tw93/Mole/blob/main/lib/core/base.sh) |
| [`lib/core/log.sh`](https://github.com/tw93/Mole/blob/main/lib/core/log.sh) | Unified logging (info, warn, error) | [lib/core/log.sh](https://github.com/tw93/Mole/blob/main/lib/core/log.sh) |
| [`lib/ui/menu_simple.sh`](https://github.com/tw93/Mole/blob/main/lib/ui/menu_simple.sh) | Simple interactive menu implementation | [lib/ui/menu_simple.sh](https://github.com/tw93/Mole/blob/main/lib/ui/menu_simple.sh) |
| [`lib/manage/update.sh`](https://github.com/tw93/Mole/blob/main/lib/manage/update.sh) | Handles Mole self-updates | [lib/manage/update.sh](https://github.com/tw93/Mole/blob/main/lib/manage/update.sh) |
| [`lib/clean/caches.sh`](https://github.com/tw93/Mole/blob/main/lib/clean/caches.sh) | Clears various application caches | [lib/clean/caches.sh](https://github.com/tw93/Mole/blob/main/lib/clean/caches.sh) |
| [`lib/check/health_json.sh`](https://github.com/tw93/Mole/blob/main/lib/check/health_json.sh) | Generates JSON health report | [lib/check/health_json.sh](https://github.com/tw93/Mole/blob/main/lib/check/health_json.sh) |
| [`tests/test_diagnostic_reports_standalone.sh`](https://github.com/tw93/Mole/blob/main/tests/test_diagnostic_reports_standalone.sh) | Example test for health-report generation | [tests/test_diagnostic_reports_standalone.sh](https://github.com/tw93/Mole/blob/main/tests/test_diagnostic_reports_standalone.sh) |

## Summary

- Mole's shell scripts are organized into a **nine-layer hierarchy** that separates entry points, core libraries, UI components, and domain-specific logic.
- The **core library** (`lib/core/`) provides foundational utilities like logging and file operations that all higher layers depend on.
- **Management scripts** (`lib/manage/`) orchestrate complex workflows by combining core utilities with **UI helpers** (`lib/ui/`) for interactive prompts.
- All executable entry points in `bin/` follow a standard pattern of sourcing [`lib/core/base.sh`](https://github.com/tw93/Mole/blob/main/lib/core/base.sh) to initialize the environment.
- The modular structure enables **standalone testing** via the `tests/` directory and ensures that utility functions remain decoupled from business logic.

## Frequently Asked Questions

### What is the purpose of the `lib/core/` directory in Mole?

The `lib/core/` directory contains the foundational utilities that the rest of Mole's shell scripts depend on. It includes [`log.sh`](https://github.com/tw93/Mole/blob/main/log.sh) for unified logging functions, [`file_ops.sh`](https://github.com/tw93/Mole/blob/main/file_ops.sh) for safe file manipulation, [`commands.sh`](https://github.com/tw93/Mole/blob/main/commands.sh) for command execution wrappers, and [`base.sh`](https://github.com/tw93/Mole/blob/main/base.sh) which serves as the main initialization module that other scripts source to set up their environment.

### How do Mole's shell scripts handle user interaction?

User interaction is handled through dedicated UI components located in `lib/ui/`. These scripts, such as [`menu_simple.sh`](https://github.com/tw93/Mole/blob/main/menu_simple.sh) and [`app_selector.sh`](https://github.com/tw93/Mole/blob/main/app_selector.sh), provide reusable functions for rendering interactive menus and selectors in the terminal. Management scripts in `lib/manage/` call these UI helpers when they need to prompt users for choices, keeping the presentation logic decoupled from business logic.

### Can I run individual Mole components without the full installation?

Yes, individual components can be executed independently. The `bin/` directory contains standalone entry points like [`bin/optimize.sh`](https://github.com/tw93/Mole/blob/main/bin/optimize.sh) and [`bin/check.sh`](https://github.com/tw93/Mole/blob/main/bin/check.sh) that can be run directly. Additionally, the `tests/` directory includes standalone test scripts such as [`tests/test_diagnostic_reports_standalone.sh`](https://github.com/tw93/Mole/blob/main/tests/test_diagnostic_reports_standalone.sh) that validate specific functionality without requiring the full Mole toolchain to be installed.

### Where are Mole's test scripts located?

Mole's test scripts are located in the `tests/` directory at the repository root. This directory contains standalone validation scripts that test specific behaviors such as diagnostic report generation. For example, [`tests/test_diagnostic_reports_standalone.sh`](https://github.com/tw93/Mole/blob/main/tests/test_diagnostic_reports_standalone.sh) validates the health-check functionality without needing the full application context, demonstrating the modular testability of Mole's shell script architecture.