290 Commits
Author SHA1 Message Date
mika kuns 0d1e3b9a6f docs(explore-notes): document the kill-on-detach gotcha and ConPtyPaneHost reparenting 2026-08-06 12:57:42 +02:00
mika kuns 0878bae19e docs(explore-notes): point both drift checks at the merged state 2026-08-06 12:12:12 +02:00
mika kuns 20bce9b424 Merge branch 'claudedo/75514ee68371402b814638290af47cca' 2026-08-06 12:11:38 +02:00
mika kuns 5d1d2d89d0 fix(ui): suppress auto-open conflict resolver during MCP-driven merges
review_task/continue_merge on a planning parent always leaves conflicts in
the tree, and the UI auto-opened the resolver on every PlanningMergeConflict
broadcast regardless of who started the merge -- so a running Claude session
resolving a unit-merge conflict could race a human editing the same shared
checkout in a resolver window neither of them asked for.

PlanningMergeOrchestrator.StartAsync now takes an externallyDriven flag (set
by ExternalMcpService's MCP-driven review_task path, left false for the UI's
ApproveReview) that rides along on the PlanningMergeConflict broadcast. The
UI only auto-opens the resolver when it's false; otherwise it shows a
persistent banner with a manual "Open resolver" button, cleared on
PlanningMergeAborted/PlanningCompleted. A new GetActiveExternalConflictsAsync
query (checked against GitService.IsMidMergeAsync rather than the in-memory
flag alone) lets the UI resync the banner on reconnect instead of trusting a
one-shot broadcast that isn't replayed after a restart.

