dsh-client-ui-cpa-quota 0.4.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-client-ui-cpa-quota contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # dsh-client-ui-cpa-quota
2
+
3
+ [![GitHub](https://img.shields.io/badge/GitHub-wkscc310%2Fdsh--client--ui--cpa--quota-181717?logo=github)](https://github.com/wkscc310/dsh-client-ui-cpa-quota)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![CI](https://github.com/wkscc310/dsh-client-ui-cpa-quota/actions/workflows/ci.yml/badge.svg)](https://github.com/wkscc310/dsh-client-ui-cpa-quota/actions/workflows/ci.yml)
6
+ [![dsh](https://img.shields.io/badge/dsh-0.1.1--rc.x-29abe2)](https://github.com/deepseek-ai/deepseek-harness)
7
+
8
+ English | [中文](README.zh.md)
9
+
10
+ A [DSH (DeepSeek Harness)](https://github.com/deepseek-ai/deepseek-harness) Web UI plugin that shows [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) quota right where you look: a native-styled ring beside the model picker, a health dot on the settings card, and a CPA-management-style panel listing **every account's quota windows** in one place.
11
+
12
+ - Zero dependencies, plain JavaScript, no build step.
13
+ - Instances are discovered automatically from your DSH provider `baseURL`s — no model lists, no config file required.
14
+ - Everything runs browser-side; your management keys never leave this browser's `localStorage`.
15
+
16
+ ## Screenshots
17
+
18
+ ### Collapsed card with quota health dot
19
+
20
+ The settings card stays collapsed like the built-in ones. The dot condenses every instance's worst window: green = healthy, amber = a window under 20%, red = exhausted or a failed refresh, gray = waiting / no key.
21
+
22
+ <p align="center">
23
+ <img src="assets/screenshots/settings-card-collapsed.png" alt="Collapsed CliProxyAPI quota card with health dot" width="900">
24
+ </p>
25
+
26
+ ### All accounts, CPA-management style
27
+
28
+ Expand it and every account of every instance is listed with its subscription plan, provider badge, and all quota windows (5-hour / weekly / monthly) — not filtered by the current model. (Demo data from `tests/mock-cpa.mjs`.)
29
+
30
+ <p align="center">
31
+ <img src="assets/screenshots/settings-card-accounts.png" alt="All-accounts quota panel" width="900">
32
+ </p>
33
+
34
+ ### Ring beside the model picker
35
+
36
+ Hover the ring next to the selected model for matching accounts, providers, plans, windows, and reset times.
37
+
38
+ <p align="center">
39
+ <img src="assets/screenshots/quota-tooltip.png" alt="Model quota tooltip" width="900">
40
+ </p>
41
+
42
+ ## Features
43
+
44
+ - Reads models and `baseURL` values from DSH providers automatically; no model list to maintain.
45
+ - Fingerprints each `baseURL` as CLIProxyAPI and never leaves an empty ring on ordinary OpenAI-compatible endpoints.
46
+ - Supports multiple CLIProxyAPI instances and accounts, filtering the hover tooltip to the selected model while the settings panel always shows everything.
47
+ - Orders windows as `5-hour → weekly → monthly → daily`; the ring uses the first available window in that order.
48
+ - Queries Codex, Claude, Antigravity, Gemini CLI, Kimi, and xAI/Grok through their upstream quota APIs; other CPA providers still expose account status and recent activity.
49
+ - Account probes run through a bounded pool with a per-request timeout — one hung upstream can never stall the refresh cycle.
50
+ - Keeps the last successful snapshot across transient refresh failures and reuses rings across DSH screen remounts.
51
+ - Colors: green ≥20% remaining, amber <20%, red exhausted/error, gray loading or missing a management key.
52
+
53
+ ## Requirements
54
+
55
+ - DSH **Web profile** on the current plugin contract (validated against `dsh` 0.1.1-rc.2); the plugin only registers in the Web UI.
56
+ - A reachable CLIProxyAPI instance with its management API enabled.
57
+ - Models must be routed through a DSH provider whose `baseURL` points at the corresponding CPA instance.
58
+ - A management key for each CPA instance. Keys entered in the settings card stay in the current browser's `localStorage`; YAML-managed keys remain in the YAML file.
59
+
60
+ ## Quick install
61
+
62
+ The plugin declares a `dsh.bundle` manifest, so one command installs **and** activates it — no config editing:
63
+
64
+ ```sh
65
+ dsh plugin --profile web add github:wkscc310/dsh-client-ui-cpa-quota
66
+ ```
67
+
68
+ Prefer the installer? It also handles networks where GitHub is flaky, falls back to copying when pnpm is unavailable, and migrates older installs:
69
+
70
+ ### Windows PowerShell
71
+
72
+ ```powershell
73
+ $p=Join-Path $env:TEMP 'dsh-cpa-install.ps1'; Invoke-WebRequest -UseBasicParsing -Uri 'https://raw.githubusercontent.com/wkscc310/dsh-client-ui-cpa-quota/main/install.ps1' -OutFile $p; powershell -NoProfile -ExecutionPolicy Bypass -File $p
74
+ ```
75
+
76
+ ### macOS / Linux
77
+
78
+ ```sh
79
+ curl -fsSL https://raw.githubusercontent.com/wkscc310/dsh-client-ui-cpa-quota/main/install.sh -o /tmp/dsh-cpa-install.sh && sh /tmp/dsh-cpa-install.sh
80
+ ```
81
+
82
+ Restart the DSH Web host, then open:
83
+
84
+ ```text
85
+ Settings → Plugins → CliProxyAPI Quota
86
+ ```
87
+
88
+ Expand the card, paste the management key for each instance, and reopen the model picker.
89
+
90
+ > After updates, just run the same `dsh plugin add` (or the installer) again and restart the host.
91
+
92
+ ## Manual install
93
+
94
+ ### macOS / Linux
95
+
96
+ ```sh
97
+ git clone https://github.com/wkscc310/dsh-client-ui-cpa-quota.git "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota"
98
+ dsh plugin --profile web add "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota"
99
+ ```
100
+
101
+ ### Windows PowerShell
102
+
103
+ ```powershell
104
+ git clone https://github.com/wkscc310/dsh-client-ui-cpa-quota.git "$env:USERPROFILE\.dsh\plugins\dsh-client-ui-cpa-quota"
105
+ dsh plugin --profile web add "$env:USERPROFILE\.dsh\plugins\dsh-client-ui-cpa-quota"
106
+ ```
107
+
108
+ Without the `dsh` CLI (or without pnpm), copy the plugin into the profile's `node_modules` instead — a symlink will not work, because Node resolves imports from the link target's real path:
109
+
110
+ ```sh
111
+ mkdir -p "$HOME/.dsh/profiles/web/node_modules"
112
+ cp -R "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota" "$HOME/.dsh/profiles/web/node_modules/"
113
+ ```
114
+
115
+ A copy install does not activate the bundle layer, so the loader entry must be added by hand to `~/.dsh/profiles/web/cordis.patch.yml` (Windows: `%USERPROFILE%\.dsh\profiles\web\cordis.patch.yml`). If the file still contains the fresh-profile placeholder `[]`, replace it with the entry:
116
+
117
+ ```yaml
118
+ - insert:
119
+ - id: ui-cpa-quota
120
+ name: dsh-client-ui-cpa-quota
121
+ ```
122
+
123
+ ## Optional configuration
124
+
125
+ Auto-discovery is usually enough. To pin instances or keep management keys in YAML:
126
+
127
+ ```yaml
128
+ - insert:
129
+ - id: ui-cpa-quota
130
+ name: dsh-client-ui-cpa-quota
131
+ config:
132
+ refreshMinutes: 5
133
+ instances:
134
+ - baseURL: https://your-cpa.example
135
+ managementKey: your-management-key
136
+ - baseURL: https://another-cpa.example/v1
137
+ managementKey: another-management-key
138
+ ```
139
+
140
+ The browser settings card overrides YAML. `refreshMinutes` is clamped to at least one minute; do not commit management keys to a public repository.
141
+
142
+ ## Supported quota sources
143
+
144
+ | Provider | Upstream source | Typical windows |
145
+ | --- | --- | --- |
146
+ | Codex / OpenAI | `wham/usage` | 5-hour, weekly, or monthly |
147
+ | Claude | OAuth usage/profile | weekly, monthly |
148
+ | Antigravity | `retrieveUserQuotaSummary`, falling back to `fetchAvailableModels` | 5-hour, weekly, monthly |
149
+ | Gemini CLI | Google quota endpoint | 5-hour, weekly, daily |
150
+ | Kimi | `/coding/v1/usages` | provider-defined |
151
+ | xAI / Grok | billing, with a paid-account health fallback | weekly, monthly |
152
+ | Other CPA providers | auth-file status and recent activity | provider-defined |
153
+
154
+ ## How detection works
155
+
156
+ 1. The plugin builds a model → `baseURL` index from DSH `llm.providers` and `settings.describe`, normalizing away the protocol, `www.`, and a trailing `/v1`.
157
+ 2. It requests `<baseURL>/v0/management/usage-statistics-enabled` for each provider base.
158
+ 3. A 401 containing `management`/`unauthorized`, or a CPA-shaped 2xx, identifies CLIProxyAPI. Typical 404s, other responses, and network failures are not added as quota instances.
159
+ 4. Verdicts are cached in the browser for one hour; **Refresh now** re-fingerprints immediately, so a newly added CPA instance shows up without waiting.
160
+
161
+ That is why a model using an ordinary OpenAI-compatible baseURL has no empty ring. An auto-detected CPA without a management key gets a gray ring and a settings hint.
162
+
163
+ ## Development
164
+
165
+ Plain JavaScript, no build step.
166
+
167
+ ```sh
168
+ node --check lib/client.js && node --check lib/index.js
169
+ node tests/smoke.mjs # full logic + settings-card render harness
170
+ node tests/mock-cpa.mjs # optional: a fake CPA on http://127.0.0.1:8317 (key: mock-key)
171
+ ```
172
+
173
+ Point the plugin's manual instance input at the mock to see a full five-account demo without a real CPA. CI runs the syntax checks and the smoke test on Ubuntu and Windows for every push and pull request.
174
+
175
+ ## FAQ
176
+
177
+ - **No ring?** The selected model's DSH provider `baseURL` must point at CLIProxyAPI rather than an upstream official API, and the management API must be enabled. The ring is per model — switch models and it follows.
178
+ - **Gray ring?** Paste the instance's management key under **Settings → Plugins → CliProxyAPI Quota**.
179
+ - **Just added a CPA instance and nothing shows up?** Hit **Refresh now** in the card — it re-fingerprints every provider base immediately instead of waiting out the one-hour probe cache.
180
+ - **Stale numbers?** Numbers refresh on the configured interval; a failed refresh keeps the last good snapshot and says so on the card.
181
+ - **Where are my keys stored?** In this browser's `localStorage` only. Quota requests go straight from the browser to each instance; the DSH host never sees your keys.
182
+
183
+ ## License
184
+
185
+ [MIT](LICENSE)
package/README.zh.md ADDED
@@ -0,0 +1,185 @@
1
+ # dsh-client-ui-cpa-quota
2
+
3
+ [![GitHub](https://img.shields.io/badge/GitHub-wkscc310%2Fdsh--client--ui--cpa--quota-181717?logo=github)](https://github.com/wkscc310/dsh-client-ui-cpa-quota)
4
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
5
+ [![CI](https://github.com/wkscc310/dsh-client-ui-cpa-quota/actions/workflows/ci.yml/badge.svg)](https://github.com/wkscc310/dsh-client-ui-cpa-quota/actions/workflows/ci.yml)
6
+ [![dsh](https://img.shields.io/badge/dsh-0.1.1--rc.x-29abe2)](https://github.com/deepseek-ai/deepseek-harness)
7
+
8
+ [English](README.md) | 中文
9
+
10
+ 一个 [DSH(DeepSeek Harness)](https://github.com/deepseek-ai/deepseek-harness) Web UI 插件,把 [CLIProxyAPI](https://github.com/router-for-me/CLIProxyAPI) 的额度放到你一定会看的地方:模型选择器旁的原生风格圆环、设置卡片上的健康度圆点,以及一块仿 CPA 管理页的「全部账号额度」面板。
11
+
12
+ - 零依赖、纯 JavaScript、无构建步骤。
13
+ - 从 DSH 提供方的 `baseURL` 自动发现实例——不需要维护模型列表,也不需要配置文件。
14
+ - 全部逻辑跑在浏览器端;管理密钥只保存在当前浏览器的 `localStorage`。
15
+
16
+ ## 展示
17
+
18
+ ### 折叠卡片 + 额度健康度圆点
19
+
20
+ 设置卡片默认折叠,与官方插件卡片一致。圆点浓缩了所有实例最紧张的额度窗口:绿色健康、黄色有窗口低于 20%、红色已耗尽或刷新失败、灰色等待中/未配置密钥。
21
+
22
+ <p align="center">
23
+ <img src="assets/screenshots/settings-card-collapsed.png" alt="折叠态 CliProxyAPI 额度卡片与健康度圆点" width="900">
24
+ </p>
25
+
26
+ ### 全部账号额度,仿 CPA 管理页
27
+
28
+ 展开后列出每个实例的每一个账号:订阅套餐、厂商徽章、全部额度窗口(5 小时 / 每周 / 每月),不按当前模型过滤。(截图数据来自 `tests/mock-cpa.mjs`。)
29
+
30
+ <p align="center">
31
+ <img src="assets/screenshots/settings-card-accounts.png" alt="全部账号额度面板" width="900">
32
+ </p>
33
+
34
+ ### 模型选择器旁的圆环
35
+
36
+ 悬停当前模型左侧的圆环,查看匹配的账号、厂商、套餐、额度窗口和刷新时间。
37
+
38
+ <p align="center">
39
+ <img src="assets/screenshots/quota-tooltip.png" alt="模型额度悬浮卡片" width="900">
40
+ </p>
41
+
42
+ ## 功能
43
+
44
+ - 自动读取 DSH 每个 LLM 提供方的模型和 `baseURL`,不维护模型列表。
45
+ - 自动识别哪些 `baseURL` 是 CLIProxyAPI;普通 OpenAI 兼容地址不会显示空圆环。
46
+ - 支持多个 CLIProxyAPI 实例和多个账号:悬浮卡片按当前模型过滤,设置面板始终展示全部。
47
+ - 窗口按 `5 小时 → 每周 → 每月 → 每日` 排序;圆环优先使用第一个可用窗口。
48
+ - 支持 Codex、Claude、Antigravity、Gemini CLI、Kimi、xAI/Grok;其它 CPA 厂商至少显示账号状态和近期请求活动。
49
+ - 账号探测走有界并发池并带单请求超时——一个挂起的上游绝不会卡住整个刷新周期。
50
+ - 刷新失败时保留上一次成功数据;DSH 切屏重挂载模型按钮时复用圆环,避免闪烁。
51
+ - 颜色含义:绿色 ≥20% 剩余,黄色 <20%,红色已耗尽/错误,灰色加载中或未配置密钥。
52
+
53
+ ## 环境要求
54
+
55
+ - 采用新版插件契约的 DSH **Web profile**(已在 `dsh` 0.1.1-rc.2 上验证;插件只注册 Web UI)。
56
+ - 可访问且启用了管理 API 的 CLIProxyAPI 实例。
57
+ - 每个要显示额度的模型,必须通过 DSH 提供方配置指向对应 CPA `baseURL`。
58
+ - 每个 CPA 实例的 management key。通过设置卡片输入的密钥只保存在当前浏览器的 `localStorage`;使用 YAML 时则由 YAML 文件管理。
59
+
60
+ ## 快速安装
61
+
62
+ 插件声明了 `dsh.bundle` manifest,一条命令即可安装**并自动激活**,无需手动编辑任何配置:
63
+
64
+ ```sh
65
+ dsh plugin --profile web add github:wkscc310/dsh-client-ui-cpa-quota
66
+ ```
67
+
68
+ 也可以用安装脚本:它额外处理 GitHub 网络不稳、pnpm 不可用时回退复制、以及旧版安装的迁移:
69
+
70
+ ### Windows PowerShell
71
+
72
+ ```powershell
73
+ $p=Join-Path $env:TEMP 'dsh-cpa-install.ps1'; Invoke-WebRequest -UseBasicParsing -Uri 'https://raw.githubusercontent.com/wkscc310/dsh-client-ui-cpa-quota/main/install.ps1' -OutFile $p; powershell -NoProfile -ExecutionPolicy Bypass -File $p
74
+ ```
75
+
76
+ ### macOS / Linux
77
+
78
+ ```sh
79
+ curl -fsSL https://raw.githubusercontent.com/wkscc310/dsh-client-ui-cpa-quota/main/install.sh -o /tmp/dsh-cpa-install.sh && sh /tmp/dsh-cpa-install.sh
80
+ ```
81
+
82
+ 重启 DSH Web 宿主,打开:
83
+
84
+ ```text
85
+ 设置 → 插件 → CliProxyAPI 额度
86
+ ```
87
+
88
+ 展开卡片,填入每个实例的 management key,然后重新打开模型选择器即可看到圆环。
89
+
90
+ > 更新插件后,重新运行同一条 `dsh plugin add`(或安装脚本)并重启宿主即可。
91
+
92
+ ## 手动安装
93
+
94
+ ### macOS / Linux
95
+
96
+ ```sh
97
+ git clone https://github.com/wkscc310/dsh-client-ui-cpa-quota.git "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota"
98
+ dsh plugin --profile web add "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota"
99
+ ```
100
+
101
+ ### Windows PowerShell
102
+
103
+ ```powershell
104
+ git clone https://github.com/wkscc310/dsh-client-ui-cpa-quota.git "$env:USERPROFILE\.dsh\plugins\dsh-client-ui-cpa-quota"
105
+ dsh plugin --profile web add "$env:USERPROFILE\.dsh\plugins\dsh-client-ui-cpa-quota"
106
+ ```
107
+
108
+ 没有 `dsh` CLI(或没有 pnpm)时,改为把插件复制进 profile 的 `node_modules` —— 不要用符号链接:Node 会从链接目标的真实路径解析依赖,插件自身的 import 会解析失败:
109
+
110
+ ```sh
111
+ mkdir -p "$HOME/.dsh/profiles/web/node_modules"
112
+ cp -R "$HOME/.dsh/plugins/dsh-client-ui-cpa-quota" "$HOME/.dsh/profiles/web/node_modules/"
113
+ ```
114
+
115
+ 复制安装不会自动激活 bundle 层,需要在 `~/.dsh/profiles/web/cordis.patch.yml`(Windows 为 `%USERPROFILE%\.dsh\profiles\web\cordis.patch.yml`)手动加入 loader 条目。如果文件还是全新 profile 的占位 `[]`,请将其替换为:
116
+
117
+ ```yaml
118
+ - insert:
119
+ - id: ui-cpa-quota
120
+ name: dsh-client-ui-cpa-quota
121
+ ```
122
+
123
+ ## 可选配置
124
+
125
+ 自动发现通常已经足够。如需固定实例或使用 YAML 传入管理密钥:
126
+
127
+ ```yaml
128
+ - insert:
129
+ - id: ui-cpa-quota
130
+ name: dsh-client-ui-cpa-quota
131
+ config:
132
+ refreshMinutes: 5
133
+ instances:
134
+ - baseURL: https://your-cpa.example
135
+ managementKey: your-management-key
136
+ - baseURL: https://another-cpa.example/v1
137
+ managementKey: another-management-key
138
+ ```
139
+
140
+ 浏览器设置卡片的配置优先于 YAML。`refreshMinutes` 最小为 1 分钟;管理密钥不建议提交到公开仓库。
141
+
142
+ ## 支持的额度来源
143
+
144
+ | 厂商 | 上游额度来源 | 常见窗口 |
145
+ | --- | --- | --- |
146
+ | Codex / OpenAI | `wham/usage` | 5 小时、每周或月度 |
147
+ | Claude | OAuth usage/profile | 每周、月度 |
148
+ | Antigravity | `retrieveUserQuotaSummary`,回退 `fetchAvailableModels` | 5 小时、每周、每月 |
149
+ | Gemini CLI | Google quota endpoint | 5 小时、每周、每日 |
150
+ | Kimi | `/coding/v1/usages` | 按接口返回 |
151
+ | xAI / Grok | billing;付费账号带健康检查回退 | 每周、月度 |
152
+ | 其它 CPA 厂商 | auth-file 状态和近期请求 | 取决于 CPA 返回数据 |
153
+
154
+ ## 自动检测原理
155
+
156
+ 1. 插件从 DSH 的 `llm.providers` 和 `settings.describe` 建立「模型 → baseURL」索引,并统一去掉协议、`www.` 和末尾 `/v1`。
157
+ 2. 对每个地址请求 `<baseURL>/v0/management/usage-statistics-enabled`。
158
+ 3. 返回带 `management`/`unauthorized` 的 401,或具备 CPA 特征的 2xx 时判定为 CPA;普通服务常见的 404、其它响应或网络失败不会加入额度实例。
159
+ 4. 探测结果缓存在浏览器一小时;**立即刷新**会立刻重新探测所有地址——新加的 CPA 实例无需等待缓存过期。
160
+
161
+ 因此,使用普通 OpenAI 兼容 baseURL 的模型不会出现空圆环。自动发现的 CPA 如果尚未填 management key,会显示灰色圆环并在设置卡片中提示。
162
+
163
+ ## 开发
164
+
165
+ 纯 JavaScript,无构建步骤。
166
+
167
+ ```sh
168
+ node --check lib/client.js && node --check lib/index.js
169
+ node tests/smoke.mjs # 完整逻辑 + 设置卡片渲染测试
170
+ node tests/mock-cpa.mjs # 可选:在 http://127.0.0.1:8317 起一个假 CPA(密钥 mock-key)
171
+ ```
172
+
173
+ 在插件卡片里手动添加该 mock 地址,无需真实 CPA 即可体验完整的五账号演示。CI 会在 Ubuntu 和 Windows 上对每次 push / PR 运行语法检查与冒烟测试。
174
+
175
+ ## 常见问题
176
+
177
+ - **没有圆环?** 当前模型的 DSH 提供方 `baseURL` 必须指向 CLIProxyAPI 而非上游官方 API,且管理 API 已启用。圆环跟模型走——切换模型即可。
178
+ - **灰色圆环?** 在「设置 → 插件 → CliProxyAPI 额度」中填入该实例的 management key。
179
+ - **刚加了 CPA 实例但没反应?** 点卡片里的「立即刷新」——它会立刻重新探测所有地址,不必等一小时的探测缓存。
180
+ - **数字不新鲜?** 按设定间隔自动刷新;刷新失败会保留上次成功数据并在卡片上说明。
181
+ - **密钥存在哪?** 只存当前浏览器的 `localStorage`。额度请求由浏览器直达各实例,DSH 宿主完全接触不到你的密钥。
182
+
183
+ ## 许可证
184
+
185
+ [MIT](LICENSE)
@@ -0,0 +1,3 @@
1
+ - insert:
2
+ - id: ui-cpa-quota
3
+ name: dsh-client-ui-cpa-quota