@rayadesu/dsh-billing 0.2.2 → 0.2.4

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/AGENTS.md CHANGED
@@ -47,7 +47,7 @@ cordis.patch.yml DSH profile bundle 补丁层:挂载 llm-billing + ui-
47
47
  - **密钥不进仓库**:`DEEPSEEK_API_KEY` 等一律由用户环境或凭据 seam 提供,仓库不含真实值。
48
48
  - **README 双语**:每个 README 遵循 DSH 结构 `README.md`(EN) + `README.zh.md`(ZH) +
49
49
  `README.i18n.yaml`(记录两文件 git blob hash,改动后需更新)。
50
- - **版本对齐**:根 bundle 与两个包统一版本号(当前 0.2.2),`pnpm-lock.yaml` 随依赖变更更新。
50
+ - **版本对齐**:根 bundle 与两个包统一版本号(当前 0.2.4),`pnpm-lock.yaml` 随依赖变更更新。
51
51
  - **文本规范**:LF 换行、文件末尾一个换行(`.editorconfig`/`.gitattributes` 已声明)。
52
52
 
53
53
  ## 常用命令
package/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority; after
3
3
  # editing either side, bring the other along and re-record both hashes with:
4
4
  # git hash-object README.md README.zh.md
5
- README.md: f3072dc71e845a685a5ffbc7148d7fa35c9d7ead
6
- README.zh.md: 99be34e3d1a1b328956b37d43aff472f9f62470b
5
+ README.md: a77dbf077c79e2809d1245e0c13e3b920a45708b
6
+ README.zh.md: 330339f5c66e32c5fb95d67d2903018c8a462664
package/README.md CHANGED
@@ -2,19 +2,20 @@
2
2
 
3
3
  English | [中文](README.zh.md)
4
4
 
5
- A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that shows your **DeepSeek account balance**, **this session's (this conversation's) billed spend**, and **today's total spend across all sessions** directly in the web session header.
5
+ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin that shows your **DeepSeek account balance**, **this session's (this conversation's) billed spend**, and **today's total spend across all sessions** directly in the web session header; each completed turn also shows its **turn cost** in the message actions row, and the detail panel ends with a **today session-spend ranking**.
6
6
 
7
- > The balance is the real `GET /user/balance` figure; the session and today spends price each message's billed tokens at the official peak/off-peak rates and are estimates, not billing promises.
7
+ > The balance is the real `GET /user/balance` figure; the session, turn, and today spends price each message's billed tokens at the official peak/off-peak rates and are estimates, not billing promises.
8
8
 
9
9
  ## What it shows
10
10
 
11
11
  - **Session-header badge** — two lines: remaining balance (`剩余额度:¥X`) and this conversation's billed spend (`本轮对话花费:¥X`).
12
- - **Detail panel** — the remaining amount, this session's spend (`本会话花费`) with today's all-session spend beside it (`今日共花费`), one priced row per model (`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`), plus a manual refresh action and a spend disclaimer.
12
+ - **Detail panel** — the remaining amount, this session's spend (`本会话花费`) with today's all-session spend beside it (`今日共花费`), one priced row per model (`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`), plus a manual refresh action and a spend disclaimer. The panel ends with a **today session-spend ranking**: sessions sorted by today's spend, highest first (names come from the log's Chinese titles and follow renames automatically; at most the top 10 rows, with a "…N more sessions" hint).
13
+ - **Turn cost row** — each completed turn's closing message shows `本轮花费:¥X` in its actions row (same strip as the time, copy, and fork controls), right next to the turn's usage card; turns without DeepSeek usage (zero cost) or failed loads stay hidden.
13
14
  - **Failures and empty states** — a session or day without priced usage shows "no usage recorded" instead of a fabricated figure; a missing key, rejected credential, or transport error renders a muted "Balance unavailable" whose tooltip carries the Remote's own error message.
14
15
 
15
16
  ## Data update mechanics
16
17
 
