dsh-plugin-subscriptions 0.1.1 → 0.1.2

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 V1ki
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.zh.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) | 中文
4
4
 
5
- 把你的 **ChatGPT(Codex)**、**Claude**、**Grok(X Premium)**订阅当作 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的 LLM provider 使用 —— 不需要 API key。登录在 dsh web 界面完成(设置 → 订阅);token 保存在 `~/.dsh/plugins/subscriptions/auth.json`(权限 0600),过期自动刷新。
5
+ 把你的 **ChatGPT(Codex)**、**Claude**、**Grok(X Premium)** 订阅当作 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的 LLM provider 使用 —— 不需要 API key。登录在 dsh web 界面完成(设置 → 订阅);token 保存在 `~/.dsh/plugins/subscriptions/auth.json`(权限 0600),过期自动刷新。
6
6
 
7
7
  ## 演示
8
8
 
package/lib/index.js CHANGED
@@ -1400,11 +1400,10 @@ var CodexAdapter = class extends LlmAdapter {
1400
1400
  }));
1401
1401
  }
1402
1402
  async listModels(provider) {
1403
- const session = await this.options.tokens.peek();
1404
- if (session === void 0) return [];
1403
+ if (await this.options.tokens.peek() === void 0) return [];
1405
1404
  if (!this.options.discovery) return this.staticModels(provider);
1406
1405
  try {
1407
- return (await this.catalog.get(() => fetchCodexModels(session, this.options.fetchFn))).map((model) => ({
1406
+ return (await this.catalog.get(async () => fetchCodexModels(await this.options.tokens.session(), this.options.fetchFn))).map((model) => ({
1408
1407
  provider,
1409
1408
  id: model.id,
1410
1409
  name: model.name,
@@ -1412,6 +1411,7 @@ var CodexAdapter = class extends LlmAdapter {
1412
1411
  inputModalities: CODEX_MODALITIES
1413
1412
  }));
1414
1413
  } catch (error) {
1414
+ if (error instanceof LlmError && (error.code === "MISSING_CREDENTIAL" || error.code === "INVALID_CREDENTIAL")) return [];
1415
1415
  if (error instanceof OAuthEndpointError && error.status === 401) this.catalog.invalidate();
1416
1416
  this.options.onWarn?.(`codex model discovery failed; using the built-in catalog (${errorChain(error)})`);
1417
1417
  return this.staticModels(provider);
@@ -2281,17 +2281,17 @@ var GrokAdapter = class extends LlmAdapter {
2281
2281
  }));
2282
2282
  }
2283
2283
  async listModels(provider) {
2284
- const session = await this.options.tokens.peek();
2285
- if (session === void 0) return [];
2284
+ if (await this.options.tokens.peek() === void 0) return [];
2286
2285
  if (!this.options.discovery) return this.staticModels(provider);
2287
2286
  try {
2288
- return (await this.catalog.get(() => fetchGrokModels(session, this.options.fetchFn))).map((model) => ({
2287
+ return (await this.catalog.get(async () => fetchGrokModels(await this.options.tokens.session(), this.options.fetchFn))).map((model) => ({
2289
2288
  provider,
2290
2289
  id: model.id,
2291
2290
  name: model.name,
2292
2291
  inputModalities: grokModalities(model.id)
2293
2292
  }));
2294
2293
  } catch (error) {
2294
+ if (error instanceof LlmError && (error.code === "MISSING_CREDENTIAL" || error.code === "INVALID_CREDENTIAL")) return [];
2295
2295
  if (error instanceof OAuthEndpointError && error.status === 401) this.catalog.invalidate();
2296
2296
  this.options.onWarn?.(`grok model discovery failed; using the built-in catalog (${errorChain(error)})`);
2297
2297
  return this.staticModels(provider);
@@ -295,7 +295,10 @@ export class CodexAdapter extends LlmAdapter {
295
295
  if (!this.options.discovery)
296
296
  return this.staticModels(provider);
297
297
  try {
298
- const discovered = await this.catalog.get(() => fetchCodexModels(session, this.options.fetchFn));
298
+ // The fetcher runs only on a cache miss, and resolves the session
299
+ // through the refresh-aware path so an expired access token renews here
300
+ // instead of failing discovery into the static fallback.
301
+ const discovered = await this.catalog.get(async () => fetchCodexModels(await this.options.tokens.session(), this.options.fetchFn));
299
302
  return discovered.map(model => ({
300
303
  provider,
301
304
  id: model.id,
@@ -305,6 +308,11 @@ export class CodexAdapter extends LlmAdapter {
305
308
  }));
306
309
  }
307
310
  catch (error) {
311
+ // A permanent refresh failure deletes the stored session: the provider
312
+ // is logged out, so hide it instead of showing a stale static catalog.
313
+ if (error instanceof LlmError
314
+ && (error.code === 'MISSING_CREDENTIAL' || error.code === 'INVALID_CREDENTIAL'))
315
+ return [];
308
316
  if (error instanceof OAuthEndpointError && error.status === 401)
309
317
  this.catalog.invalidate();
310
318
  this.options.onWarn?.(`codex model discovery failed; using the built-in catalog (${errorChain(error)})`);
@@ -252,7 +252,10 @@ export class GrokAdapter extends LlmAdapter {
252
252
  if (!this.options.discovery)
253
253
  return this.staticModels(provider);
254
254
  try {
255
- const discovered = await this.catalog.get(() => fetchGrokModels(session, this.options.fetchFn));
255
+ // The fetcher runs only on a cache miss, and resolves the session
256
+ // through the refresh-aware path so an expired access token renews here
257
+ // instead of failing discovery into the static fallback.
258
+ const discovered = await this.catalog.get(async () => fetchGrokModels(await this.options.tokens.session(), this.options.fetchFn));
256
259
  return discovered.map(model => ({
257
260
  provider,
258
261
  id: model.id,
@@ -261,6 +264,11 @@ export class GrokAdapter extends LlmAdapter {
261
264
  }));
262
265
  }
263
266
  catch (error) {
267
+ // A permanent refresh failure deletes the stored session: the provider
268
+ // is logged out, so hide it instead of showing a stale static catalog.
269
+ if (error instanceof LlmError
270
+ && (error.code === 'MISSING_CREDENTIAL' || error.code === 'INVALID_CREDENTIAL'))
271
+ return [];
264
272
  if (error instanceof OAuthEndpointError && error.status === 401)
265
273
  this.catalog.invalidate();
266
274
  this.options.onWarn?.(`grok model discovery failed; using the built-in catalog (${errorChain(error)})`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-subscriptions",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Use ChatGPT (Codex), Claude, and Grok (X Premium) subscriptions as DeepSeek Harness LLM providers, with OAuth login from the web Settings page",
5
5
  "license": "MIT",
6
6
  "repository": {