The Online API now requires the "user" project role (claim
urn:zitadel:iam:org:project:roles) instead of an ALLOWED_USER_IDS allowlist.
- IOnlineAuthProvider: add GetAccessTokenAsync(forceRefresh) overload
- ZitadelAuthProvider: forceRefresh drops the cached token and re-runs the
refresh-token grant to mint a fresh, role-bearing token
- OnlineInboxApiClient: on 401, force-refresh and retry once; if still 401,
throw a clear "missing 'user' role" error
- OnlineSyncService: surface the 401 at Error level (no longer silent)
- UI: ZitadelTokenInspector decodes the access token after login and warns
early when the "user" role is absent (fail-open); shown in settings
- docs: online-inbox-api-contract reflects role-based access (no allowlist)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New Settings tab: enable toggle, config fields, sign-in/out + status.
OnlineLoginService runs the PKCE loopback flow (Duende.IdentityModel.OidcClient
7.1.0), opens the system browser, captures the callback, hands the refresh
token to the Worker. en/de localized. Fixes: loopback callback URL built from
host:port base (avoids doubled redirect path); PollIntervalSeconds threaded
through the state DTO so it loads instead of resetting to 60.
Visual layout + the live sign-in round-trip need manual verification.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add 16 missing members to IWorkerClient (IsReconnecting, WorkerLogReceivedEvent,
PrimeFired, LastApproveTarget, Refresh/RestoreDefaultAgents, UpdateAppSettings,
prime schedule CRUD, UpdateList/UpdateListConfig, all worktree ops).
Switch all production consumers off the concrete WorkerClient type; only
Program.cs/App host still resolves the concrete registration.
Update StubWorkerClient and FakeWorkerClient to satisfy the expanded interface.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Befund (bestätigt): src/ClaudeDo.Ui/ViewModels/Modals/DiffModalViewModel.cs, LoadAsync (~Zeile 116): bei FromCommitRange=true aber HeadCommit==null fällt der Ternary still auf GetBranchDiffAsync(WorktreePath, BaseRef) zurück. In diesem Modus ist WorktreePath aber das Listen-Working-Dir (Repo-Root, kein Worktree) — es wird ein falscher Diff angezeigt, ohne jeden Hinweis.
Änderungen:
1. Guard: From
ClaudeDo-Task: d667c80c-3f32-478c-8584-46aec78357b6
- UnifiedDiffParser detects added/deleted/renamed/binary files; diff
modal shows a file list, binary/empty placeholders, and can diff a
merged task by commit range after its worktree is gone
- DetailsIslandViewModel flags children needing attention (failed,
cancelled, awaiting review, or with roadblocks) on the parent
- GitService gains worktree head-commit/range support; planning chain,
merge orchestration, and session manager tweaks with updated tests
- refresh app/installer/worker icons
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extract the unified-diff parser into UnifiedDiffParser and the styled line
renderer into a reusable DiffLinesView control. The combined (planning) diff
now parses its unified-diff string and renders color-coded rows (green
additions / red deletions, file headers) identical to the per-task viewer
instead of dumping plain text into a TextBox.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a "Max parallel executions" setting to the General settings tab so
the queue can run more than one task concurrently. QueueService now
tracks multiple active slots and reads the limit from app settings each
cycle, so changes take effect without restarting the worker.
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>
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>
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>
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.
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>