fix(merge): conventional merge-commit default and live verify progress

The merge commit message was hand-rolled per caller ("Merge task: <title>",
"Merge <branch>", "Merge subtask") and ignored the task's commit type. Every
caller now passes a blank message and TaskMergeService fills in
CommitMessageBuilder.BuildMerge -> {commitType}(list-slug): merge <title> plus the
ClaudeDo-Task trailer; the merge modal prefills it from GetMergeTargets.

A merge whose list has a verify command holds the MergeTask call for minutes (5m46s
on this repo), during which the modal only disabled its button - no spinner, no
message, so a landed merge looked like a dead app. TaskMergeService now broadcasts
MergeProgress(taskId, phase, elapsedSeconds) for the merging and verifying phases
(re-reported every 30s) plus a WorkerLog line when verify starts; the modal shows a
spinner and the localized phase.
This commit is contained in:
mika kuns
2026-08-11 19:14:36 +02:00
parent fc9df7f9ac
commit cad0582b37
22 changed files with 405 additions and 31 deletions
+2 -1
View File
@@ -120,7 +120,7 @@ Full flow, invariants, and model/effort/max-turns resolution (including the low-
- **ClaudeArgsBuilder** — `--model`, `--effort`, `--max-turns`, `--append-system-prompt`, `--agents`, `--json-schema`, `--resume`
- **StreamAnalyzer** — parses NDJSON; extracts session_id, token counts, turn counts, result text, structured output. Replaced MessageParser.
- **WorktreeManager** — worktrees on `claudedo/{taskId[:8]}` branches; commits with semantic messages, updates DB with head commit + diff stats
- **CommitMessageBuilder** — `{commitType}(slug): title\n\ndescription\n\nClaudeDo-Task: taskId`
- **CommitMessageBuilder** — `{commitType}(slug): title\n\ndescription\n\nClaudeDo-Task: taskId`; `BuildMerge` is the merge-commit variant (`{commitType}(slug): merge title` + trailer). **Every merge caller passes a blank commit message on purpose**`TaskMergeService` fills in `BuildMerge` from the task's commit type and its list's name, which is the only place that knows both. Don't reintroduce a caller-side literal.
- **TaskResetService** — discards a failed task's worktree, resets the row to Idle, preserves run history
- **AgentFileService** — manages `~/.todo-app/agents/*.md`; list/refresh via SignalR
- **LogWriter** — async StreamWriter wrapper, auto-creates parent dirs
@@ -168,6 +168,7 @@ launch specs · worktrees · agents/settings/lists · reports/notes/prep · diag
- `PrepStarted`
- `PrepLine`
- `PrepFinished`
- `MergeProgress`
- `PlanningMergeStarted`
- `PlanningSubtaskMerged`
- `PlanningMergeConflict`