How to Define a New Omarchy CLI Command: Step-by-Step Guide
To define a new Omarchy CLI command, create an executable Bash script in the bin/ directory following the omarchy-<group>-<verb> naming convention, optionally register the group in the GROUP_DESCRIPTIONS associative array inside bin/omarchy, and validate your changes using the shell test harness in test/shell.d/.
Omarchy is an open-source CLI framework that centralizes command routing through a single dispatcher. When you define a new Omarchy CLI command, you work within a convention-based architecture where the bin/omarchy script parses arguments, resolves group metadata, and delegates execution to sub-command scripts that follow predictable naming patterns.
Understanding the Omarchy CLI Architecture
The Omarchy CLI operates through a dispatcher pattern centered on the bin/omarchy entry point. When a user executes omarchy <group> <verb>, the dispatcher performs a lookup to find the corresponding executable script. The system supports two naming patterns: omarchy-<verb> for top-level commands and omarchy-<group>-<verb> for namespaced commands.
Group organization relies on the GROUP_DESCRIPTIONS associative array defined near the top of bin/omarchy. This array maps group names to human-readable descriptions that appear in help output and menu interfaces. For commands requiring conditional availability, the GUARD_READERS associative array enables automatic UI enablement based on predicate checks.
Step-by-Step Guide to Define a New Omarchy CLI Command
Step 1: Create the Command Script
Place a new executable file in the bin/ directory using the appropriate naming convention. For a command belonging to the deploy group with the verb push, name the file bin/omarchy-deploy-push. For top-level commands, use bin/omarchy-<verb>.
Every command script must begin with the standard Omarchy Bash header:
#!/usr/bin/env bash
set -euo pipefail
Use the provided helper functions for consistent output formatting. The omarchy-log function writes informational messages, while omarchy-error handles fatal errors with appropriate exit codes. Ensure your script exits with status 0 for success and non-zero for failures, as downstream automation depends on these return codes.
Step 2: Register the Group Metadata
If your command introduces a new group, open bin/omarchy and locate the GROUP_DESCRIPTIONS associative array definition. Add your group with a concise description:
GROUP_DESCRIPTIONS[deploy]="Deployment and release utilities"
This registration ensures the group appears in help menus and command listings. The dispatcher references this array when generating usage information or building interactive command palettes.
Step 3: Configure Predicate Guards (Optional)
For commands that should appear conditionally in menus, update the GUARD_READERS associative array in bin/omarchy. This array maps command patterns to predicates that determine availability. When the guard returns true, UI components render the command as enabled; when false, the command appears disabled or hidden.
Step 4: Document the Command
Update docs/cli-router.md to describe your command's routing logic and parameters. For detailed usage instructions, create or modify manual pages under the manual/ directory. Consult agents/skills/command-metadata.md for guidelines on formatting command descriptions, argument specifications, and example usage blocks.
Step 5: Implement Shell Tests
Create a test file in test/shell.d/ that sources the base-test.sh harness and validates your command. Tests should verify file existence, execution permissions, expected output strings, and exit codes. The test framework provides assertions like assert_file_exists, assert_executable, and assert_output_contains for standardized validation.
Practical Code Examples
Example 1: Top-Level Hello Command
Create bin/omarchy-hello with the following content:
#!/usr/bin/env bash
# File: bin/omarchy-hello
set -euo pipefail
omarchy-log "Running hello command"
echo "Hello, Omarchy user! 👋"
exit 0
Make the file executable:
chmod +x bin/omarchy-hello
Example 2: Grouped Command with Metadata
First, register the new group in bin/omarchy:
GROUP_DESCRIPTIONS[greet]="Greeting utilities"
Then create bin/omarchy-greet-say:
#!/usr/bin/env bash
# File: bin/omarchy-greet-say
set -euo pipefail
omarchy-log "greet say invoked"
msg=${1:-"Hello"}
echo "$msg, Omarchy!"
exit 0
Example 3: Shell Test Implementation
Create test/shell.d/hello-test.sh:
#!/usr/bin/env bash
# File: test/shell.d/hello-test.sh
source "$(dirname "$0")/base-test.sh"
assert_file_exists "$OMARCHY_PATH/bin/omarchy-hello"
assert_executable "$OMARCHY_PATH/bin/omarchy-hello"
run_cmd "$OMARCHY_PATH/bin/omarchy-hello"
assert_output_contains "Hello, Omarchy user!"
assert_exit_code 0
Summary
- Naming convention: Use
omarchy-<group>-<verb>for grouped commands oromarchy-<verb>for top-level commands in thebin/directory. - Metadata registration: Add new groups to the
GROUP_DESCRIPTIONSassociative array inbin/omarchyto enable help text generation. - Conditional availability: Use the
GUARD_READERSarray inbin/omarchyto control when commands appear in interactive menus. - Documentation: Update
docs/cli-router.mdand relevantmanual/pages to describe routing logic and usage examples. - Testing: Validate commands using the
test/shell.d/base-test.shharness, checking for correct output and exit codes.
Frequently Asked Questions
What naming convention must I follow for Omarchy CLI commands?
Omarchy CLI commands must follow the pattern omarchy-<group>-<verb> for namespaced commands or omarchy-<verb> for top-level commands. The dispatcher in bin/omarchy splits the input arguments and looks for executable files matching these hyphen-separated names in the bin/ directory.
Where is the GROUP_DESCRIPTIONS array defined?
The GROUP_DESCRIPTIONS associative array is defined near the top of bin/omarchy. This array maps group identifiers (like deploy or greet) to human-readable description strings that appear in help output and command menus. Add new entries here when creating commands for groups that do not yet exist.
How do I test a new Omarchy CLI command locally?
Write a test script in test/shell.d/ that sources base-test.sh and uses assertions like assert_output_contains and assert_exit_code. Run the full test suite with ./test/all or execute individual test files directly. Ensure your command script has executable permissions before testing.
Can I create deeply nested subcommands beyond the group-verb structure?
The standard Omarchy architecture supports exactly two levels of nesting: group and verb. While you can implement additional argument parsing within your command script to handle sub-subcommands, the dispatcher itself resolves only to the omarchy-<group>-<verb> pattern. For complex hierarchies, implement argument switching inside the verb script rather than extending the file naming convention.
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 →