diff --git a/docs/superpowers/plans/2026-08-19-desktop-integration.md b/docs/superpowers/plans/2026-08-19-desktop-integration.md new file mode 100644 index 0000000..2784c09 --- /dev/null +++ b/docs/superpowers/plans/2026-08-19-desktop-integration.md @@ -0,0 +1,137 @@ +# Desktop integration: the parts an OS owns that we still hand to someone else + +Written 2026-08-19, after the default-applications work landed. + +Settings is now a superpowered control panel, and files open in the right +applications. What remains are the jobs a desktop environment is expected to own +but that this one currently delegates, ignores, or leaves to whatever GNOME +component happens to be installed. + +Six items, ordered so each one is useful the day it lands rather than only at the +end. Effort labels are relative to each other, not to the clock. + +## What the probe found + +Two of these are far cheaper than assumed: + +- **`sushi` 50 is already installed** and owns `org.gnome.NautilusPreviewer`, so + Quick Look is a wiring-and-declaring job, not a build. +- **Vicinae script commands already exist and are repo-managed** + (`config/local/share/vicinae/scripts/panama/`, linked by + `setup/scripts/link-vicinae-scripts`), so launcher search is a generator on top + of a mechanism that works. + +And two need software this machine does not have: `restic` (backups) is not +installed, and nothing enumerates the keyring beyond lock state. + +--- + +## Phase 1 — Finish the file-opening story (small) + +Curating defaults only helps if the applications are actually present. A fresh +install seeds `org.gnome.Loupe`, `org.gnome.Papers` and `org.gnome.Decibels` +only when they exist; otherwise it correctly leaves the role alone and the +machine falls back to installation order — the exact problem we just fixed. + +- Declare Loupe, Papers, Decibels and sushi in the dependency list so + `declared-dependencies-contract` fails when a curated handler is missing. +- Wire preview: confirm space-to-preview from the file manager, and decide + whether preview is worth a compositor-level keybind for the focused selection. +- Extend the family contract to assert every seeded candidate is installable. + +**Done when** a fresh machine gets the same handlers this one has, and the +contract fails loudly if a curated application is not a declared dependency. + +## Phase 2 — Make GTK applications wear our accent (small) + +The named accents theme our own surfaces; Loupe, Papers, Nautilus and every other +libadwaita application still render in GNOME blue. GNOME exposes +`org.gnome.desktop.interface accent-color` as an enum (blue, teal, green, +yellow, orange, red, pink, purple, slate). + +- Give each named accent a nearest-GNOME-enum member in `Theme.qml`, beside the + dark/light pair it already carries. +- Apply it alongside the existing GTK theme write, so one accent change moves + both worlds. +- Contract: every named accent maps to a member the enum actually publishes, + read from `gsettings range` rather than a hardcoded list. + +**Done when** switching accent visibly recolors Papers and Nautilus. + +## Phase 3 — Disks and storage (medium) + +There is no way to see what is using the disk, and removable media is handled by +`udiskie` in the tray with no surface in Settings. `udisks2` is installed. + +- Helper `panama-disks`: JSON snapshot of filesystems, sizes, usage, mount + points, removable devices, and SMART health where the device exposes it. +- Page: usage bars per filesystem, removable devices with mount / unmount / + eject, and "open in Files". +- **Deliberately out of scope: partitioning and formatting.** A settings pane is + the wrong place to hand someone a way to erase a disk in two clicks; that stays + with GNOME Disks, which we can launch. + +**Done when** the page answers "what is filling my drive" and "is it safe to pull +this USB stick out". + +## Phase 4 — Launcher-native settings search (small) + +Settings has a search index. The launcher has script commands. They do not know +about each other, so finding a setting means opening Settings first. + +- Generate one script command per settings page from the same schema that feeds + in-app search, with the page's keywords, so typing "night light" in the + launcher opens that page directly. +- Generator gets a `--check` staleness mode, matching `panama-settings-docs`. +- Contract: every page has a command, every command resolves to a real page. + +**Open question for Gabriel:** the existing launcher commands are titled +"Panama: Open Settings", which the debranding pass did not touch. Keep the prefix +so desktop commands group together in the launcher, or drop it to match the rest? + +**Done when** the launcher is the fastest way to reach any setting. + +## Phase 5 — Keychain and secrets (medium, security-sensitive) + +`panama-keyring` knows whether the keyring is locked and can unlock it. Nothing +can see what is *in* it, so managing a stored credential means installing +Seahorse. + +- Extend the helper to enumerate collections and items through libsecret, + returning **attributes and labels only**. +- Page: unlock state, lock/unlock, items grouped by collection, delete, change + password. +- Rules that are non-negotiable and get their own contracts: a secret value never + appears in a snapshot, never reaches a command line (argv is world-readable via + `/proc`), never lands in a log or an error message, and is revealed only on an + explicit per-item request. + +**Done when** a stored password can be found, inspected and removed without +leaving Settings, and the contracts prove no value leaks on the way. + +## Phase 6 — Backups (large, staged) + +The one genuinely missing safety net. `restic` is not installed. + +- **6a** — destination and repository setup, plus a manual snapshot. Repository + password lives in the keyring (which is why this follows phase 5), never in the + repo and never on argv. +- **6b** — a systemd user timer, with the page showing schedule, last run, and + failures. +- **6c** — restore: browse a snapshot and copy files out. + +Blast radius: writes to a destination the user chooses. Nothing in this phase +modifies or deletes existing data; restore copies out rather than over. + +**Done when** losing the home directory is an inconvenience rather than a +catastrophe. + +--- + +## Order and reasoning + +Phases 1 and 2 finish work already in flight and are visible immediately. Phase 3 +is self-contained and answers a question people actually ask. Phase 4 is small +but changes daily habit. Phase 5 must precede 6 because 6 needs somewhere safe to +keep a repository password. Phase 6 is the largest and is staged so each part +stands alone.