[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-84187":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":22,"hasPages":22,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":10,"trendingCount":16,"starSnapshotCount":16,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},84187,"omni-macos","hanxiao\u002Fomni-macos","hanxiao","Native macOS semantic search over your local files - text, images, audio, video in one vector space, on-device on Apple silicon.","https:\u002F\u002Fhanxiao.io\u002Fomni",null,"Swift",140,11,1,4,0,23,34,80,3.24,"Apache License 2.0",false,"main",[],"2026-06-12 02:04:38","\u003Cp align=\"center\">\n  \u003Cimg src=\"site\u002Fomni\u002Fassets\u002Fomni-mascot.png\" alt=\"Omni\" width=\"180\">\n\u003C\u002Fp>\n\n\u003Ch1 align=\"center\">Omni\u003C\u002Fh1>\n\n\u003Cp align=\"center\">Semantic search over your local files, running entirely on-device.\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fhanxiao.io\u002Fomni\">\u003Cb>Download for macOS &rarr;\u003C\u002Fb>\u003C\u002Fa>\n\u003C\u002Fp>\n\nOmni indexes your files and lets you search them by meaning instead of filename. A\ntext query finds matching documents, code, PDFs, images, audio, and video together,\nbecause everything is embedded into one shared vector space. The model runs in-process\non Apple GPUs via a native MLX-Swift port of `jina-embeddings-v5-omni`, in two sizes -\n[Nano](https:\u002F\u002Fhuggingface.co\u002Fjinaai\u002Fjina-embeddings-v5-omni-nano-mlx) (~1.9 GB) and\n[Small](https:\u002F\u002Fhuggingface.co\u002Fjinaai\u002Fjina-embeddings-v5-omni-small-mlx) (~3.1 GB). No\nPython, no server, no cloud: the model downloads once, then indexing and search run with\nno network at all. Airgap the Mac and Omni keeps working.\n\n## Install\n\nDownload the latest DMG from [**hanxiao.io\u002Fomni**](https:\u002F\u002Fhanxiao.io\u002Fomni) (or from\n[GitHub Releases](https:\u002F\u002Fgithub.com\u002Fhanxiao\u002Fomni-macos\u002Freleases)), open it, and drag\n**Omni** onto **Applications**. Builds are notarized, so they open without a Gatekeeper prompt.\n\nOn first launch Omni downloads the model once (Nano ~1.9 GB or Small ~3.1 GB). That is the\nonly time it touches the network: after that, both indexing and search run on-device with\nnothing leaving your Mac, so you can pull the plug and run it fully airgapped. Point it at\nfolders to index (Documents, Downloads, Desktop, or any folder you pick), press Index, then search.\n\nRequires an Apple silicon Mac on macOS 14 or later.\n\n## Build from source\n\n```\nbrew install xcodegen\nexport OMNI_TEAM_ID=XXXXXXXXXX   # your 10-char Apple Team ID (see below)\nxcodegen generate\nopen Omni.xcodeproj              # then Cmd+R\n```\n\nYou need:\n\n- **Apple silicon Mac, macOS 14+.**\n- **Xcode 26 with the Metal Toolchain** (`xcodebuild -downloadComponent MetalToolchain`).\n  MLX-Swift compiles Metal shaders; a plain SwiftPM command-line build cannot, so build\n  through Xcode or `xcodebuild`.\n- **The model directory** (`model.safetensors`, `tokenizer.json`, `config.json`,\n  `adapters\u002Fretrieval\u002F`) from\n  [`jinaai\u002Fjina-embeddings-v5-omni-small-mlx`](https:\u002F\u002Fhuggingface.co\u002Fjinaai\u002Fjina-embeddings-v5-omni-small-mlx)\n  (or the `-nano-` variant). The app finds it via `$OMNI_MODEL_DIR`,\n  `~\u002FLibrary\u002FApplication Support\u002FOmni\u002F`, or the HuggingFace cache, and otherwise asks\n  you to pick the folder.\n\n### Why an Apple Developer account is needed\n\nOmni reads files in your Documents, Downloads, and Desktop, which macOS gates behind\nTCC permission. The app is code-signed (not ad-hoc) so the system ties that permission\nto a stable signature and remembers your grant across rebuilds instead of re-prompting\nevery time. Signing requires a Team ID, which is why `OMNI_TEAM_ID` is set above.\n\n- **Build and run locally:** a **free** Apple ID is enough. Add it in Xcode (Settings -\n  Accounts), use the personal team it creates, and put that team's ID in `OMNI_TEAM_ID`.\n- **Distribute a notarized DMG** like the Releases here: this needs the **paid Apple\n  Developer Program** ($99\u002Fyr) for a *Developer ID Application* certificate and Apple's\n  notary service. The release pipeline (`.github\u002Fworkflows\u002Frelease.yml`) uses it; you\n  don't need it just to run Omni yourself.\n\nThe repository contains no Apple credentials. The Team ID comes from `OMNI_TEAM_ID`\nlocally and from the `APPLE_TEAM_ID` GitHub secret in CI; the signing certificate,\nnotary password, and deploy tokens are all GitHub Actions secrets.\n\n## Verify the engine\n\nThe MLX-Swift encoder is checked numerically against Python reference fixtures: text\nmust match to cosine >= 0.999 with identical token ids; image, video, and audio towers\nmatch the upstream `model.py` to cosine ~1.0 on identical preprocessed inputs.\n\n```\nuv run python Tools\u002Fgen_fixtures.py          # regenerate fixtures (needs mlx + tokenizers)\ncp -R \u003Cmodel snapshot> \u002Fprivate\u002Ftmp\u002Fomni-model\nmake test                                    # compiles shaders, asserts the cosines\n```\n\n## Architecture\n\n```\nSources\u002FOmniKit\u002F   engine + indexer (SPM library)\nApp\u002F               SwiftUI macOS app (project.yml -> Omni.xcodeproj via XcodeGen)\nTools\u002F             reference fixture generator\nTests\u002F             numeric parity + end-to-end search tests\n```\n\n### Embedding\n\n`jina-embeddings-v5-omni` ported to MLX-Swift: a Qwen3 text tower, a Qwen3-VL vision\ntower (also used for video frames and scanned-PDF pages), and a Whisper-style audio\ntower. `WeightStore` loads the HF safetensors, merges the retrieval LoRA into the\nbackbone (upcast to fp32, merge, cast back to bf16), and the encoders pool the last\ntoken and L2-normalize. All modalities land in one shared space, with media wrapped in\na `Document:` prefix and an end-of-text suffix so cross-modal vectors align. MLX calls\nare serialized through a priority gate: an interactive query jumps ahead of in-flight\nindexing work, so search stays responsive while indexing runs.\n\n### Indexing\n\nA crawl -> extract -> chunk -> embed -> store pipeline, incremental via file mtime and\nsize so re-indexing only touches what changed. A concurrent decode stage (text\nextraction, image patchify, audio mel) feeds a single serialized GPU embed stage.\nThroughput comes from batching the GPU forward: text is chunked (~1800 chars, 200\noverlap) and embedded in cross-file batches; images run one block-diagonal vision\nforward per batch; audio batches clips under a frame budget; video samples a few frames\ninto one temporal embedding. Batches double-buffer - the next batch's GPU forward\noverlaps the previous batch's host readout.\n\n### Storing\n\nEmbeddings are stored as **bf16** (2 bytes per dimension): half the size of fp32 on\ndisk and in memory, with negligible recall loss on L2-normalized vectors. SQLite holds\nfile metadata and the persisted vectors; the live search index is a single contiguous\nbf16 matrix kept in sync on every insert, update, and delete.\n\n### Search\n\nExact brute-force cosine: one MLX matmul of the query against the resident bf16 matrix\non the GPU - no approximate index, no recall tradeoff. The matrix is split into a\nGPU-resident **base** prefix plus a small **delta** of rows added since the base was\nbuilt, scored by a second matmul fused into one evaluation, so an indexing insert never\nforces the whole matrix to be recopied per query. The base is rebuilt only on a\nstructural change (delete or reload) or once the delta grows past a threshold. Top-K\ncomes from a bounded min-heap over per-file winners rather than a full sort, and the\nresult is filtered by kind, folder, extension, and recency. Idle search is a few\nmilliseconds.\n\n## License\n\n[Apache 2.0](LICENSE). The model weights are covered by the upstream Jina license\n(CC-BY-NC-4.0), not this repository.\n",2,"2026-06-11 04:12:29","CREATED_QUERY"]