hotfix: stop auto-enabling stale Chrome DevTools reuse

This commit is contained in:
Tam Nhu Tran
2026-04-13 12:02:22 -04:00
parent 438ae9930b
commit 33f57d3cac
3 changed files with 67 additions and 12 deletions
+1 -12
View File
@@ -49,18 +49,7 @@ export function resolveDefaultChromeUserDataDir(
}
export function resolveConfiguredBrowserProfileDir(profileDir?: string): string | undefined {
if (profileDir?.trim()) {
return expandPath(profileDir);
}
try {
const defaultUserDataDir = resolveDefaultChromeUserDataDir();
return fs.existsSync(path.join(defaultUserDataDir, DEVTOOLS_ACTIVE_PORT_FILE))
? defaultUserDataDir
: undefined;
} catch {
return undefined;
}
return profileDir?.trim() ? expandPath(profileDir) : undefined;
}
export async function resolveBrowserRuntimeEnv(
@@ -151,6 +151,40 @@ exit 0
await expect(waitForMockDevtoolsPort(delayedPortFile, 500)).resolves.toBe('43123');
});
it('ignores stale default Chrome DevTools metadata unless browser reuse is explicitly configured', () => {
if (process.platform === 'win32') return;
const defaultChromeDir = path.join(
tmpHome,
'Library',
'Application Support',
'Google',
'Chrome'
);
fs.mkdirSync(defaultChromeDir, { recursive: true });
fs.writeFileSync(
path.join(defaultChromeDir, 'DevToolsActivePort'),
'9222\n/devtools/browser/stale-default',
'utf8'
);
const result = runCcs(['default', 'smoke'], {
...baseEnv,
HOME: tmpHome,
USERPROFILE: tmpHome,
});
expect(result.status).toBe(0);
expect(result.stderr).not.toContain('Chrome DevTools endpoint is unreachable');
const launchedArgs = fs.readFileSync(claudeArgsLogPath, 'utf8');
expect(launchedArgs).not.toContain(BROWSER_PROMPT_SNIPPET);
const launchedEnv = fs.readFileSync(claudeEnvLogPath, 'utf8');
expect(launchedEnv).not.toContain('9222');
expect(launchedEnv).not.toContain('devtools/browser/stale-default');
});
it('passes browser runtime env through default Claude launches when reuse is configured', async () => {
if (process.platform === 'win32') return;
@@ -3,12 +3,15 @@ import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {
resolveConfiguredBrowserProfileDir,
resolveBrowserRuntimeEnv,
resolveDefaultChromeUserDataDir,
} from '../../../../src/utils/browser/chrome-reuse';
describe('chrome reuse resolver', () => {
const originalHome = process.env.HOME;
const originalLocalAppData = process.env.LOCALAPPDATA;
const originalUserProfile = process.env.USERPROFILE;
let tempDirs: string[] = [];
let servers: Array<{ stop: () => void }> = [];
@@ -96,6 +99,18 @@ describe('chrome reuse resolver', () => {
} else {
process.env.LOCALAPPDATA = originalLocalAppData;
}
if (originalHome === undefined) {
delete process.env.HOME;
} else {
process.env.HOME = originalHome;
}
if (originalUserProfile === undefined) {
delete process.env.USERPROFILE;
} else {
process.env.USERPROFILE = originalUserProfile;
}
});
it('uses explicit profile-dir before the default path and resolves the websocket target', async () => {
@@ -122,6 +137,23 @@ describe('chrome reuse resolver', () => {
expect(fs.existsSync(path.join(defaultProfileDir, 'DevToolsActivePort'))).toBe(false);
});
it('only enables browser reuse for an explicitly configured profile directory', () => {
const isolatedHome = createTempDir('ccs-chrome-config-home-');
const defaultProfileDir = path.join(
isolatedHome,
'Library',
'Application Support',
'Google',
'Chrome'
);
writeDevToolsActivePort(defaultProfileDir, '9222\n/devtools/browser/stale-default');
process.env.HOME = isolatedHome;
process.env.USERPROFILE = isolatedHome;
expect(resolveConfiguredBrowserProfileDir()).toBeUndefined();
expect(resolveConfiguredBrowserProfileDir(defaultProfileDir)).toBe(defaultProfileDir);
});
it('uses an explicit devtools port override when metadata is missing', async () => {
const profileDir = createTempDir('ccs-chrome-explicit-port-');
const server = await startDevToolsServer({