omp packages

@qinggangli/pi-statusbar1.7.0

pi 自定义状态栏:git 分支 / token 用量 / 实时花费 / TTFT / tok/s / 上下文占用 / 订阅额度

GitHub Actions Published 6 days ago MIT ~1.4K downloads/mo

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.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-statusbar

npm

pi 自定义状态栏扩展:展示 git 分支、token 用量、实时花费、首 token 耗时、输出吞吐、上下文占用与订阅额度。

npm 包名是 @qinggangli/pi-statusbar(带 scope)。裸名 pi-statusbar 被 npm 以“Package name too similar to existing package pi-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
pi-statusbar (main) ·harness │ ↑12.3k ↓45.6k ⚡100k·85% $0.123 ⏱980ms 128 tok/s │ ▰▰▰▱▱▱▱▱▱▱ 23% │ glm-5.3·high

第二行是 cwd 停在多仓工作区根、但实际在改 pi-statusbar 时的样子(见「工作焦点」)。

五种布局(layout)可选:

  • 底部单行 footer(bottom,上面的示例)
  • 右侧浮层(right):类 opencode 的悬浮信息面板,浮在聊天上、遮右缘
  • 右侧分栏(split):占一列、聊天按剩余宽度重新换行,完全不遮挡,仅 fullscreen 模式可用
  • 自动右侧浮层(auto,默认):按终端宽度在浮层与底部单行之间切换
  • 自动右侧分栏(auto-split):按终端宽度在分栏与底部单行之间切换(宽度阈值 autoMinWidth,默认 120)

功能

  • 替换内置 footer:git 分支 │ ↑输入 ↓输出 ⚡缓存·命中率 $花费 ⏱首token 输出tok/s │ 上下文% │ 订阅额度 │ 模型 │ 其他扩展状态

  • 工作焦点(focus):分支段展示「用户要求你工作的那个仓库」,而不是硬绑 cwd。cwd 是多仓工作区根时显示 pi-statusbar (main) ·harness(仓库(分支) + 暗色 cwd 后缀);焦点与 cwd 同仓时保持原样 main。来源:/statusbar focus <路径> 手动钉住 > 按工具触碰自动推断 > cwd,另有只读工具 get_work_focus 供模型查询,详见「工作焦点」

  • 实时单价:从 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 的「编辑器上方 / 下方」widget 容器(pi-subagents 的异步 agent 面板、FleetView)搬进右栏(状态卡片下方),点击折叠等交互保留;默认开,/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 容器搬进右栏:
 // 状态面板在上、widget 容器在下,点击折叠等交互保留(默认 true)。
 // 上方容器装 pi-subagents 的异步 agent 面板;下方容器装 FleetView(fleetViewPlacement 默认 belowEditor)。
 // 入栏期间 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"
}

单价匹配规则(按顺序取第一个命中):

  1. priceMap 中 "provider:model" 精确映射
  2. priceMap 中裸 "model" 映射
  3. models.dev 中同名 provider + 同名模型直接匹配
  4. 模型注册表单价(models.json 手写的 cost / pi 内置目录,非零才采用)
  5. 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 容器(tui.children[3]「编辑器上方」与 tui.children[5]「编辑器下方」)整体搬进右栏:

  • 状态面板在上、widget 容器在下,底部只剩编辑器 + footer
  • 上方容器装 pi-subagents 的异步 agent 面板;下方容器装 FleetView(fleetViewPlacement 默认 belowEditor)——两边都搬,面板挂哪一侧都能进右栏
  • 鼠标点击折叠等交互按布局位置命中,搬动后照常可用
  • 入栏期间 panelFill 自动让位:状态面板贴内容,widget 容器占剩余高度
  • /statusbar dock on|off 或交互菜单切换,立即重排
  • 仅分栏布局(split / auto-split)生效:其余布局(底部单行/浮层)不动布局树,widget 容器仍在底部
  • 结构对不上就放弃搬运(容器留在底部),绝不猜:候选必须出现在当前布局树里、且分别是编辑器容器的直接前 / 后兄弟

排障:右栏没有 agent 面板时,先确认异步子任务真的在跑——

  • 前台子任务(async: false,或旧版 pi-subagents 在 Pi 1.2.0 上后台启动失败后被迫退回前台)不写异步 widget,因此面板本来就不会出现
  • pi-subagents ≤ 0.77 在 Pi 1.2.0 上后台子任务全部启动失败(does not provide @earendil-works/chord):后台子任务默认开启(asyncByDefault),失败后只剩前台单发;升级到 0.78+ 并重启 pi(跑着的进程不会换掉已加载的扩展)即可恢复
  • 想把 FleetView 也放进右栏,还可在 ~/.pi/agent/extensions/subagent/config.json 里设 { "fleetViewPlacement": "aboveEditor" }(本扩展已同时支持下方容器,两处都不设也没问题)

工作焦点(focus)

