# Familiar - Self-Hosted AI Companion Platform
# Copyright (c) 2026 George Scott Foley
# ORCID: 0009-0006-4957-0540
# Email: Georgescottfoley@proton.me
# Licensed under the MIT License - see LICENSE file for details

"""Familiar Installation & User Guide — PDF and HTML generation.

Provides:
    get_guide_html()          — returns the full guide as an HTML string
    generate_guide_pdf(path)  — renders to PDF via WeasyPrint (optional dep)

The generated PDF is cached at ``~/.familiar/data/familiar_guide.pdf``
and regenerated only when the package version changes.
"""

from __future__ import annotations

import logging
from pathlib import Path

logger = logging.getLogger(__name__)

# ── STYLES (shared across entire document) ──────────────────────────
STYLES = """
  @page {
    size: A4;
    margin: 2.0cm 1.8cm 2.3cm 1.8cm;
    @bottom-center {
      content: "Page " counter(page) " of " counter(pages);
      font-size: 8px; color: #888; font-family: 'Segoe UI', Arial, sans-serif;
    }
  }
  body { font-family: 'Segoe UI', 'Helvetica Neue', Arial, sans-serif; font-size: 10.5pt; line-height: 1.55; color: #1a1a2e; }
  h1 { font-size: 24pt; color: #0f3460; margin-top: 0; border-bottom: 3px solid #e94560; padding-bottom: 8px; }
  h2 { font-size: 16pt; color: #0f3460; margin-top: 26px; border-bottom: 1.5px solid #ddd; padding-bottom: 4px; page-break-after: avoid; }
  h3 { font-size: 12.5pt; color: #16213e; margin-top: 16px; page-break-after: avoid; }
  h4 { font-size: 11pt; color: #333; margin-top: 12px; page-break-after: avoid; }
  code { background: #f0f0f5; padding: 1px 4px; border-radius: 3px; font-size: 9.5pt; font-family: 'Consolas', monospace; }
  pre { background: #1a1a2e; color: #e0e0e0; padding: 12px 14px; border-radius: 6px; font-size: 9pt; line-height: 1.45; overflow-wrap: break-word; white-space: pre-wrap; page-break-inside: avoid; }
  pre code { background: none; padding: 0; color: inherit; }
  table { border-collapse: collapse; width: 100%; margin: 8px 0 14px 0; font-size: 9.5pt; page-break-inside: avoid; }
  th { background: #0f3460; color: #fff; padding: 6px 8px; text-align: left; }
  td { padding: 5px 8px; border-bottom: 1px solid #ddd; vertical-align: top; }
  tr:nth-child(even) td { background: #f8f8fc; }
  .cover { text-align: center; padding-top: 140px; page-break-after: always; }
  .cover h1 { font-size: 34pt; border: none; margin-bottom: 6px; }
  .cover .subtitle { font-size: 14pt; color: #555; margin-bottom: 30px; }
  .cover .version { font-size: 11pt; color: #888; }
  .cover .author { font-size: 10pt; color: #666; margin-top: 50px; }
  .toc { page-break-after: always; }
  .toc a { color: #0f3460; text-decoration: none; }
  .toc li { margin-bottom: 4px; }
  .tip { background: #eef6ff; border-left: 4px solid #4A90D9; padding: 10px 14px; margin: 10px 0; border-radius: 0 4px 4px 0; page-break-inside: avoid; }
  .warn { background: #fff8e6; border-left: 4px solid #ffb347; padding: 10px 14px; margin: 10px 0; border-radius: 0 4px 4px 0; page-break-inside: avoid; }
  .danger { background: #ffe6e6; border-left: 4px solid #e94560; padding: 10px 14px; margin: 10px 0; border-radius: 0 4px 4px 0; page-break-inside: avoid; }
  .step { background: #f4f4ff; border: 1px solid #ddd; border-radius: 6px; padding: 12px 16px; margin: 10px 0; page-break-inside: avoid; }
  .step-num { display: inline-block; background: #0f3460; color: #fff; width: 24px; height: 24px; border-radius: 50%; text-align: center; line-height: 24px; font-size: 12px; font-weight: bold; margin-right: 8px; }
  .section { page-break-before: always; }
  .section:first-of-type { page-break-before: auto; }
  ul, ol { padding-left: 22px; }
  li { margin-bottom: 3px; }
  /* Appendix uses slightly smaller text to fit dense reference tables */
  .appendix table { font-size: 8.5pt; }
  .appendix td code { font-size: 8pt; }
  .appendix h3 { font-size: 11pt; }
  .appendix h4 { font-size: 9.5pt; }
"""

