Skip to content

fix(wework): restrict project tools to ClaudeCode devices - #1280

Merged
qdaxb merged 2 commits into
wecode-ai:mainfrom
FicoHu:fix/claudecode-project-tools
Jun 4, 2026
Merged

qdaxb merged 2 commits into
wecode-ai:mainfrom
FicoHu:fix/claudecode-project-tools

Conversation

@FicoHu

@FicoHu FicoHu commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added an overlay-style tool launcher and an always-present “new tab” control for terminal sessions.
  • Improvements

    • Better device filtering and selection to prefer compatible cloud devices and handle bind-shell variations case-insensitively.
    • Simplified session startup behavior to avoid pre-opening probes and provide clearer failure handling.
    • Improved terminal tab/window behavior and multi-frame handling.
  • Bug Fixes

    • Fixed UI to hide incompatible cloud devices from standalone and project device selectors; IDE opening now succeeds when probing is blocked.
  • Tests

    • Expanded test coverage for device availability, terminal tabs, and IDE startup scenarios.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9b476675-4057-45c8-962a-1002ae7eab1b

📥 Commits

Reviewing files that changed from the base of the PR and between 7659815 and 3213518.

📒 Files selected for processing (2)
  • wework/src/components/projects/ProjectCreateDialog.test.tsx
  • wework/src/components/projects/ProjectCreateDialog.tsx

📝 Walkthrough

Walkthrough

This PR filters standalone devices and tool availability based on Claude Code device type detection. Device filtering via bind_shell (case-insensitive) distinguishes Claude Code devices from other types like OpenClaw. Session startup is simplified by removing URL probing, and a tool launcher overlay is added to the workspace panels component.

Changes

Device Type Filtering and Tool Availability

Layer / File(s) Summary
Device type contracts and filtering predicates
wework/src/lib/device-selection.ts, wework/src/lib/device-capabilities.ts
SelectableDevice adds optional bind_shell field. New case-insensitive isClaudeCodeDevice predicates distinguish Claude Code devices. supportsCloudSessions now requires both cloud type and Claude Code type. sortStandaloneDevices and getPreferredStandaloneDeviceId filter to Claude Code devices only.
Session startup without URL probing
wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx
Remove SessionUrlUnavailableError, toSessionProbeUrl, probeSessionUrl, and SESSION_PROBE_QUERY_KEY. Simplify error handling to generic "project_tool_start_failed". Update startTerminalSession and handleIdeClick to throw generic Error on missing session URL; no preflight probing performed.
Tool availability computation and state
wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx
Recompute hasExplicitLocalDevice and cloudToolsAvailable from new supportsCloudSessions predicate. Add showToolLauncher state to control overlay visibility. Introduce terminalTabLabel derived from project context.
Terminal and tool launcher UI refactoring
wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx
Replace early-return with conditional terminalWindow rendering. Restructure terminal tabs with updated styling and click handlers controlling showToolLauncher. Render tool launcher overlay with project/tool cards and error messaging; conditionally show frames via hidden={!isActive}.
WorkspacePanelCards test coverage
wework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsx
Add openClawCloudDevices fixture. Expand terminal UI assertions for tab content, visibility, and multi-frame management. Introduce device-specific tool availability tests. Verify IDE succeeds despite blocked probing; update session failure assertions.
ChatInput & ProjectCreateDialog device filtering validation
wework/src/components/chat/ChatInput.test.tsx, wework/src/components/projects/ProjectCreateDialog.tsx, wework/src/components/projects/ProjectCreateDialog.test.tsx
Add OpenClaw cloud device to fixtures and assert it is excluded from standalone-device and project-creation selectors. Add getProjectCreationDevices() helper and use it for default selection.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • wecode-ai/Wegent#1187: The main PR changes how the frontend decides whether a device supports cloud sessions and how it starts terminal/IDE sessions (removing URL probing and relying on session-start behavior), which aligns directly with the retrieved PR adding the backend/API endpoints to start terminal and code-server device sessions.
  • wecode-ai/Wegent#1139: Both PRs update ProjectCreateDialog device-selection behavior to exclude OpenClaw (bind_shell === 'openclaw') and add/adjust tests asserting the OpenClaw option is not rendered.
  • wecode-ai/Wegent#1200: The retrieved PR’s project/standalone chat workflow relies on standalone device selection logic (e.g., getPreferredStandaloneDeviceId/device ordering), which is directly affected by this PR’s changes to wework/src/lib/device-selection.ts/device capability filtering rules for standalone devices.

Suggested reviewers

  • qdaxb

Poem

🐰 I hop through code with a curious wink,

