# 📊 dsh-usage-estimator
**侧边栏用量监控插件,支持 [opencode.go](https://opencode.ai/docs/zh-cn/go/) 与 [commandcode](https://commandcode.ai/docs/plans/goat)** — 面向 **DeepSeek Harness Web** 的双端插件
实时用量条 · 按模型估算请求数 · 中文 / English 界面
[](LICENSE)
[](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`。
## 🖼️ 截图
**侧边栏用量条**

**按模型估算请求数弹窗** —— 大多数同类插件没有的功能
## ✨ 功能特性
- 📈 **实时用量条** — 两个供应商的滚动 / 每周 / 每月额度,以及重置倒计时。
- 🧮 **按模型估算请求数** — 一张合并表格,横向对比 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 —— 别提交它。