/ utils / settings / constants.ts
constants.ts
  1  import { getAllowedSettingSources } from '../../bootstrap/state.js'
  2  
  3  /**
  4   * All possible sources where settings can come from
  5   * Order matters - later sources override earlier ones
  6   */
  7  export const SETTING_SOURCES = [
  8    // User settings (global)
  9    'userSettings',
 10  
 11    // Project settings (shared per-directory)
 12    'projectSettings',
 13  
 14    // Local settings (gitignored)
 15    'localSettings',
 16  
 17    // Flag settings (from --settings flag)
 18    'flagSettings',
 19  
 20    // Policy settings (managed-settings.json or remote settings from API)
 21    'policySettings',
 22  ] as const
 23  
 24  export type SettingSource = (typeof SETTING_SOURCES)[number]
 25  
 26  export function getSettingSourceName(source: SettingSource): string {
 27    switch (source) {
 28      case 'userSettings':
 29        return 'user'
 30      case 'projectSettings':
 31        return 'project'
 32      case 'localSettings':
 33        return 'project, gitignored'
 34      case 'flagSettings':
 35        return 'cli flag'
 36      case 'policySettings':
 37        return 'managed'
 38    }
 39  }
 40  
 41  /**
 42   * Get short display name for a setting source (capitalized, for context/skills UI)
 43   * @param source The setting source or 'plugin'/'built-in'
 44   * @returns Short capitalized display name like 'User', 'Project', 'Plugin'
 45   */
 46  export function getSourceDisplayName(
 47    source: SettingSource | 'plugin' | 'built-in',
 48  ): string {
 49    switch (source) {
 50      case 'userSettings':
 51        return 'User'
 52      case 'projectSettings':
 53        return 'Project'
 54      case 'localSettings':
 55        return 'Local'
 56      case 'flagSettings':
 57        return 'Flag'
 58      case 'policySettings':
 59        return 'Managed'
 60      case 'plugin':
 61        return 'Plugin'
 62      case 'built-in':
 63        return 'Built-in'
 64    }
 65  }
 66  
 67  /**
 68   * Get display name for a setting or permission rule source (lowercase, for inline use)
 69   * @param source The setting source or permission rule source
 70   * @returns Display name for the source in lowercase
 71   */
 72  export function getSettingSourceDisplayNameLowercase(
 73    source: SettingSource | 'cliArg' | 'command' | 'session',
 74  ): string {
 75    switch (source) {
 76      case 'userSettings':
 77        return 'user settings'
 78      case 'projectSettings':
 79        return 'shared project settings'
 80      case 'localSettings':
 81        return 'project local settings'
 82      case 'flagSettings':
 83        return 'command line arguments'
 84      case 'policySettings':
 85        return 'enterprise managed settings'
 86      case 'cliArg':
 87        return 'CLI argument'
 88      case 'command':
 89        return 'command configuration'
 90      case 'session':
 91        return 'current session'
 92    }
 93  }
 94  
 95  /**
 96   * Get display name for a setting or permission rule source (capitalized, for UI labels)
 97   * @param source The setting source or permission rule source
 98   * @returns Display name for the source with first letter capitalized
 99   */
100  export function getSettingSourceDisplayNameCapitalized(
101    source: SettingSource | 'cliArg' | 'command' | 'session',
102  ): string {
103    switch (source) {
104      case 'userSettings':
105        return 'User settings'
106      case 'projectSettings':
107        return 'Shared project settings'
108      case 'localSettings':
109        return 'Project local settings'
110      case 'flagSettings':
111        return 'Command line arguments'
112      case 'policySettings':
113        return 'Enterprise managed settings'
114      case 'cliArg':
115        return 'CLI argument'
116      case 'command':
117        return 'Command configuration'
118      case 'session':
119        return 'Current session'
120    }
121  }
122  
123  /**
124   * Parse the --setting-sources CLI flag into SettingSource array
125   * @param flag Comma-separated string like "user,project,local"
126   * @returns Array of SettingSource values
127   */
128  export function parseSettingSourcesFlag(flag: string): SettingSource[] {
129    if (flag === '') return []
130  
131    const names = flag.split(',').map(s => s.trim())
132    const result: SettingSource[] = []
133  
134    for (const name of names) {
135      switch (name) {
136        case 'user':
137          result.push('userSettings')
138          break
139        case 'project':
140          result.push('projectSettings')
141          break
142        case 'local':
143          result.push('localSettings')
144          break
145        default:
146          throw new Error(
147            `Invalid setting source: ${name}. Valid options are: user, project, local`,
148          )
149      }
150    }
151  
152    return result
153  }
154  
155  /**
156   * Get enabled setting sources with policy/flag always included
157   * @returns Array of enabled SettingSource values
158   */
159  export function getEnabledSettingSources(): SettingSource[] {
160    const allowed = getAllowedSettingSources()
161  
162    // Always include policy and flag settings
163    const result = new Set<SettingSource>(allowed)
164    result.add('policySettings')
165    result.add('flagSettings')
166    return Array.from(result)
167  }
168  
169  /**
170   * Check if a specific source is enabled
171   * @param source The source to check
172   * @returns true if the source should be loaded
173   */
174  export function isSettingSourceEnabled(source: SettingSource): boolean {
175    const enabled = getEnabledSettingSources()
176    return enabled.includes(source)
177  }
178  
179  /**
180   * Editable setting sources (excludes policySettings and flagSettings which are read-only)
181   */
182  export type EditableSettingSource = Exclude<
183    SettingSource,
184    'policySettings' | 'flagSettings'
185  >
186  
187  /**
188   * List of sources where permission rules can be saved, in display order.
189   * Used by permission-rule and hook-save UIs to present source options.
190   */
191  export const SOURCES = [
192    'localSettings',
193    'projectSettings',
194    'userSettings',
195  ] as const satisfies readonly EditableSettingSource[]
196  
197  /**
198   * The JSON Schema URL for Claude Code settings
199   * You can edit the contents at https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/claude-code-settings.json
200   */
201  export const CLAUDE_CODE_SETTINGS_SCHEMA_URL =
202    'https://json.schemastore.org/claude-code-settings.json'