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

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-agent with automatic fallback to ~/.local/state
  • The script exposes a simple read interface via cat and 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:

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 →