Skip to content

Commit 5c497b8

Browse files
committed
refactor(theme): 调整权限风险色为语义色
- 在 PermissionPrompt 组件中将风险色映射由 riskLow/riskMedium/riskHigh 改为 success/warning/error - 修改 theme presets,移除旧的风险等级颜色配置 - 更新测试中风险颜色的断言,改为使用新的语义色断言 - 统一 README 文档中主题色 token,替换 accent/risk 相关为 primary/secondary 和语义色 - 修改 DropdownMenu 组件中选中项标签加粗表现 - 调整 MessageView 组件中 Thinking 状态颜色为 theme.text - 精简 theme 类型定义,去除旧风险色属性,改用语义色属性 - 清理测试文件中与旧风险色相关的代码和注释内容
1 parent fdd9909 commit 5c497b8

10 files changed

Lines changed: 50 additions & 97 deletions

File tree

README-en.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Override only the colors you want to change; the rest keep their defaults:
158158
"theme": {
159159
"preset": "custom",
160160
"overrides": {
161-
"accent": "#ff6600",
161+
"primary": "#ff6600",
162162
"success": "greenBright"
163163
}
164164
}
@@ -174,21 +174,16 @@ Provide a complete tokens object, merged on top of the default theme:
174174
"theme": {
175175
"preset": "custom",
176176
"tokens": {
177-
"accent": "#229ac3",
178-
"accentAlpha": "#229ac3e6",
179-
"active": "cyanBright",
177+
"primary": "#229ac3",
178+
"secondary": "#229ac3e6",
180179
"success": "green",
181180
"error": "red",
182181
"warning": "yellow",
183182
"info": "magenta",
184-
"riskLow": "#22c55e",
185-
"riskMedium": "#f59e0b",
186-
"riskHigh": "#ef4444",
187183
"text": "white",
188184
"textDim": "gray",
189185
"code": "cyan",
190186
"border": "gray",
191-
"thinking": "gray",
192187
"gradients": ["#229ac3e6", "#229ac3e6"]
193188
}
194189
}
@@ -201,10 +196,9 @@ Available token descriptions:
201196

202197
| Token | Used For |
203198
|-------|----------|
204-
| `accent`, `accentAlpha`, `active` | Logo, user messages, selected items, etc. |
205-
| `success`, `error`, `warning`, `info` | Tool statuses, permission prompts, skill loading; `warning` also colors list bullets |
206-
| `riskLow`, `riskMedium`, `riskHigh` | Permission confirmation panel |
207-
| `text`, `textDim`, `code`, `border`, `thinking` | Body text, secondary text/blockquotes, code, borders, thinking status |
199+
| `primary`, `secondary` | Logo, user messages, selected items, etc. |
200+
| `success`, `error`, `warning`, `info` | Tool statuses, permission prompts (risk levels), skill loading; `warning` also colors list bullets |
201+
| `text`, `textDim`, `code`, `border` | Body text, secondary text/blockquotes, code, borders |
208202
| `gradients` | Logo and exit panel gradient colors |
209203

210204
Color values support hex (`"#ff6600"`), hex with alpha (`"#229ac3e6"`), and chalk named colors (`"cyanBright"`, `"green"`).

README-zh_CN.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
158158
"theme": {
159159
"preset": "custom",
160160
"overrides": {
161-
"accent": "#ff6600",
161+
"primary": "#ff6600",
162162
"success": "greenBright"
163163
}
164164
}
@@ -174,21 +174,16 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
174174
"theme": {
175175
"preset": "custom",
176176
"tokens": {
177-
"accent": "#229ac3",
178-
"accentAlpha": "#229ac3e6",
179-
"active": "cyanBright",
177+
"primary": "#229ac3",
178+
"secondary": "#229ac3e6",
180179
"success": "green",
181180
"error": "red",
182181
"warning": "yellow",
183182
"info": "magenta",
184-
"riskLow": "#22c55e",
185-
"riskMedium": "#f59e0b",
186-
"riskHigh": "#ef4444",
187183
"text": "white",
188184
"textDim": "gray",
189185
"code": "cyan",
190186
"border": "gray",
191-
"thinking": "gray",
192187
"gradients": ["#229ac3e6", "#229ac3e6"]
193188
}
194189
}
@@ -201,10 +196,9 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
201196

202197
| Token | 用途 |
203198
|---------------------------------------------|----------------------------------|
204-
| `accent``accentAlpha``active` | Logo、用户消息、选中项等 |
205-
| `success``error``warning``info` | 工具状态、权限提示、技能加载,`warning` 也是列表标记色 |
206-
| `riskLow``riskMedium``riskHigh` | 权限确认面板 |
207-
| `text``textDim``code``border``thinking` | 正文、副文/引用块、代码、边框、思考状态 |
199+
| `primary``secondary` | Logo、用户消息、选中项等 |
200+
| `success``error``warning``info` | 工具状态、权限提示(风险等级)、技能加载,`warning` 也是列表标记色 |
201+
| `text``textDim``code``border` | 正文、副文/引用块、代码、边框 |
208202
| `gradients` | Logo 与退出面板的渐变色数组 |
209203

