LocalLens

Responsibilities

What each file owns and what it should not contain.

FileOwnsShould not own
domain.tsTypes and errors.SDK calls or IO.
files.tsFile discovery and adaptation.RAG search or completion.
rag.tsChunking and prompt.Model lifecycle.
qvac.tsQVAC SDK integration.UI or folder walking.
store.tsLocal JSON persistence.Model calls.
locallens.tsProduct workflow.HTTP details or DOM code.
cli.tsTerminal interface.RAG internals.
server.tsHTTP interface.Business logic.
ui/Browser interaction.QVAC calls.

Two columns matter here. The "owns" column is what you modify when you're working on a feature in that area. The "should not own" column is what to keep out. When a change pulls in something from the right column, that's a sign the change wants a different home.

Why each rule

domain.ts should not own SDK calls or IO

Domain types are imported by every other file. If they reach for QVAC or the filesystem, the dependency direction inverts and the whole graph becomes circular. Keep this file pure.

files.ts should not own RAG search or completion

The file adapter only produces LocalDocument[]. Chunking and embedding happen later, in rag.ts and qvac.ts. If you ever feel the pull to embed during file discovery — say, to deduplicate — resist it. Add a separate step.

rag.ts should not own model lifecycle

rag.ts calls ragChunk, but it doesn't load models. The QVAC gateway manages that. Change models and qvac.ts changes once. rag.ts keeps working.

qvac.ts should not own UI or folder walking

The gateway is your single source of truth for "what does QVAC do?". It doesn't read folders, render messages, or know about HTTP. That's why the five-call surface fits in your head.

store.ts should not own model calls

The JSON store is for what brains exist and what chunks they have. It never embeds, searches, or completes. When a brain is deleted, store.ts removes the entry. The workflow class handles the QVAC side.

locallens.ts should not own HTTP or DOM code

LocalLensApp is the workflow class. The CLI calls it, the server calls it, and the UI calls it transitively. None of them should leak their concerns into this class. If request.headers ever shows up here, something is wrong.

cli.ts should not own RAG internals

The CLI is one of two thin entry points over LocalLensApp. It knows about argv and console.log. It doesn't know about chunk sizes, embeddings, or prompts. A flag that would change RAG behaviour belongs in the workflow layer, not the CLI handler.

server.ts should not own business logic

Same shape as the CLI: thin. The server is route-matching, JSON parsing, and error mapping. The moment you find yourself writing branchy logic in a route handler, it belongs in LocalLensApp instead.

ui/ should not own QVAC calls

The browser can't talk to QVAC directly anyway, but the rule still matters: the UI talks only to the server's JSON API. It doesn't duplicate chunk size constants, model names, or workspace IDs.

Two entry points, one core

Notice that the CLI and the server are both thin. They sit on the same core (LocalLensApp) and provide different surfaces. That's why adding a feature to the workflow layer benefits both — the CLI gets it the moment the server's route does.

On this page