Skip to content

feat(tui): redesign AskUserQuestion panel, layout, focus and result display - #48

Open
LIUXIN557 wants to merge 6 commits into
masterfrom
improve/build-dry-run
Open

feat(tui): redesign AskUserQuestion panel, layout, focus and result display#48
LIUXIN557 wants to merge 6 commits into
masterfrom
improve/build-dry-run

Conversation

@LIUXIN557

Copy link
Copy Markdown
Collaborator

概述

完成 TUI AskUserQuestion 重设计的收尾,并修正真实交互验收中发现的 11 项界面问题。同时带入 ask.max_questions 跨端配置。

已并入最新 master(v0.9.14,29 个提交),无冲突。

面板几何与着色

  • 面板改为聊天视口底部定高浮层,四边不再越出聊天区,也不再覆盖输入框与状态栏。
  • 只对边框着色(borderStyled),不再对容器整体 color() —— 这是「整个对话区变蓝」的根因。
  • 面板绘制前对自身矩形做字符级擦除clear_under)。只设背景色不会擦掉下层字符,聊天文字会从面板没写字的格子透出来(表现为 POSTto d、行尾多出 (openai/…))。
  • 移除面板内的全局状态行行;模型切换、更新提示等只留在标题区与底部状态区。

选项与汇总排版

  • 选项页改为编号列 / 标记列 / 标题列 / 说明列四个固定槽位,逐列左对齐,列间距 2 个 ASCII 空格,标题列按本题最长标题收紧(不再固定占屏约 40%)。
  • 自定义行与其他选项共用同一组列边界,并显示单选/多选标记(( ) / (*)[ ] / [x])。
  • 已选行不再有底色;只有焦点行使用底色,且焦点不改变文字颜色与字重。
  • 题目白色加粗、答案白色不加粗、答案解释灰色不加粗,改用语义化主题色而非容器统一下发。
  • 汇总页与转录按 问题:答案 成对输出:两列块顶部对齐、所有答案共用同一左边界、块间空一行、短问题在列内补齐;宽度不足时降级为上下堆叠。

光标与帮助

  • 终端光标绑定到自定义文本的真实插入点,不再由整块面板抢占。
  • 底部帮助改为「键名: 功能」的分层片段(键名主文字色、功能弱化色),使用真实按键符号 ↑↓ ←→ Enter Esc Space Tab Ctrl+Enter PgUp/PgDn,并保留固定最小行数,避免状态切换带动面板位移。

结果展示与参数隐藏

  • AskUserQuestion 不再生成通用参数摘要;TUI 对问答结果走专用展示分支,Ctrl+E / Ctrl+O 都不会把它切回参数 JSON。
  • 历史会话恢复时忽略旧的不安全摘要,question / header / options / description / multiSelect 不再泄漏到转录。
  • 转录格式统一为 序号. 问题:答案,问题始终与答案成对出现。

顺带修复的真实缺陷

  • 窄宽度折行的零进度死循环:单字形已占满整行且下一字形为收尾标点时,回退位置等于行首,循环持续产出空区间直到 bad_alloc(原窄终端用例曾耗时 127s 后抛异常)。
  • 折行保持 ASCII 单词完整,行首不出现 ,。?!:、; 等收尾标点。
  • agent_loop.cpp interrupted 分支解引用空 optional

结构调整

  • 新增 src/tui/ask_question_panel.{hpp,cpp}:overlay 绘制层,颜色由调用方注入,因此可以用 FTXUI Screen 逐格断言位置与颜色,而不是只测字符串。
  • ask_question_layout 的行模型改为按列保存文本并携带列偏移,渲染端不再自行推算列宽。

验证

  • 问答相关 118 项测试通过
  • 合并 master 后全量 4118 项通过
  • 新测试覆盖:面板底部锚定与不越界、着色作用域、面板擦除下层内容(去掉 clear_under 时确认变红)、列对齐与标记、焦点不改字重、光标坐标(空/有文本)、汇总两列对齐与堆叠降级、参数名隐藏、帮助分层与固定高度、单选取消选中、点击自定义行进入行内编辑。
  • verify-package --target tui 13/13 PASS(staged 包内 models.dev 与 seed 资源校验通过)。

与本改动无关的既有失败

  • AgentLoopGoal.ResumeAfterAbortClearsStaleAbortAndContinuesturn_count >= 2 时序竞态。已做对照实验——临时还原本改动对该文件的唯一修改后重编译,仍同样失败。
  • TcpProbe.TimeoutOnUnreachableHost:依赖「不可达主机」的网络前提,本机探测返回 Ok,属环境问题。

OpenSpec

openspec/changes/redesign-tui-ask-user-question/(tasks 6.x / 7.x 已按完成情况勾选),需求文档同步更新:docs/specs/2026-09-07-tui-ask-user-question-requirements.md

Trae User added 5 commits September 9, 2026 16:15
…splay

真实交互验收后修正 TUI 问答界面的 11 项问题,并补上 ask.max_questions 的收尾。

面板几何与着色:
- 面板改为聊天视口底部定高浮层,四边不再越出聊天区
- 只给边框着色(borderStyled),不再对容器整体 color(),面板外聊天内容不再被染色
- 面板绘制前对自身矩形做字符级擦除(clear_under),聊天文字不再从空单元格透出
- 移除面板内的全局状态行,模型切换等通知只留在标题/状态区

