Commit Graph

78 Commits

Author SHA1 Message Date
mika kuns
c45f892591 feat(daily-prep): add Prep-log and Clear-day buttons to MyDay header
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 08:18:30 +02:00
mika kuns
a8670ee23a feat(daily-prep): add live prep-output mode to the Details island
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 08:14:09 +02:00
mika kuns
46ac3fc930 feat(daily-prep): add Prepare-day button to MyDay header 2026-06-03 16:36:25 +02:00
mika kuns
00ef11ac33 fix(i18n): live-refresh smart/virtual list names on language change
All checks were successful
Release / release (push) Successful in 35s
Smart-list nav labels were localized only at load; subscribe the singleton
ListsIslandViewModel to language changes and re-localize names in place.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-03 13:17:21 +02:00
mika kuns
350a89f364 feat(i18n): localize ViewModel-built strings via ambient Loc accessor
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:43:30 +02:00
mika kuns
a8943a9f7a feat(ui): pinned Notes row in My Day opens the notes editor
Add ShowNotesRow/OpenNotesCommand to TasksIslandViewModel; wire NotesRequested
event to Details.ShowNotes() in the shell; show a Notes button above the task
list when the My Day smart list is active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 10:08:30 +02:00
mika kuns
eccd06e182 feat(ui): notes mode in the Details island
Add IsNotesMode/Notes to DetailsIslandViewModel; ShowNotes() loads today's
notes and switches the island body to NotesEditorView via IsVisible toggling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 10:07:09 +02:00
mika kuns
c8b5ed3912 feat(ui): NotesEditorViewModel with day navigation and bullet CRUD 2026-06-03 10:01:17 +02:00
mika kuns
1cb5171fba fix(worker): harden review re-run, timestamps, and queue affordance
- Clear ReviewFeedback only after a successful re-run so a failed/cancelled
  run keeps it for a manual retry.
- Clear stale StartedAt/FinishedAt when rejecting a task back to the queue.
- Only non-planning standalone tasks gate on review (guard PlanningPhase).
- Hide "send to queue" for WaitingForReview tasks so review isn't bypassed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 08:00:13 +02:00
mika kuns
6c27ffbdca feat(ui): surface review actions and WaitingForReview status in task rows
Adds Approve/Reject/Park/Cancel buttons with a feedback flyout, a review
status chip, and a friendly status label for WaitingForReview tasks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 07:46:37 +02:00
Mika Kuns
4a36fbe5e0 feat(ui): replay run log in session terminal, drop per-row live tail
All checks were successful
Release / release (push) Successful in 34s
Set the task's log path when the run is created (not at completion) so the
session terminal can replay live output when the user navigates away and back
mid-run. Remove the now-redundant inline per-row live tail (LiveTail /
HasLiveTail / TaskMessageEvent) and scroll the terminal to end after the next
layout pass so wrapping lines aren't clipped.
2026-06-01 16:25:14 +02:00
Mika Kuns
ab44ba5e41 feat(ui): list reordering, quick actions, and resizable modals
- Drag-to-reorder user lists in the sidebar, persisted via a new
  list sort_order column (AddListSortOrder migration, backfilled by
  creation time) and ListRepository.ReorderAsync
- "Open in Explorer" / "Open in Terminal" context-menu actions on lists
- "Clear all completed" button on the Tasks island
- Inline-edit subtask titles (empty text deletes the step) and
  click-to-copy task ID in the Details island
- Make modal and planning windows resizable (BorderOnly decorations
  with min sizes) instead of fixed-size borderless

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 15:28:17 +02:00
mika kuns
ce9fadc0b5 refactor: fold single-consumer helper types into their owners
Consolidate small single-purpose types into the files that own them:
StreamResult into StreamAnalyzer, the Planning context records into
PlanningSessionContext, PrimeClock/PrimeSchedulerOptions into PrimeScheduler,
AgentMcpTools into LifecycleMcpTools, the locator subclasses into
InstallArtifactLocator, LogLineViewModel into DetailsIslandViewModel,
RepoImportItemViewModel into its modal, and StepViewModel into InstallPageViewModel.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 15:47:46 +02:00
mika kuns
7a88e8a848 fix(ui): apply blue PLANNED badge for finalized planning, drop dead converter statics
Bind the planning-parent badge to IsPlanActive/IsPlanFinalized so a
finalized plan shows the blue "planned" style instead of staying amber.
Remove the unused Instance statics on BoolToItalicConverter and
BoolToDraftOpacityConverter (registered via the App.axaml resource dictionary).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 09:39:04 +02:00
mika kuns
128fb7d4d2 feat(ui): add delete-list button to List Settings modal 2026-05-29 16:09:17 +02:00
mika kuns
c43b06d83d feat(ui): add repo import button to Lists island
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 15:46:45 +02:00
mika kuns
ce79a2d0fe feat(planning): gate subtask queueing behind plan finalization
Planning subtasks are now "Draft" until their parent plan is finalized,
then "Planned" (queueable). Finalizing a plan no longer auto-queues the
child chain; the user sends the plan to the queue explicitly.

