dsh-connect-trae 2.3.0 → 2.4.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 +138 -2
- package/README.en.md +102 -10
- package/README.md +109 -10
- package/lib/client.js +68 -14
- package/lib/index.d.ts +185 -13
- package/lib/index.js +233 -19
- package/package.json +26 -23
- package/scripts/verify-windows.mjs +311 -0
package/lib/client.js
CHANGED
|
@@ -265,6 +265,10 @@ window.__ModuleLoader__.load({
|
|
|
265
265
|
.dsm-trae-checkin-label{color:var(--dsw-alias-label-primary,#e6e6e6);font-size:13px;line-height:18px;font-weight:600}
|
|
266
266
|
.dsm-trae-checkin-hint{color:var(--dsw-alias-label-tertiary,#9aa0a8);font-size:12px;line-height:17px}
|
|
267
267
|
.dsm-trae-checkin-button{flex:none}
|
|
268
|
+
/* The "this machine already used today's check-in" note is INFORMATIONAL, not
|
|
269
|
+
an error: it is Trae's one-per-device-per-day rule, and the day is simply
|
|
270
|
+
spent. Rendering it in the error colour would read as a plugin fault. */
|
|
271
|
+
.dsm-trae-checkin-note{margin:8px 0 0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#c6c9d0)}
|
|
268
272
|
`;
|
|
269
273
|
//#endregion
|
|
270
274
|
//#region src/client/TraeUsageCard.tsx
|
|
@@ -389,6 +393,14 @@ window.__ModuleLoader__.load({
|
|
|
389
393
|
/** Last claim refusal, shown until the next successful refresh. */
|
|
390
394
|
const [claimError, setClaimError] = (0, react.useState)(void 0);
|
|
391
395
|
/**
|
|
396
|
+
* Whether this MACHINE has spent today's check-in while the selected account
|
|
397
|
+
* has not been paid — the "switched account" state. Kept separate from
|
|
398
|
+
* `claimError` because it is not a failure: it is the upstream's one-per-
|
|
399
|
+
* device-per-day rule, and rendering it through the "签到失败:…" line would
|
|
400
|
+
* present a normal rule as a plugin fault.
|
|
401
|
+
*/
|
|
402
|
+
const [deviceSpentNotice, setDeviceSpentNotice] = (0, react.useState)(false);
|
|
403
|
+
/**
|
|
392
404
|
* A refused or unpersisted settings write, surfaced instead of silently
|
|
393
405
|
* reverting. On 0.1.7 a rejected write resolves normally, so without this
|
|
394
406
|
* the control would flip and then quietly snap back on the next snapshot.
|
|
@@ -469,6 +481,7 @@ window.__ModuleLoader__.load({
|
|
|
469
481
|
*/
|
|
470
482
|
(0, react.useEffect)(() => {
|
|
471
483
|
setClaimError(void 0);
|
|
484
|
+
setDeviceSpentNotice(false);
|
|
472
485
|
}, [activeRegion]);
|
|
473
486
|
(0, react.useEffect)(() => {
|
|
474
487
|
if (!open || !activeRegionOn || status.status !== "signed-in") return;
|
|
@@ -536,13 +549,21 @@ window.__ModuleLoader__.load({
|
|
|
536
549
|
* (it stops an obviously pointless click), not the protection.
|
|
537
550
|
*
|
|
538
551
|
* A refusal is not thrown away: the route answers `claimed: false` with the
|
|
539
|
-
* upstream's business code and message, and the card shows it.
|
|
540
|
-
*
|
|
541
|
-
*
|
|
552
|
+
* upstream's business code and message, and the card shows it. Three answers
|
|
553
|
+
* are distinguished rather than collapsed into "failed":
|
|
554
|
+
*
|
|
555
|
+
* - `alreadyCheckedIn` — this ACCOUNT was already paid today; show it as
|
|
556
|
+
* claimed and refresh, never as an error.
|
|
557
|
+
* - `deviceCheckedIn` (code 9095) — this MACHINE already spent today's
|
|
558
|
+
* check-in, so this account cannot claim here today. That is the normal
|
|
559
|
+
* outcome after switching accounts, and saying "check-in failed" would
|
|
560
|
+
* blame the plugin for an upstream rule.
|
|
561
|
+
* - anything else — a real refusal, reported verbatim.
|
|
542
562
|
*/
|
|
543
563
|
const claimCheckin = async () => {
|
|
544
564
|
setClaiming(true);
|
|
545
565
|
setClaimError(void 0);
|
|
566
|
+
setDeviceSpentNotice(false);
|
|
546
567
|
try {
|
|
547
568
|
const response = await fetch(withTraeRegion(TRAE_CHECKIN_PATH, activeRegion), {
|
|
548
569
|
method: "POST",
|
|
@@ -551,6 +572,11 @@ window.__ModuleLoader__.load({
|
|
|
551
572
|
});
|
|
552
573
|
const body = await response.json().catch(() => void 0);
|
|
553
574
|
if (!response.ok) throw new Error(body?.error ?? `HTTP ${response.status}`);
|
|
575
|
+
if (body?.claimed === false && body.deviceCheckedIn === true) {
|
|
576
|
+
await refreshUsage(activeRegion);
|
|
577
|
+
if (mounted.current) setDeviceSpentNotice(true);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
554
580
|
if (body?.claimed === false && body.alreadyCheckedIn !== true) throw new Error(body.message === void 0 || body.message === "" ? t("row.checkinRefused", { code: String(body.code ?? "") }) : `${t("row.checkinRefused", { code: String(body.code ?? "") })}: ${body.message}`);
|
|
555
581
|
await refreshUsage(activeRegion);
|
|
556
582
|
} catch (error) {
|
|
@@ -637,6 +663,23 @@ window.__ModuleLoader__.load({
|
|
|
637
663
|
const savedEnabledIds = status.status === "signed-in" ? new Set(status.enabledModelIds) : /* @__PURE__ */ new Set();
|
|
638
664
|
const activeEnabledIds = draft?.enabledIds ?? savedEnabledIds;
|
|
639
665
|
const activeImageIds = draft?.imageIds ?? savedImageIds;
|
|
666
|
+
/**
|
|
667
|
+
* Effective image capability of one row, mirroring what the Host reports to
|
|
668
|
+
* DSH: the user's opt-in unioned with Trae's own `multimodal` flag (issue
|
|
669
|
+
* #16). Rendering the union is what keeps this checkbox truthful — showing the
|
|
670
|
+
* raw `imageModelIds` would draw an unticked box next to a model the plugin
|
|
671
|
+
* is in fact advertising as image-capable.
|
|
672
|
+
*/
|
|
673
|
+
const rowAcceptsImage = (model) => activeImageIds.has(model.id) || model.multimodal === true;
|
|
674
|
+
/**
|
|
675
|
+
* A row Trae itself declares multimodal needs no manual opt-in, so its box is
|
|
676
|
+
* shown ticked and read-only rather than offering a toggle that the union
|
|
677
|
+
* would immediately undo. Turning image input off for such a model is
|
|
678
|
+
* deliberately not supported: the flag is the vendor's own capability answer,
|
|
679
|
+
* and enabling it only lets DSH attach an image the user still has to pick per
|
|
680
|
+
* message — it never sends one by itself.
|
|
681
|
+
*/
|
|
682
|
+
const rowImageIsAutomatic = (model) => model.multimodal === true;
|
|
640
683
|
const activeContextBudgets = draft?.contextBudgets ?? savedContextBudgets;
|
|
641
684
|
const dirty = draft !== void 0;
|
|
642
685
|
/** Apply an edit to the ACTIVE tab's draft, seeding it from the current view. */
|
|
@@ -699,7 +742,8 @@ window.__ModuleLoader__.load({
|
|
|
699
742
|
enabled: regionOn(activeRegion),
|
|
700
743
|
lastCatalog: visibleModels.map((model) => ({
|
|
701
744
|
...model,
|
|
702
|
-
input: ["text"]
|
|
745
|
+
input: ["text"],
|
|
746
|
+
...model.multimodal === void 0 ? {} : { multimodal: model.multimodal }
|
|
703
747
|
})),
|
|
704
748
|
enabledModelIds: [...activeEnabledIds],
|
|
705
749
|
imageModelIds: [...activeImageIds].filter((id) => activeEnabledIds.has(id)),
|
|
@@ -955,10 +999,11 @@ window.__ModuleLoader__.load({
|
|
|
955
999
|
children: t("row.creditsError", { message: status.creditsError })
|
|
956
1000
|
}),
|
|
957
1001
|
status.checkin === void 0 ? null : (() => {
|
|
958
|
-
const
|
|
1002
|
+
const accountClaimed = status.checkin.checkedIn;
|
|
1003
|
+
const deviceSpent = !accountClaimed && (status.checkin.didCheckedIn || deviceSpentNotice);
|
|
959
1004
|
const reward = formatNumber(status.checkin.credits);
|
|
960
1005
|
const bonus = status.checkin.extraCredits === void 0 ? "" : ` + ${formatNumber(status.checkin.extraCredits)}`;
|
|
961
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1006
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
962
1007
|
className: "dsm-trae-checkin",
|
|
963
1008
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
964
1009
|
className: "dsm-trae-checkin-copy",
|
|
@@ -967,18 +1012,22 @@ window.__ModuleLoader__.load({
|
|
|
967
1012
|
children: t("row.checkinLabel")
|
|
968
1013
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
969
1014
|
className: "dsm-trae-checkin-hint",
|
|
970
|
-
children: [t("row.checkinReward", { reward: `${reward}${bonus}` }),
|
|
1015
|
+
children: [t("row.checkinReward", { reward: `${reward}${bonus}` }), accountClaimed ? ` · ${t("row.checkinDoneHint")}` : ""]
|
|
971
1016
|
})]
|
|
972
1017
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
973
1018
|
type: "button",
|
|
974
1019
|
className: "dsm-btn dsm-btn-primary dsm-trae-checkin-button",
|
|
975
|
-
disabled: !status.checkin.enabled ||
|
|
1020
|
+
disabled: !status.checkin.enabled || accountClaimed || deviceSpent || claiming,
|
|
976
1021
|
onClick: () => {
|
|
977
1022
|
claimCheckin();
|
|
978
1023
|
},
|
|
979
|
-
children: claiming ? t("row.checkinClaiming") :
|
|
1024
|
+
children: claiming ? t("row.checkinClaiming") : accountClaimed ? t("row.checkinClaimed") : t("row.checkinClaim")
|
|
980
1025
|
})]
|
|
981
|
-
})
|
|
1026
|
+
}), deviceSpent ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1027
|
+
className: "dsm-trae-checkin-note",
|
|
1028
|
+
role: "status",
|
|
1029
|
+
children: t("row.checkinDeviceSpent")
|
|
1030
|
+
}) : null] });
|
|
982
1031
|
})(),
|
|
983
1032
|
status.checkin !== void 0 && !status.checkin.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
984
1033
|
className: "dsm-trae-usage-error",
|
|
@@ -1046,8 +1095,9 @@ window.__ModuleLoader__.load({
|
|
|
1046
1095
|
className: "dsm-trae-model-image",
|
|
1047
1096
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1048
1097
|
type: "checkbox",
|
|
1049
|
-
checked:
|
|
1050
|
-
disabled: settingsScope?.getSnapshot().writable !== true || saving,
|
|
1098
|
+
checked: rowAcceptsImage(model),
|
|
1099
|
+
disabled: rowImageIsAutomatic(model) || settingsScope?.getSnapshot().writable !== true || saving,
|
|
1100
|
+
title: rowImageIsAutomatic(model) ? t("row.modelImageAuto") : void 0,
|
|
1051
1101
|
onChange: () => {
|
|
1052
1102
|
toggleImage(model.id);
|
|
1053
1103
|
}
|
|
@@ -1210,6 +1260,7 @@ window.__ModuleLoader__.load({
|
|
|
1210
1260
|
"row.checkinDoneHint": "come back tomorrow",
|
|
1211
1261
|
"row.checkinRefused": "Trae refused the check-in (code {code})",
|
|
1212
1262
|
"row.checkinError": "Check-in failed: {message}",
|
|
1263
|
+
"row.checkinDeviceSpent": "This machine already used today's check-in — Trae allows one per device per day, so this account cannot claim here today. Claim it on another device or from the account that checked in, or come back tomorrow.",
|
|
1213
1264
|
"row.checkinDisabled": "This account has no check-in activity available.",
|
|
1214
1265
|
"row.regionCn": "CN",
|
|
1215
1266
|
"row.regionAi": "International",
|
|
@@ -1238,11 +1289,12 @@ window.__ModuleLoader__.load({
|
|
|
1238
1289
|
"row.contextBudget": "DSH context budget",
|
|
1239
1290
|
"row.modelOutput": "Output {output}",
|
|
1240
1291
|
"row.modelImage": "Image",
|
|
1292
|
+
"row.modelImageAuto": "Enabled automatically: Trae marks this model multimodal.",
|
|
1241
1293
|
"row.modelRate": "{rate}x credits",
|
|
1242
1294
|
"row.modelReasoning": "Reasoning: {efforts}",
|
|
1243
1295
|
"row.modelReasoningSupported": "Reasoning: supported",
|
|
1244
1296
|
"row.modelUnknown": "Unknown",
|
|
1245
|
-
"row.modelCapabilityPending": "Image input
|
|
1297
|
+
"row.modelCapabilityPending": "Image input follows Trae's own multimodal flag, plus anything you tick yourself.",
|
|
1246
1298
|
"row.cheer": "Star on GitHub"
|
|
1247
1299
|
};
|
|
1248
1300
|
const zh = {
|
|
@@ -1288,6 +1340,7 @@ window.__ModuleLoader__.load({
|
|
|
1288
1340
|
"row.checkinDoneHint": "明天再来",
|
|
1289
1341
|
"row.checkinRefused": "Trae 拒绝了本次签到(业务码 {code})",
|
|
1290
1342
|
"row.checkinError": "签到失败:{message}",
|
|
1343
|
+
"row.checkinDeviceSpent": "本机今日的签到已用掉——Trae 按「每台设备每天一次」限制,所以当前账号在本机今天无法再签。可换一台设备领取,或用今天已签到的那台设备/账号,或明天再来。",
|
|
1291
1344
|
"row.checkinDisabled": "该账号当前没有可用的签到活动。",
|
|
1292
1345
|
"row.regionCn": "国内版",
|
|
1293
1346
|
"row.regionAi": "国际版",
|
|
@@ -1316,11 +1369,12 @@ window.__ModuleLoader__.load({
|
|
|
1316
1369
|
"row.contextBudget": "DSH 上下文预算",
|
|
1317
1370
|
"row.modelOutput": "最大输出 {output}",
|
|
1318
1371
|
"row.modelImage": "图片",
|
|
1372
|
+
"row.modelImageAuto": "已自动开启:Trae 把该模型标为多模态。",
|
|
1319
1373
|
"row.modelRate": "积分 {rate}x",
|
|
1320
1374
|
"row.modelReasoning": "推理强度:{efforts}",
|
|
1321
1375
|
"row.modelReasoningSupported": "推理:支持",
|
|
1322
1376
|
"row.modelUnknown": "未知",
|
|
1323
|
-
"row.modelCapabilityPending": "
|
|
1377
|
+
"row.modelCapabilityPending": "图片输入跟随 Trae 自身的多模态标注,并叠加你手动勾选的模型。",
|
|
1324
1378
|
"row.cheer": "鼓励一下"
|
|
1325
1379
|
};
|
|
1326
1380
|
//#endregion
|
package/lib/index.d.ts
CHANGED
|
@@ -46,6 +46,15 @@ interface TraeStorageCandidate {
|
|
|
46
46
|
path: string;
|
|
47
47
|
source: TraeCredentialSource;
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* One edition's plausible Windows directory spellings, in probe order.
|
|
51
|
+
*
|
|
52
|
+
* Exported so the identity reader and the credential scanner probe the SAME
|
|
53
|
+
* names: the two resolve different files (the install's `product.json` vs the
|
|
54
|
+
* per-user `storage.json`) but they describe one installation, and a spelling
|
|
55
|
+
* that works for one but not the other is a bug rather than a preference.
|
|
56
|
+
*/
|
|
57
|
+
declare function traeWindowsAppNames(edition: TraeEdition): readonly string[];
|
|
49
58
|
declare function traeStorageCandidates(platform?: NodeJS.Platform, home?: string, env?: NodeJS.ProcessEnv): TraeStorageCandidate[];
|
|
50
59
|
//#endregion
|
|
51
60
|
//#region src/region.d.ts
|
|
@@ -111,6 +120,23 @@ interface TraeModelInfo {
|
|
|
111
120
|
wireConfigName?: string;
|
|
112
121
|
/** The directory function this model must be called through (see {@link TraeWireModel.function}). */
|
|
113
122
|
wireFunction?: string;
|
|
123
|
+
/**
|
|
124
|
+
* Trae's own `multimodal` flag for this model, carried through from the
|
|
125
|
+
* directory that advertised it. It is the upstream's answer to "does this
|
|
126
|
+
* model read images", and {@link applyImageSelection} unions it with the
|
|
127
|
+
* user's explicit opt-ins.
|
|
128
|
+
*
|
|
129
|
+
* Deliberately NOT the same thing as `input`: `input` is what DSH is told
|
|
130
|
+
* this route accepts, while this field records what Trae said. Keeping both
|
|
131
|
+
* lets a future refresh re-derive `input` without losing the upstream fact,
|
|
132
|
+
* and lets the card explain WHY a model is image-capable.
|
|
133
|
+
*
|
|
134
|
+
* Absent means the directory did not say (an older `lastCatalog` saved before
|
|
135
|
+
* this field existed, a fallback row, or a directory entry that omitted the
|
|
136
|
+
* key). Absent is treated as false, never as "assume capable": sending an
|
|
137
|
+
* image to a model that cannot read one burns credits for a silent failure.
|
|
138
|
+
*/
|
|
139
|
+
multimodal?: boolean;
|
|
114
140
|
}
|
|
115
141
|
/**
|
|
116
142
|
* Bootstrap catalog: identity only where current Trae metadata has not been
|
|
@@ -166,7 +192,7 @@ declare function traeInputModalities(model: Pick<TraeModelInfo, 'input'>): TraeI
|
|
|
166
192
|
* model discovery) use this decorated name.
|
|
167
193
|
*/
|
|
168
194
|
declare function traeModelDisplayName(model: Pick<TraeModelInfo, 'name' | 'creditMultiplier'>): string;
|
|
169
|
-
/** Apply the user's explicit image opt-ins
|
|
195
|
+
/** Apply the user's explicit image opt-ins plus Trae's own multimodal flag. */
|
|
170
196
|
declare function applyImageSelection(models: readonly TraeModelInfo[], selected: ReadonlySet<string>): TraeModelInfo[];
|
|
171
197
|
/** One row from `get_detail_param`: the authoritative llm_utils_chat wire id + display name. */
|
|
172
198
|
interface TraeWireModel {
|
|
@@ -230,7 +256,7 @@ type TraeContextBudget = number;
|
|
|
230
256
|
* never to a fabricated number. Everything else keeps the dev window.
|
|
231
257
|
*/
|
|
232
258
|
declare function applyContextBudgets(catalog: readonly TraeModelInfo[], budgets?: Readonly<Record<string, TraeContextBudget | undefined>>): TraeModelInfo[];
|
|
233
|
-
/** Convert Trae metadata into
|
|
259
|
+
/** Convert Trae metadata into catalog rows; image input is decided by {@link applyImageSelection}. */
|
|
234
260
|
declare function discoveredCatalog(models: readonly TraeDiscoveredModel[]): TraeModelInfo[];
|
|
235
261
|
/**
|
|
236
262
|
* Drop rows saved by older releases that generated `@1m` variant models, so a
|
|
@@ -576,6 +602,8 @@ interface TraeObservedModelConfig {
|
|
|
576
602
|
declare function parseObservedModelConfig(line: string): TraeObservedModelConfig | undefined;
|
|
577
603
|
//#endregion
|
|
578
604
|
//#region src/model-cache.d.ts
|
|
605
|
+
/** Basename of the SQLite cache sitting beside the credential document. */
|
|
606
|
+
declare const TRAE_STATE_DB_FILENAME = "state.vscdb";
|
|
579
607
|
interface TraeCachedModelConfig {
|
|
580
608
|
name: string;
|
|
581
609
|
customConfig?: Record<string, unknown>;
|
|
@@ -594,11 +622,54 @@ interface TraeCachedModelReadOptions {
|
|
|
594
622
|
home?: string;
|
|
595
623
|
/** Environment override for testing; defaults to process.env. */
|
|
596
624
|
env?: NodeJS.ProcessEnv;
|
|
625
|
+
/**
|
|
626
|
+
* The credential candidate whose account is being read. Supplying it pins the
|
|
627
|
+
* lookup to the installation the credential actually came from, which is the
|
|
628
|
+
* only way to stay correct when several editions are installed: `storage.json`
|
|
629
|
+
* and `state.vscdb` live in the SAME `globalStorage` directory, so the cache
|
|
630
|
+
* belongs to whichever candidate yielded the sign-in.
|
|
631
|
+
*/
|
|
632
|
+
candidate?: TraeStorageCandidate;
|
|
633
|
+
/** Injectable for tests; defaults to node:fs existsSync. */
|
|
634
|
+
exists?: (path: string) => boolean;
|
|
635
|
+
/**
|
|
636
|
+
* Injectable `sqlite3` runner for tests; defaults to promisified `execFile`.
|
|
637
|
+
* Mirrors the `fetchImpl` injection used elsewhere in this plugin, and exists
|
|
638
|
+
* so a test can assert the exact argv — in particular WHICH database path was
|
|
639
|
+
* chosen, which no assertion on the candidate list alone can prove.
|
|
640
|
+
*/
|
|
641
|
+
runSqlite?: (database: string, sql: string) => Promise<{
|
|
642
|
+
stdout: string;
|
|
643
|
+
}>;
|
|
597
644
|
}
|
|
645
|
+
/**
|
|
646
|
+
* The cache paths to try, most-specific first.
|
|
647
|
+
*
|
|
648
|
+
* `state.vscdb` is a SIBLING of the credential document (both sit in
|
|
649
|
+
* `globalStorage`), so a candidate's own path is the authority for its cache —
|
|
650
|
+
* this is why the database is derived from {@link traeStorageCandidates} rather
|
|
651
|
+
* than re-spelled here.
|
|
652
|
+
*
|
|
653
|
+
* It previously hardcoded the single macOS spelling `Trae CN`, which was wrong
|
|
654
|
+
* in two ways on Windows: `paths.ts` probes `Trae CN` AND `trae-cn`, and the
|
|
655
|
+
* edition actually installed is often SOLO (`TRAE SOLO CN`). This module would
|
|
656
|
+
* then point at a directory that does not exist. That went unnoticed only
|
|
657
|
+
* because the Windows `sqlite3` dependency is absent, so the lookup failed and
|
|
658
|
+
* callers fell back — masking the wrong path behind a different error. Sharing
|
|
659
|
+
* one path table means a spelling that works for sign-in also works for the
|
|
660
|
+
* cache.
|
|
661
|
+
*/
|
|
662
|
+
declare function traeStateDatabaseCandidates(options?: TraeCachedModelReadOptions): string[];
|
|
598
663
|
/**
|
|
599
664
|
* Read Trae's own current user's model map via sqlite3 without exposing
|
|
600
665
|
* secrets. The sqlite3 command line is a macOS prerequisite; on Windows it is
|
|
601
666
|
* typically absent, so the call fails and callers fall back gracefully.
|
|
667
|
+
*
|
|
668
|
+
* Every candidate database is tried in order and the first that EXISTS is
|
|
669
|
+
* queried. Existence is checked before spawning because a missing file and a
|
|
670
|
+
* missing `sqlite3` binary are different problems: choosing the wrong directory
|
|
671
|
+
* would otherwise surface as a confusing `sqlite3` failure, hiding a path bug
|
|
672
|
+
* behind a dependency error.
|
|
602
673
|
*/
|
|
603
674
|
declare function readTraeCachedModel(functionName: string, modelName: string, userId: string, options?: TraeCachedModelReadOptions): Promise<TraeCachedModelConfig | undefined>;
|
|
604
675
|
//#endregion
|
|
@@ -634,6 +705,55 @@ interface TraeModelDetailRequest {
|
|
|
634
705
|
/** Build the exact request shape observed in successful current Trae CN logs. */
|
|
635
706
|
declare function buildTraeModelDetailRequest(configName?: string, custom?: boolean): TraeModelDetailRequest;
|
|
636
707
|
//#endregion
|
|
708
|
+
//#region src/redact.d.ts
|
|
709
|
+
/**
|
|
710
|
+
* Redaction helpers for diagnostics that a user may paste into a public issue.
|
|
711
|
+
*
|
|
712
|
+
* A verification report is only useful if it can be shared, and it is only safe
|
|
713
|
+
* to share if it carries no personal identifiers. Paths are the hard case:
|
|
714
|
+
* `C:\Users\<real name>\AppData\Roaming\Trae CN\...` contains both a real
|
|
715
|
+
* account name AND the single most diagnostic token in the whole report (the
|
|
716
|
+
* Trae data directory spelling). Redacting the whole path would make the report
|
|
717
|
+
* worthless; printing it whole would leak the user's name. So the user segment
|
|
718
|
+
* is replaced and the meaningful tail is preserved.
|
|
719
|
+
*
|
|
720
|
+
* @module dsh-connect-trae/redact
|
|
721
|
+
*/
|
|
722
|
+
/**
|
|
723
|
+
* Replace the user segment of a path with `<user>`, keeping the rest intact.
|
|
724
|
+
*
|
|
725
|
+
* Handles the shapes a Trae install can produce:
|
|
726
|
+
* - `C:\Users\<name>\...` and `C:\Documents and Settings\<name>\...` (Windows)
|
|
727
|
+
* - `/Users/<name>/...` and `/home/<name>/...` (macOS / Linux)
|
|
728
|
+
*
|
|
729
|
+
* Anything after that segment — edition directory, `User\globalStorage`,
|
|
730
|
+
* `storage.json` — is preserved verbatim, because that is what a report is
|
|
731
|
+
* actually read for. Cross-platform on purpose: the function is called by
|
|
732
|
+
* Windows-focused diagnostics, but the same helpers run in tests and on other
|
|
733
|
+
* hosts, and a report from the wrong platform must not leak either.
|
|
734
|
+
*/
|
|
735
|
+
declare function maskUserPath(path: string): string;
|
|
736
|
+
/**
|
|
737
|
+
* Describe a name by shape instead of by value: a character count, plus whether
|
|
738
|
+
* it is purely numeric.
|
|
739
|
+
*
|
|
740
|
+
* This is the deliberate middle ground for account names. A Trae account name
|
|
741
|
+
* is often a real name or a phone number, so it must never be printed; but the
|
|
742
|
+
* report still needs to show that an account WAS resolved, and the shape
|
|
743
|
+
* distinguishes a real nickname from a generated `用户<n>` id — which is the
|
|
744
|
+
* only thing a reader needs to judge whether account discovery worked.
|
|
745
|
+
*/
|
|
746
|
+
declare function describeNameShape(name: unknown): string;
|
|
747
|
+
/**
|
|
748
|
+
* Describe an identifier by shape instead of by value.
|
|
749
|
+
*
|
|
750
|
+
* A device id (`x-device-id`) is a stable installation identifier and is
|
|
751
|
+
* directly tied to the upstream's per-device rules, so it is never printed.
|
|
752
|
+
* Its shape still proves which resolution path ran: a real `icube-dc` id is
|
|
753
|
+
* 15 digits, while the fallback is a 32-character hex hash.
|
|
754
|
+
*/
|
|
755
|
+
declare function describeIdShape(value: unknown): string;
|
|
756
|
+
//#endregion
|
|
637
757
|
//#region src/protocol.d.ts
|
|
638
758
|
declare const TRAE_CN_AGENT_TASK_PATH = "/api/agent/v3/create_agent_task";
|
|
639
759
|
declare const TRAE_CN_TITLE_PATH = "/api/agent/v3/llm_utils_chat";
|
|
@@ -1239,15 +1359,32 @@ interface TraeUsageSnapshot {
|
|
|
1239
1359
|
packs: TraeUsagePack[];
|
|
1240
1360
|
}
|
|
1241
1361
|
interface TraeCheckinStatus {
|
|
1362
|
+
/**
|
|
1363
|
+
* Whether the account's REWARD PACK for today already exists. This is the
|
|
1364
|
+
* account-wide answer and it is the one that decides whether there is
|
|
1365
|
+
* anything left to claim: a day with `checkedIn: true` has already been paid
|
|
1366
|
+
* out, whichever device produced it.
|
|
1367
|
+
*/
|
|
1242
1368
|
checkedIn: boolean;
|
|
1243
1369
|
/** Reward for one check-in, as reported by the upstream (`credits`). */
|
|
1244
1370
|
credits: number;
|
|
1245
1371
|
enabled: boolean;
|
|
1246
1372
|
/**
|
|
1247
|
-
* Whether
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1373
|
+
* Whether THIS device's claim for today was already recorded. The upstream
|
|
1374
|
+
* keys this on the `x-device-id` the request carries — not on the account —
|
|
1375
|
+
* so it answers `true` for the device that claimed and `false` for the same
|
|
1376
|
+
* account and day read from any other device.
|
|
1377
|
+
*
|
|
1378
|
+
* Measured 2026-09-26 on a live CN account whose claim had succeeded minutes
|
|
1379
|
+
* earlier: `did_checked_in` was `true` with the claiming device id and
|
|
1380
|
+
* `false` with the header omitted, with a synthetic id, and with another
|
|
1381
|
+
* install's id. Repeating the read never flips it, so it is not "have I seen
|
|
1382
|
+
* you before" state either — only an actual claim sets it.
|
|
1383
|
+
*
|
|
1384
|
+
* It is therefore NOT a "today is done" signal on its own (claiming again
|
|
1385
|
+
* answers the upstream's own 9095 "该设备今日已参与签到" refusal); it is
|
|
1386
|
+
* evidence that this exact device is already accounted for, which is what
|
|
1387
|
+
* makes a claim safe to skip.
|
|
1251
1388
|
*/
|
|
1252
1389
|
didCheckedIn: boolean;
|
|
1253
1390
|
/** Bonus credit granted on top of the base reward, when the upstream reports one. */
|
|
@@ -1323,6 +1460,12 @@ declare class TraeUsageClient {
|
|
|
1323
1460
|
/**
|
|
1324
1461
|
* Daily check-in status. Read-only, and answered with or without the device
|
|
1325
1462
|
* header — the claim is what needs it.
|
|
1463
|
+
*
|
|
1464
|
+
* The read DOES carry the header whenever this installation has one, and
|
|
1465
|
+
* that is deliberate rather than incidental: `did_checked_in` is answered
|
|
1466
|
+
* per device, so omitting the header would make a device that already claimed
|
|
1467
|
+
* today look identical to one that never has (measured 2026-09-26, see
|
|
1468
|
+
* {@link TraeCheckinStatus.didCheckedIn}).
|
|
1326
1469
|
*/
|
|
1327
1470
|
checkinStatus(signal?: AbortSignal): Promise<TraeCheckinStatus>;
|
|
1328
1471
|
/**
|
|
@@ -1398,15 +1541,33 @@ interface TraeWebModel {
|
|
|
1398
1541
|
defaultEffort?: string;
|
|
1399
1542
|
};
|
|
1400
1543
|
maxContextWindow?: number;
|
|
1544
|
+
/**
|
|
1545
|
+
* Trae's own image-capability flag, as the runtime catalog carries it. The
|
|
1546
|
+
* card renders these rows with their image checkbox already ticked so the
|
|
1547
|
+
* control matches what DSH is actually told (issue #16); absent means the
|
|
1548
|
+
* directory did not declare it, which is not a capability claim either way.
|
|
1549
|
+
*/
|
|
1550
|
+
multimodal?: boolean;
|
|
1401
1551
|
}
|
|
1402
1552
|
/**
|
|
1403
1553
|
* Daily check-in state rendered below the credit stats.
|
|
1404
1554
|
*
|
|
1405
|
-
*
|
|
1406
|
-
*
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1409
|
-
*
|
|
1555
|
+
* The two booleans answer DIFFERENT questions and must never be collapsed into
|
|
1556
|
+
* one "done" flag — doing that was a shipped bug (see CHANGELOG 2.3.1):
|
|
1557
|
+
*
|
|
1558
|
+
* - `checkedIn` is ACCOUNT-level: today's reward pack exists for this account,
|
|
1559
|
+
* so there is nothing left to claim and the balance already includes it.
|
|
1560
|
+
* - `didCheckedIn` is DEVICE-level: this MACHINE already spent its one
|
|
1561
|
+
* check-in for the day, whichever account spent it. The upstream keys it on
|
|
1562
|
+
* the `x-device-id` in the request and answers it per device, not per
|
|
1563
|
+
* account (measured 2026-09-26: the same account and Beijing day answered
|
|
1564
|
+
* `false` with the header omitted, with a synthetic id, and with another
|
|
1565
|
+
* install's id, and `true` for the device that actually claimed).
|
|
1566
|
+
*
|
|
1567
|
+
* So `didCheckedIn && !checkedIn` is the "switched account" case: the device's
|
|
1568
|
+
* daily check-in is used up, but THIS account was never rewarded. Claiming
|
|
1569
|
+
* again is refused upstream (business code 9095, "该设备今日已参与签到"), so
|
|
1570
|
+
* the card disables the button — but it must say that, not "claimed today".
|
|
1410
1571
|
*/
|
|
1411
1572
|
interface TraeWebCheckin {
|
|
1412
1573
|
checkedIn: boolean;
|
|
@@ -1419,8 +1580,19 @@ interface TraeWebCheckin {
|
|
|
1419
1580
|
interface TraeWebCheckinClaim {
|
|
1420
1581
|
/** False when the upstream answered a non-zero business code (e.g. 9004). */
|
|
1421
1582
|
claimed: boolean;
|
|
1422
|
-
/**
|
|
1583
|
+
/**
|
|
1584
|
+
* True only when THIS ACCOUNT's reward for today already exists, so nothing
|
|
1585
|
+
* was sent upstream. Distinct from {@link TraeWebCheckinClaim.deviceCheckedIn}:
|
|
1586
|
+
* a device that already claimed for another account leaves this false.
|
|
1587
|
+
*/
|
|
1423
1588
|
alreadyCheckedIn: boolean;
|
|
1589
|
+
/**
|
|
1590
|
+
* True when today's check-in was already spent on this DEVICE (by this or
|
|
1591
|
+
* another account), so no claim was sent or the upstream refused it with
|
|
1592
|
+
* 9095. Not an error: it is the truthful answer to "can this account claim
|
|
1593
|
+
* here today?" — no, and the reason is the machine, not the account.
|
|
1594
|
+
*/
|
|
1595
|
+
deviceCheckedIn?: boolean;
|
|
1424
1596
|
code?: number;
|
|
1425
1597
|
message?: string;
|
|
1426
1598
|
/** The refreshed check-in state, present whenever the claim path ran. */
|
|
@@ -1731,4 +1903,4 @@ declare function asVolatile<S>(schema: S): S;
|
|
|
1731
1903
|
declare const Config: z<Config>;
|
|
1732
1904
|
declare function apply(ctx: Context, config: Config): void;
|
|
1733
1905
|
//#endregion
|
|
1734
|
-
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, type RawChatDelta, type RawChatMessage, type RawChatTool, SseDecoder, type SseEvent, TRAE_AI_PROVIDER, TRAE_CHECKIN_PATH, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, type TraeActivityRule, type TraeAdapter, type TraeCachedModelConfig, TraeCatalog, type TraeChatResult, type TraeCheckinClaim, type TraeCheckinStatus, type TraeContextBudget, type TraeCredential, TraeCredentialStore, TraeDelegatingUpstreamClient, type TraeDiscoveredModel, type TraeDiscoveredReasoning, type TraeEdition, TraeFallbackUpstreamClient, type TraeFallbackUpstreamOptions, type TraeFusionRawChatEnvelope, TraeGatedUpstreamClient, type TraeGatedUpstreamOptions, type TraeIdentity, type TraeInputModality, type TraeModelDetailRequest, type TraeModelInfo, type TraeObservedModelConfig, TraeRawCapabilityController, type TraeRawCapabilityControllerOptions, type TraeRawCapabilitySnapshot, TraeRawCapabilityState, type TraeRawChatBehaviorConfig, type TraeRawChatCapability, type TraeRawChatClientOptions, type TraeRawChatConfig, type TraeRawChatFailureReason, type TraeRawChatRuntimeConfig, TraeRawChatUpstreamClient, type TraeRawDiagnostic, type TraeRawDiagnosticState, type TraeRawGateway, type TraeRawGatewayOptions, type TraeRawResolverResult, type TraeReasoningCapability, type TraeReasoningEffort, type TraeRefreshDevice, type TraeRegion, type TraeRegionGateways, TraeRegionState, type TraeShim, TraeSoloBridge, type TraeSoloClientOptions, TraeSoloRemoteCatalogClient, type TraeSoloRemoteCatalogOptions, TraeSoloUpstreamClient, type TraeStorageCandidate, type TraeStreamEvent, type TraeUpstreamClient, TraeUsageClient, type TraeUsageOptions, type TraeUsagePack, type TraeUsageRouteOptions, type TraeUsageSnapshot, type TraeUsageSummary, type TraeUsageView, type TraeWebActivity, type TraeWebCheckin, type TraeWebCheckinClaim, type TraeWebCredits, type TraeWebUsage, type TraeWireModel, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, asVolatile, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, settingsNamespaceOf, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStorageCandidates, traeWebUsage, unwrapVolatile, unwrapVolatileDeep, withTraeRegion };
|
|
1906
|
+
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, type RawChatDelta, type RawChatMessage, type RawChatTool, SseDecoder, type SseEvent, TRAE_AI_PROVIDER, TRAE_CHECKIN_PATH, TRAE_CN_AGENT_TASK_PATH, TRAE_CN_TITLE_PATH, TRAE_MODEL_DETAIL_FUNCTIONS, TRAE_MODEL_DETAIL_PATH, TRAE_PAY_BASE, TRAE_PROVIDER, TRAE_PROVIDERS, TRAE_PROVIDER_DISPLAY_NAMES, TRAE_RAW_CHAT_V1_PATH, TRAE_RAW_CHAT_V2_PATH, TRAE_REASONING_EFFORTS, TRAE_REGIONS, TRAE_REGION_PARAM, TRAE_SETTINGS_NS, TRAE_SOLO_CHAT_PATH, TRAE_SOLO_FUNCTION, TRAE_SOLO_MODELS_PATH, TRAE_SOLO_REMOTE_BASE, TRAE_STATE_DB_FILENAME, TRAE_STREAM_IDLE_TIMEOUT_MS, TRAE_USAGE_PATH, TRAE_VERSION_CODE_FALLBACK, type TraeActivityRule, type TraeAdapter, type TraeCachedModelConfig, TraeCatalog, type TraeChatResult, type TraeCheckinClaim, type TraeCheckinStatus, type TraeContextBudget, type TraeCredential, TraeCredentialStore, TraeDelegatingUpstreamClient, type TraeDiscoveredModel, type TraeDiscoveredReasoning, type TraeEdition, TraeFallbackUpstreamClient, type TraeFallbackUpstreamOptions, type TraeFusionRawChatEnvelope, TraeGatedUpstreamClient, type TraeGatedUpstreamOptions, type TraeIdentity, type TraeInputModality, type TraeModelDetailRequest, type TraeModelInfo, type TraeObservedModelConfig, TraeRawCapabilityController, type TraeRawCapabilityControllerOptions, type TraeRawCapabilitySnapshot, TraeRawCapabilityState, type TraeRawChatBehaviorConfig, type TraeRawChatCapability, type TraeRawChatClientOptions, type TraeRawChatConfig, type TraeRawChatFailureReason, type TraeRawChatRuntimeConfig, TraeRawChatUpstreamClient, type TraeRawDiagnostic, type TraeRawDiagnosticState, type TraeRawGateway, type TraeRawGatewayOptions, type TraeRawResolverResult, type TraeReasoningCapability, type TraeReasoningEffort, type TraeRefreshDevice, type TraeRegion, type TraeRegionGateways, TraeRegionState, type TraeShim, TraeSoloBridge, type TraeSoloClientOptions, TraeSoloRemoteCatalogClient, type TraeSoloRemoteCatalogOptions, TraeSoloUpstreamClient, type TraeStorageCandidate, type TraeStreamEvent, type TraeUpstreamClient, TraeUsageClient, type TraeUsageOptions, type TraeUsagePack, type TraeUsageRouteOptions, type TraeUsageSnapshot, type TraeUsageSummary, type TraeUsageView, type TraeWebActivity, type TraeWebCheckin, type TraeWebCheckinClaim, type TraeWebCredits, type TraeWebUsage, type TraeWireModel, UnconfiguredTraeUpstreamClient, apply, applyContextBudgets, applyImageSelection, applyReasoningEffort, asVolatile, bridgeTraeSoloStream, buildTraeAgentTaskBody, buildTraeCnHeaders, buildTraeFusionRawChatEnvelope, buildTraeModelDetailRequest, buildTraeRawChatDraft, buildTraeRawChatRuntimeConfig, classifyTraeRawChatFailure, createTraeAdapter, createTraeRawGateway, createTraeShim, decodeRawChatChunk, decodeTraeEvent, decryptTraeStorageValue, deriveCatalog, describeIdShape, describeNameShape, discoveredCatalog, fallbackModelsFor, hashTraeRawChatArg, identityHeaders, inject, legacyTraeOwnAuthPath, maskUserPath, mergeTraeModelSources, name, nextRegionEnabled, nextRegionSlots, normalizeTraeCredential, normalizeTraeVersionCode, parseObservedModelConfig, parseReasoningCapability, parseTraeAuthValue, parseTraeCachedModel, parseTraeModelExtraConfigLogLine, parseTraeRawChatBehaviorConfig, parseTraeRemoteModel, parseTraeStorageDocument, pickTraeStorageIdentity, prepareSoloBody, probeTraeRawChatCapability, rawCapabilityDiagnostic, rawCapabilityFingerprint, readTraeCachedModel, readTraeCliIdentity, readTraeIdentity, refreshTraeCredential, regionEnabled, regionEnabledOf, regionOfCredential, regionOfEdition, regionOfHost, regionOfTraeProvider, regionOfTraeStatusUrl, regionOfUserRegion, regionStateOf, registerTraeUsageRoute, resolveTraeIdentity, resolveTraeRawRuntime, sanitizeCatalog, settingsNamespaceOf, traeEndpoint, traeInputModalities, traeModelDisplayName, traeOwnAuthPath, traeRawChatExtraInfo, traeStateDatabaseCandidates, traeStorageCandidates, traeWebUsage, traeWindowsAppNames, unwrapVolatile, unwrapVolatileDeep, withTraeRegion };
|