dsh-tap 0.20.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.
Files changed (121) hide show
  1. package/AGENTS.md +99 -0
  2. package/CHANGELOG.md +751 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +59 -0
  5. package/README.md +256 -0
  6. package/cordis.patch.yml +385 -0
  7. package/core/bridge.js +698 -0
  8. package/core/json-store.js +91 -0
  9. package/core/rotation.js +108 -0
  10. package/core/usage-meter.js +176 -0
  11. package/docs/diagnosis-cache-quota.md +181 -0
  12. package/docs/diagnosis-qoder-flash.md +67 -0
  13. package/docs/diagnosis-trae-3003.md +302 -0
  14. package/docs/goals/bridge-port-host-split.md +91 -0
  15. package/docs/goals/desktop-adaptation.md +106 -0
  16. package/docs/goals/qoder-cn-provider-design.md +308 -0
  17. package/docs/goals/settings-card-ux-redesign-plan.md +1680 -0
  18. package/docs/goals/settings-card-ux-redesign.md +162 -0
  19. package/docs/goals/trae-agent-v3.md +41 -0
  20. package/docs/goals/trae-work-cn-repair.md +44 -0
  21. package/docs/goals/v0.8-/351/242/235/345/272/246/345/217/257/350/247/201-/346/250/241/345/236/213/345/212/250/346/200/201/345/214/226-/345/244/232/346/234/215/345/212/241/345/225/206.md +85 -0
  22. package/docs/pitfalls.md +105 -0
  23. package/docs/reverse/trae-cloud-api.md +218 -0
  24. package/docs/reverse/trae-model-catalog.md +129 -0
  25. package/docs/reverse/traework-cn.md +520 -0
  26. package/docs/rules/STATE.md +198 -0
  27. package/docs/rules/content-moderation.md +54 -0
  28. package/docs/rules/dev-role-boundary.md +94 -0
  29. package/docs/rules/extra-providers.md +42 -0
  30. package/docs/rules/gateway-facts.md +91 -0
  31. package/docs/rules/oauth-handshake.md +76 -0
  32. package/docs/rules/prompt-cache.md +93 -0
  33. package/docs/rules/quota-signals.md +125 -0
  34. package/docs/rules/routing.md +84 -0
  35. package/docs/rules/templates/oauth-reverse-checklist.md +42 -0
  36. package/docs/rules/trae-surface.md +242 -0
  37. package/docs/rules/ua-validation.md +81 -0
  38. package/host-config.js +282 -0
  39. package/index.js +2306 -0
  40. package/lib/client.js +2893 -0
  41. package/local-scan.js +104 -0
  42. package/package.json +82 -0
  43. package/providers/ark/index.js +11 -0
  44. package/providers/bailian/index.js +10 -0
  45. package/providers/bigmodel/index.js +11 -0
  46. package/providers/codebuddy/agenttool.js +122 -0
  47. package/providers/codebuddy/catalog.js +227 -0
  48. package/providers/codebuddy/errors.js +44 -0
  49. package/providers/codebuddy/headers.js +36 -0
  50. package/providers/codebuddy/images.js +125 -0
  51. package/providers/codebuddy/index.js +123 -0
  52. package/providers/codebuddy/oauth.js +279 -0
  53. package/providers/deepseek/index.js +11 -0
  54. package/providers/moonshot/index.js +11 -0
  55. package/providers/openai-compat.js +177 -0
  56. package/providers/openrouter/index.js +27 -0
  57. package/providers/qoder/catalog.js +145 -0
  58. package/providers/qoder/cosy.js +419 -0
  59. package/providers/qoder/gateway.js +563 -0
  60. package/providers/qoder/index.js +116 -0
  61. package/providers/qoder/oauth.js +364 -0
  62. package/providers/qoder/qoder_auth.wasm +0 -0
  63. package/providers/qoder/quota.js +56 -0
  64. package/providers/qwen/index.js +15 -0
  65. package/providers/tool-pairing.js +129 -0
  66. package/providers/trae/catalog.js +103 -0
  67. package/providers/trae/errors.js +85 -0
  68. package/providers/trae/gateway.js +853 -0
  69. package/providers/trae/index.js +126 -0
  70. package/providers/trae/oauth.js +443 -0
  71. package/providers/trae/quota.js +75 -0
  72. package/providers/trae/remote.js +365 -0
  73. package/scripts/capture-cache.mjs +65 -0
  74. package/scripts/capture-traffic.mjs +83 -0
  75. package/scripts/hermes-probe-dev-role.mjs +263 -0
  76. package/scripts/measure-latency.mjs +253 -0
  77. package/scripts/probe-ark-thinking.mjs +298 -0
  78. package/scripts/probe-cache-decline.mjs +292 -0
  79. package/scripts/probe-cache-ttl.mjs +221 -0
  80. package/scripts/probe-cache.mjs +156 -0
  81. package/scripts/probe-codebuddy-efforts.mjs +355 -0
  82. package/scripts/probe-codebuddy-tier-wiring.mjs +244 -0
  83. package/scripts/probe-effort-gaps.mjs +133 -0
  84. package/scripts/probe-media.mjs +115 -0
  85. package/scripts/probe-moderation.mjs +159 -0
  86. package/scripts/probe-oauth.mjs +617 -0
  87. package/scripts/probe-qoder-attribution-arm8.mjs +92 -0
  88. package/scripts/probe-qoder-attribution-arm9.mjs +102 -0
  89. package/scripts/probe-qoder-attribution.mjs +266 -0
  90. package/scripts/probe-qoder-flash-confirm.mjs +94 -0
  91. package/scripts/probe-qoder-live.mjs +344 -0
  92. package/scripts/probe-qoder-matrix.mjs +274 -0
  93. package/scripts/probe-qoder-null-content.mjs +153 -0
  94. package/scripts/probe-qoder-pairing.mjs +308 -0
  95. package/scripts/probe-qoder-quota.mjs +162 -0
  96. package/scripts/probe-qoder-thinking-config.mjs +52 -0
  97. package/scripts/probe-qoder-thinking-efforts.mjs +269 -0
  98. package/scripts/probe-quota.mjs +136 -0
  99. package/scripts/probe-quota2.mjs +144 -0
  100. package/scripts/probe-routing.mjs +226 -0
  101. package/scripts/probe-trae-3003-diagnosis.mjs +139 -0
  102. package/scripts/probe-trae-agent-v3.mjs +399 -0
  103. package/scripts/probe-trae-efforts.mjs +149 -0
  104. package/scripts/probe-trae-live.mjs +147 -0
  105. package/scripts/probe-trae-max-effort.mjs +179 -0
  106. package/scripts/probe-trae-model-routing.mjs +381 -0
  107. package/scripts/probe-trae-thinking-scene.mjs +238 -0
  108. package/scripts/probe-trae-transport-outage.mjs +176 -0
  109. package/scripts/probe-ua.mjs +508 -0
  110. package/scripts/trae-model-catalog.mjs +632 -0
  111. package/scripts/verify-agents-md.mjs +45 -0
  112. package/scripts/verify-bridge.mjs +1041 -0
  113. package/scripts/verify-core-generic.mjs +302 -0
  114. package/scripts/verify-desktop-acceptance.mjs +184 -0
  115. package/scripts/verify-host-config.mjs +265 -0
  116. package/scripts/verify-models.mjs +390 -0
  117. package/scripts/verify-providers.mjs +255 -0
  118. package/scripts/verify-qoder-provider.mjs +1020 -0
  119. package/scripts/verify-rotation.mjs +308 -0
  120. package/scripts/verify-trae-model-catalog.mjs +284 -0
  121. package/scripts/verify-trae-provider.mjs +1451 -0
