Drop the removed tag system, fix the retired Manual status and the atomic
queue-claim location, refresh the App DI registrations to the Islands VMs,
update the Data table list, correct a stale test reference, and document the
interface-folder and single-consumer-fold conventions plus the .NET 8 build path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Unify the near-identical HandleFailure/MarkFailed into a single MarkFailed that
always persists the failed state and never throws, and replace the inline
null-if-blank checks in ListMcpTools with the existing extension.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
The PlanningMergeEvents record types were never instantiated (the broadcaster
uses identically-named methods), and RunNowRequestedEvent had no subscribers.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move interface declarations into per-area Interfaces/ subfolders, merge the
small task-list filter classes into StatusFilter/SmartFlagFilter, and simplify
related services, converters and hub DTO handling.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wire ListMcpTools, ConfigMcpTools, RunHistoryMcpTools, AgentMcpTools,
LifecycleMcpTools, and AppSettingsMcpTools into the external MCP
container and expose them via WithTools<>().
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- GetTaskLog reads at most last 256 KB; prepends truncation marker if file exceeds cap
- Wrap temp-file cleanup in finally block to prevent leak on assertion failure
- Add GetRun_NotFound_Throws, GetTaskLog_RunExistsButNoLogPath_Throws, and GetTaskLog_LargeFile_ReturnsTruncatedTail tests
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
A LocalSystem Windows service can't see the logged-in user's Claude CLI
authentication, so the worker now runs as the current user via a hidden
per-user logon Scheduled Task with restart-on-failure.
- Worker is WinExe (no console window) with a Serilog rolling file sink and
a single-instance mutex so the logon task, app ensure-running, and Restart
button can't fight over the SignalR port.
- Installer replaces the service steps (register/start/stop) with autostart
task steps, migrates the legacy ClaudeDoWorker service away on update, and
removes the task on uninstall. ServicePage drops the service-account UI.
- UI gains a WorkerLocator; the app ensures the worker is running at startup
and the Restart button kills+relaunches this install's worker process.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Default to LF, force CRLF for Windows script/solution files, and mark
common binary types — silences the CRLF-on-commit warnings.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a StubWorkerClient base implementing the full IWorkerClient surface so
the planning/conflict/diff test fakes only override the members they exercise.
Eliminates the constructor-drift duplication across the three fakes.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
System.Version can't parse SemVer prerelease ("-alpha") or MinVer build
metadata ("+sha") suffixes, so an installed 1.0.2-alpha was treated as
unparseable. Reduce both sides to their numeric core before comparing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
Long folder paths in monospace pushed the Open buttons past the 480px
window edge. Widen to 620px, disable horizontal scroll so paths trim, and
add column spacing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The IWorkerClient.ListUpdatedEvent member was added without updating three
test fakes, breaking compilation of the Ui.Tests project.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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>
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>
Worker log broadcasts arrive on a SignalR thread; raising the event
directly let UI subscribers touch bindable state off-thread.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 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>
Apply SystemDecorations=BorderOnly + ExtendClientAreaTitleBarHeightHint=-1
to WorktreesOverviewModalView and WorktreeModalView for reliable OS resize
borders. Replace SelectedFileDiff SelectableTextBlock with per-line
ItemsControl using WorktreeDiffLineKind coloring via DiffLineKindToBrushConverter.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Drop outer Border wrapper in WorktreesOverviewModalView so Avalonia edge
resize handles reach the window frame. Add split pane to WorktreeModalView
with file tree on left and per-file unified diff on right; wire SelectedNode
via SelectedItem TwoWay binding + SelectionChanged fallback; add
GetFileDiffAsync to GitService.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restyle to match ListSettingsModalView: custom title bar, DeepBrush
toolbar, LineBrush footer, SurfaceBrush outer border, no system chrome
- Add column header row (TASK / BRANCH / STATE / DIFF / AGE) with
TextFaintBrush + MonoFont + LetterSpacing, separator line below
- Replace wt-row style with task-row-equivalent: transparent bg,
CornerRadius 8, 1px border, :pointerover + .selected transitions
- Add IsSelected to WorktreeOverviewRowViewModel; SelectRow() helper
on modal VM clears previous selection before setting new one
- Wire OnRowTapped in code-behind for click-to-select
- Wire ShowDiff: VM takes Func<WorktreeModalViewModel> factory, builds
diffVm and delegates window creation to both call sites (MainWindow
and ListsIslandView); register Func<WorktreeModalViewModel> in DI
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove StatusMessage reset from LoadAsync so CleanupFinished result survives the reload; reset moved to Refresh command only. Also rename German context-menu label to "Worktrees…".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
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>
Old open.md was dated 2026-04-13 and predated Planning Sessions, Prime
Claude, Self-Update, External MCP, editable status/tags, BlockedBy
chains, and the worker state consolidation. New version audits each
plan/improvement-plan item against the source tree, marks DONE/PARTIAL/
OPEN with file evidence, adds falsifiable pass-criteria to the
verification matrix, and lists the slices that shipped between
2026-04-13 and 2026-04-30 in a dedicated §0.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Worker now runs `claude --version` before listening; on non-zero exit
it logs critical and exits with code 1. Skippable via env var
CLAUDEDO_SKIP_CLI_PREFLIGHT=1 for environments without the CLI (tests,
dev). Closes verification step 2 / open.md item 3.1.
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>
SetupChainAsync now sequences only non-terminal children (Idle/Queued).
Done/Failed/Cancelled rows are left in place so a re-run on a partially
executed chain keeps history intact and only reshapes the tail. Running
children abort the op since the chain cannot be reshaped mid-flight.
First non-terminal child is explicitly unblocked.
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>
Adds ForceSetStatusAsync on ITaskStateService (no transition guards)
plus SetTaskStatus / SetTaskTags / GetAllTags hub methods so the UI
can edit a task's status and tags directly. PlanningHubTests ctor
updated for the new ITaskStateService dependency.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Queueing a task is itself the explicit "run me" signal — the extra
tag/list filter was redundant and surprised users whose queued tasks
were silently skipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>