Skip to content

v1.7.3

Choose a tag to compare

@KyuuKyuuStone KyuuKyuuStone released this 04 Oct 10:21
· 164 commits to main since this release

Claude Code Heihei v1.7.3

清掉一批「已查实、暂未修」的缺陷:五条登记缺陷修掉四条——两处会让会话静默挂死的文件操作、一处永久转圈的协作弹窗、一处会毁掉整份台账的脏行、一处隔离实例读错实例的端口路径;第五条(turn-checkpoints 慢点)经实测把「O(n²)」证伪、成因仍未定,带数据挂档、本版未修。另把「请求超时」与「业务失败」在界面上区分开。无破坏性变更。

修复:五条登记缺陷中的四条

1. Bun 的 truncate 永不返回 → 两处产品路径改「重写语义」

  • 现象:走到任一条用 truncate 的路径,await 永不返回——不报错、不抛异常、也不自愈,表现为静默挂死。
  • 根因(后端探针 9/9 实证):fs.truncate / FileHandle.truncate / fs.ftruncate(含 sync)在缩短、等长、变长三个方向全部不返回,三种 API 无差别 ⇒ 缺陷在底层 syscall 封装,「换个 API 绕开」不可行。
  • 受影响的两处产品路径:
    • src/history.ts(提示历史写入器的回滚分支):原 await truncate(...) 永不返回 ⇒ 其 catch 兜底(毒化标记)永远不执行 ⇒ 回滚静默挂死;
    • src/utils/sessionStorage.ts(按 uuid 移除单条会话):原「定位行 + truncate」在两个分支都会出事——删最后一条直接挂死;删中间条则 truncate 挂住、补尾部永不执行 ⇒ 尾部永久丢失。
  • 修法:两处都改为重写语义——把要保留的内容拼好后整体写回(写回天然截断,字节等价),彻底绕开 truncate。新增用例覆盖「删末条 / 删中间条」两种情形(结果字节等价)。
  • 附带加固(独立审查发现):上述重写路径用 Buffer.allocUnsafe(...) 且未检查 read 的实际读取字节数——与 CLI 子进程并发追加时可能「短读」,把未初始化的堆内存写回用户转录(既污染数据、又泄露内存内容)。已加一行守卫:短读即放弃本次删除(删除属清理动作,放弃无害,且不增净行数);快路径同时补上与慢路径同款的大小上限,避免大转录下的读写尖峰。

2. 协作设置弹窗对「不在花名册的会话」永久转圈

  • 现象:对不在花名册里的会话打开「协作设置…」,弹窗永久停在加载态,无失败态、无超时、无重试,提交按钮一并锁死(隔离演示实例观察 25 秒不消失)。
  • 根因:原判断「编辑模式 && 未读到该会话」无法区分「花名册还没加载完」与「花名册加载完了、确实没这条」——后者恒为真 ⇒ 永远停在加载态。
  • 修法:引入三态(加载中 / 就绪 / 不在花名册):拉取完成后仍无此条,则给出明确的失败提示 + 重试按钮;该状态下提交按钮同样锁死(避免空表单被误提交覆盖原身份)。五语言各补一条文案,新增组件测试。

3. 端口文件读写两侧统一跟随配置目录(隔离实例不再污染 / 错读)

  • 背景:端口发现文件(desktop-server.json)此前固定在 ~/.claude/cc-heihei,配置目录环境变量不参与 ⇒ 跑一个隔离实例会覆盖真实应用的端口记录,任何读它的工具(员工汇报、CLI 投递)会打到错实例。
  • 修法(本版补齐两侧):
    • 写侧 / 默认目录:默认路径改用「配置目录优先」的解析,隔离实例落在自己的配置目录内;显式传入 home 的既有契约不变。
    • 读侧:独立实测发现读侧此前没跟着改(仍以 home 为基准)——隔离实例读不到自己的端口文件、回落拿到真实应用的地址。本版把两处读取方一并改为同一解析,并补测试锁死「读侧确实接上了」。
  • 兼容性:未设该环境变量时解析结果与旧写法逐字相同 ⇒ 真实用户零影响。

4. 台账 replay 缺字段行归一为 []

  • 现象:任务台账里只要出现一行缺 deliverables / history 字段的数据(手写行、旧版本写的行),会让整份台账加载失败,而不是只跳过这一行。
  • 更正说明(如实):复核发现「坏 JSON 行的隔离跳过」早已存在;真正的缺口是 created 分支没有做字段归一——缺字段的行照旧入账,之后读路径展开时才抛错。
  • 修法:缺失字段统一 ?? [] 兜底 + 入口归一,并对「发生归一的坏行」记一条诊断(可观测、不静默);与同模块对旧数据兼容的既有口径保持一致。新增用例覆盖。

