-
Notifications
You must be signed in to change notification settings - Fork 15.8k
[202604102203No recent activity" 问题的原因分析和修复记录 启动欢迎界面边框默认永久显示 #236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| # API 提供商集成 | ||
|
|
||
| > 记录 Claude Code 支持的 API 提供商、配置方式、模型映射和集成细节。 | ||
|
|
||
| ## 支持的提供商 | ||
|
|
||
| | 提供商 | modelType | 环境变量前缀 | API 兼容层 | | ||
| |--------|-----------|-------------|-----------| | ||
| | Anthropic (默认) | anthropic | ANTHROPIC_* | 原生 SDK | | ||
| | OpenAI | openai | OPENAI_* | OpenAI Chat Completions | | ||
| | Gemini | gemini | GEMINI_* | Gemini Generate Content | | ||
| | xAI Grok | grok | GROK_* / XAI_* | OpenAI 兼容 | | ||
| | **阿里云百炼 (DashScope)** | **anthropic** | **DASHSCOPE_* → ANTHROPIC_*** | **Anthropic 原生 SDK** | | ||
| | Amazon Bedrock | — | — | AWS SDK | | ||
| | Vertex AI | — | — | Google Cloud SDK | | ||
| | Azure Foundry | — | — | Azure SDK | | ||
|
|
||
| ## 阿里云百炼 (DashScope) | ||
|
|
||
| ### 概述 | ||
|
|
||
| DashScope 是阿里云百炼平台的 **Anthropic 兼容 API** 端点。URL 路径 `/apps/anthropic` 明确表明其使用 Anthropic 接口协议。代码中将 `DASHSCOPE_*` 环境变量映射为 `ANTHROPIC_*`,然后走 firstParty Anthropic SDK 路径,**不经过 OpenAI 兼容层**。 | ||
|
|
||
| ### 默认配置 | ||
|
|
||
| | 项目 | 值 | | ||
| |------|-----| | ||
| | Base URL | `https://coding.dashscope.aliyuncs.com/apps/anthropic` | | ||
| | OPUS 默认模型 | `qwen3-max-2026-01-23` | | ||
| | SONNET 默认模型 | `qwen3.6-plus` | | ||
| | HAIKU 默认模型 | `qwen3-coder-plus` | | ||
|
|
||
| ### 支持的模型 | ||
|
|
||
| | 模型 | 推荐用途 | | ||
| |------|---------| | ||
| | qwen3-max-2026-01-23 | OPUS 级能力 | | ||
| | qwen3.6-plus | SONNET 级能力 | | ||
| | qwen3.5-plus | SONNET 级备选 | | ||
| | qwen3-coder-next | 编码专用 | | ||
| | qwen3-coder-plus | HAIKU 级编码 | | ||
| | glm-5 | 智谱最新 | | ||
| | glm-4.7 | 智谱稳定 | | ||
| | kimi-k2.5 | 月之暗面 | | ||
| | MiniMax-M2.5 | MiniMax | | ||
|
|
||
| ### 环境变量 | ||
|
|
||
| | 变量名 | 必需 | 默认值 | 说明 | | ||
| |--------|------|--------|------| | ||
| | `DASHSCOPE_API_KEY` | 是 | — | DashScope API 密钥 → 映射为 `ANTHROPIC_AUTH_TOKEN` | | ||
| | `DASHSCOPE_BASE_URL` | 否 | `https://coding.dashscope.aliyuncs.com/apps/anthropic` | 自定义 API 端点 → 映射为 `ANTHROPIC_BASE_URL` | | ||
| | `DASHSCOPE_DEFAULT_OPUS_MODEL` | 否 | `qwen3-max-2026-01-23` | OPUS 级模型 | | ||
| | `DASHSCOPE_DEFAULT_SONNET_MODEL` | 否 | `qwen3.6-plus` | SONNET 级模型 | | ||
| | `DASHSCOPE_DEFAULT_HAIKU_MODEL` | 否 | `qwen3-coder-plus` | HAIKU 级模型 | | ||
| | `CLAUDE_CODE_USE_DASHSCOPE` | 否 | — | 环境变量启用 | | ||
|
|
||
| ### 架构 | ||
|
|
||
| ``` | ||
| 用户输入 → /login → ConsoleOAuthFlow (DashScope UI) | ||
| → 设置 modelType: 'anthropic' | ||
| → 写入 ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN | ||
|
|
||
| 启动 → getAPIProvider() 返回 'dashscope' | ||
| → claude.ts 映射 DASHSCOPE_* → ANTHROPIC_* env | ||
|
Comment on lines
+61
to
+66
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Provider selection flow is internally inconsistent. Line 62 says Based on learnings: Model provider selection follows the priority order: modelType parameter > environment variables > default firstParty; register new providers in 🤖 Prompt for AI Agents |
||
| → Anthropic SDK 自动读取 ANTHROPIC_BASE_URL | ||
| → API 调用 DashScope Anthropic 兼容端点 | ||
| ``` | ||
|
Comment on lines
+60
to
+69
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a language tag to the fenced block. The fenced code block has no language identifier (markdownlint MD040). 🛠️ Suggested markdown fix-```
+```text
用户输入 → /login → ConsoleOAuthFlow (DashScope UI)
→ 设置 modelType: 'anthropic'
→ 写入 ANTHROPIC_BASE_URL + ANTHROPIC_AUTH_TOKEN
@@
→ Anthropic SDK 自动读取 ANTHROPIC_BASE_URL
→ API 调用 DashScope Anthropic 兼容端点
-```
+```🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 60-60: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||
|
|
||
| ### 关键文件 | ||
|
|
||
| | 文件 | 作用 | | ||
| |------|------| | ||
| | `src/utils/model/providers.ts` | 添加 `'dashscope'` 到 APIProvider 类型和 `getAPIProvider()` | | ||
| | `src/utils/model/model.ts` | 3 个 getDefault 函数添加 DASHSCOPE_DEFAULT_* env 检查 | | ||
| | `src/services/api/claude.ts` | dashscope provider 映射 env → firstParty Anthropic 路径 | | ||
| | `src/components/ConsoleOAuthFlow.tsx` | DashScope 登录表单,保存为 `modelType: 'anthropic'` | | ||
|
|
||
| ### 通过 /login 配置 | ||
|
|
||
| 1. 运行 `/login` | ||
| 2. 选择 **"阿里云百炼 (DashScope) · Anthropic-compatible API"** | ||
| 3. 输入 API Key(预填默认值,可直接修改) | ||
| 4. 可选修改 Base URL、模型名称 | ||
| 5. 保存后重启生效 | ||
|
|
||
| ### 手动配置 | ||
|
|
||
| ```bash | ||
| # 环境变量方式 | ||
| export DASHSCOPE_API_KEY="your-api-key" | ||
| export DASHSCOPE_BASE_URL="https://coding.dashscope.aliyuncs.com/apps/anthropic" | ||
|
|
||
| # 或在 ~/.claude/settings.json 中配置 | ||
| { | ||
| "modelType": "anthropic", | ||
| "env": { | ||
| "ANTHROPIC_BASE_URL": "https://coding.dashscope.aliyuncs.com/apps/anthropic", | ||
| "ANTHROPIC_AUTH_TOKEN": "your-api-key", | ||
| "DASHSCOPE_DEFAULT_SONNET_MODEL": "qwen3.6-plus", | ||
| "DASHSCOPE_DEFAULT_OPUS_MODEL": "qwen3-max-2026-01-23", | ||
| "DASHSCOPE_DEFAULT_HAIKU_MODEL": "qwen3-coder-plus" | ||
| } | ||
| } | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||
| # UI 渲染与界面层 | ||||||
|
|
||||||
| > 记录 Claude Code 终端 UI(Ink 框架)的渲染行为、布局模式、常见问题及修复。 | ||||||
|
|
||||||
| ## LogoV2 启动欢迎界面 | ||||||
|
|
||||||
| ### 组件结构 | ||||||
|
|
||||||
| ``` | ||||||
| LogoV2.tsx (src/components/LogoV2/) | ||||||
| ├── CondensedLogo.tsx — 缩略模式(无边框,日常最常见) | ||||||
| ├── LogoV2.tsx — 完整模式(有边框)/ 紧凑模式(有边框) | ||||||
| ├── CondensedLogo.tsx — 缩略模式(无边框,日常最常见) | ||||||
| ├── Clawd.tsx — ASCII 猫吉祥物 | ||||||
| ├── AnimatedClawd.tsx — 动画版 Clawd | ||||||
| ├── FeedColumn.tsx — 右侧信息流(活动记录/更新日志) | ||||||
| └── WelcomeV2.tsx — 首次 Onboarding 欢迎文本 | ||||||
| ``` | ||||||
|
Comment on lines
+9
to
+18
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix the component-tree snippet. This fence is missing a language tag (MD040), the root is labeled as a file even though it has children, and 📝 Suggested edit-```
-LogoV2.tsx (src/components/LogoV2/)
-├── CondensedLogo.tsx — 缩略模式(无边框,日常最常见)
-├── LogoV2.tsx — 完整模式(有边框)/ 紧凑模式(有边框)
-├── CondensedLogo.tsx — 缩略模式(无边框,日常最常见)
+```text
+src/components/LogoV2/
+├── LogoV2.tsx — 完整模式(有边框)/ 紧凑模式(有边框)
+├── CondensedLogo.tsx — 缩略模式(当前已永久关闭)🧰 Tools🪛 markdownlint-cli2 (0.22.0)[warning] 9-9: Fenced code blocks should have a language specified (MD040, fenced-code-language) 🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### 三种渲染模式 | ||||||
|
|
||||||
| | 模式 | 触发条件 | 边框 | 说明 | | ||||||
| |------|---------|------|------| | ||||||
| | **缩略模式** (Condensed) | ~~无 Release Notes 且无首次引导~~ | ❌ | **已永久关闭**(2026-04-10),不再进入 | | ||||||
| | **紧凑模式** (Compact) | 终端宽度 < 70 列 | ✅ | 紫色圆角边框,内容居中 | | ||||||
| | **完整模式** (Full) | 默认路径 | ✅ | 紫色圆角边框,双栏布局 + 信息流 | | ||||||
|
|
||||||
| > **注**:缩略模式已在 `LogoV2.tsx` 中永久关闭(`isCondensedMode = false`),所有启动都走完整模式或紧凑模式。 | ||||||
|
|
||||||
| ### 模式判断逻辑(源码:`src/components/LogoV2/LogoV2.tsx`) | ||||||
|
|
||||||
| ```typescript | ||||||
| // 原始逻辑:三种模式切换 | ||||||
| const isCondensedMode = | ||||||
| !hasReleaseNotes && | ||||||
| !showOnboarding && | ||||||
| !isEnvTruthy(process.env.CLAUDE_CODE_FORCE_FULL_LOGO) | ||||||
|
|
||||||
| // 环境变量强制:始终显示完整模式 | ||||||
| // CLAUDE_CODE_FORCE_FULL_LOGO=1 bun run dev | ||||||
| ``` | ||||||
|
|
||||||
| **CondensedLogo 内部**(`src/components/LogoV2/CondensedLogo.tsx`):无任何边框,纯文本 + ASCII 猫。 | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refresh this sentence to match the current code.
📝 Suggested edit-**CondensedLogo 内部**(`src/components/LogoV2/CondensedLogo.tsx`):无任何边框,纯文本 + ASCII 猫。
+**CondensedLogo 内部**(`src/components/LogoV2/CondensedLogo.tsx`):当前实现也会渲染圆角边框和标题,但运行时路径已被永久关闭。📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
|
|
||||||
| ### 边框渲染机制 | ||||||
|
|
||||||
| 边框由 `@anthropic/ink` 的 `Box` 组件通过 `cli-boxes` 库绘制: | ||||||
|
|
||||||
| - `borderStyle="round"` → 使用 `cli-boxes` 的 `round` 样式(`╭─╮` `│` `╰─╯`) | ||||||
| - `borderColor="claude"` → 紫色主题色 | ||||||
| - `borderText` → 边框顶部嵌入标题文本 "Claude Code" | ||||||
|
|
||||||
| 详见 `packages/@ant/ink/src/core/render-border.ts`。 | ||||||
|
|
||||||
| ## 常见问题 | ||||||
|
|
||||||
| ### 问题:启动时欢迎边框时有时无 | ||||||
|
|
||||||
| **原因**:日常启动(无 Release Notes、非首次使用)走缩略模式,不显示边框。 | ||||||
|
|
||||||
| **修复**:在 `LogoV2.tsx` 中永久关闭缩略模式: | ||||||
|
|
||||||
| ```diff | ||||||
| - const isCondensedMode = | ||||||
| - !hasReleaseNotes && | ||||||
| - !showOnboarding && | ||||||
| - !isEnvTruthy(process.env.CLAUDE_CODE_FORCE_FULL_LOGO) | ||||||
| + const isCondensedMode = false | ||||||
|
|
||||||
| - if ( | ||||||
| - !hasReleaseNotes && | ||||||
| - !showOnboarding && | ||||||
| - !isEnvTruthy(process.env.CLAUDE_CODE_FORCE_FULL_LOGO) | ||||||
| - ) { | ||||||
| + if (false) { | ||||||
| return <CondensedLogo /> | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| 修改后,无论何种情况启动,都会显示完整模式的紫色圆角边框。 | ||||||
|
|
||||||
| **影响**: | ||||||
| - 每次启动都会渲染完整的边框 + 信息流(活动记录或更新日志) | ||||||
| - 轻微增加启动渲染开销(从 0 边框到有边框双栏) | ||||||
| - 不再走 CondensedLogo(节省了 GuestPassesUpsell 等副作用计数逻辑) | ||||||
|
|
||||||
| ### 问题:终端宽度不足导致边框变形 | ||||||
|
|
||||||
| **原因**:`getLayoutMode(columns)` 在终端 < 70 列时切换到 compact 模式。 | ||||||
|
|
||||||
| **参考**:`src/utils/logoV2Utils.ts` — `getLayoutMode(columns: number): LayoutMode` | ||||||
|
|
||||||
| ### 问题:Recent Activity 显示 "No recent activity" | ||||||
|
|
||||||
| **原因**:`src/setup.ts` 中 `getRecentActivity()` 只在 `hasReleaseNotes` 为 true 时才调用。日常启动(无新 Release Notes)时,`cachedActivity` 始终为空数组。 | ||||||
|
|
||||||
| **修复**(`src/setup.ts` 第 383-395 行): | ||||||
|
|
||||||
| ```diff | ||||||
| if (!isBareMode()) { | ||||||
| - const { hasReleaseNotes } = await checkForReleaseNotes( | ||||||
| - getGlobalConfig().lastReleaseNotesSeen, | ||||||
| - ) | ||||||
| - if (hasReleaseNotes) { | ||||||
| - await getRecentActivity() | ||||||
| - } | ||||||
| + // Populate release notes cache (side effect: fetches changelog if needed) | ||||||
| + void checkForReleaseNotes(getGlobalConfig().lastReleaseNotesSeen) | ||||||
| + // Load recent activity unconditionally (not tied to release notes) | ||||||
| + try { | ||||||
| + await getRecentActivity() | ||||||
| + } catch (error) { | ||||||
| + logError('Failed to load recent activity:', error) | ||||||
| + } | ||||||
| } | ||||||
| ``` | ||||||
|
|
||||||
| **关键变化**: | ||||||
| 1. `getRecentActivity()` 从 `if (hasReleaseNotes)` 块中移出,无条件调用 | ||||||
| 2. 增加 try-catch 防止损坏的会话文件阻塞启动 | ||||||
| 3. `checkForReleaseNotes` 改为 `void` 调用(保留 cache 填充的副作用,但不阻塞等待结果) | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix emphasis parsing in provider table cell.
The
DASHSCOPE_* → ANTHROPIC_*cell triggers markdown emphasis parsing/lint issues due to raw*. Prefer inline code or escaped asterisks.🛠️ Suggested markdown fix
📝 Committable suggestion
🤖 Prompt for AI Agents