BUG-HUNT: [consistency] TuiCommandRouter.handle() splits on whitespace but slash catalog uses colon-namespaced commands — every colon-style command returns "Unknown command" #6604

Open
opened 2026-04-09 22:08:37 +00:00 by HAL9000 · 0 comments
Owner

Bug Report: Consistency — Slash Command Namespace Routing Mismatch

Severity Assessment

  • Impact: Every colon-namespaced slash command shown in the overlay (e.g. /persona:list, /session:export, /session:show) returns "Unknown command: /persona:list" when typed. The only commands that actually work are the legacy space-separated forms (/persona list, /session show). Since the overlay only shows colon forms, users following the UI can never successfully execute any slash command except /help.
  • Likelihood: High — affects all users who follow the slash command overlay suggestions.
  • Priority: High

Location

  • File: src/cleveragents/tui/commands.py
  • Function/Class: TuiCommandRouter.handle
  • Lines: 48–58
  • Also: src/cleveragents/tui/slash_catalog.py lines 18–88 (all commands use namespace:subcommand format)

Description

TuiCommandRouter.handle() splits raw on whitespace and compares tokens[0] to bare namespace strings:

# commands.py
def handle(self, raw: str, *, session_id: str) -> str:
    tokens = raw.strip().split()   # splits on SPACES
    if not tokens:
        return "Empty command"
    if tokens[0] == "persona":     # expects "persona", not "persona:list"
        return self._persona_command(tokens[1:], session_id=session_id)
    if tokens[0] == "session":     # expects "session", not "session:export"
        return self._session_command(tokens[1:], session_id=session_id)
    if tokens[0] == "help":
        return self._help_command(tokens[1:])
    return f"Unknown command: /{raw}"

The slash overlay catalog, however, advertises every command in namespace:subcommand format:

# slash_catalog.py
SLASH_COMMAND_SPECS: tuple[SlashCommandSpec, ...] = (
    SlashCommandSpec("session:create", "Session", ...),
    SlashCommandSpec("session:list", "Session", ...),
    SlashCommandSpec("session:show", "Session", ...),
    SlashCommandSpec("session:export", "Session", ...),
    SlashCommandSpec("persona:list", "Persona", ...),
    SlashCommandSpec("persona:set", "Persona", ...),
    ...
)

Trace for /persona:list:

  1. User types /persona:list
  2. InputModeRouter.detect_mode()InputMode.COMMAND
  3. cmd = text.lstrip()[1:]"persona:list"
  4. command_router.handle("persona:list", ...) is called
  5. tokens = "persona:list".split()["persona:list"]
  6. tokens[0] == "persona:list""persona" → falls through
  7. Returns "Unknown command: /persona:list"

Only working forms (space-separated):

  • /persona listtokens[0]="persona"
  • /session showtokens[0]="session"

But the overlay never shows the space-separated form, so users have no way to discover the working syntax.

Expected Behavior

TuiCommandRouter.handle() should parse namespace:subcommand tokens, splitting on : to route to the appropriate handler. For example, "persona:list" should be parsed as namespace="persona", subcommand="list".

Actual Behavior

All colon-namespaced commands (the entire slash catalog overlay) silently fail with "Unknown command: /persona:list" etc.

Suggested Fix

def handle(self, raw: str, *, session_id: str) -> str:
    tokens = raw.strip().split()
    if not tokens:
        return "Empty command"
    # Support both "persona list" and "persona:list" forms
    first = tokens[0]
    if ":" in first:
        namespace, subcommand = first.split(":", 1)
        tokens = [namespace, subcommand] + tokens[1:]
    if tokens[0] == "persona":
        return self._persona_command(tokens[1:], session_id=session_id)
    if tokens[0] == "session":
        return self._session_command(tokens[1:], session_id=session_id)
    if tokens[0] == "help":
        return self._help_command(tokens[1:])
    return f"Unknown command: /{raw}"

Category

consistency

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it.


Automated by CleverAgents Bot
Supervisor: Bug Hunting | Agent: bug-hunter

