fix(cli): preserve slash command names in narrow terminals - #8657
Conversation
|
✅ Qwen Triage finished — CI landed green on ✅ Qwen Triage 已完成 —— |
|
Thanks for the PR!
Moving on to code review. 🔍 中文说明感谢贡献!
进入代码审查 🔍 — Qwen Code · qwen3.8-max Reviewed at |
|
Code review My independent take on "keep command names intact while hints yield" was exactly this: make the label element non-shrinkable and let the hint/badge absorb the overflow by wrapping — a single edit in the suggestion row loop. That is what this PR does, in one production line. What I checked:
Two non-blocking notes: rows with long hints can now span multiple lines, so a narrow-terminal menu can grow taller ( CI test evidence (the PR's own CI, fetched via the API — the gate does not run PR code) The unit suite on this commit is still running on Linux; macOS/Windows/integration jobs are skipped at this point, and nothing is red so far: precheck and the Desktop Shell job completed green. Final CI results for
One row per check name (latest run); skipped checks omitted; failures sort first. / 每个检查名一行(取最新一次运行),省略 skipped,失败项排在最前。 Sandboxed verification would settle this: Not verified: real-terminal rendering on Linux/Windows — CI is still in flight, and the author's Tested-on table covers macOS only (the author's claim, not independently re-run). 中文说明代码审查:我对"保持命令名完整、让提示让出空间"的独立方案正是如此——把标签元素设为不可收缩,让参数提示/来源标识通过换行吸收溢出,即建议行渲染循环里的一处改动。这个 PR 正是这么做的,生产代码仅一行。 核对结论:
两条非阻塞提醒:长提示的行现在可能占多行,窄终端下建议列表会变更高(MAX_SUGGESTIONS_TO_SHOW 按建议条数计,不按行数计)——这是 PR 在 Risk & Scope 中已说明的取舍;命令名单独超过列宽上限(slash 模式约为宽度一半)时会溢出而非截断——这正是本改动的目的,且对真实命令名很少见。 CI 测试证据(PR 自身 CI,通过 API 获取——按门禁规则不运行 PR 代码):该 commit 的 Linux 单元测试仍在运行,macOS/Windows/集成测试目前为 skipped,暂无红色项:precheck 与 Desktop Shell 任务已通过。详见上方表格(finalize 流程会在 CI 结束后原地更新)。沙盒验证可以定论: — Qwen Code · qwen3.8-max Reviewed at |
|
Confidence: 4/5 — solid minimal fix with a load-bearing test; the only residual is that real-terminal rendering beyond the author's macOS run isn't independently settled yet. This is what a good fork PR looks like. The problem is observed and reproduced (width 120, with screenshots), and the mechanism checks out in code — the command name, argument hint, and source badge shared one shrinkable flex row inside the fixed-width label column, so the name itself truncated. The fix is the smallest possible one: make the label non-shrinkable so hints wrap instead — which is also the approach I'd have taken independently. One production line, a colocated test pinning exactly the reported scenario, and nothing else in the diff. The tradeoff (long hints may take extra lines in narrow menus) is documented in the PR itself, and the unconditional application to Why not 5: the rendering claim currently rests on the test renderer and the author's macOS run, and the Linux unit suite is still in flight — hence the deferred approval below, and the CI is still running, so approval is deferred until CI lands green on 中文说明Confidence: 4/5 —— 扎实的最小修复,测试切实固定了行为;唯一的遗留是除作者的 macOS 运行外,真实终端渲染尚未独立验证。 这是一个标准的优质 fork PR。问题可观测、可复现(宽度 120,附截图),机制在代码中得到确认——命令名、参数提示和来源标识共享固定宽度标签列内的一个可收缩 flex 行,因此命令名本身被截断。修复是最小可能的改动:让标签不可收缩、使提示改为换行——这也正是我独立会采用的方案。生产代码一行,同目录测试恰好固定所报告的场景,diff 中没有其他内容。代价(长提示在窄终端可能多占行)PR 本身已说明;对 @-mention 行无条件生效也与该行既有的意图一致。 为什么不是 5 分:渲染结论目前基于测试渲染器和作者的 macOS 运行,Linux 单元测试仍在进行——因此下面的延迟批准;若维护者想在合并前获得真实终端证据,我的审查评论中已给出 CI 仍在运行,批准将等待 CI 在该 commit 上全绿后执行。 — Qwen Code · qwen3.8-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship — CI landed green after the review. ✅
doudouOUC
left a comment
There was a problem hiding this comment.
中文说明
— kimi-k3 via Qwen Code /review (v0.21.7)
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline. Not reviewed: build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally.
中文说明
已审查。 建议见行内评论。 未审查:build-and-test — Integration Tests (CLI, No Sandbox) was skipped in CI and its suite did not run locally。
— qwen3.8-max via Qwen Code /review (v0.21.7)
| expect(lines).toContainEqual(expect.stringMatching(/^> review(?: |$)/)); | ||
| expect(lines).toContainEqual(expect.stringMatching(/^ {2}doctor(?: |$)/)); |
There was a problem hiding this comment.
[Suggestion] The new test pins only the name-survival half of the fix: it never asserts that the argument hint wraps and stays visible, which is this PR's second stated behavior ("Argument hints continue to yield space by wrapping"). The sibling reverse-mode test asserts both sides of its tradeoff (reference intact AND description truncated); this one asserts only one side. — Failure scenario: a future change that renders the hint with wrap="truncate-end" (or skips it when the column overflows) keeps the command names intact, so this test stays green while the wrap-instead-of-vanish behavior silently regresses. Verified by probe: under a simulated truncate mutation this test file still passed 10/10 while the frame no longer contained the hint tail ([--fix]).
| expect(lines).toContainEqual(expect.stringMatching(/^> review(?: |$)/)); | |
| expect(lines).toContainEqual(expect.stringMatching(/^ {2}doctor(?: |$)/)); | |
| expect(lines).toContainEqual(expect.stringMatching(/^> review(?: |$)/)); | |
| expect(lines).toContainEqual(expect.stringMatching(/^ {2}doctor(?: |$)/)); | |
| expect(lastFrame()).toContain('[--fix]'); |
中文说明
新测试只固定了修复中"命令名存活"这一半:它没有断言参数提示换行后仍然可见——而这是本 PR 明确承诺的第二个行为("参数提示仍可通过换行让出空间")。同文件中 reverse 模式的姊妹测试同时断言了权衡的两个方面(引用完整保留且描述被截断),而本测试只断言了一方面。— 故障场景:未来若有改动把提示渲染为 wrap="truncate-end"(或在列溢出时直接跳过提示),命令名依然完整,本测试仍然通过,但"换行而不是消失"的行为会悄无声息地回归。已用探针验证:在模拟的截断变异下,整个测试文件仍 10/10 通过,而渲染帧中已不再包含提示尾部([--fix])。建议补充对换行后提示内容的断言,例如 expect(lastFrame()).toContain('[--fix]');——已验证在当前 HEAD 通过、在上述截断变异下失败。
— qwen3.8-max via Qwen Code /review (v0.21.7)
There was a problem hiding this comment.
Thanks for the suggestion. I agree this would strengthen a broader contract around hint visibility. This PR is intentionally scoped to the reported defect: the actionable command name must not lose characters. Argument hints are secondary and may legitimately be wrapped, truncated, or hidden by a future narrow-width policy, so asserting the full [--fix] tail would broaden the behavior guaranteed here. CI is green and the focused change has already received an approval, so I would prefer to keep this PR small and handle hint-visibility guarantees in a follow-up.
| > | ||
| <Box> | ||
| {labelElement} | ||
| <Box flexShrink={0}>{labelElement}</Box> |
There was a problem hiding this comment.
[Suggestion] With the label now wrapped in <Box flexShrink={0}>, the sibling argumentHint/sourceBadge Text nodes (default flexShrink: 1) absorb all remaining flex shrink. In very narrow terminals they collapse to ~1 column and wrap one character per line, inflating suggestion rows. — Failure scenario: a terminal ≤ ~40 columns (tmux split panes, side-by-side IDE windows) with slash commands carrying long argumentHints — measured on the real component: at width 20 the two-suggestion frame grows from 37 lines pre-fix to 88 lines post-fix (hint as 1-2-char vertical strips plus ~29 trailing blank lines); at width 30, an openwork-desktop-sync + [direction] row grows from 3 to 13 lines. With MAX_SUGGESTIONS_TO_SHOW = 8 the completion menu can balloon vertically and push the conversation off-screen (Ink bottom-anchors overflowing frames). Navigation and mouse hit-testing still work, and pre-fix rendering at these widths was already garbled, so this exacerbates a pre-existing edge case rather than regressing a working path. Suggested fix: skip the hint/badge or apply wrap="truncate-end" when the remaining label-column width after the command name is below a small threshold (e.g. < 8 columns), so narrow terminals degrade to "name only" instead of a one-character vertical strip.
中文说明
标签被包进 <Box flexShrink={0}> 之后,同级的 argumentHint/sourceBadge 文本节点(默认 flexShrink: 1)会吸收全部剩余 flex 收缩。在极窄终端里它们塌缩到约 1 列宽、按每行一个字符换行,使建议行高度暴涨。— 故障场景:终端宽度 ≤ 约 40 列(tmux 分屏、IDE 并排窗口)且命令带有较长 argumentHint 时,在真实组件上实测:宽度 20 时,两条建议的渲染帧从修复前 37 行涨到修复后 88 行(提示变成 1-2 个字符的竖条,另有约 29 行尾部空行);宽度 30 时,openwork-desktop-sync + [direction] 的行从 3 行涨到 13 行。MAX_SUGGESTIONS_TO_SHOW = 8 时,补全菜单可能纵向膨胀、把对话内容挤出屏幕(Ink 对溢出帧做底部对齐)。键盘导航和鼠标命中测试仍然正常,且这些宽度下修复前的渲染本来就是错乱的,因此这是既有边界情况的加剧,而非对原本正常路径的回归。建议:当命令名之后标签列剩余宽度低于某个较小阈值(例如 < 8 列)时,跳过提示/徽标或改用 wrap="truncate-end",让窄终端退化为"只显示名称",而不是出现每行一个字符的竖条。
— qwen3.8-max via Qwen Code /review (v0.21.7)
There was a problem hiding this comment.
Thanks for the detailed measurements. I agree that long-name and extremely narrow terminal combinations deserve a bounded fallback. A robust solution likely needs an explicit remaining-width policy that truncates or hides hints and badges, plus a width-matrix test suite, rather than another isolated flex adjustment. That is broader than the focused command-name truncation fixed here, and rendering at those widths was already degraded before this change. With CI green and the focused fix already approved, I would prefer to defer that broader narrow-width policy to a follow-up.
|
Released in v0.21.8. |
What this PR does
Keeps slash-command names intact when the completion menu has limited horizontal space. Argument hints continue to yield space by wrapping, so the actionable command token remains trustworthy.
Why it's needed
The command name, argument hint, and source badge previously shared a shrinkable row. On narrower terminals this could render
reviewasrevieanddoctorasdocto, misleading users into typing a command that does not exist.Reviewer Test Plan
How to verify
Open the interactive CLI in a narrow terminal, type
/revand/doc, and confirm the completion list always shows the completereviewanddoctorcommand names while long argument hints wrap onto following lines.Evidence (Before & After)
Before: at width 120,

reviewrendered asrevieanddoctorrendered asdocto.After: at width 120, both command names render completely and their argument hints wrap to preserve the names.

Tested on
Environment (optional)
Node.js v24.14.0, Ink 7.0.3. Focused component tests pass 10/10; build, bundle, and targeted ESLint pass. Repository-wide typecheck remains blocked by pre-existing upstream Ink type errors involving selection APIs.
Risk & Scope
Linked Issues
N/A
中文说明
本 PR 的改动
在补全菜单横向空间不足时保持斜杠命令名称完整。参数提示仍可通过换行让出空间,确保用户看到的可执行命令名称可信。
改动原因
此前命令名称、参数提示和来源标识位于同一个可收缩布局中。在较窄的终端里,
review可能显示成revie,doctor可能显示成docto,从而误导用户输入不存在的命令。Reviewer Test Plan
验证方式
在较窄的终端中启动交互式 CLI,分别输入
/rev和/doc,确认补全列表始终完整显示review和doctor,较长的参数提示则换行显示。前后对比证据
修复前:宽度为 120 时,
review显示为revie,doctor显示为docto。修复后:宽度为 120 时,两个命令名称都完整显示,参数提示通过换行保留命令名称。
测试平台
环境(可选)
Node.js v24.14.0,Ink 7.0.3。定向组件测试 10/10 通过;构建、bundle 和目标 ESLint 均通过。仓库级 typecheck 仍被 upstream 已存在的 Ink selection API 类型错误阻塞。
风险与范围
关联 Issue
N/A