grok-build 0.2.91 变更详解:plan mode 下的语音听写指示器可用性修复与 Worktree 对话框自适应宽度实现

📅 发布时间:2026/10/10 8:48:45
grok-build 0.2.91 变更详解:plan mode 下的语音听写指示器可用性修复与 Worktree 对话框自适应宽度实现
人工智能大模型AI Agent代码智能体CLI工具调用MCP Clients【免费下载链接】grok-buildSpaceXAIs coding agent harness and TUI. Fullscreen, mouse interactive, extensible.项目地址https://gitcode.com/gh_mirrors/gr/grok-build点击查看免费下载导读本篇文章基于 grok-build 仓库中 0.2.91 版本变更日志深入剖析该版本聚焦的两项终端 UI 修复其一在 plan mode计划模式审查阶段语音听写指示器与[stop]停止按钮仍保持可见、可点击其二New Worktree 新建工作树对话框在窄终端下会自适应扩张以展示长名称并在空间不足时以前导省略号滚动。文章将以仓库源码xai-grok-pager TUI 渲染层与输入分发层为佐证说明这两处修复的底层机制、测试保障与可复现路径帮助你在阅读或调试 grok-build 的终端交互时快速定位对应实现。版本背景与变更范围0.2.91发布于 2026-07-07是xai-grok-shellgrok-build 的编码代理终端外壳迭代版本之一。当前仓库中该 crate 的 Cargo.toml 版本号已演进至1.0.41但历史变更记录仍完整保留在changelogs/目录下每条记录同时提供 Markdown0.2.91.md与 JSON0.2.91.json两种格式便于脚本与人工阅读。两条变更的 JSON 元数据均为category: fixes、breaking_change: false即纯缺陷修复、无破坏性变更变更项类型影响面语音听写指示器与停止按钮在 plan mode 审查期间保持可见、可点击fix输入分发、鼠标命中区域、渲染层级New Worktree 对话框在窄终端下扩张显示长名称并以前导…滚动fix欢迎页对话框渲染、单行文本编辑器的视口逻辑下文分别从「问题场景 → 实现机制 → 测试佐证」三个层面展开。修复一plan mode 审查阶段语音听写指示器的可用性问题场景grok-build 的 TUI 支持语音听写voice dictation按下CtrlSpace或/voice开启录音后界面底部会出现一条录制指示行包含脉冲红点、Recording字样与右侧的[stop]按钮。该按钮是一个可点击的鼠标热区用于随时终止录音。问题出在 plan mode计划模式的审查环节当 Agent 提交计划、进入 plan approval 视图时行级查看器line viewer会作为覆盖层接管鼠标路由同时计划反馈plan feedback阶段提示框聚焦在 prompt 面板。在这两种状态下用户仍希望继续/终止听写但若指示行被覆盖层遮挡、或点击事件被查看器吞掉录音便无法通过 UI 停止。实现机制三层保障第一层是渲染可见性。录制指示行由 render.rs 负责绘制当voice_listening为真且布局中voice_recording区域有效时依次绘制脉冲红点、Recording文案与右侧的[stop]按钮并在渲染结束时把按钮区域写入self.hit_voice_stop_button.rect作为后续鼠标命中的依据let stop_str [stop]; let stop_w unicode_width::UnicodeWidthStr::width(stop_str) as u16; let stop_x rec_area.x rec_area .width .saturating_sub(layout_cfg.block_pad_right stop_w); // ...绘制 [stop]并根据 hovered 状态切换前景色accent_error / gray self.hit_voice_stop_button.rect Some(Rect::new(stop_x, rec_area.y, stop_w, 1));关键点在于plan approval 的 line viewer 覆盖层在布局时显式排除了录制指示行因此该行在审查阶段始终可见而不是被覆盖。第二层是鼠标路由。plan approval 的行级查看器虽然持有鼠标路由但[stop]的点击需要穿透覆盖层、直接命中VoiceToggle动作。测试注释明确写道Recording-row [stop] click keeps working while the plan approvals line-viewer overlay owns mouse routing. The row stays visible (the overlay excludes it), so the viewer must not swallow the click.input.rs。这意味着输入分发逻辑在覆盖层命中判定前会优先检查hit_voice_stop_button.rect命中的鼠标坐标将其映射为Action::VoiceToggle。第三层是动作语义。dispatch/voice.rs 中的dispatch_voice_toggle是[stop]按钮、CtrlSpace、录音中按 Esc 等入口的统一汇聚点pub(super) fn dispatch_voice_toggle(app: mut AppView) - VecEffect { if app.voice_listening() { // Stop always succeeds, even if the remote flag or /voice mode flipped mid-recording app.voice_stop_keeping_final(); return vec![]; } // 未录音则启动与 /voice 一致一次按键即拉起横幅banner dispatch_enable_voice_mode(app, /* from_hold */ false) }注释特别强调停止操作总是成功即使远端 flag 或/voice模式在录音中途被翻转——这与 0.2.91 修复审查阶段停止按钮始终可点击的目标完全吻合。此外dispatch_voice_toggle在 plan feedback 阶段同样生效因为此时提示框聚焦于 prompt 面板按钮热区仍参与常规命中检测。测试佐证修复随附的测试位于 input.rs 的voice_stop_click_during_plan_review_tests模块覆盖两个场景stop_click_dispatches_voice_toggle_under_plan_approval_viewer打开 plan approval 并确认 line viewer 已接管后模拟在(91, 30)坐标点击[stop]断言分发结果为Action::VoiceToggle——证明覆盖层不吞掉该点击stop_click_dispatches_voice_toggle_in_plan_feedback关闭 viewer、prompt 面板聚焦时点击[stop]同样断言VoiceToggle——证明反馈阶段的点击也不丢失。两个测试均通过test_fixtures::{make_agent, make_plan_approval_view_state}构造状态直接验证plan mode 审查全程可停止语音的用户可见行为。修复二New Worktree 对话框的自适应宽度与滚动问题场景在欢迎页welcome screen通过New Worktree弹窗创建工作树时用户可以输入可选的名称标签label留空则自动生成名称。旧实现中对话框宽度固定遇到较长名称时要么被截断、要么溢出终端且窄终端下无法看到正在输入的内容末尾光标一侧。实现机制宽度自适应 前导省略号滚动对话框渲染完全位于 new_worktree_dialog.rs其核心是两个常量与一个宽度函数/// Minimum dialog width (fits the title, an empty input, and the hints). const MIN_DIALOG_WIDTH: u16 50; const DIALOG_HEIGHT: u16 5; const INNER_PAD: u16 4; // 边框内侧左右内边距inner_x dialog.x 2 const LABEL_PREFIX: str Name (optional): ;宽度自适应由dialog_width_for完成new_worktree_dialog.rsfn dialog_width_for(area_width: u16, label: str) - u16 { let max_width area_width.saturating_sub(4); // The extra 1 is the block cursor cell let needed (LABEL_PREFIX.width() label.width() 1 INNER_PAD as usize) as u16; needed.max(MIN_DIALOG_WIDTH).min(max_width) }对话框宽度 max(需求宽度, 50)再钳制到终端宽度 - 4的上限需求宽度包含前缀Name (optional): 、已输入标签的显示宽度、1 个块状光标列与内边距因此名称越长对话框越宽直到占满终端可用宽度为止标题与提示行始终容纳。前导省略号滚动由输入状态机的视口逻辑承担。对话框的输入标签使用LineEditor存储状态定义在 app_view.rs并通过xai_ratatui_textarea::SingleLineViewport计算可见字节区间与光标显示列pub(crate) fn viewport(self, width: usize) - xai_ratatui_textarea::SingleLineViewport { self.label.viewport(width) }渲染时new_worktree_dialog.rs只取视口中的可见片段并据cursor_display_column在对应单元格绘制块状光标let viewport state.viewport(input_width as usize); let visible_input state.label().get(viewport.visible_byte_range).unwrap_or(); // 绘制 Name (optional): visible_input if input_width 0 { let cursor_x inner_x prefix_w viewport.cursor_display_column as u16; // 在该单元格设置 block cursor 样式 }当终端宽度不足以完整显示标签时视口保持光标侧末尾可见并滚动起始位置被滚出视野的开头以…指示——这正是 changelog 中scrolls with a leading …的含义。另外标签文本输入受MAX_WORKTREE_LABEL_BYTES 100字节上限约束app_view.rs粘贴与键入均受此限。测试佐证new_worktree_dialog.rs 内置了覆盖五种情况的测试测试断言empty_dialog_uses_minimum_width空标签时宽度恰为MIN_DIALOG_WIDTH宽终端或面积-4窄终端dialog_grows_with_long_label长标签使对话框宽度超过最小值且内部空间足够容纳完整标签与 UI 元素dialog_clamps_to_terminal_width100 字符标签在 60 列终端下被钳制到 56 列不越界long_name_fully_visible_on_wide_terminal宽终端100 列下完整长名称可见标题New Worktree也在long_name_end_visible_on_narrow_terminal窄终端40 列下标签末尾光标侧保持可见且画面含…或尾部文本narrow_dialog_keeps_middle_unicode_cursor_visible标签含 CJK、组合音标与 emoji ZWJ 序列如‍时光标单元格在窄对话框内仍然可见其中narrow_dialog_keeps_middle_unicode_cursor_visible尤其值得注意它构造了xxxxxxxxxxxx中é{‍}tail这样包含多字节与宽字符的标签并验证光标命中单元格——说明视口逻辑正确处理了**显示宽度column与字节偏移byte range**的换算emoji 组合序列不会被拆散导致光标漂移。两条修复背后的通用设计从源码结构看这两条修复体现了 xai-grok-pager 终端交互层的两个通用设计原则可作为阅读该 crate 的索引命中热区与渲染同源。[stop]按钮的命中矩形hit_voice_stop_button.rect在渲染函数中随布局一并计算并存储render.rs输入层直接复用该矩形做命中判定避免渲染与点击区域不一致这类经典 TUI 缺陷同目录下 links.rs 的遮蔽occluder测试进一步证明命中判定还考虑了覆盖层遮挡顺序。覆盖层与宿主行互斥。plan approval 的 line viewer 覆盖层在布局时排除录制指示行使指示器天然保留在交互层之上这一约定通过voice_stop_click_during_plan_review_tests固化防止未来新增覆盖层时回归。如何验证与复现仓库是只读镜像你可以通过以下方式自行验证这两处行为阅读变更记录对照 0.2.91.md 与 0.2.91.json或查看 CHANGELOG.md 中的汇总条目运行渲染层单测在 xai-grok-pager 目录下执行cargo test -p xai-grok-pager views::new_worktree_dialog与cargo test -p xai-grok-pager voice_stop_click_during_plan_review可分别跑通两个修复对应的测试模块具体测试名以cargo test -p xai-grok-pager -- --list输出为准实际体验在较窄的终端约 40 列中打开欢迎页的 New Worktree 对话框输入长名称观察对话框变宽与…前导滚动在开启语音听写CtrlSpace后进入 plan mode 审查确认[stop]仍可点击并正常结束录音。小结0.2.91 的两条变更虽小却分别触及 TUI 交互的两个关键面语音听写指示器修复保证了覆盖层出现时关键控件不丢失的可用性底线Worktree 对话框则完善了任意终端宽度下输入长文本不截断的健壮性。对希望深入 grok-build 终端实现xai-grok-pager 与 xai-grok-shell的开发者而言这两处修复连同其测试是理解鼠标热区路由与单行文本视口机制的极佳起点。赞分享人工智能大模型AI Agent代码智能体CLI工具调用MCP Clients【免费下载链接】grok-buildSpaceXAIs coding agent harness and TUI. Fullscreen, mouse interactive, extensible.项目地址https://gitcode.com/gh_mirrors/gr/grok-build点击查看免费下载相关推荐VS Code 语音支持实战指南Voice Mode 语音对话与内置听写Dictation配置详解VS Code 语音支持实战指南Voice Mode 语音对话与内置听写Dictation配置详解 本文围绕 VS Codevscode docs 仓库文档教程grok-build 0.2.80 版本深度解析会话级命令超时、语音听写与压缩持久化实战指南grok build 0.2.80 版本深度解析会话级命令超时、语音听写与压缩持久化实战指南 版本发布说明 crates/codegen/xai grok人工智能大模型AI Agent代码智能体CLI工具调用MCP ClientsGrok Voice 插件实战在 Cursor 中为应用接入 Grok 实时语音、听写与朗读并用日志驱动调试修复Grok Voice 插件实战在 Cursor 中为应用接入 Grok 实时语音、听写与朗读并用日志驱动调试修复 本插件 grok voice 是 CuAI 技能AI 插件插件系统AI Agent上一篇如何高效解密QQ音乐QMC格式qmc-decoder完整实战指南下一篇3分钟快速上手BetterNCM-Installer让网易云音乐插件安装从未如此简单创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考