dsh-all-usage 1.2.0 → 1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.2.1(2026-10-18)
4
+ ### 新功能
5
+ - **支持 DSH 0.2.1-rc.1 / rc.2** —— 新运行时可直接使用。
6
+ - **首次打开跟随 DSH 的语言** —— 按 DSH 的 Language 设置选择语言;在面板里选过之后以面板为准。
7
+ ### 修复
8
+ - **用量面板不再被第三方主题压住** —— 侧栏玻璃 / 壁纸类插件不会再盖住面板,透明主题也不会把面板底色「打洞」。
9
+ - **切换语言后看板不再变空** —— 中英切换立即刷新,不必再刷新页面;英文的「今日」趋势恢复小时曲线。
10
+ - **DeepSeek Account 用量按峰谷价计价** —— 该路由此前全天按谷价计、峰时偏少;升级后历史用量会重新计价(峰时变贵)。
11
+ ### Features
12
+ - **DSH 0.2.1-rc.1 and rc.2 are supported** — the new runtime works out of the box.
13
+ - **The panel opens in DSH's language** — it follows DSH's Language setting; a choice made in the panel wins afterwards.
14
+ ### Fixes
15
+ - **Third-party themes can no longer bury the usage panel** — sidebar glass/wallpaper plugins don't cover it, and a theme that blanks the base background can't punch holes in it.
16
+ - **Switching the language no longer empties the dashboard** — data refreshes immediately without a page reload, and English keeps its hourly curve for "Today".
17
+ - **DeepSeek Account usage is priced with peak/off-peak bands** — that route was charged the off-peak rate all day; existing rows are re-priced on the next scan (peak hours become more expensive).
18
+
3
19
  ## v1.2.0(2026-10-15)
4
20
  ### 新功能
5
21
  - **支持 DSH 0.2.1-alpha.2** —— 声明区间追加精确版本 `0.2.1-alpha.2`;本机 Node 24 严格真实 Cordis smoke 通过(Cordis `4.0.5-alpha.1` / loader `1.0.6-alpha.1` / timer `1.1.7-alpha.1`),CI 已配置 Node 22/24、待执行;仅此精确版本,不代表其他 alpha 版本。
