#!/bin/sh # Installs a global `opencode-sandbox` shim at ~/.local/bin so that command, # run from any directory, launches OpenCode v2 from the local sbx template # registered by `make build` — with the directory you're standing in as the # sandbox's workspace. # # POSIX sh only (no bashisms) -- this may run under any login shell's `sh`, # not necessarily the user's interactive shell. # # Named opencode-sandbox, not opencode, so it doesn't shadow a real, # locally-installed opencode CLI on PATH. # # Pattern (shell/OS detection, marker-based idempotent PATH edit, resolving # the login shell via $SHELL rather than the script's own running shell) # adapted from https://cloud.inputobjects.eu/forge/jrozanski/opencode-sandbox/src/branch/main/scripts/install-shortcut.sh set -eu BIN_DIR="$HOME/.local/bin" SHIM="$BIN_DIR/opencode-sandbox" mkdir -p "$BIN_DIR" cat > "$SHIM" <<'EOF' #!/bin/sh # sbx run accepts -t/--template only at sandbox creation time; re-running # against an existing sandbox with a template fails. So pass the template # only when the named sandbox doesn't exist yet. TEMPLATE=localhost/opencode-v2:local # Extract --name VALUE / --name=VALUE from the arguments, if given. name= prev= for arg in "$@"; do [ "$prev" = --name ] && name=$arg case "$arg" in --name=*) name=${arg#--name=} ;; esac prev=$arg done if [ -n "$name" ] && sbx ls -q 2>/dev/null | grep -Fxq -- "$name"; then exec sbx run "$@" opencode fi exec sbx run -t "$TEMPLATE" "$@" opencode EOF chmod +x "$SHIM" echo "==> Installed shim: $SHIM" # Already on PATH? Nothing left to do. case ":$PATH:" in *":$BIN_DIR:"*) echo "==> $BIN_DIR is already on PATH." exit 0 ;; esac # Resolve the user's *login* shell via $SHELL, not the shell running this # script, so the right config file gets edited regardless of how this # script itself was invoked. shell_name=$(basename "${SHELL:-}") if [ "$shell_name" = fish ] && command -v fish >/dev/null 2>&1; then # fish_add_path persists via a universal variable -- no config file to edit. fish -c "fish_add_path $BIN_DIR" echo "==> Added $BIN_DIR to PATH via fish_add_path." exit 0 fi case "$shell_name" in zsh) # Prefer .zshrc (the standard interactive-shell file); if it doesn't # exist but .zshenv does, respect that existing setup instead of # scattering PATH across two files. Only create .zshrc if neither exists. if [ -f "$HOME/.zshrc" ]; then rc="$HOME/.zshrc" elif [ -f "$HOME/.zshenv" ]; then rc="$HOME/.zshenv" else rc="$HOME/.zshrc" fi ;; bash) # macOS Terminal.app runs bash as a login shell, sourcing # ~/.bash_profile (not ~/.bashrc) unless the user's profile chains to it. case "$(uname -s)" in Darwin) rc="$HOME/.bash_profile" ;; *) rc="$HOME/.bashrc" ;; esac ;; *) rc="$HOME/.profile" ;; esac marker_begin="# >>> opencode-sandbox >>>" marker_end="# <<< opencode-sandbox <<<" if [ -f "$rc" ] && grep -qF "$marker_begin" "$rc"; then echo "==> $rc already configures PATH for opencode-sandbox; skipping." else touch "$rc" { printf '\n%s\n' "$marker_begin" printf 'export PATH="%s:$PATH"\n' "$BIN_DIR" printf '%s\n' "$marker_end" } >> "$rc" echo "==> Added $BIN_DIR to PATH in $rc." echo "==> Restart your shell (or run: . $rc) to pick it up." fi