dsh-spendingframe 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/README.md CHANGED
@@ -1,4 +1,8 @@
1
- # DSHBalance
1
+ # dsh-spendingframe
2
+
3
+ [![npm](https://img.shields.io/npm/v/dsh-spendingframe?label=npm)](https://www.npmjs.com/package/dsh-spendingframe)
4
+ [![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
5
+ [![node](https://img.shields.io/badge/node-%E2%89%A522-brightgreen)](package.json)
2
6
 
3
7
  **DeepSeek API 峰谷时段 · 会话消耗 · 今日花费,常驻在 DSH 输入框下方的一个小条目里。**
4
8
 
@@ -23,7 +27,7 @@ right next to DSH's context usage pill.
23
27
  - **今日花费**:北京时间自然日内的全部会话合计。
24
28
  - **跟随宿主**:颜色、字号、字体全部取用 DSH 自己的设计 token,跟随主题与字号设置。
25
29
  - **原生手感**:与同排的「上下文使用情况」同一套交互 —— 悬停出小气泡,点击出完整明细。
26
- - **零配置**:装好即用,每 5 分钟自动刷新,也随页面重新加载立即刷新。
30
+ - **零配置**:装好即用,每分钟自动刷新,也随页面重新加载立即刷新。
27
31
 
28
32
  ## 交互
29
33
 
@@ -56,12 +60,12 @@ right next to DSH's context usage pill.
56
60
 
57
61
  ### 方式一:从 npm 安装(推荐)
58
62
 
59
- 在 DSH 的插件管理里安装 `dsh-spendingframe`(版本 `^0.2.2`);或者手工编辑当前 profile
63
+ 在 DSH 的插件管理里安装 `dsh-spendingframe`(版本 `^0.2.3`);或者手工编辑当前 profile
60
64
  (`<DSH_HOME>/profiles/<profile>/package.json`):
61
65
 
62
66
  ```jsonc
63
67
  {
64
- "dependencies": { "dsh-spendingframe": "^0.2.2" },
68
+ "dependencies": { "dsh-spendingframe": "^0.2.3" },
65
69
  "dsh": { "profile": { "bundles": [/* …已有的 bundle… */, "dsh-spendingframe"] } }
66
70
  }
67
71
  ```
@@ -73,7 +77,7 @@ right next to DSH's context usage pill.
73
77
  1. 克隆仓库到任意目录(目录名随意,下文用 `<插件目录>` 指代):
74
78
 
75
79
  ```sh
76
- git clone https://github.com/JackyWadih14/DSHB.git DSHBalance
80
+ git clone https://github.com/JackyWadih14/dsh-spendingframe.git dsh-spendingframe
77
81
  ```
78
82
  2. 在 DSH 的插件管理里以**本地目录**安装它;或者把上面那段 `dependencies` 改成
79
83
  `{ "dsh-spendingframe": "file:<本目录的绝对路径>" }` 再 `pnpm install`。
@@ -171,7 +175,7 @@ right next to DSH's context usage pill.
171
175
  ```json
172
176
  {
173
177
  "ok": true, "at": 1791697077790, "peak": false, "window": "空闲时段",
174
- "nextChangeInMs": 69721543, "version": "0.2.2",
178
+ "nextChangeInMs": 69721543, "version": "0.2.4",
175
179
  "session": {
176
180
  "found": true, "id": "session-79fa1914-…", "cost": 1.611052, "calls": 112,
177
181
  "tokens": { "hit": 12345, "miss": 6789, "out": 4321 }, "lastAt": 1791697070000,
@@ -213,6 +217,8 @@ npm run test:real # 额外读本机会话日志,断言真实血缘与金额(
213
217
  | 0.2.0 | 子智能体会话的花费并入父会话;悬停高亮与原生条目一致 |
214
218
  | 0.2.1 | 悬停只显示两项消耗与统计时间,完整明细改为点击弹出,对齐原生「上下文使用情况」;悬停延迟、明细色块等细节与原生一致 |
215
219
  | 0.2.2 | 发布到 npm:包名改为 `dsh-spendingframe`(原 `dshbalance` 被 npm 判定与已有的 `dsh-balance` 过于相似),只读路由随之改为 `/dsh-spendingframe/summary` |
220
+ | 0.2.3 | 名字全仓统一为 `dsh-spendingframe`:源码目录、README 标题、面板页脚、日志前缀不再使用旧品牌名 |
221
+ | 0.2.4 | 刷新间隔由 5 分钟缩短到 1 分钟(数据源是本地会话日志,落盘即带用量,所以缩短间隔真的能更快看到变化) |
216
222
 
217
223
  ## 许可
218
224
 
package/client/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * DSHBalance 客户端半(包名 dsh-spendingframe,手写的 __ModuleLoader__ 工厂包,无需构建步骤)。
2
+ * dsh-spendingframe 客户端半(手写的 __ModuleLoader__ 工厂包,无需构建步骤)。
3
3
  *
4
4
  * 作用:在会话输入框下沿的 `conversation.composer.dock`(“上下文占用”那一行)
5
5
  * 追加一个条目,排在上下文占用右侧,从左到右显示:
@@ -37,8 +37,14 @@ window.__ModuleLoader__.load({
37
37
  const name = 'dsh-spendingframe'
38
38
  /** 只依赖插槽服务。 */
39
39
  const inject = ['slots']
40
- /** 刷新间隔:5 分钟。 */
41
- const REFRESH_MS = 5 * 60 * 1000
40
+ /**
41
+ * 刷新间隔:1 分钟。
42
+ *
43
+ * 数据源是本地会话日志(`session.v4.jsonl.zstd`),每条 `assistant/message`
44
+ * 一落盘就带着 usage,所以这里只受轮询间隔限制;DeepSeek 开放平台账单页那个
45
+ * 「可能延迟 5 分钟」说的是它自己的统计服务,与本插件无关。
46
+ */
47
+ const REFRESH_MS = 60 * 1000
42
48
  /** 宿主路由。 */
43
49
  const ROUTE = '/dsh-spendingframe/summary'
44
50
  /** 悬停多久后浮出小气泡(原生 ContextMeter 的 Tooltip 用的是 delayMs: 200)。 */
@@ -351,7 +357,7 @@ window.__ModuleLoader__.load({
351
357
  .catch((error) => {
352
358
  if (!alive) return
353
359
  setStale(true)
354
- console.warn('[DSHBalance] 读取失败:', error)
360
+ console.warn('[dsh-spendingframe] 读取失败:', error)
355
361
  })
356
362
  }
357
363
  load()
@@ -480,7 +486,7 @@ window.__ModuleLoader__.load({
480
486
  )),
481
487
  ),
482
488
  typeof data.version === 'string' && data.version !== ''
483
- ? React.createElement('div', { style: panelFooterStyle }, `DSHBalance v${data.version}`)
489
+ ? React.createElement('div', { style: panelFooterStyle }, `dsh-spendingframe v${data.version}`)
484
490
  : null,
485
491
  ))
486
492
  : null
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * DSHBalance 宿主半(包名 dsh-spendingframe):把「高峰/空闲 + 会话花费 + 今日花费」暴露成一个只读 HTTP 路由。
2
+ * dsh-spendingframe 宿主半:把「高峰/空闲 + 会话花费 + 今日花费」暴露成一个只读 HTTP 路由。
3
3
  *
4
- * 客户端半(client/client.js)只负责显示:它每 5 分钟拉一次
4
+ * 客户端半(client/client.js)只负责显示:它每 1 分钟拉一次
5
5
  * `GET /dsh-spendingframe/summary?session=<会话 id>`,因此金额只在宿主算一次,
6
6
  * 浏览器不需要接触会话日志,也不需要自己维护价目表。
7
7
  *
@@ -8,7 +8,7 @@
8
8
  * 模型在 `data.message.source.model`。
9
9
  *
10
10
  * 这里只做两件事:把文件读成用量记录,并缓存解析结果(按 mtime + size 失效),
11
- * 这样每 5 分钟一次的轮询不会反复解压没变过的历史会话。
11
+ * 这样每分钟一次的轮询不会反复解压没变过的历史会话。
12
12
  */
13
13
 
14
14
  import { readFileSync, readdirSync, statSync } from 'node:fs'
package/lib/summary.js CHANGED
@@ -206,4 +206,4 @@ export function buildSummary(options = {}) {
206
206
  }
207
207
 
208
208
  /** 与 package.json 保持一致的插件版本,随响应返回便于排查。 */
209
- export const VERSION = '0.2.2'
209
+ export const VERSION = '0.2.4'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-spendingframe",
3
- "version": "0.2.2",
4
- "description": "DSHBalance:DSH 插件,在会话输入框下方、上下文占用右侧显示 DeepSeek API 高峰/空闲状态、会话消耗(含子智能体)与今日花费。",
3
+ "version": "0.2.4",
4
+ "description": "dsh-spendingframe:DSH 插件,在会话输入框下方、上下文占用右侧显示 DeepSeek API 高峰/空闲状态、会话消耗(含子智能体)与今日花费。",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "registry": "https://registry.npmjs.org/",
@@ -9,11 +9,11 @@
9
9
  },
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "git+https://github.com/JackyWadih14/DSHB.git"
12
+ "url": "git+https://github.com/JackyWadih14/dsh-spendingframe.git"
13
13
  },
14
- "homepage": "https://github.com/JackyWadih14/DSHB#readme",
14
+ "homepage": "https://github.com/JackyWadih14/dsh-spendingframe#readme",
15
15
  "bugs": {
16
- "url": "https://github.com/JackyWadih14/DSHB/issues"
16
+ "url": "https://github.com/JackyWadih14/dsh-spendingframe/issues"
17
17
  },
18
18
  "keywords": [
19
19
  "dsh",
@@ -63,7 +63,7 @@ console.log('周一 17:00 距下一次切换 =', msUntilNextChange(bj('2026-10-1
63
63
  // --- 版本号与 package.json 一致 -------------------------------------------
64
64
  const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
65
65
  check('VERSION 与 package.json 一致', VERSION, pkg.version)
66
- check('package.json 已是 v0.2.2', pkg.version, '0.2.2')
66
+ check('package.json 已是 v0.2.4', pkg.version, '0.2.4')
67
67
 
68
68
  // --- 本机真实数据(--real 才跑)-------------------------------------------
69
69
  const now = Date.now()
@@ -212,7 +212,7 @@ function textOf(node) {
212
212
 
213
213
  // --- canned payloads ------------------------------------------------------
214
214
  const peakPayload = {
215
- ok: true, at: Date.parse('2026-10-12T02:00:00Z'), peak: true, window: '高峰时段', version: '0.2.2',
215
+ ok: true, at: Date.parse('2026-10-12T02:00:00Z'), peak: true, window: '高峰时段', version: '0.2.4',
216
216
  session: {
217
217
  cost: 0.434705, calls: 60,
218
218
  own: { cost: 0.3, calls: 57, tokens: { hit: 120000, miss: 4000, out: 900 } },
@@ -301,7 +301,7 @@ check('subagent row', rowMap['子智能体消耗'], '¥0.135(2 个会话 / 3
301
301
  check('today row', rowMap['今日消耗'], '¥1.21(2 个会话 / 91 次调用)')
302
302
  check('own token row', rowMap['本会话 Token'], '命中 120K / 未命中 4K / 输出 900')
303
303
  check('model row', rowMap['模型'], 'deepseek-flash ¥0.435(60 次)')
304
- contains('panel footer carries the version', textOf(footer), 'DSHBalance v0.2.2')
304
+ contains('panel footer carries the version', textOf(footer), 'dsh-spendingframe v0.2.4')
305
305
  check('panel carries the full breakdown, not just the hover lines', [panelText.includes('今日消耗'), panelText.includes('计费时段'), panelText.includes('统计更新时间')], [true, true, true])
306
306
 
307
307
  // --- 4. dismissal ---------------------------------------------------------