@wannanbigpig/dsh-usage-stats 0.1.1 → 0.1.3

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
@@ -24,6 +24,16 @@ DeepSeek official balance, token usage, a contribution heatmap, and per-hour sta
24
24
 
25
25
  界面支持中文和英文。Token 数据来自会话事件中的 provider-reported `usage`(`assistant/chunk` 或 `assistant/message`),不是本地估算;「消费金额」是根据模型单价 × Token 数计算的**估算值**,请以 DeepSeek 官方账单为准。统计、限额判定与「今日」口径均按**北京时间**(服务端下发 `today` 字段,客户端优先使用),机器或浏览器时区不是 UTC+8 也保持一致。
26
26
 
27
+ ## 界面预览 / Screenshots
28
+
29
+ 「用量/余额」查询中心(概览标签):DeepSeek 官方余额卡、用量预警、Token 汇总、年度贡献热图与按小时统计。
30
+
31
+ ![用量/余额查询中心(概览)](assets/screenshots/usage-panel.png)
32
+
33
+ 「设置 → 用量与计费」:按 API Key(或全局)配置每日消费限额、余额提醒线与预警比例,硬停止默认关闭。
34
+
35
+ ![设置 → 用量与计费(限额配置)](assets/screenshots/limits-settings.png)
36
+
27
37
  ## 快速安装 / Quick start
28
38
 
29
39
  需要 DeepSeek Harness `web` profile(`@deepseek-ai/dsh >= 0.1.0-rc.7`,`dsh plugin` 子命令自该版本引入)与 [pnpm](https://pnpm.io/installation)(`dsh plugin` 会把参数转发给 profile 目录里的 pnpm,因此所有 pnpm 子命令都可用)。
@@ -123,7 +133,7 @@ DEEPSEEK_API_KEY: sk-your-key-here
123
133
 
124
134
  ### 用量提醒与限额(设置 → 用量与计费)
125
135
 
126
- 「设置 → 用量与计费」页面承载限额配置(已从查询弹窗迁出,弹窗保持只读)。可**按 Key(或全局)**配置:
136
+ 「设置 → 用量与计费」页面承载限额配置(已从查询弹窗迁出,弹窗保持只读)。可**按 Key(或全局)**配置;**仅配置一个 API Key 时,「目标 API Key」选择器自动隐藏**,直接配置全局规则即可(单 Key 下全局规则就是生效规则):
127
137
 
128
138
  - **启用限额**:开关。
129
139
  - **每日消费限额**(CNY):今日估算消费达到限额 × `alertPercent`(默认 80%)→ 黄色预警;达到限额 × `criticalPercent`(默认 90%)→ 红色已超限(仅提醒与告警,不拦截);两个比例都可在设置页调整。
package/lib/client.js CHANGED
@@ -1095,7 +1095,9 @@ window.__ModuleLoader__.load({
1095
1095
  const [limits, setLimits] = react.useState(null);
1096
1096
  const limitsRef = react.useRef(null);
1097
1097
  const [statusMap, setStatusMap] = react.useState({});
1098
+ const isSingleKey = (keys || []).length <= 1;
1098
1099
  const [activeKey, setActiveKey] = react.useState(() => {
1100
+ if (isSingleKey) return "__global__";
1099
1101
  const stored = safeGetStorage("dsh_usage_limits_active_key");
1100
1102
  if (stored !== null && stored !== "") return stored;
1101
1103
  return selectedKey ?? "__global__";
@@ -1134,6 +1136,10 @@ window.__ModuleLoader__.load({
1134
1136
 
1135
1137
  // Sync activeKey when selectedKey becomes available (if not explicitly chosen in storage)
1136
1138
  react.useEffect(() => {
1139
+ if (isSingleKey) {
1140
+ setActiveKey("__global__");
1141
+ return;
1142
+ }
1137
1143
  if (selectedKey !== null && selectedKey !== undefined && selectedKey !== "") {
1138
1144
  const stored = safeGetStorage("dsh_usage_limits_active_key");
1139
1145
  if (stored) {
@@ -1142,7 +1148,7 @@ window.__ModuleLoader__.load({
1142
1148
  }
1143
1149
  setActiveKey(selectedKey);
1144
1150
  }
1145
- }, [selectedKey]);
1151
+ }, [selectedKey, isSingleKey]);
1146
1152
 
1147
1153
  // Update form fields when activeKey or limits payload change
1148
1154
  react.useEffect(() => {
@@ -1160,6 +1166,7 @@ window.__ModuleLoader__.load({
1160
1166
  }, [activeKey, limits]);
1161
1167
 
1162
1168
  const handleKeySelect = (newKey) => {
1169
+ if (isSingleKey) return;
1163
1170
  // Do not strand an unsaved batch on the previous key's form.
1164
1171
  if (pendingRef.current !== null && !savingRef.current) flushSave();
1165
1172
  setActiveKey(newKey);
@@ -1306,8 +1313,8 @@ window.__ModuleLoader__.load({
1306
1313
  }),
1307
1314
  react_jsx_runtime.jsx("p", { className: S.note, children: translate("limits.desc") }),
1308
1315
  error && react_jsx_runtime.jsx("div", { className: S.error, children: error }),
1309
- // Key selection
1310
- react_jsx_runtime.jsxs("label", {
1316
+ // Key selection — hidden when only one key is configured (the global rule IS the key rule).
1317
+ keys.length > 1 && react_jsx_runtime.jsxs("label", {
1311
1318
  className: S.pickerRow,
1312
1319
  children: [
1313
1320
  react_jsx_runtime.jsxs("span", {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wannanbigpig/dsh-usage-stats",
3
3
  "description": "DeepSeek 官方余额、Token 用量、月历热图与离线 tokenizer,内置在 Harness 侧栏",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/wannanbigpig/dsh-usage-stats.git"
@@ -17,6 +17,7 @@
17
17
  ],
18
18
  "files": [
19
19
  "lib/",
20
+ "assets/",
20
21
  "cordis.patch.yml",
21
22
  "README.md",
22
23
  "LICENSE"