diff --git a/docs/plans/2026-02-16-bedrock-ui-merge-design.md b/docs/plans/2026-02-16-bedrock-ui-merge-design.md deleted file mode 100644 index fd54250de..000000000 --- a/docs/plans/2026-02-16-bedrock-ui-merge-design.md +++ /dev/null @@ -1,141 +0,0 @@ -# AWS Bedrock UI 合并设计 - -## 背景 - -cc-switch 项目中 AWS Bedrock 当前有两个独立的 Claude preset:`AWS Bedrock (AKSK)` 和 `AWS Bedrock (API Key)`。两者功能高度重叠,仅认证方式不同。需要将它们合并为一个统一的 preset,简化用户体验。 - -## 需求 - -1. 将两个 Bedrock preset 合并为一个 `"AWS Bedrock"` preset -2. API Key 为推荐认证方式,AKSK 为备选 -3. 用户无需手动填写请求地址,根据 Region 自动生成 -4. Region 保留文本输入,增加格式验证 -5. 所有认证字段平铺展示,用户填哪个就用哪个 -6. 两种认证都填时,API Key 优先 - -## 方案选择 - -选择 **方案 A:合并为单个 Preset,全字段平铺**。理由:改动集中,不需要新 UI 组件,符合 YAGNI 原则。 - -## 设计 - -### Preset 数据结构 - -将 `claudeProviderPresets.ts` 中的两个旧 preset 合并为一个: - -```typescript -{ - id: "claude_bedrock", - name: "AWS Bedrock", - category: "cloud_provider", - icon: { type: "aws", color: "#FF9900" }, - templateValues: { - AWS_REGION: { - label: "AWS Region", - placeholder: "us-west-2", - editorValue: "us-west-2", - }, - BEDROCK_API_KEY: { - label: "Bedrock API Key (推荐)", - placeholder: "br-...", - editorValue: "", - optional: true, - }, - AWS_ACCESS_KEY_ID: { - label: "Access Key ID", - placeholder: "AKIA...", - editorValue: "", - optional: true, - }, - AWS_SECRET_ACCESS_KEY: { - label: "Secret Access Key", - placeholder: "wJalr...", - editorValue: "", - isSecret: true, - optional: true, - }, - }, - settingsConfig: { - env: { - ANTHROPIC_BASE_URL: "https://bedrock-runtime.${AWS_REGION}.amazonaws.com", - AWS_REGION: "${AWS_REGION}", - CLAUDE_CODE_USE_BEDROCK: "1", - }, - }, -} -``` - -### 提交逻辑 - -表单提交时根据填写内容条件性生成 settingsConfig: - -1. **API Key 有值** → 写入 `apiKey` 字段,不写入 AKSK env -2. **API Key 为空,AKSK 都有值** → 写入 `AWS_ACCESS_KEY_ID` 和 `AWS_SECRET_ACCESS_KEY` 到 env -3. **都为空** → 验证拦截,提示"请至少填写一种认证方式" - -API Key 模式输出: -```typescript -{ - env: { - ANTHROPIC_BASE_URL: "https://bedrock-runtime.us-west-2.amazonaws.com", - AWS_REGION: "us-west-2", - CLAUDE_CODE_USE_BEDROCK: "1", - }, - apiKey: "br-xxxxx", -} -``` - -AKSK 模式输出: -```typescript -{ - env: { - ANTHROPIC_BASE_URL: "https://bedrock-runtime.us-west-2.amazonaws.com", - AWS_REGION: "us-west-2", - AWS_ACCESS_KEY_ID: "AKIA...", - AWS_SECRET_ACCESS_KEY: "wJalr...", - CLAUDE_CODE_USE_BEDROCK: "1", - }, -} -``` - -### Region 验证 - -- 正则:`^[a-z]{2}-[a-z]+-\d+$` -- 匹配示例:`us-west-2`, `ap-northeast-1`, `eu-central-1` -- 验证失败提示:请输入有效的 AWS Region 格式 - -### UI 布局 - -``` -┌─────────────────────────────────────────┐ -│ AWS Bedrock │ -├─────────────────────────────────────────┤ -│ AWS Region [us-west-2 ] │ -│ Bedrock API Key [ ] │ ← 推荐 -│ Access Key ID [ ] │ -│ Secret Access Key [●●●●●●●● ] │ -│ ── Model Selection ── │ -│ Haiku / Sonnet / Opus dropdowns │ -│ [ Save ] │ -└─────────────────────────────────────────┘ -``` - -- Base URL 完全隐藏,根据 Region 自动拼接 -- Secret Access Key 使用密码遮罩 -- API Key 字段排在 AKSK 之前 - -## 涉及文件 - -| 文件 | 改动 | -|------|------| -| `src/config/claudeProviderPresets.ts` | 删除两个旧 Bedrock preset,新建合并的 preset | -| `src/utils/providerConfigUtils.ts` | 修改 `applyTemplateValues()`,增加 Bedrock 条件逻辑 | -| `src/components/providers/forms/ClaudeFormFields.tsx` | optional 字段渲染,Bedrock 下隐藏 Base URL | -| `src/components/providers/forms/ProviderForm.tsx` | Bedrock 表单验证(至少一种认证 + Region 格式) | - -## 不在范围内 - -- OpenCode 的 Bedrock preset -- Model 选择器逻辑 -- 后端存储结构 -- 其他 provider 配置 diff --git a/docs/plans/2026-02-16-bedrock-ui-merge-implementation.md b/docs/plans/2026-02-16-bedrock-ui-merge-implementation.md deleted file mode 100644 index 4c719aa92..000000000 --- a/docs/plans/2026-02-16-bedrock-ui-merge-implementation.md +++ /dev/null @@ -1,424 +0,0 @@ -# AWS Bedrock UI 合并实施计划 - -> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. - -**Goal:** 将 AWS Bedrock 的两个独立 Claude preset(AKSK 和 API Key)合并为一个统一的 preset,支持平铺展示所有认证字段,根据 Region 自动生成 Base URL。 - -**Architecture:** 修改 preset 定义为单一合并 preset,扩展 TemplateValueConfig 类型支持 optional/isSecret 字段,在 UI 层和提交逻辑层处理条件性认证字段。Base URL 隐藏,由 Region 自动拼接。 - -**Tech Stack:** React, TypeScript, react-hook-form, shadcn/ui - ---- - -### Task 1: 扩展 TemplateValueConfig 类型 - -**Files:** -- Modify: `src/config/claudeProviderPresets.ts:6-11` - -**Step 1: 修改 TemplateValueConfig 接口** - -在 `src/config/claudeProviderPresets.ts` 第 6-11 行,扩展接口: - -```typescript -export interface TemplateValueConfig { - label: string; - placeholder: string; - defaultValue?: string; - editorValue: string; - optional?: boolean; // 可选字段,不参与必填校验 - isSecret?: boolean; // 密码字段,使用 password 类型渲染 -} -``` - -**Step 2: Commit** - -```bash -cd /root/keith-space/github-search/cc-switch -git add src/config/claudeProviderPresets.ts -git commit -m "feat: extend TemplateValueConfig with optional and isSecret fields" -``` - ---- - -### Task 2: 合并 Bedrock Preset 定义 - -**Files:** -- Modify: `src/config/claudeProviderPresets.ts:536-610` - -**Step 1: 替换两个旧 preset 为一个合并 preset** - -删除第 536-610 行的两个 preset(`"AWS Bedrock (AKSK)"` 和 `"AWS Bedrock (API Key)"`),替换为: - -```typescript - { - name: "AWS Bedrock", - websiteUrl: "https://aws.amazon.com/bedrock/", - settingsConfig: { - apiKey: "${BEDROCK_API_KEY}", - env: { - ANTHROPIC_BASE_URL: - "https://bedrock-runtime.${AWS_REGION}.amazonaws.com", - AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}", - AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}", - AWS_REGION: "${AWS_REGION}", - ANTHROPIC_MODEL: "global.anthropic.claude-opus-4-6-v1", - ANTHROPIC_DEFAULT_HAIKU_MODEL: - "global.anthropic.claude-haiku-4-5-20251001-v1:0", - ANTHROPIC_DEFAULT_SONNET_MODEL: - "global.anthropic.claude-sonnet-4-5-20250929-v1:0", - ANTHROPIC_DEFAULT_OPUS_MODEL: "global.anthropic.claude-opus-4-6-v1", - CLAUDE_CODE_USE_BEDROCK: "1", - }, - }, - category: "cloud_provider", - templateValues: { - AWS_REGION: { - label: "AWS Region", - placeholder: "us-west-2", - editorValue: "us-west-2", - }, - BEDROCK_API_KEY: { - label: "Bedrock API Key (推荐)", - placeholder: "your-bedrock-api-key", - editorValue: "", - optional: true, - }, - AWS_ACCESS_KEY_ID: { - label: "Access Key ID", - placeholder: "AKIA...", - editorValue: "", - optional: true, - }, - AWS_SECRET_ACCESS_KEY: { - label: "Secret Access Key", - placeholder: "your-secret-key", - editorValue: "", - optional: true, - isSecret: true, - }, - }, - icon: "aws", - iconColor: "#FF9900", - }, -``` - -**Step 2: Commit** - -```bash -cd /root/keith-space/github-search/cc-switch -git add src/config/claudeProviderPresets.ts -git commit -m "feat: merge two Bedrock presets into single unified preset" -``` - ---- - -### Task 3: 更新模板值验证逻辑(跳过 optional 字段) - -**Files:** -- Modify: `src/components/providers/forms/hooks/useTemplateValues.ts:257-282` - -**Step 1: 修改 validateTemplateValues 跳过 optional 字段** - -在 `useTemplateValues.ts` 的 `validateTemplateValues` 函数中,第 265 行后增加 optional 跳过逻辑: - -```typescript - const validateTemplateValues = useCallback((): { - isValid: boolean; - missingField?: { key: string; label: string }; - } => { - if (templateValueEntries.length === 0) { - return { isValid: true }; - } - - for (const [key, config] of templateValueEntries) { - // 跳过可选字段 - if (config.optional) { - continue; - } - const entry = templateValues[key]; - const resolvedValue = ( - entry?.editorValue ?? - entry?.defaultValue ?? - config.defaultValue ?? - "" - ).trim(); - if (!resolvedValue) { - return { - isValid: false, - missingField: { key, label: config.label }, - }; - } - } - - return { isValid: true }; - }, [templateValueEntries, templateValues]); -``` - -**Step 2: Commit** - -```bash -cd /root/keith-space/github-search/cc-switch -git add src/components/providers/forms/hooks/useTemplateValues.ts -git commit -m "feat: skip optional template values in validation" -``` - ---- - -### Task 4: 更新 ClaudeFormFields 渲染 isSecret 字段 + 隐藏 Bedrock 的 Base URL - -**Files:** -- Modify: `src/components/providers/forms/ClaudeFormFields.tsx:133-153` (template rendering) -- Modify: `src/components/providers/forms/ClaudeFormFields.tsx:20-71` (props) - -**Step 1: 添加 isBedrock prop** - -在 `ClaudeFormFieldsProps` 接口中(约第 20 行)添加: - -```typescript - // Bedrock 模式标识 - isBedrock?: boolean; -``` - -在函数参数解构中也添加 `isBedrock`。 - -**Step 2: 更新模板变量渲染支持 isSecret** - -修改第 133-153 行的模板变量渲染部分,让 `isSecret` 字段使用 `type="password"`: - -```typescript - {templateValueEntries.map(([key, config]) => ( -