how it works
a technical overview of what funes does under the hood.
watching
funes monitors directories you configure using OS-level file system events — inotify on Linux, FSEvents on macOS, and ReadDirectoryChangesW on Windows. when a file changes, it's queued for reindexing automatically.
powered by the notify crate in Rust — cross-platform, zero polling, instant detection.
chunking
files are split into meaningful chunks rather than fixed token windows. code files are split by function blocks, markdown by headings and paragraphs, config files are treated as a single chunk, and shell history is split one command per chunk.
smart chunking means search results are precise — you get the relevant function, not an arbitrary 500-token window.
embedding
each chunk is sent to nomic-embed-text running locally via Ollama. the model returns a 768-dimensional vector — a list of 768 numbers that represents the semantic meaning of the chunk. similar chunks produce similar vectors.
nomic-embed-text was chosen for its quality, speed, and small size. it runs entirely on your machine.
storing
vectors and their metadata — file path, content, timestamp, chunk type — are stored in a local SQLite database at ~/.funes/funes.db. embeddings are serialized as JSON blobs. no external database, no server.
SQLite was chosen over dedicated vector databases for simplicity and zero-dependency installation.
querying
when you run funes query, your question is embedded using the same model. funes then computes cosine similarity between your query vector and every stored vector, ranks them, and returns the top 5 most semantically relevant results.
cosine similarity measures the angle between two vectors — the closer to 1.0, the more semantically similar.
synthesis (--llm mode)
with --llm, the top 5 results are passed as context to llama3 running locally via Ollama. the model synthesizes a plain English answer based only on your own content. no data leaves your machine at any point.
the prompt instructs the model to answer only from the provided context and admit when it doesn't know.