π File detail
services/remoteManagedSettings/syncCacheState.ts
π― Use case
This file lives under βservices/β, which covers long-lived services (LSP, MCP, OAuth, tool execution, memory, compaction, voice, settings sync, β¦). On the API surface it exposes setSessionCache, resetSyncCache, setEligibility, getSettingsPath, and getRemoteManagedSettingsSyncFromCache β mainly functions, hooks, or classes. Dependencies touch Node path helpers. It composes internal code from utils (relative imports). What the file header says: Leaf state module for the remote-managed-settings sync cache. Split from syncCache.ts to break the settings.ts β syncCache.ts β auth.ts β settings.ts cycle. auth.ts sits inside the large settings SCC; importing it from settings.ts's own dependency chain pulls hundreds of modules.
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
Leaf state module for the remote-managed-settings sync cache. Split from syncCache.ts to break the settings.ts β syncCache.ts β auth.ts β settings.ts cycle. auth.ts sits inside the large settings SCC; importing it from settings.ts's own dependency chain pulls hundreds of modules into the eagerly-evaluated SCC at startup. This module imports only leaves (path, envUtils, file, json, types, settings/settingsCache β also a leaf, only type-imports validation). settings.ts reads the cache from here. syncCache.ts keeps isRemoteManagedSettingsEligible (the auth-touching part) and re-exports everything from here for callers that don't care about the cycle. Eligibility is a tri-state here: undefined (not yet determined β return null), false (ineligible β return null), true (proceed). managedEnv.ts calls isRemoteManagedSettingsEligible() just before the policySettings read β after userSettings/flagSettings env vars are applied, so the check sees config-provided CLAUDE_CODE_USE_BEDROCK/ANTHROPIC_BASE_URL. That call computes once and mirrors the result here via setEligibility(). Every subsequent read hits the cached bool instead of re-running the auth chain.
π€ Exports (heuristic)
setSessionCacheresetSyncCachesetEligibilitygetSettingsPathgetRemoteManagedSettingsSyncFromCache
π External import roots
Package roots from from "β¦" (relative paths omitted).
path
π₯οΈ Source preview
/**
* Leaf state module for the remote-managed-settings sync cache.
*
* Split from syncCache.ts to break the settings.ts β syncCache.ts β auth.ts β
* settings.ts cycle. auth.ts sits inside the large settings SCC; importing it
* from settings.ts's own dependency chain pulls hundreds of modules into the
* eagerly-evaluated SCC at startup.
*
* This module imports only leaves (path, envUtils, file, json, types,
* settings/settingsCache β also a leaf, only type-imports validation). settings.ts
* reads the cache from here. syncCache.ts keeps isRemoteManagedSettingsEligible
* (the auth-touching part) and re-exports everything from here for callers that
* don't care about the cycle.
*
* Eligibility is a tri-state here: undefined (not yet determined β return
* null), false (ineligible β return null), true (proceed). managedEnv.ts
* calls isRemoteManagedSettingsEligible() just before the policySettings
* read β after userSettings/flagSettings env vars are applied, so the check
* sees config-provided CLAUDE_CODE_USE_BEDROCK/ANTHROPIC_BASE_URL. That call
* computes once and mirrors the result here via setEligibility(). Every
* subsequent read hits the cached bool instead of re-running the auth chain.
*/
import { join } from 'path'
import { getClaudeConfigHomeDir } from '../../utils/envUtils.js'
import { readFileSync } from '../../utils/fileRead.js'
import { stripBOM } from '../../utils/jsonRead.js'
import { resetSettingsCache } from '../../utils/settings/settingsCache.js'
import type { SettingsJson } from '../../utils/settings/types.js'
import { jsonParse } from '../../utils/slowOperations.js'
const SETTINGS_FILENAME = 'remote-settings.json'
let sessionCache: SettingsJson | null = null
let eligible: boolean | undefined
export function setSessionCache(value: SettingsJson | null): void {
sessionCache = value
}
export function resetSyncCache(): void {
sessionCache = null
eligible = undefined
}
export function setEligibility(v: boolean): boolean {
eligible = v
return v
}
export function getSettingsPath(): string {
return join(getClaudeConfigHomeDir(), SETTINGS_FILENAME)
}
// sync IO β settings pipeline is sync. fileRead and jsonRead are leaves;
// file.ts and json.ts both sit in the settings SCC.
function loadSettings(): SettingsJson | null {
try {
const content = readFileSync(getSettingsPath())
const data: unknown = jsonParse(stripBOM(content))
if (!data || typeof data !== 'object' || Array.isArray(data)) {
return null
}
return data as SettingsJson
} catch {
return null
}
}
export function getRemoteManagedSettingsSyncFromCache(): SettingsJson | null {
if (eligible !== true) return null
if (sessionCache) return sessionCache
const cachedSettings = loadSettings()
if (cachedSettings) {
sessionCache = cachedSettings
// Remote settings just became available for the first time. Any merged
// getSettings_DEPRECATED() result cached before this moment is missing
// the policySettings layer (the `eligible !== true` guard above returned
// null). Flush so the next merged read re-merges with this layer visible.
//
// Fires at most once: subsequent calls hit `if (sessionCache)` above.
// When called from loadSettingsFromDisk() (settings.ts:546), the merged
// cache is still null (setSessionSettingsCache runs at :732 after
// loadSettingsFromDisk returns) β no-op. The async-fetch arm (index.ts
// setSessionCache + notifyChange) already handles its own reset.
//
// gh-23085: isBridgeEnabled() at main.tsx Commander-definition time
// (before preAction β init() β isRemoteManagedSettingsEligible()) reached
// getSettings_DEPRECATED() at auth.ts:115. The try/catch in bridgeEnabled
// swallowed the later getGlobalConfig() throw, but the merged settings
// cache was already poisoned. See managedSettingsHeadless.int.test.ts.
resetSettingsCache()
return cachedSettings
}
return null
}