跳到主要内容
    ↑↓ 选择↵ 打开esc 关闭
    中文English
    Yinxe

    Tui Usage

    v1.0.5界面与主题
    @yinxe/opencode-tui-usage

    OpenCode TUI 额度显示插件 - 在侧边栏显示用量和额度信息

    GitHub 星标

    5

    近 30 天 +1

    月装机量

    92

    近 7 天 24

    综合评分SCORE

    36.0

    生态多维模型

    最近提交

    2 个月前

    2026-05-25

    快速安装与配置

    opencode.json

    写入当前项目的 opencode.json,只对这个仓库生效。

    opencode.json

    {
      "$schema": "https://opencode.ai/config.json",
      "plugin": ["@yinxe/opencode-tui-usage@1.0.5"]
    }

    opencode 启动时会通过内嵌运行时自动加载 npm 依赖并缓存至本地目录,无需手动在全局环境执行安装。

    OpenCode TUI 插件,在侧边栏显示用量和额度信息,支持多额度 provider。

    preview

    🤖 Agent 快速安装

    把下面这段提示词发给你的 AI 编码代理(OpenCode 等),即可自动完成安装和配置:

    给用户安装 opencode-tui-usage 插件(@yinxe/opencode-tui-usage)。

    步骤:

    1. ~/.config/opencode/tui.json"plugin" 数组中添加 "@yinxe/opencode-tui-usage@latest"
    2. 如果文件不存在,创建它:
      {
        "$schema": "https://opencode.ai/tui.json",
        "plugin": ["@yinxe/opencode-tui-usage@latest"]
      }
      
    3. 根据用户使用的 AI provider 设置对应的环境变量(任选其一或多个):
      • DeepSeekexport DEEPSEEK_API_KEY="sk-xxxxx"
      • MiniMaxexport MINIMAX_API_KEY="your-key"
      • OpenCode Goexport OPENCODE_GO_AUTH_COOKIE="cookie"export OPENCODE_GO_WORKSPACE_ID="wrk_xxx"
    4. 重启 OpenCode
    5. 打开一个会话,在侧边栏查看用量信息

    提示:本插件已内置环境变量保底支持。即使不创建 usage.provider.json 配置文件,只要设置了上述约定的环境变量就能工作。

    功能特性

    • 📊 支持 plan 型与按量计费型两种 provider
    • 💰 余额展示(按量计费 provider,如 DeepSeek)
    • 📈 额度展示(plan 型 provider,进度条 + rolling/weekly/monthly)
    • 🎨 树线风格展示 Session / Token 用量信息
    • 🔄 自动根据当前会话的 provider 切换数据源
    • 🛠️ 支持扩展新的 provider 适配器

    安装

    ~/.config/opencode/tui.json 中添加插件路径:

    {
      "$schema": "https://opencode.ai/tui.json",
      "plugin": ["@yinxe/opencode-tui-usage@latest"]
    }
    

    重启 OpenCode 使插件生效。

    首次配置或修改插件版本后,下次重启 OpenCode 会花费一些时间从 npm 自动下载安装插件。

    配置额度 Provider

    插件支持多个额度 provider,会根据当前会话的 providerID 自动选择对应的适配器。

    环境变量引用

    配置值支持两种环境变量引用格式,从 process.env 读取实际值:

    格式 示例 说明
    ${VAR} "apiKey": "${MY_KEY}" 旧写法(兼容)
    {env:VAR} "apiKey": "{env:MY_KEY}" 新写法

    保底支持:每个 provider 都有约定的环境变量名称。即使 usage.provider.json 中未配置,只要设置了约定环境变量就能工作。

    Provider 保底环境变量
    DeepSeek DEEPSEEK_API_KEY
    MiniMax MINIMAX_API_KEY
    OpenCode-Go OPENCODE_GO_AUTH_COOKIE + OPENCODE_GO_WORKSPACE_ID

    MiniMax-CN

    适用于 providerIDminimax-cn-coding-plan 的会话。

    创建 ~/.config/opencode/usage.provider.json

    {
      "providers": {
        "minimax-cn-coding-plan": {
          "apiKey": "${MINIMAX_API_KEY}"
        }
      }
    }
    

    设置环境变量:

    export MINIMAX_API_KEY="your-api-key-here"
    

    OpenCode-Go

    适用于 providerIDopencode-go 的会话。

    ~/.config/opencode/usage.provider.json 中添加:

    {
      "providers": {
        "opencode-go": {
          "cookie": "${OPENCODE_GO_AUTH_COOKIE}",
          "workspaceId": "${OPENCODE_GO_WORKSPACE_ID}"
        }
      }
    }
    

    设置环境变量:

    export OPENCODE_GO_AUTH_COOKIE="your-cookie"
    export OPENCODE_GO_WORKSPACE_ID="wrk_xxxxxxxxxxxx"
    

    DeepSeek

    适用于 providerIDdeepseek 的按量计费会话。

    ~/.config/opencode/usage.provider.json 中添加:

    {
      "providers": {
        "deepseek": {
          "apiKey": "{env:DEEPSEEK_API_KEY}"
        }
      }
    }
    

    设置环境变量:

    export DEEPSEEK_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    

    获取 OpenCode-Go 配置

    1. 登录 https://opencode.ai
    2. 打开浏览器开发者工具 → Network
    3. 访问 /workspace/{workspaceId}/usage 页面
    4. 找到 _server 请求,从 Request Headers 复制完整的 cookie
    5. workspaceId 从 URL 中获取(格式:wrk_ 开头)

    开发

    # 安装依赖
    npm install
    
    # 类型检查
    npm run lint
    
    # 构建输出到 dist/
    npm run build
    
    # 监听模式(开发时使用)
    npm run dev
    

    目录结构

    src/
    ├── tui.tsx              # 插件入口,注册 sidebar_content slot
    ├── formatters.ts        # 格式化工具
    ├── components.tsx       # 可复用组件 (TreeItem, Collapsible, ProgressBar)
    ├── balance-view.tsx     # 余额展示组件(按量计费)
    ├── usage.tsx            # 额度展示组件(plan 型)
    ├── session-info.tsx     # Session 组件(含 Context 合并)
    ├── tokens-usage.tsx     # Token 统计组件(树线展示)
    ├── index.ts             # 重新导出
    └── quota/               # 额度/余额服务
        ├── types.ts         # QuotaData, BalanceData 类型定义
        ├── provider.ts      # QuotaProvider + BalanceProvider 接口
        ├── service.ts       # QuotaService 多 provider 管理
        ├── config.ts        # 读取 usage.provider.json
        └── providers/       # provider 适配器
            ├── minimax.ts
            ├── opencode-go.ts
            └── deepseek.ts  # 按量计费(Balance + Quota 双接口)
    

    添加新的 Provider 适配器

    支持两种类型的 provider:

    类型 接口 适用场景 展示组件
    Quota (额度) QuotaProvider plan 型(coding plan / token plan) UsageView(进度条 + rolling/weekly/monthly)
    Balance (余额) BalanceProvider 按量计费(pay-as-you-go) BalanceView(余额数值)

    一个 provider 可以同时实现两个接口(如 DeepSeek 无 plan quota 但提供余额查询)。

    1. 抓包获取 API

    在浏览器中打开目标网站的额度页面(如 https://example.com/workspace/xxx/usage),打开开发者工具 → Network,找到获取额度数据的请求:

    • Chrome/Edge: 右键请求 → Copy → Copy as cURL
    • Firefox: 右键请求 → Copy Value → Copy as cURL

    2. 调试 curl,精简参数

    拿到 curl 后,在终端中反复调试,逐步移除不必要的 headers 和参数,直到找到最小可复现的请求。常用技巧:

    # 逐步删除 headers,看哪些是必需的(通常是 Authorization/Cookie)
    # 移除浏览器特有的 headers:sec-fetch-*, user-agent, referer, accept-language 等
    # 保留核心:认证信息 + Content-Type
    
    # 调试过程中可以用 | jq 格式化响应,方便分析
    curl -s 'https://example.com/api/quota' \
      -H 'Authorization: Bearer xxx' \
      | jq .
    

    目标:得到一个稳定可复现参数最少的 curl 命令。

    3. 分析响应结构

    运行精简后的 curl,将响应字段映射到对应数据结构:

    QuotaData(plan 型):

    响应字段 QuotaData 字段 说明
    xxx.total / xxx.used rolling.usage 计算百分比
    xxx.reset_time rolling.reset formatDurationCompact() 格式化

    BalanceData(按量计费型):

    响应字段 BalanceData 字段 说明
    xxx.total_balance totalBalance 总余额
    xxx.currency currency 币种

    4. 编写适配器

    src/quota/providers/ 创建 {name}.ts

    Plan 型(实现 QuotaProvider): 参考 minimax.tsopencode-go.ts

    import type { QuotaData, ProviderConfig } from "../types.js";
    import { QuotaProvider, resolveEnvVar } from "../provider.js";
    
    export class MyQuotaProvider implements QuotaProvider {
      readonly name = "my-provider";
      private apiKey: string | undefined;
    
      init(config: ProviderConfig, _credentials: Record<string, unknown>): void {
        this.apiKey = resolveEnvVar(config.apiKey as string | undefined);
      }
    
      async fetchQuota(): Promise<QuotaData | null> {
        // 调用 API 并映射为 QuotaData(rolling/weekly/monthly)
      }
    }
    

    按量计费型(实现 BalanceProvider): 参考 deepseek.ts

    import type { BalanceData, QuotaData, ProviderConfig } from "../types.js";
    import { QuotaProvider, BalanceProvider, resolveEnvVar } from "../provider.js";
    
    export class MyBalanceProvider implements QuotaProvider, BalanceProvider {
      readonly name = "my-provider";
    
      init(config: ProviderConfig, _credentials: Record<string, unknown>): void {
        this.apiKey = resolveEnvVar(config.apiKey as string | undefined);
      }
    
      // QuotaProvider:无 plan quota 时返回 null
      async fetchQuota(): Promise<QuotaData | null> { return null; }
    
      // BalanceProvider:返回余额数据
      async fetchBalance(): Promise<BalanceData | null> {
        // 调用 API 并映射为 BalanceData
      }
    }
    

    5. 注册到 QuotaService

    src/quota/service.ts 构造函数中注册:

    import { MyQuotaProvider } from "./providers/my-provider.js";
    this.registerProvider(new MyQuotaProvider());
    

    6. 添加配置

    ~/.config/opencode/usage.provider.json 中添加 provider 配置:

    {
      "providers": {
        "my-provider": {
          "apiKey": "${MY_API_KEY}"
        }
      }
    }
    

    7. 测试

    构建并重启 OpenCode,切换到对应 provider 的会话,检查侧边栏是否正常显示额度数据。

    调试

    查看插件日志:

    cat ~/.local/share/opencode/log/$(ls -t ~/.local/share/opencode/log/ | head -1) | grep -i "tui.plugin\|error\|QuotaService\|DeepSeek"
    

    常见问题:

    问题 原因 解决方案
    侧边栏无显示 缺少 "oc-plugin": ["tui"] 检查 package.json
    JSX 报错 缺少 pragma 每个 .tsx 顶部加 /** @jsxImportSource @opentui/solid */
    显示 "No data" provider 未注册或配置缺失 检查 usage.provider.json 和环境变量
    opencode-go 500 错误 cookie 过期或 headers 不对 重新抓包获取最新 cookie

    技术栈

    • Solid.js - 响应式 UI 框架
    • @opentui/solid - TUI 组件库(<box>, <text> 等)
    • TypeScript - 类型安全

    CI/CD 自动化发版

    本项目使用 GitHub Actions 实现自动化发版。推送 v* 格式的 tag 后,同时发布到 npm 和 GitHub Packages

    发布流程

    使用 npm version 管理版本号(会自动创建 tag):

    # 更新版本并创建 tag
    npm version patch  # 0.0.1 → 0.0.2
    npm version minor  # 0.0.1 → 0.1.0
    npm version major  # 0.0.1 → 1.0.0
    
    # 推送 tag 触发 CI/CD
    git push origin v0.0.3
    

    自动触发的工作流

    推送 tag 后,以下 job 会自动执行:

    build → publish-npm + publish-github
    
    Job 目标 依赖
    build 安装依赖、构建项目、运行测试 -
    publish-npm 发布到 npm registry build
    publish-github 发布到 GitHub Packages build

    首次发版配置

    1. GitHub Packages 认证

      • 无需额外配置,使用内置 GITHUB_TOKEN
    2. npm 认证(如需发布到 npm)

      • npm.npmjs.com 创建 Access Token
      • 在 GitHub 仓库 Settings → Secrets and variables → Actions 添加 secret:
        • Name: npm_token
        • Secret: 你的 npm access token
    3. scoped 包配置

      • 包名 @yinxe/opencode-tui-usage 已在 package.json 中配置
      • publishConfig.registry 指定发布到哪个 registry

    发布地址

    平台 包名 地址
    npm @yinxe/opencode-tui-usage https://www.npmjs.com/package/@yinxe/opencode-tui-usage
    GitHub Packages @yinxe/opencode-tui-usage https://github.com/Yinxe/opencode-tui-usage/packages

    License

    MIT