How to Add Commands to the Omarchy CLI: Metadata, Routing, and Registration

Adding commands to the Omarchy CLI requires creating an executable script in bin/ prefixed with omarchy-, embedding metadata comments starting with # omarchy:, and ensuring the file follows the group-name naming convention; the driver automatically discovers, registers, and routes commands without manual registry updates.

The Omarchy CLI framework uses a self-discovering command architecture centered in bin/omarchy that eliminates the need for manual command registration. By embedding structured metadata directly into bash scripts and following specific naming conventions, developers can extend the CLI with automatic help generation, routing, and alias support.

Understanding the Omarchy Command Architecture

Omarchy’s command system operates through a single Bash driver located at bin/omarchy. This driver dynamically discovers every sub-command by scanning for executable binaries matching the pattern omarchy-* in the bin/ directory.

The system builds routing tables automatically by parsing metadata embedded as comments at the top of each script. Key functions in the driver handle this process: load_commands() (lines 15-22) iterates over matching files, while load_child_commands_by_binary() (lines 33-40) handles nested command structures like omarchy-theme-set.

Metadata Format for Omarchy Commands

Every command script must include a metadata block using comment lines that start with # omarchy: followed by key/value pairs. The driver parses these in register_command() (starting at line 69) and stores them in associative arrays including COMMAND_GROUP, COMMAND_SUMMARY, and COMMAND_ARGS.

Required Metadata Keys

  • group – Determines the command group (e.g., theme, update)
  • name – The human-readable command name shown after the group
  • summary – A short description used by omarchy commands

Optional Metadata Keys

  • args – Argument specification shown in help text (e.g., <name>)
  • examples – Usage examples separated by pipes
  • aliases – Alternative routes separated by pipes (e.g., theme apply|theme use)
  • requires-sudo – Set to true if the command needs elevated privileges
  • hidden – Set to true to exclude from default command listings

# omarchy:group=theme

# omarchy:name=set

# omarchy:summary=Apply a theme

# omarchy:args=<name>

# omarchy:examples=omarchy theme set solarium | omarchy theme set dark

# omarchy:aliases=theme apply|theme use

Routing and Registration Mechanisms

Command Discovery

The load_commands() function scans for all executable files matching omarchy-* and calls register_command() for each. Child commands following the pattern omarchy-<group>-<name> are discovered via load_child_commands_by_binary() (lines 33-40).

Route Registration

Inside register_command() (lines 69-73), the driver constructs a canonical route from the group and name: omarchy <group> <name>. If the name is omitted, the fallback route derives directly from the binary filename. Aliases are registered separately via register_route() (lines 102-110) and tracked in the ROUTE_IS_ALIAS array.

Route Resolution and Dispatch

When users execute omarchy <tokens>, the resolve_route() function (lines 119-130) looks up the longest matching route in the ROUTE_TO_KEY array. Upon resolution, the driver passes remaining tokens to the target binary via exec. For help requests (--help or --json), the driver invokes show_command_help() or show_command_json() using the stored metadata.

Creating a New Omarchy Command

To add a command to the Omarchy CLI:

  1. Create a new executable script under bin/ named omarchy-<group>-<name> (or omarchy-<group> for group-only commands)

  2. Add the required metadata block at the top of the file using # omarchy: prefixes

  3. Make the file executable with chmod +x

  4. Implement the command logic below the metadata block

The driver picks up the command automatically on the next invocation; no additional registration steps are required.

Practical Code Examples

Minimal Command Example

Create bin/omarchy-example-hello:

#!/usr/bin/env bash

# omarchy:group=example

# omarchy:name=hello

# omarchy:summary=Print a friendly greeting

# omarchy:examples=omarchy example hello

echo "Hello from Omarchy!"

Command with Arguments and Aliases

Create bin/omarchy-weather-search:

#!/usr/bin/env bash

# omarchy:group=weather

# omarchy:name=search

# omarchy:summary=Search weather for a city

# omarchy:args=<city>

# omarchy:examples=omarchy weather search London

# omarchy:aliases=weather fetch|weather query

city="${1:-}"
if [[ -z $city ]]; then
  echo "Usage: $(basename "$0") <city>"
  exit 1
fi

echo "Fetching weather for $city …"

Hidden Sudo Command

Create bin/omarchy-system-reboot:

#!/usr/bin/env bash

# omarchy:group=system

# omarchy:name=reboot

# omarchy:summary=Reboot the machine (requires sudo)

# omarchy:requires-sudo=true

# omarchy:hidden=true

exec sudo systemctl reboot

Summary

  • The Omarchy CLI driver at bin/omarchy automatically discovers commands by scanning for omarchy-* executables.

  • Commands define routing and documentation through # omarchy: metadata comments parsed by register_command().

  • The canonical route format follows omarchy <group> <name>, with optional aliases registered via register_route().

  • Resolution occurs through resolve_route() (lines 119-130), which maps user input to binaries using the ROUTE_TO_KEY array.

  • No manual registry updates are needed; simply drop an executable script with proper metadata into the bin/ directory.

Frequently Asked Questions

What file naming convention should I use for Omarchy CLI commands?

Name your executable files using the prefix omarchy- followed by the group and optionally the command name. For group-only commands, use omarchy-<group>. For sub-commands, use omarchy-<group>-<name> (e.g., omarchy-theme-set). The driver uses these filenames to locate binaries in the bin/ directory during the discovery phase initiated by load_commands().

How does the Omarchy driver handle command aliases?

Aliases are defined in the metadata using the aliases key with pipe-separated values (e.g., # omarchy:aliases=theme apply|theme use). The driver registers these via register_route() (lines 102-110) and marks them in the ROUTE_IS_ALIAS array. When resolve_route() processes user input, it maps alias routes to their canonical command keys, allowing multiple invocation patterns for the same binary.

Can I hide commands from the default help output?

Yes, add # omarchy:hidden=true to the metadata block. Commands marked as hidden are excluded from the standard omarchy commands listing and help generation, though they remain executable if called directly. This is useful for administrative or internal commands like system maintenance scripts that require requires-sudo=true.

Where is the command routing logic implemented in the source code?

The routing logic resides primarily in bin/omarchy. The resolve_route() function (lines 119-130) handles the lookup mechanism by searching for the longest matching route in the ROUTE_TO_KEY associative array. Registration logic appears in register_command() (line 69), which builds the routing tables from parsed metadata, and register_route() (line 102), which handles alias mappings.

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 →