Fix delegation link loss across interrupt/resume; type NewTaskTool provider call (#18) - #1270
Fix delegation link loss across interrupt/resume; type NewTaskTool provider call (#18)#1270easonLiangWorldedtech wants to merge 9 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Part 1/8 of the task-tree series (upstream-ready recomposition). Adds `depth` to HistoryItem and a cycle-safe `backfillTaskDepth()` that propagates parent depth through the delegation tree, so every task knows its nesting level. Depth is surfaced for later use by settings validation, environment details, and history-tree display. Includes the single-open-invariant spec mock for backfillTaskDepth (folded in from the series' CI fix) so this PR passes unit tests standalone.
…ound-trip Part 2/8 of the task-tree series (upstream-ready recomposition). Adds two global settings that control subtask delegation: - `maxNestingDepth` (default 2, range 0-5): how many levels a subtask may nest. A value of 0 disables delegation entirely — every new_task runs inline. - `autoFlattenOnLimit` (default true): when the limit is reached, flatten the subtask into the current conversation instead of opening a new tab; when disabled such requests are rejected so you can continue directly. Full round trip: global-settings schema + defaults, ExtensionState, SettingsView control bound to cachedState with save payload, webviewMessageHandler persistence through ContextProxy, ClineProvider getState/getStateToPostToWebview, runtime consumers using the shared defaults. Includes focused tests for UI binding/save, persistence, and the saved value returned to the webview. Also completes the taskTree translation keys in all 17 non-English locales so check-translations passes standalone (folded in from the series' CI fix).
…ached (#12) Co-authored-by: Eason Liang <easonliang28@gmail.com>
Adds a three-level new_task chain e2e (root -> child -> depth-2 task) where the depth-2 task's own new_task call exceeds maxNestingDepth and is flattened inline. Asserts exactly 3 tasks exist, the flattened work completes in the depth-2 task's own conversation, parent/child resume correctly, and the task stack never holds a fourth task. Hand-written aimock fixtures (no API key needed) use unique FLATTEN_E2E_ markers with predicate matching to avoid cross-suite collisions.
…n history tree (#13) Co-authored-by: Eason Liang <easonliang28@gmail.com>
…hods (#14) Co-authored-by: Eason Liang <easonliang28@gmail.com>
Co-authored-by: Eason Liang <easonliang28@gmail.com>
…nners (#17) * feat(webview): surface inline-subtask transitions as distinct chat banners * fix(webview): localize inline-subtask banner details and task-tree settings keys --------- Co-authored-by: Eason Liang <easonliang28@gmail.com>
…ovider call (#18) ## Problem A/C — delegation link lost across interrupt/resume When a delegated child is interrupted (cancelTask / evictCurrentTask), the parent's `awaitingChildId` link is preserved only while the parent is still `delegated`. After a crash or resume cycle the parent can be left `active` with no `awaitingChildId`, so when the user resumes the child, AttemptCompletionTool refuses to route its completion back (it requires `parent.awaitingChildId === this child`). The result: a resumed subtask's result is silently stranded and never reported to the parent. Fix: re-establish the link in `createTaskWithHistoryItem` (the common funnel for every resume path) when resuming an *interrupted* child. New private helper `reestablishDelegationLinkOnResume` transitions a demoted `active` parent back to `delegated`, gated so it: - skips children whose delegation was intentionally severed (`cancelledDelegationChildIds`), - never clobbers a live delegation to a different child, - only performs the legal `active -> delegated` transition. Non-fatal: any failure is logged and the resume proceeds without the link. Because AttemptCompletionTool already accepts an `active` parent whose `awaitingChildId` matches, routing (Problem C) works automatically once the link is restored. ## Problem D — remove `as any` in NewTaskTool `task.providerRef` is a `WeakRef<ClineProvider>`, so after the null-check `provider` is already typed `ClineProvider`. The `(provider as any).delegateParentAndOpenChild(...)` cast was unnecessary; it is now a typed method call. This removes the last `as any` in NewTaskTool.ts, so its stale `no-explicit-any` suppression entry is dropped from eslint-suppressions.json (count never increases). ## Tests Added 4 focused regression tests for `reestablishDelegationLinkOnResume` covering: link restored on resume of an interrupted child with a demoted parent; no-op when already delegated to the same child; never clobbers a live delegation to another child; and no reattach for intentionally-severed children. Co-authored-by: Eason Liang <easonliang28@gmail.com>
2b017a9 to
c97bad2
Compare
|
Closing per the author: this stacked series is being re-verified in a fork sandbox before upstream submission. Will be re-opened as individually reviewed PRs once each branch's CI is confirmed green. |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Part 8/8 of the task-tree series (builds on parts 1-7). Resuming an interrupted delegated child no longer loses its parent delegation link: reestablishDelegationLinkOnResume restores the legal active->delegated transition after markDelegatedChildInterrupted, skipping cancelled children and never clobbering a live other-child delegation. Also types the NewTaskTool provider call (removes the as-any cast).