The previous wording claimed the argument must name a file under $OMARCHY_PATH/config/ and that anything else is rejected. The check is `[[ -e $default_config_file ]]` against an interpolated path, so `../AGENTS.md` resolves in both trees and copies over $HOME/AGENTS.md, exit 0.
286 lines
15 KiB
Markdown
286 lines
15 KiB
Markdown
# Style
|
|
|
|
- Two spaces for indentation, no tabs
|
|
- Use bash 5 conditionals: use `[[ ]]` for string/file tests and `(( ))` for numeric tests
|
|
- In `[[ ]]`, don't quote variables, but do quote string literals when comparing values (e.g., `[[ $branch == "dev" ]]`)
|
|
- Prefer `(( ))` over numeric operators inside `[[ ]]` (e.g., `(( count < 50 ))`, not `[[ $count -lt 50 ]]`)
|
|
- For strings/paths with spaces, quote them instead of escaping spaces with `\ ` (e.g., `"$APP_DIR/Disk Usage.desktop"`, not `$APP_DIR/Disk\ Usage.desktop`)
|
|
- Shebangs must use `#!/bin/bash` consistently (never `#!/usr/bin/env bash`)
|
|
- Scripts under `install/` and `migrations/` may be sourced and intentionally omit shebangs
|
|
|
|
# Command Naming
|
|
|
|
All commands start with `omarchy-`. Prefixes indicate purpose.
|
|
|
|
The authoritative command group list lives in `bin/omarchy` in `GROUP_DESCRIPTIONS`. Keep `GROUP_DESCRIPTIONS` updated when adding a new command prefix.
|
|
|
|
Common prefixes include:
|
|
|
|
- `cmd-` - check if commands exist, misc utility commands
|
|
- `capture-` - screenshots, screen recordings, and other capture tools
|
|
- `pkg-` - package management helpers
|
|
- `hw-` - hardware detection (return exit codes for use in conditionals)
|
|
- `refresh-` - copy default config to user's `~/.config/`
|
|
- `restart-` - restart a component
|
|
- `launch-` - open applications
|
|
- `install-` - install optional software
|
|
- `setup-` - interactive setup wizards
|
|
- `toggle-` - toggle features on/off
|
|
- `theme-` - theme management
|
|
- `update-` - update components
|
|
|
|
Do not maintain a second exhaustive prefix list here. Consult
|
|
`GROUP_DESCRIPTIONS` when selecting or checking a command group so this
|
|
guidance does not drift from the router.
|
|
|
|
# Command Metadata
|
|
|
|
Commands in `bin/` can declare CLI metadata in comments near the top of the file. `bin/omarchy` scans the first 80 lines, and tests expect command metadata to remain valid.
|
|
|
|
Supported metadata keys:
|
|
|
|
- `# omarchy:group=...` - override the command group inferred from the filename
|
|
- `# omarchy:name=...` - override the command name inferred from the filename
|
|
- `# omarchy:summary=...` - short help text
|
|
- `# omarchy:args=...` - usage arguments
|
|
- `# omarchy:examples=...` - examples separated with ` | `
|
|
- `# omarchy:alias=...` / `# omarchy:aliases=...` - alternate routes
|
|
- `# omarchy:hidden=true` - hide from default command listings
|
|
- `# omarchy:requires-sudo=true` - mark commands that require sudo
|
|
|
|
Only use `omarchy:examples` where there are args that need explaining.
|
|
|
|
Prefer explicit metadata for user-facing commands. Keep routes consistent with the filename unless there is a deliberate alias or compatibility route.
|
|
|
|
Example:
|
|
|
|
```bash
|
|
# omarchy:summary=Take a screenshot
|
|
# omarchy:args=[smart|region|windows|fullscreen] [slurp|copy]
|
|
# omarchy:examples=omarchy screenshot | omarchy capture screenshot region
|
|
```
|
|
|
|
# Runtime Environment
|
|
|
|
- `$OMARCHY_PATH` is set at the top level by the uwsm session environment and is always available to Omarchy runtime code.
|
|
- Commands in `bin/` and Quickshell QML should rely on `$OMARCHY_PATH` / `Quickshell.env("OMARCHY_PATH")`; do not derive fallback paths from `HOME`, `Quickshell.shellDir`, or re-export/default `OMARCHY_PATH` manually.
|
|
|
|
# Privileged Commands
|
|
|
|
- Follow the "Privilege Escalation" section of `default/omarchy-skill/SKILL.md`. It draws the
|
|
`sudo`/`pkexec` line by whether the caller has a terminal to enter a password in, and the repo's
|
|
own scripts follow it.
|
|
|
|
# Git
|
|
|
|
- Commits should be atomic: include only one coherent change or fix, and do not mix unrelated work.
|
|
- Commit messages should be succinct and describe the change being made.
|
|
|
|
# Install Scripts
|
|
|
|
The ISO owns installation orchestration. This repo ships target-side setup commands and reusable setup leaves:
|
|
|
|
- `bin/omarchy-setup-system` runs root-owned system setup during ISO finalization.
|
|
- `bin/omarchy-setup-hardware` runs idempotent hardware-specific setup and is called by `omarchy-setup-system`.
|
|
- `bin/omarchy-finalize-user` runs the per-user runtime finalization (skill symlinks, xdg-user-dirs, mime defaults, `install/user/all.sh`). Shipped user defaults are seeded by `/etc/skel` from `omarchy-settings`, not by this command. `bin/omarchy-reinstall-configs` is the explicit destructive resync of those defaults into an existing user's `$HOME`.
|
|
- leaf scripts under `install/` are sourced by `run_logged $OMARCHY_INSTALL/path/to/script.sh` and intentionally do not have shebangs.
|
|
- avoid `exit` in sourced setup scripts unless intentionally aborting setup.
|
|
- use `$OMARCHY_INSTALL` and `$OMARCHY_PATH` instead of hard-coded Omarchy paths.
|
|
- keep root-scoped hardware setup under `install/hardware/` and orchestrate it through `install/hardware/all.sh`.
|
|
- keep every per-user setup leaf under `install/user/` (including `install/user/hardware/` and `install/user/first-run/`) so it is clear what must run for each user.
|
|
- prefer helper commands for package and command checks where available.
|
|
|
|
Raw `command -v`, `pacman`, and `pacman-key` are acceptable in package-helper contexts where direct package-manager behavior is the point of the script.
|
|
|
|
# Helper Commands
|
|
|
|
Use these instead of raw shell commands:
|
|
|
|
- `omarchy-cmd-missing` / `omarchy-cmd-present` - check for commands
|
|
- `omarchy-pkg-missing` / `omarchy-pkg-present` - check for packages (don't use these if you can just use `omarchy-pkg-add`/`omarchy-pkg-drop`)
|
|
- `omarchy-pkg-add` - install packages (handles both pacman and AUR)
|
|
- `omarchy-pkg-drop` - remove packages; use this instead of raw `pacman -R*`
|
|
- `omarchy-notification-send` - send desktop notifications; do not call `notify-send` directly
|
|
- `omarchy-hw-asus-rog` - detect ASUS ROG hardware (and similar `hw-*` commands)
|
|
|
|
Commands installed by Omarchy's default package set are runtime invariants. Invoke them directly; do not add defensive `omarchy-cmd-present` / `omarchy-cmd-missing` checks around them. Use command-presence helpers only for genuinely optional dependencies or code that can run before the default package set is installed.
|
|
|
|
Exceptions are allowed for migration and package-helper scripts where the helper may not be available yet, where the helper itself is being implemented, or where direct package-manager behavior is required.
|
|
|
|
# Config Structure
|
|
|
|
- `config/` - default configs copied to `~/.config/`
|
|
- `default/themed/*.tpl` - templates with `{{ variable }}` placeholders for theme colors
|
|
- `themes/*/colors.toml` - theme color definitions (accent, background, foreground, red/green/yellow/blue/magenta/cyan and bright_* variants)
|
|
|
|
# Tests
|
|
|
|
Run focused automated tests for the area you changed. Current test entry points:
|
|
|
|
- `./test/all` - aggregate runner for CLI and shell tests; it intentionally does not run graphical acceptance tests
|
|
- `./test/cli` - CLI routing, command metadata, theme helpers, and safe dispatch coverage
|
|
- `./test/shell` - all Omarchy shell tests under `test/shell.d/`
|
|
|
|
New Omarchy shell tests should live in `test/shell.d/*-test.sh` so `./test/shell` picks them up automatically. Source `test/shell.d/base-test.sh` for shared root-path discovery, assertions, and Node test helpers.
|
|
|
|
# Acceptance Tests
|
|
|
|
The graphical acceptance suite lives in `test/acceptance` with test files under
|
|
`test/acceptance.d/*-test.sh`. It exercises a real installed Omarchy desktop,
|
|
including session health, shell surfaces, panels, keyboard navigation,
|
|
representative applications, and system setup. Source
|
|
`test/acceptance.d/base-test.sh` for the shared helpers.
|
|
|
|
Run acceptance tests in a disposable VM through the sibling `omarchy-iso`
|
|
repository, not in the active development session. The suite opens and closes
|
|
applications and temporarily changes desktop configuration.
|
|
|
|
For acceptance-test-only changes, reuse an installed base and sync the suite:
|
|
|
|
```bash
|
|
cd ../omarchy-iso
|
|
./bin/omarchy-iso-test release/<iso>.iso --reuse-base --sync-omarchy ../omarchy --no-preview
|
|
```
|
|
|
|
Use `--sync-all ../omarchy` instead of `--sync-omarchy ../omarchy` when the
|
|
acceptance run must exercise local `bin/`, `config/`, or `shell/` source too.
|
|
Changes to package manifests, installation, finalization, or shipped defaults
|
|
require a fresh ISO built from the local checkouts and a run without
|
|
`--reuse-base`:
|
|
|
|
```bash
|
|
cd ../omarchy-iso
|
|
./bin/omarchy-iso-make --no-boot-offer --local-source ../omarchy ../omarchy-pkgs
|
|
./bin/omarchy-iso-test release/<generated-iso>.iso --no-preview
|
|
```
|
|
|
|
Keep unrelated acceptance workflows in separate test files. The runner records
|
|
a failed file and continues with the remaining files, which preserves as much
|
|
diagnostic coverage as possible. Restore modified user state with traps, close
|
|
anything the test opens, and capture every visually distinct state (including
|
|
entered input where relevant) as `success-<step>.png`; failure helpers capture
|
|
`failure-<step>.png`. The ISO harness collects the screenshots and logs under
|
|
its timestamped `test-runs/` directory and opens the screenshots after the run
|
|
unless `--no-preview` is passed.
|
|
|
|
The ISO harness exercises compositor-level shortcuts with QMP virtual keyboard
|
|
input. In-guest `wtype` is suitable for typing into focused controls, but it
|
|
does not reliably prove that a global Hyprland keybinding works.
|
|
|
|
# Visual Verification
|
|
|
|
Visual changes must be verified in the running UI in addition to automated
|
|
tests. This includes Omarchy shell styling and layout, panels, menus,
|
|
notifications, desktop appearance, animations, transitions, screenshots, and
|
|
screen recording flows. Creating an artifact is not sufficient: inspect it for
|
|
clipping, overlap, incorrect spacing, stale state, focus problems, and visual
|
|
regressions before finishing.
|
|
|
|
Take a full-screen screenshot without opening the editor:
|
|
|
|
```bash
|
|
omarchy capture screenshot fullscreen save
|
|
```
|
|
|
|
The command prints the saved path and writes to the configured Pictures
|
|
directory. Use `omarchy screenshot` for the interactive smart-region flow.
|
|
Capture reference and candidate states as separate images when changing a
|
|
layer-shell surface or layout, then compare both.
|
|
|
|
Record a short full-screen video for animation, transition, timing, capture, or
|
|
screen-recording changes:
|
|
|
|
```bash
|
|
omarchy screenrecord --fullscreen
|
|
# Exercise the changed behavior.
|
|
omarchy screenrecord --stop-recording
|
|
```
|
|
|
|
The stop command prints the saved video path in the configured Videos
|
|
directory. Review the recording before finishing, and keep it short and focused
|
|
on the changed behavior.
|
|
|
|
For interactive UI work, use `wtype` to simulate keyboard input when available. Example: start the UI in the background, wait briefly for focus, then run `wtype -k Right -k Return` to exercise keyboard selection and confirm the resulting command output or state change. Prefer this over manual-only verification when a UI returns a selected value or changes a symlink/config.
|
|
|
|
If a launched UI would otherwise remain open, keep track of its PID and stop it
|
|
after the screenshot or recording; avoid broad process kills unless checking
|
|
with `ps` first.
|
|
|
|
# Omarchy shell
|
|
|
|
The Quickshell desktop runs as a single long-running process out of
|
|
`shell/`. Hyprland autostart launches it directly with `quickshell -n -p`;
|
|
do not start additional standalone Quickshell instances for individual
|
|
components.
|
|
|
|
Run `omarchy-restart-shell` after making changes to QML files.
|
|
|
|
Plugin contract:
|
|
|
|
- First-party plugins live directly under `shell/plugins/` or one category
|
|
level deeper, such as `shell/plugins/panels/weather/`. First-party bar-only
|
|
widgets may use adjacent `*.manifest.json` files. Third-party plugins live
|
|
at `~/.config/omarchy/plugins/<id>/` with a `manifest.json` at the root.
|
|
- Every plugin manifest declares `schemaVersion`, `id`, `name`, `version`,
|
|
`kinds`, and `entryPoints`. See
|
|
[`docs/omarchy-shell.md`](docs/omarchy-shell.md) and
|
|
`shell/services/PluginRegistry.qml` for the current contract; fields such as
|
|
`activation` are optional.
|
|
- Entry-point QML files are `Item`s (not `ShellRoot`), and accept the
|
|
shell-injected properties `omarchyPath`, `shell`, `manifest`, and
|
|
`pluginRegistry` / `barWidgetRegistry` as appropriate.
|
|
- Panel / overlay / menu plugins must expose `open(payloadJson)` and
|
|
`close()` lifecycle methods for `shell summon` and `shell hide`.
|
|
|
|
IPC:
|
|
|
|
- `bin/omarchy-shell` is the canonical IPC entry point. It forwards to
|
|
the running shell and does not start it. Prefer it over re-implementing
|
|
direct Quickshell socket calls in every CLI.
|
|
- The `shell` IPC target exposes lifecycle and configuration methods including
|
|
`ping`, `summon`, `hide`, `toggle`, `call`, `rescanPlugins`, `reloadConfig`,
|
|
`setPluginEnabled`, and `listPlugins`. `shell.qml` also registers
|
|
`image-selector`, which drives the `omarchy.image-picker` panel.
|
|
- Individual plugins register their own IPC targets, named for the plugin rather
|
|
than for where they appear: the background switcher registers `background`, and
|
|
bar widgets register one target each — `omarchy.indicators`,
|
|
`omarchy.system-update`, `omarchy.clock`. There is no `bar` target.
|
|
|
|
Widget files in `shell/plugins/bar/widgets/` contain Nerd Font glyphs as raw
|
|
unicode characters. The `Write` and `Edit` tools strip multi-byte
|
|
codepoints in some positions — do **not** rewrite widget files wholesale
|
|
through those tools. For glyph fixes, use the targeted `Edit` tool with
|
|
the surrounding context, or a Python script that inserts codepoints via
|
|
`chr(0xXXXXX)`.
|
|
|
|
# Refresh Pattern
|
|
|
|
To copy a default config to user config with automatic backup:
|
|
|
|
```bash
|
|
omarchy-refresh-config hypr/hyprland.lua
|
|
```
|
|
|
|
This copies `$OMARCHY_PATH/config/hypr/hyprland.lua` to `~/.config/hypr/hyprland.lua`. The argument
|
|
is interpolated into both paths and only checked with `[[ -e ]]`, so pass a plain relative path: a
|
|
name containing `..` resolves and copies, landing outside `~/.config` rather than being rejected.
|
|
|
|
# Migrations
|
|
|
|
Read `docs/migrations.md` before creating or changing migrations.
|
|
|
|
Migrations are per-user and run through `omarchy-migrate` during `omarchy update` or from the login-time migration notification. Put migrations directly under `migrations/<timestamp>.sh`. Pending state is per-user under `~/.local/state/omarchy/migrations/`, so every user gets a chance to run every migration. Migrations run as the user; privileged work should invoke the appropriate helper or privilege prompt, and no-op when another user already applied it.
|
|
|
|
To create a new migration, run `omarchy-dev-add-migration --no-edit`.
|
|
|
|
New migration format:
|
|
- File permissions must be `0644` (`-rw-r--r--`); migration runners execute them with `bash -euo pipefail`, not through executable bits
|
|
- No shebang line
|
|
- Start with an `echo` describing what the migration does
|
|
- Use `$OMARCHY_PATH` to reference the omarchy directory
|
|
- Prefer helper commands such as `omarchy-cmd-present`, `omarchy-cmd-missing`, `omarchy-pkg-present`, and `omarchy-pkg-missing`
|
|
|
|
Omarchy 4.0 is upgraded through `bin/omarchy-upgrade-to-quattro`, not through the normal migration runner. Do not add compatibility migrations for old installer layouts; put pre-4 package-layout transition work in the upgrade command instead.
|
|
|
|
Migrations may use raw `pacman`, `command -v`, or direct config edits when needed for one-off repair work.
|