#!/usr/bin/env bash # rb-install.sh, install ReadyBase # # Usage: # curl -fsSL https://promptforce.ai/rb-install.sh | bash # # Questions are read from the terminal. With no terminal (CI, a pipe with no # tty) every question is answered no: nothing beyond the binary is installed. set -euo pipefail GITHUB_REPO="PromptForcePrime/readybase-public" BASE_URL="https://github.com/${GITHUB_REPO}/releases/latest/download" INSTALL_DIR="${HOME}/.readybase" PREFEX_INSTALL_URL="https://promptforce.ai/install.sh" # Temp files the EXIT trap removes; set as they are created. TMP_BIN="" PREFEX_TMP="" cleanup() { rm -f "${TMP_BIN}" "${PREFEX_TMP}"; } # ── Colours ───────────────────────────────────────────────────────────────── if [ -t 1 ]; then BOLD="\033[1m"; GREEN="\033[0;32m"; YELLOW="\033[0;33m"; RED="\033[0;31m"; RESET="\033[0m" else BOLD=""; GREEN=""; YELLOW=""; RED=""; RESET="" fi info() { printf "${GREEN}==>${RESET} %s\n" "$*"; } warn() { printf "${YELLOW}warn:${RESET} %s\n" "$*"; } die() { printf "${RED}error:${RESET} %s\n" "$*" >&2; exit 1; } heading() { printf "\n${BOLD}%s${RESET}\n" "$*"; } # has_tty: a terminal can be opened for questions. stdin is no guide: under # `curl | bash` it is the script itself. has_tty() { ( : /dev/null; } # ask PROMPT DEFAULT: returns 0 for yes. DEFAULT applies to an empty reply at # a terminal only; with no terminal the answer is always no. ask() { local reply="" if ! has_tty; then printf " %s no (no terminal)\n" "$1" return 1 fi printf " %s " "$1" read -r reply /dev/null 2>&1; then shasum -a 256 "$1" | awk '{print $1}' elif command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}' else return 1 fi } # configure_mcp BIN: registers the ReadyBase MCP server with Claude Code at # user scope. Claude Code reads MCP servers from ~/.claude.json, which it owns # and rewrites while running, so the CLI edits it rather than this script; # settings.json has no mcpServers key. configure_mcp() { local cmd="claude mcp add --scope user readybase -- $1 mcp" if ! command -v claude >/dev/null 2>&1; then warn "Claude Code CLI not found. Once it is installed, run:" echo " ${cmd}" return 0 fi if claude mcp get readybase >/dev/null 2>&1; then echo " ReadyBase MCP server already configured." return 0 fi if claude mcp add --scope user readybase -- "$1" mcp >/dev/null; then echo " Configured ReadyBase MCP server in Claude Code (user scope)." else warn "MCP server not configured. Run: ${cmd}" fi } # install_prefex: interactive only. Downloads the installer to a file and runs # that, with the terminal as its stdin, rather than piping curl into bash. install_prefex() { PREFEX_TMP=$(mktemp "${TMPDIR:-/tmp}/prefex-install.XXXXXX") if ! curl -fsSL "${PREFEX_INSTALL_URL}" -o "${PREFEX_TMP}"; then warn "Could not download the Prefex installer. Install later: curl -fsSL ${PREFEX_INSTALL_URL} | bash" return 0 fi bash "${PREFEX_TMP}" ${dest}" # ── Configure Claude Code MCP server ────────────────────────────────────── echo "" printf " ${BOLD}Configure Claude Code MCP integration?${RESET}\n" echo " This registers ReadyBase as an MCP tool server with Claude Code (user scope)." echo " Claude Code will have access to: readybase_explore (start here)," echo " readybase_relate (blast radius + deps), readybase_story (history + authors)," echo " and the full toolset (score, coverage, convention, ownership, and more)." echo "" if ask "Configure? [Y/n]" y; then configure_mcp "$dest" else echo " Skipped. You can configure later by running: readybase setup " fi # ── Run first scan ──────────────────────────────────────────────────────── echo "" printf " ${BOLD}Run first scan on current directory?${RESET}\n" echo " This analyzes your codebase and generates AI-readiness score + context files." echo "" if ! has_tty; then echo " Skipped (no terminal). Run later: readybase scan " elif [ "$(pwd -P)" = "$(cd "$HOME" && pwd -P)" ]; then echo " Skipped: the current directory is your home directory, not a project." echo " Run it inside a project: readybase scan " elif ask "Scan now? [Y/n]" y; then info "Running readybase scan..." "$dest" scan . || warn "Scan failed (non-fatal), run manually: readybase scan " else echo " Skipped. Run later: readybase scan " fi # ── Optional: install Prefex ────────────────────────────────────────────── # Never chained unattended: the Prefex installer repoints Claude Code. echo "" printf " ${BOLD}Also install Prefex?${RESET}\n" echo ' Prefex is free until it saves you $500 beyond native prompt caching.' echo "" if ask "Install Prefex? [y/N]" n; then info "Installing Prefex..." install_prefex else echo " Skipped. Install later: readybase save start" fi # ── Done ────────────────────────────────────────────────────────────────── heading "ReadyBase installed successfully" echo "" echo " Commands:" echo " readybase scan Analyze codebase AI-readiness" echo " readybase go Run everything (scan + setup + index + probe)" echo " readybase probe Generate adversarial tests" echo " readybase save start Start Prefex cost optimizer" echo " readybase serve Launch dashboard at localhost:8018" echo " readybase usage Show agent tool usage + guard compliance" echo "" echo " Dashboard: readybase serve (then open localhost:8018)" echo " Uninstall: curl -fsSL https://promptforce.ai/rb-uninstall.sh | bash" echo "" } main "$@"