# 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
<!-- Icon.Sort (filled bars, decreasing width) -->
<StreamGeometry x:Key="Icon.Sort">M4 6 H20 V8 H4 Z M4 11 H16 V13 H4 Z M4 16 H11 V18 H4 Z</StreamGeometry>

<!-- Icon.Broom (filled: handle + binding band + flared bristles) -->
<StreamGeometry x:Key="Icon.Broom">M11 3 H13 V10 H11 Z M8.5 10 H15.5 V12 H8.5 Z M9 12 H15 L17 21 H7 Z</StreamGeometry>

<!-- Icon.List (filled: square bullets + lines) -->
<StreamGeometry x:Key="Icon.List">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</StreamGeometry>
```

- [ ] **Step 2: Add StyledProperties to `SessionTerminalView`** (code-behind `SessionTerminalView.axaml.cs`). Add public StyledProperties and CLR wrappers:

```csharp
public static readonly StyledProperty<System.Collections.IEnumerable?> EntriesProperty =
    AvaloniaProperty.Register<SessionTerminalView, System.Collections.IEnumerable?>(nameof(Entries));
public static readonly StyledProperty<string?> LabelProperty =
    AvaloniaProperty.Register<SessionTerminalView, string?>(nameof(Label));
public static readonly StyledProperty<bool> IsRunningProperty =
    AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(IsRunning));
public static readonly StyledProperty<bool> IsDoneProperty =
    AvaloniaProperty.Register<SessionTerminalView, bool>(nameof(IsDone));
public static readonly StyledProperty<bool> IsFailedProperty =
    AvaloniaProperty.Register<SessionTerminalView, bool>(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 `<islands:SessionTerminalView MaxHeight="420"/>`):
    ```xml
    <islands:SessionTerminalView MaxHeight="420"
        Entries="{Binding Log}"
        Label="{Binding BranchLine, StringFormat='claude-session · {0}'}"
        IsRunning="{Binding IsRunning}" IsDone="{Binding IsDone}" IsFailed="{Binding IsFailed}"/>
    ```
    (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
    <islands:SessionTerminalView
        Entries="{Binding PrepLog}" Label="daily-prep"
        IsRunning="{Binding IsPrepRunning}"/>
    ```
    Keep the panel wrapper `<Panel IsVisible="{Binding IsPrepMode}">`. 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
<Button Classes="icon-btn" IsVisible="{Binding IsMyDayList}"
        Command="{Binding ClearDayCommand}" ToolTip.Tip="{loc:Tr tasks.clearDayTip}">
  <PathIcon Width="15" Height="15" Data="{StaticResource Icon.Broom}"/>
</Button>
<Button Classes="icon-btn" IsVisible="{Binding IsMyDayList}"
        Command="{Binding ShowPrepLogCommand}" ToolTip.Tip="{loc:Tr tasks.prepLogTip}">
  <PathIcon Width="15" Height="15" Data="{StaticResource Icon.List}"/>
</Button>
```

- [ ] **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.
