# How the Omarchy CLI Router Maps Commands to Bin Binaries: A Deep Dive into Dynamic Routing

> Discover how the Omarchy CLI router maps commands to bin binaries by parsing executable metadata and building a dynamic routing table for efficient command dispatch. Learn the two-stage resolution process.

- Repository: [Omacom/omarchy](https://github.com/omacom/omarchy)
- Tags: deep-dive
- Published: 2026-09-06

---

**The Omarchy CLI router (`bin/omarchy`) discovers all `omarchy-*` executables, parses metadata from their headers to build a routing table, and dispatches user commands to the appropriate binary through a two-stage resolution process.**

The Omarchy project implements a **self-organizing command-line interface** that requires no manual registration of commands. Instead, the router dynamically discovers available functionality by scanning the `bin/` directory and extracting structured metadata from each executable's header comments. This architecture allows developers to add new commands simply by creating properly named binaries with descriptive headers.

## Command Discovery and Binary Registration

The routing process begins when `load_commands` scans for all files matching `bin/omarchy-*` and passes each to `register_command` for processing:

```bash

# From bin/omarchy, lines 15-22

load_commands() {
    for binary in "$BIN_DIR"/omarchy-*; do
        [ -x "$binary" ] && register_command "$binary"
    done
}

```

Each binary undergoes **metadata extraction** during registration. The router reads approximately the first 80 comment lines, searching for directives formatted as `# omarchy:<key>=<value>`:

| Metadata Key | Purpose |
|------------|---------|
| `group` | Logical category (e.g., `theme`, `config`) |
| `name` | Sub-command identifier within the group |
| `summary` | Brief description for help output |
| `aliases` | Alternative command strings (`|`-delimited) |

This parsing occurs between **lines 90-104** in `bin/omarchy`.

For binaries lacking explicit metadata, the router applies **fallback derivation** from the filename pattern `omarchy-<group>-<name>` (lines 54-63). A binary named `omarchy-theme-list` automatically receives group `theme` and name `list` if no `# omarchy:group` or `# omarchy:name` directives are present.

## Building the Core Routing Table

After metadata extraction, `register_command` populates several associative arrays that collectively form the routing infrastructure (lines 69-100):

- **`COMMAND_BINARY`** — the executable filename (`omarchy-foo`)
- **`COMMAND_GROUP`** — the logical grouping
- **`COMMAND_NAME`** — the sub-command identifier
- **`COMMAND_ROUTE`** — the full textual route (`omarchy theme list`)
- **`COMMAND_ALIASES`** — alternative routes from metadata
- **`ROUTE_TO_KEY`** — the primary lookup table mapping routes to internal keys

The `register_route` function (lines 51-63) adds entries to `ROUTE_TO_KEY` and detects route collisions where multiple binaries would claim the same command string. Alias handling (lines 102-111) splits `alias=` values on `|` and registers each variant with a flag marking it as non-canonical.

## Two-Stage Route Resolution

When a user invokes `omarchy <tokens...>`, resolution proceeds through distinct phases designed for efficiency and flexibility.

### Stage 1: Direct Binary Matching

The router first attempts `resolve_direct_route` (lines 89-108), checking if the initial token(s) correspond to an actual executable. For `omarchy theme`, it verifies whether `bin/omarchy-theme` exists and is executable. Direct matches bypass the routing table entirely, with remaining arguments passed unchanged.

### Stage 2: Routing Table Lookup

If no direct binary matches, `resolve_route` (lines 119-129) progressively shortens the token list to find the longest registered route:

```bash

# Conceptual flow from bin/omarchy

for ((i=${#tokens[@]}; i>0; i--)); do
    candidate="${tokens[*]:0:i}"
    if [[ -n "${ROUTE_TO_KEY[$candidate]}" ]]; then
        RESOLVED_KEY="${ROUTE_TO_KEY[$candidate]}"
        RESOLVED_COUNT=$i
        RESOLVED_ROUTE="$candidate"
        break
    fi
done

```

Upon successful resolution, the router retrieves the binary path from `COMMAND_BINARY` and prepares for dispatch (lines 130-138).

## Command Execution and Help Integration

The `dispatch_fast_or_help` function (lines 55-95) handles the final execution phase:

```bash
exec "$binary_path" "${remaining[@]}"

```

This `exec` replaces the router process entirely, eliminating overhead and ensuring signal handling and exit codes propagate correctly to the user.

Help requests (`--help`, `-h`, `-?`) trigger `show_command_help` or `show_command_json` instead of execution. These functions generate documentation from the stored metadata arrays, producing consistent help output without requiring manual maintenance of separate documentation files.

## Group-Based Navigation

When the first token matches a group with its own binary (e.g., `omarchy-theme`), the router enters **group mode**:

1. `load_group_commands` (lines 74-86) discovers all `omarchy-theme-*` binaries
2. `show_group_help` (lines 108-122) displays available sub-commands

This enables the nested command pattern `omarchy theme list`, where:
- `theme` identifies the group binary `omarchy-theme`
- `list` resolves to the specific implementation `omarchy-theme-list`

## Complete Binary-to-Command Mapping Flow

1. **Discovery** — `load_commands` finds all `omarchy-*` executables
2. **Metadata parsing** — `register_command` extracts `# omarchy:*` directives

3. **Fallback generation** — filename components provide default group/name
4. **Route registration** — `register_route` populates `ROUTE_TO_KEY`
5. **Alias expansion** — alternative routes are linked to primary keys
6. **Runtime resolution** — direct match first, then routing table traversal
7. **Dispatch** — `exec` to binary with remaining arguments

## Summary

- The **Omarchy CLI router** eliminates hard-coded command mappings through dynamic binary discovery
- **Metadata extraction** from header comments enables self-documenting commands without external configuration
- **Two-stage resolution** prioritizes direct binary matches for performance, then falls back to the routing table for complex command sequences
- **Associative arrays** (`ROUTE_TO_KEY`, `COMMAND_BINARY`, etc.) provide O(1) lookup for rapid dispatch
- Group-based organization supports intuitive nested command structures like `omarchy <group> <action>`

## Frequently Asked Questions

### How does omarchy handle command name conflicts?

The router detects collisions during `register_route` (lines 51-63) when multiple binaries would map to identical command strings. This early detection prevents ambiguous routing and surfaces configuration errors during startup rather than at invocation time.

### Can I create aliases for omarchy commands without modifying the router?

Yes. Add `# omarchy:alias=alternative|names` to any command binary's header comments. The router parses these during registration and adds each pipe-delimited alias to `ROUTE_TO_KEY` with the `ROUTE_IS_ALIAS` flag (lines 102-111).

### What happens if I run `omarchy theme` without a sub-command?

If `bin/omarchy-theme` exists as an executable binary, it receives zero arguments and executes directly. If only `omarchy-theme-*` binaries exist, the router treats `theme` as a group, loads all related commands via `load_group_commands`, and displays group help through `show_group_help`.

### Where is the routing table stored between invocations?

No persistent storage exists. The Omarchy CLI rebuilds its entire routing infrastructure on every invocation by re-scanning `bin/omarchy-*` and re-parsing metadata. This design ensures immediate availability of new commands without restart requirements, trading minimal startup overhead for maximum flexibility.