From d2305add6a0ff88fe129cb473548f4fa3eceb459 Mon Sep 17 00:00:00 2001 From: Spencer Bull Date: Sat, 26 Sep 2026 01:16:26 -0500 Subject: [PATCH] Keep the OpenClaw that can open the state when removal keeps the state Removing the runtime while keeping ~/.openclaw left state that its own updates had migrated past the packaged release, and reinstalling seeded a release that refused to open it; even `openclaw update` refused. Removal now takes openclaw off PATH and leaves the runtime inside ~/.openclaw with the state, where a reinstall picks it back up; deleting ~/.openclaw still takes both. --- bin/omarchy-remove-ai-openclaw | 15 +++++---------- manual/17-ai.md | 2 +- test/shell.d/remove-ai-test.sh | 21 +++++++++------------ 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/bin/omarchy-remove-ai-openclaw b/bin/omarchy-remove-ai-openclaw index 7d793bdc..2b9ea1a4 100755 --- a/bin/omarchy-remove-ai-openclaw +++ b/bin/omarchy-remove-ai-openclaw @@ -50,15 +50,10 @@ done omarchy-pkg-drop openclaw -# The runtime omarchy-install-openclaw-cli set up lives beside the user's state -# in ~/.openclaw: the command upstream's installer wrote, and the Node and -# package under tools/. Only a command that execs into those tools is the -# installer's; the link on PATH goes only when it points at that command. -if [[ -f $HOME/.openclaw/bin/openclaw ]] && grep -qF "\"$HOME/.openclaw/tools/" "$HOME/.openclaw/bin/openclaw"; then - rm -rf "$HOME/.openclaw/tools" - rm -f "$HOME/.openclaw/bin/openclaw" - rmdir "$HOME/.openclaw/bin" 2>/dev/null || true -fi +# The command on PATH goes, so nothing answers to openclaw. The OpenClaw it +# pointed at stays in ~/.openclaw with the state below: its own updates may +# have migrated that state past the packaged release, which could not open it +# again, and a reinstall picks the kept copy back up instead of seeding one. if [[ -L $HOME/.local/bin/openclaw && $(readlink -- "$HOME/.local/bin/openclaw") == "$HOME/.openclaw/bin/openclaw" ]]; then rm -f "$HOME/.local/bin/openclaw" fi @@ -78,7 +73,7 @@ gtk-update-icon-cache "$HOME/.local/share/icons/hicolor" &>/dev/null || true state_removed=false if [[ -d $HOME/.openclaw && -t 0 ]]; then size=$(du -sh "$HOME/.openclaw" 2>/dev/null | cut -f1) - if gum confirm --default=false "Also delete ~/.openclaw ($size: chats, memories, credentials, and downloaded plugins)?"; then + if gum confirm --default=false "Also delete ~/.openclaw ($size: chats, memories, credentials, downloaded plugins, and OpenClaw itself)?"; then rm -rf "$HOME/.openclaw" "$HOME/.openclaw.update-captures" state_removed=true fi diff --git a/manual/17-ai.md b/manual/17-ai.md index 70061b6f..1329a55f 100644 --- a/manual/17-ai.md +++ b/manual/17-ai.md @@ -54,7 +54,7 @@ The _Install > AI_ menu also carries a few graphical AI apps: the ChatGPT deskto Hermes Desktop is the one to know about, because a machine has one Hermes, and it is the app's: Hermes is only ever installed through the app, and the `hermes` command the default agent runs is the app's. Choosing Hermes as the default agent installs the same thing the _Install > AI_ entry does: the package, and a Hermes runtime under `~/.hermes` set up by Hermes' own installer, which takes a few minutes the first time. That runtime is the one Hermes the terminal `hermes` command, the default agent and the app all use, and it updates itself with `hermes update` rather than waiting on an Omarchy release. Installing it also hands Hermes the Omarchy theme as a skin named `omarchy`, which every Hermes surface follows as you switch themes; pick another under Hermes' Appearance settings or with `/skin` if you'd rather it didn't, and Omarchy leaves that choice alone. Removing the app under _Remove > AI_ closes Hermes first, gateway included, takes that runtime with it, and keeps your chats, memories, and the skills Hermes wrote for itself unless you tell it otherwise: it asks, defaulting to no, whether that data and your connection settings should go too. -OpenClaw's desktop experience is its Control UI, which opens as a web app backed by its own local gateway. OpenClaw lives in `~/.openclaw` and updates itself: use the Control UI's "Update Gateway" button or run `openclaw update`, and the gateway restarts on the new version. Omarchy only chooses the release a fresh install starts from. Removing OpenClaw under _Remove > AI_ takes the gateway service, the app and OpenClaw itself with it and then asks whether the rest of `~/.openclaw` should go too, since that holds your chats and credentials alongside the plugin runtimes OpenClaw downloads for itself; the default keeps it. +OpenClaw's desktop experience is its Control UI, which opens as a web app backed by its own local gateway. OpenClaw lives in `~/.openclaw` and updates itself: use the Control UI's "Update Gateway" button or run `openclaw update`, and the gateway restarts on the new version. Omarchy only chooses the release a fresh install starts from. Removing OpenClaw under _Remove > AI_ takes the gateway service and the app with it and then asks whether `~/.openclaw` should go too, since that holds your chats and credentials alongside OpenClaw itself and the plugin runtimes it downloads; the default keeps it, and installing OpenClaw again picks it back up. ### Local LLMs diff --git a/test/shell.d/remove-ai-test.sh b/test/shell.d/remove-ai-test.sh index 693b929d..03887c53 100644 --- a/test/shell.d/remove-ai-test.sh +++ b/test/shell.d/remove-ai-test.sh @@ -299,26 +299,23 @@ pass "OpenClaw removal stops the gateway service" fail "OpenClaw removal keeps the user's agent state" "asked about ~/.openclaw without a terminal" pass "OpenClaw removal keeps the user's agent state" -# The runtime omarchy-install-openclaw-cli set up sits beside that state and -# goes; a command that is not the installer's, or a link elsewhere, stays. +# The command on PATH goes; the OpenClaw it pointed at stays with the state, +# since only that copy is sure to open it. A link somewhere else is not Omarchy's. fresh_openclaw_home mkdir -p "$HOME/.openclaw/bin" "$HOME/.openclaw/tools/node-v24.19.0/lib" "$HOME/.local/bin" -printf '#!/usr/bin/env bash\nexec "%s/.openclaw/tools/node/bin/node" "%s/.openclaw/tools/node-v24.19.0/lib/node_modules/openclaw/dist/entry.js" "$@"\n' "$HOME" "$HOME" >"$HOME/.openclaw/bin/openclaw" +printf '#!/usr/bin/env bash\n' >"$HOME/.openclaw/bin/openclaw" ln -s "$HOME/.openclaw/bin/openclaw" "$HOME/.local/bin/openclaw" "$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null -for gone in .openclaw/tools .openclaw/bin .local/bin/openclaw; do - [[ ! -e $HOME/$gone && ! -L $HOME/$gone ]] || fail "OpenClaw removal deletes the runtime it set up" "$gone" -done -[[ -f $HOME/.openclaw/openclaw.json ]] || fail "OpenClaw removal deletes the runtime it set up" "state went with it" +[[ ! -e $HOME/.local/bin/openclaw && ! -L $HOME/.local/bin/openclaw ]] || fail "OpenClaw removal takes openclaw off PATH" +[[ -f $HOME/.openclaw/bin/openclaw && -d $HOME/.openclaw/tools && -f $HOME/.openclaw/openclaw.json ]] || + fail "OpenClaw removal keeps the OpenClaw that can open the state" fresh_openclaw_home -mkdir -p "$HOME/.openclaw/bin" "$HOME/.openclaw/tools" "$HOME/.local/bin" -printf '#!/bin/bash\nexec /opt/openclaw/openclaw.mjs "$@"\n' >"$HOME/.openclaw/bin/openclaw" +mkdir -p "$HOME/.local/bin" ln -s /opt/openclaw/openclaw "$HOME/.local/bin/openclaw" "$ROOT/bin/omarchy-remove-ai-openclaw" >/dev/null -[[ -f $HOME/.openclaw/bin/openclaw && -d $HOME/.openclaw/tools && -L $HOME/.local/bin/openclaw ]] || - fail "OpenClaw removal deletes the runtime it set up" "someone else's install went with it" -pass "OpenClaw removal deletes the runtime it set up, and only that" +[[ -L $HOME/.local/bin/openclaw ]] || fail "OpenClaw removal takes openclaw off PATH" "someone else's link went with it" +pass "OpenClaw removal takes openclaw off PATH and keeps the copy that can open the state" # A CLI that knows `gateway uninstall` owns the teardown; the manual systemd # fallback must not run.