dsh-plugin-subscription-oauth 0.16.2 → 0.17.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.
Files changed (43) hide show
  1. package/README.dev.md +1 -1
  2. package/README.md +7 -6
  3. package/README.zh.dev.md +1 -1
  4. package/README.zh.md +7 -6
  5. package/lib/auth/workbuddy-flow.d.ts +1 -1
  6. package/lib/auth/workbuddy-flow.js +14 -9
  7. package/lib/client/index.js +10 -1
  8. package/lib/client.js +6 -1
  9. package/lib/client.js.map +1 -1
  10. package/lib/index.js +21 -0
  11. package/lib/providers/antigravity.d.ts +34 -4
  12. package/lib/providers/antigravity.js +100 -28
  13. package/lib/providers/ark-provider.d.ts +10 -0
  14. package/lib/providers/ark-provider.js +6 -0
  15. package/lib/providers/ark.d.ts +96 -10
  16. package/lib/providers/ark.js +176 -48
  17. package/lib/providers/catalog.d.ts +91 -0
  18. package/lib/providers/catalog.js +190 -0
  19. package/lib/providers/common.d.ts +14 -0
  20. package/lib/providers/common.js +23 -0
  21. package/lib/providers/glm-provider.d.ts +10 -0
  22. package/lib/providers/glm-provider.js +6 -0
  23. package/lib/providers/glm.d.ts +92 -16
  24. package/lib/providers/glm.js +172 -85
  25. package/lib/providers/grok.d.ts +106 -27
  26. package/lib/providers/grok.js +312 -128
  27. package/lib/providers/kimi-provider.d.ts +10 -0
  28. package/lib/providers/kimi-provider.js +8 -3
  29. package/lib/providers/kimi.d.ts +104 -32
  30. package/lib/providers/kimi.js +198 -129
  31. package/lib/providers/mimo-provider.d.ts +14 -1
  32. package/lib/providers/mimo-provider.js +17 -6
  33. package/lib/providers/mimo.d.ts +164 -19
  34. package/lib/providers/mimo.js +318 -19
  35. package/lib/providers/model-cache.d.ts +57 -0
  36. package/lib/providers/model-cache.js +105 -0
  37. package/lib/providers/responses-stream.d.ts +8 -0
  38. package/lib/providers/responses-stream.js +21 -5
  39. package/lib/providers/workbuddy-provider.d.ts +17 -0
  40. package/lib/providers/workbuddy-provider.js +14 -6
  41. package/lib/providers/workbuddy.d.ts +140 -13
  42. package/lib/providers/workbuddy.js +520 -55
  43. package/package.json +1 -1
package/README.dev.md CHANGED
@@ -70,7 +70,7 @@ quota, which is read per subscription period and per model's free allowance.
70
70
  | --- | --- |
71
71
  | `ctx.llm` | the `kimi`, `grok`, `antigravity`, `glm` and `auto` provider routes (models, reasoning efforts, streaming) |
72
72
  | Settings | a **Subscriptions** section: one card per provider — sign in, sign out, default account, token refresh, plan quota, model catalog, manage dialog |
73
- | Model picker | each provider's own models, plus **`auto` as its own route** spanning them — Kimi ships `kimi-for-coding`, `k3`, `k3[1m]`, `k3-256k`; Grok seeds `grok-4.6`, `grok-4.5` and adds whatever its live catalog reports; Antigravity lists the agent-callable subset of what its endpoint reports (`fetchAvailableModels`), filtering out tabs, commit-message and transcription surfaces; GLM ships the `glm-5.3` family (`glm-5.3`, `glm-5.3-flash`, `glm-5.2`, `glm-5.1`, `glm-5`) and adds whatever its coding host lists |
73
+ | Model picker | each provider's own models, plus **`auto` as its own route** spanning them. Membership comes from the provider's own model list, read once and cached as that route's table (`~/.dsh/plugins/kimi-oauth/model-catalog.json`), so the picker never spends a request and a release or retirement server-side needs no plugin update. Kimi serves `kimi-for-coding`, `k3` (1M) and `k3-256k`; Grok adds whatever its live catalog reports on top of `grok-4.6`/`grok-4.5`; Antigravity lists the agent-callable subset of what its endpoint reports (`fetchAvailableModels`), filtering out tabs, commit-message and transcription surfaces; GLM adds whatever its coding host lists on top of the `glm-5.3` family |
74
74
 
