Monorepo for indexing an Obsidian vault and searching across text, images, and PDFs using Gemini embeddings + local SQLite vector search.
- Monorepo (Bun workspaces + Turborepo)
-
@obsearch/coreGemini embedding + SQLite/sqlite-vec schema - Vault crawler (
.md, images,.pdf) - TaskType embedding API (
RETRIEVAL_DOCUMENT/RETRIEVAL_QUERY) - Image indexing pipeline (
indexImage) - Markdown indexing pipeline (
indexMarkdown) - Retry + exponential backoff (
retryWithBackoff) - Incremental indexing by
mtime+size(indexVaultFile) - CLI
index <vault-path>(apps/cli) - oRPC
search(query, limit)endpoint - Web UI with thumbnails + Obsidian deep links
- Semantic chunking for long markdown
- PDF text extraction + chunking pipeline
- Snippet highlight in search results
crawlVault({ vaultPath })createEmbeddingClient({ expectedDimension: 3072 })initDb({ dbPath, embeddingDimension })indexImage(...)indexMarkdown(...)indexVaultFile(...)(incremental:indexed/skippedwith reason)retryWithBackoff(...)search(query, limit)onCoreDb
bun run apps/cli/src/index.ts index /absolute/path/to/vaultor from the CLI package:
bun run --cwd apps/cli index -- /absolute/path/to/vault- Crawls supported files from vault
- Initializes DB at
<vault>/.obsearch/index.db - Indexes per file with progress output
[i/total] - Uses incremental skip logic (
mtime+size) - Prints summary:
indexed,skipped,errors, duration - Prints heuristic API cost estimate
Cost estimate formula:
embedding_call_count * OBSEARCH_ESTIMATED_USD_PER_EMBED_CALL
If OBSEARCH_ESTIMATED_USD_PER_EMBED_CALL is unset, default is 0.
- API route implemented:
search({ query, limit? })in@obsearch/api. - Server now wires a real
coreDb.search(...)dependency into API context. - Web home route includes:
- Search form (
query, optionallimit) - Result cards with type + score
- Real image thumbnails via server route
/vault-file/<relative-path> - Obsidian deep links per result
- Search form (
CORS_ORIGIN=http://localhost:3001
GEMINI_API_KEY=your_key_here
GEMINI_EMBEDDING_MODEL=gemini-embedding-2-preview
OBSEARCH_DB_PATH=/absolute/path/to/vault/.obsearch/index.db
OBSEARCH_VAULT_PATH=/absolute/path/to/vault
OBSEARCH_THUMBNAIL_TOKEN=change_me
VITE_OBSIDIAN_VAULT_NAME=YourVaultName
VITE_OBSEARCH_THUMBNAIL_TOKEN=change_me
OBSEARCH_ESTIMATED_USD_PER_EMBED_CALL=0.00010bun install
bun run devUseful checks:
bun run --cwd packages/core testbun run --cwd packages/core check-typesbun test apps/cli/src/index.test.tsbun run --cwd apps/cli check-types