Repository navigation
Codex/feat wework local devices - #1268
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (27)
✅ Files skipped from review due to trivial changes (4)
🚧 Files skipped from review as they are similar to previous changes (19)
📝 WalkthroughWalkthroughBackend validates and rejects terminal/code-server project sessions on local devices. Frontend adds device-capability predicates, threads device lists into workspace panels, hides cloud-only tools for local-device projects, and makes settings/tasks state URL-driven. Connections settings UI, tests, docs, and i18n are updated. ChangesLocal Device Capability Gating and Path-Based Routing
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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: 6
🧹 Nitpick comments (2)
wework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsx (1)
228-237: ⚡ Quick winAdd a regression case for missing
device_type.Please add one test where the matched device omits
device_typeand assert cloud tool cards remain visible. This will lock in the intended “explicit local only” behavior.🤖 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/workspace-panels/WorkspacePanelCards.test.tsx` around lines 228 - 237, Add a new test in WorkspacePanelCards.test.tsx that mirrors the existing "does not show cloud-only project tools for local devices" case but uses a device object that intentionally omits the device_type field (e.g., clone localDevices[0] without device_type) and render WorkspacePanelCards with that devices array; then assert that cloud tool cards (queryByTestId('workspace-terminal-card'), 'workspace-ide-card', 'workspace-desktop-card') are present (or not null/getByTestId) and that the local-only message ('workspace-local-device-limited-tools') is not shown, ensuring the component treats missing device_type as non-local.wework/src/components/settings/ConnectionsSettingsPage.tsx (1)
1-1020: 🏗️ Heavy liftSplit this file into sub-modules to meet the repo size limit.
This file now exceeds 1000 lines, which increases coupling and review/test overhead for future changes. Please extract sections like settings-nav routing helpers, device card/actions, and archived chats into separate modules.
As per coding guidelines:
**/*.{py,ts,tsx,js,jsx}: File size limit: If a file exceeds 1000 lines, split it into multiple sub-modules.🤖 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/settings/ConnectionsSettingsPage.tsx` around lines 1 - 1020, The file is too large—split it into focused sub-modules: 1) extract the nav helpers (getSettingsNavFromPath, getSettingsNavPath, settingsNavItems) into a settingsNav module and export them; 2) move all device-related components (DeviceCard, DeviceSection, DeviceMetrics, VncDesktopButton, DeviceActionButton, DeviceIconActionButton, StatusPill, createSettingsDeviceApi, formatMetricPercent, ConfirmDeviceActionDialog and helper functions like formatMetricPercent) into a devices module that exports the components and createSettingsDeviceApi; 3) move ConnectionsDeviceSettingsPage into its own ConnectionsDeviceSettingsPage module that imports the devices module components and createSettingsDeviceApi; 4) move ArchivedChatsSettingsPage into an archivedChats module; then update ConnectionsSettingsPage to import these modules (and AddCloudDeviceDialog/AppearanceSettingsPage remain where they are) so the top-level file only composes the sidebar and routing; ensure all moved functions/components keep their original names and exported/imported types to preserve usage (e.g., onChanged, onListArchivedTasks, DeviceInfo types).
🤖 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 `@backend/app/services/project_device_session_service.py`:
- Around line 145-150: The guard currently only rejects device_type ==
DeviceType.LOCAL.value and lets missing/unknown values through; change it to
fail-closed by explicitly allowing only the cloud value: read device_type =
spec.get("deviceType") and if device_type != DeviceType.CLOUD.value then raise
the HTTPException (same status and detail or update detail to indicate only
cloud devices are supported). Update the check near the current device_type
handling in project_device_session_service.py so unknown/missing values are
rejected instead of permitted.
- Around line 132-150: Wrap the _ensure_device_supports_project_sessions
function with the OpenTelemetry sync tracer decorator (use `@trace_sync`) and
inside the function set span attributes for device_id and the resolved
deviceType (use set_span_attribute) and emit a span event when rejecting with
the reason (e.g., "Local devices do not support terminal or code-server
sessions") using add_span_event; also record an event or attribute when device
lookup returns no result. Ensure you import the tracing helpers and call
set_span_attribute/add_span_event at the appropriate points in
_ensure_device_supports_project_sessions so telemetry captures device_id,
resolved deviceType, and rejection reason.
In `@wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx`:
- Around line 115-119: The code treats any device with an undefined device_type
as local by negating supportsCloudSessions; change hasExplicitLocalDevice to
explicitly check the device_type (e.g. const hasExplicitLocalDevice =
Boolean(projectDevice && projectDevice.device_type === 'local')) so only devices
that explicitly mark device_type === 'local' gate off cloud tools, keep
cloudToolsAvailable = !hasExplicitLocalDevice, and if your codebase uses an
enum/constant for device types, compare against that instead of the string
literal.
In `@wework/src/features/workbench/WorkbenchProvider.tsx`:
- Around line 895-897: The current effect sets handledTaskRouteRef.current =
routeKey then calls openTask(taskRoute.taskId, taskRoute.projectId) without
handling rejections, which can leave the guard set and prevent retries; modify
the effect to await/openTask with a .catch or try/catch around the async call,
and on error clear handledTaskRouteRef.current (or only set
handledTaskRouteRef.current after openTask succeeds) so failures un-block future
attempts; use the existing handledTaskRouteRef, openTask, and
taskRoute.taskId/taskRoute.projectId identifiers when applying the fix.
- Around line 856-860: The current flow awaits
resolvedServices.chatStream.joinTask(taskId) which can block navigateTo and
leave the URL stale if joinTask fails; instead, kick off joinTask without
awaiting so route sync is immediate: call
resolvedServices.chatStream.joinTask(taskId) as a fire-and-forget (or attach
.catch(...) to log errors) after computing handledTaskRouteRef.current =
getTaskRouteKey(taskId, routeProjectId) and before/after
navigateTo(buildTaskRoute({ taskId, projectId: routeProjectId })), ensuring
navigateTo is not gated on joinTask success and errors from joinTask are logged
but do not prevent navigation.
In `@wework/src/lib/navigation.ts`:
- Around line 30-41: The parseTaskRoute function currently accepts IDs of "0";
update its regexes to only match positive integers by replacing (\d+) with
([1-9]\d*) in both /^\/projects\/(\d+)\/tasks\/(\d+)$/ and /^\/tasks\/(\d+)$/ so
paths like /tasks/0 or /projects/0/tasks/1 will no longer match and will return
null; adjust any dependent numeric conversion (projectId, taskId) as needed but
keep the existing Number(...) usage after the stricter match.
---
Nitpick comments:
In `@wework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsx`:
- Around line 228-237: Add a new test in WorkspacePanelCards.test.tsx that
mirrors the existing "does not show cloud-only project tools for local devices"
case but uses a device object that intentionally omits the device_type field
(e.g., clone localDevices[0] without device_type) and render WorkspacePanelCards
with that devices array; then assert that cloud tool cards
(queryByTestId('workspace-terminal-card'), 'workspace-ide-card',
'workspace-desktop-card') are present (or not null/getByTestId) and that the
local-only message ('workspace-local-device-limited-tools') is not shown,
ensuring the component treats missing device_type as non-local.
In `@wework/src/components/settings/ConnectionsSettingsPage.tsx`:
- Around line 1-1020: The file is too large—split it into focused sub-modules:
1) extract the nav helpers (getSettingsNavFromPath, getSettingsNavPath,
settingsNavItems) into a settingsNav module and export them; 2) move all
device-related components (DeviceCard, DeviceSection, DeviceMetrics,
VncDesktopButton, DeviceActionButton, DeviceIconActionButton, StatusPill,
createSettingsDeviceApi, formatMetricPercent, ConfirmDeviceActionDialog and
helper functions like formatMetricPercent) into a devices module that exports
the components and createSettingsDeviceApi; 3) move
ConnectionsDeviceSettingsPage into its own ConnectionsDeviceSettingsPage module
that imports the devices module components and createSettingsDeviceApi; 4) move
ArchivedChatsSettingsPage into an archivedChats module; then update
ConnectionsSettingsPage to import these modules (and
AddCloudDeviceDialog/AppearanceSettingsPage remain where they are) so the
top-level file only composes the sidebar and routing; ensure all moved
functions/components keep their original names and exported/imported types to
preserve usage (e.g., onChanged, onListArchivedTasks, DeviceInfo types).
🪄 Autofix (Beta)
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
Run ID: 25b3a43f-a465-4105-b7ba-239e17af9347
📒 Files selected for processing (26)
backend/app/services/project_device_session_service.pybackend/tests/services/test_project_device_session_service.pydocs/en/user-guide/ai-devices/local-device-support.mddocs/zh/user-guide/ai-devices/local-device-support.mdshared/models/__init__.pyshared/models/search_hints.pyshared/tests/test_search_hints.pywework/src/api/devices.test.tswework/src/api/devices.tswework/src/components/layout/DesktopWorkbenchLayout.test.tsxwework/src/components/layout/DesktopWorkbenchLayout.tsxwework/src/components/layout/DesktopWorkbenchMain.tsxwework/src/components/layout/MobileWorkbenchLayout.tsxwework/src/components/layout/workspace-panels/BottomWorkspacePanel.tsxwework/src/components/layout/workspace-panels/RightWorkspacePanel.tsxwework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsxwework/src/components/layout/workspace-panels/WorkspacePanelCards.tsxwework/src/components/projects/ProjectCreateDialog.tsxwework/src/components/settings/ConnectionsSettingsPage.test.tsxwework/src/components/settings/ConnectionsSettingsPage.tsxwework/src/features/workbench/WorkbenchProvider.test.tsxwework/src/features/workbench/WorkbenchProvider.tsxwework/src/i18n/locales/en/common.jsonwework/src/i18n/locales/zh-CN/common.jsonwework/src/lib/device-capabilities.tswework/src/lib/navigation.ts
| def _ensure_device_supports_project_sessions( | ||
| db: Session, | ||
| user_id: int, | ||
| device_id: str, | ||
| ) -> None: | ||
| """Reject project terminal and code-server sessions for local devices.""" | ||
|
|
||
| device_kind = device_service.get_device_by_device_id(db, user_id, device_id) | ||
| if not device_kind: | ||
| return | ||
|
|
||
| spec = getattr(device_kind, "json", None) | ||
| spec = spec.get("spec", {}) if isinstance(spec, dict) else {} | ||
| device_type = spec.get("deviceType") | ||
| if device_type == DeviceType.LOCAL.value: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_400_BAD_REQUEST, | ||
| detail="Local devices do not support terminal or code-server sessions", | ||
| ) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Add tracing on the new session-capability guard.
This new decision point should be instrumented with @trace_sync and span attributes/events (e.g., device_id, resolved deviceType, rejection reason) for production diagnostics and policy auditing. As per coding guidelines, "Use OpenTelemetry tracing decorators: @trace_async or @trace_sync for entire functions, and add_span_event() or set_span_attribute() for adding details to spans".
🤖 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 `@backend/app/services/project_device_session_service.py` around lines 132 -
150, Wrap the _ensure_device_supports_project_sessions function with the
OpenTelemetry sync tracer decorator (use `@trace_sync`) and inside the function
set span attributes for device_id and the resolved deviceType (use
set_span_attribute) and emit a span event when rejecting with the reason (e.g.,
"Local devices do not support terminal or code-server sessions") using
add_span_event; also record an event or attribute when device lookup returns no
result. Ensure you import the tracing helpers and call
set_span_attribute/add_span_event at the appropriate points in
_ensure_device_supports_project_sessions so telemetry captures device_id,
resolved deviceType, and rejection reason.
| device_type = spec.get("deviceType") | ||
| if device_type == DeviceType.LOCAL.value: | ||
| raise HTTPException( | ||
| status_code=status.HTTP_400_BAD_REQUEST, | ||
| detail="Local devices do not support terminal or code-server sessions", | ||
| ) |
There was a problem hiding this comment.
Fail closed on deviceType to prevent capability-gate bypass.
This guard currently rejects only deviceType == "local". Missing/unknown values pass through and can still start project sessions. For a cloud-only tool gate, only explicit cloud should be allowed.
🔧 Proposed fix
- device_type = spec.get("deviceType")
- if device_type == DeviceType.LOCAL.value:
+ device_type = spec.get("deviceType")
+ if device_type != DeviceType.CLOUD.value:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
- detail="Local devices do not support terminal or code-server sessions",
+ detail="Only cloud devices support terminal or code-server sessions",
)🤖 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 `@backend/app/services/project_device_session_service.py` around lines 145 -
150, The guard currently only rejects device_type == DeviceType.LOCAL.value and
lets missing/unknown values through; change it to fail-closed by explicitly
allowing only the cloud value: read device_type = spec.get("deviceType") and if
device_type != DeviceType.CLOUD.value then raise the HTTPException (same status
and detail or update detail to indicate only cloud devices are supported).
Update the check near the current device_type handling in
project_device_session_service.py so unknown/missing values are rejected instead
of permitted.
| const projectDevice = projectDeviceId | ||
| ? devices.find(device => device.device_id === projectDeviceId) | ||
| : undefined | ||
| const hasExplicitLocalDevice = Boolean(projectDevice && !supportsCloudSessions(projectDevice)) | ||
| const cloudToolsAvailable = !hasExplicitLocalDevice |
There was a problem hiding this comment.
Use an explicit local check for local-device gating.
Line 118 currently classifies any non-cloud (including missing device_type) as local. Because DeviceInfo.device_type is optional, this can incorrectly hide Terminal/IDE/Desktop for devices with undefined type.
Suggested fix
-import { supportsCloudSessions } from '`@/lib/device-capabilities`'
@@
- const hasExplicitLocalDevice = Boolean(projectDevice && !supportsCloudSessions(projectDevice))
+ const hasExplicitLocalDevice = projectDevice?.device_type === 'local'
const cloudToolsAvailable = !hasExplicitLocalDevice🤖 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/workspace-panels/WorkspacePanelCards.tsx` around
lines 115 - 119, The code treats any device with an undefined device_type as
local by negating supportsCloudSessions; change hasExplicitLocalDevice to
explicitly check the device_type (e.g. const hasExplicitLocalDevice =
Boolean(projectDevice && projectDevice.device_type === 'local')) so only devices
that explicitly mark device_type === 'local' gate off cloud tools, keep
cloudToolsAvailable = !hasExplicitLocalDevice, and if your codebase uses an
enum/constant for device types, compare against that instead of the string
literal.
| handledTaskRouteRef.current = routeKey | ||
| void openTask(taskRoute.taskId, taskRoute.projectId) | ||
| }, [ |
There was a problem hiding this comment.
Handle route-open failures and clear the route guard on error.
This effect sets handledTaskRouteRef before calling openTask, but it never catches failures. A rejected openTask can leave the guard set and block retries for the same route.
Suggested fix
handledTaskRouteRef.current = routeKey
- void openTask(taskRoute.taskId, taskRoute.projectId)
+ void openTask(taskRoute.taskId, taskRoute.projectId).catch(error => {
+ if (handledTaskRouteRef.current === routeKey) {
+ handledTaskRouteRef.current = null
+ }
+ dispatch({
+ type: 'error_set',
+ error: error instanceof Error ? error.message : '会话加载失败',
+ })
+ })🤖 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.tsx` around lines 895 - 897,
The current effect sets handledTaskRouteRef.current = routeKey then calls
openTask(taskRoute.taskId, taskRoute.projectId) without handling rejections,
which can leave the guard set and prevent retries; modify the effect to
await/openTask with a .catch or try/catch around the async call, and on error
clear handledTaskRouteRef.current (or only set handledTaskRouteRef.current after
openTask succeeds) so failures un-block future attempts; use the existing
handledTaskRouteRef, openTask, and taskRoute.taskId/taskRoute.projectId
identifiers when applying the fix.
| export function parseTaskRoute(path: string): TaskRoute | null { | ||
| const projectTaskMatch = path.match(/^\/projects\/(\d+)\/tasks\/(\d+)$/) | ||
| if (projectTaskMatch) { | ||
| return { | ||
| projectId: Number(projectTaskMatch[1]), | ||
| taskId: Number(projectTaskMatch[2]), | ||
| } | ||
| } | ||
|
|
||
| const taskMatch = path.match(/^\/tasks\/(\d+)$/) | ||
| if (taskMatch) { | ||
| return { taskId: Number(taskMatch[1]) } |
There was a problem hiding this comment.
Reject non-positive IDs in task-route parsing.
The current regex allows 0, so paths like /tasks/0 or /projects/0/tasks/1 are parsed as valid and can trigger invalid task loads.
Suggested fix
export function parseTaskRoute(path: string): TaskRoute | null {
- const projectTaskMatch = path.match(/^\/projects\/(\d+)\/tasks\/(\d+)$/)
+ const projectTaskMatch = path.match(/^\/projects\/([1-9]\d*)\/tasks\/([1-9]\d*)$/)
if (projectTaskMatch) {
return {
projectId: Number(projectTaskMatch[1]),
taskId: Number(projectTaskMatch[2]),
}
}
- const taskMatch = path.match(/^\/tasks\/(\d+)$/)
+ const taskMatch = path.match(/^\/tasks\/([1-9]\d*)$/)
if (taskMatch) {
return { taskId: Number(taskMatch[1]) }
}📝 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 parseTaskRoute(path: string): TaskRoute | null { | |
| const projectTaskMatch = path.match(/^\/projects\/(\d+)\/tasks\/(\d+)$/) | |
| if (projectTaskMatch) { | |
| return { | |
| projectId: Number(projectTaskMatch[1]), | |
| taskId: Number(projectTaskMatch[2]), | |
| } | |
| } | |
| const taskMatch = path.match(/^\/tasks\/(\d+)$/) | |
| if (taskMatch) { | |
| return { taskId: Number(taskMatch[1]) } | |
| export function parseTaskRoute(path: string): TaskRoute | null { | |
| const projectTaskMatch = path.match(/^\/projects\/([1-9]\d*)\/tasks\/([1-9]\d*)$/) | |
| if (projectTaskMatch) { | |
| return { | |
| projectId: Number(projectTaskMatch[1]), | |
| taskId: Number(projectTaskMatch[2]), | |
| } | |
| } | |
| const taskMatch = path.match(/^\/tasks\/([1-9]\d*)$/) | |
| if (taskMatch) { | |
| return { taskId: Number(taskMatch[1]) } |
🤖 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/navigation.ts` around lines 30 - 41, The parseTaskRoute
function currently accepts IDs of "0"; update its regexes to only match positive
integers by replacing (\d+) with ([1-9]\d*) in both
/^\/projects\/(\d+)\/tasks\/(\d+)$/ and /^\/tasks\/(\d+)$/ so paths like
/tasks/0 or /projects/0/tasks/1 will no longer match and will return null;
adjust any dependent numeric conversion (projectId, taskId) as needed but keep
the existing Number(...) usage after the stricter match.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
wework/src/components/layout/DesktopWorkbenchLayout.test.tsx (1)
1-1774: ⚖️ Poor tradeoffConsider splitting this test file to improve maintainability.
The file exceeds the 1000-line guideline (currently 1774 lines). While comprehensive test coverage is valuable, splitting by feature area would improve maintainability. Consider organizing into separate test files such as:
- Sidebar interactions (projects, chats, search, settings)
- Workspace panels (right/bottom panels, resize, close)
- Environment info (popover, commits, branches)
- Project creation and management
As per coding guidelines: "File size limit: If a file exceeds 1000 lines, split it into multiple sub-modules"
🤖 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/DesktopWorkbenchLayout.test.tsx` around lines 1 - 1774, The test file DesktopWorkbenchLayout.test.tsx is too large (>1000 lines); split it into multiple focused test files to improve maintainability. Create separate test modules (for example: DesktopWorkbenchLayout.sidebar.test.tsx for sidebar interactions referencing tests that use data-testid like 'projects-section-toggle', 'search-button', 'settings-button'; DesktopWorkbenchLayout.workspace.test.tsx for right/bottom panel/resizing tests referencing 'toggle-right-workspace-panel-button', 'right-workspace-resize-handle', 'toggle-bottom-workspace-panel-button'; DesktopWorkbenchLayout.environment.test.tsx for environment popover/commits/branches referencing 'environment-info-button', 'environment-commit-button', 'environment-branch-row'; DesktopWorkbenchLayout.project.test.tsx for project creation/management referencing 'projects-create-button', 'project-create-dialog', 'create-project-button'). Move related describe/test blocks into these files, keep shared setup (createRect, mocks, baseProps) in a new test-utils or a shared setup file and import it into each split file, and update imports to DesktopWorkbenchLayout and mocked factories so tests still run unchanged.
🤖 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/DesktopWorkbenchLayout.test.tsx`:
- Around line 1-1774: The test file DesktopWorkbenchLayout.test.tsx is too large
(>1000 lines); split it into multiple focused test files to improve
maintainability. Create separate test modules (for example:
DesktopWorkbenchLayout.sidebar.test.tsx for sidebar interactions referencing
tests that use data-testid like 'projects-section-toggle', 'search-button',
'settings-button'; DesktopWorkbenchLayout.workspace.test.tsx for right/bottom
panel/resizing tests referencing 'toggle-right-workspace-panel-button',
'right-workspace-resize-handle', 'toggle-bottom-workspace-panel-button';
DesktopWorkbenchLayout.environment.test.tsx for environment
popover/commits/branches referencing 'environment-info-button',
'environment-commit-button', 'environment-branch-row';
DesktopWorkbenchLayout.project.test.tsx for project creation/management
referencing 'projects-create-button', 'project-create-dialog',
'create-project-button'). Move related describe/test blocks into these files,
keep shared setup (createRect, mocks, baseProps) in a new test-utils or a shared
setup file and import it into each split file, and update imports to
DesktopWorkbenchLayout and mocked factories so tests still run unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c9e4ce1b-13b4-4aaf-b7fa-8dee2ee90082
📒 Files selected for processing (5)
wework/src/components/layout/DesktopSidebar.tsxwework/src/components/layout/DesktopWorkbenchLayout.test.tsxwework/src/components/settings/AddCloudDeviceDialog.tsxwework/src/components/settings/ConnectionsSettingsPage.test.tsxwework/src/components/settings/ConnectionsSettingsPage.tsx
💤 Files with no reviewable changes (1)
- wework/src/components/layout/DesktopSidebar.tsx
✅ Files skipped from review due to trivial changes (1)
- wework/src/components/settings/AddCloudDeviceDialog.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- wework/src/components/settings/ConnectionsSettingsPage.test.tsx
- wework/src/components/settings/ConnectionsSettingsPage.tsx
fc49a97 to
cdb2830
Compare
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Improvements