* feat(imessage): add chat.db scanner that ingests into memory_doc_ingest
Adds a macOS-only Tauri-side scanner at
`app/src-tauri/src/imessage_scanner/` that reads
`~/Library/Messages/chat.db` read-only on a 60s tick, groups messages
by `(chat_identifier, day)`, and posts one
`openhuman.memory_doc_ingest` JSON-RPC call per group — matching the
convention documented in `docs/webview-integration-playbook.md` and
used by the WhatsApp scanner.
This is the first local-native integration to follow the memory-doc
convention (webview sources like WhatsApp already do). No CEF / CDP /
DOM / IDB needed — iMessage persists everything locally in SQLite, so
a single-tick scanner is sufficient.
Changes:
- New module `imessage_scanner/{mod,chatdb}.rs` with unit tests.
- `lib.rs`: register `ScannerRegistry` and spawn on setup (macOS only).
- `Cargo.toml`: add `anyhow`, `parking_lot`, `chrono`, and
macOS-only `rusqlite` (bundled).
Feature-gated to `target_os = "macos"`; non-macOS builds get a no-op
stub. Requires Full Disk Access to read chat.db — the read_since
helper surfaces a clear error pointing at System Settings on
permission failure.
* test(imessage): add real chat.db integration tests (ignored by default)
Two tests validating against the actual ~/Library/Messages/chat.db:
- real_chat_db_opens_and_returns_messages — confirms the SQL JOIN is
compatible with macOS's actual schema, rusqlite bindings deserialize
rows into our Message struct, and Full Disk Access errors surface
cleanly when denied.
- real_chat_db_empty_past_cursor — confirms cursor semantics (rows
past i64::MAX-1 return empty).
Both gated with #[ignore] so CI remains green without FDA. Run with:
cargo test --manifest-path app/src-tauri/Cargo.toml \
--lib imessage_scanner -- --ignored
Verified locally against a 463K-message chat.db: both pass.
* fix(imessage): address CodeRabbit review — data loss, upsert correctness, client reuse, local TZ
Four fixes stacked on top of the scanner from the previous commit:
1. Data-loss bug (major): newer macOS versions store the body in
attributedBody (NSKeyedArchiver/typedstream blob) with text = NULL.
chatdb now fetches attributedBody alongside text. format_transcript
falls back to a heuristic extractor (longest printable-ASCII run,
skipping known typedstream type markers) when text is absent. This
recovers the plain-text body on macOS >= 11 without pulling in a
full typedstream decoder. Emoji / non-Latin glyphs in attributedBody
are deferred (follow-up).
2. Correctness bug (major): per-tick groups were ingested as partial
deltas but keyed on (chat, day) — each tick\'s upsert replaced the
full-day transcript with just the minute\'s messages. Now on each
tick we collect unique (chat, day) keys touched by the new rows,
call chatdb::read_chat_day() to fetch the complete day slice, and
post the full transcript. Upsert is idempotent; re-runs after a
crash reproduce the same document.
3. Cursor persistence: last_rowid is now read from / written to a file
under the Tauri app-data dir (per account) so a restart doesn\'t
replay the whole 30-day backfill.
4. Nits: reqwest::Client is shared via OnceLock (one TLS/pool init),
and day grouping uses chrono::Local so the user-facing (chat, day)
keys line up with the user\'s calendar day instead of UTC.
Tests: 6 unit tests green (added extractor + message_body + local-tz
coverage); 2 real-db integration tests (ignored by default) still pass
against the 463k-message chat.db on my machine.
* fix(imessage): gate scanner startup on feature="cef" to match module decl
Module declaration is #[cfg(feature = "cef")], so the macOS setup block
that references imessage_scanner::ScannerRegistry must carry the same
feature gate or wry builds fail to resolve the symbol.
* feat(channels): register iMessage channel with local-only auth + config persistence
iMessage already has the AppleScript send/receive bridge in channels/providers/imessage.rs
and the startup wiring in channels/runtime/startup.rs, but was missing from the public
channel registry, so the UI can't list or connect it and `connect_channel` returns
"unknown channel: imessage".
This adds:
- imessage_definition() in the channel registry with ManagedDm auth mode and an
optional allowed_contacts field (comma-separated phone numbers / emails; * for any)
- Short-circuit branch in connect_channel: iMessage has no credentials to store, so
it persists channels_config.imessage (IMessageConfig { allowed_contacts }) and
returns connected without calling store_provider_credentials (which rejects
empty credential payloads)
- Matching branch in disconnect_channel: skips remove_provider_credentials and
clears channels_config.imessage
- Three unit tests: contacts persisted, empty contacts allowed, disconnect clears
Capabilities: SendText + ReceiveText. No SendRichText (AppleScript bridge is
plaintext only).
Test plan:
- cargo test -p openhuman --lib channels::controllers → 66 passed
- Still need GUI end-to-end with FDA granted; covered in follow-up.
* fix(imessage-scanner): address CodeRabbit review (PR #725)
- chatdb: filter queries to `service = 'iMessage'` so SMS/MMS rows
in chat.db are never ingested into the iMessage channel.
- scanner: gate every tick on `channels_config.imessage` via the
existing `openhuman.config_get` JSON-RPC — no ingestion before
the user connects, and scanning stops as soon as they disconnect.
- scanner: apply the configured `allowed_contacts` allowlist before
rebuilding/ingesting each chat (`*` or empty list means allow all).
- scanner: keep the cursor pinned when a full-day read or memory
write fails, so a transient core outage no longer permanently
skips messages.
- tests: add `chat_allowed` coverage for empty list, wildcard, and
case-insensitive exact match.
---------
Co-authored-by: Jwalin Shah <jshah1331@gmail.com>
Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai>
OpenHuman
The age of super intelligence is here. OpenHuman is your Personal AI super intelligence. Private, Simple and extremely powerful.
Discord • Reddit • X/Twitter • Docs
"The Tet. What a brilliant machine" — Morgan Freeman as he reminisces about alien superintelligence in the movie Oblivion
Early Beta — Under active development. Expect rough edges.
To install or get started, either download from the website over at tinyhumans.ai/openhuman or run
# For MacOS/Linux
curl -fsSL https://raw.githubusercontent.com/tinyhumansai/openhuman/main/scripts/install.sh | bash
# For Windows
irm https://raw.githubusercontent.com/tinyhumansai/openhuman/main/scripts/install.ps1 | iex
What is OpenHuman?
OpenHuman is an open-source agentic assistant that is designed to integrate with you in your daily life. Here's what makes OpenHuman special:
-
Simple, UI-first — A clean desktop experience and short onboarding paths so you can go from install to a working agent in a few clicks, without a config-first setup. You don't need a terminal to run OpenHuman.
-
One subscription, many providers — You only need one account to get access to many agentic APIs (AI Models, Search, Webhooks/Tunnels and other 3rd party APIs etc..), simplifying the experience to get a powerful agent going.
-
Rich Skills — Plug into Gmail, Slack, Notion, and the rest of your stack via rich, feature-backed skills. Connections are typically one click through setup wizards instead of wiring APIs by hand. Workflow data is kept on device, encrypted locally, and treated as yours: encryption and sensitive context stay on your machine. Webhooks give instant feedback into the agent when external systems or skills emit events, so the loop stays tight without constant polling.
-
Local knowledge base — Built from your data and your activity. How you work across tools, sessions, and connected services—so the agent gets rich, workflow-aware context, not a one-off chat transcript. Everything is stored on your machine and compounding over time without becoming a cloud dossier. Channels, skills and ongoing conversations feed the same loop so day-to-day context does not reset every session.
-
Local AI model — The Rust core exposes local AI paths (and the desktop bundle can ship local/bundled runners where applicable) for the workloads above—vision snippets, speech helpers, summarization, tooling—so sensitive steps can stay off the cloud when you choose.
-
Deep desktop integrations — OpenHuman is a native desktop assistant, not a web-only chat: memory-aware keyboard autocomplete, voice (STT listening and TTS replies), screen intelligence that understands what is on screen and feeds your local context, plus windowing and OS-level permissions—so the agent meets you on the machine, not trapped in a browser tab.
Architecture: docs/ARCHITECTURE.md. Contributor orientation: CONTRIBUTING.md. Running from source: docs/install.md.
OpenHuman vs other agents
High-level comparison (products evolve—verify against each vendor). OpenHuman is built to minimize vendor sprawl, keep workflow knowledge on-device, and ship deep desktop features—not only chat.
| Claude Code/Cowork | OpenClaw | Hermes Agent | OpenHuman | |
|---|---|---|---|---|
| Open-source: Is the codebase open to review? | 🚫 Proprietary client | ✅ MIT License | ✅ MIT License | ✅ GNU License |
| Simple: Is it simple to get started? | ✅ Simple Desktop App + CLI | ⚠️ Terminal first and often complex | ⚠️ Terminal first and often complex | ✅ Simple, Clean UI/UX. Get started within minutes |
| Cost: How expensive is to run? | ⚠️ Subscription + add-on tool/API costs | ⚠️ Tied to models & hosting you choose | ⚠️ Tied to models & hosting you choose | ✅ Cost optimized with the option to run many things locally for free |
| Memory & Knowledge Base (KB): Does the agent know you and your world? | ✅ Built-in memory; mostly chat/session scoped | ⚠️ Has a local memory but often needs plugins for richer behavior | ✅ Self-learning / task loops (typical) | 🚀 Local KB + Self-learning from your activity & data (GMail, Notion etc... via skills) & prompts |
| API spagetti: How complex is it to hook mulitple features together? | 🚫 Claude bill + often extra keys for MCP/tools | 🚫 BYOK / multi-vendor common | 🚫 Multiple providers common | ✅ One account get access to many bundled platform APIs |
| Extensibility: Can you add rich features into it? | ✅ MCP (different model than sandboxed skills) | ✅ Plugin Architecture (SKILL.md) | ✅ Plugin Architecture (SKILL.md) | 🚀 Rich Skills with ability to have realtime updates, local DB & more |
| Desktop integrations: Can it integrate into your desktop completely? | ⚠️ Desktop app & access to folders | ⚠️ Often lighter native surface | ⚠️ Often lighter native surface | ✅ STT, TTS, screen intelligence, memory-aware autocomplete and a whole lot more |
Contributors Hall of Fame
Show some love and end up in the hall of fame
