891 lines
34 KiB
HTML
891 lines
34 KiB
HTML
|
|
<!DOCTYPE HTML>
|
||
|
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||
|
|
<head>
|
||
|
|
<!-- Book generated using mdBook -->
|
||
|
|
<meta charset="UTF-8">
|
||
|
|
<title>Setup Guide - VAPORA Platform Documentation</title>
|
||
|
|
|
||
|
|
|
||
|
|
<!-- Custom HTML head -->
|
||
|
|
|
||
|
|
<meta name="description" content="Comprehensive documentation for VAPORA, an intelligent development orchestration platform built entirely in Rust.">
|
||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
|
|
<meta name="theme-color" content="#ffffff">
|
||
|
|
|
||
|
|
<link rel="icon" href="../favicon.svg">
|
||
|
|
<link rel="shortcut icon" href="../favicon.png">
|
||
|
|
<link rel="stylesheet" href="../css/variables.css">
|
||
|
|
<link rel="stylesheet" href="../css/general.css">
|
||
|
|
<link rel="stylesheet" href="../css/chrome.css">
|
||
|
|
<link rel="stylesheet" href="../css/print.css" media="print">
|
||
|
|
|
||
|
|
<!-- Fonts -->
|
||
|
|
<link rel="stylesheet" href="../FontAwesome/css/font-awesome.css">
|
||
|
|
<link rel="stylesheet" href="../fonts/fonts.css">
|
||
|
|
|
||
|
|
<!-- Highlight.js Stylesheets -->
|
||
|
|
<link rel="stylesheet" id="highlight-css" href="../highlight.css">
|
||
|
|
<link rel="stylesheet" id="tomorrow-night-css" href="../tomorrow-night.css">
|
||
|
|
<link rel="stylesheet" id="ayu-highlight-css" href="../ayu-highlight.css">
|
||
|
|
|
||
|
|
<!-- Custom theme stylesheets -->
|
||
|
|
|
||
|
|
|
||
|
|
<!-- Provide site root and default themes to javascript -->
|
||
|
|
<script>
|
||
|
|
const path_to_root = "../";
|
||
|
|
const default_light_theme = "light";
|
||
|
|
const default_dark_theme = "dark";
|
||
|
|
</script>
|
||
|
|
<!-- Start loading toc.js asap -->
|
||
|
|
<script src="../toc.js"></script>
|
||
|
|
</head>
|
||
|
|
<body>
|
||
|
|
<div id="mdbook-help-container">
|
||
|
|
<div id="mdbook-help-popup">
|
||
|
|
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
|
||
|
|
<div>
|
||
|
|
<p>Press <kbd>←</kbd> or <kbd>→</kbd> to navigate between chapters</p>
|
||
|
|
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
|
||
|
|
<p>Press <kbd>?</kbd> to show this help</p>
|
||
|
|
<p>Press <kbd>Esc</kbd> to hide this help</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div id="body-container">
|
||
|
|
<!-- Work around some values being stored in localStorage wrapped in quotes -->
|
||
|
|
<script>
|
||
|
|
try {
|
||
|
|
let theme = localStorage.getItem('mdbook-theme');
|
||
|
|
let sidebar = localStorage.getItem('mdbook-sidebar');
|
||
|
|
|
||
|
|
if (theme.startsWith('"') && theme.endsWith('"')) {
|
||
|
|
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
|
||
|
|
}
|
||
|
|
|
||
|
|
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
|
||
|
|
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
|
||
|
|
}
|
||
|
|
} catch (e) { }
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<!-- Set the theme before any content is loaded, prevents flash -->
|
||
|
|
<script>
|
||
|
|
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
|
||
|
|
let theme;
|
||
|
|
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
|
||
|
|
if (theme === null || theme === undefined) { theme = default_theme; }
|
||
|
|
const html = document.documentElement;
|
||
|
|
html.classList.remove('light')
|
||
|
|
html.classList.add(theme);
|
||
|
|
html.classList.add("js");
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
|
||
|
|
|
||
|
|
<!-- Hide / unhide sidebar before it is displayed -->
|
||
|
|
<script>
|
||
|
|
let sidebar = null;
|
||
|
|
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
|
||
|
|
if (document.body.clientWidth >= 1080) {
|
||
|
|
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
|
||
|
|
sidebar = sidebar || 'visible';
|
||
|
|
} else {
|
||
|
|
sidebar = 'hidden';
|
||
|
|
}
|
||
|
|
sidebar_toggle.checked = sidebar === 'visible';
|
||
|
|
html.classList.remove('sidebar-visible');
|
||
|
|
html.classList.add("sidebar-" + sidebar);
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
|
||
|
|
<!-- populated by js -->
|
||
|
|
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
|
||
|
|
<noscript>
|
||
|
|
<iframe class="sidebar-iframe-outer" src="../toc.html"></iframe>
|
||
|
|
</noscript>
|
||
|
|
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
|
||
|
|
<div class="sidebar-resize-indicator"></div>
|
||
|
|
</div>
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
<div id="page-wrapper" class="page-wrapper">
|
||
|
|
|
||
|
|
<div class="page">
|
||
|
|
<div id="menu-bar-hover-placeholder"></div>
|
||
|
|
<div id="menu-bar" class="menu-bar sticky">
|
||
|
|
<div class="left-buttons">
|
||
|
|
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||
|
|
<i class="fa fa-bars"></i>
|
||
|
|
</label>
|
||
|
|
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||
|
|
<i class="fa fa-paint-brush"></i>
|
||
|
|
</button>
|
||
|
|
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
|
||
|
|
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
|
||
|
|
</ul>
|
||
|
|
<button id="search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="searchbar">
|
||
|
|
<i class="fa fa-search"></i>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<h1 class="menu-title">VAPORA Platform Documentation</h1>
|
||
|
|
|
||
|
|
<div class="right-buttons">
|
||
|
|
<a href="../print.html" title="Print this book" aria-label="Print this book">
|
||
|
|
<i id="print-button" class="fa fa-print"></i>
|
||
|
|
</a>
|
||
|
|
<a href="https://github.com/vapora-platform/vapora" title="Git repository" aria-label="Git repository">
|
||
|
|
<i id="git-repository-button" class="fa fa-github"></i>
|
||
|
|
</a>
|
||
|
|
<a href="https://github.com/vapora-platform/vapora/edit/main/docs/src/../setup/setup-guide.md" title="Suggest an edit" aria-label="Suggest an edit">
|
||
|
|
<i id="git-edit-button" class="fa fa-edit"></i>
|
||
|
|
</a>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="search-wrapper" class="hidden">
|
||
|
|
<form id="searchbar-outer" class="searchbar-outer">
|
||
|
|
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
|
||
|
|
</form>
|
||
|
|
<div id="searchresults-outer" class="searchresults-outer hidden">
|
||
|
|
<div id="searchresults-header" class="searchresults-header"></div>
|
||
|
|
<ul id="searchresults">
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
|
||
|
|
<script>
|
||
|
|
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
|
||
|
|
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
|
||
|
|
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
|
||
|
|
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<div id="content" class="content">
|
||
|
|
<main>
|
||
|
|
<hr />
|
||
|
|
<h2>title: Vapora Project - Complete Setup Guide
|
||
|
|
date: 2025-11-10
|
||
|
|
version: 1.0
|
||
|
|
status: READY</h2>
|
||
|
|
<h1 id="-vapora---complete-setup-guide"><a class="header" href="#-vapora---complete-setup-guide">🛠️ Vapora - Complete Setup Guide</a></h1>
|
||
|
|
<p><strong>Complete step-by-step guide for setting up the entire Vapora project from scratch.</strong></p>
|
||
|
|
<hr />
|
||
|
|
<h2 id="-table-of-contents"><a class="header" href="#-table-of-contents">📋 Table of Contents</a></h2>
|
||
|
|
<ol>
|
||
|
|
<li><a href="#prerequisites--environment">Prerequisites & Environment</a></li>
|
||
|
|
<li><a href="#installation">Installation</a></li>
|
||
|
|
<li><a href="#configuration">Configuration</a></li>
|
||
|
|
<li><a href="#building--testing">Building & Testing</a></li>
|
||
|
|
<li><a href="#development-setup">Development Setup</a></li>
|
||
|
|
<li><a href="#first-run">First Run</a></li>
|
||
|
|
<li><a href="#troubleshooting">Troubleshooting</a></li>
|
||
|
|
</ol>
|
||
|
|
<hr />
|
||
|
|
<h2 id="prerequisites--environment"><a class="header" href="#prerequisites--environment">Prerequisites & Environment</a></h2>
|
||
|
|
<h3 id="system-requirements"><a class="header" href="#system-requirements">System Requirements</a></h3>
|
||
|
|
<div class="table-wrapper"><table><thead><tr><th>Requirement</th><th>Minimum</th><th>Recommended</th></tr></thead><tbody>
|
||
|
|
<tr><td>OS</td><td>macOS 10.15+</td><td>macOS 12+ (M1/M2 optimized)</td></tr>
|
||
|
|
<tr><td>CPU</td><td>2-core</td><td>4+ cores</td></tr>
|
||
|
|
<tr><td>RAM</td><td>4GB</td><td>8GB+</td></tr>
|
||
|
|
<tr><td>Disk</td><td>2GB</td><td>5GB+</td></tr>
|
||
|
|
<tr><td>Internet</td><td>Required</td><td>Required</td></tr>
|
||
|
|
</tbody></table>
|
||
|
|
</div>
|
||
|
|
<h3 id="software-requirements"><a class="header" href="#software-requirements">Software Requirements</a></h3>
|
||
|
|
<p><strong>Required:</strong></p>
|
||
|
|
<ul>
|
||
|
|
<li>Rust 1.75+ (install from https://rustup.rs)</li>
|
||
|
|
<li>Cargo (comes with Rust)</li>
|
||
|
|
<li>Git 2.20+</li>
|
||
|
|
<li>NuShell 0.95+ (for scripts)</li>
|
||
|
|
</ul>
|
||
|
|
<p><strong>Optional but Recommended:</strong></p>
|
||
|
|
<ul>
|
||
|
|
<li>Node.js 18+ (for frontend tooling)</li>
|
||
|
|
<li>Docker (for containerization)</li>
|
||
|
|
<li>Kubernetes tools (kubectl, k3s for deployment)</li>
|
||
|
|
</ul>
|
||
|
|
<h3 id="prerequisite-check-script"><a class="header" href="#prerequisite-check-script">Prerequisite Check Script</a></h3>
|
||
|
|
<pre><code class="language-bash">#!/bin/bash
|
||
|
|
echo "🔍 Checking Vapora prerequisites..."
|
||
|
|
echo "=================================="
|
||
|
|
|
||
|
|
# Check Rust
|
||
|
|
if ! command -v rustc &> /dev/null; then
|
||
|
|
echo "❌ Rust not found. Install from https://rustup.rs"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "✅ Rust $(rustc --version | awk '{print $2}')"
|
||
|
|
|
||
|
|
# Check Cargo
|
||
|
|
if ! command -v cargo &> /dev/null; then
|
||
|
|
echo "❌ Cargo not found"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "✅ Cargo $(cargo --version | awk '{print $2}')"
|
||
|
|
|
||
|
|
# Check Git
|
||
|
|
if ! command -v git &> /dev/null; then
|
||
|
|
echo "❌ Git not found. Install from https://git-scm.com"
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
echo "✅ Git $(git --version | awk '{print $3}')"
|
||
|
|
|
||
|
|
# Check NuShell (optional)
|
||
|
|
if command -v nu &> /dev/null; then
|
||
|
|
echo "✅ NuShell $(nu --version)"
|
||
|
|
else
|
||
|
|
echo "⚠️ NuShell not found (optional, needed for scripts)"
|
||
|
|
fi
|
||
|
|
|
||
|
|
echo "=================================="
|
||
|
|
echo "✅ All prerequisites satisfied!"
|
||
|
|
</code></pre>
|
||
|
|
<p>Save as <code>check-prerequisites.sh</code> and run:</p>
|
||
|
|
<pre><code class="language-bash">chmod +x check-prerequisites.sh
|
||
|
|
./check-prerequisites.sh
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="installation"><a class="header" href="#installation">Installation</a></h2>
|
||
|
|
<h3 id="step-1-prepare-your-environment"><a class="header" href="#step-1-prepare-your-environment">Step 1: Prepare Your Environment</a></h3>
|
||
|
|
<pre><code class="language-bash"># Update Rust (if already installed)
|
||
|
|
rustup update stable
|
||
|
|
rustup component add rustfmt clippy
|
||
|
|
|
||
|
|
# Clone or verify Vapora repo
|
||
|
|
if [ ! -d vapora ]; then
|
||
|
|
git clone https://github.com/vapora/vapora.git
|
||
|
|
fi
|
||
|
|
|
||
|
|
cd vapora
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="step-2-install-nushell-if-needed"><a class="header" href="#step-2-install-nushell-if-needed">Step 2: Install NuShell (if needed)</a></h3>
|
||
|
|
<pre><code class="language-bash"># macOS with Homebrew
|
||
|
|
brew install nu
|
||
|
|
|
||
|
|
# Or from source (if on other OS)
|
||
|
|
# See https://www.nushell.sh/book/installation.html
|
||
|
|
</code></pre>
|
||
|
|
<p>Verify:</p>
|
||
|
|
<pre><code class="language-bash">nu --version # Should be 0.95+
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="step-3-install-frontend-tools-if-building-frontend"><a class="header" href="#step-3-install-frontend-tools-if-building-frontend">Step 3: Install Frontend Tools (if building frontend)</a></h3>
|
||
|
|
<pre><code class="language-bash"># Install trunk for Leptos WASM building
|
||
|
|
cargo install trunk
|
||
|
|
|
||
|
|
# Install wasm-pack for WASM compilation
|
||
|
|
rustup target add wasm32-unknown-unknown
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="step-4-download-workspace-dependencies"><a class="header" href="#step-4-download-workspace-dependencies">Step 4: Download Workspace Dependencies</a></h3>
|
||
|
|
<pre><code class="language-bash"># Download all dependencies (no compilation yet)
|
||
|
|
cargo fetch
|
||
|
|
|
||
|
|
# This may take 2-3 minutes depending on internet speed
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="step-5-verify-workspace-structure"><a class="header" href="#step-5-verify-workspace-structure">Step 5: Verify Workspace Structure</a></h3>
|
||
|
|
<pre><code class="language-bash"># Verify all crates are present
|
||
|
|
ls -la crates/
|
||
|
|
|
||
|
|
# Expected output (8 crates):
|
||
|
|
# vapora-agents/
|
||
|
|
# vapora-backend/
|
||
|
|
# vapora-doc-lifecycle/
|
||
|
|
# vapora-frontend/
|
||
|
|
# vapora-llm-router/
|
||
|
|
# vapora-mcp-server/
|
||
|
|
# vapora-shared/
|
||
|
|
# vapora-tracking/
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="configuration"><a class="header" href="#configuration">Configuration</a></h2>
|
||
|
|
<h3 id="option-1-default-configuration-recommended"><a class="header" href="#option-1-default-configuration-recommended">Option 1: Default Configuration (Recommended)</a></h3>
|
||
|
|
<p>The project works out of the box with sensible defaults:</p>
|
||
|
|
<pre><code class="language-yaml"># Default Settings
|
||
|
|
Backend:
|
||
|
|
port: 3000
|
||
|
|
host: 127.0.0.1
|
||
|
|
env: development
|
||
|
|
|
||
|
|
Database:
|
||
|
|
type: SQLite (local)
|
||
|
|
path: ~/.vapora/data.db
|
||
|
|
|
||
|
|
Tracking:
|
||
|
|
database: ~/.tracking/database.sqlite
|
||
|
|
watch_dirs:
|
||
|
|
- .coder/
|
||
|
|
- ~/.claude/todos/
|
||
|
|
debounce_ms: 500
|
||
|
|
|
||
|
|
LLM Router:
|
||
|
|
default_providers:
|
||
|
|
- claude3-opus
|
||
|
|
- gpt-4
|
||
|
|
- gemini-2-pro
|
||
|
|
fallback_enabled: true
|
||
|
|
|
||
|
|
Frontend:
|
||
|
|
port: 8080
|
||
|
|
hot_reload: true
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>No configuration needed to start developing!</strong> Skip to <a href="#building--testing">Building & Testing</a>.</p>
|
||
|
|
<h3 id="option-2-environment-variables"><a class="header" href="#option-2-environment-variables">Option 2: Environment Variables</a></h3>
|
||
|
|
<p>Create <code>.env</code> file in project root:</p>
|
||
|
|
<pre><code class="language-bash"># Backend Configuration
|
||
|
|
VAPORA_PORT=3000
|
||
|
|
VAPORA_HOST=127.0.0.1
|
||
|
|
RUST_ENV=development
|
||
|
|
RUST_LOG=debug
|
||
|
|
|
||
|
|
# Database
|
||
|
|
VAPORA_DATABASE_URL=sqlite:///Users/Akasha/.vapora/data.db
|
||
|
|
DATABASE_MAX_CONNECTIONS=5
|
||
|
|
|
||
|
|
# Tracking System
|
||
|
|
TRACKING_DATABASE_URL=sqlite:///Users/Akasha/.tracking/database.sqlite
|
||
|
|
TRACKING_API_PORT=3000
|
||
|
|
TRACKING_WATCH_DIRS=/Users/Akasha/.coder,/Users/Akasha/.claude/todos
|
||
|
|
TRACKING_DEBOUNCE_MS=500
|
||
|
|
|
||
|
|
# LLM Configuration
|
||
|
|
LLM_DEFAULT_PROVIDER=claude-opus
|
||
|
|
LLM_FALLBACK_ENABLED=true
|
||
|
|
OPENAI_API_KEY=your_key_here
|
||
|
|
ANTHROPIC_API_KEY=your_key_here
|
||
|
|
GOOGLE_API_KEY=your_key_here
|
||
|
|
|
||
|
|
# Frontend
|
||
|
|
FRONTEND_PORT=8080
|
||
|
|
FRONTEND_HOT_RELOAD=true
|
||
|
|
|
||
|
|
# Logging
|
||
|
|
LOG_LEVEL=debug
|
||
|
|
LOG_FORMAT=json
|
||
|
|
</code></pre>
|
||
|
|
<p>Load with:</p>
|
||
|
|
<pre><code class="language-bash">export $(cat .env | xargs)
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="option-3-configuration-file"><a class="header" href="#option-3-configuration-file">Option 3: Configuration File</a></h3>
|
||
|
|
<p>Create <code>~/.vapora/config.toml</code>:</p>
|
||
|
|
<pre><code class="language-toml">[server]
|
||
|
|
port = 3000
|
||
|
|
host = "127.0.0.1"
|
||
|
|
environment = "development"
|
||
|
|
|
||
|
|
[database]
|
||
|
|
url = "sqlite:///Users/Akasha/.vapora/data.db"
|
||
|
|
max_connections = 5
|
||
|
|
timeout_seconds = 5
|
||
|
|
|
||
|
|
[tracking]
|
||
|
|
database_url = "sqlite:///Users/Akasha/.tracking/database.sqlite"
|
||
|
|
api_port = 3000
|
||
|
|
watch_dirs = [
|
||
|
|
"/Users/Akasha/.coder",
|
||
|
|
"/Users/Akasha/.claude/todos"
|
||
|
|
]
|
||
|
|
debounce_ms = 500
|
||
|
|
|
||
|
|
[llm_router]
|
||
|
|
default_provider = "claude-opus"
|
||
|
|
fallback_enabled = true
|
||
|
|
|
||
|
|
[frontend]
|
||
|
|
port = 8080
|
||
|
|
hot_reload = true
|
||
|
|
|
||
|
|
[logging]
|
||
|
|
level = "debug"
|
||
|
|
format = "json"
|
||
|
|
file = "/tmp/vapora.log"
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="building--testing"><a class="header" href="#building--testing">Building & Testing</a></h2>
|
||
|
|
<h3 id="phase-1-build-all-crates"><a class="header" href="#phase-1-build-all-crates">Phase 1: Build All Crates</a></h3>
|
||
|
|
<pre><code class="language-bash"># Build all crates in workspace (dev mode)
|
||
|
|
cargo build
|
||
|
|
|
||
|
|
# Build time: 3-8 minutes (first time)
|
||
|
|
# Subsequent builds: 10-30 seconds
|
||
|
|
|
||
|
|
# For optimized release build (slower to build, faster runtime)
|
||
|
|
cargo build --release
|
||
|
|
|
||
|
|
# Build time: 5-15 minutes (first time)
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="phase-2-run-full-test-suite"><a class="header" href="#phase-2-run-full-test-suite">Phase 2: Run Full Test Suite</a></h3>
|
||
|
|
<pre><code class="language-bash"># Run all tests
|
||
|
|
cargo test --lib
|
||
|
|
|
||
|
|
# Expected output:
|
||
|
|
# test result: ok. XXX passed; 0 failed; 0 ignored; 0 measured
|
||
|
|
|
||
|
|
# Run tests for specific crate
|
||
|
|
cargo test -p vapora-tracking --lib
|
||
|
|
cargo test -p vapora-backend --lib
|
||
|
|
cargo test -p vapora-agents --lib
|
||
|
|
|
||
|
|
# Run tests with output
|
||
|
|
cargo test --lib -- --nocapture --test-threads=1
|
||
|
|
|
||
|
|
# Run specific test
|
||
|
|
cargo test test_health_endpoint -- --exact
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="phase-3-code-quality-checks"><a class="header" href="#phase-3-code-quality-checks">Phase 3: Code Quality Checks</a></h3>
|
||
|
|
<pre><code class="language-bash"># Format code
|
||
|
|
cargo fmt
|
||
|
|
|
||
|
|
# Check formatting without modifying
|
||
|
|
cargo fmt -- --check
|
||
|
|
|
||
|
|
# Lint with clippy
|
||
|
|
cargo clippy --all-targets --all-features -- -W clippy::all
|
||
|
|
|
||
|
|
# Run both format and clippy
|
||
|
|
cargo fmt && cargo clippy --all-targets --all-features -- -W clippy::all
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="phase-4-documentation"><a class="header" href="#phase-4-documentation">Phase 4: Documentation</a></h3>
|
||
|
|
<pre><code class="language-bash"># Generate documentation for all crates
|
||
|
|
cargo doc --no-deps --open
|
||
|
|
|
||
|
|
# Generate for specific crate
|
||
|
|
cargo doc -p vapora-tracking --no-deps --open
|
||
|
|
|
||
|
|
# Check documentation coverage
|
||
|
|
cargo doc --document-private-items
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="verification-checklist"><a class="header" href="#verification-checklist">Verification Checklist</a></h3>
|
||
|
|
<pre><code class="language-bash">#!/bin/bash
|
||
|
|
set -e
|
||
|
|
|
||
|
|
echo "🔍 Running Vapora verification..."
|
||
|
|
echo "=================================="
|
||
|
|
|
||
|
|
# Build
|
||
|
|
echo "1. Building workspace..."
|
||
|
|
cargo build 2>&1 | tail -3
|
||
|
|
echo "✅ Build successful"
|
||
|
|
|
||
|
|
# Tests
|
||
|
|
echo "2. Running tests..."
|
||
|
|
cargo test --lib 2>&1 | grep "test result"
|
||
|
|
echo "✅ Tests passed"
|
||
|
|
|
||
|
|
# Clippy
|
||
|
|
echo "3. Running clippy..."
|
||
|
|
cargo clippy --all-targets --all-features 2>&1 | grep -v "warning:" | tail -1
|
||
|
|
echo "✅ Code quality checks passed"
|
||
|
|
|
||
|
|
# Format
|
||
|
|
echo "4. Checking format..."
|
||
|
|
cargo fmt -- --check 2>&1 && echo "✅ Code is properly formatted" || echo "⚠️ Code needs formatting"
|
||
|
|
|
||
|
|
echo "=================================="
|
||
|
|
echo "✅ Verification complete!"
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="development-setup"><a class="header" href="#development-setup">Development Setup</a></h2>
|
||
|
|
<h3 id="ide-setup"><a class="header" href="#ide-setup">IDE Setup</a></h3>
|
||
|
|
<p><strong>VS Code (Recommended)</strong></p>
|
||
|
|
<pre><code class="language-bash"># Install recommended extensions
|
||
|
|
# 1. rust-analyzer (rust-lang.rust-analyzer)
|
||
|
|
# 2. CodeLLDB (vadimcn.vscode-lldb)
|
||
|
|
# 3. Even Better TOML (tamasfe.even-better-toml)
|
||
|
|
# 4. Leptos (Leptos)
|
||
|
|
|
||
|
|
# .vscode/settings.json
|
||
|
|
{
|
||
|
|
"[rust]": {
|
||
|
|
"editor.formatOnSave": true,
|
||
|
|
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
||
|
|
},
|
||
|
|
"rust-analyzer.inlayHints.enable": true,
|
||
|
|
"rust-analyzer.lens.enable": true
|
||
|
|
}
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>IntelliJ IDEA / CLion</strong></p>
|
||
|
|
<pre><code class="language-bash"># Install Rust plugin
|
||
|
|
# Settings → Plugins → Rust → Install
|
||
|
|
|
||
|
|
# Recommended settings:
|
||
|
|
# Rust → Clippy → Use Clippy instead of Cargo check
|
||
|
|
# Rust → Macro Expansion → Expand experimental attribute macros
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="git-setup"><a class="header" href="#git-setup">Git Setup</a></h3>
|
||
|
|
<pre><code class="language-bash"># Clone pre-commit hooks (if available)
|
||
|
|
git clone https://github.com/vapora/hooks .git/hooks
|
||
|
|
|
||
|
|
# Or create basic hook:
|
||
|
|
cat > .git/hooks/pre-commit << 'EOF'
|
||
|
|
#!/bin/bash
|
||
|
|
cargo fmt --check && cargo clippy --all -- -W clippy::all
|
||
|
|
EOF
|
||
|
|
|
||
|
|
chmod +x .git/hooks/pre-commit
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="development-workflow"><a class="header" href="#development-workflow">Development Workflow</a></h3>
|
||
|
|
<pre><code class="language-bash"># 1. Create feature branch
|
||
|
|
git checkout -b feat/my-feature
|
||
|
|
|
||
|
|
# 2. Make changes and build
|
||
|
|
cargo build
|
||
|
|
|
||
|
|
# 3. Run tests
|
||
|
|
cargo test --lib
|
||
|
|
|
||
|
|
# 4. Check code quality
|
||
|
|
cargo fmt
|
||
|
|
cargo clippy --all -- -W clippy::all
|
||
|
|
|
||
|
|
# 5. Commit and push
|
||
|
|
git add .
|
||
|
|
git commit -m "feat: implement my-feature"
|
||
|
|
git push origin feat/my-feature
|
||
|
|
|
||
|
|
# 6. Create pull request
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="first-run"><a class="header" href="#first-run">First Run</a></h2>
|
||
|
|
<h3 id="run-backend-server"><a class="header" href="#run-backend-server">Run Backend Server</a></h3>
|
||
|
|
<p><strong>Terminal 1: Backend</strong></p>
|
||
|
|
<pre><code class="language-bash"># Run backend
|
||
|
|
cargo run -p vapora-backend
|
||
|
|
|
||
|
|
# With debug logging
|
||
|
|
RUST_LOG=debug cargo run -p vapora-backend
|
||
|
|
|
||
|
|
# Expected output:
|
||
|
|
# 🚀 Vapora Backend Server
|
||
|
|
# Listening on http://127.0.0.1:3000
|
||
|
|
# Available endpoints:
|
||
|
|
# GET /api/v1/health
|
||
|
|
# GET /api/v1/tracking/summary
|
||
|
|
# POST /api/v1/agents/orchestrate
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="run-frontend-optional"><a class="header" href="#run-frontend-optional">Run Frontend (Optional)</a></h3>
|
||
|
|
<p><strong>Terminal 2: Frontend</strong></p>
|
||
|
|
<pre><code class="language-bash">cd crates/vapora-frontend
|
||
|
|
|
||
|
|
# Install trunk (if not already)
|
||
|
|
cargo install trunk
|
||
|
|
|
||
|
|
# Run frontend with hot-reload
|
||
|
|
trunk serve
|
||
|
|
|
||
|
|
# Expected output:
|
||
|
|
# 🦕 Listening on http://127.0.0.1:8080
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="test-endpoints"><a class="header" href="#test-endpoints">Test Endpoints</a></h3>
|
||
|
|
<p><strong>Terminal 3: Test</strong></p>
|
||
|
|
<pre><code class="language-bash"># Health check
|
||
|
|
curl http://localhost:3000/api/v1/health
|
||
|
|
# Response: {"status":"ok","service":"vapora-backend",...}
|
||
|
|
|
||
|
|
# Tracking summary
|
||
|
|
curl http://localhost:3000/api/v1/tracking/summary
|
||
|
|
# Response: {"total_entries":0,"changes":0,"todos":0}
|
||
|
|
|
||
|
|
# Create tracking entry
|
||
|
|
curl -X POST http://localhost:3000/api/v1/tracking/entries \
|
||
|
|
-H "Content-Type: application/json" \
|
||
|
|
-d '{"summary":"First entry","impact":"backend"}'
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="using-cli-commands"><a class="header" href="#using-cli-commands">Using CLI Commands</a></h3>
|
||
|
|
<pre><code class="language-bash"># Start tracking service (if using local service)
|
||
|
|
./scripts/start-tracking-service.nu --verbose
|
||
|
|
|
||
|
|
# Log a change
|
||
|
|
/log-change "Completed setup" --impact infrastructure --files 1
|
||
|
|
|
||
|
|
# Create a TODO
|
||
|
|
/add-todo "Review tracking system" --priority H --estimate M
|
||
|
|
|
||
|
|
# Check status
|
||
|
|
/track-status --limit 10
|
||
|
|
|
||
|
|
# Export data
|
||
|
|
./scripts/export-tracking.nu json --output setup-report.json
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="troubleshooting"><a class="header" href="#troubleshooting">Troubleshooting</a></h2>
|
||
|
|
<h3 id="build-issues"><a class="header" href="#build-issues">Build Issues</a></h3>
|
||
|
|
<p><strong>Error: "error[E0433]: failed to resolve: use of undeclared type"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Update Rust
|
||
|
|
rustup update stable
|
||
|
|
|
||
|
|
# Clean cache
|
||
|
|
cargo clean
|
||
|
|
|
||
|
|
# Rebuild
|
||
|
|
cargo build
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Error: "could not compile ... due to X previous errors"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Check Rust version (must be 1.75+)
|
||
|
|
rustc --version
|
||
|
|
|
||
|
|
# Update if needed
|
||
|
|
rustup install 1.75
|
||
|
|
rustup default 1.75
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Error: "linker 'cc' not found"</strong></p>
|
||
|
|
<p>Solution (macOS):</p>
|
||
|
|
<pre><code class="language-bash"># Install Xcode command line tools
|
||
|
|
xcode-select --install
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="test-issues"><a class="header" href="#test-issues">Test Issues</a></h3>
|
||
|
|
<p><strong>Tests fail with timeout</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Run with single thread
|
||
|
|
cargo test --lib -- --test-threads=1
|
||
|
|
|
||
|
|
# Increase timeout
|
||
|
|
RUST_TEST_TIME_UNIT=60000 cargo test --lib
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Tests panic with "thread 'main' panicked"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Run with backtrace
|
||
|
|
RUST_BACKTRACE=1 cargo test --lib -- --nocapture
|
||
|
|
|
||
|
|
# Check logs for actual error
|
||
|
|
RUST_LOG=trace cargo test --lib -- --nocapture
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="database-issues"><a class="header" href="#database-issues">Database Issues</a></h3>
|
||
|
|
<p><strong>Error: "database file not found"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Create database directory
|
||
|
|
mkdir -p ~/.tracking
|
||
|
|
mkdir -p ~/.vapora
|
||
|
|
|
||
|
|
# Initialize databases
|
||
|
|
./scripts/start-tracking-service.nu
|
||
|
|
|
||
|
|
# Wait for init and stop with Ctrl+C
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Error: "Failed to acquire database lock"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Ensure only one instance is running
|
||
|
|
lsof | grep database.sqlite
|
||
|
|
|
||
|
|
# Kill any lingering processes
|
||
|
|
pkill -f "vapora-backend"
|
||
|
|
pkill -f "tracking-service"
|
||
|
|
|
||
|
|
# Restart
|
||
|
|
cargo run -p vapora-backend
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="port-already-in-use"><a class="header" href="#port-already-in-use">Port Already in Use</a></h3>
|
||
|
|
<p><strong>Error: "Address already in use"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Find process using port 3000
|
||
|
|
lsof -i :3000
|
||
|
|
|
||
|
|
# Kill process
|
||
|
|
kill -9 <PID>
|
||
|
|
|
||
|
|
# Or use different port
|
||
|
|
VAPORA_PORT=3001 cargo run -p vapora-backend
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="nushell-script-issues"><a class="header" href="#nushell-script-issues">NuShell Script Issues</a></h3>
|
||
|
|
<p><strong>Error: "command not found: nu"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Install NuShell
|
||
|
|
brew install nu
|
||
|
|
|
||
|
|
# Or add to PATH
|
||
|
|
export PATH="/usr/local/bin:$PATH"
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Scripts not executable</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Make scripts executable
|
||
|
|
chmod +x scripts/*.nu
|
||
|
|
|
||
|
|
# Run with nu explicitly
|
||
|
|
nu scripts/start-tracking-service.nu
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="frontend-issues"><a class="header" href="#frontend-issues">Frontend Issues</a></h3>
|
||
|
|
<p><strong>Error: "trunk: command not found"</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Install trunk
|
||
|
|
cargo install trunk
|
||
|
|
|
||
|
|
# Install WASM target
|
||
|
|
rustup target add wasm32-unknown-unknown
|
||
|
|
</code></pre>
|
||
|
|
<p><strong>Frontend won't load styles</strong></p>
|
||
|
|
<p>Solution:</p>
|
||
|
|
<pre><code class="language-bash"># Clear build cache
|
||
|
|
rm -rf crates/vapora-frontend/target
|
||
|
|
rm -rf crates/vapora-frontend/dist
|
||
|
|
|
||
|
|
# Rebuild
|
||
|
|
cd crates/vapora-frontend && trunk serve
|
||
|
|
</code></pre>
|
||
|
|
<h3 id="quick-troubleshooting-reference"><a class="header" href="#quick-troubleshooting-reference">Quick Troubleshooting Reference</a></h3>
|
||
|
|
<div class="table-wrapper"><table><thead><tr><th>Problem</th><th>Quick Fix</th></tr></thead><tbody>
|
||
|
|
<tr><td>Build fails</td><td><code>cargo clean && cargo build</code></td></tr>
|
||
|
|
<tr><td>Tests fail</td><td><code>rustup update && cargo test --lib</code></td></tr>
|
||
|
|
<tr><td>Port in use</td><td><code>lsof -i :3000 && kill -9 <PID></code></td></tr>
|
||
|
|
<tr><td>DB errors</td><td><code>rm ~/.vapora/data.db && cargo run</code></td></tr>
|
||
|
|
<tr><td>NuShell missing</td><td><code>brew install nu</code></td></tr>
|
||
|
|
<tr><td>Clippy warnings</td><td><code>cargo clippy -- -W clippy::all</code></td></tr>
|
||
|
|
<tr><td>Format issues</td><td><code>cargo fmt</code></td></tr>
|
||
|
|
<tr><td>Slow build</td><td><code>export CARGO_INCREMENTAL=1</code></td></tr>
|
||
|
|
</tbody></table>
|
||
|
|
</div>
|
||
|
|
<hr />
|
||
|
|
<h2 id="verification-steps"><a class="header" href="#verification-steps">Verification Steps</a></h2>
|
||
|
|
<h3 id="post-installation-verification"><a class="header" href="#post-installation-verification">Post-Installation Verification</a></h3>
|
||
|
|
<pre><code class="language-bash">#!/bin/bash
|
||
|
|
|
||
|
|
echo "🔍 Post-installation verification..."
|
||
|
|
echo "===================================="
|
||
|
|
|
||
|
|
# 1. Check Rust
|
||
|
|
echo "1. Checking Rust..."
|
||
|
|
rustc --version | grep -q "1\.[0-9]\+\.[0-9]\+" && echo "✅ Rust OK" || echo "❌ Rust issue"
|
||
|
|
|
||
|
|
# 2. Check build
|
||
|
|
echo "2. Building..."
|
||
|
|
cargo build 2>&1 | grep -q "Finished" && echo "✅ Build OK" || echo "❌ Build failed"
|
||
|
|
|
||
|
|
# 3. Check tests
|
||
|
|
echo "3. Testing..."
|
||
|
|
cargo test --lib 2>&1 | grep -q "test result: ok" && echo "✅ Tests OK" || echo "❌ Tests failed"
|
||
|
|
|
||
|
|
# 4. Check code quality
|
||
|
|
echo "4. Code quality..."
|
||
|
|
cargo clippy --all 2>&1 | grep -v "warning:" | tail -1 | grep -q "error" && echo "❌ Clippy issues" || echo "✅ Code quality OK"
|
||
|
|
|
||
|
|
# 5. Check structure
|
||
|
|
echo "5. Project structure..."
|
||
|
|
[ -f "Cargo.toml" ] && [ -d "crates" ] && echo "✅ Structure OK" || echo "❌ Structure issue"
|
||
|
|
|
||
|
|
echo "===================================="
|
||
|
|
echo "✅ Verification complete!"
|
||
|
|
</code></pre>
|
||
|
|
<hr />
|
||
|
|
<h2 id="whats-next"><a class="header" href="#whats-next">What's Next?</a></h2>
|
||
|
|
<h3 id="immediate-next-steps"><a class="header" href="#immediate-next-steps">Immediate Next Steps</a></h3>
|
||
|
|
<ol>
|
||
|
|
<li>Read <a href="./QUICKSTART.html"><code>QUICKSTART.md</code></a> for 15-minute quick start</li>
|
||
|
|
<li>Run backend: <code>cargo run -p vapora-backend</code></li>
|
||
|
|
<li>Visit frontend: <code>http://localhost:8080</code></li>
|
||
|
|
<li>Create first tracking entry: <code>/log-change "Setup complete"</code></li>
|
||
|
|
</ol>
|
||
|
|
<h3 id="learning-resources"><a class="header" href="#learning-resources">Learning Resources</a></h3>
|
||
|
|
<ul>
|
||
|
|
<li>API Documentation: <code>cargo doc --open</code></li>
|
||
|
|
<li>Crate READMEs: <code>crates/*/README.md</code></li>
|
||
|
|
<li>Tracking System: <a href="./QUICKSTART_TRACKING.html"><code>QUICKSTART_TRACKING.md</code></a></li>
|
||
|
|
<li>Architecture: <a href="./.coder/"><code>.coder/</code></a></li>
|
||
|
|
</ul>
|
||
|
|
<h3 id="development-tips"><a class="header" href="#development-tips">Development Tips</a></h3>
|
||
|
|
<ul>
|
||
|
|
<li>Use <code>cargo watch</code> for continuous building</li>
|
||
|
|
<li>Set <code>RUST_LOG=debug</code> for detailed logs</li>
|
||
|
|
<li>Use IDE debugging (VS Code + CodeLLDB)</li>
|
||
|
|
<li>Join community for help</li>
|
||
|
|
</ul>
|
||
|
|
<hr />
|
||
|
|
<h2 id="getting-help"><a class="header" href="#getting-help">Getting Help</a></h2>
|
||
|
|
<p><strong>Issues not listed above?</strong></p>
|
||
|
|
<ol>
|
||
|
|
<li>Check crate-specific documentation: <code>cargo doc --open</code></li>
|
||
|
|
<li>Review <code>.coder/</code> documentation for architecture</li>
|
||
|
|
<li>Check inline code comments</li>
|
||
|
|
<li>Run with <code>RUST_LOG=trace</code> for detailed logs</li>
|
||
|
|
<li>See <a href="./QUICKSTART.html"><code>QUICKSTART.md</code></a> for quick reference</li>
|
||
|
|
</ol>
|
||
|
|
<hr />
|
||
|
|
<h2 id="-setup-completion-checklist"><a class="header" href="#-setup-completion-checklist">✅ Setup Completion Checklist</a></h2>
|
||
|
|
<ul>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Rust 1.75+ installed</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
All prerequisites verified</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Repository cloned</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Dependencies downloaded (<code>cargo fetch</code>)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Workspace builds successfully (<code>cargo build</code>)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
All tests pass (<code>cargo test --lib</code>)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Code quality checks pass (<code>cargo clippy</code>)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Backend runs (<code>cargo run -p vapora-backend</code>)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Frontend loads (optional)</li>
|
||
|
|
<li><input disabled="" type="checkbox"/>
|
||
|
|
Tracking system works (<code>/track-status</code>)</li>
|
||
|
|
</ul>
|
||
|
|
<p><strong>All checked? ✅ Vapora is ready for development!</strong></p>
|
||
|
|
<hr />
|
||
|
|
<p><strong>For quick 15-minute setup:</strong> See <a href="./QUICKSTART.html"><code>QUICKSTART.md</code></a></p>
|
||
|
|
<p><strong>For tracking system setup:</strong> See <a href="./SETUP_TRACKING.html"><code>SETUP_TRACKING.md</code></a></p>
|
||
|
|
|
||
|
|
</main>
|
||
|
|
|
||
|
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||
|
|
<!-- Mobile navigation buttons -->
|
||
|
|
<a rel="prev" href="../../setup/index.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
|
|
<i class="fa fa-angle-left"></i>
|
||
|
|
</a>
|
||
|
|
|
||
|
|
<a rel="next prefetch" href="../../setup/deployment.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
|
|
<i class="fa fa-angle-right"></i>
|
||
|
|
</a>
|
||
|
|
|
||
|
|
<div style="clear: both"></div>
|
||
|
|
</nav>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||
|
|
<a rel="prev" href="../../setup/index.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||
|
|
<i class="fa fa-angle-left"></i>
|
||
|
|
</a>
|
||
|
|
|
||
|
|
<a rel="next prefetch" href="../../setup/deployment.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||
|
|
<i class="fa fa-angle-right"></i>
|
||
|
|
</a>
|
||
|
|
</nav>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
<script>
|
||
|
|
window.playground_copyable = true;
|
||
|
|
</script>
|
||
|
|
|
||
|
|
|
||
|
|
<script src="../elasticlunr.min.js"></script>
|
||
|
|
<script src="../mark.min.js"></script>
|
||
|
|
<script src="../searcher.js"></script>
|
||
|
|
|
||
|
|
<script src="../clipboard.min.js"></script>
|
||
|
|
<script src="../highlight.js"></script>
|
||
|
|
<script src="../book.js"></script>
|
||
|
|
|
||
|
|
<!-- Custom JS scripts -->
|
||
|
|
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</body>
|
||
|
|
</html>
|