CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes48downloads
loadedSettingsAdapter.ts109 linesDownload Raw Back to config
1/**2 * @license3 * Copyright 2025 Qwen Team4 * SPDX-License-Identifier: Apache-2.05 *6 * Adapter that lets core's `applyProviderInstallPlan` write through7 * `LoadedSettings` while preserving CLI-specific guarantees:8 * - scope resolution via `getPersistScopeForModelSelection`9 * - on-disk `.orig` backup of the target settings file10 * - in-memory snapshot of `settings` / `originalSettings` for rollback11 * - merged-settings recomputation after restore12 */13 14import type {15  ModelProvidersConfig,16  ProviderSettingsAdapter,17} from '@qwen-code/qwen-code-core';18import type { LoadedSettings, SettingScope } from './settings.js';19import { getPersistScopeForModelSelection } from './modelProvidersScope.js';20import {21  backupSettingsFile,22  cleanupSettingsBackup,23  restoreSettingsFromBackup,24  getNestedProperty,25} from '../utils/settingsUtils.js';26 27export function createLoadedSettingsAdapter(28  settings: LoadedSettings,29  scope?: SettingScope,30): ProviderSettingsAdapter {31  const persistScope = scope ?? getPersistScopeForModelSelection(settings);32  const settingsFile = settings.forScope(persistScope);33 34  let settingsSnapshot: object | null = null;35  let originalSnapshot: object | null = null;36 37  return {38    getValue(key: string): unknown {39      return getNestedProperty(settings.merged as Record<string, unknown>, key);40    },41 42    setValue(key: string, value: unknown): void {43      // Defense in depth: refuse prototype-chain segments before delegating to44      // LoadedSettings.setValue, which goes through setNestedPropertySafe and45      // doesn't enforce this itself. Inline literal === comparisons (rather46      // than Set.has) are what CodeQL's prototype-pollution sanitiser47      // recognises — keep this list in sync with the matching guard in48      // `packages/vscode-ide-companion/src/services/settingsWriter.ts`.49      for (const part of key.split('.')) {50        if (51          part === '__proto__' ||52          part === 'constructor' ||53          part === 'prototype'54        ) {55          throw new Error(56            `Refusing to write settings key with reserved segment: ${key}`,57          );58        }59      }60      settings.setValue(persistScope, key, value);61    },62 63    getModelProviders(): ModelProvidersConfig {64      return (settings.merged.modelProviders ?? {}) as ModelProvidersConfig;65    },66 67    persist(): void {68      // LoadedSettings.setValue already persists on each write.69    },70 71    backup(): void {72      backupSettingsFile(settingsFile.path);73      settingsSnapshot = structuredClone(settingsFile.settings);74      originalSnapshot = structuredClone(settingsFile.originalSettings);75    },76 77    restore(): void {78      // restoreSettingsFromBackup returns false (rather than throwing) when79      // the .orig copy can't be restored (EACCES, disk full, missing .orig).80      // Log loudly so a user staring at the next CLI session knows the81      // on-disk file may be inconsistent with the recovered in-memory state.82      const restored = restoreSettingsFromBackup(settingsFile.path);83      if (!restored) {84        // eslint-disable-next-line no-console -- best-effort rollback path85        console.error(86          `[loadedSettingsAdapter] On-disk rollback of ${settingsFile.path} failed; ` +87            `in-memory state was restored but the file may be inconsistent. ` +88            `Re-run /auth or inspect the file directly to recover.`,89        );90      }91      if (settingsSnapshot !== null) {92        settingsFile.settings =93          settingsSnapshot as typeof settingsFile.settings;94      }95      if (originalSnapshot !== null) {96        settingsFile.originalSettings =97          originalSnapshot as typeof settingsFile.originalSettings;98      }99      settings.recomputeMerged();100    },101 102    cleanupBackup(): void {103      cleanupSettingsBackup(settingsFile.path);104      settingsSnapshot = null;105      originalSnapshot = null;106    },107  };108}109 
basant307/AI_Governance_Project · CoolFace