## Bug Report: Consistency — Slash Command Namespace Routing Mismatch ### Severity Assessment - **Impact**: Every colon-namespaced slash command shown in the overlay (e.g. `/persona:list`, `/session:export`, `/session:show`) returns `"Unknown command: /persona:list"` when typed. The only commands that actually work are the legacy space-separated forms (`/persona list`, `/session show`). Since the overlay only shows colon forms, users following the UI can never successfully execute any slash command except `/help`. - **Likelihood**: High — affects all users who follow the slash command overlay suggestions. - **Priority**: High ### Location - **File**: `src/cleveragents/tui/commands.py` - **Function/Class**: `TuiCommandRouter.handle` - **Lines**: 48–58 - **Also**: `src/cleveragents/tui/slash_catalog.py` lines 18–88 (all commands use `namespace:subcommand` format) ### Description `TuiCommandRouter.handle()` splits `raw` on whitespace and compares `tokens[0]` to bare namespace strings: ```python # commands.py def handle(self, raw: str, *, session_id: str) -> str: tokens = raw.strip().split() # splits on SPACES if not tokens: return "Empty command" if tokens[0] == "persona": # expects "persona", not "persona:list" return self._persona_command(tokens[1:], session_id=session_id) if tokens[0] == "session": # expects "session", not "session:export" return self._session_command(tokens[1:], session_id=session_id) if tokens[0] == "help": return self._help_command(tokens[1:]) return f"Unknown command: /{raw}" ``` The slash overlay catalog, however, advertises every command in `namespace:subcommand` format: ```python # slash_catalog.py SLASH_COMMAND_SPECS: tuple[SlashCommandSpec, ...] = ( SlashCommandSpec("session:create", "Session", ...), SlashCommandSpec("session:list", "Session", ...), SlashCommandSpec("session:show", "Session", ...), SlashCommandSpec("session:export", "Session", ...), SlashCommandSpec("persona:list", "Persona", ...), SlashCommandSpec("persona:set", "Persona", ...), ... ) ``` **Trace for `/persona:list`:** 1. User types `/persona:list` 2. `InputModeRouter.detect_mode()` → `InputMode.COMMAND` 3. `cmd = text.lstrip()[1:]` → `"persona:list"` 4. `command_router.handle("persona:list", ...)` is called 5. `tokens = "persona:list".split()` → `["persona:list"]` 6. `tokens[0] == "persona:list"` ≠ `"persona"` → falls through 7. Returns `"Unknown command: /persona:list"` ✗ **Only working forms (space-separated):** - `/persona list` → `tokens[0]="persona"` ✓ - `/session show` → `tokens[0]="session"` ✓ But the overlay never shows the space-separated form, so users have no way to discover the working syntax. ### Expected Behavior `TuiCommandRouter.handle()` should parse `namespace:subcommand` tokens, splitting on `:` to route to the appropriate handler. For example, `"persona:list"` should be parsed as namespace=`"persona"`, subcommand=`"list"`. ### Actual Behavior All colon-namespaced commands (the entire slash catalog overlay) silently fail with `"Unknown command: /persona:list"` etc. ### Suggested Fix ```python def handle(self, raw: str, *, session_id: str) -> str: tokens = raw.strip().split() if not tokens: return "Empty command" # Support both "persona list" and "persona:list" forms first = tokens[0] if ":" in first: namespace, subcommand = first.split(":", 1) tokens = [namespace, subcommand] + tokens[1:] if tokens[0] == "persona": return self._persona_command(tokens[1:], session_id=session_id) if tokens[0] == "session": return self._session_command(tokens[1:], session_id=session_id) if tokens[0] == "help": return self._help_command(tokens[1:]) return f"Unknown command: /{raw}" ``` ### Category consistency ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Hunting | Agent: bug-hunter
HAL9000 added this to the v3.2.0 milestone 2026-04-09 22:25:27 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
cleveragents/cleveragents-core#6604
No description provided.