@sligqoer/dsh-usage-stats 0.1.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +135 -1
  2. package/NOTICE +39 -0
  3. package/README.en.md +187 -0
  4. package/README.md +93 -224
  5. package/lib/bridge.js +33 -0
  6. package/lib/client.js +2587 -1159
  7. package/lib/index.js +420 -150
  8. package/lib/lm-fingerprint-engine.js +166 -0
  9. package/lib/lm-fingerprint-source.js +134 -0
  10. package/lib/lm-fingerprint-worker.js +31 -0
  11. package/lib/model-detection-history.js +86 -0
  12. package/lib/model-detection.js +255 -0
  13. package/lib/provider-quotas.js +26 -5
  14. package/lib/quota-controls.js +112 -30
  15. package/lib/supplemental-usage.js +77 -0
  16. package/lib/usage-preferences.js +51 -0
  17. package/locale/en.json +6 -0
  18. package/locale/ja.json +6 -0
  19. package/locale/zh.json +6 -0
  20. package/package.json +28 -18
  21. package/screenshots/controls.png +0 -0
  22. package/screenshots/detection.png +0 -0
  23. package/screenshots/quotas.png +0 -0
  24. package/screenshots/usage.png +0 -0
  25. package/third_party/brand-icons/CHANNEL-ICONS-LICENSE +21 -0
  26. package/third_party/brand-icons/LICENSE +59 -0
  27. package/third_party/brand-icons/NOTICE.txt +5 -0
  28. package/third_party/brand-icons/REACT-ICONS-LICENSE +104 -0
  29. package/third_party/brand-icons/channel-icons/LICENSE +21 -0
  30. package/third_party/brand-icons/channel-icons/UPSTREAM.json +6 -0
  31. package/third_party/brand-icons/lobe-icons/LICENSE +21 -0
  32. package/third_party/brand-icons/lobe-icons/UPSTREAM.json +16 -0
  33. package/third_party/brand-icons/react-icons/LICENSE +13 -0
  34. package/third_party/brand-icons/react-icons/UPSTREAM.json +6 -0
  35. package/third_party/lm-fingerprint/LICENSE +21 -0
  36. package/third_party/lm-fingerprint/UPSTREAM.json +32 -0
  37. package/third_party/lm-fingerprint/core/challenge-browser.mjs +210 -0
  38. package/third_party/lm-fingerprint/core/detector-codec.mjs +20 -0
  39. package/third_party/lm-fingerprint/core/fingerprint-core.mjs +121 -0
  40. package/third_party/lm-fingerprint/core/positional.mjs +64 -0
  41. package/third_party/lm-fingerprint/core/shared-detector.mjs +132 -0
  42. package/third_party/lm-fingerprint/data/shared_detector.bin +0 -0
  43. package/third_party/lm-fingerprint/data/unified_bank.json +826820 -0
  44. package/README.zh-CN.md +0 -318
