pi-cc-extensions 0.9.9 → 0.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +49 -50
- package/README.md +7 -8
- package/extensions/config/config.ts +48 -8
- package/extensions/config/panel.ts +158 -30
- package/extensions/feature/compact-thinking.ts +19 -16
- package/extensions/feature/shell/footer-currency.ts +29 -0
- package/extensions/feature/shell/footer.ts +52 -7
- package/extensions/feature/shell/mcp-chip.ts +136 -0
- package/extensions/renderer/compact-mode.ts +78 -14
- package/extensions/renderer/default-mode.ts +51 -13
- package/extensions/renderer/mouse/interaction.ts +32 -21
- package/extensions/renderer/tool/codemode.ts +306 -0
- package/extensions/renderer/tool/diff/diff-header.ts +1 -1
- package/extensions/renderer/tool/diff/diff-highlight.ts +36 -0
- package/extensions/renderer/tool/diff/diff-presentation.ts +2 -2
- package/extensions/renderer/tool/diff/diff-write-render.ts +2 -2
- package/extensions/renderer/tool/diff/line-width-safety.ts +6 -5
- package/extensions/renderer/tool/grouping.ts +31 -6
- package/extensions/renderer/tool/message-display.ts +3 -3
- package/extensions/renderer/tool/names.ts +3 -0
- package/extensions/renderer/tool/result.ts +173 -36
- package/extensions/utils/ansi-text.ts +1 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -25,16 +25,16 @@ Run `/reload` after installation.
|
|
|
25
25
|
|
|
26
26
|
## Features
|
|
27
27
|
|
|
28
|
-
| Feature | Description
|
|
29
|
-
| --------------------------- |
|
|
30
|
-
| Claude Code UI | Tool summaries, expand/collapse, rich edit/write diffs, and `on` / `compact` / `off` modes
|
|
31
|
-
| Markdown enhancements | Mermaid diagrams, admonitions, URL linking, and more
|
|
32
|
-
| Fullscreen mode | Tool card/group expand and collapse on click, previews, hover highlight, and a back-to-bottom button
|
|
33
|
-
| Settings panel | `Style / Features / UI / Diff / Thinking / Footer` tabs
|
|
34
|
-
| Context inspection | Usage breakdown and previews for the system prompt, memory, skills, tools definition, and messages
|
|
35
|
-
| Session/Subagent references | Search and inject effective context from previous Sessions or existing SubAgents
|
|
28
|
+
| Feature | Description | Entry point |
|
|
29
|
+
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
|
|
30
|
+
| Claude Code UI | Tool summaries, expand/collapse, rich edit/write diffs, and `on` / `compact` / `off` modes | `/ccstyle` |
|
|
31
|
+
| Markdown enhancements | Mermaid diagrams, admonitions, URL linking, and more | Automatic |
|
|
32
|
+
| Fullscreen mode | Tool card/group expand and collapse on click, previews, hover highlight, and a back-to-bottom button | `TUIMODE=fullscreen` or `--tui-mode fullscreen` |
|
|
33
|
+
| Settings panel | `Style / Features / UI / Diff / Thinking / Footer` tabs | `/ccstyle` |
|
|
34
|
+
| Context inspection | Usage breakdown and previews for the system prompt, memory, skills, tools definition, and messages | `/context` |
|
|
35
|
+
| Session/Subagent references | Search and inject effective context from previous Sessions or existing SubAgents | `@` |
|
|
36
36
|
| Status bar | Shows model, context, cache, cost, and git; also works with `@narumitw/pi-usage` for live quota. Git/cache Nerd Font icons can be turned off | `/ccstyle` |
|
|
37
|
-
| Theme | Bundled CC Dark and CC Light themes
|
|
37
|
+
| Theme | Bundled CC Dark and CC Light themes | `/theme` |
|
|
38
38
|
|
|
39
39
|
Renderer snapshots for `on` / `compact` modes: [default](./docs/tool-render-examples-default.md) · [compact](./docs/tool-render-examples-compact.md)
|
|
40
40
|
|
|
@@ -45,51 +45,53 @@ Renderer snapshots for `on` / `compact` modes: [default](./docs/tool-render-exam
|
|
|
45
45
|
```jsonc
|
|
46
46
|
{
|
|
47
47
|
// style
|
|
48
|
-
"mode": "on",
|
|
49
|
-
"excludeRenderers": [],
|
|
48
|
+
"mode": "on", // on / compact / off
|
|
49
|
+
"excludeRenderers": [], // tools keeping the native renderer; Agent always keeps its dedicated renderer
|
|
50
50
|
|
|
51
51
|
// features
|
|
52
|
-
"enableSessionReference": true,
|
|
53
|
-
"enableSubagentAutocomplete": true,
|
|
54
|
-
"enableContextCommand": true,
|
|
55
|
-
"enableAgentSummary": true,
|
|
56
|
-
"enableWorkingMessage": true,
|
|
57
|
-
"enableAliases": true,
|
|
52
|
+
"enableSessionReference": true, // @ session references
|
|
53
|
+
"enableSubagentAutocomplete": true, // @subagent:[name] completion and delegation hints
|
|
54
|
+
"enableContextCommand": true, // /context usage check
|
|
55
|
+
"enableAgentSummary": true, // per-turn tool summary
|
|
56
|
+
"enableWorkingMessage": true, // Working... bottom token/elapsed
|
|
57
|
+
"enableAliases": true, // /clear, /exit aliases
|
|
58
58
|
|
|
59
59
|
// ui
|
|
60
|
-
"expandedInputMaxLines": 5,
|
|
61
|
-
"expandedOutputMaxLines": 10,
|
|
62
|
-
"expandedPreviewMaxLines": 40,
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
60
|
+
"expandedInputMaxLines": 5, // expanded tool Input lines; overflow shows a footer hint
|
|
61
|
+
"expandedOutputMaxLines": 10, // expanded tool Output lines; overflow shows a footer hint
|
|
62
|
+
"expandedPreviewMaxLines": 40, // max lines for expanded TaskList bodies (expanded diffs always show all)
|
|
63
|
+
"expandedCardBackground": "userMessageBg", // expanded card background slot: userMessageBg (same as user prompts) / toolPendingBg (neutral) etc.
|
|
64
|
+
"inputClip": 0, // tool summary path/command clip length; 0 = fit width
|
|
65
|
+
"showStartupHeader": true, // startup header (logo + tips) toggle
|
|
66
66
|
|
|
67
67
|
// diff
|
|
68
|
-
"diffViewMode": "auto",
|
|
69
|
-
"diffIndicatorMode": "bars",
|
|
70
|
-
"diffSplitMinWidth": 120,
|
|
71
|
-
"editDiffCollapsedLines": 24,
|
|
72
|
-
"writeDiffCollapsedLines": 0,
|
|
73
|
-
"diffWordWrap": true,
|
|
68
|
+
"diffViewMode": "auto", // layout: auto / split / unified
|
|
69
|
+
"diffIndicatorMode": "bars", // change indicators: bars / classic / none
|
|
70
|
+
"diffSplitMinWidth": 120, // min terminal width for side-by-side columns
|
|
71
|
+
"editDiffCollapsedLines": 24, // Edit collapse lines; beyond that shows the expand hint
|
|
72
|
+
"writeDiffCollapsedLines": 0, // write collapse lines; 0 = creation summary only
|
|
73
|
+
"diffWordWrap": true, // wrap long diff lines
|
|
74
74
|
|
|
75
75
|
// thinking
|
|
76
76
|
"useSummaryTitlesAsThinkingTitle": true, // use latest summary as thinking title
|
|
77
|
-
"previewLines": 3,
|
|
78
|
-
"animationIntervalMs": 90,
|
|
79
|
-
"dimThinkingText": false,
|
|
77
|
+
"previewLines": 3, // preview lines; 0 hides
|
|
78
|
+
"animationIntervalMs": 90, // title animation interval (ms)
|
|
79
|
+
"dimThinkingText": false, // dim thinking body text
|
|
80
80
|
|
|
81
81
|
// footer
|
|
82
|
-
"enableCustomFooter": true,
|
|
83
|
-
"
|
|
84
|
-
"
|
|
85
|
-
"
|
|
86
|
-
"
|
|
87
|
-
"
|
|
82
|
+
"enableCustomFooter": true, // custom status bar
|
|
83
|
+
"footerCurrency": "USD", // display currency for the footer cost
|
|
84
|
+
"footerCurrencyRate": null, // display units per 1 cost unit; null changes the symbol only
|
|
85
|
+
"footerNerdIcons": true, // Nerd Font glyphs for git/cache; false = plain text
|
|
86
|
+
"footerHiddenKeys": [], // hidden plugin chip keys
|
|
87
|
+
"footerLine1Keys": ["pi-usage"], // line1 plugin chip order; pi-usage is shown by default, data from @narumitw/pi-usage
|
|
88
|
+
"footerLine2Keys": [], // line2 plugin chip order (after cwd/git)
|
|
89
|
+
"footerLine3Keys": [], // line3 overflow slot; painted only when a chip is visible
|
|
88
90
|
}
|
|
89
91
|
```
|
|
90
92
|
|
|
91
93
|
> [!TIP]
|
|
92
|
-
> **Fullscreen**: click `click to show more` to expand tool cards, thinking, Skill, and compact summaries. An expanded diff always shows every line; when expanded Input/Output exceeds the line cap, the footer `… +N more lines
|
|
94
|
+
> **Fullscreen**: click `click to show more` to expand tool cards, thinking, Skill, and compact summaries. An expanded diff always shows every line; when expanded Input/Output exceeds the line cap, the footer `… +N more lines · click to show more` opens a full preview. Click to collapse (dragging inside the card selects text).
|
|
93
95
|
|
|
94
96
|
> [!NOTE]
|
|
95
97
|
> **Mermaid rendering**: set `markdown.mermaid` to `final` via `~/.pi/agent/settings.json` or the Mermaid diagrams option in `/settings`. Default `streaming` redraws per frame; `final` renders once at completion.
|
|
@@ -97,9 +99,9 @@ Renderer snapshots for `on` / `compact` modes: [default](./docs/tool-render-exam
|
|
|
97
99
|
## Local development
|
|
98
100
|
|
|
99
101
|
```bash
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
./test.sh # macOS/Linux; needs node and pi
|
|
103
|
+
./test.bat # Windows; runs test.sh through Git Bash
|
|
104
|
+
pi -e . # one run, does not edit settings.json
|
|
103
105
|
```
|
|
104
106
|
|
|
105
107
|
## Compatibility
|
|
@@ -108,14 +110,11 @@ npm run typecheck
|
|
|
108
110
|
|
|
109
111
|
## Recommended companions
|
|
110
112
|
|
|
111
|
-
| Extension
|
|
112
|
-
|
|
|
113
|
-
| `npm:@
|
|
114
|
-
| `npm
|
|
115
|
-
| `npm
|
|
116
|
-
| `npm:@ff-labs/pi-fff` | FFF-powered fuzzy file and content search (fffind / ffgrep) |
|
|
117
|
-
| `npm:pi-web-access` | Web search, URL fetching, GitHub cloning, PDF/video parsing |
|
|
118
|
-
| `npm:@narumitw/pi-usage` | Current-account usage for Codex / Copilot / OpenRouter |
|
|
113
|
+
| Extension | Purpose |
|
|
114
|
+
| ------------------------ | ----------------------------------------------------------- |
|
|
115
|
+
| `npm:@ff-labs/pi-fff` | FFF-powered fuzzy file and content search (fffind / ffgrep) |
|
|
116
|
+
| `npm:pi-web-access` | Web search, URL fetching, GitHub cloning, PDF/video parsing |
|
|
117
|
+
| `npm:@narumitw/pi-usage` | Current-account usage for Codex / Copilot / OpenRouter |
|
|
119
118
|
|
|
120
119
|
## Credits
|
|
121
120
|
|
package/README.md
CHANGED
|
@@ -60,9 +60,9 @@ pi install git:github.com/minuque/pi-cc-extensions
|
|
|
60
60
|
"expandedInputMaxLines": 5, // 展开工具卡 Input 可见行数,超出在末行显示展开提示
|
|
61
61
|
"expandedOutputMaxLines": 10, // 展开工具卡 Output 可见行数,超出在末行显示展开提示
|
|
62
62
|
"expandedPreviewMaxLines": 40, // 展开 TaskList 正文最大行数(展开 diff 始终全量)
|
|
63
|
+
"expandedCardBackground": "userMessageBg", // 展开卡背景槽位;userMessageBg 与用户消息同色,toolPendingBg 为中性灰
|
|
63
64
|
"inputClip": 0, // 工具摘要 path/command 折叠字符数;0 = 按可用宽度
|
|
64
65
|
"showStartupHeader": true, // 启动头(logo + tips)开关
|
|
65
|
-
"scrollStepLines": 3, // fullscreen 滚轮步进
|
|
66
66
|
|
|
67
67
|
// diff
|
|
68
68
|
"diffViewMode": "auto", // 布局:auto / split / unified
|
|
@@ -80,6 +80,8 @@ pi install git:github.com/minuque/pi-cc-extensions
|
|
|
80
80
|
|
|
81
81
|
// footer
|
|
82
82
|
"enableCustomFooter": true, // 自定义状态栏
|
|
83
|
+
"footerCurrency": "USD", // 底栏费用的显示币种
|
|
84
|
+
"footerCurrencyRate": null, // 1 单位费用换成多少显示币种;null 只换符号、不乘倍率
|
|
83
85
|
"footerNerdIcons": true, // git/缓存用 Nerd Font 图标;false 为纯文本
|
|
84
86
|
"footerHiddenKeys": [], // 隐藏的插件芯片 key
|
|
85
87
|
"footerLine1Keys": ["pi-usage"], // line1 插件芯片顺序;pi-usage 默认显示,数据来自 @narumitw/pi-usage
|
|
@@ -89,7 +91,7 @@ pi install git:github.com/minuque/pi-cc-extensions
|
|
|
89
91
|
```
|
|
90
92
|
|
|
91
93
|
> [!TIP]
|
|
92
|
-
> **全屏模式**:单击 `click to show more` 展开工具卡、思考、Skill 和 compact 摘要;工具卡展开态 diff 全量显示,Input/Output 超行时末行 `… +N more lines
|
|
94
|
+
> **全屏模式**:单击 `click to show more` 展开工具卡、思考、Skill 和 compact 摘要;工具卡展开态 diff 全量显示,Input/Output 超行时末行 `… +N more lines · click to show more` 打开全量预览,单击收起(卡内拖动为选中文本)。
|
|
93
95
|
|
|
94
96
|
> [!NOTE]
|
|
95
97
|
> **Mermaid 渲染**:建议把 `markdown.mermaid` 设为 `final`(`~/.pi/agent/settings.json` 或 `/settings` 面板的 Mermaid diagrams 选项)。默认 `streaming` 逐帧重绘,`final` 渲染最终版更稳定。
|
|
@@ -97,9 +99,9 @@ pi install git:github.com/minuque/pi-cc-extensions
|
|
|
97
99
|
## 本地开发
|
|
98
100
|
|
|
99
101
|
```bash
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
./test.sh # macOS/Linux,需要 node 和 pi
|
|
103
|
+
./test.bat # Windows,经 Git Bash 运行 test.sh
|
|
104
|
+
pi -e . # 只跑一次,不改 settings.json
|
|
103
105
|
```
|
|
104
106
|
|
|
105
107
|
## 兼容性
|
|
@@ -110,9 +112,6 @@ npm run typecheck
|
|
|
110
112
|
|
|
111
113
|
| 扩展 | 用途 |
|
|
112
114
|
| ---------------------------------------- | ------------------------------------------------ |
|
|
113
|
-
| `npm:@tintinweb/pi-subagents` | 并行 SubAgent、后台任务与工作树隔离 |
|
|
114
|
-
| `npm:@tintinweb/pi-tasks` | Claude Code 风格任务跟踪与协调 |
|
|
115
|
-
| `npm:pi-mcp-adapter` | 按需发现 MCP 工具,减少上下文占用 |
|
|
116
115
|
| `npm:@ff-labs/pi-fff` | 模糊文件与内容检索(fffind / ffgrep) |
|
|
117
116
|
| `npm:pi-web-access` | 网页搜索、URL 抓取、GitHub 克隆、PDF/视频解析 |
|
|
118
117
|
| `npm:@narumitw/pi-usage` | 查看当前账号用量(Codex / Copilot / OpenRouter) |
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ThemeBg } from "@earendil-works/pi-coding-agent";
|
|
1
2
|
import type { CompactThinkingConfig } from "../feature/compact-thinking.ts";
|
|
2
3
|
import {
|
|
3
4
|
DEFAULT_FOOTER_CHIP_LAYOUT,
|
|
@@ -18,7 +19,7 @@ export interface ToolDisplayConfig {
|
|
|
18
19
|
diffIndicatorMode: DiffIndicatorMode;
|
|
19
20
|
diffSplitMinWidth: number;
|
|
20
21
|
editDiffCollapsedLines: number;
|
|
21
|
-
/** Write-only collapsed body lines. 0 = `↳ created
|
|
22
|
+
/** Write-only collapsed body lines. 0 = `↳ created · click to show more`. */
|
|
22
23
|
writeDiffCollapsedLines: number;
|
|
23
24
|
diffWordWrap: boolean;
|
|
24
25
|
expandedPreviewMaxLines: number;
|
|
@@ -32,7 +33,7 @@ export const DEFAULT_TOOL_DISPLAY_CONFIG: ToolDisplayConfig = {
|
|
|
32
33
|
editDiffCollapsedLines: 24,
|
|
33
34
|
/**
|
|
34
35
|
* Write create/overwrite collapsed body.
|
|
35
|
-
* 0 = `↳ created
|
|
36
|
+
* 0 = `↳ created · click to show more` (stats stay on the title).
|
|
36
37
|
*/
|
|
37
38
|
writeDiffCollapsedLines: 0,
|
|
38
39
|
diffWordWrap: true,
|
|
@@ -53,6 +54,7 @@ export type Config = {
|
|
|
53
54
|
writeDiffCollapsedLines: number;
|
|
54
55
|
diffWordWrap: boolean;
|
|
55
56
|
expandedPreviewMaxLines: number;
|
|
57
|
+
expandedCardBackground: ThemeBg;
|
|
56
58
|
expandedInputMaxLines: number;
|
|
57
59
|
expandedOutputMaxLines: number;
|
|
58
60
|
inputClip: number;
|
|
@@ -61,7 +63,6 @@ export type Config = {
|
|
|
61
63
|
animationIntervalMs: number;
|
|
62
64
|
dimThinkingText: boolean;
|
|
63
65
|
showStartupHeader: boolean;
|
|
64
|
-
scrollStepLines: number;
|
|
65
66
|
enableSessionReference: boolean;
|
|
66
67
|
enableSubagentAutocomplete: boolean;
|
|
67
68
|
enableContextCommand: boolean;
|
|
@@ -69,6 +70,10 @@ export type Config = {
|
|
|
69
70
|
enableWorkingMessage: boolean;
|
|
70
71
|
enableAliases: boolean;
|
|
71
72
|
enableCustomFooter: boolean;
|
|
73
|
+
/** ISO 4217 显示币种。USD 时不换算。 */
|
|
74
|
+
footerCurrency: string;
|
|
75
|
+
/** 1 单位费用对应的显示币种数量。null 只换符号、不乘倍率。 */
|
|
76
|
+
footerCurrencyRate: number | null;
|
|
72
77
|
footerNerdIcons: boolean;
|
|
73
78
|
footerHiddenKeys: string[];
|
|
74
79
|
footerLine1Keys: string[];
|
|
@@ -88,6 +93,20 @@ export const DIFF_COLLAPSED_LINES_VALUES = ["12", "24", "36", "48", "80", "120"]
|
|
|
88
93
|
export const WRITE_DIFF_COLLAPSED_LINES_VALUES = ["0", "4", "8", "12", "24", "36"];
|
|
89
94
|
/** Presets for expanded body height — keep low options first so cycling stays TUI-friendly. */
|
|
90
95
|
export const EXPANDED_PREVIEW_MAX_LINES_VALUES = ["40", "60", "80", "120", "200", "500", "2000"];
|
|
96
|
+
/**
|
|
97
|
+
* 展开卡可用的主题背景槽位。theme.bg/getBgAnsi 只认这些 token,
|
|
98
|
+
* 别的名字会抛 Unknown theme color,所以按白名单校验;
|
|
99
|
+
* 面板顺序把 userMessageBg(默认)和 toolPendingBg(内置主题的中性灰)放最前。
|
|
100
|
+
*/
|
|
101
|
+
export const EXPANDED_CARD_BACKGROUND_SLOTS: readonly ThemeBg[] = [
|
|
102
|
+
"userMessageBg",
|
|
103
|
+
"toolPendingBg",
|
|
104
|
+
"customMessageBg",
|
|
105
|
+
"selectedBg",
|
|
106
|
+
"searchMatchBg",
|
|
107
|
+
"toolSuccessBg",
|
|
108
|
+
"toolErrorBg",
|
|
109
|
+
];
|
|
91
110
|
/** 展开工具卡 Input 可见行数预设。 */
|
|
92
111
|
export const EXPANDED_INPUT_MAX_LINES_VALUES = ["5", "10", "20", "40", "80"];
|
|
93
112
|
/** 展开工具卡 Output 可见行数预设。 */
|
|
@@ -96,8 +115,6 @@ export const EXPANDED_OUTPUT_MAX_LINES_VALUES = ["10", "20", "40", "80", "120"];
|
|
|
96
115
|
export const INPUT_CLIP_VALUES = ["0", "40", "60", "80", "100", "120", "160"];
|
|
97
116
|
export const THINKING_PREVIEW_LINES_VALUES = ["0", "1", "3", "5", "10"];
|
|
98
117
|
export const THINKING_ANIMATION_INTERVAL_VALUES = ["40", "60", "90", "120", "180"];
|
|
99
|
-
/** fullscreen 滚轮步进行数预设。 */
|
|
100
|
-
export const SCROLL_STEP_LINES_VALUES = ["1", "2", "3", "5", "10"];
|
|
101
118
|
/** Tools commonly toggled in excludeRenderers via the settings panel. */
|
|
102
119
|
export const EXCLUDE_RENDERER_CANDIDATES = [
|
|
103
120
|
"bash",
|
|
@@ -122,6 +139,8 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
122
139
|
writeDiffCollapsedLines: DEFAULT_TOOL_DISPLAY_CONFIG.writeDiffCollapsedLines,
|
|
123
140
|
diffWordWrap: DEFAULT_TOOL_DISPLAY_CONFIG.diffWordWrap,
|
|
124
141
|
expandedPreviewMaxLines: DEFAULT_TOOL_DISPLAY_CONFIG.expandedPreviewMaxLines,
|
|
142
|
+
/** 展开卡背景。userMessageBg 与用户消息同色(ccstyle 原约定)。 */
|
|
143
|
+
expandedCardBackground: "userMessageBg",
|
|
125
144
|
expandedInputMaxLines: 5,
|
|
126
145
|
expandedOutputMaxLines: 10,
|
|
127
146
|
inputClip: 0,
|
|
@@ -130,7 +149,6 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
130
149
|
animationIntervalMs: 90,
|
|
131
150
|
dimThinkingText: false,
|
|
132
151
|
showStartupHeader: true,
|
|
133
|
-
scrollStepLines: 3,
|
|
134
152
|
enableSessionReference: true,
|
|
135
153
|
enableSubagentAutocomplete: true,
|
|
136
154
|
enableContextCommand: true,
|
|
@@ -138,6 +156,8 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
138
156
|
enableWorkingMessage: true,
|
|
139
157
|
enableAliases: true,
|
|
140
158
|
enableCustomFooter: true,
|
|
159
|
+
footerCurrency: "USD",
|
|
160
|
+
footerCurrencyRate: null,
|
|
141
161
|
footerNerdIcons: true,
|
|
142
162
|
...DEFAULT_FOOTER_CHIP_LAYOUT,
|
|
143
163
|
};
|
|
@@ -165,6 +185,19 @@ export function pickPositiveNumber(value: unknown, fallback: number, min = 1): n
|
|
|
165
185
|
return Number.isFinite(n) ? Math.max(min, n) : fallback;
|
|
166
186
|
}
|
|
167
187
|
|
|
188
|
+
function normalizeCurrency(value: unknown): string {
|
|
189
|
+
return typeof value === "string" && /^[A-Za-z]{3}$/.test(value.trim())
|
|
190
|
+
? value.trim().toUpperCase()
|
|
191
|
+
: "USD";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** 缺失、空串、非正数都视为不换算。 */
|
|
195
|
+
function normalizeFooterCurrencyRate(value: unknown): number | null {
|
|
196
|
+
if (value === undefined || value === null || value === "") return null;
|
|
197
|
+
const n = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
|
|
198
|
+
return Number.isFinite(n) && n > 0 ? n : null;
|
|
199
|
+
}
|
|
200
|
+
|
|
168
201
|
export function normalizeConfig(input: unknown): Config {
|
|
169
202
|
const source = (input && typeof input === "object" ? input : {}) as Record<string, unknown>;
|
|
170
203
|
const mode = pickEnum(source.mode, ["on", "compact", "off"], DEFAULT_CONFIG.mode);
|
|
@@ -211,6 +244,11 @@ export function normalizeConfig(input: unknown): Config {
|
|
|
211
244
|
10,
|
|
212
245
|
50_000,
|
|
213
246
|
),
|
|
247
|
+
expandedCardBackground: pickEnum(
|
|
248
|
+
source.expandedCardBackground,
|
|
249
|
+
EXPANDED_CARD_BACKGROUND_SLOTS,
|
|
250
|
+
DEFAULT_CONFIG.expandedCardBackground,
|
|
251
|
+
),
|
|
214
252
|
expandedInputMaxLines: pickPositiveInt(
|
|
215
253
|
source.expandedInputMaxLines,
|
|
216
254
|
DEFAULT_CONFIG.expandedInputMaxLines,
|
|
@@ -237,7 +275,6 @@ export function normalizeConfig(input: unknown): Config {
|
|
|
237
275
|
),
|
|
238
276
|
dimThinkingText: source.dimThinkingText === true,
|
|
239
277
|
showStartupHeader: source.showStartupHeader !== false,
|
|
240
|
-
scrollStepLines: pickPositiveInt(source.scrollStepLines, DEFAULT_CONFIG.scrollStepLines, 1, 50),
|
|
241
278
|
enableSessionReference: source.enableSessionReference !== false,
|
|
242
279
|
enableSubagentAutocomplete: source.enableSubagentAutocomplete !== false,
|
|
243
280
|
enableContextCommand: source.enableContextCommand !== false,
|
|
@@ -245,6 +282,8 @@ export function normalizeConfig(input: unknown): Config {
|
|
|
245
282
|
enableWorkingMessage: source.enableWorkingMessage !== false,
|
|
246
283
|
enableAliases: source.enableAliases !== false,
|
|
247
284
|
enableCustomFooter: source.enableCustomFooter !== false,
|
|
285
|
+
footerCurrency: normalizeCurrency(source.footerCurrency),
|
|
286
|
+
footerCurrencyRate: normalizeFooterCurrencyRate(source.footerCurrencyRate),
|
|
248
287
|
footerNerdIcons: source.footerNerdIcons !== false,
|
|
249
288
|
...normalizeFooterChipLayout(source),
|
|
250
289
|
};
|
|
@@ -293,7 +332,6 @@ export function formatConfigStatus(source: Config = config): string {
|
|
|
293
332
|
`thinkingAnimation=${source.animationIntervalMs}ms`,
|
|
294
333
|
`thinkingDim=${source.dimThinkingText ? "on" : "off"}`,
|
|
295
334
|
`startupHeader=${source.showStartupHeader ? "on" : "off"}`,
|
|
296
|
-
`scrollStep=${source.scrollStepLines}`,
|
|
297
335
|
`sessionRef=${source.enableSessionReference ? "on" : "off"}`,
|
|
298
336
|
`subagentAuto=${source.enableSubagentAutocomplete ? "on" : "off"}`,
|
|
299
337
|
`context=${source.enableContextCommand ? "on" : "off"}`,
|
|
@@ -301,6 +339,8 @@ export function formatConfigStatus(source: Config = config): string {
|
|
|
301
339
|
`workingMsg=${source.enableWorkingMessage ? "on" : "off"}`,
|
|
302
340
|
`aliases=${source.enableAliases ? "on" : "off"}`,
|
|
303
341
|
`footer=${source.enableCustomFooter ? "on" : "off"}`,
|
|
342
|
+
`footerCurrency=${source.footerCurrency}`,
|
|
343
|
+
`footerRate=${source.footerCurrencyRate ?? "-"}`,
|
|
304
344
|
`footerIcons=${source.footerNerdIcons ? "nerd" : "plain"}`,
|
|
305
345
|
formatFooterChipSummary(source),
|
|
306
346
|
].join(" · ");
|