Skip to main content
All slash commands — /new, /model, /help, and everything else — are defined once in a central registry and automatically propagate to every consumer: CLI help output, gateway dispatch, Telegram bot command menu, Slack subcommand routing, and tab autocomplete.

The CommandDef dataclass

Every slash command is represented by a CommandDef instance in hermes_cli/commands.py:

Fields

Adding a slash command

1

Add CommandDef to COMMAND_REGISTRY

Open hermes_cli/commands.py and add a CommandDef entry to the COMMAND_REGISTRY list. Place it in the appropriate category section.
Every downstream consumer — CLI help, gateway help, Telegram menu, Slack routing, autocomplete — derives from this registry at import time. No other registry-related changes are needed.
2

Add handler in HermesCLI.process_command()

Open cli.py and add a branch in HermesCLI.process_command(). Commands are dispatched on the canonical name returned by resolve_command():
For persistent settings, use save_config_value() in cli.py rather than writing to the config file directly.
3

Add gateway handler in gateway/run.py (if applicable)

If the command should be available in messaging platforms (i.e. gateway_only=True or neither flag is set), add a handler in gateway/run.py:
Skip this step if you set cli_only=True on the CommandDef.
4

For persistent settings, use save_config_value()

If the command changes a configuration value that should persist across sessions, use the save_config_value() helper in cli.py rather than directly writing to the config file:

How aliases work

Aliases are fully automatic. Adding an alias to the aliases tuple on a CommandDef is the only change required. All consumers update automatically:
  • CLI dispatchresolve_command() maps both canonical name and aliases to the same CommandDef
  • CLI help — aliases shown alongside the canonical command
  • Gateway dispatchGATEWAY_KNOWN_COMMANDS frozenset includes all aliases
  • Telegram bot menu — canonical name only (aliases excluded from the visible menu)
  • Slack routingslack_subcommand_map() maps every alias to the command handler
  • Tab autocompleteCOMMANDS flat dict includes alias → description entries
Example — the /background command has the bg alias:
Both /background my task and /bg my task resolve to the same handler with zero extra code.

Command categories

Commands are grouped by category in /help output. Use the appropriate category:

Derived consumers

All downstream consumers are built from COMMAND_REGISTRY at import time: