X Linux
Documentation menu

Overview/Scripts and CLI

x — CLI

x is the provisioning CLI of the x system (ADR-0003 in DECISIONS.md at the workspace root). Its implementation lives in bin/ of this repo and is installed as /usr/bin/x (symlink to /usr/share/x/bin/x) by the x-scripts package. When working from a checkout it can be invoked as bash bin/x.

Dispatch is by naming convention plus header-comment metadata, with no central registry: adding a command means adding one file in bin/.

Usage

x <command> [arguments]
x help          # or: x list, x -h, x --help

x with no arguments prints the help. The dispatcher exports X_BIN (the bin/ directory) and X_CLI=1 so subcommands know they run through the CLI.

Commands

Summaries are the x:summary headers of each file (shown by x help).

CommandDescription
x setupProvisions the system as root (install/system.sh; config, hardware, login, post-install). Elevates with sudo when needed.
x setup --userProvisions the current user (install/user.sh; home seed + config sync + optional node and Hyprland). Desktop selection for niri/KDE happens in the text installer.
x theme listLists available themes under themes/.
x theme set <name>Applies a theme palette: copies themes/<name>/colors to ~/.config/x/theme.conf (backing up the previous one) and records the active theme in ~/.local/state/x/theme.
x migrateRuns the user's pending idempotent migrations.
x updatepacman -Syu (privileged) followed by the user's migrations.
x hardwareRuns the hardware phase (detection + modules). Requires root.
x infoShows version, repo, user and environment info.
x agent / x agent installInstalls the Xscriptor AI bundle for OpenCode (--bundle x|dev|full, --env NAME, --project, --dest DIR, --source DIR, --ref REF, --dry-run, --list). Sources resolve from X_AGENT_SOURCE/XSCRIPTOR_AI_DIR, a sibling xscriptor-ai checkout, or a pinned download (X_AGENT_REF, cached under X_AGENT_CACHE).
x agent statusShows the recorded destinations, item counts and source in use.
x agent removeRemoves exactly the files recorded in the manifest (--dest DIR, --all, --dry-run).
x gen / x gen listLists the system generations (* marks the current one). See generations.md.
x gen newCreates a generation: btrfs snapshot + manifest (--reason, --label).
x gen statusShows the running vs default generation, pending rollback and /etc drift.
x gen rollback <id>Switches the default boot to a generation (applies on reboot; --no-safety).
x gen bootRegenerates the per-generation boot entries.
x gen diffShows package/service/migration/kernel//etc differences between two generations.
x gen verifyCompares the live system against a generation (exit 1 on drift).
x gen pin <id>Protects a generation from pruning (--unpin).
x gen pruneRemoves old generations, keeping pinned/running/default (--keep N, --older-than DAYS, --dry-run).
x gen restore <path>Restores a file/directory from a generation (--from ID, --dest PATH).
x gen restore --pkg <name>Restores every file owned by a package.
x gen export / x gen importPacks/restores a generation bundle (--with-data, --sign, --encrypt, --encrypt-to KEY, --force).
x gen quota init / statusEnables btrfs quotas and shows usage / the qgroup table.
x gen planPrints the actions to match a system.toml declaration.
x gen applyApplies a system.toml declaration (--dry-run); records a generation.
x kernel listLists the known kernels (release, running, headers) and the boot entry style.
x kernel install <kernel>Installs an official Arch kernel plus matching headers through pacman (--no-headers, --yes); the generation hooks snapshot it automatically.
x kernel remove <kernel>Removes an installed kernel (--yes); refuses the running and the last kernel; snapshots that archived it stay bootable via rollback.
x home / x home listLists the user's home generations (dotfiles).
x home new / status / diff / restore / pruneHome-generation lifecycle. See generations.md.

Root-only commands enforce root inside the dispatcher (see metadata below) and print an error if run as a non-root user.

Aliases

Aliases are defined with x:aliases metadata and let a single token map to a command file:

AliasResolves to
theme, themesx-theme-list.sh (so x theme lists themes)
hardware, hwx-hardware.sh
info, status, doctorx-info.sh
migrate, migrationsx-migrate.sh
update, upgrade, upx-update.sh
gen, generation, generationsx-gen-list.sh (so x gen lists generations)

Dispatch mechanics

Resolution tries the longest file-name prefix first, then falls back to the first argument matched against x:aliases:

  • x theme set nord → looks up x-theme.sh, then x-theme-set.sh; the latter exists, so nord is passed to x-theme-set.sh.
  • x theme (single token) → no x-theme.sh; the alias theme on x-theme-list.sh matches.
  • x nonexistent → error with help (exit 1).

