# 📊 dsh-usage-estimator **侧边栏用量监控插件,支持 [opencode.go](https://opencode.ai/docs/zh-cn/go/) 与 [commandcode](https://commandcode.ai/docs/plans/goat)** — 面向 **DeepSeek Harness Web** 的双端插件 实时用量条 · 按模型估算请求数 · 中文 / English 界面 [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) [![dsh-plugin](https://img.shields.io/badge/dsh-plugin-purple.svg)](https://github.com/topics/dsh-plugin) **🌐 [Read this in English](./README.md)** ---
**Host 端**在 DSH 自带的 HTTP 服务器上注册 `/quota` 路由 —— 无需独立进程、无需端口、无 CORS。**浏览器端**轮询该路由,并把用量条渲染到侧边栏底部(`sidebar.footer.action` 插槽)。 界面语言跟随你的 DSH 设置(简体中文或 English)。产品词汇有意不翻译:时间窗口标签 `5-Hour` / `Weekly` / `Monthly`,以及供应商名 `OpenCode Go` / `Command Code`。 ## 🖼️ 截图
**侧边栏用量条** Sidebar usage bars **按模型估算请求数弹窗** —— 大多数同类插件没有的功能 Estimated request counts
## ✨ 功能特性 - 📈 **实时用量条** — 两个供应商的滚动 / 每周 / 每月额度,以及重置倒计时。 - 🧮 **按模型估算请求数** — 一张合并表格,横向对比 OpenCode Go 与 Command Code GOAT 各模型每 5 小时 / 每周 / 每月的请求预算。只在某一个计划里出现的模型, 另一计划的列显示斜线(`/`)。 - 🌐 **完整本地化** — 跟随你的 DSH 语言设置(中文 / English)。 - 🔒 **注重隐私** — cookie 读取可选,并有清晰文档说明。 - 📦 **请求数表格零配置** — 直接从官方定价文档抓取,无需登录。 ### 为什么选这两个计划? OpenCode Go 和 Command Code GOAT 是**最实惠的两个 coding 计划** —— 大多数人 日常 coding 用的就是它们。所以插件默认跟踪它们的实时用量和请求预算。 用着别的计划或别的供应商?用量采集器和请求数表格都是可读的纯脚本,插件配置 也可以指向你自己的 workspace id 和额度上限 —— 用 DSH 就能适配成你自己的方案。 数据来源(约每 6 小时缓存): | 来源 | 地址 | |---|---| | 🌐 OpenCode Go | | | 🌐 Command Code GOAT | | ## 📦 安装 **前置条件:** `dsh plugin` 会转发给 pnpm,所以需要 pnpm 在你的 PATH 中: ```bash npm i -g pnpm # 或:corepack enable ``` 然后安装插件: ```bash dsh plugin --profile web add github:lbwfff/dsh-usage-estimator ``` > [!NOTE] > 首次从 git 安装时,pnpm 可能要求你允许其构建脚本 —— 把 pnpm 打印的 > 密钥添加到 `~/.dsh/profiles/web/pnpm-workspace.yaml` 的 `allowBuilds` > 下,然后重新执行安装命令。 然后**重启 dsh web**。插件会自动注册进 profile 的 bundle 层 (`dsh.bundle` + `cordis.patch.yml`)。 ## ⚙️ 配置 插件从 profile patch(`~/.dsh/profiles/web/cordis.patch.yml`)读取设置, 位于该条目的 `config` 下: ```yaml - insert: - id: dsh-usage-estimator name: dsh-usage-estimator config: # 你的 opencode.go workspace id(OpenCode Go 用量条必需) opencodeWorkspaceId: wrk_xxxxxxxxxxxxxxxxxxxxxxxx # 你的 commandcode 月度额度上限(用于计算月度百分比) commandcodeMonthlyCap: 70 # 读取浏览器 cookie 以向官方 API 认证 cookieEnabled: true # 你自己导出的 commandcode.ai HAR 文件路径(备用数据源) # harPath: /path/to/commandcode.ai.har ``` | 字段 | 默认值 | 说明 | |---|---|---| | `opencodeWorkspaceId` | `""` | opencode.go workspace id(`wrk_...`)。留空则禁用 OpenCode Go 用量条。 | | `commandcodeMonthlyCap` | `0` | commandcode 月度额度上限。不设时月度百分比回退到 API 上报的上限,或显示为不可用。 | | `cookieEnabled` | `true` | 读取浏览器 cookie 以向官方 API 认证。设为 `false` 则完全不读 cookie(请求数表格仍可用)。 | | `harPath` | `~/.dsh-usage-estimator/commandcode.ai.har` | 用户自备的 HAR 文件,用于在线 API 不可达时兜底。 | ### 🔑 找到你的 OpenCode Go workspace id `opencodeWorkspaceId` 是唯一**必须你自己填**的字段 —— 它是每个账号独有的值, 插件无法内置。找到它的方法: 1. 在浏览器中登录 [opencode.ai](https://opencode.ai)。 2. 打开你的 workspace 用量页 —— 地址形如 `https://opencode.ai/workspace/wrk_xxxxxxxxxxxxxxxxxxxxxxxx/go`。 3. 复制 `wrk_...` 段,粘贴到 `opencodeWorkspaceId`。 其余都是可选的:只要填了 workspace id(并保持 `cookieEnabled` 开启),插件 就会显示两个供应商的实时用量条和完整请求数表格。留空时,OpenCode Go 用量条 显示清晰的「未配置」提示,其余功能照常工作。 ## 🔒 隐私说明 启用 cookie 模式前请先阅读。 - ✅ **`cookieEnabled: true`(默认)** — 采集器会读取你的浏览器 cookie (依次尝试 Edge、Chrome、Firefox、Safari)中用于 `opencode.ai` 和 `commandcode.ai` 的部分,并且**只**发送给这些官方域名来获取额度。 Cookie 不会离开你的机器前往任何其他地方,也不会被记录或发送给任何第三方。 - 🚫 **`cookieEnabled: false`** — 完全不读取任何 cookie。你会失去实时用量条, 但请求数表格(无需登录)仍然可用。 - 💾 **HAR 兜底** — 如果你自己导出一份 `commandcode.ai` 的 HAR(开发者工具 → Network → 保存),在线 API 不可达时采集器可以从它读取用量。HAR 只留在 你的机器上,**切勿提交到仓库**。 - 🗂️ 采集器只在本地缓存公开的请求数表格 (`~/.cache/dsh-usage-estimator/`),每 6 小时刷新一次。 ## 🏗️ 架构 ``` scripts/quota.py ──────────────(execFile)──> host 端 (lib/index.js) ├─ 用量条 (opencode.go + commandcode 额度) │ └─ requestCounts (2 张定价文档表格合并, 6h 缓存) ▼ 在 ctx.webServer 上注册精确路由 "/quota" DSH web server(同源) │ ▼ 每 10 分钟 fetch("/quota") browser 端 (lib/client.js) │ ▼ ctx.slots.inject("sidebar.footer.action") 侧边栏底部组件(+ 请求数弹窗) ``` - **Host 端**(`lib/index.js`):一个 Cordis 插件,在 web profile 现有的 `webServer` 服务上注册 `/quota` 精确路由。每次请求通过 `execFile` 调用 `scripts/quota.py`,快照缓存 120 秒,以 JSON 返回。你的 cordis `config` 会以 `QM_*` 环境变量的形式传给脚本。启动即注册、关闭即注销 —— 无独立进程。 - **Browser 端**(`lib/client.js`):一个 `window.__ModuleLoader__.load()` bundle,把 React 组件挂载到 `sidebar.footer.action`,每 10 分钟轮询 `/quota`(手动刷新通过 `?force=1` 强制重新抓取)。请求数弹窗使用平台 `Modal` 原语(`@deepseek-ai/dsh-client-ui-primitives`),并通过 DSH 的 locale 插件实现中英文界面。 ## 🧩 文件 | 文件 | 作用 | |---|---| | `lib/index.js` | Host 端入口 — `apply(ctx, config)` 在 `webServer` 上注册 `/quota` 路由 | | `lib/client.js` | 浏览器 bundle — React 组件 + 插槽注入 + 轮询 + 请求数弹窗 | | `scripts/quota.py` | 数据采集器 — 读取 `QM_*` 环境变量,输出 JSON 快照 | | `scripts/requests_count_lib.py` | 请求数表格抓取器 + 名称归一化 + 合并表格 | | `requirements.txt` | Python 依赖(仅 `browser_cookie3`,用于实时用量条) | | `lib/types/*.d.ts` | 类型声明 | | `assets/` | README 截图 | | `test-host.js` | 冒烟测试:启动真实 Cordis + WebServer,访问 `/quota`,打印 JSON | | `package.json` | `dsh.bundle` + `dsh.client` 声明 + `exports["./client"]` | ## ✅ 环境要求 - Python 3 + `browser_cookie3`(仅当 `cookieEnabled: true` 时需要): ```bash pip install -r requirements.txt ``` - 请求数表格不需要额外的 Python 依赖(仅用标准库)。 - **Cookie 读取支持 Edge、Chrome、Firefox、Safari**(按此顺序优先)。采集器 从你登录过的任意一个浏览器中读取 `opencode.ai` / `commandcode.ai` 的 cookie —— 用 Chrome 登录也能用,不限于 Edge。只使用这些浏览器的登录态, 不读取其他任何东西。 ## 🧪 测试 ```bash node test-host.js # [test] webServer listening on 64573 # [test] status: 200 # [test] go.ok: ... | cc.ok: ... | cc.source: ... # [test] requestCounts.opencode.ok: true | rows: 22 # [test] requestCounts.cc_goat.ok: true | rows: 30 # [test] requestCounts.merged rows: 34 # [test] privacy scan: OK # [test] PASS ``` ## 📝 备注 - **数据刷新**:host 端缓存 quota.py 输出 120 秒;浏览器每 10 分钟轮询; 手动刷新通过 `?force=1` 绕过缓存。 - **请求数表格**:quota.py 每 6 小时从文档刷新一次 (`~/.cache/dsh-usage-estimator/requests-count-cache.json`)。 - **侧边栏收起**:折叠成导轨时组件缩成一个状态圆点(展开后仍可打开请求数弹窗)。 - **仓库不携带任何个人数据**:workspace id、额度上限、cookie 开关、HAR 路径 全部来自你的 cordis 配置。需要离线兜底就自己导出 HAR —— 别提交它。