scripts: stop creating the /usr/local/bin/claude symlink
The symlink existed because the Claude sidecar hardcoded that path, and that hardcoding came from the bwrap-sandboxed architecture: the jail ro-bound /usr and could not see the installer's real target in ~/.local/bin. The sandbox is gone, and claude-manager.ts now resolves the CLI itself — $CLAUDE_BIN, then PATH, then ~/.local/bin/claude, /usr/local/bin/claude, /opt/homebrew/bin/claude. Verified before removing rather than assumed: - the only references left in the tree are the resolver's own fallback list and this step; nothing in capabilities, no systemd unit, no crontab, no ecosystem file and no shell rc mentions the path - the agent sidecar's PATH under pm2 contains ~/.local/bin ahead of /usr/local/bin, so Bun.which resolves to the installer's target and the symlink is never consulted - replaying the resolver in that exact environment with the symlink treated as absent returns the same path, so it is not load-bearing - resolveClaudeBin runs at claude-manager module scope, which ES import ordering puts before user-instance.ts reassigns process.env.HOME — so the homedir() candidate is evaluated against the real home, not the managed one The install-and-verify step above is untouched, so a failed claude-code install is still reported. Only the sudo-owned link into /usr/local/bin goes, a directory macOS does not ship at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+7
-14
@@ -759,20 +759,13 @@ else
|
||||
if has claude; then ok "claude-code installed"; else warn "claude-code install failed"; fi
|
||||
fi
|
||||
|
||||
# The platform's Claude sidecar execs /usr/local/bin/claude (a stable, sandbox-visible path). The
|
||||
# installer only drops the CLI in ~/.local/bin, so symlink it there — pointing at the ~/.local/bin
|
||||
# launcher so it keeps tracking Claude's self-updates. Without this, claude chat ENOENTs on a fresh host.
|
||||
CLAUDE_LOCAL="$HOME/.local/bin/claude"
|
||||
if [ -e "$CLAUDE_LOCAL" ]; then
|
||||
if [ "$(readlink -f /usr/local/bin/claude 2>/dev/null)" != "$(readlink -f "$CLAUDE_LOCAL")" ]; then
|
||||
sudo ln -sf "$CLAUDE_LOCAL" /usr/local/bin/claude
|
||||
ok "claude symlinked to /usr/local/bin/claude"
|
||||
else
|
||||
skip "claude symlink at /usr/local/bin/claude"
|
||||
fi
|
||||
else
|
||||
warn "claude not found at $CLAUDE_LOCAL — /usr/local/bin/claude symlink skipped"
|
||||
fi
|
||||
# No /usr/local/bin/claude symlink. That existed because the sidecar hardcoded that path, which in
|
||||
# turn came from the bwrap-sandboxed architecture — the jail ro-bound /usr and could not see the
|
||||
# installer's real target in ~/.local/bin. The sandbox is gone and claude-manager.ts now resolves the
|
||||
# CLI itself: $CLAUDE_BIN, then PATH, then ~/.local/bin/claude, /usr/local/bin/claude and
|
||||
# /opt/homebrew/bin/claude. The installer above puts it in ~/.local/bin, which is both on PATH and the
|
||||
# first candidate, so the symlink was satisfying a requirement that no longer exists — at the cost of
|
||||
# a sudo-owned link into /usr/local/bin, a directory macOS does not even ship.
|
||||
|
||||
# pm2 (process manager)
|
||||
if has pm2; then
|
||||
|
||||
Reference in New Issue
Block a user