REFAC: Consolidated onboarding into setup.org and added one-liner installer

This commit is contained in:
2026-04-13 20:04:52 -04:00
parent 898df4b7ff
commit f1e3f92b08
6 changed files with 517 additions and 189 deletions

View File

@@ -27,14 +27,13 @@ ENV PATH="/opt/venv/bin:$PATH"
RUN pip install playwright \
&& playwright install --with-deps chromium
# 2. Install signal-cli (v0.14.0)
# 3. Install signal-cli (v0.14.0)
ENV SIGNAL_CLI_VERSION=0.14.0
RUN curl -L https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-Linux.tar.gz | tar xz -C /opt \
&& ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli /usr/local/bin/signal-cli
# 3. Install Quicklisp & Pin Distribution
# 4. Install Quicklisp & Pin Distribution
# Pinned to 2026-04-01 for bit-rot resistance.
# Monthly maintenance task in gtd.org handles testing of newer distributions.
WORKDIR /root
RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
&& sbcl --non-interactive \
@@ -42,20 +41,19 @@ RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
--eval '(quicklisp-quickstart:install)' \
--eval '(ql-dist:install-dist "http://beta.quicklisp.org/dist/quicklisp/2026-04-01/distinfo.txt" :prompt nil :replace t)'
# 4. Configure SBCL to load Quicklisp on startup
# 5. Configure SBCL to load Quicklisp on startup
RUN echo '(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))) (when (probe-file quicklisp-init) (load quicklisp-init)))' > /root/.sbclrc
# 5. Setup Application Directory
# 6. Setup Application Directory
WORKDIR /app
COPY . /app/projects/org-agent
# 6. Pre-cache Lisp Dependencies
# This minimizes startup time by downloading dexador, cl-json, etc. during build
# 7. Pre-cache Lisp Dependencies
RUN sbcl --non-interactive \
--eval '(push #p"/app/projects/org-agent/" asdf:*central-registry*)' \
--eval '(ql:quickload :org-agent)'
# 7. Environment & Volumes
# 8. Environment & Volumes
# The host's memex root should be mounted to /memex
ENV MEMEX_DIR=/memex
VOLUME ["/memex"]

View File

@@ -107,14 +107,38 @@ The agent meets you where you are. While it natively integrates with text editor
- *The Journal Scribe:* Periodically distills messy chronological logs into clean, permanent notes.
- *The Gardener:* A heartbeat-driven worker that flags broken links, finds orphaned ideas, and maintains the structural health of your Memex.
* The Long-Term Vision: A Modern Lisp Machine
* Quick Start (The Zero-to-One Experience)
Today, org-agent relies on external tools to interact with the world. We use Python wrappers for web browsing, external binaries for chat, and external AI models for semantic reasoning.
org-agent can be installed and booted with a single command. The onboarding script will detect your OS, offer to install Docker if missing, interactively gather your API keys, and launch the sovereign kernel in the background.
But the long-term trajectory of this project is to progressively pull those boundaries inward.
#+begin_src bash
curl -fsSL https://raw.githubusercontent.com/gharbeia/org-agent/main/scripts/install.sh | bash
#+end_src
As the *Deterministic Engine* grows more sophisticated, it will take on more of the heavy logical reasoning, utilizing native Lisp unification and logic engines. The Probabilistic AI models will be relegated to what they do best: acting as a natural language translation layer to make sense of the messy, unstructured outside world.
For power users who wish to run the agent natively (Baremetal) without Docker to allow direct manipulation of their local =~/.emacs.d=, please refer to the [[file:literate/setup.org][setup.org]] literate documentation.
We will systematically rewrite external dependencies in Common Lisp. The endgame of org-agent is not just to be an AI assistant, but to resurrect the dream of the *Lisp Machine*: a unified computing environment where the operating system, the text editor, the web browser, and the AI agent all share the exact same memory space, the exact same AST, and the exact same language.
* The Evolutionary Roadmap (v1.0.0 to v4.0.0+)
Zero Inter-Process Communication (IPC). Zero translation latency. Total synergy between human thought and machine actuation.
** v1.0.0 (Phase 2.5): The Verified Wrapper (Current Target)
At this stage, org-agent achieves feature parity with State-of-the-Art autonomous agents (like Devin or SWE-agent) but with Lisp-grade mathematical security.
- *The Tools are External:* The agent uses a standard bash shell, a headless browser (via Playwright), and standard file I/O.
- *The Safety is Internal:* The Bouncer and Formal Verification gates mathematically prove actions are safe before piping them to external tools.
- *The Result:* An autonomous agent capable of end-to-end software engineering, web research, and system administration, running securely and locally.
** v2.0.0 (Phase 3): The Cannibalization
Replacing string-based tool wrappers with native Lisp data structures to eliminate LLM fragility.
- *Cannibalizing the Browser:* Ingesting the DOM as a native Lisp AST rather than fighting with Playwright scripts.
- *Cannibalizing the Shell & Editor:* Moving from bash execution to native OS API bindings. Emacs becomes a viewport for the live AST, not a master.
- *The Result:* The LLM no longer has to guess at messy `stdout` or raw HTML strings; it manipulates deterministic data structures directly.
** v3.0.0 (Phase 4): True Symbolic Determinism
The great inversion. The Lisp engine takes the wheel, and the LLM is relegated to translation.
- *The Semantic Translator:* The LLM exclusively translates unstructured human intent (natural language, images) into strict Lisp S-expressions.
- *Deterministic Planning (The Solver):* The core reasoning engine uses formal logic, graph traversal, and constraint solving to plan and execute workflows.
- *Self-Correcting Syntax:* The Lisp engine catches and repairs hallucinated syntax errors without consulting the LLM.
** v4.0.0+ (Phase 5): The Neurosymbolic Singularity
The ultimate vision realized. The agent achieves homoiconic sovereignty.
- *Homoiconic Self-Writing:* The agent inspects its own literate source code, proposes optimizations, formally verifies them, and hot-reloads itself at runtime.
- *Asynchronous Swarm Cognition:* The agent spawns isolated sub-agents in jailed Lisp packages to solve sub-tasks in parallel.
- *The Digital Extension of Self:* A perfect, asynchronous operating system for your digital life, managing the Memex with zero structural degradation.

