specs/017-themes/tasks.md
description: "Task list for 017-themes implementation"
Tasks: 017-themes (GUI themes)
Input: Design documents from /specs/017-themes/ (spec.md, plan.md, data-model.md, research.md)
Prerequisites: spec.md, plan.md, data-model.md, research.md
Organization: Tasks are grouped by user story (US1, US2, US3) to enable independent implementation and testing of each story. CSS tasks are marked [CSS agent] to maintain strict isolation with the parallel CSS agent.
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions
Phase 1: Setup (Shared Infrastructure)
Purpose: Core domain types module scaffolding
- T001 Scaffold
crates/signaltty-core/src/theme.rsand exportpub mod theme;incrates/signaltty-core/src/lib.rs
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Core domain logic and tokens that MUST be complete before ANY user story can be implemented
⚠️ CRITICAL: No user story work can begin until this phase is complete
- T002 [P] Core unit tests for
theme.rswritten first (TDD) incrates/signaltty-core/src/theme.rs - T003 Core domain implementation:
Appearance,Theme,GuiPreference,pane_bg,parse(per-axis fallback, corrupt JSON fallback) andto_jsonincrates/signaltty-core/src/theme.rs - T004 [P] [CSS agent] Token ladder and semantic variables in
crates/signaltty-gui/data/style.css - T005 [P] [CSS agent] Theme selector classes (
theme-signal,theme-grove,theme-ocean,theme-ember,theme-iris) incrates/signaltty-gui/data/style.css
Checkpoint: Core domain logic and CSS tokens ready - user story implementation can begin.
Phase 3: User Story 1 - Choose an appearance and theme (Priority: P1) 🎯 MVP
Goal: User can open Preferences from primary menu, select System/Light/Dark and any of the 5 themes, and observe immediate live restyle across the entire window without terminal restart.
Independent Test: Open Preferences, switch appearance and theme, verify window classes and terminal background update live.
Tests for User Story 1 ⚠️
NOTE: Write these tests FIRST, ensure they FAIL before implementation
- T006 [P] [US1] GTK display test in
crates/signaltty-gui/src/app_tests.rsasserting live class swapping (theme-ocean,dark, removingtheme-oceanon switch to Signal)
Implementation for User Story 1
- T007 [US1] Update
crates/signaltty-gui/src/terminal.rsto acceptThemeinapply_styleand set background fromTheme::pane_bg(is_dark) - T008 [US1] Update
crates/signaltty-gui/src/app.rswithpreference: RefCell<GuiPreference>, windowtheme-*CSS class management, andrestyle_terminals()integration - T009 [US1] Create Preferences dialog with Appearance cards/toggles and 5 Theme swatch cards in
crates/signaltty-gui/src/preferences.rs - T010 [US1] Register
win.preferencesaction (<Control>comma, section 3) incrates/signaltty-gui/src/actions.rsand wire handler inapp.rs - T011 [P] [US1] [CSS agent] Styling for preferences dialog, swatch cards (
theme-swatch), and selection indicator incrates/signaltty-gui/data/style.css
Checkpoint: At this point, User Story 1 is fully functional: preferences dialog opens, choices restyle window and terminals live.
Phase 4: User Story 2 - Keep my choice across restarts (Priority: P2)
Goal: Appearance and theme choices persist across restarts in $XDG_CONFIG_HOME/signaltty/gui.json, resilient to missing, corrupted, or unwritable config.
Independent Test: Save a custom preference, restart app, verify custom preference loaded; test corrupt file and unwritable directory fallback.
Tests for User Story 2 ⚠️
- T012 [P] [US2] Unit tests for GUI preference file loading, per-axis fallback, and write error handling in
crates/signaltty-gui/src/preferences.rs
Implementation for User Story 2
- T013 [US2] Implement
load_preferenceandsave_preference(usingsignaltty_core::paths::config_dir().join("gui.json")) incrates/signaltty-gui/src/preferences.rs - T014 [US2] Integrate preference loading at startup in
App::newincrates/signaltty-gui/src/app.rsbefore window presentation - T015 [US2] Wire
save_preferenceon preference change callbacks incrates/signaltty-gui/src/preferences.rs/app.rs
Checkpoint: User Stories 1 AND 2 work together seamlessly; preferences persist and survive corrupted config.
Phase 5: User Story 3 - Read statuses in any theme (Priority: P3)
Goal: Status indicators, attention markers, and high-contrast mode remain clearly distinguishable in every theme.
Independent Test: Walk every theme in light and dark variants, verify status pill and attention badge contrast.
Implementation & Testing for User Story 3
- T016 [P] [US3] [CSS agent] Visual verification of agent status contrast against Ember/Grove accents and high contrast mode
- T017 [US3] [CSS agent] Adjust status pills, rings, and high-contrast CSS overrides for all 5 themes in
crates/signaltty-gui/data/style.css
Checkpoint: All user stories functional and visually validated.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Workspace quality gates, formatting, and verification
- T018 Code formatting with
cargo fmt --all - T019 Workspace lints clean with
cargo clippy --workspace --all-targets - T020 Run core unit tests and ignored GTK display test via
xvfb-run -a dbus-run-session
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): Can start immediately.
- Foundational (Phase 2): Depends on Phase 1; blocks US1 and US2.
- User Story 1 (Phase 3): Depends on Phase 2.
- User Story 2 (Phase 4): Depends on Phase 2 & Phase 3.
- User Story 3 (Phase 5): [CSS agent] Depends on Phase 2 & Phase 3 CSS tokens.
- Polish (Phase 6): Depends on completion of Rust implementation phases.