{"slug": "draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai", "title": "Draku: Exorcising the Ghosts in Your Camera Roll with Offline Open-Weight AI 🦇", "summary": "A developer built Draku, an open-source, fully offline desktop file manager for Windows that uses local PaddleOCR and Google's open-weight EmbeddingGemma-300M to read screenshots, photos and PDFs once and turn them into semantic search, calendar reminders, redacted safe copies and reversible cleanup suggestions. The Tauri app runs with Wi-Fi off and Airplane Mode enabled, uploading zero bytes and requiring no accounts, with OCR bounding boxes driving pixel-burned blur and EXIF stripping for sensitive documents.", "body_md": "*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine](https://dev.to/challenges/hacktoberfest-week4-2026-10-26)*\n\nYou are standing at the pharmacy counter. The pharmacist asks for your prescription. You know it is on your phone—somewhere between 4,000 WhatsApp forwards, food photos, and old boarding passes. You scroll past `IMG-20261011-WA0004.jpg`, `Screenshot_2026-09-14.png`, and `scan_final_v2.pdf`. \n\nScreenshots are the most-used notebook on earth that nobody calls a notebook. The problem is that a screenshot stores **pixels**, not **meaning**. And inside those pixels live four kinds of digital ghosts haunting every laptop and phone:\n\nMeet **Draku**—a fluffy black cat with crimson bat wings and eyes full of black flames. He sees everything on your device, and he tells no one.\n\n**Draku** is a 100% offline, open-source desktop application (built with Tauri) that reads every screenshot, photo, and PDF in a folder **once** using local **PaddleOCR** and Google's open-weight **EmbeddingGemma**, turning that single reading into four concrete outcomes:\n\n`IMG-20261011-WA0004.jpg` into `2026-10-11 Dr Patel blood test prescription.jpg` and embeds the semantic context so you can type `\"blood test\"` or `\"router password\"` in plain English and find it instantly.\nZero bytes uploaded. Zero accounts. Zero settings screens.\n\n| Outcome | Before | After | What produces it | \n|---|---|---|---|\n| **Find** | `IMG-20261011-WA0004.jpg` | `2026-10-11 Dr Patel blood test prescription.jpg` , findable by typing \"blood test\" | local OCR → rule-based reader → **EmbeddingGemma-300M** → semantic search | \n| **Remember** | A warranty screenshot quietly expiring | A real `.ics` calendar reminder, one tap | date extraction with surrounding words → confirm → local `.ics` | \n| **Protect** | A photo exposing an ID number and GPS | A safe copy with the blur burned into pixels and location metadata stripped | local OCR bounding boxes + EXIF → confirm → clean copy | \n| **Let go** | OTPs, dead tickets, duplicates | Rested in a folder you can restore from | transparent signals → an explainable dead score → \"Set aside\" | \n\nEvery capture below is recorded directly from the real desktop application on Windows with **Wi-Fi off and Airplane Mode visibly enabled**—no cloud calls, no mockups, no staged telemetry. The full airplane-mode walkthrough script lives in the repo as [`DEMO.md`](https://github.com/0dvsh0/draku/blob/main/DEMO.md).\n\nLocal PaddleOCR extracts the text, a structured rule-reader extracts human naming cues, and Google's **EmbeddingGemma-300M** embeds the reading into a 768-dimensional local vector. Type *\"internet password\"* and the router login surface appears immediately—pure meaning match with zero keyword overlap.\n\nDates are extracted alongside their surrounding contextual words, allowing Draku to recognize that *\"Warranty ends in 6 days\"* or *\"Refill by 10 Nov\"* is an actionable deadline rather than an old receipt date. One click generates an RFC-compliant `.ics` calendar file accepted by your system calendar—no cloud sync intermediary.\n\nPaddleOCR returns exact pixel bounding boxes for sensitive ID numbers, card digits, and credentials. Clicking \"Make a safe copy\" burns irreversible pixelation blur directly into new pixel buffers and strips hidden EXIF location metadata. The original document remains untouched.\n\n*Before and after, side by side — the sensitive ID number and GPS coordinates visible in the first frame are permanently eradicated in the safe copy:*\n\nExpired boarding passes, old OTP screenshots, and blurry duplicates earn transparent, inspectable \"dead file\" scores with human-readable explanations. Clicking \"Set aside\" lays them to rest in `.draku/rest/`—never deleted, completely reversible with one-tap Undo.\n\n**Your files, finally understood.**\n\nDraku is a free, open-source, on-device AI file manager for Windows. It reads\nevery screenshot, photo and PDF **on your machine** — it finds what you need\nwarns you before a date passes, hides what should stay private, and lets go of\nwhat is dead. Nothing leaves your machine.\n\nBuilt for **Hacktoberfest 2026 · Week 4 — Ghost in the Machine**.\n\n```\ndraku/\n├── CONTEXT.md     ← project context: plan, stack, tokens, status (read first)\n├── site/          ← the landing page (static HTML/CSS/JS + WebGL embers)\n├── app/           ← the product: Tauri 2 desktop app (Rust + React/TypeScript)\n│   ├── src/           One Screen UI, mascot design tokens (tokens.css)\n│   ├── scripts/       bundle prep + one-time model fetch for source builds\n│   └── src-tauri/     scanner · reader · OCR · embeddings · actions\n└── site/About.md\n```\n\n…\nTo build and run Draku from source (fetches the local models once, then runs completely offline forever):\n\n```\ngit clone https://github.com/0dvsh0/draku && cd draku/app\nnpm install && node scripts/fetch-model.mjs\nnpm run tauri dev\ndraku/\n├── site/               ← Interactive web sandbox & landing page (vanilla HTML/CSS/JS, WebGL embers)\n└── app/\n    ├── src/            ← The One Screen UI (React 19 + TypeScript, mascot design tokens)\n    ├── scripts/        ← Model fetchers, NSIS installer packager, automated CI smoke test\n    └── src-tauri/      ← Native Rust core touching every byte\n        ├── scan.rs     ← Folder walker + dHash perceptual duplicate detection\n        ├── extract/    ← The READER: PaddleOCR, PDF text parser, kamadak-exif, rule reader\n        ├── embed.rs    ← Bundled EmbeddingGemma-300M loader + local cosine similarity search\n        ├── score.rs    ← Transparent \"Let Go\" arithmetic engine — weights you can read\n        ├── store.rs    ← SQLite (WAL mode) — single local embedded DB, zero daemons\n        └── actions.rs  ← Safe copies, .ics generation, set-aside / restore (the ONLY disk mutations)\n```\n\nEmbeddingGemma's 4-bit quantized weights ship inside the installer as `model_q4.onnx` alongside an external initializer file. Draku's native Rust core loads both in memory directly into ONNX Runtime with DirectML hardware acceleration—without requiring CUDA or external services:\n\n``` js\n// app/src-tauri/src/embed.rs — the offline path is the only shipped path\nlet mut bundled = UserDefinedEmbeddingModel::new(read(\"model_q4.onnx\")?, TokenizerFiles {\n    tokenizer_file:          read(\"tokenizer.json\")?,\n    config_file:             read(\"config.json\")?,\n    special_tokens_map_file: read(\"special_tokens_map.json\")?,\n    tokenizer_config_file:   read(\"tokenizer_config.json\")?,\n})\n.with_pooling(Pooling::Mean)\n.with_quantization(QuantizationMode::None)\n.with_external_initializer(\"model_q4.onnx_data\".into(), read(\"model_q4.onnx_data\")?);\n\nTextEmbedding::try_new_from_user_defined(bundled, InitOptionsUserDefined::new())\n```\n\nWhen you search *\"internet password\"*, your query is converted to a 768-dimensional vector, and cosine similarity matches against local readings in SQLite. There is no HTTP client anywhere in the crate.\n\nRather than relying on an unexplainable black-box classifier, `score.rs` exposes a plain struct of inspectable signals. Every weight is an auditable constant with a clear rationale:\n\n``` php\n// app/src-tauri/src/score.rs\npub fn judge(s: &Signals) -> Verdict {\n    let mut score = 0.10;\n    score += (s.age_days / 180.0).min(0.30);\n    if s.is_otp      { score += 0.44; }   // one-time codes only live once\n    if s.date_passed { score += 0.50; }   // the deadline is gone; the file overstayed\n    if s.is_dup      { score += 0.50; }   // a near-identical file exists\n    // …the result clamps to [0, 1]; above 0.60 a file earns the Let-go card\n    Verdict { dead: score.clamp(0.0, 1.0), reason: choose_reason(&s) }\n}\n```\n\n`--no-default-features`) for machines that cannot run PaddleOCR.` scripts/smoke-test-installer.mjs`, wired into GitHub Actions, silent-installs the NSIS package on a clean Windows runner and verifies every bundled binary: `draku.exe`, `DirectML.dll`, all 4 OCR models, and all 6 embedding files.` SHA256: 19473E9A5AEC88BDE82DF50CD697E7A9450A0B0EA88B49E65B57F89843E52791`\nMost AI tools bolt four separate pipelines onto four separate problems: one tool for semantic search, another for reminders, another for PII redaction, and a fourth for storage cleanup. That wastes compute and clutters the UI.\n\nDraku is built around a single architectural rule: **One reading. Four outcomes.**\n\n```\n[ Screenshot / Photo / PDF ]\n             │\n             ▼\n   ┌───────────────────┐\n   │  Local PaddleOCR  │ ──► Extracts text + exact pixel bounding boxes + EXIF\n   └─────────┬─────────┘\n             │\n             ▼\n   ┌───────────────────┐\n   │ Structured Reader │ ──► Parses dates, PII patterns, category & dead-score\n   └─────────┬─────────┘\n             │\n             ▼\n   ┌───────────────────┐\n   │  EmbeddingGemma   │ ──► Generates local semantic vector embeddings\n   └─────────┬─────────┘\n             │\n             ▼\n      [ reading.json ]\n             │\n   ┌─────────┴──────────┬────────────────────┬───────────────────┐\n   ▼                    ▼                    ▼                   ▼\n[ FIND ]           [ REMEMBER ]         [ PROTECT ]         [ LET GO ]\nSemantic search    Contextual .ics      Pixel-burned PII    Transparent\n& smart rename     deadline alerts      & EXIF stripping    rest scoring\n```\n\nWhen Draku scans a file like `IMG-20261011-WA0004.jpg`, it produces a single structured internal artifact (` reading.json`):\n\n```\n{\n  \"name\":     \"2026-10-11 Dr Patel blood test prescription\",\n  \"category\": \"medical / prescription\",\n  \"dates\":    [{ \"refill_by\": \"2026-11-10\" }],\n  \"private\":  [\"patient_id\", \"gps\"],\n  \"dead\":     0.04,\n  \"network\":  null\n}\n```\n\n| Layer | Choice | Why It Earns Its Place | \n|---|---|---|\n| **Shell & Core** | **Tauri 2 · Rust** | Native filesystem speed, minimal memory footprint, and zero open sockets. Bundles everything into a clean 182 MiB installer instead of a bloated Electron container. | \n| **Semantic Memory** | **Google EmbeddingGemma-300M (4-bit ONNX)** | Generates 768-dimensional embeddings entirely on-device from open weights, making true offline semantic search possible from the first run. | \n| **Local Runtime** | **fastembed + ONNX Runtime + DirectML** | Hardware acceleration across modern Windows GPUs/NPUs with zero CUDA configuration. Loads external weight initializers directly in memory. | \n| **Vision & Text** | **PaddleOCR PP-OCR (Apache-2.0)** | Detection + classification + recognition returning exact bounding boxes that directly feed Protect's pixel-burned redaction. | \n| **Duplicate & Metadata** | **dHash + kamadak-exif** | 64-bit visual perceptual hashing detects rescaled copies; parses EXIF metadata to reveal hidden GPS coordinates and camera serials. | \n| **Frontend** | **React 19 + TypeScript + Vite** | Type-safe IPC boundaries, crisp UI with mascot tokens, and `@fontsource` vendored typography (zero CDN calls). | \n| **Persistence** | **SQLite (WAL) via rusqlite** | Single embedded database in the local app directory storing readings, vectors, and approved action history. | \n\n`\"pharmacy receipt\"` or `\"cholesterol check\"`, EmbeddingGemma matches the meaning even if those exact words aren't in the filename.`OTP`, `ticket`, `receipt`), whether the extracted date has passed, perceptual duplicate distance, blurriness, and byte size. You can read the exact reason Draku suggests letting a file rest.`network` is always `null`.\nWindows is the primary platform where DirectML and WebView2 ensure a guaranteed, zero-friction experience out of the box. For hardware without OCR capabilities, Draku provides a lightweight build (`--no-default-features`): semantic search, dates, duplicate detection, and rest actions function without OCR, while Protect reports what can be discerned from names and metadata.\n\nIf a tool asks to read your entire camera roll and `Downloads` folder, **it is asking to read your life**: your prescriptions, tax returns, national ID cards, bank statements, and private family photos.\n\nYou cannot build a trustworthy version of Draku on a closed, cloud-hosted API. Here is why open-weight models and open-source code are the only way this product can exist:\n\n`fetch-model.mjs`), your personal file guardian will work identically ten years from now on an air-gapped laptop.\nWhen I saw the **Ghost in the Machine** theme coinciding with Halloween and *Día de los Muertos*, I didn't want to build another spooky terminal chatbot pretending to be a poltergeist. I started thinking about the real ghosts that live inside our machines every single day.\n\nOur devices are full of unfinished business: the prescription we forgot to refill, the warranty we missed by three days, the old ticket stub from a trip we took a year ago, and the dead OTP screenshots cluttering the drawer. In the spirit of *Día de los Muertos*, some things in our digital lives deserve to be **remembered and honoured on time**, our private secrets deserve to be **protected**, and the things whose time has passed deserve to be **laid peacefully to rest**.\n\nThat is why Draku is a tiny guardian familiar—eyes of black flame to read the dark pixels, bat wings to shield your secrets, and a quiet nudge to help you let go of what is dead.\n\n`ci.yml`): linting and type-checking (React 19 + TypeScript + Vitest), dual cargo test suites (light and full OCR) with model caching, and a Windows runner job that builds the NSIS installer, *Built with 🦇 for Hacktoberfest 2026 — [Draku on GitHub](https://github.com/0dvsh0/draku) · [Landing page](https://0dvsh0.github.io/draku/) · [Download the installer](https://github.com/0dvsh0/draku/releases/latest/download/Draku_0.1.0_x64-setup.exe)*", "url": "https://wpnews.pro/news/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai", "canonical_source": "https://dev.to/devanshdubey/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai-3826", "published_at": "2026-10-31 14:49:54+00:00", "updated_at": "2026-10-31 14:52:11.894028+00:00", "lang": "en", "topics": ["artificial-intelligence", "ai-tools", "ai-products", "natural-language-processing", "generative-ai"], "entities": ["Draku", "Tauri", "PaddleOCR", "EmbeddingGemma", "Google", "Windows", "GitHub"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai", "markdown": "https://wpnews.pro/news/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai.md", "text": "https://wpnews.pro/news/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai.txt", "jsonld": "https://wpnews.pro/news/draku-exorcising-the-ghosts-in-your-camera-roll-with-offline-open-weight-ai.jsonld"}}