opencode-copilot-account-switcher 0.13.4 → 0.13.5

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 (36) hide show
  1. package/dist/codex-network-retry.d.ts +2 -0
  2. package/dist/codex-network-retry.js +9 -0
  3. package/dist/codex-store.js +11 -8
  4. package/dist/common-settings-actions.d.ts +15 -0
  5. package/dist/common-settings-actions.js +42 -0
  6. package/dist/common-settings-store.d.ts +20 -0
  7. package/dist/common-settings-store.js +125 -0
  8. package/dist/plugin-actions.d.ts +9 -0
  9. package/dist/plugin-actions.js +15 -35
  10. package/dist/plugin-hooks.d.ts +5 -0
  11. package/dist/plugin-hooks.js +165 -43
  12. package/dist/plugin.js +54 -33
  13. package/dist/providers/codex-menu-adapter.d.ts +5 -2
  14. package/dist/providers/codex-menu-adapter.js +21 -0
  15. package/dist/providers/copilot-menu-adapter.d.ts +3 -0
  16. package/dist/providers/copilot-menu-adapter.js +5 -0
  17. package/dist/providers/descriptor.d.ts +3 -2
  18. package/dist/providers/descriptor.js +4 -1
  19. package/dist/providers/registry.d.ts +1 -1
  20. package/dist/providers/registry.js +38 -2
  21. package/dist/retry/codex-policy.d.ts +5 -0
  22. package/dist/retry/codex-policy.js +75 -0
  23. package/dist/retry/common-policy.d.ts +37 -0
  24. package/dist/retry/common-policy.js +68 -0
  25. package/dist/retry/copilot-policy.d.ts +1 -10
  26. package/dist/retry/copilot-policy.js +24 -58
  27. package/dist/store-paths.d.ts +6 -0
  28. package/dist/store-paths.js +24 -0
  29. package/dist/store.js +34 -8
  30. package/dist/ui/menu.d.ts +2 -0
  31. package/dist/ui/menu.js +56 -46
  32. package/dist/upstream/codex-loader-adapter.d.ts +69 -0
  33. package/dist/upstream/codex-loader-adapter.js +55 -0
  34. package/dist/upstream/codex-plugin.snapshot.d.ts +13 -0
  35. package/dist/upstream/codex-plugin.snapshot.js +98 -0
  36. package/package.json +3 -1
@@ -1,5 +1,9 @@
1
1
  import { CODEX_PROVIDER_DESCRIPTOR, COPILOT_PROVIDER_DESCRIPTOR } from "./descriptor.js";
2
2
  import { createCodexProviderDescriptor, createCopilotProviderDescriptor } from "./descriptor.js";
