#!/usr/bin/env sh # Persist Claude Desktop sign-in across restarts. # Claude Desktop (Electron) stores its auth token via safeStorage, which on Linux needs the # Secret Service API (org.freedesktop.secrets). Provide it with gnome-keyring on the openbox # session bus (startwm.sh runs `dbus-launch --exit-with-session`), unlocked with an empty # password so it comes back automatically after a restart. The keyring DB lives under # $HOME/.local/share/keyrings, and HOME=/data/data is persistent add-on storage, so the # saved sign-in survives add-on restarts. eval "$(gnome-keyring-daemon --start --components=secrets 2>/dev/null)" || true printf '' | gnome-keyring-daemon --unlock 2>/dev/null || true export GNOME_KEYRING_CONTROL SSH_AUTH_SOCK dbus-update-activation-environment --all >/dev/null 2>&1 || true # --password-store=gnome-libsecret forces Electron onto the libsecret backend instead of # falling back to plaintext (and warning that the sign-in will not be saved). CLAUDE_DESKTOP_COMMAND_FILE="/tmp/claude-desktop-command" DEFAULT_CLAUDE_DESKTOP_COMMAND="claude-desktop --no-sandbox --disable-dev-shm-usage --password-store=gnome-libsecret" if [ -s "$CLAUDE_DESKTOP_COMMAND_FILE" ]; then CLAUDE_DESKTOP_COMMAND="$(cat "$CLAUDE_DESKTOP_COMMAND_FILE")" else CLAUDE_DESKTOP_COMMAND="$DEFAULT_CLAUDE_DESKTOP_COMMAND" fi # Headroom is intentionally not injected into the Desktop process. Claude Desktop overrides # ANTHROPIC_BASE_URL, so Desktop uses the registered Headroom MCP tools instead. # Launch the configured command. If a custom/wrapped command fails to start, fall back to # the plain Claude Desktop launch so the app always comes up for the user. if ! sh -c "$CLAUDE_DESKTOP_COMMAND"; then if [ "$CLAUDE_DESKTOP_COMMAND" != "$DEFAULT_CLAUDE_DESKTOP_COMMAND" ]; then echo "autostart: '$CLAUDE_DESKTOP_COMMAND' failed; falling back to default Claude Desktop launch" >&2 exec sh -c "$DEFAULT_CLAUDE_DESKTOP_COMMAND" fi fi