How to Create a Custom Omarchy CLI Command

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

# 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.

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:


# 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!

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

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:

#!/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)
  • bin/omarchy-<group>-<verb> — Your custom command implementations
  • 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.

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 →