fix(install): detect and offer to activate OpenCode on PATH

- ensure_opencode no longer reports 'already installed' when the binary exists but isn't reachable; it now reports the PATH gap
- activate_opencode: explains the rc line / 'source ~/.bashrc', and interactively offers to symlink opencode into /usr/local/bin so it works immediately in every shell
- post-install hint reflects whether opencode is actually on PATH
- README: PATH & activation section
This commit is contained in:
Claus Lohmar 2026-10-13 07:32:43 +00:00
parent b25b2fa7c8
commit b2939d525a
2 changed files with 67 additions and 13 deletions

View file

@ -179,6 +179,14 @@ The installer offers **Local** (`.opencode/` in the current project), **Global**
| `--dry-run` | show what would happen, change nothing |
| `--help` | usage |
### PATH & activation
The official OpenCode installer appends `export PATH="$HOME/.opencode/bin:$PATH"` to your shell rc (`~/.bashrc` for bash) — but it does **not** activate it in the running shell, and an installer cannot change its parent shell. So:
- **New terminal** → `opencode` is on your PATH.
- **Same terminal** → `source ~/.bashrc` (or your shell's rc file).
- If the binary is present but not yet reachable, the installer says so at the end and, interactively, offers to **symlink it into `/usr/local/bin`** so it works immediately in every shell.
### Manual install
```bash

View file

@ -204,25 +204,70 @@ opencode_path() {
fi
}
opencode_on_path() { command -v opencode >/dev/null 2>&1; }
# The official installer writes the PATH line to the shell rc but never activates
# it. Report that, and offer to make `opencode` work immediately via a symlink.
activate_opencode() {
opencode_on_path && return 0
have_opencode || return 0
warn "OpenCode is installed at ${OPENCODE_BIN_DIR} but is not on your PATH yet."
if [ "$OPENCODE_NO_PATH" = 1 ]; then
info "PATH was left untouched (--opencode-no-path). Add it yourself: export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\""
return 0
fi
local rc=""
case "$(basename "${SHELL:-bash}")" in
bash) [ -f "$HOME/.bashrc" ] && rc="$HOME/.bashrc" ;;
zsh) [ -f "$HOME/.zshrc" ] && rc="$HOME/.zshrc" ;;
*) [ -f "$HOME/.profile" ] && rc="$HOME/.profile" ;;
esac
if [ -n "$rc" ] && grep -q "${OPENCODE_BIN_DIR}" "$rc" 2>/dev/null; then
info "A PATH line is already in ${rc} — run source ${rc} or open a new terminal."
else
info "Add it to your shell profile: export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\""
fi
if [ -t 0 ] && [ -t 1 ]; then
printf "${BOLD}Make 'opencode' available now (symlink into /usr/local/bin)?${NC} [y/N]: "
ans=""; read -r ans || true
case "$ans" in
[Yy]*)
local sudo=""
[ "$(id -u)" != "0" ] && sudo="sudo"
if $sudo ln -sf "${OPENCODE_BIN_DIR}/opencode" /usr/local/bin/opencode 2>/dev/null; then
success "Linked /usr/local/bin/opencode — 'opencode' now works in this and every shell."
else
warn "Could not create the symlink — use: export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\""
fi
;;
esac
fi
return 0
}
ensure_opencode() {
if [ "$DRY_RUN" = 1 ]; then
if have_opencode; then
info "[dry-run] OpenCode already present — $(opencode_path)"
elif [ "$OPENCODE_MODE" = "no" ]; then
if [ "$OPENCODE_MODE" = "no" ]; then
info "[dry-run] would skip OpenCode (--no-opencode)"
elif have_opencode; then
info "[dry-run] OpenCode already present — $(opencode_path)"
else
info "[dry-run] would install OpenCode from ${OPENCODE_INSTALLER_URL}"
fi
return 0
fi
if have_opencode && [ "$OPENCODE_MODE" != "yes" ]; then
success "OpenCode is already installed — $(opencode_path)"
if [ "$OPENCODE_MODE" = "no" ]; then
info "Skipping the OpenCode install (--no-opencode)"
return 0
fi
if [ "$OPENCODE_MODE" = "no" ]; then
info "Skipping the OpenCode install (--no-opencode)"
if have_opencode && [ "$OPENCODE_MODE" != "yes" ]; then
success "OpenCode is already installed — $(opencode_path)"
activate_opencode
return 0
fi
@ -260,13 +305,11 @@ ensure_opencode() {
if have_opencode; then
success "OpenCode installed — $(opencode_path)"
case ":$PATH:" in
*":${OPENCODE_BIN_DIR}:"*) : ;;
*) warn "Add OpenCode to your PATH: export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\"" ;;
esac
else
warn "The OpenCode installer finished, but 'opencode' is not on PATH yet. Re-open your shell and try again."
warn "The OpenCode installer finished, but the binary was not found at ${OPENCODE_BIN_DIR}/opencode."
fi
activate_opencode
return 0
}
# ---------------------------------------------------------------------------
@ -600,9 +643,12 @@ show_post_install() {
if [ -f "$INSTALL_DIR/env.example" ]; then
echo "2. (Optional) configure integrations: ${CYAN}cp ${INSTALL_DIR}/env.example .env${NC}"
fi
if have_opencode; then
if opencode_on_path; then
echo "3. Start OpenCode and pick an agent:"
echo -e " ${CYAN}opencode${NC} → choose ${BOLD}OpenArchitect${NC} to spec/verify, ${BOLD}OpenAgent${NC} to build"
elif have_opencode; then
echo "3. OpenCode is installed but not on PATH yet — get it available:"
echo -e " ${CYAN}export PATH=\"${OPENCODE_BIN_DIR}:\$PATH\"${NC} (or open a new terminal)"
else
echo "3. Install OpenCode, then pick an agent:"
echo -e " ${CYAN}curl -fsSL ${OPENCODE_INSTALLER_URL} | bash${NC}"