From 1816e10de9034c11cfff203d08a537b9ce6ba891 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sat, 1 Aug 2026 02:10:10 +0200 Subject: [PATCH] fix(desktop): let Chromium allocate the debugging port --- docs/development.md | 15 +++--- .../desktop/scripts/dev-runtime-config.mjs | 52 ++----------------- packages/desktop/scripts/dev-runtime.test.mjs | 24 ++++----- packages/desktop/scripts/dev.ps1 | 2 - packages/desktop/scripts/dev.sh | 2 - 5 files changed, 21 insertions(+), 74 deletions(-) diff --git a/docs/development.md b/docs/development.md index 7e12cc656f..5d93542cee 100644 --- a/docs/development.md +++ b/docs/development.md @@ -103,11 +103,11 @@ The iOS simulator shares the Mac's loopback, so `localhost:` reaches the h ### Desktop renderer profiling `npm run dev:desktop` starts Electron with Chromium remote debugging enabled so -renderer CPU profiles can be captured through CDP. It prefers -`http://127.0.0.1:9223` and automatically selects a free port when that port is -already occupied. The startup banner prints the selected URL. It launches its own -Electron-flavored Expo server and passes that URL to Electron. Set -`PASEO_ELECTRON_REMOTE_DEBUGGING_PORT` when a QA workflow requires a fixed port. +renderer CPU profiles can be captured through CDP. By default it passes +`--remote-debugging-port=0`, so Chromium atomically asks the OS for an available +port and prints the selected DevTools endpoint. Set +`PASEO_ELECTRON_REMOTE_DEBUGGING_PORT` when a QA workflow requires a validated, +fixed port. Desktop dev also scopes Electron `userData` to the current dev root. This prevents desktop-only environment inherited by terminals opened inside Paseo from coupling @@ -126,8 +126,9 @@ npm run verify:electron-cdp --workspace=@getpaseo/desktop ``` The verifier reads the same `EXPO_PORT` and -`PASEO_ELECTRON_REMOTE_DEBUGGING_PORT` environment names as desktop dev. Set both when -testing an isolated instance on non-default ports. +`PASEO_ELECTRON_REMOTE_DEBUGGING_PORT` environment names as desktop dev. Set an +explicit remote-debugging port for verifier runs, and set both when testing an +isolated instance on non-default ports. When running a dedicated Electron QA instance against a non-default Expo port, set `EXPO_DEV_URL` explicitly. Desktop main defaults to `http://localhost:8081`, so diff --git a/packages/desktop/scripts/dev-runtime-config.mjs b/packages/desktop/scripts/dev-runtime-config.mjs index 2c4bb87e19..322834a5f6 100644 --- a/packages/desktop/scripts/dev-runtime-config.mjs +++ b/packages/desktop/scripts/dev-runtime-config.mjs @@ -1,8 +1,5 @@ -import net from "node:net"; import path from "node:path"; -const DEFAULT_REMOTE_DEBUGGING_PORT = 9223; - export function resolveDevUserDataDir({ devRoot, inheritedUserDataDir, fallbackRoot }) { if (devRoot) { return path.join(devRoot, ".dev", "user-data"); @@ -33,53 +30,12 @@ function parsePort(value, name) { return port; } -export function findAvailablePort(preferredPort, host = "127.0.0.1") { - return new Promise((resolve, reject) => { - const server = net.createServer(); - server.unref(); - server.once("error", (error) => { - if (error.code === "EADDRINUSE" || error.code === "EACCES") { - resolve(findAvailablePort(0, host)); - return; - } - reject(error); - }); - server.listen(preferredPort, host, () => { - const address = server.address(); - if (!address || typeof address === "string") { - server.close(); - reject(new Error("Could not resolve an available CDP port")); - return; - } - server.close((error) => { - if (error) { - reject(error); - return; - } - resolve(address.port); - }); - }); - }); -} - -export async function selectRemoteDebuggingPort({ - configuredPort, - preferredPort = DEFAULT_REMOTE_DEBUGGING_PORT, - findAvailablePort: findPort = findAvailablePort, -} = {}) { - if (configuredPort) { - return parsePort(configuredPort, "PASEO_ELECTRON_REMOTE_DEBUGGING_PORT"); - } - return findPort(preferredPort); -} - -export async function resolveDevRuntime(env = process.env) { - const remoteDebuggingPort = await selectRemoteDebuggingPort({ - configuredPort: env.PASEO_ELECTRON_REMOTE_DEBUGGING_PORT, - }); +export function resolveDevRuntime(env = process.env) { + const remoteDebuggingPort = env.PASEO_ELECTRON_REMOTE_DEBUGGING_PORT + ? parsePort(env.PASEO_ELECTRON_REMOTE_DEBUGGING_PORT, "PASEO_ELECTRON_REMOTE_DEBUGGING_PORT") + : 0; return { electronFlags: buildElectronFlags(env.PASEO_ELECTRON_FLAGS, remoteDebuggingPort), - remoteDebuggingPort, userDataDir: resolveDevUserDataDir({ devRoot: env.PASEO_DEV_ROOT, inheritedUserDataDir: env.PASEO_ELECTRON_USER_DATA_DIR, diff --git a/packages/desktop/scripts/dev-runtime.test.mjs b/packages/desktop/scripts/dev-runtime.test.mjs index c388081c13..ca2b322bec 100644 --- a/packages/desktop/scripts/dev-runtime.test.mjs +++ b/packages/desktop/scripts/dev-runtime.test.mjs @@ -2,8 +2,8 @@ import path from "node:path"; import { describe, expect, test } from "vitest"; import { buildElectronFlags, + resolveDevRuntime, resolveDevUserDataDir, - selectRemoteDebuggingPort, } from "./dev-runtime-config.mjs"; describe("desktop dev runtime isolation", () => { @@ -31,26 +31,20 @@ describe("desktop dev runtime isolation", () => { ); }); - test("selects another CDP port when the default is occupied", async () => { - const selectedPort = await selectRemoteDebuggingPort({ - preferredPort: 9223, - findAvailablePort: async (preferredPort) => { - expect(preferredPort).toBe(9223); - return 43127; - }, + test("lets Chromium atomically allocate the default CDP port", async () => { + const runtime = await resolveDevRuntime({ + PASEO_DEV_RUNTIME_FALLBACK_ROOT: "/checkouts/paseo", }); - expect(selectedPort).toBe(43127); + expect(runtime.electronFlags).toBe("--remote-debugging-port=0"); }); test("honors an explicit CDP port without silently changing it", async () => { - const selectedPort = await selectRemoteDebuggingPort({ - configuredPort: "9333", - findAvailablePort: async () => { - throw new Error("must not probe an explicit port"); - }, + const runtime = await resolveDevRuntime({ + PASEO_DEV_RUNTIME_FALLBACK_ROOT: "/checkouts/paseo", + PASEO_ELECTRON_REMOTE_DEBUGGING_PORT: "9333", }); - expect(selectedPort).toBe(9333); + expect(runtime.electronFlags).toBe("--remote-debugging-port=9333"); }); }); diff --git a/packages/desktop/scripts/dev.ps1 b/packages/desktop/scripts/dev.ps1 index bd495ca816..81f8e4ab6e 100644 --- a/packages/desktop/scripts/dev.ps1 +++ b/packages/desktop/scripts/dev.ps1 @@ -36,7 +36,6 @@ $env:EXPO_DEV_URL = "http://localhost:$($env:EXPO_PORT)" $env:PASEO_DEV_ROOT = $RootDir $env:PASEO_DEV_RUNTIME_FALLBACK_ROOT = $RootDir $DevRuntime = node "$ScriptDir\dev-runtime.mjs" | ConvertFrom-Json -$RemoteDebuggingPort = $DevRuntime.remoteDebuggingPort $env:PASEO_ELECTRON_FLAGS = $DevRuntime.electronFlags $env:PASEO_ELECTRON_USER_DATA_DIR = $DevRuntime.userDataDir Remove-Item Env:\PASEO_DEV_RUNTIME_FALLBACK_ROOT -ErrorAction SilentlyContinue @@ -104,7 +103,6 @@ Write-Host @" Paseo Desktop Dev (Windows) ====================================================== Metro: http://localhost:$($env:EXPO_PORT) - CDP: http://127.0.0.1:$RemoteDebuggingPort Daemon: $($env:PASEO_LISTEN) (isolated) PASEO_HOME: $($env:PASEO_HOME) userData: $($env:PASEO_ELECTRON_USER_DATA_DIR) diff --git a/packages/desktop/scripts/dev.sh b/packages/desktop/scripts/dev.sh index 88672ddd4b..f00625d873 100755 --- a/packages/desktop/scripts/dev.sh +++ b/packages/desktop/scripts/dev.sh @@ -15,7 +15,6 @@ DEV_ROOT="${PASEO_DEV_ROOT:-$(default_dev_paseo_root)}" export PASEO_DEV_ROOT="$DEV_ROOT" export PASEO_DEV_RUNTIME_FALLBACK_ROOT="$DEV_ROOT" DEV_RUNTIME="$(node "$SCRIPT_DIR/dev-runtime.mjs")" -REMOTE_DEBUGGING_PORT="$(node -e 'process.stdout.write(String(JSON.parse(process.argv[1]).remoteDebuggingPort))' "$DEV_RUNTIME")" export PASEO_ELECTRON_FLAGS="$(node -e 'process.stdout.write(JSON.parse(process.argv[1]).electronFlags)' "$DEV_RUNTIME")" export PASEO_ELECTRON_USER_DATA_DIR="$(node -e 'process.stdout.write(JSON.parse(process.argv[1]).userDataDir)' "$DEV_RUNTIME")" unset PASEO_DEV_RUNTIME_FALLBACK_ROOT @@ -38,7 +37,6 @@ echo "════════════════════════ echo " Paseo Desktop Dev" echo "══════════════════════════════════════════════════════" echo " Metro: ${EXPO_DEV_URL}" -echo " CDP: http://127.0.0.1:${REMOTE_DEBUGGING_PORT}" echo " Daemon: ${PASEO_LISTEN}" echo " Home: ${PASEO_HOME}" echo " userData: ${PASEO_ELECTRON_USER_DATA_DIR}"