dsh-plugin-subscriptions 0.5.2 → 0.5.3
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/README.md +36 -1
- package/README.zh.md +36 -1
- package/lib/auth/rpc.d.ts +29 -12
- package/lib/auth/rpc.js +29 -6
- package/lib/auth/store.d.ts +75 -17
- package/lib/auth/store.js +148 -27
- package/lib/client/SubscriptionsSection.d.ts +9 -3
- package/lib/client/SubscriptionsSection.js +93 -65
- package/lib/client/locales.d.ts +18 -10
- package/lib/client/locales.js +18 -10
- package/lib/client.js +250 -127
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +21 -0
- package/lib/index.js +1482 -168
- package/lib/providers/accounts.d.ts +102 -0
- package/lib/providers/accounts.js +123 -0
- package/lib/providers/claude.d.ts +22 -4
- package/lib/providers/claude.js +91 -11
- package/lib/providers/codex.d.ts +24 -3
- package/lib/providers/codex.js +116 -17
- package/lib/providers/common.d.ts +17 -0
- package/lib/providers/common.js +67 -3
- package/lib/providers/copilot.d.ts +22 -3
- package/lib/providers/copilot.js +91 -12
- package/lib/providers/grok.d.ts +24 -4
- package/lib/providers/grok.js +100 -14
- package/lib/providers/pool-family.d.ts +56 -0
- package/lib/providers/pool-family.js +45 -0
- package/lib/providers/pool-health.d.ts +74 -0
- package/lib/providers/pool-health.js +148 -0
- package/lib/providers/pool-usage.d.ts +57 -0
- package/lib/providers/pool-usage.js +130 -0
- package/lib/providers/pool.d.ts +107 -0
- package/lib/providers/pool.js +371 -0
- package/lib/tools/image-generate.d.ts +3 -3
- package/lib/tools/image-generate.js +2 -1
- package/lib/tools/video-generate.d.ts +2 -2
- package/lib/tools/video-generate.js +2 -1
- package/lib/tools/x-search.d.ts +2 -2
- package/lib/tools/x-search.js +2 -1
- package/package.json +1 -1
|
@@ -2,12 +2,18 @@ import type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client';
|
|
|
2
2
|
import type { SubscriptionsKey } from './locales.js';
|
|
3
3
|
/** Subscription provider ids, fixed by the node half's OAuth adapters. */
|
|
4
4
|
export type SubscriptionProvider = 'codex' | 'claude' | 'grok' | 'copilot';
|
|
5
|
+
/** One logged-in account as answered by the `status` endpoint. */
|
|
6
|
+
export interface AccountStatus {
|
|
7
|
+
key: string;
|
|
8
|
+
account?: string;
|
|
9
|
+
expiresAt?: number;
|
|
10
|
+
plan?: string;
|
|
11
|
+
isDefault: boolean;
|
|
12
|
+
}
|
|
5
13
|
/** One provider's login state as answered by the `status` endpoint. */
|
|
6
14
|
export interface ProviderStatus {
|
|
7
|
-
loggedIn: boolean;
|
|
8
15
|
busy: boolean;
|
|
9
|
-
|
|
10
|
-
account?: string;
|
|
16
|
+
accounts: AccountStatus[];
|
|
11
17
|
detail?: string;
|
|
12
18
|
}
|
|
13
19
|
/** One rate-limit window as answered by the `usage` endpoint. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Subscriptions settings section: one card per subscription provider with an
|
|
4
4
|
* OAuth login/logout flow driven by the node half's `/subscriptions-auth` RPC
|
|
@@ -54,6 +54,16 @@ export async function callSubscriptionsAuth(rpc, endpoint, payload) {
|
|
|
54
54
|
function messageOf(error) {
|
|
55
55
|
return error instanceof Error ? error.message : String(error);
|
|
56
56
|
}
|
|
57
|
+
/** Copy a keyed map without the entries whose key is not in `live`. */
|
|
58
|
+
function dropStale(map, live) {
|
|
59
|
+
const stale = Object.keys(map).filter(key => !live.has(key));
|
|
60
|
+
if (stale.length === 0)
|
|
61
|
+
return map;
|
|
62
|
+
const next = { ...map };
|
|
63
|
+
for (const key of stale)
|
|
64
|
+
delete next[key];
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
57
67
|
/**
|
|
58
68
|
* English-dictionary fallback for a missing inject `t` (standalone renders);
|
|
59
69
|
* the slot inject always supplies the locale-bound one.
|
|
@@ -114,6 +124,18 @@ const styles = {
|
|
|
114
124
|
display: 'flex', justifyContent: 'space-between', gap: 8,
|
|
115
125
|
fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)',
|
|
116
126
|
},
|
|
127
|
+
accountRow: {
|
|
128
|
+
display: 'flex', flexDirection: 'column', gap: 6,
|
|
129
|
+
border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8,
|
|
130
|
+
padding: '8px 10px', marginTop: 4,
|
|
131
|
+
},
|
|
132
|
+
accountHeader: { display: 'flex', alignItems: 'center', gap: 8 },
|
|
133
|
+
accountName: { fontSize: 13, lineHeight: '20px', color: 'var(--dsw-alias-label-primary)', userSelect: 'all' },
|
|
134
|
+
starButton: {
|
|
135
|
+
border: 'none', background: 'transparent', padding: 0,
|
|
136
|
+
font: 'inherit', fontSize: 14, lineHeight: '20px', cursor: 'pointer',
|
|
137
|
+
color: 'var(--dsw-alias-state-warn-label)',
|
|
138
|
+
},
|
|
117
139
|
usageTrack: {
|
|
118
140
|
height: 6, borderRadius: 3, overflow: 'hidden',
|
|
119
141
|
background: 'var(--dsw-alias-bg-layer-1)', border: '1px solid var(--dsw-alias-border-l2)',
|
|
@@ -171,7 +193,7 @@ const styles = {
|
|
|
171
193
|
function dotColor(status) {
|
|
172
194
|
if (status?.busy === true)
|
|
173
195
|
return 'var(--dsw-alias-state-warn-label)';
|
|
174
|
-
if (status?.
|
|
196
|
+
if ((status?.accounts.length ?? 0) > 0)
|
|
175
197
|
return 'var(--dsw-alias-state-success-primary)';
|
|
176
198
|
return 'var(--dsw-alias-label-dimmed)';
|
|
177
199
|
}
|
|
@@ -186,20 +208,8 @@ function statusText(t, status) {
|
|
|
186
208
|
return t('checking');
|
|
187
209
|
if (status.busy)
|
|
188
210
|
return t('loginInProgress');
|
|
189
|
-
if (status.
|
|
190
|
-
|
|
191
|
-
if (status.account !== undefined)
|
|
192
|
-
params.account = status.account;
|
|
193
|
-
if (status.expiresAt !== undefined)
|
|
194
|
-
params.date = new Date(status.expiresAt).toLocaleString();
|
|
195
|
-
if (params.account !== undefined && params.date !== undefined)
|
|
196
|
-
return t('loggedInAccountExpires', params);
|
|
197
|
-
if (params.account !== undefined)
|
|
198
|
-
return t('loggedInAccount', params);
|
|
199
|
-
if (params.date !== undefined)
|
|
200
|
-
return t('loggedInExpires', params);
|
|
201
|
-
return t('loggedIn');
|
|
202
|
-
}
|
|
211
|
+
if (status.accounts.length > 0)
|
|
212
|
+
return t('loggedInCount', { count: status.accounts.length });
|
|
203
213
|
return t('notLoggedIn');
|
|
204
214
|
}
|
|
205
215
|
/**
|
|
@@ -256,12 +266,13 @@ export function SubscriptionsSection(props) {
|
|
|
256
266
|
/** Pending device-flow codes (copilot), shown while the attempt polls. */
|
|
257
267
|
const [deviceCodes, setDeviceCodes] = useState({});
|
|
258
268
|
const [copiedCode, setCopiedCode] = useState(undefined);
|
|
269
|
+
/** Usage snapshots keyed `${provider}:${accountKey}` — every account tracks its own windows. */
|
|
259
270
|
const [usages, setUsages] = useState({});
|
|
260
271
|
const [usageErrors, setUsageErrors] = useState({});
|
|
261
272
|
const [usageLoading, setUsageLoading] = useState({});
|
|
262
273
|
const mountedRef = useRef(true);
|
|
263
274
|
const pollersRef = useRef(new Map());
|
|
264
|
-
/**
|
|
275
|
+
/** Accounts with a `usage` call in flight; guards the auto-fetch effect against re-entry. */
|
|
265
276
|
const usageInflightRef = useRef(new Set());
|
|
266
277
|
/** Proxy config as last answered by `proxyGet`/`proxySet`. */
|
|
267
278
|
const [proxy, setProxy] = useState(undefined);
|
|
@@ -315,7 +326,7 @@ export function SubscriptionsSection(props) {
|
|
|
315
326
|
setStatuses(response.providers);
|
|
316
327
|
for (const { id } of PROVIDERS) {
|
|
317
328
|
const status = response.providers[id];
|
|
318
|
-
if (status.
|
|
329
|
+
if (status.accounts.length > 0 || !status.busy) {
|
|
319
330
|
stopPolling(id);
|
|
320
331
|
// The attempt settled (success, timeout, or cancel): drop the code card.
|
|
321
332
|
setDeviceCodes((prev) => {
|
|
@@ -355,64 +366,58 @@ export function SubscriptionsSection(props) {
|
|
|
355
366
|
pollersRef.current.clear();
|
|
356
367
|
};
|
|
357
368
|
}, [refresh, startPolling]);
|
|
358
|
-
const loadUsage = useCallback(async (provider) => {
|
|
359
|
-
|
|
369
|
+
const loadUsage = useCallback(async (provider, account) => {
|
|
370
|
+
const key = `${provider}:${account}`;
|
|
371
|
+
if (rpc === undefined || usageInflightRef.current.has(key))
|
|
360
372
|
return;
|
|
361
|
-
usageInflightRef.current.add(
|
|
362
|
-
setUsageLoading(prev => ({ ...prev, [
|
|
373
|
+
usageInflightRef.current.add(key);
|
|
374
|
+
setUsageLoading(prev => ({ ...prev, [key]: true }));
|
|
363
375
|
try {
|
|
364
|
-
const usage = await callSubscriptionsAuth(rpc, 'usage', { provider });
|
|
376
|
+
const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account });
|
|
365
377
|
if (!mountedRef.current)
|
|
366
378
|
return;
|
|
367
|
-
setUsages(prev => ({ ...prev, [
|
|
379
|
+
setUsages(prev => ({ ...prev, [key]: usage }));
|
|
368
380
|
setUsageErrors((prev) => {
|
|
369
381
|
const next = { ...prev };
|
|
370
|
-
delete next[
|
|
382
|
+
delete next[key];
|
|
371
383
|
return next;
|
|
372
384
|
});
|
|
373
385
|
}
|
|
374
386
|
catch (error) {
|
|
375
387
|
if (mountedRef.current)
|
|
376
|
-
setUsageErrors(prev => ({ ...prev, [
|
|
388
|
+
setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }));
|
|
377
389
|
}
|
|
378
390
|
finally {
|
|
379
|
-
usageInflightRef.current.delete(
|
|
391
|
+
usageInflightRef.current.delete(key);
|
|
380
392
|
if (mountedRef.current)
|
|
381
|
-
setUsageLoading(prev => ({ ...prev, [
|
|
393
|
+
setUsageLoading(prev => ({ ...prev, [key]: false }));
|
|
382
394
|
}
|
|
383
395
|
}, [rpc]);
|
|
384
|
-
// Fetch usage once
|
|
385
|
-
//
|
|
386
|
-
// per-
|
|
396
|
+
// Fetch usage once an account is logged in; drop the snapshots of accounts
|
|
397
|
+
// that vanished so a re-login refetches. A failed lookup does not auto-retry
|
|
398
|
+
// — the per-account Refresh button is the retry path.
|
|
387
399
|
useEffect(() => {
|
|
400
|
+
const live = new Set();
|
|
388
401
|
for (const { id } of PROVIDERS) {
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
void loadUsage(id);
|
|
395
|
-
}
|
|
396
|
-
else if (usages[id] !== undefined || usageErrors[id] !== undefined) {
|
|
397
|
-
setUsages((prev) => {
|
|
398
|
-
const next = { ...prev };
|
|
399
|
-
delete next[id];
|
|
400
|
-
return next;
|
|
401
|
-
});
|
|
402
|
-
setUsageErrors((prev) => {
|
|
403
|
-
const next = { ...prev };
|
|
404
|
-
delete next[id];
|
|
405
|
-
return next;
|
|
406
|
-
});
|
|
402
|
+
for (const account of statuses[id]?.accounts ?? []) {
|
|
403
|
+
const key = `${id}:${account.key}`;
|
|
404
|
+
live.add(key);
|
|
405
|
+
if (usages[key] === undefined && usageErrors[key] === undefined)
|
|
406
|
+
void loadUsage(id, account.key);
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
|
+
setUsages(prev => dropStale(prev, live));
|
|
410
|
+
setUsageErrors(prev => dropStale(prev, live));
|
|
409
411
|
}, [statuses, usages, usageErrors, loadUsage]);
|
|
410
|
-
const login = useCallback(async (provider) => {
|
|
412
|
+
const login = useCallback(async (provider, method) => {
|
|
411
413
|
if (rpc === undefined)
|
|
412
414
|
return;
|
|
413
415
|
setProviderError(provider, undefined);
|
|
414
416
|
try {
|
|
415
|
-
const response = await callSubscriptionsAuth(rpc, 'login', {
|
|
417
|
+
const response = await callSubscriptionsAuth(rpc, 'login', {
|
|
418
|
+
provider,
|
|
419
|
+
...method === undefined ? {} : { method },
|
|
420
|
+
});
|
|
416
421
|
if (typeof response.authorizeUrl === 'string' && response.authorizeUrl === '') {
|
|
417
422
|
// Instant login (e.g. imported from Claude Code credentials)
|
|
418
423
|
await refresh();
|
|
@@ -424,7 +429,10 @@ export function SubscriptionsSection(props) {
|
|
|
424
429
|
if (!mountedRef.current)
|
|
425
430
|
return;
|
|
426
431
|
// Optimistic busy so Cancel and the manual fallback appear before the first poll tick.
|
|
427
|
-
setStatuses(prev => ({
|
|
432
|
+
setStatuses(prev => ({
|
|
433
|
+
...prev,
|
|
434
|
+
[provider]: { accounts: prev[provider]?.accounts ?? [], ...prev[provider], busy: true },
|
|
435
|
+
}));
|
|
428
436
|
if (typeof response.userCode === 'string' && response.userCode.length > 0) {
|
|
429
437
|
// Device flow: show the code card instead of opening the page blind —
|
|
430
438
|
// the user copies the code first, then opens the verification page.
|
|
@@ -468,20 +476,32 @@ export function SubscriptionsSection(props) {
|
|
|
468
476
|
}
|
|
469
477
|
await refresh();
|
|
470
478
|
}, [rpc, manualDrafts, setProviderError, refresh]);
|
|
471
|
-
const logout = useCallback(async (provider, name) => {
|
|
479
|
+
const logout = useCallback(async (provider, account, display, name) => {
|
|
472
480
|
if (rpc === undefined)
|
|
473
481
|
return;
|
|
474
|
-
if (!window.confirm(t('
|
|
482
|
+
if (!window.confirm(t('logoutAccountConfirm', { provider: name, account: display })))
|
|
475
483
|
return;
|
|
476
484
|
setProviderError(provider, undefined);
|
|
477
485
|
try {
|
|
478
|
-
await callSubscriptionsAuth(rpc, 'logout', { provider });
|
|
486
|
+
await callSubscriptionsAuth(rpc, 'logout', { provider, account });
|
|
479
487
|
}
|
|
480
488
|
catch (error) {
|
|
481
489
|
setProviderError(provider, messageOf(error));
|
|
482
490
|
}
|
|
483
491
|
await refresh();
|
|
484
492
|
}, [rpc, t, setProviderError, refresh]);
|
|
493
|
+
const setDefault = useCallback(async (provider, account) => {
|
|
494
|
+
if (rpc === undefined)
|
|
495
|
+
return;
|
|
496
|
+
setProviderError(provider, undefined);
|
|
497
|
+
try {
|
|
498
|
+
await callSubscriptionsAuth(rpc, 'setDefault', { provider, account });
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
setProviderError(provider, messageOf(error));
|
|
502
|
+
}
|
|
503
|
+
await refresh();
|
|
504
|
+
}, [rpc, setProviderError, refresh]);
|
|
485
505
|
const copyDeviceCode = useCallback((provider, userCode) => {
|
|
486
506
|
void navigator.clipboard?.writeText(userCode).then(() => {
|
|
487
507
|
if (!mountedRef.current)
|
|
@@ -593,16 +613,24 @@ export function SubscriptionsSection(props) {
|
|
|
593
613
|
const status = statuses[id];
|
|
594
614
|
const busy = status?.busy === true;
|
|
595
615
|
const deviceCode = deviceCodes[id];
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
616
|
+
const accounts = status?.accounts ?? [];
|
|
617
|
+
return (_jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("span", { style: { ...styles.dot, background: dotColor(status) } }), _jsx("span", { style: styles.name, children: name })] }), _jsx("p", { style: styles.statusLine, children: statusText(t, status) }), status?.detail !== undefined && status.detail !== '' && (_jsx("p", { style: styles.statusLine, children: status.detail })), errors[id] !== undefined && _jsx("p", { style: styles.errorLine, children: errors[id] }), accounts.map((account) => {
|
|
618
|
+
const usageKey = `${id}:${account.key}`;
|
|
619
|
+
const usage = usages[usageKey];
|
|
620
|
+
const usageError = usageErrors[usageKey];
|
|
621
|
+
const display = account.account ?? account.key;
|
|
622
|
+
// Providers without a usage endpoint answer supported:false — no block.
|
|
623
|
+
const showUsage = usage?.supported !== false
|
|
624
|
+
&& (usage !== undefined || usageError !== undefined || usageLoading[usageKey] === true);
|
|
625
|
+
return (_jsxs("div", { style: styles.accountRow, children: [_jsxs("div", { style: styles.accountHeader, children: [_jsx("button", { type: "button", style: styles.starButton, title: account.isDefault ? t('defaultBadge') : t('setDefault'), onClick: () => {
|
|
626
|
+
if (!account.isDefault)
|
|
627
|
+
void setDefault(id, account.key);
|
|
628
|
+
}, children: account.isDefault ? '★' : '☆' }), _jsx("span", { style: styles.accountName, children: display }), account.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: account.plan })), account.expiresAt !== undefined && (_jsx("span", { style: styles.statusLine, children: t('accountExpires', { date: new Date(account.expiresAt).toLocaleString() }) })), _jsx("button", { type: "button", style: { ...styles.button, marginLeft: 'auto', flexShrink: 0 }, onClick: () => { void logout(id, account.key, display, name); }, children: t('logout') })] }), showUsage && (_jsxs("div", { style: styles.usage, children: [_jsxs("div", { style: styles.usageHeader, children: [_jsx("span", { style: styles.usageTitle, children: t('usageTitle') }), usage?.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: t('usagePlan', { plan: usage.plan }) })), _jsx("button", { type: "button", style: { ...styles.usageRefresh, ...usageLoading[usageKey] === true ? { opacity: 0.5, cursor: 'default' } : {} }, disabled: usageLoading[usageKey] === true, onClick: () => { void loadUsage(id, account.key); }, children: t('usageRefresh') })] }), usage === undefined && usageError === undefined && (_jsx("p", { style: styles.statusLine, children: t('usageLoading') })), usageError !== undefined && (_jsx("p", { style: styles.errorLine, children: t('usageError', { message: usageError }) })), usage?.windows !== undefined && usage.windows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageEmpty') })), (usage?.windows ?? []).map((window, index) => {
|
|
629
|
+
const percent = Math.min(100, Math.max(0, window.usedPercent));
|
|
630
|
+
return (_jsxs("div", { style: styles.usageRow, children: [_jsxs("div", { style: styles.usageMeta, children: [_jsx("span", { children: usageWindowLabel(t, window) }), _jsxs("span", { children: [`${String(Math.round(percent))}%`, window.resetsAt !== undefined
|
|
631
|
+
&& ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`] })] }), _jsx("div", { style: styles.usageTrack, children: _jsx("div", { style: { ...styles.usageFill, width: `${String(percent)}%`, background: usageBarColor(percent) } }) })] }, index));
|
|
632
|
+
})] }))] }, account.key));
|
|
633
|
+
}), _jsxs("div", { style: styles.actions, children: [!busy && accounts.length === 0 && (_jsx("button", { type: "button", style: styles.button, onClick: () => { void login(id); }, children: t('login') })), !busy && accounts.length > 0 && id === 'claude' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", style: styles.button, onClick: () => { void login(id, 'oauth'); }, children: t('addAccountOAuth') }), _jsx("button", { type: "button", style: styles.button, onClick: () => { void login(id, 'keychain'); }, children: t('addAccountKeychain') })] })), !busy && accounts.length > 0 && id !== 'claude' && (_jsx("button", { type: "button", style: styles.button, onClick: () => { void login(id); }, children: t('addAccount') })), busy && (_jsx("button", { type: "button", style: styles.button, onClick: () => { void cancel(id); }, children: t('cancel') }))] }), !busy && accounts.length > 0 && (_jsx("p", { style: styles.statusLine, children: t('addAccountHint') })), busy && deviceCode !== undefined && (_jsxs("div", { style: styles.deviceCode, children: [_jsx("span", { style: styles.statusLine, children: t('deviceCodePrompt') }), _jsx("span", { style: styles.deviceCodeText, children: deviceCode.userCode }), _jsxs("div", { style: styles.actions, children: [_jsx("button", { type: "button", style: styles.button, onClick: () => { copyDeviceCode(id, deviceCode.userCode); }, children: copiedCode === id ? t('deviceCodeCopied') : t('deviceCodeCopy') }), _jsx("button", { type: "button", style: styles.button, onClick: () => { window.open(deviceCode.verificationUrl, '_blank', 'noopener'); }, children: t('deviceCodeOpenPage') })] })] })), busy && deviceCode === undefined && (_jsxs("details", { style: styles.manual, children: [_jsx("summary", { children: t('manualSummary') }), _jsxs("div", { style: styles.manualRow, children: [_jsx("input", { style: styles.manualInput, value: manualDrafts[id], placeholder: t('manualPlaceholder'), onChange: event => setManualDrafts(prev => ({ ...prev, [id]: event.target.value })) }), _jsx("button", { type: "button", style: styles.button, onClick: () => { void submitManual(id); }, children: t('submit') })] })] }))] }, id));
|
|
606
634
|
}), proxyOpen && (_jsx("div", { style: styles.modalOverlay, onClick: () => setProxyOpen(false), children: _jsxs("div", { style: styles.modal, onClick: event => event.stopPropagation(), children: [_jsxs("div", { style: styles.modalHeader, children: [_jsx("span", { style: styles.modalTitle, children: t('proxyDialogTitle') }), _jsx("button", { type: "button", style: { ...styles.button, marginLeft: 'auto' }, onClick: () => setProxyOpen(false), children: t('proxyDialogClose') })] }), _jsxs("label", { style: styles.proxyCheck, children: [_jsx("input", { type: "checkbox", checked: proxyEnabled, onChange: event => setProxyEnabled(event.target.checked) }), _jsx("span", { children: t('proxyEnabled') })] }), _jsxs("label", { style: styles.proxyField, children: [_jsx("span", { style: styles.proxyLabel, children: t('proxyUrl') }), _jsx("input", { style: styles.proxyInput, value: proxyUrl, placeholder: t('proxyUrlPlaceholder'), onChange: event => setProxyUrl(event.target.value) }), _jsx("p", { style: styles.proxyHint, children: t('proxyUrlHint') })] }), _jsxs("label", { style: styles.proxyField, children: [_jsx("span", { style: styles.proxyLabel, children: t('proxyUsername') }), _jsx("input", { style: styles.proxyInput, value: proxyUsername, placeholder: t('proxyUsernamePlaceholder'), onChange: event => setProxyUsername(event.target.value) })] }), _jsxs("div", { style: styles.proxyField, children: [_jsx("span", { style: styles.proxyLabel, children: t('proxyPassword') }), _jsx("input", { type: "password", style: styles.proxyInput, value: proxyPassword, placeholder: t('proxyPasswordPlaceholder'), onChange: event => setProxyPassword(event.target.value) }), _jsxs("label", { style: styles.proxyCheck, children: [_jsx("input", { type: "checkbox", checked: proxyClearPassword, onChange: event => setProxyClearPassword(event.target.checked) }), _jsx("span", { children: t('proxyClearPassword') })] })] }), _jsxs("label", { style: styles.proxyField, children: [_jsx("span", { style: styles.proxyLabel, children: t('proxyBypass') }), _jsx("input", { style: styles.proxyInput, value: proxyBypass, placeholder: t('proxyBypassPlaceholder'), onChange: event => setProxyBypass(event.target.value) }), _jsx("p", { style: styles.proxyHint, children: t('proxyBypassHint') })] }), _jsx("p", { style: styles.proxyHint, children: t('proxyNote') }), proxyMessage !== undefined && (_jsx("p", { style: { ...styles.proxyMessage, color: messageColor(proxyMessage.tone) }, children: proxyMessage.text })), proxyTestResult !== undefined && (_jsx("p", { style: {
|
|
607
635
|
...styles.proxyMessage,
|
|
608
636
|
color: proxyTestResult.ok
|
package/lib/client/locales.d.ts
CHANGED
|
@@ -6,15 +6,19 @@ export declare const en: {
|
|
|
6
6
|
unavailable: string;
|
|
7
7
|
checking: string;
|
|
8
8
|
loginInProgress: string;
|
|
9
|
-
loggedIn: string;
|
|
10
|
-
loggedInAccount: string;
|
|
11
|
-
loggedInExpires: string;
|
|
12
|
-
loggedInAccountExpires: string;
|
|
13
9
|
notLoggedIn: string;
|
|
10
|
+
loggedInCount: string;
|
|
11
|
+
accountExpires: string;
|
|
12
|
+
defaultBadge: string;
|
|
13
|
+
setDefault: string;
|
|
14
|
+
addAccount: string;
|
|
15
|
+
addAccountOAuth: string;
|
|
16
|
+
addAccountKeychain: string;
|
|
17
|
+
addAccountHint: string;
|
|
14
18
|
login: string;
|
|
15
19
|
cancel: string;
|
|
16
20
|
logout: string;
|
|
17
|
-
|
|
21
|
+
logoutAccountConfirm: string;
|
|
18
22
|
manualSummary: string;
|
|
19
23
|
manualPlaceholder: string;
|
|
20
24
|
submit: string;
|
|
@@ -91,15 +95,19 @@ export declare const zh: {
|
|
|
91
95
|
unavailable: string;
|
|
92
96
|
checking: string;
|
|
93
97
|
loginInProgress: string;
|
|
94
|
-
loggedIn: string;
|
|
95
|
-
loggedInAccount: string;
|
|
96
|
-
loggedInExpires: string;
|
|
97
|
-
loggedInAccountExpires: string;
|
|
98
98
|
notLoggedIn: string;
|
|
99
|
+
loggedInCount: string;
|
|
100
|
+
accountExpires: string;
|
|
101
|
+
defaultBadge: string;
|
|
102
|
+
setDefault: string;
|
|
103
|
+
addAccount: string;
|
|
104
|
+
addAccountOAuth: string;
|
|
105
|
+
addAccountKeychain: string;
|
|
106
|
+
addAccountHint: string;
|
|
99
107
|
login: string;
|
|
100
108
|
cancel: string;
|
|
101
109
|
logout: string;
|
|
102
|
-
|
|
110
|
+
logoutAccountConfirm: string;
|
|
103
111
|
manualSummary: string;
|
|
104
112
|
manualPlaceholder: string;
|
|
105
113
|
submit: string;
|
package/lib/client/locales.js
CHANGED
|
@@ -6,15 +6,19 @@ export const en = {
|
|
|
6
6
|
unavailable: 'Connection unavailable; subscription status cannot be loaded.',
|
|
7
7
|
checking: 'Checking…',
|
|
8
8
|
loginInProgress: 'Login in progress…',
|
|
9
|
-
loggedIn: 'Logged in',
|
|
10
|
-
loggedInAccount: 'Logged in as {account}',
|
|
11
|
-
loggedInExpires: 'Logged in · expires {date}',
|
|
12
|
-
loggedInAccountExpires: 'Logged in as {account} · expires {date}',
|
|
13
9
|
notLoggedIn: 'Not logged in',
|
|
10
|
+
loggedInCount: '{count} account(s) connected',
|
|
11
|
+
accountExpires: 'expires {date}',
|
|
12
|
+
defaultBadge: 'Default',
|
|
13
|
+
setDefault: 'Set as default',
|
|
14
|
+
addAccount: 'Add account',
|
|
15
|
+
addAccountOAuth: 'Browser authorization',
|
|
16
|
+
addAccountKeychain: 'Import Claude Code',
|
|
17
|
+
addAccountHint: 'Browser authorization signs in whichever account the browser currently uses — switch accounts there first (or use an incognito window with the manual code below) to add a different one.',
|
|
14
18
|
login: 'Log in',
|
|
15
19
|
cancel: 'Cancel',
|
|
16
20
|
logout: 'Log out',
|
|
17
|
-
|
|
21
|
+
logoutAccountConfirm: 'Log out {account} of {provider}?',
|
|
18
22
|
manualSummary: 'Browser flow not working? Paste the callback URL or code',
|
|
19
23
|
manualPlaceholder: 'Paste the callback URL or code',
|
|
20
24
|
submit: 'Submit',
|
|
@@ -91,15 +95,19 @@ export const zh = {
|
|
|
91
95
|
unavailable: '连接不可用,无法加载订阅状态。',
|
|
92
96
|
checking: '查询中…',
|
|
93
97
|
loginInProgress: '登录中…',
|
|
94
|
-
loggedIn: '已登录',
|
|
95
|
-
loggedInAccount: '已登录:{account}',
|
|
96
|
-
loggedInExpires: '已登录 · 过期时间 {date}',
|
|
97
|
-
loggedInAccountExpires: '已登录:{account} · 过期时间 {date}',
|
|
98
98
|
notLoggedIn: '未登录',
|
|
99
|
+
loggedInCount: '已连接 {count} 个账号',
|
|
100
|
+
accountExpires: '过期时间 {date}',
|
|
101
|
+
defaultBadge: '默认',
|
|
102
|
+
setDefault: '设为默认',
|
|
103
|
+
addAccount: '添加账号',
|
|
104
|
+
addAccountOAuth: '浏览器授权',
|
|
105
|
+
addAccountKeychain: '导入 Claude Code',
|
|
106
|
+
addAccountHint: '浏览器授权以浏览器当前登录的账号为准;要添加不同账号,请先在浏览器里切换账号,或用无痕窗口走下方手动授权码。',
|
|
99
107
|
login: '登录',
|
|
100
108
|
cancel: '取消',
|
|
101
109
|
logout: '退出登录',
|
|
102
|
-
|
|
110
|
+
logoutAccountConfirm: '确定退出 {provider} 的账号 {account} 吗?',
|
|
103
111
|
manualSummary: '浏览器流程无法完成?粘贴回调 URL 或授权码',
|
|
104
112
|
manualPlaceholder: '粘贴回调 URL 或授权码',
|
|
105
113
|
submit: '提交',
|