210204
颜色值支持 hex(`"#ff6600"`)、hex 含透明度(`"#229ac3e6"`)、chalk 命名色(`"cyanBright"``"green"`)。

README.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
158158
"theme": {
159159
"preset": "custom",
160160
"overrides": {
161-
"accent": "#ff6600",
161+
"primary": "#ff6600",
162162
"success": "greenBright"
163163
}
164164
}
@@ -174,21 +174,16 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
174174
"theme": {
175175
"preset": "custom",
176176
"tokens": {
177-
"accent": "#229ac3",
178-
"accentAlpha": "#229ac3e6",
179-
"active": "cyanBright",
177+
"primary": "#229ac3",
178+
"secondary": "#229ac3e6",
180179
"success": "green",
181180
"error": "red",
182181
"warning": "yellow",
183182
"info": "magenta",
184-
"riskLow": "#22c55e",
185-
"riskMedium": "#f59e0b",
186-
"riskHigh": "#ef4444",
187183
"text": "white",
188184
"textDim": "gray",
189185
"code": "cyan",
190186
"border": "gray",
191-
"thinking": "gray",
192187
"gradients": ["#229ac3e6", "#229ac3e6"]
193188
}
194189
}
@@ -201,10 +196,9 @@ Deep Code CLI 内置一套默认主题(`DEFAULT_THEME`),无需配置即可
201196

202197
| Token | 用途 |
203198
|---------------------------------------------|----------------------------------|
204-
| `accent``accentAlpha``active` | Logo、用户消息、选中项等 |
205-
| `success``error``warning``info` | 工具状态、权限提示、技能加载,`warning` 也是列表标记色 |
206-
| `riskLow``riskMedium``riskHigh` | 权限确认面板 |
207-
| `text``textDim``code``border``thinking` | 正文、副文/引用块、代码、边框、思考状态 |
199+
| `primary``secondary` | Logo、用户消息、选中项等 |
200+
| `success``error``warning``info` | 工具状态、权限提示(风险等级)、技能加载,`warning` 也是列表标记色 |
201+
| `text``textDim``code``border` | 正文、副文/引用块、代码、边框 |
208202
| `gradients` | Logo 与退出面板的渐变色数组 |
209203

210204
颜色值支持 hex(`"#ff6600"`)、hex 含透明度(`"#229ac3e6"`)、chalk 命名色(`"cyanBright"``"green"`)。

src/tests/permission-prompt.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@ import assert from "node:assert/strict";
33
import { getScopeRiskColor } from "../ui/views/PermissionPrompt";
44

55
test("getScopeRiskColor maps permission scopes by risk", () => {
6-
assert.equal(getScopeRiskColor("read-in-cwd"), "#22c55e");
7-
assert.equal(getScopeRiskColor("query-git-log"), "#22c55e");
6+
assert.equal(getScopeRiskColor("read-in-cwd"), "#52c41a");
7+
assert.equal(getScopeRiskColor("query-git-log"), "#52c41a");
88

9-
assert.equal(getScopeRiskColor("read-out-cwd"), "#f59e0b");
10-
assert.equal(getScopeRiskColor("write-in-cwd"), "#f59e0b");
11-
assert.equal(getScopeRiskColor("network"), "#f59e0b");
12-
assert.equal(getScopeRiskColor("mcp"), "#f59e0b");
9+
assert.equal(getScopeRiskColor("read-out-cwd"), "#faad14");
10+
assert.equal(getScopeRiskColor("write-in-cwd"), "#faad14");
11+
assert.equal(getScopeRiskColor("network"), "#faad14");
12+
assert.equal(getScopeRiskColor("mcp"), "#faad14");
1313

14-
assert.equal(getScopeRiskColor("write-out-cwd"), "#ef4444");
15-
assert.equal(getScopeRiskColor("delete-in-cwd"), "#ef4444");
16-
assert.equal(getScopeRiskColor("delete-out-cwd"), "#ef4444");
17-
assert.equal(getScopeRiskColor("mutate-git-log"), "#ef4444");
18-
assert.equal(getScopeRiskColor("unknown"), "#ef4444");
14+
assert.equal(getScopeRiskColor("write-out-cwd"), "#ff4d4f");
15+
assert.equal(getScopeRiskColor("delete-in-cwd"), "#ff4d4f");
16+
assert.equal(getScopeRiskColor("delete-out-cwd"), "#ff4d4f");
17+
assert.equal(getScopeRiskColor("mutate-git-log"), "#ff4d4f");
18+
assert.equal(getScopeRiskColor("unknown"), "#ff4d4f");
1919
});

