coding-tool-x 3.6.10 → 3.6.11
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/web/assets/{Analytics-vN7CJLtB.js → Analytics-BuBlsbcI.js} +1 -1
- package/dist/web/assets/{ConfigTemplates-D8w_9p6Z.js → ConfigTemplates-DQczxuOX.js} +1 -1
- package/dist/web/assets/Home-BvAzzWnB.js +1 -0
- package/dist/web/assets/Home-CIua-b-o.css +1 -0
- package/dist/web/assets/{PluginManager-vFp_miHj.js → PluginManager-C8gAlaps.js} +1 -1
- package/dist/web/assets/{ProjectList-DDfNp6CO.js → ProjectList-nqgi6_cR.js} +1 -1
- package/dist/web/assets/{SessionList-Cit8Ylm_.js → SessionList-D8AxMYy6.js} +1 -1
- package/dist/web/assets/{SkillManager-Cp0EigHc.js → SkillManager-BDbNbNkK.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-DPTYHnp4.js → WorkspaceManager-DGGaGW2c.js} +1 -1
- package/dist/web/assets/index-Dsh4Q5Cg.css +1 -0
- package/dist/web/assets/index-y-eEayxR.js +2 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/src/server/api/config-export.js +12 -2
- package/src/server/services/channel-balance.js +0 -147
- package/src/server/services/config-export-service.js +692 -4
- package/src/server/services/plugins-service.js +1 -17
- package/dist/web/assets/Home-BdyDRjGR.js +0 -1
- package/dist/web/assets/Home-BspgEJBb.css +0 -1
- package/dist/web/assets/index-CfBxeWy0.js +0 -2
- package/dist/web/assets/index-Dl2Bz258.css +0 -1
package/dist/web/index.html
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>coding-tool-x · AI 编程工作台</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-y-eEayxR.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/markdown-BNJfEgCA.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-B5RqjEjQ.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/naive-ui-kcWDeJwl.js">
|
|
12
12
|
<link rel="modulepreload" crossorigin href="/assets/icons-QFXzEgqM.js">
|
|
13
13
|
<link rel="modulepreload" crossorigin href="/assets/vendors-DQA4Hw9v.js">
|
|
14
14
|
<link rel="stylesheet" crossorigin href="/assets/markdown-BfC0goYb.css">
|
|
15
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
15
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dsh4Q5Cg.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body>
|
|
18
18
|
<div id="app"></div>
|
package/package.json
CHANGED
|
@@ -31,6 +31,15 @@ function resolveChannelsByType(exportData) {
|
|
|
31
31
|
|
|
32
32
|
function buildPreviewSummary(data) {
|
|
33
33
|
const channelsByType = resolveChannelsByType(data);
|
|
34
|
+
const pluginsByPlatform = data?.data?.pluginsByPlatform && typeof data.data.pluginsByPlatform === 'object'
|
|
35
|
+
? data.data.pluginsByPlatform
|
|
36
|
+
: {};
|
|
37
|
+
const platformPlugins = Object.values(pluginsByPlatform).flatMap((snapshot) => (
|
|
38
|
+
Array.isArray(snapshot?.plugins) ? snapshot.plugins : []
|
|
39
|
+
));
|
|
40
|
+
const plugins = platformPlugins.length > 0
|
|
41
|
+
? platformPlugins
|
|
42
|
+
: (Array.isArray(data.data.plugins) ? data.data.plugins : []);
|
|
34
43
|
const allChannels = [
|
|
35
44
|
...channelsByType.claude.map(c => ({ ...c, type: c.type || 'claude' })),
|
|
36
45
|
...channelsByType.codex.map(c => ({ ...c, type: c.type || 'codex' })),
|
|
@@ -44,7 +53,7 @@ function buildPreviewSummary(data) {
|
|
|
44
53
|
counts: {
|
|
45
54
|
configTemplates: (data.data.configTemplates || []).length,
|
|
46
55
|
channels: allChannels.length,
|
|
47
|
-
plugins:
|
|
56
|
+
plugins: plugins.length
|
|
48
57
|
},
|
|
49
58
|
items: {
|
|
50
59
|
configTemplates: (data.data.configTemplates || []).map(t => ({
|
|
@@ -57,9 +66,10 @@ function buildPreviewSummary(data) {
|
|
|
57
66
|
name: c.name,
|
|
58
67
|
type: c.type
|
|
59
68
|
})),
|
|
60
|
-
plugins:
|
|
69
|
+
plugins: plugins.map(p => ({
|
|
61
70
|
name: p.name,
|
|
62
71
|
type: p.type,
|
|
72
|
+
platform: p.platform,
|
|
63
73
|
version: p.version
|
|
64
74
|
}))
|
|
65
75
|
}
|
|
@@ -12,7 +12,6 @@ const REQUEST_TIMEOUT_MS = 8000;
|
|
|
12
12
|
const MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
13
13
|
const QUOTA_UNIT = 500000;
|
|
14
14
|
const VELOERA_QUOTA_UNIT = 1000000;
|
|
15
|
-
const NEWCLI_QUOTA_UNIT = 1000000;
|
|
16
15
|
const VALID_SOURCES = new Set(['claude', 'codex', 'gemini', 'opencode']);
|
|
17
16
|
const GATEWAY_PATH_SEGMENTS = new Set(['openai', 'anthropic', 'claude', 'gemini', 'codex']);
|
|
18
17
|
const HUB_PLATFORMS = new Set(['new-api', 'one-api', 'one-hub', 'done-hub', 'veloera', 'anyrouter', 'aihubmix']);
|
|
@@ -416,7 +415,6 @@ async function tryRequestJson(url, options) {
|
|
|
416
415
|
function detectPlatformByUrlHint(...values) {
|
|
417
416
|
const value = values.map(item => String(item || '')).join(' ').toLowerCase();
|
|
418
417
|
if (value.includes('88code') || value.includes('88-code') || value.includes('rainapp.top')) return '88code';
|
|
419
|
-
if (value.includes('code.newcli.com') || value.includes('newcli') || value.includes('new-cli')) return 'newcli';
|
|
420
418
|
if (value.includes('openrouter.ai') || value.includes('openrouter')) return 'openrouter';
|
|
421
419
|
if (value.includes('aihubmix')) return 'aihubmix';
|
|
422
420
|
if (value.includes('dashscope') || value.includes('dashscope.aliyuncs.com') || value.includes('compatible-mode')) return 'dashscope';
|
|
@@ -602,77 +600,6 @@ function buildSiliconFlowUserInfoSnapshot(payload) {
|
|
|
602
600
|
});
|
|
603
601
|
}
|
|
604
602
|
|
|
605
|
-
function normalizeNewCliQuotaUnit(value) {
|
|
606
|
-
return normalizeQuotaUnit(value, NEWCLI_QUOTA_UNIT);
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function extractNewCliSubscriptionItems(payload) {
|
|
610
|
-
if (!payload || typeof payload !== 'object') return [];
|
|
611
|
-
const data = payload.data && typeof payload.data === 'object' ? payload.data : payload;
|
|
612
|
-
const subscription = data.subscription && typeof data.subscription === 'object' ? data.subscription : data;
|
|
613
|
-
const candidates = [
|
|
614
|
-
subscription.active,
|
|
615
|
-
subscription.subscriptions,
|
|
616
|
-
subscription.items,
|
|
617
|
-
data.subscriptions,
|
|
618
|
-
data.items,
|
|
619
|
-
Array.isArray(subscription) ? subscription : null,
|
|
620
|
-
Array.isArray(data) ? data : null
|
|
621
|
-
];
|
|
622
|
-
for (const candidate of candidates) {
|
|
623
|
-
if (Array.isArray(candidate)) return candidate;
|
|
624
|
-
}
|
|
625
|
-
return [];
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
function shouldUseNewCliSubscription(item = {}) {
|
|
629
|
-
if (!item || typeof item !== 'object') return false;
|
|
630
|
-
if (item.isActive === false) return false;
|
|
631
|
-
const status = String(item.status || item.subscriptionStatus || '').trim().toUpperCase();
|
|
632
|
-
return !status || status === 'ACTIVE' || status === '活跃中';
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function buildNewCliDashboardSnapshot(payload) {
|
|
636
|
-
const items = extractNewCliSubscriptionItems(payload).filter(shouldUseNewCliSubscription);
|
|
637
|
-
if (!items.length) return makeHiddenSnapshot('newcli');
|
|
638
|
-
|
|
639
|
-
const data = payload?.data && typeof payload.data === 'object' ? payload.data : payload;
|
|
640
|
-
const unit = normalizeNewCliQuotaUnit(data?.quotaUnit || data?.quota_unit || data?.quota_per_unit || data?.quotaPerUnit);
|
|
641
|
-
let remainingRaw = 0;
|
|
642
|
-
let usedRaw = 0;
|
|
643
|
-
let totalRaw = 0;
|
|
644
|
-
let hasRemaining = false;
|
|
645
|
-
let hasTotal = false;
|
|
646
|
-
|
|
647
|
-
for (const item of items) {
|
|
648
|
-
const plan = item.plan && typeof item.plan === 'object' ? item.plan : {};
|
|
649
|
-
const remaining = readMoneyField(item, 'quotaRemaining', 'quota_remaining', 'remainingQuota', 'remaining_quota');
|
|
650
|
-
const used = readMoneyField(item, 'quotaUsed', 'quota_used', 'usedQuota', 'used_quota') || 0;
|
|
651
|
-
const limit = readMoneyField(item, 'quotaLimit', 'quota_limit')
|
|
652
|
-
?? readMoneyField(plan, 'quotaLimit', 'quota_limit');
|
|
653
|
-
|
|
654
|
-
if (remaining != null) {
|
|
655
|
-
hasRemaining = true;
|
|
656
|
-
remainingRaw += Math.max(0, remaining);
|
|
657
|
-
usedRaw += Math.max(0, used);
|
|
658
|
-
if (limit != null) {
|
|
659
|
-
hasTotal = true;
|
|
660
|
-
totalRaw += Math.max(0, limit);
|
|
661
|
-
} else {
|
|
662
|
-
totalRaw += Math.max(0, remaining + used);
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
if (!hasRemaining) return makeHiddenSnapshot('newcli');
|
|
668
|
-
|
|
669
|
-
return makeVisibleSnapshot('newcli', {
|
|
670
|
-
remaining: remainingRaw / unit,
|
|
671
|
-
used: usedRaw / unit,
|
|
672
|
-
total: (hasTotal || usedRaw > 0) ? totalRaw / unit : undefined
|
|
673
|
-
});
|
|
674
|
-
}
|
|
675
|
-
|
|
676
603
|
function extractQuotaUnitFromStatus(payload) {
|
|
677
604
|
if (!payload || typeof payload !== 'object') return null;
|
|
678
605
|
const data = payload.data && typeof payload.data === 'object' ? payload.data : payload;
|
|
@@ -864,41 +791,6 @@ function buildSiliconFlowApiBaseCandidates(baseUrl, channel = {}) {
|
|
|
864
791
|
return candidates;
|
|
865
792
|
}
|
|
866
793
|
|
|
867
|
-
function buildNewCliWebBaseCandidates(baseUrl, channel = {}) {
|
|
868
|
-
const candidates = [];
|
|
869
|
-
const inputs = [
|
|
870
|
-
channel.balanceBaseUrl,
|
|
871
|
-
channel.websiteUrl,
|
|
872
|
-
channel.baseUrl,
|
|
873
|
-
baseUrl
|
|
874
|
-
].filter(Boolean);
|
|
875
|
-
|
|
876
|
-
for (const input of inputs) {
|
|
877
|
-
try {
|
|
878
|
-
const parsed = new URL(input);
|
|
879
|
-
addUnique(candidates, parsed.origin);
|
|
880
|
-
} catch {}
|
|
881
|
-
}
|
|
882
|
-
return candidates;
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
function buildNewCliAuthHeaderCandidates(token) {
|
|
886
|
-
const raw = stripBearer(token).replace(/^cookie:\s*/i, '').trim();
|
|
887
|
-
if (!raw) return [];
|
|
888
|
-
if (raw.includes('=')) {
|
|
889
|
-
return [{
|
|
890
|
-
Accept: 'application/json',
|
|
891
|
-
Cookie: raw
|
|
892
|
-
}];
|
|
893
|
-
}
|
|
894
|
-
return [
|
|
895
|
-
buildAuthHeaders(raw),
|
|
896
|
-
{ Accept: 'application/json', Cookie: `auth_token=${raw}` },
|
|
897
|
-
{ Accept: 'application/json', Cookie: `session=${raw}` },
|
|
898
|
-
{ Accept: 'application/json', Cookie: `__Secure-authjs.session-token=${raw}` }
|
|
899
|
-
];
|
|
900
|
-
}
|
|
901
|
-
|
|
902
794
|
function hasGatewayPathSegment(value) {
|
|
903
795
|
try {
|
|
904
796
|
const parsed = new URL(normalizeBaseUrl(value));
|
|
@@ -1155,27 +1047,12 @@ function buildBalanceProbeStrategies(baseUrl, channel = {}, token = '') {
|
|
|
1155
1047
|
add({ type: 'siliconflow-user-info', baseUrl, apiBase });
|
|
1156
1048
|
}
|
|
1157
1049
|
};
|
|
1158
|
-
const addNewCliStrategies = () => {
|
|
1159
|
-
for (const webBase of buildNewCliWebBaseCandidates(baseUrl, channel)) {
|
|
1160
|
-
add({
|
|
1161
|
-
type: 'newcli-dashboard',
|
|
1162
|
-
baseUrl,
|
|
1163
|
-
webBase,
|
|
1164
|
-
requiresDedicatedToken: !hasDedicatedBalanceToken(channel)
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
};
|
|
1168
1050
|
|
|
1169
1051
|
if (UNSUPPORTED_BALANCE_PLATFORMS.has(hintedPlatform)) {
|
|
1170
1052
|
add({ type: 'unsupported-balance', platform: hintedPlatform, baseUrl });
|
|
1171
1053
|
return strategies;
|
|
1172
1054
|
}
|
|
1173
1055
|
|
|
1174
|
-
if (hintedPlatform === 'newcli') {
|
|
1175
|
-
addNewCliStrategies();
|
|
1176
|
-
return strategies;
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
1056
|
if (hintedPlatform === 'siliconflow') {
|
|
1180
1057
|
addSiliconFlowStrategies();
|
|
1181
1058
|
return strategies;
|
|
@@ -1347,21 +1224,6 @@ async function runSiliconFlowUserInfoStrategy(strategy, token) {
|
|
|
1347
1224
|
return buildSiliconFlowUserInfoSnapshot(payload);
|
|
1348
1225
|
}
|
|
1349
1226
|
|
|
1350
|
-
async function runNewCliDashboardStrategy(strategy, token, channel = {}) {
|
|
1351
|
-
if (strategy.requiresDedicatedToken || !hasDedicatedBalanceToken(channel)) {
|
|
1352
|
-
return makeHiddenSnapshot('newcli');
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
for (const headers of buildNewCliAuthHeaderCandidates(token)) {
|
|
1356
|
-
const payload = await tryRequestJson(joinUrl(strategy.webBase || strategy.baseUrl, '/api/user/dashboard'), {
|
|
1357
|
-
headers
|
|
1358
|
-
});
|
|
1359
|
-
const snapshot = buildNewCliDashboardSnapshot(payload);
|
|
1360
|
-
if (snapshot.visible) return snapshot;
|
|
1361
|
-
}
|
|
1362
|
-
return makeHiddenSnapshot('newcli');
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
1227
|
async function runBalanceStrategy(strategy, token, channel = {}) {
|
|
1366
1228
|
if (!strategy || !strategy.type) {
|
|
1367
1229
|
return { snapshot: makeHiddenSnapshot(), strategy };
|
|
@@ -1433,12 +1295,6 @@ async function runBalanceStrategy(strategy, token, channel = {}) {
|
|
|
1433
1295
|
strategy
|
|
1434
1296
|
};
|
|
1435
1297
|
}
|
|
1436
|
-
if (strategy.type === 'newcli-dashboard') {
|
|
1437
|
-
return {
|
|
1438
|
-
snapshot: await runNewCliDashboardStrategy(strategy, token, channel),
|
|
1439
|
-
strategy
|
|
1440
|
-
};
|
|
1441
|
-
}
|
|
1442
1298
|
|
|
1443
1299
|
return { snapshot: makeHiddenSnapshot(), strategy };
|
|
1444
1300
|
}
|
|
@@ -1464,7 +1320,6 @@ async function probeBalanceFromBase(baseUrl, channel, token) {
|
|
|
1464
1320
|
strategy.type?.startsWith('88code') ? '88code'
|
|
1465
1321
|
: strategy.type?.startsWith('openrouter') ? 'openrouter'
|
|
1466
1322
|
: strategy.type?.startsWith('siliconflow') ? 'siliconflow'
|
|
1467
|
-
: strategy.type?.startsWith('newcli') ? 'newcli'
|
|
1468
1323
|
: strategy.type?.startsWith('sub2api') ? 'sub2api'
|
|
1469
1324
|
: strategy.platform || null
|
|
1470
1325
|
);
|
|
@@ -1731,10 +1586,8 @@ module.exports = {
|
|
|
1731
1586
|
build88CodeApiBaseCandidates,
|
|
1732
1587
|
buildOpenRouterApiBaseCandidates,
|
|
1733
1588
|
buildSiliconFlowApiBaseCandidates,
|
|
1734
|
-
buildNewCliWebBaseCandidates,
|
|
1735
1589
|
build88CodeUsageSnapshot,
|
|
1736
1590
|
build88CodeSubscriptionSnapshot,
|
|
1737
|
-
buildNewCliDashboardSnapshot,
|
|
1738
1591
|
buildBalanceProbeStrategies,
|
|
1739
1592
|
getEnabledBalanceChannels,
|
|
1740
1593
|
runBalanceStrategy,
|