fix(install): make Claude Code install/update idempotent across channels
install.sh aborted with npm EEXIST when claude was already present: the binary is a native-installer symlink (~/.local/bin/claude -> ~/.local/share/claude/versions/*) that npm does not own, and the npm prefix (~/.local, set for BLK-013) targets the same path. The `else err` branch turned EEXIST into a fatal exit. No presence guard existed, unlike the RTK/GSD steps. - install.sh: skip-if-present guard (command -v claude), mirroring the RTK/GSD pattern; npm only runs on a truly fresh machine. - update-all.sh: pick updater by channel — npm for npm-managed installs, `claude update` for native installs (npm would EEXIST). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
2d76233b02
commit
8dc4027c4b
10
install.sh
10
install.sh
@ -54,9 +54,15 @@ ok "npm $(npm -v)"
|
|||||||
|
|
||||||
# ── 2. Install Claude Code CLI ──
|
# ── 2. Install Claude Code CLI ──
|
||||||
echo ""
|
echo ""
|
||||||
echo "── Installing Claude Code (latest)..."
|
echo "── Installing Claude Code..."
|
||||||
|
|
||||||
if npm install -g @anthropic-ai/claude-code@latest; then
|
# Idempotent: an existing claude (native installer under ~/.local/share/claude,
|
||||||
|
# or any prior install) already owns ~/.local/bin/claude — npm cannot clobber a
|
||||||
|
# symlink it does not manage (EEXIST). Mirror the RTK/GSD skip-if-present guard;
|
||||||
|
# upgrades are `make update`'s job (update-all.sh), not first-time install.
|
||||||
|
if command -v claude &>/dev/null; then
|
||||||
|
ok "Claude Code already installed ($(claude --version 2>/dev/null | head -1))"
|
||||||
|
elif npm install -g @anthropic-ai/claude-code@latest; then
|
||||||
ok "Claude Code installed: $(claude --version 2>/dev/null || echo 'unknown')"
|
ok "Claude Code installed: $(claude --version 2>/dev/null || echo 'unknown')"
|
||||||
else
|
else
|
||||||
err "Claude Code installation failed"
|
err "Claude Code installation failed"
|
||||||
|
|||||||
@ -27,7 +27,15 @@ echo "── Updating Claude Code CLI..."
|
|||||||
if command -v claude &>/dev/null; then
|
if command -v claude &>/dev/null; then
|
||||||
CURRENT_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
|
CURRENT_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
|
||||||
info "Current: $CURRENT_VER"
|
info "Current: $CURRENT_VER"
|
||||||
if npm install -g @anthropic-ai/claude-code@latest 2>/dev/null; then
|
# Use the updater that matches the install channel: npm-managed installs
|
||||||
|
# update via npm; native-installer installs self-update via `claude update`
|
||||||
|
# (npm would EEXIST on the ~/.local/bin/claude symlink it does not own).
|
||||||
|
if npm ls -g @anthropic-ai/claude-code &>/dev/null; then
|
||||||
|
UPDATE_CMD=(npm install -g @anthropic-ai/claude-code@latest)
|
||||||
|
else
|
||||||
|
UPDATE_CMD=(claude update)
|
||||||
|
fi
|
||||||
|
if "${UPDATE_CMD[@]}" &>/dev/null; then
|
||||||
NEW_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
|
NEW_VER=$(claude --version 2>/dev/null | head -1 || echo "unknown")
|
||||||
if [ "$CURRENT_VER" = "$NEW_VER" ]; then
|
if [ "$CURRENT_VER" = "$NEW_VER" ]; then
|
||||||
ok "Claude Code already up to date ($NEW_VER)"
|
ok "Claude Code already up to date ($NEW_VER)"
|
||||||
@ -35,7 +43,7 @@ if command -v claude &>/dev/null; then
|
|||||||
ok "Claude Code updated: $CURRENT_VER → $NEW_VER"
|
ok "Claude Code updated: $CURRENT_VER → $NEW_VER"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
warn "Claude Code update failed — try manually: npm install -g @anthropic-ai/claude-code@latest"
|
warn "Claude Code update failed — try manually: ${UPDATE_CMD[*]}"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
warn "Claude Code not found — install first with: make install"
|
warn "Claude Code not found — install first with: make install"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user