tui-tools

tui-disk

Disks, mounts, fstab, btrfs and SMART, previewed before every change

A terminal UI (TUI) for lsblk, btrfs and smartctl on Linux: the machine's storage.

v1.0.0Stable since 1.0.0storageMIT
The device tree: size, filesystem, usage and the SMART verdict of every disk
The device tree: size, filesystem, usage and the SMART verdict of every disk

A terminal UI for the machine's storage. Five screens over one read: the block devices with their filesystems and usage bars, the mount table crossed against /etc/fstab, the btrfs filesystems in full, the SMART health of every drive, and what df says about free space.

The mounts screen is the one that earns its keep. It shows what is mounted now next to what fstab says will be mounted next boot, and marks every row where those disagree: a filesystem mounted by hand that will vanish on reboot, an fstab entry that failed to mount and nobody noticed, and options fstab asks for that are not in effect.

Changes are previewed. Mounting and unmounting an entry, starting or cancelling a btrfs scrub or balance, starting a drive self-test, and editing /etc/fstab — which is validated with findmnt --verify against the staged file BEFORE the dialog opens, shown as a unified diff, then installed and applied with systemctl daemon-reload — all carry the exact command line.

Run tui-disk --demo to drive a sample machine: an NVMe root on btrfs, a spinning disk with two reallocated sectors, a USB stick mounted by hand and one fstab mismatch. Nothing touches your system.

Keys

KeyAction
1…5 / tabSwitch between devices, mounts, btrfs, health and space
enterOpen the selected row in full
m / uMount or unmount the selected fstab entry
eEdit the fstab entry for the selected row, with a diff to confirm
aAdd an fstab entry, picking the device by UUID
DReload the systemd units generated from fstab
c / CStart or cancel a btrfs scrub
b / BStart or cancel a btrfs balance, with a block group filter
s / SStart a short or extended drive self-test
/Filter the current screen across every column
RRe-read the storage
?Help
qQuit

Press ? inside the tool for the full help screen, which is generated from the same action table as the key map.

Compatibility

This tool is a face on the program below, so its version matters. Tested is not a claim: a version lands there only after the tool's own suite passed against it on a real machine in the lab, and the run is kept as evidence in the repository. At startup the tool probes the backend once and says what it found in its header — a version nobody has run against is shown as (untested) in the warning colour, one older than the minimum as (below minimum) in the error colour. Neither stops it: the backend still refuses what it cannot do, in its own words.

util-linux

lsblk ≥ 2.34
Binary
lsblk
Minimum
2.34
Probed with
lsblk --version
Tested
2.39.32.41.52.42.2

Needs a version this new

  • mountpointssince 2.37

What changes on older versions

  • util-linux <2.37

    lsblk has no MOUNTPOINTS column, so the single-valued MOUNTPOINT is asked for instead; a device mounted at several paths reports only the first one. lsblk fails the whole call on a column name it does not know, so this is a gate rather than a fallback

  • util-linux >=2.34

    blkid reads /dev directly and answers an unprivileged caller with an empty body and exit 0, so the fstab editor's device picker escalates with sudo -n and falls back to the UUIDs lsblk already reported when it cannot

btrfs-progs

btrfs ≥ 5.10
Binary
btrfs
Minimum
5.10
Probed with
btrfs --version
Tested
6.6.36.19.17.1

Needs a version this new

  • json-outputsince 5.15

What changes on older versions

  • btrfs-progs >=5.10

    --format json is supported per command, not globally: device stats and filesystem df emit JSON, while filesystem usage, subvolume list, scrub status and balance status refuse it through 6.19 at least, so those four are read from their text output

  • btrfs-progs >=5.10

    subvolume list, qgroup show, balance status, and on some kernels (Ubuntu 24.04) scrub status and device stats, refuse an unprivileged caller; they are retried with sudo -n, and what still cannot be read is left empty with a note saying so

  • btrfs-progs <5.15

    no --format json at all, so device stats is read from its text output too

smartmontools

smartctl ≥ 7.0
Binary
smartctl
Minimum
7.0
Probed with
smartctl --version
Tested
7.5

Needs a version this new

  • json-outputsince 7.0

What changes on older versions

  • smartmontools <7.0

    smartctl --json does not exist, and the health of every drive is reported as unknown rather than scraped out of a table meant for human eyes

  • smartmontools >=7.0

    reading SMART needs the raw device, so it escalates with sudo -n; a drive behind a USB bridge that passes no SMART through, and a virtual disk that has no firmware, both come back unknown with the reason smartctl gave

Maintain util-linux, btrfs-progs or smartmontools? You are welcome to help shape this tool. About → maintainers

Guides

Written after the work, from a machine the commands were actually run on. Every guide that mentions tui-disk is listed here.

  • Adding a disk to fstab safely, with tui-disk

    A line in /etc/fstab that does not parse is a boot that stops in an emergency shell. tui-disk picks the device by UUID, checks the staged file with findmnt before you are asked, shows the one-line diff, and then reads the drive's health and the btrfs state back.

