REFAC: Consolidated onboarding into setup.org and added one-liner installer
This commit is contained in:
14
Dockerfile
14
Dockerfile
@@ -27,14 +27,13 @@ ENV PATH="/opt/venv/bin:$PATH"
|
|||||||
RUN pip install playwright \
|
RUN pip install playwright \
|
||||||
&& playwright install --with-deps chromium
|
&& 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
|
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 \
|
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
|
&& 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.
|
# Pinned to 2026-04-01 for bit-rot resistance.
|
||||||
# Monthly maintenance task in gtd.org handles testing of newer distributions.
|
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
|
RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
|
||||||
&& sbcl --non-interactive \
|
&& sbcl --non-interactive \
|
||||||
@@ -42,20 +41,19 @@ RUN curl -O https://beta.quicklisp.org/quicklisp.lisp \
|
|||||||
--eval '(quicklisp-quickstart:install)' \
|
--eval '(quicklisp-quickstart:install)' \
|
||||||
--eval '(ql-dist:install-dist "http://beta.quicklisp.org/dist/quicklisp/2026-04-01/distinfo.txt" :prompt nil :replace t)'
|
--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
|
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
|
WORKDIR /app
|
||||||
COPY . /app/projects/org-agent
|
COPY . /app/projects/org-agent
|
||||||
|
|
||||||
# 6. Pre-cache Lisp Dependencies
|
# 7. Pre-cache Lisp Dependencies
|
||||||
# This minimizes startup time by downloading dexador, cl-json, etc. during build
|
|
||||||
RUN sbcl --non-interactive \
|
RUN sbcl --non-interactive \
|
||||||
--eval '(push #p"/app/projects/org-agent/" asdf:*central-registry*)' \
|
--eval '(push #p"/app/projects/org-agent/" asdf:*central-registry*)' \
|
||||||
--eval '(ql:quickload :org-agent)'
|
--eval '(ql:quickload :org-agent)'
|
||||||
|
|
||||||
# 7. Environment & Volumes
|
# 8. Environment & Volumes
|
||||||
# The host's memex root should be mounted to /memex
|
# The host's memex root should be mounted to /memex
|
||||||
ENV MEMEX_DIR=/memex
|
ENV MEMEX_DIR=/memex
|
||||||
VOLUME ["/memex"]
|
VOLUME ["/memex"]
|
||||||
|
|||||||
36
README.org
36
README.org
@@ -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 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 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
300
literate/setup.org
Normal 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
134
scripts/install.sh
Executable 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
47
scripts/onboard-baremetal.sh
Executable 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}"
|
||||||
@@ -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}"
|
|
||||||
Reference in New Issue
Block a user