Docs

For Developers

Architecture

For the strategic principles behind these architectural choices (deep modules, anti-pass-through, generality, hard constraints), see PHILOSOPHY.md.

High-Level Information Flow

This diagram illustrates the flow of data through the application, highlighting the separation between the Renderer (UI), the IPC Bridge, and the specialized in-process services.

graph LR
  classDef frontend fill:#e3f2fd,stroke:#1565c0,stroke-width:2px,color:#0d47a1
  classDef backend fill:#f1f8e9,stroke:#33691e,stroke-width:2px,color:#33691e
  classDef core fill:#eceff1,stroke:#455a64,stroke-width:2px,color:#455a64
  classDef ai fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px,color:#4a148c

  subgraph UI_Layer["Renderer Process"]
    direction TB
    AppEntry([App Entry])
    GraphView["Knowledge Graph"]
    ReduxStore[[Redux Store]]

    AppEntry --> ReduxStore
    AppEntry --> GraphView
  end

  subgraph Main_Process["Main Process"]
    direction LR

    subgraph Services["Core Services"]
      Watcher["Smart Folder Watcher"]
      ReRanker["Re-Ranking Service"]
      Matcher["Folder Matcher"]
    end

    subgraph Intelligence["AI & Analysis"]
      Vision["Llama Vision"]
      LLM["Llama Text"]
      Embeddings["Vector Embeddings"]

      Watcher --> Vision
      Watcher --> LLM
      ReRanker --> LLM
    end

    subgraph Data["Persistence"]
      Orama[(Orama Vector DB)]
      History["Analysis History"]

      Embeddings <--> Orama
      Vision --> History
    end
  end

  ReduxStore <--> Services
  GraphView -.-> Orama
  Matcher --> Embeddings

Key Architectural Components

1. Smart Folder Watcher

The watcher is the proactive heart of the system. Unlike a standard file watcher, it:

2. Semantic Search and Re-Ranking

Search is a two-stage pipeline that spans two services:

  1. Retrieval (SearchService / OramaVectorService): Fetches top candidates using hybrid search (vector similarity + BM25 full-text).
  2. Re-Ranking (ReRankerService, optional): Receives the pre-ranked candidates and uses a lightweight LLM to score each one's relevance to the query (0-10 scale, normalized to 0-1), re-ordering them to bubble up the best matches. Off by default: Chat's Deep mode turns it on; the Search tab and the MCP search_documents tool do not.

ReRankerService itself does not perform retrieval -- it operates solely on candidates passed to it.

3. Unified Folder Matching

This service acts as the bridge between raw AI analysis and your filesystem. It:

4. Knowledge Graph Visualization

Relate graph
The Relate graph, drawn from the vector index.

The Knowledge Graph is a visual representation of your vector database.

5. Service Container

The DI container that owns the lifecycle of every backend service:

6. Startup Manager

Orchestrates the boot sequence with progress reporting to the splash screen:

7. IPC Handlers

Handler modules registered by registerAllIpc() in src/main/ipc/index.js, organized by domain:

8. AI and Analysis

LlamaService

In-process GGUF inference via node-llama-cpp. Three model types: text (Llama 3.2 3B default, or Qwen2.5-7B for better quality), vision (config/coordination only, delegates to VisionService), embedding (all-MiniLM-L6-v2 or nomic-embed 768d). GPU auto-detection (CUDA -> Vulkan -> Metal -> CPU), lazy loading via ModelMemoryManager (LRU eviction; budget is the larger of 70% of free RAM capped at 16 GB and 80% of VRAM, with the VRAM share on Apple Silicon capped at total RAM minus 4 GB).

VisionService

Out of process: a bundled llama-server child reached over local HTTP, registered with ModelMemoryManager as the vision-runtime consumer and torn down when memory is needed elsewhere. The per-image timeout is the 300s AI_ANALYSIS_LONG, hard-coded in analysis/imageAnalysis.js (AppConfig.ai.imageAnalysis.timeout) and applied twice over the same budget — once as the vision HTTP request timeout and once as the abortable wrapper around it. There is no narrower inner bound and no setting that shortens it: VISION_REQUEST (90s) is only VisionService's fallback for callers that omit timeoutMs, which this path never does, and CONFIG_SCHEMA (shared/config/configSchema.js) deliberately declares no per-image timeout key — it used to carry a dead one that nothing read. VISION_STARTUP allows 120s for the first load (300s on CPU), with health check polling.

