Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Only write entries that are worth mentioning to users.

## Unreleased

- Shell: Fix slash command completion menu not appearing on exact match — typing a full command name like `/editor` now still shows the command entry (with its description) in the completion menu, while still suppressing unrelated prefix noise such as `/mcp` expanding to `/mcp-server` (fixes #1752)
- Shell: Add `/btw` side question command — ask a quick question during streaming without interrupting the main conversation; uses the same system prompt and tool definitions for prompt cache alignment; responses display in a scrollable modal panel with streaming support
- Shell: Redesign bottom dynamic area — split the monolithic `visualize.py` (1865 lines) into a modular package (`visualize/`) with dedicated modules for input routing, interactive prompts, approval/question panels, and btw modal; unify input semantics with `classify_input()` for consistent command routing
- Shell: Add queue and steer dual-channel input during streaming — Enter queues messages for delivery after the current turn; Ctrl+S injects messages immediately into the running turn's context; queued messages display in the prompt area with count indicator and can be recalled with ↑
Expand Down
1 change: 1 addition & 0 deletions docs/en/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This page documents the changes in each Kimi Code CLI release.

## Unreleased

- Shell: Fix slash command completion menu not appearing on exact match — typing a full command name like `/editor` now still shows the command entry (with its description) in the completion menu, while still suppressing unrelated prefix noise such as `/mcp` expanding to `/mcp-server` (fixes #1752)
- Shell: Add `/btw` side question command — ask a quick question during streaming without interrupting the main conversation; uses the same system prompt and tool definitions for prompt cache alignment; responses display in a scrollable modal panel with streaming support
- Shell: Redesign bottom dynamic area — split the monolithic `visualize.py` (1865 lines) into a modular package (`visualize/`) with dedicated modules for input routing, interactive prompts, approval/question panels, and btw modal; unify input semantics with `classify_input()` for consistent command routing
- Shell: Add queue and steer dual-channel input during streaming — Enter queues messages for delivery after the current turn; Ctrl+S injects messages immediately into the running turn's context; queued messages display in the prompt area with count indicator and can be recalled with ↑
Expand Down
1 change: 1 addition & 0 deletions docs/zh/release-notes/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

## 未发布

- Shell:修复 Slash 命令完全匹配时补全菜单不再弹出的问题——输入 `/editor` 等完整命令名时,补全菜单会继续显示该命令条目(含描述),同时仍然抑制诸如 `/mcp` → `/mcp-server` 这类无关前缀噪音(修复 #1752)
- Shell:新增 `/btw` 侧问命令——在 streaming 期间提出快速问题,不打断主对话;使用相同的系统提示词和工具定义以对齐 Prompt 缓存;响应在可滚动的模态面板中显示,支持流式输出
- Shell:重新设计底部动态区——将单体 `visualize.py`(1865 行)拆分为模块化包(`visualize/`),包含输入路由、交互式提示、审批/提问面板和 btw 模态面板等独立模块;通过 `classify_input()` 统一输入语义,实现一致的命令路由
- Shell:新增 streaming 期间的排队和 steer 双通道输入——Enter 将消息排队,在当前轮次结束后发送;Ctrl+S 将消息立即注入到正在运行的轮次上下文中;排队消息在提示区域显示计数指示器,可通过 ↑ 键召回编辑
Expand Down
16 changes: 16 additions & 0 deletions src/kimi_cli/ui/shell/prompt.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ def get_completions(

typed = token[1:]
if typed and typed in self._command_lookup:
# Exact match: only show the matching command itself (with its
# description), skipping fuzzy fallbacks like `/mcp` → `/mcp-server`.
# This preserves the intent of #666 (hide unrelated prefix noise)
# while still letting the user confirm the command and read its
# description (#1752).
seen_exact: set[str] = set()
for cmd in self._command_lookup[typed]:
if cmd.name in seen_exact:
continue
seen_exact.add(cmd.name)
yield Completion(
text=f"/{cmd.name}",
start_position=-len(token),
display=f"/{cmd.name}",
display_meta=cmd.description,
Comment on lines +151 to +155
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Prevent double-Enter on exact slash command input

Returning a completion for an already-complete token (e.g. typing /editor and yielding /editor) causes a UX regression in interactive mode: because this prompt uses complete_while_typing=True and binds Enter to has_completions, the first Enter is consumed by apply_completion instead of submitting the command, so users must press Enter twice to run exact-match slash commands. This was not the previous behavior for exact matches and is likely to surprise users who type full command names directly.

Useful? React with 👍 / 👎.

)
return
mention_doc = Document(text=typed, cursor_position=len(typed))
candidates = list(self._fuzzy.get_completions(mention_doc, complete_event))
Expand Down
34 changes: 28 additions & 6 deletions tests/ui_and_conv/test_slash_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,13 @@ def _completions(completer: SlashCommandCompleter, text: str):
return list(completer.get_completions(document, event))


def test_exact_command_match_hides_completions():
"""Exact matches should not show completions."""
def test_exact_command_match_shows_only_that_command():
"""Exact command name match should show only that command, not prefix fuzzy hits.

Regression for #1752 (exact match should still reveal the completion entry so
the user can read its description) while preserving the #666 intent of hiding
unrelated noise like `/mcp` → `/mcp-server`.
"""
completer = SlashCommandCompleter(
[
_make_command("mcp"),
Expand All @@ -59,11 +64,11 @@ def test_exact_command_match_hides_completions():

texts = _completion_texts(completer, "/mcp")

assert not texts
assert texts == ["/mcp"]


def test_exact_alias_match_hides_completions():
"""Exact alias matches should not show completions."""
def test_exact_alias_match_shows_only_canonical_command():
"""Exact alias match should show only the canonical command, not other fuzzy hits."""
completer = SlashCommandCompleter(
[
_make_command("help", aliases=["h"]),
Expand All @@ -73,7 +78,24 @@ def test_exact_alias_match_hides_completions():

texts = _completion_texts(completer, "/h")

assert not texts
assert texts == ["/help"]


def test_exact_command_match_completion_has_description():
"""Exact matches must carry the command's description so users can read it (#1752)."""
completer = SlashCommandCompleter(
[
_make_command("editor"),
_make_command("exit"),
]
)

completions = _completions(completer, "/editor")

assert len(completions) == 1
assert completions[0].text == "/editor"
assert completions[0].display_text == "/editor"
assert completions[0].display_meta_text == "editor command"


def test_should_complete_only_for_root_slash_token():
Expand Down
Loading