Commit Graph
538 Commits
Author SHA1 Message Date
mika kunsandClaude Sonnet 5.5 2dbec543df feat(mission-control): show running Worker operations in a Running now section
Registry of active verify/merge/rebase/worktree-creation operations in the Worker,
GetActiveOperations snapshot + OperationStarted/OperationEnded hub events, and a
Running now section in Mission Control with ticking elapsed time.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 12:08:43 +02:00
mika kuns 488c28a9d5 fix(claude-do): merge Prevent dragging completed tasks in the task list
ClaudeDo-Task: 855b766589bf42bc872f03bdbfb9abd5
2026-10-01 11:52:30 +02:00
mika kunsandClaude Sonnet 5.5 b776fd28d8 fix(ui): prevent dragging completed tasks in the task list
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 11:44:17 +02:00
mika kunsandClaude Sonnet 5.5 f66cbca65d feat(ui): show task number in Mission Control activity strip
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 11:43:50 +02:00
mika kuns 07e9f8d60e chore(claude-do): merge Unit-Branch Teil 1: Branch-Naming + Basis-Branch pro Liste
ClaudeDo-Task: e202e601-64c0-4ecb-8dc9-2fb0da01a84a
2026-10-01 11:03:02 +02:00
mika kuns ae845bf06b feat(ui): base branch field in list settings, real branch names in dialogs 2026-10-01 10:48:32 +02:00
mika kuns 0e4de9e4c0 feat(claude-do): merge Selectable colors for list dots and folders: accent-aware pa
ClaudeDo-Task: 98844480cc1f4e748908d2ce8ac6c50b
2026-10-01 10:30:48 +02:00
mika kuns a6926f53b5 feat(lists): selectable list/folder colors with accent-aware swatches and custom picker 2026-10-01 10:29:53 +02:00
mika kunsandClaude Sonnet 5.5 cf3db9197c fix(ui): deliver AltGr characters to ConPTY tiles as text
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 10:24:05 +02:00
mika kuns 97af85c816 feat(mission-control): swap tiles by dragging their header 2026-10-01 09:07:02 +02:00
mika kuns e35b054a2e feat(ui): tickets + plan day button, fallback list and prime action 2026-10-01 08:44:21 +02:00
Mika Kuns a7c3d18533 feat(mission-control): column picker for the overview grid
Auto keeps the pane-count heuristic; 1-4 fixes the column count (capped at
the pane count). Persisted to ui.config.json as MissionControlColumns.
2026-09-30 10:39:23 +02:00
mika kuns 0d029717f8 style(ui): folder chevron and icon take the folder colour 2026-09-30 10:28:14 +02:00
mika kuns 2be8ba5d66 feat(ui): folders slide open and closed, rows below follow 2026-09-30 10:25:17 +02:00
mika kuns 928e3905d9 feat(ui): animate folder expand in the sidebar 2026-09-30 10:19:35 +02:00
mika kuns 60358100be fix(ui): Recent-Sessions Resume/Brief-Buttons fuehren ihren Command wieder aus
Der Click-Handler schloss das Flyout synchron; Button liest Command erst nach dem ClickEvent, das Hide hatte die Bindung da schon geloest.
2026-09-30 10:14:55 +02:00
mika kuns bb92dc279f feat(lists): assign a colour to a sidebar folder
Tints the folder name and its guide line; picked from a swatch row in the folder settings.
2026-09-30 10:12:41 +02:00
mika kuns f2ff865dca feat(ui): searchable Material Design icon library for lists and folders 2026-09-30 09:52:34 +02:00
mika kuns 5da8036b9a style(ui): only top-level lists align to the folder chevron 2026-09-30 08:48:36 +02:00
mika kuns cf4b5c507c style(ui): lists start at the folder chevron's edge 2026-09-30 08:43:10 +02:00
mika kuns 3e2d5bab6a style(ui): keep child row highlight clear of the folder guide line 2026-09-30 08:39:20 +02:00
mika kuns ccd11a8033 style(ui): tighter sidebar tree rows and shallower child indent 2026-09-30 08:34:48 +02:00
mika kuns 9991f1fc1f feat(ui): coloured dots for icon-less lists, guide line under chevron
Lists without an icon show a dot in a stable identity colour (same
palette/hash as Mission Control tiles); "Dot" is the new picker default.
2026-09-30 08:29:46 +02:00
mika kuns 75b78cb2c0 feat(ui): make sidebar folder hierarchy readable
Lists default to the Text icon instead of the folder icon, rows align
across depths with a guide line per open folder, folder names are
semibold, folder counts only show while collapsed and zero counts hide.
2026-09-30 08:21:34 +02:00
Mika KunsandClaude Sonnet 5 0dac047c46 feat(lists): allow nested sidebar folders via drag and drop
Folders can now contain other folders, to arbitrary depth, via a
self-referencing parent_folder_id (ON DELETE SET NULL, same pattern as
lists.folder_id). Nesting/un-nesting is drag-and-drop only: dropping a
folder onto another folder's header middle moves it in, the outer
quarters or any top-level/in-folder drop insert it beside a target.
Dropping a folder into itself or one of its own subfolders is silently
ignored. Deleting a folder releases its lists and subfolders back to
the top level, unchanged from the existing list behavior.