75
75
  Credentials live at `~/.dsh/plugins/kimi-oauth/auth.json` (mode `0600`,
76
76
  written atomically, one section per provider). The directory keeps the name this
package/README.md CHANGED
@@ -13,12 +13,12 @@ Sign in once per provider from **Settings → Subscriptions** and that provider'
13
13
 
14
14
  | Provider | What you get | Sign-in |
15
15
  | --- | --- | --- |
16
- | **Kimi Code** | `kimi-for-coding`, `k3`, `k3[1m]`, `k3-256k` + live catalog | OAuth device flow (show code, confirm in browser) |
17
- | **Grok (X Premium)** | `grok-4.7`, `grok-4.6`, … + live catalog, **⚡ lightspeed** fast variant | Browser OAuth (auto-redirect) |
18
- | **Google Antigravity** | Claude Sonnet/Opus, Gemini Flash, GPT-OSS, with reasoning tiers | Google account OAuth |
19
- | **GLM (BigModel)** | `glm-5.3`, `glm-5.3-flash`, `glm-5.2`, `glm-5.1`, `glm-5` | ZCode browser sign-in (polled) |
20
- | **Volcengine Ark** | Ark coding models + live catalog | Volcengine SSO |
21
- | **Xiaomi MiMo** | MiMo Pro, MiMo Flash | Xiaomi account (QR / password) |
16
+ | **Kimi Code** | `kimi-for-coding`, `k3` (1M), `k3-256k` — read from the endpoint's own model list | OAuth device flow (show code, confirm in browser) |
17
+ | **Grok (X Premium)** | whatever the account's own model list reports (e.g. `grok-4.7`), **⚡ lightspeed** fast variant | Browser OAuth (auto-redirect) |
18
+ | **Google Antigravity** | Claude Sonnet/Opus, Gemini Flash, GPT-OSS, with reasoning tiers — read from the account's own list | Google account OAuth |
19
+ | **GLM (BigModel)** | whatever the coding host lists (e.g. `glm-5.3`, `glm-5.3-flash`) | ZCode browser sign-in (polled) |
20
+ | **Volcengine Ark** | the plan's own coding models | Volcengine SSO |
21
+ | **Xiaomi MiMo** | MiMo's own model list, with the app's two-model set as the fallback | Xiaomi account (QR / password) |
22
22
  | **WorkBuddy (国内版)** | Hy, GLM, Kimi, DeepSeek, MiniMax models | Browser OAuth (Tencent) |
23
23
 
24
24
  Every provider also feeds the **`auto`** route, which spans them all: pick `auto` and the harness walks your enabled models in order until one answers.
@@ -28,6 +28,7 @@ Every provider also feeds the **`auto`** route, which spans them all: pick `auto
28
28
  - **One sign-in per provider** — no API keys to find, paste, or rotate. The plugin runs the provider's own OAuth/device flow and keeps the token on disk (`~/.dsh/plugins/kimi-oauth/auth.json`, mode `0600`).
29
29
  - **Live plan usage** — the Settings card and the composer chip show each account's remaining quota (Kimi's 5-hour / weekly windows + credit, Grok's weekly credit, Antigravity's Gemini + Claude buckets, GLM/Ark/MiMo/WorkBuddy credits), with a meter and reset time.
30
30
  - **Model picker integration** — each provider's models appear in the session picker with context windows and reasoning tiers; hide or re-order them per provider.
31
+ - **Catalogs come from the provider, not from this build** — every route reads its own model list once and caches it as the provider's table, so a model released, renamed or retired server-side shows up (or disappears) without a plugin update. Signing in and the Settings **refresh models** action are what re-read it; browsing the picker never spends a request.
31
32
  - **⚡ Fast / lightspeed variants** — for models that have one (e.g. Grok 4.7 → `grok-4.7-build-fast`), a bolt button beside the model selector switches to the fast variant; it reads as a reasoning rung so the base model always stays selectable.
32
33
  - **Cross-account pool** — sign in to several accounts on one provider; the plugin draws on the next account when one's allowance runs out.
33
34
  - **Auto fallback** — `auto` moves to the next enabled model when a provider refuses the preferred one (renamed, rate-limited, out of quota), and stops falling back once a stream has started.
package/README.zh.dev.md CHANGED
@@ -56,7 +56,7 @@ Antigravity 的流程是 Google 的桌面 OAuth 客户端(`accounts.google.com
56
56
  | --- | --- |
