Releases: mrdulasolutions/AOS-Mail
AOS Mail v0.1.9
AOS Mail v0.1.9
See attached .dmg for installation. Auto-update users will pick
up this release through the in-app updater (latest.json) once
this draft is published.
Generated by GitHub Actions on tag push.
AOS Mail v0.1.8
AOS Mail v0.1.8
See attached .dmg for installation. Auto-update users will pick
up this release through the in-app updater (latest.json) once
this draft is published.
Generated by GitHub Actions on tag push.
v0.1.7 — briefing dismiss + Agent panel + sync-flush perf
Briefing dismiss → blank inbox
Clicking 'Got it — open inbox' now lands you on Priority (where the briefed action items live), not the empty Other tab. Default split for new sessions is now All instead of the structurally-empty Other.
Agent panel
The Agents sidebar shows a clear 'Inbox Agent runs automatically' V1 summary instead of 'No agents available.' Manage button routes to Settings → Agents specifically.
Sync-flush perf
Three no-op short-circuits on the renderer hot path. Background sync re-emissions of unchanged data no longer trigger O(N) groupByThread recomputes over 2500+ emails. Steady-state polling cycles should feel snappier.
v0.1.6 — triage rate-limiting, sender feedback, calendar subscriptions
AOS Mail v0.1.6 — triage rate-limiting + sender feedback + native calendar (V1)
What's new
Triage no longer burns through tokens
Previous behavior: boot triage of 50–100 unanalyzed emails per account fanned out at concurrency=4 with no rate-limit awareness, blew through Anthropic's 50 RPM org cap, hit a 5-attempt exponential-backoff retry storm per call, and left some emails un-analyzed → next boot retried the same emails → token-burning loop.
v0.1.6:
- Process-wide sliding-window token bucket: 30 req/min comfortably under the 50 RPM ceiling.
- Concurrency reduced from 4 → 2 — the worker pool no longer races ahead of the limiter.
- 30-min in-memory cooldown on hard-failed analyses — a rate-limited email returns a transient stub instead of immediately re-attempting.
Sender About feedback loop
The "About" panel for each email's sender now ends with 👍 Yes / 👎 No. Saying "no" deletes the cached profile so the next open re-fetches with a fresh web search instead of re-serving a wrong bio. All ratings persist locally for prompt iteration in the next sprint.
Native calendar V1: subscribe to any iCal URL
Paste a public iCal URL — works for Apple iCloud public-share calendars, Outlook published calendars, Google Calendar's "secret address in iCal format", or any RFC 5545 stream. Events appear alongside any Gmail-Calendar events you've connected. Available in Settings → Calendar → Subscribed calendars.
This unblocks the calendar story for IMAP-only users who don't have Google Calendar tied to their account. Recurring rules (RRULE) and full timezone resolution are deferred to V2 — single-instance events parse cleanly today.
Naming
Release assets now use the simpler AOSMail-V<version> convention (hyphen separator, no spaces, no parens):
AOSMail-V0.1.6.dmgAOSMail-V0.1.6.app.tar.gzAOSMail-V0.1.6.app.tar.gz.siglatest.json
The repo is now public, so auto-update should work for the first time on this version.
Known issues NOT fixed in v0.1.6
- Agent panel is empty + Manage button is a stub — needs investigation.
- General slowness (search → email body load, etc.) — needs profiling.
- Top Mac nav buttons previously reported broken — wiring inspected and looks correct; need a fresh repro on this build.
v0.1.5 — six user-feedback fixes
AOS Mail v0.1.5 — six user-feedback fixes
What's fixed
- Inbox folder click takes you home. Previously it just changed
currentFolder— if you were in calendar / awaiting-reply / a full thread / search / settings, the inbox click was a visual no-op. Now it also resets the view, clears search, and closes the settings overlay. - Permissions tray rows open the email. Click the subject/preview area or the new "Open" button to navigate to the thread. Approve / Skip stay as quick actions.
- Awaiting-reply nudge actually navigates. Now searches both inbox AND sent caches for the thread anchor (previously inbox-only — IMAP sent folders never matched). Falls back to the newest message in either store so the composer always has something to attach to.
- Prompts default-load on first install. Settings → Prompts no longer ships blank for analysis + draft prompts; defaults populate on first open. Previously two of three required clicking "Reset to default".
- Send toast countdown bar. Apple-Mail-style drain bar across the bottom of the undo toast row, refreshed at 60fps via rAF, drains right-to-left as the undo window expires.
- Briefing button in top nav with morning/afternoon/evening/night theming — already shipped in v0.1.4, included here for completeness.
Naming
Release assets now use the AOSMail Release V<version> convention:
AOSMail Release V0.1.5.dmgAOSMail Release V0.1.5.app.tar.gzAOSMail Release V0.1.5.app.tar.gz.siglatest.json
Captured for follow-up sprints (NOT in v0.1.5)
- Triage re-running for analyzed emails — concurrency limiting + rate-limit cooldown
- Sender About inaccuracy — feedback button + prompt iteration
- Native calendar for IMAP users — CalDAV + ICS + Outlook + native sharing
- Agent panel empty + can't create agents
- General slowness — search-result email opening, prefetch storm
Known issues unchanged
- Auto-update fails — repo is private; GitHub release assets need auth which the updater can't carry. Make the repo public to fix.
- Top Mac nav buttons — wiring inspected, looks correct in code; need fresh repro on this build to investigate.
v0.1.4 — IMAP folders, briefing dismiss, analytics persist, 5 broken links, briefing nav button
AOS Mail v0.1.4 — eight-issue user-feedback patch
What's fixed
| Issue | Fix |
|---|---|
IMAP folder rail showed gmail.listLabels: No tokens for every IMAP account, on every Mac |
The renderer's accounts.list mapping was dropping the provider field, so account.provider was always undefined and FolderRail's IMAP-vs-Gmail dispatch always took the Gmail branch. Bug shipped silently since IMAP support landed. |
| "Got it — open inbox" on the morning briefing was a no-op | Dismiss mutation invalidated ["briefing"], but the gate query that controls visibility uses ["briefing-gate"]. Different keys → gate never refetched → briefing kept rendering. Now invalidates both. |
| Analytics toggle reset to OFF every reopen | Save handler never invalidated React Query's ["general-config"] cache; the 5-min stale-time returned the pre-save value on the next open. Now invalidates after save. |
| Five external links did nothing when clicked (Google Cloud Console ×2, Anthropic Console, Hostinger app-password help, Google Calendar event link) | Tauri's webview no-ops <a target="_blank">. New openExternalUrl() helper using tauri-plugin-shell; converted every external link to a <button onClick>. |
What's new
- Briefing button in the top nav — sun-icon button next to the calendar toggle. Re-opens today's briefing on demand, even after dismissal. Disabled while the briefing is already on screen.
- Time-of-day theming for the briefing — morning is amber sunrise, afternoon is sky blue, evening is indigo twilight, late night is deep slate. Sun icon swaps to a moon for evening + night. Eyebrow label adapts ("Morning briefing" / "Evening briefing" / etc.).
Known issues NOT fixed in v0.1.4
- "Check for updates" still fails with "could not reach valid JSON from remote". Independent of code: the GitHub repo is currently
private, and GitHub release assets return 404 over plain HTTPS for private repos. Tauri's auto-updater can't authenticate. Either (a) make the repo public — fixes immediately, or (b) host the manifest on a public CDN. - Top Mac nav button regressions reported by user — wiring inspected and looks correct in code. Need a fresh repro on this v0.1.4 build to investigate further.
Naming change
Release assets now use the AOSmailv<version> convention:
AOSmailv0.1.4.dmgAOSmailv0.1.4.app.tar.gzAOSmailv0.1.4.app.tar.gz.siglatest.json
v0.1.3 — self-contained .app (bundles Node + better-sqlite3)
AOS Mail v0.1.3 — self-contained .app, end of "sidecar channel closed"
What this fixes
The "sidecar channel closed before response" error that broke Add Account on every Mac without a developer's exact Node.js setup.
Root cause (full story): the sidecar process was a bash stub that did exec node $TMP. When AOS Mail launched via Spotlight / Dock / Finder, macOS launchd handed the app a minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin) — no /usr/local/bin, no /opt/homebrew/bin. So node wasn't found. Bash exited 127 immediately. Tauri saw the child terminate. Every single RPC the renderer tried to make returned ChannelClosed, including the one that pops up when you click "Connect Gmail" or "Connect IMAP".
v0.1.2 fixed it for Macs that had Node.js installed at /opt/homebrew/bin, /usr/local/bin, or ~/.nvm/... — by hardcoding those probes. But that still required the user to have Node.js installed somewhere standard. Many Macs don't (Node is a developer tool, not a system runtime). That's why some users still saw the bug.
What v0.1.3 does
The .app now contains everything it needs. No system Node.js install required, no PATH dependency, nothing for the user to do.
Contents/MacOS/aos-mail-node— bundled Node.js arm64 binary, signed with our Developer ID + hardened runtime + Apple's secure timestamp.Contents/Resources/runtime-modules/— the onlynode_modulespackages the bundled JS needs at runtime (better-sqlite3,bindings,file-uri-to-path— ~2 MB pruned to justlib/andbuild/Release/*.node).better_sqlite3.nodere-signed with our Developer ID so Apple notarization accepts it.- The bash stub now finds node as a sibling (
$SIDECAR_DIR/aos-mail-node) and points NODE_PATH at the bundled modules. Same code path on every Mac.
Verified end-to-end under exactly PATH=/usr/bin:/bin:/usr/sbin:/sbin (the launchd-default that every Spotlight launch sees) — sidecar boots, opens SQLite, responds to ping with node:'v24.14.0'. Every Mac, every launch method, every time.
Tradeoff
DMG size went from ~9 MB → 46 MB; installed .app from ~43 MB → 158 MB. Worth it for the reliability win. v0.2 will graduate to Node SEA (Single Executable Applications) which can shrink this back down without giving up the self-containedness.
Auto-update
Existing v0.1.x installs will auto-update to v0.1.3 silently on next launch. macOS Apple Silicon only.
v0.1.2 — fix sidecar channel closed on Add Account
AOS Mail v0.1.2 — fixes the "sidecar channel closed" bug on Add Account
This is the fix for the showstopper bug introduced silently in v0.1.0 / v0.1.1 where clicking "Connect Gmail" or "Connect IMAP" would always produce bridge.call(...) failed: sidecar channel closed before response — making it impossible to add the very accounts the app exists to manage.
What was actually broken
When AOS Mail.app is launched via Spotlight / Finder / Dock (cold start), macOS's launchd hands the app a minimal PATH:
/usr/bin:/bin:/usr/sbin:/sbin
That doesn't include /usr/local/bin (where the standard Node.js installer puts node) or /opt/homebrew/bin (where Apple Silicon Homebrew puts it). The sidecar's bash stub did:
exec node "$TMP" "$@"— a bare command name, looked up in $PATH. On Spotlight launches that lookup failed with node: not found, bash exited 127 before the bundled JavaScript ever loaded, Tauri's plugin-shell saw the child terminate instantly, and every IPC call from the renderer returned ChannelClosed.
This is why the bug was so confusing to diagnose:
- When launched via
openfrom a terminal whose$PATHalready contained/usr/local/bin, the sidecar inherited the user's PATH, found node, and worked perfectly. - When launched via Spotlight, dead on arrival, with zero log entries because the failure was earlier in the boot sequence than the logger module.
What v0.1.2 fixes
The bash stub now probes node install locations explicitly, in priority order:
/opt/homebrew/bin/node(Apple Silicon Homebrew)/usr/local/bin/node(Intel Homebrew + standard Node.js installer)/opt/local/bin/node(MacPorts)/usr/bin/node(system, rare)~/.nvm/versions/node/*/bin/node(latest nvm install)command -v nodefallback
If none are found, prints an actionable error to stderr and exits 127 — at minimum the diagnostic is clear, instead of a silent dead-on-arrival sidecar.
Verified: under exactly PATH=/usr/bin:/bin:/usr/sbin:/sbin (the launchd default), the sidecar boots, opens the database, responds to ping with {ok:true,node:'v24.14.0'}, and exits cleanly on stdin EOF.
Bonus fixes from the same dive
While diagnosing the above, two adjacent bugs were also fixed:
- Logger EPIPE recursion. A previous attempt at instrumentation introduced an
uncaughtExceptionhandler that wrote diagnostics to stderr — but stderr was also broken when stdout was, causing infinite recursion that wrote 1.5 GB to the log file before Node OOMed. v0.1.2's logger now wraps every write in try/catch, sticky-disables broken streams, caps the log file at 16 MB with rotation, and treats EPIPE on stdout as a graceful-exit signal. - Sidecar tempfile leak. Each sidecar launch had been leaking ~33 MB to
/var/folders/.../T/because the bash stub'sEXITtrap doesn't reliably fire afterexec. Cleaning up freed ~2.3 GB on the test machine. (Long-term fix in v0.2 will graduate the sidecar to a Node SEA so this whole class of issues disappears.)
Auto-update
Existing v0.1.x installs auto-update silently on next launch. macOS Apple Silicon only.
Long-term
A v0.2 release will bundle Node.js inside the .app bundle so "node not installed" stops being a possible failure mode at all. Today that's deferred — the v0.1.2 lookup-fallback handles 99% of users since virtually every macOS dev machine has node installed in one of the probed locations.
v0.1.1 — fix sidecar EPIPE recursion + IMAP error copy
AOS Mail v0.1.1
Bug fix release.
What was broken
In v0.1.0, clicking "Add IMAP account" or "Add Gmail account" frequently produced "sidecar channel closed before response" — the sidecar process would die mid-call. Worse, it would keep dying in a tight loop and write gigabytes of repeated EPIPE errors to ~/Library/Application Support/AOS Mail/sidecar.log before Node finally OOMed.
Root cause: a self-inflicted infinite recursion in the sidecar's logger. When process.stdout.write threw EPIPE (parent disconnected, or pipe buffer overrun under the boot-time analyzer storm), the global uncaughtException handler tried to log the error via process.stderr.write — which also threw EPIPE — which re-entered the same handler. Each iteration also did an appendFileSync to disk. In one production crash the log grew to 1.5 GB.
What v0.1.1 fixes
stdoutandstderrwrites are wrapped intry/catch. EPIPE is absorbed locally, never escalated touncaughtException.- Once a stream is known broken, we stop retrying —
stdoutBroken/stderrBrokensticky flags. - The logger's file write is capped at 16 MB with auto-rotation (
sidecar.log→sidecar.log.prev) so a runaway write loop cannot fill the disk again. uncaughtExceptionandunhandledRejectionrecognize EPIPE and trigger graceful sidecar shutdown instead of trying to log through the broken pipe.- Direct
errorevent listeners onprocess.stdout/process.stderrabsorb stream errors before they escalate.
What v0.1.1 also fixes
-
IMAP auth-failure error copy. Hostinger / iCloud / Gmail all return imapflow's generic "Command failed" string when authentication fails, which we then displayed verbatim. v0.1.1 translates that into:
"Authentication failed — your email address or password didn't work. Many providers (Gmail, iCloud, Yahoo, Outlook, Hostinger) require an app-specific password rather than your account password. Check your provider's account-security page for one. (Server response: Command failed)"
And the renderer now strips the
bridge.call(imap.addAccount) failed: sidecar returned error:prefix so users see only the actionable copy.
Auto-update
Existing v0.1.0 installs will auto-update to v0.1.1 silently (Tauri updater pointed at releases/latest/download/latest.json). On macOS Apple Silicon only.
v0.1.0 — first public preview
AOS Mail v0.1.0 — first public preview
The first signed, notarized, auto-update-capable build. macOS only (Apple Silicon arm64).
What this is
AOS Mail is a downstream fork of Ankit Gupta's Exo. Exo gave us the agent loop, the Gmail integration, the draft pipeline, and the product shape. AOS Mail rewrites the shell, adds multi-inbox support, layers in a wider agent surface, and lands native Mac chrome on top.
See the README for the full delta.
What's in v0.1.0
Shell (rewritten from Electron)
- Tauri 2 Rust shell with
NSVisualEffectViewvibrancy, traffic-light positioning, hardened runtime, native menu bar, native notifications, dock badge. - Node sidecar for the entire backend (Gmail, IMAP, agents, SQLite). NDJSON JSON-RPC over stdio with end-to-end-typed contract.
- Keychain integration via Rust
keyring— passwords and OAuth refresh tokens never on disk in cleartext. - ~9 MB DMG, ~43 MB unpacked
.app(down from Electron's 80 MB+).
Inboxes
- Gmail (OAuth + History API).
- IMAP/SMTP — iCloud, Fastmail, Outlook, Yahoo, custom domains. IDLE for push, polling fallback.
- Per-account splits, snooze, drafts, learned rules.
Agent
- Triage with priority + 1-line summary on every email.
- Thread summaries (cached per
thread_id × last_message_id). - Draft replies in your voice from a sent-mail style profile.
- Morning Briefing — wake-up digest panel.
- Smart-action key — single-keystroke runs the agent's recommendation for the current thread, with full undo.
- Awaiting-reply nudges with snooze interaction.
- Learned rules — pattern detection, explicit user confirmation.
- OpenRouter as a Claude alternative for users who want an open-weight path.
- Permission tray + filterable audit log.
UX
- j/k keyboard, Cmd+K command palette, Cmd+J agent palette.
- Unified toast queue with global Cmd+Z undo across every action type.
- Hybrid local FTS5 + remote search.
- Day-view calendar with Google Calendar sync.
Install
- Download
AOS_Mail_0.1.0_aarch64.dmgfrom this release. - Double-click → drag
AOS Mailto/Applications. - First launch will ask you to paste your Anthropic key (or OpenRouter key) and connect Gmail or IMAP. You can also Skip and add an inbox later from Settings.
The DMG is signed by Developer ID Application: Matthew Dula (PPY9K2BYJH) and notarized by Apple — Gatekeeper accepts it on any Mac without warnings.
Auto-update
Future versions auto-update via Tauri's built-in updater pointed at https://github.com/mrdulasolutions/AOS-Mail/releases/latest/download/latest.json. v0.1.0 is the first version to sign update manifests, so you'll start getting auto-update prompts beginning with v0.1.1.
Known caveat
If you were running an unsigned dev build before installing this DMG, your data dir at ~/Library/Application Support/AOS Mail/ carries over cleanly — accounts, splits, rules, snippets, and the SQLite database are all reused.
License
BUSL-1.1, with full attribution to upstream Exo.