Skip to content

Commit c7b2a49

Browse files
committed
refactor(theme): 统一主题颜色与样式实现
- 终端输出相关 chalk 样式函数支持更多颜色分组 - 主题样式函数接口新增多种状态、风险、品牌等分类 - React 组件中统一使用 theme.status 和 theme.brand 下的颜色 - ExitSummaryView 和退出摘要相关样式颜色更新为更合理的边框和状态色 - DropdownMenu 和 FileMentionMenu 组件中选中、激活颜色改为 brand.accent - MessageView 组件中统一使用 brand.accent 和 status.info,提升语义明确性 - 文档更新,新增 ANSI 16色主题,调整自定义主题颜色配置示例 - 主题导出增加 ColorsTheme 类型和 buildThemeTokens 函数 - 优化配置文档中颜色 Token 结构,提供详细分组说明和新版示例配置
1 parent 34acff4 commit c7b2a49

35 files changed

Lines changed: 1552 additions & 541 deletions

README-en.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Set `theme.preset` in `settings.json` to switch:
158158
}
159159
```
160160

161-
Available presets: `light` (default), `dark`, `github-light`, `github-dark`, `gitlab-light`, `gitlab-dark`, `monokai`, `dracula`.
161+
Available presets: `light` (default), `dark`, `github-light`, `github-dark`, `monokai`, `dracula`, `ansi`.
162162

163163
You can also use the `/theme` command at runtime to open the theme picker with live preview.
164164

README-zh_CN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Deep Code CLI 内置多套预设主题,默认使用浅色主题(`light`)
158158
}
159159
```
160160

161-
可用预设:`light`(默认)、`dark``github-light``github-dark``gitlab-light``gitlab-dark``monokai``dracula`
161+
可用预设:`light`(默认)、`dark``github-light``github-dark``monokai``dracula``ansi`
162162