17
- - **Session spend follows the conversation** — on every new message in the current session, the badge recomputes only **this session's spend** and **today's spend** (purely local pricing, no network request), so the spend lines stay live during an ongoing conversation.
18
+ - **Session spend follows the conversation** — on every new message in the current session, the badge recomputes only **this session's spend** and **today's spend** (purely local pricing, no network request), so the spend lines stay live during an ongoing conversation. The host prices incrementally: an unchanged session log is served from the host-side cache, and only the appended tail of a growing log is re-priced.
18
19
  - **Balance stays manual** — the balance is account-level data, queried only on mount, session switch, the manual refresh action, or a browser reload; **there is no polling** and it does not track account changes by itself.
19
20
  - **Old values survive refreshes** — a failed refresh keeps the last good value instead of blanking it.
20
21
 
@@ -26,8 +27,8 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
26
27
 
27
28
  | Package | Side | Role |
28
29
  | --- | --- | --- |
29
- | [`packages/llm-billing`](packages/llm-billing) — `@rayadesu/dsh-llm-billing` | Host | Owns the `/user/balance` transport and the peak/off-peak pricing table. Exposes the `billing` Remote (`getBalance`, `getSessionSpend`, `getTodaySpend`). |
30
- | [`packages/ui-billing`](packages/ui-billing) — `@rayadesu/dsh-client-ui-billing` | Browser | Mounts the `billing` Remote itself and contributes the session-header badge and detail panel. |
30
+ | [`packages/llm-billing`](packages/llm-billing) — `@rayadesu/dsh-llm-billing` | Host | Owns the `/user/balance` transport and the peak/off-peak pricing table. Exposes the `billing` Remote (`getBalance`, `getSessionSpend`, `getTodaySpend`, `getTodaySessionsSpend`, `getTurnSpend`). |
31
+ | [`packages/ui-billing`](packages/ui-billing) — `@rayadesu/dsh-client-ui-billing` | Browser | Mounts the `billing` Remote itself and contributes the session-header badge and detail panel, plus the turn-cost row in the message actions strip. |
31
32
 
32
33
  ## Prerequisites
33
34
 
@@ -36,22 +37,51 @@ A [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) plugin tha
36
37
 
37
38
  ## Installation
38
39
 
39
- > 📌 **About this repository**: this repo is the plugin's **only distribution
40
- > source** — the official [deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)
41
- > repository does **not** ship the billing plugin. It was briefly integrated into
42
- > this user's fork, which has since been reverted to the official commit
43
- > (`141eb6fef8`); this repo no longer depends on any fork.
40
+ ### Install (published to npm)
44
41
 
45
- ### Installation (published to npm, one command)
42
+ The three packages are published to npm under the `@rayadesu` scope. Install the
43
+ bundle plus the two plugin packages in one command — the bundle declares the two
44
+ plugin packages as peer dependencies, which pnpm does not auto-install into the
45
+ profile, so they must be named explicitly.
46
46
 
47
- The three packages are published to npm under the `@rayadesu` scope. Install
48
- the bundle plus the two plugin packages in one command (the bundle declares the
49
- two plugin packages as peer dependencies, which pnpm does not auto-install into
50
- the profile, so they must be named explicitly):
47
+ The `dsh` command you use depends on how dsh is installed:
51
48
 
52
- ```bash
53
- dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
54
- ```
49
+ - **Global install** — use the global `dsh` from anywhere:
50
+
51
+ ```bash
52
+ dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
53
+ ```
54
+
55
+ - **Source-built dsh** (a deepseek-harness checkout) — the CLI only resolves from
56
+ the source directory, so run it through pnpm there (`pnpm dsh` is the
57
+ harness-local binary, equivalent to the global `dsh`):
58
+
59
+ ```bash
60
+ cd deepseek-harness
61
+ pnpm dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
62
+ ```
63
+
64
+ ### pnpm 11 release-age gate
65
+
66
+ A dsh profile installs plugins through pnpm, and pnpm 11's supply-chain
67
+ release-age gate does not pick up packages younger than 24 hours by default —
68
+ a freshly published version is therefore not resolved immediately. To get the
69
+ latest version right after a publish:
70
+
71
+ - Disable the age gate in the profile's pnpm config:
72
+
73
+ ```yaml
74
+ # ~/.dsh/profiles/web/pnpm-workspace.yaml
75
+ minimumReleaseAge: 0
76
+ ```
77
+
78
+ - Or, within the 24-hour window, install with an explicitly pinned version (an
79
+ explicit pin bypasses the age gate; replace `0.2.4` with the version you want;
80
+ from a source checkout, use `pnpm dsh …` as above):
81
+
82
+ ```bash
83
+ dsh plugin --profile web add @rayadesu/dsh-billing@0.2.4 @rayadesu/dsh-llm-billing@0.2.4 @rayadesu/dsh-client-ui-billing@0.2.4
84
+ ```
55
85
 