ListFolderNavItemViewModel.Lists became Children (object, mixing lists
and subfolders, mirroring TopLevel) so the existing implicit, type-matched
DataTemplates render nested folders recursively without new XAML, and each
nesting level gets its indent for free from the folder template's own
margin. Folders/RootLists/ContainerOf/PersistOrderAsync/RecomputeFolderCounts
now walk the tree instead of assuming one level.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-28 13:31:26 +02:00
Mika Kuns d3db4455fa feat(ui): Mission Control Recent Sessions mit verschachtelten Handoffs
Neue Tabelle mission_control_sessions (Migration AddMissionControlSessions), befuellt vom
InteractiveLaunchSpecService bei Task-, Ad-hoc- und Handoff-Kacheln. Flyout im Mission-Control-Header
listet die letzten 14 Tage / 50 Sessions, Handoffs eingerueckt unter ihrer Ursprungs-Session, mit
Fortsetzen (--resume im gespeicherten cwd) und Brief anzeigen.
2026-09-28 12:11:21 +02:00
mika kuns e0a1448f44 feat(ui): Mission-Control-Kacheln behalten Position und Identitaetsfarbe ueber Handoffs
Ein Handoff schloss die alte Pane und haengte die neue hinten an -- die Kachel
sprang ans Ende und das ganze Grid ordnete sich neu. Die neue Pane wird jetzt am
Index der alten eingesetzt.

Dazu bekommt jede Kachel eine aus IdentityKey (Default: TaskId) abgeleitete Farbe:
3px-Streifen links am Tile, Punkt im Focus-Mode-Tab. Kein State, keine Persistenz --
derselbe Task faerbt nach App-Neustart gleich, und ein Handoff erbt die Farbe, weil
er dieselbe TaskId behaelt. Nur kuehle Hues, damit nichts als Status gelesen wird.
2026-09-28 08:56:50 +02:00
Mika Kuns 09bcd696dd feat(ui): dirty Ziel-Verzeichnis beim Oeffnen des Merge-Dialogs melden statt nach dem Fehlschlag
MergeTargetsDto/MergeTargets bekommen TargetDirty (via HasChangesAsync,
includeUntracked: false). Das Merge-Modal zeigt Warnung + Stash-Retry
sofort in InitializeAsync statt erst nach dem dirty_target-Fehlschlag;
der REVIEW-Block in der Detail-Pane zeigt denselben Hinweis neben
Approve. Der dirty_target-Rueckgabepfad bleibt als Absicherung bestehen.

