@ponydev/dsh-model-usage 1.0.3 → 1.0.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
@@ -60,6 +60,8 @@ CI 会重复执行以上检查;失败不合并。
60
60
  - 颜色/圆角/字号只用 `--dsw-*` token,禁止硬编码色值(fallback 除外)
61
61
  - 设置页只放**短标签 + 控件**,不写说明性长文(口径说明放 README/docs)
62
62
  - 文案全走 i18n(zh/en 两个字典),不出现硬编码中文/英文
63
+ - **语言必须通过框架 `t`(`props.t`)翻译**,禁止用 `navigator.language` 自行判断(DSH 语言可在设置里切换)
64
+ - zh/en 字典键必须完全一致,CI 用 `scripts/check-i18n.mjs` 强制校验
63
65
  - 间距节奏:组件内 12px;卡片内边距 13px 15px;弹窗内容 `mbody` 12px
64
66
  - 修改 client 后:`open test-render.html` 离线验证 + 0 控制台错误
65
67
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.4 — 2026-10-20
4
+
5
+ ### 修复
6
+ - **语言跟随 DSH 设置**:此前用 `navigator.language` 判断,切到英文界面时插件仍显示中文;现在统一走框架 `t`(活动语言 → en 回退)
7
+ - 补齐分组标题(当前会话在用 / 订阅窗口 / API 余额 / 账号钱包 / 其他)的 zh/en 字典键
8
+
9
+ ### 新增
10
+ - `scripts/check-i18n.mjs`:校验 zh/en 字典键完全一致 + 代码使用的键都存在,已接入 CI
11
+
3
12
  ## 1.0.3 — 2026-10-19
4
13
 
5
14
  ### 修复