56
86
  Manual rows (only when you do not want the bundle):
57
87
 
@@ -64,6 +94,18 @@ Manual rows (only when you do not want the bundle):
64
94
  name: '@rayadesu/dsh-client-ui-billing'
65
95
  ```
66
96
 
97
+ ### Common commands
98
+
99
+ Global `dsh` is assumed; a source-built dsh uses `pnpm dsh` from the
100
+ deepseek-harness checkout instead — the subcommands are identical.
101
+
102
+ ```sh
103
+ dsh plugin --profile web list # list the web profile's installed plugins
104
+ dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
105
+ dsh plugin --profile web remove @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
106
+ dsh plugin --profile web update # update plugins to the latest allowed versions
107
+ ```
108
+
67
109
  ### Dependency notes
68
110
 
69
111
  The two plugin packages declare the DeepSeek Harness packages they build on
@@ -115,14 +157,36 @@ workspace-registered protocol package, so `packages/typert-protocol` vendors
115
157
  the published `@deepseek-ai/dsh-typert-protocol@0.1.1-rc.2` declarations; when
116
158
  the dsh dependency line moves, refresh it from the installed package.
117
159
 
118
- Publishing (the bundle and both plugins share one version):
160
+ Publishing (the bundle and both plugins share one version; `prepublishOnly`
161
+ runs the `verify` gate automatically). Use `npm publish` from **inside each
162
+ package directory** — `pnpm publish` fails (token resolution) and a folder
163
+ argument like `npm publish packages/llm-billing` is parsed as a GitHub
164
+ shorthand, which triggers a bogus `git ls-remote` instead of a publish. The
165
+ registry requires a token that bypasses 2FA (an `npm login` session token gets
166
+ E403).
167
+
168
+ **Configure the token once, so it never appears in a command** — put one line
169
+ in `~/.npmrc` referencing an environment variable, which npm expands at
170
+ publish time:
171
+
172
+ ```ini
173
+ //registry.npmjs.org/:_authToken=${NPM_TOKEN}
174
+ ```
175
+
176
+ Then set the variable and `npm publish` plainly — the token is in no argument
177
+ and stays out of shell history:
119
178
 
120
179
  ```sh
121
- pnpm --filter @rayadesu/dsh-llm-billing publish --access public
122
- pnpm --filter @rayadesu/dsh-client-ui-billing publish --access public
123
- pnpm publish --access public # @rayadesu/dsh-billing bundle
180
+ export NPM_TOKEN=<your npm token>
181
+ cd packages/llm-billing && npm publish
182
+ cd packages/ui-billing && npm publish
183
+ npm publish # @rayadesu/dsh-billing bundle (repo root)
124
184
  ```
125
185
 
186
+ (Alternatively write the real token directly into `~/.npmrc`, e.g.
187
+ `npm config set //registry.npmjs.org/:_authToken <TOKEN>`; the commands then
188
+ carry no token either. Either way, **never commit the token**.)
189
+
126
190
  ## Configuration
127
191
 
128
192
  Both packages ship sane defaults; everything below is optional.
@@ -142,12 +206,16 @@ Both packages ship sane defaults; everything below is optional.
142
206
  - Each `assistant/message` event reports three billed token buckets: **cache-hit input**, **cache-miss input** (uncached input + cache writes), and **output** (including reasoning).
143
207
  - Each message is priced at the peak/off-peak rate of its own **Beijing-time** hour, the three buckets are billed separately (`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`), then summed per model. Peak windows apply weekdays (Monday–Friday) only; weekends are always off-peak.
144
208
  - **Today's spend** aggregates every session's events on the current Beijing-time calendar day with the same pricing rules; event dates are also assigned in Beijing time.
