@ychris12138/dsh-usage-stats 0.2.10 → 0.3.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.
- package/README.md +97 -20
- package/SECURITY.md +3 -1
- package/docs/release-checklist.md +111 -0
- package/docs/release-notes-v0.3.0.md +25 -0
- package/docs/release-notes-v0.3.1.md +40 -0
- package/lib/accounts.js +421 -172
- package/lib/balance.js +116 -15
- package/lib/billing.js +319 -0
- package/lib/client.js +481 -86
- package/lib/export.js +227 -0
- package/lib/index.js +506 -64
- package/lib/network.js +65 -0
- package/lib/orcarouter.js +79 -0
- package/lib/pricing.js +391 -0
- package/lib/provider-identity.js +129 -0
- package/lib/usage.js +190 -13
- package/package.json +17 -5
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# dsh-usage-stats
|
|
2
2
|
|
|
3
|
+
<!-- stable-version: 0.3.1 -->
|
|
4
|
+
|
|
3
5
|
[](https://github.com/Ychris12138/dsh-usage-stats/releases/latest)
|
|
4
6
|
[](https://github.com/Ychris12138/dsh-usage-stats/actions/workflows/ci.yml)
|
|
5
7
|
[](LICENSE)
|
|
@@ -8,30 +10,40 @@
|
|
|
8
10
|
|
|
9
11
|
Provider balances, subscription quotas, and token-usage analytics for the DeepSeek Harness Web GUI (`dsh web`).
|
|
10
12
|
|
|
11
|
-

|
|
12
14
|
|
|
13
15
|
> 展示图使用脱敏演示数据;插件不会把 API Key、Cookie、管理 PAT 或上游原始响应发送到浏览器。
|
|
14
16
|
|
|
17
|
+
[](https://www.orcarouter.ai/ref/ref_13c34663d1527ac16963)
|
|
18
|
+
|
|
19
|
+
> 🐋 OrcaRouter sponsors this project and is available as an optional OpenAI-compatible provider. [Learn more](https://www.orcarouter.ai/ref/ref_13c34663d1527ac16963) · Referral link.
|
|
20
|
+
|
|
15
21
|
## 一眼看懂 / At a glance
|
|
16
22
|
|
|
17
23
|
| | 能力 | 说明 |
|
|
18
24
|
| --- | --- | --- |
|
|
19
25
|
| 💳 | 统一账户卡片 | API 供应商显示余额,Token Plan 显示分窗口额度;面板一次只呈现当前供应商 |
|
|
20
26
|
| 📊 | Token 用量分析 | 今日、本月、累计、缓存命中率、月历热图,以及按日期/供应商/模型下钻 |
|
|
21
|
-
|
|
|
27
|
+
| 💰 | 估算费用与预算 | 按事件时间匹配历史价格,提供日/月费用、session 级聚合及可选预算预警 |
|
|
28
|
+
| 🔄 | 后台监测 | 账户按 active/detail/background 自适应刷新;间隔可配置或完全关闭,本地 Token 聚合保持独立运行 |
|
|
22
29
|
| 🧩 | 可扩展适配器 | 支持 New API、Sub2API、通用余额模板,以及声明式 JSON Pointer 自定义查询 |
|
|
23
|
-
|
|
|
30
|
+
| 📦 | 安全导出 | 提供 daily/session CSV 与版本化 JSON;Unicode、CSV 公式前缀和不完整费用均安全处理 |
|
|
31
|
+
| 🔒 | 本机安全边界 | 数据端点仅接受回环 GET;OrcaRouter preset 仅由带防跨站请求头的显式回环 POST 写入;凭据只在服务端解析 |
|
|
24
32
|
|
|
25
|
-
界面支持中文和英文。浏览器只请求当前选择的 provider
|
|
33
|
+
界面支持中文和英文。浏览器只请求当前选择的 provider;账户自动刷新由服务端统一调度。手动刷新会更新用量、供应商列表,并强制刷新当前账户,不会批量强制请求其他供应商。
|
|
26
34
|
|
|
27
35
|
## 快速安装 / Quick start
|
|
28
36
|
|
|
29
37
|
需要 DeepSeek Harness `web` profile(`@deepseek-ai/dsh >= 0.1.0-rc.6`)。
|
|
30
38
|
|
|
39
|
+
稳定版优先安装 npm 上的精确版本;这也是 DSH Desktop Market 使用的同一个包:
|
|
40
|
+
|
|
31
41
|
```bash
|
|
32
|
-
dsh plugin --profile web add "
|
|
42
|
+
dsh plugin --profile web add "@ychris12138/dsh-usage-stats@0.3.1"
|
|
33
43
|
```
|
|
34
44
|
|
|
45
|
+
只有测试尚未发布的 source/RC 时才使用 `dsh plugin --profile web add "github:Ychris12138/dsh-usage-stats"`。GitHub `main` 可能领先 npm stable,不应把 source 安装当作市场安装验收。
|
|
46
|
+
|
|
35
47
|
然后重启已经运行的 `dsh web`,并在浏览器中硬刷新。侧边栏底部会出现“用量/余额”(Usage/Balance)入口。
|
|
36
48
|
|
|
37
49
|
### 插件市场 GUI 安装(DSH Community Market,Path A 标准来源)
|
|
@@ -41,14 +53,14 @@ dsh plugin --profile web add "github:Ychris12138/dsh-usage-stats"
|
|
|
41
53
|
- `catalog/catalog-source.json` — 来源 manifest(`catalog-source.schema.json` v1.0.0)
|
|
42
54
|
- `catalog/v1/plugins.json` — 标准 provider page(`catalog-provider-page.schema.json` v1.0.0)
|
|
43
55
|
|
|
44
|
-
**使用前提(重要)**:市场托管安装只接受 npm registry 的精确稳定版本,git 条目仅可浏览。`dsh-usage-stats` 这个 npm 名已被其他项目占用,因此目录条目身份使用 `@ychris12138/dsh-usage-stats
|
|
56
|
+
**使用前提(重要)**:市场托管安装只接受 npm registry 的精确稳定版本,git 条目仅可浏览。`dsh-usage-stats` 这个 npm 名已被其他项目占用,因此目录条目身份使用 `@ychris12138/dsh-usage-stats`。当前 stable/catalog 版本是 `0.3.1`;每个新版本都按以下顺序发布:
|
|
45
57
|
|
|
46
|
-
1.
|
|
58
|
+
1. 运行 `npm run release:sync -- <version>` 同步 `package.json` / `package-lock.json` / `catalog/v1/plugins.json`,再由 `npm run check:release` 阻止身份或版本漂移。
|
|
47
59
|
2. 发布 scoped 公共包:`npm publish --access public`。
|
|
48
60
|
3. 把 `catalog/v1/plugins.json` 内容发布到 `https://ychris12138.github.io/dsh-usage-stats/v1/plugins`(GitHub Pages,manifest 与 endpoint 必须同源、HTTPS 443、无凭据)。
|
|
49
61
|
4. 在 DSH 插件市场 → 来源管理 → 添加来源,粘贴 manifest URL:`https://ychris12138.github.io/dsh-usage-stats/catalog-source.json`,选择后即可走「可恢复安装边界」GUI 安装。
|
|
50
62
|
|
|
51
|
-
>
|
|
63
|
+
> 目录若先指向尚未发布的版本,市场安装会 fail-closed,这是预期行为。只有 npm、Pages catalog 与 Desktop Market 实际安装全部验证后,才算完成发布。
|
|
52
64
|
|
|
53
65
|
升级或卸载:
|
|
54
66
|
|
|
@@ -93,6 +105,7 @@ npx --yes github:Ychris12138/dsh-usage-stats --no-enable
|
|
|
93
105
|
| --- | --- | --- | --- |
|
|
94
106
|
| DeepSeek | 余额 | provider `apiKeyEnv` | `/user/balance` |
|
|
95
107
|
| OpenRouter | 余额 | `OPENROUTER_MANAGEMENT_KEY` | `/api/v1/credits` |
|
|
108
|
+
| OrcaRouter | 余额 | `ORCAROUTER_API_KEY` | `/v1/balance`(旧部署回退到账单摘要接口) |
|
|
96
109
|
| Moonshot / Kimi API | 余额 | provider `apiKeyEnv` | `/v1/users/me/balance` |
|
|
97
110
|
| OpenCode Go | 订阅 | `OPENCODE_GO_API_KEY` 或本地 `auth.json` | `/zen/go/v1/usage` |
|
|
98
111
|
| Z.ai / 智谱 | 订阅 | `ZAI_API_KEY` | Coding Plan quota/subscription |
|
|
@@ -110,6 +123,47 @@ npx --yes github:Ychris12138/dsh-usage-stats --no-enable
|
|
|
110
123
|
|
|
111
124
|
凭据由 Harness 从 `~/.dsh/.credentials.yaml` 解析。安装器不会读取、创建或修改该文件。不要把真实 Key、Cookie 或管理令牌提交到 Git、公开 issue,或粘贴给编码 Agent。
|
|
112
125
|
|
|
126
|
+
### 账户刷新 / Account refresh
|
|
127
|
+
|
|
128
|
+
默认刷新间隔是 active 1 分钟、detail 2 分钟、background 15 分钟。严格限流的 New API 或公司中转可以调整全局策略,或完全关闭账户自动刷新:
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
# ~/.dsh/profiles/web/cordis.patch.yml
|
|
132
|
+
- insert:
|
|
133
|
+
- id: usage-stats
|
|
134
|
+
name: "@ychris12138/dsh-usage-stats"
|
|
135
|
+
config:
|
|
136
|
+
refresh:
|
|
137
|
+
enabled: false
|
|
138
|
+
activeMs: 60000
|
|
139
|
+
detailMs: 120000
|
|
140
|
+
backgroundMs: 900000
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
三个间隔必须是 `60000` 至 `86400000` 毫秒之间的整数。需要停止时使用 `refresh.enabled: false`,不要填写超大的 timeout。关闭后,每个相同 provider 配置仍允许首次查询;之后普通面板读取只返回缓存,不会因缓存过期访问上游。账户端点的 `refresh=1`(Retry)仍可显式刷新,provider/monitor 配置变化后也会为新配置重新查询一次。
|
|
144
|
+
|
|
145
|
+
旧配置 `disableBackgroundRefresh: true` 继续等价于 `refresh.enabled: false`;两者同时存在时,显式的 `refresh.enabled` 优先。该开关只关闭账户上游自动刷新,不会关闭本地 Token 用量聚合。
|
|
146
|
+
|
|
147
|
+
### 估算费用与预算 / Estimated cost and budgets
|
|
148
|
+
|
|
149
|
+
预算是可选的非敏感配置,默认关闭。金额只在 provider、model、事件时间与货币均能由内置价格规则可靠确定时计算;未知中转、订阅路线、无价格的 cache write 或混合币种会整体显示 `—`,不会展示部分费用或进行汇率换算。
|
|
150
|
+
|
|
151
|
+
```yaml
|
|
152
|
+
# ~/.dsh/profiles/web/cordis.patch.yml
|
|
153
|
+
- insert:
|
|
154
|
+
- id: usage-stats
|
|
155
|
+
name: "@ychris12138/dsh-usage-stats"
|
|
156
|
+
config:
|
|
157
|
+
budgets:
|
|
158
|
+
currency: USD
|
|
159
|
+
daily: 5
|
|
160
|
+
monthly: 100
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
预算使用本机日历日/月边界:低于 80% 为正常,达到 80% 为 warning,达到 100% 为 critical。`daily` / `monthly` 必须是正数或 `null`;当前版本不做 FX 换算,因此预算货币与可靠价格货币不兼容时状态保持 unknown。
|
|
164
|
+
|
|
165
|
+
面板的当前 provider 会保存在浏览器的命名空间 localStorage 中;刷新页面或重启 DSH 后恢复。若该 provider 已被删除,插件会清除旧值并使用原有的 DeepSeek/已配置 provider fallback。该选择不会写入 DSH 设置、服务端缓存或新 API。
|
|
166
|
+
|
|
113
167
|
### 余额型供应商
|
|
114
168
|
|
|
115
169
|
DeepSeek、Moonshot 等默认复用对应 provider profile 的 `apiKeyEnv`。例如:
|
|
@@ -128,6 +182,8 @@ OPENROUTER_MANAGEMENT_KEY: sk-or-v1-your-management-key
|
|
|
128
182
|
|
|
129
183
|
插件按 `total_credits - total_usage` 显示 OpenRouter 余额,并同时展示累计已用和总 credits。普通 Key 的 `/api/v1/key` 只描述单个 Key 的 spending limit,不会被当作账户余额。自定义引用可在 `monitors.openrouter` 中设置 `adapter: openrouter-balance` 与 `credentialRef`。
|
|
130
184
|
|
|
185
|
+
OrcaRouter 优先读取其余额接口 `/v1/balance`,将 paid、free 和 promo credits 汇总为当前可用余额;旧部署没有该接口时,回退到官方文档提供的 OpenAI-compatible 账单摘要接口(订阅端点总额度 + usage 端点累计用量,按美分换算)。任一可用路径返回无法识别的数据时会显示明确的错误状态,不会把未知结果当作 0;无限额度哨兵值会显示为 `∞`,OrcaRouter 路由仍不参与本插件的模型价格估算。
|
|
186
|
+
|
|
131
187
|
### Token Plan 供应商
|
|
132
188
|
|
|
133
189
|
```yaml
|
|
@@ -264,6 +320,16 @@ Passion(provider id 为 `passion` 或域名为 `*.passionapi.com`)会自动
|
|
|
264
320
|
3. 使用 `‹` / `›` 切换月份,点击热图日期查看当天的 provider/model 明细。
|
|
265
321
|
4. 标题栏刷新会更新 Token、provider 列表,并强制刷新当前账户。
|
|
266
322
|
|
|
323
|
+
### 安全导出 / Secret-free export
|
|
324
|
+
|
|
325
|
+
三个下载端点只导出聚合后的白名单字段,不包含 credential ref/value、Authorization、Cookie、上游原始响应、prompt/reply 或文件路径:
|
|
326
|
+
|
|
327
|
+
- `/api/usage-stats/export/daily.csv`:每天 × provider/model 的四类 Token 与完整费用估算。
|
|
328
|
+
- `/api/usage-stats/export/sessions.csv`:session 标题、provider/model 集合、Token、完整费用估算和最后活动时间。
|
|
329
|
+
- `/api/usage-stats/export.json`:带 `schemaVersion` 的完整聚合数据、公开 pricing provenance、预算和安全账户状态。
|
|
330
|
+
|
|
331
|
+
CSV 使用 UTF-8、RFC 4180 引号与 spreadsheet formula 防护;Unicode 标题可直接打开。费用只在 `costComplete=true` 时导出,未知/混合币种保持空白或 `null`,不会输出部分金额。
|
|
332
|
+
|
|
267
333
|
“最近 14 天”按本地日历计算,只显示窗口内存在用量的日期;未来时间戳不会计入。同一模型来自不同 provider 时会分别统计,例如 `deepseek-official · deepseek-chat` 与 `ark · deepseek-chat`。
|
|
268
334
|
|
|
269
335
|
## Agent 友好安装 / Agent-friendly installation
|
|
@@ -283,12 +349,13 @@ Constraints:
|
|
|
283
349
|
|
|
284
350
|
Procedure:
|
|
285
351
|
1. Confirm node, npx, and dsh are available.
|
|
286
|
-
2. Prefer `dsh plugin --profile web
|
|
287
|
-
3.
|
|
288
|
-
4.
|
|
289
|
-
5.
|
|
290
|
-
6.
|
|
291
|
-
7.
|
|
352
|
+
2. Prefer the exact npm stable used by Desktop Market: `dsh plugin --profile web add "@ychris12138/dsh-usage-stats@0.3.1"` (or update the existing scoped package).
|
|
353
|
+
3. Use `github:Ychris12138/dsh-usage-stats` only when I explicitly ask to test unreleased source/RC code.
|
|
354
|
+
4. If dsh plugin is unavailable, use the compatible source installer only with my approval: `npx --yes github:Ychris12138/dsh-usage-stats`.
|
|
355
|
+
5. Do not combine bundle installation with an existing manual dsh-usage-stats Cordis entry.
|
|
356
|
+
6. For npx, require a verified package and exactly one Cordis entry, then run again with --check.
|
|
357
|
+
7. Report the exact package identity/version, installation path, and resolved profile paths.
|
|
358
|
+
8. If dsh web is running, report that a restart is needed and stop.
|
|
292
359
|
|
|
293
360
|
Optional account setup (never handle secret values yourself):
|
|
294
361
|
- OpenRouter account balance requires OPENROUTER_MANAGEMENT_KEY, not the inference key.
|
|
@@ -322,14 +389,16 @@ npx --yes github:Ychris12138/dsh-usage-stats --check
|
|
|
322
389
|
- 自定义 monitor 默认要求 HTTPS、同源相对路径、手动 redirect 和 JSON 响应,body 上限为 1 MiB。
|
|
323
390
|
- 发凭据前会筛选域名的 IPv4/IPv6 解析结果并固定一个允许的连接地址,优先使用公网地址;HTTPS 域名解析到 `198.18.0.0/15` 时可作为 Clash/Mihomo 等代理的 synthetic fake-IP 使用。字面量 `198.18/15`、其他私网/特殊地址仍默认拒绝,防止 DNS rebinding 绕过私网限制。
|
|
324
391
|
- `usageBaseURL` 禁止内嵌 username/password;`Authorization`、`X-API-Key`、`API-Key` 等 header 必须由 credential ref 注入。
|
|
325
|
-
-
|
|
392
|
+
- 九个数据端点仅接受 GET;OrcaRouter 集成路由的 GET 只返回布尔状态,POST 仅在用户点击后执行局部 settings mutation,并要求非简单自定义 action header。所有路由同时校验 peer socket 与 Host,支持 IPv4、IPv4-mapped IPv6 和 `[::1]:port`。
|
|
326
393
|
- 用量缓存 `~/.dsh/storages/usage-stats-cache.json` 只保存聚合 Token、会话 id、不透明 revision 与折叠游标,不保存提示词、回复或文件路径。
|
|
327
394
|
|
|
328
395
|
本机反向代理会让插件看到代理自身的回环地址。请勿把端点经反向代理暴露到局域网或公网;确需代理时必须在代理层增加可靠认证与访问控制。安全问题请按 [SECURITY.md](SECURITY.md) 私下报告。
|
|
329
396
|
|
|
330
397
|
## 正确性与数据口径 / Correctness
|
|
331
398
|
|
|
332
|
-
统计值来自 `assistant/chunk` 或 `assistant/message` 中 provider-reported `usage`,不是本地估算。相同 turn/step 的后续样本会替换旧样本,并按 `provider/model` 归集。
|
|
399
|
+
Token 统计值来自 `assistant/chunk` 或 `assistant/message` 中 provider-reported `usage`,不是本地估算。相同 turn/step 的后续样本会替换旧样本,并按 `provider/model` 归集。
|
|
400
|
+
|
|
401
|
+
费用是明确标注的估算派生值:每个 usage 样本使用自己的事件时间、原始 provider/model 与四类 token bucket 匹配 `lib/pricing.js`;替换样本会先减去旧费用,再加入新费用。绝不会用“当前价格 × 历史累计 Token”。每个 session 的派生费用继续进入 `usage.sessions`、session CSV、JSON export 与整体 billing aggregation;插件不会向 DSH composer 注入 session UI。
|
|
333
402
|
|
|
334
403
|
- 活跃会话只处理新追加事件。
|
|
335
404
|
- 持久化会话使用不透明 revision;未变化时不重复读取日志。
|
|
@@ -341,13 +410,19 @@ npx --yes github:Ychris12138/dsh-usage-stats --check
|
|
|
341
410
|
|
|
342
411
|
| Method | Path | Response |
|
|
343
412
|
| --- | --- | --- |
|
|
344
|
-
| `GET` | `/api/usage-stats/usage` | 按日期/provider/model 聚合的 Token
|
|
413
|
+
| `GET` | `/api/usage-stats/usage` | 按日期/provider/model 聚合的 Token、派生费用、session 明细与日/月预算状态 |
|
|
345
414
|
| `GET` | `/api/usage-stats/providers` | provider 列表、account mode、adapter、状态与预警摘要 |
|
|
346
415
|
| `GET` | `/api/usage-stats/account?provider=<id>` | 当前 provider 的统一余额或 Token Plan 快照;`refresh=1` 强制刷新 |
|
|
347
416
|
| `GET` | `/api/usage-stats/balance?provider=<id>` | `0.1.x` 余额兼容路由 |
|
|
348
417
|
| `GET` | `/api/usage-stats/subscriptions` | `0.1.x` Token Plan 兼容路由 |
|
|
418
|
+
| `GET` | `/api/usage-stats/session-context?session=<id>` | 当前 live session 的 route/model/account 与同一增量 fold 的 session 费用快照 |
|
|
419
|
+
| `GET` | `/api/usage-stats/export/daily.csv` | secret-free daily provider/model CSV |
|
|
420
|
+
| `GET` | `/api/usage-stats/export/sessions.csv` | secret-free session CSV |
|
|
421
|
+
| `GET` | `/api/usage-stats/export.json` | versioned usage、budget、pricing provenance 与 account-safe JSON |
|
|
422
|
+
| `GET` | `/api/usage-stats/integrations/orcarouter` | 仅返回 OrcaRouter preset 是否可写/已存在的 secret-free 布尔状态 |
|
|
423
|
+
| `POST` | `/api/usage-stats/integrations/orcarouter` | 用户明确请求后,以 revision-guarded path mutation 幂等加入 preset;要求 `application/json` 与 `X-DSH-Usage-Stats-Action: add-orcarouter` |
|
|
349
424
|
|
|
350
|
-
|
|
425
|
+
除上述 OrcaRouter POST 外,非 GET 返回 `405`;非回环请求返回 `403`。API JSON 使用 `Cache-Control: no-cache`;下载响应使用 `Cache-Control: no-store` 与固定文件名。
|
|
351
426
|
|
|
352
427
|
## 开发与验证 / Development
|
|
353
428
|
|
|
@@ -355,7 +430,7 @@ npx --yes github:Ychris12138/dsh-usage-stats --check
|
|
|
355
430
|
npm install
|
|
356
431
|
npm run check
|
|
357
432
|
npm test
|
|
358
|
-
npm pack --
|
|
433
|
+
npm pack --json
|
|
359
434
|
```
|
|
360
435
|
|
|
361
436
|
`npm test` 完全离线,覆盖 bundle、客户端渲染与请求竞态、服务端安全边界、余额/Token Plan adapter、缓存和安装器幂等性。真实数据验证需先运行 `dsh web`:
|
|
@@ -369,7 +444,9 @@ node scripts/check-balance.mjs
|
|
|
369
444
|
|
|
370
445
|
## 兼容性与致谢 / Compatibility & credits
|
|
371
446
|
|
|
372
|
-
|
|
447
|
+
当前 npm stable 为 `0.3.1`;`v0.3.1` 的完整发布门禁见 [`docs/release-checklist.md`](docs/release-checklist.md),变更摘要见 [`docs/release-notes-v0.3.1.md`](docs/release-notes-v0.3.1.md)。插件依赖 Harness 客户端模块加载器、Cordis 服务与 session persistence;Harness 预发布接口变化时可能需要同步适配。
|
|
448
|
+
|
|
449
|
+
`display.currentSessionPill` 作为 v0.3.0 legacy boolean 配置键继续被接受,避免旧配置导致启动失败;当前客户端不再注册任何 composer UI,因此该键不再产生可见效果。`session-context` 服务端 API 暂时保留原有响应语义,供 v0.3.0 API compatibility 与后续集成使用。
|
|
373
450
|
|
|
374
451
|
- [Javis603/token-monitor](https://github.com/Javis603/token-monitor):参考多 provider 配额归一化与 Z.ai 限额解析。
|
|
375
452
|
- [xiaoqi20/dsh-opencode-go-usage](https://github.com/xiaoqi20/dsh-opencode-go-usage):参考 DSH 凭据接入、OpenCode `auth.json` 回退与 Bearer usage endpoint。
|
package/SECURITY.md
CHANGED
|
@@ -12,6 +12,8 @@ Never include DeepSeek API keys, credentials files, session contents, raw logs,
|
|
|
12
12
|
|
|
13
13
|
## Scope
|
|
14
14
|
|
|
15
|
-
Security fixes target the latest version on the default branch. The
|
|
15
|
+
Security fixes target the latest version on the default branch. The nine read-only data endpoints and the optional OrcaRouter integration route are designed for direct loopback use only; exposing them through a reverse proxy is outside the supported security model unless the proxy adds authentication and access control. The integration route's `GET` response contains only availability booleans. Its `POST` performs the user's explicit, revision-guarded `llm-pi-ai.providers.orcarouter` path mutation and additionally requires JSON plus the non-simple `X-DSH-Usage-Stats-Action: add-orcarouter` header; plugin startup never performs this write.
|
|
16
|
+
|
|
17
|
+
CSV and JSON exports are fixed, versioned projections of normalized usage and account-safe metadata. They do not serialize plugin/provider configuration, credential references or values, raw upstream responses, prompts, replies, or file paths. CSV text fields are quoted and guarded against spreadsheet-formula execution; incomplete monetary derivations remain blank/null.
|
|
16
18
|
|
|
17
19
|
Declarative account monitors are trusted local configuration, but they still default to HTTPS, same-origin relative paths, manual redirects, JSON-only responses, and a 1 MiB response limit. Before sending credentials, the plugin filters IPv4/IPv6 DNS answers and pins one validated address for the connection. Public addresses are preferred. For HTTPS hostnames only, an IPv4 address in `198.18.0.0/15` may be accepted as a proxy-synthetic fake-IP mapping for Clash/Mihomo-style TUN DNS. Literal targets in that range remain blocked by default, and other private or special-use addresses still require explicit `allowPrivateNetwork` opt-in. Enabling cross-origin, insecure HTTP, or private-network access expands the trust boundary and should be done only for an endpoint you control.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Release checklist
|
|
2
|
+
|
|
3
|
+
This is the release gate for `@ychris12138/dsh-usage-stats`. Completing the checklist prepares a release; it does not authorize npm publishing, tagging, or creating a GitHub Release.
|
|
4
|
+
|
|
5
|
+
## 1. Release candidate baseline
|
|
6
|
+
|
|
7
|
+
- [ ] Start from the reviewed release-candidate PR merged into a clean `main`; record this commit as `RC_BASE_SHA` for provenance only.
|
|
8
|
+
- [ ] Do not publish or tag `RC_BASE_SHA`: the release version has not been committed yet.
|
|
9
|
+
- [ ] Confirm `cordis.patch.yml` quotes `@ychris12138/dsh-usage-stats` and `lib/client.js` registers the same identity through `__ModuleLoader__.load()`.
|
|
10
|
+
- [ ] Confirm the release notes describe estimated costs as estimates and list every unsupported/fail-closed case.
|
|
11
|
+
|
|
12
|
+
## 2. Automated gates
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm ci
|
|
16
|
+
npm run check
|
|
17
|
+
npm test
|
|
18
|
+
npm pack --json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- [ ] Inspect the pack manifest: no credentials, local caches, screenshots, backups, review diffs, or untracked planning files.
|
|
22
|
+
- [ ] Install the generated tarball into an isolated DSH profile; do not validate only against the source checkout.
|
|
23
|
+
- [ ] Confirm malformed settings fail before routes or timers register.
|
|
24
|
+
- [ ] Confirm non-GET and non-loopback export/API requests remain rejected.
|
|
25
|
+
|
|
26
|
+
## 3. Fresh install and migration
|
|
27
|
+
|
|
28
|
+
- [ ] Fresh isolated profile: install, restart DSH, hard-refresh the browser, open Usage Stats.
|
|
29
|
+
- [ ] Upgrade an existing v0.2.10 profile without deleting its usage cache or monitor configuration.
|
|
30
|
+
- [ ] Confirm a valid old cache is migrated/refolded and retains exact token totals.
|
|
31
|
+
- [ ] Replace the cache with malformed JSON; confirm the plugin rebuilds from authoritative session events without blocking DSH startup.
|
|
32
|
+
- [ ] Confirm existing account monitors remain compatible and no new provider/monitor is inserted into user configuration.
|
|
33
|
+
- [ ] Confirm legacy `display.currentSessionPill: true` and `false` configurations both start successfully and neither registers composer UI.
|
|
34
|
+
- [ ] Confirm a persisted provider selection survives browser refresh and DSH restart; removing that provider clears the saved id and uses the existing fallback.
|
|
35
|
+
- [ ] Confirm OrcaRouter is added only through the explicit fresh-user synthetic Add action; startup performs no settings mutation and existing provider configuration is not overwritten.
|
|
36
|
+
- [ ] Confirm OrcaRouter balance succeeds through `/v1/balance` or the compatible billing fallback, pricing stays unknown/null, and no credential value reaches the browser or export payloads.
|
|
37
|
+
- [ ] Confirm unchanged persisted fallback logs read only from the folded cursor, appended events remain incremental, and truncation/rewrite still refolds from sequence 0 (#58/#57).
|
|
38
|
+
|
|
39
|
+
## 4. Export and security
|
|
40
|
+
|
|
41
|
+
- [ ] Download daily CSV, session CSV, and the versioned JSON export.
|
|
42
|
+
- [ ] Check commas, quotes, CR/LF, Unicode titles, and spreadsheet-formula prefixes.
|
|
43
|
+
- [ ] Confirm incomplete/mixed-currency estimates export as blank/null rather than partial amounts.
|
|
44
|
+
- [ ] Search every export for credential names/values, Authorization, cookies, raw URLs with userinfo/query data, prompt text, response text, and file paths.
|
|
45
|
+
- [ ] Confirm exported pricing provenance contains only public rule/source metadata.
|
|
46
|
+
|
|
47
|
+
## 5. Real DSH release-candidate regression
|
|
48
|
+
|
|
49
|
+
- [ ] Test the latest supported `@deepseek-ai/dsh` Desktop/Web release candidate with an isolated profile.
|
|
50
|
+
- [ ] Confirm DSH starts without `Failed to load plugins` or loader identity errors.
|
|
51
|
+
- [ ] Confirm client bundle load and that `sidebar.footer.action` is the only extension point registered by dsh-usage-stats; verify panel open/close, provider switching, cost/budget states, and manual Retry.
|
|
52
|
+
- [ ] At 700 / 500 / 400 / 320 px, confirm dsh-usage-stats registers no `conversation.input.*` component or composer DOM and leaves native Permission / Model / Context / Submit layout untouched. Record any remaining sub-400 px overlap as DSH host behavior rather than changing host controls from this plugin.
|
|
53
|
+
- [ ] Test the sidebar action and panel in light and dark themes.
|
|
54
|
+
- [ ] Confirm Last 14 days token values retain an 84 px minimum width, right alignment, and tabular numerals while the date column shrinks/ellipsizes without adding narrow-panel overflow (#75).
|
|
55
|
+
- [ ] With `refresh.enabled: false`, confirm one first account fetch, no expiry-driven upstream requests, manual Retry, and a fresh fetch after provider configuration changes.
|
|
56
|
+
- [ ] Recheck #53 only in an available enterprise proxy environment; record evidence, but do not infer a fix without reproduction.
|
|
57
|
+
- [ ] Recheck #14 with a real MiniMax Coding Plan account: both current and weekly windows plus reset information. Record the sanitized response shape if it fails.
|
|
58
|
+
|
|
59
|
+
## 6. Create the immutable release commit
|
|
60
|
+
|
|
61
|
+
Do not run this section until every release-candidate gate above passes and the maintainer approves preparing the release commit.
|
|
62
|
+
|
|
63
|
+
- [ ] Create a release branch from the reviewed `main` at `RC_BASE_SHA`.
|
|
64
|
+
- [ ] Run `npm run release:sync -- 0.3.1` once to update `package.json`, `package-lock.json`, the Community Market catalog, and documented stable-version references together.
|
|
65
|
+
- [ ] Confirm the v0.3.1 release notes use final stable wording, preserve the historical v0.3.0 notes, and do not claim #84 fixed or include #88 behavior.
|
|
66
|
+
- [ ] Run the release gates again against the synchronized version:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm run check
|
|
70
|
+
npm test
|
|
71
|
+
npm pack --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- [ ] Inspect the final pack manifest, then commit all version/release metadata changes with `chore: prepare v0.3.1 release`.
|
|
75
|
+
- [ ] Record that commit as `RELEASE_SHA`; this replaces `RC_BASE_SHA` as the only publish/tag identity.
|
|
76
|
+
- [ ] Confirm the working tree is clean and `HEAD` equals `RELEASE_SHA`.
|
|
77
|
+
- [ ] Confirm the committed package version, not merely the working-tree version:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
test "$(git show "$RELEASE_SHA:package.json" | jq -r .version)" = "0.3.1"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The release invariant is:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
npm published source commit
|
|
87
|
+
== v0.3.1 tag commit
|
|
88
|
+
== GitHub Release commit
|
|
89
|
+
== package/catalog version commit
|
|
90
|
+
== RELEASE_SHA
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## 7. Publish and market closeout
|
|
94
|
+
|
|
95
|
+
Do not run this section until the immutable release commit exists and the maintainer explicitly authorizes publishing.
|
|
96
|
+
|
|
97
|
+
- [ ] `npm whoami` returns the expected publisher.
|
|
98
|
+
- [ ] From a clean checkout/worktree at exactly `RELEASE_SHA`, run `npm publish --access public --registry=https://registry.npmjs.org/`.
|
|
99
|
+
- [ ] `npm view "@ychris12138/dsh-usage-stats" version --registry=https://registry.npmjs.org/` equals the target version.
|
|
100
|
+
- [ ] Merge or push the release commit to `main` according to the chosen branch workflow; verify `main` contains the exact `RELEASE_SHA` without recreating the release changes.
|
|
101
|
+
- [ ] Only after npm and `main` verification: create the signed/annotated `v0.3.1` tag pointing explicitly to `RELEASE_SHA`.
|
|
102
|
+
- [ ] Verify the tag resolves to the published source commit:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
test "$(git rev-parse v0.3.1^{commit})" = "$RELEASE_SHA"
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- [ ] Create the GitHub Release from `v0.3.1`; verify it resolves to `RELEASE_SHA`.
|
|
109
|
+
- [ ] Verify the public Pages `catalog-source.json` and `/v1/plugins` response content type, package name, and exact version.
|
|
110
|
+
- [ ] Install the exact npm version through DSH Desktop Community Market and restart the host.
|
|
111
|
+
- [ ] Close the npm/market release issue only after the Desktop Market installation succeeds.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# v0.3.0 release notes
|
|
2
|
+
|
|
3
|
+
`v0.3.0` turns dsh-usage-stats from an account/Token dashboard into a route-aware usage and cost observability layer while preserving the v0.2.x credential and loopback security boundaries.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
- A shared provider identity policy keeps route, provider family, account adapter, and pricing eligibility separate. Unknown/custom gateways remain unknown unless explicitly configured.
|
|
8
|
+
- The Current Session Pill shows the active route's account state and event-derived current-session cost beside the composer, and opens the existing provider panel when clicked. It is enabled by default and can be disabled with `display.currentSessionPill: false`.
|
|
9
|
+
- Account health now includes provenance, stale state, last attempt/success, age, bounded diagnostics, configurable refresh intervals, and a true automatic-refresh off switch.
|
|
10
|
+
- DeepSeek historical pricing is matched by exact model, route eligibility, event time, and Shanghai pricing windows. Daily/monthly budgets are optional and fail closed.
|
|
11
|
+
- New API balance display respects the instance's USD/CNY quota settings. Unsupported display types and invalid CNY exchange rates do not masquerade as money.
|
|
12
|
+
- Daily CSV, session CSV, and versioned JSON exports use explicit secret-free projections, preserve Unicode, escape CSV safely, and omit incomplete cost amounts.
|
|
13
|
+
- The account panel remembers its last valid provider in namespaced browser localStorage and falls back safely if that provider is removed.
|
|
14
|
+
- Sidebar footer actions preserve the shared row layout and wrap full-width entries safely, preventing overlap or oversized entries when dsh-usage-stats is installed alongside other footer plugins (#82).
|
|
15
|
+
|
|
16
|
+
## Cost accuracy statement
|
|
17
|
+
|
|
18
|
+
All monetary values are **estimates**, not invoices. A sample is priced only when its provider route is eligible for an official catalog, its model matches exactly, its event timestamp selects a known historical rule, every reported token bucket has a price, and the result has one supported currency. Custom gateways, subscriptions, unknown models, ambiguous historical identity, unpriced cache writes, and mixed currencies return no estimate. The plugin does not call an FX service and does not reinterpret old usage using today's route or price.
|
|
19
|
+
|
|
20
|
+
## Upgrade notes
|
|
21
|
+
|
|
22
|
+
- Existing v0.2.10 configuration remains valid. The new display setting, budgets, and refresh controls are additive and default to the previous behavior.
|
|
23
|
+
- Older usage-cache schemas are invalidated and refolded from authoritative session events. Malformed cache JSON is ignored and rebuilt; it must not block DSH startup.
|
|
24
|
+
- Existing account monitor configuration is normalized without writing credentials or inserting new monitor entries.
|
|
25
|
+
- Browser provider selection is local UI state only; it creates no endpoint and no server-side setting.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# v0.3.1 release notes
|
|
2
|
+
|
|
3
|
+
`v0.3.1` is a small maintenance release focused on an optional OrcaRouter integration, lower UI intrusion, and two focused correctness and usability fixes.
|
|
4
|
+
|
|
5
|
+
## Highlights
|
|
6
|
+
|
|
7
|
+
### OrcaRouter optional integration
|
|
8
|
+
|
|
9
|
+
- Adds an optional, explicit OrcaRouter provider preset with `orcarouter/auto`.
|
|
10
|
+
- Never mutates settings at startup and never embeds or stores an API key value.
|
|
11
|
+
- Fresh installations expose a user-triggered Add flow; existing OrcaRouter provider settings remain untouched.
|
|
12
|
+
- Reads current wallet data from `/v1/balance`, with the compatible billing-summary fallback retained for older deployments.
|
|
13
|
+
- Includes paid, free, and promotional credit only when the upstream response provides valid values.
|
|
14
|
+
- Keeps OrcaRouter pricing unknown (`null`): an OrcaRouter route never inherits DeepSeek, OpenAI, or another upstream provider's prices.
|
|
15
|
+
- Keeps the sponsored-integration disclosure compact in the README and provider selector.
|
|
16
|
+
|
|
17
|
+
### Sidebar-only UI
|
|
18
|
+
|
|
19
|
+
- Removes all dsh-usage-stats components from `conversation.input.*` and the composer toolbar. Permission, Model, Context, and Submit remain entirely host-owned.
|
|
20
|
+
- Keeps Usage Stats available through `sidebar.footer.action` and the existing sidebar panel.
|
|
21
|
+
- Continues to accept legacy `display.currentSessionPill: true` and `false` configuration for compatibility; the setting is now a no-op and renders no composer UI.
|
|
22
|
+
|
|
23
|
+
### Persisted-session fallback performance
|
|
24
|
+
|
|
25
|
+
- Fixes #57 through #58: unchanged persisted fallback logs no longer refold from sequence 0.
|
|
26
|
+
- Keeps appended events incremental.
|
|
27
|
+
- Still detects truncation or rewrite and performs the required full refold.
|
|
28
|
+
|
|
29
|
+
### Recent usage list polish
|
|
30
|
+
|
|
31
|
+
- Fixes #75 by right-aligning Last 14 days token values.
|
|
32
|
+
- Lets the date column shrink and ellipsize in narrow panels instead of forcing a fixed width.
|
|
33
|
+
|
|
34
|
+
## Compatibility and non-features
|
|
35
|
+
|
|
36
|
+
- No OrcaRouter automatic pricing and no second pricing engine.
|
|
37
|
+
- No new client polling loop and no composer UI.
|
|
38
|
+
- No #84 quota-precision behavior change is claimed in this release; #84 remains open for clarification and retesting.
|
|
39
|
+
- No client price table, fallback unknown-model pricing, Beijing-tariff recomputation, independent account polling, or blended-price sidebar logic from #88 is included.
|
|
40
|
+
- No changes to historical pricing semantics and no credential migration.
|