How omarchy-default-agent Integrates with XDG Defaults: A Complete Technical Guide
The omarchy-default-agent wrapper stores the user's chosen default agent in $XDG_STATE_HOME/omarchy/default-agent and exposes it via command substitution to the rest of the Omarchy system.
The omarchy-default-agent utility in the omacom/omarchy repository provides a clean, XDG-compliant mechanism for persisting and retrieving the user's preferred AI agent. This small but critical component bridges high-level user selection with standards-compliant state management.
XDG State File Location and Fallback Behavior
The canonical storage path follows the XDG Base Directory Specification precisely:
$XDG_STATE_HOME/omarchy/default-agent
When $XDG_STATE_HOME is unset, the specification's fallback applies automatically:
~/.local/state/omarchy/default-agent
This automatic fallback ensures omarchy-default-agent works out-of-the-box while respecting custom XDG layouts. Test suites frequently override XDG_STATE_HOME to achieve isolation, and the script handles this transparently.
Reading the Default Agent Value
The script's read operation is intentionally minimal—a simple cat of the state file. The implementation returns an empty string when the file doesn't exist, allowing safe command substitution.
From default/omarchy/omarchy-menu.jsonc, the menu system queries the current selection:
[[ "$(omarchy-default-agent)" == "pi" ]]
This pattern appears throughout the codebase for conditional check-marks and agent-specific behavior.
Practical read example:
# Query the current default agent
current=$(omarchy-default-agent)
echo "Current default agent: $current"
Writing and Updating the Agent Selection
Setting a new default persists immediately to the XDG state file. The write completes before any subsequent command executes, ensuring consistency across the system.
# Set a new default agent
omarchy-default-agent copilot # writes "copilot" to $XDG_STATE_HOME/omarchy/default-agent
# Install an agent and auto-select it
omarchy-default-agent --install openclaw # writes "openclaw" after successful mise install
The --install flag combines agent installation via mise with automatic default selection, streamlining the setup workflow.
Integration Points Across Omarchy
Menu System Wiring
The Waybar/rofi menu defined in default/omarchy/omarchy-menu.jsonc drives its check-marks and installation triggers through direct $(omarchy-default-agent) calls. Each menu entry evaluates the current selection to display visual state.
Migration Compatibility
The migration script migrations/1786719479.sh explicitly documents its alignment with this approach:
# Reads default agent the same way omarchy-default-agent does
This comment ensures future maintainers preserve the XDG state file contract during data migrations.
First-Run Onboarding
The hook at install/user/first-run/setup-agent.hook determines whether to prompt for initial selection:
[[ -z $(omarchy-default-agent) ]]
An empty result triggers the interactive setup flow; an existing value allows silent continuation.
Complete Working Examples
Custom XDG layout during CI or testing:
# Respect a custom XDG layout
XDG_STATE_HOME=/tmp/xdg_state omarchy-default-agent # reads/writes under /tmp/xdg_state/omarchy/default-agent
Full workflow demonstration:
#!/bin/bash
# Typical agent selection workflow
# 1. Check current default
current=$(omarchy-default-agent)
echo "Current: ${current:-'(none set)'}"
# 2. Set new default
omarchy-default-agent pi
# 3. Verify persistence
echo "Updated to: $(omarchy-default-agent)"
Key Implementation Files
| File | Role |
|---|---|
bin/omarchy-default-agent |
Core wrapper implementing read/write logic and agent forwarding |
default/omarchy/omarchy-menu.jsonc |
Menu entries using $(omarchy-default-agent) for state display |
migrations/1786719479.sh |
Migration script with explicit XDG path documentation |
install/user/first-run/setup-agent.hook |
First-run hook checking for empty state |
test/shell.d/default-agent-test.sh |
Test suite verifying XDG override handling |
Summary
- omarchy-default-agent persists agent selection to
$XDG_STATE_HOME/omarchy/default-agentwith automatic fallback to~/.local/state - The script exposes a simple read interface via
catand write interface via argument passing - Menu system, migrations, and first-run hooks all consume the same command substitution interface
- XDG environment variable support enables seamless test isolation and custom directory layouts
- The implementation follows XDG Base Directory Specification without hardcoded paths
Frequently Asked Questions
What happens if XDG_STATE_HOME is not set?
The script automatically falls back to ~/.local/state/omarchy/default-agent per the XDG Base Directory Specification. No configuration is required for standard operation.
How do other Omarchy components read the default agent?
Components use command substitution: $(omarchy-default-agent). The menu JSON, migration scripts, and first-run hooks all employ this pattern for consistent state access.
Can I use omarchy-default-agent in CI or testing environments?
Yes. Override XDG_STATE_HOME to any writable directory. The test suite at test/shell.d/default-agent-test.sh demonstrates this pattern for isolated test execution.
Does the script handle concurrent writes safely?
The write operation completes atomically before returning, ensuring subsequent reads see the updated value. For production deployments with high concurrency, filesystem-level atomicity depends on the underlying write syscall behavior.
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 →