The four layers
window.fsapi, window.watcher,
window.tags, window.recents, window.views, window.prefs, window.llm,
window.chats, window.graph, and so on — each defined in src/preload/index.ts
and typed in src/preload/index.d.ts.
Security model
| Setting | Value |
|---|---|
contextIsolation | true |
sandbox | true |
nodeIntegration | false |
Main process modules
| Module | Responsibility |
|---|---|
index.ts | App lifecycle, BrowserWindow, window-bounds persistence |
fs/service.ts | Pure fs logic: list, info, create/rename/copy/move/duplicate, folder size, recursive tokenized search |
fs/handlers.ts | Registers every ipcMain.handle; wraps errors into Result |
fs/watch.ts | Single non-recursive fs.watch on the focused dir, debounced |
fs/thumbnails.ts | nativeImage thumbnails as data URLs, cached in memory |
db/ | SQLite metadata + AI index (see Data Layer) |
prefs.ts | Preferences in the SQLite prefs table (JSON values) |
ai/ | Embeddings, indexer, search, knowledge graph, and the LLM (see AI Pipeline) |
Renderer state
State is React context, no Redux:state/navigation.tsx— current path, back/forward/up history, sort, view mode, column widths, search query, refresh token (useReducer).state/clipboard.tsx/state/undo.tsx/state/toast.tsx— copy/cut, the undo stack, and notifications.hooks/useFileActions.ts— all mutations funnel through here; each runs the IPC call, toasts, refreshes, and pushes an inverse onto the undo stack.hooks/useTags.ts— all tag mutations funnel through here so the sidebar, dots, menus, and info panel stay in sync.
Repository layout
Next
The IPC Contract
The Result-typed spine that connects renderer to disk.
Data Layer
SQLite via
node:sqlite + Drizzle, with zero native deps.