@goodandready/dsh-subscriptions 0.7.35 → 0.7.36
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/lib/client.js +89 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -313,6 +313,13 @@ window.__ModuleLoader__.load({
|
|
|
313
313
|
"save": "Save",
|
|
314
314
|
"saved": "Saved",
|
|
315
315
|
"cancel": "Cancel",
|
|
316
|
+
"checkAllAccounts": "⚡ Check all",
|
|
317
|
+
"refreshAllQuotas": "🔄 Refresh quotas",
|
|
318
|
+
"importAllCli": "📥 Import all CLI",
|
|
319
|
+
"batchProgress": "{done}/{total} done",
|
|
320
|
+
"moveUp": "Move up",
|
|
321
|
+
"moveDown": "Move down",
|
|
322
|
+
"copyRef": "Copy account ref",
|
|
316
323
|
"unsavedChanges": "Unsaved changes",
|
|
317
324
|
"accountLabel": "Account",
|
|
318
325
|
"usageRemaining": "Remaining quota",
|
|
@@ -712,6 +719,13 @@ window.__ModuleLoader__.load({
|
|
|
712
719
|
"save": "保存",
|
|
713
720
|
"saved": "已保存",
|
|
714
721
|
"cancel": "取消",
|
|
722
|
+
"checkAllAccounts": "⚡ 全部检查",
|
|
723
|
+
"refreshAllQuotas": "🔄 刷新配额",
|
|
724
|
+
"importAllCli": "📥 导入全部 CLI",
|
|
725
|
+
"batchProgress": "已完成 {done}/{total}",
|
|
726
|
+
"moveUp": "上移",
|
|
727
|
+
"moveDown": "下移",
|
|
728
|
+
"copyRef": "复制账户引用",
|
|
715
729
|
"unsavedChanges": "有未保存的更改",
|
|
716
730
|
"accountLabel": "账户",
|
|
717
731
|
"usageRemaining": "剩余配额",
|
|
@@ -1443,6 +1457,8 @@ window.__ModuleLoader__.load({
|
|
|
1443
1457
|
}
|
|
1444
1458
|
}
|
|
1445
1459
|
const [checking, setChecking] = React.useState({})
|
|
1460
|
+
const [batch, setBatch] = React.useState(null)
|
|
1461
|
+
const batchCancelRef = React.useRef(false)
|
|
1446
1462
|
const [saved, setSaved] = React.useState(false)
|
|
1447
1463
|
const [savedSnapshot, setSavedSnapshot] = React.useState(null)
|
|
1448
1464
|
const [tokenDraft, setTokenDraft] = React.useState({})
|
|
@@ -1555,6 +1571,21 @@ window.__ModuleLoader__.load({
|
|
|
1555
1571
|
const updateSlot = (provider, index, patch) => setSlots((prev) => prev.map((s) => (
|
|
1556
1572
|
s && s.provider === provider && Number(s.index) === Number(index) ? Object.assign({}, s, patch) : s
|
|
1557
1573
|
)))
|
|
1574
|
+
const moveSlot = (provider, index, delta) => setSlots((prev) => {
|
|
1575
|
+
const positions = prev
|
|
1576
|
+
.map((slot, position) => ({ slot, position }))
|
|
1577
|
+
.filter((row) => row.slot && row.slot.provider === provider)
|
|
1578
|
+
const from = positions.findIndex((row) => Number(row.slot.index) === Number(index))
|
|
1579
|
+
const to = from + delta
|
|
1580
|
+
if (from < 0 || to < 0 || to >= positions.length) return prev
|
|
1581
|
+
const next = prev.slice()
|
|
1582
|
+
const a = positions[from].position
|
|
1583
|
+
const b = positions[to].position
|
|
1584
|
+
const tmp = next[a]
|
|
1585
|
+
next[a] = next[b]
|
|
1586
|
+
next[b] = tmp
|
|
1587
|
+
return next
|
|
1588
|
+
})
|
|
1558
1589
|
const accountOf = (provider, index) => accounts.find((a) => a.provider === provider && a.index === index) || {}
|
|
1559
1590
|
|
|
1560
1591
|
const save = async () => {
|
|
@@ -1773,6 +1804,34 @@ window.__ModuleLoader__.load({
|
|
|
1773
1804
|
later(() => setInfo(''), 3000)
|
|
1774
1805
|
}
|
|
1775
1806
|
|
|
1807
|
+
const runBatch = async (kind, provider) => {
|
|
1808
|
+
if (batch) return
|
|
1809
|
+
const rows = slots.filter((slot) => slot && slot.provider === provider)
|
|
1810
|
+
if (!rows.length) return
|
|
1811
|
+
batchCancelRef.current = false
|
|
1812
|
+
setBatch({ kind, provider, done: 0, total: rows.length })
|
|
1813
|
+
const queue = rows.slice()
|
|
1814
|
+
const worker = async () => {
|
|
1815
|
+
while (queue.length && !batchCancelRef.current) {
|
|
1816
|
+
const slot = queue.shift()
|
|
1817
|
+
try {
|
|
1818
|
+
if (kind === 'import') await importLocalCli(slot.provider, slot.index)
|
|
1819
|
+
else await doCheck(slot.provider, slot.index)
|
|
1820
|
+
} catch (e) {
|
|
1821
|
+
setErr(cleanErrorMessage(e.message || e))
|
|
1822
|
+
} finally {
|
|
1823
|
+
setBatch((b) => b ? Object.assign({}, b, { done: b.done + 1 }) : b)
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
await Promise.all([worker(), worker()])
|
|
1828
|
+
setBatch(null)
|
|
1829
|
+
}
|
|
1830
|
+
const cancelBatch = () => {
|
|
1831
|
+
batchCancelRef.current = true
|
|
1832
|
+
setBatch((b) => b ? Object.assign({}, b, { cancelled: true }) : b)
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1776
1835
|
const importToken = async (provider, index) => {
|
|
1777
1836
|
setErr('')
|
|
1778
1837
|
const tok = (tokenDraft[provider + ':' + index] || '').trim()
|
|
@@ -2860,10 +2919,22 @@ h('div', { className: 'dsub-row' },
|
|
|
2860
2919
|
.map((slot, i) => ({ slot: slot, i: i }))
|
|
2861
2920
|
.filter((row) => row.slot.provider === prov.id)
|
|
2862
2921
|
return h('div', { className: 'dsub-block', key: prov.id },
|
|
2863
|
-
h('div', { className: 'dsub-h'
|
|
2922
|
+
h('div', { className: 'dsub-h', style: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 6, flexWrap: 'wrap' } },
|
|
2923
|
+
h('span', null, prov.name),
|
|
2924
|
+
h('div', { className: 'dsub-row', style: { marginTop: 0, gap: 4, flexWrap: 'wrap' } },
|
|
2925
|
+
h('button', { type: 'button', className: 'dsub-mini', disabled: Boolean(batch), onClick: () => runBatch('check', prov.id).catch((e) => setErr(cleanErrorMessage(e.message || e))) }, t('checkAllAccounts')),
|
|
2926
|
+
h('button', { type: 'button', className: 'dsub-mini', disabled: Boolean(batch), onClick: () => runBatch('check', prov.id).catch((e) => setErr(cleanErrorMessage(e.message || e))) }, t('refreshAllQuotas')),
|
|
2927
|
+
h('button', { type: 'button', className: 'dsub-mini', disabled: Boolean(batch), onClick: () => runBatch('import', prov.id).catch((e) => setErr(cleanErrorMessage(e.message || e))) }, t('importAllCli')),
|
|
2928
|
+
batch && batch.provider === prov.id ? h(React.Fragment, null,
|
|
2929
|
+
h('span', { className: 'dsub-sub' }, t('batchProgress').replace('{done}', String(batch.done)).replace('{total}', String(batch.total))),
|
|
2930
|
+
h('button', { type: 'button', className: 'dsub-mini', onClick: cancelBatch }, t('cancel'))
|
|
2931
|
+
) : null,
|
|
2932
|
+
),
|
|
2933
|
+
),
|
|
2864
2934
|
rows.map((row) => {
|
|
2865
2935
|
const account = accountOf(row.slot.provider, row.slot.index)
|
|
2866
2936
|
const key = row.slot.provider + ':' + row.slot.index
|
|
2937
|
+
const rowPosition = rows.findIndex((candidate) => candidate.i === row.i)
|
|
2867
2938
|
const on = !!account.configured
|
|
2868
2939
|
const poolEnabled = row.slot.poolEnabled !== false
|
|
2869
2940
|
const poolModels = Array.isArray(row.slot.poolModels) ? row.slot.poolModels : null
|
|
@@ -2914,6 +2985,9 @@ h('div', { className: 'dsub-row' },
|
|
|
2914
2985
|
},
|
|
2915
2986
|
}),
|
|
2916
2987
|
h('span', { className: 'dsub-badge' + (account.isRevoked ? ' dsub-badge-bad' : (account.validationUrl ? ' dsub-badge-warn' : (on ? ' dsub-badge-on' : ''))) }, badgeFor(account, t)),
|
|
2988
|
+
account.capabilities && account.capabilities.vision ? h('span', { className: 'dsub-model-tag', title: 'Vision' }, '👁') : null,
|
|
2989
|
+
account.capabilities && account.capabilities.tools ? h('span', { className: 'dsub-model-tag', title: 'Tools' }, '🔧') : null,
|
|
2990
|
+
account.capabilities && account.capabilities.thinking ? h('span', { className: 'dsub-model-tag', title: 'Thinking' }, '🧠') : null,
|
|
2917
2991
|
normalizePlanBadge(row.slot.provider, account.plan || account.paidTierName || (account.quota && account.quota.plan)),
|
|
2918
2992
|
h('button', {
|
|
2919
2993
|
type: 'button', className: 'dsub-mini',
|
|
@@ -2979,6 +3053,20 @@ h('div', { className: 'dsub-row' },
|
|
|
2979
3053
|
type: 'button', className: 'dsub-mini', title: t('quarantineParkTitle'),
|
|
2980
3054
|
onClick: () => doParkQuarantine(row.slot.provider, row.slot.index, 3600000),
|
|
2981
3055
|
}, ('⏸ ' + t('quarantinePark'))) : null)),
|
|
3056
|
+
h('button', {
|
|
3057
|
+
type: 'button', className: 'dsub-mini', title: t('moveUp'),
|
|
3058
|
+
disabled: rowPosition <= 0,
|
|
3059
|
+
onClick: () => moveSlot(row.slot.provider, row.slot.index, -1),
|
|
3060
|
+
}, '↑'),
|
|
3061
|
+
h('button', {
|
|
3062
|
+
type: 'button', className: 'dsub-mini', title: t('moveDown'),
|
|
3063
|
+
disabled: rowPosition < 0 || rowPosition >= rows.length - 1,
|
|
3064
|
+
onClick: () => moveSlot(row.slot.provider, row.slot.index, 1),
|
|
3065
|
+
}, '↓'),
|
|
3066
|
+
h('button', {
|
|
3067
|
+
type: 'button', className: 'dsub-mini', title: t('copyRef'),
|
|
3068
|
+
onClick: () => copyText(row.slot.ref || key),
|
|
3069
|
+
}, '📋'),
|
|
2982
3070
|
h('button', {
|
|
2983
3071
|
type: 'button', className: 'dsub-mini', title: t('removeSlot'),
|
|
2984
3072
|
onClick: () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-subscriptions",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.36",
|
|
4
4
|
"description": "Use ChatGPT Codex, Claude, Grok, Antigravity, Kimi, GLM, Cursor, Kiro, Copilot, Qwen, ERNIE, Spark, JetBrains, Perplexity, Replit, and Cody subscriptions as DeepSeek Harness LLM providers via OAuth.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|