# How to Create a Custom Omarchy CLI Command

> Learn to create a custom Omarchy CLI command by adding an executable script to bin/ with embedded metadata for automatic help generation. Simplify your workflow today.

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

---

**Create a custom Omarchy CLI command by adding an executable script named `omarchy-<group>-<verb>` to the `bin/` directory with embedded metadata comments for help generation.**

The Omarchy project provides a lightweight, extensible command-line interface built around a central **router script** located at `bin/omarchy`. This router discovers available commands dynamically from the `bin/` directory, making it straightforward to add new functionality without modifying core infrastructure. Understanding this architecture lets you extend Omarchy's CLI with custom commands that integrate seamlessly with the built-in help system and testing framework.

## Understanding the Omarchy CLI Router Architecture

The Omarchy CLI follows a **convention-based discovery pattern**. The main router script in `bin/omarchy` (source: [omacom/omarchy/blob/quattro/bin/omarchy](https://github.com/omacom/omarchy/blob/quattro/bin/omarchy)) handles all command routing through three key mechanisms:

1. **Group-based organization** — commands are categorized by functional area (e.g., `toggle`, `theme`, `install`)
2. **Metadata-driven help** — scripts embed self-documenting comments parsed by the router
3. **Dynamic discovery** — the router scans `bin/` for matching filenames at runtime

### The GROUP_DESCRIPTIONS Array

Near the top of `bin/omarchy` (approximately lines 27-95), the `GROUP_DESCRIPTIONS` associative array defines available command groups. Each entry maps a group slug to a human-readable description displayed in help output. Before creating a custom command, verify whether your target group exists in this array or requires registration.

## Naming Convention for Custom Commands

Omarchy enforces a strict **filename convention** for discoverability:

```

omarchy-<group>-<verb>

```

- **`<group>`** — the functional category (must match a key in `GROUP_DESCRIPTIONS`)
- **`<verb>`** — the specific action (kebab-case preferred)

For example: `omarchy-theme-switch`, `omarchy-toggle-sound`, `omarchy-example-greet`.

## Step-by-Step: Creating a Custom Omarchy CLI Command

### Step 1: Choose or Create a Command Group

Check `bin/omarchy`'s `GROUP_DESCRIPTIONS` declaration to determine your group:

- **Existing group**: Use the established slug directly
- **New group**: Edit `bin/omarchy` to add your group to `GROUP_DESCRIPTIONS` before proceeding

```bash

# Example excerpt from bin/omarchy showing GROUP_DESCRIPTIONS structure

declare -A GROUP_DESCRIPTIONS=(
    [toggle]="Toggle system settings, features, or states"
    [theme]="Manage visual themes and appearance"
    [install]="Install packages, tools, or configurations"
    # Add your custom group here if needed

    [example]="Example custom commands for demonstration"
)

```

### Step 2: Create the Executable Script

Place your new file in `bin/` with the naming convention `omarchy-<group>-<verb>`. The file **must be executable** and include **metadata comments** in the header.

```bash
cat > bin/omarchy-example-greet <<'EOF'
#!/usr/bin/env bash

# omarchy:summary=Print a friendly greeting

# omarchy:usage=omarchy example greet [NAME]

# omarchy:description=Outputs "Hello, <NAME>!" or "Hello, world!" when no name is given.

name="${1:-world}"
printf 'Hello, %s!\n' "$name"
EOF

chmod +x bin/omarchy-example-greet

```

The router parses these metadata comments (implementation around lines 150-170 of `bin/omarchy`) to generate help output dynamically.

### Step 3: Verify Command Discovery

Test that the router recognizes your new command:

```bash

# List all available groups

omarchy help

# View help for your specific group

omarchy example help

# Execute your custom command

omarchy example greet

# Output: Hello, world!

omarchy example greet Alice

# Output: Hello, Alice!

```

### Step 4: Add Tests (Recommended)

Omarchy includes a shell-based test harness in `test/shell.d/`. Create a corresponding test file:

```bash
cat > test/shell.d/example-greet-test.sh <<'EOF'
#!/usr/bin/env bash
source "$(dirname "$0")/base-test.sh"

test_default_greeting() {
    result="$(bin/omarchy-example-greet)"
    assert_equals "Hello, world!" "$result"
}

test_named_greeting() {
    result="$(bin/omarchy-example-greet Alice)"
    assert_equals "Hello, Alice!" "$result"
}

run_tests "$@"
EOF

chmod +x test/shell.d/example-greet-test.sh

```

Run the full test suite with `./test/shell` to verify integration.

## Required Metadata Comment Format

The router extracts three specific comment prefixes from each command script:

| Prefix | Purpose | Example |
|--------|---------|---------|
| `# omarchy:summary=` | Brief one-line description | `Print a friendly greeting` |

| `# omarchy:usage=` | Command syntax | `omarchy example greet [NAME]` |

| `# omarchy:description=` | Extended explanation | `Outputs "Hello, <NAME>!"...` |

Omitting these comments will not break execution, but your command will appear undocumented in help output.

## Advanced: Commands with Subcommands

For complex functionality requiring nested verbs, implement argument parsing within your script:

```bash
#!/usr/bin/env bash

# omarchy:summary=Manage example resources

# omarchy:usage=omarchy example resource <create|delete|list> [OPTIONS]

# omarchy:description=Create, remove, or list example resources with optional filtering.

verb="${1:-help}"
shift || true

case "$verb" in
    create)
        name="${1:?Name required}"
        printf 'Creating resource: %s\n' "$name"
        ;;
    delete)
        name="${1:?Name required}"
        printf 'Deleting resource: %s\n' "$name"
        ;;
    list)
        printf 'Listing all resources...\n'
        ;;
    help|*)
        printf 'Usage: omarchy example resource <create|delete|list>\n'
        exit 1
        ;;
esac

```

Name this `bin/omarchy-example-resource` to expose `omarchy example resource <subcommand>`.

## Key Files and Locations

- **`bin/omarchy`** — Central router script with `GROUP_DESCRIPTIONS` array and metadata parser ([source](https://github.com/omacom/omarchy/blob/quattro/bin/omarchy))
- **`bin/omarchy-<group>-<verb>`** — Your custom command implementations
- **[`docs/cli-router.md`](https://github.com/omacom/omarchy/blob/main/docs/cli-router.md)** — CLI architecture documentation
- **`test/shell.d/`** — Shell test harness for command validation

## Troubleshooting Custom Commands

| Symptom | Cause | Resolution |
|---------|-------|------------|
| `Command not found` | File not executable | Run `chmod +x bin/omarchy-<group>-<verb>` |
| Missing from help | Group not in `GROUP_DESCRIPTIONS` | Add entry to `bin/omarchy` |
| Metadata not displayed | Malformed comment prefix | Verify exact format: `# omarchy:summary=` |

| Parse errors | Shell syntax issues | Test script directly: `./bin/omarchy-<group>-<verb>` |

## Summary

- **Filename convention**: Use `omarchy-<group>-<verb>` in the `bin/` directory
- **Metadata headers**: Include `omarchy:summary`, `omarchy:usage`, and `omarchy:description` comments
- **Group registration**: Ensure `<group>` exists in `GROUP_DESCRIPTIONS` within `bin/omarchy`
- **Test coverage**: Add shell tests in `test/shell.d/` for reliability
- **No router modifications**: Standard commands require zero changes to core infrastructure

## Frequently Asked Questions

### Can I write custom Omarchy commands in languages other than Bash?

Yes. The router executes files matching the naming convention directly. Use any shebang line your system supports: `#!/usr/bin/env python3`, `#!/usr/bin/env ruby`, etc. The metadata comments must remain valid shell comments (starting with `#`) for the parser to extract them.

### How do I override or replace an existing Omarchy command?

Simply create a script with the identical `omarchy-<group>-<verb>` name in `bin/`. The router discovers commands by filesystem scan; your version takes precedence if it appears first in `PATH` resolution or if you modify the discovery order. For permanent overrides, rename or remove the original upstream script.

### Why does my custom command appear in help with no description?

The metadata parser in `bin/omarchy` (lines 150-170) requires exact comment formatting. Verify your script includes `# omarchy:summary=` with no spaces between `#` and `omarchy`, and that the comment appears before any executable code. Blank lines between shebang and metadata are permitted.