Skip to content

fix(wework): unify task route and enforce list exclusivity - #1335

Merged
qdaxb merged 1 commit into
wecode-ai:mainfrom
icycrystal4:fix/wework-task-route-and-list-exclusivity
Jun 10, 2026
Merged

qdaxb merged 1 commit into
wecode-ai:mainfrom
icycrystal4:fix/wework-task-route-and-list-exclusivity

Conversation

@icycrystal4

@icycrystal4 icycrystal4 commented Jun 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • 统一会话/任务 URL 为路径风格:在 wework 发送消息创建对话后,地址栏改为规范的路径路由(/projects/:projectId/tasks/:taskId 或无项目时 /tasks/:taskId),替换原先创建后跳出的 ?taskId= 查询参数 URL,与点击已有会话的行为保持一致。
  • 强制两个列表互斥:修复一个项目下的会话偶发同时出现在「对话」列表中的问题。根因是列表划分仅靠客户端 !task.project_id 过滤,而服务端在创建后的最终一致性窗口里会瞬时返回 project_id=0,叠加 lists_refreshed 重新插入,导致同一任务出现在两个列表。现以 project.tasks 为权威来源去重 recentTasks,保证互斥。
  • 抽取共享选择器:新增 selectStandaloneConversations,桌面侧边栏与移动端抽屉复用,移除重复的本地排序逻辑。

Changes

  • wework/src/features/workbench/workbenchReducer.ts:新增 normalizeListExclusivity / collectProjectTaskIds / removeTaskFromProjects,并在 bootstrapped、lists_refreshed、upsertOpenedTask 中强制互斥。
  • wework/src/features/workbench/WorkbenchProvider.tsx:发送创建任务后走 buildTaskRoute + navigateTo 生成规范路径,移除冗余的 writeTaskIdToUrl。
  • wework/src/lib/taskLists.ts(新增)+ 复用到 DesktopSidebar.tsx / MobileDrawer.tsx。

Test plan

  • npx vitest run src/features/workbench/workbenchReducer.test.ts src/lib/taskLists.test.ts — 14 passed
  • eslint 改动文件无报错
  • 手动验证:从项目创建会话后地址栏为 /projects/:id/tasks/:taskId
  • 手动验证:创建项目会话期间该会话不再出现在「对话」列表

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Improved task list consistency to prevent duplicates between recent conversations and project task lists.
    • Enhanced URL routing behavior when opening tasks to ensure proper navigation state.
  • Tests

    • Added comprehensive test coverage for task list utilities and reducer behavior during list refreshes.

Unify the conversation/task URL to the canonical path route
(/projects/:projectId/tasks/:taskId or /tasks/:taskId) on send,
replacing the legacy query-param URL produced after creating a chat.

Enforce mutual exclusivity between the project task lists and the
standalone conversation list so a project task no longer leaks into
recent chats during the eventual-consistency window where the server
momentarily reports project_id=0. The project.tasks list is the
authoritative source used to dedupe recentTasks.

Extract a shared selectStandaloneConversations selector reused by the
desktop sidebar and mobile drawer, removing duplicated local sorting.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 10, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR refactors task-list logic by extracting sorting and filtering utilities into a shared module, applying those utilities across UI components, and enforcing mutual exclusivity between standalone conversations and project-assigned tasks in the reducer. Task routing is updated to use canonical routes instead of URL query parameters.

Changes

Task List Extraction and Exclusivity Enforcement

Layer / File(s) Summary
Task list utilities
wework/src/lib/taskLists.ts, wework/src/lib/taskLists.test.ts
A new utility module exports sortTasksByTime (orders tasks by most-recent activity), isStandaloneTask (checks absence of project_id), and selectStandaloneConversations (combines both for standalone conversation lists). Tests verify sorting by recency and filtering of project-associated tasks.
UI components consume standalone-conversation selector
wework/src/components/layout/DesktopSidebar.tsx, wework/src/components/layout/MobileDrawer.tsx
DesktopSidebar and MobileDrawer remove duplicate local sortTasksByTime helpers and import selectStandaloneConversations to compute sorted, filtered recent-task lists.
Reducer enforces task-list exclusivity
wework/src/features/workbench/workbenchReducer.ts
New helpers (normalizeListExclusivity, removeTaskFromProjects, getAllProjectTaskIds) enforce that tasks cannot exist in both recentTasks and project task lists. upsertOpenedTask applies exclusivity when updating opened tasks, and bootstrapped / lists_refreshed cases normalize state after state construction or server list refresh.
Exclusivity enforcement test cases
wework/src/features/workbench/workbenchReducer.test.ts
Two new test cases verify that project tasks are filtered from recentTasks during list refresh, and that missing project tasks are re-inserted into the project and removed from recentTasks to prevent duplication.
Task routing via canonical routes
wework/src/features/workbench/WorkbenchProvider.tsx
Removes writeTaskIdToUrl(taskId) from openTask flow. When a new task is acknowledged without a current task context, navigates to the canonical task route using buildTaskRoute + navigateTo instead of writing the query parameter.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • wecode-ai/Wegent#1126: Both PRs change how taskId is written/handled in navigation URLs (main PR removes writeTaskIdToUrl/uses canonical routing in WorkbenchProvider, retrieved PR stops appending ?taskId= in knowledge-task routing to avoid duplicates).
  • wecode-ai/Wegent#1262: Both PRs modify wework/src/features/workbench/WorkbenchProvider.tsx around updating/persisting the taskId URL state when opening/joining tasks (main PR changes the URL write/navigation behavior, retrieved PR adds broader URL persistence and clearing).
  • wecode-ai/Wegent#1309: Both PRs modify wework/src/features/workbench/WorkbenchProvider.tsx's openTask flow—main PR adjusts task URL/route handling, while the retrieved PR consumes joinTask's cached streaming response and dispatches assistant_cached.

