From c992cdff100e765ad05dc6bd435eaf137d73fa16 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Mon, 3 Aug 2026 16:52:02 -0500 Subject: [PATCH] Restart the shell unconditionally after every update Updates routinely replace the shell's QML, and a stale process can lazy-load new files into old code. Restarting at the end of every omarchy update removes the need for migrations to restart the shell or defer one with the restart-shell-required marker: the login-time migration path already runs a fresh shell that hot-reloads shell.json. Co-Authored-By: Claude Fable 5 --- bin/omarchy-update-restart | 6 ++++++ docs/migrations.md | 3 +++ docs/update-process.md | 4 ++-- migrations/1784672586.sh | 1 - migrations/1784989000.sh | 2 -- migrations/1785189600.sh | 4 ---- migrations/1785344985.sh | 2 -- test/shell.d/tmux-alert-removal-migration-test.sh | 15 +++++---------- 8 files changed, 16 insertions(+), 21 deletions(-) diff --git a/bin/omarchy-update-restart b/bin/omarchy-update-restart index 763d6b65..a2263b16 100755 --- a/bin/omarchy-update-restart +++ b/bin/omarchy-update-restart @@ -42,3 +42,9 @@ for file in "$HOME"/.local/state/omarchy/restart-*-required; do omarchy-restart-"$service" fi done + +# Updates routinely replace the shell's QML, and a stale process can lazy-load +# new files into old code. A restart failure (locked session, ssh, TTY) only +# prints its reason: the next update or login gets a fresh shell anyway. +echo "Restarting shell" +omarchy-restart-shell || true diff --git a/docs/migrations.md b/docs/migrations.md index f7f00229..4a89ca13 100644 --- a/docs/migrations.md +++ b/docs/migrations.md @@ -127,6 +127,9 @@ New migration format: - Use helper commands such as `omarchy-cmd-present`, `omarchy-cmd-missing`, `omarchy-pkg-add`, `omarchy-pkg-drop`, `omarchy-pkg-present`, and `omarchy-pkg-missing` when appropriate. +- Never restart the Omarchy shell. `omarchy update` restarts it unconditionally + after migrations run, and the login-time shell already runs current code and + hot-reloads `shell.json` edits. Example: diff --git a/docs/update-process.md b/docs/update-process.md index 80520acc..bcc0c86e 100644 --- a/docs/update-process.md +++ b/docs/update-process.md @@ -26,7 +26,7 @@ The design goal is: | `~/.local/state/omarchy/current/` | user | Generated active theme, selected theme name, and current background symlink. | | `~/.local/state/omarchy/migrations/` | user | Per-user migration markers. | | `~/.local/state/omarchy/reboot-required` | user | Optional reboot marker checked by `omarchy-update-restart`. | -| `~/.local/state/omarchy/restart-*-required` | user | Optional service/app restart markers checked by `omarchy-update-restart`. | +| `~/.local/state/omarchy/restart-*-required` | user | Optional service/app restart markers checked by `omarchy-update-restart`. The shell needs no marker: it is restarted unconditionally after every update. | ## Migration layout @@ -261,7 +261,7 @@ scripts. | `omarchy-update-mise` | Runs `mise up` for mise-managed tools. | **Keep.** Mise-managed tools are intentionally part of the blessed update path. | | `omarchy-update-orphan-pkgs` | Lists orphans and prompts before removal; noninteractive mode never removes. | **Keep for now.** Safe because it is prompt-only. | | `omarchy-update-analyze-logs` | Scans `/tmp/omarchy-update.log` for known failure patterns, currently initramfs generation. | **Keep/expand.** Useful safety net; should grow only for high-signal checks. | -| `omarchy-update-restart` | Prompts for reboot after kernel/Hyprland updates and restarts components with `restart-*-required` markers. | **Keep.** Important final step; may eventually include service-restart checks. | +| `omarchy-update-restart` | Prompts for reboot after kernel/Hyprland updates, restarts components with `restart-*-required` markers, and always restarts the shell. | **Keep.** Important final step; may eventually include service-restart checks. | | `omarchy-update-firmware` | Manual firmware update command using fwupd. Not part of the normal update pipeline. | **Keep separate.** Firmware is not a routine system update step. | | `omarchy-update-time` | Restarts `systemd-timesyncd`. | **Question.** Not really an update command. Consider renaming/moving under system/time maintenance. | diff --git a/migrations/1784672586.sh b/migrations/1784672586.sh index dd392889..87d05094 100644 --- a/migrations/1784672586.sh +++ b/migrations/1784672586.sh @@ -5,5 +5,4 @@ if ! omarchy-pkg-present quickshell-git; then # quickshell package in place; packages depending on quickshell stay # satisfied through the provides. sudo pacman -S --noconfirm --ask 4 quickshell-git - omarchy-state set restart-shell-required fi diff --git a/migrations/1784989000.sh b/migrations/1784989000.sh index 3f806b6f..2d2c008e 100644 --- a/migrations/1784989000.sh +++ b/migrations/1784989000.sh @@ -37,5 +37,3 @@ if [[ -s $config_file ]]; then .bar.layout.center |= place_indicators_before_clock ' "$config_file" >"$tmp" && mv "$tmp" "$config_file" || rm -f "$tmp" fi - -omarchy-restart-shell diff --git a/migrations/1785189600.sh b/migrations/1785189600.sh index 4916f7d9..5b6fe807 100644 --- a/migrations/1785189600.sh +++ b/migrations/1785189600.sh @@ -118,7 +118,3 @@ if [[ -s $config_file ]] && grep -q 'TmuxAlert' "$config_file"; then rm -f "$tmp" fi - -# Nothing to restart from a TTY or over ssh, and that is no reason to stop the -# rest of the queue: hand it to the post-update restart instead. -omarchy-restart-shell >/dev/null 2>&1 || omarchy-state set restart-shell-required diff --git a/migrations/1785344985.sh b/migrations/1785344985.sh index 96deab5d..8668e799 100644 --- a/migrations/1785344985.sh +++ b/migrations/1785344985.sh @@ -45,5 +45,3 @@ if [[ -s $config_file ]] && omarchy-cmd-present jq; then end ' "$config_file" >"$tmp" && mv "$tmp" "$config_file" || rm -f "$tmp" fi - -omarchy-restart-shell diff --git a/test/shell.d/tmux-alert-removal-migration-test.sh b/test/shell.d/tmux-alert-removal-migration-test.sh index 53a8e7f5..2b6d73ec 100644 --- a/test/shell.d/tmux-alert-removal-migration-test.sh +++ b/test/shell.d/tmux-alert-removal-migration-test.sh @@ -234,13 +234,8 @@ pass "alert removal handles the older indicators key" fail "alert removal leaves an already-empty list alone" "$(jq -c '.bar.layout.right[1]' "$shell_config")" pass "alert removal leaves an already-empty list alone" -(($(wc -l <"$SHELL_RESTARTS") == 1)) || fail "alert removal restarts the shell" -[[ ! -s $STATE_CALLS ]] || fail "a restarted shell needs no deferred restart" "$(cat "$STATE_CALLS")" -pass "alert removal restarts the shell" - -# Migrations run from a TTY or over ssh have no shell to restart, and stopping -# there would strand every migration queued behind this one. -reset_home -SHELL_RESTART_STATUS=1 run_migration -grep -Fxq 'set restart-shell-required' "$STATE_CALLS" || fail "an unavailable shell defers its restart" "$(cat "$STATE_CALLS")" -pass "an unavailable shell defers its restart" +# The running shell hot-reloads shell.json and the post-update restart is +# unconditional, so the migration itself never touches the shell. +[[ ! -s $SHELL_RESTARTS ]] || fail "alert removal leaves shell restarts to the update" "$(cat "$SHELL_RESTARTS")" +[[ ! -s $STATE_CALLS ]] || fail "alert removal defers no shell restart" "$(cat "$STATE_CALLS")" +pass "alert removal leaves shell restarts to the update"