209
+ - **Turn cost** prices the messages inside the turn's `turn/start`..`turn/end` range with the same rules (located by the closing message's session id + message id).
210
+ - **Today session ranking** aggregates today's spend per session with the same rules (a cross-day session counts only today's part), sorted descending; names come from the log's latest `session/title` event (the auto-generated Chinese title or a user rename).
145
211
  - Models without a rate row are not priced (the built-in catalog currently has the three V4 rows: V4 Flash, V4 Pro, and V4 Flash Vision Exp). Rates follow the DeepSeek pricing effective **August 17**; the weekend-off-peak rule (weekends billed at off-peak prices all day) follows the adjustment effective **August 23**.
146
212
 
147
213
  ## Known limitations
148
214
 
149
- - **Priced rows only** — the session and today spends only price models that have a `billing.models` row.
150
- - **On-demand read** — today's spend reads every session's full event log on each refresh, so cost grows with total log size.
215
+ - **Priced rows only** — the session, turn, and today spends only price models that have a `billing.models` row.
216
+ - **On-demand aggregation** — today's spend and the session ranking are computed on the host behind a 60-second cache; a miss scans only sessions whose persisted log changed since the last resolution (live sessions fold through the projection cells when the registry is composed), and a growing session's spend is priced incrementally (only the appended tail is re-priced).
217
+ - **Ranking capped at 10** — the panel shows at most the top 10 sessions, with a "…N more sessions" hint.
218
+ - **Turn cost needs a finalized closing message** — interrupted turns have no actions row, so no turn cost; cold sessions served straight from the projection cache may rank with an "Untitled" name until their log is read again.
151
219
  - **Balance does not follow automatically** — the balance stays a manual snapshot (no polling); spending from another client does not move the shown value until a refresh or browser reload.
152
220
  - **Estimate, not a promise** — the session spend prices tokens at official rates; the provider's actual billing prevails.
153
221
 
package/README.zh.md CHANGED
@@ -2,19 +2,20 @@
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
- 一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,在 Web 会话头部直接显示你的 **DeepSeek 账户余额**、**当前会话(本轮对话)的花费**,以及**今日所有会话的共花费**。
5
+ 一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,在 Web 会话头部直接显示你的 **DeepSeek 账户余额**、**当前会话(本轮对话)的花费**,以及**今日所有会话的共花费**;每条已完成的回合还会在消息操作行里显示**本轮花费**,详情面板底部带**今日各会话花费排行**。
6
6
 
7
- > 余额是 `GET /user/balance` 的真实数字;会话花费与今日共花费是按官方峰/谷单价对每条消息的计费 token 逐条计价的结果,不是计费承诺。
7
+ > 余额是 `GET /user/balance` 的真实数字;会话花费、本轮花费与今日共花费是按官方峰/谷单价对每条消息的计费 token 逐条计价的结果,不是计费承诺。
8
8
 
9
9
  ## 显示什么
10
10
 
11
11
  - **会话头部徽标** —— 两行:剩余余额(`剩余额度:¥X`)+ 本轮对话的计费花费(`本轮对话花费:¥X`)。
12
- - **详情面板** —— 剩余金额、本会话花费(`本会话花费`)与其右侧的今日所有会话共花费(`今日共花费`),以及每个模型一行的花费分项(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),外加手动刷新按钮与花费说明。
12
+ - **详情面板** —— 剩余金额、本会话花费(`本会话花费`)与其右侧的今日所有会话共花费(`今日共花费`),以及每个模型一行的花费分项(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),外加手动刷新按钮与花费说明;面板底部是**今日会话花费排行**:按今日花费从高到低排列的会话列表(会话名取日志中的中文标题,重命名后自动同步;最多显示前 10 条,其余以「…还有 N 个会话」提示)。
13
+ - **本轮花费行** —— 每条已完成回合的收尾消息操作行内(与时间、复制、分叉图标同一排)显示「本轮花费:¥X」,紧邻该回合的「本轮用量」卡片;回合没有 DeepSeek 用量(花费为 0)或加载失败时不显示。
13
14
  - **失败与空态** —— 会话或今日没有可计价消耗时显示「暂无消耗记录」而不是编造数字;未配置 key、凭据被拒或传输错误时显示弱化的「额度不可用」,其提示携带 Remote 自己的错误信息。
