From 35b6572f9b06b89b285fcea2a684f27ee3078165 Mon Sep 17 00:00:00 2001 From: tt-a1i Date: Sat, 22 Aug 2026 19:25:29 +0800 Subject: [PATCH] feat(ui): small unicode icons for footer metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each footer metric now carries a built-in icon that renders in standard terminal fonts (no Nerd Font): 📁 directory, ⎇ branch, ✦ model, and a context gauge that fills with occupancy (◔◑◕●). Icon text participates in the existing width budget and priority shedding unchanged. --- README.md | 6 +++--- SETUP.md | 2 +- extensions/ui-customization/footer.test.ts | 4 ++-- extensions/ui-customization/footer.ts | 22 ++++++++++++++++++---- extensions/ui-customization/index.test.ts | 4 ++-- 5 files changed, 26 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d74b0af5..0b47aa2c 100644 --- a/README.md +++ b/README.md @@ -323,13 +323,13 @@ Next-action Suggestion 是可选的:完整主 Agent Run 结束后,在空编 ## 终端体验 -默认 Footer 把真实运行状态压进一行: +默认 Footer 把真实运行状态压进一行,指标自带小图标(无需 Nerd Font): ```text -cwd git PR model context +📁 cwd ⎇ git PR ✦ model ◔ context ``` -`thinking`、`cache`、`cost`、`throughput` 也是可选指标,可通过 `/openpi-setup` 加入自定义布局。 +`📁` 目录、`⎇` 分支、`✦` 模型;context 的圆环随占用率填充(`◔◑◕●`)。`thinking`、`cache`、`cost`、`throughput` 也是可选指标,可通过 `/openpi-setup` 加入自定义布局。 - 支持 `powerline`、`powerline-mono`、`compact`,也支持自定义多行布局; - 终端变窄时按优先级隐藏次要指标,不机械截断尾部; diff --git a/SETUP.md b/SETUP.md index f7b46b7a..ab5b420e 100644 --- a/SETUP.md +++ b/SETUP.md @@ -54,7 +54,7 @@ Use the single canonical package-owned command. `/my-pi-setup` remains a compati /openpi-setup 清除 explorer 的模型,让它继承父模型 ``` -Capability discovery defaults to `explicit`, preserving the zero-resident OpenPI tool surface until the user asks for a capability. `adaptive` is an explicit opt-in that keeps only `openpi_load_tools` visible and allows the model to load a useful group on its own; because this can start Subagents, Workflows, or background processes, normal permission and configured concurrency/call limits still apply. Changing the setting updates the current Session immediately, while already loaded groups remain stable for that Session. Next-action suggestions default to off. Run `/openpi-setup` to explicitly choose an available model and reasoning level. After a fully settled main-agent run, one suggestion may appear as dim inline text on the first row of an empty editor; reserved cells at the row end keep CJK IME preedit from overwriting it. `Right` accepts it into the editor without submitting, while any other editor input dismisses it. Suggestions are ephemeral and never enter session history or model context. Workflows default to 8 concurrent agents and 128 total agent calls per run; configurable hard maxima are 64 and 1024. The large decorative header defaults off and the custom dashboard footer defaults on with a one-line plain layout (`cwd git pr |flex| model context`; `thinking`, `cache`, `cost`, and `throughput` remain opt-in metrics). Footer presets are `powerline`, `powerline-mono`, and `compact`; style can also be set independently to `plain`, `powerline`, or `powerline-mono`. Custom layouts use a 2D `footerLines` array with at most one `flex` per row for left/right alignment. Nerd Font only affects powerline separator glyphs (``); metric text stays readable without it. Footer changes apply immediately in the active TUI session. Subagent results default to the existing full display; compact mode shows only bounded status rows and keeps raw child reports behind `app.tools.expand` (`Ctrl+O` by default). Bash defaults to a folded one-line command with bounded output and a hidden-line count. Write/Edit defaults to an extra-short folded preview capped at three rendered lines including the operation header; its hidden-line hint remains inside the operation's status background. Select full independently for any category to keep it expanded. Compact views temporarily expand with `app.tools.expand`. An optional post-edit command is off by default: set one (for example `npm run format`, maximum 500 characters) and it runs once in the background after each interactive-TUI turn with successful Write/Edit operations, with failures reported as a notification. It deliberately does not guess whether arbitrary Bash commands changed files. Built-in Agent roles `explorer`, `implementer`, `reviewer`, and `advisor` are shared by `subagent_spawn.agent_type` and Workflow `agent(..., { agent_type })`; all inherit the parent model by default. `/openpi-setup` may assign a currently available Registry model to any subset; clearing one returns it to inheritance and omitted roles stay unchanged. Model precedence is explicit call > selected role-file model > setup assignment > parent inheritance; effort is explicit call > selected role > parent. A trusted project `.pi/agents/.md` overrides global `~/.pi/agent/agents/.md`, which overrides the complete built-in role definition; overrides are diagnosed. Role-model changes apply to the next spawn or Workflow agent call without reload. Configuration is stored privately at `~/.pi/agent/my-pi-setup.json`. +Capability discovery defaults to `explicit`, preserving the zero-resident OpenPI tool surface until the user asks for a capability. `adaptive` is an explicit opt-in that keeps only `openpi_load_tools` visible and allows the model to load a useful group on its own; because this can start Subagents, Workflows, or background processes, normal permission and configured concurrency/call limits still apply. Changing the setting updates the current Session immediately, while already loaded groups remain stable for that Session. Next-action suggestions default to off. Run `/openpi-setup` to explicitly choose an available model and reasoning level. After a fully settled main-agent run, one suggestion may appear as dim inline text on the first row of an empty editor; reserved cells at the row end keep CJK IME preedit from overwriting it. `Right` accepts it into the editor without submitting, while any other editor input dismisses it. Suggestions are ephemeral and never enter session history or model context. Workflows default to 8 concurrent agents and 128 total agent calls per run; configurable hard maxima are 64 and 1024. The large decorative header defaults off and the custom dashboard footer defaults on with a one-line plain layout (`cwd git pr |flex| model context`; `thinking`, `cache`, `cost`, and `throughput` remain opt-in metrics). Footer presets are `powerline`, `powerline-mono`, and `compact`; style can also be set independently to `plain`, `powerline`, or `powerline-mono`. Custom layouts use a 2D `footerLines` array with at most one `flex` per row for left/right alignment. Nerd Font only affects powerline separator glyphs (``); metric text stays readable without it. Metrics carry small built-in Unicode icons (`📁` directory, `⎇` branch, `✦` model, and a `◔◑◕●` context gauge), all of which render in standard terminal fonts. Footer changes apply immediately in the active TUI session. Subagent results default to the existing full display; compact mode shows only bounded status rows and keeps raw child reports behind `app.tools.expand` (`Ctrl+O` by default). Bash defaults to a folded one-line command with bounded output and a hidden-line count. Write/Edit defaults to an extra-short folded preview capped at three rendered lines including the operation header; its hidden-line hint remains inside the operation's status background. Select full independently for any category to keep it expanded. Compact views temporarily expand with `app.tools.expand`. An optional post-edit command is off by default: set one (for example `npm run format`, maximum 500 characters) and it runs once in the background after each interactive-TUI turn with successful Write/Edit operations, with failures reported as a notification. It deliberately does not guess whether arbitrary Bash commands changed files. Built-in Agent roles `explorer`, `implementer`, `reviewer`, and `advisor` are shared by `subagent_spawn.agent_type` and Workflow `agent(..., { agent_type })`; all inherit the parent model by default. `/openpi-setup` may assign a currently available Registry model to any subset; clearing one returns it to inheritance and omitted roles stay unchanged. Model precedence is explicit call > selected role-file model > setup assignment > parent inheritance; effort is explicit call > selected role > parent. A trusted project `.pi/agents/.md` overrides global `~/.pi/agent/agents/.md`, which overrides the complete built-in role definition; overrides are diagnosed. Role-model changes apply to the next spawn or Workflow agent call without reload. Configuration is stored privately at `~/.pi/agent/my-pi-setup.json`. ## Session Goal and Tasks diff --git a/extensions/ui-customization/footer.test.ts b/extensions/ui-customization/footer.test.ts index 8b86bb20..7338a883 100644 --- a/extensions/ui-customization/footer.test.ts +++ b/extensions/ui-customization/footer.test.ts @@ -278,8 +278,8 @@ test("legacy buildFooterContent still groups selected items", () => { ]); assert.deepEqual(content, { showCwd: false, - model: "seal/gpt-5.6-sol", - usage: "25%/1.0m · cache 82%", + model: "✦ seal/gpt-5.6-sol", + usage: "◑ 25%/1.0m · cache 82%", git: "", }); }); diff --git a/extensions/ui-customization/footer.ts b/extensions/ui-customization/footer.ts index 98dfaef7..86d1b075 100644 --- a/extensions/ui-customization/footer.ts +++ b/extensions/ui-customization/footer.ts @@ -149,6 +149,18 @@ function defaultPullRequest(number: number, url: string) { return getCapabilities().hyperlinks ? hyperlink(label, url) : label; } +/** + * Small Unicode icons for footer metrics — no Nerd Font required, and every + * glyph stays a single cell wide (📁 is the one emoji, measured at width 2). + */ +function contextGauge(percent: number | null) { + if (percent === null) return "○"; + if (percent < 25) return "◔"; + if (percent < 50) return "◑"; + if (percent < 75) return "◕"; + return "●"; +} + /** * Build the value catalog for every FooterItem. Empty text means "not available * right now" and the segment is omitted from the line. @@ -177,11 +189,13 @@ export function buildSegmentCatalog( : modelInfo.modelId; return { - cwd: { text: formatDirectory(cwd), tone: "text" }, - model: { text: modelText, tone: "muted" }, + cwd: { text: `📁 ${formatDirectory(cwd)}`, tone: "text" }, + model: { text: `✦ ${modelText}`, tone: "muted" }, thinking: { text: modelInfo.thinking, tone: "muted" }, context: { - text: contextText, + text: contextText + ? `${contextGauge(modelInfo.contextPercent)} ${contextText}` + : "", tone: contextTone(modelInfo.contextPercent), }, cache: { @@ -199,7 +213,7 @@ export function buildSegmentCatalog( : `~${Math.round(modelInfo.tokensPerSecond)} tok/s`, tone: "muted", }, - git: { text: gitInfo.branch ?? "", tone: "muted" }, + git: { text: gitInfo.branch ? `⎇ ${gitInfo.branch}` : "", tone: "muted" }, pr: { text: gitInfo.pullRequest ? formatPullRequest(gitInfo.pullRequest.number, gitInfo.pullRequest.url) diff --git a/extensions/ui-customization/index.test.ts b/extensions/ui-customization/index.test.ts index 63d15d31..a15c38eb 100644 --- a/extensions/ui-customization/index.test.ts +++ b/extensions/ui-customization/index.test.ts @@ -120,8 +120,8 @@ test("renders only selected footer items", () => { assert.deepEqual(content, { showCwd: false, - model: "seal/gpt-5.6-sol", - usage: "25%/1.0m · cache 82%", + model: "✦ seal/gpt-5.6-sol", + usage: "◑ 25%/1.0m · cache 82%", git: "", }); });