From 7a7e9872680ee181f68bd8346eee3ad1e70bbb76 Mon Sep 17 00:00:00 2001 From: Nic O'Connor Date: Thu, 17 Sep 2026 16:53:12 +0000 Subject: [PATCH] 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) --- mcp-config/install.sh | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/mcp-config/install.sh b/mcp-config/install.sh index fe3c633..8bbcb2e 100755 --- a/mcp-config/install.sh +++ b/mcp-config/install.sh @@ -120,11 +120,23 @@ say "Key stored at $KEYFILE (0600)." # bootstrap run — and then models and skills silently vanish, because sync.sh # never runs and OPENCODE_CONFIG is never exported. ~/.zshrc.local is the # unmanaged file the managed zshrc sources last, so the hook persists. -case "${SHELL:-}" in - *zsh) RC="$HOME/.zshrc.local" ;; - *bash) RC="$HOME/.bashrc" ;; - *) [ -f "$HOME/.zshrc" ] && RC="$HOME/.zshrc.local" || RC="$HOME/.bashrc" ;; -esac +# +# 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" ;; + *bash) RC="$HOME/.bashrc" ;; + *) [ -f "$HOME/.zshrc" ] && RC="$HOME/.zshrc.local" || RC="$HOME/.bashrc" ;; + esac +fi touch "$RC" # It sits alongside the user's secrets; keep it non-readable by others. [ "$RC" = "$HOME/.zshrc.local" ] && chmod 0600 "$RC" 2>/dev/null || true