# ── MAIN GUIDE (sections 1-17) ──────────────────────────────────────
MAIN_GUIDE = r"""
<!-- ==================== COVER ==================== -->
<div class="cover">
  <h1>Familiar</h1>
  <div class="subtitle">Self-Hosted AI Companion Platform</div>
  <div class="subtitle" style="font-size:13pt;">Installation &amp; User Guide</div>
  <div class="version">Version 1.14.40a4 &mdash; March 2026</div>
  <div class="author">
    George Scott Foley<br>
    ORCID: 0009-0006-4957-0540<br>
    <code>Georgescottfoley@proton.me</code><br><br>
    <span style="font-size:10pt;color:#999;">MIT License &bull; <code>pip install familiar-agent</code></span>
  </div>
</div>

<!-- ==================== TOC ==================== -->
<div class="toc">
<h2>Table of Contents</h2>
<p style="color:#555; font-size:10pt; margin-bottom:16px;">This guide is written for first-time users who have never set up an AI agent before. Every section walks you through each step. If you get stuck, jump to Section 16 (Troubleshooting).</p>
<ol style="font-size:10.5pt;">
  <li><a href="#s1">What Is Familiar?</a></li>
  <li><a href="#s2">Before You Start &mdash; What You Need</a></li>
  <li><a href="#s3">Getting an API Key (Step by Step)</a></li>
  <li><a href="#s4">Installing Familiar</a></li>
  <li><a href="#s5">First-Time Setup &mdash; The Onboarding Wizard</a></li>
  <li><a href="#s6">Running Familiar for the First Time</a></li>
  <li><a href="#s7">The Web Dashboard &mdash; Your Control Panel</a></li>
  <li><a href="#s8">Meet Your Creature &mdash; Choosing &amp; Customizing</a></li>
  <li><a href="#s9">Talking to Your Familiar &mdash; Chat Commands</a></li>
  <li><a href="#s10">Connecting Channels (Telegram, Discord, etc.)</a></li>
  <li><a href="#s11">Choosing Your AI Brain &mdash; LLM Providers</a></li>
  <li><a href="#s12">Skills &mdash; What Your Familiar Can Do</a></li>
  <li><a href="#s13">Multi-Device Mesh Networking</a></li>
  <li><a href="#s14">Security &amp; Compliance</a></li>
  <li><a href="#s15">Familiar on Android &amp; Reflection Platform</a></li>
  <li><a href="#s16">Troubleshooting &amp; FAQ</a></li>
  <li><a href="#s17">Uninstalling, Reinstalling &amp; Clean Reset</a></li>
  <li><a href="#s18">Quick Reference Card</a></li>
  <li style="margin-top:12px; font-weight:bold; color:#0f3460;"><a href="#appendix">Appendix: Advanced Command &amp; Configuration Index</a></li>
</ol>
</div>

<!-- ==================== 1. WHAT IS FAMILIAR ==================== -->
<div class="section" id="s1">
<h2>1. What Is Familiar?</h2>
<p><strong>Familiar</strong> is your own private AI assistant that lives on <em>your</em> computer, not in someone else's cloud. Think of it like having a smart personal assistant that:</p>
<ul>
  <li>Runs on your hardware &mdash; a laptop, desktop, Raspberry Pi, or even your phone</li>
  <li>Connects to the AI "brain" of your choice &mdash; Claude, GPT-4o, Gemini, or completely offline local models</li>
  <li>Comes with a cute evolving pixel creature that grows as you use it</li>
  <li>Has 50+ built-in skills &mdash; email, calendar, web browsing, voice, documents, and much more</li>
  <li>Can talk to you through a web dashboard, Telegram, Discord, and 10+ other platforms</li>
</ul>

<div class="tip">
  <strong>New to AI agents?</strong> An "agent" is an AI that can do things for you &mdash; not just chat, but actually send emails, manage calendars, browse the web, and handle tasks. Familiar is your personal agent that you control completely.
</div>

<h3>How It Works (The Big Picture)</h3>
<ol>
  <li>You <strong>install</strong> Familiar on your computer (takes about 5 minutes)</li>
  <li>You <strong>connect</strong> it to an AI provider (like getting a brain for your assistant)</li>
  <li>You <strong>talk</strong> to it through a web browser, chat app, or terminal</li>
  <li>It <strong>learns</strong> your preferences and gets better over time</li>
  <li>Your <strong>creature</strong> evolves from a baby to an adult as you interact</li>
</ol>
</div>

<!-- ==================== 2. BEFORE YOU START ==================== -->
<div class="section" id="s2">
<h2>2. Before You Start &mdash; What You Need</h2>

<h3>2.1 Your Computer</h3>
<table>
  <tr><th>What</th><th>Minimum</th><th>Recommended</th><th>Why</th></tr>
  <tr><td>Python</td><td>3.10</td><td>3.11 or 3.12</td><td>Familiar is written in Python</td></tr>
  <tr><td>RAM</td><td>512 MB</td><td>4 GB+</td><td>More RAM needed for local AI models</td></tr>
  <tr><td>Disk space</td><td>100 MB</td><td>2 GB+</td><td>Local models need extra space</td></tr>
  <tr><td>Operating system</td><td colspan="2">Linux, macOS, or Windows</td><td>Works on all three</td></tr>
</table>

<h3>2.2 Do I Have Python?</h3>
<p>Open a terminal (Command Prompt on Windows, Terminal on Mac/Linux) and type:</p>
<pre><code>python3 --version</code></pre>
<p>You should see something like <code>Python 3.11.5</code>. If you get an error:</p>
<ul>
  <li><strong>Mac:</strong> Install from python.org or run <code>brew install python</code></li>
  <li><strong>Linux (Ubuntu/Debian):</strong> <code>sudo apt install python3 python3-pip python3-venv</code></li>
  <li><strong>Windows:</strong> Download from python.org &mdash; check "Add Python to PATH" during install</li>
</ul>

<div class="warn">
  <strong>Windows users:</strong> Use <code>python</code> instead of <code>python3</code> in all commands below. Also, use <code>set</code> instead of <code>export</code> for environment variables: <code>set ANTHROPIC_API_KEY=sk-ant-...</code>
</div>

<h3>2.3 Choosing Your AI Provider</h3>
<p>Familiar needs an AI "brain." You have four options &mdash; pick whichever feels right:</p>
<table>
  <tr><th>Option</th><th>Cost</th><th>Quality</th><th>Privacy</th><th>Best For</th></tr>
  <tr><td><strong>Claude</strong> (Anthropic)</td><td>Pay per use (~$3/M tokens)</td><td>Excellent</td><td>Data sent to cloud</td><td>Best overall quality</td></tr>
  <tr><td><strong>GPT-4o</strong> (OpenAI)</td><td>Pay per use (~$2.50/M tokens)</td><td>Excellent</td><td>Data sent to cloud</td><td>Widely used, well-known</td></tr>
  <tr><td><strong>Gemini</strong> (Google)</td><td>Free tier available</td><td>Very good</td><td>Data sent to cloud</td><td>Budget-friendly start</td></tr>
  <tr><td><strong>Ollama</strong> (Local)</td><td>Free forever</td><td>Good to great</td><td>100% private</td><td>Maximum privacy, offline use</td></tr>
</table>

<div class="tip">
  <strong>Not sure?</strong> Start with <strong>Claude</strong> or <strong>Gemini</strong> (free tier). You can switch providers any time &mdash; even mid-conversation &mdash; using the <code>/model</code> command.
</div>
</div>

<!-- ==================== 3. GETTING AN API KEY ==================== -->
<div class="section" id="s3">
<h2>3. Getting an API Key (Step by Step)</h2>

<p>If you chose a cloud provider, you need an API key. This is like a password that lets Familiar talk to the AI. Skip this section if you're using Ollama (local models).</p>

<h3>3.1 Anthropic (Claude)</h3>
<div class="step">
  <span class="step-num">1</span> Go to <strong>console.anthropic.com</strong> in your web browser<br>
  <span class="step-num">2</span> Click "Sign Up" and create an account (email + password)<br>
  <span class="step-num">3</span> Once logged in, click <strong>"API Keys"</strong> in the left sidebar<br>
  <span class="step-num">4</span> Click <strong>"Create Key"</strong>, give it a name like "familiar"<br>
  <span class="step-num">5</span> Copy the key &mdash; it starts with <code>sk-ant-</code>. <strong>Save it somewhere safe!</strong> You won't see it again.<br>
  <span class="step-num">6</span> Add a payment method (Settings &rarr; Billing). Claude charges per use, typically $1-5/month for moderate use.
</div>

<h3>3.2 OpenAI (GPT-4o)</h3>
<div class="step">
  <span class="step-num">1</span> Go to <strong>platform.openai.com</strong><br>
  <span class="step-num">2</span> Sign up or log in<br>
  <span class="step-num">3</span> Navigate to <strong>API Keys</strong> (left sidebar or Settings)<br>
  <span class="step-num">4</span> Click <strong>"Create new secret key"</strong><br>
  <span class="step-num">5</span> Copy the key &mdash; starts with <code>sk-</code>. Save it!<br>
  <span class="step-num">6</span> Add billing (Settings &rarr; Billing). Prepay $5-10 to start.
</div>

<h3>3.3 Google Gemini</h3>
<div class="step">
  <span class="step-num">1</span> Go to <strong>aistudio.google.com</strong><br>
  <span class="step-num">2</span> Sign in with your Google account<br>
  <span class="step-num">3</span> Click <strong>"Get API key"</strong> in the top navigation<br>
  <span class="step-num">4</span> Click <strong>"Create API key"</strong><br>
  <span class="step-num">5</span> Copy the key. The free tier is generous enough for personal use.
</div>

<h3>3.4 Ollama (Local &mdash; No Key Needed)</h3>
<div class="step">
  <span class="step-num">1</span> Go to <strong>ollama.com</strong> and download for your OS<br>
  <span class="step-num">2</span> Install it (double-click on Mac/Windows, or follow Linux instructions)<br>
  <span class="step-num">3</span> Open a terminal and run: <code>ollama pull llama3.2</code> (downloads ~2 GB)<br>
  <span class="step-num">4</span> Start the server: <code>ollama serve</code><br>
  <span class="step-num">5</span> That's it! No API key, no payments, everything stays on your machine.
</div>

<div class="tip">
  <strong>Keep your API key secret!</strong> Never share it, post it online, or commit it to Git. Treat it like a password. If you think it's been exposed, revoke it immediately on the provider's website and create a new one.
</div>
</div>

<!-- ==================== 4. INSTALLING FAMILIAR ==================== -->
<div class="section" id="s4">
<h2>4. Installing Familiar</h2>

<h3>4.1 The Easy Way (Recommended for Beginners)</h3>
<p>Open your terminal and run these commands one at a time:</p>

<div class="step">
  <span class="step-num">1</span> <strong>Create a virtual environment</strong> (keeps Familiar separate from your system Python):<br>
  <pre><code>python3 -m venv ~/familiar-env</code></pre>
</div>

<div class="step">
  <span class="step-num">2</span> <strong>Activate the virtual environment:</strong><br>
  <pre><code># Mac/Linux:
source ~/familiar-env/bin/activate

# Windows:
familiar-env\Scripts\activate</code></pre>
  <p style="font-size:9pt; color:#666;">You should see <code>(familiar-env)</code> appear at the start of your terminal prompt. This means you're inside the virtual environment.</p>
</div>

<div class="step">
  <span class="step-num">3</span> <strong>Install Familiar</strong> with cloud LLM support:<br>
  <pre><code>pip install familiar-agent[llm,web]</code></pre>
  <p style="font-size:9pt; color:#666;">This installs the core agent plus Claude/GPT support and the web dashboard. It may take 1-2 minutes.</p>
</div>

<div class="step">
  <span class="step-num">4</span> <strong>Set your API key:</strong><br>
  <pre><code># Mac/Linux:
export ANTHROPIC_API_KEY="sk-ant-your-key-here"

# Windows:
set ANTHROPIC_API_KEY=sk-ant-your-key-here</code></pre>
  <p style="font-size:9pt; color:#666;">Replace with your actual key from Section 3. Use <code>OPENAI_API_KEY</code> or <code>GEMINI_API_KEY</code> if using a different provider.</p>
</div>

<div class="step">
  <span class="step-num">5</span> <strong>Verify the installation:</strong><br>
  <pre><code>python -m familiar --help</code></pre>
  <p style="font-size:9pt; color:#666;">You should see a list of available options. If you get an error, see Section 16 (Troubleshooting).</p>
</div>

<div class="tip">
  <strong>Why a virtual environment?</strong> It creates an isolated space so Familiar's packages don't conflict with anything else on your system. Always activate it (<code>source ~/familiar-env/bin/activate</code>) before using Familiar.
</div>

<h3>4.2 Full Install (All Features)</h3>
<p>If you want everything &mdash; voice, encryption, all channels, document processing:</p>
<pre><code>pip install familiar-agent[full]</code></pre>

<h3>4.3 Minimal Install (Ollama Only, No Cloud)</h3>
<pre><code>pip install familiar-agent[web]</code></pre>
<p>This installs just the core agent + web dashboard. Pair with Ollama for a fully offline setup.</p>

<h3>4.4 Install from Source (Developers)</h3>
<pre><code>git clone https://github.com/omegcrash/familiar.git
cd familiar
pip install -e ".[dev]"</code></pre>

<h3>4.5 Raspberry Pi</h3>
<pre><code># Full automated install with Ollama
./familiar/scripts/install-pi.sh --with-ollama

# Nonprofit preset (calendar, email, bookkeeping)
./familiar/scripts/install-pi.sh --nonprofit</code></pre>

<h3>4.6 Install Extras Reference</h3>
<p>You can install just the features you need. Combine extras with commas:</p>
<pre><code>pip install familiar-agent[llm,discord,telegram,web]</code></pre>
<table>
  <tr><th>Extra</th><th>What It Adds</th><th>When You Need It</th></tr>
  <tr><td><code>llm</code></td><td>Anthropic + OpenAI SDKs</td><td>Using Claude or GPT (most users)</td></tr>
  <tr><td><code>web</code></td><td>Flask dashboard, browser, search</td><td>Web dashboard (most users)</td></tr>
  <tr><td><code>discord</code></td><td>discord.py</td><td>Discord bot channel</td></tr>
  <tr><td><code>telegram</code></td><td>python-telegram-bot</td><td>Telegram bot channel</td></tr>
  <tr><td><code>matrix</code></td><td>matrix-nio (E2EE)</td><td>Matrix channel</td></tr>
  <tr><td><code>slack</code></td><td>slack-sdk</td><td>Slack channel</td></tr>
  <tr><td><code>voice</code></td><td>Whisper, edge-tts, gTTS</td><td>Voice commands &amp; TTS</td></tr>
  <tr><td><code>encryption</code></td><td>cryptography, pynacl</td><td>Encrypting stored data</td></tr>
  <tr><td><code>mesh</code></td><td>Encrypted P2P networking</td><td>Connecting multiple devices</td></tr>
  <tr><td><code>healthcare</code></td><td>Presidio PII/PHI detection</td><td>HIPAA compliance</td></tr>
  <tr><td><code>docs</code></td><td>Word, Excel, PDF processing</td><td>Document handling</td></tr>
  <tr><td><code>google</code></td><td>Google Workspace API</td><td>Google Drive, Calendar, Gmail</td></tr>
  <tr><td><code>redis</code></td><td>Redis backend</td><td>Distributed / multi-instance</td></tr>
  <tr><td><code>email</code></td><td>aiosmtpd</td><td>Self-hosted email server</td></tr>
  <tr><td><code>nextcloud</code></td><td>CalDAV/CardDAV</td><td>Nextcloud integration</td></tr>
  <tr><td><code>tui</code></td><td>Textual rich terminal UI</td><td>Fancy terminal onboarding</td></tr>
  <tr><td><code>full</code></td><td>All of the above</td><td>You want everything</td></tr>
  <tr><td><code>dev</code></td><td>pytest, ruff, mypy</td><td>Contributing to Familiar</td></tr>
</table>
</div>

<!-- ==================== 5. FIRST-TIME SETUP ==================== -->
<div class="section" id="s5">
<h2>5. First-Time Setup &mdash; The Onboarding Wizard</h2>

<p>Familiar includes a guided setup wizard that walks you through everything. This is the recommended way to configure your agent for the first time.</p>

<h3>5.1 Launch the Wizard</h3>
<pre><code># Option A: CLI wizard (works everywhere)
python -m familiar --onboard

# Option B: Rich terminal UI (prettier, needs [tui] extra)
python -m familiar --onboard-tui

# Option C: Web wizard (great for headless devices like Raspberry Pi)
python -m familiar --dashboard
# Then open http://localhost:5000/onboard in your browser</code></pre>

<h3>5.2 What the Wizard Asks</h3>
<p>The wizard walks you through these steps. Don't worry &mdash; you can change everything later.</p>

<div class="step">
  <span class="step-num">1</span> <strong>LLM Provider</strong> &mdash; Which AI brain to use. The wizard auto-detects available API keys and any running Ollama instance.<br>
</div>
<div class="step">
  <span class="step-num">2</span> <strong>Channels</strong> &mdash; Where you want to talk to your Familiar (CLI, dashboard, Telegram, etc.). Start with just CLI and dashboard.<br>
</div>
<div class="step">
  <span class="step-num">3</span> <strong>Owner Identity</strong> &mdash; Set a PIN so only you can control the agent. This is optional but recommended.<br>
</div>
<div class="step">
  <span class="step-num">4</span> <strong>Your Name</strong> &mdash; So your Familiar can address you properly.<br>
</div>
<div class="step">
  <span class="step-num">5</span> <strong>Creature</strong> &mdash; Pick your companion species (Fox, Owl, Cat, Dragon, Wolf, or Frog) and name it.<br>
</div>
<div class="step">
  <span class="step-num">6</span> <strong>Activation</strong> &mdash; The wizard writes your config file and starts the agent.<br>
</div>

<div class="tip">
  <strong>Need to change settings later?</strong> Run <code>python -m familiar --reconfigure</code> to re-run the wizard at any time. Or edit <code>~/.familiar/config.yaml</code> directly.
</div>

<h3>5.3 LAN Onboarding (Raspberry Pi / Headless Server)</h3>
<p>If you're setting up Familiar on a device without a monitor (like a Raspberry Pi):</p>
<pre><code># On the Pi:
FAMILIAR_ONBOARD_LAN=1 python -m familiar --dashboard

# On your laptop/phone, open:
# http://&lt;pi-ip-address&gt;:5000/onboard</code></pre>
<p>Find your Pi's IP with <code>hostname -I</code> on the Pi.</p>
</div>

<!-- ==================== 6. RUNNING FOR THE FIRST TIME ==================== -->
<div class="section" id="s6">
<h2>6. Running Familiar for the First Time</h2>

<h3>6.1 Start the Agent</h3>
<pre><code># Make sure your virtual environment is active!
source ~/familiar-env/bin/activate    # Mac/Linux
# familiar-env\Scripts\activate       # Windows

# Start with web dashboard (recommended)
python -m familiar --dashboard</code></pre>

<p>You should see output like:</p>
<pre><code>Familiar v1.14.40a4 starting...
Dashboard running at http://localhost:5000
Agent ready. Type a message or open the dashboard.</code></pre>

<div class="step">
  <span class="step-num">1</span> Open your web browser and go to <strong>http://localhost:5000</strong><br>
  <span class="step-num">2</span> You'll see the dashboard with your creature, a chat window, and settings<br>
  <span class="step-num">3</span> Type <strong>"Hello!"</strong> in the chat box and press Enter<br>
  <span class="step-num">4</span> Your Familiar will respond! Congratulations &mdash; your AI agent is running.
</div>

<h3>6.2 If You See the Tarot Onboarding</h3>
<p>If this is a brand-new setup, the dashboard may show a tarot card spread &mdash; this is the interactive onboarding experience. Follow the cards to complete your setup. You can also trigger it anytime by typing <code>/start</code> in the chat.</p>

<h3>6.3 CLI-Only Mode (No Browser)</h3>
<pre><code>python -m familiar</code></pre>
<p>This starts an interactive chat in your terminal. Type messages and press Enter. Use <code>/help</code> to see available commands. Type <code>/quit</code> to exit.</p>

<h3>6.4 Running in the Background</h3>
<pre><code># Linux/Mac: run in background
nohup python -m familiar --dashboard &amp;

# Or use screen/tmux:
screen -S familiar
python -m familiar --dashboard
# Press Ctrl+A then D to detach. Reattach with: screen -r familiar</code></pre>

<div class="warn">
  <strong>Remember:</strong> Every time you open a new terminal, activate your virtual environment first: <code>source ~/familiar-env/bin/activate</code>
</div>
</div>

<!-- ==================== 7. DASHBOARD ==================== -->
<div class="section" id="s7">
<h2>7. The Web Dashboard &mdash; Your Control Panel</h2>

<p>The dashboard at <code>http://localhost:5000</code> is where most users spend their time. Here's a tour of what you'll find.</p>

<h3>7.1 Dashboard Layout</h3>
<ul>
  <li><strong>Left sidebar</strong> &mdash; Your creature widget (sprite, name, species, stage)</li>
  <li><strong>Center</strong> &mdash; Chat interface &mdash; talk to your Familiar here</li>
  <li><strong>Right sidebar / tabs</strong> &mdash; Status, Memory, Tasks, Email, Nodes, Skills, Settings</li>
</ul>

<h3>7.2 The Chat Interface</h3>
<p>Type messages in the chat box at the bottom. Your Familiar can:</p>
<ul>
  <li>Answer questions and have conversations</li>
  <li>Execute tasks ("send an email to...", "check my calendar")</li>
  <li>Accept slash commands (type <code>/help</code> to see them all)</li>
</ul>

<h3>7.3 The Settings Card</h3>
<p>Click the Settings tab to customize your creature:</p>
<ul>
  <li><strong>Name</strong> &mdash; rename your familiar (up to 32 characters)</li>
  <li><strong>Species</strong> &mdash; switch between Fox, Owl, Cat, Dragon, Wolf, or Frog</li>
  <li><strong>Stage</strong> &mdash; manually set evolution to Baby, Juvenile, or Adult</li>
  <li><strong>Colors</strong> &mdash; pick body, eye, accent, and voice colors from the palette or enter hex codes</li>
  <li><strong>Save Changes</strong> &mdash; click to persist your choices</li>
  <li><strong>Reset to Baby</strong> &mdash; resets stage and interaction count to start fresh</li>
</ul>

<h3>7.4 Authentication</h3>
<p>By default, the dashboard has no password (it only listens on localhost). To add authentication:</p>
<pre><code>export FAMILIAR_DASHBOARD_KEY="your-secret-key-here"
python -m familiar --dashboard</code></pre>
<p>The dashboard will show a login screen. Enter your key to access it. The key can also be passed as a URL parameter: <code>http://localhost:5000?api_key=your-secret-key-here</code></p>

<h3>7.5 Accessing from Another Device</h3>
<p>By default, the dashboard only accepts connections from localhost. To access it from your phone or another computer on the same network:</p>
<pre><code>python -m familiar.dashboard --host 0.0.0.0</code></pre>
<p>Then open <code>http://&lt;your-computer-ip&gt;:5000</code> from the other device. Always set a <code>FAMILIAR_DASHBOARD_KEY</code> when exposing the dashboard to your network.</p>
</div>

<!-- ==================== 8. YOUR CREATURE ==================== -->
<div class="section" id="s8">
<h2>8. Meet Your Creature &mdash; Choosing &amp; Customizing</h2>

<p>Every Familiar has a companion creature &mdash; a pixel-art sprite that represents your AI. The species you choose actually changes how your AI talks and behaves!</p>

<h3>8.1 The Six Species</h3>
<table>
  <tr><th>Species</th><th>Personality</th><th>How It Talks</th><th>Best For</th></tr>
  <tr><td>Fox</td><td>Quick, clever, warm</td><td>Enthusiastic, playful, like a clever friend</td><td>General use (default)</td></tr>
  <tr><td>Owl</td><td>Wise, observant, calm</td><td>Measured, precise, like a trusted advisor</td><td>Research, knowledge work</td></tr>
  <tr><td>Cat</td><td>Independent, graceful</td><td>Dry, understated, gets to the point</td><td>Developers, no-nonsense users</td></tr>
  <tr><td>Dragon</td><td>Powerful, protective</td><td>Bold, confident, like a guardian</td><td>Security-focused, protective</td></tr>
  <tr><td>Wolf</td><td>Pack-minded, reliable</td><td>Steady, team-oriented, uses "we"</td><td>Teams, collaborative work</td></tr>
  <tr><td>Frog</td><td>Adaptable, cheerful</td><td>Upbeat, surprising, makes work lighter</td><td>Fun, creative tasks</td></tr>
</table>

<h3>8.2 Evolution &mdash; Watching Your Creature Grow</h3>
<p>Your creature evolves automatically as you interact with it:</p>
<table>
  <tr><th>Stage</th><th>Triggered At</th><th>What Changes</th></tr>
  <tr><td>Baby</td><td>0 interactions</td><td>Small, simple sprite &mdash; your new companion</td></tr>
  <tr><td>Juvenile</td><td>10+ interactions</td><td>Larger, more detailed sprite with new features</td></tr>
  <tr><td>Adult</td><td>50+ interactions</td><td>Full-sized, elaborate sprite &mdash; fully evolved!</td></tr>
</table>

<h3>8.3 Manual Stage Control (New in v1.14.40a4)</h3>
<p>Don't want to wait? You have full manual control:</p>
<ul>
  <li>Open <strong>Settings</strong> in the dashboard</li>
  <li>Find the <strong>Stage</strong> dropdown (below Species)</li>
  <li>Select <strong>Baby</strong>, <strong>Juvenile</strong>, or <strong>Adult</strong></li>
  <li>The sprite preview updates immediately so you can see the new form</li>
  <li>Click <strong>Save Changes</strong> to keep your choice</li>
  <li>Click <strong>Reset to Baby</strong> to start the evolution journey over (resets interactions to 0)</li>
</ul>

<div class="tip">
  Natural evolution still works in the background. Manual control simply lets you override at any time. Pick any form you like, or reset and grow again from scratch.
</div>

<h3>8.4 Colors</h3>
<p>Customize four color channels for your creature: <strong>Body</strong>, <strong>Eyes</strong>, <strong>Accent</strong>, and <strong>Voice</strong> (highlight color). Choose from 16 named retro palette colors or enter any hex code:</p>
<table>
  <tr><th>Warm</th><th>Cool</th><th>Neutral</th><th>Special</th></tr>
  <tr><td>Crimson, Ember, Gold, Amber</td><td>Emerald, Jade, Sapphire, Cobalt, Violet, Lavender</td><td>Silver, Ivory, Slate, Obsidian</td><td>Rose, Teal</td></tr>
</table>
</div>

<!-- ==================== 9. CHAT COMMANDS ==================== -->
<div class="section" id="s9">
<h2>9. Talking to Your Familiar &mdash; Chat Commands</h2>

<p>Besides normal conversation, your Familiar understands special commands that start with <code>/</code>. Type these in the chat box (dashboard) or terminal (CLI).</p>

<h3>9.1 Essential Commands (Start Here)</h3>
<table>
  <tr><th>Command</th><th>What It Does</th><th>Example</th></tr>
  <tr><td><code>/help</code></td><td>Shows all available commands</td><td><code>/help</code></td></tr>
  <tr><td><code>/start</code></td><td>Runs the tarot onboarding spread</td><td><code>/start</code></td></tr>
  <tr><td><code>/status</code></td><td>Shows system info (model, memory, skills)</td><td><code>/status</code></td></tr>
  <tr><td><code>/clear</code></td><td>Clears conversation history</td><td><code>/clear</code></td></tr>
  <tr><td><code>/model</code></td><td>Shows which AI model is active</td><td><code>/model</code></td></tr>
  <tr><td><code>/model claude</code></td><td>Switches to Claude</td><td><code>/model ollama</code></td></tr>
</table>

<h3>9.2 Memory Commands</h3>
<table>
  <tr><th>Command</th><th>What It Does</th></tr>
  <tr><td><code>/remember &lt;key&gt; &lt;value&gt;</code></td><td>Save a fact. E.g.: <code>/remember birthday March 15</code></td></tr>
  <tr><td><code>/recall &lt;query&gt;</code></td><td>Search memories. E.g.: <code>/recall birthday</code></td></tr>
</table>

<h3>9.3 Trust &amp; Budget Commands</h3>
<table>
  <tr><th>Command</th><th>What It Does</th></tr>
  <tr><td><code>/trust</code></td><td>Shows your trust level and progression</td></tr>
  <tr><td><code>/budget</code></td><td>Shows daily spending status</td></tr>
  <tr><td><code>/caps</code></td><td>Shows what capabilities are granted</td></tr>
</table>

<h3>9.4 Connection Commands</h3>
<table>
  <tr><th>Command</th><th>What It Does</th></tr>
  <tr><td><code>/connect</code></td><td>Opens the service connection wizard (main menu)</td></tr>
  <tr><td><code>/connect email</code></td><td>Set up email integration</td></tr>
  <tr><td><code>/connect ollama</code></td><td>Manage local Ollama models</td></tr>
  <tr><td><code>/browse</code></td><td>Browse data from connected services</td></tr>
  <tr><td><code>/search &lt;service&gt; &lt;query&gt;</code></td><td>Search a connected service</td></tr>
</table>

<h3>9.5 CLI-Only Commands</h3>
<table>
  <tr><th>Command</th><th>What It Does</th></tr>
  <tr><td><code>/quit</code> or <code>/exit</code></td><td>Exit the CLI</td></tr>
  <tr><td><code>/models</code></td><td>List all available LLM providers</td></tr>
  <tr><td><code>/skills</code></td><td>List all loaded skills</td></tr>
  <tr><td><code>/tools</code></td><td>List all registered tools</td></tr>
  <tr><td><code>/creature</code></td><td>Show creature stats</td></tr>
</table>
</div>

<!-- ==================== 10. CHANNELS ==================== -->
<div class="section" id="s10">
<h2>10. Connecting Channels (Telegram, Discord, etc.)</h2>

<p>Familiar can talk to you through many different platforms. The easiest way to set them up is the <code>/connect</code> wizard.</p>

<h3>10.1 Available Channels</h3>
<table>
  <tr><th>Channel</th><th>Setup Difficulty</th><th>Best For</th></tr>
  <tr><td>CLI (terminal)</td><td>Built-in</td><td>Quick tasks, developers</td></tr>
  <tr><td>Web Dashboard</td><td>Built-in</td><td>Daily use, visual interface</td></tr>
  <tr><td>Telegram</td><td>Easy (5 min)</td><td>Mobile messaging, most popular</td></tr>
  <tr><td>Discord</td><td>Easy (10 min)</td><td>Teams, communities</td></tr>
  <tr><td>Matrix</td><td>Medium</td><td>Privacy-focused, E2EE</td></tr>
  <tr><td>Slack</td><td>Medium</td><td>Workplace integration</td></tr>
  <tr><td>GitHub</td><td>Easy</td><td>Development workflow</td></tr>
  <tr><td>Microsoft Teams</td><td>Medium</td><td>Enterprise environments</td></tr>
  <tr><td>Signal / iMessage / WhatsApp / SMS</td><td>Advanced</td><td>Personal messaging</td></tr>
</table>

<h3>10.2 Setting Up Telegram (Example Walkthrough)</h3>
<div class="step">
  <span class="step-num">1</span> Open Telegram and search for <strong>@BotFather</strong><br>
  <span class="step-num">2</span> Send <code>/newbot</code> and follow the prompts to create a bot<br>
  <span class="step-num">3</span> BotFather gives you a token like <code>123456:ABC-DEF...</code> &mdash; copy it<br>
  <span class="step-num">4</span> Set the token: <code>export TELEGRAM_BOT_TOKEN="123456:ABC-DEF..."</code><br>
  <span class="step-num">5</span> Start Familiar with Telegram: <code>python -m familiar --telegram --dashboard</code><br>
  <span class="step-num">6</span> Find your bot in Telegram and send it a message!
</div>

<h3>10.3 Using the Connect Wizard</h3>
<p>For any channel, you can use the interactive wizard. Type <code>/connect</code> in the chat and follow the prompts. The wizard handles token creation, permissions, and sends test messages to verify everything works.</p>

<table>
  <tr><th>Wizard Command</th><th>What It Sets Up</th></tr>
  <tr><td><code>/connect email</code></td><td>Email (Gmail, Outlook, Yahoo, Proton, Custom)</td></tr>
  <tr><td><code>/connect calendar</code></td><td>Calendar (Google, CalDAV)</td></tr>
  <tr><td><code>/connect ollama</code></td><td>Local AI model management</td></tr>
  <tr><td><code>/connect github</code></td><td>GitHub integration</td></tr>
  <tr><td><code>/connect slack</code></td><td>Slack integration</td></tr>
  <tr><td><code>/connect jellyfin</code></td><td>Jellyfin media server</td></tr>
  <tr><td><code>/connect nextcloud</code></td><td>Nextcloud file/calendar sync</td></tr>
  <tr><td><code>/connect homeassistant</code></td><td>Home Assistant smart home</td></tr>
  <tr><td><code>/connect security</code></td><td>Encryption, RBAC, Vaultwarden</td></tr>
  <tr><td><code>/connect status</code></td><td>Shows all connection statuses</td></tr>
</table>
</div>

<!-- ==================== 11. LLM PROVIDERS ==================== -->
<div class="section" id="s11">
<h2>11. Choosing Your AI Brain &mdash; LLM Providers</h2>

<h3>11.1 Cloud Providers</h3>
<table>
  <tr><th>Provider</th><th>Default Model</th><th>Context Window</th><th>Best For</th></tr>
  <tr><td>Anthropic</td><td>claude-sonnet-4-6</td><td>200K tokens</td><td>Best reasoning, safety</td></tr>
  <tr><td>OpenAI</td><td>gpt-4o</td><td>128K tokens</td><td>Well-rounded, fast</td></tr>
  <tr><td>Google Gemini</td><td>gemini-2.5-flash</td><td>1M tokens</td><td>Largest context, free tier</td></tr>
</table>

<h3>11.2 Local Models via Ollama</h3>
<p>These run entirely on your machine &mdash; no internet needed, 100% private.</p>
<table>
  <tr><th>Model</th><th>RAM Needed</th><th>Speed</th><th>Quality</th></tr>
  <tr><td>llama3.2 (default)</td><td>~4 GB</td><td>Fast</td><td>Very good</td></tr>
  <tr><td>qwen3.5:27b</td><td>~16 GB</td><td>Medium</td><td>Excellent</td></tr>
  <tr><td>deepseek-r1:14b</td><td>~8 GB</td><td>Medium</td><td>Great reasoning</td></tr>
  <tr><td>mistral</td><td>~4 GB</td><td>Fast</td><td>Good</td></tr>
  <tr><td>phi3:mini</td><td>~2 GB</td><td>Very fast</td><td>Basic tasks</td></tr>
  <tr><td>tinyllama</td><td>~1 GB</td><td>Instant</td><td>Simple tasks only</td></tr>
</table>

<h3>11.3 Switching Models On the Fly</h3>
<p>You can switch providers at any time, even mid-conversation:</p>
<pre><code>/model claude      # Switch to Claude
/model ollama      # Switch to local Ollama
/model gpt         # Switch to GPT-4o
/model gemini      # Switch to Gemini</code></pre>

<h3>11.4 Managing Ollama Models</h3>
<pre><code>/connect ollama              # Open Ollama management wizard
/connect ollama list         # See installed models
/connect ollama pull qwen3.5:27b  # Download a new model
/connect ollama remove mistral    # Delete a model
/connect ollama test         # Test connectivity</code></pre>
</div>

<!-- ==================== 12. SKILLS ==================== -->
<div class="section" id="s12">
<h2>12. Skills &mdash; What Your Familiar Can Do</h2>

<p>Skills are modules that give your Familiar specific abilities. 50 built-in skills are included and automatically loaded based on your installed extras.</p>

<table>
  <tr><th>Category</th><th>Skills</th><th>What You Can Ask</th></tr>
  <tr><td>Communication</td><td>email, messaging, sms, notifications</td><td>"Send an email to...", "Text John..."</td></tr>
  <tr><td>Productivity</td><td>calendar, contacts, tasks, planner</td><td>"Schedule a meeting...", "What's on my calendar?"</td></tr>
  <tr><td>Knowledge</td><td>knowledge_base, documents, websearch</td><td>"Search for...", "Summarize this document"</td></tr>
  <tr><td>Web</td><td>browser, private_browser, video</td><td>"Open this URL", "Find videos about..."</td></tr>
  <tr><td>Self-Hosted</td><td>nextcloud, gitea, jellyfin, pihole, homeassistant</td><td>"Play a movie", "Turn off the lights"</td></tr>
  <tr><td>Finance</td><td>bookkeeping, nonprofit, reports</td><td>"Generate expense report", "Show budget"</td></tr>
  <tr><td>Voice</td><td>voice, transcription</td><td>"Read this aloud", "Transcribe this audio"</td></tr>
  <tr><td>Security</td><td>encryption, audit, rbac</td><td>"Encrypt my sessions", "Show audit log"</td></tr>
  <tr><td>Hardware</td><td>gpio</td><td>"Turn on GPIO pin 17" (Raspberry Pi)</td></tr>
</table>

<p>View your loaded skills anytime: type <code>/skills</code> in the CLI or check the Skills tab in the dashboard.</p>
</div>

<!-- ==================== 13. MESH ==================== -->
<div class="section" id="s13">
<h2>13. Multi-Device Mesh Networking</h2>

<p>Connect multiple Familiar instances across devices into an encrypted network. Your desktop Familiar can delegate tasks to a Raspberry Pi Familiar, for example.</p>

<h3>Setting Up a Mesh</h3>
<div class="step">
  <span class="step-num">1</span> Install the mesh extra on all devices: <code>pip install familiar-agent[mesh]</code><br>
  <span class="step-num">2</span> On the main device (gateway): <code>familiar-mesh gateway --public --discovery</code><br>
  <span class="step-num">3</span> Note the secret key: <code>familiar-mesh status</code><br>
  <span class="step-num">4</span> On other devices: <code>familiar-mesh node ws://gateway-ip:18789 --key YOUR_KEY</code><br>
  <span class="step-num">5</span> Check the Nodes tab in the dashboard to see connected devices
</div>

<ul>
  <li>All communication is <strong>NaCl-encrypted</strong></li>
  <li><strong>Zeroconf</strong> auto-discovers peers on the same LAN</li>
  <li>Nodes share skills, memory queries, and task delegation</li>
</ul>
</div>

<!-- ==================== 14. SECURITY ==================== -->
<div class="section" id="s14">
<h2>14. Security &amp; Compliance</h2>

<h3>14.1 Encryption</h3>
<p>Encrypt all stored data (sessions, memory, history):</p>
<pre><code># Generate a key (save this somewhere safe!)
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

# Set the key
export FAMILIAR_ENCRYPTION_KEY="your-generated-key"

# Enable in config.yaml
security:
  encrypt_sessions: true
  encrypt_memory: true
  encrypt_history: true</code></pre>

<h3>14.2 Compliance Modes</h3>
<table>
  <tr><th>Mode</th><th>Features</th><th>Who Needs It</th></tr>
  <tr><td><code>none</code></td><td>No enforcement (default)</td><td>Personal use</td></tr>
  <tr><td><code>hipaa</code></td><td>PHI detection, audit logging, encryption required</td><td>Healthcare organizations</td></tr>
  <tr><td><code>soc2</code></td><td>Access controls, audit trail</td><td>Businesses handling customer data</td></tr>
  <tr><td><code>gdpr</code></td><td>Data minimization, right to erasure</td><td>EU users / organizations</td></tr>
</table>

<div class="warn">
  <strong>Healthcare users:</strong> Install <code>pip install familiar-agent[healthcare]</code> and set <code>compliance.mode: hipaa</code> plus <code>agent.enable_pii_detection: true</code> in your config.
</div>
</div>

<!-- ==================== 15. ANDROID & REFLECTION ==================== -->
<div class="section" id="s15">
<h2>15. Familiar on Android &amp; the Reflection Platform</h2>

<h3>15.1 Familiar for Android</h3>
<p>A native Android app (works great on GrapheneOS).</p>

<div class="step">
  <span class="step-num">1</span> Go to <strong>github.com/omegcrash/familiar-android/releases</strong><br>
  <span class="step-num">2</span> Download the latest <code>.apk</code> file<br>
  <span class="step-num">3</span> On your phone: Settings &rarr; Security &rarr; enable "Install from unknown sources"<br>
  <span class="step-num">4</span> Open the APK and install it<br>
  <span class="step-num">5</span> Grant notification permission when prompted<br>
  <span class="step-num">6</span> The app runs a local Python agent via Chaquopy &mdash; everything stays on your device
</div>

<table>
  <tr><th>Detail</th><th>Value</th></tr>
  <tr><td>Package</td><td><code>com.omegcrash.familiar</code></td></tr>
  <tr><td>Version</td><td>1.4.16 (versionCode 25)</td></tr>
  <tr><td>Min Android</td><td>8.0 (API 26)</td></tr>
  <tr><td>Distribution</td><td>GitHub Releases (no Google Play)</td></tr>
</table>

<h3>15.2 Reflection (Multi-Tenant Platform)</h3>
<p>If you need to host multiple agents for different users or teams:</p>
<pre><code>pip install reflection-agent
reflection</code></pre>
<table>
  <tr><th>Detail</th><th>Value</th></tr>
  <tr><td>PyPI Package</td><td><code>reflection-agent</code></td></tr>
  <tr><td>Version</td><td>2.0.22</td></tr>
  <tr><td>Depends on</td><td><code>familiar-agent>=1.14.40a4</code></td></tr>
</table>
</div>

<!-- ==================== 16. TROUBLESHOOTING ==================== -->
<div class="section" id="s16">
<h2>16. Troubleshooting &amp; FAQ</h2>

<h3>16.1 Installation Problems</h3>

<h4>"command not found: python3" or "python is not recognized"</h4>
<p>Python isn't installed or not in your PATH.</p>
<ul>
  <li><strong>Mac:</strong> <code>brew install python</code> or download from python.org</li>
  <li><strong>Ubuntu/Debian:</strong> <code>sudo apt update && sudo apt install python3 python3-pip python3-venv</code></li>
  <li><strong>Windows:</strong> Download from python.org. During install, check <strong>"Add Python to PATH"</strong></li>
</ul>

<h4>"No module named pip" or "pip: command not found"</h4>
<pre><code># Linux/Mac:
python3 -m ensurepip --upgrade

# Or reinstall pip:
curl https://bootstrap.pypa.io/get-pip.py | python3</code></pre>

<h4>"ERROR: externally-managed-environment" (PEP 668)</h4>
<p>Your OS protects system Python. Use a virtual environment (recommended):</p>
<pre><code>python3 -m venv ~/familiar-env
source ~/familiar-env/bin/activate
pip install familiar-agent[llm,web]</code></pre>

<h4>pip install hangs or is very slow</h4>
<ul>
  <li>Check your internet connection</li>
  <li>Try a different mirror: <code>pip install --index-url https://pypi.org/simple/ familiar-agent[llm,web]</code></li>
  <li>If behind a corporate proxy, set <code>HTTP_PROXY</code> and <code>HTTPS_PROXY</code> environment variables</li>
</ul>

<h4>"ERROR: Could not build wheels for..." (compilation errors)</h4>
<p>Some extras need C compilers. Install build tools:</p>
<pre><code># Ubuntu/Debian:
sudo apt install build-essential python3-dev libffi-dev

# Mac:
xcode-select --install

# Windows:
# Install Visual Studio Build Tools from visualstudio.microsoft.com</code></pre>

<h3>16.2 API Key &amp; Provider Problems</h3>

<h4>"No API key found" or "AuthenticationError"</h4>
<ul>
  <li>Verify the key is set: <code>echo $ANTHROPIC_API_KEY</code> (should print your key)</li>
  <li>Make sure you're setting the right variable for your provider</li>
  <li>On Windows, use <code>set</code> not <code>export</code>: <code>set ANTHROPIC_API_KEY=sk-ant-...</code></li>
  <li>Check for trailing spaces or quotes in the key</li>
  <li>Try setting it in <code>~/.familiar/.env</code>: <code>ANTHROPIC_API_KEY=sk-ant-...</code></li>
</ul>

<h4>"Ollama connection refused" or "Connection error to localhost:11434"</h4>
<ul>
  <li>Is Ollama running? Start it: <code>ollama serve</code></li>
  <li>Check if it's listening: <code>curl http://localhost:11434/api/tags</code></li>
  <li>If Ollama is on a different machine, update <code>llm.ollama_base_url</code> in config.yaml</li>
  <li>Make sure you've pulled a model: <code>ollama pull llama3.2</code></li>
</ul>

<h4>"Rate limit exceeded" or "429 Too Many Requests"</h4>
<ul>
  <li>You've hit your provider's rate limit. Wait a minute and try again</li>
  <li>Check your provider dashboard for usage limits</li>
  <li>Consider using a local model for high-volume tasks: <code>/model ollama</code></li>
</ul>

<h4>"Insufficient funds" or "billing error"</h4>
<ul>
  <li>Your API account needs credits. Add payment at your provider's billing page</li>
  <li>Anthropic: console.anthropic.com &rarr; Settings &rarr; Billing</li>
  <li>OpenAI: platform.openai.com &rarr; Settings &rarr; Billing</li>
</ul>

<h3>16.3 Dashboard Problems</h3>

<h4>Dashboard 401 Unauthorized</h4>
<ul>
  <li>If <code>FAMILIAR_DASHBOARD_KEY</code> is set, you need to provide it</li>
  <li>Check that the key in your browser matches exactly (no extra spaces)</li>
  <li>Try clearing browser storage: open DevTools (F12) &rarr; Application &rarr; Session Storage &rarr; Clear</li>
  <li>Or pass it via URL: <code>http://localhost:5000?api_key=your-key</code></li>
</ul>

<h4>Dashboard loads but shows a blank page or broken layout</h4>
<ul>
  <li><strong>Hard refresh:</strong> Press <code>Ctrl+Shift+R</code> (Windows/Linux) or <code>Cmd+Shift+R</code> (Mac)</li>
  <li><strong>Clear browser cache:</strong> Ctrl+Shift+Delete &rarr; select "Cached images and files" &rarr; Clear</li>
  <li><strong>Try incognito/private window</strong> to rule out extensions or cached data</li>
  <li><strong>Try a different browser</strong> (Chrome, Firefox, Edge all work)</li>
  <li>Check the terminal for error messages &mdash; they often explain what went wrong</li>
</ul>

<h4>Dashboard is slow, unresponsive, or spinner won't stop</h4>
<ul>
  <li>Refresh the page (<code>F5</code> or <code>Ctrl+R</code>)</li>
  <li>Check the terminal for errors (the agent might be waiting for an LLM response)</li>
  <li>If using a local model, it may be loading into memory &mdash; give it 30-60 seconds on first use</li>
  <li>Open browser DevTools (F12) &rarr; Console tab to see JavaScript errors</li>
</ul>

<h4>Creature sprite not showing</h4>
<ul>
  <li>Run <code>/start</code> in the chat to trigger creature creation</li>
  <li>Or run <code>python -m familiar --onboard</code> and complete the setup</li>
  <li>Check <code>~/.familiar/data/creature.json</code> exists</li>
  <li>Hard refresh the browser (<code>Ctrl+Shift+R</code>)</li>
</ul>

<h4>Changes don't appear after saving settings</h4>
<ul>
  <li>Hard refresh: <code>Ctrl+Shift+R</code></li>
  <li>The sidebar creature widget updates automatically, but other pages may need a refresh</li>
  <li>Check the terminal output for save errors</li>
</ul>

<h4>"Address already in use" / port 5000 conflict</h4>
<ul>
  <li>Another process is using port 5000. Find it: <code>lsof -i :5000</code> (Mac/Linux) or <code>netstat -ano | findstr 5000</code> (Windows)</li>
  <li>Use a different port: <code>python -m familiar --dashboard --dashboard-port 5001</code></li>
  <li>On Mac, AirPlay Receiver uses port 5000 &mdash; disable it in System Settings &rarr; AirDrop &amp; Handoff</li>
</ul>

<h3>16.4 Module &amp; Import Errors</h3>

<h4>"ModuleNotFoundError: No module named 'discord'" (or telegram, etc.)</h4>
<p>You need to install the relevant extra:</p>
<pre><code>pip install familiar-agent[discord]     # for Discord
pip install familiar-agent[telegram]    # for Telegram
pip install familiar-agent[voice]       # for voice features
pip install familiar-agent[web]         # for the dashboard</code></pre>

<h4>"ImportError" after upgrading</h4>
<pre><code># Force reinstall to clear stale files
pip install --force-reinstall familiar-agent[llm,web]</code></pre>

<h3>16.5 Creature &amp; Evolution Problems</h3>

<h4>Stage dropdown doesn't change the preview</h4>
<ul>
  <li>Hard refresh the page (<code>Ctrl+Shift+R</code>)</li>
  <li>Check browser console (F12) for JavaScript errors</li>
  <li>Verify the agent is running (check terminal for errors)</li>
</ul>

<h4>"Reset to Baby" doesn't work</h4>
<ul>
  <li>A confirmation dialog should appear &mdash; check for popup blockers</li>
  <li>Check the terminal for error messages</li>
  <li>Manual fix: edit <code>~/.familiar/data/creature.json</code> and set <code>"evolution_stage": "baby"</code> and <code>"total_interactions": 0</code></li>
</ul>

<h3>16.6 Connection &amp; Network Issues</h3>

<h4>Can't access dashboard from phone/another device</h4>
<ul>
  <li>By default, the dashboard only listens on localhost. Start with: <code>python -m familiar.dashboard --host 0.0.0.0</code></li>
  <li>Make sure both devices are on the same network</li>
  <li>Check firewall: <code>sudo ufw allow 5000</code> (Linux)</li>
  <li>Find your computer's IP: <code>hostname -I</code> (Linux) or <code>ipconfig</code> (Windows)</li>
</ul>

<h4>Mesh nodes can't connect</h4>
<ul>
  <li>Verify the gateway is running with <code>--public</code> flag</li>
  <li>Check firewall allows port 18789</li>
  <li>Verify the secret key matches on both sides</li>
  <li>Test connectivity: <code>curl http://gateway-ip:18789</code></li>
</ul>

<h3>16.7 Performance Issues</h3>

<h4>Agent responds very slowly</h4>
<ul>
  <li>Cloud providers: check your internet connection</li>
  <li>Local models: try a smaller model (<code>/connect ollama</code> &rarr; switch to a lighter model)</li>
  <li>Check RAM usage: local models need the full model loaded in memory</li>
  <li>On Raspberry Pi: use <code>tinyllama</code> or <code>smollm2:135m</code> for speed</li>
</ul>

<h4>High memory usage</h4>
<ul>
  <li>Local models require significant RAM. <code>llama3.2</code> needs ~4 GB</li>
  <li>Switch to a cloud provider to free memory: <code>/model claude</code></li>
  <li>Or use a smaller model: <code>/connect ollama</code> then switch to <code>phi3:mini</code></li>
</ul>

<h3>16.8 Logs &amp; Debugging</h3>
<pre><code># Enable verbose logging at startup:
python -m familiar --verbose --dashboard

# Or set log level in config.yaml:
observability:
  log_level: DEBUG</code></pre>
<p>Logs are printed to the terminal where Familiar is running. Look for lines marked <code>ERROR</code> or <code>WARNING</code>.</p>
</div>

<!-- ==================== 17. UNINSTALLING ==================== -->
<div class="section" id="s17">
<h2>17. Uninstalling, Reinstalling &amp; Clean Reset</h2>

<h3>17.1 Complete Uninstall</h3>
<p>Follow these steps to remove Familiar entirely from your system:</p>

<div class="step">
  <span class="step-num">1</span> <strong>Stop the agent</strong> if it's running (press <code>Ctrl+C</code> in the terminal or kill the process)<br>
</div>
<div class="step">
  <span class="step-num">2</span> <strong>Uninstall the Python package:</strong><br>
  <pre><code>pip uninstall familiar-agent -y</code></pre>
</div>
<div class="step">
  <span class="step-num">3</span> <strong>Remove all data and configuration:</strong><br>
  <pre><code># This deletes your config, creature, memories, and all data!
rm -rf ~/.familiar</code></pre>
  <p style="font-size:9pt; color:#666;">Windows: <code>rmdir /s /q %USERPROFILE%\.familiar</code></p>
</div>
<div class="step">
  <span class="step-num">4</span> <strong>Remove the virtual environment</strong> (if you created one):<br>
  <pre><code>rm -rf ~/familiar-env</code></pre>
</div>
<div class="step">
  <span class="step-num">5</span> <strong>Remove Ollama models</strong> (if installed):<br>
  <pre><code># List models:
ollama list

# Remove each one:
ollama rm llama3.2
ollama rm mistral
# etc.

# To uninstall Ollama itself:
# Mac: delete the app from Applications
# Linux: sudo rm /usr/local/bin/ollama && rm -rf ~/.ollama</code></pre>
</div>
<div class="step">
  <span class="step-num">6</span> <strong>Remove Reflection</strong> (if installed):<br>
  <pre><code>pip uninstall reflection-agent -y</code></pre>
</div>

<div class="danger">
  <strong>Warning:</strong> Step 3 permanently deletes all your data &mdash; creature state, memories, conversation history, configuration, and API keys stored in <code>~/.familiar/.env</code>. Back up anything important first!
</div>

<h3>17.2 Clean Reinstall</h3>
<p>To start completely fresh (like a brand-new setup):</p>

<pre><code># 1. Uninstall
pip uninstall familiar-agent -y

# 2. Remove all data
rm -rf ~/.familiar

# 3. Clear pip cache (fixes stale package issues)
pip cache purge

# 4. Reinstall
pip install familiar-agent[llm,web]

# 5. Run the onboarding wizard
python -m familiar --onboard</code></pre>

<h3>17.3 Upgrade Without Losing Data</h3>
<p>To update to the latest version while keeping your creature, memories, and config:</p>
<pre><code>pip install --upgrade familiar-agent[llm,web]</code></pre>
<p>Your data in <code>~/.familiar/</code> is preserved. The agent will pick up new features automatically.</p>

<h3>17.4 Reset Just the Creature (Keep Everything Else)</h3>
<pre><code># Option 1: Use the dashboard button
# Settings card → "Reset to Baby"

# Option 2: Delete creature file
rm ~/.familiar/data/creature.json
# Re-run onboard or /start to create a new creature</code></pre>

<h3>17.5 Reset Configuration Only</h3>
<pre><code># Delete config but keep data
rm ~/.familiar/config.yaml

# Re-run the wizard
python -m familiar --onboard</code></pre>

<h3>17.6 Downgrade to a Specific Version</h3>
<pre><code>pip install familiar-agent==1.14.39</code></pre>

<h3>17.7 Clearing Browser Data (Dashboard Issues)</h3>
<p>If the dashboard is behaving strangely after an update:</p>
<ol>
  <li><strong>Hard refresh:</strong> <code>Ctrl+Shift+R</code> (Windows/Linux) or <code>Cmd+Shift+R</code> (Mac)</li>
  <li><strong>Clear site data:</strong> Browser DevTools (F12) &rarr; Application tab &rarr; Storage &rarr; "Clear site data"</li>
  <li><strong>Clear just session storage:</strong> DevTools &rarr; Application &rarr; Session Storage &rarr; right-click &rarr; Clear</li>
  <li><strong>Try incognito/private mode</strong> to confirm the issue is cache-related</li>
</ol>
</div>

<!-- ==================== 18. QUICK REFERENCE ==================== -->
<div class="section" id="s18">
<h2>18. Quick Reference Card</h2>

<h3>Essential Commands</h3>
<pre><code># Start (always activate venv first!)
source ~/familiar-env/bin/activate
python -m familiar --dashboard

# First-time setup
python -m familiar --onboard

# Change settings
python -m familiar --reconfigure</code></pre>

<h3>Chat Commands Cheat Sheet</h3>
<pre><code>/help              Show commands       /status       System info
/model claude      Switch to Claude    /model ollama Switch to local
/remember key val  Save a fact         /recall query Search memories
/connect           Setup wizard        /connect status  Check services
/clear             Clear history       /start        Onboarding spread
/trust             Trust level         /budget       Spending status</code></pre>

<h3>Key File Locations</h3>
<pre><code>~/.familiar/config.yaml              # Configuration
~/.familiar/.env                     # API keys (auto-managed)
~/.familiar/data/creature.json       # Creature state
~/.familiar/data/analytics.db        # Analytics database
~/.familiar/data/tasks.json          # Task list</code></pre>

<h3>Current Versions (March 2026)</h3>
<table>
  <tr><th>Component</th><th>Version</th><th>Install</th></tr>
  <tr><td>Familiar</td><td>1.14.40a4</td><td><code>pip install familiar-agent</code></td></tr>
  <tr><td>Reflection</td><td>2.0.22</td><td><code>pip install reflection-agent</code></td></tr>
  <tr><td>Android</td><td>1.4.16</td><td>GitHub Releases APK</td></tr>
</table>

<h3>Getting Help</h3>
<ul>
  <li><strong>GitHub Issues:</strong> github.com/omegcrash/familiar/issues</li>
  <li><strong>Source Code:</strong> github.com/omegcrash/familiar</li>
</ul>
</div>
"""

