feature: task-dnd-ux (2/3) - #29
Closed
myk1yt wants to merge 33 commits into
Closed
Conversation
myk1yt
force-pushed
the
pr/b08-task-persistence-v2
branch
from
August 4, 2026 11:33
de01add to
d23eddd
Compare
myk1yt
force-pushed
the
pr/b09-task-org-ipc-v2
branch
4 times, most recently
from
August 5, 2026 11:26
044753a to
5cab0cc
Compare
myk1yt
force-pushed
the
pr/b08-task-persistence-v2
branch
3 times, most recently
from
August 6, 2026 16:15
ef13c98 to
c43fdf3
Compare
myk1yt
force-pushed
the
pr/b09-task-org-ipc-v2
branch
from
August 6, 2026 16:20
707bafe to
edac770
Compare
…ence - Add Zod-based type contracts in packages/types/src/task-organization.ts - Add TaskOrganizationStore with atomic read-modify-write via safeUpdateJson - Add safeUpdateJson helper to src/utils/safeWriteJson.ts - Add taskOrganization to GlobalFileNames - Export TaskOrganizationStore types from @roo-code/types - Add ExtensionMessage/WebviewMessage fields for task organization - 29 tests covering CRUD, folder management, pinning, and concurrency - Fix all no-explicit-any lint errors with proper type narrowing
…vider state assembly - Add taskOrganizationMessageHandler.ts: validates mutation requests via Zod, applies through TaskOrganizationStore, posts typed results to webview - Add taskOrganizationMessageHandler.spec.ts: 6 tests covering validation, success, store rejection, and unexpected error paths - Wire taskOrganizationMutation case in webviewMessageHandler.ts - Integrate TaskOrganizationStore into ClineProvider: constructor init, dispose, getTaskOrganizationStore() getter, reconcile on history writes, and taskOrganization state in getStateToPostToWebview()
- Add TaskOrganizationStore for atomic persistence - Add DnD controller and UI components with dnd-kit - Add folder creation and drag-drop composition - Add pin buttons with ErrorBoundary protection - Add selection mode folder actions and DeleteFoldersDialog - Convert to whole-card drag with interactive control guard - Add localization for DnD UX redesign features - Stabilize DnD components and Welcome screen integration
…nd folders Three bugs caused workspace A's tasks/pins/folders to leak into workspace B: 1. HistoryPreview passed undefined as cwd to buildGroupedOrganizationProjection, disabling workspace filtering entirely in the preview. 2. HistoryView's renderPinnedHeader iterated ALL organization.pins (global state) without workspace filtering. Pinned tasks from other workspaces displayed raw task IDs as labels (the 'encrypted numbers' symptom). 3. buildGroupedOrganizationProjection always included folder projections even when all members belonged to other workspaces, causing empty folders from workspace A to appear in workspace B. Fix: pass cwd to the projection in HistoryView, filter pins by workspace when showAllWorkspaces is false, and skip folders with no visible members when cwd is provided. Genuinely empty folders (zero taskIds) are preserved.
Distinguish cwd === undefined (show all workspaces) from cwd === empty string (no workspace open). Previously !cwd treated both identically, causing workspace-specific folders and pins to appear when no workspace was open. - isVisibleInWorkspace: !cwd → cwd === undefined - folder skip condition: cwd && ... → cwd !== undefined && ...
… role=button to SubtaskRow - DraggableTaskEntry deliberately strips role from dnd-kit attributes so the wrapper is not matched by interactive selectors; update the two tests to assert the actual contract (no role/aria-pressed, tabindex=0, aria-roledescription=draggable) instead of role=button. - SubtaskRow's keyboard-interactive row (tabIndex + Enter/Space handler) lacked role=button; add it for a11y correctness. Safe for TaskOrganizationPointerSensor since [role=button] is not in its INTERACTIVE_SELECTOR. Fixes 4 failing platform-unit-test specs on PR #31 CI (ubuntu+windows).
…r reloads - save(): reject writes whose base revision is already on disk (>= instead of >) so two processes computing next=N+1 from the same base cannot both commit; the second now fails with TASK_ORG/PERSISTENCE/005 instead of silently overwriting the first. - load(): keep the in-memory state on transient read errors (e.g. the directory watcher firing mid temp+rename) instead of resetting to empty, which previously made the next mutation compute from an empty aggregate. - reloadFromWatcher(): fire onChange whenever the reloaded aggregate differs in content, not only when the revision increases, so the victim of a same-revision lost update still gets its webview notified.
The TaskHistoryStore.onWrite closure dereferenced this.taskOrganizationStore, which is only assigned a few lines after the history store is constructed. A history write landing in that window threw a TypeError (caught and logged, reconcile skipped). Guard the dereference so the reconcile is skipped cleanly until the store exists.
… merges The dedicated taskOrganizationUpdated handler drops stale revisions, but the full-state merge path spread newRest unconditionally, so a state push assembled before a mutation commit could arrive after the broadcast and regress the webview to an older revision (folder/pin UI flickers back and the next DnD mutation then gets a spurious TASK_ORG/CONFLICT/002). Apply the same revision guard to the taskOrganization field in mergeExtensionState.
…ty-cwd semantics - HistoryView: folder pins were exempt from workspace filtering, so a folder whose members all belong to another workspace still rendered as a pinned shortcut in Current Workspace mode. Keep a folder pin only when the folder is visible in the workspace-scoped projection (at least one visible member, or genuinely empty), matching buildGroupedOrganizationProjection. - taskOrganizationModel: filterByWorkspace treated cwd === "" as unfiltered, contradicting the documented "no workspace open" semantics. cwd === undefined is now the only unfiltered mode; "" filters to tasks without a workspace, matching buildGroupedOrganizationProjection.
myk1yt
force-pushed
the
pr/b09-task-org-ipc-v2
branch
from
August 6, 2026 18:00
edac770 to
f4b6b94
Compare
myk1yt
force-pushed
the
pr/b09-task-org-ipc-v2
branch
from
August 7, 2026 05:11
da369cf to
67f980a
Compare
…o >90% for codecov
myk1yt
force-pushed
the
pr/b09-task-org-ipc-v2
branch
from
August 7, 2026 05:34
67f980a to
5a5b996
Compare
Co-authored-by: Roomote <roomote@roomote.dev>
…1190) Co-authored-by: Roomote <roomote@roomote.dev>
…uire (PR Zoo-Code-Org#1127) CI failures: 1. Code QA Roo Code run 31229055807: @roo-code/vscode-e2e#lint failed with unused 'vscode' import in task-org-ipc.test.ts. 2. E2E Tests (Mocked) run 31229055772: all 5 Task Organization IPC tests failed with 'Cannot find module ../../../src/core/webview/ClineProvider' because the compiled test (apps/vscode-e2e/out/suite/) cannot resolve the extension's TS sources. Fix: - Add getVisibleProviderForTesting() to RooCodeAPI (packages/types) and implement it in src/extension/api.ts returning the sidebar ClineProvider. - Rework task-org-ipc.test.ts to obtain the provider via the public API and drive mutations through the real TaskOrganizationStore + Zod schema (the same pipeline handleTaskOrganizationMessage uses), with structural typing. - Remove the unused vscode import (lint fix). - Use currentRevision - 2 for the stale-revision conflict test so baseRevision is deterministically stale even when the store has only one committed revision. Runs: https://github.com/Zoo-Code-Org/Zoo-Code/actions/runs/31229055807 https://github.com/Zoo-Code-Org/Zoo-Code/actions/runs/31229055772
…tive integer for conflict validation
…tion result directly
…ames (Zoo-Code-Org#1073) * fix(telemetry): record tool usage once centrally, sanitize raw tool names * fix(telemetry): defer native MCP usage recording until validation passes * fix(telemetry): narrow UseMcpToolTool callback, harden test mocks, close coverage gaps * test(telemetry): complete native MCP mock so validateToolExists runs the real path
Co-authored-by: Roomote <roomote@roomote.dev>
Co-authored-by: Roomote <roomote@roomote.dev>
Co-authored-by: Roomote <roomote@roomote.dev>
Owner
Author
|
Closing to recreate with main as target base branch. This PR had stale base branch references after fork sync. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack Position
feature/task-dnd-uxDescription
Full Feature Description
feature/task-dnd-uxtask-organization.ts,TaskOrganizationStore.ts,safeWriteJson.ts,taskOrganizationMessageHandler.ts,ClineProvider.ts,HistoryView.tsx,ExtensionStateContext.tsx.Why Split Into 17 PRs
Instead of submitting this feature as a single unified PR, it was split into individual PRs because as code size grows, safely reviewing a PR becomes very difficult. The feature was broken into mutually exclusive individual PRs so that each can be reviewed independently.
What This PR Specifically Changes
Validates typed create/rename/move/pin/reorder/delete requests, passes them to the store, and publishes success/recoverable error and authoritative extension state to the webview. Does not include UI components.
Included Files
src/core/webview/taskOrganizationMessageHandler.tssrc/core/webview/webviewMessageHandler.tssrc/core/webview/ClineProvider.tssrc/core/webview/__tests__/taskOrganizationMessageHandler.spec.tsExclusion Scope