57
57
  | `ctx.llm` | `kimi`、`grok`、`antigravity`、`glm` 和 `auto` 提供方路由(模型、推理强度、流式输出) |
58
58
  | Settings | 一个 **Subscriptions** 区域:每个提供方一张卡片——登录、退出登录、默认账户、令牌刷新、套餐配额、模型目录、管理对话框 |
59
- | 模型选择器 | 每个提供方自己的模型,外加**作为独立路由的 `auto`**,横跨它们——Kimi 提供 `kimi-for-coding`、`k3`、`k3[1m]`、`k3-256k`;Grok 内置 `grok-4.6`、`grok-4.5`,并加入其实时目录所报告的任何模型;Antigravity 列出其端点所报告内容(`fetchAvailableModels`)中可供 agent 调用的子集,过滤掉 tabs、commit-message 和 transcription 相关层面;GLM 提供 `glm-5.3` 系列(`glm-5.3`、`glm-5.3-flash`、`glm-5.2`、`glm-5.1`、`glm-5`),并加入其编码主机所列出的一切 |
59
+ | 模型选择器 | 每个提供方自己的模型,外加**作为独立路由的 `auto`**,横跨它们。成员资格来自提供方自己的模型列表:每个路由只读取一次并缓存为该路由的目录(`~/.dsh/plugins/kimi-oauth/model-catalog.json`),因此选择器不会发出请求,服务端新增或下线模型也无需插件更新。Kimi 提供 `kimi-for-coding`、`k3`(1M)与 `k3-256k`;Grok 在 `grok-4.6`、`grok-4.5` 之上加入其实时目录所报告的任何模型;Antigravity 列出其端点所报告内容(`fetchAvailableModels`)中可供 agent 调用的子集,过滤掉 tabs、commit-message 和 transcription 相关层面;GLM 在 `glm-5.3` 系列之上加入其编码主机所列出的一切 |
60
60
 
61
61
  凭证存放在 `~/.dsh/plugins/kimi-oauth/auth.json`(模式 `0600`,原子写入,每个提供方
62
62
  一个区段)。该目录保留了本插件在只服务 Kimi Code 时所用的名称:它保存着**活跃的
package/README.zh.md CHANGED
@@ -13,12 +13,12 @@
13
13
 
14
14
  | 服务 | 可用模型 | 登录方式 |
15
15
  | --- | --- | --- |