5. turn-checkpoints 慢点:「O(n²)」已证伪,成因未定(本版未修)

  • 背景:上一版把「客户端 Request timed out after 320s」的根因候选指向某内部 checkpoint 拉取的结构性 O(m·n)。
  • 本版实测结论:
    • 三个真实会话(6.6k / 12.9k / 20.3k 行)只读副本实测 2.1s / 70.7s / 54.5s——中档比大档还慢(非单调),且小→中 checkpoint 数只 +4% 而耗时 ×34 ⇒ 与规模、条目数均无关,复杂度假设被证伪;同测另一接口 258/376/647ms 呈 ≈O(n) 作对照;
    • 同一份 83MB 转录四次实测 4.1 / 54.5 / 68.8 / 70.7 秒(差约 17×) ⇒ 不是稳定的算法复杂度问题,更像外部状态相关(磁盘 / 页缓存 / 内存压力、JIT / GC 状态);
    • CPU profiler 曾在慢跑里看到 82.9% 采样落在运行时正则引擎,但逐正则微探针实测三条候选正则合计仅 ≈0.1%,且快跑里该热点不出现 ⇒ 该「正则热点」可能是果而非因(推断,未证实)。
  • 状态:成因未定、修法未落地、本版零代码改动——带数据挂档;下一步需多次采样 + 记录同刻系统状态继续分诊。

衍生修复

  • 「320 秒超时」不再呈现为业务失败:Request timed out after 320s 此前被当普通错误弹红条,暗示「失败 / 重试」;实际它只断了连接、业务仍在后台跑。现在超时文案改为**「连接已超时;任务可能仍在后台运行,稍后刷新即可查看结果」,turn-change 错误条在超时态改用中性提示条**(而非红色失败条),并给了「刷新查看」的出路(五语言同步)。
  • 409 跨项目派活文案的正则边界:已知服务端错误串的映射正则补回了词边界 \b(此前是前缀匹配),使这条业务错误串与相似串的区分更精确。
  • CI 红灯:两笔测试侧修复(改动只在测试与断言,不碰产品行为):
    • dispatch-mailbox 用例在 CI 上因 Windows %TEMP% 的 8.3 短路径(如 RUNNER~1)导致路径归一化不识别、台账过滤出 0 条——改用 realpath 后的规范路径;
    • MessageList 的 selectionchange 用例在慢机上因两帧 rAF 早于处理完成而同步查询不到按钮——改为带超时的显式异步查询。

结构与门禁

  • 两条结构豁免(sessionService cap 3846 / handler cap 3372)expiresInVersion 由 1.7.3 续签至 1.7.4,理由=「1.7.3 已含红灯区缺陷批 ⇒ 条件达成」。
  • 如实口径:两个文件当前已超自身基线(sessionService 3796 > 3795;handler 3351 > 3322),续签后由 cap 覆盖;这是「红灯批=修复批、非减行批」的直接结果,不是新债。

文档与站点(用户可见)

  • 双语 README 与文档站首页按授权缩墙:撤下已无法重拍的旧一代界面截图,只保留当前且经验证的截图(新建会话欢迎页、本地模型页),并同步了截图规范与图注。

已知限制与未验证项(如实,不美化)

  • #5(turn-checkpoints 慢点)为挂档项:本版未修,成因未定(详见上)。
  • CI 两笔测试侧修复尚未经 CI 验证:相关提交尚未 push,只在本地 / 预检环境验证过;须 push 后由 CI 判定。
  • tasks.test.ts 负载型偶发(v1.7.1 挂账)仍在:该文件曾在流水线内红过、但失败签名缺失,独立复现多次全绿,未登记进 known-flaky;本版未见新增证据,仍待 CI 观察。
  • removeMessageByUuid 快路径的 64KB 窗口丢尾(既有债务,非本版引入):快路径只读文件最后 64KB 找目标行,若目标行落在窗口内、而其后的存量超出窗口,则新旧两版同样会丢掉窗口外的尾部。触发条件窄(目标行不在末尾且其后存量 > 64KB)。v1.7.4 候选:needle 不在窗口末尾时回退慢路径。
  • Bun truncate 的上游修复未证实:本版用「换操作方式」绕开;上游 changelog 未见对应条目、issue 库未搜,升级 Bun 能否根治未证实。

债务与豁免(如实披露)

  • sessionService.ts 豁免 cap 3846、handler.ts 豁免 cap 3372,均 expiresInVersion 1.7.4。

升级说明

  • 无破坏性变更;通过应用内「检查更新」即可升级(latest.yml + blockmap 支持增量下载),也可重新下载安装包覆盖安装。
  • 启动后调用 GET /api/whoami 可查看当前运行版本号(返回 app、version、pid、startedAt)。