dsh-subusage 0.10.11 → 0.11.1

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.
Files changed (4) hide show
  1. package/README.md +101 -51
  2. package/lib/client.js +263 -88
  3. package/lib/index.js +314 -55
  4. package/package.json +3 -3
package/README.md CHANGED
@@ -1,16 +1,44 @@
1
- # dsh-subusage
1
+ <div align="center">
2
+ <img src="https://raw.githubusercontent.com/KouzakiUmi/dsh-subusage/main/assets/title.png" width="100%" alt="dsh-subusage —— 模型选择器旁的余量药丸,右侧是同一界面的浅色与深色用量弹层(真实渲染截图)">
2
3
 
3
- ![dsh-subusage](assets/title.svg)
4
+ # 订阅用量显示
4
5
 
5
- **DeepSeek Harness 订阅用量显示插件。** 在模型选择器旁显示当前模型商的订阅余量药丸,点开可看各周期用量、重置时间与套餐;设置页集中管理 30 条提供商 / 区域路由的检测开关与凭据;并以只读额度 API 供其他插件与 Agent 查询。
6
+ **选中的模型还剩多少额度,输入框旁边一眼可见。**
6
7
 
7
- > **English.** dsh-subusage shows subscription quota and balance for the AI providers you already use, as a pill next to the model selector in DeepSeek Harness. Provider switches and credentials live in one settings page, and other plugins or agents can read the same snapshot through a read-only quota API.
8
+ dsh-subusage 把你订阅的 30 家模型服务商额度装进 DeepSeek Harness 的输入框旁边——不切控制台、不猜百分比、不等报错。
8
9
 
