"""Registry for slash commands."""
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .base import BaseCommand
class CommandRegistry:
"""Store and resolve slash commands by name/alias."""
def __init__(self) -> None:
self._commands: dict[str, BaseCommand] = {}
def register(self, command: "BaseCommand") -> None:
self._commands[command.meta.name] = command
for alias in command.meta.aliases:
self._commands[alias] = command
def get(self, name: str) -> "BaseCommand | None":
return self._commands.get(name.lower())
def all(self) -> list["BaseCommand"]:
"""Return unique commands by canonical name."""
seen: set[int] = set()
out: list[BaseCommand] = []
for cmd in self._commands.values():
cid = id(cmd)
if cid not in seen:
seen.add(cid)
out.append(cmd)
return out
def match(self, prefix: str) -> list["BaseCommand"]:
"""Return commands whose name or alias matches ``prefix``.
Case-insensitive prefix match against the canonical name and aliases.
An exact name/alias match sorts first, then remaining prefix matches in
registration order. An empty prefix returns every command (used when the
user has typed only ``/``).
"""
prefix = prefix.strip().lower()
if not prefix:
return self.all()
def rank(cmd: "BaseCommand") -> int:
names = [cmd.meta.name.lower(), *(a.lower() for a in cmd.meta.aliases)]
if prefix in names:
return 0
if any(n.startswith(prefix) for n in names):
return 1
return 2
matched = [cmd for cmd in self.all() if rank(cmd) < 2]
matched.sort(key=rank)
return matched
_GLOBAL_REGISTRY: CommandRegistry | None = None
def get_registry() -> CommandRegistry:
global _GLOBAL_REGISTRY
if _GLOBAL_REGISTRY is None:
_GLOBAL_REGISTRY = _build_default_registry()
return _GLOBAL_REGISTRY
def _build_default_registry() -> CommandRegistry:
from . import builtin
registry = CommandRegistry()
registry.register(builtin.HelpCommand())
registry.register(builtin.NewCommand())
registry.register(builtin.SessionsCommand())
registry.register(builtin.SwitchCommand())
registry.register(builtin.ProfileCommand())
registry.register(builtin.QuitCommand())
registry.register(builtin.ThinkingCommand())
registry.register(builtin.CompactCommand())
registry.register(builtin.ThemesCommand())
registry.register(builtin.MouseCommand())
registry.register(builtin.ExportCommand())
return registry