📚 Docs / Quickstart — run the desktop app

Quickstart — run the desktop app

This guide walks a new developer from a fresh clone to asking their first legal question in the desktop app. (The root README.md is the non-technical guide for end users — see the launcher at launch.bat / launch.sh.)
Prefer watching? npm run dev does everything: it starts the Python backend (auto-creating the venv), the Vite dev server, and the Electron window. The only manual step is installing Node dependencies.

1. Prerequisites

ToolWhyVersion
PythonBackend + models (Electron creates the .venv for you, but Python 3 must be on PATH)3.11+
Node.jsVite, React build, Electron18+ (npm 9+)
GitClone the repoany
GPU (optional)GPU-accelerated embedding (falls back to CPU)NVIDIA + CUDA

For LLM-powered answers you also need Ollama running locally (http://localhost:11434) with a model pulled (the launcher's default is lfm2.5:8b). If Ollama isn't running, retrieval still works; answers report the model as "unavailable".

2. Clone & install

bashgit clone https://github.com/haal-lab/Lawyer-Assistant.git
cd Lawyer-Assistant

# Install Node dependencies (three workspaces)
npm install                 # root — provides `npm run dev` (start alias)
cd frontend && npm install
cd frontend/electron && npm install
cd ..

Python is handled automatically. On first npm run dev, the Electron main process (frontend/electron/src/main/venv-manager.ts) checks for .venv; if missing it creates it with system Python and installs requirements.txt. It falls back to system Python if venv creation fails.

3. Run the app

From the repo root, one command starts the whole desktop app:

bashnpm run dev        # or: npm start

dev launches Electron only — and Electron boots everything else itself:

ProcessWho starts itPort
BackendElectron's Python bridge (frontend/electron/src/main/python-bridge.ts) — uses .venv via the venv manager, runs backend/main.py8765
FrontendElectron's Vite launcher (frontend/electron/src/main/vite-dev-server.ts)5173
Electronnpm run dev (the single process you start)— (loads the Vite URL)
Why only Electron? The Electron main process already spawns the backend and Vite itself (see frontend/electron/src/main/index.ts). A concurrently triple-start would launch duplicates that fight over ports 8765/5173. Need just the backend or frontend for browser-only dev? Use the piecemeal scripts instead: npm run dev:backend, npm run dev:frontend, or npm run dev:web (backend + frontend, no Electron window).
  1. Electron kills any stale processes on ports 8765/5173.
  2. It spawns the Python backend and polls /api/health until ready (30s timeout, 500ms interval).
  3. It starts Vite and opens the Electron window.
  4. The app's BootLoader runs its own health check; the UI appears when the backend responds {status: "ok"}.
First launch is slower: creating the venv + installing Python deps happens once. The backend also warms up models (BGE-M3 embedder, BGE-Reranker, Ollama, classifier references) in a background thread at startup, so the first query is fast after that.

4. Add documents (ingestion)

Two ways:

A. In the app (per-file, easy)

  1. Click the + (attach) button in the chat input bar — or drag & drop a file (PDF, image, TXT, etc.) onto the input area.
  2. Pick a project folder first (the "Work in a folder" button) — chat, upload and scan all require an active workspace; there is no default data/ folder anymore.
  3. Send a message. The file is uploaded to /api/upload (saved into the project folder itself), ingested into ChromaDB, and indexed for BM25.
  4. Attach files without typing and it runs a default batch-scan prompt ("Scan these documents for compliance issues: …").

Up to 5 files per message (or a whole folder — up to 50 supported docs — via the folder picker in the input bar).

B. Bulk initial ingest (CLI, one-time corpus)

With the app's venv active (or your own):

bash.venv\Scripts\activate        # Windows
# .venv/bin/activate          # macOS/Linux

# Ingest everything in data/raw/ (PDFs, images, Dataset_BA.json)
cd backend && python scripts/ingest_all.py

# Useful flags:
cd backend && python scripts/ingest_all.py --reset            # wipe ChromaDB first
cd backend && python scripts/ingest_all.py --device cpu       # force CPU
cd backend && python scripts/ingest_all.py --skip-json        # skip Dataset_BA.json
cd backend && python scripts/ingest_all.py --batch-size 32    # lower GPU memory

Pipeline: collect chunks (Docling parse + structure-aware chunking) → embed with BGE-M3save to ChromaDBbuild the BM25 index (backend/scripts/ingest_all.py does all four phases).

5. Ask your first question

Type a legal question in the input bar, e.g.:

What is rescission under the civil code?

What happens (visible live in the UI):

  1. The intent router classifies the message and writes a plan.
  2. The agent calls search_documents (dense + sparse + rerank) and verify_relevance.
  3. Retrieved chunks are cited inline; the answer streams in with chain-of-thought, tool cards, and statuses in the message.
  4. The Sources panel lists cited documents (file, page, section, score); click one to open the source viewer. The Pipeline Editor (Pipeline button in the Sources header) lights up the active node live.

6. Compliance scan (playbook)

Open the scan panel, pick a document + playbook, and run a scan. Chunks are classified by clause type and checked against the playbook rules; findings (flags) appear with severity and can be resolved / dismissed / escalated. See BACKEND.md §6.

7. Verify it works

bash# Backend health (while the app is running)
curl http://localhost:8765/api/health
# → {"status":"ok","service":"lawyer-assistant"}

# Frontend typecheck
cd frontend && npm run typecheck

8. Troubleshooting (quick)

SymptomFix
Boot screen stuck on "loading"Backend didn't start — check the Electron console; ensure Python 3 is on PATH
"Could not reach the backend server"Port 8765 blocked/stale process — restart npm run dev (it kills stale 8765/5173 listeners)
Answers say model "unavailable"Ollama isn't running or has no model — start Ollama, ollama pull lfm2.5:8b
Empty resultsCorpus not ingested — run cd backend && python scripts/ingest_all.py or attach files in the app
GPU out of memorycd backend && python scripts/ingest_all.py --batch-size 32
Stuck on something else? The full guide — TROUBLESHOOTING.md — covers 12 failure scenarios with diagnostics commands (netstat/lsof, curl health checks, Ollama checks).

9. Next steps

Questions, answered

Short, self-contained answers about this guide.

How do I install Lawyer Assistant?

Run the launcher — it creates a Python environment, installs dependencies, downloads the BGE-M3 embedding and BGE-Reranker models, sets up Ollama with a default LLM, then opens the desktop app. On Windows, double-click launch.bat; on macOS/Linux, run launch.sh.

How do I run my first legal search?

After the launcher finishes, pick a project folder, ingest your documents with 'Ingest all files', then ask a question in plain English. The app retrieves from your documents and returns a cited answer you can verify against the exact source passages.

Do I need a GPU?

No. Lawyer Assistant runs on CPU out of the box — slower for embedding but fully functional. If you have an NVIDIA GPU with enough VRAM, the GPU manager automatically uses it and shares memory between the embedding, reranking, and LLM models.