- TaskStateService rejects a child entering Queued/Running unless its parent
  is Finalized; this single invariant covers UI, queue, RunNow and MCP paths
- WorkerHub.SetTaskStatus routes Queued through the gated EnqueueAsync
- Finalize call sites pass queueAgentTasks: false
- PlanningChainCoordinator.QueuePlanAsync guards the chain build on Finalized
- TaskRowViewModel derives Draft/Planned from ParentFinalized; gates
  CanSendToQueue / CanQueuePlan; view shows a PLANNED badge

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 14:41:48 +02:00
mika kuns
967e0cd319 feat(ui): merge action and robust jump-to-task in worktrees overview
Add Merge entry to the worktrees overview context menu wiring the existing
MergeModalViewModel, replace fire-and-forget list selection with a
collection-change-aware JumpToTaskHelper, and propagate list renames to
visible task rows via a new ListUpdated event.

Harden worktree state changes: WorkerHub.SetWorktreeState now rejects
invalid transitions, WorktreeMaintenanceService only drops the DB row when
the on-disk worktree was actually removed, and Cleanup/Reset broadcast
WorktreeUpdated for affected tasks. SetWorktreeStateAsync returns the hub
error message so the modal can surface it.

Also: de-duplicate the worktrees overview modal opener, hook
OnParentTaskIdChanged to refresh IsDraft, fix MergeModal CanExecute
notifications, and add WorktreeStateHubTests for the transition rules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 13:43:39 +02:00
mika kuns
2223839595 feat(ui): hide list chip outside virtual list views
Task rows now expose a ShowListChip flag that the tasks island sets
only for Virtual list kinds, so the chip stops being redundant when
viewing a single concrete list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:27:04 +02:00
mika kuns
e55367af67 fix(ui): wire details-island buttons and drop dead handlers
- Bind star button to ToggleStarCommand; wrap header and subtask
  done-check ellipses in buttons (ToggleDone / ToggleSubtaskDone).
- Wire AgentStrip copy-path button to clipboard handler.
- Remove dead Notes/PromptInput/ApproveMerge/ShowWorktreeModal code
  with no UI bindings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 11:24:51 +02:00
mika kuns
789094fcd9 feat(ui): wire worktree overview modal entry points
Add list context-menu command (per-list mode) and Help menu entry (global mode) for the WorktreesOverviewModal; register VM and factory in DI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 09:49:44 +02:00
mika kuns
5da69ee6aa refactor(config): consolidate commit types into CommitTypeRegistry
Replaces six scattered "chore" literals across TaskEntity, ListEntity,
WorkerHub, ListsIslandViewModel, ListNavItemViewModel and the inline
commit type list in ListSettingsModalViewModel.
2026-05-19 09:00:00 +02:00
mika kuns
a62ef240d1 refactor(config): consolidate model aliases into ModelRegistry
Replaces three scattered model lists (ListSettingsModalViewModel,
DetailsIslandViewModel, GeneralSettingsTabViewModel) and the hardcoded
planning model with a single source. Planning launcher now uses the
opus alias instead of pinning claude-opus-4-7.
2026-05-19 08:58:43 +02:00
mika kuns
623ebf147b refactor(tags): remove tag entity and all references
Drops TagEntity, TagRepository, and tag wiring across data layer, worker,
and UI. Adds RemoveTags migration to clean up schema.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 08:07:24 +02:00
mika kuns
0d55002e5e refactor(planning): dequeue orphans instead of promoting, restore lost lineage
Three behavioral changes around stuck planning subtasks:

- OrphanRecovery no longer clears ParentTaskId. Queued children of a
  parent that is not in a planning phase are dequeued (Status: Queued
  -> Idle, BlockedByTaskId cleared) but stay attached to the parent so
  the historical lineage is preserved.