16
- | **Kimi Code** | `kimi-for-coding`、`k3`、`k3[1m]`、`k3-256k` + 实时目录 | OAuth 设备流(显示代码,浏览器确认) |
17
- | **Grok (X Premium)** | `grok-4.7`、`grok-4.6`… + 实时目录,**⚡ lightspeed** 快速变体 | 浏览器 OAuth(自动回调) |
18
- | **Google Antigravity** | Claude Sonnet/Opus、Gemini Flash、GPT-OSS,带推理档 | Google 账号 OAuth |
19
- | **GLM (BigModel)** | `glm-5.3`、`glm-5.3-flash`、`glm-5.2`、`glm-5.1`、`glm-5` | ZCode 浏览器登录(轮询) |
20
- | **Volcengine Ark** | Ark 编程模型 + 实时目录 | 火山引擎 SSO |
21
- | **Xiaomi MiMo** | MiMo Pro、MiMo Flash | 小米账号(扫码 / 密码) |
16
+ | **Kimi Code** | `kimi-for-coding`、`k3`(1M)、`k3-256k` —— 直接来自端点自己的模型列表 | OAuth 设备流(显示代码,浏览器确认) |
17
+ | **Grok (X Premium)** | 账号自己的模型列表所报告的一切(如 `grok-4.7`),**⚡ lightspeed** 快速变体 | 浏览器 OAuth(自动回调) |
18
+ | **Google Antigravity** | Claude Sonnet/Opus、Gemini Flash、GPT-OSS,带推理档 —— 来自账号自己的列表 | Google 账号 OAuth |
19
+ | **GLM (BigModel)** | 编码主机列出的一切(如 `glm-5.3`、`glm-5.3-flash`) | ZCode 浏览器登录(轮询) |
20
+ | **Volcengine Ark** | 套餐自己的编程模型 | 火山引擎 SSO |
21
+ | **Xiaomi MiMo** | MiMo 自己的模型列表,读取失败时回退到应用内置的两个模型 | 小米账号(扫码 / 密码) |
22
22
  | **WorkBuddy (国内版)** | Hy、GLM、Kimi、DeepSeek、MiniMax 模型 | 浏览器 OAuth(腾讯) |
23
23
 
24
24
  每个服务也会汇入 **`auto`** 路由,它横跨全部:选 `auto`,harness 会按顺序尝试你已启用的模型,直到有响应。
@@ -28,6 +28,7 @@
28
28
  - **每个服务登录一次** —— 无需找、贴、轮换 API Key。插件运行服务自己的 OAuth/设备流,令牌保存在磁盘(`~/.dsh/plugins/kimi-oauth/auth.json`,权限 `0600`)。
29
29
  - **实时套餐额度** —— 设置卡片和输入框 chip 显示每个账号的剩余额度(Kimi 的 5 小时 / 每周窗口 + 额度,Grok 每周额度,Antigravity 的 Gemini + Claude 分组,GLM/Ark/MiMo/WorkBuddy 的额度),带进度条和重置时间。
30
30
  - **模型选择器集成** —— 每个服务的模型带上下文窗口和推理档出现在选择器里;可按服务隐藏或排序。
31
+ - **模型目录来自服务本身,而不是本插件** —— 每个路由只读取一次服务自己的模型列表,并把它缓存为该路由的目录,因此服务端新增、改名或下线的模型无需插件更新即可出现(或消失)。重新读取的时机是登录成功和设置页的**刷新模型**;浏览选择器不会发出任何请求。
31
32
  - **⚡ 快速 / lightspeed 变体** —— 对有快速变体的模型(如 Grok 4.7 → `grok-4.7-build-fast`),模型选择器旁的闪电按钮一键切换;它作为推理档实现,基础模型始终可选。
32
33
  - **多账号池** —— 一个服务可登录多个账号;某账号额度用尽时自动切到下一个。
33
34
  - **Auto 回退** —— `auto` 在首选模型被拒(改名、限流、额度尽)时改用下一个已启用模型,且流开始后不再回退。
@@ -85,7 +85,7 @@ export declare function finishWorkBuddySignIn(start: WorkBuddySignInStart, fetch
85
85
  }>;
86
86
  /** The domain a token names, else the API host. */
87
87
  export declare function workbuddyDomain(token: Pick<WorkBuddyTokenSet, 'domain'>): string;
88
- /** The headers WorkBuddy's chat gateway accepts: its own CLI's, nothing more. */
88
+ /** The headers WorkBuddy's desktop client sends with a chat, as magpie's workbuddy sets. */
89
89
  export declare function workbuddyHeaders(token: WorkBuddyTokenSet): Record<string, string>;
90
90
  /** Whether a token is close enough to its end that a request should refresh it. */
91
91
  export declare function workbuddyStale(token: Pick<WorkBuddyTokenSet, 'expiresAt'>): boolean;
