pi-tool-ui
Claude Code-style tool rows for the Pi coding agent, covering built-in and third-party tools alike. Rendering only: no configuration, no hidden tools, no changes to agent behaviour.
Package details
Install pi-tool-ui from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-tool-ui- Package
pi-tool-ui- Version
0.1.0- Published
- Sep 4, 2026
- Downloads
- 179/mo · 19/wk
- Author
- nanvon
- License
- MIT
- Types
- extension, theme
- Size
- 52.8 KB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
],
"themes": [
"./themes"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
📺 效果对比
单个回合内依次执行搜索、读取文件与运行测试时的终端输出对比:
默认折叠输出(原生样式)
Grep 匹配占据约 15 行,Bash 输出截断显示:
grep /timeout/ in src
src/client.ts:42: timeout: 3000,
src/client.ts:87: const timeout = opts.timeout ?? DEFAULT;
src/pool.ts:15: timeout?: number;
⋮ 又 12 行
... (23 more lines, ctrl+o to expand)
read src/client.ts TypeScript
$ npm test
... (18 earlier lines, ctrl+o to expand)
PASS test/pool.test.ts
Tests: 24 passed, 24 total
Time: 2.412 s
pi-tool-ui 紧凑输出
每个工具收敛为两行(调用签名 + 提取后的状态摘要):
⏺ Grep(pattern: "timeout", path: "src")
⎿ 38 matches · 6 files
⏺ Read(src/client.ts)
⎿ 214 lines
⏺ Bash(npm test)
⎿ 24 lines
若安装第三方扩展(如 fff),其提供的 ffgrep、fffind 与内置工具以完全相同的两行结构排布:
⏺ Grep(pattern: "anchor", path: "src")
⎿ 56 matches · 9 files
⏺ Find(pattern: "component")
⎿ 3 paths
[!NOTE] 用户使用
Ctrl+O展开任意行时,直接调用 Pi 原生渲染逻辑,完整展示全部参数与输出文本。
📦 快速安装
当前版本支持通过本地路径向 Pi 注册:
git clone https://github.com/nanvon/pi-tool-ui.git
cd pi-tool-ui && npm install && pi install ./ -l
安装完成后重启 pi 即可生效。如需卸载,从 ~/.pi/agent/settings.json 的 packages 列表中移除对应条目。
[!TIP] 启动时终端若提示内置工具被覆盖,此为 Pi 正常加载告知,不影响功能执行。
🎨 配套主题
扩展内置 tool-ui-light 与 tool-ui-dark 两套主题。安装包时会自动注册,但不会直接覆盖用户配置。
主题将 toolPendingBg、toolSuccessBg 与 toolErrorBg 统一配置为终端默认底色。适用于未认领的第三方工具,以及 edit 工具在运行中、报错或展开态切回原生渲染时的无边框显示。
在 ~/.pi/agent/settings.json 中配置自适应主题切换:
"theme": "tool-ui-light/tool-ui-dark"
或在交互界面中通过 /settings 命令手动选择单套主题。
🔍 边界与设计原则
扩展仅负责已认领工具在折叠态下的终端字符排版,严格遵循以下行为边界:
支持的特性
- 紧凑两行结构 — 调用行统一以
⏺ Tool(args)开头,结果行缩进以⎿ 摘要衔接。 - 单行参数截断 — 展开命令行与路径时优先折叠内部空白字符,超出终端可用列宽自动补
…省略号。 - 结构化结果摘要 — 优先读取工具
details中的匹配数据,未提供时退回文本行数统计。 - 同构接管第三方工具 — 挂载于公共组件原型,使第三方检索工具与内置工具享有同等视觉规范。
- 状态感知高亮 — 工具执行报错(
isError: true)时,摘要行以主题错误色渲染。 - 展开态完整回退 —
Ctrl+O展开时交由原生渲染器绘制完整上下文,不遗漏内容。
明确不做的非目标
- 不修改 Agent 行为 — 不代理、不包装、不改写底层工具逻辑;
execute、parameters与description保持原生输入输出,模型视界无变化。 - 不丢弃输出行 — 未匹配认领规则或摘要异常的行,原样退回原生渲染器绘制。
- 不持久化压缩历史 — 对话回合完成后不对会话记录进行二次重排或折叠。
- 零额外运行时配置 — 不引入外部配置文件与交互开关;提供
/tool-ui命令查询运行时拦截状态。
🧩 支持工具矩阵
内置工具
| 工具标识 | 调用行渲染 | 结果行摘要规格 | 状态策略 |
|---|---|---|---|
read |
⏺ Read(path) |
214 lines |
实时生效 |
edit |
⏺ Edit(path) |
+2 −1 · 2 blocks replaced |
仅在执行完成后生效(settledOnly) |
grep |
⏺ Grep(pattern: …, path: …) |
38 matches · 6 files |
实时生效 |
bash |
⏺ Bash(command) |
24 lines |
实时生效 |
ls |
⏺ Ls(path) |
12 entries |
实时生效 |
find |
⏺ Find(pattern: …, path: …) |
7 paths |
实时生效 |
write |
⏺ Write(path) |
58 lines |
实时生效 |
第三方与扩展工具
| 工具来源 | 工具标识 | 调用行渲染 | 结果行摘要规格 |
|---|---|---|---|
| fff | ffgrep |
⏺ Grep(pattern: …, path: …) |
38 matches · 6 files |
| fff | fffind |
⏺ Find(pattern: …, path: …) |
7 paths |
| fff | fff-multi-grep |
⏺ MultiGrep(patterns: …) |
38 matches · 6 files |
| MCP 工具 | mcp__*__<tool> |
自动剥离命名空间前缀,映射至对应同名工具规格 | 同上 |
[!IMPORTANT]
edit工具包含settledOnly语义:在执行中(需要观察实时 Diff 预览)、执行出错(需观察具体错误信息)以及Ctrl+O展开时,均退回 Pi 原生渲染。
🔌 实现架构与降级机制
为什么采用原型拦截 (Prototype Patch)
Pi 在解析同名工具时遵循首位优先(First-registration-wins)策略,且 ExtensionAPI 未提供读取其他扩展 execute 实现的接口。通过常规 registerTool 无法拦截并重绘第三方扩展已注册的工具。
本扩展直接拦截顶层导出的公共类 ToolExecutionComponent.prototype.render。该组件负责绘制所有工具执行行,工具名称为其运行时实例属性。以此实现一套逻辑同时覆盖内置与第三方工具。
降级防护矩阵
所有拦截路径均设有结构检查与异常回退保护,降级时无条件回退至 Pi 原生组件渲染:
| 触发场景 | 处理策略 | 用户影响 |
|---|---|---|
原型缺失 render 或 updateDisplay |
跳过拦截安装 | 保持原生完整渲染 |
Pi 版本低于 0.84.0 |
跳过拦截安装 | 保持原生完整渲染 |
| 运行时无法获取版本号 | 依据组件结构特征动态检测 | 结构匹配则继续启用 |
实例缺失 toolName 属性 |
单行回退原生渲染 | 该行显示原生样式 |
| 未在认领列表中的工具 | 单行回退原生渲染 | 该行显示原生样式 |
| 主题尚未捕获就绪 | 单行回退原生渲染 | 首帧或就绪前显示原生样式 |
| 摘要解析计算异常 | 单行回退原生渲染 | 避免界面白屏或崩溃,显示原生文本 |
| 多扩展冲突防护 | 基于全局 Symbol 链式挂载 | 允许其他插件在上游或下游拦截 |
🔒 凭据与安全说明
| 维度 | 涉及范围 | 行为与安全说明 |
|---|---|---|
| 凭据与密钥 | 无 | 纯 UI 排版扩展,不读取、不写入、不转发系统凭据或 API Key |
| 网络通信 | 无 | 无外部依赖请求,所有截断与摘要计算在本地内存同步完成 |
| 状态持久化 | 无 | 不修改本地会话存储(JSONL 或数据库文件),不持久化任何数据 |
| Agent 执行链 | 零副作用 | 不改写工具入参及出参,不干扰 LLM 上下文感知 |
🔧 运行环境与兼容性
- 运行时环境:Node.js
>= 22 - Pi 版本:
@earendil-works/pi-coding-agent >= 0.84.0 < 0.86.0 - TUI 依赖:
@earendil-works/pi-tui >= 0.84.0 < 0.86.0
在 Pi 会话中执行 /tool-ui 可实时查询当前拦截器的挂载状态与版本判定结果。
🧪 本地开发与测试
# 1. 安装依赖
npm install
# 2. 执行静态检查、类型检查与单元测试
npm run verify
# 3. 在隔离环境中调试(排除其他扩展干扰)
npm run pi:dev
模块结构
| 文件路径 | 模块职责 |
|---|---|
extensions/tool-ui/patch.ts |
原型拦截挂载、卸载、环境检测与链式执行管理 |
extensions/tool-ui/rows.ts |
声明支持工具列表、参数提取与行级渲染规格 |
extensions/tool-ui/format.ts |
纯函数字符串处理、Diff 统计与行数计算 |
extensions/tool-ui/index.ts |
渲染主流程、主题捕获与 /tool-ui 状态命令实现 |
📄 许可证
本项目遵循 MIT License 开源协议。