Add a Storage page

Nothing showed what was using the drive, and removable media was handled
by a tray helper with no surface in Settings at all.

One scroll rather than tabs: space above, the device below. Every other
settings page is a scrolling card stack, and a tab would not be
deep-linkable from the launcher command or from search.

Three things the page has to get right, each now pinned by a contract,
because each is a way it could quietly lie. / and /home are one btrfs
filesystem sharing one pool of free space, and a page that copies df
shows double the free space that exists. zram is a block device and is
not storage; counting it as a drive overstates this machine by 8 GB.
Unmount and eject refuse anything not on a removable drive, because the
UI is what asks and a UI can be wrong.

The cheap read -- layout, usage, health -- runs when the page opens, at
around 90ms. Measuring what is filling the drive means walking every
file, so it happens on request and says so rather than showing an empty
list that reads as "nothing here".

Partitioning and formatting are deliberately absent. A settings pane is
the wrong place to put erasing a disk two clicks deep; the page opens
GNOME Disks for that.

Adding the page found a fourth hard-coded page list in ShellState. A
page missing from it does not error -- openSettings() falls back to
"home", so the launcher opens the wrong page and logs nothing. A
registry contract now holds the three lists together.

Claude-Session: https://claude.ai/code/session_01BRvzt4H8XXLPVH5MyYdk9L
This commit is contained in:
Gabriel Brown
2026-08-19 10:52:10 -04:00
parent a68e4f6dcd
commit 99433c0e8e
12 changed files with 1141 additions and 1 deletions
@@ -82,6 +82,27 @@ There is no way to see what is using the disk, and removable media is handled by
**Done when** the page answers "what is filling my drive" and "is it safe to pull
this USB stick out".
**Landed 2026-08-19.** Built as mock A over mock B on one scroll rather than
tabs: every other settings page is a scrolling card stack, and a tab would not be
deep-linkable from the launcher command or from search.
Three things the page had to get right, each now pinned by a contract, because
each is a way it could quietly lie:
- `/` and `/home` are one btrfs filesystem sharing one pool of free space. `df`
reports them separately, and a page that copies `df` shows double the free
space that exists.
- zram is a block device and is not storage. Counting it as a drive would
overstate this machine by 8 GB.
- unmount and eject refuse anything not on a removable drive. The UI is what
asks, and a UI can be wrong.
Adding the page also found a fourth hard-coded page list in `ShellState.qml`.
Missing from it, a page does not error -- `openSettings()` falls back to "home",
so the launcher command opens the wrong page and logs nothing. There is now a
registry contract holding the sidebar, the shell switch, and the allow-list
together.
## Phase 4 — Launcher-native settings search (small)
Settings has a search index. The launcher has script commands. They do not know