163163
也可在运行时使用 `/theme` 命令打开主题选择器,实时预览并切换。
164164

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Deep Code CLI 内置多套预设主题,默认使用浅色主题(`light`)
158158
}
159159
```
160160

161-
可用预设:`light`(默认)、`dark``github-light``github-dark``gitlab-light``gitlab-dark``monokai``dracula`
161+
可用预设:`light`(默认)、`dark``github-light``github-dark``monokai``dracula``ansi`
162162

163163
也可在运行时使用 `/theme` 命令打开主题选择器,实时预览并切换。
164164

docs/configuration.md

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -150,43 +150,93 @@ Deep Code 支持自定义主题颜色,让你的终端界面更符合个人喜
150150
| `dark` | 暗色主题(深色背景优化) |
151151
| `github-light` | GitHub Light 风格主题 |
152152
| `github-dark` | GitHub Dark 风格主题 |
153-
| `gitlab-light` | GitLab Light 风格主题 |
154-
| `gitlab-dark` | GitLab Dark 风格主题 |
155153
| `monokai` | Monokai 风格主题 |
156154
| `dracula` | Dracula 风格主题 |
155+
| `ansi-light` | ANSI 浅色主题(标准 16 色) |
156+
| `ansi-dark` | ANSI 暗色主题(标准 16 色) |
157157

158158
**自定义主题颜色**
159159

160-
使用 `preset: "custom"` 并通过 `overrides` 覆盖部分颜色
160+
推荐使用 `colors` 简化色板配置,只需定义 16 个基础色,系统自动推导完整主题
161161

162162
```json
163163
{
164164
"theme": {
165165
"preset": "custom",
166+
"colors": {
167+
"Background": "#ffffff",
168+
"Foreground": "#1F2328",
169+
"Gray": "#8b949e",
170+
"LightBlue": "#0969da",
171+
"AccentBlue": "#ff6600",
172+
"AccentPurple": "#8250df",
173+
"AccentCyan": "#0550ae",
174+
"AccentGreen": "#1a7f37",
175+
"AccentYellow": "#fa8c16",
176+
"AccentRed": "#d1242f",
177+
"AccentYellowDim": "#9a6700",
178+
"AccentRedDim": "#a40e26",
179+
"DiffAdded": "#dafbe1",
180+
"DiffRemoved": "#ffebe9",
181+
"Comment": "#6e7781"
182+
}
183+
}
184+
}
185+
```
186+
187+
也可在 `colors` 基础上用 `overrides` 微调个别 token:
188+
189+
```json
190+
{
191+
"theme": {
192+
"preset": "custom",
193+
"colors": { "Background": "#1a1a2e", "Foreground": "#e0e0e0", "..." : "..." },
194+
"overrides": {
195+
"agent": { "streaming": "#ffcc00" }
196+
}
197+
}
198+
}
199+
```
200+
201+
高级用法:通过 `base` 基于其他预设,用 `overrides` 微调:
202+
203+
```json
204+
{
205+
"theme": {
206+
"preset": "custom",
207+
"base": "dark",
166208
"overrides": {
167-
"primary": "#ff6600",
168-
"success": "greenBright"
209+
"brand": { "primary": "#ff6600" }
169210
}
170211
}
171212
}
172213
```
173214

174-
**可用的颜色 Token**
175-
176-
| Token | 说明 | 默认值 |
177-
| ------------ | -------------------------------------------- | ---------- |
178-
| `primary` | 品牌色:Logo、用户消息、选中项、标题 | `#229ac3` |
179-
| `secondary` | 辅助品牌色:边框、渐变 | `#229ac3e6`|
180-
| `success` | 成功:工具执行成功、低风险操作 | `#1a7f37` |
181-
| `error` | 错误:工具执行失败、高风险操作 | `#d1242f` |
182-
| `warning` | 警告:进行中状态、中风险操作 | `#fa8c16` |
183-
| `info` | 信息:技能、图片附件 | `#0969da` |
184-
| `text` | 主文字颜色 | `#3D4149` |
185-
| `textDim` | 次要文字:暗化提示、引用块 | `#646A71` |
186-
| `textBright` | 亮色文字:强调提示 | `#1F2329` |
187-
| `code` | 代码块/内联代码 | `#787f8a` |
188-
| `border` | 边框 | `#999` |
189-
| `gradients` | Logo 渐变色数组 | `["#229ac3", "#8250df"]` |
215+
**可用的颜色 Token 分组**
216+
217+
| 分组 | 说明 | Token |
218+
| ---- | ---- | ----- |
219+
| `text` | 文字层级 | `primary``secondary``muted``disabled``inverse` |
220+
| `border` | 边框层级 | `default``subtle``active``focus` |
221+
| `surface` | 表面色 | `default``elevated``muted``code``panel``quote``selection` |
222+
| `brand` | 品牌色 | `primary``secondary``accent` |
223+
| `status` | 状态色 | `success``warning``danger``info` |
224+
| `risk` | 风险色 | `low``medium``high``critical` |
225+
| `typography` | 排版色 | `h1`-`h6``paragraph``strong``emphasis``delete` |
226+
| `link` | 链接色 | `default``visited``hover` |
227+
| `inlineCode` | 行内代码 | `foreground``background``border` |
228+
| `codeBlock` | 代码块 | `foreground``background``border``title``lineNumber``highlight` |
229+
| `syntax` | 语法高亮 | `keyword``string``function``variable``property``type``number``operator``punctuation``comment``regexp``constant` |
230+
| `blockquote` | 引用块 | `foreground``border` |
231+
| `list` | 列表 | `bullet``ordered``marker` |
232+
| `task` | 任务列表 | `checked``unchecked` |
233+
| `table` | 表格 | `border``headerForeground``headerBackground``cellForeground` |
234+
| `hr` | 分割线 | `foreground` |
235+
| `admonition` | 提示框 | `note``tip``warning``important``caution` |
236+
| `diff` | Diff | `added``removed``modified``addedBackground``removedBackground``modifiedBackground` |
237+
| `agent` | Agent 状态 | `thinking``reasoning``toolCall``toolResult``streaming``completed` |
238+
| `approval` | 审批 | `allow``deny``review` |
239+
| `gradients` | 渐变 | `banner``logo``thinking`(每个是颜色数组) |
190240

191241
颜色值支持以下格式:
192242
- Hex 格式:`"#ff6600"``"#ff6600cc"`(带透明度)

docs/configuration_en.md

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,43 +149,93 @@ Available preset themes:
149149
| `dark` | Dark theme (optimized for dark backgrounds) |
150150
| `github-light` | GitHub Light style theme |
151151
| `github-dark` | GitHub Dark style theme |
152-
| `gitlab-light` | GitLab Light style theme |
153-
| `gitlab-dark` | GitLab Dark style theme |
154152
| `monokai` | Monokai-style theme |
155153
| `dracula` | Dracula-style theme |
154+
| `ansi-light` | ANSI light theme (standard 16 colors) |
155+
| `ansi-dark` | ANSI dark theme (standard 16 colors) |
156156

