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

+8 -2
View File
@@ -1,6 +1,6 @@
import * as fs from 'fs';
import * as path from 'path';
import { getCcsDir, loadConfigSafe } from '../../utils/config-manager';
import { buildProxyUrl, getProxyTarget } from '../../cliproxy/proxy/proxy-target-resolver';
import { getEffectiveApiKey } from '../../cliproxy/auth/auth-token-manager';
import { getModelMappingFromConfig } from '../../cliproxy/config/base-config-loader';
@@ -11,7 +11,7 @@ import {
mapExternalProviderName,
} from '../../cliproxy/provider-capabilities';
import { extractProviderFromPathname } from '../../cliproxy/ai-providers/model-id-normalizer';
import { isUnifiedMode, loadOrCreateUnifiedConfig } from '../../config/unified-config-loader';
import type { TargetType } from '../../targets/target-adapter';
import type { Settings } from '../../types/config';
import type { CLIProxyProvider } from '../../cliproxy/types';
@@ -21,6 +21,12 @@ import type {
ModelMapping,
ResolvedCliproxyBridgeProfile,
} from './profile-types';
import {
getCcsDir,
isUnifiedMode,
loadConfigSafe,
loadOrCreateUnifiedConfig,
} from '../../config/config-loader-facade';
const DEFAULT_PROFILE_SUFFIX = '-api';
+1 -1
View File
@@ -5,7 +5,7 @@
import * as fs from 'fs';
import * as path from 'path';
import { getCcsDir } from '../../utils/config-manager';
import { getCcsDir } from '../../config/config-loader-facade';
const OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/models';
function getCacheFile() {
@@ -9,12 +9,12 @@ import * as path from 'path';
import type { Config, Settings } from '../../types';
import type { TargetType } from '../../targets/target-adapter';
import { getPersistedTargetChoices, isPersistedTargetType } from '../../targets/target-metadata';
import { getCcsDir, getConfigPath, loadConfigSafe } from '../../utils/config-manager';
import { getConfigPath } from '../../utils/config-manager';
import { ensureWebSearchMcpOrThrow } from '../../utils/websearch-manager';
import { ensureImageAnalysisMcpOrThrow } from '../../utils/image-analysis';
import { isSensitiveKey } from '../../utils/sensitive-keys';
import { isReservedName } from '../../config/reserved-names';
import { isUnifiedMode, mutateUnifiedConfig } from '../../config/unified-config-loader';
import { validateApiName } from './validation-service';
import { listApiProfiles } from './profile-reader';
import { validateApiProfileSettingsPayload } from './profile-lifecycle-validation';
@@ -26,6 +26,12 @@ import type {
ImportApiProfileResult,
RegisterApiProfileOrphansResult,
} from './profile-types';
import {
getCcsDir,
isUnifiedMode,
loadConfigSafe,
mutateConfig,
} from '../../config/config-loader-facade';
const SETTINGS_FILE_SUFFIX = '.settings.json';
const REDACTED_TOKEN_SENTINEL = '__CCS_REDACTED__';
@@ -62,7 +68,7 @@ function writeJsonObjectAtomically(filePath: string, value: unknown): void {
function registerApiProfileInConfig(name: string, target: TargetType, force = false): void {
if (isUnifiedMode()) {
mutateUnifiedConfig((config) => {
mutateConfig((config) => {
if (config.profiles[name] && !force) {
throw new Error(`API profile already exists: ${name}`);
}
+6 -2
View File
@@ -6,14 +6,18 @@
*/
import * as fs from 'fs';
import { loadConfigSafe } from '../../utils/config-manager';
import { loadOrCreateUnifiedConfig, isUnifiedMode } from '../../config/unified-config-loader';
import { expandPath } from '../../utils/helpers';
import type { TargetType } from '../../targets/target-adapter';
import { isPersistedTargetType } from '../../targets/target-metadata';
import type { Settings } from '../../types/config';
import type { ApiProfileInfo, CliproxyVariantInfo, ApiListResult } from './profile-types';
import { resolveCliproxyBridgeMetadata } from './cliproxy-profile-bridge';
import {
isUnifiedMode,
loadConfigSafe,
loadOrCreateUnifiedConfig,
} from '../../config/config-loader-facade';
function sanitizeTarget(target: unknown): TargetType {
if (isPersistedTargetType(target)) {
+11 -5
View File
@@ -4,10 +4,10 @@
*/
import * as fs from 'fs';
import * as path from 'path';
import { getCcsDir, getConfigPath, loadConfigSafe } from '../../utils/config-manager';
import { getConfigPath } from '../../utils/config-manager';
import { expandPath } from '../../utils/helpers';
import { validateApiName } from './validation-service';
import { mutateUnifiedConfig, isUnifiedMode } from '../../config/unified-config-loader';
import { ensureWebSearchMcpOrThrow } from '../../utils/websearch-manager';
import { ensureImageAnalysisMcpOrThrow } from '../../utils/image-analysis';
import type { TargetType } from '../../targets/target-adapter';
@@ -31,6 +31,12 @@ import {
resolveCliproxyBridgeMetadata,
resolveCliproxyBridgeProfile,
} from './cliproxy-profile-bridge';
import {
getCcsDir,
isUnifiedMode,
loadConfigSafe,
mutateConfig,
} from '../../config/config-loader-facade';
/** Check if URL is an OpenRouter endpoint */
function isOpenRouterUrl(baseUrl: string): boolean {
@@ -232,7 +238,7 @@ function createApiProfileUnified(
throw error;
}
mutateUnifiedConfig((config) => {
mutateConfig((config) => {
config.profiles[name] = {
type: 'api',
settings: `~/.ccs/${settingsFile}`,
@@ -343,7 +349,7 @@ export function updateApiProfileTarget(
): UpdateApiProfileTargetResult {
try {
if (isUnifiedMode()) {
mutateUnifiedConfig((config) => {
mutateConfig((config) => {
if (!config.profiles[name]) {
throw new Error(`API profile not found: ${name}`);
}
@@ -392,7 +398,7 @@ export function updateApiProfileTarget(
/** Remove API profile from unified config */
function removeApiProfileUnified(name: string): void {
mutateUnifiedConfig((config) => {
mutateConfig((config) => {
const profile = config.profiles[name];
if (!profile) {