dsh-connect-trae 2.3.0 → 2.3.1
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 +81 -2
- package/README.en.md +61 -6
- package/README.md +61 -6
- package/lib/client.js +42 -9
- package/lib/index.d.ts +159 -11
- package/lib/index.js +192 -15
- package/package.json +3 -2
- package/scripts/verify-windows.mjs +311 -0
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
|
|
@@ -576,6 +585,8 @@ interface TraeObservedModelConfig {
|
|
|
576
585
|
declare function parseObservedModelConfig(line: string): TraeObservedModelConfig | undefined;
|
|
577
586
|
//#endregion
|
|
578
587
|
//#region src/model-cache.d.ts
|
|
588
|
+
/** Basename of the SQLite cache sitting beside the credential document. */
|
|
589
|
+
declare const TRAE_STATE_DB_FILENAME = "state.vscdb";
|
|
579
590
|
interface TraeCachedModelConfig {
|
|
580
591
|
name: string;
|
|
581
592
|
customConfig?: Record<string, unknown>;
|
|
@@ -594,11 +605,54 @@ interface TraeCachedModelReadOptions {
|
|
|
594
605
|
home?: string;
|
|
595
606
|
/** Environment override for testing; defaults to process.env. */
|
|
596
607
|
env?: NodeJS.ProcessEnv;
|
|
608
|
+
/**
|
|
609
|
+
* The credential candidate whose account is being read. Supplying it pins the
|
|
610
|
+
* lookup to the installation the credential actually came from, which is the
|
|
611
|
+
* only way to stay correct when several editions are installed: `storage.json`
|
|
612
|
+
* and `state.vscdb` live in the SAME `globalStorage` directory, so the cache
|
|
613
|
+
* belongs to whichever candidate yielded the sign-in.
|
|
614
|
+
*/
|
|
615
|
+
candidate?: TraeStorageCandidate;
|
|
616
|
+
/** Injectable for tests; defaults to node:fs existsSync. */
|
|
617
|
+
exists?: (path: string) => boolean;
|
|
618
|
+
/**
|
|
619
|
+
* Injectable `sqlite3` runner for tests; defaults to promisified `execFile`.
|
|
620
|
+
* Mirrors the `fetchImpl` injection used elsewhere in this plugin, and exists
|
|
621
|
+
* so a test can assert the exact argv — in particular WHICH database path was
|
|
622
|
+
* chosen, which no assertion on the candidate list alone can prove.
|
|
623
|
+
*/
|
|
624
|
+
runSqlite?: (database: string, sql: string) => Promise<{
|
|
625
|
+
stdout: string;
|
|
626
|
+
}>;
|
|
597
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* The cache paths to try, most-specific first.
|
|
630
|
+
*
|
|
631
|
+
* `state.vscdb` is a SIBLING of the credential document (both sit in
|
|
632
|
+
* `globalStorage`), so a candidate's own path is the authority for its cache —
|
|
633
|
+
* this is why the database is derived from {@link traeStorageCandidates} rather
|
|
634
|
+
* than re-spelled here.
|
|
635
|
+
*
|
|
636
|
+
* It previously hardcoded the single macOS spelling `Trae CN`, which was wrong
|
|
637
|
+
* in two ways on Windows: `paths.ts` probes `Trae CN` AND `trae-cn`, and the
|
|
638
|
+
* edition actually installed is often SOLO (`TRAE SOLO CN`). This module would
|
|
639
|
+
* then point at a directory that does not exist. That went unnoticed only
|
|
640
|
+
* because the Windows `sqlite3` dependency is absent, so the lookup failed and
|
|
641
|
+
* callers fell back — masking the wrong path behind a different error. Sharing
|
|
642
|
+
* one path table means a spelling that works for sign-in also works for the
|
|
643
|
+
* cache.
|
|
644
|
+
*/
|
|
645
|
+
declare function traeStateDatabaseCandidates(options?: TraeCachedModelReadOptions): string[];
|
|
598
646
|
/**
|
|
599
647
|
* Read Trae's own current user's model map via sqlite3 without exposing
|
|
600
648
|
* secrets. The sqlite3 command line is a macOS prerequisite; on Windows it is
|
|
601
649
|
* typically absent, so the call fails and callers fall back gracefully.
|
|
650
|
+
*
|
|
651
|
+
* Every candidate database is tried in order and the first that EXISTS is
|
|
652
|
+
* queried. Existence is checked before spawning because a missing file and a
|
|
653
|
+
* missing `sqlite3` binary are different problems: choosing the wrong directory
|
|
654
|
+
* would otherwise surface as a confusing `sqlite3` failure, hiding a path bug
|
|
655
|
+
* behind a dependency error.
|
|
602
656
|
*/
|
|
603
657
|
declare function readTraeCachedModel(functionName: string, modelName: string, userId: string, options?: TraeCachedModelReadOptions): Promise<TraeCachedModelConfig | undefined>;
|
|
604
658
|
//#endregion
|
|
@@ -634,6 +688,55 @@ interface TraeModelDetailRequest {
|
|
|
634
688
|
/** Build the exact request shape observed in successful current Trae CN logs. */
|
|
635
689
|
declare function buildTraeModelDetailRequest(configName?: string, custom?: boolean): TraeModelDetailRequest;
|
|
636
690
|
//#endregion
|
|
691
|
+
//#region src/redact.d.ts
|
|
692
|
+
/**
|
|
693
|
+
* Redaction helpers for diagnostics that a user may paste into a public issue.
|
|
694
|
+
*
|
|
695
|
+
* A verification report is only useful if it can be shared, and it is only safe
|
|
696
|
+
* to share if it carries no personal identifiers. Paths are the hard case:
|
|
697
|
+
* `C:\Users\<real name>\AppData\Roaming\Trae CN\...` contains both a real
|
|
698
|
+
* account name AND the single most diagnostic token in the whole report (the
|
|
699
|
+
* Trae data directory spelling). Redacting the whole path would make the report
|
|
700
|
+
* worthless; printing it whole would leak the user's name. So the user segment
|
|
701
|
+
* is replaced and the meaningful tail is preserved.
|
|
702
|
+
*
|
|
703
|
+
* @module dsh-connect-trae/redact
|
|
704
|
+
*/
|
|
705
|
+
/**
|
|
706
|
+
* Replace the user segment of a path with `<user>`, keeping the rest intact.
|
|
707
|
+
*
|
|
708
|
+
* Handles the shapes a Trae install can produce:
|
|
709
|
+
* - `C:\Users\<name>\...` and `C:\Documents and Settings\<name>\...` (Windows)
|
|
710
|
+
* - `/Users/<name>/...` and `/home/<name>/...` (macOS / Linux)
|
|
711
|
+
*
|
|
712
|
+
* Anything after that segment — edition directory, `User\globalStorage`,
|
|
713
|
+
* `storage.json` — is preserved verbatim, because that is what a report is
|
|
714
|
+
* actually read for. Cross-platform on purpose: the function is called by
|
|
715
|
+
* Windows-focused diagnostics, but the same helpers run in tests and on other
|
|
716
|
+
* hosts, and a report from the wrong platform must not leak either.
|
|
717
|
+
*/
|
|
718
|
+
declare function maskUserPath(path: string): string;
|
|
719
|
+
/**
|
|
720
|
+
* Describe a name by shape instead of by value: a character count, plus whether
|
|
721
|
+
* it is purely numeric.
|
|
722
|
+
*
|
|
723
|
+
* This is the deliberate middle ground for account names. A Trae account name
|
|
724
|
+
* is often a real name or a phone number, so it must never be printed; but the
|
|
725
|
+
* report still needs to show that an account WAS resolved, and the shape
|
|
726
|
+
* distinguishes a real nickname from a generated `用户<n>` id — which is the
|
|
727
|
+
* only thing a reader needs to judge whether account discovery worked.
|
|
728
|
+
*/
|
|
729
|
+
declare function describeNameShape(name: unknown): string;
|
|
730
|
+
/**
|
|
731
|
+
* Describe an identifier by shape instead of by value.
|
|
732
|
+
*
|
|
733
|
+
* A device id (`x-device-id`) is a stable installation identifier and is
|
|
734
|
+
* directly tied to the upstream's per-device rules, so it is never printed.
|
|
735
|
+
* Its shape still proves which resolution path ran: a real `icube-dc` id is
|
|
736
|
+
* 15 digits, while the fallback is a 32-character hex hash.
|
|
737
|
+
*/
|
|
738
|
+
declare function describeIdShape(value: unknown): string;
|
|
739
|
+
//#endregion
|
|
637
740
|
//#region src/protocol.d.ts
|
|
638
741
|
declare const TRAE_CN_AGENT_TASK_PATH = "/api/agent/v3/create_agent_task";
|
|
639
742
|
declare const TRAE_CN_TITLE_PATH = "/api/agent/v3/llm_utils_chat";
|
|
@@ -1239,15 +1342,32 @@ interface TraeUsageSnapshot {
|
|
|
1239
1342
|
packs: TraeUsagePack[];
|
|
1240
1343
|
}
|
|
1241
1344
|
interface TraeCheckinStatus {
|
|
1345
|
+
/**
|
|
1346
|
+
* Whether the account's REWARD PACK for today already exists. This is the
|
|
1347
|
+
* account-wide answer and it is the one that decides whether there is
|
|
1348
|
+
* anything left to claim: a day with `checkedIn: true` has already been paid
|
|
1349
|
+
* out, whichever device produced it.
|
|
1350
|
+
*/
|
|
1242
1351
|
checkedIn: boolean;
|
|
1243
1352
|
/** Reward for one check-in, as reported by the upstream (`credits`). */
|
|
1244
1353
|
credits: number;
|
|
1245
1354
|
enabled: boolean;
|
|
1246
1355
|
/**
|
|
1247
|
-
* Whether
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1250
|
-
*
|
|
1356
|
+
* Whether THIS device's claim for today was already recorded. The upstream
|
|
1357
|
+
* keys this on the `x-device-id` the request carries — not on the account —
|
|
1358
|
+
* so it answers `true` for the device that claimed and `false` for the same
|
|
1359
|
+
* account and day read from any other device.
|
|
1360
|
+
*
|
|
1361
|
+
* Measured 2026-09-26 on a live CN account whose claim had succeeded minutes
|
|
1362
|
+
* earlier: `did_checked_in` was `true` with the claiming device id and
|
|
1363
|
+
* `false` with the header omitted, with a synthetic id, and with another
|
|
1364
|
+
* install's id. Repeating the read never flips it, so it is not "have I seen
|
|
1365
|
+
* you before" state either — only an actual claim sets it.
|
|
1366
|
+
*
|
|
1367
|
+
* It is therefore NOT a "today is done" signal on its own (claiming again
|
|
1368
|
+
* answers the upstream's own 9095 "该设备今日已参与签到" refusal); it is
|
|
1369
|
+
* evidence that this exact device is already accounted for, which is what
|
|
1370
|
+
* makes a claim safe to skip.
|
|
1251
1371
|
*/
|
|
1252
1372
|
didCheckedIn: boolean;
|
|
1253
1373
|
/** Bonus credit granted on top of the base reward, when the upstream reports one. */
|
|
@@ -1323,6 +1443,12 @@ declare class TraeUsageClient {
|
|
|
1323
1443
|
/**
|
|
1324
1444
|
* Daily check-in status. Read-only, and answered with or without the device
|
|
1325
1445
|
* header — the claim is what needs it.
|
|
1446
|
+
*
|
|
1447
|
+
* The read DOES carry the header whenever this installation has one, and
|
|
1448
|
+
* that is deliberate rather than incidental: `did_checked_in` is answered
|
|
1449
|
+
* per device, so omitting the header would make a device that already claimed
|
|
1450
|
+
* today look identical to one that never has (measured 2026-09-26, see
|
|
1451
|
+
* {@link TraeCheckinStatus.didCheckedIn}).
|
|
1326
1452
|
*/
|
|
1327
1453
|
checkinStatus(signal?: AbortSignal): Promise<TraeCheckinStatus>;
|
|
1328
1454
|
/**
|
|
@@ -1402,11 +1528,22 @@ interface TraeWebModel {
|
|
|
1402
1528
|
/**
|
|
1403
1529
|
* Daily check-in state rendered below the credit stats.
|
|
1404
1530
|
*
|
|
1405
|
-
*
|
|
1406
|
-
*
|
|
1407
|
-
*
|
|
1408
|
-
*
|
|
1409
|
-
*
|
|
1531
|
+
* The two booleans answer DIFFERENT questions and must never be collapsed into
|
|
1532
|
+
* one "done" flag — doing that was a shipped bug (see CHANGELOG 2.3.1):
|
|
1533
|
+
*
|
|
1534
|
+
* - `checkedIn` is ACCOUNT-level: today's reward pack exists for this account,
|
|
1535
|
+
* so there is nothing left to claim and the balance already includes it.
|
|
1536
|
+
* - `didCheckedIn` is DEVICE-level: this MACHINE already spent its one
|
|
1537
|
+
* check-in for the day, whichever account spent it. The upstream keys it on
|
|
1538
|
+
* the `x-device-id` in the request and answers it per device, not per
|
|
1539
|
+
* account (measured 2026-09-26: the same account and Beijing day answered
|
|
1540
|
+
* `false` with the header omitted, with a synthetic id, and with another
|
|
1541
|
+
* install's id, and `true` for the device that actually claimed).
|
|
1542
|
+
*
|
|
1543
|
+
* So `didCheckedIn && !checkedIn` is the "switched account" case: the device's
|
|
1544
|
+
* daily check-in is used up, but THIS account was never rewarded. Claiming
|
|
1545
|
+
* again is refused upstream (business code 9095, "该设备今日已参与签到"), so
|
|
1546
|
+
* the card disables the button — but it must say that, not "claimed today".
|
|
1410
1547
|
*/
|
|
1411
1548
|
interface TraeWebCheckin {
|
|
1412
1549
|
checkedIn: boolean;
|
|
@@ -1419,8 +1556,19 @@ interface TraeWebCheckin {
|
|
|
1419
1556
|
interface TraeWebCheckinClaim {
|
|
1420
1557
|
/** False when the upstream answered a non-zero business code (e.g. 9004). */
|
|
1421
1558
|
claimed: boolean;
|
|
1422
|
-
/**
|
|
1559
|
+
/**
|
|
1560
|
+
* True only when THIS ACCOUNT's reward for today already exists, so nothing
|
|
1561
|
+
* was sent upstream. Distinct from {@link TraeWebCheckinClaim.deviceCheckedIn}:
|
|
1562
|
+
* a device that already claimed for another account leaves this false.
|
|
1563
|
+
*/
|
|
1423
1564
|
alreadyCheckedIn: boolean;
|
|
1565
|
+
/**
|
|
1566
|
+
* True when today's check-in was already spent on this DEVICE (by this or
|
|
1567
|
+
* another account), so no claim was sent or the upstream refused it with
|
|
1568
|
+
* 9095. Not an error: it is the truthful answer to "can this account claim
|
|
1569
|
+
* here today?" — no, and the reason is the machine, not the account.
|
|
1570
|
+
*/
|
|
1571
|
+
deviceCheckedIn?: boolean;
|
|
1424
1572
|
code?: number;
|
|
1425
1573
|
message?: string;
|
|
1426
1574
|
/** The refreshed check-in state, present whenever the claim path ran. */
|
|
@@ -1731,4 +1879,4 @@ declare function asVolatile<S>(schema: S): S;
|
|
|
1731
1879
|
declare const Config: z<Config>;
|
|
1732
1880
|
declare function apply(ctx: Context, config: Config): void;
|
|
1733
1881
|
//#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 };
|
|
1882
|
+
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 };
|
package/lib/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { createServer } from "node:http";
|
|
|
13
13
|
import { Readable } from "node:stream";
|
|
14
14
|
import { execFile } from "node:child_process";
|
|
15
15
|
import { promisify } from "node:util";
|
|
16
|
+
import { existsSync } from "node:fs";
|
|
16
17
|
//#region src/catalog.ts
|
|
17
18
|
/**
|
|
18
19
|
* Bootstrap catalog: identity only where current Trae metadata has not been
|
|
@@ -800,6 +801,43 @@ const LINUX_APP_NAMES = {
|
|
|
800
801
|
solo: ["trae-solo-cn", "TRAE SOLO CN"],
|
|
801
802
|
"solo-sg": ["trae-solo", "TRAE SOLO"]
|
|
802
803
|
};
|
|
804
|
+
/**
|
|
805
|
+
* Windows desktop config directory names.
|
|
806
|
+
*
|
|
807
|
+
* Trae is a VS Code-family Electron app, and that family names its per-user
|
|
808
|
+
* data directory from the installer-registered product name — which on Windows
|
|
809
|
+
* is `product.json`'s `win32DirName`, NOT the macOS bundle spelling. Measured
|
|
810
|
+
* from the shipped bundles (2026-09-26):
|
|
811
|
+
*
|
|
812
|
+
* Trae CN -> win32DirName = "Trae CN" (applicationName trae-cn)
|
|
813
|
+
* TRAE SOLO CN -> win32DirName = "TRAE SOLO CN" (applicationName trae-solo-cn)
|
|
814
|
+
*
|
|
815
|
+
* So the macOS spellings happen to be right here, and `win32DirName` is the
|
|
816
|
+
* authority that says so. The lowercase `applicationName` spellings
|
|
817
|
+
* (`trae-cn`, `trae-solo-cn`) are probed as well because the same family uses
|
|
818
|
+
* them for the Linux config directory, and which of the two a given installer
|
|
819
|
+
* writes has never been confirmed on a real Windows host
|
|
820
|
+
* (docs/WINDOWS_TOKEN_PROBE.md). Windows file systems are case-insensitive, so
|
|
821
|
+
* listing `trae cn` beside `Trae CN` would be the same directory twice — only
|
|
822
|
+
* genuinely different spellings are listed.
|
|
823
|
+
*/
|
|
824
|
+
const WINDOWS_APP_NAMES = {
|
|
825
|
+
cn: ["Trae CN", "trae-cn"],
|
|
826
|
+
sg: ["Trae"],
|
|
827
|
+
solo: ["TRAE SOLO CN", "trae-solo-cn"],
|
|
828
|
+
"solo-sg": ["TRAE SOLO"]
|
|
829
|
+
};
|
|
830
|
+
/**
|
|
831
|
+
* One edition's plausible Windows directory spellings, in probe order.
|
|
832
|
+
*
|
|
833
|
+
* Exported so the identity reader and the credential scanner probe the SAME
|
|
834
|
+
* names: the two resolve different files (the install's `product.json` vs the
|
|
835
|
+
* per-user `storage.json`) but they describe one installation, and a spelling
|
|
836
|
+
* that works for one but not the other is a bug rather than a preference.
|
|
837
|
+
*/
|
|
838
|
+
function traeWindowsAppNames(edition) {
|
|
839
|
+
return WINDOWS_APP_NAMES[edition];
|
|
840
|
+
}
|
|
803
841
|
function traeStorageCandidates(platform = process.platform, home = homedir(), env = process.env) {
|
|
804
842
|
const result = [];
|
|
805
843
|
for (const edition of [
|
|
@@ -816,7 +854,7 @@ function traeStorageCandidates(platform = process.platform, home = homedir(), en
|
|
|
816
854
|
appNames = [app];
|
|
817
855
|
} else if (platform === "win32") {
|
|
818
856
|
roots = [env.APPDATA, join(home, "AppData", "Roaming")].filter((value, index, all) => typeof value === "string" && value !== "" && all.indexOf(value) === index);
|
|
819
|
-
appNames = [
|
|
857
|
+
appNames = WINDOWS_APP_NAMES[edition];
|
|
820
858
|
} else if (platform === "linux") {
|
|
821
859
|
roots = [env.XDG_CONFIG_HOME || join(home, ".config")];
|
|
822
860
|
appNames = LINUX_APP_NAMES[edition];
|
|
@@ -1402,7 +1440,7 @@ async function readTraeIdentity(candidate, options = {}) {
|
|
|
1402
1440
|
if (platform === "darwin") productPaths.push(join("/Applications", `${appName}.app`, "Contents", "Resources", "app", "product.json"));
|
|
1403
1441
|
else {
|
|
1404
1442
|
const localRoots = [env.LOCALAPPDATA, join(home, "AppData", "Local")].filter((value) => typeof value === "string" && value !== "").filter((value, index, all) => all.indexOf(value) === index);
|
|
1405
|
-
for (const root of localRoots) productPaths.push(join(root, "Programs",
|
|
1443
|
+
for (const root of localRoots) for (const spelling of traeWindowsAppNames(candidate.edition)) productPaths.push(join(root, "Programs", spelling, "resources", "app", "product.json"));
|
|
1406
1444
|
}
|
|
1407
1445
|
}
|
|
1408
1446
|
let product = {};
|
|
@@ -2952,6 +2990,8 @@ function createTraeRawGateway(options) {
|
|
|
2952
2990
|
//#endregion
|
|
2953
2991
|
//#region src/model-cache.ts
|
|
2954
2992
|
const execFileAsync = promisify(execFile);
|
|
2993
|
+
/** Basename of the SQLite cache sitting beside the credential document. */
|
|
2994
|
+
const TRAE_STATE_DB_FILENAME = "state.vscdb";
|
|
2955
2995
|
function positive$1(value) {
|
|
2956
2996
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
2957
2997
|
}
|
|
@@ -2979,18 +3019,59 @@ function parseTraeCachedModel(value) {
|
|
|
2979
3019
|
};
|
|
2980
3020
|
}
|
|
2981
3021
|
/**
|
|
3022
|
+
* The cache paths to try, most-specific first.
|
|
3023
|
+
*
|
|
3024
|
+
* `state.vscdb` is a SIBLING of the credential document (both sit in
|
|
3025
|
+
* `globalStorage`), so a candidate's own path is the authority for its cache —
|
|
3026
|
+
* this is why the database is derived from {@link traeStorageCandidates} rather
|
|
3027
|
+
* than re-spelled here.
|
|
3028
|
+
*
|
|
3029
|
+
* It previously hardcoded the single macOS spelling `Trae CN`, which was wrong
|
|
3030
|
+
* in two ways on Windows: `paths.ts` probes `Trae CN` AND `trae-cn`, and the
|
|
3031
|
+
* edition actually installed is often SOLO (`TRAE SOLO CN`). This module would
|
|
3032
|
+
* then point at a directory that does not exist. That went unnoticed only
|
|
3033
|
+
* because the Windows `sqlite3` dependency is absent, so the lookup failed and
|
|
3034
|
+
* callers fell back — masking the wrong path behind a different error. Sharing
|
|
3035
|
+
* one path table means a spelling that works for sign-in also works for the
|
|
3036
|
+
* cache.
|
|
3037
|
+
*/
|
|
3038
|
+
function traeStateDatabaseCandidates(options = {}) {
|
|
3039
|
+
const platform = options.platform ?? process.platform;
|
|
3040
|
+
const home = options.home ?? homedir();
|
|
3041
|
+
const env = options.env ?? process.env;
|
|
3042
|
+
const paths = [];
|
|
3043
|
+
const push = (storagePath) => {
|
|
3044
|
+
const database = join(dirname(storagePath), TRAE_STATE_DB_FILENAME);
|
|
3045
|
+
if (!paths.some((existing) => existing.toLowerCase() === database.toLowerCase())) paths.push(database);
|
|
3046
|
+
};
|
|
3047
|
+
if (options.candidate !== void 0 && options.candidate.source === "desktop") push(options.candidate.path);
|
|
3048
|
+
for (const candidate of traeStorageCandidates(platform, home, env)) {
|
|
3049
|
+
if (candidate.source !== "desktop") continue;
|
|
3050
|
+
if (options.candidate !== void 0 && candidate.edition !== options.candidate.edition) continue;
|
|
3051
|
+
push(candidate.path);
|
|
3052
|
+
}
|
|
3053
|
+
return paths;
|
|
3054
|
+
}
|
|
3055
|
+
/**
|
|
2982
3056
|
* Read Trae's own current user's model map via sqlite3 without exposing
|
|
2983
3057
|
* secrets. The sqlite3 command line is a macOS prerequisite; on Windows it is
|
|
2984
3058
|
* typically absent, so the call fails and callers fall back gracefully.
|
|
3059
|
+
*
|
|
3060
|
+
* Every candidate database is tried in order and the first that EXISTS is
|
|
3061
|
+
* queried. Existence is checked before spawning because a missing file and a
|
|
3062
|
+
* missing `sqlite3` binary are different problems: choosing the wrong directory
|
|
3063
|
+
* would otherwise surface as a confusing `sqlite3` failure, hiding a path bug
|
|
3064
|
+
* behind a dependency error.
|
|
2985
3065
|
*/
|
|
2986
3066
|
async function readTraeCachedModel(functionName, modelName, userId, options = {}) {
|
|
2987
|
-
const
|
|
2988
|
-
const
|
|
2989
|
-
const
|
|
2990
|
-
|
|
3067
|
+
const exists = options.exists ?? existsSync;
|
|
3068
|
+
const databases = traeStateDatabaseCandidates(options);
|
|
3069
|
+
const fallback = databases[0];
|
|
3070
|
+
if (fallback === void 0) throw new Error("trae: no desktop storage candidate to locate the model cache from");
|
|
3071
|
+
const database = databases.find((candidate) => exists(candidate)) ?? fallback;
|
|
2991
3072
|
const key = `${userId}_AI.agent.model.model_list_map`;
|
|
2992
3073
|
const sql = `select value from ItemTable where key=${JSON.stringify(key)} limit 1;`;
|
|
2993
|
-
const { stdout } = await execFileAsync("sqlite3", [
|
|
3074
|
+
const { stdout } = await (options.runSqlite ?? ((db, statement) => execFileAsync("sqlite3", [db, statement], { maxBuffer: 8388608 })))(database, sql);
|
|
2994
3075
|
const document = JSON.parse(stdout);
|
|
2995
3076
|
return parseTraeCachedModel((Array.isArray(document[functionName]) ? document[functionName] : []).find((item) => typeof item === "object" && item !== null && item.name === modelName));
|
|
2996
3077
|
}
|
|
@@ -3002,7 +3083,7 @@ async function resolveTraeRawRuntime(store, modelName) {
|
|
|
3002
3083
|
const candidate = store.candidates().find((item) => item.edition === credential.edition);
|
|
3003
3084
|
if (candidate === void 0) throw new Error(`no Trae ${credential.edition} storage candidate for Raw Chat identity`);
|
|
3004
3085
|
const identity = await readTraeIdentity(candidate);
|
|
3005
|
-
const cached = credential.edition === "cn" ? await readTraeCachedModel("solo_agent", modelName, credential.userId).catch(() => void 0) : void 0;
|
|
3086
|
+
const cached = credential.edition === "cn" ? await readTraeCachedModel("solo_agent", modelName, credential.userId, { candidate }).catch(() => void 0) : void 0;
|
|
3006
3087
|
return {
|
|
3007
3088
|
identity,
|
|
3008
3089
|
runtime: buildTraeRawChatRuntimeConfig(modelName, cached, {
|
|
@@ -3202,6 +3283,12 @@ var TraeUsageClient = class {
|
|
|
3202
3283
|
/**
|
|
3203
3284
|
* Daily check-in status. Read-only, and answered with or without the device
|
|
3204
3285
|
* header — the claim is what needs it.
|
|
3286
|
+
*
|
|
3287
|
+
* The read DOES carry the header whenever this installation has one, and
|
|
3288
|
+
* that is deliberate rather than incidental: `did_checked_in` is answered
|
|
3289
|
+
* per device, so omitting the header would make a device that already claimed
|
|
3290
|
+
* today look identical to one that never has (measured 2026-09-26, see
|
|
3291
|
+
* {@link TraeCheckinStatus.didCheckedIn}).
|
|
3205
3292
|
*/
|
|
3206
3293
|
async checkinStatus(signal) {
|
|
3207
3294
|
await this.requireCnRegion("check-in status");
|
|
@@ -3423,6 +3510,16 @@ function nextRegionEnabled(value, region, enabled) {
|
|
|
3423
3510
|
}
|
|
3424
3511
|
//#endregion
|
|
3425
3512
|
//#region src/web-status.ts
|
|
3513
|
+
/**
|
|
3514
|
+
* The upstream's business code for "该设备今日已参与签到" — this DEVICE already
|
|
3515
|
+
* used today's check-in (measured 2026-09-26 on a CN account whose claim was
|
|
3516
|
+
* refused with exactly this code after an account switch on the same machine).
|
|
3517
|
+
*
|
|
3518
|
+
* It arrives as HTTP 200 with a non-zero `code`, which is why it has to be
|
|
3519
|
+
* matched on the code rather than on the HTTP status: read as a transport
|
|
3520
|
+
* failure it looks like the plugin is broken, when the day is simply spent.
|
|
3521
|
+
*/
|
|
3522
|
+
const CHECKIN_DEVICE_ALREADY_CLAIMED = 9095;
|
|
3426
3523
|
/** Redact token-like content before it crosses to the browser. */
|
|
3427
3524
|
function safeMessage(error) {
|
|
3428
3525
|
return (error instanceof Error ? error.message : String(error)).replace(/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu, "[redacted token]").replace(/(\b(?:code|token|refresh_token|access_token)=)[^&\s]+/giu, "$1[redacted]").slice(0, 500);
|
|
@@ -3619,11 +3716,22 @@ function registerTraeUsageRoute(ctx, deps) {
|
|
|
3619
3716
|
/**
|
|
3620
3717
|
* Daily check-in claim — the ONLY route in this plugin that mutates
|
|
3621
3718
|
* upstream account state, so it is guarded more tightly than its siblings:
|
|
3622
|
-
* POST only, loopback origin only, and the status read runs FIRST so
|
|
3623
|
-
* already
|
|
3624
|
-
*
|
|
3625
|
-
*
|
|
3626
|
-
*
|
|
3719
|
+
* POST only, loopback origin only, and the status read runs FIRST so a day
|
|
3720
|
+
* the ACCOUNT has already been paid for never reaches the upstream claim.
|
|
3721
|
+
*
|
|
3722
|
+
* `alreadyCheckedIn` and `deviceCheckedIn` are deliberately separate
|
|
3723
|
+
* answers, because the two flags mean different things (see
|
|
3724
|
+
* {@link TraeWebCheckin}): `checkedIn` is the account's reward for today
|
|
3725
|
+
* existing, `didCheckedIn` is this MACHINE having spent its check-in —
|
|
3726
|
+
* possibly for a different account. Treating the latter as "claimed today"
|
|
3727
|
+
* was a shipped bug: after switching accounts the card said "claimed
|
|
3728
|
+
* today" and disabled the button, which is the right call for the wrong
|
|
3729
|
+
* reason and hides that the new account was never rewarded.
|
|
3730
|
+
*
|
|
3731
|
+
* The upstream is idempotent per Beijing day (verified 2026-09-24: a
|
|
3732
|
+
* repeat claim answers `code: 0` with the entitlement total unchanged), but
|
|
3733
|
+
* relying on that for correctness would put the guard in someone else's
|
|
3734
|
+
* hands.
|
|
3627
3735
|
*/
|
|
3628
3736
|
const disposeCheckin = ctx.webServer.register({
|
|
3629
3737
|
kind: "exact",
|
|
@@ -3638,16 +3746,27 @@ function registerTraeUsageRoute(ctx, deps) {
|
|
|
3638
3746
|
const client = deps.client(region);
|
|
3639
3747
|
const current = await client.checkinStatus();
|
|
3640
3748
|
if (!current.enabled) return json(res, 409, { error: "check-in is not enabled for this account" });
|
|
3641
|
-
if (current.checkedIn
|
|
3749
|
+
if (current.checkedIn) return json(res, 200, {
|
|
3642
3750
|
claimed: false,
|
|
3643
3751
|
alreadyCheckedIn: true,
|
|
3752
|
+
deviceCheckedIn: current.didCheckedIn,
|
|
3753
|
+
checkin: toCheckin(current)
|
|
3754
|
+
});
|
|
3755
|
+
if (current.didCheckedIn) return json(res, 200, {
|
|
3756
|
+
claimed: false,
|
|
3757
|
+
alreadyCheckedIn: false,
|
|
3758
|
+
deviceCheckedIn: true,
|
|
3759
|
+
code: CHECKIN_DEVICE_ALREADY_CLAIMED,
|
|
3760
|
+
message: "this device already used today's check-in",
|
|
3644
3761
|
checkin: toCheckin(current)
|
|
3645
3762
|
});
|
|
3646
3763
|
const claim = await client.claimCheckin();
|
|
3647
3764
|
const checkin = await client.checkinStatus();
|
|
3765
|
+
const deviceClaimed = claim.code === CHECKIN_DEVICE_ALREADY_CLAIMED;
|
|
3648
3766
|
json(res, 200, {
|
|
3649
3767
|
claimed: claim.claimed,
|
|
3650
3768
|
alreadyCheckedIn: false,
|
|
3769
|
+
...deviceClaimed ? { deviceCheckedIn: true } : {},
|
|
3651
3770
|
code: claim.code,
|
|
3652
3771
|
message: claim.message,
|
|
3653
3772
|
checkin: toCheckin(checkin)
|
|
@@ -3764,6 +3883,64 @@ function buildTraeModelDetailRequest(configName = "", custom = false) {
|
|
|
3764
3883
|
};
|
|
3765
3884
|
}
|
|
3766
3885
|
//#endregion
|
|
3886
|
+
//#region src/redact.ts
|
|
3887
|
+
/**
|
|
3888
|
+
* Redaction helpers for diagnostics that a user may paste into a public issue.
|
|
3889
|
+
*
|
|
3890
|
+
* A verification report is only useful if it can be shared, and it is only safe
|
|
3891
|
+
* to share if it carries no personal identifiers. Paths are the hard case:
|
|
3892
|
+
* `C:\Users\<real name>\AppData\Roaming\Trae CN\...` contains both a real
|
|
3893
|
+
* account name AND the single most diagnostic token in the whole report (the
|
|
3894
|
+
* Trae data directory spelling). Redacting the whole path would make the report
|
|
3895
|
+
* worthless; printing it whole would leak the user's name. So the user segment
|
|
3896
|
+
* is replaced and the meaningful tail is preserved.
|
|
3897
|
+
*
|
|
3898
|
+
* @module dsh-connect-trae/redact
|
|
3899
|
+
*/
|
|
3900
|
+
/**
|
|
3901
|
+
* Replace the user segment of a path with `<user>`, keeping the rest intact.
|
|
3902
|
+
*
|
|
3903
|
+
* Handles the shapes a Trae install can produce:
|
|
3904
|
+
* - `C:\Users\<name>\...` and `C:\Documents and Settings\<name>\...` (Windows)
|
|
3905
|
+
* - `/Users/<name>/...` and `/home/<name>/...` (macOS / Linux)
|
|
3906
|
+
*
|
|
3907
|
+
* Anything after that segment — edition directory, `User\globalStorage`,
|
|
3908
|
+
* `storage.json` — is preserved verbatim, because that is what a report is
|
|
3909
|
+
* actually read for. Cross-platform on purpose: the function is called by
|
|
3910
|
+
* Windows-focused diagnostics, but the same helpers run in tests and on other
|
|
3911
|
+
* hosts, and a report from the wrong platform must not leak either.
|
|
3912
|
+
*/
|
|
3913
|
+
function maskUserPath(path) {
|
|
3914
|
+
return String(path).replace(/([A-Za-z]:\\Users\\)[^\\]+/i, "$1<user>").replace(/([A-Za-z]:\\Documents and Settings\\)[^\\]+/i, "$1<user>").replace(/^(\/(?:Users|home)\/)[^/]+/, "$1<user>");
|
|
3915
|
+
}
|
|
3916
|
+
/**
|
|
3917
|
+
* Describe a name by shape instead of by value: a character count, plus whether
|
|
3918
|
+
* it is purely numeric.
|
|
3919
|
+
*
|
|
3920
|
+
* This is the deliberate middle ground for account names. A Trae account name
|
|
3921
|
+
* is often a real name or a phone number, so it must never be printed; but the
|
|
3922
|
+
* report still needs to show that an account WAS resolved, and the shape
|
|
3923
|
+
* distinguishes a real nickname from a generated `用户<n>` id — which is the
|
|
3924
|
+
* only thing a reader needs to judge whether account discovery worked.
|
|
3925
|
+
*/
|
|
3926
|
+
function describeNameShape(name) {
|
|
3927
|
+
const text = String(name ?? "");
|
|
3928
|
+
return `${text.length} 字符${/^\d+$/.test(text) ? ",纯数字" : ""}`;
|
|
3929
|
+
}
|
|
3930
|
+
/**
|
|
3931
|
+
* Describe an identifier by shape instead of by value.
|
|
3932
|
+
*
|
|
3933
|
+
* A device id (`x-device-id`) is a stable installation identifier and is
|
|
3934
|
+
* directly tied to the upstream's per-device rules, so it is never printed.
|
|
3935
|
+
* Its shape still proves which resolution path ran: a real `icube-dc` id is
|
|
3936
|
+
* 15 digits, while the fallback is a 32-character hex hash.
|
|
3937
|
+
*/
|
|
3938
|
+
function describeIdShape(value) {
|
|
3939
|
+
const text = String(value ?? "");
|
|
3940
|
+
if (text === "") return "(空)";
|
|
3941
|
+
return `${text.length} 位${/^\d+$/.test(text) ? ",纯数字" : ",含非数字"}`;
|
|
3942
|
+
}
|
|
3943
|
+
//#endregion
|
|
3767
3944
|
//#region src/raw-envelope.ts
|
|
3768
3945
|
/** Stable JSON hash candidate used by the native DTO's arg/args_hash fields. */
|
|
3769
3946
|
function hashTraeRawChatArg(arg) {
|
|
@@ -4273,4 +4450,4 @@ function apply(ctx, config) {
|
|
|
4273
4450
|
});
|
|
4274
4451
|
}
|
|
4275
4452
|
//#endregion
|
|
4276
|
-
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, SseDecoder, 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, TraeCatalog, TraeCredentialStore, TraeDelegatingUpstreamClient, TraeFallbackUpstreamClient, TraeGatedUpstreamClient, TraeRawCapabilityController, TraeRawCapabilityState, TraeRawChatUpstreamClient, TraeSoloBridge, TraeSoloRemoteCatalogClient, TraeSoloUpstreamClient, TraeUsageClient, 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 };
|
|
4453
|
+
export { Config, FALLBACK_TRAE_MODELS, FALLBACK_TRAE_MODELS_AI, REGION_GATEWAYS, SseDecoder, 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, TraeCatalog, TraeCredentialStore, TraeDelegatingUpstreamClient, TraeFallbackUpstreamClient, TraeGatedUpstreamClient, TraeRawCapabilityController, TraeRawCapabilityState, TraeRawChatUpstreamClient, TraeSoloBridge, TraeSoloRemoteCatalogClient, TraeSoloUpstreamClient, TraeUsageClient, 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 };
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-connect-trae",
|
|
3
3
|
"displayName": "DSH Connect Trae",
|
|
4
|
-
"description": "
|
|
5
|
-
"version": "2.3.
|
|
4
|
+
"description": "把本机登录的 Trae 模型接入 DeepSeek Harness:国内版与国际版双供应商并行,提供用量/积分概览与每日签到领取。",
|
|
5
|
+
"version": "2.3.1",
|
|
6
6
|
"author": "dingminhua",
|
|
7
7
|
"copyright": "Copyright (c) 2026 LaoDing",
|
|
8
8
|
"license": "MIT",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"lib",
|
|
35
35
|
"icons",
|
|
36
36
|
"docs/assets/dsh-connect-trae-usage-card.png",
|
|
37
|
+
"scripts/verify-windows.mjs",
|
|
37
38
|
"screenshots.json",
|
|
38
39
|
"cordis.patch.yml",
|
|
39
40
|
"README.md",
|