Behebt Befund F6 aus docs/test-session-2026-09-16.md.
2026-09-16 15:43:39 +02:00
Mika Kuns 86cc309ba9 fix(ui): duplizierter Confirm-Dialog mit "Delete"-Knopf – zusammenfuehren und lokalisieren
F4: DetailsIslandView/TasksIslandView hatten je eine view-lokale Confirm/Error-Dialog-Kopie,
teils mit hartkodiertem "Delete"-Knopf fuer jede Aktion (inkl. der Stash+Merge-Bestaetigung,
die nichts loescht). Beide Kopien entfernt; DetailsIslandViewModel/TasksIslandViewModel routen
Confirm/Error jetzt durch den geteilten Dialogs-Seam (IDialogService, propagiert vom Shell wie
schon bei Lists/Tasks) statt ueber eine vom Code-behind gesetzte Func-Property.

IDialogService.ConfirmAsync bekommt einen optionalen confirmLabel-Parameter (Default: lokalisiertes
"Confirm"); nur die echten Delete-Aktionen (Task loeschen, abgeschlossene Tasks leeren) uebergeben
das lokalisierte "Delete"-Label.

F5: "Cancel"/"Confirm"/"Delete"/"OK" und die Titel "Confirm"/"Error" durch Loc.T mit neuen Keys
unter "dialog.*" ersetzt (en.json + de.json). Mission Controls eigene Dialog-Kopie bleibt bestehen
(eigenes Fenster, WindowDialogService ist an den Haupt-Owner gebunden) — nur ihre Labels wurden
lokalisiert.

