What Is the Finalize Step in Omarchy User Setup?

The Finalize step is a per-user completion phase invoked by omarchy-provision-user that bridges the gap between system-wide defaults and a functional personal environment by creating symlinks, configuring default applications, and running user-level installation scripts.

In the omacom/omarchy repository, the Finalize step ensures that every newly created user receives the correct runtime configuration after the initial system skeleton is copied. Because many user-specific resources require an existing $HOME directory—which is not available when files are copied from /etc/skel—Omarchy provides a dedicated finalization script to handle these post-creation tasks.

Why Omarchy Needs a Separate Finalization Phase

System-wide configuration files placed in /etc/skel can only contain static templates. They cannot create dynamic symlinks that point to repository locations, update user-specific PATH variables, or mark migration states because the target user’s home directory does not exist during the initial copy phase. The Finalize step solves this by running omarchy-provision-user after the home directory is established, ensuring the environment is fully operational before the user logs in.

How the Finalize Step Works

The implementation lives in bin/omarchy-provision-user, a Bash script that orchestrates the remaining runtime tweaks. The script follows an idempotent design to prevent duplicate operations across multiple invocations.

Idempotency and State Management

Before executing any changes, the script checks for a marker file at ~/.local/state/omarchy/done/finalize-user. If this file exists, the script exits immediately unless the --force flag is provided. Upon successful completion, it writes the marker using the omarchy-done mark finalize-user helper function found in the bin/ directory.

Key Operations Performed During Finalization

Environment Setup

The script guarantees that OMARCHY_PATH, OMARCHY_INSTALL, and updated PATH variables are available. This ensures that all subsequent helper functions can locate repository resources and external binaries.

To support AI-assisted development workflows, the Finalize step creates symlinks under ~/.agents/skills, ~/.claude/skills, and similar directories. These point to the repository’s default skill folders, allowing users to run development-ready agents without copying static files into /etc/skel.

XDG User Directories and GTK Bookmarks

The script creates standard user directories (Downloads, Pictures, Videos, etc.), updates xdg-user-dirs configurations, removes stale empty folders, and writes bookmarks for the GTK file chooser. This ensures the file manager presents a clean, organized structure consistent with Omarchy’s conventions.

User-Level Installation Scripts

The central installation logic resides in install/user/all.sh, which the Finalize step sources during execution. This script pulls in additional per-user packages, configurations, or database migrations that cannot be applied system-wide.

Application Refresh and Defaults

The script calls omarchy-refresh-applications to update the desktop environment’s application database. It then sets the default web browser to chromium.desktop and registers the default mail handler as HEY.desktop.

First-Install Migration Marking

When invoked with the --first-install flag (typically during ISO installation), the Finalize step marks all shipped migrations as completed. This prevents the system from attempting to apply these migrations again during future updates.

Running the Finalize Command

Users and administrators can trigger the Finalize step using the omarchy CLI:


# Run finalization for the current user (default, safe, idempotent)

omarchy finalize user

# Force a re-run after changing default applications or skills

omarchy finalize user --force

# Used by the installer ISO for brand-new user accounts

omarchy finalize user --first-install

Core Files and Architecture

The Finalize step relies on the following components from the Omarchy codebase:

  • bin/omarchy-provision-user: The main orchestration script that implements the Finalize step.
  • install/user/all.sh: Contains the bulk of per-user installation logic sourced during finalization.
  • bin/omarchy-done: Provides the check and mark functions used for idempotency tracking.
  • docs/file-layout.md: Documents the Finalize command as a top-level user-setup operation.

Summary

  • The Finalize step runs after /etc/skel copying to complete per-user setup in the actual $HOME directory.
  • Idempotency is enforced via a marker file at ~/.local/state/omarchy/done/finalize-user unless --force is used.
  • Key actions include creating dev skill symlinks, configuring XDG directories, sourcing install/user/all.sh, and setting default applications like Chromium and HEY.
  • Execution is handled by bin/omarchy-provision-user and invoked via omarchy finalize user.

Frequently Asked Questions

What happens if I run the Finalize step multiple times?

The script checks for the existence of ~/.local/state/omarchy/done/finalize-user and exits immediately if found. This prevents duplicate symlinks, redundant directory creation, and re-running user-install scripts. To override this behavior, use the --force flag.

Where does the Finalize step store its completion marker?

The idempotency marker is written to ~/.local/state/omarchy/done/finalize-user using the omarchy-done mark finalize-user helper. This path ensures the state persists across sessions while remaining outside version-controlled config files.

How do I force a re-run of the Finalize step?

Execute omarchy finalize user --force to bypass the marker file check. This is useful after updating default applications in the repository or modifying skill configurations that need new symlinks created.

What is the difference between Finalize and the system-wide skeleton installation?

The system-wide skeleton (/etc/skel) provides static files copied at account creation time, but it cannot reference the user’s actual $HOME path or create dynamic symlinks. The Finalize step runs afterward with full access to the user environment to complete runtime-specific configuration.

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 →