# 05 — Mission Control Dashboard > Next.js 16 dashboard for managing local LLM models, system resources, and inference. > Last updated: 2026-02-21 ## Quick Start ```bash cd __LOCAL_LLMs/dashboard npm install # first time only npm run dev # runs on port 3000 ``` Open: **http://localhost:3000** --- ## Recent Changes (Feb 2026) ### Memory Calculation Fix **Root cause:** The system API (`/api/system`) computed `trueFree = free + cached` and returned it as `free`. This made `free` and `cached` overlap. The UI then did `available = free + cached * 0.5`, which **double-counted** cached memory and inflated available RAM by ~8 GB. **Fix (4 files):** - `src/app/api/system/route.ts` — Return raw `Pages free` separately from `cached` (no overlap) - `src/app/lib/format.ts` — Updated `checkMemoryFit()` to use `cached × 0.9` (macOS reclaims ~90% on demand) - `src/app/(mission-control)/mission-control/page.tsx` — All UI memory references fixed - `src/app/(mission-control)/mission-control/components/RamBudgetBar.tsx` — Receives corrected `free + cached` **Memory formula:** `available for models = rawFree + cached × 0.9` ### Memory Drilldown Click the **MEMORY** card in the status bar to toggle a drilldown panel showing: 1. **Stacked bar** — vm_stat categories (Active, Wired, Compressed, Inactive, Purgeable, Free) 2. **Legend grid** — exact bytes + percentage for each category 3. **App memory summary** — Active + Wired + Compressed = total used 4. **Top 15 processes by RSS** — grouped by name, Ollama highlighted in green **New files:** - `src/app/api/system/memory/route.ts` — Process memory API (`ps` + `vm_stat`) - `src/app/(mission-control)/mission-control/components/MemoryDrilldown.tsx` — Drilldown UI ### Simplified Memory UI All memory displays now use consistent, plain language: | Element | Before (confusing) | After (clear) | | -------------------- | ---------------------------------- | ------------------------------------------- | | **MEMORY card** | "10.5 GB / 48 GB" (ambiguous) | **"35.6 GB used / 48 GB"** | | **Subtitle** | "App: 35.6 GB · Cache: 11.6 GB" | **"10.5 GB available for models"** (green) | | **Model fit** | "76 MB free + 10.5 GB reclaimable" | **"Needs ~22 GB · 10.5 GB available"** | | **Fit badge** | "✗ Won't fit" | **"✗ 11.6 GB short"** (with exact gap) | | **System panel RAM** | "76 MB avail" | **"10.5 GB avail"** (green, matches header) | --- ## Detailed Documentation - **PRD:** [`dashboard/docs/DASHBOARD_PRD.md`](../dashboard/docs/DASHBOARD_PRD.md) - **Review (39 items):** [`dashboard/docs/DASHBOARD_REVIEW.md`](../dashboard/docs/DASHBOARD_REVIEW.md) - **Roadmap (N1–N15):** [`dashboard/docs/DASHBOARD_ROADMAP.md`](../dashboard/docs/DASHBOARD_ROADMAP.md) - **Rich Features Roadmap (A–G):** [`dashboard/docs/RICH_FEATURES_ROADMAP.md`](../dashboard/docs/RICH_FEATURES_ROADMAP.md) --- ## API Routes | Route | Method | Description | | -------------------- | -------- | ---------------------------------------------------- | | `/api/ollama` | GET/POST | Ollama proxy (list, load, unload, generate) | | `/api/whisper` | GET | Whisper binary/model discovery | | `/api/system` | GET | System info (chip, RAM, disk, brew, pressure) | | `/api/system/memory` | GET | Memory drilldown (vm_stat breakdown + top processes) | | `/api/system/exec` | POST | Safe shell command execution | --- ## Key Components ``` dashboard/src/app/ ├── (mission-control)/mission-control/ │ ├── page.tsx # Main Mission Control page │ └── components/ │ ├── RamBudgetBar.tsx # Stacked RAM budget visualization │ ├── MemoryDrilldown.tsx # Process-level memory breakdown │ └── MarkdownResponse.tsx # Markdown renderer for LLM output ├── (workspace)/components/ # Chat workspace (conversations, messages) ├── api/ │ ├── ollama/route.ts │ ├── whisper/route.ts │ ├── system/route.ts │ └── system/memory/route.ts └── lib/ ├── format.ts # formatBytes, estimateRam, checkMemoryFit ├── db.ts # IndexedDB CRUD (conversations, projects, tasks) ├── cron.ts # Cron expression parser └── scheduled-tasks.ts # Built-in task templates ```