()
| 1003 | // fs.watchFile polls stat on the libuv threadpool and only calls us when mtime |
| 1004 | // changed — a stalled stat never blocks the main thread. |
| 1005 | function startGlobalConfigFreshnessWatcher(): void { |
| 1006 | if (freshnessWatcherStarted || process.env.NODE_ENV === 'test') return |
| 1007 | freshnessWatcherStarted = true |
| 1008 | const file = getGlobalClaudeFile() |
| 1009 | watchFile( |
| 1010 | file, |
| 1011 | { interval: CONFIG_FRESHNESS_POLL_MS, persistent: false }, |
| 1012 | curr => { |
| 1013 | // Our own writes fire this too — the write-through's Date.now() |
| 1014 | // overshoot makes cache.mtime > file mtime, so we skip the re-read. |
| 1015 | // Bun/Node also fire with curr.mtimeMs=0 when the file doesn't exist |
| 1016 | // (initial callback or deletion) — the <= handles that too. |
| 1017 | if (curr.mtimeMs <= globalConfigCache.mtime) return |
| 1018 | void getFsImplementation() |
| 1019 | .readFile(file, { encoding: 'utf-8' }) |
| 1020 | .then(content => { |
| 1021 | // A write-through may have advanced the cache while we were reading; |
| 1022 | // don't regress to the stale snapshot watchFile stat'd. |
| 1023 | if (curr.mtimeMs <= globalConfigCache.mtime) return |
| 1024 | const parsed = safeParseJSON(stripBOM(content)) |
| 1025 | if (parsed === null || typeof parsed !== 'object') return |
| 1026 | globalConfigCache = { |
| 1027 | config: migrateConfigFields({ |
| 1028 | ...createDefaultGlobalConfig(), |
| 1029 | ...(parsed as Partial<GlobalConfig>), |
| 1030 | }), |
| 1031 | mtime: curr.mtimeMs, |
| 1032 | } |
| 1033 | lastReadFileStats = { mtime: curr.mtimeMs, size: curr.size } |
| 1034 | }) |
| 1035 | .catch(() => {}) |
| 1036 | }, |
| 1037 | ) |
| 1038 | registerCleanup(async () => { |
| 1039 | unwatchFile(file) |
| 1040 | freshnessWatcherStarted = false |
| 1041 | }) |
| 1042 | } |
| 1043 | |
| 1044 | // Write-through: what we just wrote IS the new config. cache.mtime overshoots |
| 1045 | // the file's real mtime (Date.now() is recorded after the write) so the |
no test coverage detected