diff --git a/opencortex.sh b/opencortex.sh index 9a309e2..f9a7190 100755 --- a/opencortex.sh +++ b/opencortex.sh @@ -12,7 +12,7 @@ NC='\033[0m' command_exists() { command -v "$1" >/dev/null 2>&1; } -# --- NEW: Bootstrap Mode --- +# --- Bootstrap Mode --- bootstrap_opencortex() { echo -e "${BLUE}=== OpenCortex: Zero-to-One Bootstrapper ===${NC}" if [ -d ".git" ]; then @@ -20,24 +20,14 @@ bootstrap_opencortex() { return fi - read -p "Where should I install OpenCortex? (default: ./opencortex): " TARGET_DIR - TARGET_DIR=${TARGET_DIR:-opencortex} - + TARGET_DIR="opencortex" if [ -d "$TARGET_DIR" ]; then if [ -d "$TARGET_DIR/.git" ]; then - echo -e "${YELLOW}! Directory '$TARGET_DIR' already contains a repository. Using it...${NC}" + echo -e "${YELLOW}! Using existing repository in '$TARGET_DIR'...${NC}" else - echo -e "${RED}✗ Error: Directory '$TARGET_DIR' exists and is NOT a repository.${NC}" - read -p "Choose a different name or 'WIPE' to delete it: " NEW_INPUT - if [[ "$NEW_INPUT" == "WIPE" ]]; then - rm -rf "$TARGET_DIR" - else - TARGET_DIR=${NEW_INPUT:-opencortex-2} - fi + echo -e "${RED}! Directory '$TARGET_DIR' exists. Using it as-is...${NC}" fi - fi - - if [ ! -d "$TARGET_DIR" ]; then + else echo -e "${BLUE}Cloning repository into $TARGET_DIR...${NC}" git clone http://10.10.10.201:3001/amr/opencortex.git "$TARGET_DIR" fi @@ -46,10 +36,14 @@ bootstrap_opencortex() { git submodule update --init --recursive echo -e "${GREEN}✓ Repository prepared. Handing off to local setup...${NC}" - exec ./scripts/onboard-baremetal.sh + # Reconnect stdin to the TTY for the next script, or use /dev/null to avoid hang + if [ -t 0 ]; then + exec ./scripts/onboard-baremetal.sh + else + exec ./scripts/onboard-baremetal.sh < /dev/tty 2>/dev/null || exec ./scripts/onboard-baremetal.sh < /dev/null + fi } -# Check if we are piped via curl (no .git in current directory) if [ ! -d ".git" ]; then bootstrap_opencortex fi @@ -57,63 +51,23 @@ fi update_opencortex() { echo -e "${BLUE}Updating OpenCortex...${NC}" if [ -d ".git" ]; then - echo "Pulling latest changes from repository..." git pull origin main fi - if [ -f .env ]; then - SKILLS_DIR=$(grep "^SKILLS_DIR=" .env | cut -d"\"" -f2) - SKILLS_DIR=${SKILLS_DIR:-$(pwd)/notes} - echo "Synchronizing core skills to $SKILLS_DIR..." - mkdir -p "$SKILLS_DIR" - cp -n skills/*.org "$SKILLS_DIR/" 2>/dev/null || true - fi - if command_exists docker-compose && [ -f "docker-compose.yml" ]; then - echo "Rebuilding Docker image..." - docker-compose up -d --build - fi echo -e "${GREEN}✓ Update complete.${NC}" exit 0 } -if [[ "$1" == "--update" ]]; then - update_opencortex -fi +if [[ "$1" == "--update" ]]; then update_opencortex; fi # 1. Try to drop straight into the CLI chat if command_exists socat && socat - TCP:$HOST:$PORT,connect-timeout=1 2>/dev/null; then echo -e "${BLUE}Connected to autonomous brain at $HOST:$PORT...${NC}" socat READLINE,history=$HOME/.org_agent_history TCP:$HOST:$PORT exit 0 -elif command_exists nc && nc -z $HOST $PORT 2>/dev/null; then - echo -e "${YELLOW}socat not found. Falling back to nc (no line-editing).${NC}" - echo -e "${BLUE}Connected to autonomous brain at $HOST:$PORT...${NC}" - while true; do - read -p "User: " MESSAGE - if [ -z "$MESSAGE" ]; then continue; fi - echo "$MESSAGE" | nc -N $HOST $PORT - done - exit 0 fi -# 2. Check if we have an existing installation we can boot -if [ -f "$HOME/.opencortex-path" ]; then - INSTALL_DIR=$(cat "$HOME/.opencortex-path") - if [ -d "$INSTALL_DIR" ] && [ -f "$INSTALL_DIR/docker-compose.yml" ]; then - echo -e "${YELLOW}Daemon is offline. Booting from $INSTALL_DIR...${NC}" - cd "$INSTALL_DIR" - docker-compose up -d - echo "Waiting for brain to initialize..." - sleep 5 - exec "$0" "$@" - fi -fi - -# 3. If we are running this inside a cloned repo, configure and boot +# 2. Local repository detection and launch if [ -f "opencortex.asd" ] || [ -d "literate" ]; then - echo -e "${YELLOW}Local repository detected. Ensuring configuration...${NC}" - INSTALL_DIR=$(pwd) - echo "$INSTALL_DIR" > "$HOME/.opencortex-path" - if [ ! -f .env ]; then ./scripts/onboard-baremetal.sh fi diff --git a/scripts/onboard-baremetal.sh b/scripts/onboard-baremetal.sh index 908e20e..695a85b 100755 --- a/scripts/onboard-baremetal.sh +++ b/scripts/onboard-baremetal.sh @@ -1,26 +1,25 @@ #!/bin/bash -set -e +# set -e removed to allow graceful fallbacks RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; YELLOW='\033[0;33m'; NC='\033[0m' echo -e "${BLUE}=== OpenCortex: Baremetal Power-User Setup ===${NC}" -# Helper for robust input +# Robust Non-Blocking Prompt prompt_user() { local prompt="$1" local default="$2" local var_name="$3" local result="" - # Try reading from /dev/tty, fallback to stdin, fallback to default - if [ -t 0 ]; then - read -p "$prompt (default: $default): " result + echo -n -e "${YELLOW}$prompt (default: $default): ${NC}" >&2 + + # Try reading from stdin with a 1-second timeout. + # If it fails or times out, we use the default. + if read -t 2 result; then + : else - # If piped, try /dev/tty explicitly - if read -p "$prompt (default: $default): " result < /dev/tty 2>/dev/null; then - : - else - result="" - fi + result="$default" + echo -e "${BLUE}[Auto-Pilot: Using $default]${NC}" >&2 fi val=${result:-$default} @@ -29,28 +28,21 @@ prompt_user() { # 1. Dependency Management install_deps() { + echo -e "${BLUE}Updating packages and installing dependencies...${NC}" if command -v apt-get >/dev/null; then sudo apt-get update && sudo apt-get install -y sbcl emacs git curl socat elif command -v pacman >/dev/null; then sudo pacman -S --noconfirm sbcl emacs git curl socat - elif command -v dnf >/dev/null; then - sudo dnf install -y sbcl emacs git curl socat - elif command -v brew >/dev/null; then - brew install sbcl emacs git curl socat else - echo -e "${RED}✗ Unknown package manager. Please install SBCL and Emacs manually.${NC}" - exit 1 + echo -e "${RED}✗ Unknown package manager. Please install SBCL/Emacs manually.${NC}" fi } if ! command -v sbcl >/dev/null 2>&1 || ! command -v emacs >/dev/null 2>&1; then echo -e "${YELLOW}! Missing dependencies (SBCL/Emacs).${NC}" prompt_user "Should I attempt to install them for you? [Y/n]" "y" "DO_INSTALL" - if [[ ! "$DO_INSTALL" =~ ^[Nn]$ ]]; then + if [[ "$DO_INSTALL" =~ ^[Yy]$ ]]; then install_deps - else - echo -e "${RED}✗ Dependencies required. Exiting.${NC}" - exit 1 fi fi @@ -58,7 +50,7 @@ fi if [ ! -d "$HOME/quicklisp" ] && [ ! -d "$HOME/.quicklisp" ]; then echo -e "${YELLOW}! Quicklisp not found.${NC}" prompt_user "Install Quicklisp now? [Y/n]" "y" "DO_QL" - if [[ ! "$DO_QL" =~ ^[Nn]$ ]]; then + if [[ "$DO_QL" =~ ^[Yy]$ ]]; then curl -O https://beta.quicklisp.org/quicklisp.lisp sbcl --non-interactive --load quicklisp.lisp \ --eval "(quicklisp-quickstart:install)" \ @@ -70,10 +62,11 @@ fi # 3. Literate Tangling echo -e "${BLUE}Tangling Literate Org files into source code...${NC}" -emacs --batch --eval "(require 'org)" --eval "(mapc 'org-babel-tangle-file (file-expand-wildcards \"literate/*.org\"))" || true +# Redirect emacs output to /dev/null to keep the console clean for the user +emacs --batch --eval "(require 'org)" --eval "(mapc 'org-babel-tangle-file (file-expand-wildcards \"literate/*.org\"))" >/dev/null 2>&1 || true if [ ! -f "src/package.lisp" ]; then - echo -e "${RED}✗ Tangling failed. Source files not generated.${NC}" + echo -e "${RED}✗ Tangling failed. Manual intervention required.${NC}" exit 1 fi echo -e "${GREEN}✓ Core tangled.${NC}" @@ -81,17 +74,14 @@ echo -e "${GREEN}✓ Core tangled.${NC}" # 4. Environment Configuration if [ ! -f .env ]; then cp .env.example .env; fi -# Disable exit-on-error for the interactive part to ensure we don't crash -set +e prompt_user "What is your name?" "User" "USER_NAME" sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env prompt_user "What shall we name your Assistant?" "OpenCortex" "AGENT_NAME" sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env -echo -e "\nSelect primary neural provider:" -echo "1) Gemini (Free/Official)"; echo "2) OpenRouter"; echo "3) Anthropic"; echo "4) OpenAI" -prompt_user "Choice [1-4]" "1" "LLM_CHOICE" +echo -e "\nSelect neural provider (1:Gemini, 2:OpenRouter, 3:Anthropic, 4:OpenAI)" +prompt_user "Choice" "1" "LLM_CHOICE" case $LLM_CHOICE in 2) prompt_user "Enter OpenRouter Key" "" "INPUT"; sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$INPUT\"/g" .env ;; @@ -99,7 +89,6 @@ case $LLM_CHOICE in 4) prompt_user "Enter OpenAI Key" "" "INPUT"; sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$INPUT\"/g" .env ;; *) prompt_user "Enter Gemini Key" "" "INPUT"; sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$INPUT\"/g" .env ;; esac -set -e # 5. Path Alignment PROJECT_ROOT=$(pwd) @@ -113,5 +102,6 @@ echo -e "${GREEN}✓ Configuration complete.${NC}" # 6. Final Instructions echo -e "\n${BLUE}=== Setup Complete ===${NC}" -echo -e "To start the harness: ${YELLOW}./opencortex.sh${NC}" -echo -e "To run tests: ${YELLOW}sbcl --eval '(ql:quickload :opencortex)' --eval '(asdf:test-system :opencortex)'${NC}" +echo -e "Your OpenCortex instance is ready." +echo -e "To start the brain: ${YELLOW}./opencortex.sh${NC}" +echo -e "To configure later, edit: ${YELLOW}$(pwd)/.env${NC}"