dsh-all-usage 1.1.10 → 1.1.13
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 +34 -0
- package/README.md +30 -20
- package/lib/aggregation.js +1 -1
- package/lib/client.js +1 -1
- package/lib/http.js +32 -0
- package/lib/plugin.js +3 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,40 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `dsh-all-usage` are documented here.
|
|
4
4
|
|
|
5
|
+
## [1.1.13] - 2026-09-25
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **DSH 0.1.7-rc.2 is a supported runtime.** The real Cordis smoke passes on it — every route, the session hooks, the ledger flush, the revision fast path and disposal — so `dsh.compatibility.runtime` gains `>=0.1.7-rc.2 <0.1.8-0`, and `0.1.7-rc.2` joins the verified list and the CI smoke matrix. The DSH desktop client runs this runtime line, so the caption-strip work from v1.1.11/v1.1.12 is covered by the same declaration.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- The runtime smoke is version-aware about settings. 0.1.7 replaced the file-backed `@deepseek-ai/dsh-settings-file` provider with an abstract settings seam that no runtime package instantiates; the smoke runs without a settings service on that line and asserts that the plugin stays healthy without one, which is the behaviour the plugin already implements (`ctx.settings` is optional).
|
|
14
|
+
- `0.1.5-rc.2` is covered by the CI smoke matrix instead of being verified locally only, so the verification matrix has no exception left.
|
|
15
|
+
- `scripts/check-package.mjs` now fails when a runtime is called verified without appearing in both the CI matrix and the smoke profile table, so a declaration can no longer outrun its coverage.
|
|
16
|
+
|
|
17
|
+
## [1.1.12] - 2026-09-25
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **The runtime smoke test no longer counts routes by hand.** It asserted that dispose removed exactly 9 exact routes, so v1.1.11 — which adds `/api/all-usage/client-env` — failed every Cordis smoke job and, with it, its own npm publication, while the published package itself was correct. The expected count is now derived from the route list the test already checks, so adding a route can no longer leave a stale number behind.
|
|
22
|
+
|
|
23
|
+
### Note
|
|
24
|
+
|
|
25
|
+
- v1.1.11 was published to GitHub Releases but never reached npm: the publish workflow checks out the release tag and verifies it, and a published tag is never moved. The desktop caption-strip fix reaches npm users with this release; the shipped runtime code is identical to v1.1.11.
|
|
26
|
+
|
|
27
|
+
## [1.1.11] - 2026-09-25
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **The desktop client's own close button is no longer covered.** The usage sheet is a full-window overlay, so its backdrop and grabber bar were painted straight across the 40px caption strip the DSH desktop client keeps for its window buttons (minimise / maximise / close), dimming the client's close button behind the panel. When the host marks the document with `data-windows-titlebar`, the sheet now starts below `--dsh-windows-titlebar-height` (40px on Windows), so the strip stays clear. Browsers are unaffected: without the marker nothing changes.
|
|
32
|
+
- **The strip reservation never actually applied.** `Number(localStorage.getItem('dsh-all-usage:topInset'))` reads an unset key as `0`, which passed the `>= 0` check and returned early — the host marker, the Window Controls Overlay geometry and the user-agent fallback were dead code, so the panel reserved nothing on any desktop host even though the logic was in place. An unset key is now distinguished from an explicit `0`.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- The reserved strip is taken from the host's own declaration first (`data-windows-titlebar` plus `--dsh-windows-titlebar-height`), then the Window Controls Overlay rectangle, then the user agent. `localStorage['dsh-all-usage:topInset']` still overrides everything, so the strip can be tuned without a rebuild.
|
|
37
|
+
- The client reports its environment through the new `GET /api/all-usage/client-env` route, surfaced as `clientEnv` in `/api/all-usage/status`: user agent, overlay height, the reserved strip **and where that number came from**, viewport, and the panel's own rectangles. It reports at load and again whenever the sheet opens — this is what exposed the reservation bug from outside the desktop app.
|
|
38
|
+
|
|
5
39
|
## [1.1.10] - 2026-09-14
|
|
6
40
|
|
|
7
41
|
### Fixed
|
package/README.md
CHANGED
|
@@ -31,15 +31,18 @@ DeepSeek Harness 全量用量看板:按模型、供应商、工作区和时间
|
|
|
31
31
|
### 兼容性与已知限制
|
|
32
32
|
|
|
33
33
|
- **运行环境**:需要 Node.js `>=22 <25`;CI 会在 Node 22 和 Node 24 上运行测试、语法检查和 npm 包内容检查。
|
|
34
|
-
- **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.5-rc.1`、`0.1.1-rc.2` 和 `0.1.1-rc.1` 的真实 Cordis
|
|
34
|
+
- **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.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.1.7-rc.2` 才能让 `0.1.7-rc.2` 进入范围。
|
|
35
|
+
- **桌面客户端(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 矩阵(见下表)。
|
|
35
36
|
- **Web 服务依赖**:Host 将 `webServer` 声明为必需依赖,确保服务晚挂载时由 DSH 等待后再执行插件;该包面向 DSH Web profile,不提供无 WebServer 的 headless 路由。HTTP 守卫还会检查真实 socket peer,反向代理只有在连接本身来自 loopback 时才会被接受。
|
|
36
37
|
|
|
37
38
|
| DSH runtime | Node.js 支持 | 真实 Cordis smoke | 结论 |
|
|
38
39
|
| --- | --- | --- | --- |
|
|
39
|
-
| `0.1.
|
|
40
|
+
| `0.1.7-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证(DSH 桌面客户端即运行于此版本) |
|
|
41
|
+
| `0.1.5-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证 |
|
|
42
|
+
| `0.1.5-rc.1` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证 |
|
|
40
43
|
| `0.1.2-rc.1` | `>=22 <25` | 通过(实际使用验证,未纳入 CI) | 已实际验证兼容 |
|
|
41
|
-
| `0.1.1-rc.2` | `>=22 <25`,CI 覆盖 22/24 |
|
|
42
|
-
| `0.1.1-rc.1` | `>=22 <25`,CI 覆盖 22/24 |
|
|
44
|
+
| `0.1.1-rc.2` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证 |
|
|
45
|
+
| `0.1.1-rc.1` | `>=22 <25`,CI 覆盖 22/24 | 通过(真实 Cordis 服务链,CI 覆盖 Node 22/24) | 已声明、已验证 |
|
|
43
46
|
| 其他版本 | `>=22 <25` | 未测试 | 不在已验证矩阵内 |
|
|
44
47
|
|
|
45
48
|
未列出的 DSH 版本不代表一定不兼容;提交问题时请附 DSH、Node.js 和插件版本。
|
|
@@ -105,11 +108,12 @@ node scripts/replay-fixture.mjs fixtures/usage-events.json
|
|
|
105
108
|
|
|
106
109
|
### 最近更新
|
|
107
110
|
|
|
108
|
-
**v1.1.
|
|
111
|
+
**v1.1.13**
|
|
109
112
|
|
|
110
|
-
-
|
|
111
|
-
-
|
|
112
|
-
-
|
|
113
|
+
- **DSH `0.1.7-rc.2` 正式支持**:真实 Cordis smoke 在该运行时上通过(整条链路:全部路由、钩子、账本落盘、revision 快路径、卸载清理),因此 `dsh.compatibility.runtime` 增加 `>=0.1.7-rc.2 <0.1.8-0`,`0.1.7-rc.2` 进入 verified 列表与 CI smoke 矩阵。DSH 桌面客户端正是运行这条运行时,所以 1.1.11/1.1.12 的桌面端顶栏修复也在同一句声明覆盖之下。
|
|
114
|
+
- **smoke 对设置服务做了版本区分**:0.1.7 把文件型 `@deepseek-ai/dsh-settings-file` 换成了抽象的设置 seam(运行时里没有包实例化它),因此该版本上 smoke 不加载设置服务,并**明确断言**插件在没有设置服务时依旧健康(插件本就把 `ctx.settings` 当可选)。
|
|
115
|
+
- `0.1.5-rc.2` 也纳入 CI smoke 矩阵(此前只是本机实测),验证矩阵里不再有「未纳入 CI」的例外。
|
|
116
|
+
- 门禁加固:`check-package.mjs` 现在要求 verified 里每个版本都同时出现在 CI 矩阵与 smoke profile 表里,杜绝「声明已支持却没有被测」;README 兼容性章节与验证矩阵同步到 v1.1.13。
|
|
113
117
|
|
|
114
118
|
完整版本记录见 [CHANGELOG.md](CHANGELOG.md)。
|
|
115
119
|
|
|
@@ -155,7 +159,7 @@ dsh plugin --profile web add github:ParticleLight/dsh-all-usage
|
|
|
155
159
|
|
|
156
160
|
- **Host 端**(入口 `lib/index.js`,组装 `lib/plugin.js`):按职责拆分为 `aggregation.js`(聚合与查询)、`ledger.js`(持久账本)、`session-sync.js`(历史/实时同步)、`pricing-runtime.js`(运行时定价)、`balance.js`(余额)、`http.js`(安全路由);扫描 `turn/end`、`assistant/chunk` usage 和最终 `assistant/message.usage`,监听 `session/event` 实时折叠,并通过 `webServer` 服务注册数据路由:
|
|
157
161
|
- `GET /api/all-usage` — 兼容统计快照
|
|
158
|
-
- `GET /api/all-usage/status` — 轻量 revision
|
|
162
|
+
- `GET /api/all-usage/status` — 轻量 revision 与同步健康状态,并附带最近一次客户端环境报告(`clientEnv`)
|
|
159
163
|
- `GET /api/all-usage/query` — 按 scope 返回聚合、daily/hourly 趋势和 heatmap 数据;单日 scope 填充 `hourly`,跨日 scope 的 `hourly` 为空
|
|
160
164
|
- `GET /api/all-usage/records` — 按 scope 分页返回脱敏 canonical usage rows
|
|
161
165
|
- `GET /api/all-usage/balance?force=1` — 账户余额(复用 `llm-deepseek` 的 API Key 配置)
|
|
@@ -164,6 +168,7 @@ dsh plugin --profile web add github:ParticleLight/dsh-all-usage
|
|
|
164
168
|
- `GET /api/all-usage/pricing/models?q=...` — 检索官方模型 ID 与名称匹配结果
|
|
165
169
|
- `POST /api/all-usage/pricing` — 保存同步、mapping 和显式价格覆盖(含 context tier 档位)
|
|
166
170
|
- `POST /api/all-usage/pricing/sync` — 手动同步 models.dev 并回填未计价调用
|
|
171
|
+
- `GET /api/all-usage/client-env` — 客户端环境诊断上报(UA、窗口控件遮罩高度、预留顶栏值**及其来源**、视口、面板矩形);客户端在加载与打开面板时各上报一次,只在内存保留
|
|
167
172
|
- **Client 端**:可读源码位于 `src/client.js`,`npm run build:client` 使用固定版本 Terser 生成 `window.__ModuleLoader__` 工厂格式的 `lib/client.js` 浏览器 bundle,并注册侧边栏「用量统计」入口(`sidebar.footer.action` 槽位)。所有 API 仅接受本机 loopback 请求并拒绝显式跨域请求;余额读取与别名写入还要求插件启动时生成、仅在当前进程有效的令牌(余额 GET 兼容浏览器省略 Origin)。英文模式的日期分桶、范围筛选、连续使用、热力图和导出时间统一按 UTC;中文模式按本地时区。
|
|
168
173
|
|
|
169
174
|
### 数据说明
|
|
@@ -173,7 +178,7 @@ dsh plugin --profile web add github:ParticleLight/dsh-all-usage
|
|
|
173
178
|
- 会话删除后,已成功 flush 的用量仍从独立账本恢复;工作区删除同样不会丢数据——其历史用量汇总为一行「已删除」(含未落账的实时用量)。会话销毁提示和周期对账只负责触发重建,不会删除账本记录
|
|
174
179
|
- 同一会话的同一 `turn / step` 只保留一份最终 usage;重试或替换消息会替换旧贡献,不重复累计
|
|
175
180
|
- 输入 Token 按「未含缓存命中」计(缓存命中 / 写入独立成桶);全 0 用量的重放事件不会覆盖已记录的真实用量,纯缓存命中的请求仍会计入
|
|
176
|
-
- 轻量状态接口只公开 Host 实例、统计 revision
|
|
181
|
+
- 轻量状态接口只公开 Host 实例、统计 revision、扫描进度、同步计数与最近一次客户端环境报告(UA、视口、预留顶栏值及其来源、面板矩形——由本机客户端上报且只存内存),不公开会话 ID、工作区路径、提示词或回复正文;完整快照仅在状态变化或手动刷新时获取
|
|
177
182
|
- scope query 将回合(turns)、模型调用(calls)和去重会话(sessions)分开统计;Provider/模型筛选缺少路由信息时明确归为 Unknown,不从展示字符串猜测
|
|
178
183
|
- records 接口只返回短 hash、时间、工作区 ID、结构化模型身份、turn/step、Token buckets 和当前物化来源,不返回原始 session ID、路径、提示词、回复或凭据
|
|
179
184
|
- 看板中的总处理量 = 输入 + 输出 + 缓存读写 + 推理;缓存命中表示复用的上下文 Token,不等于新生成 Token 或实际费用
|
|
@@ -218,15 +223,18 @@ A full usage dashboard for DeepSeek Harness. Analyze tokens, cache behavior, est
|
|
|
218
223
|
### Compatibility and Known Limitations
|
|
219
224
|
|
|
220
225
|
- **Runtime**: Node.js `>=22 <25` is required. CI runs the test suite, syntax checks, and package-content checks on Node 22 and Node 24.
|
|
221
|
-
- **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`; the real Cordis service chain is verified on `0.1.5-rc.1`, `0.1.1-rc.2` and `0.1.1-rc.1
|
|
226
|
+
- **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`; the real Cordis service chain is verified on `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.1.7-rc.2` is admitted only because the range says `>=0.1.7-rc.2`.
|
|
227
|
+
- **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, and that runtime — `0.1.7-rc.2` — is now part of the declared range and of the CI smoke matrix below.
|
|
222
228
|
- **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.
|
|
223
229
|
|
|
224
230
|
| DSH runtime | Node.js support | Real Cordis smoke | Conclusion |
|
|
225
231
|
| --- | --- | --- | --- |
|
|
226
|
-
| `0.1.
|
|
232
|
+
| `0.1.7-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified (the DSH desktop client runs this version) |
|
|
233
|
+
| `0.1.5-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified |
|
|
234
|
+
| `0.1.5-rc.1` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified |
|
|
227
235
|
| `0.1.2-rc.1` | `>=22 <25` | Passed through real-world use (not in CI) | Verified compatible in real-world use |
|
|
228
|
-
| `0.1.1-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (
|
|
229
|
-
| `0.1.1-rc.1` | `>=22 <25`, CI covers 22/24 | Passed (
|
|
236
|
+
| `0.1.1-rc.2` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified |
|
|
237
|
+
| `0.1.1-rc.1` | `>=22 <25`, CI covers 22/24 | Passed (real Cordis service chain, CI covers Node 22/24) | Declared and verified |
|
|
230
238
|
| Other versions | `>=22 <25` | Not tested | Outside the verified matrix |
|
|
231
239
|
|
|
232
240
|
An unlisted DSH version is not necessarily incompatible. Include the DSH, Node.js, and plugin versions when reporting an issue.
|
|
@@ -292,11 +300,12 @@ The command loads the real plugin Host, calls its compatible APIs, checks the do
|
|
|
292
300
|
|
|
293
301
|
### Latest Update
|
|
294
302
|
|
|
295
|
-
**v1.1.
|
|
303
|
+
**v1.1.13**
|
|
296
304
|
|
|
297
|
-
- **
|
|
298
|
-
- **
|
|
299
|
-
-
|
|
305
|
+
- **DSH `0.1.7-rc.2` is now officially supported**: the real Cordis smoke passes on it (the whole plugin: every route, the hooks, the ledger flush, the revision fast path, disposal), so `dsh.compatibility.runtime` gains `>=0.1.7-rc.2 <0.1.8-0`, and `0.1.7-rc.2` joins both the verified list and the CI smoke matrix. The DSH desktop client runs this runtime line, so the caption-strip fix from 1.1.11/1.1.12 sits under the same declaration.
|
|
306
|
+
- **The smoke is version-aware about settings**: 0.1.7 replaced the file-backed `@deepseek-ai/dsh-settings-file` provider with an abstract settings seam that no runtime package instantiates; the smoke therefore runs without a settings service on that line and asserts that the plugin stays healthy without one (the plugin already treats `ctx.settings` as optional).
|
|
307
|
+
- `0.1.5-rc.2` is covered by the CI smoke matrix now instead of being verified locally only, so the matrix no longer has an exception.
|
|
308
|
+
- The gate was tightened: `check-package.mjs` now fails when a version is called verified without appearing in both the CI matrix and the smoke profile table. The README compatibility section and its verification matrix are updated for v1.1.13.
|
|
300
309
|
|
|
301
310
|
See [CHANGELOG.md](CHANGELOG.md) for the complete version history.
|
|
302
311
|
|
|
@@ -334,7 +343,7 @@ The profile patch layer hot-reloads; save the file and refresh the page.
|
|
|
334
343
|
|
|
335
344
|
- **Host** (entry `lib/index.js`, assembled by `lib/plugin.js`): split by responsibility across `aggregation.js` (aggregation/query), `ledger.js` (durable ledger), `session-sync.js` (history/live sync), `pricing-runtime.js` (runtime pricing), `balance.js` (balance), and `http.js` (protected routes); aggregates `turn/end`, `assistant/chunk` usage, and final `assistant/message.usage`, folds live `session/event` updates, and exposes data routes through `webServer`:
|
|
336
345
|
- `GET /api/all-usage` — compatible usage snapshot
|
|
337
|
-
- `GET /api/all-usage/status` — lightweight revision and sync health
|
|
346
|
+
- `GET /api/all-usage/status` — lightweight revision and sync health, plus the last client environment report (`clientEnv`)
|
|
338
347
|
- `GET /api/all-usage/query` — scoped aggregate, daily/hourly trend, and heatmap data; single-day scopes populate `hourly`, while cross-day scopes return an empty `hourly` array
|
|
339
348
|
- `GET /api/all-usage/records` — paginated privacy-safe canonical usage rows
|
|
340
349
|
- `GET /api/all-usage/balance?force=1` — account balance using the configured `llm-deepseek` API key
|
|
@@ -343,6 +352,7 @@ The profile patch layer hot-reloads; save the file and refresh the page.
|
|
|
343
352
|
- `GET /api/all-usage/pricing/models?q=...` — search official model IDs and display-name matches
|
|
344
353
|
- `POST /api/all-usage/pricing` — save sync, mappings, and explicit price overrides, including context-tier bands
|
|
345
354
|
- `POST /api/all-usage/pricing/sync` — sync models.dev and backfill unpriced calls
|
|
355
|
+
- `GET /api/all-usage/client-env` — client environment report (user agent, window-controls overlay height, the reserved strip **and its source**, viewport, panel rectangles); the client reports it at load and whenever the sheet opens, kept in memory only
|
|
346
356
|
- **Client**: readable source lives in `src/client.js`; `npm run build:client` uses the pinned Terser version to generate the `window.__ModuleLoader__` bundle at `lib/client.js`, which registers the “Usage statistics” sidebar entry through the `sidebar.footer.action` slot. All API routes accept loopback requests and reject an explicit cross-origin Origin; balance reads and alias writes also require a process-scoped token generated when the plugin starts (the balance GET tolerates browsers omitting Origin).
|
|
347
357
|
|
|
348
358
|
### Data semantics
|
|
@@ -352,7 +362,7 @@ The profile patch layer hot-reloads; save the file and refresh the page.
|
|
|
352
362
|
- After a session is deleted, successfully flushed usage is restored from the separate ledger; disposal hints and periodic reconciliation trigger rebuilds without deleting ledger rows
|
|
353
363
|
- For each session and logical `turn / step`, only the final usage contribution is kept; retries or replaced messages do not double-count
|
|
354
364
|
- Input tokens are fresh (exclude cache hits/writes, which sit in their own buckets); all-zero usage replays do not overwrite recorded usage and pure cache-read requests still count
|
|
355
|
-
- The lightweight status endpoint exposes only Host instance, stats revision, scan progress, and
|
|
365
|
+
- The lightweight status endpoint exposes only the Host instance, stats revision, scan progress, sync counters, and the last client environment report (user agent, viewport, reserved strip and its source, panel rectangles — reported by a local client and kept in memory only). It does not expose session IDs, workspace paths, prompts, or reply bodies; full snapshots are fetched only after status changes or a manual refresh
|
|
356
366
|
- Scoped results keep turns, model calls, and distinct sessions as separate metrics; missing route identity is explicitly Unknown rather than inferred from a display label
|
|
357
367
|
- The records endpoint returns only a short hash, time, workspace ID, structured model identity, turn/step, token buckets, and current materialization source. It omits raw session IDs, paths, prompts, replies, and credentials
|
|
358
368
|
- Processed tokens = input + output + cache read/write + reasoning; a cache hit means reused context, not newly generated tokens or actual cost
|
package/lib/aggregation.js
CHANGED
|
@@ -601,7 +601,7 @@ export function createAggregation(host) {
|
|
|
601
601
|
}
|
|
602
602
|
function statusSnapshot() {
|
|
603
603
|
commitPendingStats()
|
|
604
|
-
return { instanceId: state.instanceId, ...revisionSnapshot(), updatedAt: state.statsUpdatedAt, scan: scanSnapshot(), sync: syncSnapshot() }
|
|
604
|
+
return { instanceId: state.instanceId, ...revisionSnapshot(), updatedAt: state.statsUpdatedAt, scan: scanSnapshot(), sync: syncSnapshot(), clientEnv: state.clientEnv }
|
|
605
605
|
}
|
|
606
606
|
function serializeIdentity(identity) {
|
|
607
607
|
const value = coerceIdentity(identity)
|