run.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
# Slate -- one-command run.
#
# Supply your keys in slate.env (copy slate.env.example), then run: ./run.sh
#
# It is idempotent and re-runnable, and it FAILS CLOSED: any missing required
# key stops the run with a clear message, so Slate never starts half-configured.
# Read docs/configuration.md for what each key is and why. Read docs/quickstart.md
# for the whole walk-through.
#
# By default this runs Slate directly with Node (>= 24). To run it in Docker
# instead, see docs/quickstart.md ("Run it in Docker").
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
cd "$HERE"
say() { printf "\n==> %s\n" "$*"; }
info() { printf " %s\n" "$*"; }
warn() { printf " (note) %s\n" "$*"; }
die() { printf "\nERROR: %s\n" "$*" >&2; exit 1; }
# ---- 1. load and check slate.env --------------------------------------------
say "Checking your keys"
[ -f slate.env ] || die "slate.env not found. Run: cp slate.env.example slate.env (then edit it)."
# Export every value so bot.mjs (which reads process.env) can see it.
set -a; . ./slate.env; set +a
# The one hard requirement.
[ -n "${DISCORD_TOKEN:-}" ] || die "slate.env: DISCORD_TOKEN is required but empty -- get it from the Discord Developer Portal (Bot -> Reset Token)."
# The writing brain: Claude path needs its endpoint; otherwise we fall back to Ollama.
if [ -n "${CF_AIG_TOKEN:-}" ]; then
[ -n "${CF_GATEWAY_ENDPOINT:-}" ] || die "slate.env: CF_AIG_TOKEN is set (Claude path) but CF_GATEWAY_ENDPOINT is empty -- add your AI Gateway compat URL, or clear CF_AIG_TOKEN to use Ollama."
info "Writing brain: Claude via Cloudflare AI Gateway (model ${DISCORD_MODEL:-claude-sonnet-4-6})."
else
info "Writing brain: Ollama at ${OLLAMA_BASE_URL:-http://localhost:11434/v1} (model ${DISCORD_MODEL:-qwen3.6:27b-ctx8k}). Set CF_AIG_TOKEN + CF_GATEWAY_ENDPOINT to use Claude."
fi
# Optional features: warn, never fail, so a first run is easy.
[ -n "${VIVIJURE_API_URL:-}" ] || warn "VIVIJURE_API_URL is empty -- Slate will plan films but cannot render them. Point it at your Studio to enable !render."
[ -n "${CF_D1_TOKEN:-}" ] || warn "CF_D1_TOKEN is empty -- Slate will run without saved memory; projects reset when the process restarts."
[ -n "${SEARCH_WORKER_URL:-}" ] || warn "SEARCH_WORKER_URL is empty -- web search and the knowledge base are off. That is fine to start."
# ---- 2. check the runtime ---------------------------------------------------
say "Checking Node"
command -v node >/dev/null 2>&1 || die "Node is not installed. Install Node 24 or newer (nodejs.org), then run ./run.sh again. Or run Slate in Docker -- see docs/quickstart.md."
NODE_MAJOR="$(node -p "process.versions.node.split(\".\")[0]")"
[ "$NODE_MAJOR" -ge 24 ] || die "Node $NODE_MAJOR is too old. Slate needs Node 24 or newer."
info "Node $(node -v) OK."
# ---- 3. install dependencies (idempotent) -----------------------------------
say "Installing dependencies"
if [ -d node_modules ]; then
info "node_modules already present; skipping install (delete it to force a fresh install)."
else
if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi
fi
# ---- 4. run -----------------------------------------------------------------
say "Starting Slate"
info "Press Ctrl-C to stop."
exec node bot.mjs