storageshower — Documentation
Description: storageshower — a cyberpunk disk usage TUI in Rust. ratatui + crossterm, 30 builtin themes, live disk I/O, SMART health, NFS latency, threshold alerts, drill-down explorer, theme editor.

// Color scheme

## >_JACK INTO YOUR FILESYSTEM

A neon-drenched terminal UI for monitoring disk usage. Live per-mount usage bars, threshold alerts with bell + border flash, recursive drill-down explorer, live disk I/O throughput (macOS IOKit + Linux `/proc/diskstats`), SMART health badges, NFS / SMB / SSHFS latency probes, 30 builtin cyberpunk palettes, a live theme editor with per-channel color picker, persistent TOML config. Built in Rust with ratatui + crossterm.

## Install

    # Homebrew (recommended)
    brew tap MenkeTechnologies/menketech
    brew install storageshower

    # crates.io
    cargo install storageshower

    # from source
    git clone https://github.com/MenkeTechnologies/storageshower
    cd storageshower && cargo build --release
    ./target/release/storageshower

Runs on macOS and Linux. Rust ≥ 1.85 (2024 edition) to build from source. LTO + strip in release profile — lean single binary.

## Quick tour

    storageshower                            # default palette, all filesystems
    storageshower --color purple -b ascii    # purple palette + ascii bars
    storageshower -s pct -R                  # sort by usage%, descending
    storageshower -l --no-virtual            # local physical disks only
    storageshower -u gib -w 60 -C 85         # GiB units, warn 60%, crit 85%
    storageshower --theme neonpink           # activate a custom theme from config
    storageshower --list-colors              # preview every builtin palette
    storageshower --export-theme --color blue # dump a builtin palette as TOML
    storageshower --config /tmp/ss.conf      # use an alternate config file

CLI flags override config. Every `--flag` has a paired `--no-flag` inverse so either direction can be forced from the command line. Config lives at `~/.storageshower.conf` (TOML). Note: `--color` has no short alias — `-c` is reserved for `--config`.

## Subsystems

#### Render engine

Color-coded usage bars in four styles: `gradient` (`████▓▓▒▒░░`), `solid`, `thin`, `ascii`. Cycle with `b`. Optional border, headers, used/total columns, hover tooltips — each toggleable from the keyboard.

#### Telemetry core

Background thread refreshes every 3 s via `Arc<Mutex<>>`: load avg, memory, CPU count, process count, swap, uptime, kernel, arch, OS, local IP, battery, TTY. Rendered as title / footer segments with per-segment hover tooltips.

#### Alert subsystem

Threshold crossings (warn / crit) trigger terminal bell (`\x07`), 2-second pulsing red border flash, dark-red row highlight, and a status-bar message. Auto-clears when usage drops back below threshold. Default thresholds 70 % / 90 % — cycle in-app with `t` / `z`.

#### Drill-down explorer

`Enter` on any mount enters the directory explorer. Recursive size scan runs in a background worker; entries paint as they're computed with a progress bar + item count. Breadcrumb nav (`Enter` / `Backspace` / `Esc`), sort by size or name, gradient bars relative to the largest entry.

#### Live disk I/O

Per-mount read/write throughput overlaid on the usage bar (`▲1.2M/s ▼500K/s`). macOS: IOKit `IOBlockStorageDriver` byte counters via `getmntinfo` device map. Linux: `/proc/diskstats` sector counters via `/proc/mounts`.

#### SMART health

Per-device SMART probe cached per base device and mapped onto every mount that shares it. macOS via `diskutil info` SMART Status (Verified / Failing). Linux via `/sys/block/*/device/state`. Green `✔` healthy, red `✗` failing.

#### Network FS latency

Detects `nfs`, `nfs4`, `cifs`, `smbfs`, `afp`, `ncp`, `fuse.sshfs`, `fuse.rclone`, `fuse.s3fs`, `9p`, `afs`. Timed `read_dir` probe with a 2 s timeout (no root required). Color-coded badge: green < 50 ms, warn 50–200 ms, red > 200 ms / timeout.

#### Theme system

30 builtin palettes plus user themes loaded from `themes/*.toml`. Live theme chooser popup (`c`) with mouse + scroll preview. Per-channel color editor (`C`) with `h`/`l` ±1 and `H`/`L` ±10 nudges. `--export-theme` dumps any builtin to TOML for hand-editing.