9
- [![npm version](https://img.shields.io/badge/npm-0.10.11-blue)](https://www.npmjs.com/package/dsh-subusage)
10
- [![license](https://img.shields.io/badge/license-MIT-green)](#license--security--许可与安全)
11
- [![DSH](https://img.shields.io/badge/DSH-%3E%3D0.2.0--rc.1%20%3C0.3.0--0-informational)](#compatibility--兼容性)
10
+ [![npm version](https://img.shields.io/badge/npm-0.11.1-blue)](https://www.npmjs.com/package/dsh-subusage)
11
+ [![license](https://img.shields.io/badge/license-MIT-green)](#license--security--许可与安全)
12
+ [![DSH](https://img.shields.io/badge/DSH-0.2.x-informational)](#compatibility--兼容性)
12
13
 
13
- ## Overview / 功能
14
+ **安装只需一条命令** → [快速开始](#快速开始)
15
+ </div>
16
+
17
+ ---
18
+
19
+ ## 为什么需要它
20
+
21
+ | 没有它 | 有了它 |
22
+ |---|---|
23
+ | 额度散落在五六家控制台,查一次余额要开五个标签页 | 药丸常驻输入框旁:选中哪家模型就看哪家,多窗口自动取最差一窗 |
24
+ | Agent 跑到一半撞上 429,才知道额度用尽 | 弹层先给结论再给依据:「即将用尽 · 最紧张:每周 · 剩 5% · 3 天后重置」 |
25
+ | Cookie、OAuth 悄悄过期,报错才发现 | MiMo Cookie 提前 2 小时变黄、30 分钟变橙、过期变红;认证失效直说原因与修法 |
26
+ | 每家插件各管各的凭据,格式五花八门 | 一个设置页集中管理 27 条路由的开关与凭据,缺什么补什么 |
27
+
28
+ ## 15 种状态,一眼分清
29
+
30
+ 药丸不写字也能传达状态:每个额度窗口一根彩条(绿 / 黄 / 橙 / 红,满格 = 100% 剩余),需要留意时才追加一个词。下面是全部状态的离线预览(虚构用量数据):
31
+
32
+ <img src="https://raw.githubusercontent.com/KouzakiUmi/dsh-subusage/main/assets/screenshots/pill-states-light.png" width="100%" alt="药丸 15 种状态(浅色,离线预览)">
33
+
34
+ <details>
35
+ <summary>深色主题</summary>
36
+
37
+ <img src="https://raw.githubusercontent.com/KouzakiUmi/dsh-subusage/main/assets/screenshots/pill-states-dark.png" width="100%" alt="药丸 15 种状态(深色,离线预览)">
38
+
39
+ </details>
40
+
41
+ ## 三块能力,一个设置页
14
42
 
15
43
  | 能力 | 解决什么问题 | 入口 |
16
44
  |---|---|---|
@@ -18,13 +46,48 @@
18
46
  | 设置页 | 开关与凭据集中管理;缺凭据、Cookie 过期时把修复入口直接送到卡片上 | 设置 → 订阅用量 → 提供商管理 |
19
47
  | 只读额度 API | 其他插件与 Agent 复用同一份额度数据,不必各自对接各家接口 | Agent 工具 `subusage_quota`、Host 服务 `subUsage.quota()` |
20
48
 
21
- 药丸只画图形:每个额度窗口一根彩色余量条(绿 / 黄 / 橙 / 红,满 = 100% 剩余),正常时不写字;需要留意时追加一个词,如 `周 偏少`、`5时 已用尽`、`需配置`、`拉取失败`。点击弹层,顶部先给结论(额度充足 / 余量偏低 / 即将用尽 / 额度已用尽…),下面是各窗口的剩余百分比与重置倒计时;成功结果按提供商缓存 **60 秒**,手动刷新可跳过普通 TTL(仍遵守上游限流退避与 `Retry-After`)。
49
+ 药丸只画图形:每个额度窗口一根彩色余量条(绿 / 黄 / 橙 / 红,满 = 100% 剩余),正常时不写字;需要留意时追加一个词,如 `周 偏少`、`5时 已用尽`、`需配置`、`拉取失败`。成功结果按提供商缓存 **60 秒**,手动刷新可跳过普通 TTL(仍遵守上游限流退避与 `Retry-After`)。
22
50
 
23
51
  本插件**不注册模型路由**,药丸按 provider id 匹配;因此使用哪个插件提供该模型路由不影响匹配,id 对不上时才不显示。
24
52
 
53
+ ## 30 家提供商,默认开箱即用 10 家
54
+
55
+ DeepSeek、火山方舟(Agent / Coding Plan 个人版与企业版席位)、Z.ai(中国与国际)、Kimi、小米 MiMo、OpenCode Go、Command Code、SuperGrok、Codex(ChatGPT 订阅)、MiniMax(中国与国际)、Synthetic、NanoGPT、SiliconFlow、OpenRouter、Novita、Hyperbolic、DeepInfra、Chutes、Ollama Cloud、Vercel AI Gateway、ZenMux、LiteLLM——订阅窗口、余额、周期额度池都支持。**新安装默认开启 10 条**,其余在设置页一键开启;完整清单、额度类型与鉴权方式见[下方技术文档](#支持的数据--supported-data)。
56
+
57
+ ## 快速开始
58
+
59
+ ```console
60
+ dsh plugin --profile <profile> add dsh-subusage
61
+ ```
62
+
63
+ 1. 安装并启用 bundle,按部署方式重载或重启(只刷新页面不保证 Host 升级)。
64
+ 2. 打开 **设置 → 订阅用量 → 提供商管理**,开启需要的提供商并填凭据——每类凭据的官网入口与填入位置见[凭据获取指引](docs/credentials.md);MiMo 用「登录并自动导入」。
65
+ 3. 回到会话,选中该提供商的模型:输入区左侧出现药丸,点开看窗口明细。
66
+ 4. 排障:点「立即刷新」→ 看设置页顶部 `X/Y 家数据获取成功`(可点击,直接跳到第一家没读成功的)。
67
+
68
+ 可复现的最小示例(DeepSeek,余额型,默认开启,与推理同一把 Key):
69
+
70
+ ```powershell
71
+ # 任选一种凭据来源
72
+ $env:DEEPSEEK_API_KEY = "<你的 DeepSeek API Key>" # 启动环境;改完需按部署方式重启
73
+ # 或在 设置 → 订阅用量 → DeepSeek →「连接与凭据」里手动填写
74
+ ```
75
+
76
+ 重启后在会话中选中 DeepSeek 模型,药丸显示账户余额;也可以直接让 Agent 调用 `subusage_quota(providers: ["deepseek"])` 验证(无需界面)。
77
+
78
+ ## 先说清楚:哪些是实测过的
79
+
80
+ **7 家在真实账号上跑通**:火山方舟 Agent Plan、火山方舟 Coding Plan、Kimi Coding、小米 MiMo、Command Code、SuperGrok、Codex (ChatGPT)。**其余只经过桩测试**——响应形态取自公开文档、第三方实现或抓包,没有在真实账号上跑通,可能随接口变化而失效;失效时在设置页关掉那一家即可,其余不受影响。验证范围与主要风险见[实测覆盖](#support-status--实测覆盖)。额度数字仅供参考,不要当计费依据。
81
+
82
+ ---
83
+
84
+ # 技术文档
85
+
86
+ > 安装、配置、排障的完整参考。快速上手看上面就够了。
87
+
25
88
  ## 支持的数据 / Supported data
26
89
 
27
- 共 **30 条 provider id**:新安装**默认开启 10 条、默认关闭 20 条**(数字与清单取自 [`lib/index.js`](lib/index.js) 顶部的 `PROVIDERS`,展示顺序与短名取自 [`lib/client.js`](lib/client.js) 顶部的 `PROVIDER_META` / `PROVIDER_ORDER`)。
90
+ 共 **27 条 provider id**:新安装**默认开启 10 条、默认关闭 17 条**(数字与清单取自 [`lib/index.js`](lib/index.js) 顶部的 `PROVIDERS`,展示顺序与短名取自 [`lib/client.js`](lib/client.js) 顶部的 `PROVIDER_META` / `PROVIDER_ORDER`)。
28
91
 
29
92
  | 提供商 | provider id | 额度类型 | 鉴权 | 默认 |
30
93
  |---|---|---|---|---|
@@ -34,8 +97,8 @@
34
97
  | Xiaomi MiMo | `xiaomi-token-plan-cn` | 周期额度池 | 官方平台 Cookie(含登录流程) | 开 |
35
98
  | OpenCode Go | `opencode-go` | 订阅窗口 | Bearer | 开 |
36
99
  | Command Code | `commandcode` | 5 小时 / 周 / 月额度池 | 提供方插件的凭据链 | 开 |
37
- | SuperGrok | `xai-oauth` | 周期池 | 只读 Grok CLI 的 OAuth 登录文件 | 开 |
38
- | Codex (ChatGPT) | `openai-codex` | ChatGPT 订阅窗口 | 只读 Codex CLI 的 OAuth 登录文件 | 开 |
100
+ | SuperGrok | `xai-oauth` | 周期池 | 共享 Grok CLI 登录文件,过期经 grok-kit 续约 | 开 |
101
+ | Codex (ChatGPT) | `openai-codex` | ChatGPT 订阅窗口 | 只读 Codex CLI 的 OAuth 登录文件 | 关 |
39
102
  | MiniMax(中国) | `minimax-cn` | 短周期 / 周 | Bearer | 开 |
40
103
  | ARK Agent Plan (arkcli) | `arkcli-agent-plan` | 订阅窗口(AFP) | IAM AK/SK 签名 | 开 |
41
104
  | ARK Coding Plan (arkcli) | `arkcli-coding-plan` | 订阅窗口 | IAM AK/SK 签名 | 开 |
@@ -45,7 +108,6 @@
45
108
  | MiniMax(国际) | `minimax` | 短周期 / 周 | Bearer | 关 |
46
109
  | ARK Agent Plan Team (arkcli) | `arkcli-agent-plan-team` | 席位额度(AFP) | IAM AK/SK 签名 | 关 |
47
110
  | ARK Coding Plan Team (arkcli) | `arkcli-coding-plan-team` | 席位额度 | IAM AK/SK 签名 | 关 |
48
- | Ark Coding Plan(BytePlus,旧插件路由) | `ark-coding-plan-byteplus` | 订阅窗口 | IAM AK/SK 签名 | 关 |
49
111
  | SiliconFlow | `siliconflow` | 余额 | Bearer,与推理同一把 Key | 关 |
50
112
  | OpenRouter | `openrouter` | 限额窗口 + 余额 | 推理 Key(余额需 management / provisioning key) | 关 |
51
113
  | Novita AI | `novita` | 余额 | Bearer | 关 |
@@ -82,7 +144,7 @@
82
144
 
83
145
  其余提供商**只经过桩测试**——响应形态取自公开文档、第三方实现或抓包,**没有在真实账号上跑通过**:
84
146
 
85
- > Z.ai(中国与国际)、OpenCode Go、MiniMax(中国与国际)、Synthetic、NanoGPT、SiliconFlow、DeepSeek、OpenRouter、Novita、Hyperbolic、DeepInfra、Chutes、Ollama Cloud、Vercel AI Gateway、ZenMux、LiteLLM,以及火山方舟的**团队版席位**与 **BytePlus 站点**。
147
+ > Z.ai(中国与国际)、OpenCode Go、MiniMax(中国与国际)、Synthetic、NanoGPT、SiliconFlow、DeepSeek、OpenRouter、Novita、Hyperbolic、DeepInfra、Chutes、Ollama Cloud、Vercel AI Gateway、ZenMux、LiteLLM,以及火山方舟的**团队版席位**。
86
148
 
87
149
  它们可能可用,也可能因为接口变更、字段差异或权限要求而失败。**本插件只保证上面那张表里的**。
88
150
 
@@ -103,12 +165,12 @@
103
165
  |---|---|---|
104
166
  | 核心 peer 范围 | `@deepseek-ai/dsh` 及各核心包均为 `>=0.2.0-rc.1 <0.2.1-0 \|\| >=0.2.1-0 <0.3.0-0` | [`package.json`](package.json) 的 `peerDependencies` |
105
167
  | Node.js | `>=22.19.0` | `engines` 与 `dsh.compatibility.node` |
106
- | 已验证的 Core 版本 | `0.2.1-alpha.1` | 本机实机运行;逐版本状态见 `dsh.compatibility.dshReleases` |
107
- | 最后验证日期 | `2026-10-10` | [开发与验证说明](docs/development.md) |
168
+ | 已验证的 Core 版本 | `0.2.0-rc.2`、`0.2.1-alpha.1`、`0.2.1-alpha.2` | 实机运行;逐版本状态与验证方式见 `dsh.compatibility.dshReleases` |
169
+ | 最后验证日期 | `2026-10-11` | [开发与验证说明](docs/development.md) |
108
170
 
109
171
  > **范围里那个 `||` 分支不是冗余。** node-semver 只有在范围中**某个比较符与该版本的 `major.minor.patch` 元组完全一致、且自身带预发布标签**时,才放行预发布版本。所以 `>=0.2.0-rc.1 <0.3.0-0` 这种看起来覆盖 0.2.x 的写法会**静默排除** `0.2.1-alpha.1`——而它正是当前活跃版本。必须为每个 minor 元组各写一个带预发布标签的分支。
110
172
 
111
- `dsh.compatibility.dshReleases` 逐版本声明已知状态:**只有实际验证过的标 `compatible`**,其余一律 `unknown`——没有证据不猜。声明范围不代表范围内所有版本都已实机验证;实际验证范围(在线接口、真实账号、浏览器像素验收等)见 [开发与验证说明](docs/development.md)。这是树外 Host / Client bundle,通过 `cordis.patch.yml` 插入,不修改 DSH 核心、安装树或 ASAR。
173
+ `dsh.compatibility.dshReleases` 逐版本声明已知状态:**只有实际验证过的标 `compatible`**,其余一律 `unknown`——没有证据不猜。本插件只依赖 Core 的**公开扩展 API 面**(Cordis 服务 `llm`/slots/locale/remote/settings/modelDirectories、4 个核心包的公开导出、client 基座的公开模块),不碰内部组件、不依赖桌面壳版本——这是 0.2.x 各版本实际全兼容的原因;`dshReleases` 记录的是**实测证据**,不是依赖声明。实际验证范围(在线接口、真实账号、浏览器像素验收等)见 [开发与验证说明](docs/development.md)。这是树外 Host / Client bundle,通过 `cordis.patch.yml` 插入,不修改 DSH 核心、安装树或 ASAR。
112
174
 
113
175
  ## Install / 安装
114
176
 
@@ -146,24 +208,6 @@ dsh plugin --profile <profile> remove dsh-subusage
146
208
  - 只取压缩包:`npm pack dsh-subusage`;核对发布结果:`npm view dsh-subusage version dist-tags`。
147
209
  - 本包**没有** `preinstall` / `install` / `postinstall` / `prepare` 脚本,安装期不执行任何代码;也不需要 pnpm 的 `allowBuilds` 授权。
148
210
 
149
- ## Quick start / 快速开始
150
-
151
- 1. 安装并启用 bundle,按部署方式重载或重启。
152
- 2. 打开 **设置 → 订阅用量 → 提供商管理**,开启需要的提供商(默认关闭的 19 条需手动开启)。
153
- 3. 为它配置凭据:在卡片里展开「连接与凭据」填 Key / AK-SK,或把 Key 放进凭据服务 / 启动环境;MiMo 用「登录并自动导入」。**不知道去哪拿、或填了不生效** → 见[凭据获取指引](docs/credentials.md)。
154
- 4. 回到会话,选中该提供商的模型:输入区左侧出现余量药丸(绿色成功 / 红色失败),点开看窗口明细。
155
- 5. 排障顺序:点「立即刷新」→ 看设置页顶部 `X/Y 家数据获取成功`(可点击,跳到第一家没读成功的)。
156
-
157
- 可复现的最小示例(DeepSeek,余额型,默认开启,与推理同一把 Key):
158
-
159
- ```powershell
160
- # 任选一种凭据来源
161
- $env:DEEPSEEK_API_KEY = "<你的 DeepSeek API Key>" # 启动环境;改完需按部署方式重启
162
- # 或在 设置 → 订阅用量 → DeepSeek →「连接与凭据」里手动填写
163
- ```
164
-
165
- 重启后在会话中选中 DeepSeek 模型,药丸显示账户余额;也可以直接让 Agent 调用 `subusage_quota(providers: ["deepseek"])` 验证(无需界面)。
166
-
167
211
  ## 前置:这几家需要提供方插件
168
212
 
169
213
  绝大多数提供商只要一把 API Key 就能用。但下面几家要先装**提供方插件**——它们负责注册模型路由、完成登录并持有凭据;本插件只**读取**同一份凭据,不代为登录、也不保存它们。
@@ -172,7 +216,7 @@ $env:DEEPSEEK_API_KEY = "<你的 DeepSeek API Key>" # 启动环境;改完需
172
216
  | --- | --- | --- |
173
217
  | Command Code | [`@mars-sea/dsh-commandcode-provider`](https://www.npmjs.com/package/@mars-sea/dsh-commandcode-provider) | 在该插件的设置页登录,或运行 `cmd login`(兜底读 `~/.commandcode/auth.json`) |
174
218
  | SuperGrok | [`dsh-grok-kit`](https://github.com/KouzakiUmi/dsh-grok-kit) | 运行 `grok login`,登录文件 `~/.grok/auth.json` |
175
- | Codex(ChatGPT 订阅) | Codex 提供方插件(如 `dsh-codex-connect`) | 运行 `codex login`,登录文件 `$CODEX_HOME/auth.json` 或 `~/.codex/auth.json` |
219
+ | Codex(ChatGPT 订阅) | [`dsh-codex-connect`](https://github.com/franksong2702/dsh-codex-connect)(npm 同名包) | 运行 `codex login`,登录文件 `$CODEX_HOME/auth.json` 或 `~/.codex/auth.json` |
176
220
 
177
221
  > **Codex 默认关闭**:它的提供方插件本身就带一个用量药丸,两个并排只是重复信息。想要本插件这一份(比如想把 Codex 和别家放在一起看)可以在**提供商管理**里手动开启。
178
222
  >
@@ -182,8 +226,8 @@ $env:DEEPSEEK_API_KEY = "<你的 DeepSeek API Key>" # 启动环境;改完需
182
226
 
183
227
  - **设置页路径**:设置 → **订阅用量** → 提供商管理。「没有检测到API的默认隐藏」默认开启;首次没有可见条目时管理区自动展开。关闭的提供商仍可配置凭据,只是不会发起用量请求。
184
228
  - **凭据从哪来**:每一类凭据的**官网入口、环境变量名与界面填入位置**都写在[凭据获取指引](docs/credentials.md)——包括火山的 IAM AK/SK(子用户还要挂 `ArkReadOnlyAccess` 且不限制到项目)、MiMo 的平台会话 Cookie、以及各家 API Key 的对照表。**注意推理 Key 与额度凭据不通用。**
185
- - **默认开关策略**:新安装默认开启 10 条、默认关闭 20 条(**Codex 默认关闭**——它的提供方插件自带用量药丸);开关即时保存,升级保留已保存的开关,不重算默认值。默认隐藏只影响显示,不会自动开启被关闭的提供商。
186
- - **火山方舟是一组**:5 条路由共用同一组 IAM AK/SK,所以设置页只呈现**一张卡片、一个开关**(组内最后选的那条作为代表),卡片里写明本机实际装了哪几条。这些 provider id 并没有合并——药丸仍按 id 匹配路由。旧插件 `@volcengine/ark-plan-api` 的两个国内路由(`ark-coding-plan-cn` / `ark-agent-plan-cn`)**已移除**:它们与 arkcli 的路由查同一份订阅,并列显示只会让人以为买了两个套餐;装了旧插件的用户,药丸仍按那两个 id 显示同一份数据(入口归并到 arkcli 路由)。
229
+ - **默认开关策略**:新安装默认开启 10 条、默认关闭 17 条(**Codex 默认关闭**——它的提供方插件自带用量药丸);开关即时保存,升级保留已保存的开关,不重算默认值。默认隐藏只影响显示,不会自动开启被关闭的提供商。
230
+ - **火山方舟是一组**:4 条路由共用同一组 IAM AK/SK,所以设置页只呈现**一张卡片、一个开关**(本机已装的第一条路由作为代表,都没装则用第一条),卡片里写明本机实际装了哪几条。这些 provider id 并没有合并——药丸仍按 id 匹配路由。旧插件 `@volcengine/ark-plan-api` 的两个国内路由(`ark-coding-plan-cn` / `ark-agent-plan-cn`)**已移除**:它们与 arkcli 的路由查同一份订阅,并列显示只会让人以为买了两个套餐;装了旧插件的用户,药丸仍按那两个 id 显示同一份数据(入口归并到 arkcli 路由)。
187
231
  - **火山方舟不按路由收起**:它的额度走**账号级管控面**,一组 AK/SK 就能查到名下所有套餐(`GetCodingPlanUsage` 与 `GetAFPUsage` 是同一套协议、同一组凭据)。推理路由装没装只影响模型能不能用,**不影响额度能不能查**——所以只持有 Coding Plan、却没在 DSH 里配 coding-plan 路由时,那条额度照样会显示(前提是配了 AK/SK)。
188
232
  - **凭据来源优先级**(`inherit` 模式):**凭据服务 → 启动环境 → 旧手动配置兜底**;切到自定义(`manual`)模式时只使用保存的手动 Key。界面会区分这三种来源。
189
233
  - **不接受本地 Key 的提供商**:`commandcode`(凭据链属提供方插件)、`xai-oauth`、`openai-codex`(只读各自 CLI 的登录文件),以及 MiMo(Cookie 会话)。
@@ -206,9 +250,9 @@ $env:DEEPSEEK_API_KEY = "<你的 DeepSeek API Key>" # 启动环境;改完需
206
250
  | MiniMax(国际) | `MINIMAX_API_KEY` | `minimax` 路由;国际站订阅 Key |
207
251
  | MiniMax(中国) | `MINIMAX_CN_API_KEY` | `minimax-cn` 路由;中国站订阅 Key |
208
252
  | Command Code | `COMMANDCODE_API_KEY` | 凭据由提供方插件管理,本页只读继承;兜底读取 `~/.commandcode/auth.json`(`cmd login`) |
209
- | SuperGrok | 无 | `xai-oauth` 路由;只读 dsh-grok-kit / Grok CLI 共享的 OAuth 登录文件 `~/.grok/auth.json`(旧版 `~/.dsh/.xai-oauth-auth.json`),不保存、**不刷新 token**;access token 过期时直接说明过期时间并提示去刷(不代刷——refresh-token 轮换由 Grok CLI / grok-kit 各自的锁协议管理,第三端刷新会把它们的轮换顶掉)。API Key(`XAI_API_KEY`)取不到订阅周池 |
253
+ | SuperGrok | 无 | `xai-oauth` 路由;读取 dsh-grok-kit / Grok CLI 共享的 OAuth 登录文件 `~/.grok/auth.json`(旧版 `~/.dsh/.xai-oauth-auth.json`),不保存凭据。access token 过期时**借 dsh-grok-kit(≥0.2.0)的官方登录链自动续约**——同一文件、同一把写锁、compare-and-write,不会顶掉共享登录态(本插件绝不自行裸 POST 刷新);未安装 grok-kit 或续约失败时才提示手动重新登录。API Key(`XAI_API_KEY`)取不到订阅周池 |
210
254
  | Codex | 无 | `openai-codex` 路由;只读 Codex CLI 的 ChatGPT 订阅登录文件(`$CODEX_HOME/auth.json` 或 `~/.codex/auth.json`,要求 `auth_mode` 为 `chatgpt`),不保存、不刷新 token |
211
- | 火山方舟 Ark(5 条路由) | `VOLC_ACCESSKEY` + `VOLC_SECRETKEY` | 额度查询要 **IAM Access Key 的 AK/SK 配对**,与推理 API Key(`ARKCLI_*_API_KEY` / `ARK_*_API_KEY`)**不是同一套**;5 条路由共用一组 AK/SK。这一组 AK/SK 能**同时**查到 Agent Plan 与 Coding Plan(含团队版席位)——不存在「Coding Plan 专用查询 key」 |
255
+ | 火山方舟 Ark(4 条路由) | `VOLC_ACCESSKEY` + `VOLC_SECRETKEY` | 额度查询要 **IAM Access Key 的 AK/SK 配对**,与推理 API Key(`ARKCLI_*_API_KEY` / `ARK_*_API_KEY`)**不是同一套**;5 条路由共用一组 AK/SK。这一组 AK/SK 能**同时**查到 Agent Plan 与 Coding Plan(含团队版席位)——不存在「Coding Plan 专用查询 key」 |
212
256
  | SiliconFlow | `SILICONFLOW_API_KEY` | 余额型:`GET /v1/user/info` 返回账户余额,**与推理是同一把 Key** |
213
257
  | OpenRouter | `OPENROUTER_API_KEY` | key 限额与用量用推理 key 即可;**账户余额需要 management / provisioning key**,普通 key 会被 403 拒——此时静默降级为只显示限额,不判失败 |
214
258
  | Synthetic | `SYNTHETIC_API_KEY` | 模型订阅请求额度 |
@@ -252,7 +296,6 @@ arkcli-agent-plan ARKCLI_AGENT_PLAN_API_KEY (额度用 VOLC_ACCESS
252
296
  arkcli-coding-plan ARKCLI_CODING_PLAN_API_KEY
253
297
  arkcli-agent-plan-team ARKCLI_AGENT_PLAN_TEAM_API_KEY
254
298
  arkcli-coding-plan-team ARKCLI_CODING_PLAN_TEAM_API_KEY
255
- ark-coding-plan-byteplus ARK_CODING_PLAN_BYTEPLUS_API_KEY
256
299
  ```
257
300
 
258
301
  解析顺序(`inherit` 模式):**凭据服务 → 启动环境 → 旧手动配置兜底**;自定义(`manual`)模式只使用保存的手动 Key。Cookie 与登录文件型凭据不走这条链,见 [MiMo 登录与 Cookie](docs/providers.md#mimo-登录与-cookie) 与 [Codex ChatGPT 订阅凭据](docs/providers.md#codex-chatgpt-订阅凭据)。修改启动环境后是否需要重启取决于目标部署,不能把「我已经改了环境变量」当作运行进程已经读到。
@@ -267,7 +310,7 @@ ark-coding-plan-byteplus ARK_CODING_PLAN_BYTEPLUS_API_KEY
267
310
  |---|---|---|
268
311
  | `~/.dsh/dsh-subusage.json` | 本插件自己的配置:开关、手动 Key、MiMo Cookie、Z.ai 组织 / 项目、LiteLLM 地址、火山 AK/SK、计时元数据 | 读写;POSIX 上新建目录 `0700`、临时文件 `0600`,替换前再收紧 |
269
312
  | `~/.codex/auth.json`(或 `$CODEX_HOME/auth.json`) | Codex CLI 的 ChatGPT 登录(要求 `auth_mode: chatgpt`) | **只读**,不保存、不刷新 |
270
- | `~/.grok/auth.json`(回退 `~/.dsh/.xai-oauth-auth.json`) | Grok CLI / dsh-grok-kit 的 OAuth 登录 | **只读**,不保存、不刷新 |
313
+ | `~/.grok/auth.json`(回退 `~/.dsh/.xai-oauth-auth.json`) | Grok CLI / dsh-grok-kit 的 OAuth 登录 | 平时只读;过期时经 grok-kit 官方链续约并写回同一文件,不自行裸刷 |
271
314
  | `~/.commandcode/auth.json` | Command Code CLI(`cmd login`)的 Key | **只读**兜底 |
272
315
 
273
316
  **网络访问**:只连上面清单里各家自己的额度 / 余额端点,以及 `platform.xiaomimimo.com`(MiMo 用量与登录)、`api.commandcode.ai`、`cli-chat-proxy.grok.com`、`chatgpt.com/backend-api`、火山管控面 `open.volcengineapi.com`,外加你自己填写的 LiteLLM proxy 地址。完整域名表见 [网络端点](docs/providers.md#网络端点)。MiMo 自动登录会另外打开官方平台页面,由你在该页面自行输入密码与验证码。**本插件没有自己的服务器,不做遥测,也不把你的数据发给任何第三方。**
@@ -301,8 +344,10 @@ ark-coding-plan-byteplus ARK_CODING_PLAN_BYTEPLUS_API_KEY
301
344
 
302
345
  调用约定(**结果永远不为空**):
303
346
 
304
- - 模型手里的名字往往不是这里的 provider id(它更可能看到 DSH 的路由名,例如 `zai`),所以匹配是**宽松**的:一个名字命中多条路由时**全部返回**(`zai` → 中国版 + 国际版,`ark` → 5 条),每条各自带着真实 `state`(没启用的如实标 `disabled`),由调用方自己判断要看哪条。
305
- - 一个名字都认不出时,返回里会**先**给一条说明(写明可用写法),**再附上全部 30 条数据**——数据先给出去,判断交给调用方,而不是回一个空结果。
347
+ - 模型手里的名字往往不是这里的 provider id(它更可能看到 DSH 的路由名,例如 `zai`),所以匹配是**宽松**的:一个名字命中多条路由时**全部返回**(`zai` → 中国版 + 国际版,`ark` → 4 条),每条各自带着真实 `state`(没启用的如实标 `disabled`),由调用方自己判断要看哪条。
348
+ - 一个名字都认不出时,返回里会**先**给一条说明(写明可用写法),**再附上全部 27 条数据**——数据先给出去,判断交给调用方,而不是回一个空结果。
349
+ - **点名的家原样返回,其余按「有没有数据」收起**:`providers: ["kimi"]` 时被点中的家即使没配凭据也照原样给出(用户问的正是「它为什么没数据」);**不点名时**——以及名字一个都没认出来、走全量兜底时——省略检测已关闭、未配置凭据、以及接口没报告任何额度的条目,省略条数按**家**写进 `omitted`(同一家的多个 Command Code 账户只算一家),否则二十多条路由会把真正的数字淹掉。**读取失败的条目会保留**——那是「这次没读到」,不是「没配置」,省略掉只会把排障方向带偏;认不出的名字自己那行也保留。
350
+ - **Command Code 按账户各回一条**:账户清单读自提供方插件的 `llm-commandcode` 设置,每条带 `account`(账户名)、`accountActive`(当前激活的那个)与 `accountMode`(`fixed` 固定账户 / `auto` 自动轮换),激活账户排在最前。「还剩多少」与「现在实际用哪个账户」一次问清。
306
351
 
307
352
  **Host 服务**(Cordis `Service`,key 为 `subUsage`):
308
353
 
@@ -311,16 +356,19 @@ const service = ctx.get("subUsage");
311
356
  const view = await service.quota({ providerIds: ["deepseek"], force: false });
312
357
  // view = {
313
358
  // updatedAt,
314
- // providers: [{ providerId, label, state, windows, extras, coverage?, freshness?, lastSuccessAt?, error? }]
359
+ // providers: [{ providerId, label, state, windows, extras, coverage?, freshness?, lastSuccessAt?, error?,
360
+ // account?, accountActive?, accountMode? }]
315
361
  // }
316
362
  ```
317
363
 
318
364
  - `state`:`ok` | `no-key` | `no-cookie` | `error` | `disabled`
319
365
  - `windows[].percent` 是**已用**百分比(0–100);`extras` 放余额与套餐名等补充项
320
- - 视图**刻意精简**:不返回设置,也不返回 `keySource` / `apiDetected` / 继承变量名等内部状态,第三方消费者拿不到任何与 Key 相关的字段
366
+ - `account` / `accountActive` / `accountMode` 只在多账户的 Command Code 上出现(见下);此时同一条路由会有**多条**条目(每个账户一条,`providerId` 相同),消费方按 `account` 区分
367
+ - 视图**刻意精简**:不返回设置,也不返回 `keySource` / `apiDetected` / 继承变量名等内部状态,第三方消费者拿不到任何与 Key 相关的字段。多账户路由(Command Code)连错误文案里的**凭据引用名**也会换成账户标签(`Account 2`),内部 `apiKeyEnv` 只留在本机界面那条通道里(用户要靠它定位该往哪个 ref 写凭据)
321
368
  - 视图里**不出现值为 `undefined` 的字段**:字段缺席表示「这家没有报告」,而不是「报告了空」——带 `undefined` 的键会被调用方的 schema 校验判成型别错误
322
369
  - 单家读取失败只影响它自己的条目,其余照常返回
323
- - 与设置页共用同一份缓存(TTL 60 秒),频繁调用不会反复请求各家接口
370
+ - 与设置页共用同一份缓存(TTL 60 秒),频繁调用不会反复请求各家接口;多账户各按「路由 id + 账户引用名」占一份缓存,读全部账户不会互相驱逐
371
+ - `quota()` 本身**不过滤**条目(第三方可能正需要「这家没配」这个事实);`subusage_quota` 工具的不点名调用才省略空条目
324
372
 
325
373
  ## Troubleshooting / 常见问题
326
374
 
@@ -341,8 +389,8 @@ const view = await service.quota({ providerIds: ["deepseek"], force: false });
341
389
  | 保存成功但验证失败 | 凭据已保存,检查网络、区域或账号后重试;保存与在线验证分别反馈 |
342
390
  | 保存提示配置已改变 | 另一窗口或实例更新了设置;重新读取配置后再编辑,避免旧表单覆盖新值 |
343
391
  | 升级后仍是旧界面或 RPC 不匹配 | 确认运行中的 Host 和 Client 都已重载;仅刷新页面不能保证 Host 升级 |
344
- | Command Code 额度与实际账户不同 | 可在药丸弹层切换提供方插件的服务账户;「自动轮换」时仍显示默认账户(顶层 Key)的用量,不跟随轮换中的实际服务账户,提供方自定义 `apiBase` 也不跟随 |
345
- | SuperGrok 提示认证失效 | 登录文件里的 OAuth token 会过期;在 设置 → Grok Kit 重新登录、运行 `grok login`,或让 Grok 侧使用一次以刷新共享登录文件后重试。API Key(`XAI_API_KEY`)取不到订阅周池 |
392
+ | Command Code 额度与实际账户不同 | 在 设置 → 订阅用量 的 Command Code 面板或用量的药丸弹层里都能切换提供方插件的服务账户(同一开关):「自动轮换」时显示默认账户(顶层 Key)的用量,不跟随轮换中的实际服务账户,提供方自定义 `apiBase` 也不跟随。想一次看全部账户的余量与当前激活项,可让 Agent 调 `subusage_quota(providers: ["commandcode"])` |
393
+ | SuperGrok 提示认证失效 | access token 过期时插件会先经 dsh-grok-kit(≥0.2.0)的官方登录链自动续约同一共享登录文件,通常无需操作;只有未安装/旧版 dsh-grok-kit 或续约失败(如 refresh_token 已失效)才需在 设置 → Grok Kit 重新登录或运行 `grok login` 后重试。API Key(`XAI_API_KEY`)取不到订阅周池 |
346
394
  | 火山方舟报签名或权限错误 | AK 与 SK 必须来自同一个 IAM 用户(跨来源拼凑只会 401 且看不出根因);确认用的是 IAM Access Key 而不是方舟推理 API Key;403 多为未订阅或权限不足 |
347
395
 
348
396
  ## Development / 开发
@@ -381,7 +429,7 @@ node scripts/check-browser-runtime.mjs # 需要工作区可解析 playwright-c
381
429
 
382
430
  文档入口:[凭据获取指引](docs/credentials.md)(每类凭据的官网入口、环境变量与填入位置、报错对照)、[开发与验证](docs/development.md)(RPC 契约、缓存与凭据约定、离线预览与实机验收范围)、[提供商清单与额度语义](docs/providers.md)、[提供商覆盖与取舍](docs/provider-coverage.md)、[UX 设计](docs/design-ux.md)、[发布与市场收录](docs/publish.md)、[更新记录](docs/changelog.md)、[审查记录](docs/code-review.md)。
383
431
 
384
- > 打包说明:`package.json` 的 `files` 白名单是 `lib` / `locale` / `cordis.patch.yml` / `README.md`,因此 `assets/title.svg`、`assets/screenshots/` 与 `docs/` **不进 npm 包**——顶部 title 图与下面的界面预览只在 GitHub 页面显示。改动白名单属于发布决策,需单独处理。
432
+ > 打包说明:`package.json` 的 `files` 白名单是 `lib` / `cordis.patch.yml` / `README.md` / `LICENSE`,因此 `assets/title.svg`、`assets/screenshots/` 与 `docs/` **不进 npm 包**——顶部 title 图与下面的界面预览只在 GitHub 页面显示。改动白名单属于发布决策,需单独处理。
385
433
 
386
434
  ### 界面预览
387
435
 
@@ -395,7 +443,9 @@ node scripts/check-browser-runtime.mjs # 需要工作区可解析 playwright-c
395
443
 
396
444
  ![浅色 NanoGPT 用量弹层(离线测试预览)](https://raw.githubusercontent.com/KouzakiUmi/dsh-subusage/main/assets/screenshots/usage-popover-light.png)
397
445
 
398
- 截图声明见根目录 [`screenshots.json`](screenshots.json)。两张图都是**当前版本**的离线组件预览(虚构用量、桩网络、无凭据),已随本版本重做,底部水印明确标注「非运行中的 DSH 截图」。真实 DSH Loader、实际账号在线接口与多账户映射仍未验收,截图不代表已通过这些检查。
446
+ 药丸 15 种状态一览(浅色 / 深色)见[开头的能力展示](#15-种状态一眼分清)。
447
+
448
+ 截图声明见根目录 [`screenshots.json`](screenshots.json)。这些图都是**当前版本**的离线组件预览(虚构用量、桩网络、无凭据),已随本版本重做,底部水印明确标注「非运行中的 DSH 截图」。真实 DSH Loader、实际账号在线接口与多账户映射仍未验收,截图不代表已通过这些检查。
399
449
 
400
450
  ## License & security / 许可与安全
401
451