How to Add Commands to the Omarchy CLI: Metadata, Routing, and Registration
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
trueif the command needs elevated privileges - hidden – Set to
trueto exclude from default command listings
# 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:
-
Create a new executable script under
bin/namedomarchy-<group>-<name>(oromarchy-<group>for group-only commands) -
Add the required metadata block at the top of the file using
# omarchy:prefixes -
Make the file executable with
chmod +x -
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:
#!/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:
#!/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:
#!/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/omarchyautomatically discovers commands by scanning foromarchy-*executables. -
Commands define routing and documentation through
# omarchy:metadata comments parsed byregister_command(). -
The canonical route format follows
omarchy <group> <name>, with optional aliases registered viaregister_route(). -
Resolution occurs through
resolve_route()(lines 119-130), which maps user input to binaries using theROUTE_TO_KEYarray. -
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.
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 →