分支段默认只看 cwd 所属的 git 仓库;cwd 不是仓库(典型:多仓工作区根)时退回显示目录名。但实际工作时常常是:会话开在工作区根,人却只要改其中一个仓。这时候状态栏该回答“我在哪个仓的哪个分支上”,而不是把工作区根名当分支显示。

main │ …                              ← 焦点就是 cwd 所属仓库:与以前逐字一致
pi-statusbar (main) ·harness │ …      ← 焦点是另一个仓库:仓库(分支),暗色后缀是 cwd

右侧竖卡是一行 Focus(label 与其他段落一样是英文,config.language 只管配置菜单文案),默认 32 列面板放得下 pi-statusbar (main),再长会自动折行:

┌────────────────────────────────┐
│ Focus   pi-statusbar (main)    │
└────────────────────────────────┘

焦点怎么确定

优先级 来源 说明
1 手动钉住 /statusbar focus <路径>;写入会话分支(appendEntry,customType=statusbar:focus),续接/重载会话时恢复
2 自动推断 工具调用里带上路径的:edit / write 立即抢占(“你在哪干活”的最强信号);read / ls / grep / find 只在尚无焦点时建立焦点,不抢占
3 cwd 默认 没有任何焦点时,回落到 footerData.getGitBranch() / cwd 目录名(即原有行为)

别的细节:

  • 重启/续接会话时会从 transcript 回放一个焦点种子(只看最近的 400 条 assistant 消息:最近的 edit / write 优先,都没有才取最近的读取类调用),否则扩展内存一空、状态栏就退回 cwd —— 用户视角就是“重启后忘了我在哪工作”
  • 非 git 路径(工作区根里的散文件、临时文件)不改变焦点;bash 不参与(命令里解析路径噪音太大)
  • 又改回 cwd 自己那个仓库时,焦点自动复位,外观回到 main
  • git 探测走两条 execFile("git", ["-C", dir, ...]):rev-parse --show-toplevel 取仓库根、symbolic-ref --short -q HEAD 取分支(detached 时回落 rev-parse --short HEAD 取短 sha)。分两条是因为合成一条 rev-parse --show-toplevel --abbrev-ref HEAD 在未出生分支(git init 后还没提交)上会整体报错、连仓库根一起丢。全程无 shell、1.5s 超时、按目录去重 + 2s TTL 缓存;渲染路径只读快照,绝不在渲染里 spawn 进程;cwd 一侧的仓库根也取 git 的返回值(规范路径),因此软链//var→/private/var 这类拼写差异不会让同一个仓库被当成两个
  • 钉住的目录不是 git 仓库时(手动指一个普通目录),Dir 行显示该目录名

模型侧:只读工具 get_work_focus

模型可以问“我现在该在哪个仓库工作”,返回 cwd / 焦点目录 / 仓库根 / 分支 / 来源。工具声明是只读的(readOnlyHint),不会改变焦点。

它执行前会先等「同一条消息里其他工具触发的那次触碰探测」落地:pi 会先把一批工具的全部 tool_call 事件派发完,再并发执行这批次(executeToolCallsParallel),所以 read pi-statusbar/x + get_work_focus 同批时,后者不会回答“上一批”的旧焦点。

为什么不把焦点写进系统提示词

因为会明显压低缓存命中率,而收益不成比例:

  • pi 的系统提示词是按 section 名字 diff 的:内容不变就不发补丁,改了才发。
  • 补丁是一条追加在 transcript 尾部的 system 消息;只有模型 compat 里 supportsMidConvoSystemMessages 为 true 时它才留在尾部(前缀不动、缓存照命中)。
  • 大多数模型(包括本机 magpie 这类 openai-completions 自定义 provider,compat 里没这个字段)会走 collapseSystemMessages:所有 system 消息折叠成开头唯一那条。于是任意 section 变化 = 头部文本变化 = 整个 prompt 前缀从头失效(Anthropic 更直接:头部就是带 cache_control 的 system block)。

一次焦点变化就是一次全量前缀重算(100k 前缀按 cache write 计费约 $0.02~$0.35,看模型档位);更危险的是把易变字段(HEAD sha、脏文件数、时间戳、最近触碰的文件)写进去,那会变成每轮一次。所以这里改成“只展示 + 模型按需查”:提示词与工具声明在会话首个请求就固定,之后不变。

命令

命令 说明
/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)下把 pi 的「编辑器上方 / 下方」widget 容器(异步 agent 面板 / FleetView)搬进右栏(写回 dockWidgetsInSplit 并立即重排),不带参数时取反
/statusbar focus 报告当前焦点:cwd / 焦点目录 / 仓库根 / 分支 / 来源(非交互模式请让模型调 get_work_focus)
/statusbar focus <路径> 把焦点钉到指定目录(相对路径按 cwd 解析;不存在会拒绝),写入会话分支并可被续接恢复;cwd 等价于钉到当前目录
/statusbar focus auto|clear 取消钉住,回到自动推断(保留已经推断出的焦点)
/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 官方额度接口;唯一的本地子进程:工作焦点用 execFile 调 git rev-parse 探测仓库/分支,无 shell、带超时与缓存)。

License

MIT