package/lib/client.js CHANGED
@@ -40,9 +40,10 @@ window.__ModuleLoader__.load({
40
40
  waitingStats: '正在加载统计…',
41
41
  tabOverview: '总览', tabQuota: '额度', tabLog: '请求日志', tabToday: '当天', tab7d: '近 7 天', tab30d: '近 30 天', tabsLabel: '模型用量视图',
42
42
  chipAll: '全部供应商', metricTokens: 'Tokens', metricRequests: '请求数', modelsQuotaTitle: '供应商额度', filterProvider: '按供应商筛选', exportShort: 'CSV', modalStatsTitle: '今日用量', fullStatsHint: '完整统计在 设置 → 模型用量',
43
- spendTitle: '今日实际消耗', spentWord: '支出', rechargedWord: '充值', windowSpentWord: '额度消耗', obsNote: '来自服务商余额/套餐额度变动的实测值,非估算', thTime: '时间', thInput: '输入', thOutput: '输出', thCache: '缓存读', thDur: '耗时', thTtft: '首字', noLog: '暂无请求记录', backfillNote: '已从本机会话日志回填近 30 天',
43
+ spendTitle: '今日实际消耗', spentWord: '支出', rechargedWord: '充值', windowSpentWord: '额度消耗', thTime: '时间', thInput: '输入', thOutput: '输出', thCache: '缓存读', thDur: '耗时', thTtft: '首字', noLog: '暂无请求记录',
44
44
  shortAccount: '账号', remainCompact: '剩 {n}%', remainPrefix: '剩 ', remainSuffix: '', statsError: '统计加载失败', retry: '重试', emptyData: '暂无数据', emptyUsage: '今天还没有调用记录',
45
45
  kpiRequests: '模型调用', kpiTokens: '消耗 Tokens', kpiCacheHit: '缓存命中率',
46
+ groupCurrent: '当前会话在用', groupSub: '订阅窗口', groupApi: 'API 余额', groupWallet: '账号钱包', groupOther: '其他',
46
47
  trendTitle: '使用趋势',
47
48
  thProvider: '供应商', thModel: '模型', thRequests: '请求数', thTokens: 'Tokens',
48
49
  lang: 'zh',
@@ -74,20 +75,29 @@ window.__ModuleLoader__.load({
74
75
  waitingStats: 'Loading stats…',
75
76
  tabOverview: 'Overview', tabQuota: 'Quota', tabLog: 'Request log', tabToday: 'Today', tab7d: 'Last 7 days', tab30d: 'Last 30 days', tabsLabel: 'Model usage views',
76
77
  chipAll: 'All providers', metricTokens: 'Tokens', metricRequests: 'Requests', modelsQuotaTitle: 'Provider quota', filterProvider: 'Filter by provider', exportShort: 'CSV', modalStatsTitle: 'Today\'s usage', fullStatsHint: 'Full stats in Settings → Model usage',
77
- spendTitle: 'Today\'s actual usage', spentWord: 'Spent', rechargedWord: 'Recharged', windowSpentWord: 'Quota used', obsNote: 'Measured from provider balance/quota changes — not an estimate', thTime: 'Time', thInput: 'Input', thOutput: 'Output', thCache: 'Cache', thDur: 'Duration', thTtft: 'TTFT', noLog: 'No requests yet', backfillNote: 'Backfilled from local session logs (30d)',
78
+ spendTitle: 'Today\'s actual usage', spentWord: 'Spent', rechargedWord: 'Recharged', windowSpentWord: 'Quota used', thTime: 'Time', thInput: 'Input', thOutput: 'Output', thCache: 'Cache', thDur: 'Duration', thTtft: 'TTFT', noLog: 'No requests yet',
78
79
  shortAccount: 'Account', remainCompact: '{n}% left', remainPrefix: '', remainSuffix: ' left', statsError: 'Failed to load stats', retry: 'Retry', emptyData: 'No data', emptyUsage: 'No calls today yet',
79
80
  kpiRequests: 'Model calls', kpiTokens: 'Tokens', kpiCacheHit: 'Cache hit rate',
81
+ groupCurrent: 'In use this session', groupSub: 'Subscription windows', groupApi: 'API balance', groupWallet: 'Account wallet', groupOther: 'Other',
80
82
  trendTitle: 'Usage trend',
81
83
  thProvider: 'Provider', thModel: 'Model', thRequests: 'Requests', thTokens: 'Tokens',
82
84
  lang: 'en',
83
85
  }
84
- const dictOf = (t) => (t || (String(navigator.language || '').toLowerCase().startsWith('zh') ? zh : en))
86
+ // 语言:DSH 的活动语言通过框架 seat(props.t)提供;无 seat 时按浏览器语言回退
85
87
  const trWith = (t) => {
86
- const d = dictOf(t)
88
+ if (typeof t === 'function') {
89
+ return (key, vars) => {
90
+ const out = vars ? t(key, vars) : t(key)
91
+ if (out != null && out !== key) return out
92
+ const d = String(navigator.language || '').toLowerCase().startsWith('zh') ? zh : en
93
+ return d[key] != null ? d[key] : (en[key] != null ? en[key] : key)
94
+ }
95
+ }
96
+ const d = String(navigator.language || '').toLowerCase().startsWith('zh') ? zh : en
87
97
  return (key, vars) => {
88
- let s = d[key] != null ? d[key] : (zh[key] != null ? zh[key] : key)
89
- if (vars) for (const k of Object.keys(vars)) s = s.split('{' + k + '}').join(String(vars[k]))
90
- return s
98
+ let v = d[key] != null ? d[key] : (en[key] != null ? en[key] : key)
99
+ if (vars) for (const k of Object.keys(vars)) v = v.split('{' + k + '}').join(String(vars[k]))
100
+ return v
91
101
  }
92
102
  }
93
103
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ponydev/dsh-model-usage",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "DSH Web 插件:实时显示模型供应商额度与用量(DeepSeek / GLM Coding Plan / OpenRouter / Kimi Coding Plan + 自定义适配器)",
5
5
  "keywords": [
6
6
  "dsh",