How Custom Slash Commands Work in Reasonix Sessions: A Complete Technical Guide

Custom slash commands in Reasonix are Markdown-defined instructions stored in .reasonix/commands/ that get parsed at startup, registered in a local registry, and executed by the model when triggered via the UI autocomplete menu.

The DeepSeek-Reasonix repository implements a sophisticated local command system that allows users to define reusable prompt templates using simple Markdown files. Understanding how these custom slash commands operate requires examining the discovery mechanisms in internal/config/paths.go, the parsing logic in internal/command/command.go, and the execution flow through internal/control/input.go.

Command Discovery and Loading

Reasonix initializes its command ecosystem by scanning specific filesystem locations for Markdown definitions.

Directory Structure and Scanning

At startup, the engine queries internal/config/paths.go (line 550) to determine the command directories. The system primarily searches the .reasonix/commands/ folder within the project root, while maintaining backward compatibility with the legacy .claude/commands/ location.

The discovery process recursively identifies all *.md files in these directories. Each file represents an isolated command definition that the system will parse into a structured format.

The Command Parser Implementation

The loading logic resides in internal/command/command.go. The LoadCommand function reads each Markdown file and splits it into two components: an optional YAML front-matter block and the body text.

// From internal/command/command.go
func LoadCommand(path string) (Command, error) {
    data, err := os.ReadFile(path)
    if err != nil { return Command{}, err }
    // Split front‑matter (YAML) from body, parse into struct
    // → Command{Name: "greet", Title: "Greet a teammate", …, Body: "Hi @{{.arg}}! 🎉"}
}

The front-matter supports four key fields:

  • title — Human-readable name displayed in the slash menu
  • desc — Short description for the autocomplete dropdown
  • danger — Boolean flag that renders a warning pill in the UI
  • args — Schema defining expected arguments for validation

Command Registration and Namespacing

Once parsed, commands enter a runtime registry that manages availability and prevents conflicts.

Built-in vs Custom Commands

All discovered commands populate the SLASH_CMDS registry, which serves as the single source of truth for both the TUI/desktop interface and the AI model. The registry is exposed to the model via the slash_command tool, as implemented in internal/serve/serve.go (line 697).

Built-in commands like /help and /quit occupy reserved namespaces that take precedence over custom definitions.

Collision Handling and Qualified Names

When plugins or custom definitions risk name collisions, Reasonix applies automatic qualification logic. According to internal/pluginpkg/pluginpkg.go (line 86), plugin-contributed commands receive a prefixed identifier in the format plugin:command.

If a custom command conflicts with a built-in name, the system automatically rewrites it to a qualified form (/reasonix:<name>) and displays this variant in the menu, as documented in site/src/pages/docs.astro (lines 280-313).

User Interface Integration

The frontend components bridge the registry with user interaction through autocomplete functionality.

Autocomplete and Menu Rendering

When a user types / in the composer, the UI filters SLASH_CMDS against the current input. The rendering logic in desktop/frontend/src/components/Composer.tsx (line 1231) displays a dropdown containing:

  • Command name and description
  • Danger indicators (when the danger flag is set)
  • Argument hints based on the args schema

Navigation handling occurs in desktop/frontend/src/App.tsx (line 2305), managing keyboard selection and insertion.

Input Handling and Execution Flow

Command execution follows a strict resolution path in internal/control/input.go (line 579). The CustomCommand function normalizes input (case-insensitive, slash-normalized) and matches it against the registry:

// From internal/control/input.go
func CustomCommand(input string) (Command, bool) {
    name, args := splitSlash(input) // “greet”, “alice”
    cmd, ok := commandRegistry.Lookup(name) // case‑insensitive, slash‑normalized
    if ok { cmd.Body = applyArgs(cmd.Body, args) }
    return cmd, ok
}

When matched, the command body (with interpolated arguments) inserts into the conversation as a standard user turn. The model processes this locally without external service calls, ensuring zero-latency execution.

Creating Custom Slash Commands

Developers define commands using Markdown with YAML front-matter. Store files in .reasonix/commands/<name>.md:

---
title: Greet a teammate
desc: Sends a friendly greeting to @username
danger: false
---
Hi @{{.arg}}! 🎉

Invocation in a Reasonix session:

/greet alice

The UI surfaces this in the autocomplete menu with the description "Sends a friendly greeting to @username". Upon execution, Reasonix injects the resolved body:

Hi @alice! 🎉

The model then processes this content as a standard conversation turn.

Summary

Frequently Asked Questions

Where should I place custom slash command files?

Place Markdown files defining your commands in the .reasonix/commands/ directory at your project root. Reasonix also maintains backward compatibility with the legacy .claude/commands/ location. The system discovers these automatically at session startup by querying the path resolution logic in internal/config/paths.go.

Can custom commands override built-in commands like /help?

No. Built-in commands occupy reserved namespaces and take precedence over custom definitions. If you create a custom command with a conflicting name, Reasonix automatically rewrites it to a qualified form (such as /reasonix:<name>) to prevent collisions, as implemented in the namespacing logic of internal/pluginpkg/pluginpkg.go.

How are arguments passed to custom slash commands?

Arguments pass through the splitSlash function in internal/control/input.go, which separates the command name from trailing text. The system applies these arguments to the command body template using applyArgs before insertion. You can define expected arguments in the front-matter args field to enable autocomplete hints in the UI.

Do slash commands execute code locally or remotely?

Custom slash commands execute entirely locally. When triggered, Reasonix inserts the command body (with interpolated arguments) directly into the conversation as a user turn. The local model processes this content immediately without external API calls, providing zero-latency execution as noted in the internal/control/input.go implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →