@qinggangli/pi-statusbar
pi 自定义状态栏:git 分支 / token 用量 / 实时花费 / TTFT / tok/s / 上下文占用 / 订阅额度
Package details
Install @qinggangli/pi-statusbar from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@qinggangli/pi-statusbar- Package
@qinggangli/pi-statusbar- Version
1.5.0- Published
- Oct 12, 2026
- Downloads
- 1,237/mo · 228/wk
- Author
- qinggangli
- License
- MIT
- Types
- extension
- Size
- 164.5 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-statusbar
pi 自定义状态栏扩展:展示 git 分支、token 用量、实时花费、首 token 耗时、输出吞吐、上下文占用与订阅额度。
npm 包名是
@qinggangli/pi-statusbar(带 scope)。裸名pi-statusbar被 npm 以“Package name too similar to existing packagepi-status-bar”拒绝——那个是 pi 官方发的同类扩展,不是本仓库。在 npm 搜pi-statusbar也能搜到本包。
main │ ↑12.3k ↓45.6k ⚡100k·85% $0.123 ⏱980ms 128 tok/s │ ▰▰▰▱▱▱▱▱▱▱ 23% │ GLM 5h 12%(3h56m)·1周 34%(6d10h) │ glm-5.3·high │ LSP Active
五种布局(layout)可选:
- 底部单行 footer(
bottom,上面的示例) - 右侧浮层(
right):类 opencode 的悬浮信息面板,浮在聊天上、遮右缘 - 右侧分栏(
split):占一列、聊天按剩余宽度重新换行,完全不遮挡,仅 fullscreen 模式可用 - 自动右侧浮层(
auto,默认):按终端宽度在浮层与底部单行之间切换 - 自动右侧分栏(
auto-split):按终端宽度在分栏与底部单行之间切换(宽度阈值autoMinWidth,默认 120)
功能
替换内置 footer:
git 分支 │ ↑输入 ↓输出 ⚡缓存·命中率 $花费 ⏱首token 输出tok/s │ 上下文% │ 订阅额度 │ 模型 │ 其他扩展状态实时单价:从 models.dev 拉取官方单价计算花费(本地缓存 24h),失败回落 models.json 的 cost 字段;自动匹配会跳过 0 价的订阅/免费端点,
/statusbar prices强制刷新并显示单价来源与匹配方式(命中 0 价/多候选时给出 priceMap 建议)上下文告警:占用 ≥75% 变黄,≥90% 变红
订阅额度自动发现:按 provider baseUrl 匹配,只显示当前模型所属 provider 的额度
供应商(匹配的 baseUrl) 展示内容 Codex(chatgpt.com,ChatGPT OAuth) 5h / 周等真实额度窗口已用 % + 恢复倒计时 GitHub Copilot(githubcopilot.com,GitHub OAuth) 高级请求 / 聊天 / 补全已用 %;不限量窗口显示 ∞xAI(api.x.ai / cli-chat-proxy.grok.com,OAuth) 返回的订阅 credits 已用 % / 按量消费 / 预付余额;缺失订阅窗口时仅显示真实账单字段 Radius(radius.pi.dev) 组织可用 USD 余额(扣除 reserved),详情含本月实际扣费 GLM Coding Plan(bigmodel.cn / z.ai) 5h / 周 token 窗口已用 % + 恢复倒计时 Kimi(api.kimi.com) 短窗口 / 周配额已用 % + 恢复倒计时 OpenCode Go(opencode.ai/zen/go) 5h / 周 / 月三窗口已用 % + 恢复倒计时 MiniMax Coding Plan(minimaxi.com / minimax.io) 5h / 周窗口已用 % + 恢复倒计时 Command Code(commandcode.ai) 5h / 周窗口已用 %(credits 口径)+ 恢复倒计时 + 剩余积分余额 magpie(本机网关 127.0.0.1:3425) 本会话当前模型实际路由到的那个账号的窗口 / 余额:订阅、套餐、按量都行( GET /v1/magpie/route?session=定位,切模型立即重拉);其余账号在/statusbar quota详情里逐个带过DeepSeek · OpenRouter · Moonshot 开放平台 · SiliconFlow · StepFun · Novita AI 按量账户余额(按量计费,无重置概念) 每个窗口用量后括注恢复倒计时(
45s/13m/2h13m/6d4h:不足 24h 按xhyym,超 24h 按xdyyh,渲染时按重置时刻实时换算,时刻缺失则不显示);底部单行各窗口用·连接,右侧面板逐窗口分行。/statusbar quota强制刷新并显示详情(含各窗口「重置于 2026-09-15 15:45(3h56m)」)鉴权与范围:沿用 Pi 已登录的凭据,不另建登录流程。Copilot 查询使用 Pi 保存的 GitHub OAuth token,而非短期推理 proxy token;GitHub Enterprise 暂不支持。xAI 先验证当前 OAuth 账户,再查询该账户的账单;普通 xAI API key 余额暂不支持,金额从 cents 转为美元,按量消费不冒充订阅窗口。Radius 账单需要当前凭据具备对应权限,余额是组织级数据,不代表个人预算。magpie 走它自己的本机接口
GET /v1/magpie/quotas(与magpie quota --json同一份数据),先问GET /api/hello认身份,因此本机别的服务(vLLM、Ollama…)不会被当成额度源;magpie 的port改过也认(只匹配回环地址,不限定端口)。显示哪个账号由当前模型决定:带会话 id 问GET /v1/magpie/route?session=…(Pi 的X-Magpie-Session)拿本会话这一轮实际被服务的上游模型,取该 provider 的账号;还没有 route 记录时按模型 id 前缀认(kimi-code-cn/k3→kimi-code-cn);两者都没有才退回 magpie 全局最近服务过的账号。切模型立即重拉(不等 TTL)。该 provider 在 magpie 里没有额度卡时(如 Tencent Token Plan)不借别的账号的数字,只在详情里说明原因。额度是 magpie 的缓存读数,详情里会标「读数: …」。局域网共享的 magpie(非回环地址)暂不匹配。查询失败、没有 key 或返回未知结构时不显示假额度,可用/statusbar quota查看原因。Qwen Token Plan、腾讯 Token Plan 尚未接入:前者的用量查询需要控制台 Cookie/secToken,后者需要云管控鉴权,不能仅凭现有推理 API key 自动查询。不扫描或复制浏览器 Cookie,也不估算订阅剩余额度。
终端标题:会话名写入终端标题(
pi · 会话名),不占 footer 宽度(VSCode/Cursor 内置终端看不到时见「排障」)窄终端自适应:按 扩展状态 → 额度/token → 模型 的顺序逐段收起,仍放不下时整段换行成多行(分支与上下文永不丢弃)
布局可选(layout):
bottom/right/auto自动浮层(默认)/auto-split自动分栏 /split始终分栏,详见「布局」一节Agent 面板入栏:分栏布局(
split/auto-split)下把 pi-subagents 的异步 agent 面板搬进右栏(状态卡片下方),点击折叠等交互保留;默认开,/statusbar dock on|off或交互菜单切换指标显隐可配置:交互式勾选要展示的指标(分支 / 上下文 / 模型 / effort / 用量 / TTFT / 吞吐 / 额度 / 扩展状态),即时预览,保存写回配置文件
hiddenMetrics字段配置面板中英双语:
language配置项或菜单内 ←→ 实时切换,菜单/指标选择器/提示文案跟随语言单一命令
/statusbar:无参数打开交互式菜单,集中管理布局、边框、填充、Agent 入栏、语言、指标显隐与启停;也支持子命令快捷方式。新会话默认恢复自定义样式
安装
# 从 npm 安装(推荐,不需要 GitHub 访问权限)
pi install npm:@qinggangli/pi-statusbar
# 更新(未固定版本时跟随 latest)
pi update --extensions
# 固定版本(固定后 pi update --extensions 会跳过它)
pi install npm:@qinggangli/pi-statusbar@1.0.0
# 临时试用(不落盘)
pi -e npm:@qinggangli/pi-statusbar
# 卸载(配置文件 ~/.pi/agent/statusbar.json 会残留,不需要可一并删除)
pi remove npm:@qinggangli/pi-statusbar
跟着主线代码跑(开发/尝鲜)可以走 git 源:
pi install git:github.com/Lqg97/pi-statusbar
pi remove git:github.com/Lqg97/pi-statusbar
两个源别同时装:pi 的去重分别按 npm 包名和 git 仓库 URL 计算,两个源会被当成两个包各自加载一份扩展(先
pi remove掉旧的那条)。
配置(可选)
配置文件:~/.pi/agent/statusbar.json(可用环境变量 PI_STATUSBAR_CONFIG 覆盖路径)。新会话时重读,改完开新会话即生效。
{
// 本地模型 → models.dev 单价映射(一般不需要,见下方自动匹配)
// key 为本地 "provider:model" 或裸 "model",value 为 [models.dev provider, models.dev 模型 id]
"priceMap": {
"my-relay:glm-5.3": ["zhipuai", "glm-5.3"],
"deepseek-v4.1-flash": ["deepseek", "deepseek-v4-flash"]
},
// 按文本包含隐藏其他扩展的 footer 状态(默认 ["LSP Inactive"])
"hideExtStatuses": ["LSP Inactive"],
// 布局:"bottom" 底部单行 / "right" 右侧浮层(浮在聊天上)
// / "auto" 自动右侧浮层(默认)/ "auto-split" 自动右侧分栏
// / "split" 右侧分栏(占一列、聊天按剩余宽度重新换行、完全不遮挡,仅 fullscreen 可用)
// split / auto-split 时扩展会自动把 pi 的 tuiMode 设为 fullscreen(切回其他布局时还原)
"layout": "auto",
// 右侧面板宽度(列),默认 32,范围 [20, 60]
"rightWidth": 32,
// 两种 auto 模式的宽度阈值(列),默认 120,范围 [40, 400]:
// 终端 ≥ 该值时切到右侧(auto 用浮层 / auto-split 用分栏),否则底部单行
"autoMinWidth": 120,
// 面板边框字符集:"auto"(默认,只跟随 PI_STATUSBAR_BORDER 环境变量)/ "unicode"(┌─┐│└┘)/ "ascii"(+ - |)。
// 注:曾按 TERM_PROGRAM=vscode 自动猜 ascii,实测那类「边框错位」残影来自终端渲染器本身、
// 与方框字形无关(ascii 并不能修),已去掉猜测,只留手动切换;也可用 /statusbar border 切换
"panelBorder": "auto",
// 分栏面板是否把边框铺满整屏高度:true(默认)/ false(高度贴内容)。
// 只对分栏布局(split / auto-split)有意义(浮层本来就贴合内容);也可用 /statusbar fill on|off
"panelFill": true,
// split 分栏时把 pi「编辑器上方」的 widget 容器(pi-subagents 的 agent 面板)搬进右栏:
// 状态面板在上、agent 面板在下,点击折叠等交互保留(默认 true)。
// 入栏期间 panelFill 自动让位(状态面板贴内容);也可用 /statusbar dock on|off
"dockWidgetsInSplit": true,
// 隐藏的指标(可选:branch/ctx/model/effort/usage/ttft/speed/quota/ext),默认 [](全部显示);
// 也可用 /statusbar metrics 交互式配置(会写回此字段)。示例:["ttft"]
"hiddenMetrics": [],
// 配置面板显示语言:"zh" / "en"(默认 zh),/statusbar 菜单语言行 ←→ 切换
"language": "zh"
}
单价匹配规则(按顺序取第一个命中):
priceMap中"provider:model"精确映射priceMap中裸"model"映射- models.dev 中同名 provider + 同名模型直接匹配
- 模型注册表单价(models.json 手写的
cost/ pi 内置目录,非零才采用) - models.dev 全量中按模型 id 自动匹配(忽略大小写;官方 provider 优先,排除 0 价的订阅/免费端点,其余取输入+输出单价最低者;若同名条目全部 0 价则取其一并标记)
自动匹配到 0 价条目(典型:订阅制端点,花费会显示 $0)或存在多个同名候选时,/statusbar prices 会给出警告并建议配置 priceMap 固定来源。
本地中转站/网关的模型名与官方名不一致时(如 kimi-for-coding 实为 kimi-k2.7-code)才需要显式 priceMap。
布局
两种自动模式(auto / auto-split)都按终端宽度自动切换(阈值 autoMinWidth,默认 120,范围 [40, 400],可配),resize 实时生效、无需重启会话:
layout |
≥ autoMinWidth |
< autoMinWidth |
|---|---|---|
auto(默认) |
右侧浮层 | 底部单行 |
auto-split |
右侧分栏 | 底部单行 |
进入右侧时状态收进竖卡(Branch / Ctx / Model / In / Out / Cache / Cost / TTFT / Speed / Quota 每行一项,带边框),底部 footer 让位。竖卡有两种实现:
- 右侧浮层(
auto/right):非捕获 overlay,不抢键盘焦点,但会遮住聊天内容右缘(regular 模式没有布局树,pi 扩展 API 无法分栏)。 - 右侧分栏(
auto-split/split):把 pi 的核心布局根(transcript + 底部 dock)包进HStack,右侧挂状态卡片——与 opencode 的flexDirection="row"同构:聊天按剩余宽度重新换行,整屏高卡片,不遮挡任何内容。split是显式选择,所以不再套autoMinWidth阈值:只要宽度 ≥rightWidth + 24就分栏(避免把聊天压成一条),更窄才退回底部单行;auto-split则同时要求 ≥autoMinWidth与 ≥rightWidth + 24。
想调宽度阈值只改一个字段(两种自动模式共用):
{ "layout": "auto-split", "autoMinWidth": 100, "rightWidth": 28 }
右侧分栏的前提是 fullscreen 模式(alt-screen,只有它有布局树)。这个前提不用你手动配:布局切到 split / auto-split 时扩展会自己把 pi settings.json 的 tuiMode 写成 "fullscreen"(改前的值存到 statusbar.json 的 tuiModeBackup,切回其他布局时还原),所以只配一个字段就够了。
(旧配置里单独的 "split": true 会在读取时自动迁移为 "layout": "split",无需手改。)
只需注意生效时机:TUI mode 是启动时读取的,所以:
/statusbar layout split → 提示「已自动把 TUI mode 设为 fullscreen:重启 pi 后生效」
/statusbar layout auto-split → 同上(分栏要等重启后才能用,本次会话先走底部单行)
重启 pi → 右侧直接变成右侧分栏(auto-split 下宽够才分栏)
(也可以 /settings → TUI mode 当场切,效果一样。)外部写入不会被 pi 覆盖:pi 保存 settings.json 时只合并「本次修改的字段」,其他字段原样保留。
regular 模式下选 split / auto-split 不会报错,而是退回底部单行、且不再创建浮层——因为浮层会让 pi 拒绝切换 TUI mode(Close active overlays before changing TUI mode)。auto-split 在这时还会顺手把 pi 的 tuiMode 补成 fullscreen(同样提示重启),下次启动就真能分栏。
Agent 面板入栏(dockWidgetsInSplit,默认开)
split 分栏时,把 pi「编辑器上方」的 widget 容器(pi-subagents 的异步 agent 面板就在这里)整体搬进右栏:
- 状态面板在上、agent 面板在下,底部只剩编辑器 + footer
- 鼠标点击折叠等交互按布局位置命中,搬动后照常可用
- 入栏期间
panelFill自动让位:状态面板贴内容,agent 面板占剩余高度 /statusbar dock on|off或交互菜单切换,立即重排- 仅分栏布局(
split/auto-split)生效:其余布局(底部单行/浮层)不动布局树,agent 面板仍在底部
命令
| 命令 | 说明 |
|---|---|
/statusbar |
无参数打开交互式菜单:布局(auto/auto-split/bottom/right/split)/ 面板边框 / 面板填充 / Agent 面板入栏 / 语言(光标在对应行时 ←→ 调值,即时生效并写回配置)/ 指标显隐(↑↓ 选择、Space 切换、Enter 保存、Esc 取消)/ 启用停用;Enter 确认、Esc 退出 |
/statusbar on|off |
启用 / 停用自定义状态栏(停用后恢复内置 footer) |
/statusbar layout [right|bottom|auto|auto-split|split] |
切换布局并写回配置,不带参数时按 自动浮层 → 自动分栏 → 底部 → 右侧浮层 → 右侧分栏 循环;选 split / auto-split 会自动把 pi 的 tuiMode 设为 fullscreen(切走时还原) |
/statusbar split [on|off] |
layout split 的快捷别名:on = 右侧分栏(layout split),off = 回到默认布局(auto);不带参数时取反(已是 split / auto-split 则关掉) |
/statusbar border [auto|unicode|ascii] |
面板边框字符集(写回 panelBorder 并立即重绘),不带参数时按 auto → unicode → ascii 循环 |
/statusbar fill [on|off] |
分栏面板是否铺满整屏高度(写回 panelFill 并立即重绘),不带参数时取反;只对分栏布局(split / auto-split)生效 |
/statusbar dock [on|off] |
分栏布局(split / auto-split)下把 agent 面板(pi-subagents 的异步任务 widget)搬进右栏(写回 dockWidgetsInSplit 并立即重排),不带参数时取反 |
/statusbar metrics |
直接进入指标显隐交互式配置 |
/statusbar quota |
强制刷新订阅额度并显示详情 |
/statusbar prices |
强制刷新实时单价并显示当前模型单价来源 |
/exit |
退出 pi(/quit 的别名) |
兼容性
- pi 核心包(
@earendil-works/pi-ai/pi-coding-agent/pi-tui)由 pi 内置提供,声明为 optional peerDependencies:安装时不会重复拉一份 pi 本体(实测首装 ~0.1MB;若声明成必需 peer 会被 npm 连带装 249MB),扩展本身也没有第三方运行时依赖 layout: "split"/"auto-split"与「Agent 面板入栏」依赖较新 pi-tui 的HStack/VStack布局组件;旧版 pi 会静默退回底部单行——看不到分栏时请先升级 pi- 花费计算含阶梯定价,逻辑与 pi-ai 的
calculateCost一致 - 生成中的 tok/s 按字符估算(英文 ~4 字符/token,CJK ~1.5 字符/token),带
~前缀;响应结束后显示精确值
排障
右侧面板边框在不同行「错位」(半格左右的偏移,不是整格)
这是终端渲染器的问题,与扩展无关,但有一条已验证的修法:
- 触发条件:VSCode / Cursor 内置终端把
terminal.integrated.gpuAcceleration设为"off"时用的是 DOM 渲染器,它逐行按文本排版,会对字体回退字形(emoji、▰▱这类符号)做 letter-spacing 补偿 —— 行内地基偏一点,整行后面所有格子跟着偏。split(右侧分栏)下边框和聊天内容在同一行字符串里,于是边框跟着偏;浮层布局下看不明显。 - 修法:把
"terminal.integrated.gpuAcceleration"改回"auto"(或"on")用 WebGL 渲染器;Cmd+Q完全退出、新开终端后生效。 - 验证:
/statusbar layout split下聊几轮(让聊天区出现 emoji/特殊符号),边框应全程笔直。
终端标题不显示(VSCode / Cursor 内置终端)
会话名写在终端标题里(pi · 会话名)。VSCode / Cursor 内置终端默认 terminal.integrated.tabs.title: "${process}",只显示进程名,看不到扩展设置的标题;把它改成 "${sequence}" 后新开终端即可显示。
安全提示
pi 扩展以完整系统权限运行。安装前请审阅 extensions/statusbar.ts 源码(仅有的网络请求:models.dev 单价接口与各 provider 官方额度接口)。