Out of scope (siehe Task-Beschreibung): die Nachrichtentexte der Dialoge bleiben unlokalisiert.
2026-09-16 15:43:38 +02:00
Mika Kuns 1325ab9438 fix(ui): Worktrees-Uebersicht zeigt Task-Nummern, DIFF-Spalte trimmt statt abzuschneiden
Befund F7 aus der Sichtpruefung 2026-09-16. TaskNumber war bereits im
WorktreeMaintenanceService-Join und in WorktreeOverviewRow vorhanden, fehlte
aber im Wire-DTO und in der UI-Kette; jetzt bis zur Row-/Conflict-Anzeige
durchgereicht (#<number> dimmed vor dem Titel, ausgeblendet bei 0). DIFF-Spalte
bekommt CharacterEllipsis-Trimming + Tooltip statt hartem Cut, Spalte von 80
auf 110px verbreitert (Header und Row synchron).
2026-09-16 15:43:38 +02:00
Mika Kuns 56161e4e9b feat(ui): Bilder aus der Zwischenablage ins interaktive Terminal einfuegen
Ctrl+V mit einem Bild in der Zwischenablage schreibt es als temporaeres
PNG unter ~/.claudeDo/tmp/ und fuegt den Pfad in den Composer ein, genau
wie ein Datei-Drop -- Claude liest die Datei selbst. Text-Paste laeuft
unveraendert ueber den bestehenden bracketed-paste-Pfad.

Avalonia 12.0.4 liest Clipboard-Bitmaps bereits selbst (IClipboard.
TryGetDataAsync + AsyncDataTransferExtensions.TryGetBitmapAsync), kein
Win32-P/Invoke noetig. Alte Tmp-Dateien (>24h) werden beim App-Start
aufgeraeumt (ClaudeDo.App/Program.cs), keine eigene Aufraeum-Infrastruktur.
2026-09-16 15:43:38 +02:00
Mika Kuns 4ff5383b35 fix(ui): Diff-Viewer scrollt jetzt auch horizontal synchron
VerticalScrollSync mirrort nur noch Y, X blieb pro Pane unabhaengig. Beide
Panes nutzen dieselbe Schrift/Breite, also X 1:1 mitspiegeln statt wie bei
Y ueber TargetOffset umzurechnen. Die Echo-Abbruchbedingung prueft jetzt
beide Achsen (vorher nur Y), sonst wuerde der neue X-Schreibvorgang seine
eigene Echo-Bedingung nie erfuellen und endlos weiterlaufen.

Klasse in ScrollSync umbenannt (DiffTextView + ConflictResolverView
mitgezogen), da sie nicht mehr nur vertikal synchronisiert.

Kein Headless-Test hinzugefuegt: DiffDispatcherGuardTests.cs dokumentiert
bereits, dass ein bootstrapptes Avalonia Application/Dispatcher in
ClaudeDo.Ui.Tests nach drei eskalierenden Versuchen als Sackgasse verifiziert
wurde (Dispatcher-Thread-Affinitaet kollidiert mit xUnits Worker-Pool ohne
Thread-Garantie; Avalonia.Headless.XUnit kollidiert mit xunit 2.9.3). Als
Finding avaloniaedit-ui-test-dead-end festgehalten. Sichtpruefung bleibt
offen (Side-by-side + Merge-Editor mit ueberbreiten Zeilen).
2026-09-16 15:43:37 +02:00
Mika Kuns 103eb9a687 fix(ui): Shutdown terminates the app even with secondary windows open
ShutdownWorkerAndCloseApp only closed MainWindow via CloseWindow, relying
on ShutdownMode.OnMainWindowClose to bring the process down. That mode
backs off if any window cancels its own Closing event, and
MissionControlWindow always does (it hides instead of closing) - so the
process never actually exited while Mission Control, Cheat Sheets, or the
diff viewer were still open. Call IClassicDesktopStyleApplicationLifetime
.Shutdown() directly, which force-closes every window regardless of
per-window cancellation.
2026-09-16 15:43:36 +02:00
mika kuns 251b70ce83 feat(merge): Stash-Option fuer uncommittete Aenderungen im Ziel-Tree
Changelog / changelog (push) Successful in 2s
Release / release (push) Successful in 43s
Ein dirty Ziel-Arbeitsverzeichnis gibt jetzt den eigenen Status
dirty_target zurueck statt blocked. Die UI bietet daraufhin einen
Retry an, der per git merge --autostash stasht, merged und die
Aenderungen danach wiederherstellt - opt-in pro Merge:

- Approve & Merge: Bestaetigungsdialog
- Merge-Modal: Button "Aenderungen stashen und mergen"
- MCP (merge_task/review_task) wirft weiterhin, kein autostash dort
2026-09-11 11:43:28 +02:00
mika kuns bfb1c6523c feat(ui): Listen und Ordner in einer gemischten Sidebar-Reihenfolge
Die oberste Sidebar-Ebene ist jetzt eine gemischte TopLevel-Collection, so
dass eine Liste auch oberhalb eines Ordners stehen kann. DropAsync deckt
alle vier Quelle/Ziel-Kombinationen ab, ReorderSidebarAsync numeriert die
gesamte sichtbare Reihenfolge ueber lists und list_folders hinweg.
2026-09-10 15:40:10 +02:00
mika kuns 1bdf20272d feat(ui): worker-menu Shutdown ends worker + app after confirm
Adds a Shutdown entry after the Worker menu's Restart/Update Claude CLI
items. Confirms via IDialogService.ConfirmAsync, then kills this
installation's ClaudeDo.Worker process(es) (shared kill loop, extracted
from RestartWorkerService) and force-closes the window through the same
_forceClose path MainWindow already uses for the Mission-Control close
confirm, so no second confirmation dialog shows.
2026-09-10 13:48:50 +02:00
mika kuns 0cec0a77ee fix(ui): report failed paste/drop in the interactive terminal
PasteAsync silently swallowed every exception and returned void, so a
package update renaming Iciclecreek's private write seam would break
Ctrl+V/drop with zero user-visible signal. PasteAsync/SendTextAsync now
return bool (mirroring SendLineAsync), and the view checks the result,
routing a failure through InteractiveTerminalViewModel.ErrorReported ->
ConPtyPaneViewModel.ErrorReported -> the existing footer error strip.
2026-09-10 13:35:16 +02:00
mika kuns 8e6f0d1605 feat(ui): localize WorkConsole, DescriptionStepsCard and the ROADBLOCK label
The review/merge cockpit was the last unlocalized surface in the detail
pane, mixing hard English with translated tooltips on the most-used screen.
Routes all literal strings through details.workConsole.*, details.stepsCard.*
and details.roadblockLabel, with en/de parity.
2026-09-10 13:35:07 +02:00
mika kuns b4b6225432 fix(ui): surface worker connect/restart failures instead of no-opting
WorkerConnectionModalViewModel's StartWorker/RerunInstaller swallowed
missing-exe and Process.Start failures behind an empty catch and closed
the dialog anyway, looking like success. Now both show an inline error
and keep the dialog open; only a real launch closes it.