The childless single-task conflict path was checked and needed no change --
it only broadcasts the generic TaskUpdated, never PlanningMergeConflict.
2026-08-06 12:04:52 +02:00
mika kuns 0358bcf8b2 Merge branch 'claudedo/001ee94a1d8d46b0906f7466ea6beb32' 2026-08-06 12:04:47 +02:00
mika kuns e59f6c2438 fix(worker): surface empty review ranges and blocked children over MCP
preview_merge/preview_merge_set now report isEmpty (ahead==0, or
HandlerBaseCommit==HandlerHeadCommit for a worktree-less list-handler
task) instead of leaving an empty branch indistinguishable from a small
one. preview_merge also stops throwing for worktree-less handler tasks,
falling back to their fixed commit range. review_task's parent approve
returns emptyChildren, naming the Done children whose review range
contributed nothing before the unit merge lands. TaskRefDto/TaskDto now
expose roadblockCount so a CLAUDEDO_BLOCKED child is identifiable over
MCP, since it still reaches Done per the unified parent model.
2026-08-06 11:54:46 +02:00
mika kuns 46e177eb59 Merge claudedo/24acb89f61094773a0dc76d31bdae274 2026-08-06 11:43:19 +02:00
mika kuns 4a60c2bfa8 Merge branch 'claudedo/0733742e0da8407d8e2be1bc5886bf9b' 2026-08-06 11:40:47 +02:00
mika kuns 03c4ed4607 docs(explore-notes): point external-mcp drift check at the merged state 2026-08-06 11:39:12 +02:00
mika kuns f3e16412f4 Merge branch 'claudedo/c1d2a92d8d8c4705ac93d5f0b2cacaa0' 2026-08-06 11:38:32 +02:00
mika kuns db4177db83 docs(worker): evaluate planning-chain fork-base options, recommend fork-from-predecessor 2026-08-06 11:37:37 +02:00
mika kuns af16830060 feat(worker): add treatWaitingForChildrenAsBusy to wait_for_task_change
WaitingForChildren already counted as "changed" since it's outside Queued/Running,
so waiting on a planning parent returned immediately even though its children were
still running. The new opt-in flag (default false, unchanged behavior) keeps polling
through WaitingForChildren and only reports changed once the parent reaches
WaitingForReview or a terminal status.
2026-08-06 11:32:00 +02:00
mika kuns 8247a749a0 Merge claudedo/f9ee427d9f644715bafb55857ad8c3e8 2026-08-06 11:29:49 +02:00
mika kuns f8c48e2ed7 fix(worker): make list_tasks/batch_get_tasks lean by default
list_tasks on a list of ~100 verbosely-described tasks could return
390k+ characters in one call, blowing past the caller's token limit.
Both tools now default to lean TaskRefDto references (no
Description/Result) and take an includeDescription flag to opt back
into the full TaskDto payload — same flag-alongside-nullable-payload
idiom already used by BatchGetTaskResult/TaskConfigResult. get_task is
unchanged.
2026-08-06 11:25:32 +02:00
mika kuns 3e07536ee9 feat(worker): warn on near-duplicate titles in add_task/batch_add_tasks
add_task and batch_add_tasks now report up to 3 open (non-terminal)
tasks in the same list with a strongly overlapping title, so a
parallel agent can notice and mention a likely duplicate instead of
silently creating one. The task is always created regardless. Uses a
cheap normalized-word overlap heuristic (no embeddings/LLM call),
robust to German umlaut/digraph spelling variants. Breaking change:
AddTask now returns AddTaskResult { task, possibleDuplicates } instead
of a bare TaskRefDto; BatchAddTaskResult gained a PossibleDuplicates
field.
2026-08-06 11:24:17 +02:00
mika kuns 70322c203c Merge claudedo/7e54be27bc474883bc2389802123f55e 2026-08-06 11:13:30 +02:00
mika kuns 423ab7f2a9 chore(ui): remove dead AgentStripView fragment
AgentStripView was superseded by WorkConsole during the task-detail
redesign but never wired into any view and never deleted. Drops the
unused Border.agent-strip / diff-meter styles and the 14 agent.* locale
keys that only it referenced, and marks A4 in the feature-unification
spec as resolved by deletion.
2026-08-06 11:09:32 +02:00
mika kuns 68aa2f5f4b fix(ui): remove duplicate list-settings context menu entry
List settings were reachable via three doors (header button, context
menu, double-click). Drop the context menu entry, matching the same
cut already made for the "Let Claude handle it" entry point.
2026-08-06 11:07:31 +02:00
mika kuns 0f187d8e82 docs: record the verify-gate reach and the NumericUpDown null trap
review-merge: worktree-less approvals run the gate too, and all three UI merge
entry points handle verify_failed explicitly.
Ui gotchas: NumericUpDown.Value is decimal? and nulls while the box is empty.
2026-08-06 10:22:17 +02:00
mika kuns f106c890b3 fix(ui): refresh the run session id live, close the stale handoff pane
A task selected before its run started kept LatestRunSessionId null, so the
roadblock reply box and Continue stayed dead until it was re-selected.

The handoff left the Phase 1-2 tile open so its last message could be read, but
its process is gone by then and the terminal renders empty -- a dead
placeholder. It is closed on handoff now.

