pi-one-ui 0.6.0 → 0.6.1
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/CHANGELOG.md +9 -1
- package/README.en.md +59 -43
- package/README.md +60 -45
- package/extensions/app/config/panel.ts +117 -0
- package/extensions/app/config/renderer.ts +4 -0
- package/extensions/app/panel.ts +15 -9
- package/extensions/features/effort-command.ts +79 -0
- package/extensions/layouts/context/index.ts +4 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.6.1] - 2026-09-06
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Built-in `/effort` command for selecting the thinking effort level (interactive picker, argument autocomplete, and model-clamping feedback), gated by `renderer.enableEffortCommand` (default `true`) and toggleable from the `/oneui` Features section. Replaces the need for a standalone local effort extension — remove any self-installed `/effort` extension to avoid duplicate command registration.
|
|
14
|
+
- The `/oneui` settings panel overlay placement is now configurable via the optional top-level `panel` key in `pi-one-ui.json` (`anchor`, `width`, `maxHeight`, `margin`), replacing the previously hardcoded `top-center`/`85%`/`90%` layout. Invalid values fall back to the defaults, and edits apply the next time the panel opens.
|
|
15
|
+
|
|
9
16
|
## [0.6.0] - 2026-09-05
|
|
10
17
|
|
|
11
18
|
### Removed
|
|
@@ -108,7 +115,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
108
115
|
|
|
109
116
|
- Reduced rendering lag when expanding settled tool groups by reusing cached child output.
|
|
110
117
|
|
|
111
|
-
[Unreleased]: https://github.com/kerolt/pi-one-ui/compare/v0.6.
|
|
118
|
+
[Unreleased]: https://github.com/kerolt/pi-one-ui/compare/v0.6.1...HEAD
|
|
119
|
+
[0.6.1]: https://github.com/kerolt/pi-one-ui/compare/v0.6.0...v0.6.1
|
|
112
120
|
[0.6.0]: https://github.com/kerolt/pi-one-ui/compare/v0.5.1...v0.6.0
|
|
113
121
|
[0.5.1]: https://github.com/kerolt/pi-one-ui/compare/v0.5.0...v0.5.1
|
|
114
122
|
[0.5.0]: https://github.com/kerolt/pi-one-ui/compare/v0.4.0...v0.5.0
|
package/README.en.md
CHANGED
|
@@ -6,43 +6,44 @@
|
|
|
6
6
|
|
|
7
7
|
[简体中文](./README.md) | English
|
|
8
8
|
|
|
9
|
-
`pi-one-ui` is a unified TUI extension package for [Pi](https://pi.dev)
|
|
9
|
+
`pi-one-ui` is a unified TUI extension package for [Pi](https://pi.dev), designed to deliver a clean, beautiful, and efficient terminal experience. It originated as a source-level combination of:
|
|
10
10
|
|
|
11
|
-
- the terminal shell capabilities of [pi-zentui](https://github.com/lmilojevicc/pi-zentui)
|
|
11
|
+
- the terminal shell and layout capabilities of [pi-zentui](https://github.com/lmilojevicc/pi-zentui)
|
|
12
12
|
- the conversation rendering and productivity features of [pi-cc-extensions](https://github.com/minuque/pi-cc-extensions)
|
|
13
13
|
|
|
14
|
-
The result is a single installable and configurable Pi package that continues to evolve through
|
|
14
|
+
The result is a single installable and configurable Pi package that continues to evolve through architectural refactoring, strict boundary ownership, and ongoing optimization.
|
|
15
15
|
|
|
16
16
|
## Features
|
|
17
17
|
|
|
18
18
|
### Unified interface layout
|
|
19
19
|
|
|
20
|
-
`pi-one-ui` organizes the Pi interface into
|
|
20
|
+
`pi-one-ui` organizes the Pi interface into a clean hierarchy:
|
|
21
21
|
|
|
22
22
|
```text
|
|
23
23
|
Header → Context → WorkingLine → Editor → Footer
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
- **Header**:
|
|
27
|
-
- **Context**:
|
|
28
|
-
- **WorkingLine**:
|
|
29
|
-
- **Editor**:
|
|
30
|
-
- **Footer**:
|
|
31
|
-
- **Overlay**:
|
|
26
|
+
- **Header**: Startup information, logo, and shortcut hints.
|
|
27
|
+
- **Context**: Conversation content area, including user messages, assistant messages, thinking blocks, tool calls, diffs, Markdown, and turn summaries.
|
|
28
|
+
- **WorkingLine**: Working state indicator, spinner, token/thought/elapsed statistics, live output throughput, and turn summaries.
|
|
29
|
+
- **Editor**: Input editor, completion menu, metadata display, and the Minimalist style (with effortless toggle to Pi native).
|
|
30
|
+
- **Footer**: Current directory, Git status, runtime info, token/cost tracking, and extension statuses.
|
|
31
|
+
- **Overlay**: Temporary views such as the settings panel and Context Inspector, managed centrally by OverlayManager.
|
|
32
32
|
|
|
33
33
|
### Built-in functionality
|
|
34
34
|
|
|
35
35
|
| Feature | Description | Entry point |
|
|
36
36
|
| ---------------------- | ------------------------------------------------------------------------------------------- | ----------------- |
|
|
37
|
-
| Unified settings panel |
|
|
38
|
-
| Context Inspector | Shows context usage and previews
|
|
39
|
-
| Session reference | Searches previous Pi sessions or
|
|
40
|
-
| Subagent autocomplete |
|
|
41
|
-
| Tool / Diff renderer |
|
|
42
|
-
| Subagent live renderer | Preserves
|
|
43
|
-
| Markdown enhancement | Adds Mermaid, admonitions, URL linking, and
|
|
44
|
-
| Built-in themes |
|
|
37
|
+
| Unified settings panel | Centrally manages settings for Header, Context, WorkingLine, Editor, Footer, and Features | `/oneui` |
|
|
38
|
+
| Context Inspector | Shows context usage and previews system prompt, memory, skills, tools, and message contents | `/context` |
|
|
39
|
+
| Session reference | Searches previous Pi sessions or subagents and injects their relevant context | `@` completion |
|
|
40
|
+
| Subagent autocomplete | Provides subagent name completion and delegation hints | `@` completion |
|
|
41
|
+
| Tool / Diff renderer | Unified rendering for tool executions, results, collapsible blocks, and Edit/Write diffs | Automatic |
|
|
42
|
+
| Subagent live renderer | Preserves subagents' dedicated progress cards without grouping them into generic tool calls | Automatic |
|
|
43
|
+
| Markdown enhancement | Adds Mermaid diagrams, admonitions, clickable URL linking, and rendering improvements | Automatic |
|
|
44
|
+
| Built-in themes | Includes CC Dark and CC Light themes | `/theme` |
|
|
45
45
|
| Compatibility aliases | Optionally provides common command aliases | `/clear`, `/exit` |
|
|
46
|
+
| Effort command | Interactively or directly switch the active model's thinking effort level | `/effort` |
|
|
46
47
|
|
|
47
48
|
## Quick start
|
|
48
49
|
|
|
@@ -77,13 +78,22 @@ Then open the unified settings panel:
|
|
|
77
78
|
|
|
78
79
|
## Configuration
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
### Configuration methods
|
|
82
|
+
|
|
83
|
+
`pi-one-ui` uses a single canonical v1 configuration file:
|
|
81
84
|
|
|
82
85
|
```text
|
|
83
86
|
~/.pi/agent/pi-one-ui.json
|
|
84
87
|
```
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
You can configure the extension in two ways:
|
|
90
|
+
|
|
91
|
+
1. **Interactive settings panel (recommended)**: Run `/oneui` in Pi to adjust common component toggles, styles, and border modes via a visual menu. Changes take effect immediately and are persisted automatically.
|
|
92
|
+
2. **Direct JSON editing**: Advanced users can edit the JSON configuration file directly for finer-grained control. After saving edits, run `/reload` in Pi to apply changes. When the file does not exist, safe runtime defaults are used in memory.
|
|
93
|
+
|
|
94
|
+
### Basic configuration example
|
|
95
|
+
|
|
96
|
+
Below is a typical v1 configuration structure:
|
|
87
97
|
|
|
88
98
|
```json
|
|
89
99
|
{
|
|
@@ -93,52 +103,58 @@ Using the `/oneui` settings panel is recommended. The panel uses a top-centered
|
|
|
93
103
|
"style": "on",
|
|
94
104
|
"borderColorMode": "static"
|
|
95
105
|
},
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"style": "framed"
|
|
106
|
+
"footer": {
|
|
107
|
+
"style": "starship"
|
|
99
108
|
},
|
|
100
109
|
"workingLine": {
|
|
101
110
|
"enabled": true
|
|
102
111
|
},
|
|
103
|
-
"
|
|
104
|
-
"
|
|
112
|
+
"userMessages": {
|
|
113
|
+
"enabled": true,
|
|
114
|
+
"style": "framed"
|
|
105
115
|
}
|
|
106
116
|
},
|
|
107
117
|
"renderer": {
|
|
108
118
|
"mode": "on",
|
|
109
119
|
"diffViewMode": "auto"
|
|
120
|
+
},
|
|
121
|
+
"panel": {
|
|
122
|
+
"anchor": "top-center",
|
|
123
|
+
"width": "85%",
|
|
124
|
+
"maxHeight": "90%",
|
|
125
|
+
"margin": { "top": 6, "right": 1, "bottom": 1, "left": 1 }
|
|
110
126
|
}
|
|
111
127
|
}
|
|
112
128
|
```
|
|
113
129
|
|
|
114
|
-
|
|
130
|
+
### Advanced configuration & documentation guide
|
|
115
131
|
|
|
116
|
-
|
|
132
|
+
To keep the configuration section clean and focused, in-depth options, template variables, and color references are organized in dedicated documentation:
|
|
117
133
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
`
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
- **Component options & layout customization**: see [Editor & Footer Configuration Guide (docs/configuration.md)](./docs/configuration.md)
|
|
135
|
+
- **Editor**: Configure `style` (`on` for Minimalist decoration / `off` for Pi native), `borderColorMode` (`static` or `adaptive` to thinking effort), `modelLabel`, and granular Minimalist displays (directory path format, session name, timer, cost, Git status, etc.).
|
|
136
|
+
- **Footer**: Starship-style layout powered by format templates (`$cwd`, `$git_branch`, `$tokens`, `$cost`, etc.), individual `segments` toggles, customizable separators, and context-usage indicators (gauge or text).
|
|
137
|
+
- **WorkingLine**: Built-in live output throughput tracking (appends e.g. `⚡12 tok/s` when a model response runs for at least 500ms, reset per turn).
|
|
138
|
+
- **Settings panel (`/oneui`) customization**: the optional top-level `panel` section controls the overlay placement and size (all fields default to the values shown in the example above).
|
|
139
|
+
- `anchor`: one of `center`, `top-left`, `top-right`, `bottom-left`, `bottom-right`, `top-center`, `bottom-center`, `left-center`, `right-center`.
|
|
140
|
+
- `width` / `maxHeight`: absolute column/row counts, or percentage strings like `"85%"`.
|
|
141
|
+
- `margin`: distance from the terminal edges — either a single number for all sides, or an object with per-edge `top`/`right`/`bottom`/`left` values.
|
|
142
|
+
- Saved changes apply the next time `/oneui` opens; no `/reload` needed.
|
|
143
|
+
- **Color system & theme customization**: see [Editor Colors Reference (docs/editor-colors.md)](./docs/editor-colors.md)
|
|
144
|
+
- All colors resolve through unified theme semantics. Configured `colors.*` values resolve as theme tokens (adapting automatically across themes), while ANSI names map to semantic tokens (e.g. `red` to `error`). Fixed terminal colors can be specified using hex codes, 256-color indexes, or `fg:`/`bg:` prefixes.
|
|
145
|
+
- Full support for adaptive thinking-effort border colors (from Low to Max) and labels.
|
|
146
|
+
- **Migration from legacy versions**: Field cleanups from 0.5.x/0.6.0 (such as merging `opencode` into `minimalist`, or removing `colorSource`) are covered in [docs/configuration.md: Changes and Migration](./docs/configuration.md#6-变更与迁移).
|
|
129
147
|
|
|
130
148
|
## Upstream origins and project evolution
|
|
131
149
|
|
|
132
|
-
`pi-one-ui` originally
|
|
150
|
+
`pi-one-ui` was originally built upon source code from two open-source projects. We express our sincere appreciation to both upstream projects and their contributors:
|
|
133
151
|
|
|
134
152
|
| Upstream project | Capabilities incorporated into `pi-one-ui` | Reference baseline |
|
|
135
153
|
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------- |
|
|
136
|
-
| [pi-zentui](https://github.com/lmilojevicc/pi-zentui) | Starship-style Footer,
|
|
154
|
+
| [pi-zentui](https://github.com/lmilojevicc/pi-zentui) | Starship-style Footer, Editor layouts, and shell interaction capabilities | v0.21.0, commit `5341b38` |
|
|
137
155
|
| [pi-cc-extensions](https://github.com/minuque/pi-cc-extensions) | Claude Code-style Context renderer, Tool/Diff rendering, Context Inspector, and references | v0.8.67, commit `dba37e5` |
|
|
138
156
|
|
|
139
|
-
Production code lives in `extensions/`.
|
|
140
|
-
|
|
141
|
-
The upstream projects provided the original foundation. Continued development focuses on turning these capabilities into one coherent product with clear seams and sustainable maintenance.
|
|
157
|
+
Production code lives in `extensions/`. `pi-one-ui` has unified the composition entry point, configuration storage, lifecycle management, layout ownership, overlay orchestration, and input routing. The project now evolves independently and no longer tracks upstream changes directly.
|
|
142
158
|
|
|
143
159
|
See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed module boundaries, event flow, and ownership conventions.
|
|
144
160
|
|
package/README.md
CHANGED
|
@@ -6,43 +6,44 @@
|
|
|
6
6
|
|
|
7
7
|
简体中文 | [English](./README.en.md)
|
|
8
8
|
|
|
9
|
-
`pi-one-ui`
|
|
9
|
+
`pi-one-ui` 是面向 [Pi](https://pi.dev) 的统一 TUI 扩展包,旨在打造简洁、美观且高效的终端交互界面。项目最初通过源码级融合,将:
|
|
10
10
|
|
|
11
|
-
- [pi-zentui](https://github.com/lmilojevicc/pi-zentui)
|
|
11
|
+
- [pi-zentui](https://github.com/lmilojevicc/pi-zentui) 的终端外壳与布局能力
|
|
12
12
|
- [pi-cc-extensions](https://github.com/minuque/pi-cc-extensions) 的对话内容渲染及生产力功能
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
整合为开箱即用、统一可配置的单一扩展包,并在此基础上持续进行模块重构、职责收敛和体验优化。
|
|
15
15
|
|
|
16
16
|
## 特性
|
|
17
17
|
|
|
18
18
|
### 统一的界面布局
|
|
19
19
|
|
|
20
|
-
`pi-one-ui` 将 Pi
|
|
20
|
+
`pi-one-ui` 将 Pi 的交互界面划分为以下布局层级:
|
|
21
21
|
|
|
22
22
|
```text
|
|
23
23
|
Header → Context → WorkingLine → Editor → Footer
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
- **Header**:启动信息、Logo 和快捷键提示。
|
|
27
|
-
- **Context**:对话内容区,包含用户消息、Assistant 消息、Thinking
|
|
28
|
-
- **WorkingLine
|
|
29
|
-
- **Editor
|
|
30
|
-
- **Footer
|
|
31
|
-
- **Overlay**:设置面板、Context Inspector
|
|
27
|
+
- **Context**:对话内容区,包含用户消息、Assistant 消息、Thinking 思考过程、Tool 执行、Diff 对比、Markdown 及回合摘要。
|
|
28
|
+
- **WorkingLine**:工作状态指示、Spinner、Token/思考时长统计、实时吞吐速率及回合摘要。
|
|
29
|
+
- **Editor**:输入编辑器、补全建议、元数据展示及 Minimalist 极简样式(支持一键切换 Pi 原生)。
|
|
30
|
+
- **Footer**:工作目录、Git 状态、运行时信息、Token/费用统计及扩展状态等。
|
|
31
|
+
- **Overlay**:设置面板、Context Inspector 等临时浮层,统一由 OverlayManager 调度管理。
|
|
32
32
|
|
|
33
33
|
### 内置功能
|
|
34
34
|
|
|
35
35
|
| 功能 | 说明 | 入口 |
|
|
36
36
|
| --------------------- | ---------------------------------------------------------------------- | ----------------- |
|
|
37
|
-
| 统一设置面板 |
|
|
38
|
-
| Context Inspector | 查看上下文占用,并预览 System prompt、Memory、Skills、Tools
|
|
39
|
-
| Session reference |
|
|
40
|
-
| Subagent autocomplete | 提供
|
|
41
|
-
| Tool / Diff renderer |
|
|
42
|
-
| Subagent live renderer | 保留
|
|
43
|
-
| Markdown enhancement | 支持 Mermaid
|
|
44
|
-
| Built-in themes |
|
|
37
|
+
| 统一设置面板 | 集中管理 Header、Context、WorkingLine、Editor、Footer 等组件及功能设置 | `/oneui` |
|
|
38
|
+
| Context Inspector | 查看上下文占用,并预览 System prompt、Memory、Skills、Tools 及消息内容 | `/context` |
|
|
39
|
+
| Session reference | 搜索并引用注入历史 Pi 会话或 Subagent 的有效上下文 | `@` 补全 |
|
|
40
|
+
| Subagent autocomplete | 提供 Subagent 名称补全与委派提示 | `@` 补全 |
|
|
41
|
+
| Tool / Diff renderer | 工具调用、执行结果、折叠内容与 Edit/Write Diff 的统一美化渲染 | 自动生效 |
|
|
42
|
+
| Subagent live renderer | 保留 subagents 专用进度卡片,避免混入通用工具分组 | 自动生效 |
|
|
43
|
+
| Markdown enhancement | 支持 Mermaid 图表、提示框与 URL 链接化等增强渲染 | 自动生效 |
|
|
44
|
+
| Built-in themes | 内置 CC Dark 和 CC Light 主题 | `/theme` |
|
|
45
45
|
| Compatibility aliases | 可选提供常用命令别名 | `/clear`、`/exit` |
|
|
46
|
+
| Effort command | 交互式或直接切换当前模型的 Thinking 思考档位 | `/effort` |
|
|
46
47
|
|
|
47
48
|
## 快速开始
|
|
48
49
|
|
|
@@ -77,14 +78,22 @@ pi install git:github.com/kerolt/pi-one-ui
|
|
|
77
78
|
|
|
78
79
|
## 配置
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
### 配置方式
|
|
82
|
+
|
|
83
|
+
`pi-one-ui` 统一使用 Canonical v1 格式的配置文件:
|
|
81
84
|
|
|
82
85
|
```text
|
|
83
86
|
~/.pi/agent/pi-one-ui.json
|
|
84
87
|
```
|
|
85
88
|
|
|
89
|
+
提供两种配置途径:
|
|
90
|
+
|
|
91
|
+
1. **交互式设置面板(推荐)**:在 Pi 会话中运行 `/oneui`,即可在可视化面板中即时调整常用组件开关、样式和边框模式。修改即刻生效并自动持久化。
|
|
92
|
+
2. **手动编辑配置文件**:高级用户可直接编辑 JSON 配置文件以启用更多细粒度选项。修改保存后,在 Pi 中执行 `/reload` 即可生效。文件不存在时将直接使用内置默认值。
|
|
93
|
+
|
|
94
|
+
### 基础配置示例
|
|
86
95
|
|
|
87
|
-
|
|
96
|
+
以下为一个典型的 v1 配置文件结构:
|
|
88
97
|
|
|
89
98
|
```json
|
|
90
99
|
{
|
|
@@ -94,54 +103,60 @@ pi install git:github.com/kerolt/pi-one-ui
|
|
|
94
103
|
"style": "on",
|
|
95
104
|
"borderColorMode": "static"
|
|
96
105
|
},
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
"style": "framed"
|
|
106
|
+
"footer": {
|
|
107
|
+
"style": "starship"
|
|
100
108
|
},
|
|
101
109
|
"workingLine": {
|
|
102
110
|
"enabled": true
|
|
103
111
|
},
|
|
104
|
-
"
|
|
105
|
-
"
|
|
112
|
+
"userMessages": {
|
|
113
|
+
"enabled": true,
|
|
114
|
+
"style": "framed"
|
|
106
115
|
}
|
|
107
116
|
},
|
|
108
117
|
"renderer": {
|
|
109
118
|
"mode": "on",
|
|
110
119
|
"diffViewMode": "auto"
|
|
120
|
+
},
|
|
121
|
+
"panel": {
|
|
122
|
+
"anchor": "top-center",
|
|
123
|
+
"width": "85%",
|
|
124
|
+
"maxHeight": "90%",
|
|
125
|
+
"margin": { "top": 6, "right": 1, "bottom": 1, "left": 1 }
|
|
111
126
|
}
|
|
112
127
|
}
|
|
113
128
|
```
|
|
114
129
|
|
|
115
|
-
|
|
130
|
+
### 深度配置与文档指引
|
|
116
131
|
|
|
117
|
-
|
|
132
|
+
各项组件开关、模板变量与颜色字段的完整规范拆分收录于独立文档中,便于按需查阅:
|
|
118
133
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
- **组件开关与排版定制**:详见 [Editor 与 Footer 配置指南 (docs/configuration.md)](./docs/configuration.md)
|
|
135
|
+
- **Editor**:支持 `style`(`on` 极简装饰 / `off` 原生)、`borderColorMode`(固定色 / 思考档位自适应)、`modelLabel` 及 Minimalist 装饰细节(目录层级、会话名、耗时、费用、Git 状态等)。
|
|
136
|
+
- **Footer**:支持 Starship 风格排版,提供丰富的模板变量(`$cwd`、`$git_branch`、`$tokens`、`$cost` 等),支持通过 `format` 自定义或通过 `segments` 控制各段开关,并可自由配置上下文占用率的展示形式(gauge / text)。
|
|
137
|
+
- **WorkingLine**:内置实时输出速率检测(单次响应持续 >=500ms 自动追加如 `⚡12 tok/s`,按回合独立重置)。
|
|
138
|
+
- **设置面板(`/oneui`)定制**:通过顶层 `panel` 字段控制浮层位置与尺寸,全部字段可省略(缺省值见上文示例)。
|
|
139
|
+
- `anchor`:锚点,支持 `center`、`top-left`、`top-right`、`bottom-left`、`bottom-right`、`top-center`、`bottom-center`、`left-center`、`right-center`。
|
|
140
|
+
- `width` / `maxHeight`:列数 / 行数,或 `"85%"` 形式的百分比字符串。
|
|
141
|
+
- `margin`:距终端边缘的外边距,可以是四边统一数字,也可以是按 `top`/`right`/`bottom`/`left` 分别配置的对象。
|
|
142
|
+
- 修改保存后下次打开 `/oneui` 即生效,无需 `/reload`。
|
|
143
|
+
- **颜色体系与主题定制**:详见 [Editor 颜色配置说明 (docs/editor-colors.md)](./docs/editor-colors.md)
|
|
144
|
+
- 所有颜色统一按 Theme 语义解释,优先解析为当前主题语义 Token(随主题自动切换),ANSI 色名自动映射为语义色(如 `red` 对应 `error`);如需固定色彩,可直接指定 Hex、256 色索引或 `fg:`/`bg:` 前缀。
|
|
145
|
+
- 支持完整的 Thinking 思考档位(Low 至 Max)自适应边框与标签分级配色。
|
|
146
|
+
- **历史版本迁移**:旧版升级带来的字段收敛(如 `opencode` 样式统一合并入 `minimalist`、`colorSource` 双模式移除等)参见 [docs/configuration.md 变更与迁移节](./docs/configuration.md#6-变更与迁移)。
|
|
130
147
|
|
|
131
148
|
## 上游来源与项目演进
|
|
132
149
|
|
|
133
|
-
`pi-one-ui`
|
|
150
|
+
`pi-one-ui` 最初以两个开源项目的源码为基础进行整合。由衷感谢两个上游项目及其贡献者的出色工作:
|
|
134
151
|
|
|
135
|
-
| 上游项目 | 融入 `pi-one-ui` 的主要能力 | 参照
|
|
152
|
+
| 上游项目 | 融入 `pi-one-ui` 的主要能力 | 参照 Baseline |
|
|
136
153
|
| --------------------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------- |
|
|
137
|
-
| [pi-zentui](https://github.com/lmilojevicc/pi-zentui) | Starship 风格 Footer、
|
|
138
|
-
| [pi-cc-extensions](https://github.com/minuque/pi-cc-extensions) | Claude Code 风格 Context
|
|
139
|
-
|
|
140
|
-
融合后的生产代码位于 `extensions/`。项目已经在原始实现之上统一入口、配置存储、生命周期、Layout ownership、Overlay 和输入路由,并会继续独立演进;当前实现不再等同于任一上游项目,也不会自动跟随上游同步。
|
|
154
|
+
| [pi-zentui](https://github.com/lmilojevicc/pi-zentui) | Starship 风格 Footer、Editor 基础布局与 Shell 交互能力 | v0.21.0,commit `5341b38` |
|
|
155
|
+
| [pi-cc-extensions](https://github.com/minuque/pi-cc-extensions) | Claude Code 风格 Context 渲染器、Tool/Diff 视图、Context Inspector 与会话引用 | v0.8.67,commit `dba37e5` |
|
|
141
156
|
|
|
142
|
-
|
|
157
|
+
融合后的生产代码位于 `extensions/`。`pi-one-ui` 在原始实现之上完成了入口统一、配置存储规范化、生命周期治理、Layout Ownership 收敛、Overlay 统一调度与输入路由解耦,并持续独立演进。当前实现已完全独立于上游,不依赖也不自动同步上游分支。
|
|
143
158
|
|
|
144
|
-
|
|
159
|
+
更详细的模块边界、事件流与 Ownership 约定参见 [ARCHITECTURE.md](./ARCHITECTURE.md)。
|
|
145
160
|
|
|
146
161
|
## 本地开发
|
|
147
162
|
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
OverlayAnchor,
|
|
3
|
+
OverlayMargin,
|
|
4
|
+
SizeValue,
|
|
5
|
+
} from "@earendil-works/pi-tui";
|
|
6
|
+
import { configStore } from "./store.ts";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Overlay placement for the /oneui settings panel. Mirrors the Pi
|
|
10
|
+
* `OverlayOptions` subset the panel supports; persisted under the
|
|
11
|
+
* top-level `panel` key in `pi-one-ui.json`.
|
|
12
|
+
*/
|
|
13
|
+
export type PanelOverlayConfig = {
|
|
14
|
+
anchor: OverlayAnchor;
|
|
15
|
+
width: SizeValue;
|
|
16
|
+
maxHeight: SizeValue;
|
|
17
|
+
margin: OverlayMargin | number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/** Defaults preserve the historically hardcoded /oneui panel placement. */
|
|
21
|
+
export const DEFAULT_PANEL_OVERLAY: PanelOverlayConfig = {
|
|
22
|
+
anchor: "top-center",
|
|
23
|
+
width: "85%",
|
|
24
|
+
maxHeight: "90%",
|
|
25
|
+
margin: { top: 6, right: 1, bottom: 1, left: 1 },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const PANEL_ANCHORS: readonly OverlayAnchor[] = [
|
|
29
|
+
"center",
|
|
30
|
+
"top-left",
|
|
31
|
+
"top-right",
|
|
32
|
+
"bottom-left",
|
|
33
|
+
"bottom-right",
|
|
34
|
+
"top-center",
|
|
35
|
+
"bottom-center",
|
|
36
|
+
"left-center",
|
|
37
|
+
"right-center",
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
41
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function parseAnchor(value: unknown): OverlayAnchor {
|
|
45
|
+
return PANEL_ANCHORS.some((anchor) => anchor === value)
|
|
46
|
+
? (value as OverlayAnchor)
|
|
47
|
+
: DEFAULT_PANEL_OVERLAY.anchor;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Accepts a positive column/row count or a "N%" string within 0..100. */
|
|
51
|
+
function parseSizeValue(value: unknown, fallback: SizeValue): SizeValue {
|
|
52
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
53
|
+
return Math.floor(value);
|
|
54
|
+
}
|
|
55
|
+
if (typeof value === "string") {
|
|
56
|
+
const match = /^(\d+(?:\.\d+)?)%$/.exec(value.trim());
|
|
57
|
+
if (match) {
|
|
58
|
+
const percent = Number(match[1]);
|
|
59
|
+
if (percent > 0 && percent <= 100) {
|
|
60
|
+
return value.trim() as SizeValue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return fallback;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function parseMarginEdge(value: unknown): number | undefined {
|
|
68
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0
|
|
69
|
+
? value
|
|
70
|
+
: undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Accepts one non-negative integer for all edges or a per-edge object. */
|
|
74
|
+
function parseMargin(value: unknown): OverlayMargin | number {
|
|
75
|
+
const fallback = DEFAULT_PANEL_OVERLAY.margin;
|
|
76
|
+
if (typeof value === "number") {
|
|
77
|
+
return parseMarginEdge(value) ?? fallback;
|
|
78
|
+
}
|
|
79
|
+
if (!isRecord(value)) {
|
|
80
|
+
return fallback;
|
|
81
|
+
}
|
|
82
|
+
const defaults = isRecord(fallback) ? (fallback as OverlayMargin) : {};
|
|
83
|
+
const margin: OverlayMargin = {};
|
|
84
|
+
for (const edge of ["top", "right", "bottom", "left"] as const) {
|
|
85
|
+
margin[edge] = parseMarginEdge(value[edge]) ?? defaults[edge];
|
|
86
|
+
}
|
|
87
|
+
return margin;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Normalizes the raw `panel` config section, replacing invalid fields with
|
|
92
|
+
* defaults so a broken entry never blocks the /oneui panel from opening.
|
|
93
|
+
*/
|
|
94
|
+
export function normalizePanelOverlay(input: unknown): PanelOverlayConfig {
|
|
95
|
+
const source = isRecord(input) ? input : {};
|
|
96
|
+
return {
|
|
97
|
+
anchor: parseAnchor(source.anchor),
|
|
98
|
+
width: parseSizeValue(source.width, DEFAULT_PANEL_OVERLAY.width),
|
|
99
|
+
maxHeight: parseSizeValue(
|
|
100
|
+
source.maxHeight,
|
|
101
|
+
DEFAULT_PANEL_OVERLAY.maxHeight,
|
|
102
|
+
),
|
|
103
|
+
margin: parseMargin(source.margin),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Loads the panel overlay placement from the shared store. Read fresh on
|
|
109
|
+
* every /oneui open so JSON edits apply without `/reload`.
|
|
110
|
+
*/
|
|
111
|
+
export function loadPanelOverlayConfig(): PanelOverlayConfig {
|
|
112
|
+
try {
|
|
113
|
+
return normalizePanelOverlay(configStore.read().panel);
|
|
114
|
+
} catch {
|
|
115
|
+
return normalizePanelOverlay(undefined);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -62,6 +62,7 @@ export type Config = {
|
|
|
62
62
|
enableContextCommand: boolean;
|
|
63
63
|
enableAgentSummary: boolean;
|
|
64
64
|
enableAliases: boolean;
|
|
65
|
+
enableEffortCommand: boolean;
|
|
65
66
|
};
|
|
66
67
|
|
|
67
68
|
function rendererConfigFrom(record: ConfigRecord): ConfigRecord {
|
|
@@ -166,6 +167,7 @@ export const DEFAULT_CONFIG: Config = {
|
|
|
166
167
|
enableContextCommand: true,
|
|
167
168
|
enableAgentSummary: true,
|
|
168
169
|
enableAliases: true,
|
|
170
|
+
enableEffortCommand: true,
|
|
169
171
|
};
|
|
170
172
|
|
|
171
173
|
function pickEnum<T extends string>(
|
|
@@ -296,6 +298,7 @@ export function normalizeConfig(input: unknown): Config {
|
|
|
296
298
|
enableContextCommand: source.enableContextCommand !== false,
|
|
297
299
|
enableAgentSummary: source.enableAgentSummary !== false,
|
|
298
300
|
enableAliases: source.enableAliases !== false,
|
|
301
|
+
enableEffortCommand: source.enableEffortCommand !== false,
|
|
299
302
|
};
|
|
300
303
|
}
|
|
301
304
|
|
|
@@ -350,6 +353,7 @@ export function formatConfigStatus(source: Config = config): string {
|
|
|
350
353
|
`context=${source.enableContextCommand ? "on" : "off"}`,
|
|
351
354
|
`agentSummary=${source.enableAgentSummary ? "on" : "off"}`,
|
|
352
355
|
`aliases=${source.enableAliases ? "on" : "off"}`,
|
|
356
|
+
`effort=${source.enableEffortCommand ? "on" : "off"}`,
|
|
353
357
|
].join(" · ");
|
|
354
358
|
}
|
|
355
359
|
|
package/extensions/app/panel.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
renderEditorSettingsPreview,
|
|
14
14
|
renderUserMessageSettingsPreview,
|
|
15
15
|
} from "./commands/settings-previews.ts";
|
|
16
|
+
import { loadPanelOverlayConfig } from "./config/panel.ts";
|
|
16
17
|
import {
|
|
17
18
|
type CompactStyleMode,
|
|
18
19
|
type Config as ContextConfig,
|
|
@@ -303,6 +304,13 @@ function featureItems(config: ContextConfig): SettingItem[] {
|
|
|
303
304
|
currentValue: onOff(config.enableAliases),
|
|
304
305
|
values: ["on", "off"],
|
|
305
306
|
},
|
|
307
|
+
{
|
|
308
|
+
id: "enableEffortCommand",
|
|
309
|
+
label: "Effort command",
|
|
310
|
+
description: "Register the /effort thinking-level command.",
|
|
311
|
+
currentValue: onOff(config.enableEffortCommand),
|
|
312
|
+
values: ["on", "off"],
|
|
313
|
+
},
|
|
306
314
|
];
|
|
307
315
|
}
|
|
308
316
|
|
|
@@ -547,6 +555,7 @@ function updateSetting(
|
|
|
547
555
|
id === "enableContextCommand" ||
|
|
548
556
|
id === "enableAgentSummary" ||
|
|
549
557
|
id === "enableAliases" ||
|
|
558
|
+
id === "enableEffortCommand" ||
|
|
550
559
|
id === "showStartupHeader"
|
|
551
560
|
) {
|
|
552
561
|
const patch = { [id]: isOn(value) } as Partial<ContextConfig>;
|
|
@@ -598,6 +607,8 @@ export async function showOneUiPanel(
|
|
|
598
607
|
|
|
599
608
|
unifiedPanelOpen = true;
|
|
600
609
|
try {
|
|
610
|
+
// Read fresh on every open so pi-one-ui.json edits apply without /reload.
|
|
611
|
+
const panelOverlay = loadPanelOverlayConfig();
|
|
601
612
|
let panelHandle: { focus: () => void } | undefined;
|
|
602
613
|
await overlayManager.run(() =>
|
|
603
614
|
ctx.ui.custom(
|
|
@@ -680,15 +691,10 @@ export async function showOneUiPanel(
|
|
|
680
691
|
{
|
|
681
692
|
overlay: true,
|
|
682
693
|
overlayOptions: {
|
|
683
|
-
anchor:
|
|
684
|
-
width:
|
|
685
|
-
maxHeight:
|
|
686
|
-
margin:
|
|
687
|
-
top: 6,
|
|
688
|
-
right: 1,
|
|
689
|
-
bottom: 1,
|
|
690
|
-
left: 1,
|
|
691
|
-
},
|
|
694
|
+
anchor: panelOverlay.anchor,
|
|
695
|
+
width: panelOverlay.width,
|
|
696
|
+
maxHeight: panelOverlay.maxHeight,
|
|
697
|
+
margin: panelOverlay.margin,
|
|
692
698
|
},
|
|
693
699
|
onHandle: (handle: { focus: () => void }) => {
|
|
694
700
|
panelHandle = handle;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Effort Command Feature
|
|
3
|
+
*
|
|
4
|
+
* Registers the /effort command for selecting the active thinking level:
|
|
5
|
+
* /effort → interactive level picker
|
|
6
|
+
* /effort high → apply a level directly (with autocomplete)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
10
|
+
|
|
11
|
+
const EFFORT_LEVELS = [
|
|
12
|
+
"off",
|
|
13
|
+
"minimal",
|
|
14
|
+
"low",
|
|
15
|
+
"medium",
|
|
16
|
+
"high",
|
|
17
|
+
"xhigh",
|
|
18
|
+
"max",
|
|
19
|
+
] as const;
|
|
20
|
+
type EffortLevel = (typeof EFFORT_LEVELS)[number];
|
|
21
|
+
|
|
22
|
+
/** Reports whether a command argument is a supported thinking-effort level. */
|
|
23
|
+
function isEffortLevel(value: string): value is EffortLevel {
|
|
24
|
+
return EFFORT_LEVELS.some((level) => level === value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Registers the /effort command for selecting the active thinking level. */
|
|
28
|
+
export default function effortCommand(pi: ExtensionAPI): void {
|
|
29
|
+
pi.registerCommand("effort", {
|
|
30
|
+
description:
|
|
31
|
+
"Set thinking effort: off, minimal, low, medium, high, xhigh, or max",
|
|
32
|
+
getArgumentCompletions: (prefix) => {
|
|
33
|
+
const normalizedPrefix = prefix.toLowerCase();
|
|
34
|
+
const matches = EFFORT_LEVELS.filter((level) =>
|
|
35
|
+
level.startsWith(normalizedPrefix),
|
|
36
|
+
).map((level) => ({
|
|
37
|
+
value: level,
|
|
38
|
+
label: level,
|
|
39
|
+
}));
|
|
40
|
+
return matches.length > 0 ? matches : null;
|
|
41
|
+
},
|
|
42
|
+
handler: async (args, ctx) => {
|
|
43
|
+
let requested = args.trim().toLowerCase();
|
|
44
|
+
if (!requested) {
|
|
45
|
+
if (!ctx.hasUI) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const selected = await ctx.ui.select(
|
|
49
|
+
`Thinking effort (current: ${pi.getThinkingLevel()})`,
|
|
50
|
+
[...EFFORT_LEVELS],
|
|
51
|
+
);
|
|
52
|
+
if (!selected) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
requested = selected;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (!isEffortLevel(requested)) {
|
|
59
|
+
ctx.ui.notify(
|
|
60
|
+
`Unknown effort "${requested}". Expected: ${EFFORT_LEVELS.join(", ")}`,
|
|
61
|
+
"error",
|
|
62
|
+
);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
pi.setThinkingLevel(requested);
|
|
67
|
+
// The active model may clamp unsupported levels; surface the applied value.
|
|
68
|
+
const applied = pi.getThinkingLevel();
|
|
69
|
+
if (applied !== requested) {
|
|
70
|
+
ctx.ui.notify(
|
|
71
|
+
`Requested ${requested}; active model applied ${applied}`,
|
|
72
|
+
"warning",
|
|
73
|
+
);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
ctx.ui.notify(`Thinking effort: ${applied}`, "info");
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -16,6 +16,7 @@ import { type ConfigRecord, configStore } from "../../app/config/store.ts";
|
|
|
16
16
|
// shell
|
|
17
17
|
import piAliases from "../../features/aliases.ts";
|
|
18
18
|
import context from "../../features/context-inspector/index.ts";
|
|
19
|
+
import effortCommand from "../../features/effort-command.ts";
|
|
19
20
|
import { installFlushDockedBash } from "../../features/flush-docked-bash.ts";
|
|
20
21
|
import sessionReference from "../../features/session-reference/index.ts";
|
|
21
22
|
// feature
|
|
@@ -154,6 +155,9 @@ export default function (
|
|
|
154
155
|
): void {
|
|
155
156
|
// shell chrome
|
|
156
157
|
if (config.enableAliases) piAliases(pi);
|
|
158
|
+
if (config.enableEffortCommand) {
|
|
159
|
+
effortCommand(pi);
|
|
160
|
+
}
|
|
157
161
|
installFlushDockedBash();
|
|
158
162
|
// The thinking controller is queried directly by the context render stack.
|
|
159
163
|
markdownEnhance(pi);
|