Commit Graph

792 Commits

Author SHA1 Message Date
mika kuns
0d1475cb7a fix(claude-do): Maximize button hides the window instead of maximizing
## Bug
Clicking the maximize control in the custom title bar makes the main window disappear/hide instead of filling the screen. Restore is then hard or impossible.

## Where
`MainWindow` uses custom client-area chrome, so the OS does not manage maximize:
- `src/ClaudeDo.Ui/Views/MainWindow.axaml:14-16` — `WindowDecorations="BorderOnly"`, `ExtendClientAreaToDecorationsHint="True"`, `ExtendClientAr

ClaudeDo-Task: 7d3d9501a8eb4111b9d433fd917f5a22
2026-06-15 15:08:02 +02:00
mika kuns
cfe23cdd23 fix(online-inbox): invalidate cached access token when the signed-in user changes
ZitadelAuthProvider cached the access token in memory and only re-read the
refresh token when the cache expired. Re-signing as a different user saved a
new refresh token but the worker kept serving the previous user's cached
access token until it expired — so sync (and ownerId stamping) continued under
the old identity.

Track the refresh token that minted the cached token and invalidate the cache
when the stored refresh token changes (user switch or sign-out). Switching
users now takes effect on the next sync without a worker restart.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 10:38:31 +02:00
mika kuns
cee051bb6d feat(online-inbox): carry ownerId on sync to prepare for multi-user
Plumb a per-resource owner (Zitadel sub) through the sync contract without
enforcing isolation client-side — the server stays the authority.

- Dtos: add optional ownerId to RemoteList/RemoteTask/MirrorTask
- JwtClaims: decode the sub claim from the access token (never throws)
- OnlineSyncService: stamp ownerId on pushed lists + mirror; defensively skip
  pulled tasks owned by a different user (unowned tasks still sync, so
  single-user behavior is unchanged)
- docs: contract documents ownerId + multi-user readiness

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:57:39 +02:00
mika kuns
23c3065f20 feat(online-inbox): gate access on Zitadel "user" project role
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>
2026-06-10 13:46:17 +02:00
mika kuns
80a2de6c74 feat(ui): Online Inbox settings tab + auth-code/PKCE login
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>
2026-06-10 11:02:14 +02:00
mika kuns
17c7ff517a feat(worker,ui): Online Inbox config + auth hub plumbing (Phase 2)
Hub: GetOnlineInboxState / SetOnlineInboxConfig / SetOnlineInboxAuth /
ClearOnlineInboxAuth. WorkerConfig.SaveOnlineInbox persists only the
online_inbox section. OnlineTokenStore + config registered always so hub
methods work when sync is disabled. IWorkerClient surface + all test fakes
synced. RedirectUri config (default http://localhost:8765/callback).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 10:49:49 +02:00
mika kuns
8b347de131 fix(worker): preserve API base path in Online Inbox client
The API base URL is https://claudedo.kuns.dev/api — leading-slash request
paths discarded the /api segment. Use relative paths so they nest under the
base. Tests now use a /api/ base to guard the regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 10:35:30 +02:00
mika kuns
619bc0c38d feat(worker): real ZitadelAuthProvider (refresh-token grant, auth-code+PKCE)
Headless refresh-token -> access-token exchange via OIDC discovery + token
endpoint. Cached to expiry (60s margin), thread-safe, persists rotated refresh
tokens, graceful null on invalid_grant/network errors. Wired into DI when
online_inbox is enabled. Interactive PKCE login (UI) still pending the
registered redirect URI. 7 tests, stubbed HttpMessageHandler.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 10:08:33 +02:00
mika kuns
1ac9ced0bd feat(worker): Online Inbox sync engine (Phase 1)
Optional, opt-in (online_inbox.enabled, default false → zero network).
Worker-side reconcile loop: pull web-created tasks down as Idle, push the
list catalog and the Idle backlog mirror up. Auth behind IOnlineAuthProvider
(StaticTokenAuthProvider default; ZitadelAuthProvider stubbed for Phase 2).
DPAPI refresh-token store. 35 tests, no real network/Zitadel/Claude.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 09:55:20 +02:00
mika kuns
23ff3916cc docs: close out the review round in open.md, sync CLAUDE.md with merges
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 00:40:55 +02:00
mika kuns
e272053e72 chore(claude-do): refactor(ui): DetailsIslandViewModel (1431 Zeilen) in Sektio
Kontext: src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs ist mit 1431 Zeilen ein God-VM mit ~12 Concerns (Log-Streaming, Titel/Description-Editing, Subtasks, Child-Outcomes, Merge-Preview/-Targets, Diff, Agent-Settings-Overrides, Notes-Mode, Prep-Mode, Tabs, Session-Outcome/Roadblocks, Worktree-Info). Jedes neue Feature landet dort.

Änderungen — drei klar abgrenzbare Sektionen als ei

ClaudeDo-Task: 483e419f-1ec8-46ba-986b-8b90d6596b49
2026-06-10 00:31:09 +02:00
mika kuns
74ca2e0dcd fix(worker): queue dispatches skip the StartRunning re-claim
The picker claims Queued->Running atomically before dispatch; the new
StartRunningAsync guard then rejected every queue-dispatched run. Add
alreadyClaimed to RunAsync/ContinueAsync (queue passes true, override
slot keeps the guard) and align the routing tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 23:59:56 +02:00
mika kuns
0cba9f9640 Merge task branch for: fix(worker): Abort-Pfad für unterbrochenen Unit-Merge nach Worker-Restart 2026-06-09 23:46:37 +02:00
mika kuns
c6534165b2 Merge task branch for: fix(worker): FailAsync-Guard untersuchen — ist Queued→Failed erreichbar/gewollt? 2026-06-09 23:46:18 +02:00
mika kuns
290b4a602a Merge task branch for: refactor(hub): Konflikt-Merge-Methoden eindeutig benennen (ContinueMerge → ContinueConflictMerge) 2026-06-09 23:45:49 +02:00
mika kuns
fe73f45b74 fix(worker): document and test Queued→Failed guard in FailAsync
OverrideSlotService dispatches RunAsync before calling StartRunningAsync,
so a preflight failure (list not found, worktree setup) can reach MarkFailed
while the task is still Queued. The guard is intentional, not dead code.

- Add comment in FailAsync explaining the OverrideSlotService preflight gap
- Add FailAsync_FromQueued_TransitionsToFailed test
- Update CLAUDE.md transition table with the precise rationale

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:41:12 +02:00
mika kuns
d2a08d2cda chore(claude-do): refactor(hub): Konflikt-Merge-Methoden eindeutig benennen (C
Kontext: Auf der Hub/Client-Ebene existieren zwei fast gleichnamige Methodenpaare mit unterschiedlicher Semantik: ContinueMerge/AbortMerge (Single-Task-Konflikt-Resolver, Layer C) vs. ContinuePlanningMerge/AbortPlanningMerge (Unit-Merge eines Parents mit Kindern). Verwechslungsgefahr.

Änderungen (NUR die Hub/Client/UI-Ebene umbenennen):
1. src/ClaudeDo.Worker/Hub/WorkerHub.cs: ContinueMerge → Con

ClaudeDo-Task: 5f2e0f88-d4c9-490b-95a7-46244465dbb6
2026-06-09 23:36:18 +02:00
mika kuns
fb1d799b82 fix(worker): stateless AbortPlanningMerge after worker restart mid-merge
PlanningMergeOrchestrator._states is in-memory. A worker restart during a
conflict pause left the list repo mid-merge with no recovery path: both
ContinuePlanningMerge and AbortPlanningMerge threw "no in-progress merge",
and re-Approving failed on the IsMidMergeAsync guard.

AbortAsync now falls through to a stateless path when no _states entry exists:
it looks up the parent's list WorkingDir and, if the repo is mid-merge, runs
git merge --abort there directly, then broadcasts PlanningMergeAborted.
Parent remains WaitingForReview — the next Approve restarts the unit merge
(already-Merged child worktrees are skipped as before).

ContinueAsync error message now points to AbortPlanningMerge as the recovery
action. StartAsync mid-merge guard also carries an actionable hint.

Tests: AbortAsync stateless + mid-merge (restart recovery), AbortAsync
stateless + clean repo (clear error).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:35:08 +02:00
mika kuns
12fdb55a8e chore(claude-do): fix(worker): TaskRunner bricht ab, wenn StartRunningAsync fe
Befund (bestätigt): src/ClaudeDo.Worker/Runner/TaskRunner.cs:101 (RunAsync) und :211 (ContinueAsync) ignorieren das TransitionResult von _state.StartRunningAsync. Race-Szenario: Der QueuePicker claimt Queued→Running atomar; ruft der Override-Pfad (RunNow) kurz danach RunAsync für denselben Task auf, schlägt StartRunningAsync fehl (0 rows affected), der Runner startet Claude aber trotzdem → derselb

ClaudeDo-Task: 44f86be2-7f3d-462e-98b3-eb94c0174eea
2026-06-09 23:32:57 +02:00
mika kuns
eee5c99e2f Merge task branch for: fix(ui): DiffModal — Commit-Range ohne HeadCommit zeigt stillen Falsch-Diff 2026-06-09 23:21:56 +02:00
mika kuns
37df51475e Merge task branch for: fix(worker): FinalizeParentDoneAsync über TaskStateService statt Status-Direkt-Write 2026-06-09 23:21:35 +02:00
mika kuns
b5417f6b09 refactor(ui): bring IWorkerClient to parity with WorkerClient
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>
2026-06-09 23:15:05 +02:00
mika kuns
7e739afafb chore(claude-do): fix(ui): DiffModal — Commit-Range ohne HeadCommit zeigt stil
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
2026-06-09 23:14:37 +02:00
mika kuns
e9e4ad8fbc fix(worker): route FinalizeParentDoneAsync through TaskStateService
Replaces the direct EF Status write in PlanningMergeOrchestrator with
_state.ApproveReviewAsync, enforcing the TaskStateService invariant as
sole owner of Status writes. Handles the improvement-parent path where
TaskMergeService already approved the parent's own worktree during the
drain (status == Done on entry → still success). If the parent was
concurrently cancelled, the transition guard rejects the approve,
PlanningCompleted is not broadcast, and the cancelled status is
preserved. ApproveReviewAsync now also sets FinishedAt.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:13:30 +02:00
mika kuns
c27a179d2b feat(worker): let Claude set the cheapest model per generated task via MCP
AddTask, planning CreateChildTask, and SuggestImprovement now accept an
optional alias-validated model (haiku/sonnet/opus; blank = inherit) so the
model is chosen at creation time instead of a follow-up set_task_config call.
The planning, system, and improvement prompts instruct Claude to pick the
cheapest capable model (haiku < sonnet < opus).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 22:22:17 +02:00
mika kuns
49046310ef docs: refresh CLAUDE.md files and open.md to current code state
- Ui CLAUDE.md rewritten around the islands architecture (old
  MainWindow/TaskList/StatusBar VMs no longer exist)
- Worker: folder layout (Refine/, Lifecycle/Planning extras), full hub
  method/event surface, external MCP tool inventory
- Data: complete GitService operation list incl. commit-range diffs
- App: missing DI registrations; Tests: current test-area overview
- root: project list (Localization, Installer, six test projects) and
  honest docs index; plan.md/improvement-plan.md marked historical
- open.md: date bump + visual check for new diff viewer / attention band

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-09 22:00:55 +02:00
mika kuns
f21c65be18 feat(ui): richer diff viewer + surface child roadblocks on parents
All checks were successful
Changelog / changelog (push) Successful in 1s
Release / release (push) Successful in 38s
- 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>
2026-06-09 16:40:59 +02:00
mika kuns
c300f8c313 docs: document the unified parent-task model
Add WaitingForChildren to the status tables, document the single parent
lifecycle (planning + improvement) and approve-merges-the-whole-unit across
the root, Worker, and Data CLAUDE.md files.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:46:02 +02:00
mika kuns
d6e0953293 feat(worker): allow cancelling a WaitingForChildren parent
Add WaitingForChildren to the CancelAsync guard so a parent waiting on its
children can be cancelled.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:44:18 +02:00
mika kuns
a8b86e25e6 feat(ui): single approve action merges the whole unit
Approve & Merge is now the only review+merge entry. For a parent with
children it drives the unit merge via the worker (conflicts still surface
through the existing PlanningMergeConflict dialog); the separate Merge All
Subtasks button, MergeAllCommand, CanMergeAll plumbing, and the dead
MergeAllPlanningAsync client method are removed. Combined-diff preview and
conflict continue/abort are kept.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:43:04 +02:00
mika kuns
1abb429f12 feat(worker): approve drives the unit merge for parents with children
ApproveReview routes a parent that has children through
PlanningMergeOrchestrator (merge parent + each Done child, set parent Done,
conflict continue/abort) instead of the parent-only ApproveAndMergeAsync.
Childless tasks are unchanged. Removes the now-redundant MergeAllPlanning hub
method (UI rewiring follows separately).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:32:33 +02:00
mika kuns
12732d6dc9 feat(worker): planning finalize enters WaitingForChildren
A finalized planning parent now joins the unified parent lifecycle:
WaitingForChildren while its child chain runs (or WaitingForReview directly
if it has no children), advancing to review like an improvement parent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:19:29 +02:00
mika kuns
b3a2daf40d refactor(worker): single parent-advance path for planning + improvement
Collapse TryCompleteParentAsync (planning -> Done) and
TryAdvanceImprovementParentAsync (improvement -> WaitingForReview) into one
TryAdvanceParentAsync that surfaces any WaitingForChildren parent for review
once all children are terminal. Planning parents no longer auto-complete.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 11:14:43 +02:00
mika kuns
f56cc617c3 fix(worker): mark task Done on every successful merge path, not just approve
Generalizes the previous merge_task fix: the WaitingForReview->Done transition
now lives in TaskMergeService.MergeAsync/ContinueMergeAsync, so the UI Merge
button (WorkerHub.MergeTask), conflict-merge, continue-merge and the external
MCP all land a merged task in Done. ApproveAndMergeAsync no longer double-approves.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:41:08 +02:00
mika kuns
ca8326c4c5 fix(mcp): merge_task marks the task Done after a successful merge
merge_task only flipped the worktree to Merged; it never transitioned the task
status. With allowWaitingForReview this left a merged task stuck in
WaitingForReview. Approve it to Done on a successful merge (a Done task is
already terminal). Mirrors the ApproveAndMergeAsync review flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:36:26 +02:00
mika kuns
f5d165baae fix(data): drop unique index on lists.name (allow duplicate list names)
The startup-race hardening added a global unique index on lists.name, but
duplicate list names are legitimate and the index broke 8 Worker tests that
seed same-named lists. The seeder race is already handled by the atomic
INSERT...WHERE NOT EXISTS, so the index is redundant. Keep the de-dup migration
step, remove the unique index from config, migration and model snapshot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 10:15:42 +02:00
mika kuns
61a40d549b Merge task branch for: Data hardening: per-connection FK pragma + startup seed/appsettings race 2026-06-09 10:07:05 +02:00
mika kuns
5723b81992 Merge task branch for: Worker hardening: CLI arg injection, stuck-Running, planning-chain wedge, Fail guard 2026-06-09 10:06:59 +02:00
mika kuns
7f1a14ab80 fix(data): harden FK pragma per-connection and seed concurrency
- Add SqliteForeignKeyInterceptor (DbConnectionInterceptor) registered via
  OnConfiguring so every IDbContextFactory-created context runs
  PRAGMA foreign_keys=ON, not only the MigrateAndConfigure context.
- DefaultListsSeeder: replace TOCTOU read-then-insert with atomic
  INSERT … SELECT … WHERE NOT EXISTS — one SQLite writer lock, no race.
- AppSettingsRepository.GetAsync: catch DbUpdateException on the
  get-or-create path and re-read so concurrent startup cannot throw.
- Migration 20260609000000_UniqueListName: de-duplicates empty list rows
  (startup-race leftovers) then adds a UNIQUE index on lists.name.
- ForeignKeyTests: verifies ON DELETE SET NULL (blocked_by_task_id) is
  enforced on a fresh DbContext with no manual PRAGMA call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:05:41 +02:00
mika kuns
33bdff8a6e fix(worker): harden CLI injection, stuck-Running, chain wedge, and Fail guard
1. ArgumentList (fix injection): ClaudeArgsBuilder.Build() now returns
   IReadOnlyList<string>; ClaudeProcess populates ProcessStartInfo.ArgumentList
   instead of Arguments, so values like system prompts are never shell-split.
   DailyPrepPrompt, RefinePrompt, and WeekReportService migrated similarly.
   All IClaudeProcess fakes updated.

2. ContinueAsync exception guard: wrap RunOnceAsync in try/catch matching
   the RunAsync pattern so an unexpected exception never leaves the task
   stuck in Running status.

3. Planning chain cascade: OnChildFinishedAsync now calls CancelAsync on
   the immediate blocked successor when a child fails or is cancelled,
   triggering a recursive cascade that clears the entire remaining chain
   instead of leaving it wedged.

4. FailAsync guard: restrict valid source states to Running and Queued;
   WaitingForReview -> Failed is now rejected, preventing an invalid
   transition that could corrupt the review workflow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 10:05:40 +02:00
mika kuns
b5cf19b19a Merge task branch for: MCP: add missing external tools + fix status enum, branchDeleted, merge-from-review 2026-06-09 10:00:11 +02:00
mika kuns
9f19a714f7 feat(mcp): add get_task_config, continue_task; fix status enum, branchDeleted, merge-from-review
- ConfigMcpTools: add get_task_config read-back (was write-only)
- ExternalMcpService: add WaitingForChildren to ListTasks filter and GetTaskStatusValues
- ExternalMcpService: add continue_task tool wrapping QueueService.ContinueTask
- ExternalMcpService: add allowWaitingForReview param to merge_task (default false)
- ExternalMcpService: fix CleanupTaskWorktree branchDeleted — now uses real branch-delete outcome
- WorktreeMaintenanceService: TryRemoveAsync returns (Removed, BranchDeleted) tuple; ForceRemoveResult gains BranchDeleted field
- Tests: 9 new cases covering all five changes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 09:57:47 +02:00
mika kuns
b672c9aaf3 fix(git): serialize concurrent worktree add to prevent commondir race
Parallel task starts called 'git worktree add' simultaneously; git's shared
.git/worktrees metadata mutation isn't concurrency-safe and one add failed with
'failed to read .git/worktrees/<other>/commondir'. Serialize adds behind a
process-wide gate plus a bounded retry on the transient error.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:55:39 +02:00
mika kuns
01e0c1d794 fix(ui): dispose VM subscriptions/timers, guard offline Stop, align review delta-path
- DetailsIslandViewModel/TasksIslandViewModel/ListsIslandViewModel: implement
  IDisposable, unsubscribe Loc.LanguageChanged and worker events (memory leaks).
- IslandsShellViewModel: dispose the three System.Timers.Timer instances.
- StopAsync: guard on Task/IsRunning/IsConnected and wrap CancelTask in try/catch.
- TaskMatchesList virtual:review now matches WaitingForReview (aligns with ReviewFilter).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:53:58 +02:00
mika kuns
00a065bf7f fix(review): populate review queue from WaitingForReview tasks
ReviewFilter matched Status==Done && active worktree, but a successful run
lands a task in WaitingForReview, so the Review virtual list was always empty.
Match WaitingForReview instead; update VirtualFilterTests accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:53:57 +02:00
mika kuns
763732a9b3 feat(ui): surface agent roadblocks and run outcome in the detail pane
- Parse CLAUDEDO_BLOCKED roadblocks out of the run result and show them in a
  colored card between Details and Output (ApplyOutcome / ShowRoadblockCard).
- Show the run outcome summary as an OUTCOME card in the Output tab, loaded from
  the task result (falls back to the run's ErrorMarkdown) and refreshed on finish.
- Guard the Session tab so it only appears when there are child outcomes.
- Make console resize per-task and proportional (description capped at 2/3,
  console floored at ~1/3) so a long description no longer spills over the footer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:34:37 +02:00
mika kuns
a41b8de47a feat(i18n): localize task-header, task-row and prime-schedule tooltips
Replace hardcoded tooltips with loc keys (kill-session, delete-task, toggle-subtasks, agent-suggested, star, remove-schedule) and drop the unused console.maximizeTip key; en/de kept in parity.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 09:34:26 +02:00
mika kuns
7f173daecb feat(ui): wire layer A/B conflict seams to the inline resolver 2026-06-05 11:12:42 +02:00
mika kuns
e71c0ed24f merge(layer-b): multi-worktree batch-merge cockpit 2026-06-05 11:09:09 +02:00
mika kuns
d450153183 merge(layer-c): inline conflict resolver + worker conflict plumbing 2026-06-05 11:09:02 +02:00