Skip to content

Icicno/opencodeBar

Repository files navigation

opencode-bar

OpenCode TUI 底部状态栏插件,实时显示 LLM API 调用的 token 性能指标。

screenshot

简体中文 | English

显示效果

⚡ 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

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

关键注意事项

  • 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 }
}

配置

插件配置位于两个位置(自动合并,项目级优先):

  1. 项目级.opencode/opencode-bar.json
  2. 全局级~/.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 指标采用双通道:

  1. 估算值(流式过程中):基于文本字符长度 / estimationRatio
  2. 精确值(请求完成后):来自 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 过滤

通过 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

About

OpenCode TUI status bar plugin — real-time token performance metrics for LLM API calls.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors