diff --git a/docs/superpowers/plans/2026-06-04-myday-icons-terminal-reuse.md b/docs/superpowers/plans/2026-06-04-myday-icons-terminal-reuse.md new file mode 100644 index 0000000..718f304 --- /dev/null +++ b/docs/superpowers/plans/2026-06-04-myday-icons-terminal-reuse.md @@ -0,0 +1,147 @@ +# MyDay Icon Buttons + Terminal Reuse + Sort Icon Fix — Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: superpowers:subagent-driven-development. Steps use `- [ ]`. + +**Goal:** Move the "Clear day" and "Prep log" actions into the MyDay header icon row as icon buttons (broom + list), render the prep log in the real `SessionTerminalView` ("cool terminal") by making that control reusable, and fix the invisible Sort icon. + +**Approved design (chat):** +- Header icon row (`TasksIslandView.axaml`, the Sort/Eye/Settings `icon-btn` StackPanel) gets two more `icon-btn`, both `IsVisible="{Binding IsMyDayList}"`, inserted after the Eye button: **broom** (`Icon.Broom`) → `ClearDayCommand`, **list** (`Icon.List`) → `ShowPrepLogCommand`. The two full-width text buttons "Prep log" and "Clear day" are removed. "Tag vorbereiten" stays as the full-width button (already opens the prep view via `PrepRequested`). +- `SessionTerminalView` becomes reusable via StyledProperties so it renders both the task `Log` and the prep `PrepLog` with the same terminal look. The prep panel in `DetailsIslandView` embeds it instead of the copied `ItemsControl`. +- **Sort icon bug:** `PathIcon` fills geometry; `Icon.Sort` is an open-line path (no enclosed area) → invisible. Replace with a filled geometry. New icons (Broom, List) are authored as filled geometries too. + +**Tech:** Avalonia (PathIcon/StreamGeometry, StyledProperty), CommunityToolkit.Mvvm, xUnit. + +## Build/test +`.slnx` needs .NET 9 — build the csproj. Use `-c Release` if a Worker locks Debug. +```bash +dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release +dotnet test tests/ClaudeDo.Ui.Tests/ClaudeDo.Ui.Tests.csproj -c Release +dotnet test tests/ClaudeDo.Localization.Tests/ClaudeDo.Localization.Tests.csproj -c Release +``` +GUI cannot be smoke-tested headlessly — note it; the human verifies visuals. + +--- + +## Task A: Icons + reusable SessionTerminalView + +**Files:** +- Modify: `src/ClaudeDo.Ui/Design/IslandStyles.axaml` (icon geometries) +- Modify: `src/ClaudeDo.Ui/Views/Islands/SessionTerminalView.axaml` + `SessionTerminalView.axaml.cs` +- Modify: `src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml` (both embeds) + +- [ ] **Step 1: Fix `Icon.Sort` + add `Icon.Broom`, `Icon.List`** as filled geometries in `IslandStyles.axaml` (in the `Styles.Resources` icon block). Replace the existing `Icon.Sort` line and add the two new ones: + +```xml + +M4 6 H20 V8 H4 Z M4 11 H16 V13 H4 Z M4 16 H11 V18 H4 Z + + +M11 3 H13 V10 H11 Z M8.5 10 H15.5 V12 H8.5 Z M9 12 H15 L17 21 H7 Z + + +M4 5 H6 V7 H4 Z M8 5 H20 V7 H8 Z M4 11 H6 V13 H4 Z M8 11 H20 V13 H8 Z M4 17 H6 V19 H4 Z M8 17 H20 V19 H8 Z +``` + +- [ ] **Step 2: Add StyledProperties to `SessionTerminalView`** (code-behind `SessionTerminalView.axaml.cs`). Add public StyledProperties and CLR wrappers: + +```csharp +public static readonly StyledProperty EntriesProperty = + AvaloniaProperty.Register(nameof(Entries)); +public static readonly StyledProperty LabelProperty = + AvaloniaProperty.Register(nameof(Label)); +public static readonly StyledProperty IsRunningProperty = + AvaloniaProperty.Register(nameof(IsRunning)); +public static readonly StyledProperty IsDoneProperty = + AvaloniaProperty.Register(nameof(IsDone)); +public static readonly StyledProperty IsFailedProperty = + AvaloniaProperty.Register(nameof(IsFailed)); + +public System.Collections.IEnumerable? Entries { get => GetValue(EntriesProperty); set => SetValue(EntriesProperty, value); } +public string? Label { get => GetValue(LabelProperty); set => SetValue(LabelProperty, value); } +public bool IsRunning { get => GetValue(IsRunningProperty); set => SetValue(IsRunningProperty, value); } +public bool IsDone { get => GetValue(IsDoneProperty); set => SetValue(IsDoneProperty, value); } +public bool IsFailed { get => GetValue(IsFailedProperty); set => SetValue(IsFailedProperty, value); } +``` + +Replace the existing auto-scroll hook (which cast `DataContext as DetailsIslandViewModel` and watched `.Log.CollectionChanged`) with one that watches whichever collection `Entries` points at: in `OnPropertyChanged`, when `change.Property == EntriesProperty`, detach the old `INotifyCollectionChanged.CollectionChanged` handler and attach to the new value (if it implements `INotifyCollectionChanged`); the handler scrolls the existing ScrollViewer to the end (reuse the existing scroll logic / named ScrollViewer). Keep the named ScrollViewer's `x:Name`. + +- [ ] **Step 3: Repoint `SessionTerminalView.axaml` internal bindings to the control's own properties.** Give the root `UserControl` `x:Name="Root"`. Change: + - the `ItemsControl ItemsSource="{Binding Log}"` → `ItemsSource="{Binding #Root.Entries}"` + - the label `TextBlock` `Text="{Binding BranchLine, StringFormat='claude-session · {0}'}"` (or whatever it is) → `Text="{Binding #Root.Label}"` + - the LIVE chip `IsVisible="{Binding IsRunning}"` → `{Binding #Root.IsRunning}`; DONE → `#Root.IsDone`; FAILED → `#Root.IsFailed`. + Keep the `LogLineViewModel` item template as-is (it binds the item, not the VM). The `x:DataType` can stay `DetailsIslandViewModel` (element-name bindings to `#Root` don't depend on it) or be removed if it causes compile issues — verify the build. + +- [ ] **Step 4: Update both embeds in `DetailsIslandView.axaml`.** + - Task embed (currently ``): + ```xml + + ``` + (Use the exact label binding the old internal header used — match the prior `StringFormat` text precisely so the task view is visually unchanged.) + - Prep panel: replace the whole copied `ItemsControl` (and its surrounding `ScrollViewer`/title) with: + ```xml + + ``` + Keep the panel wrapper ``. Drop the now-redundant `details.prepTitle` title TextBlock (the terminal header shows the `daily-prep` label). Leave the `details.prepTitle` locale key in place (harmless) OR remove it from both en/de if you prefer — if removing, run the localization test. + +- [ ] **Step 5: Build the App; confirm no binding/compile errors.** +```bash +dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release +dotnet test tests/ClaudeDo.Ui.Tests/ClaudeDo.Ui.Tests.csproj -c Release +``` +(The existing DetailsIsland prep tests must still pass — `PrepLog`/`IsPrepMode`/`ShowPrep` are unchanged.) + +- [ ] **Step 6: Commit** (stage only Task A files; do NOT `git add -A`): +```bash +git commit -m "feat(daily-prep): reuse SessionTerminal for prep log; fix invisible Sort icon; add Broom/List icons" +``` + +--- + +## Task B: MyDay header icon buttons + +**Files:** +- Modify: `src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml` +- Modify: `src/ClaudeDo.Localization/locales/en.json`, `de.json` + +Depends on Task A (uses `Icon.Broom` / `Icon.List`). + +- [ ] **Step 1: Add two `icon-btn` to the header icon StackPanel** (the one with Sort/Eye/Settings), inserted right after the Eye button and before Settings, both MyDay-only: + +```xml + + +``` + +- [ ] **Step 2: Remove the two full-width buttons** "Prep log" (`ShowPrepLogCommand`) and "Clear day" (`ClearDayCommand`) from the DockPanel button stack. Keep the "Prepare day" (`PrepareDayCommand`) full-width button and the Notes pinned-row button. + +- [ ] **Step 3: Locales.** Add `tasks.clearDayTip` (en "Clear day", de "Tag leeren") and `tasks.prepLogTip` (en "Prep log", de "Vorbereitungs-Log") to both json files. Remove the now-unused `tasks.clearDay` and `tasks.prepLog` keys from both (keep en/de in parity). + +- [ ] **Step 4: Build + test.** +```bash +dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release +dotnet test tests/ClaudeDo.Ui.Tests/ClaudeDo.Ui.Tests.csproj -c Release +dotnet test tests/ClaudeDo.Localization.Tests/ClaudeDo.Localization.Tests.csproj -c Release +``` + +- [ ] **Step 5: Manual smoke (human):** on MyDay the header shows Sort (now visible) + Eye + Broom + List + Settings; broom clears the day; list opens the prep terminal; "Tag vorbereiten" opens the prep terminal and streams; the three MyDay-only controls hide on other lists; the task session terminal still renders normally. + +- [ ] **Step 6: Commit** (stage only Task B files): +```bash +git commit -m "feat(daily-prep): move Clear-day and Prep-log into MyDay header icon row" +``` + +## Notes / risks +- Element-name bindings (`#Root.*`) require the `UserControl` to have `x:Name="Root"`; verify compiled bindings accept them (they do in Avalonia). +- The auto-scroll hook must re-subscribe when `Entries` changes; without it the prep log won't auto-scroll. +- `ClearDayCommand` / `ShowPrepLogCommand` already exist on `TasksIslandViewModel` — no VM changes; existing VM tests remain valid.