157157
**Custom Theme Colors**
158158

159-
Use `preset: "custom"` with `overrides` to customize specific colors:
159+
The recommended way is to use `colors` — a simplified palette of 16 base colors. The system automatically derives the full theme:
160160

161161
```json
162162
{
163163
"theme": {
164164
"preset": "custom",
165+
"colors": {
166+
"Background": "#ffffff",
167+
"Foreground": "#1F2328",
168+
"Gray": "#8b949e",
169+
"LightBlue": "#0969da",
170+
"AccentBlue": "#ff6600",
171+
"AccentPurple": "#8250df",
172+
"AccentCyan": "#0550ae",
173+
"AccentGreen": "#1a7f37",
174+
"AccentYellow": "#fa8c16",
175+
"AccentRed": "#d1242f",
176+
"AccentYellowDim": "#9a6700",
177+
"AccentRedDim": "#a40e26",
178+
"DiffAdded": "#dafbe1",
179+
"DiffRemoved": "#ffebe9",
180+
"Comment": "#6e7781"
181+
}
182+
}
183+
}
184+
```
185+
186+
You can also combine `colors` with `overrides` to fine-tune specific tokens:
187+
188+
```json
189+
{
190+
"theme": {
191+
"preset": "custom",
192+
"colors": { "Background": "#1a1a2e", "Foreground": "#e0e0e0", "..." : "..." },
193+
"overrides": {
194+
"agent": { "streaming": "#ffcc00" }
195+
}
196+
}
197+
}
198+
```
199+
200+
Advanced: use `base` to inherit from another preset, with `overrides` to tweak:
201+
202+
```json
203+
{
204+
"theme": {
205+
"preset": "custom",
206+
"base": "dark",
165207
"overrides": {
166-
"primary": "#ff6600",
167-
"success": "greenBright"
208+
"brand": { "primary": "#ff6600" }
168209
}
169210
}
170211
}
171212
```
172213

173-
**Available Color Tokens**
174-
175-
| Token | Description | Default Value |
176-
| ------------ | ------------------------------------------------ | ------------- |
177-
| `primary` | Brand color: logo, user messages, selected items, headings | `#229ac3` |
178-
| `secondary` | Auxiliary brand color: borders, gradients | `#229ac3e6` |
179-
| `success` | Success: tool execution success, low-risk ops | `#1a7f37` |
180-
| `error` | Error: tool execution failure, high-risk ops | `#d1242f` |
181-
| `warning` | Warning: in-progress state, mid-risk ops | `#fa8c16` |
182-
| `info` | Info: skills, image attachments | `#0969da` |
183-
| `text` | Main text color | `#3D4149` |
184-
| `textDim` | Secondary text: dimmed hints, quote blocks | `#646A71` |
185-
| `textBright` | Bright text: emphasized hints | `#1F2329` |
186-
| `code` | Code blocks / inline code | `#787f8a` |
187-
| `border` | Borders | `#999` |
188-
| `gradients` | Logo gradient color array | `["#229ac3", "#8250df"]` |
214+
**Available Color Token Groups**
215+
216+
| Group | Description | Tokens |
217+
| ----- | ----------- | ------ |
218+
| `text` | Text hierarchy | `primary`, `secondary`, `muted`, `disabled`, `inverse` |
219+
| `border` | Border hierarchy | `default`, `subtle`, `active`, `focus` |
220+
| `surface` | Surface colors | `default`, `elevated`, `muted`, `code`, `panel`, `quote`, `selection` |
221+
| `brand` | Brand colors | `primary`, `secondary`, `accent` |
222+
| `status` | Status colors | `success`, `warning`, `danger`, `info` |
223+
| `risk` | Risk levels | `low`, `medium`, `high`, `critical` |
224+
| `typography` | Typography colors | `h1`-`h6`, `paragraph`, `strong`, `emphasis`, `delete` |
225+
| `link` | Link colors | `default`, `visited`, `hover` |
226+
| `inlineCode` | Inline code | `foreground`, `background`, `border` |
227+
| `codeBlock` | Code blocks | `foreground`, `background`, `border`, `title`, `lineNumber`, `highlight` |
228+
| `syntax` | Syntax highlighting | `keyword`, `string`, `function`, `variable`, `property`, `type`, `number`, `operator`, `punctuation`, `comment`, `regexp`, `constant` |
229+
| `blockquote` | Blockquotes | `foreground`, `border` |
230+
| `list` | Lists | `bullet`, `ordered`, `marker` |
231+
| `task` | Task lists | `checked`, `unchecked` |
232+
| `table` | Tables | `border`, `headerForeground`, `headerBackground`, `cellForeground` |
233+
| `hr` | Horizontal rules | `foreground` |
234+
| `admonition` | Admonitions | `note`, `tip`, `warning`, `important`, `caution` |
235+
| `diff` | Diff | `added`, `removed`, `modified`, `addedBackground`, `removedBackground`, `modifiedBackground` |
236+
| `agent` | Agent states | `thinking`, `reasoning`, `toolCall`, `toolResult`, `streaming`, `completed` |
237+
| `approval` | Approval | `allow`, `deny`, `review` |
238+
| `gradients` | Gradients | `banner`, `logo`, `thinking` (each is a color array) |
189239