Also drops the WARN flood from worktree cleanup (already-unregistered worktree
and already-deleted branch are normal outcomes, not failures) and replaces the
fixed sleep in UsageGate_TransitionLogging_FiresOncePerChange with the polling
helper that already sits three lines below it in the same file.
2026-08-06 10:20:54 +02:00
mika kuns 730ecb1abc docs(open): mark the usage-monitor pass done and drop the light-theme checks
The app is dark-only (App.axaml pins RequestedThemeVariant="Dark", Tokens.axaml
has no light variant), so every "Dark/Light" line was unverifiable by
construction. Adds the roadblock-reply session-id finding from the same pass.
2026-08-06 10:02:14 +02:00
mika kuns b6ecbb13f5 docs(open): record the findings from the 2026-08-06 visual pass
Verified: max-turns hints, usage pill/modal, list-handler run end to end.
New findings: NumericUpDown null binding throws in the settings modal, the
verify gate is skipped for worktree-less tasks and unhandled in two of three
merge entry points, the handoff leaves an empty pane, worktree cleanup logs
already-done as WARN, orphaned git worktrees are invisible to the app, modal
bodies are clipped at the bottom, usage tables need formatting work.
2026-08-06 09:54:15 +02:00
mika kuns b5a8d58e62 docs(open): re-verify the 2026-07-24 findings and drop the fixed ones
Ten of the twelve listed bugs/nits are fixed in the code (outcome JSON,
subtask terminology, live child rows, AskUser in the detail island, Icon.Plus,
gear glyph, rename display, TurnsText, conflict Continue gate, ConPTY resume)
and the blocked-approve silent fail is handled by the WorkerHub throw. Adds the
open verification block for the planning-resume fix.
2026-08-06 09:10:50 +02:00
mika kuns e113987d2e docs(open): drop the verified 2026-07-27 visual-pass block, keep its design notes 2026-08-06 08:53:02 +02:00
mika kuns 4309c4cb08 docs(open): mark the MaxTurnsCeiling editor as shipped 2026-08-06 08:45:49 +02:00
mika kuns 1b0ecbe361 Merge branch 'main' into claudedo/4e19605838a3404f98624cb0e90195da
# Conflicts:
#	docs/open.md
#	src/ClaudeDo.Installer/CLAUDE.md
#	src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageView.xaml
#	src/ClaudeDo.Installer/Pages/SystemCheckPage/SystemCheckPageViewModel.cs
2026-08-06 08:36:58 +02:00
mika kuns 09e0772673 feat(claude-do): „Claude Help Me"-Button: Claude-Session zur Setup-Fehlersuch
Der Button, der aus „Problem erkannt" ein „Problem gelöst" macht: startet eine interaktive Claude-Session, die dem Nutzer beim Einrichten hilft.