# ── APPENDIX (command index) ─────────────────────────────────────────
APPENDIX = r"""
<!-- ==================== APPENDIX ==================== -->
<div class="section appendix" id="appendix">
<h1 style="font-size:22pt; text-align:center; border:none; margin-bottom:4px;">Appendix: Advanced Command &amp; Configuration Index</h1>
<p style="text-align:center; color:#666; margin-bottom:20px;">This section is a comprehensive reference for advanced users. It documents every CLI flag, chat command, API endpoint, configuration key, and environment variable in the Familiar platform.</p>

<!-- A1. CLI -->
<h2>A1. CLI Commands &amp; Flags</h2>

<h3><code>python -m familiar</code></h3>
<table>
<tr><th>Flag</th><th>Short</th><th>Default</th><th>Description</th></tr>
<tr><td><code>--telegram</code></td><td><code>-t</code></td><td></td><td>Run with Telegram</td></tr>
<tr><td><code>--discord</code></td><td></td><td></td><td>Run with Discord</td></tr>
<tr><td><code>--matrix</code></td><td></td><td></td><td>Run with Matrix</td></tr>
<tr><td><code>--github</code></td><td></td><td></td><td>GitHub notification polling</td></tr>
<tr><td><code>--slack</code></td><td></td><td></td><td>Slack (Socket Mode)</td></tr>
<tr><td><code>--dashboard</code></td><td><code>-d</code></td><td></td><td>Web dashboard</td></tr>
<tr><td><code>--dashboard-port</code></td><td></td><td>5000</td><td>Dashboard port</td></tr>
<tr><td><code>--gateway</code></td><td><code>-g</code></td><td></td><td>Mesh gateway mode</td></tr>
<tr><td><code>--gateway-port</code></td><td></td><td>18789</td><td>Gateway port</td></tr>
<tr><td><code>--provider</code></td><td><code>-p</code></td><td>ollama</td><td>LLM provider</td></tr>
<tr><td><code>--init</code></td><td></td><td></td><td>Initialize config</td></tr>
<tr><td><code>--onboard</code></td><td></td><td></td><td>Onboarding wizard</td></tr>
<tr><td><code>--onboard-tui</code></td><td></td><td></td><td>Rich TUI onboarding</td></tr>
<tr><td><code>--reconfigure</code></td><td></td><td></td><td>Re-run onboarding</td></tr>
<tr><td><code>--setup-google</code></td><td></td><td></td><td>Google Workspace</td></tr>
<tr><td><code>--new-skill NAME</code></td><td></td><td></td><td>Create skill template</td></tr>
<tr><td><code>--show-key</code></td><td></td><td></td><td>Show mesh key</td></tr>
<tr><td><code>--verbose</code></td><td><code>-v</code></td><td></td><td>Verbose logging</td></tr>
</table>

<h3>Other Entry Points</h3>
<table>
<tr><th>Command</th><th>Port</th><th>Description</th></tr>
<tr><td><code>python -m familiar.dashboard</code></td><td>5000</td><td>Dashboard (--host, --port, --debug)</td></tr>
<tr><td><code>python -m familiar.admin</code></td><td>5001</td><td>Admin dashboard</td></tr>
<tr><td><code>python -m familiar.pwa</code></td><td>5002</td><td>PWA server</td></tr>
<tr><td><code>familiar-mesh gateway|node|status|genkey</code></td><td>18789</td><td>Mesh CLI</td></tr>
<tr><td><code>familiar-eval run|generate</code></td><td></td><td>CI evaluation</td></tr>
<tr><td><code>python -m familiar.core.mcp.server</code></td><td></td><td>MCP skill server</td></tr>
<tr><td><code>python -m familiar.core.backup</code></td><td></td><td>Backup tool</td></tr>
<tr><td><code>python -m familiar.channels.teams</code></td><td>3978</td><td>Teams bot</td></tr>
</table>

<!-- A2. CHAT COMMANDS -->
<h2>A2. All Chat Commands</h2>
<table>
<tr><th>Command</th><th>Scope</th><th>Description</th></tr>
<tr><td><code>/help</code></td><td>All</td><td>Show commands</td></tr>
<tr><td><code>/start</code></td><td>All</td><td>Tarot onboarding</td></tr>
<tr><td><code>/status</code></td><td>All</td><td>System status</td></tr>
<tr><td><code>/clear</code></td><td>All</td><td>Clear history</td></tr>
<tr><td><code>/model [name]</code></td><td>All</td><td>Show/switch provider</td></tr>
<tr><td><code>/remember &lt;key&gt; &lt;value&gt;</code></td><td>All</td><td>Store memory</td></tr>
<tr><td><code>/recall &lt;query&gt;</code></td><td>All</td><td>Search memories</td></tr>
<tr><td><code>/trust</code></td><td>All</td><td>Trust level</td></tr>
<tr><td><code>/budget</code></td><td>All</td><td>Spending status</td></tr>
<tr><td><code>/caps</code></td><td>All</td><td>Capabilities</td></tr>
<tr><td><code>/connect [service]</code></td><td>All</td><td>Connection wizard</td></tr>
<tr><td><code>/browse</code></td><td>All</td><td>Browse services</td></tr>
<tr><td><code>/search &lt;svc&gt; &lt;q&gt;</code></td><td>All</td><td>Search service</td></tr>
<tr><td><code>/quit</code></td><td>CLI</td><td>Exit</td></tr>
<tr><td><code>/models</code></td><td>CLI</td><td>List providers</td></tr>
<tr><td><code>/skills</code></td><td>CLI</td><td>List skills</td></tr>
<tr><td><code>/tools</code></td><td>CLI</td><td>List tools</td></tr>
<tr><td><code>/creature</code></td><td>CLI</td><td>Creature stats</td></tr>
<tr><td><code>/link &lt;email&gt;</code></td><td>Multi-user</td><td>Link account</td></tr>
<tr><td><code>/confirm &lt;code&gt;</code></td><td>Multi-user</td><td>Confirm link</td></tr>
<tr><td><code>/unlink</code></td><td>Multi-user</td><td>Unlink account</td></tr>
<tr><td><code>/whoami</code></td><td>Multi-user</td><td>Account info</td></tr>
<tr><td><code>/grant &lt;id&gt; [role]</code></td><td>Owner</td><td>Grant access</td></tr>
<tr><td><code>/revoke &lt;id&gt;</code></td><td>Owner</td><td>Revoke access</td></tr>
<tr><td><code>/preauth</code></td><td>Owner</td><td>List pre-auth users</td></tr>
<tr><td><code>/ask &lt;question&gt;</code></td><td>Discord</td><td>Ask the agent</td></tr>
</table>

<!-- A3. CONNECT WIZARD -->
<h2>A3. Connect Wizard Commands (70+)</h2>
<h4>LLM: <code>/connect anthropic|openai|gemini|ollama</code></h4>
<h4>Email: <code>/connect email [gmail|outlook|yahoo|proton|custom] | email test | email set</code></h4>
<h4>Calendar: <code>/connect calendar [google|caldav] | calendar test</code></h4>
<h4>Google: <code>/connect google [check|install|auth &lt;svc&gt;|code &lt;code&gt;]</code></h4>
<h4>Integrations: <code>/connect sms|browser|voice|healthcare|websearch|github|slack</code></h4>
<h4>Self-hosted: <code>/connect jellyfin|gitea|homeassistant|joplin|pihole|nextcloud|proton|email-server</code></h4>
<h4>Security: <code>/connect security|vaultwarden|encryption|phi|rbac|users</code></h4>
<p>Each service supports <code>test</code> subcommand and inline one-shot setup with arguments.</p>

<!-- A4. API ENDPOINTS -->
<h2>A4. Dashboard API Endpoints (55 routes)</h2>
<table>
<tr><th>#</th><th>Method</th><th>Path</th><th>Description</th></tr>
<tr><td>1</td><td>GET</td><td><code>/</code></td><td>Dashboard page</td></tr>
<tr><td>2</td><td>GET</td><td><code>/api/status</code></td><td>System status</td></tr>
<tr><td>3</td><td>GET</td><td><code>/api/creature</code></td><td>Creature state</td></tr>
<tr><td>4</td><td>POST</td><td><code>/api/creature</code></td><td>Update creature</td></tr>
<tr><td>5</td><td>GET</td><td><code>/api/creature/preview</code></td><td>Sprite preview</td></tr>
<tr><td>6</td><td>POST</td><td><code>/api/chat</code></td><td>Send message</td></tr>
<tr><td>7</td><td>POST</td><td><code>/api/terminal/stream</code></td><td>Stream response (SSE)</td></tr>
<tr><td>8</td><td>POST</td><td><code>/api/voice/stt</code></td><td>Speech-to-text</td></tr>
<tr><td>9</td><td>POST</td><td><code>/api/voice/tts</code></td><td>Text-to-speech</td></tr>
<tr><td>10-13</td><td>*</td><td><code>/api/shell/*</code></td><td>Host shell (enable, stream, kill)</td></tr>
<tr><td>14-16</td><td>*</td><td><code>/api/memory[/&lt;key&gt;]</code></td><td>Memory CRUD</td></tr>
<tr><td>17-19</td><td>*</td><td><code>/api/tasks[/&lt;id&gt;/complete]</code></td><td>Task management</td></tr>
<tr><td>20-22</td><td>*</td><td><code>/api/skills[/&lt;name&gt;/toggle]</code>, <code>/api/tools</code></td><td>Skills &amp; tools</td></tr>
<tr><td>23</td><td>GET</td><td><code>/api/nodes</code></td><td>Mesh nodes</td></tr>
<tr><td>24-26</td><td>GET</td><td><code>/api/email/*</code>, <code>/api/briefing</code></td><td>Email triage, briefing</td></tr>
<tr><td>27-38</td><td>*</td><td><code>/api/connect/*</code></td><td>Connect wizard, browse, search</td></tr>
<tr><td>39-42</td><td>*</td><td><code>/api/config[/routing]</code></td><td>Config &amp; model routing</td></tr>
<tr><td>43-44</td><td>*</td><td><code>/api/history</code></td><td>Conversation history</td></tr>
<tr><td>45-55</td><td>*</td><td><code>/onboard</code>, <code>/api/onboard/*</code></td><td>Onboarding (11 routes)</td></tr>
</table>

<h3>Admin Endpoints (29 routes, port 5001)</h3>
<p>Login, users, invites, activity, settings, analytics, budgets, audit, backups, SSO.</p>

<h3>PWA Endpoints (13 routes, port 5002)</h3>
<p>Chat, streaming, push notifications, user info.</p>

<h3>Other (19 routes)</h3>
<p>HA health/status/drain (4), audit (4), SSO (3), browser proxy (12).</p>

<!-- A5. CONFIG KEYS -->
<h2>A5. YAML Configuration Keys (97 keys)</h2>

<h3><code>agent.*</code></h3>
<table>
<tr><th>Key</th><th>Type</th><th>Default</th></tr>
<tr><td><code>name</code></td><td>str</td><td>"Agent"</td></tr>
<tr><td><code>persona</code></td><td>str</td><td>"a helpful AI assistant"</td></tr>
<tr><td><code>memory_enabled</code></td><td>bool</td><td>true</td></tr>
<tr><td><code>max_conversation_history</code></td><td>int</td><td>50</td></tr>
<tr><td><code>skills_enabled</code></td><td>bool</td><td>true</td></tr>
<tr><td><code>scheduler_enabled</code></td><td>bool</td><td>true</td></tr>
<tr><td><code>heartbeat_interval_minutes</code></td><td>int</td><td>60</td></tr>
<tr><td><code>security_mode</code></td><td>str</td><td>"balanced"</td></tr>
<tr><td><code>allow_shell_commands</code></td><td>bool</td><td>true</td></tr>
<tr><td><code>allow_file_write</code></td><td>bool</td><td>true</td></tr>
<tr><td><code>enable_pii_detection</code></td><td>bool</td><td>false</td></tr>
<tr><td><code>sandboxed_directories</code></td><td>list</td><td>[HOME]</td></tr>
</table>

<h3><code>llm.*</code></h3>
<table>
<tr><th>Key</th><th>Type</th><th>Default</th></tr>
<tr><td><code>default_provider</code></td><td>str</td><td>"anthropic"</td></tr>
<tr><td><code>anthropic_model</code></td><td>str</td><td>"claude-sonnet-4-6"</td></tr>
<tr><td><code>openai_model</code></td><td>str</td><td>"gpt-4o"</td></tr>
<tr><td><code>ollama_model</code></td><td>str</td><td>"llama3.2"</td></tr>
<tr><td><code>ollama_base_url</code></td><td>str</td><td>"http://localhost:11434"</td></tr>
<tr><td><code>max_tokens</code></td><td>int</td><td>4096</td></tr>
<tr><td><code>temperature</code></td><td>float</td><td>0.7</td></tr>
<tr><td><code>lightweight_model</code></td><td>str</td><td>""</td></tr>
<tr><td><code>lightweight_provider</code></td><td>str</td><td>""</td></tr>
</table>

<h3><code>channels.*</code> (17 keys)</h3>
<p><code>cli_enabled</code>(true), <code>telegram_enabled</code>(false), <code>telegram_token</code>, <code>telegram_allowed_users</code>, <code>owner_telegram_id</code>, <code>discord_enabled</code>(false), <code>discord_token</code>, <code>matrix_enabled</code>(false), <code>matrix_homeserver</code>, <code>matrix_user</code>, <code>signal_enabled</code>(false), <code>whatsapp_enabled</code>(false), <code>imessage_enabled</code>(false), <code>teams_enabled</code>(false), and associated tokens/IDs.</p>

<h3><code>security.*</code> (11 keys)</h3>
<p><code>encrypt_sessions</code>(false), <code>encrypt_memory</code>(false), <code>encrypt_history</code>(false), <code>encryption_key_env</code>, <code>session_timeout_minutes</code>(60), <code>require_reauth_for_sensitive</code>(false), <code>max_failed_attempts</code>(5), <code>lockout_duration_minutes</code>(30), <code>auto_trust_upgrade</code>(true), <code>max_trust_level</code>("owner"), <code>always_confirm</code>(list).</p>

<h3><code>compliance.*</code> (4), <code>proactive.*</code> (5), <code>resilience.*</code> (6), <code>observability.*</code> (5), <code>mcp.*</code> (11), <code>backup.*</code> (11)</h3>
<p>See Sections 4 and 14 of the main guide for full details.</p>

<!-- A6. ENV VARS -->
<h2>A6. Environment Variables (115+)</h2>

<h3>API Keys</h3>
<p><code>ANTHROPIC_API_KEY</code>, <code>OPENAI_API_KEY</code>, <code>GEMINI_API_KEY</code>, <code>GOOGLE_API_KEY</code></p>

<h3>LLM Overrides</h3>
<p><code>DEFAULT_PROVIDER</code>, <code>LLM_DEFAULT_PROVIDER</code>, <code>OLLAMA_MODEL</code>, <code>OLLAMA_TIMEOUT</code>, <code>OLLAMA_NUM_CTX</code>, <code>OLLAMA_FALLBACK_MODEL</code>, <code>GEMINI_MODEL</code>, <code>FAMILIAR_LIGHTWEIGHT_MODEL</code>, <code>FAMILIAR_LIGHTWEIGHT_PROVIDER</code>, <code>AGENT_NAME</code></p>

<h3>Channel Tokens</h3>
<p><code>TELEGRAM_BOT_TOKEN</code>, <code>DISCORD_BOT_TOKEN</code>, <code>GITHUB_TOKEN</code>, <code>GITHUB_REPOS</code>, <code>SLACK_BOT_TOKEN</code>, <code>SLACK_APP_TOKEN</code>, <code>MATRIX_HOMESERVER</code>, <code>MATRIX_USER</code>, <code>MATRIX_PASSWORD</code>, <code>MATRIX_ACCESS_TOKEN</code>, <code>SIGNAL_PHONE</code>, <code>WHATSAPP_BRIDGE_HOST</code>, <code>TEAMS_APP_ID</code>, <code>TEAMS_APP_PASSWORD</code>, <code>ENABLED_CHANNELS</code></p>

<h3>Owner Identity</h3>
<p><code>OWNER_TELEGRAM_ID</code>, <code>OWNER_DISCORD_ID</code>, <code>OWNER_MATRIX_ID</code>, <code>OWNER_SIGNAL_ID</code>, <code>OWNER_WHATSAPP_ID</code>, <code>OWNER_IMESSAGE_ID</code>, <code>OWNER_TEAMS_ID</code>, <code>OWNER_GITHUB_ID</code>, <code>OWNER_SLACK_ID</code>, <code>OWNER_PIN_HASH</code></p>

<h3>Email</h3>
<p><code>EMAIL_ADDRESS</code>, <code>EMAIL_PASSWORD</code>, <code>EMAIL_IMAP_SERVER</code>, <code>EMAIL_SMTP_SERVER</code>, <code>EMAIL_IMAP_PORT</code>, <code>EMAIL_SMTP_PORT</code>, <code>EMAIL_SERVER_DOMAIN</code>, <code>EMAIL_SERVER_RELAY_HOST</code>, <code>FAMILIAR_EMAIL_ADDRESS</code>, <code>FAMILIAR_SMTP_SERVER</code></p>

<h3>Self-Hosted Services</h3>
<p><code>JELLYFIN_URL/TOKEN/USER_ID</code>, <code>GITEA_URL/TOKEN</code>, <code>HOMEASSISTANT_URL/TOKEN</code>, <code>JOPLIN_URL/TOKEN</code>, <code>PIHOLE_URL/TOKEN/TYPE</code>, <code>NEXTCLOUD_URL/USER/TOKEN</code>, <code>VAULTWARDEN_URL/TOKEN</code>, <code>CALDAV_URL/USER/PASSWORD</code>, <code>PROTON_BRIDGE_HOST</code>, <code>TWILIO_ACCOUNT_SID/AUTH_TOKEN/PHONE_NUMBER</code></p>

<h3>Dashboard &amp; Web</h3>
<p><code>FAMILIAR_DASHBOARD_KEY</code>, <code>FAMILIAR_ALLOWED_ORIGINS</code>, <code>FAMILIAR_SHELL_ENABLED</code>, <code>FAMILIAR_ONBOARD_LAN</code>, <code>FAMILIAR_ADMIN_SECRET</code>, <code>FAMILIAR_PWA_SECRET</code>, <code>FAMILIAR_DATA_DIR</code>, <code>VAPID_PUBLIC_KEY</code>, <code>VAPID_PRIVATE_KEY</code></p>

<h3>Security &amp; Encryption</h3>
<p><code>FAMILIAR_ENCRYPTION_KEY</code>, <code>FAMILIAR_ENCRYPTION_PASSWORD</code>, <code>FAMILIAR_AUDIT_KEY</code>, <code>FAMILIAR_WEBHOOK_SECRET</code></p>

<h3>Mesh &amp; HA</h3>
<p><code>FAMILIAR_MESH_ENABLED</code>, <code>FAMILIAR_MESH_HOST</code>, <code>FAMILIAR_MESH_PORT</code>, <code>FAMILIAR_MESH_KEY</code>, <code>FAMILIAR_NODE_NAME</code>, <code>HA_ENABLED</code>, <code>HA_MODE</code>, <code>HA_NODE_ID</code>, <code>HA_SHARED_SECRET</code></p>

<h3>Redis</h3>
<p><code>REDIS_URL</code>, <code>REDIS_HOST</code>, <code>REDIS_PORT</code>, <code>REDIS_DB</code>, <code>REDIS_PASSWORD</code>, <code>FAMILIAR_REDIS_PREFIX</code></p>

<h3>SSO</h3>
<p><code>SSO_PROVIDER</code>, <code>SSO_CLIENT_ID</code>, <code>SSO_REDIRECT_URI</code>, <code>SSO_ALLOWED_DOMAINS</code>, <code>GOOGLE_CLIENT_ID</code>, <code>GOOGLE_CLIENT_SECRET</code>, <code>MICROSOFT_CLIENT_ID</code>, <code>MICROSOFT_CLIENT_SECRET</code></p>

<h3>Embeddings</h3>
<p><code>FAMILIAR_EMBEDDING_URL</code>, <code>FAMILIAR_EMBEDDING_DIM</code>, <code>FAMILIAR_EMBEDDING_KEY</code>, <code>FAMILIAR_EMBEDDING_MODEL</code>, <code>VOYAGE_API_KEY</code></p>

<h3>CI/Eval</h3>
<p><code>FAMILIAR_MIN_PASS_RATE</code>, <code>FAMILIAR_MAX_CRITICAL_FAILURES</code>, <code>FAMILIAR_MAX_HIGH_FAILURES</code>, <code>FAMILIAR_MAX_LATENCY_MS</code>, <code>FAMILIAR_MAX_COST_USD</code>, <code>FAMILIAR_FAIL_ON_CRITICAL</code>, <code>FAMILIAR_BAA_CONFIRMED</code></p>

<!-- A7. DATA PATHS -->
<h2>A7. Data Paths</h2>
<table>
<tr><th>Path</th><th>Purpose</th></tr>
<tr><td><code>~/.familiar/config.yaml</code></td><td>Configuration</td></tr>
<tr><td><code>~/.familiar/.env</code></td><td>Environment variables</td></tr>
<tr><td><code>~/.familiar/data/creature.json</code></td><td>Creature state</td></tr>
<tr><td><code>~/.familiar/data/analytics.db</code></td><td>Analytics database</td></tr>
<tr><td><code>~/.familiar/data/tasks.json</code></td><td>Task list</td></tr>
<tr><td><code>~/.familiar/data/training/curated/</code></td><td>Training data</td></tr>
<tr><td><code>~/.familiar/data/google_credentials.json</code></td><td>Google OAuth</td></tr>
<tr><td><code>~/.familiar/backups/</code></td><td>Backup archives</td></tr>
<tr><td><code>~/.familiar/skills/</code></td><td>Custom user skills</td></tr>
</table>

<div style="margin-top:20px; padding:12px; background:#f0f0f5; border-radius:6px; text-align:center; font-size:9pt; color:#666;">
<strong>Totals:</strong> 17 CLI flags &bull; 26 chat commands &bull; 70+ connect wizard commands &bull; 120 API endpoints &bull; 97 config keys &bull; 115+ environment variables
</div>

</div>
"""

