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:
- Group-based organization — commands are categorized by functional area (e.g.,
toggle,theme,install) - Metadata-driven help — scripts embed self-documenting comments parsed by the router
- 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 inGROUP_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/omarchyto add your group toGROUP_DESCRIPTIONSbefore 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!
Step 4: Add Tests (Recommended)
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 withGROUP_DESCRIPTIONSarray and metadata parser (source)bin/omarchy-<group>-<verb>— Your custom command implementationsdocs/cli-router.md— CLI architecture documentationtest/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 thebin/directory - Metadata headers: Include
omarchy:summary,omarchy:usage, andomarchy:descriptioncomments - Group registration: Ensure
<group>exists inGROUP_DESCRIPTIONSwithinbin/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →