Skip to content

feat(task): cancel cascade interrupts live children + surface depth in history tree - #13

Merged
easonLiangWorldedtech merged 1 commit into
main-task-treefrom
pr-4-tree-ui
Aug 16, 2026
Merged

feat(task): cancel cascade interrupts live children + surface depth in history tree#13
easonLiangWorldedtech merged 1 commit into
main-task-treefrom
pr-4-tree-ui

Conversation

@easonLiangWorldedtech

Copy link
Copy Markdown
Owner

feat(task): cancel cascade interrupts live children + surface depth in history tree

Part of the Task Tree unified subtask management plan (issue #9, PR-4). Two focused deliverables:

1. Cancel cascade — interruptLiveChildren

cancelTaskInternal() already handled "cancelled task is a child" (marks itself interrupted, keeps parent delegated) but had no path for the reverse: cancelling a parent whose children are still running in the registry left them streaming as orphans.

New private method ClineProvider.interruptLiveChildren(parentTaskId):

  • reads the parent's persisted childIds
  • skips children already terminal (interrupted / completed) — never overwrites a terminal status
  • skips children not live in the registry (already aborted/abandoned or evicted)
  • for each remaining live child: aborts its instance (which also clears any inlineSubtask phase marker via abortTask()) and persists status: "interrupted" so the user can resume it later
  • wired into cancelTaskInternal() right after the parent's own abortTask() settles, fire-and-forget with a logged catch — no-op in the common single-open case where the child is itself the current task (handled by the existing interruption path)

The parent's delegation link is left intact, mirroring markDelegatedChildInterrupted() on the parent side.

2. Depth surfacing in the history tree

SubtaskTreeNode gains an optional depth field; buildSubtree(task, childrenMap, expandedIds, parentDepth = -1) now computes it:

  • prefers the persisted HistoryItem.depth (written by PR-1's backfill)
  • falls back to tree position (parentDepth + 1) for legacy items without a depth — an isolated root resolves to 0
  • propagates recursively so every node carries its nesting level, ready for a depth badge in the UI

Tests (~235 lines per plan)

  • src/__tests__/cancel-cascade.spec.ts (new, 4 cases): aborts live children + marks interrupted; skips terminal children (never overwrites completed/interrupted); skips non-live/evicted children; no-op with no children. Uses the existing makeProviderStub-style plain-object provider double pattern — zero as any.
  • webview-ui/src/components/history/__tests__/useGroupedTasks.spec.ts (+3 cases): depth from persisted field; legacy fallback to tree position (root=0, child=1, grandchild=2); explicit parentDepth argument honored. Existing 27 tests unchanged and passing.

Verification

  • pnpm run check-types — 11/11 packages pass
  • New suites: cancel-cascade 4/4; useGroupedTasks 30/30 (was 27)
  • Regression: provider-delegation, nested-delegation-resume, new-task-delegation all pass unchanged (9/9)
  • Full turbo lint (--max-warnings=0) clean across both packages; zero eslint suppression count increases

@easonLiangWorldedtech
easonLiangWorldedtech merged commit c214ba7 into main-task-tree Aug 16, 2026
8 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants