Adds SendInteractiveMessageAsync/StopInteractiveSessionAsync and the
InteractiveSessionStarted/Ended events to IWorkerClient + WorkerClient
(UI-thread dispatch mirroring TaskQuestionAsked). Updates the IWorkerClient
fakes in both test projects.
TaskMonitorViewModel surfaces a pending AskUser question (TaskQuestionAsked /
TaskQuestionResolved events) with an AnswerDraft + SubmitAnswerCommand that calls
the new IWorkerClient.AnswerTaskQuestionAsync; MonitorPaneView shows an accent
question banner with an input box above the terminal. Pending question is cleared
on answer/resolve/finish and re-hydrated on attach via GetPendingQuestionAsync.
en/de localization for missionControl.question.*; test fakes updated.
Task rows now drive a hand-built pointer-capture drag instead of
DragDrop.DoDragDropAsync: armed on press, begins past a 4px threshold so a
plain click still selects. The ghost follows the screen cursor across windows;
on release the action is decided by what is under the cursor -- over the
Mission Control window queues the task (geometric DragHitTest, no OLE drop),
over another row in the same user list reorders, anywhere else cancels and
restores the row. Drag starts from any list kind (drag-to-queue everywhere)
but reorder-on-drop stays gated on CanReorder. Removes the obsolete OLE
TaskRowFormat path from both the source and MissionControlView (pane
PaneFormat reorder is untouched).
Add the borderless, transparent, topmost, click-through DragGhostWindow that
hosts a tilted (~-6deg) translucent snapshot of the dragged row, a
TaskDragController that owns its lifecycle (snapshot -> show -> follow -> close),
and a pure DPI-aware DragHitTest helper (unit-tested) for the cross-window
screen hit test. Adds the TaskRowViewModel.IsDragging flag and the
'grabbed' Border.task-row.dragging style (lift + scale + lower opacity +
shadow). Not yet wired into the drag source.
Button.accent set Background on the control, but Fluent's built-in accent button
paints the ContentPresenter with SystemAccentColor (blue) at higher specificity,
so the moss intent never showed (e.g. the Approve & Merge button rendered blue).
Override at the /template/ ContentPresenter level for rest/hover/pressed with the
moss accent tokens, matching the ListBoxItem overrides already in App.axaml.
The state badge in the worktrees overview used bright off-palette Material colors
with hardcoded near-black text (via WorktreeStateColorConverter), which was hard
to read. Switch to the existing chip pattern (subtle tint background + matching
border + colored text): active=blue, merged=green, kept=amber, discarded=gray.
Drop the now-unused WorktreeStateColorConverter.
Replace the static DETAILS label and its dead space with a segment switcher; the card body now shows one section at a time. Step/file counts sit in the tab labels, the edit/preview toggle is scoped to Description, and drag-and-drop or add jumps to the Files tab. Tab labels localized (en/de).
Icon.X was a stroke-only geometry; PathIcon fills its path, so the glyph rendered invisible and the attachment remove button had no visible affordance. Author it as a filled X outline. Also restores the X glyph on the task-row dequeue, agent-strip cancel, and details-header close buttons.
Data/Worker/Ui CLAUDE.md + docs/open.md updated for TaskAttachmentEntity,
AttachmentStore, AttachmentMcpTools, AttachmentOrphanRecovery, the run-prompt
injection, and the detail-pane drag-and-drop UI (incl. a manual verification
item).
Drop a file anywhere on the detail pane to attach it: pane-wide drop target
with a 'Drop to attach' hover overlay (Copy cursor, gated on an idle selected
task), an explicit lingering confirmation/error line, plus an Attachments list
with size, remove, and an Add file… picker in the DETAILS card. ComposedPreview
now shows the reference files too. en/de keys added.
The RequestConflictResolution Func was declared on 5 VMs and hand-threaded shell->details->merge-section->diff->merge-modal. Replaced with a DI-singleton IMergeCoordinator (MergeCoordinator holder; shell wires its Handler at composition, breaking the shell<->island cycle). Invokers (MergeModal, DetailsIsland, WorktreesOverview) depend on the interface; the two pass-through VMs (DiffModal, MergeSection) drop the seam entirely. No behavior change; conflict-seam + batch tests rewired to assert via the coordinator.
The select-all + target picker + Merge All cluster only makes sense per-list: a single target branch is meaningless across repos. Now gated on !IsGlobal; Refresh/Cleanup/Status stay available globally.
Collapses the ~10 per-modal Show*Modal Func callbacks (wired separately on the shell and the lists island) into one IDialogService + WindowDialogService impl. Removes the RepoImport/WorktreesOverview dialog construction duplicated across MainWindow and ListsIslandView, plus the Confirm/Error dialogs duplicated in both code-behinds. Shell/lists Open* commands now route through an injected Dialogs handle (propagated shell->lists); the per-list worktrees overview also wires conflict resolution now, matching the global one. No VM ctor changes (Dialogs is a settable seam), so no test-fake impact.
Drops the append-SortOrder query duplicated inline in TasksIslandViewModel.AddAsync; the repository (already used by MCP AddTask) is now the single home for the create+SortOrder invariant. Sets Status=Idle explicitly for parity.
GetConflictsAsync/GetMergeConflicts (+ MergeConflicts/ConflictFileContent/ConflictFileDto/ConflictHunkDto DTOs and the now-orphaned GitService.ShowStageAsync) were superseded by the segment-based GetMergeConflictDocuments path and had no production callers. Removes the IWorkerClient member, both test fakes, the lingering test, and updates the Worker/Ui/Data CLAUDE.md surface notes.
Code-review follow-ups before push:
- MergeFile.ResultText/Compose() fell back to Ours for unresolved conflicts while
the editor seeds them empty — align both on empty so the public model matches the
pane and Continue can't silently auto-accept Ours.
- Bound the gutter re-layout retry (was an unbounded Background re-post when the
editor isn't laid out, e.g. minimized).
- Pluralize the readout ('1 conflict' not '1 conflicts'). Tests updated. Ui 128 green.
- The Merge button in the Diff window now hands a conflicting merge to the in-app
3-pane editor (MergeModal routes 'conflict' through RequestConflictResolution,
the same seam Approve uses) instead of dead-ending on a conflict message.
- Add a conflict overview ruler right of the Result pane: a proportional map of
every conflict in the file, recolored by resolved state, click a tick to jump —
so conflicts are findable in long files without scrolling.
- New MergeResolvedEdgeBrush token + conflictMap en/de key. Ui 128 + Loc 16 green.
- Conflict accept is now a per-side toggle: > adds MAIN (ours), < adds INCOMING
(theirs) in click order (first on top); clicking again removes that side, so each
side is included at most once. Region content is rebuilt from the included set.
- Drop the separate reset (x) control — toggling both off clears the region.
- Relabel the panes/tooltips Ours/Theirs -> MAIN/INCOMING (merge target vs task).
- Add a cross-file 'N of M files unresolved' readout (FilesSummary) so you can see
how many more files still have conflicts. en/de updated; Ui 128 + Loc 16 green.
Replace the single-side replace (and the short-lived accept-both button) with
additive accepts: each result conflict region starts EMPTY (thin marker bar), and
the gutter controls append a side in click order — > adds ours, < adds theirs
(first pick on top, next below), x clears. Controls stay visible after the first
pick so both sides can be stacked; empty/unresolved regions render a marker so they
stay visible. en/de keys updated; Ui 128 + Localization 16 green.
The between-pane gutter only offered single-side replace (accept ours / accept
theirs). Add an 'accept both' (⊕) control under the ours chevron that drops
ours-then-theirs into the result region, so a conflict can be combined in one
click instead of picking one side and hand-adding the other. en/de keys added.
Review follow-ups: coalesce gutter re-layout posts (avoid dispatcher flooding when
visual lines aren't ready), drop the zero-length deletable segment (undo hygiene),
and clear stale scroll-sync hooks on DataContext swap. Update Ui/CLAUDE.md to the
3-pane editor and log visual-verification items (incl. empty-side + alignment edges)
in docs/open.md.
Replace the Base|Ours|Theirs read-only columns + single-conflict result with a
whole-file 3-pane editor: Ours (read-only) | editable Result | Theirs (read-only),
reconstructed from the active file's segments so the panes line up on stable text.
- IBackgroundRenderer paints each conflict block (unresolved=blood, resolved=green)
across all three panes.
- Result document edits are gated by an IReadOnlySectionProvider (stable text is
read-only; only conflict regions, tracked via TextAnchors, are editable); edits
flow back to the owning block.
- Between-pane gutters host inline accept controls (>/< ) positioned per conflict;
click accepts ours/theirs into the result.
- Proportional synced vertical scroll across the panes; file switcher + change-nav
arrows (F8 / Shift+F8); active-file 'M conflicts - K resolved' readout.
- Merge block tints + AmberBrush tokens; en/de keys for the new labels.
Seam unchanged. App builds; Ui.Tests 128, Localization.Tests 16.
Route planning unit-merge conflicts through ConflictResolverViewModel
(OpenForPlanningAsync) and delete the old ConflictResolutionViewModel dialog.
Add active-file 3-pane reconstruction (MergeFile OursText/TheirsText/ResultText,
ActiveFile, SelectFileCommand, active-file readout) as the VM foundation for the
Rider-style editor. Seam preserved; Ui.Tests 128/128.
- Feedback box + a new "Resume session" button move from the Git tab to the
Output tab; the Git review block keeps Approve & Merge / Park / Cancel / Reset.
- Add a "Parked" chip for Idle tasks that still hold an Active worktree.
- Stop showing the "Session was Cancelled" band on cancel (failed-only now).
- Fix the Worktrees-overview state-chip contrast (dark text on the colour).
Replace the whole-file conflict model with line-level hunks, the
foundation for the full in-app merge editor.
- ConflictMarkerParser: parses git conflict markers (incl. diff3 base)
into ordered stable/conflict MergeSegments; exact round-trip + Compose
- GitService.MergeNoFfAsync passes -c merge.conflictStyle=diff3 so the
working tree carries the merge base in conflict markers
- TaskMergeService.GetConflictDocumentsAsync: reads each conflicted file,
parses into segments, flags binary files
- hub GetMergeConflictDocuments + DTOs (MergeConflictDocumentsDto/
ConflictDocumentDto/MergeSegmentDto), IWorkerClient + both fakes
- tests: 8 parser unit tests + a real-git integration test asserting
line-level hunks with a diff3 base