From 2a89331697e2517fc31349a7d9e4900c388575d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Sun, 24 May 2026 00:25:38 +0800 Subject: [PATCH] =?UTF-8?q?release:=20prepare=20v0.3.0=20=E2=80=94=20relea?= =?UTF-8?q?se=20notes=20and=20version=20bump?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump version from 0.2.9 to 0.3.0 across desktop/package.json, tauri.conf.json, and Cargo.toml. Add v0.3.0 release notes covering desktop long-session performance, streaming tool previews, AskUserQuestion reliability, multi-client streaming, and H5 network fixes. Co-Authored-By: Claude Opus 4.7 --- desktop/package.json | 2 +- desktop/src-tauri/Cargo.lock | 42 ++++++------ desktop/src-tauri/Cargo.toml | 2 +- desktop/src-tauri/tauri.conf.json | 2 +- release-notes/v0.3.0.md | 106 ++++++++++++++++++++++++++++++ 5 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 release-notes/v0.3.0.md diff --git a/desktop/package.json b/desktop/package.json index f171dd25..d9bed90d 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -1,7 +1,7 @@ { "name": "claude-code-desktop", "private": true, - "version": "0.2.9", + "version": "0.3.0", "type": "module", "scripts": { "dev": "vite", diff --git a/desktop/src-tauri/Cargo.lock b/desktop/src-tauri/Cargo.lock index e953dc59..60172bae 100644 --- a/desktop/src-tauri/Cargo.lock +++ b/desktop/src-tauri/Cargo.lock @@ -218,9 +218,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base64" @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytemuck" @@ -482,7 +482,7 @@ dependencies = [ [[package]] name = "claude-code-desktop" -version = "0.2.9" +version = "0.3.0" dependencies = [ "anyhow", "portable-pty", @@ -2027,9 +2027,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -3643,9 +3643,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -5161,9 +5161,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -5174,9 +5174,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.71" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -5184,9 +5184,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5194,9 +5194,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -5207,9 +5207,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.121" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] @@ -5263,9 +5263,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.98" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/desktop/src-tauri/Cargo.toml b/desktop/src-tauri/Cargo.toml index d2311a3f..dbaca8b6 100644 --- a/desktop/src-tauri/Cargo.toml +++ b/desktop/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "claude-code-desktop" -version = "0.2.9" +version = "0.3.0" edition = "2021" [lib] diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index d05168e0..410f347a 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/nicegui/nicegui/main/nicegui/static/tauri-schema-v2.json", "productName": "Claude Code Haha", - "version": "0.2.9", + "version": "0.3.0", "identifier": "com.claude-code-haha.desktop", "build": { "frontendDist": "../dist", diff --git a/release-notes/v0.3.0.md b/release-notes/v0.3.0.md new file mode 100644 index 00000000..44da8718 --- /dev/null +++ b/release-notes/v0.3.0.md @@ -0,0 +1,106 @@ +# Claude Code Haha v0.3.0 + +这是一个围绕**桌面端长会话性能、工具流式预览、AskUserQuestion 稳定性、多客户端流式订阅和 H5 网络可靠性**的版本。 + +相比 `v0.2.9`,本次最核心的工作是对桌面端长会话进行了系统性的性能重构:从虚拟滚动稳定化、React 组件 memo 化、Markdown 缓存优化到跨 tab 高度缓存持久化,让 800+ 条消息的大会话在滚动和切换 tab 时不再出现白屏或卡顿。同时,流式 Writer 预览和 pending tool card 让长工具执行过程变得可感知,AskUserQuestion 和 IM 多端流式订阅的可靠性也得到了针对性修复。 + +## Highlight + +- **桌面端长会话滚动性能大幅提升**:797+ 条消息 / 2.6MB 会话从 1-2s 白屏降低到 0s 白屏采样(34 个滚动位置全部通过)。通过稳定 1200px overscan、React 18 自动批处理、ResizeObserver 每帧批量回调和取消 scroll-handler 的 flushSync 实现。 +- **React 组件树 memo 化**:AssistantMessage、UserMessage、ToolCallBlock 等 6 个重型组件加 React.memo;branchAction/toolResult 查找提升为 useMemo Map,窗口滑动时不变行跳过重渲染。 +- **Markdown 缓存重构**:缓存 key 从完整内容字符串改为 `${len}:${fnv1a}` hash,拆分为 200 条 finalized(8MB)+ 4 条 streaming 缓存,streaming 不再驱逐已完成的 parse;VirutalSpacer 分片渲染,消除滚动白屏。 +- **跨 tab 高度缓存持久化**:新增 virtualHeightCache(按 sessionId 的模块级 LRU),切回已访问的 session 时复用历史测量高度,跳过 estimate→measure 校正过程;O(N) 的分支/完成计算改用 useDeferredValue 延后执行。 +- **流式 Writer 预览和 pending tool card**:长 Write 在 tool_use_start 时即渲染 pending 工具卡片,通过 delta 更新输入预览;Write.content 解码为轻量纯文本预览窗口,完成后保留完整 diff 渲染。 +- **AskUserQuestion 稳定性**:CLI 的 toolUseResult 元数据在桌面 bridge 中不再丢失;重连时追踪并回放存活的 SDK 权限请求;自定义回答升级为多行编辑器(Ctrl/Cmd+Enter 提交)。 +- **多客户端流式订阅**:WebSocket handler 按客户端广播 session 消息,桌面端打开同一 session 不再"偷走" Telegram 的流内容;Telegram 长回答自动分块并累积 thinking delta。 +- **H5 内网链接更稳定**:手动选择的 LAN 地址在 sidecar 端口变化后自动刷新为当前端口;手动 LAN host 不会被 WSL/Docker 虚拟网卡的自发现结果覆盖。 + +## 主要更新 + +### 桌面端长会话性能(6 个 commit 的系统性优化) + +- 长对话切换为基于测量高度的动态虚拟窗口,短对话保持全量挂载;废弃 content-visibility 全列表覆盖方案以避免 WebView 白屏。 +- 虚拟滚动 overscan 从动态膨胀(360px → 7200px)改为固定 1200px;移除 scroll-handler 的 flushSync,让 React 18 自动批处理接管状态更新。 +- ResizeObserver 高度回调标记 pending bit 后,每帧仅触发一次 setMeasuredItemsVersion,而非每个 item 一次全列表重渲染;取消测量反馈的自动滚动,避免与用户滚动冲突。 +- TabBar 的 chat-store 订阅收窄为 running-state ids,避免流式 payload churn 导致 tab chrome 无效重渲染。 +- AssistantMessage、UserMessage、ToolCallBlock、ToolCallGroup、ToolResultBlock、MarkdownRenderer 全部加 React.memo;per-message 的 branchAction/toolResult 查找提升为 useMemo'd Map。 +- Markdown 缓存 key 改为 `${len}:${fnv1a}` hash;200 条 8MB finalized cache + 4 条 streaming cache,streaming 期间不再禁用缓存;VirtualSpacer 将 spacer 切为 ~800px 分片,配合 content-visibility: auto + contain-intrinsic-size 消除白屏。 +- virtualHeightCache(按 sessionId 的模块级 LRU)在 tab 切换时恢复历史高度和 metric map;关闭 tab 时通过 tabStore.closeTab → dropSession 释放缓存。getBranchableMessageTargets / getCompletedTurnTargets 改用 useDeferredValue(messages) 低优先级渲染。 + +### 工具流式预览 + +- tool_use_start 时 upsert 一个 pending tool_use 消息;delta 更新轻量输入预览;tool_use_complete 时原地更新为完整卡片,避免卡片重复。 +- Write.content 在 pending 阶段解码为有界纯文本预览窗口,完成后保留现有完整 diff 渲染。 + +### AskUserQuestion 可靠性 + +- CLI transcript 的 toolUseResult 结构化答案在 history replay 和 live WebSocket tool result 中保持一致传输,已回答卡片正确显示 resolved 状态。 +- 追踪存活的 SDK permission request,重连时回放给新客户端;等待用户输入的 session 获得更长的清理宽限期;aborted 结果渲染为 completed history 而非未回答提示。 +- 自定义回答输入框升级为多行编辑器,支持 Ctrl/Cmd+Enter 提交;修复历史恢复与 live permission request 重叠时出现重复未回答卡片的问题。 + +### 多客户端流式订阅 + +- WebSocket session output 改为按客户端追踪 callback,广播消息而非替换之前的订阅者;桌面端和 Telegram 可同时观察同一个流式 session。 +- Telegram thinking delta 累积后编辑占位消息,而非每次用最新小块替换;长回答自动封存完整 chunk、打开新可编辑占位符,适配 Telegram 消息长度限制。 + +### H5 内网链接 + +- 手动 LAN 地址 settings UI 支持分离 host/IP 输入,复用当前服务端口;不会被 WSL/Docker 虚拟网卡的自发现结果覆盖。 +- 普通 HTTP 私有 LAN URL 在 sidecar 重启后自动刷新为当前动态端口;反向代理 URL 保持原样不动。 + +### Worktree UI + +- worktree session 的 desktop chip 隐藏内部分支标签(如 worktree-desktop-*)和 slug,仅显示源项目和 worktree 标记。 +- git-info API 区分 launch branch 元数据和 worktree 实际 checkout 分支,session 进入 worktree 后才切换到实际分支。 + +### 其他改进 + +- OpenAI 代理流超时仅作用于建立上游连接阶段,不截断已开始的 SSE 生成。 +- filesystem browser 注册已解析的 workspace root,支持 Windows 跨盘符项目(如 D:\workspace)的文件搜索。 +- Computer Use 拒绝 Python 3.9 以下运行时,固定 Pillow 在 11.x 兼容线,配置镜像安装失败时 fallback 到默认 PyPI。 +- Shiki 代码高亮改为懒加载,旧 WebKit 解析失败时 fallback 到 Prism,避免 macOS 12 WebView 启动崩溃。 + +## 问题修复 + +- 修复长会话滚动时 1-2s 白屏(flushSync 阻塞 compositor + 动态 overscan 膨胀 + ResizeObserver 大量同步重渲染)。 +- 修复虚拟滚动 spacer 大块 div 导致 WebView 无内容可绘制、出现滚动白屏。 +- 修复 Markdown 缓存用完整内容字符串做 key 导致大会话频繁驱逐、streaming chunk 驱逐已完成解析。 +- 修复窗口滑动时每行都从零重渲染(无 memo 屏障 + 每次 render 重建 object literal)。 +- 修复 tab 切换回已访问 session 时高度和 metric map 被清空,强制 estimate→measure 全程校正。 +- 修复长 Write 工具调用在 tool_use_complete 之前不显示任何可见进度的问题。 +- 修复 AskUserQuestion 回答后仍显示为未解决、历史恢复出现重复卡片、重连导致 CLI 被 AbortError 杀死。 +- 修复桌面端打开同一 session 后 Telegram 丢失流内容和 completion 事件。 +- 修复 Telegram 长回答超过消息长度限制后停止更新、thinking delta 每次用最新小块替换导致预览回缩。 +- 修复 H5 内网链接在 sidecar 重启后保留过期端口、手动 LAN host 被自发现覆盖。 +- 修复 OpenAI 代理流被全请求超时截断,长 SSE 生成中途停止。 +- 修复 worktree session 显示 source branch 或内部 ref 标签(worktree-desktop-*)。 +- 修复 Windows 跨盘符项目在 filesystem browser 中无法搜索文件。 +- 修复 desktop compact 状态在 auto-compact 或取消后卡住不消失。 +- 修复 Computer Use 在低版本 Python 环境安装依赖失败。 +- 修复旧版 Safari/WebKit 解析 Shiki 现代 RegExp 语法导致启动崩溃。 + +## 验证 + +- 桌面端性能相关 commit 有 5 个新增的 virtualHeightCache 测试用例和 4 个 markdown-cache + spacer-chunk 回归测试;全套 731 desktop vitest suite 保持通过。 +- Chrome DevTools trace 在真实 797 消息 session 上验证:tab 切换 max RunTask 约 158ms,滚动 34 个位置 blankSamples=0,INP 从 84ms 降到 43ms,ForcedReflow insight 消失。 +- AskUserQuestion 相关变更已通过 desktop chatStore、MessageList、AskUserQuestion 组件测试和 server sessions、ws-memory-events 测试。 +- H5 相关变更已通过 h5-access-service、h5-access-api、h5-access-auth、h5-access-policy 全套测试。 +- Computer Use 相关变更已通过 computer-use-api、computer-use-requirements、computer-use-python、pipInstall 测试。 +- 各功能分支已分别跑过 targeted server / desktop / adapters 测试;`v0.3.0` 发布前建议再跑一次 `bun run verify`,并在真实长会话(800+ 消息)上补一次 scroll + tab 切换 smoke。 + +## 其他说明 + +- GitHub Release 正文继续以 `release-notes/v0.3.0.md` 作为来源,发布时无需手动复制 Markdown。 +- 桌面端性能优化涉及虚拟滚动、React memo、缓存和 layout 路径变更;升级后如果遇到滚动异常或高度计算问题,通常是测量缓存或 spacer 分片与特定 WebView 版本的兼容问题,请反馈具体 session 大小和 WebView 版本。 +- 流式 Writer 预览和 pending tool card 依赖 provider 正确发送 tool_use_start 和 input delta 事件;如果 provider 仅发送 tool_use_complete,pending 卡片不会出现但最终卡片照常渲染。 +- 本版本包含大量桌面端渲染和 layout 路径变化,建议在 macOS WebKit、Windows WebView2 和 Linux WebKitGTK 三个平台上各做一次真实长会话滚动 + tab 切换 smoke。 + +## 安装说明 + +### macOS + +首次打开如果提示"已损坏"或"无法验证开发者",请执行: + +```bash +xattr -cr /Applications/Claude\ Code\ Haha.app +```