docs(plans): grobe Task-Entwürfe je Gruppe und Test-Kommandos ergänzen
This commit is contained in:
@@ -60,6 +60,17 @@ Gilt für alle vier Gruppen:
|
||||
dotnet build src/ClaudeDo.App/ClaudeDo.App.csproj -c Release
|
||||
dotnet build src/ClaudeDo.Worker/ClaudeDo.Worker.csproj -c Release
|
||||
```
|
||||
- **Testen — pro Gruppe die relevanten Projekte:**
|
||||
```
|
||||
A, B dotnet test tests/ClaudeDo.Ui.Tests/ClaudeDo.Ui.Tests.csproj -c Release
|
||||
dotnet test tests/ClaudeDo.Localization.Tests/... -c Release (nur wenn Keys berührt)
|
||||
C Ui.Tests + ClaudeDo.Worker.Tests (Worker.Tests enthält auch UiVm-Tests)
|
||||
D dotnet test tests/ClaudeDo.Worker.Tests/ClaudeDo.Worker.Tests.csproj -c Release
|
||||
P0 Ui.Tests + Localization.Tests
|
||||
```
|
||||
Fällt ein Test innerhalb der Verify-Kette, erst die Suite **allein** laufen lassen — die
|
||||
`Ui.Tests` haben eine bekannte reihenfolgen-abhängige Flakiness, die nichts mit dem Merge zu
|
||||
tun hat.
|
||||
- **Nie `git add -A`.** Immer explizit nach Pfad stagen und `git commit -- <pfade>` — der
|
||||
`main`-Checkout ist von parallelen Sessions geteilt, ein blankes Commit fegt fremde WIP mit.
|
||||
- **Nach dem Batch-Merge `main` selbst prüfen.** Approve baut und testet nicht. Neun grüne
|
||||
@@ -152,6 +163,28 @@ Prozess startet, oder O(n) über unbegrenzt viele DB-Zeilen läuft. Einzelzeilen
|
||||
Label und setzt die Stall-Uhr zurück. `Localization.Tests` grün. Kein VM ist umgestellt — P0
|
||||
liefert nur das Werkzeug.
|
||||
|
||||
### Task-Entwürfe (grob)
|
||||
|
||||
**P0-1 · `OperationStatus` + `OperationIndicator` + `ops`-Locale-Keys**
|
||||
Baue das Primitive nach dem Vertrag oben, dazu das Anzeige-Control und den neuen
|
||||
Locale-Namespace `ops` in beiden Sprachdateien. Keys für Gruppe A und C vorab anlegen, für D
|
||||
keine. Zeitquelle über `TimeProvider`, kein statischer Timer.
|
||||
*Dateien:* `Ui/Services/OperationStatus.cs` (neu), `Ui/Views/Controls/OperationIndicator.axaml(.cs)` (neu), `Localization/locales/{en,de}.json`, `tests/ClaudeDo.Ui.Tests/`
|
||||
*Fertig wenn:* Unit-Tests für Grace, Stall-ab-Report, Elapsed, Dispose-nach-Exception, Report-Reset. Localization.Tests grün. Kein ViewModel angefasst.
|
||||
|
||||
**P0-2 · Timing-Hook für die Messung**
|
||||
Zwei Hooks: Dauer jedes Hub-Invokes in `WorkerClient`, Dauer des DB-Pfads der Islands. Ziel
|
||||
sind auswertbare Zahlen, keine Anzeige. Ausgabe so, dass sie nach einem Tag Nutzung sortierbar
|
||||
ist.
|
||||
*Dateien:* `Ui/Services/WorkerClient.cs`, der gemeinsame DB-Zugriffspfad der Island-VMs
|
||||
*Fertig wenn:* Beide Hooks aktiv, Overhead vernachlässigbar, das Format ist dokumentiert.
|
||||
|
||||
**P0-3 · Feedback-Regel in den CLAUDE.md-Dateien**
|
||||
`src/ClaudeDo.Ui/CLAUDE.md`: jeder `IWorkerClient`-Call in einem `[RelayCommand]` läuft durch
|
||||
eine `OperationStatus`, Anzeige über `OperationIndicator`. `src/ClaudeDo.Worker/CLAUDE.md`: ein
|
||||
MCP-Tool, das über ~5 s laufen kann, reportet Progress.
|
||||
*Fertig wenn:* Beide Regeln stehen, jeweils mit einem Satz Begründung.
|
||||
|
||||
---
|
||||
|
||||
## Gruppe A — Bild 1: UI-Stille
|
||||
@@ -201,6 +234,42 @@ Zustand nach einer Exception zurückgesetzt — als Test in `ClaudeDo.Ui.Tests`.
|
||||
handgebauter Spinner, immer `OperationIndicator`. **Visuelle Prüfung offen und explizit
|
||||
benannt** (Grace-Periode und Layout kann kein Test bestätigen).
|
||||
|
||||
### Task-Entwürfe (grob)
|
||||
|
||||
**A1 · Detail-Pane: Approve, Submit, Reject, Park, Preview** ⚠️ *der gemeldete Fall*
|
||||
Fünf Commands im Detail-Pane bekommen je eine `OperationStatus` und einen `OperationIndicator`
|
||||
neben dem auslösenden Button. Approve abonniert zusätzlich `MergeProgressEvent` **nur für die
|
||||
Dauer des Calls** und filtert auf die eigene TaskId, um das Label von „merging" auf „verifying"
|
||||
zu schärfen. `DetailsIslandViewModel` nicht umstrukturieren.
|
||||
*Dateien:* `Ui/ViewModels/Islands/DetailsIslandViewModel.cs`, `MergeSectionViewModel.cs`, `Ui/Views/Islands/Detail/*`
|
||||
*Fertig wenn:* Approve zeigt während des Verify-Gates Phase und Elapsed, Button ist gesperrt, Zustand nach Fehler zurückgesetzt. Visuelle Prüfung offen.
|
||||
|
||||
**A2 · WorktreesOverview: Anzeige für alle fünf Aktionen**
|
||||
`IsBusy` existiert, schaltet aber nur `IsEnabled`. Getrennte `OperationStatus` für Refresh,
|
||||
Cleanup, Reset, ForceRemove und Batch-Merge — der Batch-Merge zusätzlich mit Zeilen-Status, weil
|
||||
er N Tasks sequenziell durchläuft.
|
||||
*Dateien:* `Ui/ViewModels/Modals/WorktreesOverviewModalViewModel.cs`, `Ui/Views/Modals/WorktreesOverviewModalView.axaml`
|
||||
*Fertig wenn:* Jede der fünf Aktionen zeigt sichtbar, dass sie läuft; ein laufender Refresh blockiert die Cleanup-Anzeige nicht. Visuelle Prüfung offen.
|
||||
|
||||
**A3 · Settings-Tabs: Skill-Install, Restore-Defaults, OnlineInbox, RepoImport, Update-Check**
|
||||
Fünf Flächen, bei denen `IsBusy` heute nur den Button sperrt. Der Skill-Install ist ein
|
||||
`git clone` und der offensichtlichste Kandidat.
|
||||
*Dateien:* `Ui/ViewModels/Modals/Settings/*`, `Ui/ViewModels/Modals/RepoImportModalViewModel.cs`, `Ui/Services/UpdateCheckService.cs`, `Ui/Views/Modals/SettingsModalView.axaml`
|
||||
*Fertig wenn:* Alle fünf zeigen Aktivität; der Skill-Install zeigt zusätzlich, dass geklont wird. Visuelle Prüfung offen.
|
||||
|
||||
**A4 · Reports und Planning-UI**
|
||||
GenerateWeekReport, RunDailyPrepNow, BuildPlanningIntegrationBranch, GetPlanningAggregate,
|
||||
Finalize/QueuePlanningSubtasks. `DiffViewerViewModel.IsLoadingCombined` existiert bereits und
|
||||
bleibt unangetastet.
|
||||
*Dateien:* `Ui/ViewModels/Modals/WeeklyReportModalViewModel.cs`, Planning-Pfade in `DetailsIslandViewModel`/`TasksIslandViewModel`, zugehörige AXAML
|
||||
*Fertig wenn:* Report-Generierung und Planning-Integration zeigen Aktivität; kein Doppel-Indikator im Combined-Diff. Visuelle Prüfung offen.
|
||||
|
||||
**A5 · Island-DB-Pfade nach Messdaten**
|
||||
**Erst die Zahlen aus P0-2 auswerten**, dann nur die Ausreißer umstellen. Kandidaten:
|
||||
`ClearCompleted`, Drag-Reorder über viele Zeilen, Laden großer Listen. Nichts auf Verdacht.
|
||||
*Dateien:* nach Messergebnis
|
||||
*Fertig wenn:* Die Auswertung ist im Task dokumentiert, und jede umgestellte Stelle ist durch eine Messung begründet. Wenn nichts über der Schwelle liegt: Task mit Begründung schließen, nichts bauen.
|
||||
|
||||
---
|
||||
|
||||
## Gruppe B — Bild 2: UI-Freeze
|
||||
@@ -235,6 +304,31 @@ B3 ist der einzige Test im Vorhaben, der Blockade prüft: großes Diff-Fixture,
|
||||
der Dispatcher weiter Nachrichten verarbeitet. Visuelle Prüfung offen (Verhalten bei großem
|
||||
Diff, Indikator während des Parsens).
|
||||
|
||||
### Task-Entwürfe (grob)
|
||||
|
||||
**B1 · `UnifiedDiffParser.Parse` vom UI-Thread nehmen**
|
||||
Beide Aufrufstellen im `DiffViewerViewModel` nach `Task.Run` verschieben, danach den
|
||||
`OperationIndicator` setzen. Reihenfolge ist zwingend: erst auslagern, dann anzeigen — ein
|
||||
Spinner auf einem blockierten Dispatcher wird nicht gezeichnet. Das Zurückschreiben in
|
||||
Observable-Collections muss auf dem UI-Thread passieren.
|
||||
*Dateien:* `Ui/ViewModels/Modals/DiffViewerViewModel.cs`
|
||||
*Fertig wenn:* Kein synchroner Parse mehr im VM, Indikator während des Parsens sichtbar. Visuelle Prüfung mit einem großen Diff offen.
|
||||
|
||||
**B2 · `DiffAlignment.Build` — Grenze gegen unbegrenzte Synchron-Arbeit**
|
||||
`Build` läuft in einem Control, nicht in einem VM. Der ausführende Agent entscheidet zwischen
|
||||
Auslagern ab einer Zeilenzahl und inkrementellem Aufbau — die Vorgabe ist nur: **eine
|
||||
sichtbare, begründete Grenze**. AvaloniaEdit-Fallen aus dem Vorgaben-Abschnitt beachten
|
||||
(`TryGetResource` scheitert lautlos, `ScrollToVerticalOffset` ist ein No-op).
|
||||
*Dateien:* `Ui/Views/Controls/DiffTextView.axaml.cs`, gemeinsames Boilerplate nach `DiffEditorSetup.cs`
|
||||
*Fertig wenn:* Die gewählte Grenze ist im Code kommentiert und begründet; große Diffs blockieren nicht mehr unbegrenzt. Visuelle Prüfung offen.
|
||||
|
||||
**B3 · Guard-Test: großer Diff blockiert den Dispatcher nicht**
|
||||
Headless-Test mit großem Diff-Fixture, der nachweist, dass der Dispatcher während Parse und
|
||||
Build weiter Nachrichten verarbeitet. Der einzige Blockade-Test im Vorhaben — soll auch
|
||||
zukünftige Regressionen fangen.
|
||||
*Dateien:* `tests/ClaudeDo.Ui.Tests/`, Fixture im Testprojekt
|
||||
*Fertig wenn:* Der Test fällt gegen den Stand **vor** B1/B2 und ist danach grün.
|
||||
|
||||
---
|
||||
|
||||
## Gruppe C — Bild 3: Worker-Stille
|
||||
@@ -284,6 +378,42 @@ Progress-Callbacks in `ClaudeDo.Worker.Tests` mit einem Fake gezählt — keine
|
||||
keine echte CLI. UI-Seite: die Anzeige beim Worker-Start ersetzt „reconnecting" durch die
|
||||
laufende Recovery-Phase. Visuelle Prüfung offen.
|
||||
|
||||
### Task-Entwürfe (grob)
|
||||
|
||||
**C1 · Generischer `OperationProgress`-Kanal, `MergeProgress` darauf umstellen**
|
||||
Neues Hub-Event `OperationProgress(opKey, phase, current, total)`, ohne Elapsed auf der Leitung.
|
||||
Der Merge-Pfad sendet darüber. **`MergeProgressEvent` bleibt als vierzeiliger Forwarder** —
|
||||
Gruppe A hängt daran und darf nicht angefasst werden. Fakes in beiden Testprojekten mitziehen.
|
||||
*Dateien:* `Worker/Hub/HubBroadcaster.cs`, `Worker/Hub/WorkerHub.cs`, `Ui/Services/WorkerClient.cs`, `IWorkerClient.cs`, `tests/ClaudeDo.Ui.Tests/StubWorkerClient.cs`, UiVm-Fakes in `Worker.Tests`
|
||||
*Fertig wenn:* Merge-Phasen laufen über den neuen Kanal, das UI tickt Elapsed lokal, `MergeProgressEvent` funktioniert unverändert weiter, beide Testprojekte grün.
|
||||
|
||||
**C2 · Worker-Startup-Recovery sichtbar machen**
|
||||
Die sechs Recovery-Services beim Worker-Start melden Phase und `i/n` über den Kanal
|
||||
(`opKey = "startup-recovery"`). Das UI ersetzt „reconnecting" durch die laufende Phase.
|
||||
*Dateien:* `Worker/Lifecycle/*Recovery.cs`, Anzeige im `IslandsShellViewModel`-Umfeld
|
||||
*Fertig wenn:* Beim Worker-Start ist sichtbar, welche Recovery läuft. Visuelle Prüfung offen.
|
||||
|
||||
**C3 · Worktree-Anlage beim Task-Start sichtbar machen**
|
||||
**Zuerst prüfen**, ob der im 08-07-Spec gemeldete Broadcast-Gap in `WorktreeManager` inzwischen
|
||||
geschlossen ist — nicht doppelt beheben. Danach die stille Lücke zwischen `Queued` und erster
|
||||
Ausgabe an der Task-Zeile sichtbar machen.
|
||||
*Dateien:* `Worker/Runner/WorktreeManager.cs`, Task-Row-Anzeige
|
||||
*Fertig wenn:* Das Prüfergebnis steht im Task; die Anlage-Phase ist an der Zeile sichtbar. Visuelle Prüfung offen.
|
||||
|
||||
**C4 · Rebase-after-Merge und WorktreeMaintenance in den Kanal**
|
||||
`RebaseOthersAfterMergeAsync` läuft heute innerhalb des Merge-Calls **nach** dem
|
||||
Phasen-Broadcast und ist damit vollständig unsichtbar. Dazu der Hintergrunddienst über alle
|
||||
Worktrees, mit `i/n`.
|
||||
*Dateien:* `Worker/Lifecycle/TaskMergeService.cs` (Rebase-Abschnitt), `Worker/Worktrees/WorktreeMaintenanceService.cs`
|
||||
*Fertig wenn:* Beide melden Fortschritt; ein Merge zeigt nach dem Verify-Gate die Rebase-Phase statt Stille.
|
||||
|
||||
**C5 · Periodische Dienste — optional, Abbruch erlaubt**
|
||||
Usage, OnlineSync, Prime, Queue sollen **nur Aktivität und Fehler** melden, keinen Tick-Strom.
|
||||
Der wackeligste Punkt im Design: kommt der ausführende Agent zum Schluss, dass das nur
|
||||
Anzeige-Rauschen erzeugt, **weglassen und begründen** statt durchziehen.
|
||||
*Dateien:* `Worker/Usage/`, `Worker/Online/`, `Worker/Prime/`, `Worker/Queue/`
|
||||
*Fertig wenn:* Entweder sparsame Meldungen ohne Rauschen — oder eine begründete Absage im Task.
|
||||
|
||||
---
|
||||
|
||||
## Gruppe D — Bild 4: MCP-Stille
|
||||
@@ -321,6 +451,37 @@ Für jedes umgestellte Tool ein Test in `ClaudeDo.Worker.Tests`, der mit einem F
|
||||
zählt, dass Meldungen kommen — bei `batch_*` mindestens eine pro Element. Keine visuelle
|
||||
Prüfung nötig, diese Gruppe hat keine UI.
|
||||
|
||||
### Task-Entwürfe (grob)
|
||||
|
||||
**D1 · `ProgressReporter` extrahieren**
|
||||
`TaskMergeService.RunReportingProgressAsync` als eigenständige Klasse herauslösen, plus einen
|
||||
Overload für Element-Fortschritt (`i/n`). **Extrahieren, nicht kopieren** — es soll eine
|
||||
Implementierung bleiben. Dies ist die einzige Datei, die D mit C teilt; nur die Progress-Schleife
|
||||
anfassen.
|
||||
*Dateien:* `Worker/Lifecycle/TaskMergeService.cs`, neue Klasse im Worker-Projekt
|
||||
*Fertig wenn:* Der Merge-Pfad nutzt die extrahierte Klasse, Verhalten unverändert, bestehende Merge-Tests grün.
|
||||
|
||||
**D2 · Die acht `batch_*`-Tools mit Element-Fortschritt**
|
||||
Jedes `batch_*`-Tool reportet pro verarbeitetem Element. Grund: ohne Meldung bricht der
|
||||
MCP-Client nach 300 s Stille ab, während der Worker weiterläuft — genau der Mechanismus, der
|
||||
einen Merge durchlaufen lässt, den Task aber nie auf `Done` bringt.
|
||||
*Dateien:* `Worker/External/BatchMcpTools.cs`
|
||||
*Fertig wenn:* Pro Tool ein Test mit Fake-`IProgress`, der mindestens eine Meldung je Element zählt. Englische Klartext-Strings, keine Locale-Keys.
|
||||
|
||||
**D3 · Worktree- und Diff-Tools mit Progress**
|
||||
`cleanup_task_worktree`, `batch_cleanup_task_worktrees`, `get_task_diff`, `preview_merge_set`.
|
||||
Bereits versorgt und **nicht** anzufassen: die fünf Tools mit `IProgress` in
|
||||
`ExternalMcpService`, `TaskWaitMcpTools`, `merge_task`, `review_task`.
|
||||
*Dateien:* die betroffenen `Worker/External/*McpTools.cs`, `ExternalMcpService.cs`
|
||||
*Fertig wenn:* Jedes der vier Tools meldet Fortschritt, mit Test.
|
||||
|
||||
**D4 · Restliche Long-Runner und die Regel im Worker-`CLAUDE.md`**
|
||||
Verbleibende Tools durchgehen, die über ~5 s laufen können, und die Regel festschreiben: ein
|
||||
MCP-Tool über ~5 s reportet Progress. Ohne die Regel wiederholt sich das Muster beim nächsten
|
||||
Tool.
|
||||
*Dateien:* restliche `Worker/External/*McpTools.cs`, `src/ClaudeDo.Worker/CLAUDE.md`
|
||||
*Fertig wenn:* Die Regel steht mit Begründung; die durchgegangenen Tools sind im Task aufgelistet — auch die, die bewusst nichts bekommen.
|
||||
|
||||
---
|
||||
|
||||
## Was nach allen vier Gruppen offen bleibt
|
||||
|
||||
Reference in New Issue
Block a user