A native macOS client for the mo CLI.
SwiftUI · AppKit · WebKit · IOKit — no Electron, no bundled runtime.
The application is orbit. It is a desktop client for the upstream
moCLI.
orbit puts a desktop face on tw93/mole — the open-source
mo CLI that frees disk space and refreshes macOS caches. It reads real hardware telemetry from the
Mach kernel, drives mo as a subprocess, and renders a warm, low-glare control surface instead of a
terminal.
The mo binary is not bundled or vendored. The app resolves it at runtime from PATH
(/opt/homebrew/bin/mo, /usr/local/bin/mo, ~/.local/bin/mo, ~/.mole/mo) and shells out to it,
so you always run the upstream version you installed.
| Module | Backed by | What it does |
|---|---|---|
| Deep Clean · Earth | mo clean |
Caches, logs, browser render caches, Xcode DerivedData, package-manager caches |
| AI Care · Moon | mo clean --ai-care |
Stale AI CLI binaries, render caches, expired agent worktrees, SQLite compaction |
| Uninstaller · Mars | mo uninstall |
Removes app bundles plus their leftover support files, with "keep personal data" |
| Optimize · Mercury | mo optimize |
Refreshes caches, rebuilds QuickLook/icon caches, vacuums system SQLite databases |
| Astrolabe · disk analyzer | mo analyze --json |
Treemap of the CLI overview, with a fresh CLI scan when a directory is opened |
| Live Status · Sun | mo status |
Process table with CPU, memory and power draw |
| Purge | mo purge, mo installer |
Removes rebuildable project artifacts and stale installer packages |
| History & Whitelist | mo history, mo clean --whitelist |
Cleanup audit log and protected-path management |
Beyond the module list:
- Path & Safety Inspector — selecting any category reveals the exact subdirectories, their sizes, a rebuild-cost assessment, one-click Finder reveal, and direct whitelist protection.
- Proportional volume bars — every row carries an inline bar relative to total scan size.
- Pre-execution diff — deletions are previewed as a structured sheet (paths, safety tier, Trash recovery checkpoint) before anything runs.
- Dry-run by default —
dryRunModedefaults totrue. - Menu bar presence — an orbit-mark status item whose popover is the same WebKit tray (clean, health check, caffeinate, quit).
- Live local scan — installed apps, leftover Library paths, and large files are sampled on the Mac and pushed into the UI over the JS bridge.
- Three uninstall modes — Standard, Complete, and Cache-only, with per-path selection before anything moves to the Trash.
- Treemap drill-down — disk tiles open into their child directories.
- Live telemetry —
statfs, memory, and/bin/pssampled on a 1.5 s timer.
-
macOS 13 (Ventura) or later
-
Xcode 15+ / Swift 5.10+ toolchain
-
The
moCLI onPATH:brew install mole mo --version
git clone https://github.com/real-jacket/orbit.git
cd orbit
make run # build and launch straight from the checkout
make test # run the unit test suite
make app # package dist/MoleStudio.app
make icon # regenerate the app icon from source
make lint # SwiftLint in strict mode
make check # lint + test, the same gate CI runs
make help # list every targetPlain SwiftPM works too:
swift build
swift run MoleStudiomake app produces a self-contained, ad-hoc-signed bundle at dist/MoleStudio.app with the WebKit UI
copied into Contents/Resources/src-ui/. Drag it to /Applications to keep it around.
Sources/MoleStudio/
├── MoleStudioApp.swift # @main entry, NSWindow + WKWebView host, status item, JS bridge
├── Models/MoleModels.swift # Domain types: modules, safety tiers, scan/cleanup entries
├── Engine/
│ ├── MoleCLIRunner.swift # actor: resolves `mo`, executes it, parses output, treemap math
│ ├── MoleViewModel.swift # ObservableObject state store; lists start empty until a scan fills them
│ ├── NativeSystemMonitor.swift # Mach/statfs telemetry, screen-shield window
│ └── RealMacSystemScanner.swift # local app, large-file, and process scan for the WebKit UI
└── Views/VisualEffectAndPlanetView.swift # NSVisualEffectView bridge, Canvas planet renderer
Resources/src-ui/index.html # The shipping UI: single-file HTML/CSS/JS surface
Resources/AppIcon.icns # Generated app icon (all 10 representations)
Tests/MoleStudioTests/ # Treemap layout math + safety-model invariants
scripts/build-macos-app.sh # .app bundler
scripts/generate-app-icon.swift # Icon renderer — the icon is code, not a binary blob
The window is a WKWebView hosting Resources/src-ui/index.html, wired to native code through a
WKScriptMessageHandler registered as moleNative. The HTML posts actions (revealInFinder, copyText, killProcess, trashRealPaths,
requestRealSystemScan, toggleCaffeinate, startWindowDrag, toggleWindowZoom); Swift calls back
into JS (onNativeRealScanComplete, onNativeRealTelemetry, switchModule, openConfirmSheet).
UILocator finds the HTML in all three launch modes: a packaged .app
(Contents/Resources/src-ui/), swift run from a checkout (walks up to Resources/), or an explicit
MOLE_UI_HTML environment variable.
The icon is rendered from code, not checked in as an opaque bitmap. scripts/generate-app-icon.swift
draws the v10 brand mark with CoreGraphics and emits every size iconutil needs.
The mark matches the sidebar brand SVG: a #27272a → #09090b → #7c2d12 squircle plate, a terracotta
planet lit from the upper left (#fff7ed → #fdba74 → #ea580c → #7c2d12), a ring split so the far half
passes behind the planet and the near half crosses in front, and an ice-blue companion (#38bdf8).
make icon # rewrite Resources/AppIcon.icns + AppIcon-256.png
make icon-preview # render every size on dark and light plates → /tmp/icon-preview.pngThree details worth knowing if you edit the renderer:
- Small sizes keep the same mark, with thicker strokes. At 16–32px the planet, ring, and companion are enlarged so the silhouette still reads in the Dock.
- The output is dithered. An 8-bit gradient across a large dark surface bands visibly; a ±2 noise layer removes the steps and is invisible at 100%.
- The background is a superellipse, not a rounded rectangle. Apple's icon grid uses a continuous corner curve, so the body is drawn as an n=5 squircle inset 100px in a 1024px canvas (the standard 824×824 body).
This is an early-stage client. Being explicit about what is and is not wired up:
- The WebKit surface in
Resources/src-ui/index.htmlis the shipping UI. The SwiftUI layer (MoleViewModel,MoleModels,VisualEffectAndPlanetView) is a parallel, partly-built native implementation that the running app does not yet consume. - Lists start empty. The window shows scan results only.
MoleCLIRunneris wired to executemofor real; the UI is not yet reading its results back. - Some CLI flags shown in the UI are aspirational.
mo clean --ai-care,--retentionand--banddo not exist inmo1.56.1. Treat those strings as design intent for the AI Care module, not as working commands. - CPU load, memory, disk free space, installed apps, leftovers, installers, and build artifacts are sampled on this Mac. Temperature shown next to CPU is still estimated from load.
The app deletes files, so the guardrails are the point:
- Protected categories (
tier == .protectedSystem) cannot be selected — the toggle is a no-op. - Every destructive action is previewed before execution.
- Dry-run is on by default.
- The whitelist is read from and written to
~/.config/mole/whitelist, the same filemouses. - Operations are logged to
~/Library/Logs/mole/operations.log.
This project is an independent GUI client. It is not affiliated with or endorsed by
tw93/mole. It contains no upstream source code and does not
redistribute the mo binary — it invokes your installed copy as a subprocess. Upstream mo is
licensed GPL-3.0, and this client is licensed GPL-3.0 to match.
See CONTRIBUTING.md. Bug reports and feature requests have templates under
.github/ISSUE_TEMPLATE/.
GPL-3.0. Copyright (C) 2026 real-jacket.