- DiscardPlanningAsync stops promoting terminal (Done/Failed/Cancelled)
  children to top-level for the same reason - they remain ChildTasks of
  the (now non-planning) parent.
- New PlanningLineageRecovery hosted service scans
  ~/.todo-app/planning-sessions/ and re-attaches a single, unambiguous
  blocked-by chain to its original planning parent when the
  parent_task_id links were lost. Refuses to guess when multiple
  candidate chains exist.

UI now exposes ConnectionRestoredEvent on IWorkerClient, fired on first
connect and every reconnect. ListsIslandViewModel refreshes counters
and TasksIslandViewModel reloads the current list - so stale counts no
longer survive a worker restart.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 16:28:57 +02:00
mika kuns
d094a21e09 feat(planning): prevent orphaned subtasks via guards + startup repair
Three coordinated guards close the orphan-creation paths:

- CreateChildAsync refuses when the parent is not in a planning phase.
- DiscardPlanningAsync now returns a structured DiscardPlanningOutcome
  and refuses when children are queued or running; callers can opt into
  auto-dequeuing queued kids via dequeueQueuedChildren=true. Terminal
  children (Done/Failed/Cancelled) are promoted to top-level instead of
  becoming orphans when the parent's PlanningPhase is reset.
- OrphanRecovery hosted service clears ParentTaskId on any rows whose
  parent is missing or no longer in a planning phase on worker startup,
  mirroring the StaleTaskRecovery pattern.

UI surfaces the block reason: a confirm dialog offers to dequeue queued
children and retry; a running-children block is shown as a hard error
asking the user to cancel first.

WorkerClient now negotiates the JsonStringEnumConverter so the
DiscardPlanningResult enum round-trips correctly over SignalR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 16:02:15 +02:00
mika kuns
e68bb737e3 refactor(filtering): consolidate task list filters into single strategy registry
Replace the three drifting filter implementations (counter, list loader,
regroup) with one ITaskListFilter strategy per list kind. Counter and list
loader now share the same predicates, so they cannot diverge again. Planning
hierarchy rules (parent-as-context, orphan handling) live in PlanningRules
and are unit-tested via 29 new tests in ClaudeDo.Data.Tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 15:18:33 +02:00
mika kuns
4c92da55ad feat(ui): cascade dequeue to queued children for any parent
RemoveFromQueue previously gated cascade on PlanningPhase != None,
leaving manually-built chains stuck if their parent had no planning
phase. The handler now matches the X button's HasQueuedSubtasks gate:
queued children are unqueued and unblocked regardless of the parent's
planning phase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 14:17:37 +02:00
mika kuns
c1856657b5 feat(ui): editable task status and tags from details panel
Adds a status ComboBox in the Details header (no transition guards)
and a Tags section with chips + AutoCompleteBox. TaskRowViewModel.Tags
becomes an ObservableCollection so chip lists stay live. TasksIsland
caches AllTags for the row context menu and exposes Set/Toggle helpers.
Test fakes updated for the new IWorkerClient methods.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 10:40:03 +02:00
Mika Kuns
8eafa71ed3 fix: restore green test suite across all projects
* TaskRepository.UpdateAsync defensively detaches any locally tracked
  entity with the same Id before attaching the patched copy, preventing
  EF identity conflicts when callers load via AsNoTracking and write
  back through the same DbContext (surfaced by ExternalMcpService
  UpdateTask integration tests).
* TasksIslandViewModel auto-collapse now only fires for Finalized
  planning parents that are not yet Done. Active-phase parents stay
  expanded while the user is editing the plan, and Done parents stay
  expanded so all completed children land in CompletedItems alongside
  the parent.
* Update three Ui.Tests fakes (ConflictResolution, PlanningDiff,
  DetailsIslandPlanning) to implement the two new IWorkerClient
  members (OpenInteractiveTerminalAsync, QueuePlanningSubtasksAsync).
* Rewrite StreamLineFormatterTests to exercise the current
  assistant/user/result/system message format instead of the legacy
  stream_event parsing that was removed in the formatter rewrite.
* Align AppSettingsRepository seed-default assertion with the
  permission-mode default that flipped from bypassPermissions to auto.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 08:30:26 +02:00
Mika Kuns
dc3fc443b4 refactor(data): retire legacy TaskStatus values and backfill existing rows
Slice 6 of the worker state and queue consolidation refactor.

