OpenCode TUI 底部状态栏插件,实时显示 LLM API 调用的 token 性能指标。
⚡ 42.5 t/s ⏱ 312ms ↓ 1.2K in ↑ 639 out ○ 200 ▹ 15s [anthropic/claude-sonnet-4]
| 指标 | 含义 | 计算方式 |
|---|---|---|
⚡ 42.5 t/s |
平均 token 速度 | 输出 tokens / (当前时间 - 首 token 时间) |
⏱ 312ms |
首 token 延迟 (TTFT) | 首个 text delta 到达时间 - 请求开始时间 |
↓ 1.2K in |
输入 tokens | 流式中:用户消息文本长度/4 估算;完成后:API 精确值(含缓存) |
↑ 639 out |
输出 tokens(含 reasoning) | 流式中:delta 长度/4 逐 chunk 累加;完成后:API 精确值 |
○ 200 |
缓存读取命中 tokens | API 返回的 tokens.cache.read |
▹ 15s |
当前请求运行时间(整数秒) | 当前时间 - 请求开始时间 |
[anthropic/claude-sonnet-4] |
模型标识 | providerID/modelID |
行为特征:
- 每次模型请求独立计时
- 请求结束后保留(默认 5 秒,
holdDurationMs=0可永久保留) - 未发起请求时显示空白(回退到 OpenCode 默认 footer)
- 仅追踪主 session(parentID 为空),子 session 请求不显示
- 字体颜色跟随系统 TUI 主题
Bun 运行时原生编译 TypeScript + JSX,直接加载源码 .tsx 文件即可。
Step 1:拉取代码并安装依赖
git clone <repo-url> /path/to/opencode-bar
cd /path/to/opencode-bar
bun install前置条件:需要 Bun 运行时(
>=1.3),OpenCode 本身也依赖 Bun。
Step 2:配置 OpenCode 加载插件
在你的项目(或全局)目录下创建 .opencode/tui.json:
关键注意事项:
- 是
tui.json,不是opencode.json。TUI 插件必须在tui.json中注册file://协议在 macOS 上必须使用绝对路径,如file:///Users/xxx/opencode-bar/src/index.tsx- 路径指向
src/index.tsx(源码)
Step 3:重启 OpenCode 即生效
无需构建步骤。Bun 运行时会在加载时自动编译 .tsx 中的 TypeScript 和 JSX。
(可选)插件运行时配置
如需自定义刷新间隔、显示格式等,在 .opencode/opencode-bar.json 中配置(详见下方配置章节)。
{
"holdDurationMs": 0,
"visible": { "model": false }
}插件配置位于两个位置(自动合并,项目级优先):
- 项目级:
.opencode/opencode-bar.json - 全局级:
~/.config/opencode/opencode-bar.json
完整配置:
{
"enableLogging": false,
"refreshIntervalMs": 200,
"holdDurationMs": 5000,
"estimationRatio": 4.0,
"visible": {
"speed": true,
"ttft": true,
"input": true,
"output": true,
"cache": true,
"elapsed": true,
"model": true
}
}| 配置项 | 默认值 | 说明 |
|---|---|---|
enableLogging |
false |
启用调试日志。日志路径:macOS/Linux ~/.local/share/opentui/opencode-bar/logs/,Windows %LOCALAPPDATA%/opentui/opencode-bar/logs/ |
refreshIntervalMs |
200 |
UI 刷新间隔(毫秒),最小 100 |
holdDurationMs |
5000 |
请求 idle 后保留显示时长。0 = 永久显示 |
estimationRatio |
4.0 |
token 估算比率(字符数 / token),必须 > 0 |
visible.speed |
true |
显示/隐藏速度 ⚡ t/s |
visible.ttft |
true |
显示/隐藏首 token 延迟 ⏱ |
visible.input |
true |
显示/隐藏输入 tokens ↓ in |
visible.output |
true |
显示/隐藏输出 tokens ↑ out |
visible.cache |
true |
显示/隐藏输入缓存命中 ○ |
visible.elapsed |
true |
显示/隐藏运行时间 ▹ |
visible.model |
true |
显示/隐藏模型标识 [model] |
永久显示,隐藏模型名:
{
"holdDurationMs": 0,
"visible": { "model": false }
}仅显示速度和输出 tokens:
{
"visible": {
"speed": true, "ttft": false, "input": false,
"output": true, "cache": false, "elapsed": false, "model": false
}
}所有 token 指标采用双通道:
- 估算值(流式过程中):基于文本字符长度 /
estimationRatio - 精确值(请求完成后):来自 LLM API 的
AssistantMessage.tokens,覆盖估算值
OpenCode 的一次用户交互可能包含多次模型请求(工具调用 → 模型再请求)。插件对每次模型请求独立计时:
用户消息 → busy → [请求1: TTFT/TPS/elapsed] → idle → [工具执行]
→ busy → [请求2: TTFT/TPS/elapsed 重置] → idle
session.status(busy)
→ 创建/重置 RequestMetrics
→ 取消上一轮 hold timer
message.part.updated(text, role=user)
→ 估算输入 tokens(text.length / ratio)
message.part.delta(field=text)
→ 首次 delta 记录 firstTokenTime
→ 逐 chunk 累加 estimatedOutputTokens
message.updated(role=assistant)
→ 从 API tokens 精确覆盖(仅当至少一个值 > 0)
→ 缓存 modelID / providerID
session.status(idle)
→ 标记完成
→ holdDurationMs > 0: 按配置时长后清空
→ holdDurationMs = 0: 永久保留直到下一次请求
通过 session.created / session.updated 事件获取 parentID,仅追踪 parentID 为空的主 session。
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 状态栏不显示 | 插件未正确加载 | 检查 .opencode/tui.json 配置 |
| 插件报 "must export server()" | 配置写在了 opencode.json |
移到 .opencode/tui.json |
JSX 崩溃 H().length |
@opentui/solid 未安装 |
bun add solid-js @opentui/solid @opentui/core |
↓ 始终为 0 |
多层事件时序问题 | 检查 OpenCode 版本 ≥ v1.2 |
TTFT 显示 -- |
模型无 text delta | 正常现象 |
| 永久显示无效 | holdDurationMs=0 被验证拒绝 |
确认配置文件中值为 0(非字符串) |
file:// 加载报错 |
macOS 不支持相对路径 | 使用绝对路径 |
- 运行时:Bun(原生 TypeScript + JSX)
- UI:@opentui/solid(SolidJS for CLI)
- 插件接口:@opencode-ai/plugin/tui(v1 模块格式)
- 构建:tsup(类型检查 + DTS)
- 测试:bun test(36 个用例)
opencode-bar/
├── .opencode/
│ ├── tui.json # TUI 插件注册
│ ├── opencode.json # 项目配置(无 plugin 字段)
│ └── opencode-bar.json # 插件运行时配置
├── src/
│ ├── index.tsx # 主入口(事件处理 + slot 注册 + 工具调用重置)
│ ├── types.ts # 类型定义(RequestMetrics, BarConfig with visible)
│ ├── metrics.ts # 纯函数(formatBar, formatElapsed, estimateTokens 等)
│ ├── config.ts # 配置读取(双路径合并,允许 holdDurationMs=0)
│ ├── logger.ts # Debug logging (cross-platform data directory)
│ └── components/
│ └── BarFooter.tsx # SolidJS 渲染(主题感知,setInterval 刷新)
├── tests/
│ ├── metrics.test.ts # 单元测试
│ └── integration.test.ts # 集成测试
├── docs/
│ └── troubleshooting/ # 14 个问题的完整排查记录
├── package.json
├── tsconfig.json
└── tsup.config.ts

{ "$schema": "https://opencode.ai/config.json", "plugin": ["file:///path/to/opencode-bar/src/index.tsx"] }