Files
Panama/docs/superpowers/specs/2026-08-23-settings-navigation-redesign.md
T
Gabriel Brown 5490fd285d Fold thirty-one settings pages into fifteen categories with tabs
The sidebar was a flat scan of thirty-one rows; now it reads like a
settings app. Multi-subject categories (Input, Network & Sharing,
Applications, Users & Accounts, Privacy & Security, System) carry an
Appearance-style tab strip above the page, drawn by the shell so the
leaf pages themselves are untouched. The taxonomy lives in one new
file, services/SettingsRoutes.qml; the sidebar, the strip, route
validation, search breadcrumbs, and both generators derive from it.

ShellState.settingsPage still holds leaf ids, so every deep link, IPC
call, and search result keeps working — and now lands on the exact
tab. Dictation moves out of Sound onto its own page under Input, with
a handoff back to Sound for the microphone. The strip scrolls when
System's nine tabs outgrow a tiled window. All 161 contracts pass.

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
2026-08-23 20:21:31 -04:00

4.1 KiB
Raw Blame History

Settings navigation redesign — 31 flat pages become 15 categories

Approved 2026-08-23. The sidebar's 31 entries collapse into 15 categories. Multi-subject categories render an Appearance-style tab strip above the page; single-subject categories render no strip. Every old page id keeps working forever.

The taxonomy

Category (sidebar) Tabs (leaf page ids)
Home — (home)
Appearance — (appearance, keeps its internal tabs)
Desktop & Dock — (desktop)
Displays — (displays)
Sound — (sound, Dictation card moves out)
Notifications & Focus — (notifications)
Input Keyboard (shortcuts), Mouse & Touchpad (mouse), Dictation (dictation, new)
Network & Sharing Connections (connectivity), Firewall (firewall), Sharing (sharing), Printers (printers)
Home & Phone — (home-phone)
Applications Applications (applications), Gaming (gaming), Screen Intelligence (screen-intelligence)
Users & Accounts Users (users), Online Accounts (accounts)
Privacy & Security Privacy (privacy), SSH Keys (ssh-keys)
Power & Lock — (power)
Accessibility — (accessibility)
System About (about), Software Update (updates), System Health (services), Storage (storage), Snapshots (snapshots), Containers (containers), Date & Time (datetime), Region & Language (region), Manual (manual)

Architecture

ShellState.settingsPage keeps holding the leaf id, exactly as today. The page loader's switch, the ownership contracts, HomePage's direct jumps, and every external caller are untouched by the grouping itself. What changes:

  • services/SettingsRoutes.qml (new singleton) — the one source of truth for the taxonomy: categories (page, label, icon, tabs), resolve(id) (category id → first available leaf; leaf → itself; unknown → home), categoryOf(leaf), tabsFor(leaf) (availability-filtered), breadcrumb(leaf), pageAvailable(leaf) (the podman/snapper gating, moved from the sidebar).
  • SettingsSidebar.qml — destinations come from SettingsRoutes.categories; a row highlights when it is the category owning the current leaf; clicking requests the category id and ShellState resolves it.
  • ShellState.showSettings — the literal allow-list becomes SettingsRoutes.resolve().
  • SettingsShell.qml — renders a SettingsTabs strip between the titlebar and the page loader whenever the current leaf's category has more than one available tab. Tab click is just openSettings(leafId). Adds the dictation case.
  • SettingsTabs.qml — the strip becomes horizontally scrollable when it overflows (System has nine tabs; the window tiles down to 900px).
  • SoundPage.qml / DictationPage.qml (new) — the Dictation card moves to its own page under Input, with a labeled handoff noting the microphone is chosen in Sound.
  • SettingsSearch.qml — dictation extraEntries re-route to dictation; the search result subtitle becomes the SettingsRoutes breadcrumb ("System Storage"). Because results carry leaf ids, search now lands on the exact tab with no further work.

Blast radius owned by this change

  • scripts/panama-settings-commands regex-parses the sidebar's destinations array; it moves to parsing SettingsRoutes.qml and regenerates the Vicinae commands (one per leaf; home still skipped; dictation gained). scripts/panama-settings-docs checked the same way.
  • Test contracts updated in the same change, not after: settings-nav-contract, settings-jump-contract, search-routing-contract, gnome-handoff-contract, manual-contract, sound-page-contract, plus any contract found grepping page ids.
  • modules/settings/README.md gains the navigation model; manual chapter 05-making-it-yours.md updated where it describes the sidebar.

Non-goals

  • No per-tab deep links into Appearance's internal tabs from search (unchanged today).
  • No persistence of last-selected tab per category (Appearance already resets; same rule).
  • No renaming of leaf ids, files, or schema groups.