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

> Learn to add commands to the Omarchy CLI. Discover how to embed metadata, configure routing, and register new commands effortlessly for your Go applications.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: how-to-guide
- Published: 2026-09-10

---

**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

```bash

# 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`:

```bash
#!/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`:

```bash
#!/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`:

```bash
#!/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.