@@ -214,21 +214,26 @@ async function workbuddyEnterprise(token, who, fetchFn) {
214
214
  const pick = same.length === 1 ? same[0] : last.length === 1 ? last[0] : mine.length === 1 ? mine[0] : undefined;
215
215
  return pick && typeof pick.enterpriseId === 'string' ? pick.enterpriseId.trim() : '';
216
216
  }
217
- /** The headers WorkBuddy's chat gateway accepts: its own CLI's, nothing more. */
217
+ /** The headers WorkBuddy's desktop client sends with a chat, as magpie's workbuddy sets. */
218
218
  export function workbuddyHeaders(token) {
219
219
  const headers = {
220
- 'Accept': 'application/json, text/plain, */*',
221
- 'X-Requested-With': 'XMLHttpRequest',
222
- 'Origin': 'https://copilot.tencent.com',
223
- 'Referer': 'https://copilot.tencent.com/',
224
- 'User-Agent': 'CLI/2.63.2 CodeBuddy/2.63.2',
225
- 'Content-Type': 'application/json',
226
220
  'Authorization': `Bearer ${token.accessToken}`,
227
- ...token.uid === undefined || token.uid === '' ? { 'X-No-User-Id': '1' } : { 'X-User-Id': token.uid },
228
- ...token.enterpriseId === undefined || token.enterpriseId === '' ? { 'X-No-Enterprise-Id': '1' } : { 'X-Enterprise-Id': token.enterpriseId },
221
+ 'X-User-Id': token.uid ?? '',
229
222
  'X-Domain': workbuddyDomain(token),
230
223
  'X-Product': 'SaaS',
224
+ 'X-IDE-Type': 'WorkBuddy',
225
+ 'User-Agent': `WorkBuddy/${WORKBUDDY_UA_VERSION}`,
226
+ 'X-Requested-With': 'XMLHttpRequest',
227
+ 'X-Agent-Intent': 'craft',
228
+ 'X-Agent-Purpose': 'conversation',
229
+ 'X-IDE-Name': 'WorkBuddy',
230
+ 'X-IDE-Version': WORKBUDDY_UA_VERSION,
231
231
  };
232
+ const enterprise = typeof token.enterpriseId === 'string' ? token.enterpriseId.trim() : '';
233
+ if (enterprise !== '') {
234
+ headers['X-Enterprise-Id'] = enterprise;
235
+ headers['X-Tenant-Id'] = enterprise;
236
+ }
232
237
  return headers;
233
238
  }
234
239
  /** Whether a token is close enough to its end that a request should refresh it. */
@@ -113,7 +113,16 @@ export function apply(ctx) {
113
113
  function modelDirectoryFor(modelDirectories, sessionId) {
114
114
  if (sessionId === undefined || modelDirectories?.directoryFor === undefined)
115
115
  return undefined;
116
- const directory = modelDirectories.directoryFor(sessionId);
116
+ // The host throws when the session has no directory yet (a fresh session, say); that is
117
+ // a missing control, not a fault, so the button renders nothing instead of breaking the
118
+ // whole composer.
119
+ let directory;
120
+ try {
121
+ directory = modelDirectories.directoryFor(sessionId);
122
+ }
123
+ catch {
124
+ return undefined;
125
+ }
117
126
  if (directory?.select === undefined)
118
127
  return undefined;
119
128
  return {
package/lib/client.js CHANGED
@@ -3272,7 +3272,12 @@ function apply(ctx) {
3272
3272
  */
3273
3273
  function modelDirectoryFor(modelDirectories, sessionId) {
3274
3274
  if (sessionId === void 0 || modelDirectories?.directoryFor === void 0) return void 0;
3275
- const directory = modelDirectories.directoryFor(sessionId);
3275
+ let directory;
3276
+ try {
3277
+ directory = modelDirectories.directoryFor(sessionId);
3278
+ } catch {
3279
+ return;
3280
+ }
3276
3281
  if (directory?.select === void 0) return void 0;
3277
3282
  return { select: (selection) => directory.select?.(selection) ?? Promise.resolve() };
3278
3283
  }