IslandsShellViewModel.RestartWorkerAsync never checked whether the
relaunched worker actually stayed up, and its status property was never
bound in any view. RestartWorkerService now fails if the new process
exits within a short survival window, and the outcome routes through
the footer error/success strip instead of the dead RestartWorkerStatus.

InstallArtifactLocator.Find() is now virtual and its two subclasses
unsealed so tests can fake exe resolution without touching the real
filesystem/registry.
2026-09-10 13:34:32 +02:00
mika kuns 951c2fe92a fix(ui): validate PowerUse window, explain effort and Prime Claude in Settings
Three usability-audit findings in Settings:
- An unparseable PowerUse window (e.g. "9:0") used to save silently as null
  (= round the clock), the opposite of what the typo implied. Validate() now
  rejects an unparseable start/end unless blank; the worker-side read-time
  tolerance is unchanged.
- "Effort" column header gets a tooltip explaining it's the model's reasoning
  effort (cost/depth tradeoff).
- The "Prime Claude" tab gets a tooltip explaining scheduled Claude runs
  (Ping / Fill My Day / custom prompt).

New locale keys added to en+de. Updated the PowerUse round-trip test that
asserted the old silent-normalize behavior.
2026-09-10 13:34:06 +02:00
mika kuns 3348736e9d fix(ui): warn and block save when a list's working dir isn't a git repo
Reuses RepoScanner.IsRepo (now public) to validate WorkingDir whenever it
changes in ListSettingsModalViewModel — Browse or typing. A missing folder
or a non-repo folder shows an inline warning and gates Save via the same
CanExecute pattern the load-failure gate already uses; an empty WorkingDir
is untouched. Previously this only surfaced as a Failed task deep in
WorktreeManager on first run.

Also localizes the two hardcoded EN strings in the same file (delete
confirm, planning-sessions block) into vm.listSettings.* keys.
2026-09-10 13:32:52 +02:00
mika kuns 4cf601e423 feat(ui): surface depends_on blocking in status chip, chain label, and detail pane
Usability-Audit 2026-09-10 found three gaps versus the dependency-chain-display
spec: a Queued task blocked on an unmet task_dependencies edge rendered the same
chip as one about to run, a cross-list predecessor silently dropped the
"after #N" chip, and the detail pane showed nothing about a wait at all.

- TaskRowViewModel gains IsBlockedByDependency/DependencyWaitLabel (extrinsic,
  assigned by TasksIslandViewModel like the existing chain fields); IsQueued/
  IsWaiting/StatusChipClass/StatusLabel/StatusChipTooltip now account for it
  alongside the existing BlockedByTaskId planning-chain link.
- TasksIslandViewModel.ApplyDependencyWaitState computes the blocked flag and
  wait label per row; a new RefreshExternalDependencyCacheAsync backfills
  Number/Title/Status for predecessors not loaded into the current list's
  Items (reusing the already-open DbContext, no new hub method), so
  BuildAfterLabel/blocking both resolve a listenfremder Vorgänger correctly.
- New "waiting" chip style (IslandStyles.axaml) and locale keys (en+de);
  TaskHeaderBar shows a "Waiting on #N" line bound straight to the same row.

