Replaces six scattered "chore" literals across TaskEntity, ListEntity,
WorkerHub, ListsIslandViewModel, ListNavItemViewModel and the inline
commit type list in ListSettingsModalViewModel.
Also fixes WorkerHub.UpdateAppSettings falling back to "bypassPermissions"
when AppSettingsEntity and the runtime default are "auto". The fallback
now matches the entity default.
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.
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>
Stops and starts the ClaudeDoWorker Windows service via
ServiceController. SignalR auto-reconnect plus the existing
ConnectionRestoredEvent handle the refresh, so the UI repopulates
counters and the active list once the worker is back up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
Adds "Set status" and "Tags" submenus to the row context menu (tags
list is built lazily on Opening from AllTags ∪ row tags). Replaces
the schedule flyout's separate DATE / TIME pickers with a single
ThemedDatePicker in date+time mode.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
New themed picker supports single-date, date+time, and range modes
(replaces inconsistent CalendarDatePicker / DatePicker / TimePicker
visuals). Used in the Prime schedules row to combine StartDate /
EndDate into a single range picker.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 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>
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.
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>
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.
Replaces "bypassPermissions" with "auto" as the default for new installs
and adds "auto" as the first option in the settings dropdown. Existing
rows keep their stored value; ClaudeArgsBuilder still maps the legacy
"bypassPermissions" -> "auto" at dispatch time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Introduces ~/.todo-app/prompts/{system,planning,agent}.md as the canonical
location for prompt content. The settings modal exposes "Open in editor"
shortcuts for each, and TaskRunner merges system.md (always) and agent.md
(for "agent"-tagged tasks) into the effective system prompt alongside the
existing global/list/task layers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Replaces fixed 260/*/320 columns with two GridSplitters between Lists/Tasks/Details. Min widths preserved (200/320/280). Right splitter hides when ShowDetails is false.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
Opens a modal when PlanningMergeConflict fires, listing conflicted files
with options to open in VS Code, continue, or abort the merge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
- 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>
Adds ParentTaskId, IsExpanded, IsChild, IsPlanningParent, IsDraft, and
PlanningBadge to TaskRowViewModel with property-changed notifications.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
Self-update for app and installer. Integrates cleanly with the
worker-log-footer feature that landed on main in parallel — the
shell VM now carries both worker-log state and update-check state,
and MainWindow hosts both the update banner and the footer log line.
Conflict resolved in IslandsShellViewModel.cs: kept nullable property
types from main's test-only parameterless constructor work, and added
the UpdateCheck property exposing the injected service.