package/README.zh-CN.md DELETED
@@ -1,318 +0,0 @@
1
- <p align="center">
2
- <img src="screenshots/icon.svg" alt="dsh-usage-stats" width="80" height="80">
3
- </p>
4
-
5
- <h1 align="center">dsh-usage-stats</h1>
6
-
7
- <p align="center">
8
- <strong>在 DSH 里,看清 Token 用量、账户余额与订阅配额。</strong><br>
9
- 为 <a href="https://github.com/deepseek-ai/deepseek-harness">DeepSeek Harness 桌面端</a>打造的本地用量面板。
10
- </p>
11
-
12
- <p align="center">
13
- <a href="#安装"><img src="https://img.shields.io/badge/DSH-Desktop-2563eb?style=flat-square" alt="DSH 桌面端"></a>
14
- <a href="https://github.com/Jockjrop/dsh-usage-stats/releases/latest"><img src="https://img.shields.io/github/v/release/Jockjrop/dsh-usage-stats?style=flat-square&amp;color=64748b" alt="最新发行版"></a>
15
- <a href="LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0-22c55e?style=flat-square" alt="Apache 2.0 许可"></a>
16
- </p>
17
-
18
- <p align="center">
19
- <a href="README.md">English</a> · 简体中文<br>
20
- <a href="https://github.com/Jockjrop/dsh-usage-stats/releases/latest">下载</a> ·
21
- <a href="#功能">功能</a> ·
22
- <a href="#安装">安装</a> ·
23
- <a href="#使用">使用</a> ·
24
- <a href="#常见问题">常见问题</a> ·
25
- <a href="CHANGELOG.md">更新日志</a> ·
26
- <a href="https://github.com/Jockjrop/dsh-usage-stats/issues">反馈问题</a>
27
- </p>
28
-
29
- <p align="center">
30
- <a href="screenshots/usage.png"><img src="screenshots/usage.png" alt="用量面板:概览指标、今日图表与使用量热力图" width="800"></a>
31
- </p>
32
-
33
- <p align="center"><sub>从今天用了多少,到长期使用趋势,一眼看清。</sub></p>
34
-
35
- <table align="center">
36
- <thead>
37
- <tr><th align="center">配额</th><th align="center">控制</th></tr>
38
- </thead>
39
- <tbody>
40
- <tr>
41
- <td align="center"><a href="screenshots/quotas.png"><img src="screenshots/quotas.png" alt="供应商余额与 WorkBuddy 积分" width="400"></a></td>
42
- <td align="center"><a href="screenshots/controls.png"><img src="screenshots/controls.png" alt="自动查询设置与自定义配额查询" width="400"></a></td>
43
- </tr>
44
- <tr>
45
- <td align="center">集中查看供应商余额与 WorkBuddy 积分。</td>
46
- <td align="center">设置自动刷新间隔和自定义配额查询。</td>
47
- </tr>
48
- </tbody>
49
- </table>
50
-
51
- ## 功能
52
-
53
- | 页面 | 你可以做什么 |
54
- | --- | --- |
55
- | **用量** | 查看今日与累计 Token、使用天数、小时调用次数、每日/每周热力图和模型明细。 |
56
- | **配额** | 集中查看已配置平台的余额、订阅额度窗口,以及 WorkBuddy/WorkBuddy AI 积分。 |
57
- | **控制** | 调整查询间隔、设置自定义配额接口、切换模型明细和高级模型选择器。 |
58
-
59
- - **看清使用趋势**:历史图表支持 7/30/365 天和全部,按供应商、模型查看用量。
60
- - **汇总账户配额**:使用内置读取器,也能为自定义供应商映射 JSON 响应。
61
- - **按需刷新**:手动获取或开启定时查询;自动查询默认关闭。
62
- - **更快选择模型**:可开启模型与推理强度面板,拖动滑条调整;关闭后恢复官方选择器。
63
- - **融入桌面界面**:适配浅色/深色主题,图表自适应宽度,标签页固定,供应商选择支持键盘。
64
- - **跟随应用语言**:支持中文、英语和日语,随 DSH 所选语言即时切换;用户自定义名称与配额标签保持原样。
65
-
66
- ## 安装
67
-
68
- **推荐通过 DSH 桌面端安装 [npm 包 `@sligqoer/dsh-usage-stats`](https://www.npmjs.com/package/@sligqoer/dsh-usage-stats)。** 已包含预构建模块,无需克隆仓库或在本机构建;通过包名安装后可使用插件页的「检查更新」。
69
-
70
- ### 1. 打开插件安装入口
71
-
72
- 在 DSH 桌面端主界面的侧栏进入 **插件 → 添加插件**。
73
-
74
- ### 2. 填入完整 npm 包名
75
-
76
- ```text
77
- @sligqoer/dsh-usage-stats
78
- ```
79
-
80
- 将包名粘贴到 **包名或地址**,点击 **安装**。请保留完整的 `@sligqoer/` 前缀。
81
-
82
- ### 3. 启用并打开面板
83
-
84
- 点击 **立即启用**,进入 **设置 → 用量统计**。如果插件管理器提示需要重启,按提示重启 DSH。
85
-
86
- 用量页会读取本地 DSH 会话。进入 **配额**,点击对应卡片的刷新按钮,即可查询账户数据。
87
-
88
- <details>
89
- <summary>安装指定版本或已下载的压缩包</summary>
90
-
91
- 要安装指定版本 `0.1.2`,在同一安装入口填入:
92
-
93
- ```text
94
- @sligqoer/dsh-usage-stats@0.1.2
95
- ```
96
-
97
- 也可以手动安装 [Release 压缩包](https://github.com/Jockjrop/dsh-usage-stats/releases/latest),在安装入口填入以下地址,或下载 `.tgz` 与 `SHA256SUMS` 后填写压缩包的本地绝对路径。安装前无需解压。
98
-
99
- ```text
100
- https://github.com/Jockjrop/dsh-usage-stats/releases/latest/download/dsh-usage-stats.tgz
101
- ```
102
-
103
- ```powershell
104
- Get-FileHash ./sligqoer-dsh-usage-stats-0.1.2.tgz -Algorithm SHA256
105
- ```
106
-
107
- </details>
108
-
109
- <details>
110
- <summary>从源码安装/手动链接开发目录</summary>
111
-
112
- 开发时准备 Git、Node.js 和 pnpm,再构建仓库。以下步骤已在 Windows + Node.js 24 环境验证:
113
-
114
- ```sh
115
- git clone https://github.com/Jockjrop/dsh-usage-stats.git
116
- cd dsh-usage-stats
117
- npm ci
118
- npm run build
119
- ```
120
-
121
- 请将克隆目录保存在固定位置,DSH 会链接到该目录。
122
-
123
- 在 **插件 → 添加插件** 填入克隆目录的绝对路径,安装后点击 **立即启用**。如果选择手动链接,完全退出 DSH 桌面端,备份其 profile 的 `package.json`,然后在**刚克隆的目录内,用 PowerShell** 运行:
124
-
125
- ```powershell
126
- $pluginDir = (Get-Location).Path.Replace('\', '/')
127
- $dshDataDir = if ($env:DSH_HOME) { $env:DSH_HOME } else { Join-Path $env:USERPROFILE '.dsh' }
128
- $profileDir = Join-Path $dshDataDir 'profiles/desktop'
129
- pnpm --dir $profileDir add "link:$pluginDir"
130
- ```
131
-
132
- 打开 `$profileDir/package.json`,在其已有的 `dsh.profile.bundles` 数组末尾加入 `"@sligqoer/dsh-usage-stats"`,保留其他 bundle 条目。
133
-
134
- DSH 桌面端自行管理 desktop profile,不能使用 `dsh plugin --profile desktop`。手动链接完成后,启动应用并进入 **设置 → 用量统计**。
135
-
136
- </details>
137
-
138
- <details>
139
- <summary>更新与卸载</summary>
140
-
141
- **从旧版迁移:** 在「插件」页面卸载旧的 `dsh-usage-stats`,再填入 `@sligqoer/dsh-usage-stats` 安装并启用。包名切换仅需做一次;插件继续使用原有的数据目录、配额接口和设置标识。
142
-
143
- **npm 安装:** 使用插件页的「检查更新」,按提示更新并重启。当前更新检查器只处理直接通过 npm 包名安装的插件。GitHub 地址、压缩包地址、本地路径或 `link:` 安装需要手动升级;这些来源显示「已是最新版本」也不代表没有新发布。
144
-
145
- **Release 安装:** 从「插件」页面卸载后,使用上面的 Release 地址重新安装并启用新版。彻底卸载时,使用同一页面的卸载操作。
146
-
147
- **源码安装:** 完全退出 DSH 桌面端,在克隆目录执行以下命令,再启动应用:
148
-
149
- ```sh
150
- git pull --ff-only
151
- npm ci
152
- npm run build
153
- ```
154
-
155
- **手动链接卸载:** 退出桌面端,从 desktop profile 中仅移除 `@sligqoer/dsh-usage-stats` 依赖和 bundle 条目,在该 profile 运行 `pnpm install`,然后重启。
156
-
157
- </details>
158
-
159
- ## 使用
160
-
161
- **用量**用于查看总量与趋势。悬停图表或热力图格子可以查看明细;切换历史筛选时,概览卡片仍按今日/完整历史口径显示。
162
-
163
- **配额**展示平台接口返回的数据。已配置但尚未查询的余额可能显示 **未查询**;卡片是否可用取决于凭据和账户权限。
164
-
165
- **控制**管理显示与刷新方式:
166
-
167
- | 设置 | 默认值 |
168
- | --- | --- |
169
- | 自动获取配额 | 关闭 |
170
- | 查询间隔 | 1 小时;也可选 10 分钟、5 小时、每天 |
171
- | 模型明细与分布 | 开启 |
172
- | 高级模型选择器 | 关闭 |
173
-
174
- 开启自动查询前需要确认可能产生的查询成本。关闭设置页后,宿主仍按间隔执行;平时打开配额页只读取缓存。
175
-
176
- <details>
177
- <summary><strong>支持的平台与凭据</strong></summary>
178
-
179
- 内置读取器覆盖 Claude、DeepSeek、StepFun、Codex、GitHub Copilot、OpenRouter、Moonshot 国内/国际、Kimi Coding、MiniMax 国内/国际、Z.AI、智谱 GLM Coding、阿里云 Token Plan 国内版、xAI 和 OpenCode Go。
180
-
181
- 供应商需要已在 DSH 中配置。支持 OAuth 的读取器使用已有且未过期的登录,本插件不会刷新或改写登录信息。
182
-
183
- | 可选读取器 | 宿主凭据引用 |
184
- | --- | --- |
185
- | OpenRouter 账户总余额 | `OPENROUTER_MANAGEMENT_API_KEY` |
186
- | xAI 预付余额 | `XAI_MANAGEMENT_API_KEY`、`XAI_TEAM_ID` |
187
- | 阿里云 Token Plan 国内版 | `ALIBABA_CLOUD_ACCESS_KEY_ID`、`ALIBABA_CLOUD_ACCESS_KEY_SECRET`;临时凭据可加 `ALIBABA_CLOUD_SECURITY_TOKEN` |
188
-
189
- OpenCode Go 只使用其自身在 DSH 中配置的凭据。Zen 没有内置钱包余额读取器,可使用自定义查询;阿里云国际版 Token Plan 暂未接入。
190
-
191
- WorkBuddy 与 WorkBuddy AI 依赖可选的 `dsh-workbuddy-connect` 适配器,两套积分分别缓存、分别刷新。
192
-
193
- </details>
194
-
195
- <details>
196
- <summary><strong>配置自定义配额查询</strong></summary>
197
-
198
- 1. 进入 **控制 → 配额查询**,选择已有供应商。
199
- 2. 填写查询 URL 和响应字段映射。
200
- 3. 点击 **测试**,检查解析出的结果。
201
- 4. 确认查询后,在 **配额** 页面查看。
202
-
203
- 假设接口返回 `{ "data": { "balance": 12.34 } }`:
204
-
205
- ```json
206
- {
207
- "url": "https://api.example.com/balance",
208
- "method": "GET",
209
- "auth": "provider",
210
- "headers": { "accept": "application/json" },
211
- "response": {
212
- "metrics": [
213
- {
214
- "label": "账户可用余额",
215
- "kind": "amount",
216
- "remaining": "data.balance",
217
- "currency": "CNY"
218
- }
219
- ]
220
- }
221
- }
222
- ```
223
-
224
- 将示例 URL 替换为供应商的真实接口。`auth: "provider"` 使用其已有的 DSH 凭据,认证查询地址需与配置地址或官方配额地址同源。
225
-
226
- 模板支持 GET/POST、JSON body、余额/窗口指标,以及 `data.items[0].balance` 等字段路径。窗口支持百分比或 `total` 搭配 `remaining`/`used`,`response.rows` 指定数组;无需认证时使用 `auth: "none"`。
227
-
228
- 修改模板后需要重新测试,成功结果有效期为 15 分钟。确认后的自定义查询覆盖该供应商的内置读取器,移除后恢复。
229
-
230
- </details>
231
-
232
- ## 隐私
233
-
234
- 用量统计在本机完成。插件保存统计数、模型标识和用量时间记录,不保存对话正文;凭据只在宿主读取,不返回渲染进程。
235
-
236
- 测试查询与刷新会访问对应平台的配额服务。插件不含分析上报或遥测接口。
237
-
238
- <details>
239
- <summary>本地存储与请求保护</summary>
240
-
241
- 两个文件位于 `<DSH_HOME>/storages/`;未设置 `DSH_HOME` 时使用当前用户的 `.dsh/storages/`:
242
-
243
- | 文件 | 内容 |
244
- | --- | --- |
245
- | `usage-stats-corpus.json` | 按会话保存的用量贡献 |
246
- | `usage-stats-controls.json` | 控制设置、自定义模板与配额快照 |
247
-
248
- 这些是私人的本地数据,与凭据、环境文件、数据库、日志、备份和预览一起排除在 Git 之外。
249
-
250
- 接口检查回环地址、Host、Origin 与跨站请求,使用 `Cache-Control: no-store`,隐藏未知宿主异常的原始详情。同一用户权限下的其他进程可以访问本地数据。
251
-
252
- 自定义查询拒绝模板中的认证请求头和常见凭据字段;使用供应商认证时要求对应来源,不跟随重定向,超时 8 秒,响应上限 1 MB。WorkBuddy 适配器只保留配额展示字段。
253
-
254
- </details>
255
-
256
- ## 常见问题
257
-
258
- **支持 DSH Web 吗?**
259
-
260
- 当前版本只在 desktop profile 和 Electron 主窗口加载。
261
-
262
- **为什么配额卡片不显示或无法获取?**
263
-
264
- 先确认供应商已配置、凭据可用且账户支持配额接口。普通模型 API Key 可能没有账单查询权限。
265
-
266
- **Token 总数就是账单金额吗?**
267
-
268
- 不是。总数为输入、输出、缓存读取和缓存写入 Token 之和,账户余额来自平台接口。
269
-
270
- **会修改 DSH 的文件吗?**
271
-
272
- 插件注册外部 bundle。高级模型选择器开启时接管界面槽位,关闭后恢复官方选择器,不修改 DSH 源码。
273
-
274
- ## 参与贡献
275
-
276
- 欢迎提交问题和改进。报告问题时,请附上 DSH 版本、插件版本、复现步骤,以及已处理私人账户信息的截图。
277
-
278
- <details>
279
- <summary><strong>开发与本地接口</strong></summary>
280
-
281
- 只编辑 `src/` 中的模块源码。`npm run build` 同步到 `lib/` 和根目录兼容副本,并从 `package.json` 注入界面模块的包名和顶部版本号,包入口加载 `lib/`。
282
-
283
- ```sh
284
- npm run build
285
- npm test
286
- node scripts/render-heatmap-check.mjs
287
- node scripts/check-heat-tip-placement.mjs
288
- npm run preview:heatmap
289
- npm pack --dry-run
290
- npm run release
291
- ```
292
-
293
- 测试使用模拟数据与临时 DSH 目录,无需真实凭据或付费调用。可设置 `DSH_THEME_CLIENT` 验证已安装主题,默认使用随仓库提供的变量契约。模拟预览生成已忽略的 `preview-heatmap.html`。
294
-
295
- `npm run release` 构建插件,将 `sligqoer-dsh-usage-stats-<版本号>.tgz`、`dsh-usage-stats.tgz` 别名与 `SHA256SUMS` 写入已忽略的 `release/`,并在临时 profile 验证安装。发行说明包含 [CHANGELOG.md](CHANGELOG.md) 中对应版本的更新内容。
296
-
297
- 推送与 `package.json` 版本一致的 `v<版本号>` 标签后,GitHub Actions 会运行测试,使用 npm 可信发布将验证过的压缩包发布为公开包,再将同一文件发布到 GitHub Release。可信发布绑定 `Jockjrop/dsh-usage-stats` 仓库的 `release.yml` 工作流,无需在仓库保存 npm 令牌。`npm run publish:release` 发布已构建的压缩包;已有版本仅在完整性与本地压缩包一致时跳过,内容不同则终止。
298
-
299
- 接口统一使用 `/api/dsh-usage-stats/` 前缀:
300
-
301
- | 路由 | 方法 | 作用 |
302
- | --- | --- | --- |
303
- | `stats` | GET | 用量;`days`、`tz`、`model`、`fresh=1` |
304
- | `provider-quotas` | GET | 配额缓存;`fresh=1` 刷新 |
305
- | `workbuddy`、`workbuddy-ai` | GET | 适配器缓存;支持 `fresh=1` |
306
- | `controls` | GET/POST | 读取/修改设置,写入要求 JSON |
307
- | `quota-providers` | GET | 已有供应商与无凭据模板 |
308
- | `quota-test` | POST | 测试模板并返回限时确认 ID |
309
-
310
- 语料库每 30 秒刷新;接口最多等待 1500 ms,可能返回 `stale: true`/`partial: true`。SQLite 指纹要求 `node:sqlite`,否则回退为重读会话。时区变化时按已存事件重新分桶,逐小时保存的旧历史在半小时时区边界上可能存在近似。
311
-
312
- `platform: "web"` 是 DSH 桌面端使用的渲染通信格式;两端入口仍要求 desktop profile 与渲染进程的原生桥接。
313
-
314
- </details>
315
-
316
- ## 许可
317
-
318
- [Apache-2.0](LICENSE)。