How Skill Symlinks Are Managed in Omarchy User Provisioning
Omarchy creates idempotent, development-aware symbolic links from centralized skill definitions in $OMARCHY_PATH/default/agents/skills/ to per-user directories for Claude, Codex, Pi, and Gemini during the omarchy-provision-user runtime finalization phase.
Omarchy treats AI agent capabilities as version-controlled "skills" that live in the repository rather than individual user directories. During the provisioning process, the omarchy-provision-user script links these shared resources into each user's home directory using symlinks, ensuring compatibility with multiple AI harnesses while maintaining a single source of truth for skill definitions.
Skill Symlink Architecture
Omarchy's skill management relies on a strict separation between source and target locations. This design allows the framework to update skills centrally while immediately propagating changes to all users through filesystem links.
Centralized Source Location
All shipped skills reside in the repository at $OMARCHY_PATH/default/agents/skills/. This directory contains subdirectories for each skill (such as omarchy and diagnose-crash), including their tool definitions, instructions, and metadata. By keeping skills in the repository rather than /etc/skel, Omarchy ensures that updates to the framework automatically update available agent capabilities.
Per-User Target Directories
During provisioning, the system creates symlinks into five specific locations within the user's home directory to support various AI agents:
~/.agents/skills/— Generic agent compatibility layer~/.claude/skills/— Anthropic Claude Code integration~/.codex/skills/— OpenAI Codex integration~/.pi/agent/skills/— Pi agent harness~/.gemini/config/skills/— Google Gemini configuration
The Provisioning Flow
The symlink creation occurs during the runtime finalization step, which executes after initial dotfile seeding from /etc/skel.
Runtime Finalization with omarchy-provision-user
The script bin/omarchy-provision-user runs once per user account. Before creating links, it ensures target directories exist:
mkdir -p ~/.agents/skills ~/.claude/skills ~/.codex/skills ~/.pi/agent/skills ~/.gemini/config/skills
This preparation prevents ln errors when targeting fresh user accounts.
Symlink Creation Logic
The core linking mechanism uses a glob loop over the source directory. For each skill subdirectory found in $OMARCHY_PATH/default/agents/skills/*/, the script calculates the basename and creates symbolic links using the -sfn flags (symbolic, force, no-dereference):
for skill in "$OMARCHY_PATH"/default/agents/skills/*/; do
skill=${skill%/}
name=${skill##*/}
ln -sfn "$skill" ~/.agents/skills/"$name"
ln -sfn "$skill" ~/.claude/skills/"$name"
ln -sfn "$skill" ~/.codex/skills/"$name"
ln -sfn "$skill" ~/.pi/agent/skills/"$name"
ln -sfn "$skill" ~/.gemini/config/skills/"$name"
done
The -f flag ensures idempotency by overwriting existing links, while -n treats the destination as a normal file if it is a symlink to a directory, preventing nested link errors.
Development Mode and Path Resolution
Omarchy's skill symlinks are development-aware through the $OMARCHY_PATH environment variable. When a developer runs omarchy dev link, the variable points to their local checkout rather than the system installation. Because the provisioning script dereferences $OMARCHY_PATH at runtime, subsequent executions of omarchy-provision-user automatically redirect symlinks to the development version without requiring manual reconfiguration.
This mechanism allows developers to test skill modifications immediately by iterating in their checkout and re-running the provisioner, with changes reflecting instantly in agent environments.
Idempotency and State Management
To prevent redundant operations across shell sessions, the provisioning script maintains a state marker at ~/.local/state/omarchy/done/finalize-user. When this file exists, the script skips skill linking unless invoked with the --force flag.
According to the source in bin/omarchy-provision-user, this check ensures that expensive I/O operations occur only once per user creation or when explicitly requested. The legacy migration at migrations/1786098807.sh also performs similar symlink maintenance for older skill location formats, ensuring backward compatibility during system upgrades.
Summary
- Source location: Skills originate in
$OMARCHY_PATH/default/agents/skills/within the Omarchy repository. - Target locations: Symlinks populate
~/.agents/skills/,~/.claude/skills/,~/.codex/skills/,~/.pi/agent/skills/, and~/.gemini/config/skills/. - Creation method: The
bin/omarchy-provision-userscript iterates skill directories and executesln -sfnfor idempotent linking. - Dev workflow: Changing
OMARCHY_PATHviaomarchy dev linkautomatically redirects symlinks to development checkouts. - State tracking: The marker file at
~/.local/state/omarchy/done/finalize-userprevents redundant execution unless--forceis specified.
Frequently Asked Questions
Where are skill symlinks created during Omarchy provisioning?
Omarchy creates skill symlinks in five directories within the user's home folder: ~/.agents/skills/, ~/.claude/skills/, ~/.codex/skills/, ~/.pi/agent/skills/, and ~/.gemini/config/skills/. The bin/omarchy-provision-user script generates these links during the runtime finalization phase, pointing each back to the corresponding subdirectory in $OMARCHY_PATH/default/agents/skills/.
How does Omarchy prevent broken links when skills are renamed?
The provisioning script uses ln -sfn, which forces replacement of existing symlinks rather than creating nested links. When skills are renamed or removed from the source directory, the next provisioning run updates the symlinks accordingly. The system does not delete orphaned links in target directories, but subsequent runs will overwrite existing links with the current source structure.
What happens if I run omarchy-provision-user multiple times?
The script checks for the existence of ~/.local/state/omarchy/done/finalize-user before executing the skill linking loop. If this marker file exists, the script exits silently unless invoked with the --force flag. When forced, it recreates all symlinks idempotently, ensuring they point to the correct $OMARCHY_PATH location.
How do I manually create a skill symlink for testing purposes?
To manually link a specific skill such as omarchy for testing, create symbolic links from the skill source to each target directory:
skill_dir="$OMARCHY_PATH/default/agents/skills/omarchy"
ln -sfn "$skill_dir" "$HOME/.agents/skills/omarchy"
ln -sfn "$skill_dir" "$HOME/.claude/skills/omarchy"
ln -sfn "$skill_dir" "$HOME/.codex/skills/omarchy"
ln -sfn "$skill_dir" "$HOME/.pi/agent/skills/omarchy"
ln -sfn "$skill_dir" "$HOME/.gemini/config/skills/omarchy"
This mirrors the behavior of the provisioning loop for individual skills during development or debugging.
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 →