diff --git a/docs/downloads.md b/docs/downloads.md new file mode 100644 index 00000000..83983f90 --- /dev/null +++ b/docs/downloads.md @@ -0,0 +1,238 @@ +--- +title: Downloads +description: Download the OpenJarvis desktop app, browser app, CLI, or Python SDK +--- + +# Downloads + +OpenJarvis runs entirely on your hardware. Choose the interface that fits your workflow. + +--- + +## Desktop App + +The native desktop app bundles Ollama (the inference engine) and the OpenJarvis Python backend +into a single installer. Download, open, and start chatting — no terminal required. + +### Download + +| Platform | Download | Notes | +|----------|----------|-------| +| macOS (Apple Silicon) | [:material-download: **OpenJarvis.dmg**](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_aarch64.dmg) | M1/M2/M3/M4 Macs | +| macOS (Intel) | [:material-download: **OpenJarvis.dmg**](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_x64.dmg) | Intel Macs (2020 and earlier) | +| Windows (64-bit) | [:material-download: **OpenJarvis-setup.exe**](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_x64-setup.exe) | Windows 10+ | +| Linux (DEB) | [:material-download: **OpenJarvis.deb**](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_amd64.deb) | Ubuntu, Debian | +| Linux (RPM) | [:material-download: **OpenJarvis.rpm**](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_amd64.rpm) | Fedora, RHEL | + +!!! tip "All releases" + Browse all versions on the [GitHub Releases](https://github.com/HazyResearch/OpenJarvis/releases) page. + +### What's included + +The desktop app ships with: + +- **Ollama** sidecar — inference engine runs automatically in the background +- **OpenJarvis backend** — Python API server managed by the app +- **Full chat UI** — same interface as the browser app +- **Energy monitoring** — real-time power consumption tracking +- **Telemetry dashboard** — token throughput, latency, and cost comparison + +### Build from source + +```bash +git clone https://github.com/HazyResearch/OpenJarvis.git +cd OpenJarvis/desktop +npm install +npm run tauri build +``` + +The built installer will be in `desktop/src-tauri/target/release/bundle/`. + +--- + +## Browser App + +Run the full chat UI in your browser. Everything stays local — the backend runs on +your machine and the frontend connects via `localhost`. + +### One-command setup + +```bash +git clone https://github.com/HazyResearch/OpenJarvis.git +cd OpenJarvis +./scripts/quickstart.sh +``` + +The script handles everything: + +1. Checks for Python 3.10+ and Node.js 22+ +2. Installs Ollama if not present and pulls a starter model +3. Installs Python and frontend dependencies +4. Starts the backend API server and frontend dev server +5. Opens `http://localhost:5173` in your browser + +### Manual setup + +If you prefer to run each step yourself: + +=== "Step 1: Clone and install" + + ```bash + git clone https://github.com/HazyResearch/OpenJarvis.git + cd OpenJarvis + uv sync --extra server + cd frontend && npm install && cd .. + ``` + +=== "Step 2: Start Ollama" + + ```bash + # Install from https://ollama.com if not already installed + ollama serve & + ollama pull qwen3:0.6b + ``` + +=== "Step 3: Start backend" + + ```bash + uv run jarvis serve --port 8000 + ``` + +=== "Step 4: Start frontend" + + ```bash + cd frontend + npm run dev + ``` + +Then open [http://localhost:5173](http://localhost:5173). + +### What you get + +- **Chat interface** — markdown rendering, streaming responses, conversation history +- **Tool use** — calculator, web search, code interpreter, file I/O +- **System panel** — live telemetry, energy monitoring, cost comparison vs. cloud models +- **Dashboard** — energy graphs, trace debugging, cost breakdown +- **Settings** — model selection, agent configuration, theme toggle + +--- + +## CLI + +The command-line interface is the fastest way to interact with OpenJarvis +programmatically. Every feature is accessible from the terminal. + +### Install + +=== "uv (recommended)" + + ```bash + uv pip install openjarvis + ``` + +=== "pip" + + ```bash + pip install openjarvis + ``` + +=== "From source" + + ```bash + git clone https://github.com/HazyResearch/OpenJarvis.git + cd OpenJarvis + uv sync + ``` + +### Verify + +```bash +jarvis --version +# jarvis, version 1.0.0 +``` + +### First commands + +```bash +# Ask a question +jarvis ask "What is the capital of France?" + +# Use an agent with tools +jarvis ask --agent orchestrator --tools calculator "What is 137 * 42?" + +# Start the API server +jarvis serve --port 8000 + +# Run diagnostics +jarvis doctor + +# List available models +jarvis model list + +# Interactive chat +jarvis chat +``` + +!!! info "Inference backend required" + The CLI requires a running inference backend (e.g., Ollama). See the + [Installation guide](getting-started/installation.md#setting-up-an-inference-backend) + for setup instructions. + +--- + +## Python SDK + +For programmatic access, the `Jarvis` class provides a high-level sync API. + +### Install + +```bash +pip install openjarvis +``` + +### Quick example + +```python +from openjarvis import Jarvis + +j = Jarvis() +print(j.ask("Explain quicksort in two sentences.")) +j.close() +``` + +### With agents and tools + +```python +result = j.ask_full( + "What is the square root of 144?", + agent="orchestrator", + tools=["calculator", "think"], +) +print(result["content"]) # "12" +print(result["tool_results"]) # tool invocations +print(result["turns"]) # number of agent turns +``` + +### Composition layer + +For full control, use the `SystemBuilder`: + +```python +from openjarvis import SystemBuilder + +system = ( + SystemBuilder() + .engine("ollama") + .model("qwen3:8b") + .agent("orchestrator") + .tools(["calculator", "web_search", "file_read"]) + .enable_telemetry() + .enable_traces() + .build() +) + +result = system.ask("Summarize the latest AI news.") +system.close() +``` + +See the [Python SDK guide](user-guide/python-sdk.md) for the full API reference. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index f69ff7f0..793e960a 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -7,16 +7,43 @@ description: Install OpenJarvis and set up an inference backend This guide covers installing OpenJarvis, its optional extras, and setting up an inference backend. +## Quickstart (Recommended) + +The fastest way to get everything running — browser UI, backend, and inference engine — with a single command: + +```bash +git clone https://github.com/HazyResearch/OpenJarvis.git +cd OpenJarvis +./scripts/quickstart.sh +``` + +This script checks for Python 3.10+, Node.js, and Ollama (installing what's missing), pulls a starter model, installs all dependencies, starts the backend and frontend servers, and opens the chat UI in your browser. + +!!! tip "Desktop app" + Prefer a native app? Download the [Desktop App](../downloads.md#desktop-app) instead — it bundles everything into a single installer. + +--- + ## Requirements | Requirement | Version | Notes | |-------------|---------|-------| | Python | 3.10+ | Required | | Inference backend | Any | At least one of Ollama, vLLM, llama.cpp, SGLang, or a cloud API | -| Node.js | 22+ | Only required for OpenClaw agent infrastructure | +| Node.js | 18+ | Required for the browser UI; 22+ for OpenClaw agent | ## Installing OpenJarvis +=== "Quickstart script" + + ```bash + git clone https://github.com/HazyResearch/OpenJarvis.git + cd OpenJarvis + ./scripts/quickstart.sh + ``` + + Handles everything: deps, Ollama, model pull, backend, frontend, browser open. + === "uv (recommended)" ```bash diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index 10e04898..5a11b97c 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -5,11 +5,29 @@ description: Get up and running with OpenJarvis in minutes # Quick Start -This guide walks through the core workflows of OpenJarvis: asking questions, using agents with tools, managing memory, running benchmarks, and starting the API server. +This guide walks through the core workflows of OpenJarvis: the browser app, CLI, Python SDK, agents with tools, memory, benchmarks, and the API server. !!! info "Prerequisites" Make sure you have [installed OpenJarvis](installation.md) and have at least one inference backend running (e.g., `ollama serve`). +## Browser App + +The quickest way to experience OpenJarvis is the full chat UI running in your browser: + +```bash +git clone https://github.com/HazyResearch/OpenJarvis.git +cd OpenJarvis +./scripts/quickstart.sh +``` + +This launches the backend API server and a React frontend at [http://localhost:5173](http://localhost:5173). +You get a ChatGPT-like interface with streaming responses, tool use, energy monitoring, and a telemetry dashboard — all running locally on your hardware. + +To stop all services, press ++ctrl+c++ in the terminal. + +!!! tip "Environment variable" + Set `OPENJARVIS_MODEL` to change the default model: `OPENJARVIS_MODEL=deepseek-r1:14b ./scripts/quickstart.sh` + ## Initialize Configuration Start by detecting your hardware and generating a configuration file: diff --git a/docs/index.md b/docs/index.md index 776a4f09..eba7265c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -85,6 +85,28 @@ Everything runs on your hardware. Cloud APIs are optional. ## Quick Start +### Browser App + +Run the full chat UI locally with one script: + +```bash +git clone https://github.com/HazyResearch/OpenJarvis.git +cd OpenJarvis +./scripts/quickstart.sh +``` + +This installs dependencies, starts Ollama + a local model, launches the backend +and frontend, and opens `http://localhost:5173` in your browser. + +### Desktop App + +Download the native desktop app — it bundles Ollama and the Python backend +so everything works out of the box. + +[Download for macOS (Apple Silicon)](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_aarch64.dmg){ .md-button .md-button--primary } + +Also available for [macOS (Intel)](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_x64.dmg), [Windows](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_x64-setup.exe), [Linux (DEB)](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_amd64.deb), and [Linux (RPM)](https://github.com/HazyResearch/OpenJarvis/releases/latest/download/OpenJarvis_amd64.rpm). See the [Downloads](downloads.md) page for details. + ### Python SDK ```python diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 00000000..cacf382c --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,256 @@ +/* ── Fonts ─────────────────────────────────────────────────────────── */ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); + +:root { + --md-text-font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + --md-code-font: "JetBrains Mono", "Fira Code", "SF Mono", monospace; +} + +/* ── Color Overrides (Light) ──────────────────────────────────────── */ +[data-md-color-scheme="default"] { + --md-primary-fg-color: #1e293b; + --md-primary-fg-color--light: #334155; + --md-primary-fg-color--dark: #0f172a; + --md-accent-fg-color: #3b82f6; + --md-accent-fg-color--transparent: rgba(59, 130, 246, 0.1); + --md-default-bg-color: #ffffff; + --md-default-fg-color: #1e293b; + --md-default-fg-color--light: #475569; + --md-typeset-a-color: #2563eb; +} + +/* ── Color Overrides (Dark) ───────────────────────────────────────── */ +[data-md-color-scheme="slate"] { + --md-primary-fg-color: #0f172a; + --md-primary-fg-color--light: #1e293b; + --md-primary-fg-color--dark: #020617; + --md-accent-fg-color: #60a5fa; + --md-accent-fg-color--transparent: rgba(96, 165, 250, 0.1); + --md-default-bg-color: #0f172a; + --md-default-fg-color: #e2e8f0; + --md-default-fg-color--light: #94a3b8; + --md-typeset-a-color: #60a5fa; + --md-code-bg-color: #1e293b; +} + +/* ── Hero Section ─────────────────────────────────────────────────── */ +.hero { + padding: 4rem 0 3rem; + text-align: center; + position: relative; +} + +.hero h1 { + font-size: 3.2rem; + font-weight: 800; + letter-spacing: -0.03em; + line-height: 1.1; + margin-bottom: 1rem; + background: linear-gradient(135deg, #1e293b 0%, #3b82f6 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +[data-md-color-scheme="slate"] .hero h1 { + background: linear-gradient(135deg, #e2e8f0 0%, #60a5fa 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.hero .hero-tagline { + font-size: 1.25rem; + color: var(--md-default-fg-color--light); + max-width: 640px; + margin: 0 auto 2rem; + line-height: 1.6; + font-weight: 400; +} + +.hero-buttons { + display: flex; + gap: 1rem; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 2rem; +} + +.hero-buttons a { + display: inline-flex; + align-items: center; + gap: 0.5rem; + padding: 0.75rem 1.75rem; + border-radius: 8px; + font-weight: 600; + font-size: 0.95rem; + text-decoration: none; + transition: all 0.2s ease; +} + +.hero-buttons .btn-primary { + background: #3b82f6; + color: #fff; + box-shadow: 0 2px 8px rgba(59, 130, 246, 0.3); +} + +.hero-buttons .btn-primary:hover { + background: #2563eb; + box-shadow: 0 4px 16px rgba(59, 130, 246, 0.4); + transform: translateY(-1px); +} + +.hero-buttons .btn-secondary { + background: transparent; + color: var(--md-default-fg-color); + border: 1.5px solid var(--md-default-fg-color--light); +} + +.hero-buttons .btn-secondary:hover { + border-color: var(--md-accent-fg-color); + color: var(--md-accent-fg-color); + transform: translateY(-1px); +} + +/* ── Feature Cards ────────────────────────────────────────────────── */ +.md-typeset .grid.cards > ol > li, +.md-typeset .grid.cards > ul > li { + border: 1px solid rgba(0, 0, 0, 0.08); + border-radius: 12px; + padding: 1.5rem; + transition: all 0.25s ease; + background: var(--md-default-bg-color); +} + +[data-md-color-scheme="slate"] .md-typeset .grid.cards > ol > li, +[data-md-color-scheme="slate"] .md-typeset .grid.cards > ul > li { + border-color: rgba(255, 255, 255, 0.08); + background: #1e293b; +} + +.md-typeset .grid.cards > ol > li:hover, +.md-typeset .grid.cards > ul > li:hover { + border-color: var(--md-accent-fg-color); + box-shadow: 0 4px 20px rgba(59, 130, 246, 0.1); + transform: translateY(-2px); +} + +.md-typeset .grid.cards > ol > li > :first-child, +.md-typeset .grid.cards > ul > li > :first-child { + font-weight: 600; + font-size: 1.05rem; +} + +/* ── Code Blocks ──────────────────────────────────────────────────── */ +.md-typeset code { + border-radius: 4px; + font-size: 0.85em; +} + +.md-typeset pre { + border-radius: 10px; + border: 1px solid rgba(0, 0, 0, 0.06); +} + +[data-md-color-scheme="slate"] .md-typeset pre { + border-color: rgba(255, 255, 255, 0.06); +} + +.md-typeset pre > code { + font-size: 0.85rem; + line-height: 1.65; +} + +/* ── Tabs ─────────────────────────────────────────────────────────── */ +.md-typeset .tabbed-labels > label { + font-weight: 500; + font-size: 0.9rem; +} + +/* ── Navigation ───────────────────────────────────────────────────── */ +.md-tabs { + background: var(--md-primary-fg-color); +} + +.md-header { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08); +} + +/* ── Admonitions ──────────────────────────────────────────────────── */ +.md-typeset .admonition, +.md-typeset details { + border-radius: 8px; + border-width: 1px; + border-left-width: 4px; + box-shadow: none; +} + +/* ── Section Headers ──────────────────────────────────────────────── */ +.md-typeset h2 { + font-weight: 700; + letter-spacing: -0.02em; + margin-top: 2.5rem; +} + +.md-typeset h3 { + font-weight: 600; +} + +/* ── Footer ───────────────────────────────────────────────────────── */ +.md-footer { + background: var(--md-primary-fg-color--dark); +} + +/* ── Pill Badges (used on landing page) ───────────────────────────── */ +.pill { + display: inline-block; + padding: 0.3rem 0.9rem; + border-radius: 100px; + font-size: 0.8rem; + font-weight: 600; + letter-spacing: 0.02em; + background: var(--md-accent-fg-color--transparent); + color: var(--md-accent-fg-color); + margin-bottom: 1rem; +} + +/* ── Divider ──────────────────────────────────────────────────────── */ +.md-typeset hr { + border-color: rgba(0, 0, 0, 0.06); + margin: 3rem 0; +} + +[data-md-color-scheme="slate"] .md-typeset hr { + border-color: rgba(255, 255, 255, 0.06); +} + +/* ── Responsive ───────────────────────────────────────────────────── */ +@media (max-width: 768px) { + .hero h1 { + font-size: 2.2rem; + } + .hero .hero-tagline { + font-size: 1.05rem; + } + .hero-buttons { + flex-direction: column; + align-items: center; + } +} + +/* ── Quick-start section ──────────────────────────────────────────── */ +.quick-start { + max-width: 800px; + margin: 0 auto; +} + +.quick-start h2 { + text-align: center; + margin-bottom: 0.5rem; +} + +.quick-start > p:first-of-type { + text-align: center; + color: var(--md-default-fg-color--light); + margin-bottom: 2rem; +} diff --git a/mkdocs.yml b/mkdocs.yml index 80650f1c..c4c5ec11 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -11,6 +11,9 @@ copyright: Copyright © 2026 OpenJarvis Contributors theme: name: material language: en + font: + text: Inter + code: JetBrains Mono features: - navigation.tabs - navigation.tabs.sticky @@ -27,21 +30,24 @@ theme: palette: - media: "(prefers-color-scheme: light)" scheme: default - primary: indigo - accent: amber + primary: custom + accent: blue toggle: icon: material/brightness-7 name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: indigo - accent: amber + primary: custom + accent: blue toggle: icon: material/brightness-4 name: Switch to light mode icon: repo: fontawesome/brands/github +extra_css: + - stylesheets/extra.css + plugins: - search - mkdocstrings: @@ -118,6 +124,7 @@ extra: nav: - Home: index.md + - Downloads: downloads.md - Getting Started: - Installation: getting-started/installation.md - Quick Start: getting-started/quickstart.md diff --git a/scripts/quickstart.sh b/scripts/quickstart.sh new file mode 100755 index 00000000..33339d50 --- /dev/null +++ b/scripts/quickstart.sh @@ -0,0 +1,192 @@ +#!/usr/bin/env bash +set -euo pipefail + +# ── OpenJarvis Quickstart ───────────────────────────────────────────── +# One-command setup: installs deps, starts Ollama + model, launches +# the backend API server and frontend, then opens the browser. +# +# Usage: +# git clone https://github.com/HazyResearch/OpenJarvis.git +# cd OpenJarvis +# ./scripts/quickstart.sh +# ────────────────────────────────────────────────────────────────────── + +BLUE='\033[0;34m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' +BOLD='\033[1m' + +info() { echo -e "${BLUE}[info]${NC} $*"; } +ok() { echo -e "${GREEN}[ok]${NC} $*"; } +warn() { echo -e "${YELLOW}[warn]${NC} $*"; } +fail() { echo -e "${RED}[fail]${NC} $*"; exit 1; } + +CLEANUP_PIDS=() +cleanup() { + echo "" + info "Shutting down..." + for pid in "${CLEANUP_PIDS[@]}"; do + kill "$pid" 2>/dev/null || true + done + wait 2>/dev/null || true + ok "Done." +} +trap cleanup EXIT INT TERM + +# ── Navigate to repo root ──────────────────────────────────────────── +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" +cd "$REPO_ROOT" + +echo -e "${BOLD}" +echo " ┌──────────────────────────────────┐" +echo " │ OpenJarvis Quickstart │" +echo " └──────────────────────────────────┘" +echo -e "${NC}" + +# ── 1. Check Python ────────────────────────────────────────────────── +info "Checking Python..." +if command -v python3 &>/dev/null; then + PY_VERSION=$(python3 -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')") + PY_MAJOR=$(echo "$PY_VERSION" | cut -d. -f1) + PY_MINOR=$(echo "$PY_VERSION" | cut -d. -f2) + if [ "$PY_MAJOR" -ge 3 ] && [ "$PY_MINOR" -ge 10 ]; then + ok "Python $PY_VERSION" + else + fail "Python 3.10+ required (found $PY_VERSION)" + fi +else + fail "Python 3 not found. Install from https://python.org" +fi + +# ── 2. Check / install uv ─────────────────────────────────────────── +info "Checking uv..." +if command -v uv &>/dev/null; then + ok "uv $(uv --version 2>/dev/null | head -1)" +else + warn "uv not found — installing..." + curl -LsSf https://astral.sh/uv/install.sh | sh + export PATH="$HOME/.local/bin:$PATH" + ok "uv installed" +fi + +# ── 3. Check Node.js ──────────────────────────────────────────────── +info "Checking Node.js..." +if command -v node &>/dev/null; then + NODE_VERSION=$(node --version) + NODE_MAJOR=$(echo "$NODE_VERSION" | sed 's/v//' | cut -d. -f1) + if [ "$NODE_MAJOR" -ge 18 ]; then + ok "Node.js $NODE_VERSION" + else + fail "Node.js 18+ required (found $NODE_VERSION). Install from https://nodejs.org" + fi +else + fail "Node.js not found. Install from https://nodejs.org" +fi + +# ── 4. Check / install Ollama ──────────────────────────────────────── +info "Checking Ollama..." +if command -v ollama &>/dev/null; then + ok "Ollama found" +else + warn "Ollama not found — installing..." + case "$(uname -s)" in + Darwin) + if command -v brew &>/dev/null; then + brew install ollama + else + echo " Download Ollama from https://ollama.com/download" + echo " Then re-run this script." + exit 1 + fi + ;; + Linux) + curl -fsSL https://ollama.com/install.sh | sh + ;; + *) + echo " Download Ollama from https://ollama.com/download" + echo " Then re-run this script." + exit 1 + ;; + esac + ok "Ollama installed" +fi + +# ── 5. Start Ollama if not running ─────────────────────────────────── +info "Checking if Ollama is running..." +if curl -sf http://localhost:11434/api/tags &>/dev/null; then + ok "Ollama is running" +else + info "Starting Ollama..." + ollama serve &>/dev/null & + CLEANUP_PIDS+=($!) + sleep 3 + if curl -sf http://localhost:11434/api/tags &>/dev/null; then + ok "Ollama started" + else + fail "Could not start Ollama. Try running 'ollama serve' manually." + fi +fi + +# ── 6. Pull a starter model ───────────────────────────────────────── +MODEL="${OPENJARVIS_MODEL:-qwen3:0.6b}" +info "Ensuring model '$MODEL' is available..." +if ollama list 2>/dev/null | grep -q "$MODEL"; then + ok "Model '$MODEL' already pulled" +else + info "Pulling '$MODEL' (this may take a minute)..." + ollama pull "$MODEL" + ok "Model '$MODEL' ready" +fi + +# ── 7. Install Python dependencies ────────────────────────────────── +info "Installing Python dependencies..." +uv sync --extra server --quiet 2>/dev/null || uv sync --extra server +ok "Python dependencies installed" + +# ── 8. Install frontend dependencies ──────────────────────────────── +info "Installing frontend dependencies..." +(cd frontend && npm install --silent 2>/dev/null || npm install) +ok "Frontend dependencies installed" + +# ── 9. Start backend ──────────────────────────────────────────────── +info "Starting backend API server on port 8000..." +uv run jarvis serve --port 8000 &>/dev/null & +CLEANUP_PIDS+=($!) +sleep 3 + +if curl -sf http://localhost:8000/health &>/dev/null; then + ok "Backend running at http://localhost:8000" +else + warn "Backend may still be starting..." +fi + +# ── 10. Start frontend ────────────────────────────────────────────── +info "Starting frontend dev server on port 5173..." +(cd frontend && npm run dev) &>/dev/null & +CLEANUP_PIDS+=($!) +sleep 3 +ok "Frontend running at http://localhost:5173" + +# ── 11. Open browser ──────────────────────────────────────────────── +URL="http://localhost:5173" +info "Opening $URL ..." +case "$(uname -s)" in + Darwin) open "$URL" ;; + Linux) xdg-open "$URL" 2>/dev/null || true ;; + *) true ;; +esac + +echo "" +echo -e "${GREEN}${BOLD} OpenJarvis is running!${NC}" +echo "" +echo " Chat UI: http://localhost:5173" +echo " API: http://localhost:8000" +echo " Model: $MODEL" +echo "" +echo " Press Ctrl+C to stop all services." +echo "" + +wait