first commit
This commit is contained in:
401
claude-code-中文Wiki/13-配置与迁移系统.md
Normal file
401
claude-code-中文Wiki/13-配置与迁移系统.md
Normal file
@@ -0,0 +1,401 @@
|
||||
# 配置与迁移系统
|
||||
|
||||
Claude Code 使用 Zod 进行配置模式验证,并通过迁移系统处理配置版本升级。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
src/
|
||||
├── schemas/ # Zod 配置模式定义
|
||||
├── migrations/ # 配置迁移脚本
|
||||
└── utils/settings/ # 设置管理系统
|
||||
├── settings.ts # 设置管理核心
|
||||
├── validation.ts # 验证逻辑
|
||||
├── changeDetector.ts # 变更检测
|
||||
├── applySettingsChange.ts # 变更应用
|
||||
├── permissionValidation.ts # 权限规则验证
|
||||
├── toolValidationConfig.ts # 工具验证配置
|
||||
├── types.ts # 类型定义
|
||||
├── constants.ts # 常量
|
||||
├── mdm/ # 移动设备管理
|
||||
└── settingsCache.ts # 设置缓存
|
||||
```
|
||||
|
||||
## 1. 配置模式 (schemas/)
|
||||
|
||||
### 1.1 主模式文件
|
||||
**文件**: `src/schemas/hooks.ts` (7884行)
|
||||
|
||||
使用 Zod 定义所有配置项的验证模式。
|
||||
|
||||
### 1.2 核心模式示例
|
||||
|
||||
```typescript
|
||||
// 基础设置模式
|
||||
const baseSettingsSchema = z.object({
|
||||
// 模型配置
|
||||
model: z.string(),
|
||||
maxTokens: z.number().optional(),
|
||||
|
||||
// UI 设置
|
||||
theme: z.enum(['dark', 'light', 'system']),
|
||||
fontSize: z.number().min(8).max(24),
|
||||
|
||||
// 权限设置
|
||||
allowPermissions: z.boolean(),
|
||||
permissionRules: z.array(permissionRuleSchema).optional(),
|
||||
})
|
||||
|
||||
// MCP 服务器配置
|
||||
const mcpServerSchema = z.object({
|
||||
name: z.string(),
|
||||
command: z.string(),
|
||||
args: z.array(z.string()).optional(),
|
||||
env: z.record(z.string()).optional(),
|
||||
})
|
||||
```
|
||||
|
||||
## 2. 设置管理 (utils/settings/)
|
||||
|
||||
### 2.1 设置核心 (settings.ts)
|
||||
|
||||
**文件**: `src/utils/settings/settings.ts` (~32KB)
|
||||
|
||||
**主要函数**:
|
||||
|
||||
| 函数 | 用途 |
|
||||
|------|------|
|
||||
| `getSettings()` | 获取当前设置 |
|
||||
| `updateSettings(partial)` | 更新设置 |
|
||||
| `resetSettings()` | 重置为默认值 |
|
||||
| `loadManagedFileSettings()` | 加载托管配置文件 |
|
||||
| `parseSettingsFile(path)` | 解析设置文件 |
|
||||
|
||||
**设置加载优先级** (从低到高):
|
||||
1. 默认值
|
||||
2. 托管设置文件 (`managed-settings.json`)
|
||||
3. 托管设置 Drop-in 目录 (`managed-settings.d/*.json`)
|
||||
4. 用户设置文件 (`~/.claude/settings.json`)
|
||||
|
||||
**托管设置系统**:
|
||||
```typescript
|
||||
// 加载托管文件设置
|
||||
export function loadManagedFileSettings(): {
|
||||
settings: SettingsJson | null
|
||||
errors: ValidationError[]
|
||||
} {
|
||||
// 1. 加载 managed-settings.json (基础)
|
||||
// 2. 按字母顺序加载 managed-settings.d/*.json (覆盖)
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 变更检测 (changeDetector.ts)
|
||||
|
||||
**文件**: `src/utils/settings/changeDetector.ts` (~16KB)
|
||||
|
||||
检测设置变更并触发相应的处理逻辑。
|
||||
|
||||
**主要功能**:
|
||||
- 检测设置项的变化
|
||||
- 生成变更事件
|
||||
- 防止循环依赖
|
||||
|
||||
### 2.3 变更应用 (applySettingsChange.ts)
|
||||
|
||||
**文件**: `src/utils/settings/applySettingsChange.ts`
|
||||
|
||||
应用设置变更到运行时系统。
|
||||
|
||||
```typescript
|
||||
// 示例:应用主题变更
|
||||
async function applyThemeChange(theme: Theme): Promise<void> {
|
||||
// 1. 更新渲染器主题
|
||||
// 2. 通知所有订阅者
|
||||
// 3. 持久化到磁盘
|
||||
}
|
||||
```
|
||||
|
||||
### 2.4 验证 (validation.ts)
|
||||
|
||||
**文件**: `src/utils/settings/validation.ts` (~8KB)
|
||||
|
||||
**主要函数**:
|
||||
|
||||
| 函数 | 用途 |
|
||||
|------|------|
|
||||
| `validateSettings(settings)` | 验证完整设置 |
|
||||
| `validateSetting(key, value)` | 验证单个设置 |
|
||||
| `formatZodError(error)` | 格式化 Zod 错误 |
|
||||
| `filterInvalidPermissionRules(rules)` | 过滤无效权限规则 |
|
||||
|
||||
**验证流程**:
|
||||
```typescript
|
||||
export function validateSettings(
|
||||
settings: unknown
|
||||
): SettingsWithErrors {
|
||||
const result = SettingsSchema.safeParse(settings)
|
||||
|
||||
if (result.success) {
|
||||
return { settings: result.data, errors: [] }
|
||||
}
|
||||
|
||||
// 转换 Zod 错误为友好格式
|
||||
return {
|
||||
settings: null,
|
||||
errors: formatZodError(result.error)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.5 权限验证 (permissionValidation.ts)
|
||||
|
||||
**文件**: `src/utils/settings/permissionValidation.ts` (~8.5KB)
|
||||
|
||||
验证权限规则的有效性。
|
||||
|
||||
**权限规则结构**:
|
||||
```typescript
|
||||
interface PermissionRule {
|
||||
tool: string // 工具名称
|
||||
path?: string // 路径模式
|
||||
deny?: boolean // 拒绝还是允许
|
||||
reason?: string // 原因说明
|
||||
}
|
||||
```
|
||||
|
||||
**验证规则**:
|
||||
1. 工具名称必须有效
|
||||
2. 路径模式必须是有效的 glob 或正则
|
||||
3. 冲突规则被拒绝
|
||||
|
||||
### 2.6 工具验证配置 (toolValidationConfig.ts)
|
||||
|
||||
**文件**: `src/utils/settings/toolValidationConfig.ts`
|
||||
|
||||
配置哪些工具需要验证或可以直接执行。
|
||||
|
||||
```typescript
|
||||
// 免验证工具
|
||||
const bypassValidationTools = [
|
||||
'Read',
|
||||
'BackgroundRead',
|
||||
'TodoWrite',
|
||||
'NotebookEdit',
|
||||
]
|
||||
|
||||
// 需要路径验证的工具
|
||||
const pathValidationTools = [
|
||||
'Bash',
|
||||
'Write',
|
||||
'Edit',
|
||||
'Read',
|
||||
]
|
||||
```
|
||||
|
||||
### 2.7 MDM 配置 (mdm/)
|
||||
|
||||
**目录**: `src/utils/settings/mdm/`
|
||||
|
||||
支持移动设备管理 (Mobile Device Management) 配置。
|
||||
|
||||
```
|
||||
mdm/
|
||||
└── settings.ts # MDM 设置加载
|
||||
```
|
||||
|
||||
### 2.8 类型定义 (types.ts)
|
||||
|
||||
**文件**: `src/utils/settings/types.ts` (~43KB)
|
||||
|
||||
定义所有设置相关的类型。
|
||||
|
||||
```typescript
|
||||
// 设置 JSON 结构
|
||||
type SettingsJson = {
|
||||
// 基本设置
|
||||
model?: string
|
||||
theme?: 'dark' | 'light' | 'system'
|
||||
|
||||
// MCP
|
||||
mcpServers?: Record<string, McpServerConfig>
|
||||
|
||||
// 权限
|
||||
permissionRules?: PermissionRule[]
|
||||
|
||||
// 实验性功能
|
||||
experimental?: Record<string, boolean>
|
||||
}
|
||||
|
||||
// 设置来源
|
||||
type SettingSource =
|
||||
| 'default'
|
||||
| 'managed'
|
||||
| 'user'
|
||||
|
||||
// 可编辑的设置源
|
||||
type EditableSettingSource = 'user'
|
||||
```
|
||||
|
||||
## 3. 迁移系统 (migrations/)
|
||||
|
||||
### 3.1 迁移文件列表
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `migrateAutoUpdatesToSettings.ts` | 自动更新迁移 |
|
||||
| `migrateBypassPermissionsAcceptedToSettings.ts` | 绕过权限迁移 |
|
||||
| `migrateEnableAllProjectMcpServersToSettings.ts` | MCP 服务器迁移 |
|
||||
| `migrateFennecToOpus.ts` | Fennec → Opus 模型迁移 |
|
||||
| `migrateLegacyOpusToCurrent.ts` | Legacy Opus 迁移 |
|
||||
| `migrateOpusToOpus1m.ts` | Opus → Opus 1M 迁移 |
|
||||
| `migrateReplBridgeEnabledToRemoteControlAtStartup.ts` | REPL 桥接迁移 |
|
||||
| `migrateSonnet1mToSonnet45.ts` | Sonnet 1M → 4.5 迁移 |
|
||||
| `migrateSonnet45ToSonnet46.ts` | Sonnet 4.5 → 4.6 迁移 |
|
||||
| `resetAutoModeOptInForDefaultOffer.ts` | 自动模式重置 |
|
||||
| `resetProToOpusDefault.ts` | Pro → Opus 默认重置 |
|
||||
|
||||
### 3.2 迁移示例
|
||||
|
||||
**migrateOpusToOpus1m.ts**:
|
||||
```typescript
|
||||
export function migrateOpusToOpus1m(
|
||||
oldSettings: LegacySettings
|
||||
): NewSettings {
|
||||
return {
|
||||
...oldSettings,
|
||||
model: oldSettings.model === 'opus' ? 'opus-3-5-20241120' : oldSettings.model,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 迁移执行时机
|
||||
|
||||
迁移在以下时机执行:
|
||||
1. 应用启动时
|
||||
2. 设置加载前
|
||||
3. 版本检测后
|
||||
|
||||
## 4. 常量 (constants.ts)
|
||||
|
||||
**文件**: `src/utils/settings/constants.ts` (~5.5KB)
|
||||
|
||||
```typescript
|
||||
// 设置源优先级
|
||||
const SETTING_SOURCE_PRIORITY: Record<SettingSource, number> = {
|
||||
default: 0,
|
||||
managed: 50,
|
||||
user: 100,
|
||||
}
|
||||
|
||||
// 设置路径
|
||||
const SETTINGS_DIR = 'settings'
|
||||
const SETTINGS_FILE = 'settings.json'
|
||||
const MANAGED_SETTINGS_FILE = 'managed-settings.json'
|
||||
const MANAGED_SETTINGS_DROPIN_DIR = 'managed-settings.d'
|
||||
|
||||
// 默认值
|
||||
const DEFAULT_MODEL = 'claude-opus-4-5'
|
||||
const DEFAULT_THEME = 'dark'
|
||||
const DEFAULT_MAX_TOKENS = 8192
|
||||
```
|
||||
|
||||
## 5. 缓存管理 (settingsCache.ts)
|
||||
|
||||
**文件**: `src/utils/settings/settingsCache.ts` (~2.4KB)
|
||||
|
||||
```typescript
|
||||
// 缓存接口
|
||||
interface SettingsCache {
|
||||
get(key: string): SettingsJson | null
|
||||
set(key: string, value: SettingsJson): void
|
||||
invalidate(key: string): void
|
||||
clear(): void
|
||||
}
|
||||
|
||||
// 缓存策略
|
||||
const CACHE_TTL = 5 * 60 * 1000 // 5 分钟
|
||||
const MAX_CACHE_SIZE = 10
|
||||
```
|
||||
|
||||
## 6. 托管设置系统详解
|
||||
|
||||
### 6.1 Drop-in 机制
|
||||
|
||||
托管设置支持 Drop-in 目录机制,允许多个配置文件按优先级合并:
|
||||
|
||||
```
|
||||
~/.claude/settings.json # 用户设置
|
||||
/etc/claude/managed-settings.json # 系统托管基础
|
||||
/etc/claude/managed-settings.d/
|
||||
├── 10-base.json # 优先级 10
|
||||
├── 20-security.json # 优先级 20
|
||||
└── 30-otel.json # 优先级 30
|
||||
```
|
||||
|
||||
### 6.2 合并规则
|
||||
|
||||
1. 基础文件先加载
|
||||
2. Drop-in 文件按文件名排序后加载
|
||||
3. 后加载的文件优先级更高
|
||||
4. 数组字段替换,非数组字段合并
|
||||
|
||||
## 7. 配置验证规则
|
||||
|
||||
### 7.1 路径验证
|
||||
|
||||
```typescript
|
||||
function validatePath(path: string): boolean {
|
||||
// 禁止危险路径
|
||||
if (path.includes('..')) return false
|
||||
if (path.startsWith('/etc/')) return false
|
||||
if (path.startsWith('/sys/')) return false
|
||||
|
||||
// 检查权限
|
||||
if (!canAccessPath(path)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 命令验证
|
||||
|
||||
```typescript
|
||||
function validateCommand(command: string): boolean {
|
||||
// 白名单检查
|
||||
const allowedCommands = ['read', 'edit', 'bash']
|
||||
return allowedCommands.includes(command)
|
||||
}
|
||||
```
|
||||
|
||||
### 7.3 模型名称验证
|
||||
|
||||
```typescript
|
||||
const VALID_MODELS = [
|
||||
'claude-opus-4-5',
|
||||
'claude-sonnet-4-6',
|
||||
'claude-opus-3-5-20241120',
|
||||
// ...
|
||||
]
|
||||
|
||||
function validateModel(model: string): boolean {
|
||||
return VALID_MODELS.includes(model)
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 内部写入标识 (internalWrites.ts)
|
||||
|
||||
**文件**: `src/utils/settings/internalWrites.ts`
|
||||
|
||||
标识由系统内部触发的设置写入,防止来自用户配置文件的覆盖。
|
||||
|
||||
```typescript
|
||||
// 标记内部写入
|
||||
export function markInternalWrite(key: string): void {
|
||||
internalWrites.add(key)
|
||||
}
|
||||
|
||||
// 检查是否为内部写入
|
||||
export function isInternalWrite(key: string): boolean {
|
||||
return internalWrites.has(key)
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user