The file must be executable to be resolved. The dispatcher only consumes x:summary, x:aliases and x:root; remaining arguments are forwarded to the subcommand, which validates its own arguments (x setup --help, x theme set with the wrong arity errors out, etc.).

Adding a command

Create bin/x-<group>-<verb>.sh as an executable script with metadata in the header:

#!/usr/bin/env bash
# x:summary=one line shown by x help
# x:aliases=alias1 alias2      # optional
# x:root=true                  # optional: require root to run
set -euo pipefail

X_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
# ...
  • x:summary — one-line description, shown in x help and x list.
  • x:aliases — optional space-separated aliases resolved against the first token.
  • x:root=true — makes the dispatcher refuse to run as a non-root user.
  • x:args — optional; informational only, not parsed by the dispatcher. Use it to document the expected arguments in the header.

There is no central registry and no registration step.

Environment variables

VariableDefaultMeaning
X_BIN<repo>/binDirectory of the CLI (exported by the dispatcher).
X_CLI—1 when running through the dispatcher (exported by it).
X_ROOT<repo>Repository/payload root (exported by install/helpers/common.sh).
X_STATE_DIR~/.local/state/xUser state directory (theme, migration markers).
X_THEMES_DIR<repo>/themesTheme store.
X_THEME_CONF~/.config/x/theme.confOutput file written by x theme set.
X_MIGRATIONS_DIR<repo>/migrationsMigration scripts directory.
X_SKEL_DIR/etc/skelSkeleton seeded into the home.
X_CONFIG_SEED<repo>/configDotfile tree synced to ~/.config.
X_TScurrent timestampTimestamp used for .bak.<ts> backups.
X_DRY_RUN01 makes privileged/user helpers log instead of running.
X_NODE01 installs the node toolchain (fnm) in the user phase.
X_HYPRLAND10 skips the Hyprland setup in the user phase.
X_HW_AUTO10 disables hardware auto-detection in the hardware phase.
X_HW_NVIDIA01 forces the NVIDIA module.
X_HW_QEMU01 enables the QEMU/libvirt module.
X_GEN_BACKENDautoauto, btrfs, dir (tests/degraded) or off. See generations.md.
X_GEN_STATE / X_GEN_DIR / X_GEN_CURRENT/var/lib/x/...Generation state, manifests and current id.
X_GEN_SNAPSHOTS/.snapshotsSnapshot store (mount point).
X_GEN_SUBVOL_PREFIX$X_GEN_SNAPSHOTSIn-fs path used by mount/boot options.
X_GEN_ROOT/Tree captured by a generation (tests use a fake root).
X_GEN_CMDLINE/proc/cmdlineKernel cmdline recorded in the manifest.
X_GEN_BOOT / X_GEN_BOOT_DIR / X_GEN_BOOT_KEEPauto / /boot / 0Boot-entry management and retention (0 = every generation).
X_GEN_KEEP5Generation retention for x gen prune.
X_HGEN_STATE / X_HGEN_HOME~/.local/share/x/home-gens / $HOMEHome-generation store and captured home.
X_HGEN_INCLUDE / X_HGEN_EXCLUDEdotfiles + .config / Cache CachedData GPUCache logsPaths captured by x home new.
X_HGEN_KEEP10Home-generation retention for x home prune.
X_GEN_LIVE_SUBVOL—root_subvol of the live generation (installer uses /@).
X_GEN_RUNNINGfrom cmdlineRunning generation id (tests).
X_GEN_SKIP01 disables automatic generations in the setup/update hooks.

Hyprland-setup specific variables (X_HYPR_*) are documented in hyprland.md; the niri installer variables (X_NIRI_*) are documented in niri.md.

State

  • ~/.local/state/x/ — user state: theme (active theme) and migrations/<name> (applied-migration markers).
  • ~/.config/x/ — generated user config, e.g. theme.conf.
  • /var/lib/x/ — system state: generations/<id>/ (manifests and captures) and current (current generation id); snapshots live in /.snapshots/.

The env overrides above let tests and development redirect every state/output path away from the real home (see test/smoke.sh).

x setup --online

Runs the original equisdots installer (equisdots/dots setup) from a temporary clone, then cleans up. Use it when already logged in and the offline packaged Hyprland setup is not enough. It only covers Hyprland; use the text installer's niri option for niri. It asks for the sudo password when the upstream script needs it.

x setup --user --online

Edit this page on GitHub