@@ -0,0 +1,129 @@
1
+ # TraeWork CN 模型目录只读提取器
2
+
3
+ `scripts/trae-model-catalog.mjs` 从本机 Windows 版 TRAE SOLO CN / TraeWork CN 的 VS Code
4
+ 全局状态数据库中**离线、只读**地提取模型缓存(`AI.agent.model.model_list_map`),生成稳定
5
+ JSON 目录与人类可读 Markdown 表格。上游背景见 [traework-cn.md](./traework-cn.md)。
6
+
7
+ ## 1. 这是什么
8
+
9
+ - 数据源:`%APPDATA%\TRAE SOLO CN\User\globalStorage\state.vscdb`(SQLite,表
10
+ `ItemTable(key TEXT, value BLOB)`),关键 key 形如
11
+ `<user_id>:AI.agent.model.model_list_map` 与 `<user_id>_AI.agent.model.model_list_map`,
12
+ value 为按 function/category 分组的模型 JSON。
13
+ - 输出:去重后的模型目录(同模型跨 category 合并,差异保留在 `categoryProfiles`)。
14
+ - 仅此而已:**不做 OAuth、不做聊天、不调用云端接口、不提取凭据**。
15
+
16
+ ## 2. 安全边界
17
+
18
+ - **绝不读取/打印/保存** token、refresh token、API key、secret。条目中的 `ak`/`sk` 等
19
+ 字段在归一化时被丢弃,且成品再过一道递归 scrub(精确名匹配,故 `promptMaxTokens`
20
+ 这类含 "token" 字样的字段不受影响)。
21
+ - 禁删名单(键名小写、去非字母数字后精确匹配):`ak`、`sk`、`token`、`secret`、
22
+ `password`、`authorization`、`credential`、`apiKey`/`api_key`、`refreshToken`、
23
+ `sessionToken`、`encrypted_model_params`。
24
+ - 输出只含 SHA-256 前 12 位指纹(db 路径 / itemKey / user_id),**不含明文 user_id、
25
+ 完整 itemKey、原始 db 路径**。
26
+ - 只输出模型技术信息;账号资料、`base_url`、`commercial_info` 等非白名单字段一律忽略,
27
+ warnings 只记录字段名、不记录值。
28
+ - 原始 `state.vscdb` 与数据库 dump 永不进仓库;本工具每次运行前先把数据库(连同
29
+ `-wal`/`-shm` 若存在)复制到临时目录再打开副本,Windows 侧应用占用与否都不受影响。
30
+
31
+ ## 3. 如何运行
32
+
33
+ 需要带 `node:sqlite` 的 Node(22.5+,23.4+/24 无需 flag)。
34
+
35
+ ```sh
36
+ # 自动发现数据库(扫描 /mnt/c/Users/*/AppData/Roaming/{TRAE SOLO CN,TraeWork CN}/…,取 mtime 最新)
37
+ node scripts/trae-model-catalog.mjs --pretty
38
+
39
+ # 指定数据库
40
+ node scripts/trae-model-catalog.mjs \
41
+ --db "/mnt/c/Users/<user>/AppData/Roaming/TRAE SOLO CN/User/globalStorage/state.vscdb" \
42
+ --out docs/probes/trae-model-catalog.json \
43
+ --md docs/probes/trae-model-catalog.md \
44
+ --pretty
45
+
46
+ # 本地 stdout 列出候选 key、长度、指纹(不写文件)
47
+ node scripts/trae-model-catalog.mjs --list-keys
48
+
49
+ # 只解析某个候选 key / 输出全部候选
50
+ node scripts/trae-model-catalog.mjs --key "<完整 itemKey>" --pretty
51
+ node scripts/trae-model-catalog.mjs --all --pretty
52
+ ```
53
+
54
+ 选项:`--db`、`--out`(默认 `docs/probes/trae-model-catalog.json`)、`--md`(默认
55
+ `docs/probes/trae-model-catalog.md`)、`--pretty`、`--list-keys`、`--key`、`--all`。
56
+ `--key` 与 `--all` 互斥。
57
+
58
+ 默认候选选择规则:模型条目总数最多 → value 字节最长 → key 字典序最小。
59
+
60
+ 离线回归(fixture 全断言,本机有真实库时追加一次端到端真实提取,输出只落临时目录):
61
+
62
+ ```sh
63
+ npm run verify:trae
64
+ ```
65
+
66
+ ## 4. 如何查看输出
67
+
68
+ - `docs/probes/trae-model-catalog.md`:一眼看全模型表(列含 id / openaiCompatibleId /
69
+ displayName / provider / multimodal / contextWindowDefault / contextWindowMax /
70
+ maxOutputTokens / maxTurns / categories,按 displayName 再按 id 排序),底部 warnings
71
+ 列出被忽略/被移除的字段名。
72
+ - `docs/probes/trae-model-catalog.json`:机器可读版,结构与下节一致;`--all` 模式为
73
+ `{schemaVersion, kind: "trae-model-catalog-multi", candidates: [...]}` 信封。
74
+
75
+ ## 5. JSON 字段说明
76
+
77
+ ```
78
+ schemaVersion 固定 1
79
+ source 来源描述:kind、dbPathFingerprint、itemKeyFingerprint、
80
+ userIdFingerprint(均 sha256 前 12 位)、generatedAt(ISO8601)
81
+ functions 按 category 分组的 {id, displayName} 列表(assistant、solo_agent_lite…)
82
+ models[] 去重后的模型条目(见下)
83
+ warnings[] 排序去重后的告警(忽略字段名、敏感字段移除、跳过的坏条目等)
84
+ ```
85
+
86
+ 模型条目字段:
87
+
88
+ | 字段 | 来源/规则 |
89
+ |---|---|
90
+ | `id` | 稳定 id:`config_name` > `name` > `display_name` |
91
+ | `openaiCompatibleId` | id 的 slug:非 `[A-Za-z0-9_-]` 一律替换为 `-`(**含点号**,样例契约 `glm-5.3`→`glm-5-3`) |
92
+ | `configName` / `displayName` | 原字段;displayName 缺失时回落 name/id |
93
+ | `provider` | 第三方 provider(空串归一 null) |
94
+ | `modelType` | `reasoning_model` / `chat_model` |
95
+ | `multimodal` / `input` | true → `["text","image"]`,否则 `["text"]` |
96
+ | `promptMaxTokens` | `prompt_max_tokens` |
97
+ | `contextWindowDefault` | `context_window_size.default` |
98
+ | `contextWindowMax` | `context_window_size.max`,数字或数组原样保留 |
99
+ | `maxOutputTokens` | `max_tokens` |
100
+ | `maxTurns` | `max_turns`(数字或 `{default,max}` 取 max 优先)回落 `max_turn` |
101
+ | `isDefault` / `isPreset` / `selectable` / `status` | 布尔化(缺省 null) |
102
+ | `feeModelLevel` | `fee_model_level` |
103
+ | `reasoningEffortOptions` | `reasoning_effort_options` 原样透传(递归 scrub 后) |
104
+ | `categories` | 出现过的全部 category(源顺序) |
105
+ | `categoryProfiles` | 每个 category 下与合并值不同的限制字段(`promptMaxTokens`、`contextWindowDefault`、`contextWindowMax`、`maxOutputTokens`、`maxTurns`);相同则为 `{}` |
106
+ | `technical` | 白名单技术字段:`temperature`、`top_p`、`top_k`、`thinking_enable`、`tags`、`features` |
107
+
108
+ 合并规则:同一 id 首次出现者定基线(限制/标签取首个),`isDefault` 跨 category 取或,
109
+ `provider`/`reasoningEffortOptions` 取首个非空;限制差异全部落在 `categoryProfiles`。
110
+
111
+ ## 6. 当前限制
112
+
113
+ - 只读本地缓存:快照可能滞后于云端目录(IDE 下次启动/刷新才更新)。
114
+ - 跨 category 的 `displayName`/`modelType`/`multimodal`/`technical` 差异只保留首个
115
+ 出现值(限制类字段才有 per-category 记录)。
116
+ - 非 `[A-Za-z0-9_-]` 字符统一折叠为 `-`,`deepseek//x` 会变成 `deepseek--x`,无法还原。
117
+ - `warnings` 中"忽略字段"按字段名全局去重,不区分 category。
118
+ - 依赖 `node:sqlite`(Node 22.5+);在非 WSL/无 `/mnt/c` 环境自动发现返回空,需 `--db`。
119
+ - `--all` 输出的多候选信封与单候选结构不同,消费方需按 `candidates` 字段分支。
120
+
121
+ ## 7. 与后续 OAuth/chat 桥的关系
122
+
123
+ 这是 traework-cn.md「最小适配方案」第 1 步(本地只读桥)。后续若做聊天能力:
124
+
125
+ - 模型目录可由本工具的 JSON 直接生成静态清单(对应 CodeBuddy 插件的
126
+ catalog 同步层),无需先破解 `POST /api/ide/v1/get_model_list` 网络协议;
127
+ - 聊天需要 `Cloud-IDE-JWT` / `x-cloudide-token` 认证与设备 ECDSA 签名 refresh,
128
+ 建议仍走"本地桥收口凭据"路线(对应 CodeBuddy 的流式桥 + 凭据边缘层),
129
+ 本工具**不**为该步骤读取任何凭据。
@@ -0,0 +1,520 @@
1
+ # TraeWork CN / TRAE SOLO CN OAuth 与模型目录逆向档案
2
+
3
+ > 结论时间:2026-08-23
4
+ > 目标:Windows 安装版 `TRAE SOLO CN`,产品名 `TraeWork CN`。
5
+ > 方法:只做本地静态分析、日志/缓存结构分析和公开配置请求;不读取、输出或外传任何 token / key。
6
+
7
+ ## 目标版本与身份
8
+
9
+ 安装路径:
10
+
11
+ ```text
12
+ C:\Users\<user>\AppData\Local\Programs\TRAE SOLO CN
13
+ ```
14
+
15
+ 关键元数据:
16
+
17
+ | 项 | 值 |
18
+ |---|---|
19
+ | 产品名 | `TRAE SOLO CN` |
20
+ | Windows 显示名 | `TraeWork CN` / `TRAE Work` |
21
+ | App 版本 | `0.1.52` |
22
+ | VS Code fork 版本 | `1.107.1` |
23
+ | Build | `2.3.73734` |
24
+ | packageType | `stable_cn` |
25
+ | quality | `stable` |
26
+ | URL protocol | `solo-cn://` |
27
+ | 配置域 | `api.trae.com.cn` |
28
+ | 当前账号 API host | `https://api.trae.cn` |
29
+
30
+ 证据文件:
31
+
32
+ ```text
33
+ resources/app/product.json
34
+ resources/app/package.json
35
+ manifest.json
36
+ logs/<run>/main.log
37
+ logs/<run>/dynamicConfig.log
38
+ ```
39
+
40
+ ---
41
+
42
+ ## OAuth / 登录流程
43
+
44
+ ### 1. 本地回调服务
45
+
46
+ 登录时应用会在本机随机端口启动 HTTP 服务,只绑定回环地址:
47
+
48
+ ```text
49
+ http://127.0.0.1:<random_port>
50
+ ```
51
+
52
+ 相关路径:
53
+
54
+ | 路径 | 用途 |
55
+ |---|---|
56
+ | `/authorize` | 接收授权结果 / auth code |
57
+ | `/login-confirm` | 部分旧式本地登录确认流 |
58
+ | `/login-success` | 登录成功提示页 |
59
+
60
+ 源码模块名:
61
+
62
+ ```text
63
+ out-build/vs/code/electron-main/oauth/oauthLocalServer.js
64
+ out-build/vs/code/electron-main/oauth/userLogin/loginService.js
65
+ out-build/vs/code/electron-main/oauth/userLogin/loginUrlBuilder.js
66
+ out-build/vs/code/electron-main/oauth/marscode/request.js
67
+ out-build/vs/code/electron-main/oauth/marscode/oauthService.js
68
+ ```
69
+
70
+ ### 2. PKCE
71
+
72
+ 客户端生成:
73
+
74
+ ```text
75
+ code_verifier = 48 bytes -> base64url
76
+ code_challenge = SHA256(code_verifier) -> base64url
77
+ method = S256
78
+ ```
79
+
80
+ `code_verifier` 只保存在本地登录会话中,等回调拿到 auth code 后用于换 token。
81
+
82
+ ### 3. 授权页 URL
83
+
84
+ 对 SOLO CN,`auth_from=solo`。常见授权 URL 形态如下:
85
+
86
+ ```http
87
+ https://<login-host>/authorization
88
+ ?login_version=1
89
+ &auth_from=solo
90
+ &login_channel=native_ide
91
+ &plugin_version=2.3.73734
92
+ &auth_type=local
93
+ &client_id=<client_id>
94
+ &redirect=0
95
+ &login_trace_id=<uuid>
96
+ &auth_callback_url=http%3A%2F%2F127.0.0.1%3A<port>%2Fauthorize
97
+ &machine_id=<machine_id>
98
+ &device_id=<device_id>
99
+ &x_device_id=<device_id>
100
+ &x_machine_id=<machine_id>
101
+ &x_device_brand=<device_brand_or_model>
102
+ &x_device_type=<os_name>
103
+ &x_os_version=<os_version>
104
+ &x_app_version=0.1.52
105
+ &x_app_type=stable
106
+ &code_challenge=<code_challenge>
107
+ &code_challenge_method=S256
108
+ &hide_saas_login=true
109
+ ```
110
+
111
+ SOLO Lite 分支默认 `client_id` 为:
112
+
113
+ ```text
114
+ en1oxy7wnw8j9n
115
+ ```
116
+
117
+ 普通 TRAE 分支默认值为:
118
+
119
+ ```text
120
+ ono9krqynydwx5
121
+ ```
122
+
123
+ 实际运行时可被远端动态配置覆盖。
124
+
125
+ ### 4. 回调参数
126
+
127
+ 浏览器完成登录后,远端会跳回:
128
+
129
+ ```text
130
+ http://127.0.0.1:<port>/authorize?...
131
+ ```
132
+
133
+ 本地代码会解析 query。关键字段包括:
134
+
135
+ | 字段 | 说明 |
136
+ |---|---|
137
+ | `userInfo` | JSON 字符串,包含用户资料 |
138
+ | `authCodeInfo` | JSON 字符串,内部含 `AuthCode` |
139
+ | `codeVerifier` | 本地处理时会补充进去 |
140
+ | `consoleHost` | 可选,后续 API host |
141
+ | `error_code` / `error_msg` | 失败信息 |
142
+ | `originCredential` | 原始凭据引用,本地保留 |
143
+
144
+ ### 5. Auth Code 换 Token
145
+
146
+ 端点:
147
+
148
+ ```http
149
+ POST https://<api-host>/trae/api/v3/oauth/ExchangeToken
150
+ Content-Type: application/json
151
+ ```
152
+
153
+ Auth Code 模式请求体:
154
+
155
+ ```json
156
+ {
157
+ "ClientID": "<client_id>",
158
+ "AuthCode": "<auth_code>",
159
+ "CodeVerifier": "<pkce_code_verifier>",
160
+ "DeviceInfo": {
161
+ "DeviceID": "<device_id>",
162
+ "MachineID": "<machine_id>",
163
+ "PlatformCode": "SOLO_PC",
164
+ "DeviceType": "PC",
165
+ "DeviceName": "<device_display_name>",
166
+ "DeviceModel": "<device_model>",
167
+ "ClientVersion": "0.1.52",
168
+ "DevicePublicKey": "<ec_p256_spki_public_key>",
169
+ "DeviceBrand": "<manufacturer>",
170
+ "DeviceCPU": "<cpu>",
171
+ "OSInfo": "<os_name>",
172
+ "OSVersion": "<os_version>"
173
+ },
174
+ "IDEVersion": "0.1.52"
175
+ }
176
+ ```
177
+
178
+ 响应核心字段在 `Result` 下:
179
+
180
+ ```json
181
+ {
182
+ "Result": {
183
+ "Token": "<access_token>",
184
+ "RefreshToken": "<refresh_token>",
185
+ "TokenExpireAt": 1234567890,
186
+ "TokenExpireDuration": 123456,
187
+ "RefreshExpireAt": 1234567890
188
+ }
189
+ }
190
+ ```
191
+
192
+ 随后用返回的 `Token` 调用户信息接口。
193
+
194
+ ### 6. Refresh Token 刷新
195
+
196
+ 同一 ExchangeToken 端点支持刷新模式:
197
+
198
+ ```http
199
+ POST https://<api-host>/trae/api/v3/oauth/ExchangeToken
200
+ Content-Type: application/json
201
+ ```
202
+
203
+ 请求体:
204
+
205
+ ```json
206
+ {
207
+ "ClientID": "<client_id>",
208
+ "ClientSecret": "",
209
+ "RefreshToken": "<refresh_token>",
210
+ "DeviceInfo": {
211
+ "DeviceID": "<device_id>",
212
+ "MachineID": "<machine_id>",
213
+ "PlatformCode": "SOLO_PC",
214
+ "DeviceType": "PC",
215
+ "DeviceName": "...",
216
+ "DeviceModel": "...",
217
+ "ClientVersion": "0.1.52",
218
+ "DevicePublicKey": "...",
219
+ "DeviceBrand": "...",
220
+ "DeviceCPU": "...",
221
+ "OSInfo": "...",
222
+ "OSVersion": "..."
223
+ },
224
+ "DeviceProof": {
225
+ "Signature": "<base64_ecdsa_p256_signature>",
226
+ "Timestamp": <unix_seconds>,
227
+ "Nonce": "<32_hex_random>"
228
+ },
229
+ "IDEVersion": "0.1.52"
230
+ }
231
+ ```
232
+
233
+ 签名算法为 ECDSA P-256 / SHA-256。待签名字符串按换行拼接:
234
+
235
+ ```text
236
+ POST
237
+ /trae/api/v3/oauth/ExchangeToken
238
+ <ClientID>
239
+ <RefreshToken>
240
+ <Timestamp>
241
+ <Nonce>
242
+ ```
243
+
244
+ 私钥为首次登录/设备注册时生成的 P-256 PKCS#8 私钥,按 DeviceID 缓存在本地安全存储中。
245
+
246
+ ### 7. 账号与会话辅助端点
247
+
248
+ | 端点 | 方法 | 说明 |
249
+ |---|---|---|
250
+ | `POST /cloudide/api/v3/trae/CheckLogin` | POST | 校验登录态;body 含 `IDEVersion`、`ReqSource`、`GetAIPayHost:true` |
251
+ | `POST /cloudide/api/v3/trae/GetUserInfo` | POST | 获取用户资料;header `x-cloudide-token` |
252
+ | `POST /cloudide/api/v3/trae/GenerateTempToken` | POST | 生成临时 token |
253
+ | `POST /cloudide/api/v3/trae/oauth/ClearRefreshToken` | POST | 注销 refresh token |
254
+
255
+ 认证 header 形态:
256
+
257
+ ```text
258
+ Authorization: Cloud-IDE-JWT <token>
259
+ x-cloudide-token: <token>
260
+ X-User-Region: CN
261
+ ```
262
+
263
+ 不同路径可能分别使用 `Authorization` 或 `x-cloudide-token`。
264
+
265
+ ### 8. 动态配置
266
+
267
+ 启动时拉取无鉴权动态配置:
268
+
269
+ ```http
270
+ GET https://api.trae.com.cn/icube/api/v1/native/config/query
271
+ ```
272
+
273
+ 查询参数包括:
274
+
275
+ ```text
276
+ mid
277
+ did
278
+ uid
279
+ userRegion=CN
280
+ packageType=stable_cn
281
+ productCode=SOLO_Lite
282
+ platform=Win
283
+ branch=release_solo_win32_cn
284
+ arch=x64
285
+ tenant=marscode
286
+ appVersion=0.1.52
287
+ buildVersion=2.3.73734
288
+ ```
289
+
290
+ 响应 `data` 为加密块,由客户端 SDK 解密后合并成运行时 boot config。
291
+
292
+ ---
293
+
294
+ ## 模型列表
295
+
296
+ ### 1. 云端模型列表端点
297
+
298
+ 从本地 Rust harness 二进制中提取到以下模型相关路由:
299
+
300
+ | 路径 | 说明 |
301
+ |---|---|
302
+ | `POST /api/ide/v1/get_model_list` | 按 function 批量获取模型列表 |
303
+ | `POST /api/ide/v1/model_list` | 模型列表相关路由 |
304
+ | `POST /api/ide/v1/batch_get_detail_param` | 批量详情参数 |
305
+ | `POST /api/ide/v1/providers` | 自定义 provider 列表 |
306
+ | `POST /api/ide/v1/add_custom_model` | 添加自定义模型 |
307
+ | `POST /api/ide/v1/update_custom_model` | 更新自定义模型 |
308
+ | `POST /api/agent/v3/custom_model_connectivity_check` | 自定义模型连通性检查 |
309
+
310
+ Rust 侧请求结构名:
311
+
312
+ ```rust
313
+ GetModelListByFunctionRequest {
314
+ functions: Vec<String>,
315
+ force_refresh: bool,
316
+ }
317
+ ```
318
+
319
+ 因此云端请求形态大致为:
320
+
321
+ ```http
322
+ POST https://<api-host>/api/ide/v1/get_model_list
323
+ Authorization: Cloud-IDE-JWT <token>
324
+ Content-Type: application/json
325
+
326
+ {
327
+ "functions": [
328
+ "solo_agent_lite",
329
+ "solo_work_lite"
330
+ ],
331
+ "force_refresh": false
332
+ }
333
+ ```
334
+
335
+ 已确认的 function / category 名称包括:
336
+
337
+ ```text
338
+ assistant
339
+ agent
340
+ builder
341
+ builder_v3
342
+ chat_v3
343
+ code_reviewer
344
+ code_review_summary
345
+ refactor
346
+ solo_agent
347
+ solo_agent_lite
348
+ solo_agent_remote
349
+ solo_coder
350
+ solo_work_lite
351
+ solo_work_remote
352
+ solo_design_lite
353
+ solo_design_remote
354
+ dsl_agent
355
+ voice_chat
356
+ voice_transcription
357
+ voice_summary
358
+ ```
359
+
360
+ ### 2. 本地缓存位置
361
+
362
+ VS Code 全局状态数据库:
363
+
364
+ ```text
365
+ %APPDATA%\TRAE SOLO CN\User\globalStorage\state.vscdb
366
+ ```
367
+
368
+ 表:
369
+
370
+ ```sql
371
+ ItemTable(key TEXT, value BLOB)
372
+ ```
373
+
374
+ 关键 key:
375
+
376
+ ```text
377
+ <user_id>:AI.agent.model.model_list_map
378
+ <user_id>_AI.agent.model.model_list_map
379
+ <user_id>:AI.agent.model.session_selected_model
380
+ <user_id>:AI.agent.model.recent_user_selection_by_agent_label
381
+ <user_id>:AI.agent.model.max_mode_by_agent_model
382
+ ```
383
+
384
+ 其中 `model_list_map` 是 JSON,顶层按 function/category 分组。
385
+
386
+ 示例结构:
387
+
388
+ ```json
389
+ {
390
+ "assistant": [ { "name": "...", "display_name": "...", "context_window_size": {} } ],
391
+ "solo_agent_lite": [ { "name": "...", "config_name": "..." } ],
392
+ "solo_work_lite": [ { "name": "...", "max_tokens": 32768 } ]
393
+ }
394
+ ```
395
+
396
+ > 注意:自定义模型条目里存在 `ak` / `sk` 类字段,`state.vscdb` 应视为敏感文件,不要直接提交或分享。
397
+
398
+ ### 3. ModelConfig 主要字段
399
+
400
+ 本地缓存的每个模型条目包含大量字段,常用字段如下:
401
+
402
+ | 字段 | 含义 |
403
+ |---|---|
404
+ | `name` | 协议层模型名 / config 名 |
405
+ | `display_name` | UI 展示名 |
406
+ | `provider` | 第三方 provider,例如 `deepseek`、`volcengine-agent-plan` |
407
+ | `multimodal` | 是否支持多模态输入 |
408
+ | `model_type` | `reasoning_model` 或 `chat_model` |
409
+ | `prompt_max_tokens` | prompt 上限 |
410
+ | `context_window_size.default` | 默认上下文窗口 |
411
+ | `context_window_size.max` | 最大上下文窗口,可能是数组 |
412
+ | `max_tokens` | 输出上限 |
413
+ | `max_turn` / `max_turns` | agent 最大轮次 |
414
+ | `is_default` | 是否默认模型 |
415
+ | `is_preset` | 是否内置预设 |
416
+ | `selectable` | 是否可选 |
417
+ | `status` | 是否启用 |
418
+ | `fee_model_level` | 计费档位 |
419
+ | `commercial_info` | 商业化/用量展示信息 |
420
+ | `features` | reasoning、multimodal、context window、consumption rate 等 |
421
+
422
+ ---
423
+
424
+ ## 当前缓存中的模型清单
425
+
426
+ 以下来自当前用户缓存 `AI.agent.model.model_list_map`,按 `config_name` 去重。数值单位为 token;“ctx max” 若为数组表示协议里允许多档上限。
427
+
428
+ | config_name | 展示名 | 多模态 | 类型 | prompt 上限 | ctx default | ctx max | 输出上限 | 最大 turns |
429
+ |---|---|---:|---|---:|---:|---:|---:|---:|
430
+ | `Doubao-Seed-Evolving` | Seed-Evolving | ✔ | reasoning | 936000 | 200000 | 1000000 | 64000 | 2000 |
431
+ | `Doubao-Seed-2.1-Pro` | Seed-2.1-Pro | ✔ | reasoning | 168000–200000 | 200000 | 200000 | 32000/32768 | 500 |
432
+ | `Doubao-Seed-2.1-Turbo` | Seed-2.1-Turbo | ✔ | reasoning | 168000–200000 | 200000 | 200000 | 32000/32768 | 500 |
433
+ | `Doubao-Seed-Code` | Seed-Code | ✔ | reasoning | 168000 | 184000 | 184000 | 16000 | 500 |
434
+ | `Doubao-Seed-2.0-Code` | Doubao-Seed-2.0-Code | ✔ | reasoning | 168000 | 184000 | 184000 | 16000 | 200 |
435
+ | `glm-5.3` | GLM-5.3 | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
436
+ | `glm-5.2` | GLM-5.2 | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
437
+ | `glm-5.1` | GLM-5.1 | ✘ | reasoning | 168000 | 200000 | 200000 | 32000 | 200 |
438
+ | `glm-5` | GLM-5 | ✘ | reasoning | 168000 | 200000 | 200000 | 32000 | 200 |
439
+ | `glm-5v-turbo` | GLM-5V-Turbo | ✔ | reasoning | 168000 | 200000 | 200000 | 32000 | 200 |
440
+ | `DeepSeek-V4-Pro-Official` | DeepSeek-V4-Pro 正式版 | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
441
+ | `DeepSeek-V4-Pro` | DeepSeek-V4-Pro | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
442
+ | `DeepSeek-V4-Flash-Official` | DeepSeek-V4-Flash 正式版 | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
443
+ | `DeepSeek-V4-Flash` | DeepSeek-V4-Flash | ✘ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
444
+ | `kimi-k3` | Kimi-K3 | ✔ | chat | 936000 | 200000 | 1000000 | 64000 | 500 |
445
+ | `kimi-k2.7-code` | Kimi-K2.7-Code | ✔ | chat | 168000 | 200000 | - | 32000 | 500 |
446
+ | `kimi-k2.6` | Kimi-K2.6 | ✔ | chat | 168000 | 200000 | 200000 | 32000 | 500 |
447
+ | `kimi-k2.5` | Kimi-K2.5 | ✔ | chat | 168000 | 200000 | 200000 | 32000 | 200 |
448
+ | `minimax-m3` | MiniMax-M3 | ✔ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
449
+ | `minimax-m2.7` | MiniMax-M2.7 | ✘ | reasoning | 168000 | 200000 | 200000 | 32000 | 200 |
450
+ | `qwen3.8-max` | Qwen3.8-Max | ✔ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
451
+ | `qwen-3.7-plus` | Qwen3.7-Plus | ✔ | reasoning | 936000 | 200000 | 1000000 | 64000 | 500 |
452
+ | `qwen-3.6-plus` | Qwen3.6-Plus | ✔ | reasoning | 168000 | 200000 | - | 32000 | 200 |
453
+ | `qwen-3.5` | Qwen3.5-Plus | ✔ | reasoning | 168000 | 200000 | - | 32000 | 200 |
454
+
455
+ 另有第三方/provider 型自定义或托管条目:
456
+
457
+ | config_name | provider | 说明 |
458
+ |---|---|---|
459
+ | `deepseek//deepseek-v4-pro` | `deepseek` | 用户侧 DeepSeek 直连/代理条目 |
460
+ | `deepseek//deepseek-v4-flash` | `deepseek` | 用户侧 DeepSeek 直连/代理条目 |
461
+ | `volcengine-agent-plan//deepseek-v4-flash` | `volcengine-agent-plan` | Volcengine Agent Plan 条目 |
462
+
463
+ 旧 function 缓存中还出现过:
464
+
465
+ ```text
466
+ DeepSeek-V3.1-Terminus
467
+ GLM-4.7
468
+ MiniMax-M2.7
469
+ Qwen3.5-Plus
470
+ Qwen3.6-Plus
471
+ ```
472
+
473
+ 这些主要出现在 `builder`、`chat_v3`、`code_reviewer`、`refactor` 等旧/专用 category 中。
474
+
475
+ ---
476
+
477
+ ## 关键判断
478
+
479
+ 1. **OAuth 不是标准公共 OAuth2 授权码流的简单复用。**
480
+ 它有 PKCE,但换 token 时还带私有 `DeviceInfo`、`DeviceProof`、ECDSA 设备签名和私有错误码体系。
481
+
482
+ 2. **模型列表不是 OpenAI `GET /models`。**
483
+ 它是私有 RPC:`POST /api/ide/v1/get_model_list`,请求按 IDE 内部 function/category 批量拉取。
484
+
485
+ 3. **模型目录按功能分组,而不是全局单一列表。**
486
+ 同一个模型在不同 function 下会有不同的上下文、输出、轮次和商业化限制。
487
+
488
+ 4. **本地已有完整可解析缓存。**
489
+ 如果只是想取模型清单,可以直接读 `state.vscdb` 的 `AI.agent.model.model_list_map`,不需要先破解网络协议。
490
+
491
+ 5. **凭据不能直接明文导出。**
492
+ 主凭据在 Electron 安全存储中被加密;refresh token 刷新还依赖本地设备 ECDSA key pair。仅拿 refresh token 不足以稳定复刻官方客户端行为。
493
+
494
+ ---
495
+
496
+ ## 后续可做的最小适配方案
497
+
498
+ 如果目标是接入 dsh / OpenAI-compatible harness,不建议一开始就完整复刻 OAuth。更稳的路线是:
499
+
500
+ 1. 先做一个**本地只读桥**:
501
+ - 从 Trae 本地状态读模型缓存;
502
+ - 不读取 token;
503
+ - 只生成静态模型目录。
504
+
505
+ 2. 再决定是否需要聊天能力:
506
+ - 如需聊天,需要解决 `Cloud-IDE-JWT` / `x-cloudide-token`;
507
+ - 还需要处理设备签名和 refresh 流程;
508
+ - 建议通过本地桥收口凭据,而不是把 token 暴露给调用方。
509
+
510
+ 3. 保持与 CodeBuddy 插件相同的核心经验:
511
+ - 私有网关 → provider adapter;
512
+ - stream-only / 私有 SSE → bridge;
513
+ - 私有认证 → credential edge;
514
+ - 私有模型目录 → catalog sync。
515
+
516
+ ---
517
+
518
+ ## 免责声明
519
+
520
+ 本项目档案仅用于本机软件互操作研究、调试和安全评估。所有接口均属厂商未公开协议,可能随时变更;使用时应遵守目标服务条款,不得绕过鉴权、滥用配额或访问未授权数据。