Commit Graph
16 Commits
Author SHA1 Message Date
Mika Kuns 53e26f0340 feat(worker): report per-item progress on all 7 batch_* MCP tools
Each batch tool now sends an i/n progress ping via ProgressReporter.ReportItem
after processing every item, so a waiting agent doesn't see the MCP client's
300s idle-silence abort while the worker keeps looping. Covers BatchGetTasks,
BatchAddTasks, BatchUpdateTaskStatus, BatchCancelTasks, BatchDeleteTasks,
BatchSetMyDay, and BatchCleanupTaskWorktrees (the slowest of the seven, since
it does git work per task).
2026-08-17 08:56:32 +02:00
mika kuns 106c964410 feat(worker): surface task numbers in MCP tool return payloads
Adds Number alongside every task id in External/'s DTOs -- the two
central mappers (ToDto/ToRefDto -> TaskDto/TaskRefDto) plus every
DTO that carries a bare task id and bypasses them (batch results,
queue state, wait-for-change, config, attachments, handoff,
lifecycle, merge-preview-set, worktree list). Input resolution
(#123 as an argument) stays for slice 3.
2026-08-11 11:59:51 +02:00
mika kuns 66f7a8ae99 Merge branch 'claudedo/9f963a215bb34ca4a28050d4f39178d3' 2026-08-10 15:19:57 +02:00
mika kuns 8b75a92794 Merge branch 'claudedo/5c80a0aba5d9468a96cf809fc7a6e7a1' 2026-08-10 15:15:26 +02:00
mika kuns 333ce89eef Merge branch 'claudedo/16172942c1424a67a0499e01cefb7d60' 2026-08-10 15:08:51 +02:00
mika kuns d3155e6868 feat(queue): warn when the base branch has uncommitted changes
Queuing (update_task_status, batch_update_task_status) and run_task_now
now surface a non-blocking baseDirty warning (separate modified/untracked
counts) when the list's working dir has uncommitted changes at enqueue
time, since a new worktree forks from the commit tip and silently misses
them. BaseDirtyChecker caches per working dir for a few seconds so a
batch queue over many tasks in one list only shells out to git once. The
UI surfaces the same warning via the footer error strip on queue actions.
2026-08-10 14:30:33 +02:00
mika kuns a067a7bfff fix(mcp): report a Failed task's failureReason instead of a bare status
get_task/batch_get_tasks now return failureReason (max_turns|timeout|error|
cancelled|unknown) plus failureTurnsUsed/failureMaxTurns on a Failed task, so
max_turns (worktree usually fine, continue_task) is distinguishable from a
real error (reset_failed_task) without pulling get_task_log's raw NDJSON.
Classified and stamped onto TaskEntity by TaskRunner.MarkFailed via
TaskStateService.FailAsync; TaskRunEntity also keeps the CLI's raw
terminal_reason/result_subtype/errors for deeper diagnosis. reset_failed_task's
description now warns explicitly that it discards the worktree and points at
continue_task for max_turns. Surfaced on the task card's status-chip tooltip.
2026-08-10 14:20:00 +02:00
mika kuns ca6eb62b5c feat(mcp): truncate/select batch_get_tasks payload, expose roadblockText
batch_get_tasks with includeDescription=true had no size guard: 8 tasks'
full Description/Result serialized to a single 51k-char line, blowing past
the tool-result token budget and forcing a file/PowerShell workaround to
read it back. Roadblock text was also only reachable via a second get_task
call per task, since roadblockCount (in the lean ref) has no text sibling.

- descriptionMaxChars (default 1500, was unlimited) truncates Description
  and Result independently, flagged via *Truncated/*FullLength so a caller
  never silently works off a cut string.
- fields narrows taskFull to just the named properties, including the new
  roadblockText (the tail of Result after TaskRunner's roadblock marker) —
  reachable without pulling in the rest of Result/Description.
- taskFull is now BatchTaskDetailDto, a batch-only shape decoupled from
  TaskDto so get_task's own contract is untouched.
- The whole response is capped (MaxResponseChars); over that, the call
  throws naming which parameter (descriptionMaxChars/fields/taskIds) to
  adjust instead of shipping an oversized payload.

10 tasks with 5000-char descriptions (default settings) serialize to
~13.8k chars, comfortably under the 25k-char cap.
2026-08-10 14:19:16 +02:00
mika kuns 6c8ec245b3 feat(worker): dependsOn via MCP + honest staleness signal in merge preview
Adds a user/MCP-declared task dependency (DependsOnTaskId) distinct from the
planning chain's internal BlockedByTaskId: add_task/update_task can set it,
the queue picker skips a Queued task until the dependency reaches Done, a
Failed/Cancelled dependency leaves the dependent blocked instead of starving
silently, and setting a link rejects self-reference/unknown-id/cycles.
get_task/list_tasks/batch_get_tasks now report blocked/blockedReason, and
wait_for_task_change reports "Blocked" immediately instead of running out its
timeout on a task the picker will never claim.

preview_merge/preview_merge_set gain staleFiles: files a branch touches that
the target branch also changed since the branch's fork point, a more honest
staleness signal than `behind` alone.
2026-08-10 14:18:55 +02:00
mika kuns c792765ed3 refactor(mcp): rewrite external MCP tool descriptions for trigger clarity
Every tool description now leads with what the tool does AND when to reach for
it, since MCP clients rank tools by that text. Per-parameter prose moved onto
the parameters as [Description], exhaustive result-shape enumerations and
design/history rationale dropped, and the repeated boilerplate clauses
(lean-task-ref, batch cap, refused-while-Running) pulled into McpToolDocs,
which also documents the style for future tools.

Tool-level description text: 20494 -> 13605 chars (-34%); combined with the new
parameter descriptions 18517 (-10%).

Closes gaps that caused wrong calls rather than just verbose ones:
- list_task_attachments returns metadata only, no file content
- run_task_now shares continue_task's single override slot and throws when busy
- list_runs is ordered oldest-first and feeds get_run
- workingDir on create_list/update_list is an existing local git repo path,
  unvalidated until the first task run
- get_task_worktree's behind=0 also means the main ref was unreachable

Removes get_task_status_values: a whole tool entry for static reference text.
GetTask's description is now the canonical place for status meanings.
2026-08-07 09:25:45 +02:00
mika kuns f3e16412f4 Merge branch 'claudedo/c1d2a92d8d8c4705ac93d5f0b2cacaa0' 2026-08-06 11:38:32 +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 ecba12997a perf(worker): stop echoing task description from writing MCP tools
update_task, update_task_status, add_task, add_subtask, set_my_day,
abort_merge, review_task, and their batch variants now return a lean
TaskRefDto (id/listId/title/status/sortOrder/isMyDay) instead of the
full TaskDto. Those tools were re-sending the caller's own description
text back on every call, wasting a large share of session context on
list-handler-style runs. get_task/list_tasks/batch_get_tasks are
untouched and still return the full DTO.
2026-08-05 20:37:30 +02:00
mika kuns d569313598 feat(mcp): allow Done via update_task_status with worktree guard
External tasks finished outside a ClaudeDo run had no way to close out
their tracking task; update_task_status now permits Done alongside
Idle/Queued/Cancelled, refusing it when the task has an active
worktree so review_task stays the only path that merges.
2026-07-29 08:58:34 +02:00
Mika Kuns 1c94fbdb14 feat(worker): batch MCP tools for the external endpoint
Add seven best-effort batch variants of the single-entity external MCP
tools: batch_get_tasks, batch_add_tasks, batch_update_task_status,
batch_cancel_tasks, batch_delete_tasks, batch_set_my_day, and
batch_cleanup_task_worktrees. Each loops the existing ExternalMcpService
methods sequentially (scoped DbContext is not thread-safe), returns a
per-item result array so a failing item never aborts the rest, and
rejects empty or over-100-item batches. Merge/review stay single-task.
2026-06-26 16:11:51 +02:00