fix(cli): prevent trailing space in picker-command completions

Commands that open pickers (/model, /skin, /personality) must not
receive a trailing space from the completion handler.  The TUI's
submit handler applies pending completions on Enter — adding a space
makes the input differ from the original, blocking picker execution.

Supersedes #15339.
This commit is contained in:
Tranquil-Flow 2026-04-25 09:50:21 +10:00
parent 00c3d848d8
commit b9949fff48
2 changed files with 32 additions and 1 deletions

View file

@ -865,6 +865,12 @@ class SlashCommandCompleter(Completer):
except Exception:
return {}
# Commands that open pickers when run without arguments.
# These should NOT receive a trailing space in completions because
# the TUI's submit handler applies completions on Enter if input differs,
# which blocks picker execution.
_PICKER_COMMANDS = frozenset({"model", "skin", "personality"})
@staticmethod
def _completion_text(cmd_name: str, word: str) -> str:
"""Return replacement text for a completion.
@ -873,8 +879,16 @@ class SlashCommandCompleter(Completer):
returning ``help`` would be a no-op and prompt_toolkit suppresses the
menu. Appending a trailing space keeps the dropdown visible and makes
backspacing retrigger it naturally.
However, commands that open pickers (model, skin, personality) should
NOT get a trailing space the TUI would apply the completion on Enter
and block the picker from opening.
"""
return f"{cmd_name} " if cmd_name == word else cmd_name
if cmd_name != word:
return cmd_name
if cmd_name in SlashCommandCompleter._PICKER_COMMANDS:
return cmd_name
return f"{cmd_name} "
@staticmethod
def _extract_path_word(text: str) -> str | None:

View file

@ -359,6 +359,23 @@ class TestSlashCommandCompleter:
assert [item.text for item in completions] == ["help"]
# -- picker commands must NOT get trailing space ---------------------
def test_picker_commands_no_trailing_space(self):
"""Picker commands (/model, /skin, /personality) must not get trailing space."""
for cmd in ("model", "skin", "personality"):
result = SlashCommandCompleter._completion_text(cmd, cmd)
assert result == cmd, f"/{cmd} should not have trailing space"
def test_non_picker_exact_match_gets_trailing_space(self):
"""Regular commands like /help should still get trailing space on exact match."""
assert SlashCommandCompleter._completion_text("help", "help") == "help "
def test_partial_match_never_has_trailing_space_for_picker(self):
"""Partial matches should never have trailing space regardless of command type."""
assert SlashCommandCompleter._completion_text("model", "mo") == "model"
assert SlashCommandCompleter._completion_text("help", "he") == "help"
# -- non-slash input returns nothing ---------------------------------
def test_no_completions_for_non_slash_input(self):