#### Filter mode

`/` opens a case-insensitive substring filter with full readline-style editing: `Ctrl+a`/`e`, `Ctrl+b`/`f`, `Ctrl+w`/`u`/`k`, `Backspace`, `Delete`. `0` clears.

#### Mouse input

Left-click selects, double-click drills, column headers cycle sort, drag the column separator to resize, right-click pops a verbose per-row tooltip (capacity, rank, headroom, SMART, I/O). Scroll wheel walks the disk list, drill-down list, or theme chooser.

#### Persistent config

`~/.storageshower.conf` in TOML. Every CLI flag has a config-file equivalent. Custom palettes are merged from `[custom_themes.<name>]` blocks and selectable with `active_theme` or `--theme NAME`. Rewritten on save from the theme editor and theme chooser.

#### Bookmarks & export

`B` pins the selected disk to the top (persisted in the `bookmarks` config array). `e`/`E` exports the current disk matrix (mount, percent, used, total) to `~/.storageshower.export.txt`. `o`/`O` opens the selected mount in the system file manager. `y`/`Y` copies the mount path to clipboard.

## Builtin color palettes

30 hand-tuned cyberpunk palettes ship in `storageshower`. Cycle with `c` for the popup chooser (mouse + scroll), or pin one from the CLI with `-c <name>`. Use `--list-colors` to see all of them rendered.

defaultNeon Sprawl
greenAcid Rain
blueIce Breaker
purpleSynth Wave
amberRust Belt
cyanGhost Wire
redRed Sector
sakuraSakura Den
matrixData Stream
sunsetSolar Flare
neonnoirNeon Noir
chromeheartChrome Heart
bladerunnerBlade Runner
voidwalkerVoid Walker
toxicwasteToxic Waste
cyberfrostCyber Frost
plasmacorePlasma Core
steelnerveSteel Nerve
darksignalDark Signal
glitchpopGlitch Pop
holoshiftHolo Shift
nightcityNight City
deepnetDeep Net
lasergridLaser Grid
quantumfluxQuantum Flux
biohazardBio Hazard
darkwaveDarkwave
overlockOverlock
megacorpMegacorp
zaibatsuZaibatsu

Ten ready-to-copy custom-theme TOMLs also ship under `themes/` as starting points: `acid_rain`, `data_stream`, `ghost_wire`, `ice_breaker`, `neon_sprawl`, `red_sector`, `rust_belt`, `sakura_den`, `solar_flare`, `synth_wave`. Each file is a single `[custom_themes.<name>]` block — paste one into your config and select it with `active_theme` or `--theme <name>`.

## CLI flags

### Sorting

Flag | Description
--- | ---
-s, --sort MODE | Sort entries — `name`, `pct`, `size`
-R, --reverse / --no-reverse | Reverse sort order
-l, --local-only / --no-local | Show only local disks (HDD / SSD)
--no-virtual / --virtual | Hide or show virtual filesystems (tmpfs, devfs, etc.)

### Display

Flag | Description
--- | ---
-b, --bar-style STYLE | `gradient` · `solid` · `thin` · `ascii`
--color PALETTE | One of the 30 builtin palettes (no short flag — `-c` is `--config`)
--theme NAME | Activate a custom theme (from config `[custom_themes.NAME]`)
--list-colors | List every builtin palette with a preview
--export-theme | Export the current palette as TOML (pair with `-c` or `--theme`)
-u, --units MODE | `human` · `gib` · `mib` · `bytes`
-k, --compact / --no-compact | Compact mount names
-f, --full-mount / --no-full-mount | Show full mount paths
--bars / --no-bars | Show or hide usage bars
--border / --no-border | Show or hide border chrome
--header / --no-header | Show or hide column headers
--used / --no-used | Show or hide used / total size
--tooltips / --no-tooltips | Show or hide hover tooltips (right-click still works)

### Thresholds & columns

Flag | Description
--- | ---
-w, --warn PCT | Warning threshold (default 70 %)
-C, --crit PCT | Critical threshold (default 90 %)
--col-mount WIDTH | Mount column width (`0` = auto)
--col-bar-end WIDTH | Bar-end column width (`0` = auto)
--col-pct WIDTH | Percentage column width (`0` = auto)