14
15
 
15
16
  ## 数据更新机制
16
17
 
17
- - **会话花费自动跟随** —— 当前会话每到达一条新消息,徽标就只重算**本会话的花费**与**今日共花费**(纯本地计价,不发网络请求),连续对话时花费会实时跟着走。
18
+ - **会话花费自动跟随** —— 当前会话每到达一条新消息,徽标就只重算**本会话的花费**与**今日共花费**(纯本地计价,不发网络请求),连续对话时花费会实时跟着走。主机端按增量计价:会话日志未变化时直接命中主机端缓存,日志增长时只重算新增的尾部。
18
19
  - **额度保持手动** —— 余额是账户级数据,只在挂载、切换会话、手动点刷新、或刷新浏览器时重新查询 `/user/balance`;**没有轮询**,不会自动跟随账户变化。
19
20
  - **刷新期间旧值保留** —— 刷新失败保留上一次有效值,不会清空。
20
21
 
@@ -26,8 +27,8 @@
26
27
 
27
28
  | 包 | 侧 | 作用 |
28
29
  | --- | --- | --- |
29
- | [`packages/llm-billing`](packages/llm-billing) —— `@rayadesu/dsh-llm-billing` | 主机端 | 负责 `/user/balance` 传输与峰/谷计价表。对外暴露 `billing` Remote(`getBalance`、`getSessionSpend`、`getTodaySpend`)。 |
30
- | [`packages/ui-billing`](packages/ui-billing) —— `@rayadesu/dsh-client-ui-billing` | 浏览器端 | 自己挂载 `billing` Remote,并贡献会话头部徽标与详情面板。 |
30
+ | [`packages/llm-billing`](packages/llm-billing) —— `@rayadesu/dsh-llm-billing` | 主机端 | 负责 `/user/balance` 传输与峰/谷计价表。对外暴露 `billing` Remote(`getBalance`、`getSessionSpend`、`getTodaySpend`、`getTodaySessionsSpend`、`getTurnSpend`)。 |
31
+ | [`packages/ui-billing`](packages/ui-billing) —— `@rayadesu/dsh-client-ui-billing` | 浏览器端 | 自己挂载 `billing` Remote,并贡献会话头部徽标与详情面板、消息操作行里的本轮花费行。 |
31
32
 
32
33
  ## 前置条件
33
34
 
@@ -36,19 +37,45 @@
36
37
 
37
38
  ## 安装
38
39
 
39
- > 📌 **仓库说明**:本仓库是插件的**唯一分发来源**——deepseek-harness 官方仓库
40
- > ([deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness))
41
- > **不含**计费插件;插件曾短暂集成于本用户的 fork,现已回退到官方提交版本
42
- > (`141eb6fef8`),本仓库不再依赖任何 fork。
43
-
44
40
  ### 安装(已发布到 npm,一条命令)
45
41
 
46
42
  三个包已发布到 npm 的 `@rayadesu` scope。一条命令同时安装 bundle 与两个插件包
47
- (bundle 把两个插件包声明为 peer 依赖,而 profile 默认不自动安装 peer,所以要显式列出):
43
+ (bundle 把两个插件包声明为 peer 依赖,而 profile 默认不自动安装 peer,所以要显式列出)。
48
44
 
