Repository navigation
feat: 普通“新建任务”(侧边栏的独立会话)现在只会选择本地设备,不会再从云设备/本地设备里挑。 - #2550
Conversation
📝 WalkthroughWalkthroughThe PR centralizes local-device detection, restricts standalone selection to compatible local devices, preserves cloud standalone workspace state during refreshes, and deduplicates workspace paths across devices. ChangesStandalone device flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant WorkbenchProvider
participant useWorkbenchDataRefresh
participant DeviceSelection
participant DesktopSidebar
WorkbenchProvider->>useWorkbenchDataRefresh: refresh standalone workspace
useWorkbenchDataRefresh->>DeviceSelection: resolve device using workspace path
DeviceSelection-->>useWorkbenchDataRefresh: preserve active device
useWorkbenchDataRefresh-->>WorkbenchProvider: return refreshed workspace records
WorkbenchProvider->>DesktopSidebar: render runtime projects
DesktopSidebar-->>WorkbenchProvider: suppress duplicate path entries
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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.
Inline comments:
In `@wework/src/lib/device-selection.test.ts`:
- Around line 46-53: Update the tests around getPreferredStandaloneDeviceId to
stop claiming both fixtures are selectable, renaming them to describe local
selection and remembered-cloud replacement. Add direct assertions for
sortStandaloneDevices that map device_id values and verify local-device precedes
cloud-device, ensuring the locality comparator’s ordering is tested
independently.
In `@wework/src/lib/device-selection.ts`:
- Around line 24-25: Update isLocalStandaloneDevice to return true only when
device.device_type is the recognized local type, rather than treating every
non-cloud/non-remote value as local. Add tests covering missing, null, and
unknown device types, and verify the re-exported helper isLocalStandaloneDevice
behavior remains local-only.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 5a6a0c14-2721-4063-aedd-92f2156e17c9
📒 Files selected for processing (4)
wework/src/components/chat/composer/project-work-bar-utils.tswework/src/features/workbench/WorkbenchProvider.test.tsxwework/src/lib/device-selection.test.tswework/src/lib/device-selection.ts
| test('prefers the local device when cloud and local devices are both selectable', () => { | ||
| const devices = [ | ||
| selectableDevice({ device_id: 'cloud-device', name: 'Cloud Device', device_type: 'cloud' }), | ||
| selectableDevice({ device_id: 'local-device', name: 'Local Device', device_type: 'local' }), | ||
| ] | ||
|
|
||
| expect(getPreferredStandaloneDeviceId(devices)).toBe('local-device') | ||
| }) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Make these tests exercise the sorting contract.
The cloud-device fixture has device_type: 'cloud', so isWeWorkSelectableStandaloneDevice rejects it before getPreferredStandaloneDeviceId compares ordering. These assertions pass even if the new sortStandaloneDevices locality comparator is removed or reversed. The first test title also says that both devices are selectable, which is false.
Add a direct sortStandaloneDevices order assertion. Rename the current tests to describe local selection and remembered-cloud replacement.
Suggested assertion
expect(sortStandaloneDevices(devices).map(device => device.device_id)).toEqual([
'local-device',
'cloud-device',
])Also applies to: 55-62
🤖 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/lib/device-selection.test.ts` around lines 46 - 53, Update the
tests around getPreferredStandaloneDeviceId to stop claiming both fixtures are
selectable, renaming them to describe local selection and remembered-cloud
replacement. Add direct assertions for sortStandaloneDevices that map device_id
values and verify local-device precedes cloud-device, ensuring the locality
comparator’s ordering is tested independently.
| export function isLocalStandaloneDevice(device: Pick<SelectableDevice, 'device_type'>): boolean { | ||
| return device.device_type !== 'cloud' && device.device_type !== 'remote' |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Reject unknown device types as local.
SelectableDevice.device_type is optional. This condition returns true for undefined, null, and every unrecognized value. isWeWorkSelectableStandaloneDevice can then select a device that is not known to be local, which breaks the local-only contract.
Return device.device_type === 'local', or use an explicit allow-list if the device schema defines additional local types. Add tests for missing and unknown device types. The shared helper re-exported by project-work-bar-utils.ts inherits this behavior.
Proposed fix
export function isLocalStandaloneDevice(device: Pick<SelectableDevice, 'device_type'>): boolean {
- return device.device_type !== 'cloud' && device.device_type !== 'remote'
+ return device.device_type === 'local'
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export function isLocalStandaloneDevice(device: Pick<SelectableDevice, 'device_type'>): boolean { | |
| return device.device_type !== 'cloud' && device.device_type !== 'remote' | |
| export function isLocalStandaloneDevice(device: Pick<SelectableDevice, 'device_type'>): boolean { | |
| return device.device_type === 'local' | |
| } |
🤖 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/lib/device-selection.ts` around lines 24 - 25, Update
isLocalStandaloneDevice to return true only when device.device_type is the
recognized local type, rather than treating every non-cloud/non-remote value as
local. Add tests covering missing, null, and unknown device types, and verify
the re-exported helper isLocalStandaloneDevice behavior remains local-only.
|
Re-triggering CI on the same commit because the Wework Desktop E2E (Cloud) job failed with what looks like a timing-sensitive duplicate-project-row assertion (the branch change does not touch project creation/removal paths). |
|
Re-triggering CI on the same commit after adding the standalone-device refresh fix; the Cloud E2E progressed past the earlier duplicate-row assertion and hit a later dedup assertion in a run where other desktop E2E scenarios also failed. |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
wework/src/components/layout/DesktopSidebar.tsx (1)
360-372: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winDeduplicate workspace paths by runtime identity, not by string only.
runtimeWorkHasWorkspacetreats equal paths on independent executors as the same workspace, and the test covers two differentdeviceIdvalues without alias context. Use an identity key such as${remoteHostId ?? deviceId}\0${normalizedPath}, or pass device aliases throughstandaloneDeviceId/standaloneWorkspacePath, so the one-row expectation covers the same alias and two rows are possible for different hosts.🤖 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 360 - 372, Update runtimeWorkHasWorkspace in wework/src/components/layout/DesktopSidebar.tsx to match workspaces by runtime identity plus normalized path, using remoteHostId when available and otherwise deviceId, rather than the path alone. Update the corresponding expectations and fixtures in wework/src/components/layout/DesktopSidebar.test.tsx lines 4530-4565 so identical paths under the same alias remain one row while different hosts can produce two rows.
🧹 Nitpick comments (1)
wework/src/features/workbench/WorkbenchProvider.test.tsx (1)
6213-6215: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winAssert the retained runtime project identity.
These assertions allow the refresh to retain the cloud project with zero tasks. Assert that
runtime-task-titlescontainsLocal task, or expose and assert the retained workspace device ID.Proposed test assertion
expect(screen.getByTestId('runtime-project-count')).toHaveTextContent('1') +expect(screen.getByTestId('runtime-task-titles')).toHaveTextContent('Local task') expect(screen.getByTestId('standalone-device-id')).toHaveTextContent('device-local')🤖 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/features/workbench/WorkbenchProvider.test.tsx` around lines 6213 - 6215, Strengthen the duplicate-workspace refresh test by asserting that the retained runtime project is the local copy: verify runtime-task-titles contains “Local task,” or expose and assert the retained workspace device ID. Keep the existing project-count assertion and ensure the assertion distinguishes the local project from the cloud project with zero tasks.
🤖 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.
Outside diff comments:
In `@wework/src/components/layout/DesktopSidebar.tsx`:
- Around line 360-372: Update runtimeWorkHasWorkspace in
wework/src/components/layout/DesktopSidebar.tsx to match workspaces by runtime
identity plus normalized path, using remoteHostId when available and otherwise
deviceId, rather than the path alone. Update the corresponding expectations and
fixtures in wework/src/components/layout/DesktopSidebar.test.tsx lines 4530-4565
so identical paths under the same alias remain one row while different hosts can
produce two rows.
---
Nitpick comments:
In `@wework/src/features/workbench/WorkbenchProvider.test.tsx`:
- Around line 6213-6215: Strengthen the duplicate-workspace refresh test by
asserting that the retained runtime project is the local copy: verify
runtime-task-titles contains “Local task,” or expose and assert the retained
workspace device ID. Keep the existing project-count assertion and ensure the
assertion distinguishes the local project from the cloud project with zero
tasks.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: b44843cd-b96c-4a9c-932a-90b4f4c5cf80
📒 Files selected for processing (3)
wework/src/components/layout/DesktopSidebar.test.tsxwework/src/components/layout/DesktopSidebar.tsxwework/src/features/workbench/WorkbenchProvider.test.tsx
背景
普通“新建任务”(侧边栏的独立会话)是本地编码会话,应当固定跑在本机设备上。此前设备选择会在云设备 / 本地设备之间挑选,甚至可能回退到记忆中的云设备,导致任务被分配到云设备上执行。
改动
wework/src/lib/device-selection.ts:抽出isLocalStandaloneDevice(排除cloud/remote),isWeWorkSelectableStandaloneDevice只接受本地独立设备;sortStandaloneDevices排序改为本地设备优先,不再把云设备排在前面;有可用本地设备时不再回退到历史云设备。wework/src/components/chat/composer/project-work-bar-utils.ts:复用device-selection里的isLocalStandaloneDevice,删除重复实现。wework/src/features/workbench/useWorkbenchDataRefresh.ts:设备/runtime-work 刷新时,若存在已打开的 standalone workspace,保留其设备(例如云端工作区),不再被本地优先规则改写成本地设备。wework/src/components/layout/DesktopSidebar.tsx:standalone 项目行不再与已存在的同路径工作区重复渲染;同路径的本地项目与(别名后的)云端项目只显示一行。影响
用户从侧边栏新建独立会话时,任务只会选择本地设备,行为与“本地编码”语义一致;已打开的云端/远程工作区不受影响,也不会出现重复项目行。
验证
device-selection、WorkbenchProvider、DesktopSidebar共 253 个用例全部通过ai:verify)尚未在本会话执行,合入前可补跑Summary by CodeRabbit