Skip to content

feat(wework): complete isolated workspace tabs - #2359

Merged
qdaxb merged 14 commits into
mainfrom
feature/workspace-document-tabs
Aug 1, 2026
Merged

feat(wework): complete isolated workspace tabs#2359
qdaxb merged 14 commits into
mainfrom
feature/workspace-document-tabs

Conversation

@qdaxb

@qdaxb qdaxb commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

What changed

  • replace the fixed top-level app switcher with browser-style workspace document tabs
  • keep exactly three default tabs: Task, Project spaces, and Agent
  • give every tab its own mounted task, project-space, or agent state instead of sharing one global page instance
  • make ordinary navigation replace the active tab route rather than opening a tab for every link
  • support tab creation, selection, close, close others, reopen, drag reorder, keyboard shortcuts, and separate Tauri windows
  • make “Open in new window” atomically move one tab: the source window removes it only after the destination window is ready, while the destination starts with only that tab and its draft
  • safely dispose asynchronous Tauri listeners and keep singleton desktop bridges outside per-tab providers
  • rename the top-level board product to “项目空间” / “Project spaces” while concrete project tabs keep the project name
  • add a CI-registered desktop E2E checkpoint for multi-tab and multi-window isolation

Multi-tab semantics

  • two Task tabs retain independent conversations and composer drafts
  • two Project-space tabs retain independent project selections and routes
  • two Agent tabs retain independent iframe instances
  • hidden tabs remain mounted, so switching tabs does not reset their state
  • opening a tab in a new window transfers its state once, removes it from the source window, and does not create the destination window's three default tabs
  • a failed destination-window creation leaves the source tab intact and cleans staged transfer state

Validation

  • pnpm --filter wework test — 259 files / 2554 tests passed
  • pnpm --filter wework typecheck — passed
  • pnpm --filter wework lint — passed
  • .github/scripts/test-classify-ci-changes.sh — passed
  • node wework/e2e/desktop/run-checkpoints.mjs --segment workspace-tabs — passed in a production-built isolated Tauri app
  • real Tauri review verified the detached window contains exactly one transferred tab and draft, while the source window no longer contains that tab
  • synchronized with the latest origin/main before publication

Desktop E2E coverage

The workspace-tabs checkpoint verifies:

  1. the three default tabs
  2. independent Task drafts
  3. independent Project-space state
  4. independent Agent iframe state
  5. in-tab route replacement
  6. one-tab cross-window transfer and source-window removal

Existing E2E scenarios keep their original semantics; the new checkpoint is additive and is included in the CI-covered Wework desktop suite.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds persisted workspace document tabs with route synchronization, project selection integration, independent workspace windows, workspace screenshot capture, launcher styling, titlebar updates, credential hydration changes, automated tests, E2E checks, and QA evidence.

Changes

Workspace document tabs