Install

Once per machine, then every tool in the family is one pacman away.

Add the repository
$ curl -fsSL https://pkgs.tui.tools/install.sh | sh
Or run the same thing yourself, one command at a time

A family whose whole promise is preview before you run is not going to insist you pipe a script into a shell. These are the commands that script runs.

The one-time setup, by hand
$ curl -fsSL -o /tmp/tui-tools.asc https://pkgs.tui.tools/pubkey.asc
  sudo pacman-key --add /tmp/tui-tools.asc
  sudo pacman-key --lsign-key \
    "$(gpg --show-keys --with-colons /tmp/tui-tools.asc | awk -F: '/^fpr:/{print $10; exit}')"
  printf '[tui-tools]\nServer = https://pkgs.tui.tools/arch/$arch\n' \
    | sudo tee -a /etc/pacman.conf
  sudo pacman -Sy
Arch Linux · tui-disk
$ sudo pacman -S tui-disk

Upgrades then arrive with the rest of your system updates.

What it can do to your machine

  • Preview, then confirm

    Every change is shown as an exact command line and confirmed before it runs. The dialog and the runner receive the same value, so the preview cannot drift from what executes.

  • Escalates for actions

    Most reads are unprivileged. Five are not and escalate with sudo -n, which never prompts: blkid, btrfs subvolume list, qgroup show, balance status and smartctl -a. Every change escalates the same way.

  • No daemon, no state of its own

    Nothing keeps running after you quit, and nothing is installed to run later. The system is the source of truth; the tool re-reads it after every change.

  • No network access

    The tool opens no network connection of its own. No telemetry, no update check, no phone home.

  • Static binary

    Released statically linked, with no runtime dependencies to install.

  • Signed release, with provenance

    checksums.txt carries a keyless cosign signature from this repository's release workflow, every archive has a CycloneDX SBOM, and every archive, package and the checksum file carry SLSA build provenance. The security page shows the three commands that check it.

Reporting

Report a security issue privately, through GitHub's private vulnerability reporting on the repository's Security tab. The family-wide policy, and what counts as in scope, is on the security page.

Downloads

v1.0.0 · 2026-10-07
FileSizeSHA-256
checksums.txt1006 B—
checksums.txt.sigstore.json10 KB—
provenance.intoto.jsonl12 KB—
tui-disk-1.0.0-1-aarch64.pkg.tar.zst1.8 MB65d2772417f2840ff2bf2fd27395a00b88328323a7fc3148770b2e900fcf4087
tui-disk-1.0.0-1-x86_64.pkg.tar.zst1.9 MB215b72e62319f0ab46cf5d502a9788cd47161619788b835f54bc6801de921600
tui-disk-1.0.0-1.aarch64.rpm1.8 MB5f54403d86be12acb9f2b8785876f9e8996f9f8445d4a093b4ab16a35357f80d
tui-disk-1.0.0-1.x86_64.rpm1.9 MB1a8b8a409ecdc5bac6b8e099fb04d70e57857dd67dad978c11d572b7760e41c4
tui-disk_1.0.0_amd64.deb1.9 MB3651ad0efe15bfaa57473c5f120e2c23b59b2bc2967774cd371c87e15380632c
tui-disk_1.0.0_arm64.deb1.8 MB78984879b5fc92a639cbf950269f516a97ade7aaf34d62a83154e4f93d9f72cc
tui-disk_1.0.0_linux_amd64.tar.gz1.9 MB84206adf6787ec8d399224a337e4847af6b83fd16254c44c27cf1aacf5377b74
tui-disk_1.0.0_linux_amd64.tar.gz.cyclonedx.json23 KB10f900c8317100f06116bcbc1dad90bea4ff25a7f347bcc611f49304202af39e
tui-disk_1.0.0_linux_arm64.tar.gz1.8 MB392b927a583c9c331f131739f6262d010148b287f175992b926ca20835e67d9b
tui-disk_1.0.0_linux_arm64.tar.gz.cyclonedx.json23 KBc6ffbffe71e24054164b0318296aaa0efbfa0b1294b3598f260da1d2664a325c

Every release ships a checksums.txt. Download it next to the archive and run sha256sum -c checksums.txt --ignore-missing. See verifying a download.

Releases

v1.0.0

2026-10-07
## tui-disk v1.0.0

tui-disk 1.0.0: stable

