fix: honor browser eval env override in attach config (#1368)

This commit is contained in:
Kai (Tam Nhu) Tran
2026-05-23 21:44:44 -04:00
committed by GitHub
parent c322829f44
commit 4e7894a3da
2 changed files with 44 additions and 2 deletions
+13 -2
View File
@@ -232,6 +232,8 @@ export function getEffectiveClaudeBrowserAttachConfig(
resolveBrowserUserDataDir(config.claude.user_data_dir) ?? getRecommendedBrowserUserDataDir();
const configPort = normalizeDevtoolsPort(config.claude.devtools_port);
const configEvalMode = config.claude.eval_mode ?? 'readonly';
const envEvalMode = parseBrowserEvalMode(env.CCS_BROWSER_EVAL_MODE);
const effectiveEvalMode = envEvalMode ?? configEvalMode;
if (override.userDataDir) {
return {
@@ -241,7 +243,7 @@ export function getEffectiveClaudeBrowserAttachConfig(
userDataDir: override.userDataDir,
devtoolsPort: override.devtoolsPort ?? configPort,
hasExplicitDevtoolsPort: override.devtoolsPort !== undefined,
evalMode: configEvalMode,
evalMode: effectiveEvalMode,
};
}
@@ -252,7 +254,7 @@ export function getEffectiveClaudeBrowserAttachConfig(
userDataDir: configUserDataDir,
devtoolsPort: configPort,
hasExplicitDevtoolsPort: true,
evalMode: configEvalMode,
evalMode: effectiveEvalMode,
};
}
@@ -304,6 +306,15 @@ function parseDevtoolsPort(value?: string): number | undefined {
return normalizeDevtoolsPort(Number.parseInt(value.trim(), 10));
}
function parseBrowserEvalMode(value?: string): BrowserEvalMode | undefined {
const trimmed = value?.trim();
if (trimmed === 'disabled' || trimmed === 'readonly' || trimmed === 'readwrite') {
return trimmed;
}
return undefined;
}
function normalizeDevtoolsPort(value: number | undefined): number {
if (!Number.isFinite(value)) {
return 9222;
@@ -22,6 +22,7 @@ describe('browser status', () => {
let originalBrowserUserDataDir: string | undefined;
let originalBrowserProfileDir: string | undefined;
let originalBrowserDevtoolsPort: string | undefined;
let originalBrowserEvalMode: string | undefined;
beforeEach(() => {
tempHome = mkdtempSync(join(tmpdir(), 'ccs-browser-status-'));
@@ -29,11 +30,13 @@ describe('browser status', () => {
originalBrowserUserDataDir = process.env.CCS_BROWSER_USER_DATA_DIR;
originalBrowserProfileDir = process.env.CCS_BROWSER_PROFILE_DIR;
originalBrowserDevtoolsPort = process.env.CCS_BROWSER_DEVTOOLS_PORT;
originalBrowserEvalMode = process.env.CCS_BROWSER_EVAL_MODE;
process.env.CCS_HOME = tempHome;
delete process.env.CCS_BROWSER_USER_DATA_DIR;
delete process.env.CCS_BROWSER_PROFILE_DIR;
delete process.env.CCS_BROWSER_DEVTOOLS_PORT;
delete process.env.CCS_BROWSER_EVAL_MODE;
});
afterEach(() => {
@@ -60,6 +63,11 @@ describe('browser status', () => {
} else {
delete process.env.CCS_BROWSER_DEVTOOLS_PORT;
}
if (originalBrowserEvalMode !== undefined) {
process.env.CCS_BROWSER_EVAL_MODE = originalBrowserEvalMode;
} else {
delete process.env.CCS_BROWSER_EVAL_MODE;
}
rmSync(tempHome, { recursive: true, force: true });
});
@@ -290,6 +298,29 @@ describe('browser status', () => {
});
});
it('honors CCS_BROWSER_EVAL_MODE over configured eval_mode', () => {
mutateUnifiedConfig((config) => {
config.browser = {
claude: {
enabled: true,
policy: 'manual',
user_data_dir: '/config-browser',
devtools_port: 9333,
eval_mode: 'readonly',
},
codex: {
enabled: false,
policy: 'manual',
},
};
});
process.env.CCS_BROWSER_EVAL_MODE = 'disabled';
const effective = getEffectiveClaudeBrowserAttachConfig(getBrowserConfig());
expect(effective.evalMode).toBe('disabled');
});
it('returns the same managed attach warning when the configured DevTools port is unreachable', async () => {
const managedDir = join(tempHome, '.ccs', 'browser', 'chrome-user-data');
mkdirSync(managedDir, { recursive: true });