Suggested reviewers

  • qdaxb

Poem

🐰 A task list neat, no duplication found,
Utilities extracted, logic sound,
Canonical routes now guide the way,
Exclusivity enforced—hooray, hooray!
Conversations standalone, projects apart,
Refactoring done with rabbity heart. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix(wework): unify task route and enforce list exclusivity' clearly and specifically summarizes the main changes: unifying task route navigation and enforcing mutual exclusivity between task lists.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
wework/src/components/layout/DesktopSidebar.tsx (1)

1-1309: ⚖️ Poor tradeoff

Consider splitting DesktopSidebar.tsx into smaller modules.

This file is 1309 lines, exceeding the 1000-line guideline. While this PR only touches 2 lines, consider extracting sub-components (e.g., ProjectItem, RecentTaskRow, SidebarSectionHeader) into separate files to improve maintainability.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@wework/src/components/layout/DesktopSidebar.tsx` around lines 1 - 1309, The
DesktopSidebar.tsx is too large; split it into smaller modules by extracting the
subcomponents and related helpers: create separate files (e.g., ProjectItem.tsx,
ProjectTaskRow.tsx, RecentTaskRow.tsx, SidebarSectionHeader.tsx) and move their
component implementations and any tightly-coupled helper functions they use
(like getProjectTaskTitle, getProjectTaskTime, sortProjectTasks,
formatRelativeSidebarTime, isGitWorktreeSession, GitWorktreeSidebarIcon,
SidebarDeviceStatusIndicator, getSidebarDeviceState, getProjectDeviceId,
getSidebarDeviceName, getSidebarDeviceStatusLabel,
getDeviceUnavailableActionTitle) into those files or a shared utils file; keep
all prop types and data-testid strings intact, export the components/utility
functions, and update DesktopSidebar to import them (preserve names:
ProjectItem, ProjectTaskRow, RecentTaskRow, SidebarSectionHeader,
formatRelativeSidebarTime, etc.) so behavior and tests remain unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@wework/src/components/layout/DesktopSidebar.tsx`:
- Around line 1-1309: The DesktopSidebar.tsx is too large; split it into smaller
modules by extracting the subcomponents and related helpers: create separate
files (e.g., ProjectItem.tsx, ProjectTaskRow.tsx, RecentTaskRow.tsx,
SidebarSectionHeader.tsx) and move their component implementations and any
tightly-coupled helper functions they use (like getProjectTaskTitle,
getProjectTaskTime, sortProjectTasks, formatRelativeSidebarTime,
isGitWorktreeSession, GitWorktreeSidebarIcon, SidebarDeviceStatusIndicator,
getSidebarDeviceState, getProjectDeviceId, getSidebarDeviceName,
getSidebarDeviceStatusLabel, getDeviceUnavailableActionTitle) into those files
or a shared utils file; keep all prop types and data-testid strings intact,
export the components/utility functions, and update DesktopSidebar to import
them (preserve names: ProjectItem, ProjectTaskRow, RecentTaskRow,
SidebarSectionHeader, formatRelativeSidebarTime, etc.) so behavior and tests
remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2025822a-301d-40fd-8ae3-c522338d1e32

📥 Commits

Reviewing files that changed from the base of the PR and between 6d36678 and 14e05fd.

📒 Files selected for processing (7)
  • wework/src/components/layout/DesktopSidebar.tsx
  • wework/src/components/layout/MobileDrawer.tsx
  • wework/src/features/workbench/WorkbenchProvider.tsx
  • wework/src/features/workbench/workbenchReducer.test.ts
  • wework/src/features/workbench/workbenchReducer.ts
  • wework/src/lib/taskLists.test.ts
  • wework/src/lib/taskLists.ts

@qdaxb
qdaxb merged commit 98699fb into wecode-ai:main Jun 10, 2026
22 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