Files
ClaudeDo/docs/superpowers/plans/2026-06-04-plan-day-in-log-window.md
2026-06-04 10:02:29 +02:00

6.6 KiB

Move "Plan day" into the Prep-Log Window — Plan

For agentic workers: REQUIRED SUB-SKILL: superpowers:subagent-driven-development. Steps use - [ ].

Goal: Guard daily-prep planning behind a second click. The MyDay header's full-width "Tag vorbereiten" button is removed; instead the user opens the prep-log window (list icon), sees the last run or an empty-state hint, and clicks a "Plan day" button inside that window to run the prep.

Approved flow: Header list-icon (ShowPrepLogCommand) opens the prep window → if empty, an empty-state hint shows → "Plan day" button in the window runs RunDailyPrepNowAsync().

Tech: Avalonia + CommunityToolkit.Mvvm, xUnit.

Build/test

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 not headlessly verifiable — note it; human verifies visuals.


Task: relocate planning trigger + empty-state

Files:

  • Modify: src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs (remove PrepareDay)

  • Modify: src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml (remove header button)

  • Modify: src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs (PlanDayCommand + empty-state)

  • Modify: src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml (prep panel toolbar + empty hint)

  • Modify: src/ClaudeDo.Localization/locales/en.json, de.json

  • Test: tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandPrepModeTests.cs, and the existing TasksIslandDailyPrepTests.cs (remove the obsolete prepare test)

  • Step 1: Write/adjust tests first.

    • In DetailsIslandPrepModeTests.cs add:
      [Fact]
      public async Task PlanDayCommand_calls_worker()
      {
          var stub = new StubWorkerClient();
          var vm = NewDetailsVm(stub);
          await vm.PlanDayCommand.ExecuteAsync(null);
          Assert.Equal(1, stub.RunDailyPrepNowCalls);
      }
      
      [Fact]
      public void ShowPrepEmptyState_true_when_empty_and_not_running()
      {
          var vm = NewDetailsVm(new StubWorkerClient());
          Assert.True(vm.ShowPrepEmptyState);
      }
      
      StubWorkerClient needs a RunDailyPrepNowCalls counter incremented in RunDailyPrepNowAsync (add if missing; it currently likely returns Task.FromResult(true) — keep that and bump a counter).
    • In TasksIslandDailyPrepTests.cs remove PrepareDayCommand_raises_PrepRequested (the command is being deleted). Keep ClearDayCommand_calls_worker.
  • Step 2: Run — expect FAIL/compile error.

  • Step 3: TasksIslandViewModel — remove planning trigger.

    • Delete the PrepareDayAsync [RelayCommand] entirely.
    • Keep the PrepRequested event and ShowPrepLog command (the list icon still raises PrepRequested to open the window).
    • Grep the VM for any remaining PrepareDay references and remove them.
  • Step 4: TasksIslandView.axaml — remove the header button. Delete the full-width "Prepare day" <Button … Command="{Binding PrepareDayCommand}" …>. Leave the Notes pinned-row button, and the header icon buttons (broom = ClearDay, list = ShowPrepLog) untouched.

  • Step 5: DetailsIslandViewModel — add PlanDayCommand + empty-state.

    • Add:
      [RelayCommand]
      private async Task PlanDayAsync()
      {
          if (_worker is null) return;
          try { await _worker.RunDailyPrepNowAsync(); }
          catch { /* worker offline; PrepStarted/PrepLine will reconcile */ }
      }
      
      public bool ShowPrepEmptyState => !IsPrepRunning && PrepLog.Count == 0;
      
    • Notify ShowPrepEmptyState: in the constructor add PrepLog.CollectionChanged += (_, _) => OnPropertyChanged(nameof(ShowPrepEmptyState));, and add partial void OnIsPrepRunningChanged(bool value) => OnPropertyChanged(nameof(ShowPrepEmptyState));.
  • Step 6: DetailsIslandView.axaml — prep panel toolbar + empty hint. In the <Panel IsVisible="{Binding IsPrepMode}">, wrap the existing SessionTerminalView in a DockPanel; dock a top toolbar row with the Plan-day button, and overlay/stack an empty-state hint:

    <Panel IsVisible="{Binding IsPrepMode}">
      <DockPanel>
        <Border DockPanel.Dock="Top" Padding="12,8">
          <Button Classes="btn primary"
                  Command="{Binding PlanDayCommand}"
                  IsEnabled="{Binding !IsPrepRunning}"
                  Content="{loc:Tr details.planDay}"/>
        </Border>
        <Panel>
          <islands:SessionTerminalView
              Entries="{Binding PrepLog}" Label="daily-prep"
              IsRunning="{Binding IsPrepRunning}"/>
          <TextBlock IsVisible="{Binding ShowPrepEmptyState}"
                     HorizontalAlignment="Center" VerticalAlignment="Center"
                     Foreground="{DynamicResource TextMuteBrush}"
                     Text="{loc:Tr details.prepEmpty}"/>
        </Panel>
      </DockPanel>
    </Panel>
    

    (Match the surrounding view's class names/brushes; use the existing button class style seen elsewhere, e.g. Classes="btn" — verify primary exists, else plain btn.)

  • Step 7: Locales. Add details.planDay (en "Plan day", de "Tag planen") and details.prepEmpty (en "No prep run today yet — click Plan day", de "Heute noch keine Vorbereitung — klick Tag planen") to both json files. Remove the now-unused tasks.prepareDay key from both (grep first to confirm no other reference). Keep en/de key parity.

  • Step 8: Build + tests.

    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 9: Manual smoke (human): on MyDay there is no "Tag vorbereiten" button; the list icon opens the prep window showing the empty hint; "Plan day" runs the prep and streams; the hint disappears while running; after restart the persisted last run shows and "Plan day" is available to re-run.

  • Step 10: Commit:

    git commit -m "feat(daily-prep): trigger planning from inside the prep-log window with an empty-state hint"
    

Notes / risks

  • PrepRequested and ShowPrepLogCommand stay — only PrepareDayCommand and its header button are removed.
  • ShowPrepEmptyState must re-notify on both PrepLog changes and IsPrepRunning changes, else the hint won't hide when a run starts or lines arrive.
  • Removing tasks.prepareDay: confirm via grep it has no remaining references before deleting (keep locale parity or the Localization.Tests parity check fails).