tui-disk 1.0.0 is stable. Stable means a frozen contract under semver: the keys, the flags and the `--check` JSON only grow in minor releases, and anything removed or changed waits for a major release announced one minor ahead. It has driven a real machine through its main job, an fstab entry added by UUID and verified before install, mounted, scrubbed and unmounted, and read SMART on real drives; installs from apt, dnf, pacman and a static binary; and ships signed checksums, SBOMs and build provenance. This release also carries what that work found: `btrfs scrub status` and `btrfs device stats` are retried with `sudo -n` when the kernel refuses them to an ordinary user (Ubuntu 24.04), and `--check` gains `btrfsUncounted`, the number of btrfs filesystems whose error counters could not be read, so a `btrfsErrors` of zero means clean only when it is zero too. smartmontools 7.5 joins the tested versions. Built with Go 1.27.1 and tui-kit v0.4.4.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 2051c50777b8843923190b2ec3e77ab4be338fed Bump the github-actions group with 4 updates (#17)
* 700c411edd2b236cc29c24b7060b5f8b7207c4d0 Promote tui-disk to stable: 1.0.0 (#19)
* 64c68010144124fc334ff89bec2dd49b8dbf1271 btrfs: escalate scrub status and device stats; --check btrfsUncounted; smartmontools 7.5 recorded; Go 1.27.1 (#18)

v0.1.4

2026-09-25
## tui-disk v0.1.4

tui-disk 0.1.4: tui-kit v0.4.4

tui-disk 0.1.4 moves to tui-kit v0.4.4: every mount, btrfs and smartctl command now runs in its own session without a controlling terminal, so a step that would prompt fails at once instead of hanging behind the UI, and a failed step reports its meaningful line, cleaned of escape codes. Command previews are POSIX shell-quoted, the README screenshots are re-rendered with continuous box borders, and the README banner now carries the kit's stability markers.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* d2f882a9c3cc7ae1b5c209fb122ef7962b17240e 0.1.4: tui-kit v0.4.4 (#16)
* 8f104787eb8951b5db18f8497bd3af43b3d1c2c4 Bump anchore/sbom-action/download-syft (#3)
* 5e8bbfca872abdba1dfa63cd49a8a38c4fc33ead Bump anchore/sbom-action/download-syft in the github-actions group (#14)
* 7d6ac289a0d7fbe9881412357435423f2c634787 Bump the github-actions group with 4 updates (#15)
* 13366d7c3c2fd298e5e486c6fb0406d1f2f1ff27 README: link the tool's page on tui.tools (#13)
* 8e4088c780c1af893ba625975261753c6bc1da63 README: point the install snippet at the current release (#12)

v0.1.3

2026-09-02
## tui-disk v0.1.3

tui-kit v0.3.0: the dialogs wrap and scroll instead of clipping the
command preview, and the picker filters as you type.

Built by this repository's CI on the tag itself. Each archive ships a
CycloneDX SBOM, `checksums.txt` carries a keyless cosign signature, and
every file has SLSA build provenance — see the README's "Verify a
download" for the two commands that check them.

The commits in this release:

## Changelog
* 758d647719756631e261025cf701af6af85a553d A code of conduct that fits on one screen (#9)
* f8f4d9de86a65647a5055aa592f512808057547a Add --report, and a bug form that asks for it (#10)
* 4f5b42ee88c58de6a98d940fef6dc0cb6b57e639 Bump tui-kit to v0.3.0 (#11)
* 31e9a328028b02741283eaf5ca4833fb4fcc0ce6 Carry the OpenSSF Best Practices badge (#7)
* a509fa7eb5c2101b21cbb157cde8ba46992a01f3 Fetch the tag annotation before releasing (#5)
* 1f560a6457d8ccaf29ed43e88e1775f0157d48d3 Pin what CI runs, fuzz the parsers, and say the releases are signed (#2)
* 81aa808b96da07c91ed3f2a5a278ad26cd5fbc1f Print the whole tag message, not only its body (#6)
* cc1519b60b0bf405d9b94ef05b093355a177bbee Say beta once (#4)
* ac8e8a1d937bc797393fe52f04d18b4d12f96add Take tui-kit v0.2.8: hashed pip install, provenance bundle on the release (#8)

v0.1.2

2026-08-30
## Changelog
* 975225eb161be0ddb3fd46c6495e640dc6de208f Drop cross-repo dispatch; the package repo and the site poll releases
* f0068de4d16ddad07176bbb2540591023c19bebe Gate the release on a security job, and sign what it publishes (#1)
* 1b3d2a5871317e91d1ee18ac9d399d71e374ec76 Stop telling readers the packages are unpublished

v0.1.1

2026-08-30
## Changelog
* 6e2c0ac055010364892989959f23ec4ed1ae3980 Cover the btrfs filesystem that is not the root, and record the first real run
* 2922593be9f088a3a1bb62b9e13bbd4c5cf520a6 Packages are available from pkgs.tui.tools
* 3d74312aec38354d784b2ae8021fdb042274e161 Re-pin the kit at v0.2.3
* c7a25638d6e73e1f13cf3b0175ddbe2c3ef7a4ac Ship the tool as a .deb, an .rpm and a pacman package

v0.1.0

2026-08-30
## Changelog
* 32f35b639edef85b8a39f13f82bc0a70bdf91fae Build tui-disk: disks, mounts, fstab, btrfs and SMART on one screen
* 53b08c5ec4331f3890a7636851c92509bcd33a63 Fit the manifest inside the family schema
* f4eab3e7cc3bbff4422b3b8607d71f464ff1884d Initial commit