fix: run claude install --force and persist fnm PATH to shell configs (#1245)

After installing Claude Code (via any method), run `claude install --force`
to set up shell integration, then ensure fnm bootstrap is persisted to both
.bashrc and .zshrc so interactive sessions can find node.

Also simplify all launch commands across 9 clouds: instead of hardcoding
PATH entries that may miss fnm, source the rc files which now contain all
the necessary PATH entries from both inject_env_vars and _finalize_claude_install.

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
A 2026-02-15 23:34:09 -08:00 committed by GitHub
parent 34e17e0146
commit db06ff84e0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 24 additions and 10 deletions

View file

@ -69,4 +69,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "${LIGHTSAIL_SERVER_IP}" "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "${LIGHTSAIL_SERVER_IP}" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -64,4 +64,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -72,4 +72,4 @@ save_vm_connection "${DO_SERVER_IP}" "root" "${DO_DROPLET_ID}" "${DROPLET_NAME}"
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "${DO_SERVER_IP}" "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "${DO_SERVER_IP}" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -63,4 +63,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.bashrc && claude"
interactive_session "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -72,4 +72,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "${GCP_SERVER_IP}" "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "${GCP_SERVER_IP}" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -42,4 +42,4 @@ inject_env_vars_cb "$RUN" "$UPLOAD" \
# Claude-specific config
setup_claude_code_config "${OPENROUTER_API_KEY}" "$UPLOAD" "$RUN"
launch_session "Hetzner server" "$SESSION" "export PATH=\$HOME/.claude/local/bin:\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
launch_session "Hetzner server" "$SESSION" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -72,4 +72,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "${OCI_SERVER_IP}" "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "${OCI_SERVER_IP}" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -70,4 +70,4 @@ echo ""
log_step "Starting Claude Code..."
sleep 1
clear
interactive_session "${OVH_SERVER_IP}" "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
interactive_session "${OVH_SERVER_IP}" "source ~/.bashrc 2>/dev/null; source ~/.zshrc 2>/dev/null; claude"

View file

@ -1263,9 +1263,20 @@ install_claude_code() {
# Include fnm paths so node is found even in non-interactive SSH sessions
local claude_path='export PATH=$HOME/.claude/local/bin:$HOME/.local/bin:$HOME/.bun/bin:$HOME/.local/share/fnm:$PATH; if command -v fnm >/dev/null 2>&1; then eval "$(fnm env)"; fi'
# Finalize installation: set up shell integration (PATH, completions)
# Also persists fnm bootstrap to shell configs so interactive sessions find node
_finalize_claude_install() {
log_step "Setting up Claude Code shell integration..."
${run_cb} "${claude_path} && claude install --force" >/dev/null 2>&1 || true
# Ensure fnm bootstrap is in .bashrc and .zshrc so new shells can find node
local fnm_snippet='export PATH="\$HOME/.local/share/fnm:\$PATH"; if command -v fnm >/dev/null 2>&1; then eval "\$(fnm env)"; fi'
${run_cb} "if command -v fnm >/dev/null 2>&1 || test -d \$HOME/.local/share/fnm; then for rc in ~/.bashrc ~/.zshrc; do grep -q 'fnm env' \"\$rc\" 2>/dev/null || printf '\\n# fnm (node version manager)\\n${fnm_snippet}\\n' >> \"\$rc\"; done; fi" >/dev/null 2>&1 || true
}
# Already installed?
if ${run_cb} "${claude_path} && command -v claude && claude --version" >/dev/null 2>&1; then
log_info "Claude Code already installed"
_finalize_claude_install
return 0
fi
@ -1274,6 +1285,7 @@ install_claude_code() {
if ${run_cb} "curl -fsSL https://claude.ai/install.sh | bash" 2>&1; then
if ${run_cb} "${claude_path} && command -v claude && claude --version" >/dev/null 2>&1; then
log_info "Claude Code installed via curl installer"
_finalize_claude_install
return 0
fi
log_warn "curl installer exited 0 but claude not found on PATH"
@ -1306,6 +1318,7 @@ install_claude_code() {
if ${run_cb} "${claude_path} && npm install -g @anthropic-ai/claude-code 2>&1" 2>&1; then
if ${run_cb} "${claude_path} && command -v claude && claude --version" >/dev/null 2>&1; then
log_info "Claude Code installed via npm"
_finalize_claude_install
return 0
fi
log_warn "npm install exited 0 but claude binary not working"
@ -1318,6 +1331,7 @@ install_claude_code() {
if ${run_cb} "${claude_path} && bun add -g @anthropic-ai/claude-code 2>&1" 2>&1; then
if ${run_cb} "${claude_path} && command -v claude && claude --version" >/dev/null 2>&1; then
log_info "Claude Code installed via bun"
_finalize_claude_install
return 0
fi
log_warn "bun install exited 0 but claude binary not working"

View file

@ -70,11 +70,11 @@ if [[ -n "${SPAWN_PROMPT:-}" ]]; then
escaped_prompt=$(printf '%q' "${SPAWN_PROMPT}")
# Execute without -tty flag
sprite exec -s "${SPRITE_NAME}" -- zsh -c "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude -p ${escaped_prompt}"
sprite exec -s "${SPRITE_NAME}" -- zsh -c "source ~/.zshrc 2>/dev/null; claude -p ${escaped_prompt}"
else
# Interactive mode: start Claude Code normally
log_step "Starting Claude Code..."
sleep 1
clear 2>/dev/null || true
sprite exec -s "${SPRITE_NAME}" -tty -- zsh -c "export PATH=\$HOME/.local/bin:\$HOME/.bun/bin:\$PATH && source ~/.zshrc && claude"
sprite exec -s "${SPRITE_NAME}" -tty -- zsh -c "source ~/.zshrc 2>/dev/null; claude"
fi