Files
Panama/docs/superpowers/plans/2026-08-18-settings-completion-codex.md

8.2 KiB

Panama Settings Completion Codex Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Complete Codex's portion of Panama Settings with default-application and autostart management, shared page scaffolds, and real controls for every remaining hardcoded shell behavior value.

Architecture: DefaultApps.qml is the typed system boundary for freedesktop default handlers and user autostart entries; ApplicationsPage.qml binds reactively to DesktopEntries.applications.values and never snapshots the asynchronous model. Existing pages adopt SettingsPage; schema-bound values use ChoiceRow, SliderRow, and ToggleRow, while specialized controls and genuinely read-only facts remain specialized or use TextRow.

Tech Stack: Quickshell 0.3 QML, QtQuick, xdg-settings, xdg-mime, freedesktop .desktop files, Bash/Python contract tests, Hyprland.

Spec: docs/superpowers/specs/2026-08-17-panama-cohesion-design.md

Status: Implemented and independently reviewed on 2026-08-18. The combined verification gate is recorded in the integrating commit history.

Global Constraints

  • Claude owns and must be the only editor of PreferenceSchema.qml, SettingsSidebar.qml, SettingsShell.qml, qmldir, ShellState.qml, SystemSettings.qml, AppearancePage.qml, DesktopPage.qml, ShortcutsPage.qml, and config/dot/hypr/*.
  • Never use hyprctl keyword; every hl.bind requires a description.
  • Use DesktopEntries.applications.values in reactive bindings. Do not call byId() or heuristicLookup() in a one-time initialization path.
  • Use SettingRow.activatable for whole-row clicks. Nested Repeaters address outer models through explicit ids, never parent.modelData.
  • Only these verified GNOME panels may be opened: applications, background, bluetooth, color, display, keyboard, mouse, multitasking, network, notifications, online-accounts, power, printers, privacy, search, sharing, sound, system, universal-access, wacom, wellbeing, wifi, wwan.
  • No mock phase, new visual direction, color literals, or idle animation. Preserve page copy and behavior unless a dead read-only row is replaced by a real control.
  • Automated tests isolate XDG config/state, do not change live defaults or autostart entries, do not launch applications, and do not invoke Home actions.

Task 1: Applications, default handlers, and user autostart

Files:

  • Create: config/dot/quickshell/services/DefaultApps.qml
  • Create: config/dot/quickshell/modules/settings/ApplicationsPage.qml
  • Create only if needed for a safe parser/writer boundary: config/dot/quickshell/scripts/panama-default-apps
  • Create: tests/quickshell/default-apps-contract.sh
  • Create: tests/quickshell/applications-settings-contract.sh

Interfaces:

  • Consumes: DesktopEntries.applications.values, SettingsPage, SettingsCard, SettingRow.activatable, ActionRow, TextRow, and Claude-owned routing for page id applications.

  • Produces: a singleton DefaultApps with reactive handlers, autostartEntries, luaAutostartEntries, busy, lastError, refresh(), setDefault(role, desktopId), and setAutostart(desktopId, enabled).

  • Step 1: Write failing helper/service and page contracts

Cover seven roles: browser (xdg-settings default-web-browser), mail (x-scheme-handler/mailto), files (inode/directory), terminal (x-scheme-handler/terminal), music (audio/mpeg), images (image/png), and video (video/mp4). Use temporary XDG directories and fake xdg-settings/xdg-mime binaries; assert setters pass separate arguments and reject unknown roles or desktop ids. Fixture user autostart entries must expose id/name/enabled and toggle with standard Hidden= semantics; hl.exec_cmd entries parsed from config/dot/hypr/autostart.lua are read-only and identify their source.

The page contract must require DesktopEntries.applications.values, page id/object name, all seven role labels, user and compositor autostart sections, SettingRow.activatable, and must reject Component.onCompleted snapshots plus byId()/heuristicLookup().

  • Step 2: Run focused contracts to verify RED
tests/quickshell/default-apps-contract.sh
tests/quickshell/applications-settings-contract.sh

Expected: fail because the service/page and behavior do not exist.

  • Step 3: Implement the minimal typed boundary and page

All process commands use argument arrays. Validate roles against a fixed map and desktop ids against the reactive applications model or a strict freedesktop id pattern plus discovered entries. The page filters role choices from category/generic-name data, sorts by display name, keeps the current handler visible even when category metadata is sparse, and shows calm inline errors. Toggling applies only to files under $XDG_CONFIG_HOME/autostart; Lua entries remain read-only with explanatory copy.

  • Step 4: Verify and commit
tests/quickshell/default-apps-contract.sh
tests/quickshell/applications-settings-contract.sh
tests/quickshell/settings-pages-contract.sh

Commit subject: Add application and autostart settings.


Task 2: Remaining page scaffolds and hardcoded behavior controls

Files:

  • Modify: config/dot/quickshell/config/Settings.qml
  • Modify: config/dot/quickshell/modules/settings/HomePage.qml
  • Modify: config/dot/quickshell/modules/settings/DisplaysPage.qml
  • Modify: config/dot/quickshell/modules/settings/ConnectivityPage.qml
  • Modify: config/dot/quickshell/modules/settings/SoundPage.qml
  • Modify: config/dot/quickshell/modules/settings/NotificationsPage.qml
  • Modify: config/dot/quickshell/modules/settings/ScreenIntelligencePage.qml
  • Modify: config/dot/quickshell/modules/settings/ServicesPage.qml
  • Modify: config/dot/quickshell/modules/settings/AboutPage.qml
  • Modify: tests/quickshell/settings-pages-contract.sh
  • Create: tests/quickshell/settings-hardcoded-values-contract.sh

Interfaces:

  • Consumes: Claude-owned schema keys temperatureUnit, weatherRefreshMinutes, vitalsIntervalMs, notificationTimeoutMs, notificationTimeoutCriticalMs, notificationHistoryLimit, maxVisibleToasts, screenshotDir, recordingDir, and recorderArgs; shared Settings rows; existing services and system handoffs.

  • Produces: the same public Settings.qml properties, now each reading DesktopPreferences.get("key"), and controls routed to weather/vitals, notifications, and capture pages.

  • Step 1: Write failing contracts

Require all ten Settings.qml properties to use DesktopPreferences.get() exactly. Require every listed page root to be SettingsPage and reject its copied root Flickable scaffold. Require weather/vitals controls on HomePage, notification controls on NotificationsPage, and capture directory/encoder controls on ScreenIntelligencePage; every schema-bound control uses a shared row and writes only through SystemSettings.commitPreference via that row.

  • Step 2: Run contracts to verify RED
tests/quickshell/settings-hardcoded-values-contract.sh
tests/quickshell/settings-pages-contract.sh

Expected: fail on hardcoded properties and copied page scaffolds.

  • Step 3: Implement controls and migrate scaffolds

Use ChoiceRow for temperatureUnit, screenshotDir, recordingDir, and recorderArgs; use SliderRow for numeric refresh, timeout, history, and toast limits. Give notificationTimeoutCriticalMs zeroLabel: "Never". Preserve all specialized buttons, service status rows, display diagnostics, permission/privacy explanations, and GNOME handoff actions. Convert genuinely read-only rows to TextRow; delete only rows superseded by working controls.

  • Step 4: Run focused and full suite, then commit
tests/quickshell/settings-hardcoded-values-contract.sh
tests/quickshell/settings-pages-contract.sh
tests/quickshell/settings-preferences-contract.sh
tests/quickshell/settings-search-contract.sh

Then run every tests/quickshell/*.sh, every tests/hypr/*.sh, and all three tests/quickshell/*_test.py files sequentially.

Commit subject: Complete Panama settings controls.