How Omarchy CLI Command Discovery Works: A Deep Dive into the Self-Discovering Router

Omarchy automatically discovers CLI commands by scanning the bin/ directory for files matching the omarchy-<group>-<verb> pattern, extracting metadata from # omarchy: comment blocks, and routing execution through a longest-prefix matching algorithm.

The Omarchy framework (basecamp/omarchy) implements a self-discovering command-line interface that requires no manual registration or configuration files. By leveraging filesystem conventions and structured code comments, the CLI router dynamically builds its command tree at runtime, allowing new commands to appear immediately simply by dropping executable scripts into the bin/ directory.

Router Entry Point and Architecture

The command discovery process begins at bin/omarchy, the single entry point for all CLI operations. This router script functions as a dispatch hub that inspects the filesystem to construct the available command catalog rather than relying on hard-coded command lists.

According to the Omarchy source code, the router operates through a specific discovery sequence:

  1. Scan the bin/ directory for executable files matching the omarchy-* prefix
  2. Parse group metadata from the GROUP_DESCRIPTIONS associative array
  3. Extract per-command metadata from specially formatted comment blocks
  4. Match user input against available commands using longest-prefix resolution

Command Discovery Mechanism

File Naming Conventions

Every user-facing command resides in the bin/ directory and follows the strict naming convention omarchy-<group>-<verb>. For example, bin/omarchy-theme-install or bin/omarchy-toggle-nightlight.

The router discovers these automatically by globbing for files beginning with omarchy-. This design eliminates the need for a centralized registry; the filesystem itself serves as the command database.

Group Registration via GROUP_DESCRIPTIONS

Inside bin/omarchy, the script defines a GROUP_DESCRIPTIONS associative array that maps command groups to human-readable descriptions:

declare -A GROUP_DESCRIPTIONS=(
  ["audio"]="Audio management commands"
  ["theme"]="Theme and appearance controls"
  ["toggle"]="Feature toggles and switches"
  ["hw"]="Hardware-specific utilities"
)

This array serves as the authoritative source for which command groups exist. When users run omarchy list-groups or request top-level help, the router iterates over this mapping to display available categories.

Metadata Parsing System

Comment-Based Annotations

Each command file contains structured metadata in the form of comment lines beginning with # omarchy:. The router parses these comments to build help text and determine command behavior without executing the script.

Common metadata tags include:

  • # omarchy:summary=<description> — Short description for help output

  • # omarchy:args=<argument-spec> — Argument specification documentation

  • # omarchy:hidden=true — Excludes the command from default listings

#!/bin/bash

# omarchy:summary=Install a theme from the repository

# omarchy:args=<theme-name>

# omarchy:group=theme

# Command implementation follows...

Alias Resolution

The metadata system supports command aliases defined within the same comment block. This allows shorter commands to resolve to longer file paths. For instance, bin/omarchy-screenshot might contain:


# omarchy:alias=screenshot

# omarchy:alias=sc

When a user types omarchy screenshot, the router recognizes this alias and dispatches to the appropriate underlying command script.

Command Resolution Strategy

Longest-Prefix Matching

When a user executes omarchy theme install dark, the router employs a longest-prefix resolution algorithm:

  1. Attempt to match the full argument list (theme install dark) against existing command files
  2. If no exact match exists, fall back to shorter prefixes (theme install)
  3. Continue iterating backward through the argument list until reaching a valid group name (theme)
  4. If only a group matches, display all commands within that group

This approach enables intuitive subcommand hierarchies. For example, omarchy hw asus might resolve to bin/omarchy-hw-asus, or fall back to listing all hardware-related commands if the specific verb is omitted.

Subcommand Listing Fallback

If resolution fails for a given prefix, the router automatically lists possible sub-commands for that prefix. Running omarchy hw without a specific verb displays all available hardware commands:

$ omarchy hw
Available hardware commands:
  omarchy hw asus       - ASUS-specific utilities
  omarchy hw info       - Display hardware information
  omarchy hw monitor    - External display controls

Execution Dispatch

Once the router identifies the proper command file, it uses exec to replace the current process with the target binary, passing only the remaining arguments:


# Inside bin/omarchy router

exec "${OMARCHY_ROOT}/bin/${command_file}" "${remaining_args[@]}"

This dispatch method means the executed command receives a clean argument list and its own process context. The command script handles argument parsing independently, while the router focuses solely on discovery and routing.

JSON Introspection for Tooling

For programmatic access and debugging, the router supports omarchy --json, which outputs the complete routing table as structured JSON. This includes discovered commands, their metadata, aliases, and group associations:

$ omarchy --json
{
  "groups": {
    "theme": "Theme and appearance controls",
    "toggle": "Feature toggles and switches"
  },
  "commands": [
    {
      "name": "theme-install",
      "group": "theme",
      "summary": "Install a theme from the repository",
      "hidden": false
    }
  ]
}

This introspection capability enables shell completion scripts and IDE integrations to query the available command set dynamically.

Summary

  • Self-discovering architecture: Commands appear automatically by placing files matching omarchy-<group>-<verb> in the bin/ directory

  • Group management: The GROUP_DESCRIPTIONS array in bin/omarchy defines available command categories and their descriptions

  • Metadata-driven: # omarchy: comment blocks provide help text, argument specifications, and visibility flags without requiring a separate documentation system

  • Flexible routing: Longest-prefix matching resolves commands with multiple arguments, falling back gracefully to subcommand listings

  • Process isolation: Commands execute via exec replacement, ensuring clean argument passing and independent exit codes

  • Machine-readable: The --json flag exposes the full routing table for tooling and automation

Frequently Asked Questions

How do I add a new command to the Omarchy CLI?

Create an executable file in the bin/ directory following the naming convention omarchy-<group>-<verb>. Add metadata comments starting with # omarchy: to define the summary and arguments. The command will automatically appear in help listings and routing tables without modifying the router script.

What happens if two commands have similar prefixes?

The router uses longest-prefix matching to disambiguate commands. If you have both omarchy-theme-install and omarchy-theme-install-local, running omarchy theme install local resolves to the longer match, while omarchy theme install resolves to the shorter one. If the prefix is ambiguous, the router displays available options for that prefix.

How does Omarchy handle command aliases?

Aliases are defined within the metadata comments of command files using # omarchy:alias=<shortcut>. Multiple aliases can be defined per command. The router maintains an alias lookup table during the discovery phase, allowing short commands like omarchy screenshot to resolve to longer underlying script names.

Can I programmatically list all available commands without parsing help text?

Yes. Running omarchy --json outputs the complete routing discovery data as JSON, including all groups, commands, summaries, and aliases. This is the recommended approach for building shell completions, GUIs, or documentation generators that need to consume the command catalog programmatically.

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 →