* Drop Manual, Planning, Planned, Draft, Waiting from the TaskStatus enum
  and from the EF value converter; only the lifecycle values remain
  (Idle, Queued, Running, Done, Failed, Cancelled).
* Add migration RetireLegacyTaskStatus that rewrites existing rows:
  manual/draft -> idle, planning -> idle+planning_phase=active,
  planned -> idle+planning_phase=finalized, waiting -> queued+blocked_by
  derived from sort_order via a CTE with LAG().
* Reroute every call site that compared/set legacy values to the new
  three-field model (Status + PlanningPhase + BlockedByTaskId), including
  the planning repo helpers, MCP services, the planning chain coordinator,
  and the UI view-models. TaskRowViewModel now exposes PlanningPhase to
  drive the planning badge.
* Refresh Worker/CLAUDE.md and Data/CLAUDE.md, the docs/plan.md status
  section, and the planning verification notes in docs/open.md.
2026-04-27 15:28:55 +02:00
Mika Kuns
4ab906ff0b feat(planning): consolidate finalize+chain via TaskStateService, fix queue pickup
Slice 4 of the worker state consolidation refactor. Eliminates the
"queue never picks up planning tasks" bug structurally by routing both
the manager and MCP finalize paths through TaskStateService and
PlanningChainCoordinator.SetupChainAsync, where the auto-wake on enqueue
guarantees the queue picker claims the first child immediately.

- Delete TaskRepository.FinalizePlanningAsync; PlanningSessionManager
  now orchestrates via _state.FinalizePlanningAsync + _chain.SetupChainAsync.
- Rename QueueSubtasksSequentiallyAsync to SetupChainAsync (internal);
  layout is now Status=Queued + BlockedByTaskId, with auto-attached agent tag.
- OnChildFinishedAsync looks up the successor by BlockedByTaskId, drops
  the legacy Waiting status lookup.
- PlanningMcpService.Finalize routes through state+chain; EditableStatuses
  drops Waiting and adds Idle; gate uses PlanningPhase==Active.
- TaskStateService.FinalizePlanningAsync clears the planning session token.
- UI: TaskRowViewModel adds BlockedByTaskId; IsQueued/IsWaiting reflect
  the new layout; TasksIslandViewModel.RemoveFromQueueAsync clears
  BlockedByTaskId on dequeue.
- New regression test PlanningEndToEndTests.FinalizeAsync_FirstChildIs
  ClaimedByPicker_WithinDeadline asserts the picker claims the first
  child within 200ms with no manual WakeQueue.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:16:12 +02:00
Mika Kuns
bdb709b264 feat(ui): show dequeue affordance on planning parents with queued children
Planning parents stay in Planning/Planned status while their children are
Queued/Waiting, so the existing IsQueued-only visibility rule hid the dequeue
button. Add HasQueuedSubtasks tracking and a CanRemoveFromQueue helper; the
parent-row dequeue cascades to all queued/waiting children. Also attach the
'agent' tag on explicit enqueue so the queue picker accepts the task.
2026-04-27 10:16:40 +02:00
mika kuns
6c54759aa0 feat(ui): add Run interactively action to task context menu
Spawns Windows Terminal in the list working directory running
`claude --permission-mode auto` with the task title and description
prefilled as the initial prompt. Reuses the planning launcher
infrastructure but skips worktree, system prompt, and MCP setup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 10:02:21 +02:00
mika kuns
a6ca1c0108 feat(ui): add MarkdownView control and editable description in details island
New MarkdownView UserControl renders a markdown preview. Details island gains an editable Description section with edit/preview toggle, collapsible header, copy-to-clipboard, and debounced auto-save (400ms).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 09:37:14 +02:00
mika kuns
8f94dddbc5 feat(ui): queue planning subtasks sequentially and surface waiting status
Adds a "Queue subtasks sequentially" context-menu entry on rows with planning children, wires it to WorkerHub.QueuePlanningSubtasksAsync via IWorkerClient. TaskRowViewModel exposes IsWaiting/StatusChipClass for the new Waiting status, and HasPlanningChildren keeps parents expandable after they leave the planning state. TasksIslandViewModel auto-collapses parents whose every child is Done and includes Waiting children in the queued virtual list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 09:37:04 +02:00
mika kuns
a6ebff3f34 feat(ui): add aggregated diff viewer for planning tasks
Implements Task 14: PlanningDiffView (Window), PlanningDiffViewModel,
ShowPlanningDiffModal callback wired in DetailsIslandView, and 5 xUnit tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:39:38 +02:00
mika kuns
1aead9dad0 refactor(ui): test planning detail pane via real ViewModel and restore merge-all IsEnabled binding
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 16:31:54 +02:00
mika kuns
4c6fd9f024 feat(ui): add merge-target dropdown and merge-all controls to planning detail
- Add SubtaskDiffDto and CombinedDiffResultDto to PlanningDtos.cs
- Extend IWorkerClient with 5 planning merge methods and 5 events
- Implement methods and hub subscriptions on WorkerClient
- Add Status and WorktreeState to SubtaskRowViewModel
- Add MergeTargetBranches, SelectedMergeTarget, CanMergeAll,
  MergeAllDisabledReason, MergeAllError, RecomputeCanMergeAll,
  MergeAllCommand, ReviewCombinedDiffCommand (Task 14 TODO)
  to DetailsIslandViewModel