bind_shells whisper and choices shrink.
The launcher pops up — no probes in the way,
Claude Code hops forward to join the play.
OpenClaw stays quiet, watching the day.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(wework): restrict project tools to ClaudeCode devices' clearly and specifically describes the main objective of the changeset—restricting project tools to work only with ClaudeCode devices.
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.

✏️ 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 (2)
wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx (1)

110-127: 💤 Low value

getSessionStartErrorMessage receives an unused argument.

The function is defined with no parameters but is called with e as an argument at lines 127 and 169. The error details are discarded. If this is intentional (to always show a generic message), remove the argument from the call sites for clarity. If error details should influence the message, update the function signature.

-  const getSessionStartErrorMessage = () => t('workbench.project_tool_start_failed', '启动失败')
+  const getSessionStartErrorMessage = (_error?: unknown) => t('workbench.project_tool_start_failed', '启动失败')

Or remove arguments at call sites:

-      setProjectError(getSessionStartErrorMessage(e))
+      setProjectError(getSessionStartErrorMessage())
🤖 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 110 - 127, getSessionStartErrorMessage is defined with no parameters but
callers (in startTerminalSession and another call around where
setProjectError(...) is invoked) pass the caught error `e`; either remove the
unused `e` argument from those setProjectError(getSessionStartErrorMessage(e))
call sites so they call getSessionStartErrorMessage() with no args, or change
getSessionStartErrorMessage to accept an error parameter (e.g., (err?: unknown))
and incorporate err into the returned string; update all usages (references in
startTerminalSession and the other setProjectError call) to match the chosen
signature so the function and callers stay consistent.
wework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsx (1)

306-323: 💤 Low value

Test name is misleading; setup includes dead code.

The test sets up fetchMock.mockRejectedValueOnce but then asserts fetchMock is never called. The test verifies probing was removed entirely, not that it handles blocked probing. Consider:

  1. Renaming the test to match actual behavior
  2. Removing the unnecessary mock setup
-  test('opens IDE even when browser preflight probing would be blocked', async () => {
+  test('opens IDE without preflight probing', async () => {
     const api = createProjectApiMock()
-    fetchMock.mockRejectedValueOnce(new TypeError('Mixed content blocked'))
     render(<WorkspacePanelCards currentProject={project} devices={cloudDevices} />)
🤖 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 306 - 323, Rename the test and remove the dead mock setup: change
the test title on the test that currently reads "opens IDE even when browser
preflight probing would be blocked" to something matching the actual behavior
(e.g. "opens IDE without preflight probing") and delete the unused
fetchMock.mockRejectedValueOnce(new TypeError('Mixed content blocked')) line;
the rest of the test (render(<WorkspacePanelCards ...>),
userEvent.click(screen.getByTestId('workspace-ide-card')), and the assertions
expect(fetchMock).not.toHaveBeenCalled() / expect(api.startCodeServerSession)...
/ expect(window.open)...) should remain 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/workspace-panels/WorkspacePanelCards.test.tsx`:
- Around line 306-323: Rename the test and remove the dead mock setup: change
the test title on the test that currently reads "opens IDE even when browser
preflight probing would be blocked" to something matching the actual behavior
(e.g. "opens IDE without preflight probing") and delete the unused
fetchMock.mockRejectedValueOnce(new TypeError('Mixed content blocked')) line;
the rest of the test (render(<WorkspacePanelCards ...>),
userEvent.click(screen.getByTestId('workspace-ide-card')), and the assertions
expect(fetchMock).not.toHaveBeenCalled() / expect(api.startCodeServerSession)...
/ expect(window.open)...) should remain unchanged.

In `@wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx`:
- Around line 110-127: getSessionStartErrorMessage is defined with no parameters
but callers (in startTerminalSession and another call around where
setProjectError(...) is invoked) pass the caught error `e`; either remove the
unused `e` argument from those setProjectError(getSessionStartErrorMessage(e))
call sites so they call getSessionStartErrorMessage() with no args, or change
getSessionStartErrorMessage to accept an error parameter (e.g., (err?: unknown))
and incorporate err into the returned string; update all usages (references in
startTerminalSession and the other setProjectError call) to match the chosen
signature so the function and callers stay consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5a79372f-21ca-4529-8372-586ce35ae971

📥 Commits

Reviewing files that changed from the base of the PR and between 2aecdfb and 7659815.

📒 Files selected for processing (5)
  • wework/src/components/chat/ChatInput.test.tsx
  • wework/src/components/layout/workspace-panels/WorkspacePanelCards.test.tsx
  • wework/src/components/layout/workspace-panels/WorkspacePanelCards.tsx
  • wework/src/lib/device-capabilities.ts
  • wework/src/lib/device-selection.ts

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