@eddyskywalker/dsh-chatgpt-subscription 0.2.18 → 0.2.19

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/lib/index.js CHANGED
@@ -3114,7 +3114,7 @@ function identityKey(credentials) {
3114
3114
  //#endregion
3115
3115
  //#region src/host/routes.ts
3116
3116
  const MAX_BODY_BYTES = 64 * 1024;
3117
- function registerRoutes(ctx, oauth, usage, preferences, proxyManager) {
3117
+ function registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher) {
3118
3118
  const handler = async (request, response) => {
3119
3119
  const url = new URL(request.url ?? "/", "http://dsh.local");
3120
3120
  if (request.method === "GET" && url.pathname === `/api/dsh-chatgpt-subscription/status`) {
@@ -3126,7 +3126,8 @@ function registerRoutes(ctx, oauth, usage, preferences, proxyManager) {
3126
3126
  quota: await usage.status(oauthStatus.authenticated),
3127
3127
  preferences: preferences.status(),
3128
3128
  detectedProxy: proxyManager?.getSystemProxy() ?? null,
3129
- activeProxy: proxyManager?.resolveActiveProxyUrl() ?? null
3129
+ activeProxy: proxyManager?.resolveActiveProxyUrl() ?? null,
3130
+ switcher: searchSwitcher?.status() ?? null
3130
3131
  }
3131
3132
  });
3132
3133
  return;
@@ -3783,12 +3784,25 @@ var SearchProviderSwitcher = class {
3783
3784
  originalSearchProvider;
3784
3785
  originalFetchProvider;
3785
3786
  initialized = false;
3787
+ state = "idle";
3786
3788
  constructor(loader) {
3787
3789
  this.loader = loader;
3788
3790
  }
3791
+ status() {
3792
+ const entry = this.findWebEntry();
3793
+ const config = entry ? currentConfig(entry) : {};
3794
+ return {
3795
+ state: this.state,
3796
+ configuredSearchProvider: providerId(config.searchProvider),
3797
+ configuredFetchProvider: providerId(config.fetchProvider)
3798
+ };
3799
+ }
3789
3800
  async select(preference, options = {}) {
3790
3801
  const entry = this.findWebEntry();
3791
- if (entry === null) return;
3802
+ if (entry === null) {
3803
+ this.state = "missing";
3804
+ return;
3805
+ }
3792
3806
  const config = currentConfig(entry);
3793
3807
  if (!this.initialized) {
3794
3808
  this.originalSearchProvider = typeof config.searchProvider === "string" && config.searchProvider !== "codex-subscription" ? config.searchProvider : void 0;
@@ -3804,13 +3818,17 @@ var SearchProviderSwitcher = class {
3804
3818
  else nextConfig.searchProvider = nextSearch;
3805
3819
  if (nextFetch === void 0) delete nextConfig.fetchProvider;
3806
3820
  else nextConfig.fetchProvider = nextFetch;
3807
- await entry.update({ config: nextConfig });
3821
+ this.state = "applying";
3822
+ try {
3823
+ await entry.update({ config: nextConfig });
3824
+ this.state = "applied";
3825
+ } catch (error) {
3826
+ this.state = "failed";
3827
+ throw error;
3828
+ }
3808
3829
  }
3809
3830
  findWebEntry() {
3810
- for (const entry of this.loader.entries()) {
3811
- if (entry.options.id === "web") return entry;
3812
- if (entry.options.name === "@deepseek-ai/dsh-web") return entry;
3813
- }
3831
+ for (const entry of this.loader.entries()) if (entry.options.id === "web" || entry.options.name === "@deepseek-ai/dsh-web") return entry;
3814
3832
  return null;
3815
3833
  }
3816
3834
  };
@@ -3818,6 +3836,10 @@ function currentConfig(entry) {
3818
3836
  const config = entry.options.config;
3819
3837
  return typeof config === "object" && config !== null && !Array.isArray(config) ? config : {};
3820
3838
  }
3839
+ /** Never include paths, credentials, or arbitrary configuration in public diagnostics. */
3840
+ function providerId(value) {
3841
+ return typeof value === "string" && /^[a-zA-Z0-9_-]{1,80}$/.test(value) ? value : null;
3842
+ }
3821
3843
  //#endregion
3822
3844
  //#region src/host/antigravity/types.ts
3823
3845
  const PROVIDER_NAME = "Antigravity";
@@ -6212,7 +6234,7 @@ function apply(ctx, pluginConfig = {}) {
6212
6234
  ctx.logger.warn(`[dsh-chatgpt-subscription] Web provider selection could not be applied: ${error instanceof Error ? error.message : String(error)}`);
6213
6235
  });
6214
6236
  };
6215
- const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences, proxyManager);
6237
+ const disposeRoutes = registerRoutes(ctx, oauth, usage, preferences, proxyManager, searchSwitcher);
6216
6238
  const disposeAdapter = ctx.llm.registerAdapter([PROVIDER_ID$1], adapter);
6217
6239
  const disposeImageTool = ctx.tools.register(createCodexImageTool(oauth, ctx.attachments, { fetchFn: proxyFetch }));
6218
6240
  ctx.inject(["web"], (ctx) => {
@@ -6241,4 +6263,4 @@ function localWebServerBaseUrl(host, port) {
6241
6263
  return `http://${host === "0.0.0.0" ? "127.0.0.1" : host}:${port}`;
6242
6264
  }
6243
6265
  //#endregion
6244
- export { AntigravityAdapter, CodexChatGptAdapter, Config, FileCredentialStore, FileModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, UsageService, WindowsDpapiTokenStore, apply, authorizedRoutesFor, beginWebLogin, clearCachedQuota, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createPlatformTokenStore, createSubagentAuthorization, credentialPath, delegationDenialReason, detectSystemProxy, fetchAccountQuota, getCachedQuota, inject, installSubagentModelAuthorization, loginAndSave, mapCodexUsage, modelSettingsPath, normalizeDelegationToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, refreshAntigravityToken, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames };
6266
+ export { AntigravityAdapter, CodexChatGptAdapter, Config, FileCredentialStore, FileModelSettingsStore, LinuxFileTokenStore, MacKeychainTokenStore, OAuthService, ProxyManager, ResponsesClient, SUBAGENT_MODEL_SELECTION_NAMESPACE, SUBAGENT_POLICY_EVENT, SearchProviderSwitcher, UsageService, WindowsDpapiTokenStore, apply, authorizedRoutesFor, beginWebLogin, clearCachedQuota, createCodexFetchProvider, createCodexImageTool, createCodexSearchProvider, createPlatformTokenStore, createSubagentAuthorization, credentialPath, delegationDenialReason, detectSystemProxy, fetchAccountQuota, getCachedQuota, inject, installSubagentModelAuthorization, loginAndSave, mapCodexUsage, modelSettingsPath, normalizeDelegationToolNames, parseAllowedRoutes, parseCodexUsage, parseResponsesStream, policyRoutesOf, refreshAntigravityToken, subagentModelSelectionPreference, unauthorizedRouteReason, validateAuthorizationScope, validateDelegationToolNames };
@@ -2,6 +2,7 @@ import type { Context } from '@deepseek-ai/cordis';
2
2
  import { OAuthService } from './oauth-service.ts';
3
3
  import { type SubscriptionPreferenceStore } from './preferences.ts';
4
4
  import type { ProxyManager } from './proxy-manager.ts';
5
+ import type { SearchProviderSwitcher } from './search-provider-switcher.ts';
5
6
  import { UsageService } from './usage-service.ts';
6
- export declare function registerRoutes(ctx: Context, oauth: OAuthService, usage: UsageService, preferences: SubscriptionPreferenceStore, proxyManager?: ProxyManager): () => void;
7
+ export declare function registerRoutes(ctx: Context, oauth: OAuthService, usage: UsageService, preferences: SubscriptionPreferenceStore, proxyManager?: ProxyManager, searchSwitcher?: SearchProviderSwitcher): () => void;
7
8
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/host/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAmB,KAAK,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAqB,MAAM,oBAAoB,CAAA;AAIpE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,2BAA2B,EACxC,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,IAAI,CAsKZ"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/host/routes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAMlD,OAAO,EAAE,YAAY,EAAe,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAmB,KAAK,2BAA2B,EAAE,MAAM,kBAAkB,CAAA;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAqB,MAAM,oBAAoB,CAAA;AAIpE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,2BAA2B,EACxC,YAAY,CAAC,EAAE,YAAY,EAC3B,cAAc,CAAC,EAAE,sBAAsB,GACtC,MAAM,IAAI,CAuKZ"}
@@ -3,26 +3,23 @@ import type { SearchProviderPreference } from '../shared/contracts.ts';
3
3
  interface LoaderLike {
4
4
  entries(): Iterable<Entry>;
5
5
  }
6
- /** What one selection asks for on top of the settings preference. */
7
6
  export interface WebProviderSelectionOptions {
8
- /**
9
- * Whether this plugin's fetch provider must serve the `web_fetch` tool.
10
- *
11
- * DSH's built-in provider resolves and pins every destination before it
12
- * connects and routes through a proxy only when the process environment names
13
- * one, so an OS-level proxy plus the fake-ip DNS that usually comes with it
14
- * fails every fetch with `WEB_BLOCKED_URL`. Selecting this plugin's provider
15
- * hands the origin's resolution to the configured proxy — the same
16
- * proxied-hop semantics DSH applies to a URL it routes through a proxy.
17
- */
18
7
  readonly pluginFetch?: boolean;
19
8
  }
9
+ /** Configuration diagnostics, not proof that an in-flight tool uses this service. */
10
+ export interface SearchProviderSwitcherStatus {
11
+ readonly state: 'idle' | 'applying' | 'applied' | 'missing' | 'failed';
12
+ readonly configuredSearchProvider: string | null;
13
+ readonly configuredFetchProvider: string | null;
14
+ }
20
15
  export declare class SearchProviderSwitcher {
21
16
  private readonly loader;
22
17
  private originalSearchProvider;
23
18
  private originalFetchProvider;
24
19
  private initialized;
20
+ private state;
25
21
  constructor(loader: LoaderLike);
22
+ status(): SearchProviderSwitcherStatus;
26
23
  select(preference: SearchProviderPreference, options?: WebProviderSelectionOptions): Promise<void>;
27
24
  private findWebEntry;
28
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search-provider-switcher.d.ts","sourceRoot":"","sources":["../../../src/host/search-provider-switcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAA;AAG9D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAEtE,UAAU,UAAU;IAClB,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;CAC3B;AAED,qEAAqE;AACrE,MAAM,WAAW,2BAA2B;IAC1C;;;;;;;;;OASG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,qBAAa,sBAAsB;IAKrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,sBAAsB,CAAoB;IAClD,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,WAAW,CAAQ;gBAEE,MAAM,EAAE,UAAU;IAEzC,MAAM,CAAC,UAAU,EAAE,wBAAwB,EAAE,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAkC5G,OAAO,CAAC,YAAY;CAOrB"}
1
+ {"version":3,"file":"search-provider-switcher.d.ts","sourceRoot":"","sources":["../../../src/host/search-provider-switcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mCAAmC,CAAA;AAG9D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAA;AAEtE,UAAU,UAAU;IAClB,OAAO,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAA;CAC3B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAC/B;AAED,qFAAqF;AACrF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;IACtE,QAAQ,CAAC,wBAAwB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChD,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;CAChD;AAED,qBAAa,sBAAsB;IAMrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,sBAAsB,CAAoB;IAClD,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,KAAK,CAAgD;gBAEhC,MAAM,EAAE,UAAU;IAE/C,MAAM,IAAI,4BAA4B;IAUhC,MAAM,CAAC,UAAU,EAAE,wBAAwB,EAAE,OAAO,GAAE,2BAAgC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiC5G,OAAO,CAAC,YAAY;CAMrB"}
@@ -27,6 +27,7 @@ export { CodexChatGptAdapter } from './host/adapter.ts';
27
27
  export { createCodexImageTool } from './host/codex-images.ts';
28
28
  export { createCodexSearchProvider } from './host/codex-search.ts';
29
29
  export { createCodexFetchProvider } from './host/codex-fetch.ts';
30
+ export { SearchProviderSwitcher, type SearchProviderSwitcherStatus } from './host/search-provider-switcher.ts';
30
31
  export { ResponsesClient, parseResponsesStream } from './host/responses-client.ts';
31
32
  export { UsageService, mapCodexUsage, parseCodexUsage } from './host/usage-service.ts';
32
33
  export { createPlatformTokenStore } from './host/platform-token-store.ts';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAsCxC,yDAAyD;AACzD,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CAC9C;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAI3B,CAAA;AAEF,eAAO,MAAM,MAAM,UAAqE,CAAA;AAExF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,GAAE,MAAW,GAAG,IAAI,CA8GnE;AAED,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACzE,OAAO,EACL,kCAAkC,EAClC,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAC3B,sBAAsB,EACtB,iCAAiC,EACjC,4BAA4B,EAC5B,kBAAkB,EAClB,cAAc,EACd,gCAAgC,EAChC,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAClG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,CAAC,MAAM,0BAA0B,CAAA;AAsCxC,yDAAyD;AACzD,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,OAAO,CAAA;IACpC,qFAAqF;IACrF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,SAAS,GAAG,YAAY,CAAA;CAC9C;AAED,eAAO,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAI3B,CAAA;AAEF,eAAO,MAAM,MAAM,UAAqE,CAAA;AAExF,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,GAAE,MAAW,GAAG,IAAI,CA8GnE;AAED,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AACzE,OAAO,EACL,kCAAkC,EAClC,qBAAqB,EACrB,mBAAmB,EACnB,2BAA2B,EAC3B,sBAAsB,EACtB,iCAAiC,EACjC,4BAA4B,EAC5B,kBAAkB,EAClB,cAAc,EACd,gCAAgC,EAChC,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,GAC5B,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,sBAAsB,EAAE,KAAK,4BAA4B,EAAE,MAAM,oCAAoC,CAAA;AAC9G,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAA;AACtE,YAAY,EAAE,UAAU,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAA;AAClE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,GAClB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AAClG,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eddyskywalker/dsh-chatgpt-subscription",
3
- "version": "0.2.18",
3
+ "version": "0.2.19",
4
4
  "description": "DSH provider plugin for Codex access through a ChatGPT subscription.",
5
5
  "author": {
6
6
  "name": "eddyskywalker",