Document Extractors

PDF (unpdf + OCR fallback), DOC (word-extractor; RTF or plain text saved as .doc is read as such), DOCX (mammoth), XLSX (xlsx-populate), PPTX and ODT/ODS/ODP (officeparser, with ZIP tag-stripping fallbacks), EPUB (OPF spine order), EML (postal-mime), MSG (@kenjiuno/msgreader, compressed-RTF bodies via @kenjiuno/decompressrtf), KML/KMZ, Jupyter notebooks, CSV, RTF (tokenizer in analysis/extractors/rtfText.js, shared with the text extraction worker), plain text. 3D and design files (analysis/extractors/cadDesignExtractors.js) are read as metadata text; tar/tgz/gz archives are listed (archiveListing.js); SVG text is read before rasterizing; HEIC/HEIF is decoded through the bundled FFmpeg when possible (heicDecode.js); Windows icons are decoded with decode-ico. OCR: Tesseract.js (bundled eng traineddata only) on unpdf-rendered pages, max 3 PDF pages / 10 office images, 150 DPI, 30 MB input cap. File-size limits (configurable in Advanced mode under Settings → Performance → Processing limits; the panel is hidden in Simple mode unless a settings search matches it): 100 MB images, 200 MB documents, 50 MB text; text files over the 50 MB limit are analyzed from their first 50 MB. The 500k-character cap on extracted text is a hard-coded constant (MAX_TEXT_LENGTH in analysis/documentExtractors.js), not a setting.

Concurrency & Resilience

Model Download (ModelDownloadManager.js)

Resume support (.partial + Range headers), SHA-256 verification, disk space checks. Auto-downloads companion files (vision projectors), model catalog in src/shared/modelRegistry.js.

Embedding Pipeline

Renderer / UI Layer

Entry & Routing

Entry: src/renderer/index.js (React 19 + createRoot, prefetches docs path / redact paths / smart folders / settings).

Phase-based routing via PhaseRenderer.jsx (no React Router): WELCOME -> SETUP -> DISCOVER -> ORGANIZE -> COMPLETE

Each phase lazy-loaded with React.lazy() + Suspense, wrapped in PhaseErrorBoundary.

Redux Store (7 slices)

Slice Responsibility
uiSlice Phase management, loading flags, settings cache, modals
filesSlice File selection, smart folders, organization history, naming
analysisSlice Analysis progress, results (max 5000), embedding state
systemSlice CPU/memory metrics, service health, notifications, paths
mcpServerSlice MCP server lifecycle/status (mcp reducer key)
aiProviderSlice Cloud AI provider config, per-feature routing, budget
licenseSlice License status shown under Settings → License (license)

Middleware: ipcMiddleware (event queue + Zod validation), persistenceMiddleware (1s debounce, quota-aware degradation).

Knowledge Graph (GraphTabContent.jsx + search/hooks/useGraphTab.js, about 7,400 lines together)

React Flow with ELK layout, max 300 nodes.

Graph UX Notes

Component Groups

Directory Contents
discover/ Drag-drop zone, analysis progress
organize/ Suggestions, virtualized grids
search/ Graph, chat panel, autocomplete
settings/ Model selection, embedding rebuild
setup/ Smart folder management (add/edit modals)
ui/ Design system (Button, Card, Modal, etc.)
icons/ Icon components
layout/ AppShell, ActionBar

Root-level components include PhaseRenderer, NavigationBar, SettingsPanel, ModelSetupWizard, Toast system, and error boundaries.

IPC Bridge (src/preload/preload.js)

Rate-limited (200 req/s), sanitized, channel-whitelisted. Default invoke timeout is 330s (IPC_INVOKE_TIMEOUT), with per-channel overrides via src/shared/ipcInvokeTimeout.js (e.g. downloads triage scans allow up to 900s). Retries use exponential backoff.

Data Flow & Caching

Analysis Caching

To respect local resources, we use a multi-tiered caching strategy:

In-Flight Deduplication

We maintain separate queues to manage different types of bottlenecks:

Service Depth Review (2026-05-16)

A review of shallow-looking services examined three candidates for merging or collapsing (LOC figures below are approximate as of 2026-10 and drift with the code):

No code changes came out of the review. The outcome is recorded here for future contributors.

Code Standards

For information on coding patterns, error handling, and dependency injection, refer to the other documentation files:

Edit this page on GitHub