mcp-config: put the shell hook in ~/.zshrc.local on a fresh box

install.sh chose the rc file from $SHELL. On a fresh box bootstrap runs
from the user's original bash: zsh/ has already switched the login shell
to zsh, but $SHELL in that process still says bash. The hook went into
~/.bashrc, below zsh/'s auto-exec hook, so every new terminal exec'd into
zsh before reaching it, sync.sh never ran, OPENCODE_CONFIG was never
exported, and opencode came up unconfigured. Boxes already on zsh were
fine, which is why it only showed up on a new machine.

Now the dotfiles-managed ~/.zshrc, or zsh as the account's login shell
(getent), selects ~/.zshrc.local regardless of $SHELL. Standalone
`curl | sh` installs without these dotfiles behave as before.

Reproduced and verified in a clean ubuntu:24.04 container (zsh/ then
mcp-config/, dummy key): before, hook in .bashrc and OPENCODE_CONFIG
unset in a new zsh; after, hook in .zshrc.local and OPENCODE_CONFIG
points at a config with the covert-gpt provider and gitea/proxmox MCP
servers. A box already broken this way is repaired by re-running the
module, and re-runs leave a single hook.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 16:53:12 +00:00
co-authored by Claude Opus 5
parent 0426ebc973
commit 7a7e987268
+14 -2
View File
@@ -120,11 +120,23 @@ say "Key stored at $KEYFILE (0600)."
# bootstrap run — and then models and skills silently vanish, because sync.sh # bootstrap run — and then models and skills silently vanish, because sync.sh
# never runs and OPENCODE_CONFIG is never exported. ~/.zshrc.local is the # never runs and OPENCODE_CONFIG is never exported. ~/.zshrc.local is the
# unmanaged file the managed zshrc sources last, so the hook persists. # unmanaged file the managed zshrc sources last, so the hook persists.
case "${SHELL:-}" in #
# Do NOT pick the file from $SHELL alone. On a fresh box bootstrap runs this
# from the user's ORIGINAL shell: zsh/ has just switched the login shell to zsh,
# but $SHELL in this process still says bash. The hook then went into ~/.bashrc,
# below zsh/'s auto-exec hook, so every new terminal exec'd into zsh before
# reaching it, zsh never sourced sync.sh, and opencode came up unconfigured.
# The dotfiles-managed ~/.zshrc (or zsh as the account's login shell) wins.
_login_shell="$(getent passwd "$(id -un)" 2>/dev/null | cut -d: -f7)"
if grep -qs 'Managed by dotfiles/zsh/install.sh' "$HOME/.zshrc"; then
RC="$HOME/.zshrc.local"
else
case "${_login_shell:-${SHELL:-}}" in
*zsh) RC="$HOME/.zshrc.local" ;; *zsh) RC="$HOME/.zshrc.local" ;;
*bash) RC="$HOME/.bashrc" ;; *bash) RC="$HOME/.bashrc" ;;
*) [ -f "$HOME/.zshrc" ] && RC="$HOME/.zshrc.local" || RC="$HOME/.bashrc" ;; *) [ -f "$HOME/.zshrc" ] && RC="$HOME/.zshrc.local" || RC="$HOME/.bashrc" ;;
esac esac
fi
touch "$RC" touch "$RC"
# It sits alongside the user's secrets; keep it non-readable by others. # It sits alongside the user's secrets; keep it non-readable by others.
[ "$RC" = "$HOME/.zshrc.local" ] && chmod 0600 "$RC" 2>/dev/null || true [ "$RC" = "$HOME/.zshrc.local" ] && chmod 0600 "$RC" 2>/dev/null || true