Skip to content

fix(desktop): revert broken chrome-devtools-mcp/browser PRs, re-implement with fixes#1673

Merged
benjaminshafii merged 6 commits intodevfrom
fix/chrome-devtools-browser-panel
May 6, 2026
Merged

fix(desktop): revert broken chrome-devtools-mcp/browser PRs, re-implement with fixes#1673
benjaminshafii merged 6 commits intodevfrom
fix/chrome-devtools-browser-panel

Conversation

@benjaminshafii
Copy link
Copy Markdown
Member

@benjaminshafii benjaminshafii commented May 6, 2026

Summary

Reverts the two broken PRs (#1670, #1671) and re-implements them with fixes.

Bugs found and fixed

Bug Root cause Fix
Control Chrome writes nothing to opencode.json resolveChromeDevtoolsMcpBin IPC returned [process.execPath, binPath]process.execPath in Electron is the Electron binary (e.g. .../Electron.app/.../Electron), not node. OpenCode couldn't spawn it. Use "node" string literal instead of process.execPath
Leaked -y flag Args filter arg.startsWith("-") matched npx's -y flag and passed it to chrome-devtools-mcp Changed filter to arg.startsWith("--") only
mcp.add fallback used original command The mcp.add SDK call at store.ts:590 used entry.command (original npx command) instead of the resolved command Use mcpEntryConfig["command"] which has the resolved value
Browser panel zero-dimension bounds getBoundingClientRect() on first render could return {width: 0, height: 0} before layout settles Skip browser.show() until dimensions are non-zero, let ResizeObserver trigger it
destroyBrowserView crash on window close webContents.close() could fail if already destroyed with parent window Added try/catch

Verification

# IPC handler returns correct command
resolveChromeDevtoolsMcpBin() → ["node", "/abs/path/to/.../index.js"]
# NOT ["Electron", "/abs/path/..."]

# All tests pass
bun test apps/app/tests/
# 17 pass, 0 fail

# Electron app starts and loads
OPENWORK_DEV_MODE=1 pnpm exec electron ./electron/main.mjs
# DevTools listening on ws://127.0.0.1:9824/...
# CDP targets visible at /json endpoint

Files changed

File Change
apps/desktop/package.json Add chrome-devtools-mcp@0.17.0 dependency
apps/desktop/electron/main.mjs WebContentsView browser + fixed resolveChromeDevtoolsMcpBin IPC (uses "node" not process.execPath)
apps/desktop/electron/preload.mjs Expose browser.* methods
apps/app/src/app/mcp.ts Add resolveChromeDevtoolsMcpCommand()
apps/app/src/app/lib/desktop.ts TypeScript types for browser bridge
apps/app/src/react-app/domains/connections/store.ts Use resolved command + fix mcp.add fallback
apps/app/src/react-app/domains/session/browser/browser-panel.tsx Browser panel with zero-dimension guard
apps/app/src/react-app/domains/session/chat/session-page.tsx Globe toggle + browser panel integration
apps/desktop/scripts/chrome-devtools-mcp-shim.ts Try bundled bin first, npm exec fallback
apps/desktop/scripts/prepare-sidecar.mjs Remove bun-compiled sidecar build

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openwork-app Ready Ready Preview, Comment May 6, 2026 4:46am
openwork-den Ready Ready Preview, Comment May 6, 2026 4:46am
openwork-den-worker-proxy Ready Ready Preview, Comment May 6, 2026 4:46am
openwork-landing Ready Ready Preview, Comment, Open in v0 May 6, 2026 4:46am
openwork-share Ready Ready Preview, Comment May 6, 2026 4:46am

…ixed)

Re-implements both features with fixes for the issues found in #1670/#1671:

Fixes from PR1 (chrome-devtools-mcp bundling):
- Use 'node' string literal instead of process.execPath in the IPC
  handler — process.execPath in Electron is the Electron binary, not
  node, so OpenCode couldn't spawn the command
- Fix args filter to only carry --prefixed flags (not -y from npx)
- Fix mcp.add fallback path to use resolved command from mcpEntryConfig
  instead of the original entry.command

Fixes from PR2 (embedded browser panel):
- Guard against zero-dimension bounds on first render — skip
  browser.show() until the panel has non-zero dimensions, let
  ResizeObserver trigger the actual show
- Defensive try/catch in destroyBrowserView for already-destroyed
  webContents

Verified:
- resolveChromeDevtoolsMcpBin returns ['node', '<abs-path>'] (not
  ['Electron', '<path>'])
- All 17 existing tests pass
- Electron app starts and loads successfully
- CDP targets visible at the remote debugging port
…engine start

When the OpenCode engine starts in the Electron desktop app,
ensureOpencodeConfig now automatically adds a chrome-devtools MCP entry
to opencode.json if one doesn't already exist. The command uses the
bundled chrome-devtools-mcp package (['node', '<abs-path>']) so no
npm/npx is needed at runtime.

This mirrors what Tauri's ensure_workspace_files() does in files.rs for
the starter preset, making Control Chrome a zero-setup default for all
Electron workspaces.
ensureOpencodeConfig in runtime.mjs only runs when the OpenCode engine
starts, which happens asynchronously after the workspace is selected.
New workspaces were left without a chrome-devtools entry because the
engine hadn't started yet.

Fix: call seedChromeDevtoolsMcp(folderPath) directly inside the
workspaceCreate IPC handler so the config is written synchronously
during workspace creation. The runtime.mjs ensureOpencodeConfig
remains as a backup for workspaces created before this change.

Verified: created a workspace via IPC, confirmed opencode.jsonc
contains chrome-devtools with ['node', '<bundled-bin-path>'].
…dled node path

Existing workspaces created by Tauri or older Electron versions have
chrome-devtools MCP entries with npx-based or bare-binary commands
like ['npx','-y','chrome-devtools-mcp@latest'] or ['chrome-devtools-mcp'].

Both seedChromeDevtoolsMcp (main.mjs, runs at workspace creation) and
ensureOpencodeConfig (runtime.mjs, runs at engine start) now detect
these legacy commands and migrate them to the bundled ['node', path]
command. User-customised commands (absolute paths, etc.) are preserved.
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