refactor(config): adopt config-loader-facade across the codebase

Issue #1161. Sweeps 127 files to import from
src/config/config-loader-facade.ts instead of unified-config-loader or
utils/config-manager directly.

WRITE callers (32 files): replaced raw saveUnifiedConfig /
mutateUnifiedConfig / updateUnifiedConfig calls with the facade's
cache-coherent wrappers saveConfig / mutateConfig / updateConfig. This
fixes a latent stale-cache window where direct writes through the
underlying loader bypassed the facade's memoization.

READ callers (95 files): mechanical import-path migration only —
function names unchanged because the facade re-exports them. No
behavior change.

Also updated:
- tests/unit/utils/browser/browser-setup.test.ts (DI interface rename)
- src/management/checks/image-analysis-check.ts (dynamic import rename)
- src/web-server/health-service.ts (dynamic require rename)
- src/ccs.ts (path prefix fix from sweep script)

After sweep: zero raw write callers remain outside src/config/. Direct
imports of config-manager remain only for symbols not in the facade
(getConfigPath, getCcsDirSource, etc). Behavior unchanged; full suite
passes 1824/1824.

Out of scope: switching loadOrCreateUnifiedConfig() callers to
getCachedConfig() — needs per-callsite cache-safety analysis. Tracked
as follow-up.

Refs #1161
This commit is contained in:
Tam Nhu Tran committed 2026-05-03 01:42:53 -04:00
1 parent 74898210f9
commit 4f6e61739c
128 files changed
+397 -267

No files matched your search

