# 错误记录 同一根因 / 同一用户可见故障只留一条 `##`(后续跟进并进该条,标题用最晚日期)。新条目只要 **现象** / **根因** / **修复**,各 1–2 行。 ## 2026-09-19:catch 变量收紧(useUnknownInCatchVariables,25 条);noImplicitAny 实测**不是**可清扫项 **现象**:`strictNullChecks` 落地后逐个开关实测——`strictFunctionTypes` / `strictBindCallApply` / `strictPropertyInitialization` / `noImplicitThis` / `alwaysStrict` 全是 **0**(`declare` 字段那一轮顺手清掉了),`--strict` 只剩 **25** 条 `useUnknownInCatchVariables`;而 `--noImplicitAny` 是 **2082** 条。 **根因**:25 条全是 `catch (error)` 后直接读 `error.message` / `error?.code`——把 catch 变量从 `any` 收紧成 `unknown` 正是这个开关要抓的东西。2082 条里 **1726 条**是 TS7006「参数隐式 any」(`value` 139 / `session` 128 / `payload` 73 / `id` 62 …),绝大多数**只能标 `: any`**。 **修复**:在 [`src/utils/http.ts`](src/utils/http.ts) 里 `describeError(error: unknown)` 旁边加两个同风格的无 cast 助手 `errorCode(error)` / `errorMessage(error)`(用 `'code' in error` 收窄),替换 7 个文件 25 处 `error.message` / `error?.code`。开启 `"useUnknownInCatchVariables": true`,695 tests 全绿。 **判断(不做的事)**:`noImplicitAny` **不清扫**。给 1726 个参数补 `: any` 只是把「隐式」变「显式」,不产生任何安全性,属于用注解掩盖诊断;它需要的是逐模块设计类型面。这条结论已写进棘轮脚本头部,避免以后有人再当清扫项试一遍。 **收口**:棘轮第二项改名 `strict`,显式传 `--strictNullChecks --useUnknownInCatchVariables`;两项基线均 **0**。 ## 2026-09-19:strictNullChecks 收敛 431→0 并开关落地,棘轮两项归零 **现象**:`noCheck` 摘掉后宿主半已真检查,但 `strictNullChecks` 仍未开;`npx tsc --noEmit --strictNullChecks` 报 **431** 条(TS2345 217 / TS2339 152 / TS18048 31 / TS2322 18 …),`controller.ts`、`cursor/proto.ts`、`devin/proto.ts` 是重灾区。 **根因**:**369 条**来自推断规则而非真的 null 安全问题——`const xs = []` 在 strictNullChecks 下被推断成 `never[]`(之后每次 push / 读取都报 never),`let x = undefined` 被推断成 `undefined`。另有 4 个家族 catalog 的模块级缓存写成 `models: /** @type {any[] | undefined} */ (undefined)`:那个 JSDoc 在 `.ts` 里**根本不生效**,于是 `models` 的类型真的就是 `undefined`。 **修复**:在声明处补显式类型——110 处 `const x: any[] = []`、4 处 catalog 缓存改成真类型注解、7 处参数默认值 `= []`;`listStoredSessions` 改 `flatMap` 丢掉不可能出现的 `undefined` 行(一处消掉 controller 二十余条)。再把 6 个我**上一轮加的** `= undefined` 默认值补外层 `: any`。剩 20 条逐条加守卫或提升局部变量,**不用 cast**。宿主半 **431→0**。 **并行**:`src/apikey/**` + `src/utils/**` + `src/index.ts`(24→0)由 subagent 同时进行,文件集与 `src/oauth/**` 不相交;`src/oauth/cline/**` 是维护者当时正在改的文件,**当时全程未动**——等它停笔两小时后再清掉最后 17 条(同为 `never[]` 家族)。 **踩坑**:strictNullChecks 下 `key = undefined` 不是「可选」,而是把该键定型成字面量 `undefined`,反而拒绝真值;要修只能给整个解构参数加外层 `: any`——写成 `key: any = undefined` 是**重命名**(同 2026-09-19 那条的 `runFn` 陷阱)。 **收口**:`"strictNullChecks": true` 已进 `tsconfig.json`——宿主半现在**真做 null 检查**,`npm run build` 会拦。棘轮两项基线均归 **0**,并分别显式传 `--noCheck false` / `--strictNullChecks`:任一开关将来被移除都会立刻失败。 ## 2026-09-19:宿主半 `noCheck` 下的 1917 条类型错误——逐条核对全是声明缺口,不是 bug,并加债务棘轮 **现象**:`npx tsc --noEmit --noCheck false` 报 1917 条(TS2339 1625 / TS2554 117 / TS2353 80 / TS2551 53 …),而 `tsconfig.json` 的 `noCheck: true` 让 `npm run build` 一条都不查,`tests 全绿`与`类型安全`是两件事。 **根因**:宿主类是 JS 风格——构造函数里 `this.x = …` 但类体不声明字段,tsc 于是把每个 `this.<字段>` 都当「属性不存在」。把 53 条 TS2551 与 117 条 TS2554 逐条追到定义后确认**没有一条是真错**:属性都在构造函数里赋值(`AuthController` 的 `outboundProxy`/`setOutboundProxy` 由 `src/index.ts` 外部挂载),省略的尾参在函数体里都有 `??` / `=== undefined` 兜底。`AuthController` 一个类占 620 条。 **修复**:四步都**零运行时改动**,不用 cast、不新增抑制。① 调用方合法省略的尾参在**定义处**标 `?`(`saveSession` options、`deleteSession` source、`refreshQuota` accountId、`settle` / `h2-session finish`、cache 家族的 `explicit`、`QuotaStore.peek/clear/refresh/ensure/consume` …),TS2554 归零。 ② 给 JS 风格类补 `declare` 字段(`AuthController` 58 个、`TokenManager` / `CommitGate` / `QuotaStore` / `ModelSwitch` / `Pump` / `OpencodeGoStore` / 四个 FlowManager / 三个错误类),`error.code = …` 改 `Object.assign(new Error(…), { code })`。 ③ `fn({ a, b = 1 } = {})` 的选项对象,tsc 只把**带默认值的键**算进参数类型,于是每个 `fn({ 必填键 })` 都报「多余属性」;同理**一个默认值都没有**的解构参数被推断成 `{}`,`fn(options = {})` 这种整体形参也一样。这些选项袋统一在参数上标 `: any`(`update.ts`、各 session builder、各 `toOpenai*` 翻译函数、`runFn`/`fetchFn` 测试缝、各家族 `options`/`payload`)。 ④ 无默认值键的解构参数、`options = {}` 形参、被条件扩展的局部对象字面量,以及 40 余处上游 JSON / `Object.entries` 的 `unknown`——同一套按需 `: any` 收尾。合计 **1917→0**。 **踩坑 1**:解构里写 `{ runFn: any = f }` 是**重命名绑定**(把局部变量改名成 `any`),不是注解;没有 `= {}` 默认值时注解必须写在花括号外——`{ runFn = f }: any`。写错会静默丢掉 `runFn`,cursor/devin 4 个传输测试立刻 502,tsc 报 `TS2304 Cannot find name 'runFn'`——见到这个码先查解构。 **踩坑 2**:批量注解别用「标识符 + `= {}`」的宽松正则,它同时踩两个雷:把语句位置的赋值 `record = {}` 改成 `record: any = {}`(变成 label + 给未定义变量 `any` 赋值,运行期 `ReferenceError: any is not defined`,只有 antigravity 那条路径会炸),以及把已注解的 `: any = {}` 再注一遍并**复制** `= {}`(190 处)。两处都是 `npm test` 抓出来的——批量改类型后必须跑全量测试,并 grep 生成物确认没有注解漏进 `lib/*.js`。 **收口**:归零后删掉 `tsconfig.json` 的 `noCheck: true`——`npm run build` 从「只擦类型」变成**真做类型检查**,`npm test` 随之会在类型错误上失败。CI 棘轮 `scripts/typecheck-ratchet.ts` + `typecheck-baseline.json` 基线降到 **0**,且脚本显式传 `--noCheck false`,将来有人把开关加回来它仍会拦下。`strict` / `noImplicitAny` 仍未开、选项袋仍是 `any`,所以它抓的是拼错属性、错实参个数、坏字面量,**不是** null 安全。 ## 2026-09-19:Cline 活测命中率 74%——大头是上游分片轮换,附带修掉 system 头钉串模型 **现象**:`npm run analyze` 一份 70 调用的会话:命中率 74.0%,12 次 affinity_miss 占未缓存 token 的 74%(1.55M/2.08M);每次 miss 都是整体 miss(reuse<10%)且**下一次调用立刻 ~100% 命中**——缓存条目在上游还活着,只是这次请求落到了没有它的分片/供应商上。miss 间隔 24s–10min 不等,排除 TTL。 **根因**:Cline 背后是 OpenRouter 隐式前缀缓存,亲和只有 `X-Task-ID` 一个字段(CLI 同款已正确发送),上游按供应商池路由时缓存不随人走——免费/便宜模型尤其明显;hop 侧无法再钉。附带发现真 bug:DSH 在 Completions 调用上**根本不发** `session_id`/`prompt_cache_key`(整个运行时 grep 为零),`SYSTEM_PINS` 永远落在常量 `dsh-cline` 上 = 进程级单钉;会话中 `kimi-k3`→`deepseek-v4.1-flash` 换模型后新 system 头与旧钉不兼容,旧逻辑把整段新 prompt 停到 messages 尾部、继续发旧模型身份头(剩余 54 次调用 + 下个会话都会串)。 **修复**:`stabilizeClineSystemPrefix` 只在「新头是旧头的纯扩展」时停车;不兼容的头直接重钉(前缀本来就已断,冷写不可避免,但模型拿到正确的 system prompt)。kimi/copilot 同款 stabilize 有同一模式,本次未动,换模型多的家族应跟进。回归测试:`test/cline.test.ts`「an incompatible system head re-pins」。 ## 2026-09-19:README 缺 Devin / Cline 两个已落地家族——代码 11 家,文档只写 9/10 **现象**:`store.ts` `PROVIDER_IDS` 已有 11 个家族(含 Devin、Cline),但 `README.md` / `README.zh.md` 的系列表、导入路径表、回环行、Fast 表、额度表都查不到这两家,`PRODUCT.md` 写「Nine OAuth families」,`AGENTS.md` Index 漏 Cline;`proxyUrl` / `cursorProxy` 两个 Config 选项也不在 Options 表。新用户按 README 找不到 Devin / Cline 的登录入口。 **根因**:两个家族都按「新家族」流程落地了 `src/oauth//` + README + `docs/oauth.md` + error.md + 测试,但步骤 7「README 归因补齐」只补了家族 README,根 README / PRODUCT 没跟着收口——`PROVIDER_IDS` 是唯一权威清单,文档抄漏了。 **修复**:双语 README 的系列 / 路径 / 回环 / Fast / 额度表补齐 Devin、Cline,Options 表补 `proxyUrl`、`cursorProxy`;PRODUCT.md 改 11 家;AGENTS.md Index 补 Cline。不改码,纯文档对齐 `PROVIDER_IDS`。 ## 2026-09-19:Cline 免费档活测——4/5 可用且不扣余额,muse-spark 区域门 **现象**:feed 的 `free` 桶 5 个模型进目录后要确认真能跑:`cline-free/muse-spark-1.3-contributor` 每次 403 `{"error":"access forbidden: … is not available in your region","success":false}`,其余 4 个正常。 **根因**:区域门在上游按出口 IP 判,与本 hop 无关(同账号、同 token、直接打 `api.cline.bot` 也是 403);插件没有也不该按地区猜着过滤目录——feed 是 Cline 自己的推荐列表,换个地区/出口就能用。 **修复**:不改码。活测记录:`cline-free/deepseek-v4.1-flash` / `z-ai/glm-5.3-flash` / `cline-free/solar-pro4` / `poolside/laguna-s-2.1:free` 四条全部 200:流式出字、`reasoning_effort: low` 被接受、非流式解包后 `tool_calls` 返回 `get_weather({"city":"Paris"})`(`finish_reason: tool_calls`);`/usages` 台账里这些调用的 `creditsUsed` 全是 `0`,余额停在 $0.335787 未动;laguna 第二次还带回 `cached_tokens: 32`。muse-spark 只能靠非受限地区出口(插件出站代理设置,未实测)。 **踩坑**:免费档里有推理模型,`max_tokens` 给小(32)时 reasoning token 会吃满预算、`content` 为空但 `finish_reason: stop` —— 不是 hop bug;给到 512 就正常出字。 ## 2026-09-19:Cline 卡片只有余额没有进度条——credit 账号没有分母,ClinePass 才有三条窗口 **现象**:Cline 卡片只有「额度余额 $0.34」,没有进度条,看起来像漏做。 **根因**:`cline` 是 credit(usage-billing)产品:`/balance` 只给余量,`/usages` 只给流水,`/users/me/plan` 对无订阅账号 404——没有「窗口 + 上限」就没有分母。官方 CLI 同样只打 `Credits: $x.xx`(`apps/cli/src/tui/interactive-welcome.ts`),整棵 TUI 搜不到 cline 的百分数字段。 **修复**:补上只对订阅账号生效的三条窗口条:`GET /users/me/plan/usage-limits` 的 `limits[] = {type: five_hour|weekly|monthly, percentUsed, resetsAt}` 直接给服务端百分比(转成 DSH 的剩余条),cap 取 `plan.entitlements.cline_pass.inferenceCapThreshold`,单位 1e-8 USD;cap 缺失只画纯百分比条,不补默认值;credit 账号行为不变(仍是余额行)。 **未验证**:本机账号无订阅,两个 plan 端点都 404,三条窗口的**数值**没有活体样本。已验证路由真实存在——`/users/me/plan/usage-limits` 回应用级 404 `{"data":null,"error":"no plan history found for user"}`,未知路由回 `{"error":"Not Found"}`;形状取自 MIT `pi-clinepass` `0.1.5` `src/usage.ts`。拿到订阅账号后需重跑 `fetchClineQuota` 复核。 ## 2026-09-19:Cline hop 活测三条结论(响应信封 / `workos:` 前缀 / 隐式缓存) **现象**:接入 Cline(CLI 3.0.62,WorkOS 设备码)时本机账号活测暴露三件事——①非流式对话回 `200 {"data":{…choices…},"success":true}`,直通给 DSH 时读不到 `choices`;②裸 JWT 当 bearer 一律 401 `Please make sure you're using the latest version of Cline`;③`anthropic/claude-opus-5` 连打两次 `cached_tokens` 都是 0,`openai/gpt-6-astra` 第二次 1461/1464。 **根因**:Cline 只给**非流式**回包套 `{success,data}` 信封(SSE 不套),CLI 因为始终 `stream: true` 从没撞上;bearer 必须是 `workos:`(`provider-auth-registry.ts` `formatAccessToken` 加的前缀);Anthropic 经 OpenRouter 要显式 `cache_control` 断点,CLI 不发,隐式前缀缓存只对 OpenAI 系生效。 **修复**:`unwrapClineEnvelope` 在非流式分支先解包再过 usage 映射;`formatClineAccessToken` 幂等加前缀(导入 / 粘贴 / 刷新同一入口);`CLINE_REASONING` 无 `off` 键(CLI 禁用思考时不发字段)、`max`→`xhigh`。活测:设备码 → `POST /auth/register` → `/users/me` + `/balance`(微美元)+ `/plan`(无订阅 404)全通,proxy 流式与非流式都拿到 `ok` 与 usage。 ## 2026-10-23:xAI Grok 额度显示「0 / 0」——上游改了 GetGrokCreditsConfig schema **现象**:SuperGrok Heavy 账号额度卡只有「每周 0 / 0」和重置倒计时,没有用量条;billing JSON 与 gRPC 帧都 200。 **根因**:①billing 的 `onDemandCap{val:0}`(pay-as-you-go 关闭)被 `grokOnDemandBag` 当成真额度包,造出 0/0 行;②上游把 GetGrokCreditsConfig 的 usage float 从 nested field 1 移走(周期挪到 nested field 8 `{type,start,end}`),解码器只认旧形状,拿不到 percent 也填不进 0/0 行。 **修复**:`grokOnDemandBag` 与 monthly 一样要求 `total > 0`;`decodeGrokCreditsFrame` 读 nested field 8 的 start/end(旧 field 4/5 保留回退),有周期无 usage 时按 proto3 省略零值 = 0% 已用(与 grok.com 网页一致);snapshot 的 `periodStart` 并入行。活测:Heavy 账号返回 weekly 100% 剩余 + 正确 resetAt。 ## 2026-10-22:令牌生命周期对齐 CLIProxyAPI——401 刷新重试 / 后台 sweep / 失败退避 **现象**:对照 router-for-me/CLIProxyAPI 后发现三处缺口——①上游 401(令牌被吊销/轮转但未到 expiresAt)直接透传给客户端,用户只能重登;②令牌纯惰性刷新,闲置后首个请求付刷新 RTT,refresh token 静默死亡只在请求中暴露;③token 端点瞬时故障时每个请求都重打端点,且仍有效的旧 access token 被白白丢弃;④同账号重登录整体覆盖 session,丢 projectId / cachedEmail 等水合字段。 **根因**:`TokenManager` 只有「到期前 preempt 窗口内惰性刷新」一条路径,无强制刷新、无失败退避;`saveSession` 无合并语义。 **修复**:`refreshNow(id, failedAccessToken)`(已轮转的并发刷新直接复用,不二次兑换 refresh token);`forward()` 捕获 `UnauthorizedUpstream` 刷新一次重试,失败则原样透传上游 401 body;`startTokenSweep` 每 60s 扫全部已存账号;瞬时刷新失败记 5min 退避且未过期令牌继续服务;`saveSession` 同 id 合并非凭据字段(`SESSION_CREDENTIAL_KEYS` 除外)。Kiro / Cursor / Devin 自有 transport 的 401 不在本次范围(Devin 已有 jwt 401 重试先例)。 ## 2026-10-21:手动更新「经常失败」——装上了但不重启、update 超时即放弃 **现象**:关于页手动点更新常报失败或装完版本仍旧;自动更新却稳定。根因有三:①手动 apply 不传 restart,装上后进程仍跑旧模块,用户不重启就永远「有新版本」;②`dsh plugin update`(pnpm update,对 git spec 常 no-op)一超时就不再走确定性的 `add #tag`;③GUI 启动的 dsh web PATH 极简,spawn 的 dsh 找不到 pnpm/node。 **修复**:手动 apply 默认 `restart !== false`(与自动更新、DSH 卡一致,装完自动重启);`applyHostUpdate` 在 update 超时后仍重试 `add #tag`;`runDshPlugin` 与 npm 一样补 PATH 默认值。UI 拆开「检查更新」与「更新到 vX」,加版本带、进度秒数与自动更新「上次检查」行(`update-state.json` 记录 lastRun)。 ## 2026-10-20:Devin hop 的三个活测结论(双前缀 / ide_name / fast) **现象**:接入 Devin 时发现三类会做错的事——①给已带 `devin-session-token$` 的 token 再加前缀,上游 401;②`GetCliModelConfigs` 用 `ide_name: devin` 只回 1 条 stub config(209→1),MITM 真二进制后确认 `chisel`/`3000.10.31` 才是 CLI 真实指纹;③`GetCliModelConfigs` 有 `*-fast` 真后端变体,过 `applyFastMode` 会把模型 id 剥掉 `-fast`。 **根因**:token 导入/粘贴/paste 共用入口,不 normalize 就双前缀;服务端按客户端身份区分目录;共享 fast-mode 语义把「快档」当后缀 flag,和 Devin 把它当独立模型冲突。 **修复**:`normalizeDevinToken` 幂等加前缀;身份按真 CLI MITM 固定 `chisel`/`3000.10.31` + `os` + `Basic -`(`windsurf` 也能回全量但那是 windsurf 指纹,不是 devin 的);Devin 分支跳过 `applyFastMode`,`-fast` 收成独立 picker 行 `*-fast`。 ## 2026-09-17:宿主/页面版本错配时「导入」把 Grok 会话写进 devin 槽 **现象**:`dsh web` 跑着旧版宿主、Settings 页已是新版时,点「导入本机 Devin CLI」无报错也没有 Devin 账户;auth.json 的 `devin` 键却多出一份 Grok 会话(`auth.x.ai` token、`SuperGrok` 套餐),模型界面没有 `oauth-devin` 路由。 **根因**:旧版 `importFrom` 对不认识的 provider 落到末尾 `importGrokAuth()` fallthrough,再以调用方的 provider 名 `saveSession('devin', grokSession)`;占住槽位后 `#maybeAutoImportDevin` 只看 `rows.length` 永不自动导入。另发现 `sync()` 漏传 `devinModels`,活目录不进 DSH 路由。 **修复**:`importFrom` 先校验 `PROVIDER_IDS`,未知 provider 抛 `unknown provider`;新增 `isDevinSessionToken`(`devin-session-token$` 前缀)形状检查,auto-import 只认本家族会话(外来行留给 refresh 401 自清);`sync()` 补传 `devinModels`;页面把 `unknown provider` 错误翻译成 `hostStale`「重启 dsh web」横幅(沿用 `opencodeGoHostStale` 的错配先例)。 ## 2026-09-17:Devin hop 的孤立 cache_read=0 是上游行为,不是 hop bug **现象**:两个 session(88 跳 96% / 115 跳 93%)各有孤立 `cache_read_tokens=0`(墙钟 ~5–8min 一次),下一跳立刻恢复读满前缀;活测同 cascade 连打 8 跳复现——read 恒落后 1–3 跳、偶发 0。 **根因**:上游 `PromptCacheOptions{type:1}`(ephemeral)缓存异步提交 + 定期失效;与 pin/cascade/effort/splice 无关——A/B 活测证伪 message_id 回传影响(上游自发 `bot-uuid`,回传与否命中率一致)。 **修复**:hop 侧无解;顺藤摸到 `GetUserJwt` 每跳都打(RTT ≈2s),jwt `exp`≈15min——`devinChatAuth` 按 exp−90s 复用 per-token,chat 401 丢缓存重试一次 token-only。另外修分析器误报:tool/result 序列化 envelope 的 `content`/`arguments`/`parts` 载的是文件文本(读 error.md 触发 `TRANSPORT`/`stream idle timeout` 误报 2 条),现剥掉 payload 键再扫描。 ## 2026-09-17:Cursor 区域锁模型全挂 + 勾选格停在静态底表 **现象**:Cursor 勾选格里 Claude / Gemini / GPT-5.x 一跑就 `Model not available: This model provider is not supported in your region`;同时账号实际可用的 `default`(Auto) / `kimi-k3` / `kimi-k2.7-code` / `glm-5.2` / `*-fast` 不进勾选格,活目录(GetUsableModels 23 行)从未落到 picker。 **根因**:Cursor 按请求出口 IP 做合规区锁(官方解法就是 `http.proxy`,本 hop 的 `http2.connect` 没有任何代理支持);活目录只在登录 / 导入 / 手动刷额度时拉取,静态底表一直顶在 picker 上。 **修复**:新增 `cursor/upstream-proxy.ts` —— `PI_CURSOR_PROXY` / `CURSOR_PROXY` / 插件配置 `cursorProxy`(http://、https://、socks5://)时 Run 与目录 RPC 走 CONNECT/SOCKS5 隧道再 TLS+h2(`cursorH2Connect`,connectFn 允许异步);`warmCatalogs()` 在启动时为已登录家族跑活目录并重 sync;目录缓存键并入代理出口;区域错误追加指向该配置的提示;picker 名字去掉 `Cursor ` 品牌前缀。跑通验证:default / composer-2.5(±fast) / grok-4.5/4.6(±fast) / glm-5.2 / kimi-k2.7-code / kimi-k3 全 200。 ## 2026-09-15:OpenCode Go 的内置 27 个模型被插件带进 DSH 模型列表 **现象**:`OPENCODE_API_KEY` 一旦存在,DSH 模型列表就多出内置 `opencode-go` 的 27 个模型;插件 Settings > 模型 家族组只列 `deepseek-flash` 一条,用户没在 DSH 模型设置页开过它,删掉下次 sync 又回来。 **根因**:llm-pi-ai 只注册 profile 点名的目录路由;`ensureOpencodeGoRoute` 有 key 就补写 `providers.opencode-go = { apiKeyEnv, x-opencode-session }`,等于替用户把内置目录整条激活(旧版裸 `{ apiKeyEnv }` 还会被升级成同一形状)。 **修复**:sync 不再创建/刷新 `providers.opencode-go`,只写插件自有的 `opencode-go-flash`,并 unset 旧版本插件自己写的同形 profile(裸 `{ apiKeyEnv }` 等用户形状不动);没有任何账号带 key 时清掉镜像的 `OPENCODE_API_KEY`,路由不再滞留。 ## 2026-09-11:OpenCode Go 全家族 400 MissingSessionID **现象**:默认模型 `opencode-go-flash/deepseek-flash` 每轮报 `400 {"type":"MissingSessionID","message":"…missing x-opencode-session…"}`;实测内置 `glm-5.3` 直连同样 400,带上 `x-opencode-session` 才 200。 **根因**:Console Go 现在硬性要求该头(官方文档 "Your client should … send a stable session ID in `x-opencode-session`")。DSH 有每会话 `sessionId`,但 pi-ai 0.85.1 的 completions/`sendSessionAffinityHeaders` 都不映射它,llm-pi-ai compat gate 又 withhold 该字段,profile 无法转发会话 id。 **修复**:`ensureOpencodeGoRoute` 给 `opencode-go`(内置目录)和 `opencode-go-flash` 两条 profile 都写稳定头 `x-opencode-session: dsh-opencode-go`;旧 `{ apiKeyEnv }` 形态自动升级;无 key 仍整条 unset。这是单机单 shard 的常量回退,等 DSH/pi-ai 原生按会话发送后可去掉。 ## 2026-09-11:未登录家族的模型被勾选,OpenCode Go 无 key 仍写进 DSH **现象**:Settings > 模型 里 Kimi / Copilot / OpenCode Go 未登录时勾选框仍打勾(灰的,`已开启 3 / 3`);OpenCode Go 没有 `OPENCODE_API_KEY` 也把两条路由写进 `llm-pi-ai`,DSH 模型列表里出现不能用的模型。 **根因**:`describeCatalog.enabled` 只是 ModelSwitch 的用户偏好,`ModelRow` 直接拿它当 `checked`;`ensureOpencodeGoRoute` 不看 key,缺失就补。 **修复**:锁定的家族一律渲染未勾选、计数 `0 / m`;`sync()` 把 `#opencodeGoKeySet()` 传给 `ensureOpencodeGoRoute(apiKeySet)`,无 key 时插件自写的 `opencode-go` / `opencode-go-flash` 都 unset(用户自建路由不动);`goSave` / `goClear` / `switch` / `logout` 后触发 sync。 ## 2026-09-11:OpenCode Go 只能存一个账号,展示框架也不是通用账号卡 **现象**:Settings > OpenCode Go 只能保存一个 key/cookie/workspace,再加会覆盖;没有其它 OAuth 家族那种账号卡,不能切号、也不能一账号一条额度。 **根因**:`opencode-go.json` 是单 entry 结构,key 直接写死 `OPENCODE_API_KEY`;页签是自绘面板,没复用 `ProviderCard` / `AccountCard`。 **修复**:`store.ts` 改多账号 0600 vault(旧单账号文件自动迁移,key 随账号落盘),活动账号 key 镜像到 `OPENCODE_API_KEY`;`switch` / `logout` / `quota` 走通用 RPC;UI 改 `card('opencode-go')`,添加走 `ProviderCard` 的居中 Dialog(`goSave`)。 ## 2026-09-11:模型页不显示 OpenCode Go 模型,插件却在重复部署 28 个 **现象**:Settings > 模型 只有 9 个 OAuth 家族,没有 OpenCode Go;`OPENCODE_API_KEY` 未注入时也看不到 Go 模型。DSH 模型设置页里却有内置的 OpenCode Go(27 个)。 **根因**:`catalogProviders` 只投影 OAuth 家族;插件还试图把官方 28 个模型全写进 3 条 `opencode-go*` 路由,覆盖/复制了 DSH 内置 pi-ai catalog(内置 provider 只缺 `deepseek-flash`)。 **修复**:改「内置目录 + 单模型补充」——`providers.opencode-go` 只写 `apiKeyEnv`(不带 `api`/`models`,DSH 复用它自带的 27 个模型),插件只写 `opencode-go-flash`(`deepseek-flash`);picker 只列补充路由,快照按 `OPENCODE_API_KEY` 标记 `loggedIn`(无 key 只锁勾选、不隐藏)。 ## 2026-09-11:空 reasoningEfforts 让 3 条 OpenCode Go 路由整段写不进 **现象**:v0.0.87 启动后 `llm-pi-ai.providers` 里没有任何 `opencode-go*`;Composer 选不到 Go 模型,也没有报错文案。 **根因**:`opencode-go/models.ts` 的 `model()` 用 `{ ...reasoningEfforts }` 存 `false`,JS 展开得到 `{}`;DSH strict 校验把空 dict 当配置错误,`settings.mutate('llm-pi-ai')` 整次原子写被拒,`ensureOpencodeGoRoute` 只吞成 `{status:'error'}`。 **修复**:`false` 原样保留;`assertDshServiceableProvider` 同步拒绝空 dict。全量 3 路由已改为只补 `deepseek-flash`,不再有 `false` 行。 ## 2026-09-11:OpenCode Go 保存报 unknown method;添加还是页内表单不是悬浮窗 **现象**:Settings > OpenCode Go 粘贴 API key/cookie 点保存,红字 `保存失败: unknown oauth-subs method goSave`;添加 UI 是页内表单。 **根因**:`dsh web` 宿主进程启动早于 v0.0.87;`client.js` 被 live 重载成新版,Node ESM 缓存里的宿主还是旧版 RPC 表,故 `goSave` 不识别。面板也违反「添加账号用居中 Dialog」的 UI 约定。 **修复**:OpenCode Go 页改为单账号卡片 + `CenterDialog`(key/cookie/workspace、清除、错误都在窗内);客户端把 unknown method 映射成「重启 dsh web 后再保存」。宿主 RPC 不变,重启宿主后保存生效。 ## 2026-09-10:关于页 DSH 只读 latest dist-tag,next 上的 rc 被判成 npm 未发布 **现象**:npm 已有 0.1.5-rc.2(`next` tag),About 仍显示「GitHub 有新 Tag dsh-v0.1.5-rc.2(npm 尚未发布)」;「最新发布」停在 0.1.5-rc.1,「稳定版」显示 —。 **根因**:`fetchDshLatest` 用 `dist-tags.latest || next || alpha` 当最新发布,`latest`=rc.1 永远压过 `next`=rc.2;服务端 npm 载荷没带 `stable`,覆盖了客户端 fallback 的稳定版字段。 **修复**:npm 最新发布取全量版本排序首位(与 npm 页一致),`stable` 单独取 `latest` tag 并随载荷返回;rc.2 > rc.1 即 status `update`。 ## 2026-09-10:OpenCode Go 页没有 API key 输入,cookie/workspace 框被撑到 240px 高 **现象**:Settings > OpenCode Go 只能填 cookie 和工作区;对话密钥要去 DSH API Keys。两个输入框异常高。 **根因**:面板没写 `OPENCODE_API_KEY`;`.osubs-fields` 是竖排,子项 `.osubs-input { flex: 1 1 240px }` 把高度拉成 240px。 **修复**:面板第一项是 API key,`goSave` 经 `credentials.set('OPENCODE_API_KEY')` 写入宿主凭据;cookie/workspace 仍只读额度。`.osubs-fields > .osubs-input` 改为 `flex: none; height: 36px`。 ## 2026-09-10:OpenCode Go 页签误放右侧工具列 **现象**:Settings 顶栏 OpenCode Go 图标在右侧 Models/About 列,不在左侧家族胶囊。 **根因**:新增时把 `apikey` tab 放进了 `.osubs-tabs-util`。 **修复**:`apikey` 放进左侧 `.osubs-tabs`,排在 Copilot 之后换到第 2 行左侧;右侧 util 只留 Models + About。实现仍在 `src/apikey/opencode-go/`,不走 hop、不另开第三胶囊。 ## 2026-09-10:上游静默时代理不主动断流,靠客户端 300s 超时兜底 **现象**:`grok-4.6` 会话最后一步上游一个字节不发,DSH 连续两次 `pi-ai stream idle timeout after 300000ms`,约 15 分钟后用户中止;分析器却报 transport 0 / HEALTHY。 **根因**:`attemptUpstream` 的 `reader.read()` 没有读空闲看门狗;`CommitGate` 的 120s deadline 只在 `push()` 收到 chunk 时才检查,全静默流永不触发,代理一直挂着,直到 llm-pi-ai 自己的 300s 超时。失败藏在 `assistant/attempt.stream[].chunk.reason.failure`,分析器只扫顶层 error 字段所以漏报。 **修复**:`withIdleTimeout` 给每次 `reader.read()` 加 `UPSTREAM_IDLE_TIMEOUT_MS`(默认 120s,`createProxy.upstreamIdleTimeoutMs` 可覆盖);静默即抛 `UpstreamIdleError` → 复用既有 3 次重试。分析器补扫嵌套 failure(`stream idle timeout` = transport)。 ## 2026-09-10:Cursor Run 把 requestContext / KV set / MCP 调用一律当拒绝,模型跑不通 **现象**:Cursor 任一模型一调用即 500 `{"error":"dsh owns tool execution"}`;工具轮次也拿不到结果。 **根因**:Run 握手的 `ExecServerMessage.request_context_args` 被统一回 `ExecClientThrow`,上游判 `Failed to get request context`;`KvClientMessage` 对 `setBlobArgs` 也回 `getBlobResult`;原生 read/shell 与 MCP 调用同样先 throw,MCP 参数被丢。 **修复**:`requestContextArgs` 回 `RequestContextResult.success`(带 DSH 工具定义);KV 按 get/set 回对应 result;原生 Cursor 工具回类型化 rejection 让模型回退 MCP;MCP 调用带真实参数交给 DSH,结束后以工具结果续跑(`parseTurns` 完成轮 + 工具输出作当前动作)。 ## 2026-09-10:OpenCode Go 以 API key 模块加入(cookie + 工作区读额度) **现象**:需要 OpenCode Go 页签显示剩余额度,但 Go 不属于 OAuth 订阅;对话在 DSH 配 `OPENCODE_API_KEY` 即可,不应再包一层回环网关。 **根因**:Go 是 API key 制(Responses 直连 `opencode.ai/zen/go/v1`)。额度只在 Web 侧 cookie + 工作区可见,官方未给 Bearer 用量接口。 **修复**:新增 `src/apikey/opencode-go/`(`store.ts` 存 `/opencode-go.json` 的 cookie + workspace,`quota.ts` 刮 `/workspace/{wrk_}/go`);`sync()` 用 `ensureOpencodeGoRoute` 在缺失时补 3 条路由(`opencode-go` / `-responses` / `-anthropic`,`models.ts` 钉 28 个模型的 name/id/api/context/input/思考档);已存在不覆盖;`RETIRED_FAMILY_IDS` 仍 unset `oauth-opencode`,无 `proxy.ts` hop。 ## 2026-09-10:Grok leading 文本改写后整块重挂,未变前缀不缓存 **现象**:`grok-4.6` 长会话每步约 10k token 命中不到,加权命中卡在 ~90%,热身前段 44–68%;分析器把前段标成 `prefix_break`(`affinity-miss` 0)。 **根因**:`pinGrokSystemPrefix` 只在「新文本 = 旧文本 + 后缀」时挂增量;前插快照 / 中段改写等任何非后缀变化都把**整段** leading blob 当 extra 重挂到 input 后缀。钉住前缀虽 byte-stable,但重挂的整段每步都变,未变部分也进不了缓存(gap ≈ leading 块大小)。 **修复**:`changedRegion` 取最长公共前缀 + 最长公共后缀(不重叠),再外扩到整行边界,只把变化区域挂后缀;钉住前缀保持 byte-stable。`test/grok-request.test.ts` 覆盖前插快照与中段改写。 ## 2026-09-10:关于页检查失败 GitHub releases 403 **现象**:About 当前版本正常,最新版本 `-`,红字 `检查失败 · GitHub releases 403`;DSH 卡 GitHub Tag 也是 `-`。 **根因**:未认证 `api.github.com` 每小时 60 次用尽后回 403。`fetchLatest` 把非 200 直接抛错,没有走 github.com 页面。 **修复**:API 失败后先试本机 `gh api repos/…/releases/latest`(PATH / Homebrew / `GH_BIN`),再读 github.com `/releases/latest` 的 302。有 `GITHUB_TOKEN` / `GH_TOKEN` 时带 Bearer。 ## 2026-09-09:关于页检查更新 405 `/oauth-subs-auth/status` **现象**:设置 > OAuth 订阅 > About,「检查更新」无反应,红字 `transport failure for /oauth-subs-auth/status: HTTP 405`,最新版本显示 `-`。 **根因**:`rpc.handle` 用 `this.ctx.webServer.register` 挂前缀。插件没 inject `webServer` 会直接拒读;inject 了 Cordis 仍把 `this.ctx` shadow 成 connection 提供方 fiber,那边也没有 `webServer`。通道没挂上,POST 落到 SPA fallback 回 405。 **修复**:`registerRpc` 同时 inject `connection` + `webServer`,并把 traced service 的 `ctx` 绑回调用方 scope 再 `handle('/oauth-subs-auth')`。 ## 2026-09-09:关于页更新插件报 PATH 上找不到 dsh **现象**:About 已显示本机 DSH 版本,点插件「检查更新」红字 `PATH 上找不到 dsh`,0.0.82 装不上。 **根因**:`runDshPlugin` spawn PATH 上的 `dsh`。GUI / Homebrew 启动的进程 PATH 没有那份;关于页用的是 `DSH_BIN_PATH` / `process.argv[1]`。 **修复**:插件更新 spawn 当前进程那份 DSH(`.js` 入口用 `process.execPath`)。找不到才回落到 PATH `dsh`。 ## 2026-09-09:Completions 透传没把 cache_read 交给 DSH **现象**:Copilot / Kimi / GLM Completions 残留长聊 DSH `cacheReadTokens` 一直是 0%,上游 usage 里其实有 `cache_read_input_tokens`。 **根因**:`mapCopilotUsage` 只在单测里跑;代理 SSE/JSON 原样转发。流式默认不带 `stream_options.include_usage`,很多 Completions 上游根本不回 usage。 **修复**:这三家 Completions hop 缺省要 `include_usage`(已显式设置则不改)。JSON 和 SSE 的 `usage` 译成 `prompt_tokens_details.cached_tokens`。没有字段不发明 0。Anthropic / Responses 不改。Completions 流不走 Codex preamble 闸(没有 `response.created`),否则小回复会等到 120s。 ## 2026-09-09:代理透传 content-encoding: gzip 但 body 已被解压 **现象**:非流式上游响应(xAI Cloudflare 对 JSON 响应 gzip)经代理后带 `content-encoding: gzip` 头但 body 是明文,客户端 gunzip 报 incorrect header check / terminated,Grok 非流式调用不可用。 **根因**:undici fetch 自动解压 gzip,代理转发已解压字节却保留上游 `content-encoding` / `content-length`(描述的是上游线上字节)。 **修复**:`forwardedHeaders` 剥离 `content-encoding` / `content-length`(wire-only),Node 重新分帧;回归测试覆盖。 ## 2026-09-08:账号刷新跨越切换或注销后误写凭据 **现象**:A 刷新期间切到 B 会被切回 A;A 的永久失败可能删除 B;注销后旧刷新 / 额度补全可能复活账号。 **根因**:刷新按厂商共用 inflight,保存和删除操作重新读取 active;后台额度绕过刷新归并且异步补全无来源快照校验。 **修复**:刷新按账号和登录代次归并,store 进程内串行条件写回 / 删除校验来源凭据;聊天与额度共用 TokenManager,metadata 只向来源账号做差量更新(含显式删除旧验证字段)且不激活账号。 ## 2026-09-08:OAuth 错误回调无需 state 即可取消登录 **现象**:向 loopback callback 发送无 state 或错误 state 的 error 参数即可终止正在等待的合法登录。 **根因**:handler 在核对 state 前接受 error / error_description 并结算登录。 **修复**:成功和失败回调均先校验 state;不匹配回 400 且保留当前尝试,合法失败仍正常报告。 ## 2026-09-08:显式模型全关被后续同步重新开启 **现象**:用户全关一族后,当次路由消失,但普通同步或重启又启用模型。 **根因**:旧全关恢复逻辑只看当前目录是否全禁用,无法区别用户选择与历史坏状态。 **修复**:持久化显式选择标记;用户操作后同步尊重选择,无标记旧文件仍可恢复,新增普通模型仍按原默认启用。 ## 2026-09-08:Cursor 截断流或错误被包装为成功答复 **现象**:HTTP2 在 Connect 头 / payload 中途结束时得到空白成功答复;已有输出后的异常被混进回答文字并附 DONE。 **根因**:Run 在 EOF 未检查解析器剩余字节,HTTP 转换把传输异常当普通内容发送。 **修复**:残帧 EOF 明确拒绝;发头后使用结构化 error SSE 且不附成功 DONE,保留已输出的正常文字。 ## 2026-09-08:Cursor 取消后 HTTP2 流仍继续工作 **现象**:取消对话 / unary 超时后远端流未关闭,仍接收文本或回应 KV;SSE 慢消费者的等待也未传回上游。 **根因**:client.close 仅优雅关闭,不终止活动流;data handler 未检查结算状态,onEvent 写入未等待。 **修复**:终止时销毁请求独占的 HTTP2 连接,预取消不建连接,运行中取消保留原原因,结算后不处理消息;事件消费逐条等待并暂停上游读取,错误沿调用链传播。 ## 2026-09-08:Kiro 畸形或失败流被当作成功完成 **现象**:非法帧前缀持续积累后续数据,截断尾帧或异常事件可能被返回为成功 stop / DONE。 **根因**:parser 对非法长度只 break 且无 EOF 校验;流转换提前发 200 并将异常转为正常终帧。 **修复**:非法总长 / header 长度立即报错,finish 拒绝残帧;发头前返回上游错误,发头后发送 error SSE 而非成功终帧,释放上游 reader。 ## 2026-09-08:Kiro 交错工具调用被拼成同一个调用 **现象**:同轮多个工具被客户端合并,参数中还可能混入对象而非字符串。 **根因**:流转换固定 index 为 0,仅带 name 的分片才序列化对象参数。 **修复**:每个 toolUseId 分配稳定且互异的 OpenAI index,所有参数分片统一为字符串,停止帧不重复输出。 ## 2026-09-08:Antigravity 流式多字节字符损坏 **现象**:中文、重音字符或 emoji 在网络分片处变成替换字符。 **根因**:每个 byte chunk 单独 toString('utf8'),截断的多字节字符无法由下一块补全。 **修复**:厂商 transport 使用有状态 TextDecoder 增量解码并在 EOF 刷新,再解析 SSE;逐字节分片回归保留原文。 ## 2026-09-08:无响应体的上游回复令本地请求挂起 **现象**:上游返回无 body 的响应(如 204)后,本地请求一直等到客户端超时。 **根因**:透传在 body 为 null 时仅提交响应头便提前返回,没有结束本地响应。 **修复**:无 body 同样走统一释放 / 结束路径;流式空回复仍经过无输出重试判定,reader 在结束或失败后释放。 ## 2026-09-07:DSH 更新后 dsh web 无限重启;本机版本忽高忽低 ### 现象 关于页点「更新宿主」或勾选自动更新后 `dsh web` 反复重启,本机版本一直停在 0.1.2-alpha.5;换个终端启动又显示别的版本。 ### 根因 探测把 `$_`、PATH 上的 `dsh`、各全局 prefix 都当候选,报出的不是当前进程那份;`npm install -g` 写进 `npm prefix -g`(`~/.local`),运行中的是 `/opt/homebrew`;宿主只看 npm 退出码 0 就重启,重启后版本未变再装再重启。 ### 修复 只认 `DSH_BIN_PATH` / `process.argv[1]` 这份;安装用 `--prefix` 指向该份所在 npm prefix;装完探测版本须与目标精确一致才重启,否则报 `installed-unchanged` 不重启,且自动更新记住该目标、下个整点跳过(手动点击仍重试)。前端本机版本按宿主 → 快照 → 静态戳取值,不再取三者最新。 ## 2026-09-06:切到 Codex 整卡闪入 ### 现象 每次打开 Codex(及其他家族)整张卡重新出现,入场动画一闪,刺眼。 ### 根因 `tab === id && card()` 卸载再挂载,加上 `.osubs-pane > *` clip/opacity 入场。 ### 修复 各 tab 面板常驻 `hidden` 切换;去掉 pane 入场动画。Settings 重挂时用 localStorage 上次 status 先画出账号卡,避免空壳再整卡灌入。额度条不再从 100% scale 过渡到真实剩余。 ## 2026-09-06:未登录 Copilot 模型列表被收成「登录后同步」 ### 现象 模型页 GitHub Copilot 未登录时只剩标题、已开启 10/10 和登录按钮,没有和其他 OAuth 一样列出禁用 checkbox。 ### 根因 `ModelFamily` 在 `!loggedIn` 时不渲染 `.osubs-models`。 ### 修复 未登录仍画出模型行,checkbox 保持 disabled;全选/全关仍换成登录。 ## 2026-09-06:关于页本机 DSH 版本无法从已下发静态资源读取 ### 现象 本机版本一直是 —。GitHub Tag / npm 能显示。HTML、manifest、shell JS、client-modules bundle 均无 semver。 ### 根因 dsh web 不下发 package.json;boot 图只有 content hash。宿主 RPC 未重启时也读不到 CLI 版本。 ### 修复 把本机版本写入已下发的 `lib/ui/client.js` 哨兵 `DSH_HOST_VERSION_STAMP`;插件 apply 时盖戳,前端优先读该静态常量。 ## 2026-09-06:自动更新勾选报 unknown oauth-subs method autoUpdate ### 现象 关于页勾选「检测到新版本时自动更新」立刻失败,红字 `unknown oauth-subs method autoUpdate`,checkbox 弹回未选。 ### 根因 前端已热更,宿主 Cordis 进程仍是旧 RPC 表,没有 `autoUpdate`。失败后 `snap.autoUpdate` 仍为空,受控 checkbox 被打回。 ### 修复 勾选先写入 localStorage 并乐观更新 UI;RPC 缺失时静默忽略;宿主就绪后再把本地偏好同步上去。 ## 2026-09-06:关于页未展示 DSH 本机与官方/npm 最新版本 ### 现象 关于页 DeepSeek Harness 本机版本为 —;官方 Tag / npm 版本曾整块缺失。后来 Tag 与 npm 能显示,但仍提示「请在终端重启 dsh web」,且无法选定版本回退。 ### 根因 宿主进程未加载新后端时 `dshUpdate` RPC 不存在;本机探测不能在浏览器里完成。安装成功后只提示手动重启,没有版本下拉。 ### 修复 去掉重启提示;npm 版本下拉支持升级/回退;安装成功后自动重启 `dsh web`。 ## 2026-09-06:DSH 官方 GitHub Tag 无法直接通过 git/tarball 作为 npm 包安装 ### 现象 尝试通过 GitHub Tag(如 `dsh-v0.1.3-alpha.1`)的 Git URL 或 Tarball 直接执行 `npm install -g` 报错退出,未能作为全局 CLI 安装。 ### 根因 DSH 官方仓库为 pnpm monorepo,根目录为 `private: true` 且无构建产物 `lib/bin.js`(被 gitignore),必须依赖官方 CI 编译发布至 npm。 ### 修复 监控分别请求 GitHub Tags 与 npm registry;仅在 npm 发布新版时允许更新,仅有 GitHub Tag 时展示提示且不盲目调用安装。 ## 2026-09-06:Cursor composer-2 下线致流中断「Stream ended without finish_reason」 ### 现象 Cursor 官方下线 composer-2 / composer-1.5,对话报错 `ERROR_MODEL_NO_LONGER_SUPPORTED`;代理丢弃 Connect 错误详情且直接截断流,客户端显示「Stream ended without finish_reason」。 ### 根因 静态模型底表强制把 composer-2 / composer-1.5 重新塞入已发现列表;流式代理在收到上游首包前过早发送 SSE 200 头,中间出错未以内容形式输出并干净终止。 ### 修复 `mergeCursorStaticFloor` 优先信任非空在线列表并从静态底表移除已下线模型;`consumeCursorFrames` 提取 Connect 错误说明;`forwardCursor` 延迟首包并安全收尾。 ## 2026-09-05:Ollama 每周条不画「n后重置」 ### 现象 5 小时条有「3 小时 17 分钟后重置」。每周条只剩剩余 %,倒计时空。官方 Cloud UI 两条都有。`GET /api/usage` 的 `limits.weekly` 仍只有 `usage` + `models`。 ### 根因 `ollamaWindowResetAt` 缺 stamp 时只给 session 推 5h unix 桶。Weekly 只信 wire。#12532 的 `604800-((epoch-4d)%604800)` 当时当未证实偏移留下。 ### 修复 Weekly 缺 stamp → `ollamaWeeklyResetAt`(下一 UTC 7d 桶、偏移 −4d = 周一 00:00 UTC)。Wire stamp 仍优先。不 `now+7d`,不刮 settings HTML。 ## 2026-09-05:GLM 体验套餐(Start Plan)对话 3007,决定不支持 ### 现象 体验套餐 JWT 打 `https://zcode.z.ai/api/v1/zcode-plan/anthropic/v1/messages` 一直 `400 {"code":3007,"msg":"captcha verify failed"}`(有/无 Desktop 指纹都一样);同一 JWT 打 `open.bigmodel.cn` 是 401。 ### 根因 ZCode Desktop 对 zcode-plan hop 注入阿里云 captcha 头。插件不伪造、不接 captcha SDK,这颗头过不去。 ### 修复 不支持体验套餐:`glmKeyFromZcodeConfig` 跳过 start-plan JWT、不捡 `enabled: false` 的死 coding-plan key(没有可用的就导入失败);目录 / 路由只留 Coding Plan 三行。试用对话在 ZCode.app。 ## 2026-09-05:模型里看不到 GitHub Copilot ### 现象 0.0.74 用户说「模型里面没有显示 GitHub Copilot 的模型」。本机 `auth.json` 无 `copilot` session。 ### 根因 Harness picker 只在登录后写入 `oauth-copilot`。Settings 目录虽有锁定组,标题是 `OAuth · Copilot`,且九家长 checkbox 把最后的 Copilot 顶出视口。 ### 修复 展示名改为 `OAuth · GitHub Copilot`。未登录家族只留标题 +「登录后同步」+ 登录跳转,不再铺禁用 checkbox。 ## 2026-09-05:移除 OpenCode Go Free ### 现象 Settings 仍有 OpenCode Go Free 页签,`oauth-opencode` 还在 llm-pi-ai。 ### 根因 维护者要求整条产品线下架(Zen 匿名免费档与 Go Free 都不要),不是再改名。 ### 修复 删 `src/oauth/opencode/`。FAMILY_IDS / 目录 / 代理 hop / Settings 页签去掉。`RETIRED_FAMILY_IDS` 仍 unset 残留 `oauth-opencode`。 ## 2026-09-05:额度「n后重置」夹在两条进度条中间 ### 现象 Ollama Cloud(及其他共用 `QuotaRow` 的卡)「5 小时」和「每周」之间浮着「3 小时 16 分钟后重置」,分不清属于哪条窗口。 ### 根因 `QuotaRow` 把 `formatReset` 画在整条 meter 后面。`.osubs-qmeter { display: contents }` 让重置行和下一窗口标签同一列,间距看起来像共享说明。 ### 修复 重置改到该条 `QuotaMeter` 内、百分比行下方、进度条上方。无 `resetAt` 的窗口不画。两条都有就各画各的。 ## 2026-09-05:OpenCode Go Free 被做成了 Zen 匿名免费档 ### 现象 Settings 家族叫 OpenCode Free,picker 是 `big-pickle` / `ling-3.0-flash-fin-free` / Muse Contributor Free 等 Zen `/zen/v1` 行。 ### 根因 实现抄了 Hermes `opencode-free`(匿名 Zen)。产品意图是 OpenCode Go(`/zen/go/v1` + API key),不是 Zen 免费档。 ### 修复 hop 改 `https://opencode.ai/zen/go/v1`,目录 live Go ∩ 去掉 `OPENCODE_ZEN_FREE`,贴 Go API key;废匿名哨兵。 ## 2026-09-05:Copilot 用 OpenCode Ov23li8 换不出 tid= ### 现象 设备码登录后预览模型 400 `model_not_supported`,Business 403。`GET /copilot_internal/v2/token` 404。 ### 根因 OpenCode 自家 OAuth App `Ov23li8tweQw6odWQebz` 发 `gho_`,GitHub 不给 vscode-chat session。VS Code / goose / Cherry Studio / hermes 走公开 `Iv1.b507a08c87ecfe98`(`ghu_`)。 ### 修复 设备码 `client_id` 用 `Iv1.b507a08c87ecfe98`,换 `tid=` 再打 `api.githubcopilot.com`。导入的 OpenCode `gho_` 404 时退回 raw Bearer(只保 GA 模型)。 ## 2026-09-05:OpenCode Free 无 x-opencode-session,缓存按 IP 混 ### 现象 长聊 DSH `cacheReadTokens` 一直是 0。同一对话后续轮次像全新 prompt。匿名流量和别的会话挤在同一 sticky 提供商上。 ### 根因 hop 对齐 hermes「不发 Authorization」,`opencodeCacheHeaders()` 为空。官方 CLI v1.18.29 发 `Bearer public` + `x-opencode-session`(Zen `stickyId`;空则回落到 IP)+ `x-opencode-request` + `x-opencode-client: cli`。 ### 修复 对齐 [anomalyco/opencode](https://github.com/anomalyco/opencode) v1.18.29。`Bearer public` 是无 key 哨兵(不是 store 的 `anonymous`)。session 头写 DSH pin。Zen 若回 `cache_read_*` 再译成 `cached_tokens`。 ## 2026-09-05:Cursor 选择器只有 Composer 2 / 1.5 等 5 个 ### 现象 Settings OAuth · Cursor `已开启 2/5`。没有 Composer 2.5、Grok 4.6、Claude Opus 5、Fable 5.1、GPT-5.6、Gemini。 ### 根因 静态 `CURSOR_MODELS` 停在年中 5 行。活目录非空时整表替换静态,GetUsableModels 仍返回旧 5 个时官方新模型进不了 picker。 ### 修复 静态对齐 [cursor.com/docs/models-and-pricing](https://cursor.com/docs/models-and-pricing)(Composer 2.5 / Grok 4.6 / Fable 5.1 / Opus 5 / Gemini 3.1 Pro / 3.8 Flash / GPT-5.6 Sol·Terra·Luna)。`mergeCursorStaticFloor` 把活家族叠在静态楼上。 ## 2026-09-05:本地 DSH Cursor 缓存命中率显示为 0% ### 现象 长 Cursor 会话 DSH `cacheReadTokens` 一直是 0。同一 `conversation_id` 的后续轮次仍像全新 prompt。 ### 根因 `TurnEndedUpdate` 在 `@cursor/sdk` 1.0.27 已有 `cache_read_tokens`,hop 只把 field 14 当结束标志。历史 turn 的 `messageId` / `requestId` 每跳 `randomUUID()`,conversationState prefix 字节全变。CLI 指纹停在 `cli-2026.05.01-eea359f`。 ### 修复 解码 field 3 → `prompt_tokens_details.cached_tokens`。turn id 改内容哈希。`x-request-id` = `x-original-request-id`。CLI 指纹对齐 pi-cursor `cli-2026.07.23-e383d2b`。不改 `client-type: sdk`(本 hop 是 CLI OAuth)。 ## 2026-09-05:关于页更新成功但重启后版本仍旧 ### 现象 磁盘与 pnpm-lock 已是 0.0.71,About 仍显示 0.0.70。触发是周四夜起一直活着的 Homebrew `dsh web`;zsh wrapper 的 `~/.dsh.pid` 杀不到那个 PID,用户以为已重启。 ### 根因 旧进程仍加载更新前模块,且 `installedVersion()` 把 `require('../../package.json')` 冻在加载时。 About 优先 snapshot 旧 version;apply 成功后仍返回更新前的 `info.version`。 ### 修复 每次读 package.json(失败返回空)。About 取检查结果与 snapshot 的较新者。apply 成功后再读一遍再返回。 ## 2026-09-03:OpenCode Free 目录漏 Big Pickle、含过期 DeepSeek/Laguna ### 现象 picker 有 `deepseek-v4-flash-free`(400 Model is unavailable)和 `laguna-s-2.1-free`(503)。官方 Free 里的 `big-pickle` 进不了目录。 ### 根因 `isOpencodeFreeSlug` 只认 `*-free`。Zen `/models` 还挂着过期 slug;`big-pickle` 官方免费但不带 `-free`。 ### 修复 匿名 picker 改官方 7 个 id 白名单 ∩ live `/models`。静态楼同样 7 个。DeepSeek/Laguna 下架。 ## 2026-09-03:OpenCode Muse Spark 500 Internal server error ### 现象 DSH 选 Muse Spark 1.3 Xhigh 五次重试都是 `500 Internal server error`。同 hop 打 `muse-spark-*-contributor-free` completions 500;直连 Zen `/zen/v1/responses` 200。 ### 根因 `proxy.ts` 把 OpenCode 全家转发到 `/zen/v1/chat/completions`,`/opencode/v1/responses` 还 501。Zen 文档把 Muse Spark 放在 `/zen/v1/responses`。 ### 修复 `isOpencodeResponsesModel` 认 `muse-spark*`。Completions hop 把 chat body 译成 Responses 打 Zen `/v1/responses`,再译回 chat.completion。`POST /opencode/v1/responses` 对 Muse 不再 501。 ## 2026-09-03:额度失败红字撑破账号卡 ### 现象 Kimi 卡「额度读取失败」把 429 JSON(`resource_exhausted` / protobuf details)单行贴出,红字冲出卡片右缘。 ### 根因 `QuotaBlock` 原样拼接 `quota.error`。`.osubs-hint` 不换行。上游 body 是无空格长 JSON。 ### 修复 解析 `error.message` / `message` / `code`,截首行 ≤160。`.osubs-hint` / `.osubs-bad` `overflow-wrap: anywhere`。全文只留 `title`。 ## 2026-09-03:OpenCode Free picker 全是 text、没有思考档 ### 现象 8 个 live `*-free` 在 DSH 里都是 `input: ['text']`、无 `reasoningEfforts`。muse / mimo 实际能图,laguna / deepseek / muse 有 effort 档。 ### 根因 Zen `GET /zen/v1/models` 只有 `{id,object,created,owned_by}`。能力在 models.dev `opencode.models`。目录没 overlay,又不敢写 `reasoningEfforts: false`。 ### 修复 Zen 定 id,models.dev overlay 窗口 / `text|image` / effort 图。空 options + reasoning 省略字段。有图才 stamp Completions `compat`。hop 只发顶层 `reasoning_effort`。 ## 2026-09-03:OpenCode Free 空 roster 未登录,settings 没有 oauth-opencode ### 现象 plugin 0.0.68 重启后 `POST /opencode/v1/chat/completions` 500 `OpenCode Free is not logged in`。`auth.json` 无 `opencode`,`settings.yaml` 无 `oauth-opencode`,用户无法选模型或对话。 ### 根因 匿名 Zen 仍要先点 Settings「启用免费模型」才写哨兵并 sync。空 roster 不自动启用。Completions 行 `reasoningEfforts: false` 可能让 DSH 丢掉整段 mutate。 ### 修复 空 roster 在 start / snapshot / sync 写 `opencodeSession()` 并 `syncHarnessModels`。不覆盖已有 session。hop 仍不带 Authorization。省略 `reasoningEfforts`,不 stamp Completions `compat`。 ## 2026-09-03:OpenCode Free 带 Bearer 会 401;硬编码目录 delist 后仍 401 ### 现象 匿名 `https://opencode.ai/zen/v1` 打 `*-free` 带任意 Authorization(空串、哨兵 `anonymous`、过期 Zen key)都 401。硬编码 `hy3-free` 在目录轮换后 picker 仍 401。 ### 根因 Hermes `opencode-free` 把 SDK Bearer 盖成空头。本插件 hop 若转发 store 哨兵同样 401。Zen 免费档会 delist。`ox-alpha-free` 看起来免费但是 Go 订阅。`big-pickle` 只给官方 CLI UA。 ### 修复 store 哨兵 `anonymous` / 空串 / 过期 Zen key 不当 Bearer。官方无 key 是 `Bearer public`(见上条 session 头)。live `GET /zen/v1/models` ∩ 官方 Free 白名单,不含 hy3-free / Go keyed。 ## 2026-09-03:Ollama 周模型 note 一行溢出 ### 现象 Weekly 下 `glm-5.3-flash × 1317 · web search × 3 · web fetch × 2` 挤成一行溢出。 ### 根因 `ollamaModelsNote` 用 ` · ` 拼一条。`span.osubs-note` 不换行。 ### 修复 每条 `name × count` 换行。`.osubs-note` `white-space: pre-wrap` + `overflow-wrap: anywhere`。web search / web fetch 保留。 ## 2026-09-03:tab 栏右侧空白 / 两胶囊对不齐 ### 现象 OAuth 和 Models/GitHub 两胶囊贴左边后,整条 tab 右侧还有一大块空白。icon 挤在 36px 格子里。 ### 根因 `.osubs-tabs` `width: max-content` + `flex: none`,8×36 不吃剩余宽度。更早是 nav `space-between` / util `margin-left: auto` 把第二胶囊推到最右。 ### 修复 两胶囊保留,nav `flex-start` + `gap: 4px`。OAuth 胶囊 `flex: 1 1 auto`,`repeat(8, 36px)` + `justify-content: space-between`,剩余宽度进 8 个 icon 之间。util 仍 36px。空态 OpenCode 主按钮是「启用免费模型」,不是「登录」。 ## 2026-09-03:Kimi Code 不能写自定义 api;设备码过期要重开 ### 现象 `api: kimi-openai-completions` 整段 `llm-pi-ai` 被丢。设备码过期后一直转圈。Settings 里 `import { Kimi }` 图标空白。 ### 根因 DSH `api` 只有三值。Kimi 上游是 Completions。`expired_token` 必须重新 `device_authorization`。经典脚本 UI 不打包 `@lobehub/icons`。 ### 修复 `api: openai-completions`,hop `/kimi/v1/chat/completions`。`DeviceFlowManager.restartOnExpired`。LobeHub `kimi.svg` path 进 `TAB_ICONS`。 ## 2026-09-03:两张 Cursor 卡刷新时间一种日期一种倒计时 ### 现象 PRO 卡「9月24日 13:23」,ULTRA 卡「13天9小时50分钟后重置」。同一 Settings 栏两套格式。 ### 根因 `formatReset` / `formatRelativeReset` 满 14 天改打 `toLocaleString`。两套餐 `resetAt` 一个约 21 天、一个 13 天。 ### 修复 额度重置一律相对时间(天/小时/分钟)。`formatStamp` 只留给重置券过期。删 14 天门槛。 ## 2026-09-03:Settings tab 九个 icon 仍挤一行 ### 现象 7 家族 + Models + About 九个 icon-only tab 在宽栏仍并排一行。用户要一行 8 个、第 9 个换到第二行。 ### 根因 `.osubs-tabs` 是 `flex-wrap` 无列数。格子钉 36px 后够宽就 9 个并排,不会在第 8 个后折行。 ### 修复 8 列 grid:`grid-template-columns: repeat(8, 36px)`,About 落到第二行。禁止 `flex: 1 1 0` / 把格子 `min-width` 收到 0。 ## 2026-09-03:Ollama 卡无额度条、抬头是 ollama-sha8 ### 现象 已登录卡只有 KEY / 使用中,无套餐、无剩余条。抬头 `ollama-3f67f6bb`。官方 Cloud usage 是 Pro + Session 0% used + Weekly 9.5% used。 ### 根因 `QuotaStore#load` 对 ollama 直接 idle。`POST /api/me` 字段是 `Email`/`Name`/`Plan`,解析只读了小写 email。`limits.*.usage` 是 0..1 分数。 ### 修复 并行 GET `/api/usage` + POST `/api/me`。`usedPercent = fraction * 100`,剩余条。`pro`→Pro。刷新后把 Email 写回 session,opaque `ollama-` `replaceAccountId`。无 `resets_at` 不编倒计时。 ## 2026-09-03:Ollama picker 把 glm-5.3-flash 标成纯文本 ### 现象 DSH 在 `glm-5.3-flash` 上挡图片(不支持图片)。Cloud `POST /api/show` 的 `capabilities` 含 `vision`。 ### 根因 `inferOllamaInput` 只认 `/gemma|vision|\bvl\b|-vl/`。`glm-5.3-flash` / `kimi-k3` / `qwen3.5` / `mistral-large-3` 等 vision 行对不上。`/api/tags` `details` 空,没有 capabilities。 ### 修复 `ollamaShowInput` 读 show.capabilities(大小写不敏感)。`applyOllamaShowWindows` 同时钉 `input`。19 行快照按 2026-09-03 show 表烘焙(flash 图文,`glm-5.3` 纯文本)。无 capabilities 才回落名字 regex。不发明 audio。 ## 2026-09-03:Cursor 刷新后仍是 auth0|… / PRO / 已用 0%;Ollama 图标被挤没 ### 现象 PKCE 卡抬头 `auth0|user_…`、PRO、已用 0%/0%。IDE 卡 PRO(实 Ultra)、API 已用 0%(实 0.454%)。点刷新额度不变。Ollama 图标在窄 Settings 栏消失。 ### 根因 `GetCurrentPeriodUsage` 无 email,缺 `membershipType` 时默认 Pro。`clampPct` 把 0.454 收成 0。刷新没打 GetEmail / `full_stripe_profile`。九个 tab `flex:1 1 0` 被 `min-width:0` 压到 0。 ### 修复 刷新并行 GetEmail(必要时 GetMe)+ stripe。回填 `cachedEmail` / opaque `replaceAccountId`。套餐用 `individualMembershipType`。已用>0 且四舍五入为 0 则显示 1。条走 `RemainingBar`/`QuotaMeter`(剩余)。Tab wrap,每格 36px。 ## 2026-09-03:Kiro 复合 tool id / 静态目录缺口 / 思考 XML ### 现象 Responses 形 `call_…|fc_…` 超 64 且含 `|` → AWS 400。picker 仍是静态表,缺 Auto / `claude-fable-5`。`MONTHLY_REQUEST_COUNT` 被当 429 锤。思考事件写成 `` 进 `content`。 ### 根因 翻译层 + 离线目录。hop 仍是 `q..amazonaws.com` `GenerateAssistantResponse`,不是 `runtime.*.kiro.dev`。 ### 修复 非法 id 稳定 remap 成 `tooluse_<32>`(use/result 同一函数)。登录后 `ListAvailableModels`(空/403 再探 us-east-1 / eu-central-1)。`MONTHLY_REQUEST_COUNT` → 400。thinking → `reasoning_content`。GPT-5.6 Sol/Terra/Luna 不删。 ## 2026-09-03:Ollama Cloud — signin 不是 Bearer,无 cache-read ### 现象 社区把 `ollama signin` / `id_ed25519.pub` 当 Cloud key。还指望 cache 命中率。 ### 根因 本家族是 Cloud API key + Completions 薄透传,不是 localhost:11434,也不是 PKCE。signin 身份不能当 Bearer。cache-read 官方没给。 ### 修复 粘贴 API key + 空花名册 `OLLAMA_API_KEY`(在添加账号 Dialog 里)。hop:`POST /ollama/v1/chat/completions` → `https://ollama.com/v1/chat/completions`。**不能**把 local signin 变成 Bearer,也不能发明 `cached_tokens`。额度见上条 `/api/usage`。 ## 2026-09-03:Ollama contextWindow 不能猜家族默认 ### 现象 picker 把 Cloud 窗口写成 128k/200k/256k。`minimax-m2.7` 超报(200000 vs 196608)。`glm-5.3` / `kimi-k3` / `deepseek-v4-*` 实际是 1M。 ### 根因 `/api/tags` 的 `details` 空。家族 regex 不是 Cloud cap。`extraCloudModelLimits` 过期。 ### 修复 `contextWindow` = `POST /api/show` `model_info.*.context_length`,钉在 19 行快照;登录后 live show 覆盖;失败回落快照,不回落 128k regex。 ## 2026-09-03:Cursor 卡抬头是 JWT `sub`,不是邮箱 / 用户名 ### 现象 Settings → Cursor 抬头是 WorkOS 形 `provider|user_…`。登录和两条额度杠正常。 ### 根因 `cursorAccountFromToken` 在无 email 时回落 JWT `sub`。vscdb 没读 `cursorAuth/cachedEmail`。GetCurrentPeriodUsage 经常也没有 email。 ### 修复 可见身份:JWT `email` / `preferred_username`,然后 cachedEmail,然后 GetEmail / GetMe,然后 usage email。永不展示 `sub` / `cursor` / `provider|user_*`。没有人类 id 就省略抬头。vault 仍可用 `sub`,刷新后 `replaceAccountId`。 ## 2026-09-03:GLM 账号卡身份显示内部 id,不是邮箱(始 08-30) ### 现象 已登录卡抬头先是 **zcode**(CLI app id),挡住站点 id 后又变成 poll `user.id` / 短字母数字 handle。登录成功,用户名不对。 ### 根因 身份层。`zcode` / `zai` / `bigmodel` / `glm`、纯数字 uid、UUID / 长 hex、无 `@` 的短 handle 都是智谱内部 id。官方展示是 JWT `email` / `preferred_username`,或 userinfo / `getCustomerInfo`。`accountFromJwt` 不取 `sub` / `id`。 ### 修复 `isGlmOpaqueAccount` 拒绝上述值。优先邮箱,其次电话,再次人类 `customerName`。没有邮箱就打 userinfo;失败省略抬头,不回落 uid。已存 opaque vault 行 snapshot 回填。卡抬头不走 `accountIdOf`。 ## 2026-09-03:Cursor 选择器仍是静态 5 行 — 活目录没接到 picker / yaml ### 现象 Settings / `oauth-cursor.models` 只有冻结的 5 个 id。账号在 Cursor 里能用的 Auto / Claude / Gemini 进不了勾选格。 ### 根因 `fetchCursorUsableModels` 已能 unary `GetUsableModels`,`buildProviders` 只读 `CURSOR_MODELS`。发现层写了、目录层没用。 ### 修复 `refreshCursorCatalog` 登录 / 导入 / 额度后拉活列表;失败回落静态 5,不挡对话。`toCursorPickerModels` 收成一行/家族。`reasoningEfforts` 键只有 `off|low|medium|high|xhigh`。活列表进 yaml。 ## 2026-09-03:Cursor 额度条把美分封顶画成「40000 / 40000」 ### 现象 卡片 `40000 / 40000`、一条「本周期」。仪表盘其实是「补全 & Composer」与「API 调用」两条已用百分比。`includedSpend` / `limit` 是美元封顶。 ### 根因 `parseCursorPeriodUsage` 只发 `kind: 'cycle'`,used/total 取 spend cap,忽略 `autoPercentUsed` / `apiPercentUsed`。 ### 修复 两条 `kind: 'product'`(`auto` / `api`)。不写 includedSpend/limit。`resetAt` = `billingCycleEnd`。条是剩余(`100 - used`),不要 `showUsed` / 「已用」。 ## 2026-09-03:Cursor 本机导入 — Keychain 可能弹授权,vscdb 键名可能改 ### 现象 「导入本机 Cursor」或空花名册自动导入时,第一次读 macOS Keychain 会弹系统授权;或 Cursor 改了 `state.vscdb` `ItemTable` 键名后导入变空。 ### 根因 本机登录复用,不是第二套 OAuth。Keychain / vscdb schema 由官方 CLI / IDE 拥有。 ### 修复 顺序:`CURSOR_ACCESS_TOKEN` → Keychain+vscdb → 仍有效的本地 access → refresh。空花名册才自动导入,已有 PKCE/session 不覆盖。WSL 只解析当前 Windows 用户,不扫 Public / Default / 其他 profile。弹窗与键变更:**本插件不能消掉系统授权,也不能钉死官方 schema**;失败走空文案。 ## 2026-09-03:Cursor Run 没有文档化的 cache-read 字段 ### 现象 长对话 `cacheReadTokens` / 命中率可能一直是 0%,即使 `conversation_id` 粘住了。 ### 根因 Cursor Agent conversation cache。Run 没有与 Codex / Gemini / Kiro 对等的稳定 cache-read 字段。 ### 修复 粘性 id + system pin 在 `src/oauth/cursor/cache.ts`。看见 `cached_tokens` 才映射。**非修复**:不能发明 cache-read。命中率 0% 不代表 conversation 断了。禁止 `Date.now()`。 ## 2026-09-03:Cursor 非流 Completions 是收集 Run 流后再回一条 JSON ### 现象 DSH `openai-completions` 非流 POST `/cursor/v1/chat/completions`。上游 `AgentService/Run` 本身是 Connect 流。 ### 根因 协议层。Cursor 原生是 protobuf,只能 Completions + 翻译;不是 SSE-only。 ### 修复 `forwardCursor` 非流等 Run 结束后 `cursorToOpenai`。`stream: true` 仍写 SSE。`POST /cursor/v1/responses` → 501。 ## 2026-09-03:Cursor Connect/protobuf 是社区逆向,官方改线会断 ### 现象 对话走 `agentn.us.api5.cursor.sh` `agent.v1.AgentService/Run`。字段号、host、CLI 指纹随时可能被改掉,表现为 4xx / 空流 / 工具步对不上。 ### 根因 上游未公开稳定 REST。本插件不能拥有 Cursor 的 wire。 ### 修复 最小编码器 + Node `http2`。**改线后对照社区协议与 `@cursor/sdk` 再改 `src/oauth/cursor/`**,不要从别的家族抄 cache / hop。指纹钉 `x-cursor-client-version: cli-2026.07.23-e383d2b`。 ## 2026-09-03:Antigravity Cloud Code 400 — JSON Schema、首条必须是 user ### 现象 Claude / GPT-OSS 自定义工具立刻 400:`Unknown name "additionalProperties"`(或 anyOf / `$ref` / format / nullable)。Gemini 3 若 `contents[0].role === "model"` 或 `systemInstruction` 缺 `role: "user"` 同样 400。`maxOutputTokens` 超线 id 上限也是 400。 ### 根因 `openaiToAntigravity`(`src/oauth/antigravity/request.ts`)。Cloud Code Claude/GPT 桥吃 protobuf `Schema`,不是 JSON Schema。Gemini 3 要求第一条 user。 ### 修复 Gemini:`parametersJsonSchema`。Claude / GPT-OSS:allowlist `parameters`,配对 `functionCall.id`(Gemini 3 不发 id)。model 开头补 `Hello` user;`systemInstruction.role = "user"`。Claude 永远 `VALIDATED`。`maxOutputTokens` 只走钳位表。chat 头只有 User-Agent;**不要**加 `anthropic-beta` / `Client-Metadata` / `x-goog-api-client`。不改 fingerprint、`requestType: "agent"`、picker 线 id。 ## 2026-09-03:Antigravity Gemini 3.8 Flash 线 id 是 `gemini-3.8-flash-high` ### 现象 官方文档 / 选择器是 Gemini 3.8 Flash(Medium 档)。Gemini API 裸 id 是 `gemini-3.8-flash`。那不是 Cloud Code 线 id。 ### 根因 Cloud Code 用 effort 后缀 id。把裸 `gemini-3.8-flash` 发给 daily-cloudcode-pa 会走错线。CCA 当天没有 3.8 ≠ 线上没有。 ### 修复 `ANTIGRAVITY_MODELS` 一行 `gemini-3.8-flash-high` / `Gemini 3.8 Flash`(窗口同 3.7)。不加 Cyber,不发明 quota 条,不把 `-low` / `-medium` 拆成独立 checkbox。 ## 2026-09-03:Antigravity 工具轮 400 缺 `thought_signature`(始 09-01) ### 现象 `Function call is missing a thought_signature in functionCall parts`(`INVALID_ARGUMENT`)。DSH 工具再放进 `contents` 时签名丢了。 ### 根因 `collectAntigravityParts` / `openaiToAntigravity`。签名在 part 级 `thoughtSignature`,不是 OpenAI `tool_calls` 标准键。DSH Completions 没有一等该字段。 ### 修复 入站读 part / `functionCall` 上的签名,抄到 `tool_calls`(含 `extra_content.google.thought_signature`);DSH 剥键时按 session 再贴回 part 级。缺签名不编空串 / 不发 `skip_thought_signature_validator`。Gemini 3 一组仍无签名:丢掉这组 `functionCall`,匹配 tool 结果改成 user Observation。Claude / GPT-OSS 仍发 unsigned。 ## 2026-09-03:Kiro tool_result 与 tool_use 不相邻(始 09-01) ### 现象 `unexpected tool_use_id found in tool_result blocks`。交错 `assistant(A) / user / assistant(B) / toolResult(A)` 仍 400。 ### 根因 先 `flushUser` 会把 pending result 贴到错的 assistant。只靠位置 flush 不能处理 displaced result。`parkKiroSystemExtra` 也可能插进 unpaired `toolUses` 与 `toolResults` 中间。 ### 修复 `relocateDisplacedToolResults` 先按 id 纯重排(不编造、不丢已有 call 的 result)。再 `flushAssistant` 再 `flushUser`。extra system 仍挂后缀,永不夹在一对中间。 ## 2026-09-01:Codex 上游 400 `Unsupported parameter: session_id` ### 现象 DSH 长会话带 `session_id` 时 chatgpt.com 400。只带同一值的 `prompt_cache_key` 是 200。 ### 根因 `applyCodexCache` 把 `session_id` 抄到 `prompt_cache_key` 和亲和头,但原字段还留在对话 Responses body。chatgpt.com 不认这个 DSH 字段。 ### 修复 写出清洗后的 `prompt_cache_key` 后 `delete session_id`。头仍是 `session-id` = `x-client-request-id` = `prompt_cache_key`。不把 Codex `prompt_cache_key` 抄给别的家族。 ## 2026-09-01:Kiro overlay 后 usage 仍 0/0/0 — 现场没有 metadataEvent ### 现象 refresh 429 修好后每个 200 仍是 `{prompt_tokens:0,completion_tokens:0,total_tokens:0}`。现场 eventstream 常见 `contextUsageEvent` / `meteringEvent`,很少下发 `metadataEvent.tokenUsage`。 ### 根因 `mapKiroUsage` 只认 `metadataEvent`。`contextUsageEvent` 是百分比;`meteringEvent` 是 credit,不是 token。 ### 修复 有 `tokenUsage`(含 snake_case)优先,并加 `cacheWriteInputTokens`。否则 `prompt_tokens = contextUsagePercentage/100 * contextWindow`,completion 按输出字数估。不把 metering credit 当 token,不编 `cached_tokens`。连 contextUsage 也没有则保持 0/0/0。 ## 2026-09-01:Kiro 0.0.57 live — 每轮 refresh 429 ### 现象 短聊能通,但多数轮死在 `kiro social refresh failed (HTTP 429)`,DSH 看到的是 500。`expiresAt` 在大量 200 之后仍停在旧毫秒戳。 ### 根因 `expiresAtOf()` 看见已有 `>1e12` 就丢掉 refresh JSON 的 `expiresIn`,于是每条请求都打 `/refreshToken`。`readJson()` 非 2xx 无 `.status`,代理 `error.status ?? 500`。 ### 修复 刷新成功后一律用新的 `expiresIn` / `expiresAt` 写 `expiresAt`(IdC / Entra 同一条)。`KiroHttpError` 带 `status` + `Retry-After`,代理原样回 429。eventstream 头解码所有 AWS 类型(勿只认 type-7 string)。 ## 2026-08-31:Antigravity 长聊缓存命中率 0 / Google 不回 cached_tokens ### 现象 页脚命中率 0%。早期是 mapper 没抄 `cachedContentTokenCount`;钉了 system 之后 Google 仍常不回该字段(工具 JSON / `thinkingConfig` 闪断)。 ### 根因 Gemini 隐式缓存吃 **systemInstruction + contents 前缀 + tools**。DSH 每步塞 runtime-context snapshot,工具 key 顺序和 `reasoning_effort` 有无会抖。缺 session 时各模型共用 `dsh-antigravity`。禁止 `` `-${Date.now()}` ``。 ### 修复 `pinAntigravitySystemInstruction`:首次钉住,多余 snapshot → trailing **user**。`pinAntigravityTools`:names+schemas 等价则复用首份字节。`pinAntigravityThinking` sticky-first。不发 `implicitCacheConfig`。fallback `dsh-antigravity:`。`cachedTokensOf` 兼读 `cache_read_tokens` / `cacheReadTokens` / `cacheReadInputTokens`。 ## 2026-08-31:Kiro 18 个模型多轮 cacheReadInputTokens 偏低 ### 现象 长 system + tools 前缀下多轮 cache 偏低;同一 DSH session 换模型还打到同一条 AWS conversation。 ### 根因 `openaiToKiro` 把全部 system 拼进每一轮 `currentMessage`。`conversationId` 回落裸 `dsh-kiro` 且不带 model。`cacheReadInputTokens` 没映到 `prompt_tokens_details.cached_tokens`。官方 wire 无 system 字段。 ### 修复 system 钉 history 首对 user + ack `I will follow these instructions.`;增量 snapshot 挂后缀(不插在 toolUses/toolResults 之间)。`conversationId` = DSH pin **加 model**;缺 pin 时 `dsh-kiro:`。禁止 `Date.now()`。`cacheReadInputTokens` → `cached_tokens`。不写 Codex / Grok 缓存字段。 ## 2026-08-31:Kiro 登录后 settings.yaml 没有 oauth-kiro ### 现象 Kiro 已登录、选择器勾选亮着,`llm-pi-ai.providers` 仍没有 `oauth-kiro`。Composer 选不到。先修 `none` 键后 yaml 仍冻住。 ### 根因 `syncHarnessModels` 一次原子 mutate。两枚杀手:Kiro GPT `reasoningEfforts` 键写成 `none`(DSH 闭集是 `off|minimal|low|medium|high|xhigh|max`);GLM 改 `anthropic-messages` 后仍带 Completions-only `compat.supportsReasoningEffort` / `thinkingFormat`。`assertServiceable` 拒整段,上次合法 section 保留。 ### 修复 `KIRO_REASONING_GPT` 为 `off: "none"`(键 `off`,值 `none`)。**不要复活键 `none`。** GLM Anthropic 路由不写 `compat`。Kiro / Antigravity Completions 仍可带 `supportsReasoningEffort`。mutate 前 `assertDshServiceableProvider`。裸 `api: openai` 是另一条。 ## 2026-08-31:Kiro 导入只吃第一条,且 IDE token 丢了 IdC client 注册 ### 现象 「导入本机会话」只返回第一个账号。卡密 / 精简 JSON / CSV 被当成非法 Social refresh。Builder ID 从 IDE 文件导入后刷新缺 `clientId`/`clientSecret`。 ### 根因 导入器按 Codex「找一份 auth.json」写。SSO cache 里 token 与 `{hash}.json` OIDC 注册被当成互不相关。 ### 修复 `src/oauth/kiro/import.ts` 自写解析。写入全部账号;IDE token 配对 `clientIdHash` 注册。Settings「粘贴凭证」同一套。 ## 2026-08-31:GLM 默认协议应对齐 ZCode Anthropic,150% 不是协议证明 ### 现象 插件把 GLM 写成 Completions,但 ZCode Desktop UA 是 `ai-sdk/anthropic`,默认 hop 是 Anthropic Messages。 ### 根因 把「有 Completions 兼容」当成 DSH 该选的 `api`。闭集规则:三种里哪条是上游原生就选哪条。150% 是 **身份** 计费,不是协议。 ### 修复 `oauth-glm`:`api: anthropic-messages`,`baseURL: ${origin}/glm`。`POST /glm/v1/messages` → `/api/anthropic/v1/messages`。Completions 残留留到下次 `sync()`。**不要**说切协议就能吃上 150%。不要把 Completions-only `compat` 盖到 Anthropic 路由上。Codex / Grok / Kiro / Antigravity / Cursor 协议不动。 ## 2026-08-31:各家 OAuth 缓存被混成 Codex 一套 ### 现象 Grok / GLM / Kiro / Antigravity 共用 `codexCacheSessionId` 和同一个 `pinCache`,body 上被写 `prompt_cache_key`,头上抄 Codex `session-id`。 ### 根因 把「清洗 DSH session id」当成可共享的缓存实现。各家后端键、头、前缀钉法都不一样。 ### 修复 每家一个 `src/oauth//cache.ts`。`proxy.ts` 只分发。删除 `src/utils/cache-session.ts`。**不要**把 Codex `session-id` / `prompt_cache_key` 写给 GLM / Kiro / Antigravity / Cursor;**不要**把 Grok `x-grok-conv-id` 写给别人。停车形状跟家族,不跟 Codex。 ## 2026-08-31:额度刷新时间只精确到小时 ### 现象 「5 小时后重置」其实还有分钟。4 小时 32 分被显示成 5 小时。 ### 根因 `formatReset` 对 1–47 小时 `Math.round(minutes / 60)`,不是解析丢了 `resetAt`。 ### 修复 按天 / 小时 / 剩余分钟拼接,0 的单位省略。额度重置不再在满 14 天改打绝对日期。 ## 2026-08-31:Antigravity 额度条 / 套餐 STANDARD(始 08-30) ### 现象 先是已登录卡身空白(额度 idle)。后来有条但没有重置时间、按模型系列一条 remaining、pill 显示 **STANDARD TIER**。官方是 Gemini / Claude+GPT 两组,每组 Weekly + Five Hour;订阅在 `paidTier`。 ### 根因 0.0.38 故意不打额度 API。之后只读 `fetchAvailableModels.quotaInfo`(5 小时)和登录时的 `currentTier`(Code Assist SKU = STANDARD)。`resetAt` 没抄上。 ### 修复 先 `retrieveUserQuotaSummary`,失败再回落 `fetchAvailableModels`。两组 weekly + 5h;每组 `resetAt` 取 remaining 最低那条。套餐优先 `paidTier`(Pro / Ultra);`STANDARD TIER` 不显示。Free 仍读 `currentTier: free-tier`。失败 `status: error`,不再静默空卡。 ## 2026-08-31:Kiro 对话 501 → generateAssistantResponse 翻译(始 08-30) ### 现象 已登录、额度 / 目录都活着,Composer 对话 `501`:`Kiro chat is AWS generateAssistantResponse, not OpenAI`。 ### 根因 上游是 CodeWhisperer EventStream(`X-Amz-Target: …GenerateAssistantResponse`),不是 `/v1/chat/completions`。0.0.34 故意 stub 501。 ### 修复 `src/oauth/kiro/request.ts`:OpenAI messages ↔ `conversationState` + eventstream。`forwardKiro` 替换 501。`conversationId` 禁止 `Date.now()`。上游 401/403 改写 **400**(非 AUTH)。`/kiro/v1/responses` 仍 501。 ## 2026-08-31:Antigravity 流式对话「用量 0 tok」且首 token 从半句开始 ### 现象 页脚用量 0 tok;第一条 `text-delta` 从正文中途开始。最终组装文本完整。 ### 根因 Google SSE `part.text` 是**累计全文**;chunk 把全文当 delta,DSH 按累计 diff 丢掉前缀。只有 usage/finish 的末帧被丢掉;`thoughtsTokenCount` 没进 `completion_tokens`。 ### 修复 累计帧只发新后缀。`[DONE]` 前必写带 usage 的收尾 chunk。`completion_tokens` 含 `thoughtsTokenCount`。`part.thought` 仍不进可见 `delta.content`。 ## 2026-08-31:Kiro 模型没有思考深度,也没标明 text / image ### 现象 选择器里 Claude / GPT 没有思考档;附件能力看不出纯文字还是图文。 ### 根因 `kiroModel()` 没有 `reasoningEfforts`;路由没有 `compat.supportsReasoningEffort`。 ### 修复 每行写 `reasoningEfforts` + `input`。GPT 官方 `none` 必须是键 `off` 的值(见上条 yaml)。Haiku / DeepSeek / MiniMax / GLM-5 / Qwen 无档。 ## 2026-08-31:Kiro 登录成功后「打开授权页」还在 ### 现象 Social 已登录、状态「已登录」,卡片下方仍有「打开授权页」。 ### 根因 `pending.authorizeUrl` 只在 logout / cancel 时清;轮询已不 busy 仍渲染该链接。 ### 修复 配对码 / 打开授权页仅在 `busy` 时渲染。snapshot 已不 busy 时清掉 client `pending`。 ## 2026-08-31:DSH 换模型会丢掉 reasoningEffort,选择器回到 Default ### 现象 OAuth 系列把思考深度设成 High 后换模型,选择器回到 Default。YAML `agent-default-model` 省略了 `reasoningEffort`。 ### 根因 DSH `choose` 换模型时只带新模型的 `defaultEffort`,不抄上一档。只改 YAML 赶不上活选择器。 ### 修复 **不要**写 `llm-pi-ai.providers.oauth-*.reasoning`。用 `settings/updated` 缓存上次显式档;oauth-* 换模型按新模型键还原(`xhigh`/`max` 没有则夹到最高可用)。对当前 session 再 `selectModel` 带上 effort。 ## 2026-08-31:Kiro Social 换票 HTTP 500(`redirect_uri`,始 08-30) ### 现象 走完「打开授权页」后 `exchangeKiroSocialCode` 仍 `HTTP 500` `Oops, something went wrong`。dummy code 是 400;真 code + 对不上的 `redirect_uri` 是 Cognito 常见 500。#38/#39 之后仍炸。 ### 根因 授权 / 换票 `redirect_uri` 漂移:先是 origin vs path,再是 `127.0.0.1` vs `localhost`,最后两边都 origin-only —— Kiro 换票要的是**落地回调 URL**(path + `login_option`)。 ### 修复 授权 URL 继续 origin-only `http://localhost:`。换票 `redirect_uri` = origin + 落地 path,有则 `?login_option=`。`127.0.0.1` 在授权/换票里改写成 `localhost`。回跳接受 `/`、`/oauth/callback`、`/signin/callback`。UA `KiroIDE-1.0.0-<64hex>`,同一次登录复用 `machineId`。 ## 2026-08-31:Antigravity 对话 403 VALIDATION_REQUIRED 被显示成「API 密钥无效」 ### 现象 OAuth 活着、额度正常,对话 Cloud Code **403** `VALIDATION_REQUIRED` / `Verify your account to continue.` DSH 把 403 收成 AUTH →「API 密钥无效」。 ### 根因 `forwardAntigravity` 原样转发 403。这是账号验证闸,不是 refresh 失效,也不是本机 proxy-key 错了。 ### 修复 识别后改写 **HTTP 400**(非 AUTH),卡片条 + 打开 `validationUrl`。不把 `plt=` 打进日志。`isAntigravityPermanentRefreshError` 对此为 false,不清登录。 ## 2026-08-30:GLM 思考链被清 ### 现象 GLM-5.3 / Flash 对话断思考前缀:不带 `thinking.clear_thinking: false`,或丢掉上一轮 `reasoning_content`。 ### 根因 官方思考模式要求 `clear_thinking: false` 且回放思考。DSH 助手常用别名 `reasoning`。`type: disabled` 对 5.3 / Flash 是 400。 ### 修复 5.3 / Flash 始终 `thinking: { type: 'enabled', clear_thinking: false }`。Turbo 不强制关。不剥 `reasoning_content` / `reasoning`;`reasoning` 抄到 `reasoning_content`。 ## 2026-08-30:Antigravity Gemini 长会话 400 — function_response 列表 ### 现象 `Unknown name "response" … Proto field is not repeating, cannot start list`(`INVALID_ARGUMENT`)。 ### 根因 `functionResponse.response` 是单个 Struct。OpenAI tool `content` 常是数组,被写成 JSON 数组。 ### 修复 对象原样;数组 / 标量包 `{ result }`;字符串走 `{ text }`。连续 tool 合成多个 `functionResponse` parts。绝不把 `functionResponse` 或 `response` 写成 JSON 数组。 ## 2026-08-30:GLM 首轮 400 `1214 角色信息不正确` ### 现象 新会话第一轮注入 AGENTS.md 等之后 400 `角色信息不正确`。 ### 根因 DSH 系统提示是 `role: "developer"`。Zhipu Coding Plan Completions 只认 `system` / `user` / `assistant` / `tool`。 ### 修复 `normalizeGlmChatBody`:`developer` 及未知 instructional → `system`。只改 `family === 'glm'`。Codex Responses 自己吃 `developer`。 ## 2026-08-30:勾选 GLM / Antigravity / Kiro 不写 settings.yaml(`api: openai`) ### 现象 选择器 3/3 已开,`llm-pi-ai.providers` 只有 oauth-codex / oauth-grok。启动 `sync()` 吞成 `llm-pi-ai sync failed`。 ### 根因 DSH `api` 闭集只有 `openai-completions | openai-responses | anthropic-messages`。三家写成裸 `api: 'openai'`,整段 mutate 被拒。 ### 修复 Completions 家族写 `openai-completions`。**不要**写裸 `openai`。mutate 失败要抛给选择器,能回读则缺 `providers.oauth-*` 当失败。 ## 2026-08-30:Antigravity 指纹 / 主机必须像官方 hub,不像 IDE / 第三方包装 ### 现象 打 prod `cloudcode-pa`(IDE `--subclient_type ide`)或 UA 停在 `hub/2.9.1`;混用 `IDE_UNSPECIFIED` / 数字 `ideType: 9` / `dsh-plugin` UA 会被 Google 403 / 封。 ### 根因 控制面和聊天面必须是同一套官方 **Antigravity.app / hub** 身份。CLIProxyAPI 的 prod 主机、IDE.app 版本、Gemini CLI 默认头都不能抄。 ### 修复 默认 `https://daily-cloudcode-pa.googleapis.com`;5xx / 传输失败才回落 prod,**4xx 不回落**。UA `antigravity/hub/ /`,版本读 Antigravity.app(地板 2.11.0),**不**读 Antigravity IDE.app。metadata 字符串 `ANTIGRAVITY`。chat 头只有 User-Agent。session 必存 `projectId`;缺 project 直接 403,不上游。 ## 2026-08-30:GLM 对话/额度带第三方 UA,拿不到 ZCode 1.5 倍额度 ### 现象 官方限时「在 ZCode 中登录使用」1.5 倍额度。插件 UA 是 `dsh-plugin-oauth-subs/…`,上游按第三方记账。 ### 根因 150% 是 **身份**(ZCode Desktop UA / `X-ZCode-*`),不是协议。把插件名写进 Coding Plan UA。 ### 修复 Desktop 3.10.1:`User-Agent: ZCode/3.10.1 ai-sdk/anthropic/3.0.81` + `X-ZCode-*` + `Referer: https://zcode.z.ai`。CLI init/poll 只用 `ZCode/3.10.1`。不要抄 claude-cli 伪装头。本插件没有和官方 Desktop 对比过用量斜率。 ## 2026-08-30:GLM 卡要看见官方「150%配额」 ### 现象 用户要在已登录 GLM 账号卡上直接看到 **150%配额**,不要只写在说明里。 ### 根因 pill 只有套餐 / 使用中 / 区域。额度条数学不该改。 ### 修复 抬头加 **150%配额**;额度标题下一行说明。不做日期开关。**不要**把 used/total 乘 1.5。Codex / Grok / Antigravity 卡不出现。 ## 2026-08-30:GLM 额度两条「本周期」,没有 5 小时 / 每周 / ZCode MCP ### 现象 两条杠都标 **本周期**(各 2000)。官方是 5 小时 + 每周,MCP 另算。 ### 根因 `limits[]` 用 `type` / `unit`+`number` 区分窗口;旧解析只认 duration 字符串,没有就 `cycle`。 ### 修复 映射 `primary` / `weekly` / `mcp`。UI(仅 GLM):**5 小时剩余** / **每周剩余** / **ZCode MCP**。不编造额度数字。 ## 2026-08-30:GLM 模型勾选 0/3,settings.yaml 没有 oauth-glm ### 现象 已登录,选择器 **已开启 0 / 3**。勾选或全选后 yaml 仍无 `oauth-glm`。`disabled` 含当前三条 + 退役旧 id。 ### 根因 `syncHarnessModels` 只给「至少一条当前 catalog key 开启」的系列写路由。旧目录全关把后来仍在目录里的三条也写进 `disabled`;登录 `sync()` 不把残留全关当成要恢复。 ### 修复 `setFamily(true)` 只 enable 当前 catalog id,不复活退役 id。已登录且当前 key 全关 → 打开当前 key 再写路由。选择器里主动全关仍 unset。 ## 2026-08-30:关于页假安装入口(zip 三行 + 打开发布页) ### 现象 关于页把一份通用 zip 拆成 Win / macOS / Linux 三行下载,后来又留「打开发布页」。检查更新只比版本。真实升级是 `dsh plugin --profile web update`。 ### 根因 `pickDownloads` 把 generic zip 复制成三行假安装器。宿主没有自动升级器。 ### 修复 通用 zip 不生成下载行;去掉「打开发布页」。有新版本时 spawn `dsh plugin --profile web update dsh-plugin-oauth-subs`。不 `npm i -g`,不杀当前进程。 ## 2026-08-30:Grok Fast 无加速;Codex Fast 只靠 body 字段 ### 现象 Grok `-fast` 回显 `priority` 但吞吐无差。Codex `-fast` 回显一直 `default`/`auto`;不合格 id(mini)原样转发会 400。 ### 根因 xAI 接受 `priority` 但不给吞吐。Codex CLI 还要 `x-codex-routing-hint` + `store: false`。回显 `default` 本身不是失败判据。`peelFastSuffix` 只在 `fastTier` 为真时剥。 ### 修复 删掉 Grok Fast;残留只剥后缀,永不给 Grok 写 `service_tier`。Codex 合格 `-fast`:剥后缀 + `service_tier: priority` + `x-codex-routing-hint` + `store: false`。不合格 `-fast` 本地剥掉。文档不再把某次 1.54× 写成当前事实。 ## 2026-08-30:GLM「导入本机会话」是空操作 ### 现象 本机已用 ZCode Desktop 登录 BigModel,按钮点了没反应。活会话在 `~/.zcode/v2/config.json`。 ### 根因 `glmAuthSearchPaths` 只扫了旧 CLI 路径。 ### 修复 搜索路径最前加 `~/.zcode/v2/config.json`。多钥匙优先 **可用** coding-plan,非 JWT 压过 JWT(start-plan JWT 后按体验套餐不支持处理)。不读加密 `credentials.json`。 ## 2026-08-30:智谱 GLM 双站 OAuth / BigModel init 500 ### 现象 先是只有一颗「登录」,国内账号打到 `api.z.ai`。加上中国按钮后,`provider: "zcode"` 的 CLI init 线上 500;`bigmodel` 才 200 并打开 `bigmodel.cn/login`。 ### 根因 ZCode 拆成 Z.ai(`zai` → `api.z.ai`)与 BigModel(init `bigmodel` → `open.bigmodel.cn`)。0.0.19 误把国内 CLI id 写成 `zcode`。`GLM_BIGMODEL_APP_ID` 仍是授权 URL 上的 `zcode`。 ### 修复 两颗按钮。`GLM_CLI_PROVIDERS.bigmodel = 'bigmodel'`。session 带 `region`,账号 id `email@zai` / `email@bigmodel`。导入路径上 `zcode` → `bigmodel` 仍是别名。 ## 2026-08-30:多个账号挤在一条横条里,额度只显示当前账号 ### 现象 邮箱挤成 pill 横条,额度挂在家族卡片底部。第二张 Grok 卡只有邮箱,必须先切换才看得到额度。 ### 根因 `ProviderCard` 把 roster 画成横条;`QuotaStore` 按 provider 只读当前 session;UI 只在 `row.active` 时挂 `QuotaBlock`。 ### 修复 一个 session 一张卡,额度永远在卡内(含未使用)。缓存键 `provider\0accountId`。snapshot 每张卡带自己的 `quota`。切换不清别人的缓存。标题不重复套餐。 ## 2026-08-30:Codex Pro 徽章没区分 5x / 20x ### 现象 ChatGPT Pro 已拆 $100 Pro 5x / $200 Pro 20x,卡上只显示 **Pro**。 ### 根因 `$200` slug 仍是 `pro`,`$100` 是 `prolite`。`formatPlanLabel` 都画成 Pro。 ### 修复 `pro` → **Pro 20x**,`prolite` → **Pro 5x**。GLM 的 `pro` 仍显示 Pro。 ## 2026-08-30:GLM 思考深度没写进目录,会话选不了 ### 现象 GLM-5.3 / Flash 没有 low / high / max,请求不带 `reasoning_effort`,上游一直默认 max。 ### 根因 目录 `reasoningEfforts: false`。localhost Completions 不会猜 `supportsReasoningEffort`。5.3 / Flash 无 `off` / `medium`;`disabled` 400。 ### 修复 `GLM_REASONING = { low, high, max }` 写在 5.3 / Flash;Turbo 仍 `false`。Anthropic 路由不要盖 Completions `compat`(见 yaml 条)。 ## 2026-08-30:智谱 GLM 模型清单错了,缺 Flash,且全部标成图文 ### 现象 选择器 6 条旧 id,没有 GLM-5.3-Flash。全家 `input` 写死 `['text','image']`。5.3 / Turbo 官方是纯文本。 ### 根因 0.0.16 按当时 Coding Plan 抄清单。`toHarnessModel` 硬编码图文。 ### 修复 只留 `glm-5.3` / `glm-5.3-flash` / `glm-5-turbo`,各自 `input`。`toHarnessModel` 读目录。不要硬编码每行都图文。 ## 2026-08-30:xAI Grok 额度读出来是预付 0、Grok Code 空行 ### 现象 刷新后只见「预付余额 0」和没有数字的「Grok Code」,没有周额度条。OAuth 活着。 ### 根因 付费账号是共享周池。CLI billing 对统一计费常省略 `creditUsagePercent`、给出 `prepaidBalance: 0`。周池在 grok.com `GetGrokCreditsConfig`。 ### 修复 并行 CLI billing + user + gRPC credits。JSON 已有 percent 用 JSON;缺了用 gRPC weekly。预付 0 和没有数字的产品行不画。 ## 2026-09-04:Grok 缓存命中率卡在 ~70%,热身后反复出现 512 token 块 ### 现象 多数步 ~99% 复用,中间几拍 `cacheReadTokens` **正好 512**、命中 <1%,下一拍立刻回到 ~99%。加权被拉到 ~70%。只带 `x-grok-conv-id` 后长会话仍会掉下来。 ### 根因 xAI prompt cache **按服务器分片**(粒度 512),粘性头是 grok-build 整套:`x-grok-conv-id` / `x-grok-session-id` / `x-grok-req-id` / `x-grok-model-override`(body 等价 `prompt_cache_key`)。不带粘性就打到只有全局系统前缀的机器。同时 grok-build Responses 要求下一次 **byte-for-byte** 重放 `input`;DSH 每步把 snapshot 插到 `input` 最前。分析器若只认 `cacheReadTokens === 0` 会把 512 块误判成 `prefix_break`。 ### 修复 完整 grok-build sticky 头(**仍然不**发送 Codex `session-id` / `x-client-request-id`)。每个 conv 钉第一次 system/developer,增量 snapshot 挂 **input 后缀**。`prompt_cache_key` 默认 conv id。分析器:512 + 复用 <10% = `affinity_miss`。健康:加权 ≥80%,亲和丢失 0。 ## 2026-09-05:本地 DSH Codex 缓存命中率异常偏低 ### 现象 长会话加权命中约 27%。同一会话不能稳打到同一缓存分片;退出 plan / header 重建时 leading developer 顶掉已缓存前缀。 ### 根因 转发丢掉 `session-id` / `thread-id` / `x-client-request-id`。Codex CLI 0.153.4 `build_session_headers` 同时发 session(prompt cache)和 thread(粘滞);chatgpt.com 按前者命中前缀、按后者粘分片。DSH 多出来的 leading developer 留在 `input` 开头会 bust。 ### 修复 `session-id` = `thread-id` = `x-client-request-id` = `prompt_cache_key`(DSH 一轮对话就是一条 thread;可回退 `session_id`)。同一 DSH 请求的重试回放 `x-codex-turn-state`。剥与 `instructions` 重复的 leading developer/system,多余文本停到 **input 后缀**。剥 `prompt_cache_retention` / `prompt_cache_options`。Grok 不继承这套头。压缩 / plan 重建零缓存不是分片丢失。健康:加权 ≥80%,**亲和丢失 0**,无 TRANSPORT。 ## 2026-08-26:`Error: tool call timed out after 30000ms` 不是本插件 ### 现象 验收会话里 glob / read / grep `host_timeout` / `cascade_abort`,TRANSPORT 为 0。 ### 根因 DSH 把 fs 工具交给 `@deepseek-ai/dsh-tool-fs-search`,默认 `timeoutMs` **30000**。oauth-subs 是 Responses 回环,**不跑** glob / read / grep。 ### 修复 **非修复。** 不要在本插件加 `toolTimeoutMs`,也不要在代理层重试 glob。要加长预算改 `dsh-tool-fs-search`,或等 DSH 让补丁能打到 agent-preset。 ## 2026-08-26:并发子代理全线 `stream ended before a terminal response event` ### 现象 七会话同时恢复后,走 oauth-codex 的全报该 TRANSPORT(llm-pi-ai 读完 SSE 没等到 `response.completed`),盲重试 5 次。走别的 provider 的活着。头发出前的同类故障曾是 `500 "fetch failed"`。 ### 根因 上游瞬时断流。`forward()` 的 `finally { response.end() }` 把已发出头的中断收成「HTTP 200 + 干净 EOF」,真实原因丢失。 ### 修复 头已发出且非客户端断连 → `response.destroy(error)`,不要假装正常结束。`CommitGate`:未证明产出前不提交头;未提交断流可重试(3 次);耗尽回 502。已产出内容之后不能重放。不保证上游不再抖动。 ## 2026-08-26:Codex 目录漂移(minimal / 下线 id / ultra / -fast) ### 现象 排查 TRANSPORT 时打到真实接口:`minimal` 400、`gpt-5.3-codex` 对 ChatGPT 账号已下线、`ultra` 400、不合格 `-fast` 400、窗口写死 900K 不准、`/codex/v1/models` 缺 `client_version` 400。 ### 根因 同一批模型事实在多个文件各抄一份。`ultra` 是 CLI 多智能体委派,不是 wire effort。 ### 修复 事实收进一张 `codexModel()` 表。去掉 `minimal`、下线 id、`ultra` 别名(只能退化成 `max`)。`-fast` 与窗口按模型。补 `client_version`。