opencode-copilot-account-switcher 0.2.6 → 0.2.8

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/dist/store.js CHANGED
@@ -16,8 +16,8 @@ export function parseStore(raw) {
16
16
  const data = raw ? JSON.parse(raw) : { accounts: {} };
17
17
  if (!data.accounts)
18
18
  data.accounts = {};
19
- if (data.loopSafetyEnabled !== true)
20
- data.loopSafetyEnabled = false;
19
+ if (data.loopSafetyEnabled !== false)
20
+ data.loopSafetyEnabled = true;
21
21
  if (data.networkRetryEnabled !== true)
22
22
  data.networkRetryEnabled = false;
23
23
  for (const [name, entry] of Object.entries(data.accounts)) {
package/dist/ui/menu.d.ts CHANGED
@@ -53,6 +53,8 @@ export type MenuAction = {
53
53
  type: "toggle-refresh";
54
54
  } | {
55
55
  type: "set-interval";
56
+ } | {
57
+ type: "toggle-language";
56
58
  } | {
57
59
  type: "toggle-loop-safety";
58
60
  } | {
@@ -68,6 +70,31 @@ export type MenuAction = {
68
70
  } | {
69
71
  type: "cancel";
70
72
  };
73
+ export type MenuLanguage = "zh" | "en";
74
+ export declare function getMenuCopy(language?: MenuLanguage): {
75
+ menuTitle: string;
76
+ menuSubtitle: string;
77
+ switchLanguageLabel: string;
78
+ actionsHeading: string;
79
+ addAccount: string;
80
+ addAccountHint: string;
81
+ importAuth: string;
82
+ checkQuotas: string;
83
+ refreshIdentity: string;
84
+ checkModels: string;
85
+ enableRefresh: string;
86
+ disableRefresh: string;
87
+ setRefresh: string;
88
+ enableLoopSafety: string;
89
+ disableLoopSafety: string;
90
+ loopSafetyHint: string;
91
+ enableRetry: string;
92
+ disableRetry: string;
93
+ retryHint: string;
94
+ accountsHeading: string;
95
+ dangerHeading: string;
96
+ removeAll: string;
97
+ };
71
98
  export declare function buildMenuItems(input: {
72
99
  accounts: AccountInfo[];
73
100
  refresh?: {
@@ -77,9 +104,10 @@ export declare function buildMenuItems(input: {
77
104
  lastQuotaRefresh?: number;
78
105
  loopSafetyEnabled: boolean;
79
106
  networkRetryEnabled: boolean;
107
+ language?: MenuLanguage;
80
108
  }): MenuItem<MenuAction>[];
81
109
  export declare function showMenu(accounts: AccountInfo[], refresh?: {
82
110
  enabled: boolean;
83
111
  minutes: number;
84
- }, lastQuotaRefresh?: number, loopSafetyEnabled?: boolean, networkRetryEnabled?: boolean): Promise<MenuAction>;
112
+ }, lastQuotaRefresh?: number, loopSafetyEnabled?: boolean, networkRetryEnabled?: boolean, language?: MenuLanguage): Promise<MenuAction>;
85
113
  export declare function showAccountActions(account: AccountInfo): Promise<"switch" | "remove" | "back">;
package/dist/ui/menu.js CHANGED
@@ -1,6 +1,58 @@
1
1
  import { ANSI } from "./ansi.js";
2
2
  import { select } from "./select.js";
3
3
  import { confirm } from "./confirm.js";
4
+ export function getMenuCopy(language = "zh") {
5
+ if (language === "en") {
6
+ return {
7
+ menuTitle: "GitHub Copilot accounts",
8
+ menuSubtitle: "Select an action or account",
9
+ switchLanguageLabel: "切换到中文",
10
+ actionsHeading: "Actions",
11
+ addAccount: "Add account",
12
+ addAccountHint: "device login or manual",
13
+ importAuth: "Import from auth.json",
14
+ checkQuotas: "Check quotas",
15
+ refreshIdentity: "Refresh identity",
16
+ checkModels: "Check models",
17
+ enableRefresh: "Enable auto refresh",
18
+ disableRefresh: "Disable auto refresh",
19
+ setRefresh: "Set refresh interval",
20
+ enableLoopSafety: "Enable guided loop safety",
21
+ disableLoopSafety: "Disable guided loop safety",
22
+ loopSafetyHint: "Prompt-guided: fewer report interruptions, fewer unnecessary subagents",
23
+ enableRetry: "Enable Copilot network retry",
24
+ disableRetry: "Disable Copilot network retry",
25
+ retryHint: "Overrides official fetch path; may drift from upstream",
26
+ accountsHeading: "Accounts",
27
+ dangerHeading: "Danger zone",
28
+ removeAll: "Remove all accounts",
29
+ };
30
+ }
31
+ return {
32
+ menuTitle: "GitHub Copilot 账号",
33
+ menuSubtitle: "请选择操作或账号",
34
+ switchLanguageLabel: "Switch to English",
35
+ actionsHeading: "操作",
36
+ addAccount: "添加账号",
37
+ addAccountHint: "设备登录或手动录入",
38
+ importAuth: "从 auth.json 导入",
39
+ checkQuotas: "检查配额",
40
+ refreshIdentity: "刷新身份信息",
41
+ checkModels: "检查模型",
42
+ enableRefresh: "开启自动刷新",
43
+ disableRefresh: "关闭自动刷新",
44
+ setRefresh: "设置刷新间隔",
45
+ enableLoopSafety: "开启 Guided Loop Safety",
46
+ disableLoopSafety: "关闭 Guided Loop Safety",
47
+ loopSafetyHint: "提示词引导:减少汇报打断与不必要子代理",
48
+ enableRetry: "开启 Copilot Network Retry",
49
+ disableRetry: "关闭 Copilot Network Retry",
50
+ retryHint: "包装官方 fetch;可能随 upstream 产生漂移",
51
+ accountsHeading: "账号",
52
+ dangerHeading: "危险操作",
53
+ removeAll: "删除全部账号",
54
+ };
55
+ }
4
56
  function formatRelativeTime(timestamp) {
5
57
  if (!timestamp)
6
58
  return "never";
@@ -26,35 +78,37 @@ function getStatusBadge(status) {
26
78
  return "";
27
79
  }
28
80
  export function buildMenuItems(input) {
81
+ const copy = getMenuCopy(input.language);
29
82
  const quotaHint = input.lastQuotaRefresh ? `last ${formatRelativeTime(input.lastQuotaRefresh)}` : undefined;
30
83
  return [
31
- { label: "Actions", value: { type: "cancel" }, kind: "heading" },
32
- { label: "Add account", value: { type: "add" }, color: "cyan", hint: "device login or manual" },
33
- { label: "Import from auth.json", value: { type: "import" }, color: "cyan" },
34
- { label: "Check quotas", value: { type: "quota" }, color: "cyan", hint: quotaHint },
35
- { label: "Refresh identity", value: { type: "refresh-identity" }, color: "cyan" },
36
- { label: "Check models", value: { type: "check-models" }, color: "cyan" },
84
+ { label: copy.actionsHeading, value: { type: "cancel" }, kind: "heading" },
85
+ { label: copy.switchLanguageLabel, value: { type: "toggle-language" }, color: "cyan" },
86
+ { label: copy.addAccount, value: { type: "add" }, color: "cyan", hint: copy.addAccountHint },
87
+ { label: copy.importAuth, value: { type: "import" }, color: "cyan" },
88
+ { label: copy.checkQuotas, value: { type: "quota" }, color: "cyan", hint: quotaHint },
89
+ { label: copy.refreshIdentity, value: { type: "refresh-identity" }, color: "cyan" },
90
+ { label: copy.checkModels, value: { type: "check-models" }, color: "cyan" },
37
91
  {
38
- label: input.refresh?.enabled ? "Disable auto refresh" : "Enable auto refresh",
92
+ label: input.refresh?.enabled ? copy.disableRefresh : copy.enableRefresh,
39
93
  value: { type: "toggle-refresh" },
40
94
  color: "cyan",
41
95
  hint: input.refresh ? `${input.refresh.minutes}m` : undefined,
42
96
  },
43
- { label: "Set refresh interval", value: { type: "set-interval" }, color: "cyan" },
97
+ { label: copy.setRefresh, value: { type: "set-interval" }, color: "cyan" },
44
98
  {
45
- label: input.loopSafetyEnabled ? "Disable guided loop safety" : "Enable guided loop safety",
99
+ label: input.loopSafetyEnabled ? copy.disableLoopSafety : copy.enableLoopSafety,
46
100
  value: { type: "toggle-loop-safety" },
47
101
  color: "cyan",
48
- hint: "Prompt-guided: fewer report interruptions, fewer unnecessary subagents",
102
+ hint: copy.loopSafetyHint,
49
103
  },
50
104
  {
51
- label: input.networkRetryEnabled ? "Disable Copilot network retry" : "Enable Copilot network retry",
105
+ label: input.networkRetryEnabled ? copy.disableRetry : copy.enableRetry,
52
106
  value: { type: "toggle-network-retry" },
53
107
  color: "cyan",
54
- hint: "Overrides official fetch path; may drift from upstream",
108
+ hint: copy.retryHint,
55
109
  },
56
110
  { label: "", value: { type: "cancel" }, separator: true },
57
- { label: "Accounts", value: { type: "cancel" }, kind: "heading" },
111
+ { label: copy.accountsHeading, value: { type: "cancel" }, kind: "heading" },
58
112
  ...input.accounts.map((account) => {
59
113
  const statusBadge = getStatusBadge(account.status);
60
114
  const currentBadge = account.isCurrent ? ` ${ANSI.cyan}*${ANSI.reset}` : "";
@@ -78,26 +132,33 @@ export function buildMenuItems(input) {
78
132
  };
79
133
  }),
80
134
  { label: "", value: { type: "cancel" }, separator: true },
81
- { label: "Danger zone", value: { type: "cancel" }, kind: "heading" },
82
- { label: "Remove all accounts", value: { type: "remove-all" }, color: "red" },
135
+ { label: copy.dangerHeading, value: { type: "cancel" }, kind: "heading" },
136
+ { label: copy.removeAll, value: { type: "remove-all" }, color: "red" },
83
137
  ];
84
138
  }
85
- export async function showMenu(accounts, refresh, lastQuotaRefresh, loopSafetyEnabled = false, networkRetryEnabled = false) {
86
- const items = buildMenuItems({
87
- accounts,
88
- refresh,
89
- lastQuotaRefresh,
90
- loopSafetyEnabled,
91
- networkRetryEnabled,
92
- });
139
+ export async function showMenu(accounts, refresh, lastQuotaRefresh, loopSafetyEnabled = false, networkRetryEnabled = false, language = "zh") {
140
+ let currentLanguage = language;
93
141
  while (true) {
142
+ const copy = getMenuCopy(currentLanguage);
143
+ const items = buildMenuItems({
144
+ accounts,
145
+ refresh,
146
+ lastQuotaRefresh,
147
+ loopSafetyEnabled,
148
+ networkRetryEnabled,
149
+ language: currentLanguage,
150
+ });
94
151
  const result = await select(items, {
95
- message: "GitHub Copilot accounts",
96
- subtitle: "Select an action or account",
152
+ message: copy.menuTitle,
153
+ subtitle: copy.menuSubtitle,
97
154
  clearScreen: true,
98
155
  });
99
156
  if (!result)
100
157
  return { type: "cancel" };
158
+ if (result.type === "toggle-language") {
159
+ currentLanguage = currentLanguage === "zh" ? "en" : "zh";
160
+ continue;
161
+ }
101
162
  if (result.type === "remove-all") {
102
163
  const ok = await confirm("Remove ALL accounts? This cannot be undone.");
103
164
  if (!ok)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-copilot-account-switcher",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "GitHub Copilot account switcher plugin for OpenCode",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",