49
- ```bash
50
- dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
51
- ```
45
+ 用哪个 `dsh` 命令取决于你的 dsh 安装方式:
46
+
47
+ - **全局安装** —— 任意目录直接用全局 `dsh`:
48
+
49
+ ```bash
50
+ dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
51
+ ```
52
+
53
+ - **源码构建的 dsh**(deepseek-harness 源码目录)—— CLI 只在源码目录里能解析,
54
+ 所以要在这个目录里用 pnpm 跑(`pnpm dsh` 即源码内二进制,等价于全局 `dsh`):
55
+
56
+ ```bash
57
+ cd deepseek-harness
58
+ pnpm dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
59
+ ```
60
+
61
+ ### pnpm 11 发布龄门槛
62
+
63
+ dsh profile 通过 pnpm 安装插件,而 pnpm 11 的供应链发布龄门槛默认不会采纳发布不足
64
+ 24 小时的包——刚发布的新版本不会立即被解析。想在发布后立刻拿到最新版:
65
+
66
+ - 在 profile 的 pnpm 配置里关掉发布龄门槛:
67
+
68
+ ```yaml
69
+ # ~/.dsh/profiles/web/pnpm-workspace.yaml
70
+ minimumReleaseAge: 0
71
+ ```
72
+
73
+ - 或者在 24 小时窗口内用**显式钉版本**安装(显式钉版本可绕开门槛,把 `0.2.4` 换成你要的版本;
74
+ 源码构建的 dsh 用 `pnpm dsh …`,同上):
75
+
76
+ ```bash
77
+ dsh plugin --profile web add @rayadesu/dsh-billing@0.2.4 @rayadesu/dsh-llm-billing@0.2.4 @rayadesu/dsh-client-ui-billing@0.2.4
78
+ ```
52
79
 
53
80
  手动补行(仅当不想用 bundle 时):
54
81
 
@@ -61,6 +88,18 @@ dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @ra
61
88
  name: '@rayadesu/dsh-client-ui-billing'
62
89
  ```
63
90
 
91
+ ### 常用命令
92
+
93
+ 下面以全局 `dsh` 为例;源码构建的 dsh 用 `pnpm dsh` 并在 deepseek-harness 源码目录执行,
94
+ 子命令完全一致。
95
+
96
+ ```sh
97
+ dsh plugin --profile web list # 列出 web profile 已安装的插件
98
+ dsh plugin --profile web add @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
99
+ dsh plugin --profile web remove @rayadesu/dsh-billing @rayadesu/dsh-llm-billing @rayadesu/dsh-client-ui-billing
100
+ dsh plugin --profile web update # 把插件更新到当前允许的最新版本
101
+ ```
102
+
64
103
  ### 依赖说明
65
104
 
66
105
  两个插件包把它们依赖的 DeepSeek Harness 包(`@deepseek-ai/cordis`、
@@ -107,14 +146,31 @@ typert 生成器只认工作区内已注册协议包里的 `Remote`/`TypertRemot
107
146
  `packages/typert-protocol` 内嵌了 npm 上 `@deepseek-ai/dsh-typert-protocol@0.1.1-rc.2` 的
108
147
  声明文件;dsh 依赖线升级时,从安装包重新刷新它。
109
148
 
110
- 发布(bundle 与两个插件包统一版本号):
149
+ 发布(bundle 与两个插件包统一版本号;`prepublishOnly` 会自动跑 `verify` 门禁)。
150
+ 要用 `npm publish` 且**必须在各包目录内执行**——`pnpm publish` 会失败(token 读取方式问题),
151
+ 而 `npm publish packages/llm-billing` 这种带路径参数的形式会被 npm 解析成 GitHub 仓库简写,
152
+ 触发假的 `git ls-remote` 而不是发布。registry 要求 **bypass-2FA 的 token**(`npm login`
153
+ 的会话 token 会 E403)。
154
+
155
+ **一次性配置 token(之后命令里不再出现 token)** —— 在 `~/.npmrc` 里写一行并引用环境变量,
156
+ npm 发布时从环境展开:
157
+
158
+ ```ini
159
+ //registry.npmjs.org/:_authToken=${NPM_TOKEN}
160
+ ```
161
+
162
+ 然后设置环境变量并直接 `npm publish` —— token 不在任何命令行参数里,也不进 shell 历史:
111
163
 
112
164
  ```sh
113
- pnpm --filter @rayadesu/dsh-llm-billing publish --access public
114
- pnpm --filter @rayadesu/dsh-client-ui-billing publish --access public
115
- pnpm publish --access public # @rayadesu/dsh-billing bundle
165
+ export NPM_TOKEN=<你的 npm token>
166
+ cd packages/llm-billing && npm publish
167
+ cd packages/ui-billing && npm publish
168
+ npm publish # @rayadesu/dsh-billing bundle(仓库根)
116
169
  ```
117
170
 
