# i18n 静态键值对重构计划

## 任务背景

将所有动态拼接的 i18n 使用方式改为静态数组方式，使 i18n-ally 工具能够正确识别翻译键。

**目标**：从 `i18n.t(\`language:configLangHint.${l}\`)` 改为静态对象访问方式。

## 重构范围

### 1. 语言配置提示 (2处)
- **文件**：`src/commands/update.ts:44`, `src/commands/init.ts:254`
- **当前代码**：`i18n.t(\`language:configLangHint.${l}\`)`
- **变量范围**：`l` ∈ `['zh-CN', 'en']`

### 2. 工作流选项 (2处)
- **文件**：`src/utils/workflow-installer.ts:28,83`
- **当前代码**：`i18n.t(\`workflow:workflowOption.${workflow.id}\`)`
- **变量范围**：`workflow.id` ∈ `['bmadWorkflow', 'commonTools', 'featPlanUx', 'gitWorkflow', 'sixStepsWorkflow']`

### 3. 输出风格配置 (6处)
- **文件**：`src/utils/output-style.ts:151,173,175,182,184`
- **当前代码**：
  - `i18n.t(\`configuration:outputStyles.${style.id}.name\`)`
  - `i18n.t(\`configuration:outputStyles.${style.id}.description\`)`
- **变量范围**：`style.id` ∈ `['default', 'engineer-professional', 'nekomata-engineer', 'laowang-engineer', 'explanatory', 'learning']`

### 4. MCP 服务配置 (3处)
- **文件**：`src/config/mcp-services.ts:77,78,85`
- **当前代码**：
  - `i18n.t(\`mcp:services.${config.id}.name\`)`
  - `i18n.t(\`mcp:services.${config.id}.description\`)`
  - `i18n.t(\`mcp:services.${config.id}.apiKeyPrompt\`)`

## 实现方案

### 核心模式
```typescript
// 旧方式
i18n.t(`namespace:key.${variable}`)

// 新方式
const STATIC_KEYS = {
  'value1': i18n.t('namespace:key.value1'),
  'value2': i18n.t('namespace:key.value2')
} as const

// 使用
STATIC_KEYS[variable]
```

### 具体实现

#### 1. 语言配置提示
```typescript
// 在 src/commands/init.ts 和 src/commands/update.ts 中
const LANG_HINT_KEYS = {
  'zh-CN': i18n.t('language:configLangHint.zh-CN'),
  'en': i18n.t('language:configLangHint.en')
} as const

// 替换使用
name: `${LANG_LABELS[l]} - ${LANG_HINT_KEYS[l]}`
```

#### 2. 工作流选项
```typescript
// 在 src/utils/workflow-installer.ts 中
const WORKFLOW_OPTION_KEYS = {
  'bmadWorkflow': i18n.t('workflow:workflowOption.bmadWorkflow'),
  'commonTools': i18n.t('workflow:workflowOption.commonTools'), 
  'featPlanUx': i18n.t('workflow:workflowOption.featPlanUx'),
  'gitWorkflow': i18n.t('workflow:workflowOption.gitWorkflow'),
  'sixStepsWorkflow': i18n.t('workflow:workflowOption.sixStepsWorkflow')
} as const

// 替换使用
const name = WORKFLOW_OPTION_KEYS[workflow.id] || workflow.id
```

#### 3. 输出风格配置 (对象数组方式)
```typescript
// 在 src/utils/output-style.ts 中
const outputStyleList = [
  {
    id: 'default',
    name: i18n.t('configuration:outputStyles.default.name'),
    description: i18n.t('configuration:outputStyles.default.description')
  },
  {
    id: 'engineer-professional',
    name: i18n.t('configuration:outputStyles.engineer-professional.name'),
    description: i18n.t('configuration:outputStyles.engineer-professional.description')
  },
  {
    id: 'nekomata-engineer',
    name: i18n.t('configuration:outputStyles.nekomata-engineer.name'),
    description: i18n.t('configuration:outputStyles.nekomata-engineer.description')
  },
  {
    id: 'laowang-engineer',
    name: i18n.t('configuration:outputStyles.laowang-engineer.name'),
    description: i18n.t('configuration:outputStyles.laowang-engineer.description')
  },
  {
    id: 'explanatory',
    name: i18n.t('configuration:outputStyles.explanatory.name'),
    description: i18n.t('configuration:outputStyles.explanatory.description')
  },
  {
    id: 'learning',
    name: i18n.t('configuration:outputStyles.learning.name'),
    description: i18n.t('configuration:outputStyles.learning.description')
  }
]

// 替换使用
const styleInfo = outputStyleList.find(s => s.id === styleId)
name: `${styleInfo?.name || styleId} - ${ansis.gray(styleInfo?.description || '')}`
```

#### 4. MCP 服务配置 (对象数组方式)
```typescript
// 在 src/config/mcp-services.ts 中
const mcpServiceList = [
  {
    id: 'context7',
    name: i18n.t('mcp:services.context7.name'),
    description: i18n.t('mcp:services.context7.description'),
    apiKeyPrompt: i18n.t('mcp:services.context7.apiKeyPrompt')
  },
  {
    id: 'exa',
    name: i18n.t('mcp:services.exa.name'),
    description: i18n.t('mcp:services.exa.description'),
    apiKeyPrompt: i18n.t('mcp:services.exa.apiKeyPrompt')
  },
  // ...其他 MCP 服务
]

// 替换使用
const serviceInfo = mcpServiceList.find(s => s.id === config.id)
name: serviceInfo?.name || config.id,
description: serviceInfo?.description || '',
const apiKeyPrompt = serviceInfo?.apiKeyPrompt
```

## 执行步骤

### 阶段 1：数据收集
1. ✅ 分析所有动态拼接使用模式
2. ✅ 收集所有可能的变量值
3. ✅ 设计静态对象结构

### 阶段 2：代码重构
1. 重构语言配置提示 (2处)
2. 重构工作流选项 (2处)
3. 重构输出风格配置 (6处)
4. 重构 MCP 服务配置 (3处)

### 阶段 3：验证测试
1. 运行相关功能测试
2. 验证 i18n-ally 识别效果
3. 确保翻译功能正常工作

## 预期效果

1. **i18n-ally 兼容性** ✅ - 所有静态 i18n.t() 调用都能被识别
2. **类型安全性** ✅ - 使用 as const 确保类型检查
3. **性能优化** ✅ - 翻译值在对象创建时预计算
4. **代码整洁性** ✅ - 消除所有动态拼接，提高可读性
5. **维护便利性** ✅ - 静态对象集中管理，易于扩展

## 成功标准

- [ ] 所有动态拼接改为静态对象访问
- [ ] i18n-ally 能识别所有翻译键
- [ ] 功能测试全部通过
- [ ] TypeScript 类型检查通过
- [ ] 代码结构保持整洁

---

**状态**: 计划完成，等待执行批准
**负责人**: 浮浮酱 (猫娘工程师)
**创建时间**: 2025-08-31