opencode-copilot-account-switcher 0.13.3 → 0.13.4

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.
@@ -66,5 +66,6 @@ export declare function fetchCodexStatus(input: {
66
66
  accountId?: string;
67
67
  fetchImpl?: typeof globalThis.fetch;
68
68
  now?: () => number;
69
+ timeoutMs?: number;
69
70
  refreshTokens?: (oauth: OpenAIOAuthAuth) => Promise<OpenAIOAuthAuth | undefined>;
70
71
  }): Promise<CodexStatusFetcherResult>;
@@ -1,4 +1,5 @@
1
1
  const CODEX_USAGE_URL = "https://chatgpt.com/backend-api/codex/usage";
2
+ const CODEX_USAGE_TIMEOUT_MS = 15_000;
2
3
  function isInvalidAccountRefreshError(error) {
3
4
  if (!error || typeof error !== "object")
4
5
  return false;
@@ -158,24 +159,30 @@ async function requestUsage(input) {
158
159
  access: input.oauth.access,
159
160
  accountId: input.accountId,
160
161
  }),
162
+ signal: input.signal,
161
163
  });
162
164
  }
163
165
  export async function fetchCodexStatus(input) {
164
166
  const fetchImpl = input.fetchImpl ?? globalThis.fetch;
165
167
  const now = input.now ?? Date.now;
166
168
  const explicitAccountId = input.accountId;
169
+ const timeoutMs = input.timeoutMs ?? CODEX_USAGE_TIMEOUT_MS;
167
170
  let oauth = input.oauth;
168
171
  let authPatch;
169
172
  for (let attempt = 0; attempt < 2; attempt += 1) {
170
173
  let response;
174
+ const controller = new AbortController();
175
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
171
176
  try {
172
177
  response = await requestUsage({
173
178
  oauth,
174
179
  accountId: explicitAccountId ?? oauth.accountId,
175
180
  fetchImpl,
181
+ signal: controller.signal,
176
182
  });
177
183
  }
178
184
  catch (error) {
185
+ clearTimeout(timeout);
179
186
  if (isTimeoutError(error)) {
180
187
  return {
181
188
  ok: false,
@@ -193,6 +200,9 @@ export async function fetchCodexStatus(input) {
193
200
  },
194
201
  };
195
202
  }
203
+ finally {
204
+ clearTimeout(timeout);
205
+ }
196
206
  if (response.status === 401 && attempt === 0 && input.refreshTokens) {
197
207
  let refreshed;
198
208
  try {
@@ -6,6 +6,7 @@ type WriteMeta = {
6
6
  export type MenuAccountInfo = {
7
7
  id?: string;
8
8
  name: string;
9
+ workspaceName?: string;
9
10
  index: number;
10
11
  isCurrent?: boolean;
11
12
  };
@@ -421,6 +421,8 @@ function pruneTouchWriteCache(input) {
421
421
  }
422
422
  }
423
423
  export function buildPluginHooks(input) {
424
+ const authProvider = input.auth.provider ?? COPILOT_PROVIDER_DESCRIPTOR.providerIDs[0] ?? "github-copilot";
425
+ const enableCopilotAuthLoader = isCopilotProviderID(authProvider);
424
426
  const compactionLoopSafetyBypass = createCompactionLoopSafetyBypass();
425
427
  const loadStore = input.loadStore ?? readStoreSafe;
426
428
  const loadStoreSync = input.loadStoreSync ?? readStoreSafeSync;
@@ -1121,9 +1123,9 @@ export function buildPluginHooks(input) {
1121
1123
  return {
1122
1124
  auth: {
1123
1125
  ...input.auth,
1124
- provider: input.auth.provider ?? COPILOT_PROVIDER_DESCRIPTOR.providerIDs[0] ?? "github-copilot",
1126
+ provider: authProvider,
1125
1127
  methods: input.auth.methods,
1126
- loader,
1128
+ loader: enableCopilotAuthLoader ? loader : undefined,
1127
1129
  },
1128
1130
  config: async (config) => {
1129
1131
  if (!config.command)
@@ -255,6 +255,7 @@ export function createCodexMenuAdapter(inputDeps) {
255
255
  fallback: `openai-${now()}`,
256
256
  }),
257
257
  providerId: "openai",
258
+ workspaceName: oauth.workspaceName,
258
259
  refresh,
259
260
  access,
260
261
  expires: oauth.expires,
@@ -269,6 +270,7 @@ export function createCodexMenuAdapter(inputDeps) {
269
270
  return Object.entries(store.accounts).map(([name, entry], index) => ({
270
271
  id: entry.accountId ?? name,
271
272
  name: entry.email ?? entry.accountId ?? name,
273
+ workspaceName: entry.workspaceName,
272
274
  index,
273
275
  isCurrent: store.active === name,
274
276
  source: entry.source,
package/dist/ui/menu.d.ts CHANGED
@@ -3,6 +3,7 @@ import { confirm } from "./confirm.js";
3
3
  export type AccountStatus = "active" | "expired" | "unknown";
4
4
  export interface AccountInfo {
5
5
  name: string;
6
+ workspaceName?: string;
6
7
  index: number;
7
8
  addedAt?: number;
8
9
  lastUsed?: number;
package/dist/ui/menu.js CHANGED
@@ -318,6 +318,7 @@ export function buildMenuItems(input) {
318
318
  const numbered = `${account.index + 1}. ${account.name}`;
319
319
  const label = `${numbered}${currentBadge}${statusBadge ? " " + statusBadge : ""}${quotaBadge}`;
320
320
  const detail = [
321
+ account.workspaceName,
321
322
  account.lastUsed ? formatRelativeTime(account.lastUsed) : undefined,
322
323
  account.plan,
323
324
  account.models ? `${account.models.enabled}/${account.models.enabled + account.models.disabled} mods` : undefined,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-copilot-account-switcher",
3
- "version": "0.13.3",
3
+ "version": "0.13.4",
4
4
  "description": "GitHub Copilot account switcher plugin for OpenCode",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",