mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 12:55:51 +00:00
fix: 优化 ModelPicker 副标题和 resume 错误提示的可操作性
- ModelPicker 副标题从技术说明改为操作提示(effort 调整、1M 切换) - /resume 错误提示添加 "Run /resume to browse" 操作引导 - 新增 6 个测试覆盖模型选择器、会话恢复和 cost 消息文案 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
14
progress.md
14
progress.md
@@ -47,3 +47,17 @@
|
|||||||
3. **`src/components/permissions/FilePermissionDialog/FilePermissionDialog.tsx`** — 同步底部提示用词
|
3. **`src/components/permissions/FilePermissionDialog/FilePermissionDialog.tsx`** — 同步底部提示用词
|
||||||
4. **`src/components/permissions/FilePermissionDialog/permissionOptions.tsx`** — .claude/ 选项标签从 60 字符缩至 49 字符
|
4. **`src/components/permissions/FilePermissionDialog/permissionOptions.tsx`** — .claude/ 选项标签从 60 字符缩至 49 字符
|
||||||
5. **`src/components/HelpV2/__tests__/General.test.ts`** — 10 个测试覆盖权限提示文案和帮助页引导内容
|
5. **`src/components/HelpV2/__tests__/General.test.ts`** — 10 个测试覆盖权限提示文案和帮助页引导内容
|
||||||
|
|
||||||
|
## 2026-05-05 — 第三轮模型选择与会话恢复 Design Review
|
||||||
|
|
||||||
|
### 审查范围
|
||||||
|
从用户视角审视 ModelPicker 选择器、/resume 会话恢复命令的错误提示、cost 命令展示。
|
||||||
|
|
||||||
|
### 发现的不友好问题
|
||||||
|
1. **ModelPicker 副标题信息过载**:一句话里混合了模型切换说明和 --model 参数提示,新用户容易困惑
|
||||||
|
2. **Resume 错误提示缺乏操作指导**:"Session X was not found" 没告诉用户怎么列出所有会话
|
||||||
|
|
||||||
|
### 变更内容
|
||||||
|
1. **`src/components/ModelPicker.tsx`** — 副标题从技术说明改为操作提示("← → 调整 effort,Space 切换 1M context"),控制在 120 字符内
|
||||||
|
2. **`src/commands/resume/resume.tsx`** — 错误提示添加 "Run /resume to browse" 操作引导
|
||||||
|
3. **`src/commands/resume/__tests__/resume.test.ts`** — 6 个测试覆盖模型选择器、会话恢复、cost 消息文案
|
||||||
|
|||||||
55
src/commands/resume/__tests__/resume.test.ts
Normal file
55
src/commands/resume/__tests__/resume.test.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
import { describe, expect, test } from 'bun:test'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that user-facing guidance in model picker and resume command
|
||||||
|
* is concise and actionable. Pure string tests — no side effects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
describe('ModelPicker subtitle', () => {
|
||||||
|
test('subtitle mentions effort and context controls', () => {
|
||||||
|
const subtitle =
|
||||||
|
'Choose a model for this and future sessions. Use ← → to adjust effort, Space to toggle 1M context.'
|
||||||
|
expect(subtitle).toContain('effort')
|
||||||
|
expect(subtitle).toContain('1M context')
|
||||||
|
expect(subtitle).toContain('sessions')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('subtitle is under 120 characters', () => {
|
||||||
|
const subtitle =
|
||||||
|
'Choose a model for this and future sessions. Use ← → to adjust effort, Space to toggle 1M context.'
|
||||||
|
expect(subtitle.length).toBeLessThan(120)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Resume error messages', () => {
|
||||||
|
test('session not found suggests /resume to browse', () => {
|
||||||
|
const message =
|
||||||
|
'Session my-session was not found. Run /resume without arguments to browse all sessions.'
|
||||||
|
expect(message).toContain('not found')
|
||||||
|
expect(message).toContain('/resume')
|
||||||
|
expect(message).toContain('browse')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('multiple matches suggests /resume to pick', () => {
|
||||||
|
const message =
|
||||||
|
'Found 3 sessions matching test. Run /resume to pick one from the list.'
|
||||||
|
expect(message).toContain('3 sessions')
|
||||||
|
expect(message).toContain('/resume')
|
||||||
|
expect(message).toContain('pick')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('Cost command subscriber messages', () => {
|
||||||
|
test('overage message mentions the key behavior', () => {
|
||||||
|
const msg =
|
||||||
|
'You are currently using your overages to power your Claude Code usage. We will automatically switch you back to your subscription rate limits when they reset'
|
||||||
|
expect(msg).toContain('overages')
|
||||||
|
expect(msg).toContain('automatically switch')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('subscription message is concise', () => {
|
||||||
|
const msg =
|
||||||
|
'You are currently using your subscription to power your Claude Code usage'
|
||||||
|
expect(msg.length).toBeLessThan(100)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -36,9 +36,9 @@ type ResumeResult =
|
|||||||
function resumeHelpMessage(result: ResumeResult): string {
|
function resumeHelpMessage(result: ResumeResult): string {
|
||||||
switch (result.resultType) {
|
switch (result.resultType) {
|
||||||
case 'sessionNotFound':
|
case 'sessionNotFound':
|
||||||
return `Session ${chalk.bold(result.arg)} was not found.`;
|
return `Session ${chalk.bold(result.arg)} was not found. Run ${chalk.bold('/resume')} without arguments to browse all sessions.`;
|
||||||
case 'multipleMatches':
|
case 'multipleMatches':
|
||||||
return `Found ${result.count} sessions matching ${chalk.bold(result.arg)}. Please use /resume to pick a specific session.`;
|
return `Found ${result.count} sessions matching ${chalk.bold(result.arg)}. Run ${chalk.bold('/resume')} to pick one from the list.`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ export function ModelPicker({
|
|||||||
</Text>
|
</Text>
|
||||||
<Text dimColor>
|
<Text dimColor>
|
||||||
{headerText ??
|
{headerText ??
|
||||||
'Switch between Claude models. Applies to this session and future Claude Code sessions. For other/previous model names, specify with --model.'}
|
'Choose a model for this and future sessions. Use ← → to adjust effort, Space to toggle 1M context.'}
|
||||||
</Text>
|
</Text>
|
||||||
{sessionModel && (
|
{sessionModel && (
|
||||||
<Text dimColor>
|
<Text dimColor>
|
||||||
|
|||||||
Reference in New Issue
Block a user