171
+ (备选:把真实 token 直接写进 `~/.npmrc`,如 `npm config set //registry.npmjs.org/:_authToken <TOKEN>`,
172
+ 之后命令行同样不含 token。无论哪种方式,**绝不把 token 提交进仓库**。)
173
+
118
174
  ## 配置
119
175
 
120
176
  两个包都有合理默认值,下面都是可选的。
@@ -134,12 +190,16 @@ pnpm publish --access public # @rayadesu/dsh-billing bundle
134
190
  - 每条 `assistant/message` 事件报告三个计费 token 桶:**缓存命中输入**、**未命中输入**(未缓存输入 + 缓存写入)、**输出**(含推理)。
135
191
  - 每条消息按其**发生时刻(北京时间)**所在的峰/谷时段单价计价,三个桶分别计费(`缓存命中 ¥X · 未命中输入 ¥Y · 输出 ¥Z`),再按模型汇总。高峰窗口仅周一至周五适用;周末全天按低谷价计费。
136
192
  - **今日共花费**按同一个计价规则汇总当天(北京时间自然日)所有会话的事件;事件归属的日期同样按北京时间计算。
193
+ - **本轮花费**按同一规则计价该回合 `turn/start`..`turn/end` 区间内的消息(定位到收尾消息的会话 id + 消息 id)。
194
+ - **今日会话花费排行**按同一规则按会话汇总今日花费(跨天会话只统计今天的部分),从高到低排序;会话名取日志中最后一条 `session/title` 事件(自动生成的中文标题或用户重命名的新标题)。
137
195
  - 没有费率行的模型不计入(内置价目表目前含三个 V4 行:V4 Flash、V4 Pro、V4 Flash Vision Exp)。计费按 DeepSeek **8 月 17 日实行**的费率;**周末按低谷价计费**的规则按 **8 月 23 日**生效的调整执行。
138
196
 
139
197
  ## 已知限制
140
198
 
141
- - **有费率行才计价** —— 会话花费与今日共花费只统计价目表(`billing.models`)里有的模型。
142
- - **按需读取** —— 今日共花费每次刷新都会读取所有会话的完整事件日志,成本随总日志大小增长。
199
+ - **有费率行才计价** —— 会话花费、本轮花费与今日共花费只统计价目表(`billing.models`)里有的模型。
200
+ - **按需聚合** —— 今日共花费与今日会话排行在主机端 60 秒缓存之后计算;缓存未命中时只扫描持久化日志自上次解析以来变化过的会话(有投影注册表时,活跃会话直接读投影单元),增长中的会话花费按增量计价(只重算新增尾部)。
201
+ - **排行只显示前 10** —— 详情面板最多展示前 10 个会话,其余以「…还有 N 个会话」提示。
202
+ - **本轮花费只出现在已定稿的收尾消息** —— 中断的回合没有操作行,不显示本轮花费;冷会话(投影缓存直接命中)排行标题可能显示「未命名」,待其日志被重新读取后恢复。
143
203
  - **额度不自动跟随** —— 余额保持手动刷新(无轮询),账户在其他客户端产生消耗时,界面值不会自动变化,需手动刷新或刷新浏览器。
144
204
  - **是估算,不是承诺** —— 会话花费按官方单价对 token 计价;实际计费以服务商为准。
145
205
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayadesu/dsh-billing",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "DeepSeek Harness billing plugin: account balance and this session's billed spend with a session-header badge.",
5
5
  "license": "MIT",
6
6
  "packageManager": "pnpm@11.7.0",
@@ -24,6 +24,7 @@
24
24
  "cordis.patch.yml",
25
25
  "README.md",
26
26
  "README.zh.md",
27
+ "README.i18n.yaml",
27
28
  "LICENSE",
28
29
  "AGENTS.md"
29
30
  ],
@@ -31,8 +32,8 @@
31
32
  "access": "public"
32
33
  },
33
34
  "peerDependencies": {
34
- "@rayadesu/dsh-llm-billing": "^0.2.2",
35
- "@rayadesu/dsh-client-ui-billing": "^0.2.2"
35
+ "@rayadesu/dsh-llm-billing": "^0.2.4",
36
+ "@rayadesu/dsh-client-ui-billing": "^0.2.4"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@deepseek-ai/cordis": "^4.0.1",