package/README.en.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![stars](https://img.shields.io/github/stars/ParticleLight/dsh-all-usage?label=stars&logo=github)](https://github.com/ParticleLight/dsh-all-usage/stargazers)
8
8
  [![license](https://img.shields.io/github/license/ParticleLight/dsh-all-usage?label=license&color=green)](LICENSE)
9
9
  [![CI](https://github.com/ParticleLight/dsh-all-usage/actions/workflows/ci.yml/badge.svg)](https://github.com/ParticleLight/dsh-all-usage/actions/workflows/ci.yml)
10
- [![DSH runtime compatibility](https://img.shields.io/badge/DSH%20runtime-7%20verified-4D6BFE)](#compatibility-and-known-limitations)
10
+ [![DSH runtime compatibility](https://img.shields.io/badge/DSH%20runtime-9%20verified-4D6BFE)](#compatibility-and-known-limitations)
11
11
  [![status](https://img.shields.io/badge/status-stable-brightgreen)](https://github.com/ParticleLight/dsh-all-usage/releases)
12
12
 
13
13
  [中文](README.md) · [English](README.en.md)
@@ -75,13 +75,16 @@ This is a standard DSH community plugin package with a `dsh.bundle` manifest and
75
75
  ### Compatibility and Known Limitations
76
76
 
77
77
  - **Runtime**: Node.js `>=22 <25` is required. CI runs the test suite, syntax checks, and package-content checks on Node 22 and Node 24.
78
- - **DSH compatibility**: `package.json` declares DSH runtime `>=0.1.1-rc.1 <0.1.5-0 || >=0.1.5-rc.1 <0.1.6-0 || >=0.1.7-rc.2 <0.1.8-0 || >=0.2.0-rc.2 <0.2.1-0 || 0.2.1-alpha.2`; the real Cordis service chain is verified on `0.2.0-rc.2`, `0.1.7-rc.2`, `0.1.5-rc.2`, `0.1.5-rc.1`, `0.1.1-rc.2` and `0.1.1-rc.1`, all of them covered by the CI smoke matrix on Node 22 and 24. `0.1.2-rc.1` has also been verified compatible through real-world use, but is not covered by the CI smoke matrix. The declaration is split per tuple rather than written as one interval because node-semver only admits a prerelease version when some comparator shares its exact `major.minor.patch` tuple and itself carries a prerelease tag — `0.2.0-rc.2` is admitted only because the range says `>=0.2.0-rc.2`.
78
+ - **DSH compatibility**: `package.json` declares DSH runtime `>=0.1.1-rc.1 <0.1.5-0 || >=0.1.5-rc.1 <0.1.6-0 || >=0.1.7-rc.2 <0.1.8-0 || >=0.2.0-rc.2 <0.2.1-0 || 0.2.1-alpha.2 || 0.2.1-rc.1 || 0.2.1-rc.2`; the real Cordis service chain is verified locally on `0.2.1-rc.1` and `0.2.1-rc.2` (strict smoke on Node 24; both promote Cordis to the stable 4.0.5 / loader 1.0.6 / timer 1.1.7 pairing), `0.2.1-alpha.2`, `0.2.0-rc.2`, `0.1.7-rc.2`, `0.1.5-rc.2`, `0.1.5-rc.1`, `0.1.1-rc.2` and `0.1.1-rc.1`. Every declared runtime is in the CI smoke matrix on Node 22 and 24, but the two `0.2.1` lines are reported as SKIPPED — not passed — because upstream has never published the matching `@deepseek-ai/dsh-invariants` version. `0.1.2-rc.1` has also been verified compatible through real-world use, but is not covered by the CI smoke matrix. The declaration is split per tuple rather than written as one interval because node-semver only admits a prerelease version when some comparator shares its exact `major.minor.patch` tuple and itself carries a prerelease tag — `0.2.0-rc.2` is admitted only because the range says `>=0.2.0-rc.2`.
79
79
  - **Desktop client (Electron, Windows)**: the plugin is verified running in the DSH desktop client (`@deepseek-ai/dsh-desktop` `0.1.7-rc.2` as measured). The desktop client keeps a 40px caption strip across the top of its window for its own minimise / maximise / close buttons and marks the document with `data-windows-titlebar` and `--dsh-windows-titlebar-height`; the panel draws from **below** that strip, so the client's own close button is never covered. Browsers carry no such marker and reserve nothing. The strip height comes from the host's declaration first, then the Window Controls Overlay rectangle, then the user agent; to tune it, run `localStorage.setItem('dsh-all-usage:topInset', '48')` in DevTools and reload (`0` reserves nothing) — no rebuild required. The desktop client ships its own runtime; the version measured there, `0.1.7-rc.2`, is part of the declared range and of the CI smoke matrix below.
80
80
  - **Web service dependency**: the Host declares `webServer` as a required dependency, so DSH waits for a late-mounted service before applying the plugin; this package targets the DSH Web profile and does not expose routes without WebServer. The HTTP guard also checks the actual socket peer, so a reverse proxy is accepted only when the connection itself is loopback.
81
+ - **Interface language**: on first entry the panel follows DSH's **Language** setting (`Settings → General → Language`, read through the host's `locale` service); without that service it falls back to the browser language and then to English. Once a language is picked inside the panel, the panel's choice wins and the host setting stops overriding it. The language also decides the timezone — Chinese uses local time, English uses UTC — so switching it refetches the matching snapshot.
81
82
 
82
83
  | DSH runtime | Node.js support | Real Cordis smoke | Conclusion |
83
84
  | --- | --- | --- | --- |
84
- | `0.2.1-alpha.2` | `>=22 <25` | Passed (strict real Cordis smoke verified locally on Node 24; CI configured for Node 22/24, pending execution) | Declared and verified (this exact alpha.2 only; no other alpha versions implied) |
85
+ | `0.2.1-rc.2` | `>=22 <25` | Passed (strict real Cordis smoke verified locally on Node 24; stable Cordis 4.0.5 / loader 1.0.6 / timer 1.1.7) | Declared and verified (this exact rc only; CI reports SKIPPED because upstream never published `dsh-invariants@0.2.1-rc.2`) |
86
+ | `0.2.1-rc.1` | `>=22 <25` | Passed (strict real Cordis smoke verified locally on Node 24; stable Cordis 4.0.5 / loader 1.0.6 / timer 1.1.7) | Declared and verified (this exact rc only; no other rc versions implied; CI reports SKIPPED because upstream never published `dsh-invariants@0.2.1-rc.1`) |
87
+ | `0.2.1-alpha.2` | `>=22 <25` | Passed (strict real Cordis smoke verified locally on Node 24; CI reports SKIPPED because upstream never published `dsh-invariants@0.2.1-alpha.2`) | Declared and verified (this exact alpha.2 only; no other alpha versions implied) |
85
88
  | `0.2.0-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified (historically verified; CI covers Node 22/24) |
86
89
  | `0.1.7-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified (historically verified; CI covers Node 22/24) |
87
90
  | `0.1.5-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified |
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  [![stars](https://img.shields.io/github/stars/ParticleLight/dsh-all-usage?label=stars&logo=github)](https://github.com/ParticleLight/dsh-all-usage/stargazers)
8
8
  [![license](https://img.shields.io/github/license/ParticleLight/dsh-all-usage?label=license&color=green)](LICENSE)
9
9
  [![CI](https://github.com/ParticleLight/dsh-all-usage/actions/workflows/ci.yml/badge.svg)](https://github.com/ParticleLight/dsh-all-usage/actions/workflows/ci.yml)
10
- [![DSH runtime compatibility](https://img.shields.io/badge/DSH%20runtime-7%20verified-4D6BFE)](#兼容性与已知限制)
10
+ [![DSH runtime compatibility](https://img.shields.io/badge/DSH%20runtime-9%20verified-4D6BFE)](#兼容性与已知限制)
11
11
  [![status](https://img.shields.io/badge/status-stable-brightgreen)](https://github.com/ParticleLight/dsh-all-usage/releases)
12
12
 
13
13
  [中文](README.md) · [English](README.en.md)
@@ -75,13 +75,16 @@ dsh plugin --profile web add github:ParticleLight/dsh-all-usage
75
75
  ### 兼容性与已知限制
76
76
 
77
77
  - **运行环境**:需要 Node.js `>=22 <25`;CI 会在 Node 22 和 Node 24 上运行测试、语法检查和 npm 包内容检查。
78
- - **DSH 兼容**:`package.json` 声明 DSH runtime `>=0.1.1-rc.1 <0.1.5-0 || >=0.1.5-rc.1 <0.1.6-0 || >=0.1.7-rc.2 <0.1.8-0 || >=0.2.0-rc.2 <0.2.1-0 || 0.2.1-alpha.2`,已使用 `0.2.0-rc.2`、`0.1.7-rc.2`、`0.1.5-rc.2`、`0.1.5-rc.1`、`0.1.1-rc.2` 和 `0.1.1-rc.1` 的真实 Cordis 服务链验证,且全部纳入 CI smoke 矩阵(Node 22/24 双档);`0.1.2-rc.1` 已通过实际使用验证兼容,但未纳入 CI smoke 矩阵。声明按元组拆成四段而非写成单一区间,是因为 node-semver 只有在范围里存在与目标版本同 `major.minor.patch` 且自身带预发布标签的比较符时,才会放行该预发布版本 —— 例如必须写成 `>=0.2.0-rc.2` 才能让 `0.2.0-rc.2` 进入范围。
78
+ - **DSH 兼容**:`package.json` 声明 DSH runtime `>=0.1.1-rc.1 <0.1.5-0 || >=0.1.5-rc.1 <0.1.6-0 || >=0.1.7-rc.2 <0.1.8-0 || >=0.2.0-rc.2 <0.2.1-0 || 0.2.1-alpha.2 || 0.2.1-rc.1 || 0.2.1-rc.2`,已在本机用真实 Cordis 服务链验证 `0.2.1-rc.1` / `0.2.1-rc.2`(Node 24 严格 smoke;这两条把 Cordis 提升为稳定版 4.0.5 / loader 1.0.6 / timer 1.1.7)、`0.2.1-alpha.2` 以及 `0.2.0-rc.2`、`0.1.7-rc.2`、`0.1.5-rc.2`、`0.1.5-rc.1`、`0.1.1-rc.2`、`0.1.1-rc.1`;全部已声明版本都进了 CI smoke 矩阵(Node 22/24 双档),但 `0.2.1` 那两条因上游从未发布对应版本的 `@deepseek-ai/dsh-invariants`,CI 会**如实标记 SKIPPED,不等于通过**;`0.1.2-rc.1` 已通过实际使用验证兼容,但未纳入 CI smoke 矩阵。声明按元组逐条拆开而非写成单一区间,是因为 node-semver 只有在范围里存在与目标版本同 `major.minor.patch` 且自身带预发布标签的比较符时,才会放行该预发布版本 —— 例如必须写成 `>=0.2.0-rc.2` 才能让 `0.2.0-rc.2` 进入范围。
79
79
  - **桌面客户端(Electron,Windows)**:本插件在 DSH 桌面客户端上实测运行正常(实测 `@deepseek-ai/dsh-desktop` `0.1.7-rc.2`)。桌面客户端会在窗口顶部为自身的最小化 / 最大化 / 关闭按钮保留一条 40px 顶栏,并在文档上标记 `data-windows-titlebar` 与 `--dsh-windows-titlebar-height`;面板据此从该条**下方**开始绘制,所以桌面端自己的关闭按钮永远不会被面板盖住。浏览器端没有该标记,不留白。顶栏高度优先取宿主声明,其次取 Window Controls Overlay 矩形,最后退回 UA;需要微调时可在 DevTools 执行 `localStorage.setItem('dsh-all-usage:topInset', '48')` 后刷新(`0` 表示不留白),无需重新构建。桌面客户端自带运行时,实测版本 `0.1.7-rc.2` 已纳入声明区间与 CI smoke 矩阵(见下表)。
80
80
  - **Web 服务依赖**:Host 将 `webServer` 声明为必需依赖,确保服务晚挂载时由 DSH 等待后再执行插件;该包面向 DSH Web profile,不提供无 WebServer 的 headless 路由。HTTP 守卫还会检查真实 socket peer,反向代理只有在连接本身来自 loopback 时才会被接受。写接口(价格保存、立即同步、节假日抓取、别名)以**进程令牌**为授权凭据,不强制要求 `Origin`:DSH 桌面端把 UI 跑在自定义协议上、请求由 Electron 主进程转发,转发时会删掉 `Origin`(连同 `Host`/`Cookie`/`Sec-Fetch-*`),强制 Origin 会让桌面端所有写入 403;而 `Origin` 若存在仍必须是 loopback 或桌面端自身 scheme,`Host` 仍必须是 loopback(防 DNS rebinding)。
81
+ - **界面语言**:首次进入时面板跟随 DSH 的 **Language 设置**(`Settings → General → Language`,经宿主的 `locale` 服务读取);宿主未提供该服务时退回浏览器语言,最后退回英语。在面板里手动选过语言之后以面板的选择为准,宿主设置不再覆盖它。语言同时决定时区口径——中文按本地时区,英文按 UTC——所以切换语言会重新取一份对应时区的快照。
81
82
 
82
83
  | DSH runtime | Node.js 支持 | 真实 Cordis smoke | 结论 |
83
84
  | --- | --- | --- | --- |
84
- | `0.2.1-alpha.2` | `>=22 <25` | 通过(本机 Node 24 严格真实 Cordis smoke;CI 已配置 Node 22/24,待执行) | 已声明、已验证(仅此精确版本,不代表其他 alpha 版本) |
85
+ | `0.2.1-rc.2` | `>=22 <25` | 通过(本机 Node 24 严格真实 Cordis smoke;稳定版 Cordis 4.0.5 / loader 1.0.6 / timer 1.1.7) | 已声明、已验证(仅此精确版本;CI 因上游缺 `dsh-invariants@0.2.1-rc.2` 如实标记 SKIPPED) |
86
+ | `0.2.1-rc.1` | `>=22 <25` | 通过(本机 Node 24 严格真实 Cordis smoke;稳定版 Cordis 4.0.5 / loader 1.0.6 / timer 1.1.7) | 已声明、已验证(仅此精确版本,不代表其他 rc 版本;CI 因上游缺 `dsh-invariants@0.2.1-rc.1` 如实标记 SKIPPED) |
87
+ | `0.2.1-alpha.2` | `>=22 <25` | 通过(本机 Node 24 严格真实 Cordis smoke;CI 因上游缺 `dsh-invariants@0.2.1-alpha.2` 如实标记 SKIPPED) | 已声明、已验证(仅此精确版本,不代表其他 alpha 版本) |
85
88
  | `0.2.0-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证(历史验证结果,CI 覆盖 Node 22/24) |
86
89
  | `0.1.7-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证(历史验证结果,CI 覆盖 Node 22/24) |
87
90
  | `0.1.5-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证 |
@@ -348,6 +348,11 @@ export function createAggregation(host) {
348
348
  const resolved = resolvePricing(normalized, state.pricingState)
349
349
  state.pricingResolutionCache.set(key, resolved)
350
350
  while (state.pricingResolutionCache.size > 5000) state.pricingResolutionCache.delete(state.pricingResolutionCache.keys().next().value)
351
+ // Every identity is resolved once per revision, which makes this the one place
352
+ // where a DeepSeek-looking route that did not resolve as first-party is visible.
353
+ if (host.pricing !== undefined && host.pricing !== null && typeof host.pricing.noteUnclassifiedRoute === 'function') {
354
+ host.pricing.noteUnclassifiedRoute(normalized, resolved)
355
+ }
351
356
  return resolved
352
357
  }
353
358
  function costForUsage(values, identity, previous, pricingAt, pricingTimeSource) {
@@ -1104,6 +1109,9 @@ export function createAggregation(host) {
1104
1109
  counters: Object.fromEntries(state.diagCounters instanceof Map ? state.diagCounters : []),
1105
1110
  mismatch: state.diagMismatch === undefined ? null : state.diagMismatch,
1106
1111
  accounting: accountingSnapshot(),
1112
+ // Pricing diagnostics: the last reconciliation that moved stored cost, and any
1113
+ // DeepSeek-looking route that is not in the first-party table yet.
1114
+ pricingHealth: typeof host.pricingHealth === 'function' ? host.pricingHealth() : null,
1107
1115
  memory: {
1108
1116
  heapUsedMB: Number((process.memoryUsage().heapUsed / 1048576).toFixed(1)),
1109
1117
  rssMB: Number((process.memoryUsage().rss / 1048576).toFixed(1)),