### System

Flag | Description
--- | ---
-r, --refresh SECS | Data refresh interval (default 1 s)
-c, --config PATH | Config file path (default `~/.storageshower.conf`)
-h, --help | Display help transmission
-V, --version | Display version information

## Keybindings

### General

q Q | Disconnect (or close help overlay)
h H ? | Toggle help HUD
p P | Pause / resume data stream
Esc | Deselect current disk

### Navigation

j Down | Select next disk
k Up | Select previous disk
G End | Jump to last disk
Home Ctrl+g | Jump to first disk
Ctrl+d / Ctrl+u | Half-page down / up

### Sort & filter

n N | Sort by name (again to reverse)
u U | Sort by usage %
s S | Sort by size
r R | Reverse sort
l L | Local disks only
a A | Show all filesystems
/ | Enter filter mode
0 | Purge filter

### Display toggles

b | Cycle bar style (gradient / solid / thin / ascii)
c | Theme chooser popup
C | Theme editor (per-channel color picker)
v V | Toggle usage bars
d D | Toggle used / size columns
g | Toggle column headers
x X | Toggle border chrome
m M | Compact mount names
w W | Full mount paths
i I | Cycle units (human / GiB / MiB / bytes)
f F | Cycle refresh rate (1 / 2 / 5 / 10 s)
t / z | Cycle warn / crit threshold
T | Toggle hover tooltips

### Disk ops

Enter | Drill down into selected mount
o O | Open in file manager
y Y | Copy mount path to clipboard
e E | Export disk matrix to `~/.storageshower.export.txt`
B | Toggle bookmark (pin to top, persisted)

### Drill-down mode

j k | Navigate entries
Enter | Drill into selected directory
Backspace | Go up one level
Esc | Return to disk list
s S | Sort by size (again to reverse)
n N | Sort by name (again to reverse)
r R | Reverse sort direction
o O | Open current directory in file manager
g G | Jump to first / last entry

### Filter edit mode (after `/`)

Enter | Confirm filter
Esc | Cancel (restore previous filter)
Backspace Ctrl+h | Delete char before cursor
Delete | Delete char at cursor
Ctrl+w | Delete word backward
Ctrl+u | Clear line before cursor
Ctrl+k | Delete to end of line
Ctrl+a Home | Cursor to start
Ctrl+e End | Cursor to end
Ctrl+b Left | Cursor left
Ctrl+f Right | Cursor right

### Theme editor (`C`)

j k | Select color channel
h l | Adjust value ±1
H L | Adjust value ±10
Enter s | Save (prompts for a name)
Esc q | Cancel

## Mouse input

Action | Effect
--- | ---
Left-click disk row | Select disk
Left-click selected disk | Drill down into mount
Left-click column header | Cycle sort on that column
Left-click theme chooser row | Select and preview theme
Left-click outside theme popup | Cancel and revert theme
Left-drag column separator | Resize mount / pct / right columns
Right-click disk row | Verbose tooltip: capacity, rank, headroom, SMART, I/O
Right-click drill-down entry | Verbose tooltip: size, rank, share bar, depth, sort
Hover title / footer segment | Per-segment tooltip (auto-hides after 3 s)
Scroll wheel | Walk the disk list, drill-down list, or theme chooser

## Config file

The config lives at `~/.storageshower.conf` and is written from the default template (`storageshower.default.conf`) on first run if it does not yet exist. The theme editor and theme chooser save changes back to it on apply. Keys map directly to the serialized `Prefs` struct (TOML via `serde`); custom palettes are merged from `[custom_themes.<name>]` blocks and selected with `active_theme` or `--theme NAME`. Enum-valued keys are serialized in their TitleCase form. Example:

    sort_mode     = "Pct"        # Name | Pct | Size
    sort_rev      = true
    show_local    = false        # only local disks (HDD/SSD)
    show_all      = true         # include virtual filesystems
    bar_style     = "Gradient"   # Gradient | Solid | Thin | Ascii
    color_mode    = "Purple"     # one of the 30 builtin palettes
    unit_mode     = "Human"      # Human | GiB | MiB | Bytes
    thresh_warn   = 70           # cycle: 50 -> 60 -> 70 -> 80
    thresh_crit   = 90           # cycle: 80 -> 85 -> 90 -> 95
    refresh_rate  = 1            # seconds; cycle: 1 -> 2 -> 5 -> 10
    show_bars     = true
    show_border   = true
    show_header   = true
    show_used     = true
    show_tooltips = true
    compact       = false
    full_mount    = false
    col_mount_w   = 0            # 0 = auto
    col_bar_end_w = 0            # 0 = auto
    col_pct_w     = 0            # 0 = auto
    active_theme  = "neonpink"
    bookmarks     = []

    [custom_themes.neonpink]
    blue          = 199
    green         = 46
    purple        = 201
    light_purple  = 213
    royal         = 196
    dark_purple   = 161

