@cortexkit/opencode-anthropic-auth 1.15.0 → 1.15.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/index.js +11 -20
- package/dist/prompt-context.d.ts +5 -2
- package/package.json +13 -10
- package/src/tui/entry.mjs +37 -0
- package/src/tui-compiled/rpc/port-file.ts +70 -0
- package/src/tui-compiled/rpc/protocol.ts +34 -0
- package/src/tui-compiled/rpc/rpc-client.ts +62 -0
- package/src/tui-compiled/rpc/rpc-dir.ts +19 -0
- package/src/tui-compiled/sidebar-state.ts +410 -0
- package/src/tui-compiled/tui/command-dialogs.tsx +615 -0
- package/src/tui-compiled/tui-preferences.ts +370 -0
- package/src/tui-compiled/tui.tsx +1102 -0
- package/src/tui.tsx +16 -13
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
import { createTextNode as _$createTextNode } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
2
|
+
import { createComponent as _$createComponent } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
3
|
+
import { insertNode as _$insertNode } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
4
|
+
import { insert as _$insert } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
5
|
+
import { setProp as _$setProp } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
6
|
+
import { createElement as _$createElement } from "opentui:runtime-module:%40opentui%2Fsolid";
|
|
7
|
+
/** @jsxImportSource @opentui/solid */
|
|
8
|
+
|
|
9
|
+
export function buildKillswitchThresholdSeed(config, accountIds) {
|
|
10
|
+
const readT = t => {
|
|
11
|
+
const fh = t?.five_hour ?? t?.['5h'] ?? 5;
|
|
12
|
+
const sd = t?.seven_day ?? t?.['1w'] ?? 10;
|
|
13
|
+
const scoped = t?.scoped ?? 0;
|
|
14
|
+
return {
|
|
15
|
+
fh,
|
|
16
|
+
sd,
|
|
17
|
+
scoped
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
const mainT = readT(config.main);
|
|
21
|
+
const seedParts = [`main:${mainT.fh},${mainT.sd},${mainT.scoped}`];
|
|
22
|
+
for (const id of accountIds) {
|
|
23
|
+
const t = readT(config.accounts?.[id] ?? config.main);
|
|
24
|
+
seedParts.push(`${id}:${t.fh},${t.sd},${t.scoped}`);
|
|
25
|
+
}
|
|
26
|
+
return seedParts.join(' ');
|
|
27
|
+
}
|
|
28
|
+
function showText(api, text) {
|
|
29
|
+
api.ui.dialog.setSize('xlarge');
|
|
30
|
+
api.ui.dialog.replace(() => (() => {
|
|
31
|
+
var _el$ = _$createElement("box"),
|
|
32
|
+
_el$2 = _$createElement("text");
|
|
33
|
+
_$insertNode(_el$, _el$2);
|
|
34
|
+
_$setProp(_el$, "flexDirection", 'column');
|
|
35
|
+
_$setProp(_el$, "padding", 1);
|
|
36
|
+
_$setProp(_el$, "width", '100%');
|
|
37
|
+
_$insert(_el$2, text);
|
|
38
|
+
return _el$;
|
|
39
|
+
})());
|
|
40
|
+
}
|
|
41
|
+
export function openCommandDialog(api, payload, apply) {
|
|
42
|
+
if (payload.command === 'claude-routing') {
|
|
43
|
+
const current = payload.knobs.mode ?? 'main-first';
|
|
44
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
45
|
+
api.ui.dialog.setSize('xlarge');
|
|
46
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
47
|
+
title: "Claude routing",
|
|
48
|
+
current: current,
|
|
49
|
+
options: [{
|
|
50
|
+
title: 'Main first',
|
|
51
|
+
value: 'main-first',
|
|
52
|
+
description: 'Use the main account until exhausted'
|
|
53
|
+
}, {
|
|
54
|
+
title: 'Fallback first',
|
|
55
|
+
value: 'fallback-first',
|
|
56
|
+
description: 'Prefer fallback accounts, preserve main'
|
|
57
|
+
}],
|
|
58
|
+
onSelect: option => {
|
|
59
|
+
void apply('claude-routing', String(option.value)).then(r => {
|
|
60
|
+
api.ui.toast({
|
|
61
|
+
message: r.text
|
|
62
|
+
});
|
|
63
|
+
api.ui.dialog.clear();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (payload.command === 'claude-fast' || payload.command === 'claude-dump') {
|
|
70
|
+
const enabled = payload.knobs.enabled === true;
|
|
71
|
+
const label = payload.command === 'claude-fast' ? 'fast mode' : 'request dump';
|
|
72
|
+
const DialogConfirm = api.ui.DialogConfirm;
|
|
73
|
+
api.ui.dialog.setSize('xlarge');
|
|
74
|
+
api.ui.dialog.replace(() => _$createComponent(DialogConfirm, {
|
|
75
|
+
title: `Claude ${label}`,
|
|
76
|
+
get message() {
|
|
77
|
+
return `${payload.text}\n\n${enabled ? 'Disable' : 'Enable'} ${label}?`;
|
|
78
|
+
},
|
|
79
|
+
onConfirm: () => {
|
|
80
|
+
void apply(payload.command, enabled ? 'off' : 'on').then(r => {
|
|
81
|
+
api.ui.toast({
|
|
82
|
+
message: r.text
|
|
83
|
+
});
|
|
84
|
+
api.ui.dialog.clear();
|
|
85
|
+
});
|
|
86
|
+
},
|
|
87
|
+
onCancel: () => api.ui.dialog.clear()
|
|
88
|
+
}));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (payload.command === 'claude-cache') {
|
|
92
|
+
const enabled = payload.knobs.enabled === true;
|
|
93
|
+
const mode = payload.knobs.mode ?? 'hybrid';
|
|
94
|
+
const currentValue = enabled ? mode : 'off';
|
|
95
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
96
|
+
api.ui.dialog.setSize('xlarge');
|
|
97
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
98
|
+
title: "Claude 1h cache",
|
|
99
|
+
current: currentValue,
|
|
100
|
+
options: [{
|
|
101
|
+
title: 'Off',
|
|
102
|
+
value: 'off',
|
|
103
|
+
description: 'Disable 1h cache'
|
|
104
|
+
}, {
|
|
105
|
+
title: 'Explicit',
|
|
106
|
+
value: 'explicit',
|
|
107
|
+
description: 'Existing OpenCode breakpoints'
|
|
108
|
+
}, {
|
|
109
|
+
title: 'Automatic',
|
|
110
|
+
value: 'automatic',
|
|
111
|
+
description: 'Top-level cache_control only'
|
|
112
|
+
}, {
|
|
113
|
+
title: 'Hybrid',
|
|
114
|
+
value: 'hybrid',
|
|
115
|
+
description: 'system + messages[0] + top-level'
|
|
116
|
+
}],
|
|
117
|
+
onSelect: option => {
|
|
118
|
+
if (option.value === 'off') {
|
|
119
|
+
void apply('claude-cache', 'off').then(r => {
|
|
120
|
+
api.ui.toast({
|
|
121
|
+
message: r.text
|
|
122
|
+
});
|
|
123
|
+
api.ui.dialog.clear();
|
|
124
|
+
});
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
void apply('claude-cache', `mode ${option.value}`).then(() => apply('claude-cache', 'on')).then(r => {
|
|
128
|
+
api.ui.toast({
|
|
129
|
+
message: r.text
|
|
130
|
+
});
|
|
131
|
+
api.ui.dialog.clear();
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (payload.command === 'claude-cachekeep') {
|
|
138
|
+
const window = payload.knobs.window;
|
|
139
|
+
const seed = window ? `${String(window.startHour).padStart(2, '0')}-${String(window.endHour).padStart(2, '0')}` : '';
|
|
140
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
141
|
+
api.ui.dialog.setSize('xlarge');
|
|
142
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
143
|
+
title: "Claude cachekeep window",
|
|
144
|
+
description: () => (() => {
|
|
145
|
+
var _el$3 = _$createElement("text");
|
|
146
|
+
_$insert(_el$3, () => payload.text);
|
|
147
|
+
return _el$3;
|
|
148
|
+
})(),
|
|
149
|
+
placeholder: "HH-HH (e.g. 08-20) or 'off'",
|
|
150
|
+
value: seed,
|
|
151
|
+
onConfirm: value => {
|
|
152
|
+
void apply('claude-cachekeep', value.trim()).then(r => {
|
|
153
|
+
api.ui.toast({
|
|
154
|
+
message: r.text
|
|
155
|
+
});
|
|
156
|
+
api.ui.dialog.clear();
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
onCancel: () => api.ui.dialog.clear()
|
|
160
|
+
}));
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (payload.command === 'claude-killswitch') {
|
|
164
|
+
const config = payload.knobs.config ?? {};
|
|
165
|
+
const accountIds = payload.knobs.accountIds ?? [];
|
|
166
|
+
const enabled = config.enabled === true;
|
|
167
|
+
const seed = buildKillswitchThresholdSeed(config, accountIds);
|
|
168
|
+
const openEdit = () => {
|
|
169
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
170
|
+
api.ui.dialog.setSize('xlarge');
|
|
171
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
172
|
+
title: "Killswitch thresholds",
|
|
173
|
+
description: () => (() => {
|
|
174
|
+
var _el$4 = _$createElement("text");
|
|
175
|
+
_$insert(_el$4, () => payload.text);
|
|
176
|
+
return _el$4;
|
|
177
|
+
})(),
|
|
178
|
+
placeholder: "main:5,10,0 work-alt:5,10,0",
|
|
179
|
+
value: seed,
|
|
180
|
+
onConfirm: value => {
|
|
181
|
+
void apply('claude-killswitch', `set ${value.trim()}`).then(r => {
|
|
182
|
+
api.ui.toast({
|
|
183
|
+
message: r.text
|
|
184
|
+
});
|
|
185
|
+
api.ui.dialog.clear();
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
onCancel: () => api.ui.dialog.clear()
|
|
189
|
+
}));
|
|
190
|
+
};
|
|
191
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
192
|
+
api.ui.dialog.setSize('xlarge');
|
|
193
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
194
|
+
title: "Claude killswitch",
|
|
195
|
+
options: [{
|
|
196
|
+
title: enabled ? 'Disable killswitch' : 'Enable killswitch',
|
|
197
|
+
value: enabled ? 'off' : 'on',
|
|
198
|
+
description: enabled ? 'Stop hard-blocking on low quota' : 'Hard-block requests when quota drops below thresholds'
|
|
199
|
+
}, {
|
|
200
|
+
title: 'Edit thresholds…',
|
|
201
|
+
value: 'edit',
|
|
202
|
+
description: 'Set per-account 5h,1w,scoped cutoffs'
|
|
203
|
+
}],
|
|
204
|
+
onSelect: option => {
|
|
205
|
+
if (option.value === 'edit') {
|
|
206
|
+
openEdit();
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
void apply('claude-killswitch', String(option.value)).then(r => {
|
|
210
|
+
api.ui.toast({
|
|
211
|
+
message: r.text
|
|
212
|
+
});
|
|
213
|
+
api.ui.dialog.clear();
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
}));
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (payload.command === 'claude-account') {
|
|
220
|
+
const accounts = payload.knobs.accounts ?? [];
|
|
221
|
+
const updateAccounts = r => {
|
|
222
|
+
const updated = r.knobs.accounts;
|
|
223
|
+
if (updated && updated.length > 0) {
|
|
224
|
+
accounts.length = 0;
|
|
225
|
+
accounts.push(...updated);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
const buildL1 = () => {
|
|
229
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
230
|
+
const l1Options = [{
|
|
231
|
+
title: 'Add account\u2026',
|
|
232
|
+
value: '__add__',
|
|
233
|
+
description: 'Add an API key or OAuth fallback account'
|
|
234
|
+
}, ...accounts.map(a => {
|
|
235
|
+
const pct = a.quotaPercent != null ? ` ${Math.round(a.quotaPercent)}%` : ' \u2013%';
|
|
236
|
+
const status = !a.enabled ? ' (disabled)' : '';
|
|
237
|
+
return {
|
|
238
|
+
title: `${a.label} [${a.role}]${status}${pct}`,
|
|
239
|
+
value: a.id
|
|
240
|
+
};
|
|
241
|
+
})];
|
|
242
|
+
api.ui.dialog.setSize('xlarge');
|
|
243
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
244
|
+
title: "Claude accounts",
|
|
245
|
+
options: l1Options,
|
|
246
|
+
onSelect: option => {
|
|
247
|
+
if (option.value === '__add__') {
|
|
248
|
+
openAddType();
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const account = accounts.find(a => a.id === option.value);
|
|
252
|
+
if (!account) return;
|
|
253
|
+
if (account.role === 'main') {
|
|
254
|
+
const pct = account.quotaPercent != null ? ` ${Math.round(account.quotaPercent)}%` : ' \u2013%';
|
|
255
|
+
showText(api, `${account.label}\nRole: main (read-only)\nQuota:${pct}`);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
openManage(account, false);
|
|
259
|
+
}
|
|
260
|
+
}));
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// -- Add type selection (OAuth vs API key) ------------------------------
|
|
264
|
+
const openAddType = () => {
|
|
265
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
266
|
+
api.ui.dialog.setSize('xlarge');
|
|
267
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
268
|
+
title: "Add account",
|
|
269
|
+
options: [{
|
|
270
|
+
title: 'OAuth (login)',
|
|
271
|
+
value: 'oauth',
|
|
272
|
+
description: 'Sign in to Claude via browser — works with Pro, Max, and Team plans'
|
|
273
|
+
}, {
|
|
274
|
+
title: 'API key',
|
|
275
|
+
value: 'apikey',
|
|
276
|
+
description: 'Provide an API key for an Anthropic-compatible endpoint'
|
|
277
|
+
}, {
|
|
278
|
+
title: 'Back',
|
|
279
|
+
value: 'back'
|
|
280
|
+
}],
|
|
281
|
+
onSelect: option => {
|
|
282
|
+
if (option.value === 'back') {
|
|
283
|
+
buildL1();
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (option.value === 'apikey') {
|
|
287
|
+
openAddApiKey();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
openAddOAuthStart();
|
|
291
|
+
}
|
|
292
|
+
}));
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// -- Add API key (multi-step: key → baseURL → authHeader → label) ------
|
|
296
|
+
const openAddApiKey = () => {
|
|
297
|
+
const collected = {};
|
|
298
|
+
const openApiKeyPrompt = () => {
|
|
299
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
300
|
+
api.ui.dialog.setSize('xlarge');
|
|
301
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
302
|
+
title: "Add API key account \\u2014 API key",
|
|
303
|
+
description: () => (() => {
|
|
304
|
+
var _el$5 = _$createElement("text");
|
|
305
|
+
_$insertNode(_el$5, _$createTextNode(`Paste your API key (required).`));
|
|
306
|
+
return _el$5;
|
|
307
|
+
})(),
|
|
308
|
+
placeholder: "sk-ant-...",
|
|
309
|
+
value: "",
|
|
310
|
+
onConfirm: value => {
|
|
311
|
+
const trimmed = value.trim();
|
|
312
|
+
if (!trimmed) {
|
|
313
|
+
openAddType();
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
collected.apiKey = trimmed;
|
|
317
|
+
openBaseURLPrompt();
|
|
318
|
+
},
|
|
319
|
+
onCancel: () => openAddType()
|
|
320
|
+
}));
|
|
321
|
+
};
|
|
322
|
+
const openBaseURLPrompt = () => {
|
|
323
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
324
|
+
api.ui.dialog.setSize('xlarge');
|
|
325
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
326
|
+
title: "Add API key account \\u2014 base URL",
|
|
327
|
+
description: () => (() => {
|
|
328
|
+
var _el$7 = _$createElement("text");
|
|
329
|
+
_$insertNode(_el$7, _$createTextNode(`Anthropic-compatible API base URL. Default: https://api.kie.ai/claude`));
|
|
330
|
+
return _el$7;
|
|
331
|
+
})(),
|
|
332
|
+
placeholder: "https://api.kie.ai/claude",
|
|
333
|
+
value: "",
|
|
334
|
+
onConfirm: value => {
|
|
335
|
+
const trimmed = value.trim();
|
|
336
|
+
collected.baseURL = trimmed || 'https://api.kie.ai/claude';
|
|
337
|
+
openAuthHeaderSelect();
|
|
338
|
+
},
|
|
339
|
+
onCancel: () => openApiKeyPrompt()
|
|
340
|
+
}));
|
|
341
|
+
};
|
|
342
|
+
const openAuthHeaderSelect = () => {
|
|
343
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
344
|
+
api.ui.dialog.setSize('xlarge');
|
|
345
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
346
|
+
title: "Add API key account \\u2014 auth header",
|
|
347
|
+
options: [{
|
|
348
|
+
title: 'Authorization: Bearer (default)',
|
|
349
|
+
value: 'authorization-bearer',
|
|
350
|
+
description: 'Standard bearer token authentication'
|
|
351
|
+
}, {
|
|
352
|
+
title: 'X-API-Key',
|
|
353
|
+
value: 'x-api-key',
|
|
354
|
+
description: 'Custom header-based API key'
|
|
355
|
+
}],
|
|
356
|
+
onSelect: option => {
|
|
357
|
+
collected.authHeader = option.value;
|
|
358
|
+
openLabelPrompt();
|
|
359
|
+
}
|
|
360
|
+
}));
|
|
361
|
+
};
|
|
362
|
+
const openLabelPrompt = () => {
|
|
363
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
364
|
+
api.ui.dialog.setSize('xlarge');
|
|
365
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
366
|
+
title: "Add API key account \\u2014 label",
|
|
367
|
+
description: () => (() => {
|
|
368
|
+
var _el$9 = _$createElement("text");
|
|
369
|
+
_$insertNode(_el$9, _$createTextNode(`A short name for this account (optional).`));
|
|
370
|
+
return _el$9;
|
|
371
|
+
})(),
|
|
372
|
+
placeholder: "e.g. Work API",
|
|
373
|
+
value: "",
|
|
374
|
+
onConfirm: value => {
|
|
375
|
+
const trimmed = value.trim();
|
|
376
|
+
collected.label = trimmed || undefined;
|
|
377
|
+
const apiKey = collected.apiKey;
|
|
378
|
+
if (!apiKey) return;
|
|
379
|
+
let args = `add-apikey ${apiKey}`;
|
|
380
|
+
if (collected.baseURL && collected.baseURL !== 'https://api.kie.ai/claude') {
|
|
381
|
+
args += ` --base-url ${collected.baseURL}`;
|
|
382
|
+
}
|
|
383
|
+
if (collected.authHeader && collected.authHeader !== 'authorization-bearer') {
|
|
384
|
+
args += ` --auth-header ${collected.authHeader}`;
|
|
385
|
+
}
|
|
386
|
+
if (collected.label) {
|
|
387
|
+
args += ` --label ${collected.label}`;
|
|
388
|
+
}
|
|
389
|
+
void apply('claude-account', args).then(r => {
|
|
390
|
+
api.ui.toast({
|
|
391
|
+
message: r.text
|
|
392
|
+
});
|
|
393
|
+
updateAccounts(r);
|
|
394
|
+
buildL1();
|
|
395
|
+
});
|
|
396
|
+
},
|
|
397
|
+
onCancel: () => openAuthHeaderSelect()
|
|
398
|
+
}));
|
|
399
|
+
};
|
|
400
|
+
openApiKeyPrompt();
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
// -- Add OAuth (OSC-52 copy + code entry) ------------------------------
|
|
404
|
+
const openAddOAuthStart = () => {
|
|
405
|
+
void apply('claude-account', 'add-oauth-start').then(r => {
|
|
406
|
+
const oauthUrl = r.knobs.oauthUrl;
|
|
407
|
+
updateAccounts(r);
|
|
408
|
+
if (oauthUrl) {
|
|
409
|
+
openOAuthUrlScreen(oauthUrl);
|
|
410
|
+
} else {
|
|
411
|
+
api.ui.toast({
|
|
412
|
+
message: r.text
|
|
413
|
+
});
|
|
414
|
+
buildL1();
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
};
|
|
418
|
+
const openOAuthUrlScreen = oauthUrl => {
|
|
419
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
420
|
+
api.ui.dialog.setSize('xlarge');
|
|
421
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
422
|
+
title: "OAuth sign-in",
|
|
423
|
+
options: [{
|
|
424
|
+
title: 'Copy URL to clipboard',
|
|
425
|
+
value: 'copy',
|
|
426
|
+
description: oauthUrl
|
|
427
|
+
}, {
|
|
428
|
+
title: 'Enter sign-in code',
|
|
429
|
+
value: 'code',
|
|
430
|
+
description: 'Open the URL in your browser, sign in, then paste the callback URL or code'
|
|
431
|
+
}, {
|
|
432
|
+
title: 'Cancel',
|
|
433
|
+
value: 'cancel'
|
|
434
|
+
}],
|
|
435
|
+
onSelect: option => {
|
|
436
|
+
if (option.value === 'cancel') {
|
|
437
|
+
buildL1();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (option.value === 'copy') {
|
|
441
|
+
const ok = api.renderer.copyToClipboardOSC52(oauthUrl);
|
|
442
|
+
if (ok) {
|
|
443
|
+
api.ui.toast({
|
|
444
|
+
message: 'URL copied to clipboard'
|
|
445
|
+
});
|
|
446
|
+
} else {
|
|
447
|
+
api.ui.toast({
|
|
448
|
+
message: 'Copy unavailable \u2014 select the URL text above to copy'
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
openOAuthUrlScreen(oauthUrl);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
openOAuthCodePrompt(oauthUrl);
|
|
455
|
+
}
|
|
456
|
+
}));
|
|
457
|
+
};
|
|
458
|
+
const openOAuthCodePrompt = oauthUrl => {
|
|
459
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
460
|
+
api.ui.dialog.setSize('xlarge');
|
|
461
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
462
|
+
title: "OAuth sign-in \\u2014 enter code",
|
|
463
|
+
description: () => (() => {
|
|
464
|
+
var _el$1 = _$createElement("text");
|
|
465
|
+
_$insertNode(_el$1, _$createTextNode(`After signing in you will be redirected. Paste the full callback URL or authorization code below.`));
|
|
466
|
+
return _el$1;
|
|
467
|
+
})(),
|
|
468
|
+
placeholder: "Paste callback URL or code here",
|
|
469
|
+
value: "",
|
|
470
|
+
onConfirm: value => {
|
|
471
|
+
const trimmed = value.trim();
|
|
472
|
+
if (!trimmed) {
|
|
473
|
+
buildL1();
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
openOAuthLabelPrompt(trimmed, oauthUrl);
|
|
477
|
+
},
|
|
478
|
+
onCancel: () => openOAuthUrlScreen(oauthUrl)
|
|
479
|
+
}));
|
|
480
|
+
};
|
|
481
|
+
const openOAuthLabelPrompt = (code, oauthUrl) => {
|
|
482
|
+
const DialogPrompt = api.ui.DialogPrompt;
|
|
483
|
+
api.ui.dialog.setSize('xlarge');
|
|
484
|
+
api.ui.dialog.replace(() => _$createComponent(DialogPrompt, {
|
|
485
|
+
title: "OAuth sign-in \\u2014 label",
|
|
486
|
+
description: () => (() => {
|
|
487
|
+
var _el$11 = _$createElement("text");
|
|
488
|
+
_$insertNode(_el$11, _$createTextNode(`A short name for this account (optional).`));
|
|
489
|
+
return _el$11;
|
|
490
|
+
})(),
|
|
491
|
+
placeholder: "e.g. work",
|
|
492
|
+
value: "",
|
|
493
|
+
onConfirm: value => {
|
|
494
|
+
const label = value.trim();
|
|
495
|
+
const args = label ? `add-oauth-finish ${code} --label ${label}` : `add-oauth-finish ${code}`;
|
|
496
|
+
void apply('claude-account', args).then(r => {
|
|
497
|
+
api.ui.toast({
|
|
498
|
+
message: r.text
|
|
499
|
+
});
|
|
500
|
+
updateAccounts(r);
|
|
501
|
+
buildL1();
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
onCancel: () => openOAuthCodePrompt(oauthUrl)
|
|
505
|
+
}));
|
|
506
|
+
};
|
|
507
|
+
|
|
508
|
+
// -- Manage existing account -------------------------------------------
|
|
509
|
+
const openManage = (account, isMain) => {
|
|
510
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
511
|
+
const DialogConfirm = api.ui.DialogConfirm;
|
|
512
|
+
api.ui.dialog.setSize('xlarge');
|
|
513
|
+
const options = [];
|
|
514
|
+
if (!isMain) {
|
|
515
|
+
const toggleLabel = account.enabled ? 'Disable' : 'Enable';
|
|
516
|
+
options.push({
|
|
517
|
+
title: toggleLabel,
|
|
518
|
+
value: account.enabled ? 'disable' : 'enable',
|
|
519
|
+
description: account.enabled ? 'Stop using this fallback account' : 'Allow this fallback account to be used'
|
|
520
|
+
});
|
|
521
|
+
options.push({
|
|
522
|
+
title: 'Move up',
|
|
523
|
+
value: 'move-up',
|
|
524
|
+
description: 'Higher priority in fallback order'
|
|
525
|
+
});
|
|
526
|
+
options.push({
|
|
527
|
+
title: 'Move down',
|
|
528
|
+
value: 'move-down',
|
|
529
|
+
description: 'Lower priority in fallback order'
|
|
530
|
+
});
|
|
531
|
+
options.push({
|
|
532
|
+
title: 'Remove\u2026',
|
|
533
|
+
value: 'remove',
|
|
534
|
+
description: 'Delete this account permanently'
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
options.push({
|
|
538
|
+
title: 'Back',
|
|
539
|
+
value: 'back'
|
|
540
|
+
});
|
|
541
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
542
|
+
get title() {
|
|
543
|
+
return `Manage ${account.label}`;
|
|
544
|
+
},
|
|
545
|
+
options: options,
|
|
546
|
+
onSelect: option => {
|
|
547
|
+
if (option.value === 'back') {
|
|
548
|
+
buildL1();
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
if (option.value === 'remove') {
|
|
552
|
+
api.ui.dialog.replace(() => _$createComponent(DialogConfirm, {
|
|
553
|
+
get title() {
|
|
554
|
+
return `Remove ${account.label}?`;
|
|
555
|
+
},
|
|
556
|
+
get message() {
|
|
557
|
+
return `Are you sure you want to remove the fallback account "${account.label}"?`;
|
|
558
|
+
},
|
|
559
|
+
onConfirm: () => {
|
|
560
|
+
void apply('claude-account', `remove ${account.id}`).then(r => {
|
|
561
|
+
api.ui.toast({
|
|
562
|
+
message: r.text
|
|
563
|
+
});
|
|
564
|
+
updateAccounts(r);
|
|
565
|
+
buildL1();
|
|
566
|
+
});
|
|
567
|
+
},
|
|
568
|
+
onCancel: () => openManage(account, isMain)
|
|
569
|
+
}));
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
void apply('claude-account', `${option.value} ${account.id}`).then(r => {
|
|
573
|
+
api.ui.toast({
|
|
574
|
+
message: r.text
|
|
575
|
+
});
|
|
576
|
+
updateAccounts(r);
|
|
577
|
+
const updatedList = r.knobs.accounts;
|
|
578
|
+
const refreshed = (updatedList && updatedList.length > 0 ? updatedList.find(a => a.id === account.id) : undefined) ?? account;
|
|
579
|
+
openManage(refreshed, isMain);
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
}));
|
|
583
|
+
};
|
|
584
|
+
buildL1();
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
if (payload.command === 'claude-logging') {
|
|
588
|
+
const current = payload.knobs.level ?? 'info';
|
|
589
|
+
const levels = ['error', 'warn', 'info', 'debug', 'trace'];
|
|
590
|
+
const DialogSelect = api.ui.DialogSelect;
|
|
591
|
+
api.ui.dialog.setSize('xlarge');
|
|
592
|
+
api.ui.dialog.replace(() => _$createComponent(DialogSelect, {
|
|
593
|
+
title: "Claude log level",
|
|
594
|
+
current: current,
|
|
595
|
+
get options() {
|
|
596
|
+
return levels.map(level => ({
|
|
597
|
+
title: level === current ? `\u2022 ${level}` : level,
|
|
598
|
+
value: level
|
|
599
|
+
}));
|
|
600
|
+
},
|
|
601
|
+
onSelect: option => {
|
|
602
|
+
void apply('claude-logging', String(option.value)).then(r => {
|
|
603
|
+
api.ui.toast({
|
|
604
|
+
message: r.text
|
|
605
|
+
});
|
|
606
|
+
api.ui.dialog.clear();
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
}));
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// fallback for quota (display-only)
|
|
614
|
+
showText(api, payload.text);
|
|
615
|
+
}
|