Coverage for src / agent / commands / registry.py: 100%
25 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 14:30 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-11 14:30 +0000
1# Copyright 2025-2026 Microsoft Corporation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
15"""Runtime registry for slash commands.
17Provides O(1) lookup and completion support for discovered commands.
18"""
20from agent.commands.manifest import SlashCommandManifest
23class SlashCommandRegistry:
24 """Registry for slash commands with lookup and completion support.
26 Maintains a dictionary of commands for O(1) lookup by name and provides
27 methods for auto-completion and help display integration.
29 Example:
30 >>> registry = SlashCommandRegistry()
31 >>> registry.register(SlashCommandManifest(name="clone", description="Clone repos"))
32 >>> registry.get("clone")
33 SlashCommandManifest(name='clone', ...)
34 >>> registry.get_completions()
35 ['/clone']
36 """
38 def __init__(self) -> None:
39 """Initialize empty command registry."""
40 self._commands: dict[str, SlashCommandManifest] = {}
42 def register(self, command: SlashCommandManifest) -> None:
43 """Register a slash command.
45 Args:
46 command: Command manifest to register
47 """
48 self._commands[command.name] = command
50 def get(self, name: str) -> SlashCommandManifest | None:
51 """Get command by name.
53 Args:
54 name: Command name (without leading /)
56 Returns:
57 Command manifest if found, None otherwise
58 """
59 return self._commands.get(name)
61 def count(self) -> int:
62 """Get number of registered commands.
64 Returns:
65 Number of commands in registry
66 """
67 return len(self._commands)
69 def get_completions(self) -> list[str]:
70 """Get list of command names for auto-completion.
72 Returns command names prefixed with / for direct use with
73 prompt_toolkit WordCompleter.
75 Returns:
76 List of command names with / prefix (e.g., ["/clone", "/test"])
77 """
78 return [f"/{name}" for name in sorted(self._commands.keys())]
80 def get_help_text(self) -> list[tuple[str, str, str]]:
81 """Get help text for all registered commands.
83 Returns:
84 List of (name, args, description) tuples for help display.
85 Args is empty string if command takes no arguments.
86 """
87 result = []
88 for name in sorted(self._commands.keys()):
89 cmd = self._commands[name]
90 args_display = cmd.args or ""
91 result.append((name, args_display, cmd.description))
92 return result
94 def get_all_commands(self) -> list[SlashCommandManifest]:
95 """Get all registered commands.
97 Returns:
98 List of all command manifests, sorted by name
99 """
100 return [self._commands[name] for name in sorted(self._commands.keys())]
102 def __contains__(self, name: str) -> bool:
103 """Check if command is registered.
105 Args:
106 name: Command name (without leading /)
108 Returns:
109 True if command is registered
110 """
111 return name in self._commands
113 def __len__(self) -> int:
114 """Get number of registered commands."""
115 return len(self._commands)