Tests: TasksIslandChainTests (blocked/unblocked chip, cross-list predecessor),
DetailsIslandDependencyWaitTests (new), TaskRowViewModelNotificationsTests
updated for the new notification set.
2026-09-10 13:32:36 +02:00
mika kuns 256bea5ffa fix(ui): show a banner when a ConPTY session dies after startup
InteractiveTerminalViewModel.HasExitedAfterStartup now covers every
post-startup death that ExitedAfterStartup alone missed (crash, clean
exit, quiet exit inside the grace window) -- previously the tile just
stayed looking alive/thinking with zero signal. ConPtyPaneView binds a
new banner to it (message + Retry + Close); CanRetry simplifies to
"any HasExited state" since the same descriptor factory can relaunch
either kind of death. HandlerRestartCoordinator's worker-side
auto-restart path is untouched.
2026-09-10 13:32:19 +02:00
mika kuns dbee4a0de9 feat(ui): Worker-Menü "Update Claude CLI" führt claude update aus
Neuer Eintrag im Worker-Menü der Titelleiste, der die Claude CLI über
das konfigurierte claude_bin (ExecutableResolver, inkl. Shim-Handling)
mit `claude update` aktualisiert. Ausgabe/Fehler landen im Footer-Strip
(FlashFooterSuccess/FlashFooterError), Menüpunkt ist während des Laufs
deaktiviert. 5-Minuten-Timeout tötet den Prozessbaum.
2026-09-10 13:10:30 +02:00
mika kuns 1177463a82 feat(ui): triage model picker (opus/fable) in the merge helper start modal 2026-09-10 09:42:55 +02:00
mika kuns 25c9a619dc feat(ui): collapsible folders for the list sidebar
Folders render above the top-level lists, each with its own collapsible
children; tapping a folder header folds it instead of selecting it.
Lists move in by dragging onto a folder header (or onto a row inside it)
and out by dropping between top-level rows or via the context menu.

Creating a folder is a toggle in the New-list modal, not a third sidebar
button: it reduces the modal to name + icon and writes a folder row
instead of the list row the create flow pre-created.
2026-09-10 08:29:56 +02:00
mika kuns 23491d3b49 feat(ui): Einfuegen und Datei-Drop im interaktiven Terminal
Ctrl+V wurde von TerminalControl als rohes Control-Byte an das Kind
weitergegeben und tat nichts; jetzt wird es im Tunnel abgefangen und geht
ueber TerminalView.PasteAsync, damit Bracketed Paste greift und ein
mehrzeiliger Paste nicht auf der ersten Zeile abschickt. Gedroppte Dateien
werden als Pfade in den Composer getippt, ohne Enter.
2026-09-07 08:17:37 +02:00
mika kuns 0db9fadee9 feat(ui): Cheat-Sheet-Fenster im Hilfe-Menue
Sechs Markdown-Sheets (git, Conventional Commits, Claude CLI, Claude-Config,
dotnet CLI, PowerShell) als EmbeddedResource, gerendert im modelosen, per
Topmost anpinnbaren CheatSheetsWindow. MarkdownView bekommt dafuer das Opt-in
CommandRows: `befehl` - beschreibung wird zu Mono-Chip + Copy-Button, jede
##-Sektion landet in einem Expander. Enthaelt ausserdem: Mission Control
wird beim Oeffnen aus dem Minimiert-Zustand geholt, nicht nur aktiviert.
2026-09-07 08:17:37 +02:00
mika kuns 7c7c33d677 feat(ui): PowerUse-Einstellungen nach Settings -> Ausfuehrung verschieben
Schalter, Zeitfenster und Handoff-Prozent lagen im Usage-Monitor und mussten
in SettingsModalViewModel nur load->save durchgeschleift werden, damit ein
Settings-Speichern sie nicht zurueckwirft. Jetzt gehoeren sie dem General-Tab,
der Monitor ist wieder nur Anzeige + Threshold-Drag, und "Jetzt aktualisieren"
sitzt als Icon in der Titelleiste (neuer ModalShell.HeaderActions-Slot).
2026-09-07 08:17:37 +02:00
mika kuns c16c7b97ef refactor(ui): "Nach Updates suchen" ins Hilfe-Menue verschieben
Changelog / changelog (push) Successful in 2s
Release / release (push) Successful in 41s
2026-09-03 10:20:35 +02:00