From 28dcbae37622d0c8d4ef5e5300ea6cd402e3981b Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 14 Aug 2026 12:24:47 +0200 Subject: [PATCH] Restore preinstalls from the menu, and match the lists to what quattro ships (#6854) * Restore preinstalls from the menu, and drop the Omacom apps with them Remove Preinstalls missed omacut, omacalc, and omawrite, so the three Omacom apps survived an opt-out that was supposed to clear the desk. Opting out was also one-way. Install > Preinstalls now puts everything back: the shipped .desktop launchers and mise stubs via omarchy-refresh-applications, the dropped packages via pacman, and the opt-out marker deleted so the preinstalled keybindings return on reload. The two menu entries guard on the marker, so exactly one of them is ever visible. Co-Authored-By: Claude Opus 5 * Trim the preinstall lists to what quattro actually ships Remove Preinstalls was still dropping typora, spotify, 1password, 1password-cli, signal-desktop, opencode, claude-code, and github-cli. None of those are in omarchy-base.packages anymore: typora gave way to omawrite, the services moved to on-demand menu installs, and the agent CLIs are mise-managed. Removing them took out apps the user had deliberately installed, and restoring them would have put back what we no longer ship. Both lists are now the same twelve packages, all of them in omarchy-base.packages. Co-Authored-By: Claude Opus 5 * Keep the opt-out marker when a restore fails omarchy-pkg-add exits non-zero when pacman cannot install a package, but the restore ran straight past it, cleared the marker, and reloaded Hyprland. That reported success and brought back keybindings for apps that never arrived. The marker now falls last, behind a check on the transaction. The new test also pins the two lists to each other and to omarchy-base.packages, which is the drift that let retired packages linger in the removal list. Co-Authored-By: Claude Opus 5 --------- Co-authored-by: Claude Opus 5 --- bin/omarchy-install-preinstalls | 35 ++++++++++++ bin/omarchy-remove-preinstalls | 11 +--- default/omarchy/omarchy-menu.jsonc | 1 + test/shell.d/preinstalls-test.sh | 91 ++++++++++++++++++++++++++++++ 4 files changed, 130 insertions(+), 8 deletions(-) create mode 100755 bin/omarchy-install-preinstalls create mode 100755 test/shell.d/preinstalls-test.sh diff --git a/bin/omarchy-install-preinstalls b/bin/omarchy-install-preinstalls new file mode 100755 index 00000000..27a76a6d --- /dev/null +++ b/bin/omarchy-install-preinstalls @@ -0,0 +1,35 @@ +#!/bin/bash + +# omarchy:summary=Restore the preinstalled Omarchy applications (web apps, TUIs, and selected packages). +# omarchy:requires-sudo=true + +if gum confirm "Are you sure you want to restore all preinstalled web apps, TUI wrappers, and desktop applications?"; then + echo -e "Restoring preinstalled Omarchy applications...\n" + + # Recreates the shipped .desktop launchers (web apps and TUIs) and the mise stubs + # that back claude, gh, opencode, and the rest of the agents + omarchy-refresh-applications + + # Mirrors the list in omarchy-remove-preinstalls; both track omarchy-base.packages + if ! omarchy-pkg-add \ + aether \ + cliamp \ + libreoffice-fresh \ + xournalpp \ + pinta \ + obsidian \ + obs-studio \ + kdenlive \ + lazydocker \ + omacut \ + omacalc \ + omawrite; then + echo -e "\nPreinstalls are still marked as removed. Fix the errors above and try again." + exit 1 + fi + + # Last, so a failure above leaves the opt-out intact rather than restoring + # keybindings for apps that never came back + rm -f ~/.local/state/omarchy/preinstalls-removed + hyprctl reload +fi diff --git a/bin/omarchy-remove-preinstalls b/bin/omarchy-remove-preinstalls index e3c9c908..6cdbca2a 100755 --- a/bin/omarchy-remove-preinstalls +++ b/bin/omarchy-remove-preinstalls @@ -20,19 +20,14 @@ if gum confirm "Are you sure you want to remove all preinstalled web apps, TUI w omarchy-pkg-drop \ aether \ cliamp \ - typora \ - spotify \ libreoffice-fresh \ - 1password \ - 1password-cli \ xournalpp \ - signal-desktop \ pinta \ obsidian \ obs-studio \ kdenlive \ lazydocker \ - opencode \ - claude-code \ - github-cli + omacut \ + omacalc \ + omawrite fi diff --git a/default/omarchy/omarchy-menu.jsonc b/default/omarchy/omarchy-menu.jsonc index a75b65c8..22d45810 100644 --- a/default/omarchy/omarchy-menu.jsonc +++ b/default/omarchy/omarchy-menu.jsonc @@ -202,6 +202,7 @@ "install.ai": {"icon":"󱚤","label":"AI"}, "install.gaming": {"icon":"","label":"Gaming"}, "install.windows": {"icon":"󰍲","label":"Windows","when":"[[ ! -f $HOME/.local/share/applications/windows-vm.desktop ]]","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-windows-vm install'"}, + "install.preinstalls": {"icon":"󰏓","label":"Preinstalls","when":"[[ -f $HOME/.local/state/omarchy/preinstalls-removed ]]","action":"omarchy-launch-floating-terminal-with-presentation omarchy-install-preinstalls"}, "install.browser.chrome": {"icon":"","label":"Chrome","when":"! omarchy-pkg-present google-chrome","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser chrome'"}, "install.browser.edge": {"icon":"󰇩","label":"Edge","when":"! omarchy-pkg-present microsoft-edge-stable-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser edge'"}, "install.browser.brave": {"icon":"","label":"Brave","when":"! omarchy-pkg-present brave-bin","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-install-browser brave'"}, diff --git a/test/shell.d/preinstalls-test.sh b/test/shell.d/preinstalls-test.sh new file mode 100755 index 00000000..fb4f19a2 --- /dev/null +++ b/test/shell.d/preinstalls-test.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +test_tmp=$(mktemp -d) +trap 'rm -rf "$test_tmp"' EXIT + +mock_bin="$test_tmp/bin" +test_home="$test_tmp/home" +marker="$test_home/.local/state/omarchy/preinstalls-removed" +pkg_log="$test_tmp/packages" +mkdir -p "$mock_bin" "$test_home/.local/state/omarchy" + +for command in omarchy-webapp-remove-all omarchy-tui-remove-all omarchy-refresh-applications hyprctl; do + printf '#!/bin/bash\nexit 0\n' >"$mock_bin/$command" +done + +cat >"$mock_bin/gum" <<'SH' +#!/bin/bash +[[ $1 == confirm ]] && exit "${OMARCHY_TEST_CONFIRM:-0}" +exit 0 +SH + +cat >"$mock_bin/omarchy-pkg-add" <<'SH' +#!/bin/bash +printf '%s\n' "$@" >"$OMARCHY_TEST_PKG_LOG" +exit "${OMARCHY_TEST_PKG_ADD_STATUS:-0}" +SH + +cat >"$mock_bin/omarchy-pkg-drop" <<'SH' +#!/bin/bash +printf '%s\n' "$@" >"$OMARCHY_TEST_PKG_LOG" +SH + +chmod +x "$mock_bin"/* + +export PATH="$mock_bin:$PATH" +export HOME="$test_home" +export OMARCHY_TEST_PKG_LOG="$pkg_log" + +# Both scripts restore and remove the same set, and every package in it has to be +# one Omarchy actually ships, or Remove Preinstalls takes out an app the user +# chose from the menu and Install Preinstalls puts back one we retired. +mapfile -t shipped < <(sed -e 's/[[:space:]]*#.*$//' -e '/^[[:space:]]*$/d' "$ROOT/install/omarchy-base.packages") + +"$ROOT/bin/omarchy-install-preinstalls" >/dev/null +mapfile -t restored <"$pkg_log" + +"$ROOT/bin/omarchy-remove-preinstalls" >/dev/null +mapfile -t dropped <"$pkg_log" + +[[ ${restored[*]} == "${dropped[*]}" ]] || + fail "Install and Remove Preinstalls cover the same packages" \ + "restored: ${restored[*]} +dropped: ${dropped[*]}" +pass "Install and Remove Preinstalls cover the same packages" + +for package in "${restored[@]}"; do + printf '%s\n' "${shipped[@]}" | grep -qxF "$package" || + fail "every preinstall is shipped in omarchy-base.packages" "$package is not shipped" +done +pass "every preinstall is shipped in omarchy-base.packages" + +for package in omacut omacalc omawrite; do + printf '%s\n' "${restored[@]}" | grep -qxF "$package" || + fail "preinstalls cover the Omacom apps" "$package is missing" +done +pass "preinstalls cover the Omacom apps" + +# The bindings key off the marker, so clearing it before the packages land would +# point them at apps that never came back. +touch "$marker" +OMARCHY_TEST_PKG_ADD_STATUS=1 "$ROOT/bin/omarchy-install-preinstalls" >/dev/null && status=0 || status=$? +(( status == 1 )) || fail "restore reports a failed package transaction" "exit status was $status" +[[ -f $marker ]] || fail "restore keeps the opt-out marker when packages fail to install" +pass "restore keeps the opt-out marker when packages fail to install" + +"$ROOT/bin/omarchy-install-preinstalls" >/dev/null +[[ ! -e $marker ]] || fail "restore clears the opt-out marker once the packages are back" +pass "restore clears the opt-out marker once the packages are back" + +rm -f "$marker" +OMARCHY_TEST_CONFIRM=1 "$ROOT/bin/omarchy-remove-preinstalls" >/dev/null +[[ ! -e $marker ]] || fail "declining Remove Preinstalls changes nothing" +pass "declining Remove Preinstalls changes nothing" + +"$ROOT/bin/omarchy-remove-preinstalls" >/dev/null +[[ -f $marker ]] || fail "Remove Preinstalls records the opt-out" +pass "Remove Preinstalls records the opt-out"