190240
Color values support the following formats:
191241
- Hex format: `"#ff6600"`, `"#ff6600cc"` (with alpha)

src/common/update-check.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export async function promptForPendingUpdate(packageInfo: PackageInfo): Promise<
5959
if (ok) {
6060
writeUpdateState({ ...state, pending: null });
6161
process.stdout.write(
62-
`\n${chalk.hex(LIGHT_THEME.error)("Deep Code has been updated. Please restart the CLI to use the new version.")}\n\n`
62+
`\n${chalk.hex(LIGHT_THEME.status.danger)("Deep Code has been updated. Please restart the CLI to use the new version.")}\n\n`
6363
);
6464
}
6565
return { installed: ok };

src/tests/permission-prompt.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ import { getScopeRiskColor } from "../ui/views/PermissionPrompt";
44
import { LIGHT_THEME } from "../ui/theme";
55

66
test("getScopeRiskColor maps permission scopes by risk", () => {
7-
assert.equal(getScopeRiskColor("read-in-cwd"), LIGHT_THEME.success);
8-
assert.equal(getScopeRiskColor("query-git-log"), LIGHT_THEME.success);
7+
assert.equal(getScopeRiskColor("read-in-cwd"), LIGHT_THEME.risk.low);
8+
assert.equal(getScopeRiskColor("query-git-log"), LIGHT_THEME.risk.low);
99

10-
assert.equal(getScopeRiskColor("read-out-cwd"), LIGHT_THEME.warning);
11-
assert.equal(getScopeRiskColor("write-in-cwd"), LIGHT_THEME.warning);
12-
assert.equal(getScopeRiskColor("network"), LIGHT_THEME.warning);
13-
assert.equal(getScopeRiskColor("mcp"), LIGHT_THEME.warning);
10+
assert.equal(getScopeRiskColor("read-out-cwd"), LIGHT_THEME.risk.medium);
11+
assert.equal(getScopeRiskColor("write-in-cwd"), LIGHT_THEME.risk.medium);
12+
assert.equal(getScopeRiskColor("network"), LIGHT_THEME.risk.medium);
13+
assert.equal(getScopeRiskColor("mcp"), LIGHT_THEME.risk.medium);
1414

15-
assert.equal(getScopeRiskColor("write-out-cwd"), LIGHT_THEME.error);
16-
assert.equal(getScopeRiskColor("delete-in-cwd"), LIGHT_THEME.error);
17-
assert.equal(getScopeRiskColor("delete-out-cwd"), LIGHT_THEME.error);
18-
assert.equal(getScopeRiskColor("mutate-git-log"), LIGHT_THEME.error);
19-
assert.equal(getScopeRiskColor("unknown"), LIGHT_THEME.error);
15+
assert.equal(getScopeRiskColor("write-out-cwd"), LIGHT_THEME.risk.high);
16+
assert.equal(getScopeRiskColor("delete-in-cwd"), LIGHT_THEME.risk.high);
17+
assert.equal(getScopeRiskColor("delete-out-cwd"), LIGHT_THEME.risk.high);
18+
assert.equal(getScopeRiskColor("mutate-git-log"), LIGHT_THEME.risk.high);
19+
assert.equal(getScopeRiskColor("unknown"), LIGHT_THEME.risk.critical);
2020
});

0 commit comments

Comments
 (0)