@eddyskywalker/dsh-chatgpt-subscription 0.64.0 → 0.65.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 CHANGED
@@ -2,6 +2,44 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.65.0 - 2026-11-08
6
+
7
+ - **[antigravity] 出站请求身份、版本清单跟随与控制面契约对齐官方客户端**
8
+ - **问题**:
9
+ 1. **推理与生图请求带自造特征**:`systemInstruction` 使用了官方 persona 的改写版,并在末尾叠了 `Please ignore following [ignore]…[/ignore]` 与 `NEVER output rule checks…` 两段自造指令;chat / 生图两个信封的 `requestId` 是 `req_<毫秒>_<6位36进制>`、`img_<毫秒>_…` 自造格式(官方形态为 `agent-<uuid>`);项目发现为空时信封里的 `project` 兜底填 `antigravity-default`(任何真实客户端都不会发送的字符串);每个内容请求还额外携带 `X-Goog-Api-Client` 与 `Client-Metadata` 两个非推理头。
10
+ 2. **UA 版本写死 `2.23.0`**:恰好停在社区参考实现标注的最低可接受版本;Cloud Code 按 UA 版本下发模型目录与 Gemini 配额桶,写死意味着同一账号看到的模型与配额桶少于官方客户端。
11
+ 3. **控制面与推理面混用同一套身份**:`onboardUser`(新账号开通)原沿用推理请求的 camelCase `metadata.ideType` 与裸 UA;而官方在 `loadCodeAssist` 只发 `{ ideType }`,在 `onboardUser` 控制面则使用蛇形 `{ ide_type, ide_version, ide_name }`、UA 追加 `google-api-nodejs-client/10.3.0` 并携带 `X-Goog-Api-Client: gl-node/22.21.1`。
12
+ - **依据**:官方 `/v1internal:*` 请求由 Electron 壳内启动的 Go `language_server` 发出;persona 开头两句原文、默认兜底项目 `rising-fact-p41fc`、`agent-<uuid>` 请求 ID、`loadCodeAssist` / `onboardUser` 的控制面契约,以及 Hub 自动更新清单地址 `https://antigravity-hub-auto-updater-974169037036.us-central1.run.app/manifest/latest-arm64-mac.yml`(读取时 UA 为 `electron-builder`)与版本→CL 对照表(`opencode-antigravity-auth` 及 CLIProxyAPI `internal/misc/antigravity_version.go`,更新至 `2.29.0` → `1013060670`)均与抓包和社区参考实现核对一致;persona 截断残片(`**Absolute paths only****Proactiveness**`)之后的不可考下文不作臆造。
13
+ - **改法**:
14
+ - **信封与请求头**(`src/host/antigravity/types.ts`、`mapper.ts`、`adapter.ts`、`client.ts`、`image-tool.ts`):`ANTIGRAVITY_SYSTEM_INSTRUCTION` 恢复为可考的两句官方原文并删除 `ANTIGRAVITY_NO_PREAMBLE_INSTRUCTION`(`systemInstruction.parts` 只保留官方 persona 与 DSH 自身 system 提示);两个信封的 `requestId` 统一改为 `agent-${randomUUID()}`;三处 `'antigravity-default'` 兜底改用 `FALLBACK_PROJECT_ID`(`rising-fact-p41fc`);`antigravityHeaders()` 默认只发 `Authorization` / `Content-Type` / `Accept` / `User-Agent` 四个头,旧的两个头收拢至 `DSH_ANTIGRAVITY_LEGACY_HEADERS` 开关之后。
15
+ - **版本跟随与控制面拆分**(`src/host/antigravity/client-version.ts`、`client.ts`、`oauth.ts`、`types.ts`):新增 `client-version.ts`,启动时(及每次拉额度时按 TTL)读取一次 Hub 更新清单(6 小时信任窗口、30 分钟失败重试、单飞、永不抛错),内置基线版本抬升至 `2.29.0` / `cl=1013060670`,清单返回未知新版本时按官方规则省略 `cl=`,`DSH_ANTIGRAVITY_VERSION` / `DSH_ANTIGRAVITY_CL` 环境变量优先并完全跳过清单请求;新增 `antigravityControlPlaneHeaders()` 专供 `onboardUser`(及其 LRO 轮询)使用,`loadCodeAssist` 的 metadata 只留 `{ ideType }`;`oauth.ts` 新增 `selectOnboardTier()`(默认 tier → 免费 tier → 首个 allowed tier → current tier → `free-tier`)。
16
+ - **回归**:新增 `test/antigravity-wire-identity.test.ts` 与 `test/antigravity-hub-version.test.ts`,更新 `test/antigravity-mapper.test.ts` 与 `test/antigravity-oauth.test.ts`——覆盖默认 4 头集合、`DSH_ANTIGRAVITY_LEGACY_HEADERS` 布尔解析、两个信封 `agent-<uuid>` 格式、官方 persona 原文与已删段落断言、`FALLBACK_PROJECT_ID` 值、Hub 清单解析/6 小时缓存/失败回退/未知版本省略 `cl=`/环境变量钉死、以及 `loadCodeAssist` 与 `onboardUser` 的契约分离。
17
+
18
+ - **[antigravity / proxy] 每凭据独立 HTTP/1.1 连接池、剥离 `fetch` 浏览器头与直连无 ALPN**
19
+ - **问题**:
20
+ 1. **多账号共用同一条 TLS 连接**:官方客户端是「一凭据一进程」,一条连接只服务一个账号;本插件单进程多账号在代理路径共用单个 `ProxyAgent`、直连路径共用 Node 全局 fetch 的进程级连接池,上游能看到同一条连接先后出现多个不同的 `Authorization`。
21
+ 2. **代理与直连协议不一致**:undici 8 的 `ProxyAgent` 默认允许 ALPN 协商出 h2(实测 GFE 在 `http/1.1,h2` 与 `h2,http/1.1` 下均选 h2),而直连路径是 HTTP/1.1。
22
+ 3. **Node `fetch` 自带浏览器头与默认 ALPN**:undici 的 `fetch` 会为每条出站请求追加 `sec-fetch-mode: cors` 与 `accept-language: *`(原生 Go HTTP 客户端均不发);直连 TLS ClientHello 默认还会 offer `http/1.1`(原生 `language_server` 不发任何 ALPN 扩展)。
23
+ - **改法**(`src/host/proxy-manager.ts`、`src/index.ts`、`src/host/antigravity/types.ts`):
24
+ - **HTTP/1.1 协议钉死与按凭据分池**:`ProxyManager` 新增 `proxyAgentOptions()` 与 `createFetch({ allowH2: false, credentialPools: true })`。池键取自请求 `Authorization` 头 SHA-256 的前 16 位(映射表不存原始 token);代理路径按 `poolKey` 细分 pin 到 HTTP/1.1 的 `ProxyAgent`,直连路径改走 undici `fetch` + 每凭据独立 `Agent`(池总数上限 64,超限时对最旧池调 `close()` 平滑排空);不带 `Authorization` 的请求(Hub 清单、OAuth 换票)继续走共享池。其余 12 条线路的 dispatcher 与行为零变化。
25
+ - **Dispatcher 层剥离浏览器头与直连省略 ALPN**:`ProxyManager.createFetch()` 新增 `stripHeaders`(`stripDispatchHeaders` 在 dispatcher 层过滤 `ANTIGRAVITY_ABSENT_HEADERS`,`WeakMap` 缓存包装层保持池身份稳定;`connection: keep-alive` 会被 undici HTTP/1.1 writer 重加故不列入)与 `omitAlpn`(`buildNativeConnector` 自定义 TLS connector 不设 `ALPNProtocols`、显式填充 `servername` SNI、30 秒连接超时、HTTP 目标退回普通 TCP)。
26
+ - **回归**:`test/proxy-manager.test.ts` 与 `test/antigravity-proxy.test.ts` 新增 HTTP/1.1 协议钉死、按凭据分池(同 token 复用、异 token 隔离、无凭据走共享池、直连走独立 `Agent`)、对象/数组双形态 header 剥离、真实本地 HTTP 服务 `rawHeaders` 抓包、以及无 ALPN connector SNI 透传等用例。
27
+
28
+ - **[antigravity] 实测确认 TLS ClientHello 指纹无法在 Node 进程内对齐:不做原生模块,结论归档**
29
+ - **实测**(完整数据见 [`docs/antigravity-tls-fingerprint-probe.md`](docs/antigravity-tls-fingerprint-probe.md)):`tls-impersonate@0.2.2` 在 **Node 24.14.1** 上调用 `impersonate()` 会触发原生层崩溃(exit 127,无 JS 异常);在 **Node 24.20.0 / OpenSSL 3.5.7** 上虽可运行,但 OpenSSL 固定将 `ec_point_formats` 设为 `[0,1,2]`(Go 只发 `[0]`)、不支持自定义扩展 `50`,且**恒定把 TLS 1.3 套件排在 cipher 列表最前**(`0x1301,0x1302,0x1303,0xc02b,…,0xc014`),而 Go `crypto/tls` 是 TLS 1.2 列表在前、TLS 1.3 追加在后。
30
+ - **决定与残余边界**:不引入原生依赖、不加实验开关(低于 Node 24.15 会崩进程,且无法真正复刻 Go ClientHello;同时无任何实测表明 GFE 按 JA3/JA4 拦截)。本轮收敛后留存的已知差异仅剩:工具名与 schema 为 DSH 自有契约、TLS ClientHello 为 Node/OpenSSL、代理路径受 undici `ProxyAgent` 内部 endpoint connector 封装限制仍会携带 `http/1.1` ALPN、以及不带 `Authorization` 头的 OAuth 表单换票请求共用连接池。
31
+ - **验证**:`npm run typecheck`、`npx tsc -b --force`、全量 `npm test`(374 个文件 / 6880 例通过)与 `npm run build` 通过。
32
+
33
+ ## 0.64.1 - 2026-11-08
34
+
35
+ - **[client] 修复 0.64.0 的派发卡片撞车:整个客户端插件被回滚,设置枢纽与全部工具卡片一起消失**
36
+ - **现象**(真实浏览器,0.64.0 + DSH 0.2.2-rc.1):设置面板里只剩宿主自己的分页和别的插件的分页,本插件的「订阅」枢纽、每条线路的额度胶囊、生图/视频/`code_run` 卡片全部不见;控制台只有一行:
37
+ `@eddyskywalker/dsh-chatgpt-subscription: failed: Error: keyed slot "tool.call.toolview" already has an entry for key "subagent" at priority 0 (registered by details-toolview) — register at a different priority to shadow it (lowest renders)`。
38
+ - **根因**(`src/client/index.tsx`):派发卡片给 `subagent` / `subagent_fork` 注册 `tool.call.toolview` 时没写 `priority`,而宿主自己的 `details-toolview` 已经用**默认** priority 0 占了这两个 key。keyed 槽位一个 key 在一个 priority 上只允许一条,同优先级再注册直接抛错;这个错发生在 `apply()` 里,于是 Cordis 判定整个客户端插件启动失败并**回滚它的全部注册**——所以消失的不是某个分页,而是这一插件的整个客户端面。(宿主侧不受影响:host half 照常挂载,`dispatch_ledger` 等工具正常。)
39
+ - **修法**:两条注册降到 `priority: -10`。keyed 槽位里最低优先级的那条渲染,其余只是被遮蔽——这正是「用更低优先级遮蔽宿主那一行」的正确写法,与 `installSubagentSettingsCard` 用同 id + `priority: -10` 遮蔽宿主设置卡是同一个道理。
40
+ - **回归**:`test/client-registration.test.ts` 的假 `slots` 现在**按宿主契约判占用**(预置 `details-toolview` 的 priority 0 占用,同 key 同优先级即抛错),并断言这两行必须是 `priority: -10`。改前该测试复现浏览器里一字不差的报错,改后通过——它此前只是一份「记录注册」的假实现,所以这类冲突能一路发到线上。
41
+ - **验证**:`npx tsc -b --force` 通过;`npm run build` 重建 `lib/client.js`;用 jsdom 加载**重建后的产物**、按宿主占用规则跑 `apply()`,6 条 `tool.call.toolview` 全部注册成功(`subagent`/`subagent_fork` = -10,其余 = 0),`settings.section` 的两格(`subscription-hub@45`、`progress-updates@150`)也都在。
42
+
5
43
  ## 0.64.0 - 2026-11-08
6
44
 
7
45
  - **[dispatch] 派发前被拒的调用不再烧掉命名空间;`subagent_fork` 的路由约束写进工具描述与人格**
package/lib/client.js CHANGED
@@ -61109,6 +61109,7 @@ window.__ModuleLoader__.load({
61109
61109
  for (const key of ["subagent", "subagent_fork"]) ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
61110
61110
  name: "tool.call.toolview",
61111
61111
  key,
61112
+ priority: -10,
61112
61113
  locale: NS_DISPATCH_LEDGER
61113
61114
  }, MandateToolView));
61114
61115
  installVideoDocumentPreview(ctx);