Layer / File(s) Summary
Tab state and route management
wework/src/features/workspace-tabs/*
Adds tab models, route parsing, persistence, selection, opening, closing, restoration, reordering, and context operations.
Tab strip and shell integration
wework/src/App.tsx, wework/src/components/topnav/*, wework/src/styles/globals.css, wework/src/i18n/locales/*, related tests
The shell provides workspace-tab state. The titlebar renders the tab strip with localized labels, menus, keyboard actions, drag reordering, and platform-specific layout.
Project selection synchronization
wework/src/components/layout/DesktopWorkbenchLayout.tsx, wework/src/features/todo/CloudTodoWorkspace.tsx, related tests
The active board tab controls the selected cloud project. Project selection updates the tab title and route. Controlled project changes reset project-specific views.
Workspace windows and capture support
wework/src/features/workspace-tabs/workspaceWindow.ts, wework/src-tauri/*, wework/src/e2e/automation.ts, wework/scripts/ai-verify.mjs
Workspace tabs open in browser or Tauri windows. Automation inspects workspace windows and captures a selected workspace webview.
Platform shell, launcher, and credential lifecycle
wework/src/components/topnav/*, wework/src/components/layout/*, wework/src/components/chat/*, wework/src/features/model-settings/*, wework/src/main.tsx
macOS Tauri feedback controls use a dedicated portal. The launcher uses compact composer and suggestion styling. Local model credentials hydrate when model settings mounts and only for eligible configurations.
Workspace tab validation
wework/e2e/desktop/task-flow.e2e.mjs, design-qa.md, docs/*, related tests
Tests, documentation, and QA evidence cover tab lifecycle, menus, independent windows, accessibility, localization, screenshots, and visual results.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ChromeTitlebar
  participant WorkspaceTabsProvider
  participant CloudTodoWorkspace
  participant WorkspaceWindow
  User->>ChromeTitlebar: create or select workspace tab
  ChromeTitlebar->>WorkspaceTabsProvider: update active tab and route
  WorkspaceTabsProvider->>CloudTodoWorkspace: provide active project ID
  CloudTodoWorkspace-->>WorkspaceTabsProvider: report project selection
  User->>WorkspaceWindow: open tab in new window
  WorkspaceWindow-->>User: show and focus workspace window
Loading

Possibly related PRs

Suggested reviewers: micro66, icycrystal4

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.35% 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
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.
Title check ✅ Passed The title clearly summarizes the main change: adding isolated workspace document tabs and related behavior.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/workspace-document-tabs

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.

@qdaxb
qdaxb marked this pull request as ready for review July 31, 2026 16:44

@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.

Actionable comments posted: 11

🧹 Nitpick comments (5)
wework/src/features/workspace-tabs/workspaceWindow.test.ts (1)

28-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the tauri://error and timeout branches.

The suite covers the browser fallback and the successful Tauri creation path. It does not cover the tauri://error rejection or the creation-timeout path in openWorkspaceTabWindow. These are the two error-handling branches of the function and are currently unverified.

Add a test that makes once invoke the 'tauri://error' callback, and assert the promise rejects with the error message. Add a test that never invokes 'tauri://created', uses fake timers to advance past the timeout, and asserts rejection (and, once the leak fix lands, that the window is closed).

🤖 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/workspace-tabs/workspaceWindow.test.ts` around lines 28 -
76, Add coverage in the openWorkspaceTabWindow tests for both unverified failure
paths: configure once to invoke the tauri://error callback and assert
openWorkspaceTabWindow rejects with the reported error message, then add a
fake-timer test where tauri://created is never invoked, advance beyond the
creation timeout, and assert rejection plus closure of the created window once
that cleanup is implemented.
wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx (1)

176-301: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider splitting WorkspaceTabsProvider into smaller units.

WorkspaceTabsProvider is about 125 lines and combines persistence, seven useCallback handlers, and the memoized context value. Extracting the tab-action callbacks (e.g., into a useWorkspaceTabsActions(state, dispatch, labels) hook) would keep each unit under the guideline size and make the individual actions easier to test in isolation.

As per path instructions: "Comments must be in English, names must be clear, and functions should remain focused, preferably under 50 lines."

🤖 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/workspace-tabs/WorkspaceTabsContext.tsx` around lines 176
- 301, Split WorkspaceTabsProvider into smaller focused units, extracting the
tab-action callbacks into a clearly named useWorkspaceTabsActions hook that
receives state, dispatch, and labels and returns the existing actions. Keep
persistence, state initialization, and context memoization in
WorkspaceTabsProvider, preserving all current behavior while keeping each
function preferably under 50 lines and using clear English names.

Source: Path instructions

wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx (2)

254-261: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Clamp the context menu to the viewport.

The add menu uses menuPosition, which clamps left against window.innerWidth. The context menu uses the raw event.clientX and event.clientY. A right-click near the right edge pushes the 196px menu off screen. Reuse the same clamp for both menus.

🤖 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/workspace-tabs/WorkspaceTabStrip.tsx` around lines 254 -
261, Update the context-menu positioning in WorkspaceTabStrip, where the portal
style uses contextMenu.left and contextMenu.top, to clamp both coordinates
against the viewport using the same menuPosition logic as the add menu. Account
for the context menu’s 196px width and its height when constraining right and
bottom edges, while preserving valid spacing from the viewport.

83-98: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider tightening the tab ARIA structure.

The element carries role="tab" and aria-selected, but it is not focusable and contains two nested buttons. Screen readers announce a tab that cannot receive focus, and the tablist has no arrow-key navigation. Moving role="tab" and aria-selected onto the select button, and keeping the wrapper as a plain container, matches the tabs pattern more closely.

🤖 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/workspace-tabs/WorkspaceTabStrip.tsx` around lines 83 -
98, Update the tab markup in the WorkspaceTabStrip rendering so the outer
wrapper becomes a plain container without role="tab" or aria-selected, and apply
those attributes to the select button instead. Ensure the select button is
focusable and retains the tab’s active-state semantics while preserving the
existing nested close-button behavior and drag/context-menu handlers.
wework/src/features/todo/CloudTodoWorkspace.test.tsx (1)

204-225: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Feed the reported project back into the controlled prop.

activeProjectId stays null for the whole test, so the component never enters the selected state. The assertion on line 223 then passes even if selection state was never tracked. Wrap the component in a small stateful harness that sets activeProjectId from onActiveProjectChange. The test then covers the real synchronization path and can assert the resulting project name.

🤖 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/todo/CloudTodoWorkspace.test.tsx` around lines 204 - 225,
Update the test around CloudTodoWorkspace so a stateful harness feeds each
onActiveProjectChange result back into the activeProjectId prop, including
resetting it to null. Keep the existing project-selection interactions, and
assert the selected project name after synchronization so the test exercises the
controlled state path rather than a permanently null prop.
🤖 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/e2e/desktop/task-flow.e2e.mjs`:
- Around line 2944-2953: Replace the immediate snapshot parsing and assertion
after the board-tab close click with the existing waitForSnapshot helper,
polling until no testId starts with workspace-tab-board-. Preserve the current
failure message and removal condition, following the established pattern used
elsewhere in this test file.

In `@wework/src-tauri/capabilities/default.json`:
- Line 5: Restrict the default capability’s window scope by removing workspace-*
from the windows list in default.json. Define a separate capability for
workspace-* windows containing only the permissions required by secondary
workspace routes, excluding shell execution/opening, unscoped HTTP, dialog,
notification, and webview-creation permissions.

In `@wework/src-tauri/src/desktop_capture.rs`:
- Around line 22-40: The fallback in capture_workspace_webview must select a
deterministic workspace window instead of using HashMap iteration order. Replace
the into_keys().find fallback with logic that filters workspace- labels,
compares their timestamp suffixes, and selects the lexicographically greatest
label; preserve focused-window preference and the existing error when no
workspace window exists.

In `@wework/src/App.tsx`:
- Line 320: Update the workspaceTabStorageScope initialization in App so browser
windows receive a stable, unique per-window scope instead of the shared
'browser' value, while preserving the existing Tauri window-label scope. Use
window.name or another persistent generated window identifier compatible with
WorkspaceTabsProvider storageKey usage.

In `@wework/src/features/todo/CloudTodoWorkspace.tsx`:
- Around line 214-215: Reset project-specific view, board parent, search, and
filter state when the controlled activeProjectId changes externally. Add an
effect keyed to activeProjectId and use a ref or equivalent marker to
distinguish updates initiated by selectProject/applyProjectSelection, preserving
deliberate internal overrides such as onManageProject setting projectView to
manage after selection. Reuse the existing applyProjectSelection reset behavior
without duplicating divergent logic.

In `@wework/src/features/workspace-tabs/workspaceTabs.ts`:
- Around line 51-65: Update WorkspaceTabLabels and workspaceTabTitle to use
caller-provided localized labels for the auxiliary routes instead of hardcoded
English strings. Extend App.tsx’s workspaceTabLabels useMemo with t() values for
Plugins, Sites, Automations, Cloud, and Apps, and add the corresponding
translations to the appropriate Wework namespace in both English and Chinese
locale files.

In `@wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx`:
- Around line 149-160: Compute the collision-adjusted restored tab ID once in
restoreClosedTab, pass that restored tab through the restoreClosed action, and
have the restoreClosed reducer reuse the supplied tab instead of generating
another ID. Keep the existing non-collision behavior and ensure
navigateTo(workspaceTabRoute(...)) and the reducer state reference the same
restored tab.

In `@wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx`:
- Around line 134-135: Update WorkspaceTabButton to call
useTranslation('common') and replace the hardcoded aria-label and title close
text with the translated workbench.workspace_tab_close key, passing the tab
title as its interpolation value. Add matching workspace_tab_close entries to
the English and zh-CN common locale files.
- Around line 76-80: Update handleDragOver to stop reading the source tab ID
from event.dataTransfer, since that value is unavailable during dragover in
Chromium/WebKit. Reuse the drag-start tab ID from the surrounding drag state for
moveTab(sourceId, tab.id), or perform the reorder in the existing drop handler
while preserving the self-tab guard.

In `@wework/src/features/workspace-tabs/workspaceWindow.ts`:
- Around line 46-68: Update the timeout handler in the workspace window creation
flow to close or destroy workspaceWindow before rejecting via finish. Preserve
the existing timeout error and cleanup behavior, and ensure the close operation
is handled without preventing the rejection if it fails.

In `@wework/src/styles/globals.css`:
- Around line 75-95: Update the tablist container in WorkspaceTabStrip so the
10px-outset corners from workspace-document-tab-active::before and ::after are
not clipped: either add sufficient horizontal padding or replace overflow-hidden
with overflow-x-auto overflow-y-visible, while preserving the intended tablist
scrolling behavior.

---

Nitpick comments:
In `@wework/src/features/todo/CloudTodoWorkspace.test.tsx`:
- Around line 204-225: Update the test around CloudTodoWorkspace so a stateful
harness feeds each onActiveProjectChange result back into the activeProjectId
prop, including resetting it to null. Keep the existing project-selection
interactions, and assert the selected project name after synchronization so the
test exercises the controlled state path rather than a permanently null prop.

In `@wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx`:
- Around line 176-301: Split WorkspaceTabsProvider into smaller focused units,
extracting the tab-action callbacks into a clearly named useWorkspaceTabsActions
hook that receives state, dispatch, and labels and returns the existing actions.
Keep persistence, state initialization, and context memoization in
WorkspaceTabsProvider, preserving all current behavior while keeping each
function preferably under 50 lines and using clear English names.

In `@wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx`:
- Around line 254-261: Update the context-menu positioning in WorkspaceTabStrip,
where the portal style uses contextMenu.left and contextMenu.top, to clamp both
coordinates against the viewport using the same menuPosition logic as the add
menu. Account for the context menu’s 196px width and its height when
constraining right and bottom edges, while preserving valid spacing from the
viewport.
- Around line 83-98: Update the tab markup in the WorkspaceTabStrip rendering so
the outer wrapper becomes a plain container without role="tab" or aria-selected,
and apply those attributes to the select button instead. Ensure the select
button is focusable and retains the tab’s active-state semantics while
preserving the existing nested close-button behavior and drag/context-menu
handlers.

In `@wework/src/features/workspace-tabs/workspaceWindow.test.ts`:
- Around line 28-76: Add coverage in the openWorkspaceTabWindow tests for both
unverified failure paths: configure once to invoke the tauri://error callback
and assert openWorkspaceTabWindow rejects with the reported error message, then
add a fake-timer test where tauri://created is never invoked, advance beyond the
creation timeout, and assert rejection plus closure of the created window once
that cleanup is implemented.
🪄 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 Plus

Run ID: d23fafa4-1657-47b2-a139-9fcb390d02c4

📥 Commits

Reviewing files that changed from the base of the PR and between 4953299 and e83be5d.

📒 Files selected for processing (27)
  • design-qa.md
  • wework/e2e/desktop/task-flow.e2e.mjs
  • wework/scripts/ai-verify.mjs
  • wework/src-tauri/capabilities/default.json
  • wework/src-tauri/src/desktop_capture.rs
  • wework/src-tauri/src/lib.rs
  • wework/src/App.apps.test.tsx
  • wework/src/App.tsx
  • wework/src/components/layout/DesktopAppSwitcher.test.tsx
  • wework/src/components/layout/DesktopAppSwitcher.tsx
  • wework/src/components/layout/DesktopWorkbenchLayout.tsx
  • wework/src/components/topnav/ChromeTitlebar.test.tsx
  • wework/src/components/topnav/ChromeTitlebar.tsx
  • wework/src/e2e/automation.ts
  • wework/src/features/todo/CloudTodoWorkspace.test.tsx
  • wework/src/features/todo/CloudTodoWorkspace.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.test.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
  • wework/src/features/workspace-tabs/workspaceTabs.test.ts
  • wework/src/features/workspace-tabs/workspaceTabs.ts
  • wework/src/features/workspace-tabs/workspaceTabsContextValue.ts
  • wework/src/features/workspace-tabs/workspaceWindow.test.ts
  • wework/src/features/workspace-tabs/workspaceWindow.ts
  • wework/src/i18n/locales/en/common.json
  • wework/src/i18n/locales/zh-CN/common.json
  • wework/src/styles/globals.css

Comment thread wework/e2e/desktop/task-flow.e2e.mjs Outdated
Comment thread wework/src-tauri/capabilities/default.json Outdated
Comment thread wework/src-tauri/src/desktop_capture.rs
Comment thread wework/src/App.tsx Outdated
Comment thread wework/src/features/todo/CloudTodoWorkspace.tsx
Comment thread wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
Comment thread wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx
Comment thread wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx Outdated
Comment thread wework/src/features/workspace-tabs/workspaceWindow.ts
Comment thread wework/src/styles/globals.css Outdated

@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.

Actionable comments posted: 5

🤖 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 `@design-qa.md`:
- Around line 19-20: Reorder the documentation sections in design-qa.md so the
Chinese workspace-tabs documentation appears before the English “Workspace
Document Tabs Follow-up Review” section, preserving the content of both sections
unchanged.
- Line 23: Replace the developer-specific absolute reference path in the design
evidence entry with a repository-relative path or a review artifact attachment,
ensuring all reviewers and CI can access the referenced image.
- Around line 53-61: Add case-level QA evidence to the “Interaction and
accessibility verification” section for every changed tab flow, documenting
preconditions, environment, test data, exact steps, expected and actual results,
negative and recovery cases, cleanup, and supporting evidence. Retain the
existing accessibility and visual verification outcomes while expanding the
flows into complete QA cases.

In `@wework/src-tauri/capabilities/workspace-window.json`:
- Around line 7-20: Remove the "core:default" entry from the workspace-window
capability permissions, leaving the explicit window chrome permissions in place.
Do not add broader core permissions unless a concrete caller requires them.

In `@wework/src/features/todo/CloudTodoWorkspace.test.tsx`:
- Line 234: Update the project ID passed to CloudTodoWorkspace in the test
fixture around project.id so it is an actual string, using String(project.id) or
defining the fixture ID as a string. Remove the as unknown as string cast and
preserve the controlled string-ID behavior used by the component.
🪄 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 Plus

Run ID: 7dd6b08c-6165-44d4-b194-f5d6a382cc53

📥 Commits

Reviewing files that changed from the base of the PR and between e83be5d and 3579d57.

📒 Files selected for processing (19)
  • design-qa.md
  • wework/e2e/desktop/task-flow.e2e.mjs
  • wework/src-tauri/capabilities/workspace-window.json
  • wework/src-tauri/src/desktop_capture.rs
  • wework/src/App.apps.test.tsx
  • wework/src/App.tsx
  • wework/src/components/topnav/ChromeTitlebar.test.tsx
  • wework/src/features/todo/CloudTodoWorkspace.test.tsx
  • wework/src/features/todo/CloudTodoWorkspace.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.test.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
  • wework/src/features/workspace-tabs/workspaceTabs.test.ts
  • wework/src/features/workspace-tabs/workspaceTabs.ts
  • wework/src/features/workspace-tabs/workspaceWindow.test.ts
  • wework/src/features/workspace-tabs/workspaceWindow.ts
  • wework/src/i18n/locales/en/common.json
  • wework/src/i18n/locales/zh-CN/common.json
  • wework/src/styles/globals.css
🚧 Files skipped from review as they are similar to previous changes (12)
  • wework/src/App.apps.test.tsx
  • wework/src-tauri/src/desktop_capture.rs
  • wework/src/i18n/locales/zh-CN/common.json
  • wework/e2e/desktop/task-flow.e2e.mjs
  • wework/src/features/workspace-tabs/workspaceWindow.ts
  • wework/src/styles/globals.css
  • wework/src/App.tsx
  • wework/src/features/workspace-tabs/workspaceTabs.test.ts
  • wework/src/i18n/locales/en/common.json
  • wework/src/features/todo/CloudTodoWorkspace.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx

Comment thread design-qa.md Outdated
Comment thread design-qa.md Outdated
Comment thread design-qa.md Outdated
Comment thread wework/src-tauri/capabilities/workspace-window.json Outdated
Comment thread wework/src/features/todo/CloudTodoWorkspace.test.tsx Outdated

@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.

Actionable comments posted: 1

🤖 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/main.tsx`:
- Line 50: Add a regression test covering a cold start where a persisted
local-model request is selected from the workbench before
LocalModelSettingsSection mounts, and verify native API keys are hydrated before
the request begins. Alternatively, update the request initialization path
associated with installWeworkAutomationBridge so it invokes
ensureLocalModelApiKeysHydrated() before starting local-model requests.
🪄 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 Plus

Run ID: 48487c55-c8e1-47b5-9a67-2d1e30f70f64

📥 Commits

Reviewing files that changed from the base of the PR and between a9f297a and eac9e5c.

📒 Files selected for processing (23)
  • docs/en/wework/workbench.md
  • docs/zh/wework/workbench.md
  • wework/e2e/desktop/task-flow.e2e.mjs
  • wework/src-tauri/src/lib.rs
  • wework/src/App.apps.test.tsx
  • wework/src/App.tsx
  • wework/src/components/layout/DesktopWorkbenchLayout.test.tsx
  • wework/src/components/layout/DesktopWorkbenchMain.tsx
  • wework/src/components/settings/ModelSettingsPage.tsx
  • wework/src/components/topnav/ChromeTitlebar.test.tsx
  • wework/src/components/topnav/ChromeTitlebar.tsx
  • wework/src/components/topnav/TitlebarActionsPortal.tsx
  • wework/src/e2e/automation.ts
  • wework/src/features/model-settings/localModelSettings.secure.test.ts
  • wework/src/features/model-settings/localModelSettings.ts
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.test.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.test.tsx
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
  • wework/src/features/workspace-tabs/workspaceWindow.test.ts
  • wework/src/features/workspace-tabs/workspaceWindow.ts
  • wework/src/main.tsx
  • wework/src/styles/globals.css
🚧 Files skipped from review as they are similar to previous changes (12)
  • wework/src-tauri/src/lib.rs
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.test.tsx
  • wework/src/styles/globals.css
  • wework/src/features/workspace-tabs/workspaceWindow.test.ts
  • wework/src/features/workspace-tabs/WorkspaceTabStrip.tsx
  • wework/src/features/workspace-tabs/workspaceWindow.ts
  • wework/src/App.apps.test.tsx
  • wework/e2e/desktop/task-flow.e2e.mjs
  • wework/src/e2e/automation.ts
  • wework/src/features/workspace-tabs/WorkspaceTabsContext.tsx
  • wework/src/App.tsx
  • wework/src/components/topnav/ChromeTitlebar.test.tsx

Comment thread wework/src/main.tsx
console.error('Failed to restore local model credentials', error)
})
void installWeworkAutomationBridge(localModelApiKeyHydration)
void installWeworkAutomationBridge()

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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Credential hydration and local-model consumers"
rg -n -C 6 \
  'ensureLocalModelApiKeysHydrated|hydrateLocalModelApiKeys|localModelApiKeys|apiKeyConfigured|listLocalModelConfigs' \
  wework/src --glob '*.{ts,tsx}'

echo "Settings routes and workbench entry points"
rg -n -i -C 8 \
  'ModelSettingsPage|LocalModelSettingsSection|local model|localmodel' \
  wework/src --glob '*.{ts,tsx}'

Repository: wecode-ai/Wegent

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "wework/src/main.tsx relevant startup"
sed -n '1,90p' wework/src/main.tsx

echo "localModelSettings hydration exports"
rg -n -C 5 \
  '(ensureLocalModelApiKeysHydrated|hydrateLocalModelApiKeys|localModelApiKeys|LocalModelApiKeysContext|setApiKeys|getApiKeys|useLocalModelApiKeys|LOCAL_MODEL_API_KEYS_CHANGED_EVENT)' \
  wework/src/features/model-settings wework/src --glob '*.{ts,tsx}' | head -n 240

echo "localModelProviders calls with apiKey and model selection"
rg -n -C 7 \
  'discoverProviderModels|findLocalModelProviderProfile|LocalModelConfig|providerProfileId|baseUrl|apiKeyConfigured|apiKey' \
  wework/src/features/model-settings/localModelProviders.ts \
  wework/src/features/workbench/runtimeModelSelection.ts \
  wework/src/components/settings/ModelSettingsPage.tsx | head -n 360

Repository: wecode-ai/Wegent

Length of output: 50372


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "ModelSettingsPage hydration and change handling"
sed -n '680,750p' wework/src/components/settings/ModelSettingsPage.tsx
sed -n '1620,1700p' wework/src/components/settings/ModelSettingsPage.tsx
sed -n '2065,2125p' wework/src/components/settings/ModelSettingsPage.tsx

echo "workbench model loading and request construction"
sed -n '1,180p' wework/src/features/workbench/useWorkbenchModels.ts
sed -n '1,170p' wework/src/features/workbench/runtimeModelSelection.ts

echo "workbench API consumers with model and execution"
rg -n -C 6 \
  'listModels|selectedModel|execute|send|chat|messages|createCompletion|createChatCompletion|create.*Responses|provider === .local|runtime: {.*provider.*local|modelId' \
  wework/src/features/workbench wework/src/components/workbench --glob '*.{ts,tsx}' | head -n 320

echo "local model request helpers focused"
rg -n -C 4 \
  'buildLocalModelRequestUrl|defaultLocalModelRequestPath|getLocalModelApiKey|readLocalModelConfig|updateLocalModelConfig|deleteLocalModelConfig' \
  wework/src/features/model-settings/localModelSettings.ts

echo "exported local-model helper list"
sed -n '160,240p' wework/src/features/model-settings/localModelSettings.ts
sed -n '730,770p' wework/src/features/model-settings/localModelSettings.ts
sed -n '790,870p' wework/src/features/model-settings/localModelSettings.ts

Repository: wecode-ai/Wegent

Length of output: 21463


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "workbench execution/request model consumers"
rg -n -C 5 \
  'selectedModel|selectedModelOptions|selectedModelExecutionFields|listModels|execute|send|chat|messages|createCompletion|createChatCompletion|create.*Responses|modelId|modelType|provider.*local|RuntimeSendRequest' \
  wework/src/features/workbench wework/src/components/workbench --glob '*.{ts,tsx}' | head -n 420

echo "model API definitions and workbench API wiring"
fd -a 'workbench.*\.(ts|tsx)|models|Model' wework/src | sed 's#^\./##' | head -n 80
rg -n -C 5 \
  'listModels|UnifiedModel|UnifiedModelListResponse|runtime.*local|provider.*local|modelId|modelType' \
  wework/src/api wework/src/features wework/src/components --glob '*.{ts,tsx}' | head -n 500

echo "local model helper exports"
sed -n '145,155p' wework/src/features/model-settings/localModelSettings.ts
sed -n '210,225p' wework/src/features/model-settings/localModelSettings.ts
sed -n '760,810p' wework/src/features/model-settings/localModelSettings.ts
sed -n '830,885p' wework/src/features/model-settings/localModelSettings.ts

echo "model settings hydration event imports"
rg -n \
  'LOCAL_MODEL_SETTINGS_CHANGED_EVENT|LOCAL_MODEL_API_KEYS_CHANGED_EVENT|ensureLocalModelApiKeysHydrated' \
  wework/src --glob '*.{ts,tsx}'

Repository: wecode-ai/Wegent

Length of output: 38257


Add a cold-start test for local-model hydration.

ensureLocalModelApiKeysHydrated() is only called after LocalModelSettingsSection mounts, so a persisted local-model request can start before the native API keys are loaded. Add a regression test that selects a persisted local model from the workbench without opening Model Settings, or hydrate credentials from the request initialization path.

🤖 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/main.tsx` at line 50, Add a regression test covering a cold start
where a persisted local-model request is selected from the workbench before
LocalModelSettingsSection mounts, and verify native API keys are hydrated before
the request begins. Alternatively, update the request initialization path
associated with installWeworkAutomationBridge so it invokes
ensureLocalModelApiKeysHydrated() before starting local-model requests.

@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.

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/DesktopEmptyTaskLauncher.tsx (1)

163-204: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Restore 44px mobile touch targets.

On mobile, the back button is 32px high. The category and suggestion buttons are 36px high. These controls must be at least 44px × 44px.

  • wework/src/components/layout/DesktopEmptyTaskLauncher.tsx#L163-L204: use min-h-11 and min-w-11 for mobile controls. Apply smaller dimensions only at lg or above if required.
  • wework/src/components/layout/DesktopEmptyTaskLauncher.test.tsx#L68-L71: update the assertion to enforce the mobile touch-target classes.

As per coding guidelines, “Mobile controls must be at least 44px × 44px.”

🤖 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/DesktopEmptyTaskLauncher.tsx` around lines 163 -
204, Restore 44px mobile touch targets in DesktopEmptyTaskLauncher.tsx by
applying min-h-11 and min-w-11 to the back, category, and suggestion buttons,
with any smaller sizing restricted to lg and above. Update
DesktopEmptyTaskLauncher.test.tsx lines 68-71 to assert the required mobile
touch-target classes.

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.

Outside diff comments:
In `@wework/src/components/layout/DesktopEmptyTaskLauncher.tsx`:
- Around line 163-204: Restore 44px mobile touch targets in
DesktopEmptyTaskLauncher.tsx by applying min-h-11 and min-w-11 to the back,
category, and suggestion buttons, with any smaller sizing restricted to lg and
above. Update DesktopEmptyTaskLauncher.test.tsx lines 68-71 to assert the
required mobile touch-target classes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 00f9f51f-d9a9-4d68-91fe-4514329c086a

📥 Commits

Reviewing files that changed from the base of the PR and between eac9e5c and fdd6728.

📒 Files selected for processing (9)
  • docs/en/wework/workbench.md
  • docs/zh/wework/workbench.md
  • wework/src/components/chat/ChatInput.test.tsx
  • wework/src/components/chat/ChatInput.tsx
  • wework/src/components/chat/composer/ProjectChatComposer.tsx
  • wework/src/components/layout/DesktopEmptyTaskLauncher.module.css
  • wework/src/components/layout/DesktopEmptyTaskLauncher.test.tsx
  • wework/src/components/layout/DesktopEmptyTaskLauncher.tsx
  • wework/src/components/layout/DesktopWorkbenchMain.tsx
💤 Files with no reviewable changes (1)
  • wework/src/components/layout/DesktopEmptyTaskLauncher.module.css
🚧 Files skipped from review as they are similar to previous changes (3)
  • wework/src/components/layout/DesktopWorkbenchMain.tsx
  • docs/zh/wework/workbench.md
  • docs/en/wework/workbench.md

@qdaxb qdaxb changed the title feat(wework): add workspace document tabs feat(wework): complete isolated workspace tabs Aug 1, 2026
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.

1 participant