## Warum externes Terminal
Der ConPTY-Stack (`PtyTerminalSession`, `ConPtyPaneView`) liegt in `ClaudeDo.Ui` und ist Avalonia — der Installer ist WPF und referenziert nur Data/Releases/Localization. Beim Fresh Install sind `app\`/`worker\` außerdem noch n

ClaudeDo-Task: 4e196058-38a3-404f-9862-4cb0e90195da
2026-08-06 08:25:36 +02:00
mika kuns 7e1b1177de feat(installer): add Diagnose section to SettingsWindow
Re-runs the environment checks against the installed configuration
(worker.config.json + detected install dir) without blocking navigation
and without auto-running on window open, only on a "Recheck" click.

Extracted the check-row rendering and check-run logic (busy state,
summary, Recheck command) out of SystemCheckPage into a shared
Checks/CheckListViewModel + Checks/CheckListView, composed by both
SystemCheckPage (wizard) and the new DiagnosePage (settings) instead
of duplicating it.
2026-08-06 08:22:45 +02:00
mika kuns b3a8373c70 Merge branch 'claudedo/852c2328ec8b4fc1bf143df203e1dc6c' 2026-08-06 08:01:25 +02:00
mika kuns 7c4bce63d3 Merge subtask 2026-08-06 07:54:04 +02:00
mika kuns cdfd0614dd Merge claudedo/616befd0f8a64dcb9e3dac9d6499de16 2026-08-05 22:45:32 +02:00
mika kuns 1d258a3e2c Merge claudedo/123b0241b5e94b69bfa592fde89c51aa 2026-08-05 22:44:47 +02:00
mika kuns a6af90ff0d docs(installer,worker): document Environment Checks + note unmerged prerequisite gap
Documents the Checks/ + SystemCheckPage feature (gating rule, check list,
FreshInstall-only placement) and the ExecutableResolver/.cmd-shim wiring in
ClaudeDo.Worker's ClaudeCliPreflight/ClaudeProcess. Adds docs/explore-notes/installer-preflight.md
(bumped/corrected against the actual implementation) and links it from the
explore-notes README and root CLAUDE.md.

The underlying code lives only on unmerged task branches (06aca9b3.../40272c0b...),
not on main yet, and two follow-up features ("Claude Help Me" button, Config-mode
Diagnose section) were never implemented because they blocked on that same missing
merge. Both gaps are called out explicitly in the new docs and in docs/open.md's
verification checklist, instead of being asserted as done.
2026-08-05 21:19:21 +02:00
mika kuns d43b5fcefc feat(worker-mcp): raise wait_for_task_change timeout, expose queue slot state
MaxTimeoutSeconds was 170s against runs that take tens of minutes, forcing
a dozen full-context wait rounds per long-running batch. Raise it to 900s
and raise MCP_TOOL_TIMEOUT in lockstep (ClaudeProcess + every
InteractiveLaunchSpecService launch spec) to 930000ms so the client
connection actually stays open that long instead of aborting first.

Add get_queue_state (QueueStateMcpTools): configured vs. effective
parallel-slot count (via QueueService.GetSlotCountsAsync, extracted from
the former GetEffectiveMaxParallelAsync), active slots with taskId +
startedAt including the run_task_now override slot, and queued tasks in
pick order -- so a caller can observe queue occupancy instead of inferring
it from maxParallelExecutions.
2026-08-05 20:47:57 +02:00
mika kuns a768bc4163 feat(worker): add get_effective_run_config MCP tool
Adds a read-only get_effective_run_config(taskId) tool that reports the
model/max-turns/effort/permission-mode/agent-path/system-prompt/skills a
task will actually run with, each tagged with its source (task/list/
preset/global), plus max-turns' raw requested value and clamp status.

Extracted the model/max-turns/agent-path resolution out of
TaskRunner.ResolveConfigAsync into EffectiveRunConfigResolver so the run
path and the new reporting tool share one codepath instead of risking
drift, per docs/explore-notes/worker-task-pipeline.md's max-turns trap.
2026-08-05 20:39:35 +02:00
mika kuns bee06bc307 docs(claude-do): Prompt-Audit: bekommen interaktive und autonome Sessions den
## Der Zweifel

Ein autonomer Agent und eine interaktive Session sollen sich unterschiedlich verhalten. Unklar war, ob beide denselben System-Prompt mitbekommen.

## Vorbefund (2026-08-05, beim Verfeinern erhoben — **selbst nachpruefen, nicht uebernehmen**)

Sie teilen ihn **nicht**. Pro Startweg:

| Startweg | Einstieg | System-Prompt |
|---|---|---|
| Autonomer Run | `ClaudeArgsBuilder.cs:69-73`

ClaudeDo-Task: b259a1c9a73846ce833f0b555fb1de79
2026-08-05 20:33:04 +02:00
mika kuns dce42a9c22 docs(explore-notes): root-cause --permission-mode auto + CLI/.NET preflight research 2026-08-05 18:57:07 +02:00
mika kuns bdee731376 Merge branch 'claudedo/f359858ac98a439593e459df9c5d0a5d' 2026-08-05 16:49:08 +02:00
Mika Kuns d15aa27707 fix:Improve Claude Mds 2026-08-05 16:46:02 +02:00
mika kuns 2700c3d817 fix(usage): stop 429s with an activity-dependent poll cadence + manual refresh
The usage monitor polled the undocumented OAuth usage endpoint every 60s and
earned 429s. It now polls every 5 min while any task is Running and every
15 min while idle (usage_poll_interval_active_seconds / _idle_seconds, both
clamped to >= 60; the old single usage_poll_interval_seconds key is gone).

A 429 comes back as UsageRateLimitedException carrying Retry-After and adds
exponential backoff on top, capped at 30 min and never shorter than the normal
cadence; the strike count resets on the first success. The schedule arithmetic
is the pure static UsagePollSchedule.NextDelay.

Since the idle cadence is slow on purpose, WorkerHub.RefreshUsage drives
UsageMonitorService.RefreshNowAsync behind a Refresh now button in the Usage
Monitor modal: an out-of-band poll that pushes the loop's next-due time out so
no double poll follows, with a 10s cooldown so click-spam can't earn a 429.

Staleness now measures against the slower (idle) interval so an idle worker
isn't flagged stale just for not polling.
2026-08-05 16:40:34 +02:00
mika kuns 08ac8bf7b1 feat(worker): clamp max-turns to a configurable ceiling
Runaway sessions were the single biggest cost driver: model_presets was
never persisted (stayed code-only), default_max_turns shipped at 100, and
ResolveMaxTurns had no upper bound, so a task/list override could run
hundreds of turns unchecked.

- TaskRunner.ResolveMaxTurns now clamps the resolved value to
  AppSettings.MaxTurnsCeiling (new column, default 80) and logs a warning
  with task id / requested / effective value when it clamps.
- default_max_turns default lowered from 100 to 40 (entity, EF config,
  and the seeded row via the new AddMaxTurnsCeiling migration).
- AppSettingsRepository.GetAsync backfills model_presets with the
  shipping defaults on first read instead of leaving the column null.
- Settings > General's per-model preset table and the task/list agent
  editor now show a hint when a set max-turns value exceeds the ceiling.
2026-08-05 15:40:02 +02:00
mika kuns 032debc780 docs(handoff): mark the 2026-08-05 list-handler run complete
All three brief tasks and the nine-child Usage Monitor unit are merged and main
verified green. Correct section 5: "exited with code 1 and no result" is a
catch-all, not a CLI crash — max_turns (sonnet presets default to 30 because
app_settings.model_presets is NULL) and the account session limit both surface
through the same message.
2026-08-05 14:28:36 +02:00
mika kuns cf9dd1cc94 docs(usage): document usage monitor & gate across CLAUDE.md files
Add a dedicated Usage Monitor & Gate section to Worker CLAUDE.md, wire
UsagePillViewModel/UsageMonitorModalViewModel and the new IWorkerClient
usage surface into Ui CLAUDE.md, and record open verification points
for the pill/modal visual pass and the real gate E2E in docs/open.md.
Data CLAUDE.md already covered the new entity columns and migration.
2026-08-05 14:13:06 +02:00
mika kuns 519ea5a8e0 Merge claudedo/8c1c213004574c4fad6beb75b84b70d7 2026-08-05 12:15:21 +02:00
mika kuns 1aaa40b894 Merge branch 'claudedo/0b2fbb48d44c41558c21d3464c0bd5c2' 2026-08-05 12:11:55 +02:00
mika kuns 3e7126b3f2 Merge branch 'claudedo/9e3071992eca4eb79057d2c675cc57ca' 2026-08-05 12:05:18 +02:00
mika kuns d2ca7fb500 feat(ui): add roadblock reply field to the ROADBLOCK card
A task that reports a roadblock but finishes successfully (Done/WaitingForReview/
Failed/Cancelled) had no way to answer it short of a full reset-and-rerun, losing
the run's context. Adds a reply textbox + Send button to the existing ROADBLOCK
card, modeled on the AskUser question card, that resumes the session via
ContinueTaskAsync with the user's own text. Gated on LatestRunSessionId (disabled
with a hint when there's nothing to resume); failures surface through the footer
error strip instead of a modal.
2026-08-05 11:49:33 +02:00
mika kuns c9ba1e2645 feat(worker): add post-merge verification gate for list merges
Per-list optional VerifyCommand (list_config.verify_command) runs via
VerifyCommandRunner in the list's working dir right after a successful
merge/continue-merge, before the task is allowed to reach Done. A
non-zero exit or timeout leaves the merge in place but keeps the task
out of Done and reports StatusVerifyFailed with an output excerpt
through MergeResultDto/review_task; no command configured behaves
exactly as before. Merges against the same repo are now serialized
per working dir so a running verify can't be interrupted by a second
merge landing mid-build. Adds the field to the List Settings modal
(en/de localized) and covers success/failure/timeout in
TaskMergeServiceTests + VerifyCommandRunnerTests.
2026-08-05 11:19:22 +02:00
mika kuns 47e2734357 Merge claudedo/b0317ec7aa1a4584ad2cca1e69cf8dd7 2026-08-05 09:23:05 +02:00
mika kuns c07c1f70a8 feat(mission-control): give the list handler its own review task
"Let Claude handle it" now creates one ClaudeDo task per run to host the
ConPTY session (Idle/IsManual, never queued) instead of an untracked
ad-hoc tile, so the run has a real title, diff, and review outcome.
Since the handler merges its own changes straight into the list's
working dir, the task never gets a WorktreeEntity; its review range
lives as new HandlerBaseCommit/HandlerHeadCommit columns on TaskEntity
instead, reusing the existing commit-range diff machinery and keeping
it out of the worktrees overview entirely.
2026-08-05 09:16:34 +02:00