3
+ import { createCopilotRetryingFetch } from "../copilot-network-retry.js";
4
+ import { createCodexRetryingFetch } from "../codex-network-retry.js";
5
+ import { loadOfficialCopilotChatHeaders, loadOfficialCopilotConfig } from "../upstream/copilot-loader-adapter.js";
6
+ import { loadOfficialCodexChatHeaders, loadOfficialCodexConfig } from "../upstream/codex-loader-adapter.js";
3
7
  const PROVIDER_DESCRIPTORS = [
4
8
  COPILOT_PROVIDER_DESCRIPTOR,
5
9
  CODEX_PROVIDER_DESCRIPTOR,
@@ -16,13 +20,45 @@ export function getProviderDescriptorByProviderID(providerID) {
16
20
  export function isProviderIDSupportedByAnyDescriptor(providerID) {
17
21
  return getProviderDescriptorByProviderID(providerID) !== undefined;
18
22
  }
23
+ function hasCapability(descriptor, capability) {
24
+ return descriptor.capabilities.includes(capability);
25
+ }
19
26
  export function createProviderRegistry(input) {
27
+ const copilotCapabilities = COPILOT_PROVIDER_DESCRIPTOR;
28
+ const codexCapabilities = CODEX_PROVIDER_DESCRIPTOR;
29
+ const buildCopilotPluginHooks = (hookInput) => input.buildPluginHooks({
30
+ ...hookInput,
31
+ authLoaderMode: hasCapability(copilotCapabilities, "auth") ? "copilot" : "none",
32
+ enableModelRouting: hasCapability(copilotCapabilities, "model-routing"),
33
+ loadOfficialConfig: hasCapability(copilotCapabilities, "auth") ? loadOfficialCopilotConfig : undefined,
34
+ loadOfficialChatHeaders: hasCapability(copilotCapabilities, "chat-headers") ? loadOfficialCopilotChatHeaders : undefined,
35
+ createRetryFetch: hasCapability(copilotCapabilities, "network-retry") ? createCopilotRetryingFetch : undefined,
36
+ });
37
+ const buildCodexPluginHooks = (hookInput) => input.buildPluginHooks({
38
+ ...hookInput,
39
+ authLoaderMode: hasCapability(codexCapabilities, "auth") ? "codex" : "none",
40
+ enableModelRouting: hasCapability(codexCapabilities, "model-routing"),
41
+ loadOfficialConfig: hasCapability(codexCapabilities, "auth")
42
+ ? ({ getAuth, baseFetch, version }) => loadOfficialCodexConfig({
43
+ getAuth: getAuth,
44
+ baseFetch,
45
+ version,
46
+ client: hookInput.client,
47
+ })
48
+ : undefined,
49
+ loadOfficialChatHeaders: hasCapability(codexCapabilities, "chat-headers")
50
+ ? loadOfficialCodexChatHeaders
51
+ : undefined,
52
+ createRetryFetch: hasCapability(codexCapabilities, "network-retry")
53
+ ? createCodexRetryingFetch
54
+ : undefined,
55
+ });
20
56
  return {
21
57
  copilot: {
22
- descriptor: createCopilotProviderDescriptor({ buildPluginHooks: input.buildPluginHooks }),
58
+ descriptor: createCopilotProviderDescriptor({ buildPluginHooks: buildCopilotPluginHooks }),
23
59
  },
24
60
  codex: {
25
- descriptor: createCodexProviderDescriptor({ enabled: true }),
61
+ descriptor: createCodexProviderDescriptor({ buildPluginHooks: buildCodexPluginHooks, enabled: true }),
26
62
  },
27
63
  };
28
64
  }
@@ -0,0 +1,5 @@
1
+ import type { NetworkRetryPolicy } from "../network-retry-engine.js";
2
+ export declare const CODEX_RETRYABLE_MESSAGES: string[];
3
+ export type CodexRetryableErrorGroup = "transport" | "status";
4
+ export declare function isRetryableCodexTransportError(error: unknown): boolean;
5
+ export declare function createCodexRetryPolicy(): NetworkRetryPolicy;
@@ -0,0 +1,75 @@
1
+ import { createMessageRetryClassifier, isAbortError, isRetryableApiCallError, normalizeRetryableStatusResponse, toRequestUrl, toRetryableApiCallError, } from "./common-policy.js";
2
+ export const CODEX_RETRYABLE_MESSAGES = [
3
+ "load failed",
4
+ "failed to fetch",
5
+ "network request failed",
6
+ "unable to connect",
7
+ "connection reset",
8
+ "connection aborted",
9
+ "econnreset",
10
+ "etimedout",
11
+ "timeout",
12
+ "socket hang up",
13
+ ];
14
+ function isCodexUrl(request) {
15
+ const raw = toRequestUrl(request);
16
+ try {
17
+ const url = new URL(raw);
18
+ return url.hostname === "chatgpt.com" && url.pathname.startsWith("/backend-api/codex/");
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ const isRetryableCodexTransportErrorByMessage = createMessageRetryClassifier({
25
+ retryableMessages: CODEX_RETRYABLE_MESSAGES,
26
+ isAbortError,
27
+ });
28
+ export function isRetryableCodexTransportError(error) {
29
+ return isRetryableCodexTransportErrorByMessage(error);
30
+ }
31
+ function isRetryableCodexStatus(status) {
32
+ if (status === 429)
33
+ return true;
34
+ return status >= 500 && status <= 599;
35
+ }
36
+ function normalizeRetryableStatusResponseForCodex(response, request) {
37
+ return normalizeRetryableStatusResponse({
38
+ response,
39
+ request,
40
+ providerLabel: "Codex",
41
+ group: "status",
42
+ isRetryableStatus: isRetryableCodexStatus,
43
+ });
44
+ }
45
+ function toCodexRetryableApiCallError(error, request, options) {
46
+ return toRetryableApiCallError(error, request, {
47
+ providerLabel: "Codex",
48
+ group: options?.group ?? "transport",
49
+ statusCode: options?.statusCode,
50
+ responseHeaders: options?.responseHeaders,
51
+ responseBody: options?.responseBody,
52
+ });
53
+ }
54
+ export function createCodexRetryPolicy() {
55
+ return {
56
+ matchesRequest: (request) => isCodexUrl(request),
57
+ classifyFailure: async ({ error }) => {
58
+ if (isRetryableApiCallError(error)) {
59
+ return { retryable: false, category: "already-normalized" };
60
+ }
61
+ if (isRetryableCodexTransportError(error)) {
62
+ return { retryable: true, category: "transport" };
63
+ }
64
+ return { retryable: false, category: "none" };
65
+ },
66
+ handleResponse: async ({ response, request }) => normalizeRetryableStatusResponseForCodex(response, request),
67
+ normalizeFailure: ({ error, classification, request }) => {
68
+ if (classification.retryable && classification.category === "transport") {
69
+ return toCodexRetryableApiCallError(error, request);
70
+ }
71
+ return error;
72
+ },
73
+ buildRepairPlan: async () => undefined,
74
+ };
75
+ }
@@ -0,0 +1,37 @@
1
+ import type { NetworkRetryRequest } from "../network-retry-engine.js";
2
+ export type RetryableApiCallError = Error & {
3
+ url: string;
4
+ requestBodyValues: unknown;
5
+ statusCode?: number;
6
+ responseHeaders?: Record<string, string>;
7
+ responseBody?: string;
8
+ isRetryable: boolean;
9
+ cause: unknown;
10
+ [key: symbol]: unknown;
11
+ };
12
+ export declare function toRequestUrl(request: Request | URL | string): string;
13
+ export declare function getErrorMessage(error: unknown): string;
14
+ export declare function isAbortError(error: unknown): boolean;
15
+ export declare function createMessageRetryClassifier(options: {
16
+ retryableMessages: string[];
17
+ isAbortError?: (error: unknown) => boolean;
18
+ }): (error: unknown) => boolean;
19
+ export declare function toRetryableApiCallError(error: unknown, request: {
20
+ url: string;
21
+ body?: string;
22
+ }, options: {
23
+ providerLabel: string;
24
+ group: string;
25
+ requestBodyValues?: unknown;
26
+ statusCode?: number;
27
+ responseHeaders?: Headers | Record<string, string>;
28
+ responseBody?: string;
29
+ }): RetryableApiCallError;
30
+ export declare function isRetryableApiCallError(error: unknown): error is RetryableApiCallError;
31
+ export declare function normalizeRetryableStatusResponse(input: {
32
+ response: Response;
33
+ request: NetworkRetryRequest;
34
+ providerLabel: string;
35
+ group: string;
36
+ isRetryableStatus: (status: number) => boolean;
37
+ }): Promise<Response>;
@@ -0,0 +1,68 @@
1
+ const AI_ERROR_MARKER = Symbol.for("vercel.ai.error");
2
+ const API_CALL_ERROR_MARKER = Symbol.for("vercel.ai.error.AI_APICallError");
3
+ export function toRequestUrl(request) {
4
+ return request instanceof Request ? request.url : request instanceof URL ? request.href : String(request);
5
+ }
6
+ export function getErrorMessage(error) {
7
+ return String(error instanceof Error ? error.message : error).toLowerCase();
8
+ }
9
+ export function isAbortError(error) {
10
+ return error instanceof Error && error.name === "AbortError";
11
+ }
12
+ export function createMessageRetryClassifier(options) {
13
+ return function isRetryableByMessage(error) {
14
+ if (!error)
15
+ return false;
16
+ if (options.isAbortError?.(error) ?? isAbortError(error))
17
+ return false;
18
+ const message = getErrorMessage(error);
19
+ return options.retryableMessages.some((part) => message.includes(part));
20
+ };
21
+ }
22
+ function buildRetryableApiCallMessage(providerLabel, group, detail) {
23
+ return `${providerLabel} retryable error [${group}]: ${detail}`;
24
+ }
25
+ export function toRetryableApiCallError(error, request, options) {
26
+ const base = error instanceof Error ? error : new Error(String(error));
27
+ const wrapped = new Error(buildRetryableApiCallMessage(options.providerLabel, options.group, base.message));
28
+ wrapped.name = "AI_APICallError";
29
+ wrapped.url = request.url;
30
+ wrapped.requestBodyValues = options.requestBodyValues ?? (() => {
31
+ if (!request.body)
32
+ return {};
33
+ try {
34
+ return JSON.parse(request.body);
35
+ }
36
+ catch {
37
+ return {};
38
+ }
39
+ })();
40
+ wrapped.statusCode = options.statusCode;
41
+ wrapped.responseHeaders = options.responseHeaders instanceof Headers
42
+ ? Object.fromEntries(options.responseHeaders.entries())
43
+ : options.responseHeaders;
44
+ wrapped.responseBody = options.responseBody;
45
+ wrapped.isRetryable = true;
46
+ wrapped.cause = error;
47
+ wrapped[AI_ERROR_MARKER] = true;
48
+ wrapped[API_CALL_ERROR_MARKER] = true;
49
+ return wrapped;
50
+ }
51
+ export function isRetryableApiCallError(error) {
52
+ return Boolean(error
53
+ && typeof error === "object"
54
+ && error[AI_ERROR_MARKER] === true
55
+ && error[API_CALL_ERROR_MARKER] === true);
56
+ }
57
+ export async function normalizeRetryableStatusResponse(input) {
58
+ if (!input.isRetryableStatus(input.response.status))
59
+ return input.response;
60
+ const responseBody = await input.response.clone().text().catch(() => "");
61
+ throw toRetryableApiCallError(new Error(responseBody || `status code ${input.response.status}`), input.request, {
62
+ providerLabel: input.providerLabel,
63
+ group: input.group,
64
+ statusCode: input.response.status,
65
+ responseHeaders: input.response.headers,
66
+ responseBody: responseBody || undefined,
67
+ });
68
+ }
@@ -1,16 +1,7 @@
1
1
  import type { NetworkRetryPolicy } from "../network-retry-engine.js";
2
+ import { type RetryableApiCallError } from "./common-policy.js";
2
3
  export declare const COPILOT_RETRYABLE_MESSAGES: string[];
3
4
  export type RetryableErrorGroup = "transport" | "status" | "stream";
4
- type RetryableApiCallError = Error & {
5
- url: string;
6
- requestBodyValues: unknown;
7
- statusCode?: number;
8
- responseHeaders?: Record<string, string>;
9
- responseBody?: string;
10
- isRetryable: boolean;
11
- cause: unknown;
12
- [key: symbol]: unknown;
13
- };
14
5
  type CopilotStreamErrorInput = {
15
6
  error: unknown;
16
7
  request: Request | URL | string;
@@ -1,5 +1,4 @@
1
- const AI_ERROR_MARKER = Symbol.for("vercel.ai.error");
2
- const API_CALL_ERROR_MARKER = Symbol.for("vercel.ai.error.AI_APICallError");
1
+ import { createMessageRetryClassifier, getErrorMessage, isAbortError, isRetryableApiCallError as isRetryableApiCallErrorByMarker, normalizeRetryableStatusResponse, toRequestUrl, toRetryableApiCallError as toRetryableApiCallErrorByCommon, } from "./common-policy.js";
3
2
  export const COPILOT_RETRYABLE_MESSAGES = [
4
3
  "load failed",
5
4
  "failed to fetch",
@@ -13,15 +12,6 @@ export const COPILOT_RETRYABLE_MESSAGES = [
13
12
  "unable to verify the first certificate",
14
13
  "self-signed certificate in certificate chain",
15
14
  ];
16
- function toRequestUrl(request) {
17
- return request instanceof Request ? request.url : request instanceof URL ? request.href : String(request);
18
- }
19
- function getErrorMessage(error) {
20
- return String(error instanceof Error ? error.message : error).toLowerCase();
21
- }
22
- function isAbortError(error) {
23
- return error instanceof Error && error.name === "AbortError";
24
- }
25
15
  function isSseReadTimeoutError(error) {
26
16
  return getErrorMessage(error).includes("sse read timed out");
27
17
  }
@@ -96,57 +86,33 @@ export function isCopilotUrl(request) {
96
86
  return false;
97
87
  }
98
88
  }
89
+ const isRetryableCopilotTransportErrorByMessage = createMessageRetryClassifier({
90
+ retryableMessages: COPILOT_RETRYABLE_MESSAGES,
91
+ isAbortError,
92
+ });
99
93
  export function isRetryableCopilotTransportError(error) {
100
- if (!error || isAbortError(error))
101
- return false;
102
- const message = getErrorMessage(error);
103
- return COPILOT_RETRYABLE_MESSAGES.some((part) => message.includes(part));
104
- }
105
- function buildRetryableApiCallMessage(group, detail) {
106
- return `Copilot retryable error [${group}]: ${detail}`;
94
+ return isRetryableCopilotTransportErrorByMessage(error);
107
95
  }
108
96
  export function toRetryableApiCallError(error, request, options) {
109
- const base = error instanceof Error ? error : new Error(String(error));
110
- const wrapped = new Error(buildRetryableApiCallMessage(options?.group ?? "transport", base.message));
111
- wrapped.name = "AI_APICallError";
112
- wrapped.url = request.url;
113
- wrapped.requestBodyValues = options?.requestBodyValues ?? (() => {
114
- if (!request.body)
115
- return {};
116
- try {
117
- return JSON.parse(request.body);
118
- }
119
- catch {
120
- return {};
121
- }
122
- })();
123
- wrapped.statusCode = options?.statusCode;
124
- wrapped.responseHeaders = options?.responseHeaders instanceof Headers
125
- ? Object.fromEntries(options.responseHeaders.entries())
126
- : options?.responseHeaders;
127
- wrapped.responseBody = options?.responseBody;
128
- wrapped.isRetryable = true;
129
- wrapped.cause = error;
130
- wrapped[AI_ERROR_MARKER] = true;
131
- wrapped[API_CALL_ERROR_MARKER] = true;
132
- return wrapped;
97
+ return toRetryableApiCallErrorByCommon(error, request, {
98
+ providerLabel: "Copilot",
99
+ group: options?.group ?? "transport",
100
+ requestBodyValues: options?.requestBodyValues,
101
+ statusCode: options?.statusCode,
102
+ responseHeaders: options?.responseHeaders,
103
+ responseBody: options?.responseBody,
104
+ });
133
105
  }
134
106
  export function isRetryableApiCallError(error) {
135
- return Boolean(error
136
- && typeof error === "object"
137
- && error[AI_ERROR_MARKER] === true
138
- && error[API_CALL_ERROR_MARKER] === true);
139
- }
140
- function normalizeRetryableStatusResponse(response, request) {
141
- if (response.status !== 499)
142
- return response;
143
- return response.clone().text().catch(() => "").then((responseBody) => {
144
- throw toRetryableApiCallError(new Error(responseBody || `status code ${response.status}`), request, {
145
- group: "status",
146
- statusCode: response.status,
147
- responseHeaders: response.headers,
148
- responseBody: responseBody || undefined,
149
- });
107
+ return isRetryableApiCallErrorByMarker(error);
108
+ }
109
+ function normalizeRetryableStatusResponseForCopilot(response, request) {
110
+ return normalizeRetryableStatusResponse({
111
+ response,
112
+ request,
113
+ providerLabel: "Copilot",
114
+ group: "status",
115
+ isRetryableStatus: (status) => status === 499,
150
116
  });
151
117
  }
152
118
  export function createCopilotRetryPolicy(options) {
@@ -161,7 +127,7 @@ export function createCopilotRetryPolicy(options) {
161
127
  }
162
128
  return { retryable: false, category: "none" };
163
129
  },
164
- handleResponse: async ({ response, request }) => normalizeRetryableStatusResponse(response, request),
130
+ handleResponse: async ({ response, request }) => normalizeRetryableStatusResponseForCopilot(response, request),
165
131
  normalizeFailure: ({ error, classification, request }) => {
166
132
  if (classification.retryable && classification.category === "transport") {
167
133
  return toRetryableApiCallError(error, request);
@@ -0,0 +1,6 @@
1
+ export declare function accountSwitcherConfigDir(): string;
2
+ export declare function commonSettingsPath(): string;
3
+ export declare function copilotAccountsPath(): string;
4
+ export declare function codexAccountsPath(): string;
5
+ export declare function legacyCopilotStorePath(): string;
6
+ export declare function legacyCodexStorePath(): string;
@@ -0,0 +1,24 @@
1
+ import path from "node:path";
2
+ import os from "node:os";
3
+ import { xdgConfig } from "xdg-basedir";
4
+ function configBaseDir() {
5
+ return xdgConfig ?? path.join(os.homedir(), ".config");
6
+ }
7
+ export function accountSwitcherConfigDir() {
8
+ return path.join(configBaseDir(), "opencode", "account-switcher");
9
+ }
10
+ export function commonSettingsPath() {
11
+ return path.join(accountSwitcherConfigDir(), "settings.json");
12
+ }
13
+ export function copilotAccountsPath() {
14
+ return path.join(accountSwitcherConfigDir(), "copilot-accounts.json");
15
+ }
16
+ export function codexAccountsPath() {
17
+ return path.join(accountSwitcherConfigDir(), "codex-accounts.json");
18
+ }
19
+ export function legacyCopilotStorePath() {
20
+ return path.join(configBaseDir(), "opencode", "copilot-accounts.json");
21
+ }
22
+ export function legacyCodexStorePath() {
23
+ return path.join(configBaseDir(), "opencode", "codex-store.json");
24
+ }
package/dist/store.js CHANGED
@@ -3,7 +3,7 @@ import os from "node:os";
3
3
  import { promises as fs } from "node:fs";
4
4
  import { readFileSync } from "node:fs";
5
5
  import { xdgConfig, xdgData } from "xdg-basedir";
6
- const filename = "copilot-accounts.json";
6
+ import { copilotAccountsPath, legacyCopilotStorePath } from "./store-paths.js";
7
7
  const authFile = "auth.json";
8
8
  const defaultStoreDebugLogFile = (() => {
9
9
  const tmp = process.env.TEMP || process.env.TMP || "/tmp";
@@ -57,8 +57,7 @@ async function logStoreWrite(input) {
57
57
  }
58
58
  }
59
59
  export function storePath() {
60
- const base = xdgConfig ?? path.join(os.homedir(), ".config");
61
- return path.join(base, "opencode", filename);
60
+ return copilotAccountsPath();
62
61
  }
63
62
  export function authPath() {
64
63
  const dataDir = xdgData ?? path.join(os.homedir(), ".local", "share");
@@ -134,16 +133,32 @@ export function parseStore(raw) {
134
133
  return store;
135
134
  }
136
135
  export async function readStore(filePath = storePath()) {
137
- const raw = await fs.readFile(filePath, "utf-8").catch((error) => {
138
- if (error.code === "ENOENT")
136
+ const raw = await fs.readFile(filePath, "utf-8").catch(async (error) => {
137
+ if (error.code !== "ENOENT")
138
+ throw error;
139
+ if (filePath !== storePath())
139
140
  return "";
140
- throw error;
141
+ return fs.readFile(legacyCopilotStorePath(), "utf-8").catch((legacyError) => {
142
+ if (legacyError.code === "ENOENT")
143
+ return "";
144
+ throw legacyError;
145
+ });
141
146
  });
142
147
  return parseStore(raw);
143
148
  }
144
149
  export async function readStoreSafe(filePath = storePath()) {
145
150
  try {
146
- const raw = await fs.readFile(filePath, "utf-8");
151
+ const raw = await fs.readFile(filePath, "utf-8").catch(async (error) => {
152
+ if (error.code !== "ENOENT")
153
+ throw error;
154
+ if (filePath !== storePath())
155
+ return "";
156
+ return fs.readFile(legacyCopilotStorePath(), "utf-8").catch((legacyError) => {
157
+ if (legacyError.code === "ENOENT")
158
+ return "";
159
+ throw legacyError;
160
+ });
161
+ });
147
162
  return parseStore(raw);
148
163
  }
149
164
  catch (error) {
@@ -159,8 +174,19 @@ export function readStoreSafeSync(filePath = storePath()) {
159
174
  }
160
175
  catch (error) {
161
176
  const issue = error;
162
- if (issue.code === "ENOENT")
177
+ if (issue.code === "ENOENT") {
178
+ try {
179
+ if (filePath === storePath()) {
180
+ return parseStore(readFileSync(legacyCopilotStorePath(), "utf-8"));
181
+ }
182
+ }
183
+ catch (legacyError) {
184
+ const legacyIssue = legacyError;
185
+ if (legacyIssue.code !== "ENOENT")
186
+ return undefined;
187
+ }
163
188
  return parseStore("");
189
+ }
164
190
  return undefined;
165
191
  }
166
192
  }
package/dist/ui/menu.d.ts CHANGED
@@ -102,6 +102,8 @@ export declare function getMenuCopy(language?: MenuLanguage, provider?: MenuProv
102
102
  menuSubtitle: string;
103
103
  switchLanguageLabel: string;
104
104
  actionsHeading: string;
105
+ commonSettingsHeading: string;
106
+ providerSettingsHeading: string;
105
107
  addAccount: string;
106
108
  addAccountHint: string;
107
109
  importAuth: string;