pi-yancy-ui0.1.0
Claude Code-style folding of Pi's thinking blocks and tool calls.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-yancy-ui
English · 中文
为 Pi 提供 Claude Code 风格的折叠:思考块与工具输出各自收成一行, 再用 Pi 自带的按键展开。
● read src/injector.ts · 42 lines · 0.3s
● bash npm test · exit 0 · 18 lines · 4.2s
✻ Thought for 3.2s
✻ Worked for 12.3s · 3 tools · thought 4.1s
每个已完成的工具调用收成一行状态行(compact 模式,默认开启)。/yancyui compact
可以切回两行布局:
● read src/injector.ts
⎿ 42 lines · 0.3s
12 import { createInjector } from "./injector";
13 return createInjector(options);
14
15 export function bootstrap() {
16 return start();
… 37 more lines (ctrl+o to expand)
● bash npm test
⎿ exit 0 · 18 lines · 4.2s
✓ 18 passed
… 17 earlier lines (ctrl+o to expand)
- 助手正文永不折叠,只折叠思考块和工具结果。
- 没有东西被永久隐藏:每一行折叠内容都能用 Pi 原生的
ctrl+o/ctrl+t或鼠标点击展开。不引入任何新按键。 - 工具执行本身不受影响,只改渲染;模型看到的输出和以前完全一样。
目录
环境要求
- 一个带扩展 API 的 Pi:需要
registerToolRenderer、registerEntryRenderer、appendEntry,以及tool_execution_*/agent_*事件。当前所有 Pi 版本都有。 - 思考折叠额外依赖 Pi 的
hideThinkingBlock设置(见首次使用)。
安装
推荐:从 npm 安装
pi install npm:pi-yancy-ui
pi 会读取 package.json 里的 pi.extensions 字段,安装包并把它登记进你的设置,
之后每次启动都会加载。
pi list # 确认已登记
pi update npm:pi-yancy-ui # 升级到最新版本
pi remove npm:pi-yancy-ui # 移除
或者:从 git 引用或本地检出安装
也可以直接从仓库安装,适合在版本发布前试某个分支:
pi install git:github.com/Yancyz1/pi-yancy-ui # 最新的 main
pi install ./pi-yancy-ui # 本地检出
或者:软链到扩展目录
macOS / Linux:
ln -s "/path/to/pi-yancy-ui/extensions/yancy-ui" ~/.pi/agent/extensions/yancy-ui
Windows(PowerShell):
New-Item -ItemType SymbolicLink `
-Path "$env:USERPROFILE\.pi\agent\extensions\yancy-ui" `
-Target "C:\path\to\pi-yancy-ui\extensions\yancy-ui"
直接把 extensions/yancy-ui 目录复制过去也可以;用软链只是方便跟本仓库保持同步。
只试一次
pi --no-extensions -e /path/to/pi-yancy-ui/extensions/yancy-ui/index.ts
--no-extensions 会关掉其它被发现的扩展,但显式用 -e 指定的路径仍会加载。首次尝试建议
用它,可以避免和别的折叠类扩展打架——见疑难排查。
首次使用
启动 Pi,确认扩展已生效:
/yancyui status应该看到类似
fold: enabled=true tools=true compact=true thinking=true summary=true preview=true/5 turn=true hints=true | patch=yes …的输出。做一次思考折叠的初始化:
/yancyui initPi 只有在自己的
hideThinkingBlock为真时才会折叠思考块,而且这个设置只在启动时读取。/yancyui init会把它写进~/.pi/agent/settings.json,并在会话空闲时自动重载。 跳过这一步,思考块会完整显示,扩展也不会去动它。发一个会用到工具的提示,结果默认就是折叠状态。
看懂对话区
单行工具行(compact,默认)
● read src/injector.ts · 42 lines · 0.3s
- 开头的
●是状态灯:执行中是 accent 色(此时整行是● bash npm test · running…), 成功后变绿,失败变红。 - 工具名后面是参数摘要:
read/write/edit显示文件名(basename),bash显示 首条命令,grep显示 pattern,以此类推。 - 其余部分与经典模式的汇总相同(见下面那张表)。shell 失败时会在末尾追加输出首行 作为失败原因。
- 工具还在执行、尚无任何输出时,同一行显示
running…代替汇总。 edit是例外:状态行下方附 diff 预览,直接从原始 diff 文本切片——改动行优先 (-/+红/绿着色),每处改动上下各保留 1 行上下文,总量钳制在previewLines + 2行, 末尾加… N more diff lines提示。不像 Pi 自顶向下的 diff 渲染会把行数浪费在开头上下文上。write维持单行。- 按
ctrl+o(或点击该行)展开成 Pi 原生的调用行和完整结果,与经典模式一致。
工具调用行(经典模式)
● read src/injector.ts
● 是 pi-yancy-ui 的标记,颜色反映工具状态:执行中是 accent 色,失败是错误红,其余是弱化色。
这一行剩下的部分是 Pi 自己的调用渲染器,原样保留。
折叠后的结果行(经典模式)
⎿ 42 lines · 0.3s
12 import { createInjector } from "./injector";
13 return createInjector(options);
… 37 more lines (ctrl+o to expand)
⎿引出汇总行。可以通过/yancyui summary关掉。42 lines是汇总内容,因工具而异——见下面那张表。0.3s是工具耗时,只有耗时达到 1 秒及以上才显示。- 缩进的那块是预览:默认显示前
previewLines行(默认 5 行)。read的预览带真实行号,从请求的offset开始编号。 … 37 more lines (ctrl+o to expand)是展开提示。bash会显示… 17 earlier lines,因为它预览的是输出的尾部。ctrl+o是从 Pi 的按键表里查出来的,所以你如果重绑了app.tools.expand,这里显示的会是你的按键。
按 ctrl+o(或点击该行)后,● 以下的全部内容会换成 Pi 原本那份完整结果——就是不带扩展
时 Pi 自己会画的那个组件。展开状态下,● 标记本身会变成 ▾ 三角形,并保留同样的状态色
(红=失败、accent=执行中、绿=成功),一眼就能看出当前是展开态。
各工具的汇总对照表
| 工具 | 汇总 | 预览 |
|---|---|---|
read |
N lines(截断时附 truncated) |
头部,带从 offset 起的行号槽 |
write |
wrote N lines |
无——调用行已经显示了内容 |
edit |
+新增 -删除 |
无——调用行已经显示了 diff |
bash、powershell |
exit N · M lines |
尾部(输出里有价值的那端) |
grep |
N matches / no matches |
头部 |
find |
N files / no files |
头部 |
ls |
N entries / empty |
头部 |
| 其它任何工具 | 输出的第一行 | 头部 |
| 任何失败 | 错误文本;shell 则显示 exit N |
shell 保留预览 |
几点说明:
read读到图片时显示image,不给预览。write统计的是"被要求写入的行数",不是结果文本。- shell 失败时保留有用的输出,同时隐藏 Pi 追加的
Command exited with code N那行——因为exit N已经表达了同样的信息。 no matches/no files/empty被识别为空结果,所以不会出现一行误导性的预览。
思考行
✻ Thinking… ← 这段思考还在流式输出
✻ Thought for 3.2s ← 已结束,耗时至少 0.5 秒
✻ Thought ← 已结束,不足 0.5 秒,或从会话里恢复出来的
思考块隐藏时,这个标签会替换掉 Pi 的 Thinking... 占位符。耗时只对实时观察到的思考段
计算,所以恢复一个历史会话时,不会凭空给出一个它没有测量过的时长。
ctrl+t(Pi 的 app.thinking.toggle)会显示完整的思考 Markdown,和 Pi 原本渲染的一模一样
——扩展不去碰展开态。
轮次汇总
✻ Worked for 12.3s · 3 tools · thought 4.1s
每一轮结束后追加(仅 TUI 模式)。几种变体:
Stopped after …:这一轮被你中断了。Failed after …:这一轮以错误结束。· 3 tools (1 failed):有工具调用失败。· thought 4.1s:仅当思考耗时达到 0.5 秒。
按 ctrl+o 会展开成每个工具一行:
✻ Worked for 12.3s · 2 tools
✓ read 1.2s
✗ bash 0.8s
没有任何工具调用、且思考不足半秒的轮次不会产生汇总。这条记录属于会话数据而非上下文: 永远不会发给模型。
按键
pi-yancy-ui 不新增任何按键,只复用 Pi 的:
| 按键 | 作用 | Pi 的动作名 |
|---|---|---|
ctrl+o |
展开/收起工具输出和轮次汇总 | app.tools.expand |
ctrl+t |
显示/隐藏思考块 | app.thinking.toggle |
| 鼠标点击 | 切换某个工具行或思考行 | — |
按 Pi 的常规方式重绑即可,提示文字会跟着你的绑定走。
命令
全部挂在 /yancyui 下。
| 命令 | 作用 |
|---|---|
/yancyui |
总开关取反(等同 /yancyui toggle) |
/yancyui on · /yancyui off |
全开 / 全关 |
/yancyui tools |
切换工具折叠 |
/yancyui compact |
切换单行工具行(● 工具 参数 · 结果) |
/yancyui diff |
切换 compact edit 行下方的 diff 预览 |
/yancyui thinking |
切换思考折叠 |
/yancyui summary |
切换 ⎿ summary 汇总行 |
/yancyui preview |
切换截断预览 |
/yancyui turn |
切换每轮的 ✻ Worked for … 汇总 |
/yancyui hints |
切换 (ctrl+o to expand) 提示 |
/yancyui init |
把 hideThinkingBlock: true 写进 Pi 设置并重载 |
/yancyui status |
显示当前设置和补丁状态 |
示例:
/yancyui off # 暂时停止折叠,扩展仍加载着
/yancyui preview # 保留汇总,去掉预览块
/yancyui turn # 不要再追加每轮的页脚
/yancyui status # 现在到底开了什么?
改动立即生效于新产生的行,已经渲染好的行也会针对你改动的那部分重绘。设置持久化到
yancy-ui.json(见下)并在重启后保留。/yancyui 的总开关也会被保存,所以 /yancyui init
只用于一次性设置 hideThinkingBlock。
配置
yancy-ui.json
/yancyui 会写到这里:
| 平台 | 路径 |
|---|---|
| 默认 | ~/.pi/agent/yancyui.json |
| 自定义 agent 目录 | $PI_CODING_AGENT_DIR/yancyui.json |
路径来自 Pi 自己的 getAgentDir(),所以它会跟随你的 Pi 安装位置,而不是靠猜。
完整字段说明:
| 字段 | 类型 | 默认值 | 含义 |
|---|---|---|---|
enabled |
boolean | true |
总开关。false 会完全恢复 Pi 的原生渲染。 |
tools |
boolean | true |
把工具结果折叠成 ⎿ summary 行。 |
compact |
boolean | true |
把每个折叠的工具收成一行 ● 工具 参数 · 结果,而不是调用行 + 汇总行。 |
editDiff |
boolean | true |
在 compact edit 行下方显示改动行 diff 预览。 |
thinking |
boolean | true |
把隐藏的思考标签替换为 ✻ …。 |
summary |
boolean | true |
是否绘制 ⎿ summary 行。 |
preview |
boolean | true |
是否在汇总下方绘制截断预览。 |
previewLines |
number | 5 |
预览行数,钳制在 0–50;0 等价于 preview: false。 |
turnSummary |
boolean | true |
每轮追加 ✻ Worked for … 记录。 |
hints |
boolean | true |
在截断行末尾追加 (ctrl+o to expand)。 |
未知键会被忽略,类型不对的值会退回默认值,所以手改坏了或残留旧字段的文件都不可能造成 无效状态。
示例:
{
"enabled": true,
"tools": true,
"compact": true,
"thinking": true,
"summary": true,
"preview": true,
"previewLines": 3,
"turnSummary": true,
"hints": false
}
这个文件只在扩展加载时读取一次。请在 Pi 停止时编辑,或者直接用 /yancyui 做实时修改。
hideThinkingBlock
思考折叠需要 Pi 保持思考块处于折叠态。那是 Pi 自己的设置,存在
~/.pi/agent/settings.json:
{ "hideThinkingBlock": true }
/yancyui init 会替你写好。ctrl+t 切换的也是同一个设置并且会持久化,所以你手动展开过一次思考
之后,折叠就会一直关着,直到你再隐藏回去。
命令行参数
pi --yancyui # 启动时开启折叠,覆盖 yancy-ui.json
没有 --no-fold:布尔参数无法从命令行取反(Pi 会报 unknown option)。要用 /yancyui off
或直接改 yancy-ui.json。
关掉某一部分
| 我想要… | 这么做 |
|---|---|
| 完全不要折叠,但扩展还留着 | /yancyui off |
| 要折叠,但不要预览 | /yancyui preview |
| 只要汇总,不要预览也不要提示 | /yancyui preview + /yancyui hints |
| 只折工具,不动思考 | /yancyui thinking |
| 不要每轮页脚 | /yancyui turn |
| 只折思考,不动工具 | /yancyui tools |
/yancyui off 会让扩展保持加载并继续响应 /yancyui,方便和 Pi 的原生渲染来回对比。
要彻底移除扩展,见卸载。
疑难排查
思考块没有折叠 / 还是 Pi 的 Thinking...。
运行 /yancyui init(如果提示了再重载一次)。Pi 必须处于 hideThinkingBlock: true,而它只在启动
时读一次。ctrl+t 也会翻转这个设置,所以如果你手动展开过思考,再隐藏回去即可。
/yancyui status 显示 patch=no。
用于装饰思考标签的私有钩子(AssistantMessageComponent.prototype.updateContent)
在你这个 Pi 版本里已经找不到了。思考会退回 Pi 的原生渲染,其它功能照常工作。请带上你的 Pi
版本提个 issue。
改完 yancy-ui.json 没反应。
这个文件在加载时读取。实时修改请用 /yancyui …,或者重启 Pi。
显示错乱 / 在两种排版之间来回跳。
有别的扩展也在注册工具渲染器。最常见的是 transcript-blocks.ts:它同样给 assistant 渲染器打
补丁并注册自己的工具渲染器,两者会互相包裹。只启用其中一个。
窄终端下预览被截得奇怪。
预览会按可见宽度截断,汇总行和提示行都用 visibleWidth 计量,因此 emoji 宽度的终端里也能对齐。
如果仍有错位,请附上终端类型和宽度反馈。
/yancyui init 提示写不了设置。
agent 目录不可写。修一下 ~/.pi/agent 的权限,或者把 PI_CODING_AGENT_DIR 指到一个可写目录。
兼容性与平台
宿主 API。 工具折叠和轮次汇总只用公开的扩展 API。思考折叠是唯一的私有钩子:它包裹
AssistantMessageComponent.prototype.updateContent。这个导出以前就从公开入口消失过,所以扩展
通过一个小的兼容层(host.ts)去解析它,并且是软失败的。钩子找不到只会让思考折叠失效,
别的功能不受影响,会话也绝不会因此崩掉。
Pi 升级之后。 工具折叠和轮次汇总应当继续工作。如果私有钩子挪了位置,/yancyui status 会变成
patch=no,思考退回原生渲染。
平台。 纯 Node API,没有 shell 调用,也没有平台相关代码。配置目录来自 getAgentDir(),
所以 macOS、Linux、Windows(包括自定义 PI_CODING_AGENT_DIR)都能正确解析。
其它 Pi 发行版。 扩展导入的是 @earendil-works/pi-coding-agent。如果某个 fork 用了不同的
包名,需要一层包名解析适配,而且它的私有组件内部结构可能不同。
实现细节、兼容层设计和基准测试见 docs/ARCHITECTURE.md(英文)。
卸载
pi remove npm:pi-yancy-ui
如果当初用的是 git 引用或本地路径,就把同一个来源传给它:
pi remove git:github.com/Yancyz1/pi-yancy-ui 或 pi remove ./pi-yancy-ui。
或者删掉 ~/.pi/agent/extensions/ 下的软链/副本,再删除 ~/.pi/agent/yancyui.json。
若要同时恢复 Pi 对思考的默认行为,要么停用扩展,要么在 ~/.pi/agent/settings.json
里设置 hideThinkingBlock: false。
开发
npm run typecheck # tsc --noEmit
npm test # 99 条断言:折叠、思考、汇总、配置(失败时 exit 1)
npm run smoke # 人读的渲染 dump(无需 TUI、无需模型)
npm run bench # 折叠渲染 vs 原生的耗时
npm run verify:host # 在 Pi 真实的 virtualModules 加载路径下验证兼容层
这些断言经过变异测试:把某个修复回退掉(shell 退出码匹配、write 行数、isPartial 短路、
settle 守卫……)测试就会变红。基准测试显示:折叠行的开销基本不随输出增长,而 Pi 原生展开渲染
会随输出规模线性增长。
许可证
MIT — 见 LICENSE。