opencode-copilot-account-switcher 0.12.4 → 0.13.1
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/codex-oauth.d.ts +39 -0
- package/dist/codex-oauth.js +316 -0
- package/dist/codex-status-command.js +85 -28
- package/dist/codex-store.d.ts +36 -13
- package/dist/codex-store.js +231 -39
- package/dist/menu-runtime.d.ts +69 -0
- package/dist/menu-runtime.js +108 -0
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.js +153 -686
- package/dist/providers/codex-menu-adapter.d.ts +47 -0
- package/dist/providers/codex-menu-adapter.js +307 -0
- package/dist/providers/copilot-menu-adapter.d.ts +65 -0
- package/dist/providers/copilot-menu-adapter.js +763 -0
- package/dist/providers/descriptor.js +7 -2
- package/dist/providers/registry.js +3 -2
- package/dist/ui/menu.d.ts +49 -3
- package/dist/ui/menu.js +208 -43
- package/package.json +1 -1
|
@@ -40,8 +40,13 @@ export const CODEX_PROVIDER_DESCRIPTOR = {
|
|
|
40
40
|
commands: [
|
|
41
41
|
"codex-status",
|
|
42
42
|
],
|
|
43
|
-
menuEntries: [
|
|
43
|
+
menuEntries: [
|
|
44
|
+
"switch-account",
|
|
45
|
+
"add-account",
|
|
46
|
+
"refresh-snapshot",
|
|
47
|
+
],
|
|
44
48
|
capabilities: [
|
|
49
|
+
"auth",
|
|
45
50
|
"slash-commands",
|
|
46
51
|
],
|
|
47
52
|
};
|
|
@@ -61,6 +66,6 @@ export function createCodexProviderDescriptor(input = {}) {
|
|
|
61
66
|
auth: {
|
|
62
67
|
provider: "openai",
|
|
63
68
|
},
|
|
64
|
-
enabledByDefault: input.enabled
|
|
69
|
+
enabledByDefault: input.enabled !== false,
|
|
65
70
|
};
|
|
66
71
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { COPILOT_PROVIDER_DESCRIPTOR } from "./descriptor.js";
|
|
1
|
+
import { CODEX_PROVIDER_DESCRIPTOR, COPILOT_PROVIDER_DESCRIPTOR } from "./descriptor.js";
|
|
2
2
|
import { createCodexProviderDescriptor, createCopilotProviderDescriptor } from "./descriptor.js";
|
|
3
3
|
const PROVIDER_DESCRIPTORS = [
|
|
4
4
|
COPILOT_PROVIDER_DESCRIPTOR,
|
|
5
|
+
CODEX_PROVIDER_DESCRIPTOR,
|
|
5
6
|
];
|
|
6
7
|
export function listProviderDescriptors() {
|
|
7
8
|
return [...PROVIDER_DESCRIPTORS];
|
|
@@ -21,7 +22,7 @@ export function createProviderRegistry(input) {
|
|
|
21
22
|
descriptor: createCopilotProviderDescriptor({ buildPluginHooks: input.buildPluginHooks }),
|
|
22
23
|
},
|
|
23
24
|
codex: {
|
|
24
|
-
descriptor: createCodexProviderDescriptor({ enabled:
|
|
25
|
+
descriptor: createCodexProviderDescriptor({ enabled: true }),
|
|
25
26
|
},
|
|
26
27
|
};
|
|
27
28
|
}
|
package/dist/ui/menu.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type MenuItem } from "./select.js";
|
|
1
|
+
import { select, type MenuItem } from "./select.js";
|
|
2
|
+
import { confirm } from "./confirm.js";
|
|
2
3
|
export type AccountStatus = "active" | "expired" | "unknown";
|
|
3
4
|
export interface AccountInfo {
|
|
4
5
|
name: string;
|
|
@@ -81,7 +82,21 @@ export type MenuAction = {
|
|
|
81
82
|
type: "cancel";
|
|
82
83
|
};
|
|
83
84
|
export type MenuLanguage = "zh" | "en";
|
|
84
|
-
export
|
|
85
|
+
export type MenuProvider = "copilot" | "codex";
|
|
86
|
+
type MenuCapabilities = {
|
|
87
|
+
importAuth: boolean;
|
|
88
|
+
quota: boolean;
|
|
89
|
+
refreshIdentity: boolean;
|
|
90
|
+
checkModels: boolean;
|
|
91
|
+
defaultAccountGroup: boolean;
|
|
92
|
+
assignModels: boolean;
|
|
93
|
+
loopSafety: boolean;
|
|
94
|
+
policyScope: boolean;
|
|
95
|
+
experimentalSlashCommands: boolean;
|
|
96
|
+
networkRetry: boolean;
|
|
97
|
+
syntheticAgentInitiator: boolean;
|
|
98
|
+
};
|
|
99
|
+
export declare function getMenuCopy(language?: MenuLanguage, provider?: MenuProvider): {
|
|
85
100
|
menuTitle: string;
|
|
86
101
|
menuSubtitle: string;
|
|
87
102
|
switchLanguageLabel: string;
|
|
@@ -117,6 +132,7 @@ export declare function getMenuCopy(language?: MenuLanguage): {
|
|
|
117
132
|
removeAll: string;
|
|
118
133
|
};
|
|
119
134
|
export declare function buildMenuItems(input: {
|
|
135
|
+
provider?: MenuProvider;
|
|
120
136
|
accounts: AccountInfo[];
|
|
121
137
|
refresh?: {
|
|
122
138
|
enabled: boolean;
|
|
@@ -130,9 +146,28 @@ export declare function buildMenuItems(input: {
|
|
|
130
146
|
networkRetryEnabled: boolean;
|
|
131
147
|
syntheticAgentInitiatorEnabled?: boolean;
|
|
132
148
|
experimentalSlashCommandsEnabled?: boolean;
|
|
149
|
+
capabilities?: Partial<MenuCapabilities>;
|
|
133
150
|
language?: MenuLanguage;
|
|
134
151
|
}): MenuItem<MenuAction>[];
|
|
135
152
|
export declare function showMenu(accounts: AccountInfo[], input?: {
|
|
153
|
+
provider?: MenuProvider;
|
|
154
|
+
refresh?: {
|
|
155
|
+
enabled: boolean;
|
|
156
|
+
minutes: number;
|
|
157
|
+
};
|
|
158
|
+
lastQuotaRefresh?: number;
|
|
159
|
+
modelAccountAssignmentCount?: number;
|
|
160
|
+
defaultAccountGroupCount?: number;
|
|
161
|
+
loopSafetyEnabled?: boolean;
|
|
162
|
+
loopSafetyProviderScope?: "copilot-only" | "all-models";
|
|
163
|
+
networkRetryEnabled?: boolean;
|
|
164
|
+
syntheticAgentInitiatorEnabled?: boolean;
|
|
165
|
+
experimentalSlashCommandsEnabled?: boolean;
|
|
166
|
+
capabilities?: Partial<MenuCapabilities>;
|
|
167
|
+
language?: MenuLanguage;
|
|
168
|
+
}): Promise<MenuAction>;
|
|
169
|
+
export declare function showMenuWithDeps(accounts: AccountInfo[], input?: {
|
|
170
|
+
provider?: MenuProvider;
|
|
136
171
|
refresh?: {
|
|
137
172
|
enabled: boolean;
|
|
138
173
|
minutes: number;
|
|
@@ -145,6 +180,17 @@ export declare function showMenu(accounts: AccountInfo[], input?: {
|
|
|
145
180
|
networkRetryEnabled?: boolean;
|
|
146
181
|
syntheticAgentInitiatorEnabled?: boolean;
|
|
147
182
|
experimentalSlashCommandsEnabled?: boolean;
|
|
183
|
+
capabilities?: Partial<MenuCapabilities>;
|
|
148
184
|
language?: MenuLanguage;
|
|
185
|
+
}, deps?: {
|
|
186
|
+
select?: typeof select;
|
|
187
|
+
confirm?: typeof confirm;
|
|
188
|
+
showAccountActions?: typeof showAccountActions;
|
|
149
189
|
}): Promise<MenuAction>;
|
|
150
|
-
export declare function
|
|
190
|
+
export declare function buildAccountActionItems(account: AccountInfo, input?: {
|
|
191
|
+
provider?: MenuProvider;
|
|
192
|
+
}): MenuItem<"switch" | "remove" | "back" | "models">[];
|
|
193
|
+
export declare function showAccountActions(account: AccountInfo, input?: {
|
|
194
|
+
provider?: MenuProvider;
|
|
195
|
+
}): Promise<"switch" | "remove" | "back">;
|
|
196
|
+
export {};
|
package/dist/ui/menu.js
CHANGED
|
@@ -1,7 +1,111 @@
|
|
|
1
1
|
import { ANSI } from "./ansi.js";
|
|
2
2
|
import { select } from "./select.js";
|
|
3
3
|
import { confirm } from "./confirm.js";
|
|
4
|
-
|
|
4
|
+
function defaultMenuCapabilities(provider) {
|
|
5
|
+
if (provider === "codex") {
|
|
6
|
+
return {
|
|
7
|
+
importAuth: false,
|
|
8
|
+
quota: true,
|
|
9
|
+
refreshIdentity: false,
|
|
10
|
+
checkModels: false,
|
|
11
|
+
defaultAccountGroup: false,
|
|
12
|
+
assignModels: false,
|
|
13
|
+
loopSafety: false,
|
|
14
|
+
policyScope: false,
|
|
15
|
+
experimentalSlashCommands: false,
|
|
16
|
+
networkRetry: false,
|
|
17
|
+
syntheticAgentInitiator: false,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
importAuth: true,
|
|
22
|
+
quota: true,
|
|
23
|
+
refreshIdentity: true,
|
|
24
|
+
checkModels: true,
|
|
25
|
+
defaultAccountGroup: true,
|
|
26
|
+
assignModels: true,
|
|
27
|
+
loopSafety: true,
|
|
28
|
+
policyScope: true,
|
|
29
|
+
experimentalSlashCommands: true,
|
|
30
|
+
networkRetry: true,
|
|
31
|
+
syntheticAgentInitiator: true,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function getMenuCopy(language = "zh", provider = "copilot") {
|
|
35
|
+
if (provider === "codex") {
|
|
36
|
+
if (language === "en") {
|
|
37
|
+
return {
|
|
38
|
+
menuTitle: "OpenAI Codex accounts",
|
|
39
|
+
menuSubtitle: "Select an action or account",
|
|
40
|
+
switchLanguageLabel: "切换到中文",
|
|
41
|
+
actionsHeading: "Actions",
|
|
42
|
+
addAccount: "Add account",
|
|
43
|
+
addAccountHint: "OpenAI OAuth login",
|
|
44
|
+
importAuth: "Import from auth.json",
|
|
45
|
+
checkQuotas: "Refresh snapshots",
|
|
46
|
+
refreshIdentity: "Sync account identity",
|
|
47
|
+
checkModels: "Sync available models",
|
|
48
|
+
defaultAccountGroup: "Default account group",
|
|
49
|
+
assignModels: "Assign account groups per model",
|
|
50
|
+
autoRefreshOn: "Auto refresh: On",
|
|
51
|
+
autoRefreshOff: "Auto refresh: Off",
|
|
52
|
+
setRefresh: "Set refresh interval",
|
|
53
|
+
loopSafetyOn: "Guided Loop Safety: On",
|
|
54
|
+
loopSafetyOff: "Guided Loop Safety: Off",
|
|
55
|
+
loopSafetyHint: "Reduce unnecessary handoff replies while work can continue",
|
|
56
|
+
policyScopeCopilotOnly: "Policy default scope: Current provider only",
|
|
57
|
+
policyScopeAllModels: "Policy default scope: All models",
|
|
58
|
+
policyScopeHint: "Choose whether Guided Loop Safety applies only to the current provider by default or to all models",
|
|
59
|
+
experimentalSlashCommandsOn: "Experimental slash commands: On",
|
|
60
|
+
experimentalSlashCommandsOff: "Experimental slash commands: Off",
|
|
61
|
+
experimentalSlashCommandsHint: "Experimental provider-specific slash commands",
|
|
62
|
+
retryOn: "Network Retry: On",
|
|
63
|
+
retryOff: "Network Retry: Off",
|
|
64
|
+
retryHint: "Helps recover some requests after retries or malformed responses",
|
|
65
|
+
syntheticInitiatorOn: "Send synthetic messages as agent: On",
|
|
66
|
+
syntheticInitiatorOff: "Send synthetic messages as agent: Off",
|
|
67
|
+
syntheticInitiatorHint: "Changes upstream behavior; misuse may increase billing risk or trigger abuse signals",
|
|
68
|
+
accountsHeading: "Accounts",
|
|
69
|
+
dangerHeading: "Danger zone",
|
|
70
|
+
removeAll: "Remove all accounts",
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
menuTitle: "OpenAI Codex 账号",
|
|
75
|
+
menuSubtitle: "请选择操作或账号",
|
|
76
|
+
switchLanguageLabel: "Switch to English",
|
|
77
|
+
actionsHeading: "操作",
|
|
78
|
+
addAccount: "添加账号",
|
|
79
|
+
addAccountHint: "OpenAI OAuth 登录",
|
|
80
|
+
importAuth: "从 auth.json 导入",
|
|
81
|
+
checkQuotas: "刷新快照",
|
|
82
|
+
refreshIdentity: "同步账号身份信息",
|
|
83
|
+
checkModels: "同步可用模型列表",
|
|
84
|
+
defaultAccountGroup: "配置默认账号组",
|
|
85
|
+
assignModels: "为模型配置账号组",
|
|
86
|
+
autoRefreshOn: "自动刷新:已开启",
|
|
87
|
+
autoRefreshOff: "自动刷新:已关闭",
|
|
88
|
+
setRefresh: "设置刷新间隔",
|
|
89
|
+
loopSafetyOn: "Guided Loop Safety:已开启",
|
|
90
|
+
loopSafetyOff: "Guided Loop Safety:已关闭",
|
|
91
|
+
loopSafetyHint: "让模型更少无谓汇报,没做完前优先继续干活",
|
|
92
|
+
policyScopeCopilotOnly: "Policy 默认注入范围:仅当前 provider",
|
|
93
|
+
policyScopeAllModels: "Policy 默认注入范围:所有模型",
|
|
94
|
+
policyScopeHint: "决定 Guided Loop Safety 默认只作用于当前 provider,还是扩展到所有模型",
|
|
95
|
+
experimentalSlashCommandsOn: "实验性 Slash Commands:已开启",
|
|
96
|
+
experimentalSlashCommandsOff: "实验性 Slash Commands:已关闭",
|
|
97
|
+
experimentalSlashCommandsHint: "当前 provider 的实验性 Slash Commands 开关",
|
|
98
|
+
retryOn: "Network Retry:已开启",
|
|
99
|
+
retryOff: "Network Retry:已关闭",
|
|
100
|
+
retryHint: "请求异常时可自动重试并修复部分请求",
|
|
101
|
+
syntheticInitiatorOn: "synthetic 消息按 agent 身份发送:已开启",
|
|
102
|
+
syntheticInitiatorOff: "synthetic 消息按 agent 身份发送:已关闭",
|
|
103
|
+
syntheticInitiatorHint: "会改变与 upstream 的默认行为;误用可能带来异常计费或 abuse 风险",
|
|
104
|
+
accountsHeading: "账号",
|
|
105
|
+
dangerHeading: "危险操作",
|
|
106
|
+
removeAll: "删除全部账号",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
5
109
|
if (language === "en") {
|
|
6
110
|
return {
|
|
7
111
|
menuTitle: "GitHub Copilot accounts",
|
|
@@ -100,67 +204,108 @@ function getStatusBadge(status) {
|
|
|
100
204
|
return "";
|
|
101
205
|
}
|
|
102
206
|
export function buildMenuItems(input) {
|
|
103
|
-
const
|
|
207
|
+
const provider = input.provider ?? "copilot";
|
|
208
|
+
const copy = getMenuCopy(input.language, provider);
|
|
209
|
+
const capabilities = {
|
|
210
|
+
...defaultMenuCapabilities(provider),
|
|
211
|
+
...input.capabilities,
|
|
212
|
+
};
|
|
213
|
+
if (provider === "codex") {
|
|
214
|
+
capabilities.refreshIdentity = false;
|
|
215
|
+
capabilities.checkModels = false;
|
|
216
|
+
capabilities.defaultAccountGroup = false;
|
|
217
|
+
capabilities.assignModels = false;
|
|
218
|
+
capabilities.loopSafety = false;
|
|
219
|
+
capabilities.policyScope = false;
|
|
220
|
+
capabilities.experimentalSlashCommands = false;
|
|
221
|
+
capabilities.networkRetry = false;
|
|
222
|
+
capabilities.syntheticAgentInitiator = false;
|
|
223
|
+
}
|
|
104
224
|
const quotaHint = input.lastQuotaRefresh ? `last ${formatRelativeTime(input.lastQuotaRefresh)}` : undefined;
|
|
105
225
|
const loopSafetyProviderScope = input.loopSafetyProviderScope ?? "copilot-only";
|
|
106
226
|
const experimentalSlashCommandsEnabled = input.experimentalSlashCommandsEnabled !== false;
|
|
107
|
-
|
|
227
|
+
const actions = [
|
|
108
228
|
{ label: copy.actionsHeading, value: { type: "cancel" }, kind: "heading" },
|
|
109
229
|
{ label: copy.switchLanguageLabel, value: { type: "toggle-language" }, color: "cyan" },
|
|
110
230
|
{ label: copy.addAccount, value: { type: "add" }, color: "cyan", hint: copy.addAccountHint },
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
{ label: copy.
|
|
114
|
-
|
|
115
|
-
|
|
231
|
+
];
|
|
232
|
+
if (capabilities.importAuth) {
|
|
233
|
+
actions.push({ label: copy.importAuth, value: { type: "import" }, color: "cyan" });
|
|
234
|
+
}
|
|
235
|
+
if (capabilities.quota) {
|
|
236
|
+
actions.push({ label: copy.checkQuotas, value: { type: "quota" }, color: "cyan", hint: quotaHint });
|
|
237
|
+
}
|
|
238
|
+
if (capabilities.refreshIdentity) {
|
|
239
|
+
actions.push({ label: copy.refreshIdentity, value: { type: "refresh-identity" }, color: "cyan" });
|
|
240
|
+
}
|
|
241
|
+
if (capabilities.checkModels) {
|
|
242
|
+
actions.push({ label: copy.checkModels, value: { type: "check-models" }, color: "cyan" });
|
|
243
|
+
}
|
|
244
|
+
if (capabilities.defaultAccountGroup) {
|
|
245
|
+
actions.push({
|
|
116
246
|
label: copy.defaultAccountGroup,
|
|
117
247
|
value: { type: "configure-default-group" },
|
|
118
248
|
color: "cyan",
|
|
119
249
|
hint: input.defaultAccountGroupCount !== undefined ? `${input.defaultAccountGroupCount} selected` : undefined,
|
|
120
|
-
}
|
|
121
|
-
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
if (capabilities.assignModels) {
|
|
253
|
+
actions.push({
|
|
122
254
|
label: copy.assignModels,
|
|
123
255
|
value: { type: "assign-models" },
|
|
124
256
|
color: "cyan",
|
|
125
257
|
hint: input.modelAccountAssignmentCount ? `${input.modelAccountAssignmentCount} groups` : undefined,
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
actions.push({
|
|
261
|
+
label: input.refresh?.enabled ? copy.autoRefreshOn : copy.autoRefreshOff,
|
|
262
|
+
value: { type: "toggle-refresh" },
|
|
263
|
+
color: "cyan",
|
|
264
|
+
hint: input.refresh ? `${input.refresh.minutes}m` : undefined,
|
|
265
|
+
});
|
|
266
|
+
actions.push({ label: copy.setRefresh, value: { type: "set-interval" }, color: "cyan" });
|
|
267
|
+
if (capabilities.loopSafety) {
|
|
268
|
+
actions.push({
|
|
135
269
|
label: input.loopSafetyEnabled ? copy.loopSafetyOn : copy.loopSafetyOff,
|
|
136
270
|
value: { type: "toggle-loop-safety" },
|
|
137
271
|
color: "cyan",
|
|
138
272
|
hint: copy.loopSafetyHint,
|
|
139
|
-
}
|
|
140
|
-
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (capabilities.policyScope) {
|
|
276
|
+
actions.push({
|
|
141
277
|
label: loopSafetyProviderScope === "all-models" ? copy.policyScopeAllModels : copy.policyScopeCopilotOnly,
|
|
142
278
|
value: { type: "toggle-loop-safety-provider-scope" },
|
|
143
279
|
color: "cyan",
|
|
144
280
|
hint: copy.policyScopeHint,
|
|
145
|
-
}
|
|
146
|
-
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (capabilities.experimentalSlashCommands) {
|
|
284
|
+
actions.push({
|
|
147
285
|
label: experimentalSlashCommandsEnabled ? copy.experimentalSlashCommandsOn : copy.experimentalSlashCommandsOff,
|
|
148
286
|
value: { type: "toggle-experimental-slash-commands" },
|
|
149
287
|
color: "cyan",
|
|
150
288
|
hint: copy.experimentalSlashCommandsHint,
|
|
151
|
-
}
|
|
152
|
-
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
if (capabilities.networkRetry) {
|
|
292
|
+
actions.push({
|
|
153
293
|
label: input.networkRetryEnabled ? copy.retryOn : copy.retryOff,
|
|
154
294
|
value: { type: "toggle-network-retry" },
|
|
155
295
|
color: "cyan",
|
|
156
296
|
hint: copy.retryHint,
|
|
157
|
-
}
|
|
158
|
-
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
if (capabilities.syntheticAgentInitiator) {
|
|
300
|
+
actions.push({
|
|
159
301
|
label: input.syntheticAgentInitiatorEnabled ? copy.syntheticInitiatorOn : copy.syntheticInitiatorOff,
|
|
160
302
|
value: { type: "toggle-synthetic-agent-initiator" },
|
|
161
303
|
color: "cyan",
|
|
162
304
|
hint: copy.syntheticInitiatorHint,
|
|
163
|
-
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
return [
|
|
308
|
+
...actions,
|
|
164
309
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
165
310
|
{ label: copy.accountsHeading, value: { type: "cancel" }, kind: "heading" },
|
|
166
311
|
...input.accounts.map((account) => {
|
|
@@ -191,10 +336,18 @@ export function buildMenuItems(input) {
|
|
|
191
336
|
];
|
|
192
337
|
}
|
|
193
338
|
export async function showMenu(accounts, input = {}) {
|
|
339
|
+
return showMenuWithDeps(accounts, input);
|
|
340
|
+
}
|
|
341
|
+
export async function showMenuWithDeps(accounts, input = {}, deps = {}) {
|
|
342
|
+
const selectMenu = deps.select ?? select;
|
|
343
|
+
const confirmAction = deps.confirm ?? confirm;
|
|
344
|
+
const showAccountActionMenu = deps.showAccountActions ?? showAccountActions;
|
|
194
345
|
let currentLanguage = input.language ?? "zh";
|
|
195
346
|
while (true) {
|
|
196
|
-
const
|
|
347
|
+
const provider = input.provider ?? "copilot";
|
|
348
|
+
const copy = getMenuCopy(currentLanguage, provider);
|
|
197
349
|
const items = buildMenuItems({
|
|
350
|
+
provider,
|
|
198
351
|
accounts,
|
|
199
352
|
refresh: input.refresh,
|
|
200
353
|
lastQuotaRefresh: input.lastQuotaRefresh,
|
|
@@ -205,9 +358,10 @@ export async function showMenu(accounts, input = {}) {
|
|
|
205
358
|
networkRetryEnabled: input.networkRetryEnabled === true,
|
|
206
359
|
syntheticAgentInitiatorEnabled: input.syntheticAgentInitiatorEnabled === true,
|
|
207
360
|
experimentalSlashCommandsEnabled: input.experimentalSlashCommandsEnabled,
|
|
361
|
+
capabilities: input.capabilities,
|
|
208
362
|
language: currentLanguage,
|
|
209
363
|
});
|
|
210
|
-
const result = await
|
|
364
|
+
const result = await selectMenu(items, {
|
|
211
365
|
message: copy.menuTitle,
|
|
212
366
|
subtitle: copy.menuSubtitle,
|
|
213
367
|
clearScreen: true,
|
|
@@ -218,15 +372,34 @@ export async function showMenu(accounts, input = {}) {
|
|
|
218
372
|
currentLanguage = currentLanguage === "zh" ? "en" : "zh";
|
|
219
373
|
continue;
|
|
220
374
|
}
|
|
375
|
+
if (result.type === "switch") {
|
|
376
|
+
const next = await showAccountActionMenu(result.account, { provider });
|
|
377
|
+
if (next === "back")
|
|
378
|
+
continue;
|
|
379
|
+
return { type: next, account: result.account };
|
|
380
|
+
}
|
|
221
381
|
if (result.type === "remove-all") {
|
|
222
|
-
const ok = await
|
|
382
|
+
const ok = await confirmAction("Remove ALL accounts? This cannot be undone.");
|
|
223
383
|
if (!ok)
|
|
224
384
|
continue;
|
|
225
385
|
}
|
|
226
386
|
return result;
|
|
227
387
|
}
|
|
228
388
|
}
|
|
229
|
-
export
|
|
389
|
+
export function buildAccountActionItems(account, input = {}) {
|
|
390
|
+
const provider = input.provider ?? "copilot";
|
|
391
|
+
const modelAction = provider === "copilot" && (account.modelList || account.modelsError)
|
|
392
|
+
? [{ label: "View models", value: "models", color: "cyan" }]
|
|
393
|
+
: [];
|
|
394
|
+
return [
|
|
395
|
+
{ label: "Back", value: "back" },
|
|
396
|
+
...modelAction,
|
|
397
|
+
{ label: "Switch to this account", value: "switch", color: "cyan" },
|
|
398
|
+
{ label: "Remove this account", value: "remove", color: "red" },
|
|
399
|
+
];
|
|
400
|
+
}
|
|
401
|
+
export async function showAccountActions(account, input = {}) {
|
|
402
|
+
const provider = input.provider ?? "copilot";
|
|
230
403
|
const badge = getStatusBadge(account.status);
|
|
231
404
|
const header = `${account.name}${badge ? " " + badge : ""}`;
|
|
232
405
|
const info = [
|
|
@@ -234,23 +407,15 @@ export async function showAccountActions(account) {
|
|
|
234
407
|
account.plan ? `Plan: ${account.plan}` : undefined,
|
|
235
408
|
account.sku ? `SKU: ${account.sku}` : undefined,
|
|
236
409
|
account.reset ? `Reset: ${account.reset}` : undefined,
|
|
237
|
-
account.models ? `Models: ${account.models.enabled}/${account.models.enabled + account.models.disabled}` : undefined,
|
|
410
|
+
provider === "copilot" && account.models ? `Models: ${account.models.enabled}/${account.models.enabled + account.models.disabled}` : undefined,
|
|
238
411
|
account.orgs?.length ? `Orgs: ${account.orgs.slice(0, 2).join(",")}` : undefined,
|
|
239
|
-
account.modelsError ? `Models error: ${account.modelsError}` : undefined,
|
|
412
|
+
provider === "copilot" && account.modelsError ? `Models error: ${account.modelsError}` : undefined,
|
|
240
413
|
]
|
|
241
414
|
.filter(Boolean)
|
|
242
415
|
.join("\n");
|
|
243
416
|
const subtitle = info;
|
|
244
417
|
while (true) {
|
|
245
|
-
const
|
|
246
|
-
? [{ label: "View models", value: "models", color: "cyan" }]
|
|
247
|
-
: [];
|
|
248
|
-
const result = await select([
|
|
249
|
-
{ label: "Back", value: "back" },
|
|
250
|
-
...modelAction,
|
|
251
|
-
{ label: "Switch to this account", value: "switch", color: "cyan" },
|
|
252
|
-
{ label: "Remove this account", value: "remove", color: "red" },
|
|
253
|
-
], { message: header, subtitle, clearScreen: true, autoSelectSingle: false });
|
|
418
|
+
const result = await select(buildAccountActionItems(account, { provider }), { message: header, subtitle, clearScreen: true, autoSelectSingle: false });
|
|
254
419
|
if (result === "models") {
|
|
255
420
|
await showModels(account);
|
|
256
421
|
continue;
|