选项与汇总排版:
- 选项页改为编号列/标记列/标题列/说明列四个固定槽位,列间距 2 个 ASCII 空格,标题列按最长标题收紧
- 自定义行与其他选项共用列边界并显示单选/多选标记
- 已选行不再有底色,只有焦点行有底色,且焦点不改变字重与字色
- 题目白色加粗、答案白色不加粗、说明灰色不加粗
- 汇总页与转录按“问题:答案”成对输出,答案列左对齐、块内顶部对齐、块间空行

光标与帮助:
- 终端光标绑定到自定义文本真实插入点,不再由整块面板抢占
- 帮助区改为“键名: 功能”分层片段并使用真实按键符号,保留固定最小行数以免状态切换带动面板位移

结果展示与参数隐藏:
- AskUserQuestion 不再生成通用参数摘要,TUI 走专用问答结果分支
- 历史会话恢复时忽略旧的不安全摘要,避免 question/header/options/multiSelect 泄漏

顺带修复:
- 窄宽度折行的零进度死循环(曾退化为 bad_alloc)
- 折行保持 ASCII 单词完整,行首不出现收尾标点
- agent_loop interrupted 分支解引用空 optional

新增 src/tui/ask_question_panel.* 渲染层(颜色注入,可逐格断言)。问答相关 118 项测试通过,全量 3920 项通过(2 项为既有基线/环境失败)。

OpenSpec: openspec/changes/redesign-tui-ask-user-question (tasks 6.x, 7.x)
- daemon_pool: check executables exist before std::filesystem::equivalent,
  so a missing expected executable is consistently Unsafe across platforms.
- pty_shell: only fall back to generic /bin/sh when no named shell
  (bash/zsh/fish) is available, so a broken login shell falls back to bash.
- toolchains_test: guard the Windows-path DetectsDirectories case with
  _WIN32 since backslash is not a POSIX path separator.
@LIUXIN557

Copy link
Copy Markdown
Collaborator Author

CI 单元测试失败分析(unit-tests / linux-x64)

ctest 汇总:4105 个测试中 3 个失败(exit code 8)。三个失败点均位于本 PR 未改动的模块(daemon_pool / terminal_resolver / toolchains),与 AskUserQuestion TUI 重构无关,属于基础分支上既有的测试环境 / 测试预期偏差。

1. DaemonPool.InstallationCompatibilityRequiresSameVersionAndExecutable

  • 断言:tests/desktop/daemon_pool_test.cpp#L631 期望 Unsafe(3),实际得到 Replace(2)。
  • 根因:测试把不存在的 missing.exe 传给 std::filesystem::equivalent()。Linux runner 上 equivalent 对缺失文件返回"不相同"(未置错误码),src/desktop/daemon_pool.cpp#L40-L42 走了 Replace 分支,而非 L36-L38ecUnsafe。平台 / filesystem 行为差异。

2. TerminalResolverPosixTest.BrokenLoginShellFallsBackToBash

  • 断言:tests/environment/terminal_resolver_test.cpp#L268-L276 期望坏登录 shell 回退到 /bin/bash(id bash),实际得到 shell / /bin/sh
  • 根因:src/environment/terminal_resolver.cpp#L58-L64 的回退顺序把通用 /bin/sh 排在 bash 前,实现与测试预期不符。

3. ToolchainsDetectTest.DetectsDirectoriesAndSkipsStoreStub

  • 行为:抛出 map::at 异常。
  • 根因:测试使用 Windows 风格路径C:\...),但在 Linux runner 上反斜杠非分隔符,src/environment/toolchains.cpp#L73parent_path() 返回空导致检出被跳过,随后 anchors.at("node") 撞 key 抛异常。测试环境(Windows 语义)与运行平台(Linux)不匹配。

修复(已合入本分支,commit dfebe5c

  • daemon_pool:先用 is_regular_file 显式确认两个可执行文件都存在,再调用 equivalent;任一缺失稳定返回 Unsafe,消除平台差异。
  • pty_shell(terminal_resolver 候选来源):通用 /bin/sh 兜底改为"仅当没有任何命名 shell(bash/zsh/fish)可用时"才挂上,使坏登录 shell 回退到真实的 bash。
  • toolchains_test:将 Windows 路径语义的 DetectsDirectoriesAndSkipsStoreStub#ifdef _WIN32 限定,避免在 POSIX 上误报。

Windows 侧 39 个相关用例已回归通过;Linux 侧行为需 CI 再次确认。

更新 PR #48 到当前 master 基线,并解决提问通道与主题确认的兼容问题。
修复滚动条命中、手动滚动、光标可见性、自定义答案选择和多行显示、
空首行编辑、窄屏汇总点击、双击 Esc 及大整数配置钳制。
同步主题通道测试,补齐轮次切换测试的请求开始前置条件。

验证:183 项定向测试通过;TUI 与 Desktop 构建通过;OpenSpec 严格验证通过。
全量 CTest 已运行,固定端口和临时目录竞争的失败项串行复查通过。
既有子任务测试断言通过但进程收尾超时,在原 Release 构建中同样复现。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants