diff --git a/src/ClaudeDo.Localization/locales/de.json b/src/ClaudeDo.Localization/locales/de.json
index eb13706..8a23529 100644
--- a/src/ClaudeDo.Localization/locales/de.json
+++ b/src/ClaudeDo.Localization/locales/de.json
@@ -66,7 +66,6 @@
"addPlaceholder": "Aufgabe hinzufügen…",
"enterKey": "ENTER",
"notesPinnedRow": "Notizen (Tagesnotizen)",
- "prepareDay": "Tag vorbereiten",
"clearDayTip": "Tag leeren",
"prepLogTip": "Vorbereitungs-Log",
"overdue": "ÜBERFÄLLIG",
@@ -140,7 +139,9 @@
"previewBtn": "Vorschau",
"editBtn": "Bearbeiten",
"descriptionPlaceholder": "Aufgabendetails hinzufügen (Markdown unterstützt)...",
- "prepTitle": "Tagesvorbereitung"
+ "prepTitle": "Tagesvorbereitung",
+ "planDay": "Tag planen",
+ "prepEmpty": "Heute noch keine Vorbereitung — klick Tag planen"
},
"agent": {
"stopTip": "Agent stoppen",
diff --git a/src/ClaudeDo.Localization/locales/en.json b/src/ClaudeDo.Localization/locales/en.json
index b4ee915..e25721b 100644
--- a/src/ClaudeDo.Localization/locales/en.json
+++ b/src/ClaudeDo.Localization/locales/en.json
@@ -66,7 +66,6 @@
"addPlaceholder": "Add a task…",
"enterKey": "ENTER",
"notesPinnedRow": "Notes (daily notes)",
- "prepareDay": "Prepare day",
"clearDayTip": "Clear day",
"prepLogTip": "Prep log",
"overdue": "OVERDUE",
@@ -140,7 +139,9 @@
"previewBtn": "Preview",
"editBtn": "Edit",
"descriptionPlaceholder": "Add task details (markdown supported)...",
- "prepTitle": "Daily prep"
+ "prepTitle": "Daily prep",
+ "planDay": "Plan day",
+ "prepEmpty": "No prep run today yet — click Plan day"
},
"agent": {
"stopTip": "Stop agent",
diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs
index 5360151..e4335d1 100644
--- a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs
+++ b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs
@@ -346,6 +346,8 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
RecomputeCanMergeAll();
ReviewCombinedDiffCommand.NotifyCanExecuteChanged();
};
+
+ PrepLog.CollectionChanged += (_, _) => OnPropertyChanged(nameof(ShowPrepEmptyState));
}
private void OnTaskMessage(string taskId, string line)
@@ -381,6 +383,18 @@ public sealed partial class DetailsIslandViewModel : ViewModelBase
AppendClaudeText(formatted, target, buf);
}
+ [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;
+
+ partial void OnIsPrepRunningChanged(bool value) => OnPropertyChanged(nameof(ShowPrepEmptyState));
+
private void OnPrepStarted()
{
PrepLog.Clear();
diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs
index 31e86da..0875488 100644
--- a/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs
+++ b/src/ClaudeDo.Ui/ViewModels/Islands/TasksIslandViewModel.cs
@@ -37,15 +37,6 @@ public sealed partial class TasksIslandViewModel : ViewModelBase
NotesRequested?.Invoke();
}
- [RelayCommand]
- private async Task PrepareDayAsync()
- {
- if (_worker is null) return;
- PrepRequested?.Invoke();
- try { await _worker.RunDailyPrepNowAsync(); }
- catch { /* worker offline; broadcast will reconcile on return */ }
- }
-
[RelayCommand]
private void ShowPrepLog() => PrepRequested?.Invoke();
diff --git a/src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml b/src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml
index d17c4e2..1a92704 100644
--- a/src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml
+++ b/src/ClaudeDo.Ui/Views/Islands/DetailsIslandView.axaml
@@ -303,9 +303,23 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml b/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml
index ff48fb8..2470c47 100644
--- a/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml
+++ b/src/ClaudeDo.Ui/Views/Islands/TasksIslandView.axaml
@@ -79,14 +79,6 @@
Command="{Binding OpenNotesCommand}"
Content="{loc:Tr tasks.notesPinnedRow}"/>
-
-
-
diff --git a/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs b/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs
index 47384cb..6231ee0 100644
--- a/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs
+++ b/tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs
@@ -33,6 +33,7 @@ public abstract class StubWorkerClient : IWorkerClient
#pragma warning restore CS0067
public int ClearMyDayCalls { get; private set; }
+ public int RunDailyPrepNowCalls { get; private set; }
public void RaisePrepStarted() => PrepStartedEvent?.Invoke();
public void RaisePrepLine(string line) => PrepLineEvent?.Invoke(line);
@@ -71,7 +72,7 @@ public abstract class StubWorkerClient : IWorkerClient
public virtual Task QueuePlanningSubtasksAsync(string parentTaskId, CancellationToken ct = default) => Task.CompletedTask;
public virtual Task GetWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult(null);
public virtual Task GenerateWeekReportAsync(DateOnly start, DateOnly end) => Task.FromResult("");
- public virtual Task RunDailyPrepNowAsync() => Task.FromResult(false);
+ public virtual Task RunDailyPrepNowAsync() { RunDailyPrepNowCalls++; return Task.FromResult(false); }
public virtual Task ClearMyDayAsync() { ClearMyDayCalls++; return Task.CompletedTask; }
public virtual Task GetAppSettingsAsync() => Task.FromResult(null);
public virtual Task> GetDailyNotesAsync(DateOnly day) => Task.FromResult(new List());
diff --git a/tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandPrepModeTests.cs b/tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandPrepModeTests.cs
index 19e15cf..487ae1d 100644
--- a/tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandPrepModeTests.cs
+++ b/tests/ClaudeDo.Ui.Tests/ViewModels/DetailsIslandPrepModeTests.cs
@@ -92,4 +92,20 @@ public class DetailsIslandPrepModeTests : IDisposable
Assert.NotEmpty(vm.PrepLog);
}
+
+ [Fact]
+ public async Task PlanDayCommand_calls_worker()
+ {
+ var stub = new DefaultStub();
+ 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 DefaultStub());
+ Assert.True(vm.ShowPrepEmptyState);
+ }
}
diff --git a/tests/ClaudeDo.Ui.Tests/ViewModels/TasksIslandDailyPrepTests.cs b/tests/ClaudeDo.Ui.Tests/ViewModels/TasksIslandDailyPrepTests.cs
index f212be6..b7edb17 100644
--- a/tests/ClaudeDo.Ui.Tests/ViewModels/TasksIslandDailyPrepTests.cs
+++ b/tests/ClaudeDo.Ui.Tests/ViewModels/TasksIslandDailyPrepTests.cs
@@ -53,15 +53,4 @@ public class TasksIslandDailyPrepTests : IDisposable
Assert.Equal(1, stub.ClearMyDayCalls);
}
- [Fact]
- public async Task PrepareDayCommand_raises_PrepRequested()
- {
- var vm = NewTasksVm(new DefaultStub());
- var raised = false;
- vm.PrepRequested += () => raised = true;
-
- await vm.PrepareDayCommand.ExecuteAsync(null);
-
- Assert.True(raised);
- }
}