+4 -4
View File
@@ -1,4 +1,3 @@
import { getBrowserConfig, mutateUnifiedConfig } from '../../config/unified-config-loader';
import type { BrowserConfig } from '../../config/unified-config-types';
import { getNodePlatformKey } from './platform';
import { type BrowserStatusPayload, getBrowserStatus } from './browser-status';
@@ -9,6 +8,7 @@ import {
getRecommendedBrowserUserDataDir,
isManagedClaudeBrowserAttachConfig,
} from './browser-settings';
import { getBrowserConfig, mutateConfig } from '../../config/config-loader-facade';
export interface BrowserSetupResult {
configUpdated: boolean;
@@ -23,14 +23,14 @@ export interface BrowserSetupResult {
export interface BrowserSetupDeps {
getBrowserConfig: typeof getBrowserConfig;
mutateUnifiedConfig: typeof mutateUnifiedConfig;
mutateConfig: typeof mutateConfig;
ensureBrowserMcp: typeof ensureBrowserMcp;
getBrowserStatus: typeof getBrowserStatus;
}
const defaultBrowserSetupDeps: BrowserSetupDeps = {
getBrowserConfig,
mutateUnifiedConfig,
mutateConfig,
ensureBrowserMcp,
getBrowserStatus,
};
@@ -81,7 +81,7 @@ export async function runBrowserSetup(
function persistBrowserSetupConfig(deps: BrowserSetupDeps, currentConfig: BrowserConfig): boolean {
const before = JSON.stringify(currentConfig);
deps.mutateUnifiedConfig((config) => {
deps.mutateConfig((config) => {
const existingBrowser = config.browser ?? currentConfig;
const currentUserDataDir = existingBrowser.claude.user_data_dir?.trim();
+2 -1
View File
@@ -4,7 +4,7 @@ import type {
BrowserEvalMode,
BrowserToolPolicy,
} from '../../config/unified-config-types';
import { getBrowserConfig, loadUnifiedConfig } from '../../config/unified-config-loader';
import { getCcsPathDisplay } from '../config-manager';
import { getCodexBinaryInfo } from '../../targets/codex-detector';
import { type BrowserRuntimeEnv, resolveBrowserRuntimeEnv } from './chrome-reuse';
@@ -19,6 +19,7 @@ import {
getEffectiveClaudeBrowserAttachConfig,
getRecommendedBrowserUserDataDir,
} from './browser-settings';
import { getBrowserConfig, loadUnifiedConfig } from '../../config/config-loader-facade';
export interface ClaudeBrowserStatus {
enabled: boolean;
+1 -1
View File
@@ -6,7 +6,7 @@ import { isConfig, isSettings } from '../types';
import type { Config, Settings, CLIProxyVariantsConfig, CLIProxyVariantConfig } from '../types';
import { expandPath, error } from './helpers';
import { info } from './ui';
import { isUnifiedMode, loadOrCreateUnifiedConfig } from '../config/unified-config-loader';
import { isUnifiedMode, loadOrCreateUnifiedConfig } from '../config/config-loader-facade';
// TODO: Replace with proper imports after converting these files
// const { ErrorManager } = require('./error-manager');
@@ -7,7 +7,6 @@
* @module utils/hooks/image-analysis-hook-env
*/
import { getImageAnalysisConfig } from '../../config/unified-config-loader';
import { resolveCliproxyBridgeProfile } from '../../api/services/cliproxy-profile-bridge';
import { getEffectiveApiKey } from '../../cliproxy/auth/auth-token-manager';
import { mapExternalProviderName } from '../../cliproxy/provider-capabilities';
@@ -21,6 +20,7 @@ import {
resolveImageAnalysisStatus,
type ImageAnalysisResolutionContext,
} from './image-analysis-backend-resolver';
import { getImageAnalysisConfig } from '../../config/config-loader-facade';
/**
* Serialize provider_models map to env var format: provider:model,provider:model
@@ -7,8 +7,9 @@
*/
import * as path from 'path';
import { getImageAnalysisConfig } from '../../config/unified-config-loader';
import { getCcsHooksDir } from '../config-manager';
import { getImageAnalysisConfig } from '../../config/config-loader-facade';
// Hook file name
const IMAGE_ANALYZER_HOOK = 'image-analyzer-transformer.cjs';
@@ -12,9 +12,10 @@ import * as path from 'path';
import { info, warn } from '../ui';
import { getImageAnalyzerHookPath } from './image-analyzer-hook-configuration';
import { getCcsHooksDir } from '../config-manager';
import { getImageAnalysisConfig } from '../../config/unified-config-loader';
import { removeMigrationMarker } from './image-analyzer-profile-hook-injector';
import { installImageAnalysisPrompts } from '../image-analysis/hook-installer';
import { getImageAnalysisConfig } from '../../config/config-loader-facade';
// Re-export from hook-configuration for backward compatibility
export {
@@ -21,12 +21,13 @@ import {
isCcsImageAnalyzerHook,
removeCcsImageAnalyzerHooks,
} from './image-analyzer-hook-utils';
import { getImageAnalysisConfig } from '../../config/unified-config-loader';
import { getCcsDir } from '../config-manager';
import {
resolveImageAnalysisStatus,
type ImageAnalysisResolutionContext,
} from './image-analysis-backend-resolver';
import { getImageAnalysisConfig } from '../../config/config-loader-facade';
// Valid profile name pattern (alphanumeric, dot, dash, underscore only)
const VALID_PROFILE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
+2 -1
View File
@@ -5,12 +5,13 @@
import * as fs from 'fs';
import * as path from 'path';
import * as lockfile from 'proper-lockfile';
import { getImageAnalysisConfig } from '../../config/unified-config-loader';
import { getCcsDir } from '../config-manager';
import { getClaudeUserConfigPath } from '../claude-config-path';
import { info, warn } from '../ui';
import { InstanceManager } from '../../management/instance-manager';
import { installImageAnalysisPrompts } from './hook-installer';
import { getImageAnalysisConfig } from '../../config/config-loader-facade';
const IMAGE_ANALYSIS_MCP_SERVER = 'ccs-image-analysis-server.cjs';
const IMAGE_ANALYSIS_MCP_RUNTIME = 'image-analysis-runtime.cjs';
+2 -1
View File
@@ -8,8 +8,9 @@ import { spawn, spawnSync, ChildProcess, type SpawnOptions } from 'child_process
import { ErrorManager } from './error-manager';
import { getWebSearchHookEnv } from './websearch-manager';
import { wireChildProcessSignals } from './signal-forwarder';
import { loadOrCreateUnifiedConfig } from '../config/unified-config-loader';
import SharedManager from '../management/shared-manager';
import { loadOrCreateUnifiedConfig } from '../config/config-loader-facade';
/**
* Strip ANTHROPIC_* env vars from an environment object.
+2 -1
View File
@@ -9,10 +9,11 @@
import * as fs from 'fs';
import * as path from 'path';
import { info, warn } from '../ui';
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { getCcsHooksDir } from '../config-manager';
import { getClaudeSettingsPath } from '../claude-config-path';
import { isCcsWebSearchHook, deduplicateCcsHooks } from './hook-utils';
import { getWebSearchConfig } from '../../config/config-loader-facade';
// Hook file name
const WEBSEARCH_HOOK = 'websearch-transformer.cjs';
+1 -1
View File
@@ -6,9 +6,9 @@
* @module utils/websearch/hook-env
*/
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { normalizeSearxngBaseUrl } from './types';
import { resolveAllowedWebSearchTraceFile } from './trace';
import { getWebSearchConfig } from '../../config/config-loader-facade';
/**
* Get environment variables for WebSearch hook configuration.
+2 -1
View File
@@ -9,9 +9,10 @@
import * as fs from 'fs';
import * as path from 'path';
import { info, warn } from '../ui';
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { getCcsDir, getCcsHooksDir } from '../config-manager';
import { getHookPath } from './hook-config';
import { getWebSearchConfig } from '../../config/config-loader-facade';
// Re-export from hook-config for backward compatibility
export { getHookPath, getWebSearchHookConfig } from './hook-config';
+2 -1
View File
@@ -4,13 +4,14 @@
import * as fs from 'fs';
import * as path from 'path';
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { getCcsDir } from '../config-manager';
import { getClaudeUserConfigPath } from '../claude-config-path';
import { info, warn } from '../ui';
import { InstanceManager } from '../../management/instance-manager';
import { installWebSearchHook } from './hook-installer';
import { appendWebSearchTrace } from './trace';
import { getWebSearchConfig } from '../../config/config-loader-facade';
const WEBSEARCH_MCP_SERVER = 'ccs-websearch-server.cjs';
const WEBSEARCH_MCP_SERVER_NAME = 'ccs-websearch';
+2 -1
View File
@@ -12,11 +12,12 @@ import * as fs from 'fs';
import * as path from 'path';
import { info, warn } from '../ui';
import { getWebSearchHookConfig, getHookPath } from './hook-config';
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { removeHookConfig } from './hook-config';
import { getCcsDir } from '../config-manager';
import { isCcsWebSearchHook, deduplicateCcsHooks } from './hook-utils';
import { getMigrationMarkerPath, installWebSearchHook } from './hook-installer';
import { getWebSearchConfig } from '../../config/config-loader-facade';
// Valid profile name pattern (alphanumeric, dash, underscore only)
const VALID_PROFILE_NAME = /^[a-zA-Z0-9_-]+$/;
+1 -1
View File
@@ -1,5 +1,5 @@
import { getGlobalEnvConfig } from '../../config/unified-config-loader';
import { maskSensitiveValue } from '../sensitive-keys';
import { getGlobalEnvConfig } from '../../config/config-loader-facade';
export type WebSearchApiKeyProviderId = 'exa' | 'tavily' | 'brave';
export type WebSearchApiKeySource = 'global_env' | 'process_env' | 'both' | 'none';
+2 -1
View File
@@ -9,13 +9,14 @@
import { existsSync, readFileSync } from 'fs';
import { join } from 'path';
import { ok, warn, fail, info } from '../ui';
import { getWebSearchConfig } from '../../config/unified-config-loader';
import { getCcsDir } from '../config-manager';
import { getGeminiCliStatus, isGeminiAuthenticated } from './gemini-cli';
import { getGrokCliStatus } from './grok-cli';
import { getOpenCodeCliStatus } from './opencode-cli';
import { getWebSearchApiKeyStates } from './provider-secrets';
import { normalizeSearxngBaseUrl, type WebSearchCliInfo, type WebSearchStatus } from './types';
import { getWebSearchConfig } from '../../config/config-loader-facade';
const PROVIDER_STATE_FILE = 'websearch-provider-state.json';