- Add planning merge section to DetailsIslandView.axaml
  (merge target ComboBox + buttons + error label), gated on
  Task.IsPlanningParent
- Add 4 xUnit tests covering CanMergeAll logic and DTO shape

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 16:22:27 +02:00
mika kuns
6bdfa73150 fix(ui): align virtual list semantics and complete planning roll-up coverage 2026-04-24 16:03:27 +02:00
mika kuns
6d460ea996 fix(ui): planning parents roll up child status; children stay nested until parent Done 2026-04-24 15:47:47 +02:00
mika kuns
b7c60f5838 feat(ui): live task updates from worker events + planning polish
Wire TasksIslandViewModel to TaskUpdated/WorktreeUpdated/TaskMessage worker
events so rows refresh without a full reload; add ForegroundHelper to permit
wt.exe to take foreground on planning launch; misc UI polish on lists, task
rows and settings modal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 11:12:27 +02:00
mika kuns
0e116bec7b feat(ui): friendly error when deleting task with children 2026-04-23 19:22:28 +02:00
mika kuns
47b49743c0 feat(ui): unfinished planning session dialog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 19:19:16 +02:00
mika kuns
388a8c1fae feat(ui): planning entries in task context menu 2026-04-23 19:02:06 +02:00
mika kuns
309f84b388 feat(ui): planning commands and expand/collapse in TasksIslandViewModel
- Add IWorkerClient interface; WorkerClient implements it
- TasksIslandViewModel accepts IWorkerClient? and gains OpenPlanningSession,
  ResumePlanningSession, DiscardPlanningSession, FinalizePlanningSession,
  and ToggleExpand commands
- Regroup() is hierarchy-aware: children of collapsed planning parents are hidden
- InternalsVisibleTo ClaudeDo.Worker.Tests for Regroup()
- 4 new unit tests covering collapse/expand and guard logic

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:51:22 +02:00
mika kuns
229d4bbb2b feat(ui): TaskRowViewModel gains planning hierarchy flags
Adds ParentTaskId, IsExpanded, IsChild, IsPlanningParent, IsDraft, and
PlanningBadge to TaskRowViewModel with property-changed notifications.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:39:44 +02:00
mika kuns
ee2cbc92ef feat(ui): move list-settings access from lists pane to tasks header
The gear button on list rows became noisy and overlapped with row
selection. Moves it into the tasks island header where it targets the
currently selected list. Lists pane regains a cleaner row layout.
Also: swallow GetListConfig errors on fresh lists that have no row yet.
2026-04-23 17:40:27 +02:00
mika kuns
c8c8bb4a47 feat(ui): replay persisted task log when selecting a task
Read the task's LogPath on selection and feed each line through the
live-stream parser so Claude output stays visible across app restarts.
Tail-caps at 2000 lines to avoid flooding the UI.
2026-04-23 13:07:54 +02:00
mika kuns
6f725d12f5 feat(ui): add queueing and scheduling from task row context menu
- Right-click on a task row exposes Send to queue / Remove from queue
  and Schedule for... / Clear schedule actions.
- New virtual:queued list in the sidebar with live count.
- Sidebar counts are now computed (open per list, running, queued,
  review) and refreshed on task- and worker-side events.
- Sending a task to the queue wakes the worker so it starts immediately.
2026-04-23 13:07:48 +02:00