300
literate/setup.org Normal file
View File

@@ -0,0 +1,300 @@
#+TITLE: Setup & Onboarding (setup.org)
#+AUTHOR: Amr
#+FILETAGS: :harness:setup:onboarding:
#+STARTUP: content
* Overview: The Zero-to-One Experience
The *Setup & Onboarding* process ensures that users can boot the ~org-agent~ Lisp Machine with zero friction. We follow the *Appliance Paradigm* for standard users (Docker-first) and provide a *Power User Path* (Baremetal) for those wanting deep native integration.
This file is a Literate Devops document. Tangling it generates the Docker configuration, the one-liner installation script, and the baremetal onboarding script.
* 1. The Appliance Paradigm (Docker First)
The easiest way to run the agent is via Docker. This prevents the user from having to manually manage SBCL, Quicklisp, Python virtual environments, Playwright binaries, and Java (for Signal).
** The Dockerfile
The container wraps all messy OS dependencies and pre-caches the Lisp environment for rapid booting.
#+begin_src dockerfile :tangle ../Dockerfile
# ORG-AGENT v1.0 Production Environment
FROM debian:bookworm-slim
# Prevent interactive prompts during build
ENV DEBIAN_FRONTEND=noninteractive
# 1. Install System Dependencies
# - sbcl: The Lisp Runtime
# - curl/git/unzip: Standard tools for Quicklisp and binaries
# - default-jre: Required by signal-cli
# - python3/pip: Required for Playwright bridge
RUN apt-get update && apt-get install -y \
sbcl \
curl \
git \
unzip \
default-jre \
libsqlite3-0 \
python3 \
python3-pip \
python3-venv \
&& rm -rf /var/lib/apt/lists/*
# 2. Setup Playwright (High-Fidelity Browsing)
RUN python3 -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
RUN pip install playwright \
&& playwright install --with-deps chromium
# 3. Install signal-cli (v0.14.0)
ENV SIGNAL_CLI_VERSION=0.14.0
RUN curl -L https://github.com/AsamK/signal-cli/releases/download/v${SIGNAL_CLI_VERSION}/signal-cli-${SIGNAL_CLI_VERSION}-Linux.tar.gz | tar xz -C /opt \
&& ln -s /opt/signal-cli-${SIGNAL_CLI_VERSION}/bin/signal-cli /usr/local/bin/signal-cli
# 4. Install Quicklisp & Pin Distribution
# Pinned to 2026-04-01 for bit-rot resistance.
WORKDIR /root
RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
&& sbcl --non-interactive \
--load quicklisp.lisp \
--eval '(quicklisp-quickstart:install)' \
--eval '(ql-dist:install-dist "http://beta.quicklisp.org/dist/quicklisp/2026-04-01/distinfo.txt" :prompt nil :replace t)'
# 5. Configure SBCL to load Quicklisp on startup
RUN echo '(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp" (user-homedir-pathname)))) (when (probe-file quicklisp-init) (load quicklisp-init)))' > /root/.sbclrc
# 6. Setup Application Directory
WORKDIR /app
COPY . /app/projects/org-agent
# 7. Pre-cache Lisp Dependencies
RUN sbcl --non-interactive \
--eval '(push #p"/app/projects/org-agent/" asdf:*central-registry*)' \
--eval '(ql:quickload :org-agent)'
# 8. Environment & Volumes
# The host's memex root should be mounted to /memex
ENV MEMEX_DIR=/memex
VOLUME ["/memex"]
# Default Ports
EXPOSE 9105 8080
# Entrypoint
CMD ["sbcl", "--non-interactive", \
"--eval", "(push #p\"/app/projects/org-agent/\" asdf:*central-registry*)", \
"--eval", "(ql:quickload :org-agent)", \
"--eval", "(org-agent:main)"]
#+end_src
** Docker Compose
#+begin_src yaml :tangle ../docker-compose.yml
services:
org-agent:
build:
context: .
dockerfile: Dockerfile
container_name: org-agent
env_file: .env
volumes:
# Mount the entire memex directory (2 levels up from projects/org-agent)
- ../..:/memex
# Ensure signal-cli state is preserved
- signal-state:/root/.local/share/signal-cli
ports:
- "${ORG_AGENT_DAEMON_PORT:-9105}:9105"
- "${ORG_AGENT_WEB_PORT:-8080}:8080"
restart: unless-stopped
volumes:
signal-state:
#+end_src
* 2. The Interactive One-Liner (install.sh)
This script is what the user pipes to ~bash~ from curl. It detects the OS, installs Docker if missing (after asking permission), clones the repo, interactively generates the ~.env~, and launches the container.
#+begin_src bash :tangle ../scripts/install.sh :shebang "#!/bin/bash"
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${BLUE}==================================================${NC}"
echo -e "${BLUE} org-agent: Sovereign Intelligence Onboarding ${NC}"
echo -e "${BLUE}==================================================${NC}"
# --- OS & Docker Detection ---
echo -e "\n${BLUE}[1/4] Verifying Environment...${NC}"
command_exists() { command -v "$1" >/dev/null 2>&1; }
install_docker() {
echo -e "${YELLOW}Docker is required to run org-agent natively without messy dependencies.${NC}"
read -p "Would you like me to attempt to install Docker? [Y/n]: " install_choice
install_choice=${install_choice:-Y}
if [[ "$install_choice" =~ ^[Yy]$ ]]; then
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command_exists apt-get; then
echo "Installing Docker via apt..."
sudo apt-get update
sudo apt-get install -y docker.io docker-compose
elif command_exists dnf; then
echo "Installing Docker via dnf..."
sudo dnf install -y docker docker-compose
sudo systemctl start docker
sudo systemctl enable docker
else
echo -e "${RED}Unsupported package manager. Please install Docker manually.${NC}"
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
if command_exists brew; then
echo "Installing Docker Desktop via Homebrew..."
brew install --cask docker
echo -e "${YELLOW}Please start Docker Desktop from your Applications folder, then re-run this script.${NC}"
exit 0
else
echo -e "${RED}Homebrew not found. Please install Docker Desktop for Mac manually.${NC}"
exit 1
fi
else
echo -e "${RED}Unsupported OS for automated Docker installation. Please install manually.${NC}"
exit 1
fi
else
echo -e "${RED}Docker is required. Aborting.${NC}"
exit 1
fi
}
if ! command_exists docker || ! command_exists docker-compose; then
install_docker
else
echo -e "${GREEN}✓ Docker and docker-compose detected.${NC}"
fi
# --- Repository Setup ---
echo -e "\n${BLUE}[2/4] Downloading Kernel...${NC}"
MEMEX_DEFAULT="$HOME/memex"
read -p "Where is your Memex located? (default: $MEMEX_DEFAULT): " MEMEX_TARGET
MEMEX_TARGET=${MEMEX_TARGET:-$MEMEX_DEFAULT}
mkdir -p "$MEMEX_TARGET/projects"
cd "$MEMEX_TARGET/projects"
if [ ! -d "org-agent" ]; then
echo "Cloning org-agent..."
git clone https://github.com/gharbeia/org-agent.git
cd org-agent
else
echo -e "${GREEN}✓ Repository already exists.${NC}"
cd org-agent
git pull origin main
fi
# --- Interactive Configuration ---
echo -e "\n${BLUE}[3/4] Neural & Identity Calibration...${NC}"
if [ ! -f .env ]; then
cp .env.example .env
fi
# Ask for Name
read -p "What is your name? (default: User): " USER_NAME
USER_NAME=${USER_NAME:-User}
sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env
# Ask for Assistant Name
read -p "What shall we name your Assistant? (default: Agent): " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-Agent}
sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env
# Ask for LLM
echo -e "\nSelect your primary neural provider:"
echo "1) Google Gemini (Free Tier / Official)"
echo "2) OpenRouter (Unified / Paid)"
echo "3) Anthropic (Claude / API Key)"
echo "4) OpenAI (GPT / API Key)"
read -p "Choice [1-4]: " LLM_CHOICE
case $LLM_CHOICE in
2) read -p "Enter OpenRouter API Key: " INPUT; sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$INPUT\"/g" .env ;;
3) read -p "Enter Anthropic API Key: " INPUT; sed -i "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=\"$INPUT\"/g" .env ;;
4) read -p "Enter OpenAI API Key: " INPUT; sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$INPUT\"/g" .env ;;
*) read -p "Enter Gemini API Key: " INPUT; sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$INPUT\"/g" .env ;;
esac
# Seed Core Skills
echo -e "\n${BLUE}[4/4] Seeding Skills...${NC}"
# In Docker, the host's memex maps to /memex. The skills should be saved in the host's memex notes folder.
SKILLS_DIR="$MEMEX_TARGET/notes"
mkdir -p "$SKILLS_DIR"
cp -n skills/*.org "$SKILLS_DIR/" 2>/dev/null || true
echo -e "${GREEN}✓ Core skills seeded to $SKILLS_DIR.${NC}"
# Ensure proper ownership if sudo was used for apt
if [ -n "$SUDO_USER" ]; then
chown -R "$SUDO_USER" "$MEMEX_TARGET/projects/org-agent"
fi
echo -e "\n${GREEN}==================================================${NC}"
echo -e "${GREEN} Onboarding Complete! ${NC}"
echo -e "${GREEN} Booting your sovereign brain in the background...${NC}"
echo -e "${GREEN}==================================================${NC}"
# Launch
docker-compose up -d --build
echo -e "\n${YELLOW}To view logs, run: cd $MEMEX_TARGET/projects/org-agent && docker-compose logs -f${NC}"
#+end_src
* 3. The Power-User Path (Baremetal Onboarding)
For users who want to run the Lisp Machine natively on their host OS (typically Emacs users who want the agent to directly manipulate their local =.emacs.d=), we provide the baremetal setup script. This script verifies the host has SBCL and Quicklisp installed, and configures the paths natively.
#+begin_src bash :tangle ../scripts/onboard-baremetal.sh :shebang "#!/bin/bash"
set -e
RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; NC='\033[0m'
echo -e "${BLUE}=== org-agent: Baremetal Power-User Setup ===${NC}"
if ! command -v sbcl >/dev/null 2>&1; then
echo -e "${RED}✗ SBCL not found. Please install it first.${NC}"
exit 1
fi
if [ ! -d "$HOME/quicklisp" ] && [ ! -d "$HOME/.quicklisp" ]; then
echo -e "${RED}✗ Quicklisp not found. Please install Quicklisp.${NC}"
exit 1
fi
if [ ! -f .env ]; then cp .env.example .env; fi
read -p "What is your name? (default: User): " USER_NAME
USER_NAME=${USER_NAME:-User}
sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env
read -p "What shall we name your Assistant? (default: Agent): " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-Agent}
sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env
echo "Select primary neural provider:"
echo "1) Gemini"; echo "2) OpenRouter"; echo "3) Anthropic"; echo "4) OpenAI"
read -p "Choice [1-4]: " LLM_CHOICE
case $LLM_CHOICE in
2) read -p "Enter OpenRouter Key: " INPUT; sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$INPUT\"/g" .env ;;
3) read -p "Enter Anthropic Key: " INPUT; sed -i "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=\"$INPUT\"/g" .env ;;
4) read -p "Enter OpenAI Key: " INPUT; sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$INPUT\"/g" .env ;;
*) read -p "Enter Gemini Key: " INPUT; sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$INPUT\"/g" .env ;;
esac
# Update baremetal paths based on current directory structure
PROJECT_ROOT=$(pwd)
PARENT_DIR=$(dirname "$PROJECT_ROOT")
sed -i "s|MEMEX_DIR=.*|MEMEX_DIR=\"$PARENT_DIR\"|g" .env
sed -i "s|ZETTELKASTEN_DIR=.*|ZETTELKASTEN_DIR=\"$PARENT_DIR/notes\"|g" .env
sed -i "s|SKILLS_DIR=.*|SKILLS_DIR=\"$PARENT_DIR/notes\"|g" .env
mkdir -p "$PARENT_DIR/notes"
cp -n skills/*.org "$PARENT_DIR/notes/" 2>/dev/null || true
echo -e "${GREEN}Baremetal setup complete. Run 'make run' to start.${NC}"
#+end_src

134
scripts/install.sh Executable file
View File

@@ -0,0 +1,134 @@
#!/bin/bash
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
echo -e "${BLUE}==================================================${NC}"
echo -e "${BLUE} org-agent: Sovereign Intelligence Onboarding ${NC}"
echo -e "${BLUE}==================================================${NC}"
# --- OS & Docker Detection ---
echo -e "\n${BLUE}[1/4] Verifying Environment...${NC}"
command_exists() { command -v "$1" >/dev/null 2>&1; }
install_docker() {
echo -e "${YELLOW}Docker is required to run org-agent natively without messy dependencies.${NC}"
read -p "Would you like me to attempt to install Docker? [Y/n]: " install_choice
install_choice=${install_choice:-Y}
if [[ "$install_choice" =~ ^[Yy]$ ]]; then
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if command_exists apt-get; then
echo "Installing Docker via apt..."
sudo apt-get update
sudo apt-get install -y docker.io docker-compose
elif command_exists dnf; then
echo "Installing Docker via dnf..."
sudo dnf install -y docker docker-compose
sudo systemctl start docker
sudo systemctl enable docker
else
echo -e "${RED}Unsupported package manager. Please install Docker manually.${NC}"
exit 1
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
if command_exists brew; then
echo "Installing Docker Desktop via Homebrew..."
brew install --cask docker
echo -e "${YELLOW}Please start Docker Desktop from your Applications folder, then re-run this script.${NC}"
exit 0
else
echo -e "${RED}Homebrew not found. Please install Docker Desktop for Mac manually.${NC}"
exit 1
fi
else
echo -e "${RED}Unsupported OS for automated Docker installation. Please install manually.${NC}"
exit 1
fi
else
echo -e "${RED}Docker is required. Aborting.${NC}"
exit 1
fi
}
if ! command_exists docker || ! command_exists docker-compose; then
install_docker
else
echo -e "${GREEN}✓ Docker and docker-compose detected.${NC}"
fi
# --- Repository Setup ---
echo -e "\n${BLUE}[2/4] Downloading Kernel...${NC}"
MEMEX_DEFAULT="$HOME/memex"
read -p "Where is your Memex located? (default: $MEMEX_DEFAULT): " MEMEX_TARGET
MEMEX_TARGET=${MEMEX_TARGET:-$MEMEX_DEFAULT}
mkdir -p "$MEMEX_TARGET/projects"
cd "$MEMEX_TARGET/projects"
if [ ! -d "org-agent" ]; then
echo "Cloning org-agent..."
git clone https://github.com/gharbeia/org-agent.git
cd org-agent
else
echo -e "${GREEN}✓ Repository already exists.${NC}"
cd org-agent
git pull origin main
fi
# --- Interactive Configuration ---
echo -e "\n${BLUE}[3/4] Neural & Identity Calibration...${NC}"
if [ ! -f .env ]; then
cp .env.example .env
fi
# Ask for Name
read -p "What is your name? (default: User): " USER_NAME
USER_NAME=${USER_NAME:-User}
sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env
# Ask for Assistant Name
read -p "What shall we name your Assistant? (default: Agent): " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-Agent}
sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env
# Ask for LLM
echo -e "\nSelect your primary neural provider:"
echo "1) Google Gemini (Free Tier / Official)"
echo "2) OpenRouter (Unified / Paid)"
echo "3) Anthropic (Claude / API Key)"
echo "4) OpenAI (GPT / API Key)"
read -p "Choice [1-4]: " LLM_CHOICE
case $LLM_CHOICE in
2) read -p "Enter OpenRouter API Key: " INPUT; sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$INPUT\"/g" .env ;;
3) read -p "Enter Anthropic API Key: " INPUT; sed -i "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=\"$INPUT\"/g" .env ;;
4) read -p "Enter OpenAI API Key: " INPUT; sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$INPUT\"/g" .env ;;
*) read -p "Enter Gemini API Key: " INPUT; sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$INPUT\"/g" .env ;;
esac
# Seed Core Skills
echo -e "\n${BLUE}[4/4] Seeding Skills...${NC}"
# In Docker, the host's memex maps to /memex. The skills should be saved in the host's memex notes folder.
SKILLS_DIR="$MEMEX_TARGET/notes"
mkdir -p "$SKILLS_DIR"
cp -n skills/*.org "$SKILLS_DIR/" 2>/dev/null || true
echo -e "${GREEN}✓ Core skills seeded to $SKILLS_DIR.${NC}"
# Ensure proper ownership if sudo was used for apt
if [ -n "$SUDO_USER" ]; then
chown -R "$SUDO_USER" "$MEMEX_TARGET/projects/org-agent"
fi
echo -e "\n${GREEN}==================================================${NC}"
echo -e "${GREEN} Onboarding Complete! ${NC}"
echo -e "${GREEN} Booting your sovereign brain in the background...${NC}"
echo -e "${GREEN}==================================================${NC}"
# Launch
docker-compose up -d --build
echo -e "\n${YELLOW}To view logs, run: cd $MEMEX_TARGET/projects/org-agent && docker-compose logs -f${NC}"

47
scripts/onboard-baremetal.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/bin/bash
set -e
RED='\033[0;31m'; GREEN='\033[0;32m'; BLUE='\033[0;34m'; NC='\033[0m'
echo -e "${BLUE}=== org-agent: Baremetal Power-User Setup ===${NC}"
if ! command -v sbcl >/dev/null 2>&1; then
echo -e "${RED}✗ SBCL not found. Please install it first.${NC}"
exit 1
fi
if [ ! -d "$HOME/quicklisp" ] && [ ! -d "$HOME/.quicklisp" ]; then
echo -e "${RED}✗ Quicklisp not found. Please install Quicklisp.${NC}"
exit 1
fi
if [ ! -f .env ]; then cp .env.example .env; fi
read -p "What is your name? (default: User): " USER_NAME
USER_NAME=${USER_NAME:-User}
sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env
read -p "What shall we name your Assistant? (default: Agent): " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-Agent}
sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env
echo "Select primary neural provider:"
echo "1) Gemini"; echo "2) OpenRouter"; echo "3) Anthropic"; echo "4) OpenAI"
read -p "Choice [1-4]: " LLM_CHOICE
case $LLM_CHOICE in
2) read -p "Enter OpenRouter Key: " INPUT; sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$INPUT\"/g" .env ;;
3) read -p "Enter Anthropic Key: " INPUT; sed -i "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=\"$INPUT\"/g" .env ;;
4) read -p "Enter OpenAI Key: " INPUT; sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$INPUT\"/g" .env ;;
*) read -p "Enter Gemini Key: " INPUT; sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$INPUT\"/g" .env ;;
esac
# Update baremetal paths based on current directory structure
PROJECT_ROOT=$(pwd)
PARENT_DIR=$(dirname "$PROJECT_ROOT")
sed -i "s|MEMEX_DIR=.*|MEMEX_DIR=\"$PARENT_DIR\"|g" .env
sed -i "s|ZETTELKASTEN_DIR=.*|ZETTELKASTEN_DIR=\"$PARENT_DIR/notes\"|g" .env
sed -i "s|SKILLS_DIR=.*|SKILLS_DIR=\"$PARENT_DIR/notes\"|g" .env
mkdir -p "$PARENT_DIR/notes"
cp -n skills/*.org "$PARENT_DIR/notes/" 2>/dev/null || true
echo -e "${GREEN}Baremetal setup complete. Run 'make run' to start.${NC}"

View File

@@ -1,175 +0,0 @@
#!/bin/bash
# org-agent Onboarding Script: The First Breath
# This script prepares your PSF environment for the Lisp Machine.
set -e
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${BLUE}==================================================${NC}"
echo -e "${BLUE} org-agent: Personal Software Foundry Onboarding ${NC}"
echo -e "${BLUE}==================================================${NC}"
# 1. Environment Verification
echo -e "\n${BLUE}[1/5] Verifying Environment...${NC}"
if command -v sbcl >/dev/null 2>&1; then
echo -e "${GREEN}✓ SBCL (Steel Bank Common Lisp) found.${NC}"
else
echo -e "${RED}✗ SBCL not found. Please install it first.${NC}"
exit 1
fi
if [ -d "$HOME/quicklisp" ] || [ -d "$HOME/.quicklisp" ]; then
echo -e "${GREEN}✓ Quicklisp found.${NC}"
else
echo -e "${RED}✗ Quicklisp not found. Please install Quicklisp to manage Lisp dependencies.${NC}"
exit 1
fi
# 2. Configuration Setup
echo -e "\n${BLUE}[2/5] Setting up .env configuration...${NC}"
if [ ! -f .env ]; then
cp .env.example .env
echo -e "${GREEN}✓ Created .env from .env.example.${NC}"
else
echo -e "${BLUE}! .env already exists. Loading existing values.${NC}"
fi
# Function to get value from .env without quotes
get_env_val() {
local key=$1
local val=$(grep "^${key}=" .env | cut -d'=' -f2- | sed 's/^"//;s/"$//;s/^\x27//;s/\x27$//')
echo "$val"
}
# Load variables
MEMEX_DIR=$(get_env_val "MEMEX_DIR")
SKILLS_DIR=$(get_env_val "SKILLS_DIR")
# If MEMEX_DIR is still the default or empty, normalize it to the parent of the project
PROJECT_ROOT=$(pwd)
PARENT_DIR=$(dirname "$PROJECT_ROOT")
if [[ -z "$MEMEX_DIR" || "$MEMEX_DIR" == "/memex" ]]; then
MEMEX_DIR="$PARENT_DIR"
sed -i "s|MEMEX_DIR=.*|MEMEX_DIR=\"$MEMEX_DIR\"|g" .env
sed -i "s|ZETTELKASTEN_DIR=.*|ZETTELKASTEN_DIR=\"$MEMEX_DIR/notes\"|g" .env
sed -i "s|SKILLS_DIR=.*|SKILLS_DIR=\"$MEMEX_DIR/notes\"|g" .env
sed -i "s|INBOX_DIR=.*|INBOX_DIR=\"$MEMEX_DIR/inbox\"|g" .env
sed -i "s|DAILY_DIR=.*|DAILY_DIR=\"$MEMEX_DIR/daily\"|g" .env
sed -i "s|PROJECTS_DIR=.*|PROJECTS_DIR=\"$MEMEX_DIR/projects\"|g" .env
sed -i "s|SYSTEM_DIR=.*|SYSTEM_DIR=\"$MEMEX_DIR/system\"|g" .env
echo -e "${GREEN}✓ Paths normalized to: $MEMEX_DIR${NC}"
# Refresh SKILLS_DIR after normalization
SKILLS_DIR=$(get_env_val "SKILLS_DIR")
fi
# 3. Model Strategy
echo -e "\n${BLUE}[3/5] Primary LLM Configuration...${NC}"
GEMINI_KEY=$(get_env_val "GEMINI_API_KEY")
OR_KEY=$(get_env_val "OPENROUTER_API_KEY")
ANTH_KEY=$(get_env_val "ANTHROPIC_API_KEY")
OPENAI_KEY=$(get_env_val "OPENAI_API_KEY")
if [[ ! -z "$GEMINI_KEY" && "$GEMINI_KEY" != "your_gemini_key_here" ]] || \
[[ ! -z "$OR_KEY" && "$OR_KEY" != "your_openrouter_key_here" ]] || \
[[ ! -z "$ANTH_KEY" && "$ANTH_KEY" != "your_anthropic_key_here" ]] || \
[[ ! -z "$OPENAI_KEY" && "$OPENAI_KEY" != "your_openai_key_here" ]]; then
echo -e "${GREEN}✓ Neural provider already configured in .env.${NC}"
else
echo "Select your primary neural provider:"
echo "1) Google Gemini (Free Tier / Official)"
echo "2) OpenRouter (Unified / Paid)"
echo "3) Anthropic (Claude / API Key)"
echo "4) OpenAI (GPT / API Key)"
read -p "Choice [1-4]: " LLM_CHOICE
case $LLM_CHOICE in
2)
read -p "Enter OpenRouter API Key: " OR_INPUT
sed -i "s/OPENROUTER_API_KEY=.*/OPENROUTER_API_KEY=\"$OR_INPUT\"/g" .env
echo -e "${GREEN}✓ OpenRouter configured.${NC}"
;;
3)
read -p "Enter Anthropic API Key: " ANTH_INPUT
sed -i "s/ANTHROPIC_API_KEY=.*/ANTHROPIC_API_KEY=\"$ANTH_INPUT\"/g" .env
echo -e "${GREEN}✓ Anthropic configured.${NC}"
;;
4)
read -p "Enter OpenAI API Key: " OPENAI_INPUT
sed -i "s/OPENAI_API_KEY=.*/OPENAI_API_KEY=\"$OPENAI_INPUT\"/g" .env
echo -e "${GREEN}✓ OpenAI configured.${NC}"
;;
*)
read -p "Enter Gemini API Key (or leave blank for OAuth): " GEM_INPUT
if [ ! -z "$GEM_INPUT" ]; then
sed -i "s/GEMINI_API_KEY=.*/GEMINI_API_KEY=\"$GEM_INPUT\"/g" .env
fi
echo -e "${GREEN}✓ Gemini selected.${NC}"
;;
esac
fi
# 4. Identity
echo -e "\n${BLUE}[4/5] Identity Setup...${NC}"
CURRENT_USER=$(get_env_val "MEMEX_USER")
if [[ "$CURRENT_USER" == "YourName" || -z "$CURRENT_USER" ]]; then
read -p "What is your name? (default: User): " USER_NAME
USER_NAME=${USER_NAME:-User}
read -p "What shall we name your Assistant? (default: Agent): " AGENT_NAME
AGENT_NAME=${AGENT_NAME:-Agent}
sed -i "s/MEMEX_USER=.*/MEMEX_USER=\"$USER_NAME\"/g" .env
sed -i "s/MEMEX_ASSISTANT=.*/MEMEX_ASSISTANT=\"$AGENT_NAME\"/g" .env
else
echo -e "${GREEN}✓ Identity already set: $CURRENT_USER${NC}"
fi
# 5. Skill Seeding
echo -e "\n${BLUE}[5/5] Seeding Skills...${NC}"
# Use SKILLS_DIR from .env, expanding $HOME if necessary
REAL_SKILLS_DIR=$(echo "$SKILLS_DIR" | sed "s|\$HOME|$HOME|g")
mkdir -p "$REAL_SKILLS_DIR"
echo -e "Installing Standard Library to $REAL_SKILLS_DIR..."
for skill_path in skills/*.org; do
skill_name=$(basename "$skill_path")
if [[ "$1" == "--dev" ]]; then
ln -sf "$PROJECT_ROOT/$skill_path" "$REAL_SKILLS_DIR/$skill_name"
echo -e " Linked: $skill_name"
else
cp -n "$skill_path" "$REAL_SKILLS_DIR/$skill_name"
echo -e " Copied: $skill_name"
fi
done
# Contrib skills
CONTRIB_DIR="$PROJECT_ROOT/../org-agent-contrib"
if [ -d "$CONTRIB_DIR" ]; then
echo -e "\n${BLUE}Ecosystem Skills detected in $CONTRIB_DIR.${NC}"
read -p "Would you like to install additional domain skills? [y/N]: " INSTALL_CONTRIB
if [[ "$INSTALL_CONTRIB" =~ ^[Yy]$ ]]; then
for skill_path in "$CONTRIB_DIR"/*.org; do
skill_name=$(basename "$skill_path")
if [[ "$1" == "--dev" ]]; then
ln -sf "$skill_path" "$REAL_SKILLS_DIR/$skill_name"
echo -e " Linked: $skill_name"
else
cp -n "$skill_path" "$REAL_SKILLS_DIR/$skill_name"
echo -e " Copied: $skill_name"
fi
done
fi
fi
echo -e "\n${GREEN}==================================================${NC}"
echo -e "${GREEN} Onboarding Complete! ${NC}"
echo -e "${GREEN} Your sovereign brain is ready to boot. ${NC}"
echo -e "${GREEN} Next: Start the daemon with 'make run'. ${NC}"
echo -e "${GREEN}==================================================${NC}"