# How Slash Commands Work in Reasonix: Built-In vs Custom Implementations

> Discover how Reasonix handles slash commands. Understand built-in Go handlers and custom command loading for a dynamic runtime experience in this technical deep dive.

- Repository: [YHH/DeepSeek-Reasonix](https://github.com/esengine/DeepSeek-Reasonix)
- Tags: deep-dive
- Published: 2026-06-27

---

**Reasonix treats every line beginning with a forward-slash (`/`) as a slash command, routing built-in verbs through compiled Go handlers while dynamically loading custom commands from user directories into a mutable runtime registry.**

The DeepSeek-Reasonix codebase implements a dual-layer command system that distinguishes between static binary commands and user-defined scripts. Understanding how slash commands function in Reasonix requires examining the input processing pipeline in [`internal/control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/controller.go), the registration mechanisms in [`internal/command/slashtool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/command/slashtool.go), and the dynamic discovery system that parses files from configurable command directories.

## Input Handling and Command Detection

When the UI transmits user input to the backend, the `controller.Submit` method (line 590 of [`internal/control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/controller.go)) performs the initial classification. The controller checks whether the submitted line starts with the `/` character to determine if it should trigger the slash command pipeline.

If the token following the slash matches a **built-in verb**, the dispatcher immediately routes execution to the corresponding hard-coded handler in [`internal/command/slashtool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/command/slashtool.go). For all other inputs, the system delegates to `CustomCommand` (line 465 of [`internal/control/input.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/input.go)), which queries the **runtime registry** populated by `ReloadCommands`. When a match exists, the command body is inlined as a *skill* (as noted in the comment at line 484); otherwise, the user receives an "unknown slash command" notification.

## Built-In Command Registration

Built-in commands are compiled directly into the Reasonix binary, ensuring they are always available and cannot be accidentally overridden by user files. The registration occurs in [`internal/command/slashtool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/command/slashtool.go) via the `RegisterBuiltinSlashCommands` function.

Each built-in entry supplies a short name, description, and Go handler function. Because these commands exist as native code in `internal/tool/builtin`, they execute with minimal overhead and appear consistently in the `/help` output.

```go
// In internal/command/slashtool.go – registration of the built-in /help command
RegisterBuiltinSlashCommands([]SlashCommand{
    {
        Cmd:  "help",
        Desc: "list all slash commands",
        Run: func(ctx *RunContext, args []string) error {
            return ctx.PrintHelp()
        },
    },
    // … other built-ins like /goal, /compact …
})

```

## Custom Command Loading and Registry

Custom commands reside as plain text files (typically `.slash` or `.cmd` extensions) within configurable command directories. By default, Reasonix scans `~/.reasonix/commands` and any paths listed in [`reasonix.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml).

At startup or when explicitly triggered, `ReloadCommands` (line 2396 of [`internal/control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/controller.go)) executes the following sequence:

1. Walks every directory specified in `config.Paths.CommandDirs`
2. Parses each file, extracting the command signature from the first line (`/name args…`)
3. Constructs a `SlashItem` object (defined at line 17 of [`internal/control/slash.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/slash.go)) containing the command name, description, and compiled argument completer (`SlashArgItems`)
4. Inserts the `SlashItem` into the live `slash_command` tool registry (referenced in [`internal/control/mcp.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/mcp.go) line 114)

This registry is mutable, allowing users to add, modify, or remove commands without restarting the server.

**Example custom command file** (`~/.reasonix/commands/hello.cmd`):

```

/hello name
Say hello to {{.name}}.

```

After saving the file, run `reasonix reload` to populate the registry. The command then appears in `/help` and the UI menu alongside built-ins.

## Frontend Slash Menu Implementation

The web interface exposes the command registry through the global `SLASH_CMDS` JSON array defined in [`internal/serve/index.html`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/index.html). Around line 744, the JavaScript initializes the slash menu UI (lines 1023–1050), which filters available commands as the user types `/`.

The interface displays command names and descriptions (lines 1038–1040) and handles selection via the `acceptSlash` function (line 1046), inserting the chosen command into the input box.

## Execution Flow and Dispatch Logic

The complete lifecycle of a custom slash command follows this path:

```text
User types → /mycmd arg1 arg2
      ↓
controller.Submit → detects slash prefix
      ↓
Built-in check? → No → CustomCommand()
      ↓
Registry lookup → Found → Inline as skill
      ↓
Skill execution → Result returned to UI

```

When `CustomCommand` locates a matching entry in the registry, it treats the command body as a template skill, substituting arguments (such as `{{.name}}` in the example above) with the provided values before execution.

## Key Differences Between Built-In and Custom Commands

| Aspect | Built-In | Custom |
|--------|----------|--------|
| **Location** | Go source ([`slashtool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/slashtool.go) and `internal/tool/builtin/*`) | Files in command directories (`~/.reasonix/commands` or paths from [`reasonix.toml`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/reasonix.toml)) |
| **Registration** | Static, at compile time via `RegisterBuiltinSlashCommands` | Dynamic, via `ReloadCommands` at runtime |
| **Overridable** | No—name collisions are ignored by the dispatcher | Yes—custom files can shadow built-ins only if the built-in is explicitly disabled via configuration |
| **Visibility** | Always listed in `/help` output | Listed after first reload; appears in slash menu identically to built-ins |
| **Implementation** | Native Go functions | Plain text interpreted as a skill; can invoke other skills or tools |

## Summary

- **Reasonix** processes all `/` prefixed input as slash commands through a dual-layer system in [`internal/control/controller.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/control/controller.go).
- **Built-in commands** are hard-coded in [`internal/command/slashtool.go`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/command/slashtool.go), registered at compile time, and execute as native Go functions.
- **Custom commands** are text files loaded dynamically from configurable directories into `SlashItem` objects via `ReloadCommands`.
- The **registry** is mutable, allowing runtime updates without server restarts.
- The **frontend** renders available commands from the `SLASH_CMDS` array in [`internal/serve/index.html`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/index.html), providing autocompletion and insertion.

## Frequently Asked Questions

### Can custom commands override built-in slash commands?

No, built-in commands generally take precedence and cannot be overridden by custom files of the same name. However, if a built-in is explicitly disabled via configuration (a rare scenario), a custom command with an identical name could shadow it. Normally, name collisions result in the built-in executing while the custom file is ignored.

### What file extensions does Reasonix recognize for custom commands?

Reasonix typically recognizes `.slash` and `.cmd` extensions when scanning command directories. The parser examines the first line of each file to extract the command signature (`/name args…`) and uses the remainder of the file as the command body or template.

### How do I reload custom commands without restarting the server?

Execute `reasonix reload` or trigger the `ReloadCommands` function programmatically. This re-scans all configured command directories, reconstructs the `SlashItem` registry, and updates the live `slash_command` tool without requiring a server restart. The frontend will immediately reflect changes in the slash menu.

### Where is the slash menu UI defined in the source code?

The slash menu UI is implemented in [`internal/serve/index.html`](https://github.com/esengine/DeepSeek-Reasonix/blob/main/internal/serve/index.html), specifically around lines 744 and 1023–1050. The JavaScript loads the `SLASH_CMDS` array to populate the menu, filters entries based on user input, and handles selection through the `acceptSlash` function at line 1046.