Commit Graph
28 Commits
Author SHA1 Message Date
mika kuns 8930b564e4 refactor(ipc): declare the SignalR wire DTOs once in ClaudeDo.Data
WorkerHub and IWorkerClient each carried their own copy of every record and
had already drifted — MergePreviewDto lost its verify fields on the client
side, two records disagreed on their name. They now live in Data/Wire.cs and
reach both sides via a <Using> item, so a hub signature change is a compile
error instead of a silently dropped JSON field.
2026-08-26 13:55:40 +02:00
mika kuns 76d836a278 test: dedupe the nested test doubles into one shared file
TestDbFactory was redeclared as a private nested class in 40 test files,
NullServiceProvider and StubNotesApi in 14 each, DefaultStub in 5 — 73
declarations, all semantically identical (StubNotesApi differed only in
formatting and type qualification). They now live in TestDoubles.cs next to the
existing StubWorkerClient, which was already the shared-double pattern in this
project.
2026-08-26 10:11:58 +02:00
mika kuns 9c4a63d2c5 fix(worker): thread handler task id into list-handler kickoff prompts
Neither the initial nor the handoff kickoff ever told a list-handler
session its own handler task id, so handoff_list_handler(taskId, ...)
was unrenderable -- the handoff chain broke exactly where it was needed
(#200/#201 on 2026-08-21).

Add {handlerTaskId} to both MergeHelperInitialDefault and
MergeHelperHandoffDefault, thread a handlerTaskId parameter through
BuildForMergeHelperAsync (interface, WorkerHub.GetMergeHelperLaunchSpec,
IWorkerClient/WorkerClient, and the MissionControlViewModel call site,
which already had the id from CreateMergeHelperTaskAsync but never
passed it on), and render it in BuildForMergeHelperHandoffAsync from the
taskId parameter it already receives.

RenderTemplate leaves unknown/missing tokens untouched, so a
user-edited override without the new token still renders fine -- no
forced migration for override users.
2026-08-21 18:00:16 +02:00
mika kuns 99bb5be5da fix(ui): silent no-ops raise ErrorReported instead of swallowing failures (UX-Audit #1)
Stop/Enqueue/Dequeue/Reset&Retry (DetailsIslandViewModel), status/cancel/reject
commands (TasksIslandViewModel), Mission Control's drag-enqueue and queue
refresh, and "Open findings folder" (ListsIslandViewModel) used to catch {}
or silently return on a blocked precondition. They now report through the
existing ErrorReported -> FlashFooterError path, with new en/de locale keys
and Ui.Tests covering each converted command.
2026-08-21 09:13:00 +02:00
mika kuns e343baf21a fix(ui): close the outgoing ConPTY pane on merge-helper handoff
Each handoff tile is a live claude process with the full mcp__claudedo__* surface; leaving the
outgoing phase's pane open leaked one process per phase. Close it via CloseConPtySession before
opening the next phase's tile, restoring the one-pane-per-TaskId invariant so
OpenConPtySessionAsync's dedupe and OnPaneSubmitForReview can go back to FirstOrDefault.
2026-08-11 16:55:25 +02:00
mika kuns 8da1a12389 fix(test): give Ui.Tests task seeds a unique Number
The task-numbers slice added a UNIQUE index on tasks.number. Ui.Tests seed
TaskEntity rows directly instead of going through TaskRepository, so every row
kept the default Number = 0 and 31 tests failed with
'UNIQUE constraint failed: tasks.number'.
2026-08-11 11:32:01 +02:00
mika kuns d3155e6868 feat(queue): warn when the base branch has uncommitted changes
Queuing (update_task_status, batch_update_task_status) and run_task_now
now surface a non-blocking baseDirty warning (separate modified/untracked
counts) when the list's working dir has uncommitted changes at enqueue
time, since a new worktree forks from the commit tip and silently misses
them. BaseDirtyChecker caches per working dir for a few seconds so a
batch queue over many tasks in one list only shells out to git once. The
UI surfaces the same warning via the footer error strip on queue actions.
2026-08-10 14:30:33 +02:00
mika kuns bac8387069 Merge claudedo/c52ba287db6e4a7c9bac38c30bcc21ec 2026-08-06 13:50:41 +02:00
mika kuns d1ed29f19f Merge branch 'claudedo/12bae32376504fd28bedb3c7202feba5' 2026-08-06 13:50:14 +02:00
mika kuns 176ba78e11 fix(ui): serialize ConPTY env launch and close open-path dedupe races
Two sessions starting back-to-back could interleave SetEnvironmentVariable
calls before either LaunchProcess() forks, leaking one task's env (e.g.
CLAUDEDO_PLANNING_TOKEN) into another's claude process. Serialize the
set-env + LaunchProcess critical section behind a static SemaphoreSlim in
PtyTerminalSession.

OpenConPtySessionAsync/OpenPlanningConPtySessionAsync ran their TaskId
dedupe check before an awaited DB title lookup, and OpenMergeHelperConPtySessionAsync
awaited task creation before any dedupe was possible - rapid double-invocation
could open two panes or mint two host tasks. Claim the key synchronously at
method entry, before any await, and release it in a finally.
2026-08-06 13:43:00 +02:00
mika kuns 57c61a2043 fix(ui): gate Mission Control submit-for-review, add retry, fix event leak
Submit for Review is now disabled while a ConPTY pane is starting, has
failed to launch, or has already exited, and MissionControlViewModel
guards against a rapid double-click racing two SubmitTaskForReviewAsync
calls. A failed launch no longer permanently occupies its TaskId dedupe
slot -- a Retry button re-fetches the launch spec and restarts the pane
in place. CloseConPtySession/Dispose now also unsubscribe
SubmitForReviewRequested, matching the other pane event handlers. Also
fixes the pre-existing nullable-dereference warning in
IslandsShellViewModel.SyncInteractiveSessionChips.
2026-08-06 13:42:06 +02:00
mika kuns d84607f796 fix(ui): gate queueing on an open interactive ConPTY session
A task-based ConPTY session leaves the row Idle in the DB (sessions never
touch status), so nothing stopped the queue picker from claiming it too:
CanSendToQueue ignored HasInteractiveSession, and both TasksIslandViewModel.
SendToQueueAsync and MissionControlViewModel.EnqueueTaskAsync (drag-to-queue)
wrote Status=Queued straight via EF, bypassing TaskStateService entirely and
its manual/draft-child guards. That let an autonomous claude process spawn in
the same worktree a user was hand-editing in the ConPTY pane.

Add !HasInteractiveSession to CanSendToQueue, and route both UI enqueue paths
through IWorkerClient.SetTaskStatusAsync (worker hub -> TaskStateService.
EnqueueAsync) instead of raw EF writes. The interactive-session gate itself
stays in the UI: the worker has no notion of a UI-hosted ConPTY pane.
2026-08-06 13:29:44 +02:00
mika kuns 7cbd4e66ae feat(ui): add usage pill to footer and mission control header
Adds the IWorkerClient/WorkerClient usage surface (GetUsageSnapshot,
GetModelUsage, GetTaskUsage, UsageUpdated event) and a shared
UsagePillViewModel hosted once in IslandsShellViewModel (footer) and
once in MissionControlViewModel (header), showing "5h X% · 7d Y%"
with warn/blocked/stale states via existing design tokens. The
OpenMonitorCommand is wired but currently a no-op, pending the usage
monitor modal.
2026-08-05 13:16:29 +02:00
mika kuns 524836ffe8 Merge claudedo/02777289600f499ab274e844eb070ff4 2026-08-05 09:24:21 +02:00
mika kuns c07c1f70a8 feat(mission-control): give the list handler its own review task
"Let Claude handle it" now creates one ClaudeDo task per run to host the
ConPTY session (Idle/IsManual, never queued) instead of an untracked
ad-hoc tile, so the run has a real title, diff, and review outcome.
Since the handler merges its own changes straight into the list's
working dir, the task never gets a WorktreeEntity; its review range
lives as new HandlerBaseCommit/HandlerHeadCommit columns on TaskEntity
instead, reusing the existing commit-range diff machinery and keeping
it out of the worktrees overview entirely.
2026-08-05 09:16:34 +02:00
mika kuns c82ea2eea1 chore(ui): remove dead Mission Control monitor-pane stack
Auto-seeding of monitor tiles was disabled in 724814f; Mission Control now
only shows ConPTY panes. Removes Monitors/EnsureMonitor/SeedActive, the
detach/re-dock machinery, MonitorPaneView and the detached monitor window,
plus their tests and orphaned localization keys.

TaskMonitorViewModel itself stays: DetailsIslandViewModel still uses it as
the backing state for the task Log/AgentState/AskUser-question UI, so only
its Mission-Control-only members (Title/DisplayTitle, detach, cancel command,
IMissionControlPane) were stripped. IMissionControlPane/Panes were kept
(now a 1:1 mirror of ConPtySessions) rather than dissolved, to avoid
churning the still-live ConPTY pane tests and AXAML for a single-implementer
interface.

Visual verification still open: Mission Control with several open ConPTY
tiles, and the Focus/Overview toggle.
2026-08-05 09:03:55 +02:00
mika kuns 44cdad386c feat(mission-control): sidebar shows queued+running, no auto-monitor seeding
- TaskStarted no longer creates a monitor pane; Panes stays empty unless a
  ConPTY session is explicitly opened
- SeedActive no longer called on construction or ConnectionRestored
- EnsureMonitor / SeedActive kept compiling and functional (internal), just unused
- RefreshQueueAsync now loads Queued + Running tasks, Running sorted first
- QueuedTaskViewModel gains IsRunning + OpenInAppCommand (IRelayCommand)
- Sidebar row is a Button; running rows get RunningTint overlay + "Running" label
- HasQueued is true whenever any queued or running task exists
- New localization keys: missionControl.running (en + de)
- Tests updated: 12 monitor-machinery tests use EnsureMonitor directly;
  3 new acceptance-criteria tests (no-auto-pane, running-first sort, row click)
2026-07-29 12:12:34 +02:00
Mika Kuns 1466d0fbab feat(ui): spinners for ConPTY session start and task refine
Both actions previously gave no feedback: opening a ConPTY session only created
the tile after the launch-spec roundtrip (which may build a worktree), and the
refine button just disappeared while the run was in flight.

Add a shared Ellipse.spinner style, and let ConPtyPaneViewModel resolve its own
launch spec so the tile shows up immediately with a starting overlay. A failed
launch now keeps the tile with its inline error banner instead of never
appearing — Start() is separated from the ctor so the host can subscribe to
ErrorReported before the launch begins.
2026-07-27 15:02:51 +02:00
Mika Kuns 4877802bcd refactor(worker): make the list-handler launch spec single-list and single-repo 2026-07-27 15:02:50 +02:00
mika kuns 083e1f3948 feat(ui): open merge-helper ConPTY tile from selection
Changelog / changelog (push) Successful in 1s
Release / release (push) Successful in 38s
2026-07-24 14:21:26 +02:00
mika kuns 3feb08d9d9 feat(interactive): New session button for ad-hoc ConPTY sessions
Adds a 'New session' header button in Mission Control that opens a folder picker
and starts a task-less embedded ConPTY session in the chosen directory. ConPtyPaneViewModel
TaskId is now nullable (ad-hoc panes have no task and are never deduped) with a
CreateAdHoc factory; the view does the picking, the VM stays picker-agnostic.
2026-07-23 16:47:15 +02:00
mika kuns 0513265c49 feat(interactive): host task-based ConPTY sessions in Command Center
Adds an 'Open ConPTY session' entry that fetches a task's launch spec and hosts
an embedded ConPTY terminal as a Mission Control pane, coexisting with the
streamed-log monitor panes (streaming stack untouched). Introduces IMissionControlPane
+ ConPtyPaneViewModel, a non-destructive Panes mirror (Monitors prefix + ConPtySessions
suffix) so unrelated monitor churn never tears down a live terminal, and a grid<->tabs
layout toggle. Launch failures surface via the footer error strip.
2026-07-23 16:47:15 +02:00
Mika Kuns 3b629c218f feat(ui): drag a task into Mission Control to queue it 2026-06-26 16:11:51 +02:00
Mika Kuns 9eb54a0d2f feat(ui): read-only queue side strip in Mission Control 2026-06-26 16:11:51 +02:00
Mika Kuns fbcffce79c feat(ui): mission control detach/redock toggle, clear review panes, reorder helper 2026-06-26 16:11:51 +02:00
Mika Kuns 5f6e7480f2 feat(ui): detach a monitor into its own window 2026-06-26 16:11:51 +02:00
Mika Kuns 5a21d673c1 feat(ui): reveal a task by id from anywhere 2026-06-26 16:11:50 +02:00
Mika Kuns 42da840066 feat(ui): add MissionControlViewModel 2026-06-26 16:11:50 +02:00