# ── Public API ────────────────────────────────────────────────────────


def _get_version() -> str:
    """Return the installed familiar-agent version string."""
    try:
        from importlib.metadata import version

        return version("familiar-agent")
    except Exception:
        return "dev"


def get_guide_html() -> str:
    """Return the full user guide as an HTML string."""
    return (
        "<!DOCTYPE html>\n"
        '<html lang="en">\n'
        f"<head><meta charset=\"UTF-8\"><style>{STYLES}</style></head>\n"
        f"<body>\n{MAIN_GUIDE}\n{APPENDIX}\n</body>\n</html>"
    )


def generate_guide_pdf(output_path: str | Path | None = None) -> Path:
    """Render the guide to PDF, caching by version.

    Args:
        output_path: Explicit output file. When ``None`` the PDF is
            cached at ``~/.familiar/data/familiar_guide.pdf`` and only
            regenerated when the package version changes.

    Returns:
        Path to the generated PDF file.

    Raises:
        ImportError: If WeasyPrint is not installed.
    """
    try:
        from familiar.core.paths import DATA_DIR
    except ImportError:
        DATA_DIR = Path.home() / ".familiar" / "data"

    if output_path is not None:
        dest = Path(output_path)
    else:
        DATA_DIR.mkdir(parents=True, exist_ok=True)
        dest = DATA_DIR / "familiar_guide.pdf"
        stamp_file = DATA_DIR / ".guide_version"
        current_ver = _get_version()
        if dest.exists() and stamp_file.exists():
            try:
                if stamp_file.read_text().strip() == current_ver:
                    return dest
            except OSError:
                pass

    import weasyprint  # noqa: F811 — optional dependency

    html_str = get_guide_html()
    weasyprint.HTML(string=html_str).write_pdf(str(dest))
    logger.info("Generated guide PDF at %s", dest)

    # Write version stamp for cache invalidation
    if output_path is None:
        try:
            stamp_file.write_text(_get_version())
        except OSError:
            pass

    return dest