src/tests/theme.test.ts

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,10 @@ const REQUIRED_TOKEN_KEYS: Array<keyof ThemeTokens> = [
2626
"error",
2727
"warning",
2828
"info",
29-
"riskLow",
30-
"riskMedium",
31-
"riskHigh",
3229
"text",
3330
"textDim",
3431
"code",
3532
"border",
36-
"thinking",
3733
"gradients",
3834
];
3935

@@ -62,7 +58,6 @@ test("DEFAULT_THEME semantic colors match expected values", () => {
6258
assert.equal(DEFAULT_THEME.error, "#f5222d");
6359
assert.equal(DEFAULT_THEME.warning, "#fa8c16");
6460
assert.equal(DEFAULT_THEME.info, "#2f54eb");
65-
assert.equal(DEFAULT_THEME.thinking, "#ff4400");
6661
});
6762

6863
test("DEFAULT_THEME base colors match expected values", () => {
@@ -71,12 +66,6 @@ test("DEFAULT_THEME base colors match expected values", () => {
7166
assert.equal(DEFAULT_THEME.code, "#787f8a");
7267
});
7368

74-
test("DEFAULT_THEME risk colors match expected values", () => {
75-
assert.equal(DEFAULT_THEME.riskLow, "#22c55e");
76-
assert.equal(DEFAULT_THEME.riskMedium, "#f59e0b");
77-
assert.equal(DEFAULT_THEME.riskHigh, "#ef4444");
78-
});
79-
8069
test("PRESETS map contains default", () => {
8170
assert.ok("default" in PRESETS);
8271
assert.equal(Object.keys(PRESETS).length, 1);
@@ -136,14 +125,10 @@ test("resolveTheme full custom tokens with custom preset", () => {
136125
error: "blue",
137126
warning: "blue",
138127
info: "blue",
139-
riskLow: "#111111",
140-
riskMedium: "#222222",
141-
riskHigh: "#333333",
142128
text: "blue",
143129
textDim: "blue",
144130
code: "blue",
145131
border: "blue",
146-
thinking: "blue",
147132
gradients: ["#aaaaaa", "#bbbbbb"],
148133
};
149134
const result = resolveTheme({ preset: "custom", tokens: customTokens });
@@ -312,17 +297,17 @@ test("resolveSettingsSources uses default theme when preset is not custom", () =
312297
// getScopeRiskColor with theme parameter
313298
// ---------------------------------------------------------------------------
314299

315-
test("getScopeRiskColor returns dark theme defaults when no theme is passed", () => {
316-
assert.equal(getScopeRiskColor("read-in-cwd"), "#22c55e");
317-
assert.equal(getScopeRiskColor("write-in-cwd"), "#f59e0b");
318-
assert.equal(getScopeRiskColor("write-out-cwd"), "#ef4444");
300+
test("getScopeRiskColor returns default theme colors when no theme is passed", () => {
301+
assert.equal(getScopeRiskColor("read-in-cwd"), "#52c41a");
302+
assert.equal(getScopeRiskColor("write-in-cwd"), "#faad14");
303+
assert.equal(getScopeRiskColor("write-out-cwd"), "#ff4d4f");
319304
});
320305

321-
test("getScopeRiskColor uses theme risk colors when theme is provided", () => {
306+
test("getScopeRiskColor uses theme semantic colors when theme is provided", () => {
322307
const custom: Partial<ThemeTokens> = {
323-
riskLow: "#aaaaaa",
324-
riskMedium: "#bbbbbb",
325-
riskHigh: "#cccccc",
308+
success: "#aaaaaa",
309+
warning: "#bbbbbb",
310+
error: "#cccccc",
326311
};
327312
assert.equal(getScopeRiskColor("read-in-cwd", custom as ThemeTokens), "#aaaaaa");
328313
assert.equal(getScopeRiskColor("mcp", custom as ThemeTokens), "#bbbbbb");

src/ui/components/DropdownMenu/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ const DropdownMenu = React.memo(function DropdownMenu({
161161
<Box width={labelColumnWidth} flexShrink={0}>
162162
<Text color={isActive ? effectiveActiveColor : undefined} wrap="truncate-end">
163163
{isActive ? "> " : " "}
164-
{item.selected !== undefined ? (item.selected ? "●" : "○") : null} <Text>{item.label}</Text>
164+
{item.selected !== undefined ? (item.selected ? "●" : "○") : null} <Text bold>{item.label}</Text>
165165
{item.statusIndicator ? (
166166
<Text color={item.statusIndicator.color}> {item.statusIndicator.symbol}</Text>
167167
) : null}

src/ui/components/MessageView/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ export function MessageView({ message, collapsed, width = 80 }: MessageViewProps
4646
if (collapsed !== false) {
4747
return (
4848
<Box marginLeft={1} marginBottom={1} marginY={0}>
49-
<StatusLine width={width} bulletColor={theme.thinking} name="Thinking" params={summary} />
49+
<StatusLine width={width} bulletColor={theme.text} name="Thinking" params={summary} />
5050
</Box>
5151
);
5252
}
5353
return (
5454
<Box marginLeft={1} flexDirection="column" marginBottom={1} marginY={0}>
55-
<StatusLine width={width} bulletColor={theme.thinking} name="Thinking" params={content ? "" : summary} />
55+
<StatusLine width={width} bulletColor={theme.text} name="Thinking" params={content ? "" : summary} />
5656
<Box flexDirection="column" marginLeft={2}>
5757
{content ? <Text dimColor>{renderMarkdown(content)}</Text> : null}
5858
</Box>

src/ui/theme/presets.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,10 @@ export const DEFAULT_THEME: ThemeTokens = {
88
error: "#f5222d",
99
warning: "#fa8c16",
1010
info: "#2f54eb",
11-
riskLow: "#22c55e",
12-
riskMedium: "#f59e0b",
13-
riskHigh: "#ef4444",
1411
text: "#3D4149",
1512
textDim: "#646A71",
1613
code: "#787f8a",
1714
border: "#ABADB1",
18-
thinking: "#ff4400",
1915
gradients: ["#229ac3", "#7c3aed"],
2016
};
2117

src/ui/theme/types.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,15 @@ export interface ThemeTokens {
77
secondary: string;
88

99
// ——— 语义颜色 ———
10-
/** 成功:工具执行成功、MCP ready */
10+
/** 成功:工具执行成功、MCP ready,低风险操作 */
1111
success: string;
12-
/** 失败/错误:工具执行失败、错误信息 */
12+
/** 失败/错误:工具执行失败、错误信息,高风险操作 */
1313
error: string;
14-
/** 警告/进行中:忙时 spinner、权限提示,及 Markdown 列表标记 */
14+
/** 警告/进行中:忙时 spinner、权限提示、中风险操作,及 Markdown 列表标记 */
1515
warning: string;
1616
/** 特殊指示:技能、图片附件 */
1717
info: string;
1818

19-
// ——— 风险等级色 ———
20-
/** 低风险操作 */
21-
riskLow: string;
22-
/** 中风险操作 */
23-
riskMedium: string;
24-
/** 高风险操作 */
25-
riskHigh: string;
26-
2719
// ——— 基础色 ———
2820
/** 主文字颜色 */
2921
text: string;
@@ -33,8 +25,6 @@ export interface ThemeTokens {
3325
code: string;
3426
/** 边框 */
3527
border: string;
36-
/** 思考状态 bullet 颜色 */
37-
thinking: string;
3828

3929
// ——— 渐变 ———
4030
/** Logo 渐变色数组 */

src/ui/views/PermissionPrompt.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { Box, Text } from "ink";
33
import { useTerminalInput } from "../hooks";
44
import type { AskPermissionRequest, AskPermissionScope, UserToolPermission } from "../../common/permissions";
55
import type { PermissionScope } from "../../settings";
6-
import { useTheme } from "../theme/ThemeContext";
7-
import type { ThemeTokens } from "../theme/types";
6+
import { useTheme } from "../theme";
7+
import type { ThemeTokens } from "../theme";
88

99
export type PermissionPromptResult = {
1010
permissions: UserToolPermission[];
@@ -232,24 +232,24 @@ function isAlwaysAllowedScope(scope: AskPermissionScope): scope is PermissionSco
232232
}
233233

234234
export function getScopeRiskColor(scope: AskPermissionScope, theme?: ThemeTokens): string {
235-
const t = theme ?? { riskLow: "#22c55e", riskMedium: "#f59e0b", riskHigh: "#ef4444" };
235+
const t = theme ?? ({ success: "#52c41a", warning: "#faad14", error: "#ff4d4f" } as ThemeTokens);
236236
switch (scope) {
237237
case "read-in-cwd":
238238
case "query-git-log":
239-
return t.riskLow;
239+
return t.success;
240240
case "read-out-cwd":
241241
case "write-in-cwd":
242242
case "network":
243243
case "mcp":
244-
return t.riskMedium;
244+
return t.warning;
245245
case "write-out-cwd":
246246
case "delete-in-cwd":
247247
case "delete-out-cwd":
248248
case "mutate-git-log":
249249
case "unknown":
250-
return t.riskHigh;
250+
return t.error;
251251
default:
252-
return t.riskHigh;
252+
return t.error;
253253
}
254254
}
255255

0 commit comments

Comments
 (0)