dsh-connect-trae 2.10.0 → 3.0.0
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/CHANGELOG.md +461 -0
- package/README.en.md +4 -1
- package/README.md +4 -1
- package/lib/client.js +719 -287
- package/lib/index.d.ts +12 -20
- package/lib/index.js +75 -8
- package/package.json +2 -1
package/lib/index.d.ts
CHANGED
|
@@ -1689,15 +1689,6 @@ interface TraeWebAccount {
|
|
|
1689
1689
|
tokenExpiresAtMs: number;
|
|
1690
1690
|
selected: boolean;
|
|
1691
1691
|
}
|
|
1692
|
-
/**
|
|
1693
|
-
* Another account on this machine that still has credit, surfaced only while
|
|
1694
|
-
* the BOUND account is exhausted (issue #25).
|
|
1695
|
-
*
|
|
1696
|
-
* The account switch is persisted, so a user whose bound account ran out sees
|
|
1697
|
-
* a permanently zeroed card with no explanation. This carries just enough to
|
|
1698
|
-
* name the alternative in the UI — identity plus the two CN credit buckets —
|
|
1699
|
-
* and is only ever produced by a read-only upstream call.
|
|
1700
|
-
*/
|
|
1701
1692
|
interface TraeWebCreditAlternative {
|
|
1702
1693
|
id: string;
|
|
1703
1694
|
accountName: string;
|
|
@@ -2023,19 +2014,20 @@ interface Config {
|
|
|
2023
2014
|
*/
|
|
2024
2015
|
accounts?: Partial<Record<TraeRegion, string>>;
|
|
2025
2016
|
/**
|
|
2026
|
-
* Show the
|
|
2027
|
-
*
|
|
2017
|
+
* Show the credit readout in the composer tool row: `Trae CN · <n>`, rendered
|
|
2018
|
+
* ONLY while the session's selected model belongs to this plugin, clickable
|
|
2019
|
+
* for the account/balances panel.
|
|
2028
2020
|
*
|
|
2029
|
-
*
|
|
2030
|
-
*
|
|
2031
|
-
*
|
|
2032
|
-
*
|
|
2033
|
-
*
|
|
2034
|
-
*
|
|
2035
|
-
* sidebar, which is reachable exactly where the feature renders.
|
|
2021
|
+
* This field first gated the sidebar credit line (issue #26, contributed by
|
|
2022
|
+
* JiewiW); when that line was removed in 2.13.0 the composer readout replaced
|
|
2023
|
+
* it and rendered unconditionally; 2.13.3 restores the switch, because the
|
|
2024
|
+
* user went looking for it and a readout inside the SHARED composer row
|
|
2025
|
+
* deserves the same opt-in the sidebar line had. The field is REUSED so an
|
|
2026
|
+
* existing `true` keeps the readout on across the upgrade.
|
|
2036
2027
|
*
|
|
2037
|
-
*
|
|
2038
|
-
*
|
|
2028
|
+
* OFF by default. The card's checkbox is the only writer, so exactly one path
|
|
2029
|
+
* can change it. Declared volatile alongside `accounts`/`regions` so the
|
|
2030
|
+
* settings form can both read and write it.
|
|
2039
2031
|
*/
|
|
2040
2032
|
showPointsInMainUi?: boolean;
|
|
2041
2033
|
/**
|
package/lib/index.js
CHANGED
|
@@ -1266,13 +1266,16 @@ var TraeCredentialStore = class {
|
|
|
1266
1266
|
*/
|
|
1267
1267
|
async readAll() {
|
|
1268
1268
|
const { credentials: desktop } = await this.readDesktopAll();
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
if (!this.matchesRegion(
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1269
|
+
const byAccount = /* @__PURE__ */ new Map();
|
|
1270
|
+
const consider = (credential) => {
|
|
1271
|
+
if (!this.matchesRegion(credential)) return;
|
|
1272
|
+
const id = traeAccountId(credential);
|
|
1273
|
+
const incumbent = byAccount.get(id);
|
|
1274
|
+
if (incumbent === void 0 || credential.expiresAtMs > incumbent.expiresAtMs) byAccount.set(id, credential);
|
|
1275
|
+
};
|
|
1276
|
+
for (const credential of desktop) consider(credential);
|
|
1277
|
+
for (const own of await this.readOwns()) consider(own);
|
|
1278
|
+
return [...byAccount.values()];
|
|
1276
1279
|
}
|
|
1277
1280
|
/**
|
|
1278
1281
|
* Which paths were tried and why each one failed. Read-only and token-free:
|
|
@@ -3939,6 +3942,17 @@ const TRAE_MODELS_TEST_PATH = "/plugins/dsh-connect-trae/models/test";
|
|
|
3939
3942
|
/** Plugin-owned local account rescan endpoint. */
|
|
3940
3943
|
const TRAE_ACCOUNTS_REFRESH_PATH = "/plugins/dsh-connect-trae/accounts/refresh";
|
|
3941
3944
|
/**
|
|
3945
|
+
* General balance of EVERY account in a region, for the composer panel's table.
|
|
3946
|
+
*
|
|
3947
|
+
* Separate from the usage route on purpose: the usage document backs the
|
|
3948
|
+
* 5-minute readout, and multiplying its upstream reads by the account count
|
|
3949
|
+
* would charge a healthy account for something it never looks at — the same
|
|
3950
|
+
* principle that keeps `creditAlternatives` firing only when a balance hits
|
|
3951
|
+
* zero. This one is paid when the panel is actually opened, which is the only
|
|
3952
|
+
* place the table is shown.
|
|
3953
|
+
*/
|
|
3954
|
+
const TRAE_ACCOUNT_CREDITS_PATH = "/plugins/dsh-connect-trae/account-credits";
|
|
3955
|
+
/**
|
|
3942
3956
|
* Plugin-owned daily check-in claim endpoint. POST, loopback-only, and the only
|
|
3943
3957
|
* route in this plugin that changes upstream account state.
|
|
3944
3958
|
*/
|
|
@@ -4297,6 +4311,37 @@ async function creditAlternatives(deps, region, accounts) {
|
|
|
4297
4311
|
* The region a request addresses, or a 400 answer. Absent parameter means the
|
|
4298
4312
|
* domestic tab; an unknown value is refused rather than guessed.
|
|
4299
4313
|
*/
|
|
4314
|
+
/**
|
|
4315
|
+
* The general balance of every account in one region.
|
|
4316
|
+
*
|
|
4317
|
+
* One upstream read per account — the same call `creditsOfAccount` already
|
|
4318
|
+
* makes for the exhausted-balance alternatives, widened to every account and to
|
|
4319
|
+
* zero balances. Costs nothing until the composer panel is opened, so the
|
|
4320
|
+
* 5-minute readout never pays for it (see {@link TRAE_ACCOUNT_CREDITS_PATH}).
|
|
4321
|
+
*
|
|
4322
|
+
* An account whose read fails or is unavailable still appears, without a
|
|
4323
|
+
* figure: the table lists how many accounts exist even when one cannot be
|
|
4324
|
+
* quoted, rather than dropping it and making the switch unavailable.
|
|
4325
|
+
*/
|
|
4326
|
+
async function traeAccountCredits(deps, region) {
|
|
4327
|
+
const accounts = (await deps.store(region).accounts()).filter((account) => account.region === region);
|
|
4328
|
+
if (accounts.length === 0) return [];
|
|
4329
|
+
return Promise.all(accounts.map(async (account) => {
|
|
4330
|
+
let generalAvailable;
|
|
4331
|
+
if (account.selected) try {
|
|
4332
|
+
generalAvailable = toCredits(await deps.client(region).snapshot()).generalAvailable;
|
|
4333
|
+
} catch {}
|
|
4334
|
+
else if (deps.creditsOfAccount !== void 0) try {
|
|
4335
|
+
generalAvailable = (await deps.creditsOfAccount(region, account.id))?.generalAvailable;
|
|
4336
|
+
} catch {}
|
|
4337
|
+
return {
|
|
4338
|
+
id: account.id,
|
|
4339
|
+
accountName: account.accountName,
|
|
4340
|
+
selected: account.selected,
|
|
4341
|
+
...generalAvailable === void 0 ? {} : { generalAvailable }
|
|
4342
|
+
};
|
|
4343
|
+
}));
|
|
4344
|
+
}
|
|
4300
4345
|
function requestRegion(req, res) {
|
|
4301
4346
|
const region = regionOfTraeStatusUrl(req.url ?? "/");
|
|
4302
4347
|
if (region === void 0) {
|
|
@@ -4329,6 +4374,27 @@ function registerTraeUsageRoute(ctx, deps) {
|
|
|
4329
4374
|
}
|
|
4330
4375
|
}
|
|
4331
4376
|
});
|
|
4377
|
+
/**
|
|
4378
|
+
* General balance of every account in the region — read only when the
|
|
4379
|
+
* composer panel is opened. One upstream read per account, paid once per
|
|
4380
|
+
* open rather than on the 5-minute cycle (see
|
|
4381
|
+
* {@link TRAE_ACCOUNT_CREDITS_PATH}).
|
|
4382
|
+
*/
|
|
4383
|
+
const disposeAccountCredits = ctx.webServer.register({
|
|
4384
|
+
kind: "exact",
|
|
4385
|
+
path: TRAE_ACCOUNT_CREDITS_PATH,
|
|
4386
|
+
handler: async (req, res) => {
|
|
4387
|
+
if (req.method !== "GET") return json(res, 405, { error: "method not allowed" });
|
|
4388
|
+
if (!loopbackOrigin(req)) return json(res, 403, { error: "origin-not-trusted" });
|
|
4389
|
+
const region = requestRegion(req, res);
|
|
4390
|
+
if (region === void 0) return;
|
|
4391
|
+
try {
|
|
4392
|
+
json(res, 200, { accounts: await traeAccountCredits(deps, region) });
|
|
4393
|
+
} catch (error) {
|
|
4394
|
+
json(res, 500, { error: safeMessage(error) });
|
|
4395
|
+
}
|
|
4396
|
+
}
|
|
4397
|
+
});
|
|
4332
4398
|
const disposeAccounts = ctx.webServer.register({
|
|
4333
4399
|
kind: "exact",
|
|
4334
4400
|
path: TRAE_ACCOUNTS_REFRESH_PATH,
|
|
@@ -4462,6 +4528,7 @@ function registerTraeUsageRoute(ctx, deps) {
|
|
|
4462
4528
|
disposeRefresh();
|
|
4463
4529
|
disposeModelsTest();
|
|
4464
4530
|
disposeAccounts();
|
|
4531
|
+
disposeAccountCredits();
|
|
4465
4532
|
disposeUsage();
|
|
4466
4533
|
};
|
|
4467
4534
|
}, "dsh-connect-trae: Web usage route");
|
|
@@ -4769,7 +4836,7 @@ const Config = z.object({
|
|
|
4769
4836
|
"solo-sg"
|
|
4770
4837
|
]).default("auto").description("Trae edition hint")),
|
|
4771
4838
|
accountId: z.string().description("Deprecated: pre-split account selector, attributed to its own region"),
|
|
4772
|
-
showPointsInMainUi: asVolatile(z.boolean().default(
|
|
4839
|
+
showPointsInMainUi: asVolatile(z.boolean().default(false).description("在输入框工具栏显示积分读数「Trae CN · <数值>」(仅当选中的模型属于本插件时出现,可点击查看账号与积分明细)")),
|
|
4773
4840
|
accounts: asVolatile(accountSelectionConfig.description("Per-region account selections, keyed cn | ai")),
|
|
4774
4841
|
regions: asVolatile(z.dict(regionStateConfig).default({}).description("Per-region model directory and selection, keyed cn | ai")),
|
|
4775
4842
|
lastCatalog: z.array(modelConfig).description("Deprecated: pre-region-split CN model directory"),
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-connect-trae",
|
|
3
3
|
"displayName": "DSH Connect Trae",
|
|
4
4
|
"description": "把本机登录的 Trae 模型接入 DeepSeek Harness:国内版与国际版双供应商并行,提供用量/积分概览与每日签到领取。",
|
|
5
|
-
"version": "
|
|
5
|
+
"version": "3.0.0",
|
|
6
6
|
"author": "dingminhua",
|
|
7
7
|
"copyright": "Copyright (c) 2026 LaoDing",
|
|
8
8
|
"license": "MIT",
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
"@testing-library/react": "^16.3.3",
|
|
110
110
|
"@types/node": "^22.20.0",
|
|
111
111
|
"@types/react": "~18.3.31",
|
|
112
|
+
"@types/react-dom": "^18.3.7",
|
|
112
113
|
"@types/semver": "^7.7.0",
|
|
113
114
|
"jsdom": "^25.0.1",
|
|
114
115
|
"react": "^18.3.1",
|