A custom theme is six 256-color terminal indices: `blue`, `green`, `purple`, `light_purple`, `royal`, `dark_purple`. Set `active_theme` (or pass `--theme`) to a `[custom_themes.<name>]` key to activate it. Bookmarked mounts persist in the `bookmarks` array and pin to the top of the list across runs.

Inverse `--no-flag` CLI variants force-override the corresponding config field in either direction — useful for one-off invocations that diverge from the saved baseline (e.g. `--no-tooltips` defeats `show_tooltips = true` without rewriting the file). The shipped `storageshower.default.conf` in the repo root documents every key inline with comments and a full flag/keybinding reference.

## Platform notes

- macOS — disk I/O via IOKit `IOBlockStorageDriver` byte counters, device-to-mount mapping via `getmntinfo`. SMART via `diskutil info` (parses the `SMART Status:` line). Battery via IOKit, local IP from `getifaddrs`.
- Linux — disk I/O via `/proc/diskstats` (sector counters, scaled by sector size), mount mapping via `/proc/mounts`. SMART status read from `/sys/block/<dev>/device/state`. Battery from `/sys/class/power_supply/`, local IP via `getifaddrs`.
- No root required for any feature. Network FS latency is a userspace `read_dir` probe with a 2 s timeout.

## Worked examples

Goal | Command
--- | ---
Local physical disks, no virtual fs | `storageshower -l --no-virtual`
Sort by usage %, highest first | `storageshower -s pct -R`
Raw byte counts, ASCII bars | `storageshower -u bytes -b ascii`
Tighter alert thresholds in GiB | `storageshower -u gib -w 60 -C 85`
Minimal chrome (no border / header) | `storageshower --no-border --no-header`
Slower refresh for a remote session | `storageshower -r 5`
Preview every builtin palette | `storageshower --list-colors`
Dump a palette to TOML for editing | `storageshower --export-theme --color blue`
Run with an alternate config | `storageshower -c /tmp/ss.conf`

Inverse forms (`--virtual`, `--no-reverse`, `--no-local`, `--bars`, `--header`, …) let a one-off invocation override a saved config field without rewriting the file.

## Troubleshooting

- No disk I/O numbers — throughput overlays (`▲▼`) appear only when a mount has measurable read/write delta between refresh ticks. An idle disk shows no overlay. On macOS the IOKit device map and on Linux `/proc/diskstats` must resolve the mount to a base device; loopback / overlay / pseudo devices may not map.
- No SMART badge — SMART is probed per base device. Network, virtual, and removable mounts that don't expose SMART (or report an unknown state) render no health glyph rather than a false one.
- Network mount latency badge missing — the probe times out after 2 s; an unreachable mount returns no badge instead of hanging the UI. Only the recognized network filesystem types are probed.
- Blank mount rows — disk enumeration omits entries with an empty mount path, so the TUI never paints a blank row even when the OS reports an odd mount-table entry.
- Config not loading — a malformed `~/.storageshower.conf` falls back to defaults silently rather than erroring out. Enum keys must use TitleCase values (e.g. `color_mode = "Purple"`, not `"purple"`); the on-CLI `--color purple` uses the kebab/lower form.
- No root required — every probe (I/O, SMART, network latency) is a userspace read; storageshower never needs elevated privileges.

## Source & links

- Source — GitHub repo
- Crate — crates.io (`cargo install storageshower`)
- Homebrew — MenkeTechnologies/menketech tap
- API docs — docs.rs
- Issues — issue tracker
- README — full README on GitHub
- Engineering report — report.html (source distribution, test surface, dependency tree, key design decisions)