rinco-pi-hud 1.0.0 → 1.1.0
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.md +23 -19
- package/docs/CONTRIBUTING.md +21 -7
- package/docs/README.zh-CN.md +23 -19
- package/docs/footer.md +38 -33
- package/extensions/hud/commands/settings-controller.ts +74 -0
- package/extensions/hud/commands/settings.ts +35 -23
- package/extensions/hud/config/normalize.ts +19 -4
- package/extensions/hud/config/persist.ts +7 -3
- package/extensions/hud/config/schema.ts +16 -8
- package/extensions/hud/footer/groups.ts +104 -0
- package/extensions/hud/footer/index.ts +58 -60
- package/extensions/hud/footer/layout.ts +67 -10
- package/extensions/hud/footer/render-labels.ts +37 -16
- package/extensions/hud/index.ts +38 -295
- package/extensions/hud/segments/skill-activity.ts +1 -1
- package/extensions/hud/session/event-handlers.ts +174 -0
- package/extensions/hud/state/project-controller.ts +106 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,17 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
Rinco Pi HUD provides a rich, real-time status footer for Pi TUI sessions. It displays project state, Git metrics, runtime versions, session activity, model usage, token costs, and more — all in a
|
|
15
|
+
Rinco Pi HUD provides a rich, real-time status footer for Pi TUI sessions. It displays project state, Git metrics, runtime versions, session activity, model usage, token costs, and more — all in a responsive four-group or customizable single-line layout. Pi loads the TypeScript extension directly, so no build step is required (`tsconfig.json` sets `noEmit: true` and is used only for `npm run typecheck`).
|
|
16
16
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
|
-
- **Project state** — Working directory, Git branch, commit, tag, status, diff metrics, and runtime versions.
|
|
20
|
-
- **Session activity** — Model, provider, context usage, tokens, cache, session cost, turn count, and thinking level.
|
|
21
|
-
- **Tool and agent activity** —
|
|
19
|
+
- **Project state** — Working directory, Git branch, commit, tag, status, operation state, diff metrics, and runtime versions.
|
|
20
|
+
- **Session activity** — Model, provider, context usage, independently controlled input/output tokens, cache, session cost, turn count, and thinking level.
|
|
21
|
+
- **Tool and agent activity** — Independent controls for running tools, completed tool counts, active agents, idle state, skills, and MCP server status.
|
|
22
22
|
- **Model quota** — Automatic Codex weekly quota or Token Switch balance display by model provider.
|
|
23
23
|
- **Git awareness** — Branches, detached HEAD, tags, ahead/behind, stash, merge/rebase conflicts, and dirty state.
|
|
24
24
|
- **Runtime detection** — Node, Python, Go, Rust, Java, and 60+ other runtimes with package version parsing.
|
|
25
|
-
- **Configurable layout** —
|
|
25
|
+
- **Configurable layout** — Responsive Project, Session, Activity, and Usage groups by default, or fully customizable single-line templates.
|
|
26
|
+
- **Granular status controls** — Toggle Git operation state, tool runtime/counts, active/idle agents, and input/output tokens separately from `/zentui`.
|
|
26
27
|
- **Extension statuses** — Reads third-party extension statuses and places them by configurable position and color mode.
|
|
27
28
|
- **Safe fallback** — Graceful timeout and error handling; no stale data after session shutdown.
|
|
28
29
|
|
|
@@ -82,24 +83,24 @@ The HUD footer is enabled by default. Run `/zentui` to open the interactive sett
|
|
|
82
83
|
|
|
83
84
|
| Path | Purpose |
|
|
84
85
|
| --- | --- |
|
|
85
|
-
| [`extensions/hud/index.ts`](extensions/hud/index.ts) |
|
|
86
|
-
| [`extensions/hud/config/`](extensions/hud/config/config.ts) | Configuration model, normalization, and persistence |
|
|
87
|
-
| [`extensions/hud/footer/`](extensions/hud/footer/index.ts) | Footer rendering,
|
|
86
|
+
| [`extensions/hud/index.ts`](extensions/hud/index.ts) | Composition root for controllers, shared state, and UI installation |
|
|
87
|
+
| [`extensions/hud/config/`](extensions/hud/config/config.ts) | Configuration model, normalization, migration, and persistence |
|
|
88
|
+
| [`extensions/hud/footer/`](extensions/hud/footer/index.ts) | Footer rendering, semantic grouping, responsive layout, and template parsing |
|
|
88
89
|
| [`extensions/hud/segments/`](extensions/hud/segments/) | State collectors: Git, runtime, MCP, skills, projects, etc. |
|
|
89
90
|
| [`extensions/hud/telemetry/`](extensions/hud/telemetry/format.ts) | Usage formatting, token switch, and Codex subscription client |
|
|
90
|
-
| [`extensions/hud/session/`](extensions/hud/session/) |
|
|
91
|
-
| [`extensions/hud/state/`](extensions/hud/state/) | Aggregated state, telemetry, and project refresh |
|
|
92
|
-
| [`extensions/hud/commands/`](extensions/hud/commands/settings.ts) | `/zentui`
|
|
91
|
+
| [`extensions/hud/session/`](extensions/hud/session/) | Pi event registration, session lifecycle, and live context overlay |
|
|
92
|
+
| [`extensions/hud/state/`](extensions/hud/state/) | Aggregated state, telemetry reducer, and project refresh controller |
|
|
93
|
+
| [`extensions/hud/commands/`](extensions/hud/commands/settings.ts) | `/zentui` settings UI and configuration controller |
|
|
93
94
|
| [`extensions/hud/ui/`](extensions/hud/ui/) | Icons and terminal style utilities |
|
|
94
95
|
| [`docs/footer.md`](docs/footer.md) | Complete footer configuration reference |
|
|
95
96
|
| [`docs/CONTRIBUTING.md`](docs/CONTRIBUTING.md) | Local development, testing guidance, and pull request checklist |
|
|
96
|
-
| [`tests/`](tests/) | Vitest test suite (
|
|
97
|
+
| [`tests/`](tests/) | Vitest test suite (41 tests across 8 files) |
|
|
97
98
|
|
|
98
99
|
## Customization
|
|
99
100
|
|
|
100
101
|
### Layout
|
|
101
102
|
|
|
102
|
-
The default
|
|
103
|
+
The default layout groups Project, Session, Activity, and Usage information. Long groups wrap at complete segment boundaries with aligned continuation lines. Set `footerFormat` to a template string for a single-line layout:
|
|
103
104
|
|
|
104
105
|
```text
|
|
105
106
|
/zentui format "$cwd( $git_branch)$fill($context)( $tokens)( $cost)"
|
|
@@ -109,13 +110,16 @@ Template variables use `$name` or `${name}` syntax. See the [footer reference](d
|
|
|
109
110
|
|
|
110
111
|
### Segments
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
Open `/zentui`, then select **Built-in segments** to enable or disable individual statuses. Fine-grained controls include:
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
| Group | Independently controlled statuses |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| Project | Git status, Git operation state (`MERGING`, `REBASING`, etc.), commit, metrics, runtime, package, OS, and user |
|
|
118
|
+
| Session | Model, thinking level, turn count, and duration |
|
|
119
|
+
| Activity | Running tools, completed tool counts, active agents, `Agent idle`, skills, and MCP |
|
|
120
|
+
| Usage | Context, input tokens, output tokens, cache details/hit rate, cost, quota, and time |
|
|
121
|
+
|
|
122
|
+
Existing configs using the former aggregate `tokens`, `toolActivity`, or `agentActivity` switches are migrated automatically. The whole footer can still be controlled with `/zentui statusline enable|disable|toggle`.
|
|
119
123
|
|
|
120
124
|
### Extension statuses
|
|
121
125
|
|
package/docs/CONTRIBUTING.md
CHANGED
|
@@ -48,7 +48,9 @@ Tests live in `tests/`:
|
|
|
48
48
|
|
|
49
49
|
- `zentui-status.test.ts` — Config counts, MCP status parsing, and extension status helpers.
|
|
50
50
|
- `codex-usage.test.ts` — Codex payload normalization and model-specific quota formatting.
|
|
51
|
-
- `footer-layout.test.ts` —
|
|
51
|
+
- `footer-layout.test.ts` — Four-group categorized layout, segment wrapping, and narrow-width budget.
|
|
52
|
+
- `footer-groups.test.ts` — Semantic Project, Session, Activity, and Usage segment ordering.
|
|
53
|
+
- `footer-segment-controls.test.ts` — Independent status controls and legacy-config migration.
|
|
52
54
|
- `model-switch-statusline.test.ts` — Model switch statusline integration.
|
|
53
55
|
- `model-usage-refresh.test.ts` — Model usage refresh integration.
|
|
54
56
|
- `token-switch-usage.test.ts` — Token Switch balance formatting.
|
|
@@ -78,24 +80,36 @@ Do not add ignore rules, skip tests, or weaken types merely to bypass a check.
|
|
|
78
80
|
|
|
79
81
|
The HUD extension is organized into functional modules under `extensions/hud/`:
|
|
80
82
|
|
|
81
|
-
- **`index.ts`** —
|
|
83
|
+
- **`index.ts`** — Composition root for controllers, shared state, and UI installation.
|
|
84
|
+
- **`commands/`** — `/zentui` presentation and its configuration-persistence controller.
|
|
82
85
|
- **`config/`** — Configuration model, normalization, and persistence.
|
|
83
|
-
- **`footer/`** — Footer rendering,
|
|
86
|
+
- **`footer/`** — Footer rendering, semantic group construction, responsive layout, and templates.
|
|
84
87
|
- **`segments/`** — State collectors: Git, runtime, MCP, skills, projects, etc.
|
|
88
|
+
- **`session/`** — Pi event registration, lifecycle generations, and live-context throttling.
|
|
89
|
+
- **`state/`** — Shared footer state, telemetry reducer, and project-refresh controller.
|
|
85
90
|
- **`telemetry/`** — Usage formatting, token switch, and Codex subscription client.
|
|
86
|
-
- **`session/`** — Session lifecycle, context, and live context overlay.
|
|
87
|
-
- **`state/`** — Aggregated state, telemetry, and project refresh.
|
|
88
|
-
- **`commands/`** — `/zentui` command and interactive TUI settings.
|
|
89
91
|
- **`ui/`** — Icons and terminal style utilities.
|
|
90
92
|
|
|
91
93
|
Key conventions:
|
|
92
94
|
|
|
93
|
-
- Keep event listeners
|
|
95
|
+
- Keep composition in `index.ts`, Pi event listeners in `session/event-handlers.ts`, and avoid file reads or subprocesses in `render()`.
|
|
94
96
|
- Async results check session generation before applying.
|
|
95
97
|
- Timers should be cleaned up on shutdown and `unref()` where possible.
|
|
96
98
|
- State collectors return explicit `ok` / `error` / `not found` semantics.
|
|
97
99
|
- Use `visibleWidth()` and `truncateToWidth()` for terminal width calculations.
|
|
98
100
|
|
|
101
|
+
## Releases
|
|
102
|
+
|
|
103
|
+
npm releases use GitHub Trusted Publishing through `.github/workflows/publish.yml`; no `NPM_TOKEN` repository secret is required. The workflow has narrowly scoped `id-token: write` permission, verifies the package, and publishes with provenance.
|
|
104
|
+
|
|
105
|
+
1. Update the same version in `package.json` and `package-lock.json`.
|
|
106
|
+
2. Commit and push the release changes to `main`.
|
|
107
|
+
3. Create an annotated tag that exactly matches the package version, for example `git tag -a v1.1.0 -m "v1.1.0"`.
|
|
108
|
+
4. Push the tag with `git push origin v1.1.0`.
|
|
109
|
+
5. Confirm the **Publish npm package** workflow succeeds and verify the version on npm.
|
|
110
|
+
|
|
111
|
+
The tag/version guard fails the workflow before publication if they do not match.
|
|
112
|
+
|
|
99
113
|
## Pull request checklist
|
|
100
114
|
|
|
101
115
|
Before opening a pull request, confirm that:
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -12,17 +12,18 @@
|
|
|
12
12
|
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
|
-
Rinco Pi HUD 为 Pi TUI 会话提供丰富的实时状态脚注,可显示项目状态、Git 指标、运行时版本、会话活动、模型用量、Token
|
|
15
|
+
Rinco Pi HUD 为 Pi TUI 会话提供丰富的实时状态脚注,可显示项目状态、Git 指标、运行时版本、会话活动、模型用量、Token 费用等信息,支持响应式四分组布局或可定制的单行布局。Pi 可直接加载 TypeScript 扩展,无需构建步骤(`tsconfig.json` 设置了 `noEmit: true`,仅用于 `npm run typecheck` 类型检查)。
|
|
16
16
|
|
|
17
17
|
## 功能
|
|
18
18
|
|
|
19
|
-
- **Project state**:当前目录、Git 分支、Commit、Tag
|
|
20
|
-
- **Session activity**:模型、Provider、Context
|
|
21
|
-
- **Tool and agent activity
|
|
19
|
+
- **Project state**:当前目录、Git 分支、Commit、Tag、工作区状态、Git 操作状态、差异指标和运行时版本。
|
|
20
|
+
- **Session activity**:模型、Provider、Context 用量、可独立控制的输入/输出 Token、缓存、会话费用、轮次和 Thinking 等级。
|
|
21
|
+
- **Tool and agent activity**:可分别控制正在运行的 Tool、已完成 Tool 计数、活跃 Agent、空闲状态、Skill 和 MCP Server 状态。
|
|
22
22
|
- **Model quota**:根据当前模型自动切换 Codex 周限额或 Token Switch 余额。
|
|
23
23
|
- **Git awareness**:分支、Detached HEAD、Tag、Ahead/Behind、Stash、合并冲突和脏状态。
|
|
24
24
|
- **Runtime detection**:支持 Node、Python、Go、Rust、Java 等 60+ 运行时,并解析项目清单版本。
|
|
25
|
-
- **Configurable layout
|
|
25
|
+
- **Configurable layout**:默认使用响应式 Project、Session、Activity、Usage 四分组布局,或完全自定义的单行模板。
|
|
26
|
+
- **Granular status controls**:可在 `/zentui` 中分别控制 Git 操作状态、Tool 运行状态/计数、Agent 活跃/空闲状态及输入/输出 Token。
|
|
26
27
|
- **Extension statuses**:读取第三方扩展发布的状态,按配置的位置和颜色模式显示。
|
|
27
28
|
- **Safe fallback**:超时和错误处理优雅,会话关闭后不留过期数据。
|
|
28
29
|
|
|
@@ -82,24 +83,24 @@ HUD 脚注默认启用。运行 `/zentui` 打开交互式设置。
|
|
|
82
83
|
|
|
83
84
|
| 路径 | 说明 |
|
|
84
85
|
| --- | --- |
|
|
85
|
-
| [`extensions/hud/index.ts`](../extensions/hud/index.ts) |
|
|
86
|
-
| [`extensions/hud/config/`](../extensions/hud/config/config.ts) |
|
|
87
|
-
| [`extensions/hud/footer/`](../extensions/hud/footer/index.ts) |
|
|
86
|
+
| [`extensions/hud/index.ts`](../extensions/hud/index.ts) | Controller、共享状态与 UI 安装的组合入口 |
|
|
87
|
+
| [`extensions/hud/config/`](../extensions/hud/config/config.ts) | 配置模型、归一化、迁移与持久化 |
|
|
88
|
+
| [`extensions/hud/footer/`](../extensions/hud/footer/index.ts) | 脚注渲染、语义分组、响应式布局与模板解析 |
|
|
88
89
|
| [`extensions/hud/segments/`](../extensions/hud/segments/) | 状态采集器:Git、运行时、MCP、Skill、项目等 |
|
|
89
90
|
| [`extensions/hud/telemetry/`](../extensions/hud/telemetry/format.ts) | 用量格式化、Token Switch 与 Codex 订阅客户端 |
|
|
90
|
-
| [`extensions/hud/session/`](../extensions/hud/session/) |
|
|
91
|
-
| [`extensions/hud/state/`](../extensions/hud/state/) |
|
|
92
|
-
| [`extensions/hud/commands/`](../extensions/hud/commands/settings.ts) | `/zentui`
|
|
91
|
+
| [`extensions/hud/session/`](../extensions/hud/session/) | Pi 事件注册、会话生命周期与实时 Context 覆盖 |
|
|
92
|
+
| [`extensions/hud/state/`](../extensions/hud/state/) | 聚合状态、Telemetry Reducer 与项目刷新 Controller |
|
|
93
|
+
| [`extensions/hud/commands/`](../extensions/hud/commands/settings.ts) | `/zentui` 设置界面与配置 Controller |
|
|
93
94
|
| [`extensions/hud/ui/`](../extensions/hud/ui/) | 图标与终端样式工具 |
|
|
94
95
|
| [`docs/footer.md`](footer.md) | 完整脚注配置参考 |
|
|
95
96
|
| [`docs/CONTRIBUTING.md`](CONTRIBUTING.md) | 本地开发、测试规范和 PR 检查清单 |
|
|
96
|
-
| [`tests/`](../tests/) | Vitest 测试套件(
|
|
97
|
+
| [`tests/`](../tests/) | Vitest 测试套件(41 个测试用例,8 个文件) |
|
|
97
98
|
|
|
98
99
|
## 定制
|
|
99
100
|
|
|
100
101
|
### 布局
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
默认布局将信息分为 Project、Session、Activity 和 Usage 四组;超长分组会在完整状态项边界处换行,并保持续行对齐。设置 `footerFormat` 模板字符串可切换为单行布局:
|
|
103
104
|
|
|
104
105
|
```text
|
|
105
106
|
/zentui format "$cwd( $git_branch)$fill($context)( $tokens)( $cost)"
|
|
@@ -109,13 +110,16 @@ HUD 脚注默认启用。运行 `/zentui` 打开交互式设置。
|
|
|
109
110
|
|
|
110
111
|
### 状态段
|
|
111
112
|
|
|
112
|
-
|
|
113
|
+
运行 `/zentui` 并进入 **Built-in segments**,即可启用或禁用单个状态:
|
|
113
114
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
| 分组 | 可独立控制的状态 |
|
|
116
|
+
| --- | --- |
|
|
117
|
+
| Project | Git 状态、Git 操作状态(`MERGING`、`REBASING` 等)、Commit、差异指标、运行时、包版本、OS 和用户 |
|
|
118
|
+
| Session | 模型、Thinking 等级、轮次和会话时长 |
|
|
119
|
+
| Activity | 正在运行的 Tool、已完成 Tool 计数、活跃 Agent、`Agent idle`、Skill 和 MCP |
|
|
120
|
+
| Usage | Context、输入 Token、输出 Token、缓存详情/命中率、费用、限额和时间 |
|
|
121
|
+
|
|
122
|
+
使用旧版聚合开关 `tokens`、`toolActivity` 或 `agentActivity` 的配置会自动迁移。仍可通过 `/zentui statusline enable|disable|toggle` 控制整个脚注。
|
|
119
123
|
|
|
120
124
|
### 扩展状态
|
|
121
125
|
|
package/docs/footer.md
CHANGED
|
@@ -2,46 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
## Default layout
|
|
4
4
|
|
|
5
|
-
When `footerFormat` is empty, the HUD displays
|
|
5
|
+
When `footerFormat` is empty, the HUD displays four semantic groups:
|
|
6
6
|
|
|
7
7
|
```text
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
Project · pi-sakura · main · 24.18
|
|
9
|
+
Session · gpt-5.3 · Thinking level: high · Turn 8
|
|
10
|
+
Activity · Agent idle · Skill 2/3 · MCP 2/2
|
|
11
|
+
Usage · 35%/200k · ↑ 4.2k · ↓ 1.1k · $ 0.030
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
The category column is sized from visible text so every separator aligns. When a row exceeds the terminal width, complete status segments move to an indented continuation line. Only a single segment that is wider than the available content area is truncated. Third-party extension statuses appear on the Activity group in configured `left`, `middle`, then `right` order.
|
|
14
15
|
|
|
15
16
|
## Built-in status segments
|
|
16
17
|
|
|
17
|
-
| Key | Default |
|
|
18
|
+
| Key | Default | Group | Description |
|
|
18
19
|
| --- | --- | --- | --- |
|
|
19
|
-
| `
|
|
20
|
-
| `
|
|
21
|
-
| `
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `packageVersion` | off |
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
20
|
+
| `cwd` | on | Project | Current working directory |
|
|
21
|
+
| `gitBranch` | on | Project | Branch name or `HEAD` when detached |
|
|
22
|
+
| `gitStatus` | on | Project | Conflicts, staged, modified, untracked, stash, ahead/behind |
|
|
23
|
+
| `gitState` | on | Project | Git operation state such as `MERGING` or `REBASING` |
|
|
24
|
+
| `gitCounts` | off | Project | Numeric counts embedded in ahead/behind and stash status |
|
|
25
|
+
| `gitCommit` | off | Project | Short commit hash and optional exact tag |
|
|
26
|
+
| `gitMetrics` | off | Project | Added/deleted lines from `git diff HEAD --numstat` |
|
|
27
|
+
| `runtime` | on | Project | Detected language/build system and tool version |
|
|
28
|
+
| `packageVersion` | off | Project | Project manifest version |
|
|
29
|
+
| `configCounts` | off | Project | Instruction files and installed Pi packages count |
|
|
30
|
+
| `os` | on | Project | OS icon/text per platform |
|
|
31
|
+
| `username` | off | Project | `user@hostname` |
|
|
32
|
+
| `sessionName` | on | Session | Current Pi session name |
|
|
33
|
+
| `model` | on | Session | Provider and model ID |
|
|
34
|
+
| `thinking` | on | Session | Thinking level when reasoning-capable |
|
|
35
|
+
| `turnCount` | on | Session | Current turn index |
|
|
36
|
+
| `sessionDuration` | off | Session | Current session duration |
|
|
37
|
+
| `runningTools` | on | Activity | Currently running native tools and elapsed time |
|
|
38
|
+
| `toolCounts` | on | Activity | Cumulative completed native-tool counts |
|
|
39
|
+
| `activeAgents` | on | Activity | Active primary agent runs |
|
|
40
|
+
| `agentIdle` | on | Activity | `Agent idle` when no primary agent run is active |
|
|
41
|
+
| `skills` | on | Activity | Active/available skills count, e.g. `Skill 1/3` |
|
|
42
|
+
| `mcp` | on | Activity | MCP connected/total servers |
|
|
43
|
+
| `context` | on | Usage | Context percentage, window size, and/or gauge |
|
|
44
|
+
| `inputTokens` | on | Usage | Cumulative input tokens |
|
|
45
|
+
| `outputTokens` | on | Usage | Cumulative output tokens |
|
|
46
|
+
| `cacheDetails` | on | Usage | Cache read/write tokens and latest hit rate |
|
|
47
|
+
| `cost` | on | Usage | Cumulative session cost |
|
|
48
|
+
| `codexUsage` | on | Usage | Codex weekly quota remaining |
|
|
49
|
+
| `time` | off | Usage | Current time `HH:MM` |
|
|
45
50
|
|
|
46
51
|
## Template syntax
|
|
47
52
|
|
|
@@ -100,7 +105,7 @@ Clear it:
|
|
|
100
105
|
| `$instruction_files` | `AGENTS.md` + `CLAUDE.md` total |
|
|
101
106
|
| `$agents_files` | `AGENTS.md` count |
|
|
102
107
|
| `$claude_files` | `CLAUDE.md` count |
|
|
103
|
-
| `$skills` | Active/available skills, e.g.
|
|
108
|
+
| `$skills` | Active/available skills, e.g. `Skill 1/3` |
|
|
104
109
|
| `$active_skills` | Active skills count only |
|
|
105
110
|
| `$extensions` | Installed Pi packages count |
|
|
106
111
|
| `$mcp` | MCP connected/total |
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import {
|
|
3
|
+
type PolishedTuiConfig,
|
|
4
|
+
saveColorSourcesPatch,
|
|
5
|
+
saveContextStylePatch,
|
|
6
|
+
saveExtensionStatusColorMode,
|
|
7
|
+
saveExtensionStatusPlacement,
|
|
8
|
+
saveFooterFormatPatch,
|
|
9
|
+
saveFooterSegmentsPatch,
|
|
10
|
+
saveGitBranchPatch,
|
|
11
|
+
saveIconsModePatch,
|
|
12
|
+
savePathDisplayPatch,
|
|
13
|
+
saveSeparatorPatch,
|
|
14
|
+
saveUiFeaturesPatch,
|
|
15
|
+
} from "../config/config.js";
|
|
16
|
+
import { registerZentuiSettingsCommand } from "./settings.js";
|
|
17
|
+
|
|
18
|
+
interface SettingsControllerDeps {
|
|
19
|
+
getConfig: () => PolishedTuiConfig;
|
|
20
|
+
setConfig: (config: PolishedTuiConfig) => void;
|
|
21
|
+
applyConfiguredUi: (ctx: ExtensionContext) => void;
|
|
22
|
+
restartSessionTimer: () => void;
|
|
23
|
+
getActiveExtensionStatuses: () => ReadonlyMap<string, string>;
|
|
24
|
+
requestRender: () => void;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Connect the settings UI to persistence without exposing patch mechanics to the extension root. */
|
|
28
|
+
export function registerSettingsController(pi: ExtensionAPI, deps: SettingsControllerDeps): void {
|
|
29
|
+
const updateConfig = (config: PolishedTuiConfig) => {
|
|
30
|
+
deps.setConfig(config);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
registerZentuiSettingsCommand(pi, {
|
|
34
|
+
getConfig: deps.getConfig,
|
|
35
|
+
setColorSources(patch) {
|
|
36
|
+
updateConfig(saveColorSourcesPatch(patch));
|
|
37
|
+
},
|
|
38
|
+
setUiFeatures(patch, ctx) {
|
|
39
|
+
updateConfig(saveUiFeaturesPatch(patch));
|
|
40
|
+
deps.applyConfiguredUi(ctx);
|
|
41
|
+
},
|
|
42
|
+
setFooterSegments(patch) {
|
|
43
|
+
updateConfig(saveFooterSegmentsPatch(patch));
|
|
44
|
+
deps.restartSessionTimer();
|
|
45
|
+
},
|
|
46
|
+
setFooterFormat(value) {
|
|
47
|
+
updateConfig(saveFooterFormatPatch(value));
|
|
48
|
+
deps.restartSessionTimer();
|
|
49
|
+
},
|
|
50
|
+
setIconMode(mode) {
|
|
51
|
+
updateConfig(saveIconsModePatch(mode));
|
|
52
|
+
},
|
|
53
|
+
setContextStyle(style) {
|
|
54
|
+
updateConfig(saveContextStylePatch(style));
|
|
55
|
+
},
|
|
56
|
+
setSeparator(separator) {
|
|
57
|
+
updateConfig(saveSeparatorPatch(separator));
|
|
58
|
+
},
|
|
59
|
+
setPathDisplay(patch) {
|
|
60
|
+
updateConfig(savePathDisplayPatch(patch));
|
|
61
|
+
},
|
|
62
|
+
setGitBranch(patch) {
|
|
63
|
+
updateConfig(saveGitBranchPatch(patch));
|
|
64
|
+
},
|
|
65
|
+
getActiveExtensionStatuses: deps.getActiveExtensionStatuses,
|
|
66
|
+
setExtensionStatusPlacement(key, placement) {
|
|
67
|
+
updateConfig(saveExtensionStatusPlacement(key, placement));
|
|
68
|
+
},
|
|
69
|
+
setExtensionStatusColorMode(key, colorMode) {
|
|
70
|
+
updateConfig(saveExtensionStatusColorMode(key, colorMode));
|
|
71
|
+
},
|
|
72
|
+
requestRender: deps.requestRender,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -113,44 +113,50 @@ const footerSegmentSettingLabels: Record<FooterSegmentSettingId, string> = {
|
|
|
113
113
|
cwd: "Current directory",
|
|
114
114
|
gitBranch: "Git branch",
|
|
115
115
|
gitStatus: "Git status",
|
|
116
|
+
gitState: "Git operation state",
|
|
116
117
|
gitCounts: "Git counts",
|
|
117
|
-
sessionDuration: "Session duration",
|
|
118
|
-
username: "Username@host",
|
|
119
|
-
time: "Current time",
|
|
120
|
-
os: "OS icon",
|
|
121
|
-
runtime: "Runtime",
|
|
122
|
-
context: "Context usage",
|
|
123
|
-
tokens: "Token counts",
|
|
124
|
-
cost: "Session cost",
|
|
125
|
-
packageVersion: "Package version",
|
|
126
118
|
gitCommit: "Git commit",
|
|
127
119
|
gitMetrics: "Git line metrics",
|
|
120
|
+
runtime: "Runtime",
|
|
121
|
+
packageVersion: "Package version",
|
|
122
|
+
configCounts: "Config counts",
|
|
123
|
+
os: "OS icon",
|
|
124
|
+
username: "Username@host",
|
|
128
125
|
sessionName: "Session name",
|
|
129
126
|
model: "Model",
|
|
130
127
|
thinking: "Thinking level",
|
|
131
128
|
turnCount: "Turn count",
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
sessionDuration: "Session duration",
|
|
130
|
+
runningTools: "Running tools",
|
|
131
|
+
toolCounts: "Completed tool counts",
|
|
132
|
+
activeAgents: "Active agents",
|
|
133
|
+
agentIdle: "Agent idle status",
|
|
135
134
|
skills: "Skill activity",
|
|
136
135
|
mcp: "MCP connections",
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
context: "Context usage",
|
|
137
|
+
inputTokens: "Input tokens",
|
|
138
|
+
outputTokens: "Output tokens",
|
|
139
|
+
cacheDetails: "Cache details",
|
|
140
|
+
cost: "Session cost",
|
|
141
|
+
codexUsage: "Codex subscription",
|
|
142
|
+
time: "Current time",
|
|
139
143
|
};
|
|
140
144
|
|
|
141
145
|
const footerSegmentSettingDescriptions: Record<FooterSegmentSettingId, string> = {
|
|
142
146
|
cwd: "Show or hide the current working directory on the project row.",
|
|
143
147
|
gitBranch: "Show or hide the git branch name on the project row.",
|
|
144
148
|
gitStatus: "Show or hide git status icons and ahead/behind markers on the project row.",
|
|
149
|
+
gitState: "Show or hide Git operation states such as MERGING and REBASING.",
|
|
145
150
|
gitCounts:
|
|
146
151
|
"Show numeric ahead/behind and stash counts (requires the Git status segment to be enabled).",
|
|
147
|
-
sessionDuration: "Show session running time on the
|
|
152
|
+
sessionDuration: "Show session running time on the session row.",
|
|
148
153
|
username: "Show user@hostname on the project row.",
|
|
149
154
|
time: "Show the current time (HH:MM) on the usage row.",
|
|
150
155
|
os: "Show an operating-system icon on the project row.",
|
|
151
156
|
runtime: "Show or hide the detected runtime/language on the project row.",
|
|
152
157
|
context: "Show or hide context usage on the usage row.",
|
|
153
|
-
|
|
158
|
+
inputTokens: "Show or hide cumulative input tokens on the usage row.",
|
|
159
|
+
outputTokens: "Show or hide cumulative output tokens on the usage row.",
|
|
154
160
|
cost: "Show or hide session cost on the usage row.",
|
|
155
161
|
packageVersion:
|
|
156
162
|
"Show the project’s own manifest version (package.json, Cargo.toml, pyproject.toml, …) on the project row. Distinct from the installed toolchain version.",
|
|
@@ -165,10 +171,12 @@ const footerSegmentSettingDescriptions: Record<FooterSegmentSettingId, string> =
|
|
|
165
171
|
cacheDetails: "Show cumulative cache read/write token totals on the usage row.",
|
|
166
172
|
codexUsage: "Show OpenAI Codex subscription rate limits on the usage row when available.",
|
|
167
173
|
configCounts: "Show instruction-file and installed Pi package counts on the project row.",
|
|
168
|
-
skills: "Show active/available Pi skill counts on the
|
|
169
|
-
mcp: "Show parsed MCP connected/total server counts on the
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
skills: "Show active/available Pi skill counts on the activity row.",
|
|
175
|
+
mcp: "Show parsed MCP connected/total server counts on the activity row.",
|
|
176
|
+
runningTools: "Show currently running native tools and their elapsed time.",
|
|
177
|
+
toolCounts: "Show cumulative completed native-tool counts.",
|
|
178
|
+
activeAgents: "Show active main agent runs on the activity row (not subagent count).",
|
|
179
|
+
agentIdle: "Show Agent idle when no main agent run is active.",
|
|
172
180
|
};
|
|
173
181
|
|
|
174
182
|
const directCommandSuggestions = [
|
|
@@ -209,11 +217,13 @@ function isFooterSegmentSettingId(value: string): value is FooterSegmentSettingI
|
|
|
209
217
|
value === "cwd" ||
|
|
210
218
|
value === "gitBranch" ||
|
|
211
219
|
value === "gitStatus" ||
|
|
220
|
+
value === "gitState" ||
|
|
212
221
|
value === "gitCounts" ||
|
|
213
222
|
value === "sessionDuration" ||
|
|
214
223
|
value === "runtime" ||
|
|
215
224
|
value === "context" ||
|
|
216
|
-
value === "
|
|
225
|
+
value === "inputTokens" ||
|
|
226
|
+
value === "outputTokens" ||
|
|
217
227
|
value === "cost" ||
|
|
218
228
|
value === "username" ||
|
|
219
229
|
value === "time" ||
|
|
@@ -230,8 +240,10 @@ function isFooterSegmentSettingId(value: string): value is FooterSegmentSettingI
|
|
|
230
240
|
value === "configCounts" ||
|
|
231
241
|
value === "skills" ||
|
|
232
242
|
value === "mcp" ||
|
|
233
|
-
value === "
|
|
234
|
-
value === "
|
|
243
|
+
value === "runningTools" ||
|
|
244
|
+
value === "toolCounts" ||
|
|
245
|
+
value === "activeAgents" ||
|
|
246
|
+
value === "agentIdle"
|
|
235
247
|
);
|
|
236
248
|
}
|
|
237
249
|
|
|
@@ -155,6 +155,17 @@ function footerSegmentValue(
|
|
|
155
155
|
return typeof value === "boolean" ? value : defaultConfig.footerSegments[key];
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
function footerSegmentValueWithLegacy(
|
|
159
|
+
record: Record<string, unknown>,
|
|
160
|
+
key: keyof FooterSegmentsConfig,
|
|
161
|
+
legacyKey: "tokens" | "toolActivity" | "agentActivity",
|
|
162
|
+
): boolean {
|
|
163
|
+
const value = record[key];
|
|
164
|
+
if (typeof value === "boolean") return value;
|
|
165
|
+
const legacyValue = record[legacyKey];
|
|
166
|
+
return typeof legacyValue === "boolean" ? legacyValue : defaultConfig.footerSegments[key];
|
|
167
|
+
}
|
|
168
|
+
|
|
158
169
|
function definedColors(
|
|
159
170
|
colors: Partial<Record<keyof PolishedTuiConfig["colors"], string | undefined>>,
|
|
160
171
|
): Partial<PolishedTuiConfig["colors"]> {
|
|
@@ -212,10 +223,13 @@ function normalizeFooterSegments(record: Record<string, unknown>): FooterSegment
|
|
|
212
223
|
cwd: footerSegmentValue(record, "cwd"),
|
|
213
224
|
gitBranch: footerSegmentValue(record, "gitBranch"),
|
|
214
225
|
gitStatus: footerSegmentValue(record, "gitStatus"),
|
|
226
|
+
gitState: footerSegmentValue(record, "gitState"),
|
|
215
227
|
gitCounts: footerSegmentValue(record, "gitCounts"),
|
|
216
228
|
runtime: footerSegmentValue(record, "runtime"),
|
|
217
229
|
context: footerSegmentValue(record, "context"),
|
|
218
|
-
|
|
230
|
+
inputTokens: footerSegmentValueWithLegacy(record, "inputTokens", "tokens"),
|
|
231
|
+
outputTokens: footerSegmentValueWithLegacy(record, "outputTokens", "tokens"),
|
|
232
|
+
cacheDetails: footerSegmentValue(record, "cacheDetails"),
|
|
219
233
|
cost: footerSegmentValue(record, "cost"),
|
|
220
234
|
sessionDuration: footerSegmentValue(record, "sessionDuration"),
|
|
221
235
|
username: footerSegmentValue(record, "username"),
|
|
@@ -228,13 +242,14 @@ function normalizeFooterSegments(record: Record<string, unknown>): FooterSegment
|
|
|
228
242
|
model: footerSegmentValue(record, "model"),
|
|
229
243
|
thinking: footerSegmentValue(record, "thinking"),
|
|
230
244
|
turnCount: footerSegmentValue(record, "turnCount"),
|
|
231
|
-
cacheDetails: footerSegmentValue(record, "cacheDetails"),
|
|
232
245
|
codexUsage: footerSegmentValue(record, "codexUsage"),
|
|
233
246
|
configCounts: footerSegmentValue(record, "configCounts"),
|
|
234
247
|
skills: footerSegmentValue(record, "skills"),
|
|
235
248
|
mcp: footerSegmentValue(record, "mcp"),
|
|
236
|
-
|
|
237
|
-
|
|
249
|
+
runningTools: footerSegmentValueWithLegacy(record, "runningTools", "toolActivity"),
|
|
250
|
+
toolCounts: footerSegmentValueWithLegacy(record, "toolCounts", "toolActivity"),
|
|
251
|
+
activeAgents: footerSegmentValueWithLegacy(record, "activeAgents", "agentActivity"),
|
|
252
|
+
agentIdle: footerSegmentValueWithLegacy(record, "agentIdle", "agentActivity"),
|
|
238
253
|
};
|
|
239
254
|
}
|
|
240
255
|
|
|
@@ -46,10 +46,12 @@ function isFooterSegmentKey(value: string): value is keyof FooterSegmentsConfig
|
|
|
46
46
|
value === "cwd" ||
|
|
47
47
|
value === "gitBranch" ||
|
|
48
48
|
value === "gitStatus" ||
|
|
49
|
+
value === "gitState" ||
|
|
49
50
|
value === "gitCounts" ||
|
|
50
51
|
value === "runtime" ||
|
|
51
52
|
value === "context" ||
|
|
52
|
-
value === "
|
|
53
|
+
value === "inputTokens" ||
|
|
54
|
+
value === "outputTokens" ||
|
|
53
55
|
value === "cost" ||
|
|
54
56
|
value === "sessionDuration" ||
|
|
55
57
|
value === "username" ||
|
|
@@ -67,8 +69,10 @@ function isFooterSegmentKey(value: string): value is keyof FooterSegmentsConfig
|
|
|
67
69
|
value === "configCounts" ||
|
|
68
70
|
value === "skills" ||
|
|
69
71
|
value === "mcp" ||
|
|
70
|
-
value === "
|
|
71
|
-
value === "
|
|
72
|
+
value === "runningTools" ||
|
|
73
|
+
value === "toolCounts" ||
|
|
74
|
+
value === "activeAgents" ||
|
|
75
|
+
value === "agentIdle"
|
|
72
76
|
);
|
|
73
77
|
}
|
|
74
78
|
|